diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 9becc5eff794..f10014fa1d14 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -193,20 +193,6 @@ Why: /proc//oom_adj allows userspace to influence the oom killer's --------------------------- -What: CS5535/CS5536 obsolete GPIO driver -When: June 2011 -Files: drivers/staging/cs5535_gpio/* -Check: drivers/staging/cs5535_gpio/cs5535_gpio.c -Why: A newer driver replaces this; it is drivers/gpio/cs5535-gpio.c, and - integrates with the Linux GPIO subsystem. The old driver has been - moved to staging, and will be removed altogether around 3.0. - Please test the new driver, and ensure that the functionality you - need and any bugfixes from the old driver are available in the new - one. -Who: Andres Salomon - --------------------------- - What: remove EXPORT_SYMBOL(kernel_thread) When: August 2006 Files: arch/*/kernel/*_ksyms.c diff --git a/MAINTAINERS b/MAINTAINERS index f5474304e7ba..128829424747 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1546,9 +1546,10 @@ F: drivers/net/tg3.* BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER M: Brett Rudley M: Henry Ptasinski -M: Dowan Kim M: Roland Vossen M: Arend van Spriel +M: Franky (Zhenhui) Lin +M: Kan Yan L: linux-wireless@vger.kernel.org S: Supported F: drivers/staging/brcm80211/ @@ -6092,6 +6093,145 @@ L: devel@driverdev.osuosl.org S: Maintained F: drivers/staging/ +STAGING - AGERE HERMES II and II.5 WIRELESS DRIVERS +M: Henk de Groot +S: Odd Fixes +F: drivers/staging/wlags49_h2/ +F: drivers/staging/wlags49_h25/ + +STAGING - ASUS OLED +M: Jakub Schmidtke +S: Odd Fixes +F: drivers/staging/asus_oled/ + +STAGING - ATHEROS ATH6KL WIRELESS DRIVER +M: Luis R. Rodriguez +M: Naveen Singh +S: Odd Fixes +F: drivers/staging/ath6kl/ + +STAGING - COMEDI +M: Ian Abbott +M: Mori Hess +S: Odd Fixes +F: drivers/staging/comedi/ + +STAGING - CRYSTAL HD VIDEO DECODER +M: Naren Sankar +M: Jarod Wilson +M: Scott Davilla +M: Manu Abraham +S: Odd Fixes +F: drivers/staging/crystalhd/ + +STAGING - CYPRESS WESTBRIDGE SUPPORT +M: David Cross +S: Odd Fixes +F: drivers/staging/westbridge/ + +STAGING - ECHO CANCELLER +M: Steve Underwood +M: David Rowe +S: Odd Fixes +F: drivers/staging/echo/ + +STAGING - FLARION FT1000 DRIVERS +M: Marek Belisko +S: Odd Fixes +F: drivers/staging/ft1000/ + +STAGING - FRONTIER TRANZPORT AND ALPHATRACK +M: David Täht +S: Odd Fixes +F: drivers/staging/frontier/ + +STAGING - HYPER-V (MICROSOFT) +M: Hank Janssen +M: Haiyang Zhang +S: Odd Fixes +F: drivers/staging/hv/ + +STAGING - INDUSTRIAL IO +M: Jonathan Cameron +L: linux-iio@vger.kernel.org +S: Odd Fixes +F: drivers/staging/iio/ + +STAGING - LIRC (LINUX INFRARED REMOTE CONTROL) DRIVERS +M: Jarod Wilson +W: http://www.lirc.org/ +S: Odd Fixes +F: drivers/staging/lirc/ + +STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON) +M: Andres Salomon +M: Chris Ball +M: Jon Nettleton +W: http://wiki.laptop.org/go/DCON +S: Odd Fixes +F: drivers/staging/olpc_dcon/ + +STAGING - PARALLEL LCD/KEYPAD PANEL DRIVER +M: Willy Tarreau +S: Odd Fixes +F: drivers/staging/panel/ + +STAGING - REALTEK RTL8712U DRIVERS +M: Larry Finger +M: Florian Schilhabel . +S: Odd Fixes +F: drivers/staging/rtl8712/ + +STAGING - SILICON MOTION SM7XX FRAME BUFFER DRIVER +M: Teddy Wang +S: Odd Fixes +F: drivers/staging/sm7xx/ + +STAGING - SOFTLOGIC 6x10 MPEG CODEC +M: Ben Collins +S: Odd Fixes +F: drivers/staging/solo6x10/ + +STAGING - SPEAKUP CONSOLE SPEECH DRIVER +M: William Hubbs +M: Chris Brannon +M: Kirk Reiser +M: Samuel Thibault +L: speakup@braille.uwo.ca +W: http://www.linux-speakup.org/ +S: Odd Fixes +F: drivers/staging/speakup/ + +STAGING - TI DSP BRIDGE DRIVERS +M: Omar Ramirez Luna +S: Odd Fixes +F: drivers/staging/tidspbridge/ + +STAGING - TRIDENT TVMASTER TMxxxx USB VIDEO CAPTURE DRIVERS +L: linux-media@vger.kernel.org +S: Odd Fixes +F: drivers/staging/tm6000/ + +STAGING - USB ENE SM/MS CARD READER DRIVER +M: Al Cho +S: Odd Fixes +F: drivers/staging/keucr/ + +STAGING - VIA VT665X DRIVERS +M: Forest Bond +S: Odd Fixes +F: drivers/staging/vt665?/ + +STAGING - WINBOND IS89C35 WLAN USB DRIVER +M: Pavel Machek +S: Odd Fixes +F: drivers/staging/winbond/ + +STAGING - XGI Z7,Z9,Z11 PCI DISPLAY DRIVER +M: Arnaud Patard +S: Odd Fixes +F: drivers/staging/xgifb/ + STARFIRE/DURALAN NETWORK DRIVER M: Ion Badulescu S: Odd Fixes @@ -6594,13 +6734,6 @@ W: http://pegasus2.sourceforge.net/ S: Maintained F: drivers/net/usb/rtl8150.c -USB SE401 DRIVER -L: linux-usb@vger.kernel.org -W: http://www.chello.nl/~j.vreeken/se401/ -S: Orphan -F: Documentation/video4linux/se401.txt -F: drivers/staging/se401/ - USB SERIAL BELKIN F5U103 DRIVER M: William Greathouse L: linux-usb@vger.kernel.org diff --git a/arch/arm/mach-ux500/board-mop500-u8500uib.c b/arch/arm/mach-ux500/board-mop500-u8500uib.c index d8a8734a0eba..8ce46c0fdfd5 100644 --- a/arch/arm/mach-ux500/board-mop500-u8500uib.c +++ b/arch/arm/mach-ux500/board-mop500-u8500uib.c @@ -12,34 +12,14 @@ #include #include #include -#include <../drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h> #include #include #include "board-mop500.h" -/* - * Synaptics RMI4 touchscreen interface on the U8500 UIB - */ - -/* - * Descriptor structure. - * Describes the number of i2c devices on the bus that speak RMI. - */ -static struct synaptics_rmi4_platform_data rmi4_i2c_dev_platformdata = { - .irq_number = NOMADIK_GPIO_TO_IRQ(84), - .irq_type = (IRQF_TRIGGER_FALLING | IRQF_SHARED), - .x_flip = false, - .y_flip = true, - .regulator_en = false, -}; - -static struct i2c_board_info __initdata mop500_i2c3_devices_u8500[] = { - { - I2C_BOARD_INFO("synaptics_rmi4_i2c", 0x4B), - .platform_data = &rmi4_i2c_dev_platformdata, - }, +/* Dummy data that can be overridden by staging driver */ +struct i2c_board_info __initdata __weak mop500_i2c3_devices_u8500[] = { }; /* diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 196284dc2f36..06c9081d596d 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -24,10 +24,6 @@ menuconfig STAGING if STAGING -source "drivers/staging/tty/Kconfig" - -source "drivers/staging/generic_serial/Kconfig" - source "drivers/staging/et131x/Kconfig" source "drivers/staging/slicoss/Kconfig" @@ -100,8 +96,6 @@ source "drivers/staging/sep/Kconfig" source "drivers/staging/iio/Kconfig" -source "drivers/staging/cs5535_gpio/Kconfig" - source "drivers/staging/zram/Kconfig" source "drivers/staging/zcache/Kconfig" @@ -120,8 +114,6 @@ source "drivers/staging/cxt1e1/Kconfig" source "drivers/staging/xgifb/Kconfig" -source "drivers/staging/msm/Kconfig" - source "drivers/staging/lirc/Kconfig" source "drivers/staging/easycap/Kconfig" @@ -132,8 +124,6 @@ source "drivers/staging/tidspbridge/Kconfig" source "drivers/staging/quickstart/Kconfig" -source "drivers/staging/westbridge/Kconfig" - source "drivers/staging/sbe-2t3e3/Kconfig" source "drivers/staging/ath6kl/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index fa41b9c23783..f3c5e33bb263 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -3,8 +3,6 @@ # fix for build system bug... obj-$(CONFIG_STAGING) += staging.o -obj-y += tty/ -obj-y += generic_serial/ obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ obj-$(CONFIG_VIDEO_GO7007) += go7007/ @@ -41,7 +39,6 @@ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_IIO) += iio/ -obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio/ obj-$(CONFIG_ZRAM) += zram/ obj-$(CONFIG_XVMALLOC) += zram/ obj-$(CONFIG_ZCACHE) += zcache/ @@ -52,12 +49,10 @@ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ obj-$(CONFIG_CRYSTALHD) += crystalhd/ obj-$(CONFIG_CXT1E1) += cxt1e1/ obj-$(CONFIG_FB_XGI) += xgifb/ -obj-$(CONFIG_MSM_STAGING) += msm/ obj-$(CONFIG_EASYCAP) += easycap/ obj-$(CONFIG_SOLO6X10) += solo6x10/ obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/ obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/ -obj-$(CONFIG_WESTBRIDGE_ASTORIA) += westbridge/astoria/ obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/ obj-$(CONFIG_ATH6K_LEGACY) += ath6kl/ obj-$(CONFIG_USB_ENESTORAGE) += keucr/ diff --git a/drivers/staging/altera-stapl/Kconfig b/drivers/staging/altera-stapl/Kconfig index 7f01d8e93992..b6537321ed72 100644 --- a/drivers/staging/altera-stapl/Kconfig +++ b/drivers/staging/altera-stapl/Kconfig @@ -1,5 +1,3 @@ -comment "Altera FPGA firmware download module" - config ALTERA_STAPL tristate "Altera FPGA firmware download module" depends on I2C diff --git a/drivers/staging/altera-stapl/Makefile b/drivers/staging/altera-stapl/Makefile index 055f61ee781a..ddeede3c4b96 100644 --- a/drivers/staging/altera-stapl/Makefile +++ b/drivers/staging/altera-stapl/Makefile @@ -1,3 +1,3 @@ -altera-stapl-objs = altera-lpt.o altera-jtag.o altera-comp.o altera.o +altera-stapl-y := altera-lpt.o altera-jtag.o altera-comp.o altera.o obj-$(CONFIG_ALTERA_STAPL) += altera-stapl.o diff --git a/drivers/staging/altera-stapl/altera.c b/drivers/staging/altera-stapl/altera.c index 9cd5e76880c0..8d73a8642736 100644 --- a/drivers/staging/altera-stapl/altera.c +++ b/drivers/staging/altera-stapl/altera.c @@ -2430,16 +2430,23 @@ int altera_init(struct altera_config *config, const struct firmware *fw) int index = 0; s32 offset = 0L; s32 error_address = 0L; + int retval = 0; - key = kzalloc(33 * sizeof(char), GFP_KERNEL); - if (!key) - return -ENOMEM; - value = kzalloc(257 * sizeof(char), GFP_KERNEL); - if (!value) - return -ENOMEM; + key = kzalloc(33, GFP_KERNEL); + if (!key) { + retval = -ENOMEM; + goto out; + } + value = kzalloc(257, GFP_KERNEL); + if (!value) { + retval = -ENOMEM; + goto free_key; + } astate = kzalloc(sizeof(struct altera_state), GFP_KERNEL); - if (!astate) - return -ENOMEM; + if (!astate) { + retval = -ENOMEM; + goto free_value; + } astate->config = config; if (!astate->config->jtag_io) { @@ -2518,10 +2525,12 @@ int altera_init(struct altera_config *config, const struct firmware *fw) } else if (exec_result) printk(KERN_ERR "%s: error %d\n", __func__, exec_result); - kfree(key); - kfree(value); kfree(astate); - - return 0; +free_value: + kfree(value); +free_key: + kfree(key); +out: + return retval; } EXPORT_SYMBOL(altera_init); diff --git a/drivers/staging/ath6kl/TODO b/drivers/staging/ath6kl/TODO index 019df4b471eb..7be4b46ebb59 100644 --- a/drivers/staging/ath6kl/TODO +++ b/drivers/staging/ath6kl/TODO @@ -1,7 +1,7 @@ TODO: We are working hard on cleaning up the driver. There's sooooooooo much todo -so instead of editign this file please use the wiki: +so instead of editing this file please use the wiki: http://wireless.kernel.org/en/users/Drivers/ath6kl diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index 48dd9e363596..499b7a90e941 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -954,9 +954,13 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, const char *filename; const struct firmware *fw_entry; u32 fw_entry_size; + u8 **buf; + size_t *buf_len; switch (file) { case AR6K_OTP_FILE: + buf = &ar->fw_otp; + buf_len = &ar->fw_otp_len; if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { filename = AR6003_REV1_OTP_FILE; } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { @@ -970,6 +974,8 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, break; case AR6K_FIRMWARE_FILE: + buf = &ar->fw; + buf_len = &ar->fw_len; if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { filename = AR6003_REV1_FIRMWARE_FILE; } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { @@ -1028,6 +1034,8 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, break; case AR6K_PATCH_FILE: + buf = &ar->fw_patch; + buf_len = &ar->fw_patch_len; if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { filename = AR6003_REV1_PATCH_FILE; } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { @@ -1041,6 +1049,8 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, break; case AR6K_BOARD_DATA_FILE: + buf = &ar->fw_data; + buf_len = &ar->fw_data_len; if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { filename = AR6003_REV1_BOARD_DATA_FILE; } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { @@ -1057,23 +1067,29 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file)); return A_ERROR; } - if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename)); - return A_ENOENT; + + if (*buf == NULL) { + if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename)); + return A_ENOENT; + } + + *buf = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); + *buf_len = fw_entry->size; + A_RELEASE_FIRMWARE(fw_entry); } #ifdef SOFTMAC_FILE_USED - if (file==AR6K_BOARD_DATA_FILE && fw_entry->data) { - ar6000_softmac_update(ar, (u8 *)fw_entry->data, fw_entry->size); + if (file==AR6K_BOARD_DATA_FILE && *buf_len) { + ar6000_softmac_update(ar, *buf, *buf_len); } #endif - fw_entry_size = fw_entry->size; + fw_entry_size = *buf_len; /* Load extended board data for AR6003 */ - if ((file==AR6K_BOARD_DATA_FILE) && (fw_entry->data)) { + if ((file==AR6K_BOARD_DATA_FILE) && *buf) { u32 board_ext_address; u32 board_ext_data_size; u32 board_data_size; @@ -1089,14 +1105,13 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address)); /* check whether the target has allocated memory for extended board data and file contains extended board data */ - if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) { + if ((board_ext_address) && (*buf_len == (board_data_size + board_ext_data_size))) { u32 param; - status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(fw_entry->data + board_data_size), board_ext_data_size); + status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(*buf + board_data_size), board_ext_data_size); if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); - A_RELEASE_FIRMWARE(fw_entry); return A_ERROR; } @@ -1110,17 +1125,16 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, } if (compressed) { - status = BMIFastDownload(ar->arHifDevice, address, (u8 *)fw_entry->data, fw_entry_size); + status = BMIFastDownload(ar->arHifDevice, address, *buf, fw_entry_size); } else { - status = BMIWriteMemory(ar->arHifDevice, address, (u8 *)fw_entry->data, fw_entry_size); + status = BMIWriteMemory(ar->arHifDevice, address, *buf, fw_entry_size); } if (status) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); - A_RELEASE_FIRMWARE(fw_entry); return A_ERROR; } - A_RELEASE_FIRMWARE(fw_entry); + return 0; } @@ -2088,6 +2102,11 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister) ar6000_remove_ap_interface(); #endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ + kfree(ar->fw_otp); + kfree(ar->fw); + kfree(ar->fw_patch); + kfree(ar->fw_data); + AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n")); } @@ -4114,6 +4133,13 @@ ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver) ar->arVersion.wlan_ver = sw_ver; ar->arVersion.abi_ver = abi_ver; + snprintf(ar->wdev->wiphy->fw_version, sizeof(ar->wdev->wiphy->fw_version), + "%u:%u:%u:%u", + (ar->arVersion.wlan_ver & 0xf0000000) >> 28, + (ar->arVersion.wlan_ver & 0x0f000000) >> 24, + (ar->arVersion.wlan_ver & 0x00ff0000) >> 16, + (ar->arVersion.wlan_ver & 0x0000ffff)); + /* Indicate to the waiting thread that the ready event was received */ ar->arWmiReady = true; wake_up(&arEvent); diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c index d3a774dbb7e8..5fdda4aa2fee 100644 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ b/drivers/staging/ath6kl/os/linux/cfg80211.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "ar6000_drv.h" @@ -867,26 +868,31 @@ ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status) AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status)); - if(ar->scan_request) - { - /* Translate data to cfg80211 mgmt format */ - if (ar->arWmi) - wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy); + if (!ar->scan_request) + return; - cfg80211_scan_done(ar->scan_request, - ((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false); + if ((status == A_ECANCELED) || (status == A_EBUSY)) { + cfg80211_scan_done(ar->scan_request, true); + goto out; + } - if(ar->scan_request->n_ssids && - ar->scan_request->ssids[0].ssid_len) { + /* Translate data to cfg80211 mgmt format */ + wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy); + + cfg80211_scan_done(ar->scan_request, false); + + if(ar->scan_request->n_ssids && + ar->scan_request->ssids[0].ssid_len) { u8 i; for (i = 0; i < ar->scan_request->n_ssids; i++) { - wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG, - 0, NULL); + wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG, + 0, NULL); } - } - ar->scan_request = NULL; } + +out: + ar->scan_request = NULL; } static int @@ -1453,6 +1459,159 @@ ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) return 0; } +#ifdef CONFIG_NL80211_TESTMODE +enum ar6k_testmode_attr { + __AR6K_TM_ATTR_INVALID = 0, + AR6K_TM_ATTR_CMD = 1, + AR6K_TM_ATTR_DATA = 2, + + /* keep last */ + __AR6K_TM_ATTR_AFTER_LAST, + AR6K_TM_ATTR_MAX = __AR6K_TM_ATTR_AFTER_LAST - 1 +}; + +enum ar6k_testmode_cmd { + AR6K_TM_CMD_TCMD = 0, + AR6K_TM_CMD_RX_REPORT = 1, +}; + +#define AR6K_TM_DATA_MAX_LEN 5000 + +static const struct nla_policy ar6k_testmode_policy[AR6K_TM_ATTR_MAX + 1] = { + [AR6K_TM_ATTR_CMD] = { .type = NLA_U32 }, + [AR6K_TM_ATTR_DATA] = { .type = NLA_BINARY, + .len = AR6K_TM_DATA_MAX_LEN }, +}; + +void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf, + int buf_len) +{ + if (down_interruptible(&ar->arSem)) + return; + + kfree(ar->tcmd_rx_report); + + ar->tcmd_rx_report = kmemdup(buf, buf_len, GFP_KERNEL); + ar->tcmd_rx_report_len = buf_len; + + up(&ar->arSem); + + wake_up(&arEvent); +} + +static int ar6000_testmode_rx_report(struct ar6_softc *ar, void *buf, + int buf_len, struct sk_buff *skb) +{ + int ret = 0; + long left; + + if (down_interruptible(&ar->arSem)) + return -ERESTARTSYS; + + if (ar->arWmiReady == false) { + ret = -EIO; + goto out; + } + + if (ar->bIsDestroyProgress) { + ret = -EBUSY; + goto out; + } + + WARN_ON(ar->tcmd_rx_report != NULL); + WARN_ON(ar->tcmd_rx_report_len > 0); + + if (wmi_test_cmd(ar->arWmi, buf, buf_len) < 0) { + up(&ar->arSem); + return -EIO; + } + + left = wait_event_interruptible_timeout(arEvent, + ar->tcmd_rx_report != NULL, + wmitimeout * HZ); + + if (left == 0) { + ret = -ETIMEDOUT; + goto out; + } else if (left < 0) { + ret = left; + goto out; + } + + if (ar->tcmd_rx_report == NULL || ar->tcmd_rx_report_len == 0) { + ret = -EINVAL; + goto out; + } + + NLA_PUT(skb, AR6K_TM_ATTR_DATA, ar->tcmd_rx_report_len, + ar->tcmd_rx_report); + + kfree(ar->tcmd_rx_report); + ar->tcmd_rx_report = NULL; + +out: + up(&ar->arSem); + + return ret; + +nla_put_failure: + ret = -ENOBUFS; + goto out; +} + +static int ar6k_testmode_cmd(struct wiphy *wiphy, void *data, int len) +{ + struct ar6_softc *ar = wiphy_priv(wiphy); + struct nlattr *tb[AR6K_TM_ATTR_MAX + 1]; + int err, buf_len, reply_len; + struct sk_buff *skb; + void *buf; + + err = nla_parse(tb, AR6K_TM_ATTR_MAX, data, len, + ar6k_testmode_policy); + if (err) + return err; + + if (!tb[AR6K_TM_ATTR_CMD]) + return -EINVAL; + + switch (nla_get_u32(tb[AR6K_TM_ATTR_CMD])) { + case AR6K_TM_CMD_TCMD: + if (!tb[AR6K_TM_ATTR_DATA]) + return -EINVAL; + + buf = nla_data(tb[AR6K_TM_ATTR_DATA]); + buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]); + + wmi_test_cmd(ar->arWmi, buf, buf_len); + + return 0; + + break; + case AR6K_TM_CMD_RX_REPORT: + if (!tb[AR6K_TM_ATTR_DATA]) + return -EINVAL; + + buf = nla_data(tb[AR6K_TM_ATTR_DATA]); + buf_len = nla_len(tb[AR6K_TM_ATTR_DATA]); + + reply_len = nla_total_size(AR6K_TM_DATA_MAX_LEN); + skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len); + if (!skb) + return -ENOMEM; + + err = ar6000_testmode_rx_report(ar, buf, buf_len, skb); + if (err < 0) { + kfree_skb(skb); + return err; + } + + return cfg80211_testmode_reply(skb); + default: + return -EOPNOTSUPP; + } +} +#endif static const u32 cipher_suites[] = { @@ -1607,6 +1766,28 @@ static int ar6k_get_station(struct wiphy *wiphy, struct net_device *dev, return 0; } +static int ar6k_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, + struct cfg80211_pmksa *pmksa) +{ + struct ar6_softc *ar = ar6k_priv(netdev); + return wmi_setPmkid_cmd(ar->arWmi, pmksa->bssid, pmksa->pmkid, true); +} + +static int ar6k_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, + struct cfg80211_pmksa *pmksa) +{ + struct ar6_softc *ar = ar6k_priv(netdev); + return wmi_setPmkid_cmd(ar->arWmi, pmksa->bssid, pmksa->pmkid, false); +} + +static int ar6k_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) +{ + struct ar6_softc *ar = ar6k_priv(netdev); + if (ar->arConnected) + return wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, false); + return 0; +} + static struct cfg80211_ops ar6k_cfg80211_ops = { .change_virtual_intf = ar6k_cfg80211_change_iface, @@ -1628,6 +1809,10 @@ cfg80211_ops ar6k_cfg80211_ops = { .join_ibss = ar6k_cfg80211_join_ibss, .leave_ibss = ar6k_cfg80211_leave_ibss, .get_station = ar6k_get_station, + .set_pmksa = ar6k_set_pmksa, + .del_pmksa = ar6k_del_pmksa, + .flush_pmksa = ar6k_flush_pmksa, + CFG80211_TESTMODE_CMD(ar6k_testmode_cmd) }; struct wireless_dev * diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h index 11dc39c6987a..80cef77738fb 100644 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h @@ -545,15 +545,9 @@ struct ar6_softc { s8 arMaxRetries; u8 arPhyCapability; #ifdef CONFIG_HOST_TCMD_SUPPORT - u8 tcmdRxReport; - u32 tcmdRxTotalPkt; - s32 tcmdRxRssi; - u32 tcmdPm; u32 arTargetMode; - u32 tcmdRxcrcErrPkt; - u32 tcmdRxsecErrPkt; - u16 tcmdRateCnt[TCMD_MAX_RATES]; - u16 tcmdRateCntShortGuard[TCMD_MAX_RATES]; + void *tcmd_rx_report; + int tcmd_rx_report_len; #endif AR6000_WLAN_STATE arWlanState; struct ar_node_mapping arNodeMap[MAX_NODE_NUM]; @@ -650,6 +644,15 @@ struct ar6_softc { void *arApDev; #endif u8 arAutoAuthStage; + + u8 *fw_otp; + size_t fw_otp_len; + u8 *fw; + size_t fw_len; + u8 *fw_patch; + size_t fw_patch_len; + u8 *fw_data; + size_t fw_data_len; }; #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h index 1a6ae97c6b08..d5253207b198 100644 --- a/drivers/staging/ath6kl/os/linux/include/cfg80211.h +++ b/drivers/staging/ath6kl/os/linux/include/cfg80211.h @@ -41,6 +41,17 @@ void ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason, void ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast); +#ifdef CONFIG_NL80211_TESTMODE +void ar6000_testmode_rx_report_event(struct ar6_softc *ar, void *buf, + int buf_len); +#else +static inline void ar6000_testmode_rx_report_event(struct ar6_softc *ar, + void *buf, int buf_len) +{ +} +#endif + + #endif /* _AR6K_CFG80211_H_ */ diff --git a/drivers/staging/ath6kl/os/linux/include/config_linux.h b/drivers/staging/ath6kl/os/linux/include/config_linux.h index d4030e26b20c..dbbe1a00b92c 100644 --- a/drivers/staging/ath6kl/os/linux/include/config_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/config_linux.h @@ -28,8 +28,6 @@ extern "C" { #endif -#include - /* * Host side Test Command support */ diff --git a/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h b/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h index 769a48014313..e6e96de3fc6b 100644 --- a/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h +++ b/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h @@ -24,8 +24,6 @@ #ifndef _IEEE80211_IOCTL_H_ #define _IEEE80211_IOCTL_H_ -#include - #ifdef __cplusplus extern "C" { #endif diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h index 07078b49583f..41f437307727 100644 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h @@ -29,7 +29,6 @@ #ifdef __KERNEL__ -#include #include #include #include diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c index 4a17f99ea143..c7b5e5cf9df7 100644 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ b/drivers/staging/ath6kl/wmi/wmi.c @@ -41,6 +41,7 @@ #include "a_debug.h" #include "dbglog_api.h" #include "roaming.h" +#include "cfg80211.h" #define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0) @@ -4465,10 +4466,9 @@ wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance) static int wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len) { + ar6000_testmode_rx_report_event(wmip->wmi_devt, datap, len); - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - return 0; + return 0; } #endif /* CONFIG_HOST_TCMD_SUPPORT*/ diff --git a/drivers/staging/bcm/Debug.h b/drivers/staging/bcm/Debug.h index 3138729cf34f..420382d1cacf 100644 --- a/drivers/staging/bcm/Debug.h +++ b/drivers/staging/bcm/Debug.h @@ -131,7 +131,7 @@ DriverEntry.c, bcmfwup.c, ChipDetectTask.c, HaltnReset.c, InterfaceDDR.c */ // TODO - put PHS_SEND in Tx PHS_RECEIVE in Rx path ? #define PHS_SEND (OTHERS<<16) -#define PHS_RECIEVE (OTHERS<<17) +#define PHS_RECEIVE (OTHERS<<17) #define PHS_MODULE (OTHERS<<18) #define INTF_INIT (OTHERS<<19) diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c index 806ef5d18522..d495828a731f 100644 --- a/drivers/staging/bcm/InterfaceRx.c +++ b/drivers/staging/bcm/InterfaceRx.c @@ -157,7 +157,7 @@ static void read_bulk_callback(struct urb *urb) { /* Moving ahead by ETH_HLEN to the data ptr as received from FW */ skb_pull(skb, ETH_HLEN); - PHSRecieve(Adapter, pLeader->Vcid, skb, &skb->len, + PHSReceive(Adapter, pLeader->Vcid, skb, &skb->len, NULL,bHeaderSupressionEnabled); if(!Adapter->PackInfo[QueueIndex].bEthCSSupport) @@ -229,7 +229,7 @@ static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_RCB pRcb) /* Function: InterfaceRx -Description: This is the hardware specific Function for Recieveing +Description: This is the hardware specific Function for Receiving data packet/control packets from the device. Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h index feb351578c8b..916bebb7ed50 100644 --- a/drivers/staging/bcm/Macros.h +++ b/drivers/staging/bcm/Macros.h @@ -176,8 +176,8 @@ enum enLinkStatus { PHY_SYNC_ACHIVED = 2, LINKUP_IN_PROGRESS = 3, LINKUP_DONE = 4, - DREG_RECIEVED = 5, - LINK_STATUS_RESET_RECIEVED = 6, + DREG_RECEIVED = 5, + LINK_STATUS_RESET_RECEIVED = 6, PERIODIC_WAKE_UP_NOTIFICATION_FRM_FW = 7, LINK_SHUTDOWN_REQ_FROM_FIRMWARE = 8, COMPLETE_WAKE_UP_NOTIFICATION_FRM_FW =9 diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index c5003b62234c..c5b3a3666bc7 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -1447,16 +1447,10 @@ static void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount) int rdm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) { - INT uiRetVal =0; - - uiRetVal = Adapter->interface_rdm(Adapter->pvInterfaceAdapter, + return Adapter->interface_rdm(Adapter->pvInterfaceAdapter, uiAddress, pucBuff, sSize); - - if(uiRetVal < 0) - return uiRetVal; - - return uiRetVal; } + int wrm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) { int iRetVal; diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index d1ca1912a74b..4aa2b71a40eb 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -209,7 +209,7 @@ int PHSTransmit(PMINI_ADAPTER Adapter, return STATUS_SUCCESS; } -int PHSRecieve(PMINI_ADAPTER Adapter, +int PHSReceive(PMINI_ADAPTER Adapter, USHORT usVcid, struct sk_buff *packet, UINT *punPacketLen, @@ -223,7 +223,7 @@ int PHSRecieve(PMINI_ADAPTER Adapter, UINT TotalBytesAdded = 0; if(!bHeaderSuppressionEnabled) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nPhs Disabled for incoming packet"); return ulPhsStatus; } @@ -238,7 +238,7 @@ int PHSRecieve(PMINI_ADAPTER Adapter, &nTotalsupressedPktHdrBytes, &nStandardPktHdrLen); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nSupressed PktHdrLen : 0x%x Restored PktHdrLen : 0x%x", nTotalsupressedPktHdrBytes,nStandardPktHdrLen); if(ulPhsStatus != STATUS_PHS_COMPRESSED) @@ -786,14 +786,14 @@ ULONG PhsDeCompress(IN void* pvContext, if(pDeviceExtension == NULL) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Invalid Device Extension\n"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"Invalid Device Extension\n"); return ERR_PHS_INVALID_DEVICE_EXETENSION; } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"Restoring header \n"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"Restoring header\n"); phsi = *((unsigned char *)(pvInputBuffer)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x \n",phsi); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"PHSI To Be Used For restore : %x\n",phsi); if(phsi == UNCOMPRESSED_PACKET ) { return STATUS_PHS_NOCOMPRESSION; @@ -804,7 +804,7 @@ ULONG PhsDeCompress(IN void* pvContext, uiVcid,&pstServiceFlowEntry); if(nSFIndex == PHS_INVALID_TABLE_INDEX) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"SFID Match Failed During Lookup\n"); return ERR_SF_MATCH_FAIL; } @@ -1417,7 +1417,7 @@ int phs_decompress(unsigned char *in_buf,unsigned char *out_buf, int in_buf_len = *header_size-1; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); in_buf++; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"====>\n"); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"====>\n"); *header_size = 0; if((decomp_phs_rules == NULL )) @@ -1425,7 +1425,7 @@ int phs_decompress(unsigned char *in_buf,unsigned char *out_buf, tmp_memb = decomp_phs_rules; - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi)); + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI 1 %d",phsi)); //*header_size = tmp_memb->u8PHSFLength; phss = tmp_memb->u8PHSS; phsf = tmp_memb->u8PHSF; @@ -1433,7 +1433,7 @@ int phs_decompress(unsigned char *in_buf,unsigned char *out_buf, if(phss > MAX_PHS_LENGTHS) phss = MAX_PHS_LENGTHS; - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI %d phss %d index %d",phsi,phss,index)); + //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phs_decompress PHSI %d phss %d index %d",phsi,phss,index)); while((phss > 0) && (size < in_buf_len)) { bit = ((*phsm << i)& SUPPRESS); @@ -1441,13 +1441,13 @@ int phs_decompress(unsigned char *in_buf,unsigned char *out_buf, if(bit == SUPPRESS) { *out_buf = *phsf; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d", + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d phsf %d ouput %d", phss,*phsf,*out_buf); } else { *out_buf = *in_buf; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECIEVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d", + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_RECEIVE,DBG_LVL_ALL,"\nDECOMP:In phss %d input %d ouput %d", phss,*in_buf,*out_buf); in_buf++; size++; diff --git a/drivers/staging/bcm/PHSModule.h b/drivers/staging/bcm/PHSModule.h index 0dd05a7c55d9..c629585d0a8c 100644 --- a/drivers/staging/bcm/PHSModule.h +++ b/drivers/staging/bcm/PHSModule.h @@ -9,7 +9,7 @@ int PHSTransmit(PMINI_ADAPTER Adapter, PUINT PacketLen, UCHAR bEthCSSupport); -int PHSRecieve(PMINI_ADAPTER Adapter, +int PHSReceive(PMINI_ADAPTER Adapter, USHORT usVcid, struct sk_buff *packet, UINT *punPacketLen, diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h index 8fe8d2b1f627..947d06325681 100644 --- a/drivers/staging/bcm/headers.h +++ b/drivers/staging/bcm/headers.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/bcm/sort.c b/drivers/staging/bcm/sort.c index fc5d07aec3d2..63c966a02546 100644 --- a/drivers/staging/bcm/sort.c +++ b/drivers/staging/bcm/sort.c @@ -1,4 +1,5 @@ #include "headers.h" +#include /* * File Name: sort.c @@ -10,54 +11,42 @@ * Copyright (c) 2007 Beceem Communications Pvt. Ltd */ +static int compare_packet_info(void const *a, void const *b) +{ + PacketInfo const *pa = a; + PacketInfo const *pb = b; + + if (!pa->bValid || !pb->bValid) + return 0; + + return pa->u8TrafficPriority - pb->u8TrafficPriority; +} + VOID SortPackInfo(PMINI_ADAPTER Adapter) { - UINT nIndex1; - UINT nIndex2; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, + DBG_LVL_ALL, "<======="); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<======="); + sort(Adapter->PackInfo, NO_OF_QUEUES, sizeof(PacketInfo), + compare_packet_info, NULL); +} - for(nIndex1 = 0; nIndex1 < NO_OF_QUEUES -2 ; nIndex1++) - { - for(nIndex2 = nIndex1 + 1 ; nIndex2 < NO_OF_QUEUES -1 ; nIndex2++) - { - if(Adapter->PackInfo[nIndex1].bValid && Adapter->PackInfo[nIndex2].bValid) - { - if(Adapter->PackInfo[nIndex2].u8TrafficPriority < - Adapter->PackInfo[nIndex1].u8TrafficPriority) - { - PacketInfo stTemppackInfo = Adapter->PackInfo[nIndex2]; - Adapter->PackInfo[nIndex2] = Adapter->PackInfo[nIndex1]; - Adapter->PackInfo[nIndex1] = stTemppackInfo; +static int compare_classifiers(void const *a, void const *b) +{ + S_CLASSIFIER_RULE const *pa = a; + S_CLASSIFIER_RULE const *pb = b; - } - } - } - } + if (!pa->bUsed || !pb->bUsed) + return 0; + + return pa->u8ClassifierRulePriority - pb->u8ClassifierRulePriority; } VOID SortClassifiers(PMINI_ADAPTER Adapter) { - UINT nIndex1; - UINT nIndex2; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, + DBG_LVL_ALL, "<======="); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<======="); - - for(nIndex1 = 0; nIndex1 < MAX_CLASSIFIERS -1 ; nIndex1++) - { - for(nIndex2 = nIndex1 + 1 ; nIndex2 < MAX_CLASSIFIERS ; nIndex2++) - { - if(Adapter->astClassifierTable[nIndex1].bUsed && Adapter->astClassifierTable[nIndex2].bUsed) - { - if(Adapter->astClassifierTable[nIndex2].u8ClassifierRulePriority < - Adapter->astClassifierTable[nIndex1].u8ClassifierRulePriority) - { - S_CLASSIFIER_RULE stTempClassifierRule = Adapter->astClassifierTable[nIndex2]; - Adapter->astClassifierTable[nIndex2] = Adapter->astClassifierTable[nIndex1]; - Adapter->astClassifierTable[nIndex1] = stTempClassifierRule; - - } - } - } - } + sort(Adapter->astClassifierTable, MAX_CLASSIFIERS, + sizeof(S_CLASSIFIER_RULE), compare_classifiers, NULL); } diff --git a/drivers/staging/brcm80211/Makefile b/drivers/staging/brcm80211/Makefile index e7b3f27847cf..8b01f5e7ba25 100644 --- a/drivers/staging/brcm80211/Makefile +++ b/drivers/staging/brcm80211/Makefile @@ -17,8 +17,8 @@ # common flags subdir-ccflags-y := -DBCMDMA32 -subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG -DBCMDBG_ASSERT +subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG -obj-$(CONFIG_BRCMUTIL) += util/ +obj-$(CONFIG_BRCMUTIL) += brcmutil/ obj-$(CONFIG_BRCMFMAC) += brcmfmac/ obj-$(CONFIG_BRCMSMAC) += brcmsmac/ diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README index 8ad558675bd3..bb86b1b3e58e 100644 --- a/drivers/staging/brcm80211/README +++ b/drivers/staging/brcm80211/README @@ -1,64 +1 @@ -Broadcom brcmsmac (mac80211-based softmac PCIe) and brcmfmac (SDIO) drivers. - -Completely open source host drivers, no binary object files. - -Support for the following chips: -=============================== - - brcmsmac (PCIe) - Name Device ID - BCM4313 0x4727 - BCM43224 0x4353 - BCM43225 0x4357 - - brcmfmac (SDIO) - Name - BCM4329 - -Both brcmsmac and brcmfmac drivers require firmware files that need to be -separately downloaded. - -Firmware -====================== -Firmware is available from the Linux firmware repository at: - - git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2/linux-firmware.git - http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git - https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git - - -=============================================================== -Broadcom brcmsmac driver -=============================================================== -- Support for both 32 and 64 bit Linux kernels - - -Firmware installation -====================== -Copy brcm/bcm43xx-0.fw and brcm/bcm43xx_hdr-0.fw to -/lib/firmware/brcm (or wherever firmware is normally installed -on your system). - - -=============================================================== -Broadcom brcmfmac driver -=============================================================== -- Support for 32 bit Linux kernel, 64 bit untested - - -Firmware installation -====================== -Copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt -to /lib/firmware/brcm (or wherever firmware is normally installed on your -system). - - -Contact Info: -============= -Brett Rudley brudley@broadcom.com -Henry Ptasinski henryp@broadcom.com -Dowan Kim dowan@broadcom.com -Roland Vossen rvossen@broadcom.com -Arend van Spriel arend@broadcom.com - -For more info, refer to: http://linuxwireless.org/en/users/Drivers/brcm80211 +refer to: http://linuxwireless.org/en/users/Drivers/brcm80211 diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO index e9c1393a2b92..e2e2ef9bd7ac 100644 --- a/drivers/staging/brcm80211/TODO +++ b/drivers/staging/brcm80211/TODO @@ -2,14 +2,12 @@ To Do List for Broadcom Mac80211 driver before getting in mainline Bugs ==== -- Oops on AMPDU traffic, to be solved by new ucode (currently under test) - -brcmfmac and brcmsmac -===================== -- ASSERTS not allowed in mainline, replace by warning + error handling -- Replace printk and WL_ERROR() with proper routines +- none known at this moment brcmfmac ===================== -- Replace driver's proprietary ssb interface with generic kernel ssb module -- Build and test on 64 bit linux kernel +- ASSERTS deprecated in mainline, replace by warning + error handling + +brcm80211 info page +===================== +http://linuxwireless.org/en/users/Drivers/brcm80211 diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile index c5ec562c3645..da3c80575907 100644 --- a/drivers/staging/brcm80211/brcmfmac/Makefile +++ b/drivers/staging/brcm80211/brcmfmac/Makefile @@ -16,23 +16,11 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ccflags-y := \ - -DARP_OFFLOAD_SUPPORT \ - -DBCMLXSDMMC \ - -DBCMPLATFORM_BUS \ - -DBCMSDIO \ - -DBDC \ - -DBRCM_FULLMAC \ - -DDHD_FIRSTREAD=64 \ - -DDHD_SCHED \ - -DDHD_SDALIGN=64 \ - -DEMBEDDED_PLATFORM \ - -DMAX_HDR_READ=64 \ - -DMMC_SDIO_ABORT \ - -DPKT_FILTER_SUPPORT \ - -DSHOW_EVENTS \ - -DTOE + -DBRCMF_FIRSTREAD=64 \ + -DBRCMF_SDALIGN=64 \ + -DMAX_HDR_READ=64 -ccflags-$(CONFIG_BRCMDBG) += -DDHD_DEBUG +ccflags-$(CONFIG_BRCMDBG) += -DSHOW_EVENTS ccflags-y += \ -Idrivers/staging/brcm80211/brcmfmac \ @@ -40,17 +28,12 @@ ccflags-y += \ DHDOFILES = \ wl_cfg80211.o \ - wl_iw.o \ dhd_cdc.o \ dhd_common.o \ - dhd_custom_gpio.o \ dhd_sdio.o \ dhd_linux.o \ - dhd_linux_sched.o \ bcmsdh.o \ - bcmsdh_linux.o \ - bcmsdh_sdmmc.o \ - bcmsdh_sdmmc_linux.o + bcmsdh_sdmmc.o obj-$(CONFIG_BRCMFMAC) += brcmfmac.o brcmfmac-objs += $(DHDOFILES) diff --git a/drivers/staging/brcm80211/brcmfmac/README b/drivers/staging/brcm80211/brcmfmac/README deleted file mode 100644 index 139597f9cb07..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/README +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/drivers/staging/brcm80211/brcmfmac/aiutils.c b/drivers/staging/brcm80211/brcmfmac/aiutils.c deleted file mode 100644 index e64808648ce3..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/aiutils.c +++ /dev/null @@ -1 +0,0 @@ -#include "../util/aiutils.c" diff --git a/drivers/staging/brcm80211/brcmfmac/bcmcdc.h b/drivers/staging/brcm80211/brcmfmac/bcmcdc.h deleted file mode 100644 index ed4c4a517eca..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/bcmcdc.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include - -typedef struct cdc_ioctl { - u32 cmd; /* ioctl command value */ - u32 len; /* lower 16: output buflen; upper 16: - input buflen (excludes header) */ - u32 flags; /* flag defns given below */ - u32 status; /* status code returned from the device */ -} cdc_ioctl_t; - -/* Max valid buffer size that can be sent to the dongle */ -#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) - -/* len field is divided into input and output buffer lengths */ -#define CDCL_IOC_OUTLEN_MASK 0x0000FFFF /* maximum or expected - response length, */ - /* excluding IOCTL header */ -#define CDCL_IOC_OUTLEN_SHIFT 0 -#define CDCL_IOC_INLEN_MASK 0xFFFF0000 /* input buffer length, - excluding IOCTL header */ -#define CDCL_IOC_INLEN_SHIFT 16 - -/* CDC flag definitions */ -#define CDCF_IOC_ERROR 0x01 /* 0=success, 1=ioctl cmd failed */ -#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */ -#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */ -#define CDCF_IOC_IF_SHIFT 12 -#define CDCF_IOC_ID_MASK 0xFFFF0000 /* used to uniquely id an ioctl - req/resp pairing */ -#define CDCF_IOC_ID_SHIFT 16 /* # of bits of shift for ID Mask */ - -#define CDC_IOC_IF_IDX(flags) \ - (((flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT) -#define CDC_IOC_ID(flags) \ - (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT) - -#define CDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags) & CDCF_IOC_IF_MASK) >> CDCF_IOC_IF_SHIFT)) -#define CDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | \ - ((idx) << CDCF_IOC_IF_SHIFT))) - -/* - * BDC header - * - * The BDC header is used on data packets to convey priority across USB. - */ - -#define BDC_HEADER_LEN 4 - -#define BDC_PROTO_VER 1 /* Protocol version */ - -#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ -#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ - -#define BDC_FLAG__UNUSED 0x03 /* Unassigned */ -#define BDC_FLAG_SUM_GOOD 0x04 /* Dongle has verified good - RX checksums */ -#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ - -#define BDC_PRIORITY_MASK 0x7 - -#define BDC_FLAG2_FC_FLAG 0x10 /* flag to indicate if pkt contains */ - /* FLOW CONTROL info only */ -#define BDC_PRIORITY_FC_SHIFT 4 /* flow control info shift */ - -#define BDC_FLAG2_IF_MASK 0x0f /* APSTA: interface on which the - packet was received */ -#define BDC_FLAG2_IF_SHIFT 0 - -#define BDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) -#define BDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \ - ((idx) << BDC_FLAG2_IF_SHIFT))) - -struct bdc_header { - u8 flags; /* Flags */ - u8 priority; /* 802.1d Priority 0:2 bits, 4:7 flow - control info for usb */ - u8 flags2; - u8 rssi; -}; diff --git a/drivers/staging/brcm80211/brcmfmac/bcmchip.h b/drivers/staging/brcm80211/brcmfmac/bcmchip.h index c0d4c3bf6d42..d7d3afd5a10f 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmchip.h +++ b/drivers/staging/brcm80211/brcmfmac/bcmchip.h @@ -17,12 +17,6 @@ #ifndef _bcmchip_h_ #define _bcmchip_h_ -/* Core reg address translation */ -#define CORE_CC_REG(base, field) (base + offsetof(chipcregs_t, field)) -#define CORE_BUS_REG(base, field) (base + offsetof(sdpcmd_regs_t, field)) -#define CORE_SB(base, field) \ - (base + SBCONFIGOFF + offsetof(sbconfig_t, field)) - /* bcm4329 */ /* SDIO device core, ID 0x829 */ #define BCM4329_CORE_BUS_BASE 0x18011000 @@ -31,5 +25,8 @@ /* ARM Cortex M3 core, ID 0x82a */ #define BCM4329_CORE_ARM_BASE 0x18002000 #define BCM4329_RAMSIZE 0x48000 +/* firmware name */ +#define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin" +#define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt" #endif /* _bcmchip_h_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h b/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h deleted file mode 100644 index 53c32915acc9..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdbus.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _sdio_api_h_ -#define _sdio_api_h_ - -#define SDIOH_API_RC_SUCCESS (0x00) -#define SDIOH_API_RC_FAIL (0x01) -#define SDIOH_API_SUCCESS(status) (status == 0) - -#define SDIOH_READ 0 /* Read request */ -#define SDIOH_WRITE 1 /* Write request */ - -#define SDIOH_DATA_FIX 0 /* Fixed addressing */ -#define SDIOH_DATA_INC 1 /* Incremental addressing */ - -#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */ -#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */ -#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */ - -#define SDIOH_DATA_PIO 0 /* PIO mode */ -#define SDIOH_DATA_DMA 1 /* DMA mode */ - -typedef int SDIOH_API_RC; - -/* SDio Host structure */ -typedef struct sdioh_info sdioh_info_t; - -/* callback function, taking one arg */ -typedef void (*sdioh_cb_fn_t) (void *); - -/* attach, return handler on success, NULL if failed. - * The handler shall be provided by all subsequent calls. No local cache - * cfghdl points to the starting address of pci device mapped memory - */ -extern sdioh_info_t *sdioh_attach(void *cfghdl, uint irq); -extern SDIOH_API_RC sdioh_detach(sdioh_info_t *si); -extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si, - sdioh_cb_fn_t fn, void *argh); -extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si); - -/* query whether SD interrupt is enabled or not */ -extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *si, bool *onoff); - -/* enable or disable SD interrupt */ -extern SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *si, bool enable_disable); - -#if defined(DHD_DEBUG) -extern bool sdioh_interrupt_pending(sdioh_info_t *si); -#endif - -extern int sdioh_claim_host_and_lock(sdioh_info_t *si); -extern int sdioh_release_host_and_unlock(sdioh_info_t *si); - -/* read or write one byte using cmd52 */ -extern SDIOH_API_RC sdioh_request_byte(sdioh_info_t *si, uint rw, uint fnc, - uint addr, u8 *byte); - -/* read or write 2/4 bytes using cmd53 */ -extern SDIOH_API_RC sdioh_request_word(sdioh_info_t *si, uint cmd_type, - uint rw, uint fnc, uint addr, - u32 *word, uint nbyte); - -/* read or write any buffer using cmd53 */ -extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma, - uint fix_inc, uint rw, uint fnc_num, - u32 addr, uint regwidth, - u32 buflen, u8 *buffer, - struct sk_buff *pkt); - -/* get cis data */ -extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, u8 *cis, - u32 length); - -extern SDIOH_API_RC sdioh_cfg_read(sdioh_info_t *si, uint fuc, u32 addr, - u8 *data); -extern SDIOH_API_RC sdioh_cfg_write(sdioh_info_t *si, uint fuc, u32 addr, - u8 *data); - -/* query number of io functions */ -extern uint sdioh_query_iofnum(sdioh_info_t *si); - -/* handle iovars */ -extern int sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set); - -/* Issue abort to the specified function and clear controller as needed */ -extern int sdioh_abort(sdioh_info_t *si, uint fnc); - -/* Start and Stop SDIO without re-enumerating the SD card. */ -extern int sdioh_start(sdioh_info_t *si, int stage); -extern int sdioh_stop(sdioh_info_t *si); - -/* Reset and re-initialize the device */ -extern int sdioh_sdio_reset(sdioh_info_t *si); - -/* Helper function */ -void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); - -#endif /* _sdio_api_h_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index 3750fcf5a871..f4e72ed126b0 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -13,29 +13,59 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* ****************** BCMSDH Interface Functions *************************** */ +/* ****************** SDIO CARD Interface Functions **************************/ #include #include +#include #include -#include -#include -#include -#include +#include +#include -#include /* BRCM API for SDIO - clients (such as wl, dhd) */ -#include /* common SDIO/controller interface */ -#include /* BRCM sdio device core */ - -#include /* sdio spec */ -#include "dngl_stats.h" +#include +#include +#include +#include +#include #include "dhd.h" +#include "dhd_bus.h" +#include "sdio_host.h" #define SDIOH_API_ACCESS_RETRY_LIMIT 2 -const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL; -struct bcmsdh_info { +#define BRCMF_SD_ERROR_VAL 0x0001 /* Error */ +#define BRCMF_SD_INFO_VAL 0x0002 /* Info */ + + +#ifdef BCMDBG +#define BRCMF_SD_ERROR(x) \ + do { \ + if ((brcmf_sdio_msglevel & BRCMF_SD_ERROR_VAL) && \ + net_ratelimit()) \ + printk x; \ + } while (0) +#define BRCMF_SD_INFO(x) \ + do { \ + if ((brcmf_sdio_msglevel & BRCMF_SD_INFO_VAL) && \ + net_ratelimit()) \ + printk x; \ + } while (0) +#else /* BCMDBG */ +#define BRCMF_SD_ERROR(x) +#define BRCMF_SD_INFO(x) +#endif /* BCMDBG */ + +/* debugging macros */ +#define SDLX_MSG(x) + +#define SDIOH_CMD_TYPE_NORMAL 0 /* Normal command */ +#define SDIOH_CMD_TYPE_APPEND 1 /* Append command */ +#define SDIOH_CMD_TYPE_CUTTHRU 2 /* Cut-through command */ + +#define SDIOH_DATA_PIO 0 /* PIO mode */ +#define SDIOH_DATA_DMA 1 /* DMA mode */ + +struct brcmf_sdio_card { bool init_success; /* underlying driver successfully attached */ void *sdioh; /* handler for sdioh */ u32 vendevid; /* Target Vendor and Device ID on SD bus */ @@ -43,282 +73,232 @@ struct bcmsdh_info { reg_read/reg_write call */ u32 sbwad; /* Save backplane window address */ }; + +/** + * SDIO Host Controller info + */ +struct sdio_hc { + struct sdio_hc *next; + struct device *dev; /* platform device handle */ + void *regs; /* SDIO Host Controller address */ + struct brcmf_sdio_card *card; + void *ch; + unsigned int oob_irq; + unsigned long oob_flags; /* OOB Host specifiction + as edge and etc */ + bool oob_irq_registered; +}; + /* local copy of bcm sd handler */ -bcmsdh_info_t *l_bcmsdh; +static struct brcmf_sdio_card *l_card; -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) -extern int sdioh_enable_hw_oob_intr(void *sdioh, bool enable); +const uint brcmf_sdio_msglevel = BRCMF_SD_ERROR_VAL; -void bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable) +static struct sdio_hc *sdhcinfo; + +/* driver info, initialized when brcmf_sdio_register is called */ +static struct brcmf_sdioh_driver drvinfo = { NULL, NULL }; + +/* Module parameters specific to each host-controller driver */ + +module_param(sd_msglevel, uint, 0); + +extern uint sd_f2_blocksize; +module_param(sd_f2_blocksize, int, 0); + +/* forward declarations */ +int brcmf_sdio_probe(struct device *dev); +EXPORT_SYMBOL(brcmf_sdio_probe); + +int brcmf_sdio_remove(struct device *dev); +EXPORT_SYMBOL(brcmf_sdio_remove); + +struct brcmf_sdio_card* +brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq) { - sdioh_enable_hw_oob_intr(sdh->sdioh, enable); -} -#endif + struct brcmf_sdio_card *card; -bcmsdh_info_t *bcmsdh_attach(void *cfghdl, void **regsva, uint irq) -{ - bcmsdh_info_t *bcmsdh; - - bcmsdh = kzalloc(sizeof(bcmsdh_info_t), GFP_ATOMIC); - if (bcmsdh == NULL) { - BCMSDH_ERROR(("bcmsdh_attach: out of memory")); + card = kzalloc(sizeof(struct brcmf_sdio_card), GFP_ATOMIC); + if (card == NULL) { + BRCMF_SD_ERROR(("sdcard_attach: out of memory")); return NULL; } /* save the handler locally */ - l_bcmsdh = bcmsdh; + l_card = card; - bcmsdh->sdioh = sdioh_attach(cfghdl, irq); - if (!bcmsdh->sdioh) { - bcmsdh_detach(bcmsdh); + card->sdioh = brcmf_sdioh_attach(cfghdl, irq); + if (!card->sdioh) { + brcmf_sdcard_detach(card); return NULL; } - bcmsdh->init_success = true; + card->init_success = true; - *regsva = (u32 *) SI_ENUM_BASE; + *regsva = SI_ENUM_BASE; /* Report the BAR, to fix if needed */ - bcmsdh->sbwad = SI_ENUM_BASE; - return bcmsdh; + card->sbwad = SI_ENUM_BASE; + return card; } -int bcmsdh_detach(void *sdh) +int brcmf_sdcard_detach(struct brcmf_sdio_card *card) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - - if (bcmsdh != NULL) { - if (bcmsdh->sdioh) { - sdioh_detach(bcmsdh->sdioh); - bcmsdh->sdioh = NULL; + if (card != NULL) { + if (card->sdioh) { + brcmf_sdioh_detach(card->sdioh); + card->sdioh = NULL; } - kfree(bcmsdh); + kfree(card); } - l_bcmsdh = NULL; + l_card = NULL; return 0; } int -bcmsdh_iovar_op(void *sdh, const char *name, +brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name, void *params, int plen, void *arg, int len, bool set) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set); + return brcmf_sdioh_iovar_op(card->sdioh, name, params, plen, arg, + len, set); } -bool bcmsdh_intr_query(void *sdh) +int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; - bool on; - - ASSERT(bcmsdh); - status = sdioh_interrupt_query(bcmsdh->sdioh, &on); - if (SDIOH_API_SUCCESS(status)) - return false; - else - return on; + return brcmf_sdioh_interrupt_set(card->sdioh, true); } -int bcmsdh_intr_enable(void *sdh) +int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_set(bcmsdh->sdioh, true); - return SDIOH_API_SUCCESS(status) ? 0 : -EIO; + return brcmf_sdioh_interrupt_set(card->sdioh, false); } -int bcmsdh_intr_disable(void *sdh) +int brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card, + void (*fn)(void *), void *argh) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_set(bcmsdh->sdioh, false); - return SDIOH_API_SUCCESS(status) ? 0 : -EIO; + return brcmf_sdioh_interrupt_register(card->sdioh, fn, argh); } -int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) +int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh); - return SDIOH_API_SUCCESS(status) ? 0 : -EIO; + return brcmf_sdioh_interrupt_deregister(card->sdioh); } -int bcmsdh_intr_dereg(void *sdh) +u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint fnc_num, u32 addr, + int *err) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; - ASSERT(bcmsdh); - - status = sdioh_interrupt_deregister(bcmsdh->sdioh); - return SDIOH_API_SUCCESS(status) ? 0 : -EIO; -} - -#if defined(DHD_DEBUG) -bool bcmsdh_intr_pending(void *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - - ASSERT(sdh); - return sdioh_interrupt_pending(bcmsdh->sdioh); -} -#endif - -int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh) -{ - ASSERT(sdh); - - /* don't support yet */ - return -ENOTSUPP; -} - -u8 bcmsdh_cfg_read(void *sdh, uint fnc_num, u32 addr, int *err) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT + int status; s32 retry = 0; -#endif u8 data = 0; - if (!bcmsdh) - bcmsdh = l_bcmsdh; + if (!card) + card = l_card; - ASSERT(bcmsdh->init_success); - -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT do { if (retry) /* wait for 1 ms till bus get settled down */ udelay(1000); -#endif status = - sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr, + brcmf_sdioh_cfg_read(card->sdioh, fnc_num, addr, (u8 *) &data); -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - } while (!SDIOH_API_SUCCESS(status) + } while (status != 0 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); -#endif if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO); + *err = status; - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n", + BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n", __func__, fnc_num, addr, data)); return data; } void -bcmsdh_cfg_write(void *sdh, uint fnc_num, u32 addr, u8 data, int *err) +brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint fnc_num, u32 addr, + u8 data, int *err) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT + int status; s32 retry = 0; -#endif - if (!bcmsdh) - bcmsdh = l_bcmsdh; + if (!card) + card = l_card; - ASSERT(bcmsdh->init_success); - -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT do { if (retry) /* wait for 1 ms till bus get settled down */ udelay(1000); -#endif status = - sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr, + brcmf_sdioh_cfg_write(card->sdioh, fnc_num, addr, (u8 *) &data); -#ifdef SDIOH_API_ACCESS_RETRY_LIMIT - } while (!SDIOH_API_SUCCESS(status) + } while (status != 0 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); -#endif if (err) - *err = SDIOH_API_SUCCESS(status) ? 0 : -EIO; + *err = status; - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n", + BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n", __func__, fnc_num, addr, data)); } -u32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, u32 addr, int *err) +u32 brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num, + u32 addr, int *err) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; + int status; u32 data = 0; - if (!bcmsdh) - bcmsdh = l_bcmsdh; + if (!card) + card = l_card; - ASSERT(bcmsdh->init_success); - - status = - sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ, - fnc_num, addr, &data, 4); + status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL, + SDIOH_READ, fnc_num, addr, &data, 4); if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO); + *err = status; - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n", + BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n", __func__, fnc_num, addr, data)); return data; } void -bcmsdh_cfg_write_word(void *sdh, uint fnc_num, u32 addr, u32 data, - int *err) +brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card, uint fnc_num, + u32 addr, u32 data, int *err) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; + int status; - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - ASSERT(bcmsdh->init_success); + if (!card) + card = l_card; status = - sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, + brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, fnc_num, addr, &data, 4); if (err) - *err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO); + *err = status; - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n", + BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n", __func__, fnc_num, addr, data)); } -int bcmsdh_cis_read(void *sdh, uint func, u8 * cis, uint length) +int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, u8 * cis, + uint length) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; + int status; u8 *tmp_buf, *tmp_ptr; u8 *ptr; bool ascii = func & ~0xf; func &= 0x7; - if (!bcmsdh) - bcmsdh = l_bcmsdh; + if (!card) + card = l_card; - ASSERT(bcmsdh->init_success); - ASSERT(cis); - ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT); - - status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length); + status = brcmf_sdioh_cis_read(card->sdioh, func, cis, length); if (ascii) { /* Move binary bits to tmp and format them into the provided buffer. */ tmp_buf = kmalloc(length, GFP_ATOMIC); if (tmp_buf == NULL) { - BCMSDH_ERROR(("%s: out of memory\n", __func__)); + BRCMF_SD_ERROR(("%s: out of memory\n", __func__)); return -ENOMEM; } memcpy(tmp_buf, cis, length); @@ -331,60 +311,60 @@ int bcmsdh_cis_read(void *sdh, uint func, u8 * cis, uint length) kfree(tmp_buf); } - return SDIOH_API_SUCCESS(status) ? 0 : -EIO; + return status; } -static int bcmsdhsdio_set_sbaddr_window(void *sdh, u32 address) +static int +brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_card *card, u32 address) { int err = 0; - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); if (!err) - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, - (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + SBSDIO_FUNC1_SBADDRMID, + (address >> 16) & SBSDIO_SBADDRMID_MASK, + &err); if (!err) - bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, - (address >> 24) & SBSDIO_SBADDRHIGH_MASK, - &err); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + SBSDIO_FUNC1_SBADDRHIGH, + (address >> 24) & SBSDIO_SBADDRHIGH_MASK, + &err); return err; } -u32 bcmsdh_reg_read(void *sdh, u32 addr, uint size) +u32 brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; + int status; u32 word = 0; uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; - BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr)); + BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr)); - if (!bcmsdh) - bcmsdh = l_bcmsdh; + if (!card) + card = l_card; - ASSERT(bcmsdh->init_success); - - if (bar0 != bcmsdh->sbwad) { - if (bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0)) + if (bar0 != card->sbwad) { + if (brcmf_sdcard_set_sbaddr_window(card, bar0)) return 0xFFFFFFFF; - bcmsdh->sbwad = bar0; + card->sbwad = bar0; } addr &= SBSDIO_SB_OFT_ADDR_MASK; if (size == 4) addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, + status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ, SDIO_FUNC_1, addr, &word, size); - bcmsdh->regfail = !(SDIOH_API_SUCCESS(status)); + card->regfail = (status != 0); - BCMSDH_INFO(("u32data = 0x%x\n", word)); + BRCMF_SD_INFO(("u32data = 0x%x\n", word)); /* if ok, return appropriately masked word */ - if (SDIOH_API_SUCCESS(status)) { + if (status == 0) { switch (size) { case sizeof(u8): return word & 0xff; @@ -393,90 +373,86 @@ u32 bcmsdh_reg_read(void *sdh, u32 addr, uint size) case sizeof(u32): return word; default: - bcmsdh->regfail = true; + card->regfail = true; } } /* otherwise, bad sdio access or invalid size */ - BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__, + BRCMF_SD_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__, addr, size)); return 0xFFFFFFFF; } -u32 bcmsdh_reg_write(void *sdh, u32 addr, uint size, u32 data) +u32 brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size, + u32 data) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; + int status; uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; int err = 0; - BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n", + BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n", __func__, addr, size * 8, data)); - if (!bcmsdh) - bcmsdh = l_bcmsdh; + if (!card) + card = l_card; - ASSERT(bcmsdh->init_success); - - if (bar0 != bcmsdh->sbwad) { - err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0); + if (bar0 != card->sbwad) { + err = brcmf_sdcard_set_sbaddr_window(card, bar0); if (err) return err; - bcmsdh->sbwad = bar0; + card->sbwad = bar0; } addr &= SBSDIO_SB_OFT_ADDR_MASK; if (size == 4) addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; status = - sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, + brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size); - bcmsdh->regfail = !(SDIOH_API_SUCCESS(status)); + card->regfail = (status != 0); - if (SDIOH_API_SUCCESS(status)) + if (status == 0) return 0; - BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n", + BRCMF_SD_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n", __func__, data, addr, size)); return 0xFFFFFFFF; } -bool bcmsdh_regfail(void *sdh) +bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card) { - return ((bcmsdh_info_t *) sdh)->regfail; + return card->regfail; } int -bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags, - u8 *buf, uint nbytes, struct sk_buff *pkt, - bcmsdh_cmplt_fn_t complete, void *handle) +brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn, + uint flags, + u8 *buf, uint nbytes, struct sk_buff *pkt, + void (*complete)(void *handle, int status, + bool sync_waiting), + void *handle) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; + int status; uint incr_fix; uint width; uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; int err = 0; - ASSERT(bcmsdh); - ASSERT(bcmsdh->init_success); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", + BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", __func__, fn, addr, nbytes)); /* Async not implemented yet */ - ASSERT(!(flags & SDIO_REQ_ASYNC)); if (flags & SDIO_REQ_ASYNC) return -ENOTSUPP; - if (bar0 != bcmsdh->sbwad) { - err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0); + if (bar0 != card->sbwad) { + err = brcmf_sdcard_set_sbaddr_window(card, bar0); if (err) return err; - bcmsdh->sbwad = bar0; + card->sbwad = bar0; } addr &= SBSDIO_SB_OFT_ADDR_MASK; @@ -486,42 +462,37 @@ bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags, if (width == 4) addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix, - SDIOH_READ, fn, addr, width, nbytes, buf, - pkt); + status = brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO, + incr_fix, SDIOH_READ, fn, addr, width, nbytes, buf, pkt); - return SDIOH_API_SUCCESS(status) ? 0 : -EIO; + return status; } int -bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags, - u8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle) +brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes, void *pkt, + void (*complete)(void *handle, int status, + bool sync_waiting), + void *handle) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; uint incr_fix; uint width; uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; int err = 0; - ASSERT(bcmsdh); - ASSERT(bcmsdh->init_success); - - BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", + BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", __func__, fn, addr, nbytes)); /* Async not implemented yet */ - ASSERT(!(flags & SDIO_REQ_ASYNC)); if (flags & SDIO_REQ_ASYNC) return -ENOTSUPP; - if (bar0 != bcmsdh->sbwad) { - err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0); + if (bar0 != card->sbwad) { + err = brcmf_sdcard_set_sbaddr_window(card, bar0); if (err) return err; - bcmsdh->sbwad = bar0; + card->sbwad = bar0; } addr &= SBSDIO_SB_OFT_ADDR_MASK; @@ -531,101 +502,141 @@ bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags, if (width == 4) addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix, - SDIOH_WRITE, fn, addr, width, nbytes, buf, - pkt); - - return SDIOH_API_SUCCESS(status) ? 0 : -EIO; + return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO, + incr_fix, SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt); } -int bcmsdh_rwdata(void *sdh, uint rw, u32 addr, u8 *buf, uint nbytes) +int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr, + u8 *buf, uint nbytes) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - SDIOH_API_RC status; - - ASSERT(bcmsdh); - ASSERT(bcmsdh->init_success); - ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0); - addr &= SBSDIO_SB_OFT_ADDR_MASK; addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - status = - sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC, - (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1, - addr, 4, nbytes, buf, NULL); - - return SDIOH_API_SUCCESS(status) ? 0 : -EIO; + return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO, + SDIOH_DATA_INC, (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1, + addr, 4, nbytes, buf, NULL); } -int bcmsdh_abort(void *sdh, uint fn) +int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - - return sdioh_abort(bcmsdh->sdioh, fn); + return brcmf_sdioh_abort(card->sdioh, fn); } -int bcmsdh_start(void *sdh, int stage) +int brcmf_sdcard_query_device(struct brcmf_sdio_card *card) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - - return sdioh_start(bcmsdh->sdioh, stage); + card->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0; + return card->vendevid; } -int bcmsdh_stop(void *sdh) +u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; + if (!card) + card = l_card; - return sdioh_stop(bcmsdh->sdioh); + return card->sbwad; } -int bcmsdh_query_device(void *sdh) +int brcmf_sdio_probe(struct device *dev) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - bcmsdh->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0; - return bcmsdh->vendevid; + struct sdio_hc *sdhc = NULL; + u32 regs = 0; + struct brcmf_sdio_card *card = NULL; + int irq = 0; + u32 vendevid; + unsigned long irq_flags = 0; + + /* allocate SDIO Host Controller state info */ + sdhc = kzalloc(sizeof(struct sdio_hc), GFP_ATOMIC); + if (!sdhc) { + SDLX_MSG(("%s: out of memory\n", __func__)); + goto err; + } + sdhc->dev = (void *)dev; + + card = brcmf_sdcard_attach((void *)0, ®s, irq); + if (!card) { + SDLX_MSG(("%s: attach failed\n", __func__)); + goto err; + } + + sdhc->card = card; + sdhc->oob_irq = irq; + sdhc->oob_flags = irq_flags; + sdhc->oob_irq_registered = false; /* to make sure.. */ + + /* chain SDIO Host Controller info together */ + sdhc->next = sdhcinfo; + sdhcinfo = sdhc; + /* Read the vendor/device ID from the CIS */ + vendevid = brcmf_sdcard_query_device(card); + + /* try to attach to the target device */ + sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF), + 0, 0, 0, 0, regs, card); + if (!sdhc->ch) { + SDLX_MSG(("%s: device attach failed\n", __func__)); + goto err; + } + + return 0; + + /* error handling */ +err: + if (sdhc) { + if (sdhc->card) + brcmf_sdcard_detach(sdhc->card); + kfree(sdhc); + } + + return -ENODEV; } -uint bcmsdh_query_iofnum(void *sdh) +int brcmf_sdio_remove(struct device *dev) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; + struct sdio_hc *sdhc, *prev; - if (!bcmsdh) - bcmsdh = l_bcmsdh; + sdhc = sdhcinfo; + drvinfo.detach(sdhc->ch); + brcmf_sdcard_detach(sdhc->card); + /* find the SDIO Host Controller state for this pdev + and take it out from the list */ + for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { + if (sdhc->dev == (void *)dev) { + if (prev) + prev->next = sdhc->next; + else + sdhcinfo = NULL; + break; + } + prev = sdhc; + } + if (!sdhc) { + SDLX_MSG(("%s: failed\n", __func__)); + return 0; + } - return sdioh_query_iofnum(bcmsdh->sdioh); -} - -int bcmsdh_reset(bcmsdh_info_t *sdh) -{ - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; - - return sdioh_sdio_reset(bcmsdh->sdioh); -} - -void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh) -{ - ASSERT(sdh); - return sdh->sdioh; -} - -/* Function to pass device-status bits to DHD. */ -u32 bcmsdh_get_dstatus(void *sdh) -{ + /* release SDIO Host Controller info */ + kfree(sdhc); return 0; } -u32 bcmsdh_cur_sbwad(void *sdh) +int brcmf_sdio_register(struct brcmf_sdioh_driver *driver) { - bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; + drvinfo = *driver; - if (!bcmsdh) - bcmsdh = l_bcmsdh; - - return bcmsdh->sbwad; + SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n")); + return brcmf_sdio_function_init(); } -void bcmsdh_chipinfo(void *sdh, u32 chip, u32 chiprev) +void brcmf_sdio_unregister(void) { - return; + brcmf_sdio_function_cleanup(); +} + +void brcmf_sdio_wdtmr_enable(bool enable) +{ + if (enable) + brcmf_sdbrcm_wd_timer(sdhcinfo->ch, brcmf_watchdog_ms); + else + brcmf_sdbrcm_wd_timer(sdhcinfo->ch, 0); } diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c deleted file mode 100644 index 465f623760f3..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/** - * @file bcmsdh_linux.c - */ - -#define __UNDEF_NO_VERSION__ - -#include -#include -#include - -#include -#include -#include -#include - -#if defined(OOB_INTR_ONLY) -#include -extern void dhdsdio_isr(void *args); -#include -#include -#endif /* defined(OOB_INTR_ONLY) */ -#if defined(CONFIG_MACH_SANDGATE2G) || defined(CONFIG_MACH_LOGICPD_PXA270) -#if !defined(BCMPLATFORM_BUS) -#define BCMPLATFORM_BUS -#endif /* !defined(BCMPLATFORM_BUS) */ - -#include -#endif /* CONFIG_MACH_SANDGATE2G */ - -#include "dngl_stats.h" -#include "dhd.h" - -/** - * SDIO Host Controller info - */ -typedef struct bcmsdh_hc bcmsdh_hc_t; - -struct bcmsdh_hc { - bcmsdh_hc_t *next; -#ifdef BCMPLATFORM_BUS - struct device *dev; /* platform device handle */ -#else - struct pci_dev *dev; /* pci device handle */ -#endif /* BCMPLATFORM_BUS */ - void *regs; /* SDIO Host Controller address */ - bcmsdh_info_t *sdh; /* SDIO Host Controller handle */ - void *ch; - unsigned int oob_irq; - unsigned long oob_flags; /* OOB Host specifiction - as edge and etc */ - bool oob_irq_registered; -#if defined(OOB_INTR_ONLY) - spinlock_t irq_lock; -#endif -}; -static bcmsdh_hc_t *sdhcinfo; - -/* driver info, initialized when bcmsdh_register is called */ -static bcmsdh_driver_t drvinfo = { NULL, NULL }; - -/* debugging macros */ -#define SDLX_MSG(x) - -/** - * Checks to see if vendor and device IDs match a supported SDIO Host Controller. - */ -bool bcmsdh_chipmatch(u16 vendor, u16 device) -{ - /* Add other vendors and devices as required */ - -#ifdef BCMSDIOH_STD - /* Check for Arasan host controller */ - if (vendor == VENDOR_SI_IMAGE) - return true; - - /* Check for BRCM 27XX Standard host controller */ - if (device == BCM27XX_SDIOH_ID && vendor == PCI_VENDOR_ID_BROADCOM) - return true; - - /* Check for BRCM Standard host controller */ - if (device == SDIOH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM) - return true; - - /* Check for TI PCIxx21 Standard host controller */ - if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI) - return true; - - if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI) - return true; - - /* Ricoh R5C822 Standard SDIO Host */ - if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH) - return true; - - /* JMicron Standard SDIO Host */ - if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON) - return true; -#endif /* BCMSDIOH_STD */ -#ifdef BCMSDIOH_SPI - /* This is the PciSpiHost. */ - if (device == SPIH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM) { - return true; - } -#endif /* BCMSDIOH_SPI */ - - return false; -} - -#if defined(BCMPLATFORM_BUS) -#if defined(BCMLXSDMMC) -/* forward declarations */ -int bcmsdh_probe(struct device *dev); -EXPORT_SYMBOL(bcmsdh_probe); - -int bcmsdh_remove(struct device *dev); -EXPORT_SYMBOL(bcmsdh_remove); - -#else -/* forward declarations */ -static int __devinit bcmsdh_probe(struct device *dev); -static int __devexit bcmsdh_remove(struct device *dev); -#endif /* BCMLXSDMMC */ - -#ifndef BCMLXSDMMC -static -#endif /* BCMLXSDMMC */ -int bcmsdh_probe(struct device *dev) -{ - bcmsdh_hc_t *sdhc = NULL; - unsigned long regs = 0; - bcmsdh_info_t *sdh = NULL; -#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) - struct platform_device *pdev; - struct resource *r; -#endif /* BCMLXSDMMC */ - int irq = 0; - u32 vendevid; - unsigned long irq_flags = 0; - -#if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) - pdev = to_platform_device(dev); - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (!r || irq == NO_IRQ) - return -ENXIO; -#endif /* BCMLXSDMMC */ - -#if defined(OOB_INTR_ONLY) -#ifdef HW_OOB - irq_flags = - IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | - IORESOURCE_IRQ_SHAREABLE; -#else - irq_flags = IRQF_TRIGGER_FALLING; -#endif /* HW_OOB */ - irq = dhd_customer_oob_irq_map(&irq_flags); - if (irq < 0) { - SDLX_MSG(("%s: Host irq is not defined\n", __func__)); - return 1; - } -#endif /* defined(OOB_INTR_ONLY) */ - /* allocate SDIO Host Controller state info */ - sdhc = kzalloc(sizeof(bcmsdh_hc_t), GFP_ATOMIC); - if (!sdhc) { - SDLX_MSG(("%s: out of memory\n", __func__)); - goto err; - } - sdhc->dev = (void *)dev; - -#ifdef BCMLXSDMMC - sdh = bcmsdh_attach((void *)0, (void **)®s, irq); - if (!sdh) { - SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__)); - goto err; - } -#else - sdh = bcmsdh_attach((void *)r->start, (void **)®s, irq); - if (!sdh) { - SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__)); - goto err; - } -#endif /* BCMLXSDMMC */ - sdhc->sdh = sdh; - sdhc->oob_irq = irq; - sdhc->oob_flags = irq_flags; - sdhc->oob_irq_registered = false; /* to make sure.. */ -#if defined(OOB_INTR_ONLY) - spin_lock_init(&sdhc->irq_lock); -#endif - - /* chain SDIO Host Controller info together */ - sdhc->next = sdhcinfo; - sdhcinfo = sdhc; - /* Read the vendor/device ID from the CIS */ - vendevid = bcmsdh_query_device(sdh); - - /* try to attach to the target device */ - sdhc->ch = drvinfo.attach((vendevid >> 16), (vendevid & 0xFFFF), - 0, 0, 0, 0, (void *)regs, sdh); - if (!sdhc->ch) { - SDLX_MSG(("%s: device attach failed\n", __func__)); - goto err; - } - - return 0; - - /* error handling */ -err: - if (sdhc) { - if (sdhc->sdh) - bcmsdh_detach(sdhc->sdh); - kfree(sdhc); - } - - return -ENODEV; -} - -#ifndef BCMLXSDMMC -static -#endif /* BCMLXSDMMC */ -int bcmsdh_remove(struct device *dev) -{ - bcmsdh_hc_t *sdhc, *prev; - - sdhc = sdhcinfo; - drvinfo.detach(sdhc->ch); - bcmsdh_detach(sdhc->sdh); - /* find the SDIO Host Controller state for this pdev - and take it out from the list */ - for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { - if (sdhc->dev == (void *)dev) { - if (prev) - prev->next = sdhc->next; - else - sdhcinfo = NULL; - break; - } - prev = sdhc; - } - if (!sdhc) { - SDLX_MSG(("%s: failed\n", __func__)); - return 0; - } - - /* release SDIO Host Controller info */ - kfree(sdhc); - -#if !defined(BCMLXSDMMC) - dev_set_drvdata(dev, NULL); -#endif /* !defined(BCMLXSDMMC) */ - - return 0; -} -#endif /* BCMPLATFORM_BUS */ - -extern int sdio_function_init(void); - -int bcmsdh_register(bcmsdh_driver_t *driver) -{ - drvinfo = *driver; - - SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n")); - return sdio_function_init(); -} - -extern void sdio_function_cleanup(void); - -void bcmsdh_unregister(void) -{ - sdio_function_cleanup(); -} - -#if defined(OOB_INTR_ONLY) -void bcmsdh_oob_intr_set(bool enable) -{ - static bool curstate = 1; - unsigned long flags; - - spin_lock_irqsave(&sdhcinfo->irq_lock, flags); - if (curstate != enable) { - if (enable) - enable_irq(sdhcinfo->oob_irq); - else - disable_irq_nosync(sdhcinfo->oob_irq); - curstate = enable; - } - spin_unlock_irqrestore(&sdhcinfo->irq_lock, flags); -} - -static irqreturn_t wlan_oob_irq(int irq, void *dev_id) -{ - dhd_pub_t *dhdp; - - dhdp = (dhd_pub_t *) dev_get_drvdata(sdhcinfo->dev); - - bcmsdh_oob_intr_set(0); - - if (dhdp == NULL) { - SDLX_MSG(("Out of band GPIO interrupt fired way too early\n")); - return IRQ_HANDLED; - } - - dhdsdio_isr((void *)dhdp->bus); - - return IRQ_HANDLED; -} - -int bcmsdh_register_oob_intr(void *dhdp) -{ - int error = 0; - - SDLX_MSG(("%s Enter\n", __func__)); - - sdhcinfo->oob_flags = - IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | - IORESOURCE_IRQ_SHAREABLE; - dev_set_drvdata(sdhcinfo->dev, dhdp); - - if (!sdhcinfo->oob_irq_registered) { - SDLX_MSG(("%s IRQ=%d Type=%X\n", __func__, - (int)sdhcinfo->oob_irq, (int)sdhcinfo->oob_flags)); - /* Refer to customer Host IRQ docs about - proper irqflags definition */ - error = - request_irq(sdhcinfo->oob_irq, wlan_oob_irq, - sdhcinfo->oob_flags, "bcmsdh_sdmmc", NULL); - if (error) - return -ENODEV; - - irq_set_irq_wake(sdhcinfo->oob_irq, 1); - sdhcinfo->oob_irq_registered = true; - } - - return 0; -} - -void bcmsdh_unregister_oob_intr(void) -{ - SDLX_MSG(("%s: Enter\n", __func__)); - - irq_set_irq_wake(sdhcinfo->oob_irq, 0); - disable_irq(sdhcinfo->oob_irq); /* just in case.. */ - free_irq(sdhcinfo->oob_irq, NULL); - sdhcinfo->oob_irq_registered = false; -} -#endif /* defined(OOB_INTR_ONLY) */ -/* Module parameters specific to each host-controller driver */ - -extern uint sd_msglevel; /* Debug message level */ -module_param(sd_msglevel, uint, 0); - -extern uint sd_power; /* 0 = SD Power OFF, - 1 = SD Power ON. */ -module_param(sd_power, uint, 0); - -extern uint sd_clock; /* SD Clock Control, 0 = SD Clock OFF, - 1 = SD Clock ON */ -module_param(sd_clock, uint, 0); - -extern uint sd_divisor; /* Divisor (-1 means external clock) */ -module_param(sd_divisor, uint, 0); - -extern uint sd_sdmode; /* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */ -module_param(sd_sdmode, uint, 0); - -extern uint sd_hiok; /* Ok to use hi-speed mode */ -module_param(sd_hiok, uint, 0); - -extern uint sd_f2_blocksize; -module_param(sd_f2_blocksize, int, 0); diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index c0ffbd35e0ca..38bd9ba3096f 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -15,64 +15,179 @@ */ #include #include -#include -#include -#include -#include /* SDIO Device and Protocol Specs */ -#include /* SDIO Host Controller Specification */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* ioctl/iovars */ - +#include #include #include #include +#include #include +#include +#include /* request_irq() */ +#include -#include -#include +#include +#include +#include +#include +#include "sdio_host.h" +#include "dhd.h" +#include "dhd_dbg.h" +#include "wl_cfg80211.h" -#include "bcmsdh_sdmmc.h" +#define BLOCK_SIZE_64 64 +#define BLOCK_SIZE_512 512 +#define BLOCK_SIZE_4318 64 +#define BLOCK_SIZE_4328 512 -extern int sdio_function_init(void); -extern void sdio_function_cleanup(void); +/* private bus modes */ +#define SDIOH_MODE_SD4 2 -#if !defined(OOB_INTR_ONLY) -static void IRQHandler(struct sdio_func *func); -static void IRQHandlerF2(struct sdio_func *func); -#endif /* !defined(OOB_INTR_ONLY) */ -static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, u32 regaddr); -extern int sdio_reset_comm(struct mmc_card *card); +#define CLIENT_INTR 0x100 /* Get rid of this! */ -extern PBCMSDH_SDMMC_INSTANCE gInstance; +#if !defined(SDIO_VENDOR_ID_BROADCOM) +#define SDIO_VENDOR_ID_BROADCOM 0x02d0 +#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */ -uint sd_sdmode = SDIOH_MODE_SD4; /* Use SD4 mode by default */ -uint sd_f2_blocksize = 512; /* Default blocksize */ - -uint sd_divisor = 2; /* Default 48MHz/2 = 24MHz */ - -uint sd_power = 1; /* Default to SD Slot powered ON */ -uint sd_clock = 1; /* Default to SD Clock turned ON */ -uint sd_hiok = false; /* Don't use hi-speed mode by default */ -uint sd_msglevel = 0x01; -uint sd_use_dma = true; -DHD_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait); -DHD_PM_RESUME_WAIT_INIT(sdioh_request_word_wait); -DHD_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait); -DHD_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait); +#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000 #define DMA_ALIGN_MASK 0x03 -int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, u32 regaddr, - int regsize, u32 *data); +#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) +#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB 0x0492 /* BCM94325SDGWB */ +#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */ +#if !defined(SDIO_DEVICE_ID_BROADCOM_4325) +#define SDIO_DEVICE_ID_BROADCOM_4325 0x0493 +#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */ +#if !defined(SDIO_DEVICE_ID_BROADCOM_4329) +#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 +#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */ +#if !defined(SDIO_DEVICE_ID_BROADCOM_4319) +#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319 +#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */ -void sdioh_sdio_set_host_pm_flags(int flag) -{ - if (sdio_set_host_pm_flags(gInstance->func[1], flag)) - printk(KERN_ERR "%s: Failed to set pm_flags 0x%08x\n",\ - __func__, (unsigned int)flag); -} +/* Common msglevel constants */ +#define SDH_ERROR_VAL 0x0001 /* Error */ +#define SDH_TRACE_VAL 0x0002 /* Trace */ +#define SDH_INFO_VAL 0x0004 /* Info */ +#define SDH_DEBUG_VAL 0x0008 /* Debug */ +#define SDH_DATA_VAL 0x0010 /* Data */ +#define SDH_CTRL_VAL 0x0020 /* Control Regs */ +#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */ +#define SDH_DMA_VAL 0x0080 /* DMA */ -static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) +#ifdef BCMDBG +#define sd_err(x) \ + do { \ + if ((sd_msglevel & SDH_ERROR_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) +#define sd_trace(x) \ + do { \ + if ((sd_msglevel & SDH_TRACE_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) +#define sd_info(x) \ + do { \ + if ((sd_msglevel & SDH_INFO_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) +#define sd_debug(x) \ + do { \ + if ((sd_msglevel & SDH_DEBUG_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) +#define sd_data(x) \ + do { \ + if ((sd_msglevel & SDH_DATA_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) +#define sd_ctrl(x) \ + do { \ + if ((sd_msglevel & SDH_CTRL_VAL) && net_ratelimit()) \ + printk x; \ + } while (0) +#else +#define sd_err(x) +#define sd_trace(x) +#define sd_info(x) +#define sd_debug(x) +#define sd_data(x) +#define sd_ctrl(x) +#endif + +struct sdos_info { + struct sdioh_info *sd; + spinlock_t lock; +}; + +static void brcmf_sdioh_irqhandler(struct sdio_func *func); +static void brcmf_sdioh_irqhandler_f2(struct sdio_func *func); +static int brcmf_sdioh_get_cisaddr(struct sdioh_info *sd, u32 regaddr); +static int brcmf_ops_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id); +static void brcmf_ops_sdio_remove(struct sdio_func *func); + +#ifdef CONFIG_PM +static int brcmf_sdio_suspend(struct device *dev); +static int brcmf_sdio_resume(struct device *dev); +#endif /* CONFIG_PM */ + +uint sd_f2_blocksize = 512; /* Default blocksize */ + +uint sd_msglevel = 0x01; + +/* module param defaults */ +static int clockoverride; + +module_param(clockoverride, int, 0644); +MODULE_PARM_DESC(clockoverride, "SDIO card clock override"); + +struct brcmf_sdmmc_instance *gInstance; + +struct device sdmmc_dev; + +/* devices we support, null terminated */ +static const struct sdio_device_id brcmf_sdmmc_ids[] = { + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT)}, + {SDIO_DEVICE + (SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319)}, + { /* end: all zeroes */ }, +}; + +#ifdef CONFIG_PM +static const struct dev_pm_ops brcmf_sdio_pm_ops = { + .suspend = brcmf_sdio_suspend, + .resume = brcmf_sdio_resume, +}; +#endif /* CONFIG_PM */ + +static struct sdio_driver brcmf_sdmmc_driver = { + .probe = brcmf_ops_sdio_probe, + .remove = brcmf_ops_sdio_remove, + .name = "brcmfmac", + .id_table = brcmf_sdmmc_ids, +#ifdef CONFIG_PM + .drv = { + .pm = &brcmf_sdio_pm_ops, + }, +#endif /* CONFIG_PM */ +}; + +MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); + +BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait); +BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_word_wait); +BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait); +BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait); + +static int +brcmf_sdioh_card_regread(struct sdioh_info *sd, int func, u32 regaddr, + int regsize, u32 *data); + +static int brcmf_sdioh_enablefuncs(struct sdioh_info *sd) { int err_ret; u32 fbraddr; @@ -81,16 +196,16 @@ static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) sd_trace(("%s\n", __func__)); /* Get the Card's common CIS address */ - sd->com_cis_ptr = sdioh_sdmmc_get_cisaddr(sd, SDIOD_CCCR_CISPTR_0); + sd->com_cis_ptr = brcmf_sdioh_get_cisaddr(sd, SDIO_CCCR_CIS); sd->func_cis_ptr[0] = sd->com_cis_ptr; sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __func__, sd->com_cis_ptr)); /* Get the Card's function CIS (for each function) */ - for (fbraddr = SDIOD_FBR_STARTADDR, func = 1; + for (fbraddr = SDIO_FBR_BASE(1), func = 1; func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { sd->func_cis_ptr[func] = - sdioh_sdmmc_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr); + brcmf_sdioh_get_cisaddr(sd, SDIO_FBR_CIS + fbraddr); sd_info(("%s: Function %d CIS Ptr = 0x%x\n", __func__, func, sd->func_cis_ptr[func])); } @@ -104,8 +219,8 @@ static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) err_ret = sdio_enable_func(gInstance->func[1]); sdio_release_host(gInstance->func[1]); if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to enable F1 Err: 0x%08x", - err_ret)); + sd_err(("brcmf_sdioh_enablefuncs: Failed to enable F1 " + "Err: 0x%08x\n", err_ret)); } return false; @@ -114,9 +229,9 @@ static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) /* * Public entry points & extern's */ -sdioh_info_t *sdioh_attach(void *bar0, uint irq) +struct sdioh_info *brcmf_sdioh_attach(void *bar0, uint irq) { - sdioh_info_t *sd; + struct sdioh_info *sd; int err_ret; sd_trace(("%s\n", __func__)); @@ -126,19 +241,18 @@ sdioh_info_t *sdioh_attach(void *bar0, uint irq) return NULL; } - sd = kzalloc(sizeof(sdioh_info_t), GFP_ATOMIC); + sd = kzalloc(sizeof(struct sdioh_info), GFP_ATOMIC); if (sd == NULL) { sd_err(("sdioh_attach: out of memory\n")); return NULL; } - if (sdioh_sdmmc_osinit(sd) != 0) { + if (brcmf_sdioh_osinit(sd) != 0) { sd_err(("%s:sdioh_sdmmc_osinit() failed\n", __func__)); kfree(sd); return NULL; } sd->num_funcs = 2; - sd->sd_blockmode = true; sd->use_client_ints = true; sd->client_block_size[0] = 64; @@ -150,7 +264,7 @@ sdioh_info_t *sdioh_attach(void *bar0, uint irq) sd->client_block_size[1] = 64; err_ret = sdio_set_block_size(gInstance->func[1], 64); if (err_ret) - sd_err(("bcmsdh_sdmmc: Failed to set F1 blocksize\n")); + sd_err(("brcmf_sdioh_attach: Failed to set F1 blocksize\n")); /* Release host controller F1 */ sdio_release_host(gInstance->func[1]); @@ -163,20 +277,20 @@ sdioh_info_t *sdioh_attach(void *bar0, uint irq) err_ret = sdio_set_block_size(gInstance->func[2], sd_f2_blocksize); if (err_ret) - sd_err(("bcmsdh_sdmmc: Failed to set F2 blocksize " - "to %d\n", sd_f2_blocksize)); + sd_err(("brcmf_sdioh_attach: Failed to set F2 blocksize" + " to %d\n", sd_f2_blocksize)); /* Release host controller F2 */ sdio_release_host(gInstance->func[2]); } - sdioh_sdmmc_card_enablefuncs(sd); + brcmf_sdioh_enablefuncs(sd); sd_trace(("%s: Done\n", __func__)); return sd; } -extern SDIOH_API_RC sdioh_detach(sdioh_info_t *sd) +extern int brcmf_sdioh_detach(struct sdioh_info *sd) { sd_trace(("%s\n", __func__)); @@ -193,92 +307,25 @@ extern SDIOH_API_RC sdioh_detach(sdioh_info_t *sd) sdio_release_host(gInstance->func[1]); /* deregister irq */ - sdioh_sdmmc_osfree(sd); + brcmf_sdioh_osfree(sd); kfree(sd); } - return SDIOH_API_RC_SUCCESS; + return 0; } -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) - -extern SDIOH_API_RC sdioh_enable_func_intr(void) -{ - u8 reg; - int err; - - if (gInstance->func[0]) { - sdio_claim_host(gInstance->func[0]); - - reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err); - if (err) { - sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n", - __func__, err)); - sdio_release_host(gInstance->func[0]); - return SDIOH_API_RC_FAIL; - } - - /* Enable F1 and F2 interrupts, set master enable */ - reg |= - (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN | - INTR_CTL_MASTER_EN); - - sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err); - sdio_release_host(gInstance->func[0]); - - if (err) { - sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n", - __func__, err)); - return SDIOH_API_RC_FAIL; - } - } - - return SDIOH_API_RC_SUCCESS; -} - -extern SDIOH_API_RC sdioh_disable_func_intr(void) -{ - u8 reg; - int err; - - if (gInstance->func[0]) { - sdio_claim_host(gInstance->func[0]); - reg = sdio_readb(gInstance->func[0], SDIOD_CCCR_INTEN, &err); - if (err) { - sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n", - __func__, err)); - sdio_release_host(gInstance->func[0]); - return SDIOH_API_RC_FAIL; - } - - reg &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN); - /* Disable master interrupt with the last function interrupt */ - if (!(reg & 0xFE)) - reg = 0; - sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err); - - sdio_release_host(gInstance->func[0]); - if (err) { - sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n", - __func__, err)); - return SDIOH_API_RC_FAIL; - } - } - return SDIOH_API_RC_SUCCESS; -} -#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */ - /* Configure callback to client when we receive client interrupt */ -extern SDIOH_API_RC -sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) +extern int +brcmf_sdioh_interrupt_register(struct sdioh_info *sd, void (*fn)(void *), + void *argh) { sd_trace(("%s: Entering\n", __func__)); if (fn == NULL) { sd_err(("%s: interrupt handler is NULL, not registering\n", __func__)); - return SDIOH_API_RC_FAIL; + return -EINVAL; } -#if !defined(OOB_INTR_ONLY) + sd->intr_handler = fn; sd->intr_handler_arg = argh; sd->intr_handler_valid = true; @@ -286,26 +333,23 @@ sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh) /* register and unmask irq */ if (gInstance->func[2]) { sdio_claim_host(gInstance->func[2]); - sdio_claim_irq(gInstance->func[2], IRQHandlerF2); + sdio_claim_irq(gInstance->func[2], brcmf_sdioh_irqhandler_f2); sdio_release_host(gInstance->func[2]); } if (gInstance->func[1]) { sdio_claim_host(gInstance->func[1]); - sdio_claim_irq(gInstance->func[1], IRQHandler); + sdio_claim_irq(gInstance->func[1], brcmf_sdioh_irqhandler); sdio_release_host(gInstance->func[1]); } -#elif defined(HW_OOB) - sdioh_enable_func_intr(); -#endif /* defined(OOB_INTR_ONLY) */ - return SDIOH_API_RC_SUCCESS; + + return 0; } -extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *sd) +extern int brcmf_sdioh_interrupt_deregister(struct sdioh_info *sd) { sd_trace(("%s: Entering\n", __func__)); -#if !defined(OOB_INTR_ONLY) if (gInstance->func[1]) { /* register and unmask irq */ sdio_claim_host(gInstance->func[1]); @@ -324,73 +368,28 @@ extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *sd) sd->intr_handler_valid = false; sd->intr_handler = NULL; sd->intr_handler_arg = NULL; -#elif defined(HW_OOB) - sdioh_disable_func_intr(); -#endif /* !defined(OOB_INTR_ONLY) */ - return SDIOH_API_RC_SUCCESS; -} -extern SDIOH_API_RC sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff) -{ - sd_trace(("%s: Entering\n", __func__)); - *onoff = sd->client_intr_enabled; - return SDIOH_API_RC_SUCCESS; -} - -#if defined(DHD_DEBUG) -extern bool sdioh_interrupt_pending(sdioh_info_t *sd) -{ return 0; } -#endif - -uint sdioh_query_iofnum(sdioh_info_t *sd) -{ - return sd->num_funcs; -} /* IOVar table */ enum { IOV_MSGLEVEL = 1, - IOV_BLOCKMODE, IOV_BLOCKSIZE, - IOV_DMA, IOV_USEINTS, IOV_NUMINTS, - IOV_NUMLOCALINTS, - IOV_HOSTREG, IOV_DEVREG, - IOV_DIVISOR, - IOV_SDMODE, - IOV_HISPEED, IOV_HCIREGS, - IOV_POWER, - IOV_CLOCK, IOV_RXCHAIN }; -const bcm_iovar_t sdioh_iovars[] = { +const struct brcmu_iovar sdioh_iovars[] = { {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0}, - {"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0}, {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0},/* ((fn << 16) | size) */ - {"sd_dma", IOV_DMA, 0, IOVT_BOOL, 0}, {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0}, {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0}, - {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0}, - {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t)} - , - {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t)} - , - {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0} - , - {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0} - , - {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0} - , - {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100} - , - {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0} + {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)} , {"sd_rxchain", IOV_RXCHAIN, 0, IOVT_BOOL, 0} , @@ -398,33 +397,37 @@ const bcm_iovar_t sdioh_iovars[] = { }; int -sdioh_iovar_op(sdioh_info_t *si, const char *name, - void *params, int plen, void *arg, int len, bool set) +brcmf_sdioh_iovar_op(struct sdioh_info *si, const char *name, + void *params, int plen, void *arg, int len, bool set) { - const bcm_iovar_t *vi = NULL; + const struct brcmu_iovar *vi = NULL; int bcmerror = 0; int val_size; s32 int_val = 0; bool bool_val; u32 actionid; - ASSERT(name); - ASSERT(len >= 0); + if (name == NULL || len <= 0) + return -EINVAL; - /* Get must have return space; Set does not take qualifiers */ - ASSERT(set || (arg && len)); - ASSERT(!set || (!params && !plen)); + /* Set does not take qualifiers */ + if (set && (params || plen)) + return -EINVAL; + + /* Get must have return space;*/ + if (!set && !(arg && len)) + return -EINVAL; sd_trace(("%s: Enter (%s %s)\n", __func__, (set ? "set" : "get"), name)); - vi = bcm_iovar_lookup(sdioh_iovars, name); + vi = brcmu_iovar_lookup(sdioh_iovars, name); if (vi == NULL) { bcmerror = -ENOTSUPP; goto exit; } - bcmerror = bcm_iovar_lencheck(vi, arg, len, set); + bcmerror = brcmu_iovar_lencheck(vi, arg, len, set); if (bcmerror != 0) goto exit; @@ -457,16 +460,6 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, sd_msglevel = int_val; break; - case IOV_GVAL(IOV_BLOCKMODE): - int_val = (s32) si->sd_blockmode; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_BLOCKMODE): - si->sd_blockmode = (bool) int_val; - /* Haven't figured out how to make non-block mode with DMA */ - break; - case IOV_GVAL(IOV_BLOCKSIZE): if ((u32) int_val > si->num_funcs) { bcmerror = -EINVAL; @@ -518,15 +511,6 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, memcpy(arg, &int_val, val_size); break; - case IOV_GVAL(IOV_DMA): - int_val = (s32) si->sd_use_dma; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_DMA): - si->sd_use_dma = (bool) int_val; - break; - case IOV_GVAL(IOV_USEINTS): int_val = (s32) si->use_client_ints; memcpy(arg, &int_val, val_size); @@ -541,117 +525,18 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, break; - case IOV_GVAL(IOV_DIVISOR): - int_val = (u32) sd_divisor; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_DIVISOR): - sd_divisor = int_val; - break; - - case IOV_GVAL(IOV_POWER): - int_val = (u32) sd_power; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_POWER): - sd_power = int_val; - break; - - case IOV_GVAL(IOV_CLOCK): - int_val = (u32) sd_clock; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_CLOCK): - sd_clock = int_val; - break; - - case IOV_GVAL(IOV_SDMODE): - int_val = (u32) sd_sdmode; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_SDMODE): - sd_sdmode = int_val; - break; - - case IOV_GVAL(IOV_HISPEED): - int_val = (u32) sd_hiok; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_HISPEED): - sd_hiok = int_val; - break; - case IOV_GVAL(IOV_NUMINTS): int_val = (s32) si->intrcount; memcpy(arg, &int_val, val_size); break; - case IOV_GVAL(IOV_NUMLOCALINTS): - int_val = (s32) 0; - memcpy(arg, &int_val, val_size); - break; - - case IOV_GVAL(IOV_HOSTREG): - { - sdreg_t *sd_ptr = (sdreg_t *) params; - - if (sd_ptr->offset < SD_SysAddr - || sd_ptr->offset > SD_MaxCurCap) { - sd_err(("%s: bad offset 0x%x\n", __func__, - sd_ptr->offset)); - bcmerror = -EINVAL; - break; - } - - sd_trace(("%s: rreg%d at offset %d\n", __func__, - (sd_ptr->offset & 1) ? 8 - : ((sd_ptr->offset & 2) ? 16 : 32), - sd_ptr->offset)); - if (sd_ptr->offset & 1) - int_val = 8; /* sdioh_sdmmc_rreg8(si, - sd_ptr->offset); */ - else if (sd_ptr->offset & 2) - int_val = 16; /* sdioh_sdmmc_rreg16(si, - sd_ptr->offset); */ - else - int_val = 32; /* sdioh_sdmmc_rreg(si, - sd_ptr->offset); */ - - memcpy(arg, &int_val, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_HOSTREG): - { - sdreg_t *sd_ptr = (sdreg_t *) params; - - if (sd_ptr->offset < SD_SysAddr - || sd_ptr->offset > SD_MaxCurCap) { - sd_err(("%s: bad offset 0x%x\n", __func__, - sd_ptr->offset)); - bcmerror = -EINVAL; - break; - } - - sd_trace(("%s: wreg%d value 0x%08x at offset %d\n", - __func__, sd_ptr->value, - (sd_ptr->offset & 1) ? 8 - : ((sd_ptr->offset & 2) ? 16 : 32), - sd_ptr->offset)); - break; - } - case IOV_GVAL(IOV_DEVREG): { - sdreg_t *sd_ptr = (sdreg_t *) params; + struct brcmf_sdreg *sd_ptr = + (struct brcmf_sdreg *) params; u8 data = 0; - if (sdioh_cfg_read + if (brcmf_sdioh_cfg_read (si, sd_ptr->func, sd_ptr->offset, &data)) { bcmerror = -EIO; break; @@ -664,10 +549,11 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, case IOV_SVAL(IOV_DEVREG): { - sdreg_t *sd_ptr = (sdreg_t *) params; + struct brcmf_sdreg *sd_ptr = + (struct brcmf_sdreg *) params; u8 data = (u8) sd_ptr->value; - if (sdioh_cfg_write + if (brcmf_sdioh_cfg_write (si, sd_ptr->func, sd_ptr->offset, &data)) { bcmerror = -EIO; break; @@ -684,50 +570,32 @@ sdioh_iovar_op(sdioh_info_t *si, const char *name, return bcmerror; } -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) - -SDIOH_API_RC sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable) +extern int +brcmf_sdioh_cfg_read(struct sdioh_info *sd, uint fnc_num, u32 addr, u8 *data) { - SDIOH_API_RC status; - u8 data; - - if (enable) - data = 3; /* enable hw oob interrupt */ - else - data = 4; /* disable hw oob interrupt */ - data |= 4; /* Active HIGH */ - - status = sdioh_request_byte(sd, SDIOH_WRITE, 0, 0xf2, &data); - return status; -} -#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */ - -extern SDIOH_API_RC -sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, u32 addr, u8 *data) -{ - SDIOH_API_RC status; - /* No lock needed since sdioh_request_byte does locking */ - status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); + int status; + /* No lock needed since brcmf_sdioh_request_byte does locking */ + status = brcmf_sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); return status; } -extern SDIOH_API_RC -sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, u32 addr, u8 *data) +extern int +brcmf_sdioh_cfg_write(struct sdioh_info *sd, uint fnc_num, u32 addr, u8 *data) { - /* No lock needed since sdioh_request_byte does locking */ - SDIOH_API_RC status; - status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); + /* No lock needed since brcmf_sdioh_request_byte does locking */ + int status; + status = brcmf_sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); return status; } -static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, u32 regaddr) +static int brcmf_sdioh_get_cisaddr(struct sdioh_info *sd, u32 regaddr) { /* read 24 bits and return valid 17 bit addr */ int i; u32 scratch, regdata; u8 *ptr = (u8 *)&scratch; for (i = 0; i < 3; i++) { - if ((sdioh_sdmmc_card_regread(sd, 0, regaddr, 1, ®data)) != + if ((brcmf_sdioh_card_regread(sd, 0, regaddr, 1, ®data)) != SUCCESS) sd_err(("%s: Can't read!\n", __func__)); @@ -741,8 +609,8 @@ static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, u32 regaddr) return scratch; } -extern SDIOH_API_RC -sdioh_cis_read(sdioh_info_t *sd, uint func, u8 *cisd, u32 length) +extern int +brcmf_sdioh_cis_read(struct sdioh_info *sd, uint func, u8 *cisd, u32 length) { u32 count; int offset; @@ -754,7 +622,7 @@ sdioh_cis_read(sdioh_info_t *sd, uint func, u8 *cisd, u32 length) if (!sd->func_cis_ptr[func]) { memset(cis, 0, length); sd_err(("%s: no func_cis_ptr[%d]\n", __func__, func)); - return SDIOH_API_RC_FAIL; + return -ENOTSUPP; } sd_err(("%s: func_cis_ptr[%d]=0x%04x\n", __func__, func, @@ -762,37 +630,37 @@ sdioh_cis_read(sdioh_info_t *sd, uint func, u8 *cisd, u32 length) for (count = 0; count < length; count++) { offset = sd->func_cis_ptr[func] + count; - if (sdioh_sdmmc_card_regread(sd, 0, offset, 1, &foo) < 0) { + if (brcmf_sdioh_card_regread(sd, 0, offset, 1, &foo) < 0) { sd_err(("%s: regread failed: Can't read CIS\n", __func__)); - return SDIOH_API_RC_FAIL; + return -EIO; } *cis = (u8) (foo & 0xff); cis++; } - return SDIOH_API_RC_SUCCESS; + return 0; } -extern SDIOH_API_RC -sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, - u8 *byte) +extern int +brcmf_sdioh_request_byte(struct sdioh_info *sd, uint rw, uint func, + uint regaddr, u8 *byte) { int err_ret; sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __func__, rw, func, regaddr)); - DHD_PM_RESUME_WAIT(sdioh_request_byte_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); + BRCMF_PM_RESUME_WAIT(sdioh_request_byte_wait); + BRCMF_PM_RESUME_RETURN_ERROR(-EIO); if (rw) { /* CMD52 Write */ if (func == 0) { /* Can only directly write to some F0 registers. * Handle F2 enable * as a special case. */ - if (regaddr == SDIOD_CCCR_IOEN) { + if (regaddr == SDIO_CCCR_IOEx) { if (gInstance->func[2]) { sdio_claim_host(gInstance->func[2]); if (*byte & SDIO_FUNC_ENABLE_2) { @@ -801,7 +669,9 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, sdio_enable_func (gInstance->func[2]); if (err_ret) - sd_err(("bcmsdh_sdmmc: enable F2 failed:%d", + sd_err(("request_byte: " + "enable F2 " + "failed:%d\n", err_ret)); } else { /* Disable Function 2 */ @@ -809,15 +679,16 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, sdio_disable_func (gInstance->func[2]); if (err_ret) - sd_err(("bcmsdh_sdmmc: Disab F2 failed:%d", + sd_err(("request_byte: " + "Disab F2 " + "failed:%d\n", err_ret)); } sdio_release_host(gInstance->func[2]); } } -#if defined(MMC_SDIO_ABORT) /* to allow abort command through F1 */ - else if (regaddr == SDIOD_CCCR_IOABORT) { + else if (regaddr == SDIO_CCCR_ABORT) { sdio_claim_host(gInstance->func[func]); /* * this sdio_f0_writeb() can be replaced @@ -828,10 +699,8 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, sdio_writeb(gInstance->func[func], *byte, regaddr, &err_ret); sdio_release_host(gInstance->func[func]); - } -#endif /* MMC_SDIO_ABORT */ - else if (regaddr < 0xF0) { - sd_err(("bcmsdh_sdmmc: F0 Wr:0x%02x: write " + } else if (regaddr < 0xF0) { + sd_err(("brcmf: F0 Wr:0x%02x: write " "disallowed\n", regaddr)); } else { /* Claim host controller, perform F0 write, @@ -867,29 +736,29 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, } if (err_ret) - sd_err(("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, " + sd_err(("brcmf: Failed to %s byte F%d:@0x%05x=%02x, " "Err: %d\n", rw ? "Write" : "Read", func, regaddr, *byte, err_ret)); - return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); + return err_ret; } -extern SDIOH_API_RC -sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, - uint addr, u32 *word, uint nbytes) +extern int +brcmf_sdioh_request_word(struct sdioh_info *sd, uint cmd_type, uint rw, + uint func, uint addr, u32 *word, uint nbytes) { - int err_ret = SDIOH_API_RC_FAIL; + int err_ret = -EIO; if (func == 0) { sd_err(("%s: Only CMD52 allowed to F0.\n", __func__)); - return SDIOH_API_RC_FAIL; + return -EINVAL; } sd_info(("%s: cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", __func__, cmd_type, rw, func, addr, nbytes)); - DHD_PM_RESUME_WAIT(sdioh_request_word_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); + BRCMF_PM_RESUME_WAIT(sdioh_request_word_wait); + BRCMF_PM_RESUME_RETURN_ERROR(-EIO); /* Claim host controller */ sdio_claim_host(gInstance->func[func]); @@ -920,16 +789,16 @@ sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, sdio_release_host(gInstance->func[func]); if (err_ret) { - sd_err(("bcmsdh_sdmmc: Failed to %s word, Err: 0x%08x", + sd_err(("brcmf: Failed to %s word, Err: 0x%08x\n", rw ? "Write" : "Read", err_ret)); } - return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); + return err_ret; } -static SDIOH_API_RC -sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, - uint addr, struct sk_buff *pkt) +static int +brcmf_sdioh_request_packet(struct sdioh_info *sd, uint fix_inc, uint write, + uint func, uint addr, struct sk_buff *pkt) { bool fifo = (fix_inc == SDIOH_DATA_FIX); u32 SGCount = 0; @@ -939,9 +808,8 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, sd_trace(("%s: Enter\n", __func__)); - ASSERT(pkt); - DHD_PM_RESUME_WAIT(sdioh_request_packet_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); + BRCMF_PM_RESUME_WAIT(sdioh_request_packet_wait); + BRCMF_PM_RESUME_RETURN_ERROR(-EIO); /* Claim host controller */ sdio_claim_host(gInstance->func[func]); @@ -950,21 +818,6 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, pkt_len += 3; pkt_len &= 0xFFFFFFFC; -#ifdef CONFIG_MMC_MSM7X00A - if ((pkt_len % 64) == 32) { - sd_trace(("%s: Rounding up TX packet +=32\n", - __func__)); - pkt_len += 32; - } -#endif /* CONFIG_MMC_MSM7X00A */ - /* Make sure the packet is aligned properly. - * If it isn't, then this - * is the fault of sdioh_request_buffer() which - * is supposed to give - * us something we can work with. - */ - ASSERT(((u32) (pkt->data) & DMA_ALIGN_MASK) == 0); - if ((write) && (!fifo)) { err_ret = sdio_memcpy_toio(gInstance->func[func], addr, ((u8 *) (pnext->data)), @@ -1005,7 +858,7 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, sdio_release_host(gInstance->func[func]); sd_trace(("%s: Exit\n", __func__)); - return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); + return err_ret; } /* @@ -1023,114 +876,101 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, * aligned packet. * */ -extern SDIOH_API_RC -sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, - uint func, uint addr, uint reg_width, uint buflen_u, - u8 *buffer, struct sk_buff *pkt) +extern int +brcmf_sdioh_request_buffer(struct sdioh_info *sd, uint pio_dma, uint fix_inc, + uint write, uint func, uint addr, uint reg_width, + uint buflen_u, u8 *buffer, struct sk_buff *pkt) { - SDIOH_API_RC Status; + int Status; struct sk_buff *mypkt = NULL; sd_trace(("%s: Enter\n", __func__)); - DHD_PM_RESUME_WAIT(sdioh_request_buffer_wait); - DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL); + BRCMF_PM_RESUME_WAIT(sdioh_request_buffer_wait); + BRCMF_PM_RESUME_RETURN_ERROR(-EIO); /* Case 1: we don't have a packet. */ if (pkt == NULL) { sd_data(("%s: Creating new %s Packet, len=%d\n", __func__, write ? "TX" : "RX", buflen_u)); - mypkt = bcm_pkt_buf_get_skb(buflen_u); + mypkt = brcmu_pkt_buf_get_skb(buflen_u); if (!mypkt) { - sd_err(("%s: bcm_pkt_buf_get_skb failed: len %d\n", + sd_err(("%s: brcmu_pkt_buf_get_skb failed: len %d\n", __func__, buflen_u)); - return SDIOH_API_RC_FAIL; + return -EIO; } /* For a write, copy the buffer data into the packet. */ if (write) memcpy(mypkt->data, buffer, buflen_u); - Status = - sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); + Status = brcmf_sdioh_request_packet(sd, fix_inc, write, func, + addr, mypkt); /* For a read, copy the packet data back to the buffer. */ if (!write) memcpy(buffer, mypkt->data, buflen_u); - bcm_pkt_buf_free_skb(mypkt); - } else if (((u32) (pkt->data) & DMA_ALIGN_MASK) != 0) { - /* Case 2: We have a packet, but it is unaligned. */ - - /* In this case, we cannot have a chain. */ - ASSERT(pkt->next == NULL); - + brcmu_pkt_buf_free_skb(mypkt); + } else if (((ulong) (pkt->data) & DMA_ALIGN_MASK) != 0) { + /* + * Case 2: We have a packet, but it is unaligned. + * In this case, we cannot have a chain (pkt->next == NULL) + */ sd_data(("%s: Creating aligned %s Packet, len=%d\n", __func__, write ? "TX" : "RX", pkt->len)); - mypkt = bcm_pkt_buf_get_skb(pkt->len); + mypkt = brcmu_pkt_buf_get_skb(pkt->len); if (!mypkt) { - sd_err(("%s: bcm_pkt_buf_get_skb failed: len %d\n", + sd_err(("%s: brcmu_pkt_buf_get_skb failed: len %d\n", __func__, pkt->len)); - return SDIOH_API_RC_FAIL; + return -EIO; } /* For a write, copy the buffer data into the packet. */ if (write) memcpy(mypkt->data, pkt->data, pkt->len); - Status = - sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); + Status = brcmf_sdioh_request_packet(sd, fix_inc, write, func, + addr, mypkt); /* For a read, copy the packet data back to the buffer. */ if (!write) memcpy(pkt->data, mypkt->data, mypkt->len); - bcm_pkt_buf_free_skb(mypkt); + brcmu_pkt_buf_free_skb(mypkt); } else { /* case 3: We have a packet and it is aligned. */ sd_data(("%s: Aligned %s Packet, direct DMA\n", __func__, write ? "Tx" : "Rx")); - Status = - sdioh_request_packet(sd, fix_inc, write, func, addr, pkt); + Status = brcmf_sdioh_request_packet(sd, fix_inc, write, func, + addr, pkt); } return Status; } /* this function performs "abort" for both of host & device */ -extern int sdioh_abort(sdioh_info_t *sd, uint func) +extern int brcmf_sdioh_abort(struct sdioh_info *sd, uint func) { -#if defined(MMC_SDIO_ABORT) char t_func = (char)func; -#endif /* defined(MMC_SDIO_ABORT) */ sd_trace(("%s: Enter\n", __func__)); -#if defined(MMC_SDIO_ABORT) - /* issue abort cmd52 command through F1 */ - sdioh_request_byte(sd, SD_IO_OP_WRITE, SDIO_FUNC_0, SDIOD_CCCR_IOABORT, + /* issue abort cmd52 command through F0 */ + brcmf_sdioh_request_byte(sd, SDIOH_WRITE, SDIO_FUNC_0, SDIO_CCCR_ABORT, &t_func); -#endif /* defined(MMC_SDIO_ABORT) */ sd_trace(("%s: Exit\n", __func__)); - return SDIOH_API_RC_SUCCESS; -} - -/* Reset and re-initialize the device */ -int sdioh_sdio_reset(sdioh_info_t *si) -{ - sd_trace(("%s: Enter\n", __func__)); - sd_trace(("%s: Exit\n", __func__)); - return SDIOH_API_RC_SUCCESS; + return 0; } /* Disable device interrupt */ -void sdioh_sdmmc_devintr_off(sdioh_info_t *sd) +void brcmf_sdioh_dev_intr_off(struct sdioh_info *sd) { sd_trace(("%s: %d\n", __func__, sd->use_client_ints)); sd->intmask &= ~CLIENT_INTR; } /* Enable device interrupt */ -void sdioh_sdmmc_devintr_on(sdioh_info_t *sd) +void brcmf_sdioh_dev_intr_on(struct sdioh_info *sd) { sd_trace(("%s: %d\n", __func__, sd->use_client_ints)); sd->intmask |= CLIENT_INTR; @@ -1138,19 +978,19 @@ void sdioh_sdmmc_devintr_on(sdioh_info_t *sd) /* Read client card reg */ int -sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, u32 regaddr, +brcmf_sdioh_card_regread(struct sdioh_info *sd, int func, u32 regaddr, int regsize, u32 *data) { if ((func == 0) || (regsize == 1)) { u8 temp = 0; - sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); + brcmf_sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); *data = temp; *data &= 0xff; sd_data(("%s: byte read data=0x%02x\n", __func__, *data)); } else { - sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data, + brcmf_sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data, regsize); if (regsize == 2) *data &= 0xffff; @@ -1161,25 +1001,20 @@ sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, u32 regaddr, return SUCCESS; } -#if !defined(OOB_INTR_ONLY) -/* bcmsdh_sdmmc interrupt handler */ -static void IRQHandler(struct sdio_func *func) +static void brcmf_sdioh_irqhandler(struct sdio_func *func) { - sdioh_info_t *sd; + struct sdioh_info *sd; - sd_trace(("bcmsdh_sdmmc: ***IRQHandler\n")); + sd_trace(("brcmf: ***IRQHandler\n")); sd = gInstance->sd; - ASSERT(sd != NULL); sdio_release_host(gInstance->func[0]); if (sd->use_client_ints) { sd->intrcount++; - ASSERT(sd->intr_handler); - ASSERT(sd->intr_handler_arg); (sd->intr_handler) (sd->intr_handler_arg); } else { - sd_err(("bcmsdh_sdmmc: ***IRQHandler\n")); + sd_err(("brcmf: ***IRQHandler\n")); sd_err(("%s: Not ready for intr: enabled %d, handler %p\n", __func__, sd->client_intr_enabled, sd->intr_handler)); @@ -1188,52 +1023,174 @@ static void IRQHandler(struct sdio_func *func) sdio_claim_host(gInstance->func[0]); } -/* bcmsdh_sdmmc interrupt handler for F2 (dummy handler) */ -static void IRQHandlerF2(struct sdio_func *func) +/* interrupt handler for F2 (dummy handler) */ +static void brcmf_sdioh_irqhandler_f2(struct sdio_func *func) { - sdioh_info_t *sd; + struct sdioh_info *sd; - sd_trace(("bcmsdh_sdmmc: ***IRQHandlerF2\n")); + sd_trace(("brcmf: ***IRQHandlerF2\n")); sd = gInstance->sd; - - ASSERT(sd != NULL); } -#endif /* !defined(OOB_INTR_ONLY) */ -#ifdef NOTUSED -/* Write client card reg */ -static int -sdioh_sdmmc_card_regwrite(sdioh_info_t *sd, int func, u32 regaddr, - int regsize, u32 data) +static int brcmf_ops_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) { + int ret = 0; + static struct sdio_func sdio_func_0; + sd_trace(("sdio_probe: %s Enter\n", __func__)); + sd_trace(("sdio_probe: func->class=%x\n", func->class)); + sd_trace(("sdio_vendor: 0x%04x\n", func->vendor)); + sd_trace(("sdio_device: 0x%04x\n", func->device)); + sd_trace(("Function#: 0x%04x\n", func->num)); - if ((func == 0) || (regsize == 1)) { - u8 temp; - - temp = data & 0xff; - sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); - sd_data(("%s: byte write data=0x%02x\n", __func__, data)); - } else { - if (regsize == 2) - data &= 0xffff; - - sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, &data, - regsize); - - sd_data(("%s: word write data=0x%08x\n", __func__, data)); + if (func->num == 1) { + sdio_func_0.num = 0; + sdio_func_0.card = func->card; + gInstance->func[0] = &sdio_func_0; + if (func->device == 0x4) { /* 4318 */ + gInstance->func[2] = NULL; + sd_trace(("NIC found, calling brcmf_sdio_probe...\n")); + ret = brcmf_sdio_probe(&sdmmc_dev); + } } - return SUCCESS; -} -#endif /* NOTUSED */ + gInstance->func[func->num] = func; -int sdioh_start(sdioh_info_t *si, int stage) + if (func->num == 2) { + brcmf_cfg80211_sdio_func(func); + sd_trace(("F2 found, calling brcmf_sdio_probe...\n")); + ret = brcmf_sdio_probe(&sdmmc_dev); + } + + return ret; +} + +static void brcmf_ops_sdio_remove(struct sdio_func *func) { + sd_trace(("%s Enter\n", __func__)); + sd_info(("func->class=%x\n", func->class)); + sd_info(("sdio_vendor: 0x%04x\n", func->vendor)); + sd_info(("sdio_device: 0x%04x\n", func->device)); + sd_info(("Function#: 0x%04x\n", func->num)); + + if (func->num == 2) { + sd_trace(("F2 found, calling brcmf_sdio_remove...\n")); + brcmf_sdio_remove(&sdmmc_dev); + } +} + + +#ifdef CONFIG_PM +static int brcmf_sdio_suspend(struct device *dev) +{ + mmc_pm_flag_t sdio_flags; + int ret = 0; + + sd_trace(("%s\n", __func__)); + + sdio_flags = sdio_get_host_pm_caps(gInstance->func[1]); + if (!(sdio_flags & MMC_PM_KEEP_POWER)) { + sd_err(("Host can't keep power while suspended\n")); + return -EINVAL; + } + + ret = sdio_set_host_pm_flags(gInstance->func[1], MMC_PM_KEEP_POWER); + if (ret) { + sd_err(("Failed to set pm_flags\n")); + return ret; + } + + brcmf_sdio_wdtmr_enable(false); + + return ret; +} + +static int brcmf_sdio_resume(struct device *dev) +{ + brcmf_sdio_wdtmr_enable(true); + return 0; +} +#endif /* CONFIG_PM */ + +int brcmf_sdioh_osinit(struct sdioh_info *sd) +{ + struct sdos_info *sdos; + + sdos = kmalloc(sizeof(struct sdos_info), GFP_ATOMIC); + sd->sdos_info = (void *)sdos; + if (sdos == NULL) + return -ENOMEM; + + sdos->sd = sd; + spin_lock_init(&sdos->lock); return 0; } -int sdioh_stop(sdioh_info_t *si) +void brcmf_sdioh_osfree(struct sdioh_info *sd) { + struct sdos_info *sdos; + + sdos = (struct sdos_info *)sd->sdos_info; + kfree(sdos); +} + +/* Interrupt enable/disable */ +int brcmf_sdioh_interrupt_set(struct sdioh_info *sd, bool enable) +{ + unsigned long flags; + struct sdos_info *sdos; + + sd_trace(("%s: %s\n", __func__, enable ? "Enabling" : "Disabling")); + + sdos = (struct sdos_info *)sd->sdos_info; + + if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { + sd_err(("%s: no handler registered, will not enable\n", + __func__)); + return -EINVAL; + } + + /* Ensure atomicity for enable/disable calls */ + spin_lock_irqsave(&sdos->lock, flags); + + sd->client_intr_enabled = enable; + if (enable) + brcmf_sdioh_dev_intr_on(sd); + else + brcmf_sdioh_dev_intr_off(sd); + + spin_unlock_irqrestore(&sdos->lock, flags); + return 0; } + +/* + * module init +*/ +int brcmf_sdio_function_init(void) +{ + int error = 0; + sd_trace(("brcmf_sdio_function_init: %s Enter\n", __func__)); + + gInstance = kzalloc(sizeof(struct brcmf_sdmmc_instance), GFP_KERNEL); + if (!gInstance) + return -ENOMEM; + + memset(&sdmmc_dev, 0, sizeof(sdmmc_dev)); + error = sdio_register_driver(&brcmf_sdmmc_driver); + + return error; +} + +/* + * module cleanup +*/ +void brcmf_sdio_function_cleanup(void) +{ + sd_trace(("%s Enter\n", __func__)); + + sdio_unregister_driver(&brcmf_sdmmc_driver); + + kfree(gInstance); +} diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h deleted file mode 100644 index 3ef42b318493..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __BCMSDH_SDMMC_H__ -#define __BCMSDH_SDMMC_H__ - -#ifdef BCMDBG -#define sd_err(x) \ - do { \ - if ((sd_msglevel & SDH_ERROR_VAL) && net_ratelimit()) \ - printk x; \ - } while (0) -#define sd_trace(x) \ - do { \ - if ((sd_msglevel & SDH_TRACE_VAL) && net_ratelimit()) \ - printk x; \ - } while (0) -#define sd_info(x) \ - do { \ - if ((sd_msglevel & SDH_INFO_VAL) && net_ratelimit()) \ - printk x; \ - } while (0) -#define sd_debug(x) \ - do { \ - if ((sd_msglevel & SDH_DEBUG_VAL) && net_ratelimit()) \ - printk x; \ - } while (0) -#define sd_data(x) \ - do { \ - if ((sd_msglevel & SDH_DATA_VAL) && net_ratelimit()) \ - printk x; \ - } while (0) -#define sd_ctrl(x) \ - do { \ - if ((sd_msglevel & SDH_CTRL_VAL) && net_ratelimit()) \ - printk x; \ - } while (0) -#else -#define sd_err(x) -#define sd_trace(x) -#define sd_info(x) -#define sd_debug(x) -#define sd_data(x) -#define sd_ctrl(x) -#endif - -/* Allocate/init/free per-OS private data */ -extern int sdioh_sdmmc_osinit(sdioh_info_t *sd); -extern void sdioh_sdmmc_osfree(sdioh_info_t *sd); - -#define BLOCK_SIZE_64 64 -#define BLOCK_SIZE_512 512 -#define BLOCK_SIZE_4318 64 -#define BLOCK_SIZE_4328 512 - -/* internal return code */ -#define SUCCESS 0 -#define ERROR 1 - -/* private bus modes */ -#define SDIOH_MODE_SD4 2 -#define CLIENT_INTR 0x100 /* Get rid of this! */ - -struct sdioh_info { - struct osl_info *osh; /* osh handler */ - bool client_intr_enabled; /* interrupt connnected flag */ - bool intr_handler_valid; /* client driver interrupt handler valid */ - sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ - void *intr_handler_arg; /* argument to call interrupt handler */ - u16 intmask; /* Current active interrupts */ - void *sdos_info; /* Pointer to per-OS private data */ - - uint irq; /* Client irq */ - int intrcount; /* Client interrupts */ - bool sd_use_dma; /* DMA on CMD53 */ - bool sd_blockmode; /* sd_blockmode == false => 64 Byte Cmd 53s. */ - /* Must be on for sd_multiblock to be effective */ - bool use_client_ints; /* If this is false, make sure to restore */ - int sd_mode; /* SD1/SD4/SPI */ - int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ - u8 num_funcs; /* Supported funcs on client */ - u32 com_cis_ptr; - u32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; - uint max_dma_len; - uint max_dma_descriptors; /* DMA Descriptors supported by this controller. */ - /* SDDMA_DESCRIPTOR SGList[32]; *//* Scatter/Gather DMA List */ -}; - -/************************************************************ - * Internal interfaces: per-port references into bcmsdh_sdmmc.c - */ - -/* Global message bits */ -extern uint sd_msglevel; - -/* OS-independent interrupt handler */ -extern bool check_client_intr(sdioh_info_t *sd); - -/* Core interrupt enable/disable of device interrupts */ -extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd); -extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); - -/************************************************************** - * Internal interfaces: bcmsdh_sdmmc.c references to per-port code - */ - -/* Register mapping routines */ -extern u32 *sdioh_sdmmc_reg_map(s32 addr, int size); -extern void sdioh_sdmmc_reg_unmap(s32 addr, int size); - -/* Interrupt (de)registration routines */ -extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq); -extern void sdioh_sdmmc_free_irq(uint irq, sdioh_info_t *sd); - -typedef struct _BCMSDH_SDMMC_INSTANCE { - sdioh_info_t *sd; - struct sdio_func *func[SDIOD_MAX_IOFUNCS]; - u32 host_claimed; -} BCMSDH_SDMMC_INSTANCE, *PBCMSDH_SDMMC_INSTANCE; - -#endif /* __BCMSDH_SDMMC_H__ */ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c deleted file mode 100644 index 2792a4dfe651..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include /* request_irq() */ -#include -#include -#include -#include /* SDIO Specs */ -#include /* bcmsdh to/from specific controller APIs */ -#include /* to get msglevel bit values */ - -#include -#include -#include -#include - -#include "dngl_stats.h" -#include "dhd.h" - -#if !defined(SDIO_VENDOR_ID_BROADCOM) -#define SDIO_VENDOR_ID_BROADCOM 0x02d0 -#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */ - -#define SDIO_DEVICE_ID_BROADCOM_DEFAULT 0x0000 - -#if !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) -#define SDIO_DEVICE_ID_BROADCOM_4325_SDGWB 0x0492 /* BCM94325SDGWB */ -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325_SDGWB) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4325) -#define SDIO_DEVICE_ID_BROADCOM_4325 0x0493 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4325) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4329) -#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */ -#if !defined(SDIO_DEVICE_ID_BROADCOM_4319) -#define SDIO_DEVICE_ID_BROADCOM_4319 0x4319 -#endif /* !defined(SDIO_DEVICE_ID_BROADCOM_4329) */ - -#include - -#include -#include - -extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); -extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd); - -int sdio_function_init(void); -void sdio_function_cleanup(void); - -/* module param defaults */ -static int clockoverride; - -module_param(clockoverride, int, 0644); -MODULE_PARM_DESC(clockoverride, "SDIO card clock override"); - -PBCMSDH_SDMMC_INSTANCE gInstance; - -/* Maximum number of bcmsdh_sdmmc devices supported by driver */ -#define BCMSDH_SDMMC_MAX_DEVICES 1 - -extern int bcmsdh_probe(struct device *dev); -extern int bcmsdh_remove(struct device *dev); -struct device sdmmc_dev; - -static int bcmsdh_sdmmc_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - int ret = 0; - static struct sdio_func sdio_func_0; - sd_trace(("bcmsdh_sdmmc: %s Enter\n", __func__)); - sd_trace(("sdio_bcmsdh: func->class=%x\n", func->class)); - sd_trace(("sdio_vendor: 0x%04x\n", func->vendor)); - sd_trace(("sdio_device: 0x%04x\n", func->device)); - sd_trace(("Function#: 0x%04x\n", func->num)); - - if (func->num == 1) { - sdio_func_0.num = 0; - sdio_func_0.card = func->card; - gInstance->func[0] = &sdio_func_0; - if (func->device == 0x4) { /* 4318 */ - gInstance->func[2] = NULL; - sd_trace(("NIC found, calling bcmsdh_probe...\n")); - ret = bcmsdh_probe(&sdmmc_dev); - } - } - - gInstance->func[func->num] = func; - - if (func->num == 2) { - wl_cfg80211_sdio_func(func); - sd_trace(("F2 found, calling bcmsdh_probe...\n")); - ret = bcmsdh_probe(&sdmmc_dev); - } - - return ret; -} - -static void bcmsdh_sdmmc_remove(struct sdio_func *func) -{ - sd_trace(("bcmsdh_sdmmc: %s Enter\n", __func__)); - sd_info(("sdio_bcmsdh: func->class=%x\n", func->class)); - sd_info(("sdio_vendor: 0x%04x\n", func->vendor)); - sd_info(("sdio_device: 0x%04x\n", func->device)); - sd_info(("Function#: 0x%04x\n", func->num)); - - if (func->num == 2) { - sd_trace(("F2 found, calling bcmsdh_remove...\n")); - bcmsdh_remove(&sdmmc_dev); - } -} - -/* devices we support, null terminated */ -static const struct sdio_device_id bcmsdh_sdmmc_ids[] = { - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT)}, - {SDIO_DEVICE - (SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325_SDGWB)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4325)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4319)}, - { /* end: all zeroes */ }, -}; - -MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids); - -static struct sdio_driver bcmsdh_sdmmc_driver = { - .probe = bcmsdh_sdmmc_probe, - .remove = bcmsdh_sdmmc_remove, - .name = "brcmfmac", - .id_table = bcmsdh_sdmmc_ids, -}; - -struct sdos_info { - sdioh_info_t *sd; - spinlock_t lock; -}; - -int sdioh_sdmmc_osinit(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - - sdos = kmalloc(sizeof(struct sdos_info), GFP_ATOMIC); - sd->sdos_info = (void *)sdos; - if (sdos == NULL) - return -ENOMEM; - - sdos->sd = sd; - spin_lock_init(&sdos->lock); - return 0; -} - -void sdioh_sdmmc_osfree(sdioh_info_t *sd) -{ - struct sdos_info *sdos; - ASSERT(sd && sd->sdos_info); - - sdos = (struct sdos_info *)sd->sdos_info; - kfree(sdos); -} - -/* Interrupt enable/disable */ -SDIOH_API_RC sdioh_interrupt_set(sdioh_info_t *sd, bool enable) -{ - unsigned long flags; - struct sdos_info *sdos; - - sd_trace(("%s: %s\n", __func__, enable ? "Enabling" : "Disabling")); - - sdos = (struct sdos_info *)sd->sdos_info; - ASSERT(sdos); - -#if !defined(OOB_INTR_ONLY) - if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { - sd_err(("%s: no handler registered, will not enable\n", - __func__)); - return SDIOH_API_RC_FAIL; - } -#endif /* !defined(OOB_INTR_ONLY) */ - - /* Ensure atomicity for enable/disable calls */ - spin_lock_irqsave(&sdos->lock, flags); - - sd->client_intr_enabled = enable; - if (enable) - sdioh_sdmmc_devintr_on(sd); - else - sdioh_sdmmc_devintr_off(sd); - - spin_unlock_irqrestore(&sdos->lock, flags); - - return SDIOH_API_RC_SUCCESS; -} - -/* - * module init -*/ -int sdio_function_init(void) -{ - int error = 0; - sd_trace(("bcmsdh_sdmmc: %s Enter\n", __func__)); - - gInstance = kzalloc(sizeof(BCMSDH_SDMMC_INSTANCE), GFP_KERNEL); - if (!gInstance) - return -ENOMEM; - - memset(&sdmmc_dev, 0, sizeof(sdmmc_dev)); - error = sdio_register_driver(&bcmsdh_sdmmc_driver); - - return error; -} - -/* - * module cleanup -*/ -extern int bcmsdh_remove(struct device *dev); -void sdio_function_cleanup(void) -{ - sd_trace(("%s Enter\n", __func__)); - - sdio_unregister_driver(&bcmsdh_sdmmc_driver); - - kfree(gInstance); -} diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h index a726b493ea8d..82bf04df16d0 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd.h @@ -18,51 +18,539 @@ * Common types * */ -#ifndef _dhd_h_ -#define _dhd_h_ +#ifndef _BRCMF_H_ +#define _BRCMF_H_ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* The kernel threading is sdio-specific */ +#define BRCMF_VERSION_STR "4.218.248.5" -#include +#define BRCMF_C_IOCTL_SMLEN 256 /* "small" ioctl buffer required */ +#define BRCMF_C_IOCTL_MEDLEN 1536 /* "med" ioctl buffer required */ +#define BRCMF_C_IOCTL_MAXLEN 8192 -/* Forward decls */ -struct dhd_bus; -struct dhd_prot; -struct dhd_info; +#define BRCMF_C_UP 2 +#define BRCMF_C_SET_PROMISC 10 +#define BRCMF_C_GET_RATE 12 +#define BRCMF_C_GET_INFRA 19 +#define BRCMF_C_SET_INFRA 20 +#define BRCMF_C_GET_AUTH 21 +#define BRCMF_C_SET_AUTH 22 +#define BRCMF_C_GET_BSSID 23 +#define BRCMF_C_GET_SSID 25 +#define BRCMF_C_SET_SSID 26 +#define BRCMF_C_GET_CHANNEL 29 +#define BRCMF_C_GET_SRL 31 +#define BRCMF_C_GET_LRL 33 +#define BRCMF_C_GET_RADIO 37 +#define BRCMF_C_SET_RADIO 38 +#define BRCMF_C_GET_PHYTYPE 39 +#define BRCMF_C_SET_KEY 45 +#define BRCMF_C_SET_PASSIVE_SCAN 49 +#define BRCMF_C_SCAN 50 +#define BRCMF_C_SCAN_RESULTS 51 +#define BRCMF_C_DISASSOC 52 +#define BRCMF_C_REASSOC 53 +#define BRCMF_C_SET_ROAM_TRIGGER 55 +#define BRCMF_C_SET_ROAM_DELTA 57 +#define BRCMF_C_GET_DTIMPRD 77 +#define BRCMF_C_SET_COUNTRY 84 +#define BRCMF_C_GET_PM 85 +#define BRCMF_C_SET_PM 86 +#define BRCMF_C_GET_AP 117 +#define BRCMF_C_SET_AP 118 +#define BRCMF_C_GET_RSSI 127 +#define BRCMF_C_GET_WSEC 133 +#define BRCMF_C_SET_WSEC 134 +#define BRCMF_C_GET_PHY_NOISE 135 +#define BRCMF_C_GET_BSS_INFO 136 +#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 +#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 +#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 +#define BRCMF_C_GET_VALID_CHANNELS 217 +#define BRCMF_C_GET_KEY_PRIMARY 235 +#define BRCMF_C_SET_KEY_PRIMARY 236 +#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258 +#define BRCMF_C_GET_VAR 262 +#define BRCMF_C_SET_VAR 263 -/* The level of bus communication with the dongle */ -enum dhd_bus_state { - DHD_BUS_DOWN, /* Not ready for frame transfers */ - DHD_BUS_LOAD, /* Download access only (CPU reset) */ - DHD_BUS_DATA /* Ready for frame transfers */ +/* phy types (returned by WLC_GET_PHYTPE) */ +#define WLC_PHY_TYPE_A 0 +#define WLC_PHY_TYPE_B 1 +#define WLC_PHY_TYPE_G 2 +#define WLC_PHY_TYPE_N 4 +#define WLC_PHY_TYPE_LP 5 +#define WLC_PHY_TYPE_SSN 6 +#define WLC_PHY_TYPE_HT 7 +#define WLC_PHY_TYPE_LCN 8 +#define WLC_PHY_TYPE_NULL 0xf + +#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter, u) +#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \ + offsetof(struct brcmf_pkt_filter_pattern, mask_and_pattern) + +#define BRCMF_EVENTING_MASK_LEN 16 + +#define TOE_TX_CSUM_OL 0x00000001 +#define TOE_RX_CSUM_OL 0x00000002 + +/* maximum channels returned by the get valid channels iovar */ +#define WL_NUMCHANNELS 64 + +#define BRCMF_BSS_INFO_VERSION 108 /* current ver of brcmf_bss_info struct */ + +/* size of brcmf_scan_params not including variable length array */ +#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 + +/* masks for channel and ssid count */ +#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff +#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 + +#define BRCMF_SCAN_ACTION_START 1 +#define BRCMF_SCAN_ACTION_CONTINUE 2 +#define WL_SCAN_ACTION_ABORT 3 + +#define BRCMF_ISCAN_REQ_VERSION 1 + +/* brcmf_iscan_results status values */ +#define BRCMF_SCAN_RESULTS_SUCCESS 0 +#define BRCMF_SCAN_RESULTS_PARTIAL 1 +#define BRCMF_SCAN_RESULTS_PENDING 2 +#define BRCMF_SCAN_RESULTS_ABORTED 3 +#define BRCMF_SCAN_RESULTS_NO_MEM 4 + +#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ +#define BRCMF_PRIMARY_KEY (1 << 1) /* primary (ie tx) key */ +#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ +#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ +#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */ + +/* For supporting multiple interfaces */ +#define BRCMF_MAX_IFS 16 +#define BRCMF_DEL_IF -0xe +#define BRCMF_BAD_IF -0xf + +#define DOT11_BSSTYPE_ANY 2 +#define DOT11_MAX_DEFAULT_KEYS 4 + +#define BRCMF_EVENT_MSG_LINK 0x01 +#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 +#define BRCMF_EVENT_MSG_GROUP 0x04 + +struct brcmf_event_msg { + u16 version; + u16 flags; + u32 event_type; + u32 status; + u32 reason; + u32 auth_type; + u32 datalen; + u8 addr[ETH_ALEN]; + char ifname[IFNAMSIZ]; +} __packed; + +struct brcm_ethhdr { + u16 subtype; + u16 length; + u8 version; + u8 oui[3]; + u16 usr_subtype; +} __packed; + +struct brcmf_event { + struct ethhdr eth; + struct brcm_ethhdr hdr; + struct brcmf_event_msg msg; +} __packed; + +struct dngl_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; /* packets dropped by dongle */ + unsigned long tx_dropped; /* packets dropped by dongle */ + unsigned long multicast; /* multicast packets received */ }; -/* Common structure for module and instance linkage */ -typedef struct dhd_pub { - /* Linkage ponters */ - struct dhd_bus *bus; /* Bus module handle */ - struct dhd_prot *prot; /* Protocol module handle */ - struct dhd_info *info; /* Info module handle */ +#define BRCMF_E_SET_SSID 0 +#define BRCMF_E_JOIN 1 +#define BRCMF_E_START 2 +#define BRCMF_E_AUTH 3 +#define BRCMF_E_AUTH_IND 4 +#define BRCMF_E_DEAUTH 5 +#define BRCMF_E_DEAUTH_IND 6 +#define BRCMF_E_ASSOC 7 +#define BRCMF_E_ASSOC_IND 8 +#define BRCMF_E_REASSOC 9 +#define BRCMF_E_REASSOC_IND 10 +#define BRCMF_E_DISASSOC 11 +#define BRCMF_E_DISASSOC_IND 12 +#define BRCMF_E_QUIET_START 13 +#define BRCMF_E_QUIET_END 14 +#define BRCMF_E_BEACON_RX 15 +#define BRCMF_E_LINK 16 +#define BRCMF_E_MIC_ERROR 17 +#define BRCMF_E_NDIS_LINK 18 +#define BRCMF_E_ROAM 19 +#define BRCMF_E_TXFAIL 20 +#define BRCMF_E_PMKID_CACHE 21 +#define BRCMF_E_RETROGRADE_TSF 22 +#define BRCMF_E_PRUNE 23 +#define BRCMF_E_AUTOAUTH 24 +#define BRCMF_E_EAPOL_MSG 25 +#define BRCMF_E_SCAN_COMPLETE 26 +#define BRCMF_E_ADDTS_IND 27 +#define BRCMF_E_DELTS_IND 28 +#define BRCMF_E_BCNSENT_IND 29 +#define BRCMF_E_BCNRX_MSG 30 +#define BRCMF_E_BCNLOST_MSG 31 +#define BRCMF_E_ROAM_PREP 32 +#define BRCMF_E_PFN_NET_FOUND 33 +#define BRCMF_E_PFN_NET_LOST 34 +#define BRCMF_E_RESET_COMPLETE 35 +#define BRCMF_E_JOIN_START 36 +#define BRCMF_E_ROAM_START 37 +#define BRCMF_E_ASSOC_START 38 +#define BRCMF_E_IBSS_ASSOC 39 +#define BRCMF_E_RADIO 40 +#define BRCMF_E_PSM_WATCHDOG 41 +#define BRCMF_E_PROBREQ_MSG 44 +#define BRCMF_E_SCAN_CONFIRM_IND 45 +#define BRCMF_E_PSK_SUP 46 +#define BRCMF_E_COUNTRY_CODE_CHANGED 47 +#define BRCMF_E_EXCEEDED_MEDIUM_TIME 48 +#define BRCMF_E_ICV_ERROR 49 +#define BRCMF_E_UNICAST_DECODE_ERROR 50 +#define BRCMF_E_MULTICAST_DECODE_ERROR 51 +#define BRCMF_E_TRACE 52 +#define BRCMF_E_IF 54 +#define BRCMF_E_RSSI 56 +#define BRCMF_E_PFN_SCAN_COMPLETE 57 +#define BRCMF_E_EXTLOG_MSG 58 +#define BRCMF_E_ACTION_FRAME 59 +#define BRCMF_E_ACTION_FRAME_COMPLETE 60 +#define BRCMF_E_PRE_ASSOC_IND 61 +#define BRCMF_E_PRE_REASSOC_IND 62 +#define BRCMF_E_CHANNEL_ADOPTED 63 +#define BRCMF_E_AP_STARTED 64 +#define BRCMF_E_DFS_AP_STOP 65 +#define BRCMF_E_DFS_AP_RESUME 66 +#define BRCMF_E_RESERVED1 67 +#define BRCMF_E_RESERVED2 68 +#define BRCMF_E_ESCAN_RESULT 69 +#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 +#define BRCMF_E_DCS_REQUEST 73 - /* Internal dhd items */ +#define BRCMF_E_FIFO_CREDIT_MAP 74 + +#define BRCMF_E_LAST 75 + +#define BRCMF_E_STATUS_SUCCESS 0 +#define BRCMF_E_STATUS_FAIL 1 +#define BRCMF_E_STATUS_TIMEOUT 2 +#define BRCMF_E_STATUS_NO_NETWORKS 3 +#define BRCMF_E_STATUS_ABORT 4 +#define BRCMF_E_STATUS_NO_ACK 5 +#define BRCMF_E_STATUS_UNSOLICITED 6 +#define BRCMF_E_STATUS_ATTEMPT 7 +#define BRCMF_E_STATUS_PARTIAL 8 +#define BRCMF_E_STATUS_NEWSCAN 9 +#define BRCMF_E_STATUS_NEWASSOC 10 +#define BRCMF_E_STATUS_11HQUIET 11 +#define BRCMF_E_STATUS_SUPPRESS 12 +#define BRCMF_E_STATUS_NOCHANS 13 +#define BRCMF_E_STATUS_CS_ABORT 15 +#define BRCMF_E_STATUS_ERROR 16 + +#define BRCMF_E_REASON_INITIAL_ASSOC 0 +#define BRCMF_E_REASON_LOW_RSSI 1 +#define BRCMF_E_REASON_DEAUTH 2 +#define BRCMF_E_REASON_DISASSOC 3 +#define BRCMF_E_REASON_BCNS_LOST 4 +#define BRCMF_E_REASON_MINTXRATE 9 +#define BRCMF_E_REASON_TXFAIL 10 + +#define BRCMF_E_REASON_FAST_ROAM_FAILED 5 +#define BRCMF_E_REASON_DIRECTED_ROAM 6 +#define BRCMF_E_REASON_TSPEC_REJECTED 7 +#define BRCMF_E_REASON_BETTER_AP 8 + +#define BRCMF_E_PRUNE_ENCR_MISMATCH 1 +#define BRCMF_E_PRUNE_BCAST_BSSID 2 +#define BRCMF_E_PRUNE_MAC_DENY 3 +#define BRCMF_E_PRUNE_MAC_NA 4 +#define BRCMF_E_PRUNE_REG_PASSV 5 +#define BRCMF_E_PRUNE_SPCT_MGMT 6 +#define BRCMF_E_PRUNE_RADAR 7 +#define BRCMF_E_RSN_MISMATCH 8 +#define BRCMF_E_PRUNE_NO_COMMON_RATES 9 +#define BRCMF_E_PRUNE_BASIC_RATES 10 +#define BRCMF_E_PRUNE_CIPHER_NA 12 +#define BRCMF_E_PRUNE_KNOWN_STA 13 +#define BRCMF_E_PRUNE_WDS_PEER 15 +#define BRCMF_E_PRUNE_QBSS_LOAD 16 +#define BRCMF_E_PRUNE_HOME_AP 17 + +#define BRCMF_E_SUP_OTHER 0 +#define BRCMF_E_SUP_DECRYPT_KEY_DATA 1 +#define BRCMF_E_SUP_BAD_UCAST_WEP128 2 +#define BRCMF_E_SUP_BAD_UCAST_WEP40 3 +#define BRCMF_E_SUP_UNSUP_KEY_LEN 4 +#define BRCMF_E_SUP_PW_KEY_CIPHER 5 +#define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6 +#define BRCMF_E_SUP_MSG3_IE_MISMATCH 7 +#define BRCMF_E_SUP_NO_INSTALL_FLAG 8 +#define BRCMF_E_SUP_MSG3_NO_GTK 9 +#define BRCMF_E_SUP_GRP_KEY_CIPHER 10 +#define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11 +#define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12 +#define BRCMF_E_SUP_SEND_FAIL 13 +#define BRCMF_E_SUP_DEAUTH 14 + +#define BRCMF_E_IF_ADD 1 +#define BRCMF_E_IF_DEL 2 +#define BRCMF_E_IF_CHANGE 3 + +#define BRCMF_E_IF_ROLE_STA 0 +#define BRCMF_E_IF_ROLE_AP 1 +#define BRCMF_E_IF_ROLE_WDS 2 + +#define BRCMF_E_LINK_BCN_LOSS 1 +#define BRCMF_E_LINK_DISASSOC 2 +#define BRCMF_E_LINK_ASSOC_REC 3 +#define BRCMF_E_LINK_BSSCFG_DIS 4 + +/* The level of bus communication with the dongle */ +enum brcmf_bus_state { + BRCMF_BUS_DOWN, /* Not ready for frame transfers */ + BRCMF_BUS_LOAD, /* Download access only (CPU reset) */ + BRCMF_BUS_DATA /* Ready for frame transfers */ +}; + +/* Pattern matching filter. Specifies an offset within received packets to + * start matching, the pattern to match, the size of the pattern, and a bitmask + * that indicates which bits within the pattern should be matched. + */ +struct brcmf_pkt_filter_pattern { + u32 offset; /* Offset within received packet to start pattern matching. + * Offset '0' is the first byte of the ethernet header. + */ + u32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */ + u8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts + * at offset 0. Pattern immediately follows mask. + */ +}; + +/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */ +struct brcmf_pkt_filter { + u32 id; /* Unique filter id, specified by app. */ + u32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */ + u32 negate_match; /* Negate the result of filter matches */ + union { /* Filter definitions */ + struct brcmf_pkt_filter_pattern pattern; /* Filter pattern */ + } u; +}; + +/* IOVAR "pkt_filter_enable" parameter. */ +struct brcmf_pkt_filter_enable { + u32 id; /* Unique filter id */ + u32 enable; /* Enable/disable bool */ +}; + +/* BSS info structure + * Applications MUST CHECK ie_offset field and length field to access IEs and + * next bss_info structure in a vector (in struct brcmf_scan_results) + */ +struct brcmf_bss_info { + u32 version; /* version field */ + u32 length; /* byte length of data in this record, + * starting at version and including IEs + */ + u8 BSSID[ETH_ALEN]; + u16 beacon_period; /* units are Kusec */ + u16 capability; /* Capability information */ + u8 SSID_len; + u8 SSID[32]; + struct { + uint count; /* # rates in this set */ + u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ + } rateset; /* supported rates */ + chanspec_t chanspec; /* chanspec for bss */ + u16 atim_window; /* units are Kusec */ + u8 dtim_period; /* DTIM period */ + s16 RSSI; /* receive signal strength (in dBm) */ + s8 phy_noise; /* noise (in dBm) */ + + u8 n_cap; /* BSS is 802.11N Capable */ + u32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */ + u8 ctl_ch; /* 802.11N BSS control channel number */ + u32 reserved32[1]; /* Reserved for expansion of BSS properties */ + u8 flags; /* flags */ + u8 reserved[3]; /* Reserved for expansion of BSS properties */ + u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ + + u16 ie_offset; /* offset at which IEs start, from beginning */ + u32 ie_length; /* byte length of Information Elements */ + s16 SNR; /* average SNR of during frame reception */ + /* Add new fields here */ + /* variable length Information Elements */ +}; + +struct brcmf_ssid { + u32 SSID_len; + unsigned char SSID[32]; +}; + +struct brcmf_scan_params { + struct brcmf_ssid ssid; /* default: {0, ""} */ + u8 bssid[ETH_ALEN]; /* default: bcast */ + s8 bss_type; /* default: any, + * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT + */ + u8 scan_type; /* flags, 0 use default */ + s32 nprobes; /* -1 use default, number of probes per channel */ + s32 active_time; /* -1 use default, dwell time per channel for + * active scanning + */ + s32 passive_time; /* -1 use default, dwell time per channel + * for passive scanning + */ + s32 home_time; /* -1 use default, dwell time for the home channel + * between channel scans + */ + s32 channel_num; /* count of channels and ssids that follow + * + * low half is count of channels in + * channel_list, 0 means default (use all + * available channels) + * + * high half is entries in struct brcmf_ssid + * array that follows channel_list, aligned for + * s32 (4 bytes) meaning an odd channel count + * implies a 2-byte pad between end of + * channel_list and first ssid + * + * if ssid count is zero, single ssid in the + * fixed parameter portion is assumed, otherwise + * ssid in the fixed portion is ignored + */ + u16 channel_list[1]; /* list of chanspecs */ +}; + +/* incremental scan struct */ +struct brcmf_iscan_params { + u32 version; + u16 action; + u16 scan_duration; + struct brcmf_scan_params params; +}; + +/* 3 fields + size of brcmf_scan_params, not including variable length array */ +#define BRCMF_ISCAN_PARAMS_FIXED_SIZE \ + (offsetof(struct brcmf_iscan_params, params) + \ + sizeof(struct brcmf_ssid)) + +struct brcmf_scan_results { + u32 buflen; + u32 version; + u32 count; + struct brcmf_bss_info bss_info[1]; +}; + +/* used for association with a specific BSSID and chanspec list */ +struct brcmf_assoc_params { + u8 bssid[ETH_ALEN]; /* 00:00:00:00:00:00: broadcast scan */ + s32 chanspec_num; /* 0: all available channels, + * otherwise count of chanspecs in chanspec_list + */ + chanspec_t chanspec_list[1]; /* list of chanspecs */ +}; +#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ + (sizeof(struct brcmf_assoc_params) - sizeof(chanspec_t)) + +/* used for join with or without a specific bssid and channel list */ +struct brcmf_join_params { + struct brcmf_ssid ssid; + struct brcmf_assoc_params params; +}; + +/* size of brcmf_scan_results not including variable length array */ +#define BRCMF_SCAN_RESULTS_FIXED_SIZE \ + (sizeof(struct brcmf_scan_results) - sizeof(struct brcmf_bss_info)) + +/* incremental scan results struct */ +struct brcmf_iscan_results { + u32 status; + struct brcmf_scan_results results; +}; + +/* size of brcmf_iscan_results not including variable length array */ +#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \ + (BRCMF_SCAN_RESULTS_FIXED_SIZE + \ + offsetof(struct brcmf_iscan_results, results)) + +struct brcmf_wsec_key { + u32 index; /* key index */ + u32 len; /* key length */ + u8 data[WLAN_MAX_KEY_LEN]; /* key data */ + u32 pad_1[18]; + u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ + u32 flags; /* misc flags */ + u32 pad_2[2]; + int pad_3; + int iv_initialized; /* has IV been initialized already? */ + int pad_4; + /* Rx IV */ + struct { + u32 hi; /* upper 32 bits of IV */ + u16 lo; /* lower 16 bits of IV */ + } rxiv; + u32 pad_5[2]; + u8 ea[ETH_ALEN]; /* per station */ +}; + +/* Used to get specific STA parameters */ +struct brcmf_scb_val { + u32 val; + u8 ea[ETH_ALEN]; +}; + +/* channel encoding */ +struct brcmf_channel_info { + int hw_channel; + int target_channel; + int scan_channel; +}; + +/* Linux network driver ioctl encoding */ +struct brcmf_ioctl { + uint cmd; /* common ioctl definition */ + void *buf; /* pointer to user buffer */ + uint len; /* length of user buffer */ + u8 set; /* get or set request (optional) */ + uint used; /* bytes read or written (optional) */ + uint needed; /* bytes needed (optional) */ +}; + +/* Forward decls for struct brcmf_pub (see below) */ +struct brcmf_bus; /* device bus info */ +struct brcmf_proto; /* device communication protocol info */ +struct brcmf_info; /* device driver info */ + +/* Common structure for module and instance linkage */ +struct brcmf_pub { + /* Linkage ponters */ + struct brcmf_bus *bus; + struct brcmf_proto *prot; + struct brcmf_info *info; + + /* Internal brcmf items */ bool up; /* Driver up/down (to OS) */ bool txoff; /* Transmit flow-controlled */ bool dongle_reset; /* true = DEVRESET put dongle into reset */ - enum dhd_bus_state busstate; - uint hdrlen; /* Total DHD header length (proto + bus) */ + enum brcmf_bus_state busstate; + uint hdrlen; /* Total BRCMF header length (proto + bus) */ uint maxctl; /* Max size rxctl request from proto to bus */ uint rxsz; /* Rx buffer size bus module should use */ u8 wme_dp; /* wme discard priority */ @@ -71,7 +559,7 @@ typedef struct dhd_pub { bool iswl; /* Dongle-resident driver is wl */ unsigned long drv_version; /* Version of dongle-resident driver */ u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ - dngl_stats_t dstats; /* Stats for dongle-based data */ + struct dngl_stats dstats; /* Stats for dongle-based data */ /* Additional stats for the bus level */ unsigned long tx_packets; /* Data packets sent to dongle */ @@ -88,7 +576,7 @@ typedef struct dhd_pub { unsigned long rx_dropped; /* Packets dropped locally (no memory) */ unsigned long rx_flushed; /* Packets flushed due to unscheduled sendup thread */ - unsigned long wd_dpc_sched; /* Number of times dhd dpc scheduled by + unsigned long wd_dpc_sched; /* Number of times dpc scheduled by watchdog timer */ unsigned long rx_readahead_cnt; /* Number of packets where header read-ahead @@ -108,40 +596,51 @@ typedef struct dhd_pub { int suspend_disable_flag; /* "1" to disable all extra powersaving during suspend */ int in_suspend; /* flag set to 1 when early suspend called */ -#ifdef PNO_SUPPORT - int pno_enable; /* pno status : "1" is pno enable */ -#endif /* PNO_SUPPORT */ int dtim_skip; /* dtim skip , default 0 means wake each dtim */ /* Pkt filter defination */ char *pktfilter[100]; int pktfilter_count; - u8 country_code[WLC_CNTRY_BUF_SZ]; - char eventmask[WL_EVENTING_MASK_LEN]; + u8 country_code[BRCM_CNTRY_BUF_SZ]; + char eventmask[BRCMF_EVENTING_MASK_LEN]; -} dhd_pub_t; +}; + +struct brcmf_if_event { + u8 ifidx; + u8 action; + u8 flags; + u8 bssidx; +}; + +struct brcmf_timeout { + u32 limit; /* Expiration time (usec) */ + u32 increment; /* Current expiration increment (usec) */ + u32 elapsed; /* Current elapsed time (usec) */ + u32 tick; /* O/S tick time (usec) */ +}; + +struct bcmevent_name { + uint event; + const char *name; +}; #if defined(CONFIG_PM_SLEEP) -extern atomic_t dhd_mmc_suspend; -#define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); -#define _DHD_PM_RESUME_WAIT(a, b) do { \ +extern atomic_t brcmf_mmc_suspend; +#define BRCMF_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); +#define _BRCMF_PM_RESUME_WAIT(a, b) do { \ int retry = 0; \ - while (atomic_read(&dhd_mmc_suspend) && retry++ != b) { \ + while (atomic_read(&brcmf_mmc_suspend) && retry++ != b) { \ wait_event_timeout(a, false, HZ/100); \ } \ } while (0) -#define DHD_PM_RESUME_WAIT(a) _DHD_PM_RESUME_WAIT(a, 30) -#define DHD_PM_RESUME_WAIT_FOREVER(a) _DHD_PM_RESUME_WAIT(a, ~0) -#define DHD_PM_RESUME_RETURN_ERROR(a) \ - do { if (atomic_read(&dhd_mmc_suspend)) return a; } while (0) -#define DHD_PM_RESUME_RETURN do { \ - if (atomic_read(&dhd_mmc_suspend)) \ - return; \ - } while (0) +#define BRCMF_PM_RESUME_WAIT(a) _BRCMF_PM_RESUME_WAIT(a, 30) +#define BRCMF_PM_RESUME_RETURN_ERROR(a) \ + do { if (atomic_read(&brcmf_mmc_suspend)) return a; } while (0) -#define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); -#define SPINWAIT_SLEEP(a, exp, us) do { \ +#define BRCMF_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); +#define BRCMF_SPINWAIT_SLEEP(a, exp, us) do { \ uint countdown = (us) + 9999; \ while ((exp) && (countdown >= 10000)) { \ wait_event_timeout(a, false, HZ/100); \ @@ -151,14 +650,12 @@ extern atomic_t dhd_mmc_suspend; #else -#define DHD_PM_RESUME_WAIT_INIT(a) -#define DHD_PM_RESUME_WAIT(a) -#define DHD_PM_RESUME_WAIT_FOREVER(a) -#define DHD_PM_RESUME_RETURN_ERROR(a) -#define DHD_PM_RESUME_RETURN +#define BRCMF_PM_RESUME_WAIT_INIT(a) +#define BRCMF_PM_RESUME_WAIT(a) +#define BRCMF_PM_RESUME_RETURN_ERROR(a) -#define DHD_SPINWAIT_SLEEP_INIT(a) -#define SPINWAIT_SLEEP(a, exp, us) do { \ +#define BRCMF_SPINWAIT_SLEEP_INIT(a) +#define BRCMF_SPINWAIT_SLEEP(a, exp, us) do { \ uint countdown = (us) + 9; \ while ((exp) && (countdown >= 10)) { \ udelay(10); \ @@ -167,29 +664,82 @@ extern atomic_t dhd_mmc_suspend; } while (0) #endif /* defined(CONFIG_PM_SLEEP) */ -#define DHD_IF_VIF 0x01 /* Virtual IF (Hidden from user) */ -static inline void MUTEX_LOCK_INIT(dhd_pub_t *dhdp) +/* + * Insmod parameters for debug/test + */ + +/* Use interrupts */ +extern uint brcmf_intr; + +/* Use polling */ +extern uint brcmf_poll; + +/* ARP offload agent mode */ +extern uint brcmf_arp_mode; + +/* ARP offload enable */ +extern uint brcmf_arp_enable; + +/* Pkt filte enable control */ +extern uint brcmf_pkt_filter_enable; + +/* Pkt filter init setup */ +extern uint brcmf_pkt_filter_init; + +/* Pkt filter mode control */ +extern uint brcmf_master_mode; + +/* Roaming mode control */ +extern uint brcmf_roam; + +/* Roaming mode control */ +extern uint brcmf_radio_up; + +/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */ +extern int brcmf_idletime; +#define BRCMF_IDLETIME_TICKS 1 + +/* SDIO Drive Strength */ +extern uint brcmf_sdiod_drive_strength; + +/* Override to force tx queueing all the time */ +extern uint brcmf_force_tx_queueing; + +#ifdef SDTEST +/* Echo packet generator (SDIO), pkts/s */ +extern uint brcmf_pktgen; + +/* Echo packet len (0 => sawtooth, max 1800) */ +extern uint brcmf_pktgen_len; +#define BRCMF_MAX_PKTGEN_LEN 1800 +#endif + +extern const struct bcmevent_name bcmevent_names[]; +extern const int bcmevent_names_size; + + +static inline void MUTEX_LOCK_INIT(struct brcmf_pub *drvr) { } -static inline void MUTEX_LOCK(dhd_pub_t *dhdp) +static inline void MUTEX_LOCK(struct brcmf_pub *drvr) { } -static inline void MUTEX_UNLOCK(dhd_pub_t *dhdp) +static inline void MUTEX_UNLOCK(struct brcmf_pub *drvr) { } -static inline void MUTEX_LOCK_SOFTAP_SET_INIT(dhd_pub_t *dhdp) +static inline void MUTEX_LOCK_SOFTAP_SET_INIT(struct brcmf_pub *drvr) { } -static inline void MUTEX_LOCK_SOFTAP_SET(dhd_pub_t *dhdp) +static inline void MUTEX_LOCK_SOFTAP_SET(struct brcmf_pub *drvr) { } -static inline void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t *dhdp) +static inline void MUTEX_UNLOCK_SOFTAP_SET(struct brcmf_pub *drvr) { } @@ -205,210 +755,150 @@ static inline void MUTEX_UNLOCK_WL_SCAN_SET(void) { } -typedef struct dhd_if_event { - u8 ifidx; - u8 action; - u8 flags; - u8 bssidx; -} dhd_if_event_t; - -/* - * Exported from dhd OS modules (dhd_linux/dhd_ndis) - */ - /* Indication from bus module regarding presence/insertion of dongle. - * Return dhd_pub_t pointer, used as handle to OS module in later calls. + * Return struct brcmf_pub pointer, used as handle to OS module in later calls. * Returned structure should have bus and prot pointers filled in. * bus_hdrlen specifies required headroom for bus module header. */ -extern dhd_pub_t *dhd_attach(struct dhd_bus *bus, - uint bus_hdrlen); -extern int dhd_net_attach(dhd_pub_t *dhdp, int idx); +extern struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, + uint bus_hdrlen); +extern int brcmf_net_attach(struct brcmf_pub *drvr, int idx); +extern int brcmf_netdev_wait_pend8021x(struct net_device *dev); /* Indication from bus module regarding removal/absence of dongle */ -extern void dhd_detach(dhd_pub_t *dhdp); +extern void brcmf_detach(struct brcmf_pub *drvr); /* Indication from bus module to change flow-control state */ -extern void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool on); +extern void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool on); -extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, +extern bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q, struct sk_buff *pkt, int prec); /* Receive frame for delivery to OS. Callee disposes of rxp. */ -extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, +extern void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *rxp, int numpkt); /* Return pointer to interface name */ -extern char *dhd_ifname(dhd_pub_t *dhdp, int idx); - -/* Request scheduling of the bus dpc */ -extern void dhd_sched_dpc(dhd_pub_t *dhdp); +extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); /* Notify tx completion */ -extern void dhd_txcomplete(dhd_pub_t *dhdp, struct sk_buff *txp, bool success); +extern void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, + bool success); /* Query ioctl */ -extern int dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, - uint len); +extern int brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx, + uint cmd, void *buf, uint len); /* OS independent layer functions */ -extern int dhd_os_proto_block(dhd_pub_t *pub); -extern int dhd_os_proto_unblock(dhd_pub_t *pub); -extern int dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition, +extern int brcmf_os_proto_block(struct brcmf_pub *drvr); +extern int brcmf_os_proto_unblock(struct brcmf_pub *drvr); +extern int brcmf_os_ioctl_resp_wait(struct brcmf_pub *drvr, uint *condition, bool *pending); -extern int dhd_os_ioctl_resp_wake(dhd_pub_t *pub); -extern unsigned int dhd_os_get_ioctl_resp_timeout(void); -extern void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec); -extern void *dhd_os_open_image(char *filename); -extern int dhd_os_get_image_block(char *buf, int len, void *image); -extern void dhd_os_close_image(void *image); -extern void dhd_os_wd_timer(void *bus, uint wdtick); -extern void dhd_os_sdlock(dhd_pub_t *pub); -extern void dhd_os_sdunlock(dhd_pub_t *pub); -extern void dhd_os_sdlock_txq(dhd_pub_t *pub); -extern void dhd_os_sdunlock_txq(dhd_pub_t *pub); -extern void dhd_os_sdlock_rxq(dhd_pub_t *pub); -extern void dhd_os_sdunlock_rxq(dhd_pub_t *pub); -extern void dhd_os_sdlock_sndup_rxq(dhd_pub_t *pub); -extern void dhd_customer_gpio_wlan_ctrl(int onoff); -extern int dhd_custom_get_mac_address(unsigned char *buf); -extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t *pub); -extern void dhd_os_sdlock_eventq(dhd_pub_t *pub); -extern void dhd_os_sdunlock_eventq(dhd_pub_t *pub); -#ifdef DHD_DEBUG -extern int write_to_file(dhd_pub_t *dhd, u8 *buf, int size); -#endif /* DHD_DEBUG */ -#if defined(OOB_INTR_ONLY) -extern int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr); -#endif /* defined(OOB_INTR_ONLY) */ -extern void dhd_os_sdtxlock(dhd_pub_t *pub); -extern void dhd_os_sdtxunlock(dhd_pub_t *pub); +extern int brcmf_os_ioctl_resp_wake(struct brcmf_pub *drvr); +extern unsigned int brcmf_os_get_ioctl_resp_timeout(void); +extern void brcmf_os_set_ioctl_resp_timeout(unsigned int timeout_msec); +#ifdef BCMDBG +extern int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size); +#endif /* BCMDBG */ -int setScheduler(struct task_struct *p, int policy, struct sched_param *param); +extern void brcmf_timeout_start(struct brcmf_timeout *tmo, uint usec); +extern int brcmf_timeout_expired(struct brcmf_timeout *tmo); -typedef struct { - u32 limit; /* Expiration time (usec) */ - u32 increment; /* Current expiration increment (usec) */ - u32 elapsed; /* Current elapsed time (usec) */ - u32 tick; /* O/S tick time (usec) */ -} dhd_timeout_t; +extern int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name); +extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx, + void *pktdata, struct brcmf_event_msg *, + void **data_ptr); -extern void dhd_timeout_start(dhd_timeout_t *tmo, uint usec); -extern int dhd_timeout_expired(dhd_timeout_t *tmo); +extern void brcmf_c_init(void); -extern int dhd_ifname2idx(struct dhd_info *dhd, char *name); -extern u8 *dhd_bssidx2bssid(dhd_pub_t *dhd, int idx); -extern int wl_host_event(struct dhd_info *dhd, int *idx, void *pktdata, - wl_event_msg_t *, void **data_ptr); - -extern void dhd_common_init(void); - -extern int dhd_add_if(struct dhd_info *dhd, int ifidx, void *handle, +extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, void *handle, char *name, u8 *mac_addr, u32 flags, u8 bssidx); -extern void dhd_del_if(struct dhd_info *dhd, int ifidx); - -extern void dhd_vif_add(struct dhd_info *dhd, int ifidx, char *name); -extern void dhd_vif_del(struct dhd_info *dhd, int ifidx); - -extern void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx); -extern void dhd_vif_sendup(struct dhd_info *dhd, int ifidx, unsigned char * cp, - int len); +extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx); /* Send packet to dongle via data channel */ -extern int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pkt); +extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\ + struct sk_buff *pkt); -/* Send event to host */ -extern void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, - void *data); -extern int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag); -extern uint dhd_bus_status(dhd_pub_t *dhdp); -extern int dhd_bus_start(dhd_pub_t *dhdp); +extern int brcmf_bus_devreset(struct brcmf_pub *drvr, u8 flag); +extern int brcmf_bus_start(struct brcmf_pub *drvr); -enum cust_gpio_modes { - WLAN_RESET_ON, - WLAN_RESET_OFF, - WLAN_POWER_ON, - WLAN_POWER_OFF +extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg); +extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, + int enable, int master_mode); + +/* Linux network driver ioctl encoding */ +struct brcmf_c_ioctl { + uint cmd; /* common ioctl definition */ + void *buf; /* pointer to user buffer */ + uint len; /* length of user buffer */ + bool set; /* get or set request (optional) */ + uint used; /* bytes read or written (optional) */ + uint needed; /* bytes needed (optional) */ + uint driver; /* to identify target driver */ }; -/* - * Insmod parameters for debug/test - */ -/* Watchdog timer interval */ -extern uint dhd_watchdog_ms; +/* per-driver magic numbers */ +#define BRCMF_IOCTL_MAGIC 0x00444944 -#if defined(DHD_DEBUG) -/* Console output poll interval */ -extern uint dhd_console_ms; -#endif /* defined(DHD_DEBUG) */ +/* bump this number if you change the ioctl interface */ +#define BRCMF_IOCTL_VERSION 1 +#define BRCMF_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ -/* Use interrupts */ -extern uint dhd_intr; +/* common ioctl definitions */ +#define BRCMF_GET_MAGIC 0 +#define BRCMF_GET_VERSION 1 +#define BRCMF_GET_VAR 2 +#define BRCMF_SET_VAR 3 -/* Use polling */ -extern uint dhd_poll; - -/* ARP offload agent mode */ -extern uint dhd_arp_mode; - -/* ARP offload enable */ -extern uint dhd_arp_enable; - -/* Pkt filte enable control */ -extern uint dhd_pkt_filter_enable; - -/* Pkt filter init setup */ -extern uint dhd_pkt_filter_init; - -/* Pkt filter mode control */ -extern uint dhd_master_mode; - -/* Roaming mode control */ -extern uint dhd_roam; - -/* Roaming mode control */ -extern uint dhd_radio_up; - -/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */ -extern int dhd_idletime; -#define DHD_IDLETIME_TICKS 1 - -/* SDIO Drive Strength */ -extern uint dhd_sdiod_drive_strength; - -/* Override to force tx queueing all the time */ -extern uint dhd_force_tx_queueing; +/* message levels */ +#define BRCMF_ERROR_VAL 0x0001 +#define BRCMF_TRACE_VAL 0x0002 +#define BRCMF_INFO_VAL 0x0004 +#define BRCMF_DATA_VAL 0x0008 +#define BRCMF_CTL_VAL 0x0010 +#define BRCMF_TIMER_VAL 0x0020 +#define BRCMF_HDRS_VAL 0x0040 +#define BRCMF_BYTES_VAL 0x0080 +#define BRCMF_INTR_VAL 0x0100 +#define BRCMF_GLOM_VAL 0x0400 +#define BRCMF_EVENT_VAL 0x0800 +#define BRCMF_BTA_VAL 0x1000 +#define BRCMF_ISCAN_VAL 0x2000 #ifdef SDTEST -/* Echo packet generator (SDIO), pkts/s */ -extern uint dhd_pktgen; +/* For pktgen iovar */ +struct brcmf_pktgen { + uint version; /* To allow structure change tracking */ + uint freq; /* Max ticks between tx/rx attempts */ + uint count; /* Test packets to send/rcv each attempt */ + uint print; /* Print counts every attempts */ + uint total; /* Total packets (or bursts) */ + uint minlen; /* Minimum length of packets to send */ + uint maxlen; /* Maximum length of packets to send */ + uint numsent; /* Count of test packets sent */ + uint numrcvd; /* Count of test packets received */ + uint numfail; /* Count of test send failures */ + uint mode; /* Test mode (type of test packets) */ + uint stop; /* Stop after this many tx failures */ +}; -/* Echo packet len (0 => sawtooth, max 1800) */ -extern uint dhd_pktgen_len; -#define MAX_PKTGEN_LEN 1800 -#endif +/* Version in case structure changes */ +#define BRCMF_PKTGEN_VERSION 2 -/* optionally set by a module_param_string() */ -#define MOD_PARAM_PATHLEN 2048 -extern char fw_path[MOD_PARAM_PATHLEN]; -extern char nv_path[MOD_PARAM_PATHLEN]; +/* Type of test packets to use */ +#define BRCMF_PKTGEN_ECHO 1 /* Send echo requests */ +#define BRCMF_PKTGEN_SEND 2 /* Send discard packets */ +#define BRCMF_PKTGEN_RXBURST 3 /* Request dongle send N packets */ +#define BRCMF_PKTGEN_RECV 4 /* Continuous rx from continuous + tx dongle */ +#endif /* SDTEST */ -/* For supporting multiple interfaces */ -#define DHD_MAX_IFS 16 -#define DHD_DEL_IF -0xe -#define DHD_BAD_IF -0xf +/* Enter idle immediately (no timeout) */ +#define BRCMF_IDLE_IMMEDIATE (-1) -extern void dhd_wait_for_event(dhd_pub_t *dhd, bool * lockvar); -extern void dhd_wait_event_wakeup(dhd_pub_t *dhd); +/* Values for idleclock iovar: other values are the sd_divisor to use + when idle */ +#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change + when idle */ -extern u32 g_assert_type; - -#ifdef BCMDBG -#define ASSERT(exp) \ - do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) -extern void osl_assert(char *exp, char *file, int line); -#else -#define ASSERT(exp) do {} while (0) -#endif /* defined(BCMDBG) */ - -#endif /* _dhd_h_ */ +#endif /* _BRCMF_H_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h index 065f1aeb6ca9..653cf0daa0eb 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h @@ -14,69 +14,65 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _dhd_bus_h_ -#define _dhd_bus_h_ +#ifndef _BRCMF_BUS_H_ +#define _BRCMF_BUS_H_ + +/* Packet alignment for most efficient SDIO (can change based on platform) */ +#ifndef BRCMF_SDALIGN +#define BRCMF_SDALIGN 32 +#endif +#if !ISPOWEROF2(BRCMF_SDALIGN) +#error BRCMF_SDALIGN is not a power of 2! +#endif /* - * Exported from dhd bus module (dhd_usb, dhd_sdio) + * Exported from brcmf bus module (brcmf_usb, brcmf_sdio) */ -/* Indicate (dis)interest in finding dongles. */ -extern int dhd_bus_register(void); -extern void dhd_bus_unregister(void); +/* dongle ram module parameter */ +extern int brcmf_dongle_memsize; -/* Download firmware image and nvram image */ -extern bool dhd_bus_download_firmware(struct dhd_bus *bus, - char *fw_path, char *nv_path); +/* Tx/Rx bounds module parameters */ +extern uint brcmf_txbound; +extern uint brcmf_rxbound; + +/* Watchdog timer interval */ +extern uint brcmf_watchdog_ms; + +/* Indicate (dis)interest in finding dongles. */ +extern int brcmf_bus_register(void); +extern void brcmf_bus_unregister(void); /* Stop bus module: clear pending frames, disable data flow */ -extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex); +extern void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex); /* Initialize bus module: prepare for communication w/dongle */ -extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex); +extern int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr, bool enforce_mutex); /* Send a data frame to the dongle. Callee disposes of txp. */ -extern int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *txp); +extern int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *txp); /* Send/receive a control message to/from the dongle. * Expects caller to enforce a single outstanding transaction. */ -extern int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen); -extern int dhd_bus_rxctl(struct dhd_bus *bus, unsigned char *msg, uint msglen); +extern int +brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen); -/* Watchdog timer function */ -extern bool dhd_bus_watchdog(dhd_pub_t *dhd); - -#ifdef DHD_DEBUG -/* Device console input function */ -extern int dhd_bus_console_in(dhd_pub_t *dhd, unsigned char *msg, uint msglen); -#endif /* DHD_DEBUG */ - -/* Deferred processing for the bus, return true requests reschedule */ -extern bool dhd_bus_dpc(struct dhd_bus *bus); -extern void dhd_bus_isr(bool *InterruptRecognized, - bool *QueueMiniportHandleInterrupt, void *arg); +extern int +brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen); /* Check for and handle local prot-specific iovar commands */ -extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, +extern int brcmf_sdbrcm_bus_iovar_op(struct brcmf_pub *drvr, const char *name, void *params, int plen, void *arg, int len, bool set); /* Add bus dump output to a buffer */ -extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf); +extern void brcmf_sdbrcm_bus_dump(struct brcmf_pub *drvr, + struct brcmu_strbuf *strbuf); /* Clear any bus counters */ -extern void dhd_bus_clearcounts(dhd_pub_t *dhdp); +extern void brcmf_bus_clearcounts(struct brcmf_pub *drvr); -/* return the dongle chipid */ -extern uint dhd_bus_chip(struct dhd_bus *bus); +extern void brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick); -/* Set user-specified nvram parameters. */ -extern void dhd_bus_set_nvram_params(struct dhd_bus *bus, - const char *nvram_params); - -extern void *dhd_bus_pub(struct dhd_bus *bus); -extern void *dhd_bus_txq(struct dhd_bus *bus); -extern uint dhd_bus_hdrlen(struct dhd_bus *bus); - -#endif /* _dhd_bus_h_ */ +#endif /* _BRCMF_BUS_H_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index ba5a5cb7eede..345acabe935e 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -16,33 +16,71 @@ #include #include -#include +#include +#include -#include -#include +#include +#include -#include -#include -#include -#include -#include -#ifdef CUSTOMER_HW2 -int wifi_get_mac_addr(unsigned char *buf); -#endif +#include "dhd.h" +#include "dhd_proto.h" +#include "dhd_bus.h" +#include "dhd_dbg.h" -extern int dhd_preinit_ioctls(dhd_pub_t *dhd); +struct brcmf_proto_cdc_ioctl { + u32 cmd; /* ioctl command value */ + u32 len; /* lower 16: output buflen; + * upper 16: input buflen (excludes header) */ + u32 flags; /* flag defns given below */ + u32 status; /* status code returned from the device */ +}; + +/* Max valid buffer size that can be sent to the dongle */ +#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) + +/* CDC flag definitions */ +#define CDCF_IOC_ERROR 0x01 /* 1=ioctl cmd failed */ +#define CDCF_IOC_SET 0x02 /* 0=get, 1=set cmd */ +#define CDCF_IOC_IF_MASK 0xF000 /* I/F index */ +#define CDCF_IOC_IF_SHIFT 12 +#define CDCF_IOC_ID_MASK 0xFFFF0000 /* id an ioctl pairing */ +#define CDCF_IOC_ID_SHIFT 16 /* ID Mask shift bits */ +#define CDC_IOC_ID(flags) \ + (((flags) & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT) +#define CDC_SET_IF_IDX(hdr, idx) \ + ((hdr)->flags = (((hdr)->flags & ~CDCF_IOC_IF_MASK) | \ + ((idx) << CDCF_IOC_IF_SHIFT))) + +/* + * BDC header - Broadcom specific extension of CDC. + * Used on data packets to convey priority across USB. + */ +#define BDC_HEADER_LEN 4 +#define BDC_PROTO_VER 1 /* Protocol version */ +#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ +#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ +#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */ +#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ +#define BDC_PRIORITY_MASK 0x7 +#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */ +#define BDC_FLAG2_IF_SHIFT 0 + +#define BDC_GET_IF_IDX(hdr) \ + ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) +#define BDC_SET_IF_IDX(hdr, idx) \ + ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \ + ((idx) << BDC_FLAG2_IF_SHIFT))) + +struct brcmf_proto_bdc_header { + u8 flags; + u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */ + u8 flags2; + u8 rssi; +}; -/* Packet alignment for most efficient SDIO (can change based on platform) */ -#ifndef DHD_SDALIGN -#define DHD_SDALIGN 32 -#endif -#if !ISPOWEROF2(DHD_SDALIGN) -#error DHD_SDALIGN is not a power of 2! -#endif #define RETRIES 2 /* # of retries to retrieve matching ioctl response */ -#define BUS_HEADER_LEN (16+DHD_SDALIGN) /* Must be atleast SDPCM_RESERVE - * defined in dhd_sdio.c +#define BUS_HEADER_LEN (16+BRCMF_SDALIGN) /* Must be atleast SDPCM_RESERVE * (amount of header tha might be added) * plus any space that might be needed * for alignment padding. @@ -51,21 +89,22 @@ extern int dhd_preinit_ioctls(dhd_pub_t *dhd); * round off at the end of buffer */ -typedef struct dhd_prot { +struct brcmf_proto { u16 reqid; u8 pending; u32 lastcmd; u8 bus_header[BUS_HEADER_LEN]; - cdc_ioctl_t msg; - unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN]; -} dhd_prot_t; + struct brcmf_proto_cdc_ioctl msg; + unsigned char buf[BRCMF_C_IOCTL_MAXLEN + ROUND_UP_MARGIN]; +}; -static int dhdcdc_msg(dhd_pub_t *dhd) +static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) { - dhd_prot_t *prot = dhd->prot; - int len = le32_to_cpu(prot->msg.len) + sizeof(cdc_ioctl_t); + struct brcmf_proto *prot = drvr->prot; + int len = le32_to_cpu(prot->msg.len) + + sizeof(struct brcmf_proto_cdc_ioctl); - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); /* NOTE : cdc->msg.len holds the desired length of the buffer to be * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area @@ -75,20 +114,21 @@ static int dhdcdc_msg(dhd_pub_t *dhd) len = CDC_MAX_MSG_SIZE; /* Send request */ - return dhd_bus_txctl(dhd->bus, (unsigned char *)&prot->msg, len); + return brcmf_sdbrcm_bus_txctl(drvr->bus, (unsigned char *)&prot->msg, + len); } -static int dhdcdc_cmplt(dhd_pub_t *dhd, u32 id, u32 len) +static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) { int ret; - dhd_prot_t *prot = dhd->prot; + struct brcmf_proto *prot = drvr->prot; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); do { - ret = - dhd_bus_rxctl(dhd->bus, (unsigned char *)&prot->msg, - len + sizeof(cdc_ioctl_t)); + ret = brcmf_sdbrcm_bus_rxctl(drvr->bus, + (unsigned char *)&prot->msg, + len + sizeof(struct brcmf_proto_cdc_ioctl)); if (ret < 0) break; } while (CDC_IOC_ID(le32_to_cpu(prot->msg.flags)) != id); @@ -97,30 +137,31 @@ static int dhdcdc_cmplt(dhd_pub_t *dhd, u32 id, u32 len) } int -dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) +brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd, + void *buf, uint len) { - dhd_prot_t *prot = dhd->prot; - cdc_ioctl_t *msg = &prot->msg; + struct brcmf_proto *prot = drvr->prot; + struct brcmf_proto_cdc_ioctl *msg = &prot->msg; void *info; int ret = 0, retries = 0; u32 id, flags = 0; - DHD_TRACE(("%s: Enter\n", __func__)); - DHD_CTL(("%s: cmd %d len %d\n", __func__, cmd, len)); + BRCMF_TRACE(("%s: Enter\n", __func__)); + BRCMF_CTL(("%s: cmd %d len %d\n", __func__, cmd, len)); /* Respond "bcmerror" and "bcmerrorstr" with local cache */ - if (cmd == WLC_GET_VAR && buf) { + if (cmd == BRCMF_C_GET_VAR && buf) { if (!strcmp((char *)buf, "bcmerrorstr")) { strncpy((char *)buf, "bcm_error", BCME_STRLEN); goto done; } else if (!strcmp((char *)buf, "bcmerror")) { - *(int *)buf = dhd->dongle_error; + *(int *)buf = drvr->dongle_error; goto done; } } - memset(msg, 0, sizeof(cdc_ioctl_t)); + memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl)); msg->cmd = cpu_to_le32(cmd); msg->len = cpu_to_le32(len); @@ -131,16 +172,16 @@ dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) if (buf) memcpy(prot->buf, buf, len); - ret = dhdcdc_msg(dhd); + ret = brcmf_proto_cdc_msg(drvr); if (ret < 0) { - DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status " - "%d\n", ret)); + BRCMF_ERROR(("brcmf_proto_cdc_query_ioctl: brcmf_proto_cdc_msg " + "failed w/status %d\n", ret)); goto done; } retry: /* wait for interrupt and get first fragment */ - ret = dhdcdc_cmplt(dhd, prot->reqid, len); + ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len); if (ret < 0) goto done; @@ -150,8 +191,9 @@ dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) if ((id < prot->reqid) && (++retries < RETRIES)) goto retry; if (id != prot->reqid) { - DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", - dhd_ifname(dhd, ifidx), __func__, id, prot->reqid)); + BRCMF_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", + brcmf_ifname(drvr, ifidx), __func__, id, + prot->reqid)); ret = -EINVAL; goto done; } @@ -170,24 +212,25 @@ dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) if (flags & CDCF_IOC_ERROR) { ret = le32_to_cpu(msg->status); /* Cache error from dongle */ - dhd->dongle_error = ret; + drvr->dongle_error = ret; } done: return ret; } -int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) +int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd, + void *buf, uint len) { - dhd_prot_t *prot = dhd->prot; - cdc_ioctl_t *msg = &prot->msg; + struct brcmf_proto *prot = drvr->prot; + struct brcmf_proto_cdc_ioctl *msg = &prot->msg; int ret = 0; u32 flags, id; - DHD_TRACE(("%s: Enter\n", __func__)); - DHD_CTL(("%s: cmd %d len %d\n", __func__, cmd, len)); + BRCMF_TRACE(("%s: Enter\n", __func__)); + BRCMF_CTL(("%s: cmd %d len %d\n", __func__, cmd, len)); - memset(msg, 0, sizeof(cdc_ioctl_t)); + memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl)); msg->cmd = cpu_to_le32(cmd); msg->len = cpu_to_le32(len); @@ -198,11 +241,11 @@ int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) if (buf) memcpy(prot->buf, buf, len); - ret = dhdcdc_msg(dhd); + ret = brcmf_proto_cdc_msg(drvr); if (ret < 0) goto done; - ret = dhdcdc_cmplt(dhd, prot->reqid, len); + ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len); if (ret < 0) goto done; @@ -210,8 +253,9 @@ int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; if (id != prot->reqid) { - DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", - dhd_ifname(dhd, ifidx), __func__, id, prot->reqid)); + BRCMF_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", + brcmf_ifname(drvr, ifidx), __func__, id, + prot->reqid)); ret = -EINVAL; goto done; } @@ -220,41 +264,40 @@ int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len) if (flags & CDCF_IOC_ERROR) { ret = le32_to_cpu(msg->status); /* Cache error from dongle */ - dhd->dongle_error = ret; + drvr->dongle_error = ret; } done: return ret; } -extern int dhd_bus_interface(struct dhd_bus *bus, uint arg, void *arg2); int -dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, void *buf, int len) +brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx, struct brcmf_ioctl *ioc, + void *buf, int len) { - dhd_prot_t *prot = dhd->prot; + struct brcmf_proto *prot = drvr->prot; int ret = -1; - if (dhd->busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s : bus is down. we have nothing to do\n", - __func__)); + if (drvr->busstate == BRCMF_BUS_DOWN) { + BRCMF_ERROR(("%s : bus is down. we have nothing to do\n", + __func__)); return ret; } - dhd_os_proto_block(dhd); + brcmf_os_proto_block(drvr); - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - ASSERT(len <= WLC_IOCTL_MAXLEN); - - if (len > WLC_IOCTL_MAXLEN) + if (len > BRCMF_C_IOCTL_MAXLEN) goto done; if (prot->pending == true) { - DHD_TRACE(("CDC packet is pending!!!! cmd=0x%x (%lu) " - "lastcmd=0x%x (%lu)\n", - ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd, - (unsigned long)prot->lastcmd)); - if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR)) - DHD_TRACE(("iovar cmd=%s\n", (char *)buf)); + BRCMF_TRACE(("CDC packet is pending!!!! cmd=0x%x (%lu) " + "lastcmd=0x%x (%lu)\n", + ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd, + (unsigned long)prot->lastcmd)); + if ((ioc->cmd == BRCMF_C_SET_VAR) || + (ioc->cmd == BRCMF_C_GET_VAR)) + BRCMF_TRACE(("iovar cmd=%s\n", (char *)buf)); goto done; } @@ -262,36 +305,39 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, void *buf, int len) prot->pending = true; prot->lastcmd = ioc->cmd; if (ioc->set) - ret = dhdcdc_set_ioctl(dhd, ifidx, ioc->cmd, buf, len); + ret = brcmf_proto_cdc_set_ioctl(drvr, ifidx, ioc->cmd, + buf, len); else { - ret = dhdcdc_query_ioctl(dhd, ifidx, ioc->cmd, buf, len); + ret = brcmf_proto_cdc_query_ioctl(drvr, ifidx, ioc->cmd, + buf, len); if (ret > 0) - ioc->used = ret - sizeof(cdc_ioctl_t); + ioc->used = ret - sizeof(struct brcmf_proto_cdc_ioctl); } /* Too many programs assume ioctl() returns 0 on success */ if (ret >= 0) ret = 0; else { - cdc_ioctl_t *msg = &prot->msg; + struct brcmf_proto_cdc_ioctl *msg = &prot->msg; /* len == needed when set/query fails from dongle */ ioc->needed = le32_to_cpu(msg->len); } /* Intercept the wme_dp ioctl here */ - if ((!ret) && (ioc->cmd == WLC_SET_VAR) && (!strcmp(buf, "wme_dp"))) { + if (!ret && ioc->cmd == BRCMF_C_SET_VAR && + !strcmp(buf, "wme_dp")) { int slen, val = 0; slen = strlen("wme_dp") + 1; if (len >= (int)(slen + sizeof(int))) memcpy(&val, (char *)buf + slen, sizeof(int)); - dhd->wme_dp = (u8) le32_to_cpu(val); + drvr->wme_dp = (u8) le32_to_cpu(val); } prot->pending = false; done: - dhd_os_proto_unblock(dhd); + brcmf_os_proto_unblock(drvr); return ret; } @@ -302,35 +348,23 @@ dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, void *buf, int len) (((struct sk_buff *)(skb))->ip_summed = \ ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) -/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because - skb->ip_summed is overloaded */ - -int -dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set) +void brcmf_proto_dump(struct brcmf_pub *drvr, struct brcmu_strbuf *strbuf) { - return -ENOTSUPP; + brcmu_bprintf(strbuf, "Protocol CDC: reqid %d\n", drvr->prot->reqid); } -void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) +void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, + struct sk_buff *pktbuf) { - bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid); -} + struct brcmf_proto_bdc_header *h; -void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, struct sk_buff *pktbuf) -{ -#ifdef BDC - struct bdc_header *h; -#endif /* BDC */ + BRCMF_TRACE(("%s: Enter\n", __func__)); - DHD_TRACE(("%s: Enter\n", __func__)); - -#ifdef BDC /* Push BDC header used to convey priority for buses that don't */ skb_push(pktbuf, BDC_HEADER_LEN); - h = (struct bdc_header *)(pktbuf->data); + h = (struct brcmf_proto_bdc_header *)(pktbuf->data); h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); if (PKTSUMNEEDED(pktbuf)) @@ -339,79 +373,74 @@ void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, struct sk_buff *pktbuf) h->priority = (pktbuf->priority & BDC_PRIORITY_MASK); h->flags2 = 0; h->rssi = 0; -#endif /* BDC */ BDC_SET_IF_IDX(h, ifidx); } -int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, struct sk_buff *pktbuf) +int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx, + struct sk_buff *pktbuf) { -#ifdef BDC - struct bdc_header *h; -#endif + struct brcmf_proto_bdc_header *h; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); -#ifdef BDC /* Pop BDC header used to convey priority for buses that don't */ if (pktbuf->len < BDC_HEADER_LEN) { - DHD_ERROR(("%s: rx data too short (%d < %d)\n", __func__, - pktbuf->len, BDC_HEADER_LEN)); + BRCMF_ERROR(("%s: rx data too short (%d < %d)\n", __func__, + pktbuf->len, BDC_HEADER_LEN)); return -EBADE; } - h = (struct bdc_header *)(pktbuf->data); + h = (struct brcmf_proto_bdc_header *)(pktbuf->data); *ifidx = BDC_GET_IF_IDX(h); - if (*ifidx >= DHD_MAX_IFS) { - DHD_ERROR(("%s: rx data ifnum out of range (%d)\n", - __func__, *ifidx)); + if (*ifidx >= BRCMF_MAX_IFS) { + BRCMF_ERROR(("%s: rx data ifnum out of range (%d)\n", + __func__, *ifidx)); return -EBADE; } if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) { - DHD_ERROR(("%s: non-BDC packet received, flags 0x%x\n", - dhd_ifname(dhd, *ifidx), h->flags)); + BRCMF_ERROR(("%s: non-BDC packet received, flags 0x%x\n", + brcmf_ifname(drvr, *ifidx), h->flags)); return -EBADE; } if (h->flags & BDC_FLAG_SUM_GOOD) { - DHD_INFO(("%s: BDC packet received with good rx-csum, " - "flags 0x%x\n", - dhd_ifname(dhd, *ifidx), h->flags)); + BRCMF_INFO(("%s: BDC packet received with good rx-csum, " + "flags 0x%x\n", + brcmf_ifname(drvr, *ifidx), h->flags)); PKTSETSUMGOOD(pktbuf, true); } pktbuf->priority = h->priority & BDC_PRIORITY_MASK; skb_pull(pktbuf, BDC_HEADER_LEN); -#endif /* BDC */ return 0; } -int dhd_prot_attach(dhd_pub_t *dhd) +int brcmf_proto_attach(struct brcmf_pub *drvr) { - dhd_prot_t *cdc; + struct brcmf_proto *cdc; - cdc = kzalloc(sizeof(dhd_prot_t), GFP_ATOMIC); + cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC); if (!cdc) { - DHD_ERROR(("%s: kmalloc failed\n", __func__)); + BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); goto fail; } /* ensure that the msg buf directly follows the cdc msg struct */ if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) { - DHD_ERROR(("dhd_prot_t is not correctly defined\n")); + BRCMF_ERROR(("struct brcmf_proto is not correctly defined\n")); goto fail; } - dhd->prot = cdc; -#ifdef BDC - dhd->hdrlen += BDC_HEADER_LEN; -#endif - dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN; + drvr->prot = cdc; + drvr->hdrlen += BDC_HEADER_LEN; + drvr->maxctl = BRCMF_C_IOCTL_MAXLEN + + sizeof(struct brcmf_proto_cdc_ioctl) + ROUND_UP_MARGIN; return 0; fail: @@ -420,55 +449,54 @@ int dhd_prot_attach(dhd_pub_t *dhd) } /* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ -void dhd_prot_detach(dhd_pub_t *dhd) +void brcmf_proto_detach(struct brcmf_pub *drvr) { - kfree(dhd->prot); - dhd->prot = NULL; + kfree(drvr->prot); + drvr->prot = NULL; } -void dhd_prot_dstats(dhd_pub_t *dhd) +void brcmf_proto_dstats(struct brcmf_pub *drvr) { /* No stats from dongle added yet, copy bus stats */ - dhd->dstats.tx_packets = dhd->tx_packets; - dhd->dstats.tx_errors = dhd->tx_errors; - dhd->dstats.rx_packets = dhd->rx_packets; - dhd->dstats.rx_errors = dhd->rx_errors; - dhd->dstats.rx_dropped = dhd->rx_dropped; - dhd->dstats.multicast = dhd->rx_multicast; + drvr->dstats.tx_packets = drvr->tx_packets; + drvr->dstats.tx_errors = drvr->tx_errors; + drvr->dstats.rx_packets = drvr->rx_packets; + drvr->dstats.rx_errors = drvr->rx_errors; + drvr->dstats.rx_dropped = drvr->rx_dropped; + drvr->dstats.multicast = drvr->rx_multicast; return; } -int dhd_prot_init(dhd_pub_t *dhd) +int brcmf_proto_init(struct brcmf_pub *drvr) { int ret = 0; char buf[128]; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - dhd_os_proto_block(dhd); + brcmf_os_proto_block(drvr); /* Get the device MAC address */ strcpy(buf, "cur_etheraddr"); - ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf)); + ret = brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR, + buf, sizeof(buf)); if (ret < 0) { - dhd_os_proto_unblock(dhd); + brcmf_os_proto_unblock(drvr); return ret; } - memcpy(dhd->mac, buf, ETH_ALEN); + memcpy(drvr->mac, buf, ETH_ALEN); - dhd_os_proto_unblock(dhd); + brcmf_os_proto_unblock(drvr); -#ifdef EMBEDDED_PLATFORM - ret = dhd_preinit_ioctls(dhd); -#endif /* EMBEDDED_PLATFORM */ + ret = brcmf_c_preinit_ioctls(drvr); /* Always assumes wl for now */ - dhd->iswl = true; + drvr->iswl = true; return ret; } -void dhd_prot_stop(dhd_pub_t *dhd) +void brcmf_proto_stop(struct brcmf_pub *drvr) { /* Nothing to do for CDC */ } diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 0bfb93c0075a..fdec4683c422 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -15,64 +15,41 @@ */ #include #include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include "dhd.h" +#include "dhd_bus.h" +#include "dhd_proto.h" +#include "dhd_dbg.h" -int dhd_msg_level; -char fw_path[MOD_PARAM_PATHLEN]; -char nv_path[MOD_PARAM_PATHLEN]; +#define BRCM_OUI "\x00\x10\x18" +#define DOT11_OUI_LEN 3 +#define BCMILCP_BCM_SUBTYPE_EVENT 1 +#define PKTFILTER_BUF_SIZE 2048 -/* Last connection success/failure status */ -u32 dhd_conn_event; -u32 dhd_conn_status; -u32 dhd_conn_reason; +int brcmf_msg_level; -extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, - uint len); -extern void dhd_ind_scan_confirm(void *h, bool status); -extern int dhd_wl_ioctl(dhd_pub_t *dhd, uint cmd, char *buf, uint buflen); -void dhd_iscan_lock(void); -void dhd_iscan_unlock(void); +#define MSGTRACE_VERSION 1 -/* Packet alignment for most efficient SDIO (can change based on platform) */ -#ifndef DHD_SDALIGN -#define DHD_SDALIGN 32 -#endif -#if !ISPOWEROF2(DHD_SDALIGN) -#error DHD_SDALIGN is not a power of 2! -#endif - -#define EPI_VERSION_STR "4.218.248.5" -#ifdef DHD_DEBUG -const char dhd_version[] = -"Dongle Host Driver, version " EPI_VERSION_STR "\nCompiled on " __DATE__ +#ifdef BCMDBG +const char brcmf_version[] = +"Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " __DATE__ " at " __TIME__; #else -const char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR; +const char brcmf_version[] = "Dongle Host Driver, version " BRCMF_VERSION_STR; #endif -void dhd_set_timer(void *bus, uint wdtick); - /* IOVar table */ enum { IOV_VERSION = 1, IOV_MSGLEVEL, IOV_BCMERRORSTR, IOV_BCMERROR, - IOV_WDTICK, IOV_DUMP, -#ifdef DHD_DEBUG - IOV_CONS, - IOV_DCONSOLE_POLL, -#endif IOV_CLEARCOUNTS, IOV_LOGDUMP, IOV_LOGCAL, @@ -82,27 +59,19 @@ enum { IOV_LAST }; -const bcm_iovar_t dhd_iovars[] = { - {"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(dhd_version)} +const struct brcmu_iovar brcmf_iovars[] = { + {"version", IOV_VERSION, 0, IOVT_BUFFER, sizeof(brcmf_version)} , -#ifdef DHD_DEBUG +#ifdef BCMDBG {"msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0} , -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ {"bcmerrorstr", IOV_BCMERRORSTR, 0, IOVT_BUFFER, BCME_STRLEN} , {"bcmerror", IOV_BCMERROR, 0, IOVT_INT8, 0} , - {"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0} + {"dump", IOV_DUMP, 0, IOVT_BUFFER, BRCMF_IOCTL_MAXLEN} , - {"dump", IOV_DUMP, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN} - , -#ifdef DHD_DEBUG - {"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0} - , - {"cons", IOV_CONS, 0, IOVT_BUFFER, 0} - , -#endif {"clearcounts", IOV_CLEARCOUNTS, 0, IOVT_VOID, 0} , {"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0} @@ -112,7 +81,23 @@ const bcm_iovar_t dhd_iovars[] = { {NULL, 0, 0, 0, 0} }; -void dhd_common_init(void) +/* Message trace header */ +struct msgtrace_hdr { + u8 version; + u8 spare; + u16 len; /* Len of the trace */ + u32 seqnum; /* Sequence number of message. Useful + * if the messsage has been lost + * because of DMA error or a bus reset + * (ex: SDIO Func2) + */ + u32 discarded_bytes; /* Number of discarded bytes because of + trace overflow */ + u32 discarded_printf; /* Number of discarded printf + because of trace overflow */ +} __packed; + +void brcmf_c_init(void) { /* Init global variables at run-time, not as part of the declaration. * This is required to support init/de-init of the driver. @@ -122,87 +107,77 @@ void dhd_common_init(void) * first time that the driver is initialized vs subsequent * initializations. */ - dhd_msg_level = DHD_ERROR_VAL; -#ifdef CONFIG_BCM4329_FW_PATH - strncpy(fw_path, CONFIG_BCM4329_FW_PATH, MOD_PARAM_PATHLEN - 1); -#else - fw_path[0] = '\0'; -#endif -#ifdef CONFIG_BCM4329_NVRAM_PATH - strncpy(nv_path, CONFIG_BCM4329_NVRAM_PATH, MOD_PARAM_PATHLEN - 1); -#else - nv_path[0] = '\0'; -#endif + brcmf_msg_level = BRCMF_ERROR_VAL; } -static int dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen) +static int brcmf_c_dump(struct brcmf_pub *drvr, char *buf, int buflen) { - struct bcmstrbuf b; - struct bcmstrbuf *strbuf = &b; + struct brcmu_strbuf b; + struct brcmu_strbuf *strbuf = &b; - bcm_binit(strbuf, buf, buflen); + brcmu_binit(strbuf, buf, buflen); - /* Base DHD info */ - bcm_bprintf(strbuf, "%s\n", dhd_version); - bcm_bprintf(strbuf, "\n"); - bcm_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n", - dhdp->up, dhdp->txoff, dhdp->busstate); - bcm_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n", - dhdp->hdrlen, dhdp->maxctl, dhdp->rxsz); - bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %pM\n", - dhdp->iswl, dhdp->drv_version, &dhdp->mac); - bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", dhdp->bcmerror, - dhdp->tickcnt); + /* Base info */ + brcmu_bprintf(strbuf, "%s\n", brcmf_version); + brcmu_bprintf(strbuf, "\n"); + brcmu_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n", + drvr->up, drvr->txoff, drvr->busstate); + brcmu_bprintf(strbuf, "pub.hdrlen %d pub.maxctl %d pub.rxsz %d\n", + drvr->hdrlen, drvr->maxctl, drvr->rxsz); + brcmu_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac %pM\n", + drvr->iswl, drvr->drv_version, &drvr->mac); + brcmu_bprintf(strbuf, "pub.bcmerror %d tickcnt %d\n", drvr->bcmerror, + drvr->tickcnt); - bcm_bprintf(strbuf, "dongle stats:\n"); - bcm_bprintf(strbuf, + brcmu_bprintf(strbuf, "dongle stats:\n"); + brcmu_bprintf(strbuf, "tx_packets %ld tx_bytes %ld tx_errors %ld tx_dropped %ld\n", - dhdp->dstats.tx_packets, dhdp->dstats.tx_bytes, - dhdp->dstats.tx_errors, dhdp->dstats.tx_dropped); - bcm_bprintf(strbuf, + drvr->dstats.tx_packets, drvr->dstats.tx_bytes, + drvr->dstats.tx_errors, drvr->dstats.tx_dropped); + brcmu_bprintf(strbuf, "rx_packets %ld rx_bytes %ld rx_errors %ld rx_dropped %ld\n", - dhdp->dstats.rx_packets, dhdp->dstats.rx_bytes, - dhdp->dstats.rx_errors, dhdp->dstats.rx_dropped); - bcm_bprintf(strbuf, "multicast %ld\n", dhdp->dstats.multicast); + drvr->dstats.rx_packets, drvr->dstats.rx_bytes, + drvr->dstats.rx_errors, drvr->dstats.rx_dropped); + brcmu_bprintf(strbuf, "multicast %ld\n", drvr->dstats.multicast); - bcm_bprintf(strbuf, "bus stats:\n"); - bcm_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n", - dhdp->tx_packets, dhdp->tx_multicast, dhdp->tx_errors); - bcm_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n", - dhdp->tx_ctlpkts, dhdp->tx_ctlerrs); - bcm_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld\n", - dhdp->rx_packets, dhdp->rx_multicast, dhdp->rx_errors); - bcm_bprintf(strbuf, + brcmu_bprintf(strbuf, "bus stats:\n"); + brcmu_bprintf(strbuf, "tx_packets %ld tx_multicast %ld tx_errors %ld\n", + drvr->tx_packets, drvr->tx_multicast, drvr->tx_errors); + brcmu_bprintf(strbuf, "tx_ctlpkts %ld tx_ctlerrs %ld\n", + drvr->tx_ctlpkts, drvr->tx_ctlerrs); + brcmu_bprintf(strbuf, "rx_packets %ld rx_multicast %ld rx_errors %ld\n", + drvr->rx_packets, drvr->rx_multicast, drvr->rx_errors); + brcmu_bprintf(strbuf, "rx_ctlpkts %ld rx_ctlerrs %ld rx_dropped %ld rx_flushed %ld\n", - dhdp->rx_ctlpkts, dhdp->rx_ctlerrs, dhdp->rx_dropped, - dhdp->rx_flushed); - bcm_bprintf(strbuf, + drvr->rx_ctlpkts, drvr->rx_ctlerrs, drvr->rx_dropped, + drvr->rx_flushed); + brcmu_bprintf(strbuf, "rx_readahead_cnt %ld tx_realloc %ld fc_packets %ld\n", - dhdp->rx_readahead_cnt, dhdp->tx_realloc, dhdp->fc_packets); - bcm_bprintf(strbuf, "wd_dpc_sched %ld\n", dhdp->wd_dpc_sched); - bcm_bprintf(strbuf, "\n"); + drvr->rx_readahead_cnt, drvr->tx_realloc, drvr->fc_packets); + brcmu_bprintf(strbuf, "wd_dpc_sched %ld\n", drvr->wd_dpc_sched); + brcmu_bprintf(strbuf, "\n"); /* Add any prot info */ - dhd_prot_dump(dhdp, strbuf); - bcm_bprintf(strbuf, "\n"); + brcmf_proto_dump(drvr, strbuf); + brcmu_bprintf(strbuf, "\n"); /* Add any bus info */ - dhd_bus_dump(dhdp, strbuf); + brcmf_sdbrcm_bus_dump(drvr, strbuf); return !strbuf->size ? -EOVERFLOW : 0; } static int -dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, - const char *name, void *params, int plen, void *arg, int len, - int val_size) +brcmf_c_doiovar(struct brcmf_pub *drvr, const struct brcmu_iovar *vi, + u32 actionid, const char *name, void *params, int plen, + void *arg, int len, int val_size) { int bcmerror = 0; s32 int_val = 0; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid)); + bcmerror = brcmu_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid)); if (bcmerror != 0) goto exit; @@ -212,16 +187,16 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, switch (actionid) { case IOV_GVAL(IOV_VERSION): /* Need to have checked buffer length */ - strncpy((char *)arg, dhd_version, len); + strncpy((char *)arg, brcmf_version, len); break; case IOV_GVAL(IOV_MSGLEVEL): - int_val = (s32) dhd_msg_level; + int_val = (s32) brcmf_msg_level; memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_MSGLEVEL): - dhd_msg_level = int_val; + brcmf_msg_level = int_val; break; case IOV_GVAL(IOV_BCMERRORSTR): @@ -231,58 +206,29 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, break; case IOV_GVAL(IOV_BCMERROR): - int_val = (s32) dhd_pub->bcmerror; + int_val = (s32) drvr->bcmerror; memcpy(arg, &int_val, val_size); break; - case IOV_GVAL(IOV_WDTICK): - int_val = (s32) dhd_watchdog_ms; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_WDTICK): - if (!dhd_pub->up) { - bcmerror = -ENOLINK; - break; - } - dhd_os_wd_timer(dhd_pub, (uint) int_val); - break; - case IOV_GVAL(IOV_DUMP): - bcmerror = dhd_dump(dhd_pub, arg, len); + bcmerror = brcmf_c_dump(drvr, arg, len); break; -#ifdef DHD_DEBUG - case IOV_GVAL(IOV_DCONSOLE_POLL): - int_val = (s32) dhd_console_ms; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_DCONSOLE_POLL): - dhd_console_ms = (uint) int_val; - break; - - case IOV_SVAL(IOV_CONS): - if (len > 0) - bcmerror = dhd_bus_console_in(dhd_pub, arg, len - 1); - break; -#endif - case IOV_SVAL(IOV_CLEARCOUNTS): - dhd_pub->tx_packets = dhd_pub->rx_packets = 0; - dhd_pub->tx_errors = dhd_pub->rx_errors = 0; - dhd_pub->tx_ctlpkts = dhd_pub->rx_ctlpkts = 0; - dhd_pub->tx_ctlerrs = dhd_pub->rx_ctlerrs = 0; - dhd_pub->rx_dropped = 0; - dhd_pub->rx_readahead_cnt = 0; - dhd_pub->tx_realloc = 0; - dhd_pub->wd_dpc_sched = 0; - memset(&dhd_pub->dstats, 0, sizeof(dhd_pub->dstats)); - dhd_bus_clearcounts(dhd_pub); + drvr->tx_packets = drvr->rx_packets = 0; + drvr->tx_errors = drvr->rx_errors = 0; + drvr->tx_ctlpkts = drvr->rx_ctlpkts = 0; + drvr->tx_ctlerrs = drvr->rx_ctlerrs = 0; + drvr->rx_dropped = 0; + drvr->rx_readahead_cnt = 0; + drvr->tx_realloc = 0; + drvr->wd_dpc_sched = 0; + memset(&drvr->dstats, 0, sizeof(drvr->dstats)); + brcmf_bus_clearcounts(drvr); break; case IOV_GVAL(IOV_IOCTLTIMEOUT):{ - int_val = (s32) dhd_os_get_ioctl_resp_timeout(); + int_val = (s32) brcmf_os_get_ioctl_resp_timeout(); memcpy(arg, &int_val, sizeof(int_val)); break; } @@ -291,7 +237,7 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, if (int_val <= 0) bcmerror = -EINVAL; else - dhd_os_set_ioctl_resp_timeout((unsigned int) + brcmf_os_set_ioctl_resp_timeout((unsigned int) int_val); break; } @@ -305,8 +251,8 @@ dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, u32 actionid, return bcmerror; } -bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt, - int prec) +bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q, + struct sk_buff *pkt, int prec) { struct sk_buff *p; int eprec = -1; /* precedence to evict from */ @@ -316,7 +262,7 @@ bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt, * exceeding total queue length */ if (!pktq_pfull(q, prec) && !pktq_full(q)) { - bcm_pktq_penq(q, prec, pkt); + brcmu_pktq_penq(q, prec, pkt); return true; } @@ -324,8 +270,7 @@ bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt, if (pktq_pfull(q, prec)) eprec = prec; else if (pktq_full(q)) { - p = bcm_pktq_peek_tail(q, &eprec); - ASSERT(p); + p = brcmu_pktq_peek_tail(q, &eprec); if (eprec > prec) return false; } @@ -333,60 +278,58 @@ bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt, /* Evict if needed */ if (eprec >= 0) { /* Detect queueing to unconfigured precedence */ - ASSERT(!pktq_pempty(q, eprec)); - discard_oldest = AC_BITMAP_TST(dhdp->wme_dp, eprec); + discard_oldest = AC_BITMAP_TST(drvr->wme_dp, eprec); if (eprec == prec && !discard_oldest) return false; /* refuse newer (incoming) packet */ /* Evict packet according to discard policy */ - p = discard_oldest ? bcm_pktq_pdeq(q, eprec) : - bcm_pktq_pdeq_tail(q, eprec); + p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) : + brcmu_pktq_pdeq_tail(q, eprec); if (p == NULL) { - DHD_ERROR(("%s: bcm_pktq_penq() failed, oldest %d.", - __func__, discard_oldest)); - ASSERT(p); + BRCMF_ERROR(("%s: brcmu_pktq_penq() failed, oldest %d.", + __func__, discard_oldest)); } - - bcm_pkt_buf_free_skb(p); + brcmu_pkt_buf_free_skb(p); } /* Enqueue */ - p = bcm_pktq_penq(q, prec, pkt); + p = brcmu_pktq_penq(q, prec, pkt); if (p == NULL) { - DHD_ERROR(("%s: bcm_pktq_penq() failed.", __func__)); - ASSERT(p); + BRCMF_ERROR(("%s: brcmu_pktq_penq() failed.", __func__)); } - return true; + return p != NULL; } static int -dhd_iovar_op(dhd_pub_t *dhd_pub, const char *name, +brcmf_c_iovar_op(struct brcmf_pub *drvr, const char *name, void *params, int plen, void *arg, int len, bool set) { int bcmerror = 0; int val_size; - const bcm_iovar_t *vi = NULL; + const struct brcmu_iovar *vi = NULL; u32 actionid; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - ASSERT(name); - ASSERT(len >= 0); + if (name == NULL || len <= 0) + return -EINVAL; - /* Get MUST have return space */ - ASSERT(set || (arg && len)); + /* Set does not take qualifiers */ + if (set && (params || plen)) + return -EINVAL; - /* Set does NOT take qualifiers */ - ASSERT(!set || (!params && !plen)); + /* Get must have return space;*/ + if (!set && !(arg && len)) + return -EINVAL; - vi = bcm_iovar_lookup(dhd_iovars, name); + vi = brcmu_iovar_lookup(brcmf_iovars, name); if (vi == NULL) { bcmerror = -ENOTSUPP; goto exit; } - DHD_CTL(("%s: %s %s, len %d plen %d\n", __func__, - name, (set ? "set" : "get"), len, plen)); + BRCMF_CTL(("%s: %s %s, len %d plen %d\n", __func__, + name, (set ? "set" : "get"), len, plen)); /* set up 'params' pointer in case this is a set command so that * the convenience int and bool code can be common to set and get @@ -406,39 +349,40 @@ dhd_iovar_op(dhd_pub_t *dhd_pub, const char *name, actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); bcmerror = - dhd_doiovar(dhd_pub, vi, actionid, name, params, plen, arg, len, + brcmf_c_doiovar(drvr, vi, actionid, name, params, plen, arg, len, val_size); exit: return bcmerror; } -int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen) +int brcmf_c_ioctl(struct brcmf_pub *drvr, struct brcmf_c_ioctl *ioc, void *buf, + uint buflen) { int bcmerror = 0; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); if (!buf) return -EINVAL; switch (ioc->cmd) { - case DHD_GET_MAGIC: + case BRCMF_GET_MAGIC: if (buflen < sizeof(int)) bcmerror = -EOVERFLOW; else - *(int *)buf = DHD_IOCTL_MAGIC; + *(int *)buf = BRCMF_IOCTL_MAGIC; break; - case DHD_GET_VERSION: + case BRCMF_GET_VERSION: if (buflen < sizeof(int)) bcmerror = -EOVERFLOW; else - *(int *)buf = DHD_IOCTL_VERSION; + *(int *)buf = BRCMF_IOCTL_VERSION; break; - case DHD_GET_VAR: - case DHD_SET_VAR:{ + case BRCMF_GET_VAR: + case BRCMF_SET_VAR:{ char *arg; uint arglen; @@ -456,38 +400,25 @@ int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen) arg++, arglen--; /* call with the appropriate arguments */ - if (ioc->cmd == DHD_GET_VAR) - bcmerror = - dhd_iovar_op(dhd_pub, buf, arg, arglen, buf, - buflen, IOV_GET); + if (ioc->cmd == BRCMF_GET_VAR) + bcmerror = brcmf_c_iovar_op(drvr, buf, arg, + arglen, buf, buflen, IOV_GET); else bcmerror = - dhd_iovar_op(dhd_pub, buf, NULL, 0, arg, - arglen, IOV_SET); - if (bcmerror != -ENOTSUPP) - break; - - /* not in generic table, try protocol module */ - if (ioc->cmd == DHD_GET_VAR) - bcmerror = dhd_prot_iovar_op(dhd_pub, buf, arg, - arglen, buf, - buflen, IOV_GET); - else - bcmerror = dhd_prot_iovar_op(dhd_pub, buf, - NULL, 0, arg, - arglen, IOV_SET); + brcmf_c_iovar_op(drvr, buf, NULL, 0, arg, + arglen, IOV_SET); if (bcmerror != -ENOTSUPP) break; /* if still not found, try bus module */ - if (ioc->cmd == DHD_GET_VAR) - bcmerror = dhd_bus_iovar_op(dhd_pub, buf, - arg, arglen, buf, - buflen, IOV_GET); + if (ioc->cmd == BRCMF_GET_VAR) + bcmerror = brcmf_sdbrcm_bus_iovar_op(drvr, + buf, arg, arglen, buf, buflen, + IOV_GET); else - bcmerror = dhd_bus_iovar_op(dhd_pub, buf, - NULL, 0, arg, - arglen, IOV_SET); + bcmerror = brcmf_sdbrcm_bus_iovar_op(drvr, + buf, NULL, 0, arg, arglen, + IOV_SET); break; } @@ -500,7 +431,8 @@ int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen) } #ifdef SHOW_EVENTS -static void wl_show_host_event(wl_event_msg_t *event, void *event_data) +static void +brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) { uint i, status, reason; bool group = false, flush_txq = false, link = false; @@ -512,62 +444,62 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) char *event_name; } event_names[] = { { - WLC_E_SET_SSID, "SET_SSID"}, { - WLC_E_JOIN, "JOIN"}, { - WLC_E_START, "START"}, { - WLC_E_AUTH, "AUTH"}, { - WLC_E_AUTH_IND, "AUTH_IND"}, { - WLC_E_DEAUTH, "DEAUTH"}, { - WLC_E_DEAUTH_IND, "DEAUTH_IND"}, { - WLC_E_ASSOC, "ASSOC"}, { - WLC_E_ASSOC_IND, "ASSOC_IND"}, { - WLC_E_REASSOC, "REASSOC"}, { - WLC_E_REASSOC_IND, "REASSOC_IND"}, { - WLC_E_DISASSOC, "DISASSOC"}, { - WLC_E_DISASSOC_IND, "DISASSOC_IND"}, { - WLC_E_QUIET_START, "START_QUIET"}, { - WLC_E_QUIET_END, "END_QUIET"}, { - WLC_E_BEACON_RX, "BEACON_RX"}, { - WLC_E_LINK, "LINK"}, { - WLC_E_MIC_ERROR, "MIC_ERROR"}, { - WLC_E_NDIS_LINK, "NDIS_LINK"}, { - WLC_E_ROAM, "ROAM"}, { - WLC_E_TXFAIL, "TXFAIL"}, { - WLC_E_PMKID_CACHE, "PMKID_CACHE"}, { - WLC_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, { - WLC_E_PRUNE, "PRUNE"}, { - WLC_E_AUTOAUTH, "AUTOAUTH"}, { - WLC_E_EAPOL_MSG, "EAPOL_MSG"}, { - WLC_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, { - WLC_E_ADDTS_IND, "ADDTS_IND"}, { - WLC_E_DELTS_IND, "DELTS_IND"}, { - WLC_E_BCNSENT_IND, "BCNSENT_IND"}, { - WLC_E_BCNRX_MSG, "BCNRX_MSG"}, { - WLC_E_BCNLOST_MSG, "BCNLOST_MSG"}, { - WLC_E_ROAM_PREP, "ROAM_PREP"}, { - WLC_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, { - WLC_E_PFN_NET_LOST, "PNO_NET_LOST"}, { - WLC_E_RESET_COMPLETE, "RESET_COMPLETE"}, { - WLC_E_JOIN_START, "JOIN_START"}, { - WLC_E_ROAM_START, "ROAM_START"}, { - WLC_E_ASSOC_START, "ASSOC_START"}, { - WLC_E_IBSS_ASSOC, "IBSS_ASSOC"}, { - WLC_E_RADIO, "RADIO"}, { - WLC_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, { - WLC_E_PROBREQ_MSG, "PROBREQ_MSG"}, { - WLC_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, { - WLC_E_PSK_SUP, "PSK_SUP"}, { - WLC_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, { - WLC_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, { - WLC_E_ICV_ERROR, "ICV_ERROR"}, { - WLC_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, { - WLC_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, { - WLC_E_TRACE, "TRACE"}, { - WLC_E_ACTION_FRAME, "ACTION FRAME"}, { - WLC_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, { - WLC_E_IF, "IF"}, { - WLC_E_RSSI, "RSSI"}, { - WLC_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"} + BRCMF_E_SET_SSID, "SET_SSID"}, { + BRCMF_E_JOIN, "JOIN"}, { + BRCMF_E_START, "START"}, { + BRCMF_E_AUTH, "AUTH"}, { + BRCMF_E_AUTH_IND, "AUTH_IND"}, { + BRCMF_E_DEAUTH, "DEAUTH"}, { + BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, { + BRCMF_E_ASSOC, "ASSOC"}, { + BRCMF_E_ASSOC_IND, "ASSOC_IND"}, { + BRCMF_E_REASSOC, "REASSOC"}, { + BRCMF_E_REASSOC_IND, "REASSOC_IND"}, { + BRCMF_E_DISASSOC, "DISASSOC"}, { + BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, { + BRCMF_E_QUIET_START, "START_QUIET"}, { + BRCMF_E_QUIET_END, "END_QUIET"}, { + BRCMF_E_BEACON_RX, "BEACON_RX"}, { + BRCMF_E_LINK, "LINK"}, { + BRCMF_E_MIC_ERROR, "MIC_ERROR"}, { + BRCMF_E_NDIS_LINK, "NDIS_LINK"}, { + BRCMF_E_ROAM, "ROAM"}, { + BRCMF_E_TXFAIL, "TXFAIL"}, { + BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, { + BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, { + BRCMF_E_PRUNE, "PRUNE"}, { + BRCMF_E_AUTOAUTH, "AUTOAUTH"}, { + BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, { + BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, { + BRCMF_E_ADDTS_IND, "ADDTS_IND"}, { + BRCMF_E_DELTS_IND, "DELTS_IND"}, { + BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, { + BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, { + BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, { + BRCMF_E_ROAM_PREP, "ROAM_PREP"}, { + BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, { + BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, { + BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, { + BRCMF_E_JOIN_START, "JOIN_START"}, { + BRCMF_E_ROAM_START, "ROAM_START"}, { + BRCMF_E_ASSOC_START, "ASSOC_START"}, { + BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, { + BRCMF_E_RADIO, "RADIO"}, { + BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, { + BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, { + BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, { + BRCMF_E_PSK_SUP, "PSK_SUP"}, { + BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, { + BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, { + BRCMF_E_ICV_ERROR, "ICV_ERROR"}, { + BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, { + BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, { + BRCMF_E_TRACE, "TRACE"}, { + BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, { + BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, { + BRCMF_E_IF, "IF"}, { + BRCMF_E_RSSI, "RSSI"}, { + BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"} }; uint event_type, flags, auth_type, datalen; event_type = be32_to_cpu(event->event_type); @@ -585,54 +517,55 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) event_name = event_names[i].event_name; } - DHD_EVENT(("EVENT: %s, event ID = %d\n", event_name, event_type)); - DHD_EVENT(("flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n", - flags, status, reason, auth_type, eabuf)); + BRCMF_EVENT(("EVENT: %s, event ID = %d\n", event_name, event_type)); + BRCMF_EVENT(("flags 0x%04x, status %d, reason %d, auth_type %d" + " MAC %s\n", flags, status, reason, auth_type, eabuf)); - if (flags & WLC_EVENT_MSG_LINK) + if (flags & BRCMF_EVENT_MSG_LINK) link = true; - if (flags & WLC_EVENT_MSG_GROUP) + if (flags & BRCMF_EVENT_MSG_GROUP) group = true; - if (flags & WLC_EVENT_MSG_FLUSHTXQ) + if (flags & BRCMF_EVENT_MSG_FLUSHTXQ) flush_txq = true; switch (event_type) { - case WLC_E_START: - case WLC_E_DEAUTH: - case WLC_E_DISASSOC: - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); + case BRCMF_E_START: + case BRCMF_E_DEAUTH: + case BRCMF_E_DISASSOC: + BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); break; - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC_IND: - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); + case BRCMF_E_ASSOC_IND: + case BRCMF_E_REASSOC_IND: + BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); break; - case WLC_E_ASSOC: - case WLC_E_REASSOC: - if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, MAC %s, SUCCESS\n", - event_name, eabuf)); - } else if (status == WLC_E_STATUS_TIMEOUT) { - DHD_EVENT(("MACEVENT: %s, MAC %s, TIMEOUT\n", - event_name, eabuf)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, MAC %s, FAILURE, reason %d\n", - event_name, eabuf, (int)reason)); + case BRCMF_E_ASSOC: + case BRCMF_E_REASSOC: + if (status == BRCMF_E_STATUS_SUCCESS) { + BRCMF_EVENT(("MACEVENT: %s, MAC %s, SUCCESS\n", + event_name, eabuf)); + } else if (status == BRCMF_E_STATUS_TIMEOUT) { + BRCMF_EVENT(("MACEVENT: %s, MAC %s, TIMEOUT\n", + event_name, eabuf)); + } else if (status == BRCMF_E_STATUS_FAIL) { + BRCMF_EVENT(("MACEVENT: %s, MAC %s, FAILURE," + " reason %d\n", event_name, eabuf, + (int)reason)); } else { - DHD_EVENT(("MACEVENT: %s, MAC %s, unexpected status " - "%d\n", event_name, eabuf, (int)status)); + BRCMF_EVENT(("MACEVENT: %s, MAC %s, unexpected status " + "%d\n", event_name, eabuf, (int)status)); } break; - case WLC_E_DEAUTH_IND: - case WLC_E_DISASSOC_IND: - DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, - eabuf, (int)reason)); + case BRCMF_E_DEAUTH_IND: + case BRCMF_E_DISASSOC_IND: + BRCMF_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, + eabuf, (int)reason)); break; - case WLC_E_AUTH: - case WLC_E_AUTH_IND: + case BRCMF_E_AUTH: + case BRCMF_E_AUTH_IND: if (auth_type == WLAN_AUTH_OPEN) auth_str = "Open System"; else if (auth_type == WLAN_AUTH_SHARED_KEY) @@ -641,102 +574,102 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) sprintf(err_msg, "AUTH unknown: %d", (int)auth_type); auth_str = err_msg; } - if (event_type == WLC_E_AUTH_IND) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s\n", event_name, - eabuf, auth_str)); - } else if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s, SUCCESS\n", - event_name, eabuf, auth_str)); - } else if (status == WLC_E_STATUS_TIMEOUT) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s, TIMEOUT\n", - event_name, eabuf, auth_str)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, " - "reason %d\n", - event_name, eabuf, auth_str, (int)reason)); + if (event_type == BRCMF_E_AUTH_IND) { + BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s\n", event_name, + eabuf, auth_str)); + } else if (status == BRCMF_E_STATUS_SUCCESS) { + BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s, SUCCESS\n", + event_name, eabuf, auth_str)); + } else if (status == BRCMF_E_STATUS_TIMEOUT) { + BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s, TIMEOUT\n", + event_name, eabuf, auth_str)); + } else if (status == BRCMF_E_STATUS_FAIL) { + BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, " + "reason %d\n", + event_name, eabuf, auth_str, (int)reason)); } break; - case WLC_E_JOIN: - case WLC_E_ROAM: - case WLC_E_SET_SSID: - if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, - eabuf)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, failed\n", event_name)); - } else if (status == WLC_E_STATUS_NO_NETWORKS) { - DHD_EVENT(("MACEVENT: %s, no networks found\n", - event_name)); + case BRCMF_E_JOIN: + case BRCMF_E_ROAM: + case BRCMF_E_SET_SSID: + if (status == BRCMF_E_STATUS_SUCCESS) { + BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, + eabuf)); + } else if (status == BRCMF_E_STATUS_FAIL) { + BRCMF_EVENT(("MACEVENT: %s, failed\n", event_name)); + } else if (status == BRCMF_E_STATUS_NO_NETWORKS) { + BRCMF_EVENT(("MACEVENT: %s, no networks found\n", + event_name)); } else { - DHD_EVENT(("MACEVENT: %s, unexpected status %d\n", - event_name, (int)status)); + BRCMF_EVENT(("MACEVENT: %s, unexpected status %d\n", + event_name, (int)status)); } break; - case WLC_E_BEACON_RX: - if (status == WLC_E_STATUS_SUCCESS) { - DHD_EVENT(("MACEVENT: %s, SUCCESS\n", event_name)); - } else if (status == WLC_E_STATUS_FAIL) { - DHD_EVENT(("MACEVENT: %s, FAIL\n", event_name)); + case BRCMF_E_BEACON_RX: + if (status == BRCMF_E_STATUS_SUCCESS) { + BRCMF_EVENT(("MACEVENT: %s, SUCCESS\n", event_name)); + } else if (status == BRCMF_E_STATUS_FAIL) { + BRCMF_EVENT(("MACEVENT: %s, FAIL\n", event_name)); } else { - DHD_EVENT(("MACEVENT: %s, status %d\n", event_name, - status)); + BRCMF_EVENT(("MACEVENT: %s, status %d\n", event_name, + status)); } break; - case WLC_E_LINK: - DHD_EVENT(("MACEVENT: %s %s\n", event_name, - link ? "UP" : "DOWN")); + case BRCMF_E_LINK: + BRCMF_EVENT(("MACEVENT: %s %s\n", event_name, + link ? "UP" : "DOWN")); break; - case WLC_E_MIC_ERROR: - DHD_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n", - event_name, eabuf, group, flush_txq)); + case BRCMF_E_MIC_ERROR: + BRCMF_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n", + event_name, eabuf, group, flush_txq)); break; - case WLC_E_ICV_ERROR: - case WLC_E_UNICAST_DECODE_ERROR: - case WLC_E_MULTICAST_DECODE_ERROR: - DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); + case BRCMF_E_ICV_ERROR: + case BRCMF_E_UNICAST_DECODE_ERROR: + case BRCMF_E_MULTICAST_DECODE_ERROR: + BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); break; - case WLC_E_TXFAIL: - DHD_EVENT(("MACEVENT: %s, RA %s\n", event_name, eabuf)); + case BRCMF_E_TXFAIL: + BRCMF_EVENT(("MACEVENT: %s, RA %s\n", event_name, eabuf)); break; - case WLC_E_SCAN_COMPLETE: - case WLC_E_PMKID_CACHE: - DHD_EVENT(("MACEVENT: %s\n", event_name)); + case BRCMF_E_SCAN_COMPLETE: + case BRCMF_E_PMKID_CACHE: + BRCMF_EVENT(("MACEVENT: %s\n", event_name)); break; - case WLC_E_PFN_NET_FOUND: - case WLC_E_PFN_NET_LOST: - case WLC_E_PFN_SCAN_COMPLETE: - DHD_EVENT(("PNOEVENT: %s\n", event_name)); + case BRCMF_E_PFN_NET_FOUND: + case BRCMF_E_PFN_NET_LOST: + case BRCMF_E_PFN_SCAN_COMPLETE: + BRCMF_EVENT(("PNOEVENT: %s\n", event_name)); break; - case WLC_E_PSK_SUP: - case WLC_E_PRUNE: - DHD_EVENT(("MACEVENT: %s, status %d, reason %d\n", + case BRCMF_E_PSK_SUP: + case BRCMF_E_PRUNE: + BRCMF_EVENT(("MACEVENT: %s, status %d, reason %d\n", event_name, (int)status, (int)reason)); break; - case WLC_E_TRACE: + case BRCMF_E_TRACE: { static u32 seqnum_prev; - msgtrace_hdr_t hdr; + struct msgtrace_hdr hdr; u32 nblost; char *s, *p; buf = (unsigned char *) event_data; - memcpy(&hdr, buf, MSGTRACE_HDRLEN); + memcpy(&hdr, buf, sizeof(struct msgtrace_hdr)); if (hdr.version != MSGTRACE_VERSION) { - DHD_ERROR( + BRCMF_ERROR( ("\nMACEVENT: %s [unsupported version --> " - "dhd version:%d dongle version:%d]\n", + "brcmf version:%d dongle version:%d]\n", event_name, MSGTRACE_VERSION, hdr.version) ); /* Reset datalen to avoid display below */ @@ -745,11 +678,12 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) } /* There are 2 bytes available at the end of data */ - buf[MSGTRACE_HDRLEN + be16_to_cpu(hdr.len)] = '\0'; + *(buf + sizeof(struct msgtrace_hdr) + + be16_to_cpu(hdr.len)) = '\0'; if (be32_to_cpu(hdr.discarded_bytes) || be32_to_cpu(hdr.discarded_printf)) { - DHD_ERROR( + BRCMF_ERROR( ("\nWLC_E_TRACE: [Discarded traces in dongle -->" "discarded_bytes %d discarded_printf %d]\n", be32_to_cpu(hdr.discarded_bytes), @@ -758,7 +692,7 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1; if (nblost > 0) { - DHD_ERROR( + BRCMF_ERROR( ("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n", be32_to_cpu(hdr.seqnum), nblost)); } @@ -768,7 +702,7 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) * avoid display big * printf (issue with Linux printk ) */ - p = (char *)&buf[MSGTRACE_HDRLEN]; + p = (char *)&buf[sizeof(struct msgtrace_hdr)]; while ((s = strstr(p, "\n")) != NULL) { *s = '\0'; printk(KERN_DEBUG"%s\n", p); @@ -781,49 +715,49 @@ static void wl_show_host_event(wl_event_msg_t *event, void *event_data) } break; - case WLC_E_RSSI: - DHD_EVENT(("MACEVENT: %s %d\n", event_name, - be32_to_cpu(*((int *)event_data)))); + case BRCMF_E_RSSI: + BRCMF_EVENT(("MACEVENT: %s %d\n", event_name, + be32_to_cpu(*((int *)event_data)))); break; default: - DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, " - "auth %d\n", event_name, event_type, eabuf, - (int)status, (int)reason, (int)auth_type)); + BRCMF_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, " + "auth %d\n", event_name, event_type, eabuf, + (int)status, (int)reason, (int)auth_type)); break; } /* show any appended data */ if (datalen) { buf = (unsigned char *) event_data; - DHD_EVENT((" data (%d) : ", datalen)); + BRCMF_EVENT((" data (%d) : ", datalen)); for (i = 0; i < datalen; i++) - DHD_EVENT((" 0x%02x ", *buf++)); - DHD_EVENT(("\n")); + BRCMF_EVENT((" 0x%02x ", *buf++)); + BRCMF_EVENT(("\n")); } } #endif /* SHOW_EVENTS */ int -wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event, void **data_ptr) +brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, + struct brcmf_event_msg *event, void **data_ptr) { /* check whether packet is a BRCM event pkt */ - bcm_event_t *pvt_data = (bcm_event_t *) pktdata; + struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata; char *event_data; u32 type, status; u16 flags; int evlen; - if (memcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) { - DHD_ERROR(("%s: mismatched OUI, bailing\n", __func__)); + if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) { + BRCMF_ERROR(("%s: mismatched OUI, bailing\n", __func__)); return -EBADE; } /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ - if (get_unaligned_be16(&pvt_data->bcm_hdr.usr_subtype) != + if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) { - DHD_ERROR(("%s: mismatched subtype, bailing\n", __func__)); + BRCMF_ERROR(("%s: mismatched subtype, bailing\n", __func__)); return -EBADE; } @@ -831,93 +765,87 @@ wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, event_data = *data_ptr; /* memcpy since BRCM event pkt may be unaligned. */ - memcpy(event, &pvt_data->event, sizeof(wl_event_msg_t)); + memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg)); type = get_unaligned_be32(&event->event_type); flags = get_unaligned_be16(&event->flags); status = get_unaligned_be32(&event->status); - evlen = get_unaligned_be32(&event->datalen) + sizeof(bcm_event_t); + evlen = get_unaligned_be32(&event->datalen) + + sizeof(struct brcmf_event); switch (type) { - case WLC_E_IF: + case BRCMF_E_IF: { - dhd_if_event_t *ifevent = (dhd_if_event_t *) event_data; - DHD_TRACE(("%s: if event\n", __func__)); + struct brcmf_if_event *ifevent = + (struct brcmf_if_event *) event_data; + BRCMF_TRACE(("%s: if event\n", __func__)); if (ifevent->ifidx > 0 && - ifevent->ifidx < DHD_MAX_IFS) { - if (ifevent->action == WLC_E_IF_ADD) - dhd_add_if(dhd, ifevent->ifidx, + ifevent->ifidx < BRCMF_MAX_IFS) { + if (ifevent->action == BRCMF_E_IF_ADD) + brcmf_add_if(drvr_priv, ifevent->ifidx, NULL, event->ifname, pvt_data->eth.h_dest, ifevent->flags, ifevent->bssidx); else - dhd_del_if(dhd, ifevent->ifidx); + brcmf_del_if(drvr_priv, ifevent->ifidx); } else { - DHD_ERROR(("%s: Invalid ifidx %d for %s\n", - __func__, ifevent->ifidx, - event->ifname)); + BRCMF_ERROR(("%s: Invalid ifidx %d for %s\n", + __func__, ifevent->ifidx, + event->ifname)); } } /* send up the if event: btamp user needs it */ - *ifidx = dhd_ifname2idx(dhd, event->ifname); - /* push up to external supp/auth */ - dhd_event(dhd, (char *)pvt_data, evlen, *ifidx); + *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname); break; -#ifdef P2P - case WLC_E_NDIS_LINK: - break; -#endif - /* fall through */ /* These are what external supplicant/authenticator wants */ - case WLC_E_LINK: - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC_IND: - case WLC_E_DISASSOC_IND: - case WLC_E_MIC_ERROR: + case BRCMF_E_LINK: + case BRCMF_E_ASSOC_IND: + case BRCMF_E_REASSOC_IND: + case BRCMF_E_DISASSOC_IND: + case BRCMF_E_MIC_ERROR: default: /* Fall through: this should get _everything_ */ - *ifidx = dhd_ifname2idx(dhd, event->ifname); - /* push up to external supp/auth */ - dhd_event(dhd, (char *)pvt_data, evlen, *ifidx); - DHD_TRACE(("%s: MAC event %d, flags %x, status %x\n", - __func__, type, flags, status)); + *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname); + BRCMF_TRACE(("%s: MAC event %d, flags %x, status %x\n", + __func__, type, flags, status)); - /* put it back to WLC_E_NDIS_LINK */ - if (type == WLC_E_NDIS_LINK) { + /* put it back to BRCMF_E_NDIS_LINK */ + if (type == BRCMF_E_NDIS_LINK) { u32 temp; temp = get_unaligned_be32(&event->event_type); - DHD_TRACE(("Converted to WLC_E_LINK type %d\n", temp)); + BRCMF_TRACE(("Converted to WLC_E_LINK type %d\n", + temp)); - temp = be32_to_cpu(WLC_E_NDIS_LINK); - memcpy((void *)(&pvt_data->event.event_type), &temp, - sizeof(pvt_data->event.event_type)); + temp = be32_to_cpu(BRCMF_E_NDIS_LINK); + memcpy((void *)(&pvt_data->msg.event_type), &temp, + sizeof(pvt_data->msg.event_type)); } break; } #ifdef SHOW_EVENTS - wl_show_host_event(event, event_data); + brcmf_c_show_host_event(event, event_data); #endif /* SHOW_EVENTS */ return 0; } /* Convert user's input in hex pattern to byte-size mask */ -static int wl_pattern_atoh(char *src, char *dst) +static int brcmf_c_pattern_atoh(char *src, char *dst) { int i; if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) { - DHD_ERROR(("Mask invalid format. Needs to start with 0x\n")); + BRCMF_ERROR(("Mask invalid format. Needs to start with 0x\n")); return -1; } src = src + 2; /* Skip past 0x */ if (strlen(src) % 2 != 0) { - DHD_ERROR(("Mask invalid format. Length must be even.\n")); + BRCMF_ERROR(("Mask invalid format. Length must be even.\n")); return -1; } for (i = 0; *src != '\0'; i++) { @@ -931,7 +859,7 @@ static int wl_pattern_atoh(char *src, char *dst) } void -dhd_pktfilter_offload_enable(dhd_pub_t *dhd, char *arg, int enable, +brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable, int master_mode) { char *argv[8]; @@ -942,12 +870,12 @@ dhd_pktfilter_offload_enable(dhd_pub_t *dhd, char *arg, int enable, char *arg_save = 0, *arg_org = 0; int rc; char buf[128]; - wl_pkt_filter_enable_t enable_parm; - wl_pkt_filter_enable_t *pkt_filterp; + struct brcmf_pkt_filter_enable enable_parm; + struct brcmf_pkt_filter_enable *pkt_filterp; arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC); if (!arg_save) { - DHD_ERROR(("%s: kmalloc failed\n", __func__)); + BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); goto fail; } arg_org = arg_save; @@ -957,7 +885,7 @@ dhd_pktfilter_offload_enable(dhd_pub_t *dhd, char *arg, int enable, i = 0; if (NULL == argv[i]) { - DHD_ERROR(("No args provided\n")); + BRCMF_ERROR(("No args provided\n")); goto fail; } @@ -967,7 +895,7 @@ dhd_pktfilter_offload_enable(dhd_pub_t *dhd, char *arg, int enable, buf[str_len] = '\0'; buf_len = str_len + 1; - pkt_filterp = (wl_pkt_filter_enable_t *) (buf + str_len + 1); + pkt_filterp = (struct brcmf_pkt_filter_enable *) (buf + str_len + 1); /* Parse packet filter id. */ enable_parm.id = simple_strtoul(argv[i], NULL, 0); @@ -979,33 +907,34 @@ dhd_pktfilter_offload_enable(dhd_pub_t *dhd, char *arg, int enable, memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm)); /* Enable/disable the specified filter. */ - rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len); + rc = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len); rc = rc >= 0 ? 0 : rc; if (rc) - DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __func__, arg, rc)); + BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", + __func__, arg, rc)); else - DHD_TRACE(("%s: successfully added pktfilter %s\n", - __func__, arg)); + BRCMF_TRACE(("%s: successfully added pktfilter %s\n", + __func__, arg)); /* Contorl the master mode */ - bcm_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf, + brcmu_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf, sizeof(buf)); - rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf)); + rc = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, buf, + sizeof(buf)); rc = rc >= 0 ? 0 : rc; if (rc) - DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __func__, arg, rc)); + BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", + __func__, arg, rc)); fail: kfree(arg_org); } -void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) +void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) { const char *str; - wl_pkt_filter_t pkt_filter; - wl_pkt_filter_t *pkt_filterp; + struct brcmf_pkt_filter pkt_filter; + struct brcmf_pkt_filter *pkt_filterp; int buf_len; int str_len; int rc; @@ -1014,29 +943,22 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) char *argv[8], *buf = 0; int i = 0; char *arg_save = 0, *arg_org = 0; -#define BUF_SIZE 2048 arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC); if (!arg_save) { - DHD_ERROR(("%s: kmalloc failed\n", __func__)); + BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); goto fail; } arg_org = arg_save; - buf = kmalloc(BUF_SIZE, GFP_ATOMIC); + buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC); if (!buf) { - DHD_ERROR(("%s: kmalloc failed\n", __func__)); + BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); goto fail; } - memcpy(arg_save, arg, strlen(arg) + 1); - - if (strlen(arg) > BUF_SIZE) { - DHD_ERROR(("Not enough buffer %d < %d\n", (int)strlen(arg), - (int)sizeof(buf))); - goto fail; - } + strcpy(arg_save, arg); argv[i] = strsep(&arg_save, " "); while (argv[i++]) @@ -1044,23 +966,22 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) i = 0; if (NULL == argv[i]) { - DHD_ERROR(("No args provided\n")); + BRCMF_ERROR(("No args provided\n")); goto fail; } str = "pkt_filter_add"; + strcpy(buf, str); str_len = strlen(str); - strncpy(buf, str, str_len); - buf[str_len] = '\0'; buf_len = str_len + 1; - pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1); + pkt_filterp = (struct brcmf_pkt_filter *) (buf + str_len + 1); /* Parse packet filter id. */ pkt_filter.id = simple_strtoul(argv[i], NULL, 0); if (NULL == argv[++i]) { - DHD_ERROR(("Polarity not provided\n")); + BRCMF_ERROR(("Polarity not provided\n")); goto fail; } @@ -1068,7 +989,7 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) pkt_filter.negate_match = simple_strtoul(argv[i], NULL, 0); if (NULL == argv[++i]) { - DHD_ERROR(("Filter type not provided\n")); + BRCMF_ERROR(("Filter type not provided\n")); goto fail; } @@ -1076,7 +997,7 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) pkt_filter.type = simple_strtoul(argv[i], NULL, 0); if (NULL == argv[++i]) { - DHD_ERROR(("Offset not provided\n")); + BRCMF_ERROR(("Offset not provided\n")); goto fail; } @@ -1084,34 +1005,34 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) pkt_filter.u.pattern.offset = simple_strtoul(argv[i], NULL, 0); if (NULL == argv[++i]) { - DHD_ERROR(("Bitmask not provided\n")); + BRCMF_ERROR(("Bitmask not provided\n")); goto fail; } /* Parse pattern filter mask. */ mask_size = - wl_pattern_atoh + brcmf_c_pattern_atoh (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern); if (NULL == argv[++i]) { - DHD_ERROR(("Pattern not provided\n")); + BRCMF_ERROR(("Pattern not provided\n")); goto fail; } /* Parse pattern filter pattern. */ pattern_size = - wl_pattern_atoh(argv[i], + brcmf_c_pattern_atoh(argv[i], (char *)&pkt_filterp->u.pattern. mask_and_pattern[mask_size]); if (mask_size != pattern_size) { - DHD_ERROR(("Mask and pattern not the same size\n")); + BRCMF_ERROR(("Mask and pattern not the same size\n")); goto fail; } pkt_filter.u.pattern.size_bytes = mask_size; - buf_len += WL_PKT_FILTER_FIXED_LEN; - buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); + buf_len += BRCMF_PKT_FILTER_FIXED_LEN; + buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); /* Keep-alive attributes are set in local * variable (keep_alive_pkt), and @@ -1120,17 +1041,17 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) */ memcpy((char *)pkt_filterp, &pkt_filter, - WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN); + BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN); - rc = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, buf_len); + rc = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len); rc = rc >= 0 ? 0 : rc; if (rc) - DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __func__, arg, rc)); + BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", + __func__, arg, rc)); else - DHD_TRACE(("%s: successfully added pktfilter %s\n", - __func__, arg)); + BRCMF_TRACE(("%s: successfully added pktfilter %s\n", + __func__, arg)); fail: kfree(arg_org); @@ -1138,711 +1059,138 @@ void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg) kfree(buf); } -void dhd_arp_offload_set(dhd_pub_t *dhd, int arp_mode) +void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode) { char iovbuf[32]; int retcode; - bcm_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf)); - retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + brcmu_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf)); + retcode = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, + iovbuf, sizeof(iovbuf)); retcode = retcode >= 0 ? 0 : retcode; if (retcode) - DHD_TRACE(("%s: failed to set ARP offload mode to 0x%x, " - "retcode = %d\n", __func__, arp_mode, retcode)); + BRCMF_TRACE(("%s: failed to set ARP offload mode to 0x%x, " + "retcode = %d\n", __func__, arp_mode, retcode)); else - DHD_TRACE(("%s: successfully set ARP offload mode to 0x%x\n", - __func__, arp_mode)); + BRCMF_TRACE(("%s: successfully set ARP offload mode to 0x%x\n", + __func__, arp_mode)); } -void dhd_arp_offload_enable(dhd_pub_t *dhd, int arp_enable) +void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable) { char iovbuf[32]; int retcode; - bcm_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf)); - retcode = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + brcmu_mkiovar("arpoe", (char *)&arp_enable, 4, iovbuf, sizeof(iovbuf)); + retcode = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, + iovbuf, sizeof(iovbuf)); retcode = retcode >= 0 ? 0 : retcode; if (retcode) - DHD_TRACE(("%s: failed to enabe ARP offload to %d, " - "retcode = %d\n", __func__, arp_enable, retcode)); + BRCMF_TRACE(("%s: failed to enabe ARP offload to %d, " + "retcode = %d\n", __func__, arp_enable, retcode)); else - DHD_TRACE(("%s: successfully enabed ARP offload to %d\n", - __func__, arp_enable)); + BRCMF_TRACE(("%s: successfully enabed ARP offload to %d\n", + __func__, arp_enable)); } -int dhd_preinit_ioctls(dhd_pub_t *dhd) +int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr) { - char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for + char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ uint up = 0; char buf[128], *ptr; uint power_mode = PM_FAST; - u32 dongle_align = DHD_SDALIGN; + u32 dongle_align = BRCMF_SDALIGN; u32 glom = 0; uint bcn_timeout = 3; int scan_assoc_time = 40; int scan_unassoc_time = 40; -#ifdef GET_CUSTOM_MAC_ENABLE - int ret = 0; - u8 ea_addr[ETH_ALEN]; -#endif /* GET_CUSTOM_MAC_ENABLE */ + int i; - dhd_os_proto_block(dhd); - -#ifdef GET_CUSTOM_MAC_ENABLE - /* Read MAC address from external customer place - ** NOTE that default mac address has to be present in - ** otp or nvram file to bring up - ** firmware but unique per board mac address maybe provided by - ** customer code - */ - ret = dhd_custom_get_mac_address(ea_addr); - if (!ret) { - bcm_mkiovar("cur_etheraddr", (void *)ea_addr, ETH_ALEN, - buf, sizeof(buf)); - ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf)); - if (ret < 0) { - DHD_ERROR(("%s: can't set MAC address , error=%d\n", - __func__, ret)); - } else - memcpy(dhd->mac.octet, (void *)&ea_addr, - ETH_ALEN); - } -#endif /* GET_CUSTOM_MAC_ENABLE */ + brcmf_os_proto_block(drvr); /* Set Country code */ - if (dhd->country_code[0] != 0) { - if (dhdcdc_set_ioctl(dhd, 0, WLC_SET_COUNTRY, - dhd->country_code, - sizeof(dhd->country_code)) < 0) { - DHD_ERROR(("%s: country code setting failed\n", - __func__)); + if (drvr->country_code[0] != 0) { + if (brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_COUNTRY, + drvr->country_code, + sizeof(drvr->country_code)) < 0) { + BRCMF_ERROR(("%s: country code setting failed\n", + __func__)); } } /* query for 'ver' to get version info from firmware */ memset(buf, 0, sizeof(buf)); ptr = buf; - bcm_mkiovar("ver", 0, 0, buf, sizeof(buf)); - dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, buf, sizeof(buf)); + brcmu_mkiovar("ver", 0, 0, buf, sizeof(buf)); + brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf)); strsep(&ptr, "\n"); /* Print fw version info */ - DHD_ERROR(("Firmware version = %s\n", buf)); + BRCMF_ERROR(("Firmware version = %s\n", buf)); /* Set PowerSave mode */ - dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, + brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_PM, (char *)&power_mode, sizeof(power_mode)); /* Match Host and Dongle rx alignment */ - bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, + brcmu_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf, + sizeof(iovbuf)); /* disable glom option per default */ - bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + brcmu_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); + brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf, + sizeof(iovbuf)); /* Setup timeout if Beacons are lost and roam is off to report link down */ - bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, + brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf, + sizeof(iovbuf)); /* Enable/Disable build-in roaming to allowed ext supplicant to take of romaing */ - bcm_mkiovar("roam_off", (char *)&dhd_roam, 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + brcmu_mkiovar("roam_off", (char *)&brcmf_roam, 4, + iovbuf, sizeof(iovbuf)); + brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf, + sizeof(iovbuf)); /* Force STA UP */ - if (dhd_radio_up) - dhdcdc_set_ioctl(dhd, 0, WLC_UP, (char *)&up, sizeof(up)); + if (brcmf_radio_up) + brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_UP, (char *)&up, + sizeof(up)); /* Setup event_msgs */ - bcm_mkiovar("event_msgs", dhd->eventmask, WL_EVENTING_MASK_LEN, iovbuf, - sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + brcmu_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, + iovbuf, sizeof(iovbuf)); + brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, iovbuf, + sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_CHANNEL_TIME, + brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME, (char *)&scan_assoc_time, sizeof(scan_assoc_time)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_SCAN_UNASSOC_TIME, + brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time, sizeof(scan_unassoc_time)); -#ifdef ARP_OFFLOAD_SUPPORT /* Set and enable ARP offload feature */ - if (dhd_arp_enable) - dhd_arp_offload_set(dhd, dhd_arp_mode); - dhd_arp_offload_enable(dhd, dhd_arp_enable); -#endif /* ARP_OFFLOAD_SUPPORT */ + if (brcmf_arp_enable) + brcmf_c_arp_offload_set(drvr, brcmf_arp_mode); + brcmf_c_arp_offload_enable(drvr, brcmf_arp_enable); -#ifdef PKT_FILTER_SUPPORT - { - int i; - /* Set up pkt filter */ - if (dhd_pkt_filter_enable) { - for (i = 0; i < dhd->pktfilter_count; i++) { - dhd_pktfilter_offload_set(dhd, - dhd->pktfilter[i]); - dhd_pktfilter_offload_enable(dhd, - dhd->pktfilter[i], - dhd_pkt_filter_init, - dhd_master_mode); - } + /* Set up pkt filter */ + if (brcmf_pkt_filter_enable) { + for (i = 0; i < drvr->pktfilter_count; i++) { + brcmf_c_pktfilter_offload_set(drvr, + drvr->pktfilter[i]); + brcmf_c_pktfilter_offload_enable(drvr, + drvr->pktfilter[i], + brcmf_pkt_filter_init, + brcmf_master_mode); } } -#endif /* PKT_FILTER_SUPPORT */ - dhd_os_proto_unblock(dhd); + brcmf_os_proto_unblock(drvr); return 0; } - -#ifdef SIMPLE_ISCAN -uint iscan_thread_id; -iscan_buf_t *iscan_chain; - -iscan_buf_t *dhd_iscan_allocate_buf(dhd_pub_t *dhd, iscan_buf_t **iscanbuf) -{ - iscan_buf_t *iscanbuf_alloc = 0; - iscan_buf_t *iscanbuf_head; - - dhd_iscan_lock(); - - iscanbuf_alloc = kmalloc(sizeof(iscan_buf_t), GFP_ATOMIC); - if (iscanbuf_alloc == NULL) - goto fail; - - iscanbuf_alloc->next = NULL; - iscanbuf_head = *iscanbuf; - - DHD_ISCAN(("%s: addr of allocated node = 0x%X" - "addr of iscanbuf_head = 0x%X dhd = 0x%X\n", - __func__, iscanbuf_alloc, iscanbuf_head, dhd)); - - if (iscanbuf_head == NULL) { - *iscanbuf = iscanbuf_alloc; - DHD_ISCAN(("%s: Head is allocated\n", __func__)); - goto fail; - } - - while (iscanbuf_head->next) - iscanbuf_head = iscanbuf_head->next; - - iscanbuf_head->next = iscanbuf_alloc; - -fail: - dhd_iscan_unlock(); - return iscanbuf_alloc; -} - -void dhd_iscan_free_buf(void *dhdp, iscan_buf_t *iscan_delete) -{ - iscan_buf_t *iscanbuf_free = 0; - iscan_buf_t *iscanbuf_prv = 0; - iscan_buf_t *iscanbuf_cur = iscan_chain; - dhd_pub_t *dhd = dhd_bus_pub(dhdp); - - dhd_iscan_lock(); - /* If iscan_delete is null then delete the entire - * chain or else delete specific one provided - */ - if (!iscan_delete) { - while (iscanbuf_cur) { - iscanbuf_free = iscanbuf_cur; - iscanbuf_cur = iscanbuf_cur->next; - iscanbuf_free->next = 0; - kfree(iscanbuf_free); - } - iscan_chain = 0; - } else { - while (iscanbuf_cur) { - if (iscanbuf_cur == iscan_delete) - break; - iscanbuf_prv = iscanbuf_cur; - iscanbuf_cur = iscanbuf_cur->next; - } - if (iscanbuf_prv) - iscanbuf_prv->next = iscan_delete->next; - - iscan_delete->next = 0; - kfree(iscan_delete); - - if (!iscanbuf_prv) - iscan_chain = 0; - } - dhd_iscan_unlock(); -} - -iscan_buf_t *dhd_iscan_result_buf(void) -{ - return iscan_chain; -} - -/* -* print scan cache -* print partial iscan_skip list differently -*/ -int dhd_iscan_print_cache(iscan_buf_t *iscan_skip) -{ - int i = 0, l = 0; - iscan_buf_t *iscan_cur; - wl_iscan_results_t *list; - wl_scan_results_t *results; - wl_bss_info_t UNALIGNED *bi; - - dhd_iscan_lock(); - - iscan_cur = dhd_iscan_result_buf(); - - while (iscan_cur) { - list = (wl_iscan_results_t *)iscan_cur->iscan_buf; - if (!list) - break; - - results = (wl_scan_results_t *)&list->results; - if (!results) - break; - - if (results->version != WL_BSS_INFO_VERSION) { - DHD_ISCAN(("%s: results->version %d != " - "WL_BSS_INFO_VERSION\n", - __func__, results->version)); - goto done; - } - - bi = results->bss_info; - for (i = 0; i < results->count; i++) { - if (!bi) - break; - - DHD_ISCAN(("%s[%2.2d:%2.2d] %X:%X:%X:%X:%X:%X\n", - iscan_cur != iscan_skip ? "BSS" : "bss", l, - i, bi->BSSID.octet[0], bi->BSSID.octet[1], - bi->BSSID.octet[2], bi->BSSID.octet[3], - bi->BSSID.octet[4], bi->BSSID.octet[5])); - - bi = (wl_bss_info_t *)((unsigned long)bi + bi->length); - } - iscan_cur = iscan_cur->next; - l++; - } - -done: - dhd_iscan_unlock(); - return 0; -} - -/* -* delete disappeared AP from specific scan cache but skip partial -* list in iscan_skip -*/ -int dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip) -{ - int i = 0, j = 0, l = 0; - iscan_buf_t *iscan_cur; - wl_iscan_results_t *list; - wl_scan_results_t *results; - wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next; - - unsigned char *s_addr = addr; - - dhd_iscan_lock(); - DHD_ISCAN(("%s: BSS to remove %X:%X:%X:%X:%X:%X\n", - __func__, s_addr[0], s_addr[1], s_addr[2], - s_addr[3], s_addr[4], s_addr[5])); - - iscan_cur = dhd_iscan_result_buf(); - - while (iscan_cur) { - if (iscan_cur != iscan_skip) { - list = (wl_iscan_results_t *)iscan_cur->iscan_buf; - if (!list) - break; - - results = (wl_scan_results_t *)&list->results; - if (!results) - break; - - if (results->version != WL_BSS_INFO_VERSION) { - DHD_ERROR(("%s: results->version %d != " - "WL_BSS_INFO_VERSION\n", - __func__, results->version)); - goto done; - } - - bi = results->bss_info; - for (i = 0; i < results->count; i++) { - if (!bi) - break; - - if (!memcmp - (bi->BSSID.octet, addr, ETH_ALEN)) { - DHD_ISCAN(("%s: Del BSS[%2.2d:%2.2d] " - "%X:%X:%X:%X:%X:%X\n", - __func__, l, i, bi->BSSID.octet[0], - bi->BSSID.octet[1], bi->BSSID.octet[2], - bi->BSSID.octet[3], bi->BSSID.octet[4], - bi->BSSID.octet[5])); - - bi_new = bi; - bi = (wl_bss_info_t *)((unsigned long) - bi + bi->length); -/* - if(bi && bi_new) { - memcpy(bi_new, bi, results->buflen - - bi_new->length); - results->buflen -= bi_new->length; - } -*/ - results->buflen -= bi_new->length; - results->count--; - - for (j = i; j < results->count; j++) { - if (bi && bi_new) { - DHD_ISCAN(("%s: Moved up BSS[%2.2d:%2.2d]" "%X:%X:%X:%X:%X:%X\n", - __func__, l, j, - bi->BSSID.octet[0], - bi->BSSID.octet[1], - bi->BSSID.octet[2], - bi->BSSID.octet[3], - bi->BSSID.octet[4], - bi->BSSID.octet[5])); - - bi_next = - (wl_bss_info_t *)((unsigned long)bi + - bi->length); - memcpy(bi_new, bi, - bi->length); - bi_new = - (wl_bss_info_t *)((unsigned long)bi_new + - bi_new-> - length); - bi = bi_next; - } - } - - if (results->count == 0) { - /* Prune now empty partial - scan list */ - dhd_iscan_free_buf(dhdp, - iscan_cur); - goto done; - } - break; - } - bi = (wl_bss_info_t *)((unsigned long)bi + - bi->length); - } - } - iscan_cur = iscan_cur->next; - l++; - } - -done: - dhd_iscan_unlock(); - return 0; -} - -int dhd_iscan_remove_duplicates(void *dhdp, iscan_buf_t *iscan_cur) -{ - int i = 0; - wl_iscan_results_t *list; - wl_scan_results_t *results; - wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next; - - dhd_iscan_lock(); - - DHD_ISCAN(("%s: Scan cache before delete\n", __func__)); - dhd_iscan_print_cache(iscan_cur); - - if (!iscan_cur) - goto done; - - list = (wl_iscan_results_t *)iscan_cur->iscan_buf; - if (!list) - goto done; - - results = (wl_scan_results_t *)&list->results; - if (!results) - goto done; - - if (results->version != WL_BSS_INFO_VERSION) { - DHD_ERROR(("%s: results->version %d != WL_BSS_INFO_VERSION\n", - __func__, results->version)); - goto done; - } - - bi = results->bss_info; - for (i = 0; i < results->count; i++) { - if (!bi) - break; - - DHD_ISCAN(("%s: Find dups for BSS[%2.2d] %X:%X:%X:%X:%X:%X\n", - __func__, i, bi->BSSID.octet[0], - bi->BSSID.octet[1], bi->BSSID.octet[2], - bi->BSSID.octet[3], bi->BSSID.octet[4], - bi->BSSID.octet[5])); - - dhd_iscan_delete_bss(dhdp, bi->BSSID.octet, iscan_cur); - - bi = (wl_bss_info_t *)((unsigned long)bi + bi->length); - } - -done: - DHD_ISCAN(("%s: Scan cache after delete\n", __func__)); - dhd_iscan_print_cache(iscan_cur); - dhd_iscan_unlock(); - return 0; -} - -void dhd_iscan_ind_scan_confirm(void *dhdp, bool status) -{ - - dhd_ind_scan_confirm(dhdp, status); -} - -int dhd_iscan_request(void *dhdp, u16 action) -{ - int rc; - wl_iscan_params_t params; - dhd_pub_t *dhd = dhd_bus_pub(dhdp); - char buf[WLC_IOCTL_SMLEN]; - - memset(¶ms, 0, sizeof(wl_iscan_params_t)); - memcpy(¶ms.params.bssid, ðer_bcast, ETH_ALEN); - - params.params.bss_type = DOT11_BSSTYPE_ANY; - params.params.scan_type = DOT11_SCANTYPE_ACTIVE; - - params.params.nprobes = -1; - params.params.active_time = -1; - params.params.passive_time = -1; - params.params.home_time = -1; - params.params.channel_num = 0; - - params.version = ISCAN_REQ_VERSION; - params.action = action; - params.scan_duration = 0; - - bcm_mkiovar("iscan", (char *)¶ms, sizeof(wl_iscan_params_t), buf, - WLC_IOCTL_SMLEN); - rc = dhd_wl_ioctl(dhdp, WLC_SET_VAR, buf, WLC_IOCTL_SMLEN); - - return rc; -} - -static int dhd_iscan_get_partial_result(void *dhdp, uint *scan_count) -{ - wl_iscan_results_t *list_buf; - wl_iscan_results_t list; - wl_scan_results_t *results; - iscan_buf_t *iscan_cur; - int status = -1; - dhd_pub_t *dhd = dhd_bus_pub(dhdp); - int rc; - - iscan_cur = dhd_iscan_allocate_buf(dhd, &iscan_chain); - if (!iscan_cur) { - DHD_ERROR(("%s: Failed to allocate node\n", __func__)); - dhd_iscan_free_buf(dhdp, 0); - dhd_iscan_request(dhdp, WL_SCAN_ACTION_ABORT); - goto fail; - } - - dhd_iscan_lock(); - - memset(iscan_cur->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN); - list_buf = (wl_iscan_results_t *) iscan_cur->iscan_buf; - results = &list_buf->results; - results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; - results->version = 0; - results->count = 0; - - memset(&list, 0, sizeof(list)); - list.results.buflen = WLC_IW_ISCAN_MAXLEN; - bcm_mkiovar("iscanresults", (char *)&list, WL_ISCAN_RESULTS_FIXED_SIZE, - iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN); - rc = dhd_wl_ioctl(dhdp, WLC_GET_VAR, iscan_cur->iscan_buf, - WLC_IW_ISCAN_MAXLEN); - - results->buflen = results->buflen; - results->version = results->version; - *scan_count = results->count = results->count; - status = list_buf->status; - - dhd_iscan_unlock(); - - if (!(*scan_count)) - dhd_iscan_free_buf(dhdp, iscan_cur); - else - dhd_iscan_remove_duplicates(dhdp, iscan_cur); - -fail: - return status; -} -#endif /* SIMPLE_ISCAN */ - -#ifdef PNO_SUPPORT -int dhd_pno_clean(dhd_pub_t *dhd) -{ - char iovbuf[128]; - int pfn_enabled = 0; - int iov_len = 0; - int ret; - - /* Disable pfn */ - iov_len = - bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, sizeof(iovbuf)); - ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - if (ret >= 0) { - /* clear pfn */ - iov_len = bcm_mkiovar("pfnclear", 0, 0, iovbuf, sizeof(iovbuf)); - if (iov_len) { - ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, - iov_len); - if (ret < 0) { - DHD_ERROR(("%s failed code %d\n", __func__, - ret)); - } - } else { - ret = -1; - DHD_ERROR(("%s failed code %d\n", __func__, iov_len)); - } - } else - DHD_ERROR(("%s failed code %d\n", __func__, ret)); - - return ret; -} - -int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled) -{ - char iovbuf[128]; - int ret = -1; - - if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) { - DHD_ERROR(("%s error exit\n", __func__)); - return ret; - } - - /* Enable/disable PNO */ - ret = bcm_mkiovar("pfn", (char *)&pfn_enabled, 4, iovbuf, - sizeof(iovbuf)); - if (ret > 0) { - ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, - sizeof(iovbuf)); - if (ret < 0) { - DHD_ERROR(("%s failed for error=%d\n", __func__, ret)); - return ret; - } else { - dhd->pno_enable = pfn_enabled; - DHD_TRACE(("%s set pno as %d\n", __func__, - dhd->pno_enable)); - } - } else - DHD_ERROR(("%s failed err=%d\n", __func__, ret)); - - return ret; -} - -/* Function to execute combined scan */ -int -dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t *ssids_local, int nssid, unsigned char scan_fr) -{ - int err = -1; - char iovbuf[128]; - int k, i; - wl_pfn_param_t pfn_param; - wl_pfn_t pfn_element; - - DHD_TRACE(("%s nssid=%d nchan=%d\n", __func__, nssid, scan_fr)); - - if ((!dhd) && (!ssids_local)) { - DHD_ERROR(("%s error exit\n", __func__)); - err = -1; - } - - /* Check for broadcast ssid */ - for (k = 0; k < nssid; k++) { - if (!ssids_local[k].SSID_len) { - DHD_ERROR(("%d: Broadcast SSID is ilegal for PNO " - "setting\n", k)); - return err; - } - } -/* #define PNO_DUMP 1 */ -#ifdef PNO_DUMP - { - int j; - for (j = 0; j < nssid; j++) { - DHD_ERROR(("%d: scan for %s size =%d\n", j, - ssids_local[j].SSID, - ssids_local[j].SSID_len)); - } - } -#endif /* PNO_DUMP */ - - /* clean up everything */ - err = dhd_pno_clean(dhd); - if (err < 0) { - DHD_ERROR(("%s failed error=%d\n", __func__, err)); - return err; - } - memset(&pfn_param, 0, sizeof(pfn_param)); - memset(&pfn_element, 0, sizeof(pfn_element)); - - /* set pfn parameters */ - pfn_param.version = PFN_VERSION; - pfn_param.flags = (PFN_LIST_ORDER << SORT_CRITERIA_BIT); - - /* set up pno scan fr */ - if (scan_fr != 0) - pfn_param.scan_freq = scan_fr; - - bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, - sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - - /* set all pfn ssid */ - for (i = 0; i < nssid; i++) { - - pfn_element.bss_type = DOT11_BSSTYPE_INFRASTRUCTURE; - pfn_element.auth = WLAN_AUTH_OPEN; - pfn_element.wpa_auth = WPA_AUTH_PFN_ANY; - pfn_element.wsec = 0; - pfn_element.infra = 1; - - memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID, - ssids_local[i].SSID_len); - pfn_element.ssid.SSID_len = ssids_local[i].SSID_len; - - err = bcm_mkiovar("pfn_add", (char *)&pfn_element, - sizeof(pfn_element), iovbuf, sizeof(iovbuf)); - if (err > 0) { - err = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, - sizeof(iovbuf)); - if (err < 0) { - DHD_ERROR(("%s failed for i=%d error=%d\n", - __func__, i, err)); - return err; - } - } else - DHD_ERROR(("%s failed err=%d\n", __func__, err)); - } - - /* Enable PNO */ - /* dhd_pno_enable(dhd, 1); */ - return err; -} - -int dhd_pno_get_status(dhd_pub_t *dhd) -{ - int ret = -1; - - if (!dhd) - return ret; - else - return dhd->pno_enable; -} - -#endif /* PNO_SUPPORT */ - -/* Androd ComboSCAN support */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c deleted file mode 100644 index 1cf6c5dc2bb7..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include - -#include -#include - -#include -#include - -#define WL_ERROR(fmt, args...) printk(fmt, ##args) -#define WL_TRACE(fmt, args...) no_printk(fmt, ##args) - -#ifdef CUSTOMER_HW -extern void bcm_wlan_power_off(int); -extern void bcm_wlan_power_on(int); -#endif /* CUSTOMER_HW */ -#ifdef CUSTOMER_HW2 -int wifi_set_carddetect(int on); -int wifi_set_power(int on, unsigned long msec); -int wifi_get_irq_number(unsigned long *irq_flags_ptr); -#endif - -#if defined(OOB_INTR_ONLY) - -#if defined(BCMLXSDMMC) -extern int sdioh_mmc_irq(int irq); -#endif /* (BCMLXSDMMC) */ - -#ifdef CUSTOMER_HW3 -#include -#endif - -/* Customer specific Host GPIO definition */ -static int dhd_oob_gpio_num = -1; /* GG 19 */ - -module_param(dhd_oob_gpio_num, int, 0644); -MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number"); - -int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr) -{ - int host_oob_irq = 0; - -#ifdef CUSTOMER_HW2 - host_oob_irq = wifi_get_irq_number(irq_flags_ptr); - -#else /* for NOT CUSTOMER_HW2 */ -#if defined(CUSTOM_OOB_GPIO_NUM) - if (dhd_oob_gpio_num < 0) - dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM; -#endif - - if (dhd_oob_gpio_num < 0) { - WL_ERROR("%s: ERROR customer specific Host GPIO is NOT defined\n", - __func__); - return dhd_oob_gpio_num; - } - - WL_ERROR("%s: customer specific Host GPIO number is (%d)\n", - __func__, dhd_oob_gpio_num); - -#if defined CUSTOMER_HW - host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num); -#elif defined CUSTOMER_HW3 - gpio_request(dhd_oob_gpio_num, "oob irq"); - host_oob_irq = gpio_to_irq(dhd_oob_gpio_num); - gpio_direction_input(dhd_oob_gpio_num); -#endif /* CUSTOMER_HW */ -#endif /* CUSTOMER_HW2 */ - - return host_oob_irq; -} -#endif /* defined(OOB_INTR_ONLY) */ - -/* Customer function to control hw specific wlan gpios */ -void dhd_customer_gpio_wlan_ctrl(int onoff) -{ - switch (onoff) { - case WLAN_RESET_OFF: - WL_TRACE("%s: call customer specific GPIO to insert WLAN RESET\n", - __func__); -#ifdef CUSTOMER_HW - bcm_wlan_power_off(2); -#endif /* CUSTOMER_HW */ -#ifdef CUSTOMER_HW2 - wifi_set_power(0, 0); -#endif - WL_ERROR("=========== WLAN placed in RESET ========\n"); - break; - - case WLAN_RESET_ON: - WL_TRACE("%s: callc customer specific GPIO to remove WLAN RESET\n", - __func__); -#ifdef CUSTOMER_HW - bcm_wlan_power_on(2); -#endif /* CUSTOMER_HW */ -#ifdef CUSTOMER_HW2 - wifi_set_power(1, 0); -#endif - WL_ERROR("=========== WLAN going back to live ========\n"); - break; - - case WLAN_POWER_OFF: - WL_TRACE("%s: call customer specific GPIO to turn off WL_REG_ON\n", - __func__); -#ifdef CUSTOMER_HW - bcm_wlan_power_off(1); -#endif /* CUSTOMER_HW */ - break; - - case WLAN_POWER_ON: - WL_TRACE("%s: call customer specific GPIO to turn on WL_REG_ON\n", - __func__); -#ifdef CUSTOMER_HW - bcm_wlan_power_on(1); -#endif /* CUSTOMER_HW */ - /* Lets customer power to get stable */ - udelay(200); - break; - } -} - -#ifdef GET_CUSTOM_MAC_ENABLE -/* Function to get custom MAC address */ -int dhd_custom_get_mac_address(unsigned char *buf) -{ - WL_TRACE("%s Enter\n", __func__); - if (!buf) - return -EINVAL; - - /* Customer access to MAC address stored outside of DHD driver */ - -#ifdef EXAMPLE_GET_MAC - /* EXAMPLE code */ - { - u8 ea_example[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xFF}; - memcpy(buf, ea_example, ETH_ALEN); - } -#endif /* EXAMPLE_GET_MAC */ - - return 0; -} -#endif /* GET_CUSTOM_MAC_ENABLE */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h b/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h index 0817f1348e09..5be4d7a609c2 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h @@ -14,90 +14,57 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _dhd_dbg_ -#define _dhd_dbg_ +#ifndef _BRCMF_DBG_H_ +#define _BRCMF_DBG_H_ -#if defined(DHD_DEBUG) +#if defined(BCMDBG) -#define DHD_ERROR(args) \ - do {if ((dhd_msg_level & DHD_ERROR_VAL) && (net_ratelimit())) \ +#define BRCMF_ERROR(args) \ + do {if ((brcmf_msg_level & BRCMF_ERROR_VAL) && (net_ratelimit())) \ printk args; } while (0) -#define DHD_TRACE(args) do {if (dhd_msg_level & DHD_TRACE_VAL) \ +#define BRCMF_TRACE(args) do {if (brcmf_msg_level & BRCMF_TRACE_VAL) \ printk args; } while (0) -#define DHD_INFO(args) do {if (dhd_msg_level & DHD_INFO_VAL) \ +#define BRCMF_INFO(args) do {if (brcmf_msg_level & BRCMF_INFO_VAL) \ printk args; } while (0) -#define DHD_DATA(args) do {if (dhd_msg_level & DHD_DATA_VAL) \ +#define BRCMF_DATA(args) do {if (brcmf_msg_level & BRCMF_DATA_VAL) \ printk args; } while (0) -#define DHD_CTL(args) do {if (dhd_msg_level & DHD_CTL_VAL) \ +#define BRCMF_CTL(args) do {if (brcmf_msg_level & BRCMF_CTL_VAL) \ printk args; } while (0) -#define DHD_TIMER(args) do {if (dhd_msg_level & DHD_TIMER_VAL) \ +#define BRCMF_TIMER(args) do {if (brcmf_msg_level & BRCMF_TIMER_VAL) \ printk args; } while (0) -#define DHD_HDRS(args) do {if (dhd_msg_level & DHD_HDRS_VAL) \ +#define BRCMF_INTR(args) do {if (brcmf_msg_level & BRCMF_INTR_VAL) \ printk args; } while (0) -#define DHD_BYTES(args) do {if (dhd_msg_level & DHD_BYTES_VAL) \ +#define BRCMF_GLOM(args) do {if (brcmf_msg_level & BRCMF_GLOM_VAL) \ printk args; } while (0) -#define DHD_INTR(args) do {if (dhd_msg_level & DHD_INTR_VAL) \ - printk args; } while (0) -#define DHD_GLOM(args) do {if (dhd_msg_level & DHD_GLOM_VAL) \ - printk args; } while (0) -#define DHD_EVENT(args) do {if (dhd_msg_level & DHD_EVENT_VAL) \ - printk args; } while (0) -#define DHD_BTA(args) do {if (dhd_msg_level & DHD_BTA_VAL) \ - printk args; } while (0) -#define DHD_ISCAN(args) do {if (dhd_msg_level & DHD_ISCAN_VAL) \ +#define BRCMF_EVENT(args) do {if (brcmf_msg_level & BRCMF_EVENT_VAL) \ printk args; } while (0) -#define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL) -#define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL) -#define DHD_INFO_ON() (dhd_msg_level & DHD_INFO_VAL) -#define DHD_DATA_ON() (dhd_msg_level & DHD_DATA_VAL) -#define DHD_CTL_ON() (dhd_msg_level & DHD_CTL_VAL) -#define DHD_TIMER_ON() (dhd_msg_level & DHD_TIMER_VAL) -#define DHD_HDRS_ON() (dhd_msg_level & DHD_HDRS_VAL) -#define DHD_BYTES_ON() (dhd_msg_level & DHD_BYTES_VAL) -#define DHD_INTR_ON() (dhd_msg_level & DHD_INTR_VAL) -#define DHD_GLOM_ON() (dhd_msg_level & DHD_GLOM_VAL) -#define DHD_EVENT_ON() (dhd_msg_level & DHD_EVENT_VAL) -#define DHD_BTA_ON() (dhd_msg_level & DHD_BTA_VAL) -#define DHD_ISCAN_ON() (dhd_msg_level & DHD_ISCAN_VAL) +#define BRCMF_DATA_ON() (brcmf_msg_level & BRCMF_DATA_VAL) +#define BRCMF_CTL_ON() (brcmf_msg_level & BRCMF_CTL_VAL) +#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL) +#define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL) +#define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL) -#else /* (defined BCMDBG) || (defined DHD_DEBUG) */ +#else /* (defined BCMDBG) || (defined BCMDBG) */ -#define DHD_ERROR(args) do {if (net_ratelimit()) printk args; } while (0) -#define DHD_TRACE(args) -#define DHD_INFO(args) -#define DHD_DATA(args) -#define DHD_CTL(args) -#define DHD_TIMER(args) -#define DHD_HDRS(args) -#define DHD_BYTES(args) -#define DHD_INTR(args) -#define DHD_GLOM(args) -#define DHD_EVENT(args) -#define DHD_BTA(args) -#define DHD_ISCAN(args) +#define BRCMF_ERROR(args) do {if (net_ratelimit()) printk args; } while (0) +#define BRCMF_TRACE(args) +#define BRCMF_INFO(args) +#define BRCMF_DATA(args) +#define BRCMF_CTL(args) +#define BRCMF_TIMER(args) +#define BRCMF_INTR(args) +#define BRCMF_GLOM(args) +#define BRCMF_EVENT(args) -#define DHD_ERROR_ON() 0 -#define DHD_TRACE_ON() 0 -#define DHD_INFO_ON() 0 -#define DHD_DATA_ON() 0 -#define DHD_CTL_ON() 0 -#define DHD_TIMER_ON() 0 -#define DHD_HDRS_ON() 0 -#define DHD_BYTES_ON() 0 -#define DHD_INTR_ON() 0 -#define DHD_GLOM_ON() 0 -#define DHD_EVENT_ON() 0 -#define DHD_BTA_ON() 0 -#define DHD_ISCAN_ON() 0 -#endif /* defined(DHD_DEBUG) */ +#define BRCMF_DATA_ON() 0 +#define BRCMF_CTL_ON() 0 +#define BRCMF_HDRS_ON() 0 +#define BRCMF_BYTES_ON() 0 +#define BRCMF_GLOM_ON() 0 -#define DHD_LOG(args) +#endif /* defined(BCMDBG) */ -#define DHD_NONE(args) -extern int dhd_msg_level; +extern int brcmf_msg_level; -/* Defines msg bits */ -#include - -#endif /* _dhd_dbg_ */ +#endif /* _BRCMF_DBG_H_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 09957bd6b79c..05dada98eb6b 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -14,9 +14,6 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifdef CONFIG_WIFI_CONTROL_FUNC -#include -#endif #include #include #include @@ -33,177 +30,32 @@ #include #include #include -#include -#include +#include +#include +#include +#include -#include -#include -#include -#include -#include - -#include - -#define EPI_VERSION_STR "4.218.248.5" -#define ETH_P_BRCM 0x886c - -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) -#include - -struct semaphore wifi_control_sem; - -struct dhd_bus *g_bus; - -static struct wifi_platform_data *wifi_control_data; -static struct resource *wifi_irqres; - -int wifi_get_irq_number(unsigned long *irq_flags_ptr) -{ - if (wifi_irqres) { - *irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK; - return (int)wifi_irqres->start; - } -#ifdef CUSTOM_OOB_GPIO_NUM - return CUSTOM_OOB_GPIO_NUM; -#else - return -1; -#endif -} - -int wifi_set_carddetect(int on) -{ - printk(KERN_ERR "%s = %d\n", __func__, on); - if (wifi_control_data && wifi_control_data->set_carddetect) - wifi_control_data->set_carddetect(on); - return 0; -} - -int wifi_set_power(int on, unsigned long msec) -{ - printk(KERN_ERR "%s = %d\n", __func__, on); - if (wifi_control_data && wifi_control_data->set_power) - wifi_control_data->set_power(on); - if (msec) - mdelay(msec); - return 0; -} - -int wifi_set_reset(int on, unsigned long msec) -{ - printk(KERN_ERR "%s = %d\n", __func__, on); - if (wifi_control_data && wifi_control_data->set_reset) - wifi_control_data->set_reset(on); - if (msec) - mdelay(msec); - return 0; -} - -static int wifi_probe(struct platform_device *pdev) -{ - struct wifi_platform_data *wifi_ctrl = - (struct wifi_platform_data *)(pdev->dev.platform_data); - - printk(KERN_ERR "## %s\n", __func__); - wifi_irqres = - platform_get_resource_byname(pdev, IORESOURCE_IRQ, - "bcm4329_wlan_irq"); - wifi_control_data = wifi_ctrl; - - wifi_set_power(1, 0); /* Power On */ - wifi_set_carddetect(1); /* CardDetect (0->1) */ - - up(&wifi_control_sem); - return 0; -} - -static int wifi_remove(struct platform_device *pdev) -{ - struct wifi_platform_data *wifi_ctrl = - (struct wifi_platform_data *)(pdev->dev.platform_data); - - printk(KERN_ERR "## %s\n", __func__); - wifi_control_data = wifi_ctrl; - - wifi_set_carddetect(0); /* CardDetect (1->0) */ - wifi_set_power(0, 0); /* Power Off */ - - up(&wifi_control_sem); - return 0; -} - -static int wifi_suspend(struct platform_device *pdev, pm_message_t state) -{ - DHD_TRACE(("##> %s\n", __func__)); - return 0; -} - -static int wifi_resume(struct platform_device *pdev) -{ - DHD_TRACE(("##> %s\n", __func__)); - return 0; -} - -static struct platform_driver wifi_device = { - .probe = wifi_probe, - .remove = wifi_remove, - .suspend = wifi_suspend, - .resume = wifi_resume, - .driver = { - .name = KBUILD_MODNAME, - } -}; - -int wifi_add_dev(void) -{ - DHD_TRACE(("## Calling platform_driver_register\n")); - return platform_driver_register(&wifi_device); -} - -void wifi_del_dev(void) -{ - DHD_TRACE(("## Unregister platform_driver_register\n")); - platform_driver_unregister(&wifi_device); -} -#endif /* defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */ +#include "dhd.h" +#include "dhd_bus.h" +#include "dhd_proto.h" +#include "dhd_dbg.h" +#include "wl_cfg80211.h" +#include "bcmchip.h" #if defined(CONFIG_PM_SLEEP) #include -atomic_t dhd_mmc_suspend; -DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait); +atomic_t brcmf_mmc_suspend; #endif /* defined(CONFIG_PM_SLEEP) */ -#if defined(OOB_INTR_ONLY) -extern void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable); -#endif /* defined(OOB_INTR_ONLY) */ - MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver."); MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); MODULE_LICENSE("Dual BSD/GPL"); -#define DRV_MODULE_NAME "brcmfmac" - -/* Linux wireless extension support */ -#if defined(CONFIG_WIRELESS_EXT) -#include -extern wl_iw_extra_params_t g_wl_iw_params; -#endif /* defined(CONFIG_WIRELESS_EXT) */ - -#if defined(CONFIG_HAS_EARLYSUSPEND) -#include -extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, - uint len); -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ - -#ifdef PKT_FILTER_SUPPORT -extern void dhd_pktfilter_offload_set(dhd_pub_t *dhd, char *arg); -extern void dhd_pktfilter_offload_enable(dhd_pub_t *dhd, char *arg, int enable, - int master_mode); -#endif /* Interface control information */ -typedef struct dhd_if { - struct dhd_info *info; /* back pointer to dhd_info */ +struct brcmf_if { + struct brcmf_info *info; /* back pointer to brcmf_info */ /* OS/stack specifics */ struct net_device *net; struct net_device_stats stats; @@ -214,33 +66,17 @@ typedef struct dhd_if { bool attached; /* Delayed attachment when unset */ bool txflowcontrol; /* Per interface flow control indicator */ char name[IFNAMSIZ]; /* linux interface name */ -} dhd_if_t; +}; /* Local private structure (extension of pub) */ -typedef struct dhd_info { -#if defined(CONFIG_WIRELESS_EXT) - wl_iw_t iw; /* wireless extensions state (must be first) */ -#endif /* defined(CONFIG_WIRELESS_EXT) */ - - dhd_pub_t pub; +struct brcmf_info { + struct brcmf_pub pub; /* OS/stack specifics */ - dhd_if_t *iflist[DHD_MAX_IFS]; + struct brcmf_if *iflist[BRCMF_MAX_IFS]; struct semaphore proto_sem; wait_queue_head_t ioctl_resp_wait; - struct timer_list timer; - bool wd_timer_valid; - struct tasklet_struct tasklet; - spinlock_t sdlock; - spinlock_t txqlock; - /* Thread based operation */ - bool threads_only; - struct semaphore sdsem; - struct task_struct *watchdog_tsk; - struct semaphore watchdog_sem; - struct task_struct *dpc_tsk; - struct semaphore dpc_sem; /* Thread to issue ioctl for multicast */ struct task_struct *sysioc_tsk; @@ -248,83 +84,44 @@ typedef struct dhd_info { bool set_multicast; bool set_macaddress; u8 macvalue[ETH_ALEN]; - wait_queue_head_t ctrl_wait; atomic_t pend_8021x_cnt; - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; -#endif /* CONFIG_HAS_EARLYSUSPEND */ -} dhd_info_t; - -/* Definitions to provide path to the firmware and nvram - * example nvram_path[MOD_PARAM_PATHLEN]="/projects/wlan/nvram.txt" - */ -char firmware_path[MOD_PARAM_PATHLEN]; -char nvram_path[MOD_PARAM_PATHLEN]; - -/* load firmware and/or nvram values from the filesystem */ -module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0); -module_param_string(nvram_path, nvram_path, MOD_PARAM_PATHLEN, 0); +}; /* Error bits */ -module_param(dhd_msg_level, int, 0); +module_param(brcmf_msg_level, int, 0); /* Spawn a thread for system ioctls (set mac, set mcast) */ -uint dhd_sysioc = true; -module_param(dhd_sysioc, uint, 0); - -/* Watchdog interval */ -uint dhd_watchdog_ms = 10; -module_param(dhd_watchdog_ms, uint, 0); - -#ifdef DHD_DEBUG -/* Console poll interval */ -uint dhd_console_ms; -module_param(dhd_console_ms, uint, 0); -#endif /* DHD_DEBUG */ +uint brcmf_sysioc = true; +module_param(brcmf_sysioc, uint, 0); /* ARP offload agent mode : Enable ARP Host Auto-Reply and ARP Peer Auto-Reply */ -uint dhd_arp_mode = 0xb; -module_param(dhd_arp_mode, uint, 0); +uint brcmf_arp_mode = 0xb; +module_param(brcmf_arp_mode, uint, 0); /* ARP offload enable */ -uint dhd_arp_enable = true; -module_param(dhd_arp_enable, uint, 0); +uint brcmf_arp_enable = true; +module_param(brcmf_arp_enable, uint, 0); /* Global Pkt filter enable control */ -uint dhd_pkt_filter_enable = true; -module_param(dhd_pkt_filter_enable, uint, 0); +uint brcmf_pkt_filter_enable = true; +module_param(brcmf_pkt_filter_enable, uint, 0); /* Pkt filter init setup */ -uint dhd_pkt_filter_init; -module_param(dhd_pkt_filter_init, uint, 0); +uint brcmf_pkt_filter_init; +module_param(brcmf_pkt_filter_init, uint, 0); /* Pkt filter mode control */ -uint dhd_master_mode = true; -module_param(dhd_master_mode, uint, 1); +uint brcmf_master_mode = true; +module_param(brcmf_master_mode, uint, 0); -/* Watchdog thread priority, -1 to use kernel timer */ -int dhd_watchdog_prio = 97; -module_param(dhd_watchdog_prio, int, 0); - -/* DPC thread priority, -1 to use tasklet */ -int dhd_dpc_prio = 98; -module_param(dhd_dpc_prio, int, 0); - -/* DPC thread priority, -1 to use tasklet */ -extern int dhd_dongle_memsize; -module_param(dhd_dongle_memsize, int, 0); +module_param(brcmf_dongle_memsize, int, 0); /* Contorl fw roaming */ -#ifdef CUSTOMER_HW2 -uint dhd_roam; -#else -uint dhd_roam = 1; -#endif +uint brcmf_roam = 1; /* Control radio state */ -uint dhd_radio_up = 1; +uint brcmf_radio_up = 1; /* Network inteface name */ char iface_name[IFNAMSIZ] = "wlan"; @@ -333,252 +130,58 @@ module_param_string(iface_name, iface_name, IFNAMSIZ, 0); /* The following are specific to the SDIO dongle */ /* IOCTL response timeout */ -int dhd_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT; +int brcmf_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT; /* Idle timeout for backplane clock */ -int dhd_idletime = DHD_IDLETIME_TICKS; -module_param(dhd_idletime, int, 0); +int brcmf_idletime = BRCMF_IDLETIME_TICKS; +module_param(brcmf_idletime, int, 0); /* Use polling */ -uint dhd_poll = false; -module_param(dhd_poll, uint, 0); - -/* Use cfg80211 */ -uint dhd_cfg80211 = true; -module_param(dhd_cfg80211, uint, 0); +uint brcmf_poll; +module_param(brcmf_poll, uint, 0); /* Use interrupts */ -uint dhd_intr = true; -module_param(dhd_intr, uint, 0); +uint brcmf_intr = true; +module_param(brcmf_intr, uint, 0); /* SDIO Drive Strength (in milliamps) */ -uint dhd_sdiod_drive_strength = 6; -module_param(dhd_sdiod_drive_strength, uint, 0); +uint brcmf_sdiod_drive_strength = 6; +module_param(brcmf_sdiod_drive_strength, uint, 0); /* Tx/Rx bounds */ -extern uint dhd_txbound; -extern uint dhd_rxbound; -module_param(dhd_txbound, uint, 0); -module_param(dhd_rxbound, uint, 0); - -/* Deferred transmits */ -extern uint dhd_deferred_tx; -module_param(dhd_deferred_tx, uint, 0); +module_param(brcmf_txbound, uint, 0); +module_param(brcmf_rxbound, uint, 0); #ifdef SDTEST /* Echo packet generator (pkts/s) */ -uint dhd_pktgen; -module_param(dhd_pktgen, uint, 0); +uint brcmf_pktgen; +module_param(brcmf_pktgen, uint, 0); /* Echo packet len (0 => sawtooth, max 2040) */ -uint dhd_pktgen_len; -module_param(dhd_pktgen_len, uint, 0); +uint brcmf_pktgen_len; +module_param(brcmf_pktgen_len, uint, 0); #endif -#define FAVORITE_WIFI_CP (!!dhd_cfg80211) -#define IS_CFG80211_FAVORITE() FAVORITE_WIFI_CP -#define DBG_CFG80211_GET() ((dhd_cfg80211 & WL_DBG_MASK) >> 1) -#define NO_FW_REQ() (dhd_cfg80211 & 0x80) - -/* Version string to report */ -#ifdef DHD_DEBUG -#define DHD_COMPILED "\nCompiled in " SRCBASE -#else -#define DHD_COMPILED -#endif - -static void dhd_dpc(unsigned long data); -/* forward decl */ -extern int dhd_wait_pend8021x(struct net_device *dev); - -#ifdef TOE -#ifndef BDC -#error TOE requires BDC -#endif /* !BDC */ -static int dhd_toe_get(dhd_info_t *dhd, int idx, u32 *toe_ol); -static int dhd_toe_set(dhd_info_t *dhd, int idx, u32 toe_ol); -#endif /* TOE */ - -static int dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event_ptr, void **data_ptr); - -#if defined(CONFIG_PM_SLEEP) -static int dhd_sleep_pm_callback(struct notifier_block *nfb, - unsigned long action, void *ignored) -{ - switch (action) { - case PM_HIBERNATION_PREPARE: - case PM_SUSPEND_PREPARE: - atomic_set(&dhd_mmc_suspend, true); - return NOTIFY_OK; - case PM_POST_HIBERNATION: - case PM_POST_SUSPEND: - atomic_set(&dhd_mmc_suspend, false); - return NOTIFY_OK; - } - return 0; -} - -static struct notifier_block dhd_sleep_pm_notifier = { - .notifier_call = dhd_sleep_pm_callback, - .priority = 0 -}; - -extern int register_pm_notifier(struct notifier_block *nb); -extern int unregister_pm_notifier(struct notifier_block *nb); -#endif /* defined(CONFIG_PM_SLEEP) */ - /* && defined(DHD_GPL) */ -static void dhd_set_packet_filter(int value, dhd_pub_t *dhd) -{ -#ifdef PKT_FILTER_SUPPORT - DHD_TRACE(("%s: %d\n", __func__, value)); - /* 1 - Enable packet filter, only allow unicast packet to send up */ - /* 0 - Disable packet filter */ - if (dhd_pkt_filter_enable) { - int i; - - for (i = 0; i < dhd->pktfilter_count; i++) { - dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]); - dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], - value, dhd_master_mode); - } - } -#endif -} - -#if defined(CONFIG_HAS_EARLYSUSPEND) -static int dhd_set_suspend(int value, dhd_pub_t *dhd) -{ - int power_mode = PM_MAX; - /* wl_pkt_filter_enable_t enable_parm; */ - char iovbuf[32]; - int bcn_li_dtim = 3; -#ifdef CUSTOMER_HW2 - uint roamvar = 1; -#endif /* CUSTOMER_HW2 */ - - DHD_TRACE(("%s: enter, value = %d in_suspend=%d\n", - __func__, value, dhd->in_suspend)); - - if (dhd && dhd->up) { - if (value && dhd->in_suspend) { - - /* Kernel suspended */ - DHD_TRACE(("%s: force extra Suspend setting\n", - __func__)); - - dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, - (char *)&power_mode, - sizeof(power_mode)); - - /* Enable packet filter, only allow unicast - packet to send up */ - dhd_set_packet_filter(1, dhd); - - /* if dtim skip setup as default force it - * to wake each third dtim - * for better power saving. - * Note that side effect is chance to miss BC/MC - * packet - */ - if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1)) - bcn_li_dtim = 3; - else - bcn_li_dtim = dhd->dtim_skip; - bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim, - 4, iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, - sizeof(iovbuf)); -#ifdef CUSTOMER_HW2 - /* Disable build-in roaming to allowed \ - * supplicant to take of romaing - */ - bcm_mkiovar("roam_off", (char *)&roamvar, 4, - iovbuf, sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, - sizeof(iovbuf)); -#endif /* CUSTOMER_HW2 */ - } else { - - /* Kernel resumed */ - DHD_TRACE(("%s: Remove extra suspend setting\n", - __func__)); - - power_mode = PM_FAST; - dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, - (char *)&power_mode, - sizeof(power_mode)); - - /* disable pkt filter */ - dhd_set_packet_filter(0, dhd); - - /* restore pre-suspend setting for dtim_skip */ - bcm_mkiovar("bcn_li_dtim", (char *)&dhd->dtim_skip, - 4, iovbuf, sizeof(iovbuf)); - - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, - sizeof(iovbuf)); -#ifdef CUSTOMER_HW2 - roamvar = 0; - bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, - sizeof(iovbuf)); - dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, - sizeof(iovbuf)); -#endif /* CUSTOMER_HW2 */ - } - } - - return 0; -} - -static void dhd_suspend_resume_helper(struct dhd_info *dhd, int val) -{ - dhd_pub_t *dhdp = &dhd->pub; - - dhd_os_proto_block(dhdp); - /* Set flag when early suspend was called */ - dhdp->in_suspend = val; - if (!dhdp->suspend_disable_flag) - dhd_set_suspend(val, dhdp); - dhd_os_proto_unblock(dhdp); -} - -static void dhd_early_suspend(struct early_suspend *h) -{ - struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend); - - DHD_TRACE(("%s: enter\n", __func__)); - - if (dhd) - dhd_suspend_resume_helper(dhd, 1); - -} - -static void dhd_late_resume(struct early_suspend *h) -{ - struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend); - - DHD_TRACE(("%s: enter\n", __func__)); - - if (dhd) - dhd_suspend_resume_helper(dhd, 0); -} -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ +static int brcmf_toe_get(struct brcmf_info *drvr_priv, int idx, u32 *toe_ol); +static int brcmf_toe_set(struct brcmf_info *drvr_priv, int idx, u32 toe_ol); +static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, + struct brcmf_event_msg *event_ptr, + void **data_ptr); /* * Generalized timeout mechanism. Uses spin sleep with exponential * back-off until * the sleep time reaches one jiffy, then switches over to task delay. Usage: * - * dhd_timeout_start(&tmo, usec); - * while (!dhd_timeout_expired(&tmo)) + * brcmf_timeout_start(&tmo, usec); + * while (!brcmf_timeout_expired(&tmo)) * if (poll_something()) * break; - * if (dhd_timeout_expired(&tmo)) + * if (brcmf_timeout_expired(&tmo)) * fatal(); */ -void dhd_timeout_start(dhd_timeout_t *tmo, uint usec) +void brcmf_timeout_start(struct brcmf_timeout *tmo, uint usec) { tmo->limit = usec; tmo->increment = 0; @@ -586,7 +189,7 @@ void dhd_timeout_start(dhd_timeout_t *tmo, uint usec) tmo->tick = 1000000 / HZ; } -int dhd_timeout_expired(dhd_timeout_t *tmo) +int brcmf_timeout_expired(struct brcmf_timeout *tmo) { /* Does nothing the first call */ if (tmo->increment == 0) { @@ -623,74 +226,68 @@ int dhd_timeout_expired(dhd_timeout_t *tmo) return 0; } -static int dhd_net2idx(dhd_info_t *dhd, struct net_device *net) +static int brcmf_net2idx(struct brcmf_info *drvr_priv, struct net_device *net) { int i = 0; - ASSERT(dhd); - while (i < DHD_MAX_IFS) { - if (dhd->iflist[i] && (dhd->iflist[i]->net == net)) + while (i < BRCMF_MAX_IFS) { + if (drvr_priv->iflist[i] && (drvr_priv->iflist[i]->net == net)) return i; i++; } - return DHD_BAD_IF; + return BRCMF_BAD_IF; } -int dhd_ifname2idx(dhd_info_t *dhd, char *name) +int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) { - int i = DHD_MAX_IFS; - - ASSERT(dhd); + int i = BRCMF_MAX_IFS; if (name == NULL || *name == '\0') return 0; while (--i > 0) - if (dhd->iflist[i] - && !strncmp(dhd->iflist[i]->name, name, IFNAMSIZ)) + if (drvr_priv->iflist[i] + && !strncmp(drvr_priv->iflist[i]->name, name, IFNAMSIZ)) break; - DHD_TRACE(("%s: return idx %d for \"%s\"\n", __func__, i, name)); + BRCMF_TRACE(("%s: return idx %d for \"%s\"\n", __func__, i, name)); return i; /* default - the primary interface */ } -char *dhd_ifname(dhd_pub_t *dhdp, int ifidx) +char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) { - dhd_info_t *dhd = (dhd_info_t *) dhdp->info; + struct brcmf_info *drvr_priv = drvr->info; - ASSERT(dhd); - - if (ifidx < 0 || ifidx >= DHD_MAX_IFS) { - DHD_ERROR(("%s: ifidx %d out of range\n", __func__, ifidx)); + if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { + BRCMF_ERROR(("%s: ifidx %d out of range\n", __func__, ifidx)); return ""; } - if (dhd->iflist[ifidx] == NULL) { - DHD_ERROR(("%s: null i/f %d\n", __func__, ifidx)); + if (drvr_priv->iflist[ifidx] == NULL) { + BRCMF_ERROR(("%s: null i/f %d\n", __func__, ifidx)); return ""; } - if (dhd->iflist[ifidx]->net) - return dhd->iflist[ifidx]->net->name; + if (drvr_priv->iflist[ifidx]->net) + return drvr_priv->iflist[ifidx]->net->name; return ""; } -static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) +static void _brcmf_set_multicast_list(struct brcmf_info *drvr_priv, int ifidx) { struct net_device *dev; struct netdev_hw_addr *ha; u32 allmulti, cnt; - wl_ioctl_t ioc; + struct brcmf_ioctl ioc; char *buf, *bufp; uint buflen; int ret; - ASSERT(dhd && dhd->iflist[ifidx]); - dev = dhd->iflist[ifidx]->net; + dev = drvr_priv->iflist[ifidx]->net; cnt = netdev_mc_count(dev); /* Determine initial value of allmulti flag */ @@ -701,8 +298,8 @@ static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN); bufp = buf = kmalloc(buflen, GFP_ATOMIC); if (!bufp) { - DHD_ERROR(("%s: out of memory for mcast_list, cnt %d\n", - dhd_ifname(&dhd->pub, ifidx), cnt)); + BRCMF_ERROR(("%s: out of memory for mcast_list, cnt %d\n", + brcmf_ifname(&drvr_priv->pub, ifidx), cnt)); return; } @@ -722,15 +319,15 @@ static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) } memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; + ioc.cmd = BRCMF_C_SET_VAR; ioc.buf = buf; ioc.len = buflen; ioc.set = true; - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); + ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { - DHD_ERROR(("%s: set mcast_list failed, cnt %d\n", - dhd_ifname(&dhd->pub, ifidx), cnt)); + BRCMF_ERROR(("%s: set mcast_list failed, cnt %d\n", + brcmf_ifname(&drvr_priv->pub, ifidx), cnt)); allmulti = cnt ? true : allmulti; } @@ -744,32 +341,33 @@ static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) buflen = sizeof("allmulti") + sizeof(allmulti); buf = kmalloc(buflen, GFP_ATOMIC); if (!buf) { - DHD_ERROR(("%s: out of memory for allmulti\n", - dhd_ifname(&dhd->pub, ifidx))); + BRCMF_ERROR(("%s: out of memory for allmulti\n", + brcmf_ifname(&drvr_priv->pub, ifidx))); return; } allmulti = cpu_to_le32(allmulti); - if (!bcm_mkiovar + if (!brcmu_mkiovar ("allmulti", (void *)&allmulti, sizeof(allmulti), buf, buflen)) { - DHD_ERROR(("%s: mkiovar failed for allmulti, datalen %d " - "buflen %u\n", dhd_ifname(&dhd->pub, ifidx), - (int)sizeof(allmulti), buflen)); + BRCMF_ERROR(("%s: mkiovar failed for allmulti, datalen %d " + "buflen %u\n", + brcmf_ifname(&drvr_priv->pub, ifidx), + (int)sizeof(allmulti), buflen)); kfree(buf); return; } memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; + ioc.cmd = BRCMF_C_SET_VAR; ioc.buf = buf; ioc.len = buflen; ioc.set = true; - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); + ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { - DHD_ERROR(("%s: set allmulti %d failed\n", - dhd_ifname(&dhd->pub, ifidx), - le32_to_cpu(allmulti))); + BRCMF_ERROR(("%s: set allmulti %d failed\n", + brcmf_ifname(&drvr_priv->pub, ifidx), + le32_to_cpu(allmulti))); } kfree(buf); @@ -781,45 +379,44 @@ static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) allmulti = cpu_to_le32(allmulti); memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_PROMISC; + ioc.cmd = BRCMF_C_SET_PROMISC; ioc.buf = &allmulti; ioc.len = sizeof(allmulti); ioc.set = true; - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); + ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { - DHD_ERROR(("%s: set promisc %d failed\n", - dhd_ifname(&dhd->pub, ifidx), - le32_to_cpu(allmulti))); + BRCMF_ERROR(("%s: set promisc %d failed\n", + brcmf_ifname(&drvr_priv->pub, ifidx), + le32_to_cpu(allmulti))); } } -static int -_dhd_set_mac_address(dhd_info_t *dhd, int ifidx, u8 *addr) +static int _brcmf_set_mac_address(struct brcmf_info *drvr_priv, int ifidx, u8 *addr) { char buf[32]; - wl_ioctl_t ioc; + struct brcmf_ioctl ioc; int ret; - DHD_TRACE(("%s enter\n", __func__)); - if (!bcm_mkiovar + BRCMF_TRACE(("%s enter\n", __func__)); + if (!brcmu_mkiovar ("cur_etheraddr", (char *)addr, ETH_ALEN, buf, 32)) { - DHD_ERROR(("%s: mkiovar failed for cur_etheraddr\n", - dhd_ifname(&dhd->pub, ifidx))); + BRCMF_ERROR(("%s: mkiovar failed for cur_etheraddr\n", + brcmf_ifname(&drvr_priv->pub, ifidx))); return -1; } memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; + ioc.cmd = BRCMF_C_SET_VAR; ioc.buf = buf; ioc.len = 32; ioc.set = true; - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); + ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { - DHD_ERROR(("%s: set cur_etheraddr failed\n", - dhd_ifname(&dhd->pub, ifidx))); + BRCMF_ERROR(("%s: set cur_etheraddr failed\n", + brcmf_ifname(&drvr_priv->pub, ifidx))); } else { - memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETH_ALEN); + memcpy(drvr_priv->iflist[ifidx]->net->dev_addr, addr, ETH_ALEN); } return ret; @@ -829,45 +426,44 @@ _dhd_set_mac_address(dhd_info_t *dhd, int ifidx, u8 *addr) extern struct net_device *ap_net_dev; #endif -static void dhd_op_if(dhd_if_t *ifp) +/* Virtual interfaces only ((ifp && ifp->info && ifp->idx == true) */ +static void brcmf_op_if(struct brcmf_if *ifp) { - dhd_info_t *dhd; + struct brcmf_info *drvr_priv; int ret = 0, err = 0; - ASSERT(ifp && ifp->info && ifp->idx); /* Virtual interfaces only */ + drvr_priv = ifp->info; - dhd = ifp->info; - - DHD_TRACE(("%s: idx %d, state %d\n", __func__, ifp->idx, ifp->state)); + BRCMF_TRACE(("%s: idx %d, state %d\n", __func__, ifp->idx, ifp->state)); switch (ifp->state) { - case WLC_E_IF_ADD: + case BRCMF_E_IF_ADD: /* * Delete the existing interface before overwriting it - * in case we missed the WLC_E_IF_DEL event. + * in case we missed the BRCMF_E_IF_DEL event. */ if (ifp->net != NULL) { - DHD_ERROR(("%s: ERROR: netdev:%s already exists, " - "try free & unregister\n", - __func__, ifp->net->name)); + BRCMF_ERROR(("%s: ERROR: netdev:%s already exists, " + "try free & unregister\n", + __func__, ifp->net->name)); netif_stop_queue(ifp->net); unregister_netdev(ifp->net); free_netdev(ifp->net); } /* Allocate etherdev, including space for private structure */ - ifp->net = alloc_etherdev(sizeof(dhd)); + ifp->net = alloc_etherdev(sizeof(drvr_priv)); if (!ifp->net) { - DHD_ERROR(("%s: OOM - alloc_etherdev\n", __func__)); + BRCMF_ERROR(("%s: OOM - alloc_etherdev\n", __func__)); ret = -ENOMEM; } if (ret == 0) { strcpy(ifp->net->name, ifp->name); - memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd)); - err = dhd_net_attach(&dhd->pub, ifp->idx); + memcpy(netdev_priv(ifp->net), &drvr_priv, sizeof(drvr_priv)); + err = brcmf_net_attach(&drvr_priv->pub, ifp->idx); if (err != 0) { - DHD_ERROR(("%s: dhd_net_attach failed, " - "err %d\n", - __func__, err)); + BRCMF_ERROR(("%s: brcmf_net_attach failed, " + "err %d\n", + __func__, err)); ret = -EOPNOTSUPP; } else { #ifdef SOFTAP @@ -882,26 +478,25 @@ static void dhd_op_if(dhd_if_t *ifp) wl0.1 is ready */ up(&ap_eth_sema); #endif - DHD_TRACE(("\n ==== pid:%x, net_device for " - "if:%s created ===\n\n", - current->pid, ifp->net->name)); + BRCMF_TRACE(("\n ==== pid:%x, net_device for " + "if:%s created ===\n\n", + current->pid, ifp->net->name)); ifp->state = 0; } } break; - case WLC_E_IF_DEL: + case BRCMF_E_IF_DEL: if (ifp->net != NULL) { - DHD_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n", - __func__)); + BRCMF_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n", + __func__)); netif_stop_queue(ifp->net); unregister_netdev(ifp->net); - ret = DHD_DEL_IF; /* Make sure the free_netdev() + ret = BRCMF_DEL_IF; /* Make sure the free_netdev() is called */ } break; default: - DHD_ERROR(("%s: bad op %d\n", __func__, ifp->state)); - ASSERT(!ifp->state); + BRCMF_ERROR(("%s: bad op %d\n", __func__, ifp->state)); break; } @@ -909,7 +504,7 @@ static void dhd_op_if(dhd_if_t *ifp) if (ifp->net) free_netdev(ifp->net); - dhd->iflist[ifp->idx] = NULL; + drvr_priv->iflist[ifp->idx] = NULL; kfree(ifp); #ifdef SOFTAP if (ifp->net == ap_net_dev) @@ -919,9 +514,9 @@ static void dhd_op_if(dhd_if_t *ifp) } } -static int _dhd_sysioc_thread(void *data) +static int _brcmf_sysioc_thread(void *data) { - dhd_info_t *dhd = (dhd_info_t *) data; + struct brcmf_info *drvr_priv = (struct brcmf_info *) data; int i; #ifdef SOFTAP bool in_ap = false; @@ -929,46 +524,51 @@ static int _dhd_sysioc_thread(void *data) allow_signal(SIGTERM); - while (down_interruptible(&dhd->sysioc_sem) == 0) { + while (down_interruptible(&drvr_priv->sysioc_sem) == 0) { if (kthread_should_stop()) break; - for (i = 0; i < DHD_MAX_IFS; i++) { - if (dhd->iflist[i]) { + for (i = 0; i < BRCMF_MAX_IFS; i++) { + struct brcmf_if *ifentry = drvr_priv->iflist[i]; + if (ifentry) { #ifdef SOFTAP in_ap = (ap_net_dev != NULL); #endif /* SOFTAP */ - if (dhd->iflist[i]->state) - dhd_op_if(dhd->iflist[i]); + if (ifentry->state) + brcmf_op_if(ifentry); #ifdef SOFTAP - if (dhd->iflist[i] == NULL) { - DHD_TRACE(("\n\n %s: interface %d " - "removed!\n", __func__, i)); + if (drvr_priv->iflist[i] == NULL) { + BRCMF_TRACE(("\n\n %s: interface %d " + "removed!\n", __func__, + i)); continue; } - if (in_ap && dhd->set_macaddress) { - DHD_TRACE(("attempt to set MAC for %s " - "in AP Mode," "blocked. \n", - dhd->iflist[i]->net->name)); - dhd->set_macaddress = false; + if (in_ap && drvr_priv->set_macaddress) { + BRCMF_TRACE(("attempt to set MAC for" + " %s in AP Mode," + " blocked.\n", + ifentry->net->name)); + drvr_priv->set_macaddress = false; continue; } - if (in_ap && dhd->set_multicast) { - DHD_TRACE(("attempt to set MULTICAST list for %s" "in AP Mode, blocked. \n", - dhd->iflist[i]->net->name)); - dhd->set_multicast = false; + if (in_ap && drvr_priv->set_multicast) { + BRCMF_TRACE(("attempt to set MULTICAST " + "list for %s in AP Mode, " + "blocked.\n", + ifentry->net->name)); + drvr_priv->set_multicast = false; continue; } #endif /* SOFTAP */ - if (dhd->set_multicast) { - dhd->set_multicast = false; - _dhd_set_multicast_list(dhd, i); + if (drvr_priv->set_multicast) { + drvr_priv->set_multicast = false; + _brcmf_set_multicast_list(drvr_priv, i); } - if (dhd->set_macaddress) { - dhd->set_macaddress = false; - _dhd_set_mac_address(dhd, i, - dhd->macvalue); + if (drvr_priv->set_macaddress) { + drvr_priv->set_macaddress = false; + _brcmf_set_mac_address(drvr_priv, i, + drvr_priv->macvalue); } } } @@ -976,47 +576,44 @@ static int _dhd_sysioc_thread(void *data) return 0; } -static int dhd_set_mac_address(struct net_device *dev, void *addr) +static int brcmf_netdev_set_mac_address(struct net_device *dev, void *addr) { int ret = 0; - dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev); + struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(dev); struct sockaddr *sa = (struct sockaddr *)addr; int ifidx; - ifidx = dhd_net2idx(dhd, dev); - if (ifidx == DHD_BAD_IF) + ifidx = brcmf_net2idx(drvr_priv, dev); + if (ifidx == BRCMF_BAD_IF) return -1; - ASSERT(dhd->sysioc_tsk); - memcpy(&dhd->macvalue, sa->sa_data, ETH_ALEN); - dhd->set_macaddress = true; - up(&dhd->sysioc_sem); + memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN); + drvr_priv->set_macaddress = true; + up(&drvr_priv->sysioc_sem); return ret; } -static void dhd_set_multicast_list(struct net_device *dev) +static void brcmf_netdev_set_multicast_list(struct net_device *dev) { - dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev); + struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(dev); int ifidx; - ifidx = dhd_net2idx(dhd, dev); - if (ifidx == DHD_BAD_IF) + ifidx = brcmf_net2idx(drvr_priv, dev); + if (ifidx == BRCMF_BAD_IF) return; - ASSERT(dhd->sysioc_tsk); - dhd->set_multicast = true; - up(&dhd->sysioc_sem); + drvr_priv->set_multicast = true; + up(&drvr_priv->sysioc_sem); } -int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) +int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf) { - int ret; - dhd_info_t *dhd = (dhd_info_t *) (dhdp->info); + struct brcmf_info *drvr_priv = drvr->info; /* Reject if down */ - if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN)) + if (!drvr->up || (drvr->busstate == BRCMF_BUS_DOWN)) return -ENODEV; /* Update multicast statistic */ @@ -1025,143 +622,107 @@ int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) struct ethhdr *eh = (struct ethhdr *)pktdata; if (is_multicast_ether_addr(eh->h_dest)) - dhdp->tx_multicast++; + drvr->tx_multicast++; if (ntohs(eh->h_proto) == ETH_P_PAE) - atomic_inc(&dhd->pend_8021x_cnt); + atomic_inc(&drvr_priv->pend_8021x_cnt); } /* If the protocol uses a data header, apply it */ - dhd_prot_hdrpush(dhdp, ifidx, pktbuf); + brcmf_proto_hdrpush(drvr, ifidx, pktbuf); /* Use bus module to send data frame */ -#ifdef BCMDBUS - ret = dbus_send_pkt(dhdp->dbus, pktbuf, NULL /* pktinfo */); -#else - ret = dhd_bus_txdata(dhdp->bus, pktbuf); -#endif /* BCMDBUS */ - - return ret; + return brcmf_sdbrcm_bus_txdata(drvr->bus, pktbuf); } -static inline void * -osl_pkt_frmnative(struct sk_buff *skb) -{ - return (void *)skb; -} -#define PKTFRMNATIVE(osh, skb) \ - osl_pkt_frmnative((struct sk_buff *)(skb)) - -static inline struct sk_buff * -osl_pkt_tonative(void *pkt) -{ - return (struct sk_buff *)pkt; -} -#define PKTTONATIVE(osh, pkt) \ - osl_pkt_tonative((pkt)) - -static int dhd_start_xmit(struct sk_buff *skb, struct net_device *net) +static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *net) { int ret; - void *pktbuf; - dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net); + struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); int ifidx; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); /* Reject if down */ - if (!dhd->pub.up || (dhd->pub.busstate == DHD_BUS_DOWN)) { - DHD_ERROR(("%s: xmit rejected pub.up=%d busstate=%d\n", - __func__, dhd->pub.up, dhd->pub.busstate)); + if (!drvr_priv->pub.up || (drvr_priv->pub.busstate == BRCMF_BUS_DOWN)) { + BRCMF_ERROR(("%s: xmit rejected pub.up=%d busstate=%d\n", + __func__, drvr_priv->pub.up, + drvr_priv->pub.busstate)); netif_stop_queue(net); return -ENODEV; } - ifidx = dhd_net2idx(dhd, net); - if (ifidx == DHD_BAD_IF) { - DHD_ERROR(("%s: bad ifidx %d\n", __func__, ifidx)); + ifidx = brcmf_net2idx(drvr_priv, net); + if (ifidx == BRCMF_BAD_IF) { + BRCMF_ERROR(("%s: bad ifidx %d\n", __func__, ifidx)); netif_stop_queue(net); return -ENODEV; } /* Make sure there's enough room for any header */ - if (skb_headroom(skb) < dhd->pub.hdrlen) { + if (skb_headroom(skb) < drvr_priv->pub.hdrlen) { struct sk_buff *skb2; - DHD_INFO(("%s: insufficient headroom\n", - dhd_ifname(&dhd->pub, ifidx))); - dhd->pub.tx_realloc++; - skb2 = skb_realloc_headroom(skb, dhd->pub.hdrlen); + BRCMF_INFO(("%s: insufficient headroom\n", + brcmf_ifname(&drvr_priv->pub, ifidx))); + drvr_priv->pub.tx_realloc++; + skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen); dev_kfree_skb(skb); skb = skb2; if (skb == NULL) { - DHD_ERROR(("%s: skb_realloc_headroom failed\n", - dhd_ifname(&dhd->pub, ifidx))); + BRCMF_ERROR(("%s: skb_realloc_headroom failed\n", + brcmf_ifname(&drvr_priv->pub, ifidx))); ret = -ENOMEM; goto done; } } - /* Convert to packet */ - pktbuf = PKTFRMNATIVE(dhd->pub.osh, skb); - if (!pktbuf) { - DHD_ERROR(("%s: PKTFRMNATIVE failed\n", - dhd_ifname(&dhd->pub, ifidx))); - dev_kfree_skb_any(skb); - ret = -ENOMEM; - goto done; - } - - ret = dhd_sendpkt(&dhd->pub, ifidx, pktbuf); + ret = brcmf_sendpkt(&drvr_priv->pub, ifidx, skb); done: if (ret) - dhd->pub.dstats.tx_dropped++; + drvr_priv->pub.dstats.tx_dropped++; else - dhd->pub.tx_packets++; + drvr_priv->pub.tx_packets++; /* Return ok: we always eat the packet */ return 0; } -void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state) +void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool state) { struct net_device *net; - dhd_info_t *dhd = dhdp->info; + struct brcmf_info *drvr_priv = drvr->info; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - dhdp->txoff = state; - ASSERT(dhd && dhd->iflist[ifidx]); - net = dhd->iflist[ifidx]->net; + drvr->txoff = state; + net = drvr_priv->iflist[ifidx]->net; if (state == ON) netif_stop_queue(net); else netif_wake_queue(net); } -void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf, +void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb, int numpkt) { - dhd_info_t *dhd = (dhd_info_t *) dhdp->info; - struct sk_buff *skb; + struct brcmf_info *drvr_priv = drvr->info; unsigned char *eth; uint len; void *data; struct sk_buff *pnext, *save_pktbuf; int i; - dhd_if_t *ifp; - wl_event_msg_t event; + struct brcmf_if *ifp; + struct brcmf_event_msg event; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - save_pktbuf = pktbuf; + save_pktbuf = skb; - for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) { + for (i = 0; skb && i < numpkt; i++, skb = pnext) { - pnext = pktbuf->next; - pktbuf->next = NULL; - - skb = PKTTONATIVE(dhdp->osh, pktbuf); + pnext = skb->next; + skb->next = NULL; /* Get the protocol, maintain skb around eth_type_trans() * The main reason for this hack is for the limitation of @@ -1178,16 +739,15 @@ void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf, eth = skb->data; len = skb->len; - ifp = dhd->iflist[ifidx]; + ifp = drvr_priv->iflist[ifidx]; if (ifp == NULL) - ifp = dhd->iflist[0]; + ifp = drvr_priv->iflist[0]; - ASSERT(ifp); skb->dev = ifp->net; skb->protocol = eth_type_trans(skb, skb->dev); if (skb->pkt_type == PACKET_MULTICAST) - dhd->pub.rx_multicast++; + drvr_priv->pub.rx_multicast++; skb->data = eth; skb->len = len; @@ -1196,20 +756,20 @@ void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf, skb_pull(skb, ETH_HLEN); /* Process special event packets and then discard them */ - if (ntohs(skb->protocol) == ETH_P_BRCM) - dhd_wl_host_event(dhd, &ifidx, + if (ntohs(skb->protocol) == ETH_P_LINK_CTL) + brcmf_host_event(drvr_priv, &ifidx, skb_mac_header(skb), &event, &data); - ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]); - if (dhd->iflist[ifidx] && !dhd->iflist[ifidx]->state) - ifp = dhd->iflist[ifidx]; + if (drvr_priv->iflist[ifidx] && + !drvr_priv->iflist[ifidx]->state) + ifp = drvr_priv->iflist[ifidx]; if (ifp->net) ifp->net->last_rx = jiffies; - dhdp->dstats.rx_bytes += skb->len; - dhdp->rx_packets++; /* Local count */ + drvr->dstats.rx_bytes += skb->len; + drvr->rx_packets++; /* Local count */ if (in_interrupt()) { netif_rx(skb); @@ -1225,216 +785,83 @@ void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf, } } -void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx) -{ - /* Linux version has nothing to do */ - return; -} - -void dhd_txcomplete(dhd_pub_t *dhdp, struct sk_buff *txp, bool success) +void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success) { uint ifidx; - dhd_info_t *dhd = (dhd_info_t *) (dhdp->info); + struct brcmf_info *drvr_priv = drvr->info; struct ethhdr *eh; u16 type; - dhd_prot_hdrpull(dhdp, &ifidx, txp); + brcmf_proto_hdrpull(drvr, &ifidx, txp); eh = (struct ethhdr *)(txp->data); type = ntohs(eh->h_proto); if (type == ETH_P_PAE) - atomic_dec(&dhd->pend_8021x_cnt); + atomic_dec(&drvr_priv->pend_8021x_cnt); } -static struct net_device_stats *dhd_get_stats(struct net_device *net) +static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *net) { - dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net); - dhd_if_t *ifp; + struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); + struct brcmf_if *ifp; int ifidx; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - ifidx = dhd_net2idx(dhd, net); - if (ifidx == DHD_BAD_IF) + ifidx = brcmf_net2idx(drvr_priv, net); + if (ifidx == BRCMF_BAD_IF) return NULL; - ifp = dhd->iflist[ifidx]; - ASSERT(dhd && ifp); + ifp = drvr_priv->iflist[ifidx]; - if (dhd->pub.up) { + if (drvr_priv->pub.up) { /* Use the protocol to get dongle stats */ - dhd_prot_dstats(&dhd->pub); + brcmf_proto_dstats(&drvr_priv->pub); } /* Copy dongle stats to net device stats */ - ifp->stats.rx_packets = dhd->pub.dstats.rx_packets; - ifp->stats.tx_packets = dhd->pub.dstats.tx_packets; - ifp->stats.rx_bytes = dhd->pub.dstats.rx_bytes; - ifp->stats.tx_bytes = dhd->pub.dstats.tx_bytes; - ifp->stats.rx_errors = dhd->pub.dstats.rx_errors; - ifp->stats.tx_errors = dhd->pub.dstats.tx_errors; - ifp->stats.rx_dropped = dhd->pub.dstats.rx_dropped; - ifp->stats.tx_dropped = dhd->pub.dstats.tx_dropped; - ifp->stats.multicast = dhd->pub.dstats.multicast; + ifp->stats.rx_packets = drvr_priv->pub.dstats.rx_packets; + ifp->stats.tx_packets = drvr_priv->pub.dstats.tx_packets; + ifp->stats.rx_bytes = drvr_priv->pub.dstats.rx_bytes; + ifp->stats.tx_bytes = drvr_priv->pub.dstats.tx_bytes; + ifp->stats.rx_errors = drvr_priv->pub.dstats.rx_errors; + ifp->stats.tx_errors = drvr_priv->pub.dstats.tx_errors; + ifp->stats.rx_dropped = drvr_priv->pub.dstats.rx_dropped; + ifp->stats.tx_dropped = drvr_priv->pub.dstats.tx_dropped; + ifp->stats.multicast = drvr_priv->pub.dstats.multicast; return &ifp->stats; } -static int dhd_watchdog_thread(void *data) -{ - dhd_info_t *dhd = (dhd_info_t *) data; - - /* This thread doesn't need any user-level access, - * so get rid of all our resources - */ -#ifdef DHD_SCHED - if (dhd_watchdog_prio > 0) { - struct sched_param param; - param.sched_priority = (dhd_watchdog_prio < MAX_RT_PRIO) ? - dhd_watchdog_prio : (MAX_RT_PRIO - 1); - setScheduler(current, SCHED_FIFO, ¶m); - } -#endif /* DHD_SCHED */ - - allow_signal(SIGTERM); - /* Run until signal received */ - while (1) { - if (kthread_should_stop()) - break; - if (down_interruptible(&dhd->watchdog_sem) == 0) { - if (dhd->pub.dongle_reset == false) { - /* Call the bus module watchdog */ - dhd_bus_watchdog(&dhd->pub); - } - /* Count the tick for reference */ - dhd->pub.tickcnt++; - } else - break; - } - return 0; -} - -static void dhd_watchdog(unsigned long data) -{ - dhd_info_t *dhd = (dhd_info_t *) data; - - if (dhd->watchdog_tsk) { - up(&dhd->watchdog_sem); - - /* Reschedule the watchdog */ - if (dhd->wd_timer_valid) { - mod_timer(&dhd->timer, - jiffies + dhd_watchdog_ms * HZ / 1000); - } - return; - } - - /* Call the bus module watchdog */ - dhd_bus_watchdog(&dhd->pub); - - /* Count the tick for reference */ - dhd->pub.tickcnt++; - - /* Reschedule the watchdog */ - if (dhd->wd_timer_valid) - mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000); -} - -static int dhd_dpc_thread(void *data) -{ - dhd_info_t *dhd = (dhd_info_t *) data; - - /* This thread doesn't need any user-level access, - * so get rid of all our resources - */ -#ifdef DHD_SCHED - if (dhd_dpc_prio > 0) { - struct sched_param param; - param.sched_priority = - (dhd_dpc_prio < - MAX_RT_PRIO) ? dhd_dpc_prio : (MAX_RT_PRIO - 1); - setScheduler(current, SCHED_FIFO, ¶m); - } -#endif /* DHD_SCHED */ - - allow_signal(SIGTERM); - /* Run until signal received */ - while (1) { - if (kthread_should_stop()) - break; - if (down_interruptible(&dhd->dpc_sem) == 0) { - /* Call bus dpc unless it indicated down - (then clean stop) */ - if (dhd->pub.busstate != DHD_BUS_DOWN) { - if (dhd_bus_dpc(dhd->pub.bus)) { - up(&dhd->dpc_sem); - } - } else { - dhd_bus_stop(dhd->pub.bus, true); - } - } else - break; - } - return 0; -} - -static void dhd_dpc(unsigned long data) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *) data; - - /* Call bus dpc unless it indicated down (then clean stop) */ - if (dhd->pub.busstate != DHD_BUS_DOWN) { - if (dhd_bus_dpc(dhd->pub.bus)) - tasklet_schedule(&dhd->tasklet); - } else { - dhd_bus_stop(dhd->pub.bus, true); - } -} - -void dhd_sched_dpc(dhd_pub_t *dhdp) -{ - dhd_info_t *dhd = (dhd_info_t *) dhdp->info; - - if (dhd->dpc_tsk) { - up(&dhd->dpc_sem); - return; - } - - tasklet_schedule(&dhd->tasklet); -} - -#ifdef TOE /* Retrieve current toe component enables, which are kept as a bitmap in toe_ol iovar */ -static int dhd_toe_get(dhd_info_t *dhd, int ifidx, u32 *toe_ol) +static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol) { - wl_ioctl_t ioc; + struct brcmf_ioctl ioc; char buf[32]; int ret; memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_GET_VAR; + ioc.cmd = BRCMF_C_GET_VAR; ioc.buf = buf; ioc.len = (uint) sizeof(buf); ioc.set = false; strcpy(buf, "toe_ol"); - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); + ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { /* Check for older dongle image that doesn't support toe_ol */ if (ret == -EIO) { - DHD_ERROR(("%s: toe not supported by device\n", - dhd_ifname(&dhd->pub, ifidx))); + BRCMF_ERROR(("%s: toe not supported by device\n", + brcmf_ifname(&drvr_priv->pub, ifidx))); return -EOPNOTSUPP; } - DHD_INFO(("%s: could not get toe_ol: ret=%d\n", - dhd_ifname(&dhd->pub, ifidx), ret)); + BRCMF_INFO(("%s: could not get toe_ol: ret=%d\n", + brcmf_ifname(&drvr_priv->pub, ifidx), ret)); return ret; } @@ -1444,15 +871,15 @@ static int dhd_toe_get(dhd_info_t *dhd, int ifidx, u32 *toe_ol) /* Set current toe component enables in toe_ol iovar, and set toe global enable iovar */ -static int dhd_toe_set(dhd_info_t *dhd, int ifidx, u32 toe_ol) +static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol) { - wl_ioctl_t ioc; + struct brcmf_ioctl ioc; char buf[32]; int toe, ret; memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = WLC_SET_VAR; + ioc.cmd = BRCMF_C_SET_VAR; ioc.buf = buf; ioc.len = (uint) sizeof(buf); ioc.set = true; @@ -1462,10 +889,10 @@ static int dhd_toe_set(dhd_info_t *dhd, int ifidx, u32 toe_ol) strcpy(buf, "toe_ol"); memcpy(&buf[sizeof("toe_ol")], &toe_ol, sizeof(u32)); - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); + ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { - DHD_ERROR(("%s: could not set toe_ol: ret=%d\n", - dhd_ifname(&dhd->pub, ifidx), ret)); + BRCMF_ERROR(("%s: could not set toe_ol: ret=%d\n", + brcmf_ifname(&drvr_priv->pub, ifidx), ret)); return ret; } @@ -1476,44 +903,42 @@ static int dhd_toe_set(dhd_info_t *dhd, int ifidx, u32 toe_ol) strcpy(buf, "toe"); memcpy(&buf[sizeof("toe")], &toe, sizeof(u32)); - ret = dhd_prot_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len); + ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { - DHD_ERROR(("%s: could not set toe: ret=%d\n", - dhd_ifname(&dhd->pub, ifidx), ret)); + BRCMF_ERROR(("%s: could not set toe: ret=%d\n", + brcmf_ifname(&drvr_priv->pub, ifidx), ret)); return ret; } return 0; } -#endif /* TOE */ -static void dhd_ethtool_get_drvinfo(struct net_device *net, +static void brcmf_ethtool_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) { - dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net); + struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); - sprintf(info->driver, DRV_MODULE_NAME); - sprintf(info->version, "%lu", dhd->pub.drv_version); - sprintf(info->fw_version, "%s", wl_cfg80211_get_fwname()); - sprintf(info->bus_info, "%s", dev_name(&wl_cfg80211_get_sdio_func()->dev)); + sprintf(info->driver, KBUILD_MODNAME); + sprintf(info->version, "%lu", drvr_priv->pub.drv_version); + sprintf(info->fw_version, "%s", BCM4329_FW_NAME); + sprintf(info->bus_info, "%s", + dev_name(&brcmf_cfg80211_get_sdio_func()->dev)); } -struct ethtool_ops dhd_ethtool_ops = { - .get_drvinfo = dhd_ethtool_get_drvinfo +struct ethtool_ops brcmf_ethtool_ops = { + .get_drvinfo = brcmf_ethtool_get_drvinfo }; -static int dhd_ethtool(dhd_info_t *dhd, void *uaddr) +static int brcmf_ethtool(struct brcmf_info *drvr_priv, void *uaddr) { struct ethtool_drvinfo info; char drvname[sizeof(info.driver)]; u32 cmd; -#ifdef TOE struct ethtool_value edata; u32 toe_cmpnt, csum_dir; int ret; -#endif - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); /* all ethtool calls start with a cmd word */ if (copy_from_user(&cmd, uaddr, sizeof(u32))) @@ -1531,36 +956,35 @@ static int dhd_ethtool(dhd_info_t *dhd, void *uaddr) memset(&info, 0, sizeof(info)); info.cmd = cmd; - /* if dhd requested, identify ourselves */ + /* if requested, identify ourselves */ if (strcmp(drvname, "?dhd") == 0) { sprintf(info.driver, "dhd"); - strcpy(info.version, EPI_VERSION_STR); + strcpy(info.version, BRCMF_VERSION_STR); } /* otherwise, require dongle to be up */ - else if (!dhd->pub.up) { - DHD_ERROR(("%s: dongle is not up\n", __func__)); + else if (!drvr_priv->pub.up) { + BRCMF_ERROR(("%s: dongle is not up\n", __func__)); return -ENODEV; } /* finally, report dongle driver type */ - else if (dhd->pub.iswl) + else if (drvr_priv->pub.iswl) sprintf(info.driver, "wl"); else sprintf(info.driver, "xx"); - sprintf(info.version, "%lu", dhd->pub.drv_version); + sprintf(info.version, "%lu", drvr_priv->pub.drv_version); if (copy_to_user(uaddr, &info, sizeof(info))) return -EFAULT; - DHD_CTL(("%s: given %*s, returning %s\n", __func__, - (int)sizeof(drvname), drvname, info.driver)); + BRCMF_CTL(("%s: given %*s, returning %s\n", __func__, + (int)sizeof(drvname), drvname, info.driver)); break; -#ifdef TOE /* Get toe offload components from dongle */ case ETHTOOL_GRXCSUM: case ETHTOOL_GTXCSUM: - ret = dhd_toe_get(dhd, 0, &toe_cmpnt); + ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt); if (ret < 0) return ret; @@ -1581,7 +1005,7 @@ static int dhd_ethtool(dhd_info_t *dhd, void *uaddr) return -EFAULT; /* Read the current settings, update and write back */ - ret = dhd_toe_get(dhd, 0, &toe_cmpnt); + ret = brcmf_toe_get(drvr_priv, 0, &toe_cmpnt); if (ret < 0) return ret; @@ -1593,22 +1017,21 @@ static int dhd_ethtool(dhd_info_t *dhd, void *uaddr) else toe_cmpnt &= ~csum_dir; - ret = dhd_toe_set(dhd, 0, toe_cmpnt); + ret = brcmf_toe_set(drvr_priv, 0, toe_cmpnt); if (ret < 0) return ret; /* If setting TX checksum mode, tell Linux the new mode */ if (cmd == ETHTOOL_STXCSUM) { if (edata.data) - dhd->iflist[0]->net->features |= + drvr_priv->iflist[0]->net->features |= NETIF_F_IP_CSUM; else - dhd->iflist[0]->net->features &= + drvr_priv->iflist[0]->net->features &= ~NETIF_F_IP_CSUM; } break; -#endif /* TOE */ default: return -EOPNOTSUPP; @@ -1617,10 +1040,11 @@ static int dhd_ethtool(dhd_info_t *dhd, void *uaddr) return 0; } -static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) +static int brcmf_netdev_ioctl_entry(struct net_device *net, struct ifreq *ifr, + int cmd) { - dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net); - dhd_ioctl_t ioc; + struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); + struct brcmf_c_ioctl ioc; int bcmerror = 0; int buflen = 0; void *buf = NULL; @@ -1628,22 +1052,14 @@ static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) int ifidx; bool is_set_key_cmd; - ifidx = dhd_net2idx(dhd, net); - DHD_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __func__, ifidx, cmd)); + ifidx = brcmf_net2idx(drvr_priv, net); + BRCMF_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __func__, ifidx, cmd)); - if (ifidx == DHD_BAD_IF) + if (ifidx == BRCMF_BAD_IF) return -1; -#if defined(CONFIG_WIRELESS_EXT) - /* linux wireless extensions */ - if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) { - /* may recurse, do NOT lock */ - return wl_iw_ioctl(net, ifr, cmd); - } -#endif /* defined(CONFIG_WIRELESS_EXT) */ - if (cmd == SIOCETHTOOL) - return dhd_ethtool(dhd, (void *)ifr->ifr_data); + return brcmf_ethtool(drvr_priv, (void *)ifr->ifr_data); if (cmd != SIOCDEVPRIVATE) return -EOPNOTSUPP; @@ -1651,14 +1067,14 @@ static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) memset(&ioc, 0, sizeof(ioc)); /* Copy the ioc control structure part of ioctl request */ - if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) { + if (copy_from_user(&ioc, ifr->ifr_data, sizeof(struct brcmf_ioctl))) { bcmerror = -EINVAL; goto done; } /* Copy out any buffer passed */ if (ioc.buf) { - buflen = min_t(int, ioc.len, DHD_IOCTL_MAXLEN); + buflen = min_t(int, ioc.len, BRCMF_IOCTL_MAXLEN); /* optimization for direct ioctl calls from kernel */ /* if (segment_eq(get_fs(), KERNEL_DS)) { @@ -1678,9 +1094,9 @@ static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) } } - /* To differentiate between wl and dhd read 4 more byes */ - if ((copy_from_user(&driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t), - sizeof(uint)) != 0)) { + /* To differentiate read 4 more byes */ + if ((copy_from_user(&driver, (char *)ifr->ifr_data + + sizeof(struct brcmf_ioctl), sizeof(uint)) != 0)) { bcmerror = -EINVAL; goto done; } @@ -1690,39 +1106,41 @@ static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) goto done; } - /* check for local dhd ioctl and handle it */ - if (driver == DHD_IOCTL_MAGIC) { - bcmerror = dhd_ioctl((void *)&dhd->pub, &ioc, buf, buflen); + /* check for local brcmf ioctl and handle it */ + if (driver == BRCMF_IOCTL_MAGIC) { + bcmerror = brcmf_c_ioctl((void *)&drvr_priv->pub, &ioc, buf, buflen); if (bcmerror) - dhd->pub.bcmerror = bcmerror; + drvr_priv->pub.bcmerror = bcmerror; goto done; } /* send to dongle (must be up, and wl) */ - if ((dhd->pub.busstate != DHD_BUS_DATA)) { - DHD_ERROR(("%s DONGLE_DOWN,__func__\n", __func__)); + if ((drvr_priv->pub.busstate != BRCMF_BUS_DATA)) { + BRCMF_ERROR(("%s DONGLE_DOWN,__func__\n", __func__)); bcmerror = -EIO; goto done; } - if (!dhd->pub.iswl) { + if (!drvr_priv->pub.iswl) { bcmerror = -EIO; goto done; } - /* Intercept WLC_SET_KEY IOCTL - serialize M4 send and set key IOCTL to - * prevent M4 encryption. + /* + * Intercept BRCMF_C_SET_KEY IOCTL - serialize M4 send and + * set key IOCTL to prevent M4 encryption. */ - is_set_key_cmd = ((ioc.cmd == WLC_SET_KEY) || - ((ioc.cmd == WLC_SET_VAR) && + is_set_key_cmd = ((ioc.cmd == BRCMF_C_SET_KEY) || + ((ioc.cmd == BRCMF_C_SET_VAR) && !(strncmp("wsec_key", ioc.buf, 9))) || - ((ioc.cmd == WLC_SET_VAR) && + ((ioc.cmd == BRCMF_C_SET_VAR) && !(strncmp("bsscfg:wsec_key", ioc.buf, 15)))); if (is_set_key_cmd) - dhd_wait_pend8021x(net); + brcmf_netdev_wait_pend8021x(net); bcmerror = - dhd_prot_ioctl(&dhd->pub, ifidx, (wl_ioctl_t *)&ioc, buf, buflen); + brcmf_proto_ioctl(&drvr_priv->pub, ifidx, (struct brcmf_ioctl *)&ioc, + buf, buflen); done: if (!bcmerror && buf && ioc.buf) { @@ -1738,159 +1156,146 @@ static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) return bcmerror; } -static int dhd_stop(struct net_device *net) +static int brcmf_netdev_stop(struct net_device *net) { #if !defined(IGNORE_ETH0_DOWN) - dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net); + struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); - DHD_TRACE(("%s: Enter\n", __func__)); - if (IS_CFG80211_FAVORITE()) { - wl_cfg80211_down(); - } - if (dhd->pub.up == 0) + BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_cfg80211_down(); + if (drvr_priv->pub.up == 0) return 0; /* Set state and stop OS transmissions */ - dhd->pub.up = 0; + drvr_priv->pub.up = 0; netif_stop_queue(net); #else - DHD_ERROR(("BYPASS %s:due to BRCM compilation : under investigation\n", - __func__)); + BRCMF_ERROR(("BYPASS %s:due to BRCM compilation: under investigation\n", + __func__)); #endif /* !defined(IGNORE_ETH0_DOWN) */ return 0; } -static int dhd_open(struct net_device *net) +static int brcmf_netdev_open(struct net_device *net) { - dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net); -#ifdef TOE + struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); u32 toe_ol; -#endif - int ifidx = dhd_net2idx(dhd, net); + int ifidx = brcmf_net2idx(drvr_priv, net); s32 ret = 0; - DHD_TRACE(("%s: ifidx %d\n", __func__, ifidx)); + BRCMF_TRACE(("%s: ifidx %d\n", __func__, ifidx)); if (ifidx == 0) { /* do it only for primary eth0 */ /* try to bring up bus */ - ret = dhd_bus_start(&dhd->pub); + ret = brcmf_bus_start(&drvr_priv->pub); if (ret != 0) { - DHD_ERROR(("%s: failed with code %d\n", __func__, ret)); + BRCMF_ERROR(("%s: failed with code %d\n", + __func__, ret)); return -1; } - atomic_set(&dhd->pend_8021x_cnt, 0); + atomic_set(&drvr_priv->pend_8021x_cnt, 0); - memcpy(net->dev_addr, dhd->pub.mac, ETH_ALEN); + memcpy(net->dev_addr, drvr_priv->pub.mac, ETH_ALEN); -#ifdef TOE /* Get current TOE mode from dongle */ - if (dhd_toe_get(dhd, ifidx, &toe_ol) >= 0 + if (brcmf_toe_get(drvr_priv, ifidx, &toe_ol) >= 0 && (toe_ol & TOE_TX_CSUM_OL) != 0) - dhd->iflist[ifidx]->net->features |= NETIF_F_IP_CSUM; + drvr_priv->iflist[ifidx]->net->features |= + NETIF_F_IP_CSUM; else - dhd->iflist[ifidx]->net->features &= ~NETIF_F_IP_CSUM; -#endif + drvr_priv->iflist[ifidx]->net->features &= + ~NETIF_F_IP_CSUM; } /* Allow transmit calls */ netif_start_queue(net); - dhd->pub.up = 1; - if (IS_CFG80211_FAVORITE()) { - if (unlikely(wl_cfg80211_up())) { - DHD_ERROR(("%s: failed to bring up cfg80211\n", - __func__)); - return -1; - } + drvr_priv->pub.up = 1; + if (unlikely(brcmf_cfg80211_up())) { + BRCMF_ERROR(("%s: failed to bring up cfg80211\n", + __func__)); + return -1; } return ret; } int -dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name, +brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, void *handle, char *name, u8 *mac_addr, u32 flags, u8 bssidx) { - dhd_if_t *ifp; + struct brcmf_if *ifp; - DHD_TRACE(("%s: idx %d, handle->%p\n", __func__, ifidx, handle)); + BRCMF_TRACE(("%s: idx %d, handle->%p\n", __func__, ifidx, handle)); - ASSERT(dhd && (ifidx < DHD_MAX_IFS)); - - ifp = dhd->iflist[ifidx]; - if (!ifp && !(ifp = kmalloc(sizeof(dhd_if_t), GFP_ATOMIC))) { - DHD_ERROR(("%s: OOM - dhd_if_t\n", __func__)); - return -ENOMEM; + ifp = drvr_priv->iflist[ifidx]; + if (!ifp) { + ifp = kmalloc(sizeof(struct brcmf_if), GFP_ATOMIC); + if (!ifp) { + BRCMF_ERROR(("%s: OOM - struct brcmf_if\n", __func__)); + return -ENOMEM; + } } - memset(ifp, 0, sizeof(dhd_if_t)); - ifp->info = dhd; - dhd->iflist[ifidx] = ifp; + memset(ifp, 0, sizeof(struct brcmf_if)); + ifp->info = drvr_priv; + drvr_priv->iflist[ifidx] = ifp; strlcpy(ifp->name, name, IFNAMSIZ); if (mac_addr != NULL) memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); if (handle == NULL) { - ifp->state = WLC_E_IF_ADD; + ifp->state = BRCMF_E_IF_ADD; ifp->idx = ifidx; - ASSERT(dhd->sysioc_tsk); - up(&dhd->sysioc_sem); + up(&drvr_priv->sysioc_sem); } else ifp->net = (struct net_device *)handle; return 0; } -void dhd_del_if(dhd_info_t *dhd, int ifidx) +void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx) { - dhd_if_t *ifp; + struct brcmf_if *ifp; - DHD_TRACE(("%s: idx %d\n", __func__, ifidx)); + BRCMF_TRACE(("%s: idx %d\n", __func__, ifidx)); - ASSERT(dhd && ifidx && (ifidx < DHD_MAX_IFS)); - ifp = dhd->iflist[ifidx]; + ifp = drvr_priv->iflist[ifidx]; if (!ifp) { - DHD_ERROR(("%s: Null interface\n", __func__)); + BRCMF_ERROR(("%s: Null interface\n", __func__)); return; } - ifp->state = WLC_E_IF_DEL; + ifp->state = BRCMF_E_IF_DEL; ifp->idx = ifidx; - ASSERT(dhd->sysioc_tsk); - up(&dhd->sysioc_sem); + up(&drvr_priv->sysioc_sem); } -dhd_pub_t *dhd_attach(struct dhd_bus *bus, uint bus_hdrlen) +struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) { - dhd_info_t *dhd = NULL; + struct brcmf_info *drvr_priv = NULL; struct net_device *net; - DHD_TRACE(("%s: Enter\n", __func__)); - /* updates firmware nvram path if it was provided as module - paramters */ - if ((firmware_path != NULL) && (firmware_path[0] != '\0')) - strcpy(fw_path, firmware_path); - if ((nvram_path != NULL) && (nvram_path[0] != '\0')) - strcpy(nv_path, nvram_path); + BRCMF_TRACE(("%s: Enter\n", __func__)); /* Allocate etherdev, including space for private structure */ - net = alloc_etherdev(sizeof(dhd)); + net = alloc_etherdev(sizeof(drvr_priv)); if (!net) { - DHD_ERROR(("%s: OOM - alloc_etherdev\n", __func__)); + BRCMF_ERROR(("%s: OOM - alloc_etherdev\n", __func__)); goto fail; } - /* Allocate primary dhd_info */ - dhd = kzalloc(sizeof(dhd_info_t), GFP_ATOMIC); - if (!dhd) { - DHD_ERROR(("%s: OOM - alloc dhd_info\n", __func__)); + /* Allocate primary brcmf_info */ + drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC); + if (!drvr_priv) { + BRCMF_ERROR(("%s: OOM - alloc brcmf_info\n", __func__)); goto fail; } /* - * Save the dhd_info into the priv + * Save the brcmf_info into the priv */ - memcpy(netdev_priv(net), &dhd, sizeof(dhd)); + memcpy(netdev_priv(net), &drvr_priv, sizeof(drvr_priv)); /* Set network interface name if it was provided as module parameter */ if (iface_name[0]) { @@ -1904,317 +1309,180 @@ dhd_pub_t *dhd_attach(struct dhd_bus *bus, uint bus_hdrlen) strcat(net->name, "%d"); } - if (dhd_add_if(dhd, 0, (void *)net, net->name, NULL, 0, 0) == - DHD_BAD_IF) + if (brcmf_add_if(drvr_priv, 0, (void *)net, net->name, NULL, 0, 0) == + BRCMF_BAD_IF) goto fail; net->netdev_ops = NULL; - sema_init(&dhd->proto_sem, 1); + sema_init(&drvr_priv->proto_sem, 1); /* Initialize other structure content */ - init_waitqueue_head(&dhd->ioctl_resp_wait); - init_waitqueue_head(&dhd->ctrl_wait); - - /* Initialize the spinlocks */ - spin_lock_init(&dhd->sdlock); - spin_lock_init(&dhd->txqlock); + init_waitqueue_head(&drvr_priv->ioctl_resp_wait); /* Link to info module */ - dhd->pub.info = dhd; + drvr_priv->pub.info = drvr_priv; /* Link to bus module */ - dhd->pub.bus = bus; - dhd->pub.hdrlen = bus_hdrlen; + drvr_priv->pub.bus = bus; + drvr_priv->pub.hdrlen = bus_hdrlen; /* Attach and link in the protocol */ - if (dhd_prot_attach(&dhd->pub) != 0) { - DHD_ERROR(("dhd_prot_attach failed\n")); + if (brcmf_proto_attach(&drvr_priv->pub) != 0) { + BRCMF_ERROR(("brcmf_prot_attach failed\n")); goto fail; } -#if defined(CONFIG_WIRELESS_EXT) - /* Attach and link in the iw */ - if (wl_iw_attach(net, (void *)&dhd->pub) != 0) { - DHD_ERROR(("wl_iw_attach failed\n")); - goto fail; - } -#endif /* defined(CONFIG_WIRELESS_EXT) */ /* Attach and link in the cfg80211 */ - if (IS_CFG80211_FAVORITE()) { - if (unlikely(wl_cfg80211_attach(net, &dhd->pub))) { - DHD_ERROR(("wl_cfg80211_attach failed\n")); - goto fail; - } - if (!NO_FW_REQ()) { - strcpy(fw_path, wl_cfg80211_get_fwname()); - strcpy(nv_path, wl_cfg80211_get_nvramname()); - } + if (unlikely(brcmf_cfg80211_attach(net, &drvr_priv->pub))) { + BRCMF_ERROR(("wl_cfg80211_attach failed\n")); + goto fail; } - /* Set up the watchdog timer */ - init_timer(&dhd->timer); - dhd->timer.data = (unsigned long) dhd; - dhd->timer.function = dhd_watchdog; - - /* Initialize thread based operation and lock */ - sema_init(&dhd->sdsem, 1); - if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0)) - dhd->threads_only = true; - else - dhd->threads_only = false; - - if (dhd_dpc_prio >= 0) { - /* Initialize watchdog thread */ - sema_init(&dhd->watchdog_sem, 0); - dhd->watchdog_tsk = kthread_run(dhd_watchdog_thread, dhd, - "dhd_watchdog"); - if (IS_ERR(dhd->watchdog_tsk)) { + if (brcmf_sysioc) { + sema_init(&drvr_priv->sysioc_sem, 0); + drvr_priv->sysioc_tsk = kthread_run(_brcmf_sysioc_thread, drvr_priv, + "_brcmf_sysioc"); + if (IS_ERR(drvr_priv->sysioc_tsk)) { printk(KERN_WARNING - "dhd_watchdog thread failed to start\n"); - dhd->watchdog_tsk = NULL; - } - } else { - dhd->watchdog_tsk = NULL; - } - - /* Set up the bottom half handler */ - if (dhd_dpc_prio >= 0) { - /* Initialize DPC thread */ - sema_init(&dhd->dpc_sem, 0); - dhd->dpc_tsk = kthread_run(dhd_dpc_thread, dhd, "dhd_dpc"); - if (IS_ERR(dhd->dpc_tsk)) { - printk(KERN_WARNING - "dhd_dpc thread failed to start\n"); - dhd->dpc_tsk = NULL; - } - } else { - tasklet_init(&dhd->tasklet, dhd_dpc, (unsigned long) dhd); - dhd->dpc_tsk = NULL; - } - - if (dhd_sysioc) { - sema_init(&dhd->sysioc_sem, 0); - dhd->sysioc_tsk = kthread_run(_dhd_sysioc_thread, dhd, - "_dhd_sysioc"); - if (IS_ERR(dhd->sysioc_tsk)) { - printk(KERN_WARNING - "_dhd_sysioc thread failed to start\n"); - dhd->sysioc_tsk = NULL; + "_brcmf_sysioc thread failed to start\n"); + drvr_priv->sysioc_tsk = NULL; } } else - dhd->sysioc_tsk = NULL; + drvr_priv->sysioc_tsk = NULL; /* - * Save the dhd_info into the priv + * Save the brcmf_info into the priv */ - memcpy(netdev_priv(net), &dhd, sizeof(dhd)); + memcpy(netdev_priv(net), &drvr_priv, sizeof(drvr_priv)); -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) - g_bus = bus; -#endif #if defined(CONFIG_PM_SLEEP) - atomic_set(&dhd_mmc_suspend, false); - if (!IS_CFG80211_FAVORITE()) - register_pm_notifier(&dhd_sleep_pm_notifier); + atomic_set(&brcmf_mmc_suspend, false); #endif /* defined(CONFIG_PM_SLEEP) */ - /* && defined(DHD_GPL) */ - /* Init lock suspend to prevent kernel going to suspend */ -#ifdef CONFIG_HAS_EARLYSUSPEND - dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20; - dhd->early_suspend.suspend = dhd_early_suspend; - dhd->early_suspend.resume = dhd_late_resume; - register_early_suspend(&dhd->early_suspend); -#endif - - return &dhd->pub; + return &drvr_priv->pub; fail: if (net) free_netdev(net); - if (dhd) - dhd_detach(&dhd->pub); + if (drvr_priv) + brcmf_detach(&drvr_priv->pub); return NULL; } -int dhd_bus_start(dhd_pub_t *dhdp) +int brcmf_bus_start(struct brcmf_pub *drvr) { int ret = -1; - dhd_info_t *dhd = (dhd_info_t *) dhdp->info; -#ifdef EMBEDDED_PLATFORM - char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + - '\0' + bitvec */ -#endif /* EMBEDDED_PLATFORM */ + struct brcmf_info *drvr_priv = drvr->info; + /* Room for "event_msgs" + '\0' + bitvec */ + char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; - ASSERT(dhd); - - DHD_TRACE(("%s:\n", __func__)); - - /* try to download image and nvram to the dongle */ - if (dhd->pub.busstate == DHD_BUS_DOWN) { - if (!(dhd_bus_download_firmware(dhd->pub.bus, - fw_path, nv_path))) { - DHD_ERROR(("%s: dhdsdio_probe_download failed. " - "firmware = %s nvram = %s\n", - __func__, fw_path, nv_path)); - return -1; - } - } - - /* Start the watchdog timer */ - dhd->pub.tickcnt = 0; - dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms); + BRCMF_TRACE(("%s:\n", __func__)); /* Bring up the bus */ - ret = dhd_bus_init(&dhd->pub, true); + ret = brcmf_sdbrcm_bus_init(&drvr_priv->pub, true); if (ret != 0) { - DHD_ERROR(("%s, dhd_bus_init failed %d\n", __func__, ret)); + BRCMF_ERROR(("%s, brcmf_sdbrcm_bus_init failed %d\n", __func__, + ret)); return ret; } -#if defined(OOB_INTR_ONLY) - /* Host registration for OOB interrupt */ - if (bcmsdh_register_oob_intr(dhdp)) { - del_timer_sync(&dhd->timer); - dhd->wd_timer_valid = false; - DHD_ERROR(("%s Host failed to resgister for OOB\n", __func__)); - return -ENODEV; - } - - /* Enable oob at firmware */ - dhd_enable_oob_intr(dhd->pub.bus, true); -#endif /* defined(OOB_INTR_ONLY) */ /* If bus is not ready, can't come up */ - if (dhd->pub.busstate != DHD_BUS_DATA) { - del_timer_sync(&dhd->timer); - dhd->wd_timer_valid = false; - DHD_ERROR(("%s failed bus is not ready\n", __func__)); + if (drvr_priv->pub.busstate != BRCMF_BUS_DATA) { + BRCMF_ERROR(("%s failed bus is not ready\n", __func__)); return -ENODEV; } -#ifdef EMBEDDED_PLATFORM - bcm_mkiovar("event_msgs", dhdp->eventmask, WL_EVENTING_MASK_LEN, iovbuf, - sizeof(iovbuf)); - dhdcdc_query_ioctl(dhdp, 0, WLC_GET_VAR, iovbuf, sizeof(iovbuf)); - memcpy(dhdp->eventmask, iovbuf, WL_EVENTING_MASK_LEN); - setbit(dhdp->eventmask, WLC_E_SET_SSID); - setbit(dhdp->eventmask, WLC_E_PRUNE); - setbit(dhdp->eventmask, WLC_E_AUTH); - setbit(dhdp->eventmask, WLC_E_REASSOC); - setbit(dhdp->eventmask, WLC_E_REASSOC_IND); - setbit(dhdp->eventmask, WLC_E_DEAUTH_IND); - setbit(dhdp->eventmask, WLC_E_DISASSOC_IND); - setbit(dhdp->eventmask, WLC_E_DISASSOC); - setbit(dhdp->eventmask, WLC_E_JOIN); - setbit(dhdp->eventmask, WLC_E_ASSOC_IND); - setbit(dhdp->eventmask, WLC_E_PSK_SUP); - setbit(dhdp->eventmask, WLC_E_LINK); - setbit(dhdp->eventmask, WLC_E_NDIS_LINK); - setbit(dhdp->eventmask, WLC_E_MIC_ERROR); - setbit(dhdp->eventmask, WLC_E_PMKID_CACHE); - setbit(dhdp->eventmask, WLC_E_TXFAIL); - setbit(dhdp->eventmask, WLC_E_JOIN_START); - setbit(dhdp->eventmask, WLC_E_SCAN_COMPLETE); -#ifdef PNO_SUPPORT - setbit(dhdp->eventmask, WLC_E_PFN_NET_FOUND); -#endif /* PNO_SUPPORT */ + brcmu_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, + iovbuf, sizeof(iovbuf)); + brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR, iovbuf, + sizeof(iovbuf)); + memcpy(drvr->eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN); + + setbit(drvr->eventmask, BRCMF_E_SET_SSID); + setbit(drvr->eventmask, BRCMF_E_PRUNE); + setbit(drvr->eventmask, BRCMF_E_AUTH); + setbit(drvr->eventmask, BRCMF_E_REASSOC); + setbit(drvr->eventmask, BRCMF_E_REASSOC_IND); + setbit(drvr->eventmask, BRCMF_E_DEAUTH_IND); + setbit(drvr->eventmask, BRCMF_E_DISASSOC_IND); + setbit(drvr->eventmask, BRCMF_E_DISASSOC); + setbit(drvr->eventmask, BRCMF_E_JOIN); + setbit(drvr->eventmask, BRCMF_E_ASSOC_IND); + setbit(drvr->eventmask, BRCMF_E_PSK_SUP); + setbit(drvr->eventmask, BRCMF_E_LINK); + setbit(drvr->eventmask, BRCMF_E_NDIS_LINK); + setbit(drvr->eventmask, BRCMF_E_MIC_ERROR); + setbit(drvr->eventmask, BRCMF_E_PMKID_CACHE); + setbit(drvr->eventmask, BRCMF_E_TXFAIL); + setbit(drvr->eventmask, BRCMF_E_JOIN_START); + setbit(drvr->eventmask, BRCMF_E_SCAN_COMPLETE); /* enable dongle roaming event */ - dhdp->pktfilter_count = 1; + drvr->pktfilter_count = 1; /* Setup filter to allow only unicast */ - dhdp->pktfilter[0] = "100 0 0 0 0x01 0x00"; -#endif /* EMBEDDED_PLATFORM */ + drvr->pktfilter[0] = "100 0 0 0 0x01 0x00"; /* Bus is ready, do any protocol initialization */ - ret = dhd_prot_init(&dhd->pub); + ret = brcmf_proto_init(&drvr_priv->pub); if (ret < 0) return ret; return 0; } -int -dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, - int set) -{ - char buf[strlen(name) + 1 + cmd_len]; - int len = sizeof(buf); - wl_ioctl_t ioc; - int ret; - - len = bcm_mkiovar(name, cmd_buf, cmd_len, buf, len); - - memset(&ioc, 0, sizeof(ioc)); - - ioc.cmd = set ? WLC_SET_VAR : WLC_GET_VAR; - ioc.buf = buf; - ioc.len = len; - ioc.set = set; - - ret = dhd_prot_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len); - if (!set && ret >= 0) - memcpy(cmd_buf, buf, cmd_len); - - return ret; -} - -static struct net_device_ops dhd_ops_pri = { - .ndo_open = dhd_open, - .ndo_stop = dhd_stop, - .ndo_get_stats = dhd_get_stats, - .ndo_do_ioctl = dhd_ioctl_entry, - .ndo_start_xmit = dhd_start_xmit, - .ndo_set_mac_address = dhd_set_mac_address, - .ndo_set_multicast_list = dhd_set_multicast_list +static struct net_device_ops brcmf_netdev_ops_pri = { + .ndo_open = brcmf_netdev_open, + .ndo_stop = brcmf_netdev_stop, + .ndo_get_stats = brcmf_netdev_get_stats, + .ndo_do_ioctl = brcmf_netdev_ioctl_entry, + .ndo_start_xmit = brcmf_netdev_start_xmit, + .ndo_set_mac_address = brcmf_netdev_set_mac_address, + .ndo_set_multicast_list = brcmf_netdev_set_multicast_list }; -int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) +int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) { - dhd_info_t *dhd = (dhd_info_t *) dhdp->info; + struct brcmf_info *drvr_priv = drvr->info; struct net_device *net; u8 temp_addr[ETH_ALEN] = { 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33}; - DHD_TRACE(("%s: ifidx %d\n", __func__, ifidx)); + BRCMF_TRACE(("%s: ifidx %d\n", __func__, ifidx)); - ASSERT(dhd && dhd->iflist[ifidx]); - - net = dhd->iflist[ifidx]->net; - ASSERT(net); - - ASSERT(!net->netdev_ops); - net->netdev_ops = &dhd_ops_pri; + net = drvr_priv->iflist[ifidx]->net; + net->netdev_ops = &brcmf_netdev_ops_pri; /* * We have to use the primary MAC for virtual interfaces */ if (ifidx != 0) { /* for virtual interfaces use the primary MAC */ - memcpy(temp_addr, dhd->pub.mac, ETH_ALEN); + memcpy(temp_addr, drvr_priv->pub.mac, ETH_ALEN); } if (ifidx == 1) { - DHD_TRACE(("%s ACCESS POINT MAC: \n", __func__)); + BRCMF_TRACE(("%s ACCESS POINT MAC:\n", __func__)); /* ACCESSPOINT INTERFACE CASE */ temp_addr[0] |= 0X02; /* set bit 2 , - Locally Administered address */ } - net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen; - net->ethtool_ops = &dhd_ethtool_ops; + net->hard_header_len = ETH_HLEN + drvr_priv->pub.hdrlen; + net->ethtool_ops = &brcmf_ethtool_ops; - dhd->pub.rxsz = net->mtu + net->hard_header_len + dhd->pub.hdrlen; + drvr_priv->pub.rxsz = net->mtu + net->hard_header_len + + drvr_priv->pub.hdrlen; memcpy(net->dev_addr, temp_addr, ETH_ALEN); if (register_netdev(net) != 0) { - DHD_ERROR(("%s: couldn't register the net device\n", - __func__)); + BRCMF_ERROR(("%s: couldn't register the net device\n", + __func__)); goto fail; } - DHD_INFO(("%s: Broadcom Dongle Host Driver\n", net->name)); + BRCMF_INFO(("%s: Broadcom Dongle Host Driver\n", net->name)); return 0; @@ -2223,221 +1491,139 @@ int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) return -EBADE; } -void dhd_bus_detach(dhd_pub_t *dhdp) +static void brcmf_bus_detach(struct brcmf_pub *drvr) { - dhd_info_t *dhd; + struct brcmf_info *drvr_priv; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - if (dhdp) { - dhd = (dhd_info_t *) dhdp->info; - if (dhd) { + if (drvr) { + drvr_priv = drvr->info; + if (drvr_priv) { /* Stop the protocol module */ - dhd_prot_stop(&dhd->pub); + brcmf_proto_stop(&drvr_priv->pub); /* Stop the bus module */ - dhd_bus_stop(dhd->pub.bus, true); -#if defined(OOB_INTR_ONLY) - bcmsdh_unregister_oob_intr(); -#endif /* defined(OOB_INTR_ONLY) */ - - /* Clear the watchdog timer */ - del_timer_sync(&dhd->timer); - dhd->wd_timer_valid = false; + brcmf_sdbrcm_bus_stop(drvr_priv->pub.bus, true); } } } -void dhd_detach(dhd_pub_t *dhdp) +void brcmf_detach(struct brcmf_pub *drvr) { - dhd_info_t *dhd; + struct brcmf_info *drvr_priv; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - if (dhdp) { - dhd = (dhd_info_t *) dhdp->info; - if (dhd) { - dhd_if_t *ifp; + if (drvr) { + drvr_priv = drvr->info; + if (drvr_priv) { + struct brcmf_if *ifp; int i; -#if defined(CONFIG_HAS_EARLYSUSPEND) - if (dhd->early_suspend.suspend) - unregister_early_suspend(&dhd->early_suspend); -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ + for (i = 1; i < BRCMF_MAX_IFS; i++) + if (drvr_priv->iflist[i]) + brcmf_del_if(drvr_priv, i); - for (i = 1; i < DHD_MAX_IFS; i++) - if (dhd->iflist[i]) - dhd_del_if(dhd, i); - - ifp = dhd->iflist[0]; - ASSERT(ifp); - if (ifp->net->netdev_ops == &dhd_ops_pri) { - dhd_stop(ifp->net); + ifp = drvr_priv->iflist[0]; + if (ifp->net->netdev_ops == &brcmf_netdev_ops_pri) { + brcmf_netdev_stop(ifp->net); unregister_netdev(ifp->net); } - if (dhd->watchdog_tsk) { - send_sig(SIGTERM, dhd->watchdog_tsk, 1); - kthread_stop(dhd->watchdog_tsk); - dhd->watchdog_tsk = NULL; + if (drvr_priv->sysioc_tsk) { + send_sig(SIGTERM, drvr_priv->sysioc_tsk, 1); + kthread_stop(drvr_priv->sysioc_tsk); + drvr_priv->sysioc_tsk = NULL; } - if (dhd->dpc_tsk) { - send_sig(SIGTERM, dhd->dpc_tsk, 1); - kthread_stop(dhd->dpc_tsk); - dhd->dpc_tsk = NULL; - } else - tasklet_kill(&dhd->tasklet); + brcmf_bus_detach(drvr); - if (dhd->sysioc_tsk) { - send_sig(SIGTERM, dhd->sysioc_tsk, 1); - kthread_stop(dhd->sysioc_tsk); - dhd->sysioc_tsk = NULL; - } + if (drvr->prot) + brcmf_proto_detach(drvr); - dhd_bus_detach(dhdp); + brcmf_cfg80211_detach(); - if (dhdp->prot) - dhd_prot_detach(dhdp); - -#if defined(CONFIG_WIRELESS_EXT) - wl_iw_detach(); -#endif /* (CONFIG_WIRELESS_EXT) */ - - if (IS_CFG80211_FAVORITE()) - wl_cfg80211_detach(); - -#if defined(CONFIG_PM_SLEEP) - if (!IS_CFG80211_FAVORITE()) - unregister_pm_notifier(&dhd_sleep_pm_notifier); -#endif /* defined(CONFIG_PM_SLEEP) */ - /* && defined(DHD_GPL) */ free_netdev(ifp->net); kfree(ifp); - kfree(dhd); + kfree(drvr_priv); } } } -static void __exit dhd_module_cleanup(void) +static void __exit brcmf_module_cleanup(void) { - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - dhd_bus_unregister(); -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) - wifi_del_dev(); -#endif - /* Call customer gpio to turn off power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); + brcmf_bus_unregister(); } -static int __init dhd_module_init(void) +static int __init brcmf_module_init(void) { int error; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - /* Sanity check on the module parameters */ - do { - /* Both watchdog and DPC as tasklets are ok */ - if ((dhd_watchdog_prio < 0) && (dhd_dpc_prio < 0)) - break; - - /* If both watchdog and DPC are threads, TX must be deferred */ - if ((dhd_watchdog_prio >= 0) && (dhd_dpc_prio >= 0) - && dhd_deferred_tx) - break; - - DHD_ERROR(("Invalid module parameters.\n")); - return -EINVAL; - } while (0); - /* Call customer gpio to turn on power with WL_REG_ON signal */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON); - -#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) - sema_init(&wifi_control_sem, 0); - - error = wifi_add_dev(); - if (error) { - DHD_ERROR(("%s: platform_driver_register failed\n", __func__)); - goto failed; - } - - /* Waiting callback after platform_driver_register is done or - exit with error */ - if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) { - printk(KERN_ERR "%s: platform_driver_register timeout\n", - __func__); - /* remove device */ - wifi_del_dev(); - goto failed; - } -#endif /* #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */ - - error = dhd_bus_register(); + error = brcmf_bus_register(); if (error) { - DHD_ERROR(("%s: sdio_register_driver failed\n", __func__)); + BRCMF_ERROR(("%s: brcmf_bus_register failed\n", __func__)); goto failed; } - return error; + return 0; failed: - /* turn off power and exit */ - dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); return -EINVAL; } -module_init(dhd_module_init); -module_exit(dhd_module_cleanup); +module_init(brcmf_module_init); +module_exit(brcmf_module_cleanup); -/* - * OS specific functions required to implement DHD driver in OS independent way - */ -int dhd_os_proto_block(dhd_pub_t *pub) +int brcmf_os_proto_block(struct brcmf_pub *drvr) { - dhd_info_t *dhd = (dhd_info_t *) (pub->info); + struct brcmf_info *drvr_priv = drvr->info; - if (dhd) { - down(&dhd->proto_sem); + if (drvr_priv) { + down(&drvr_priv->proto_sem); return 1; } return 0; } -int dhd_os_proto_unblock(dhd_pub_t *pub) +int brcmf_os_proto_unblock(struct brcmf_pub *drvr) { - dhd_info_t *dhd = (dhd_info_t *) (pub->info); + struct brcmf_info *drvr_priv = drvr->info; - if (dhd) { - up(&dhd->proto_sem); + if (drvr_priv) { + up(&drvr_priv->proto_sem); return 1; } return 0; } -unsigned int dhd_os_get_ioctl_resp_timeout(void) +unsigned int brcmf_os_get_ioctl_resp_timeout(void) { - return (unsigned int)dhd_ioctl_timeout_msec; + return (unsigned int)brcmf_ioctl_timeout_msec; } -void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec) +void brcmf_os_set_ioctl_resp_timeout(unsigned int timeout_msec) { - dhd_ioctl_timeout_msec = (int)timeout_msec; + brcmf_ioctl_timeout_msec = (int)timeout_msec; } -int dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition, bool *pending) +int brcmf_os_ioctl_resp_wait(struct brcmf_pub *drvr, uint *condition, + bool *pending) { - dhd_info_t *dhd = (dhd_info_t *) (pub->info); + struct brcmf_info *drvr_priv = drvr->info; DECLARE_WAITQUEUE(wait, current); - int timeout = dhd_ioctl_timeout_msec; + int timeout = brcmf_ioctl_timeout_msec; /* Convert timeout in millsecond to jiffies */ timeout = timeout * HZ / 1000; /* Wait until control frame is available */ - add_wait_queue(&dhd->ioctl_resp_wait, &wait); + add_wait_queue(&drvr_priv->ioctl_resp_wait, &wait); set_current_state(TASK_INTERRUPTIBLE); while (!(*condition) && (!signal_pending(current) && timeout)) @@ -2447,366 +1633,59 @@ int dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition, bool *pending) *pending = true; set_current_state(TASK_RUNNING); - remove_wait_queue(&dhd->ioctl_resp_wait, &wait); + remove_wait_queue(&drvr_priv->ioctl_resp_wait, &wait); return timeout; } -int dhd_os_ioctl_resp_wake(dhd_pub_t *pub) +int brcmf_os_ioctl_resp_wake(struct brcmf_pub *drvr) { - dhd_info_t *dhd = (dhd_info_t *) (pub->info); + struct brcmf_info *drvr_priv = drvr->info; - if (waitqueue_active(&dhd->ioctl_resp_wait)) - wake_up_interruptible(&dhd->ioctl_resp_wait); + if (waitqueue_active(&drvr_priv->ioctl_resp_wait)) + wake_up_interruptible(&drvr_priv->ioctl_resp_wait); return 0; } -void dhd_os_wd_timer(void *bus, uint wdtick) -{ - dhd_pub_t *pub = bus; - static uint save_dhd_watchdog_ms; - dhd_info_t *dhd = (dhd_info_t *) pub->info; - - /* don't start the wd until fw is loaded */ - if (pub->busstate == DHD_BUS_DOWN) - return; - - /* Totally stop the timer */ - if (!wdtick && dhd->wd_timer_valid == true) { - del_timer_sync(&dhd->timer); - dhd->wd_timer_valid = false; - save_dhd_watchdog_ms = wdtick; - return; - } - - if (wdtick) { - dhd_watchdog_ms = (uint) wdtick; - - if (save_dhd_watchdog_ms != dhd_watchdog_ms) { - - if (dhd->wd_timer_valid == true) - /* Stop timer and restart at new value */ - del_timer_sync(&dhd->timer); - - /* Create timer again when watchdog period is - dynamically changed or in the first instance - */ - dhd->timer.expires = - jiffies + dhd_watchdog_ms * HZ / 1000; - add_timer(&dhd->timer); - - } else { - /* Re arm the timer, at last watchdog period */ - mod_timer(&dhd->timer, - jiffies + dhd_watchdog_ms * HZ / 1000); - } - - dhd->wd_timer_valid = true; - save_dhd_watchdog_ms = wdtick; - } -} - -void *dhd_os_open_image(char *filename) -{ - struct file *fp; - - if (IS_CFG80211_FAVORITE() && !NO_FW_REQ()) - return wl_cfg80211_request_fw(filename); - - fp = filp_open(filename, O_RDONLY, 0); - /* - * 2.6.11 (FC4) supports filp_open() but later revs don't? - * Alternative: - * fp = open_namei(AT_FDCWD, filename, O_RD, 0); - * ??? - */ - if (IS_ERR(fp)) - fp = NULL; - - return fp; -} - -int dhd_os_get_image_block(char *buf, int len, void *image) -{ - struct file *fp = (struct file *)image; - int rdlen; - - if (IS_CFG80211_FAVORITE() && !NO_FW_REQ()) - return wl_cfg80211_read_fw(buf, len); - - if (!image) - return 0; - - rdlen = kernel_read(fp, fp->f_pos, buf, len); - if (rdlen > 0) - fp->f_pos += rdlen; - - return rdlen; -} - -void dhd_os_close_image(void *image) -{ - if (IS_CFG80211_FAVORITE() && !NO_FW_REQ()) - return wl_cfg80211_release_fw(); - if (image) - filp_close((struct file *)image, NULL); -} - -void dhd_os_sdlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *) (pub->info); - - if (dhd->threads_only) - down(&dhd->sdsem); - else - spin_lock_bh(&dhd->sdlock); -} - -void dhd_os_sdunlock(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *) (pub->info); - - if (dhd->threads_only) - up(&dhd->sdsem); - else - spin_unlock_bh(&dhd->sdlock); -} - -void dhd_os_sdlock_txq(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *) (pub->info); - spin_lock_bh(&dhd->txqlock); -} - -void dhd_os_sdunlock_txq(dhd_pub_t *pub) -{ - dhd_info_t *dhd; - - dhd = (dhd_info_t *) (pub->info); - spin_unlock_bh(&dhd->txqlock); -} - -void dhd_os_sdlock_rxq(dhd_pub_t *pub) -{ -} - -void dhd_os_sdunlock_rxq(dhd_pub_t *pub) -{ -} - -void dhd_os_sdtxlock(dhd_pub_t *pub) -{ - dhd_os_sdlock(pub); -} - -void dhd_os_sdtxunlock(dhd_pub_t *pub) -{ - dhd_os_sdunlock(pub); -} - -static int -dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata, - wl_event_msg_t *event, void **data) +static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, + struct brcmf_event_msg *event, void **data) { int bcmerror = 0; - ASSERT(dhd != NULL); - - bcmerror = wl_host_event(dhd, ifidx, pktdata, event, data); + bcmerror = brcmf_c_host_event(drvr_priv, ifidx, pktdata, event, data); if (bcmerror != 0) return bcmerror; -#if defined(CONFIG_WIRELESS_EXT) - if (!IS_CFG80211_FAVORITE()) { - if ((dhd->iflist[*ifidx] == NULL) - || (dhd->iflist[*ifidx]->net == NULL)) { - DHD_ERROR(("%s Exit null pointer\n", __func__)); - return bcmerror; - } - - if (dhd->iflist[*ifidx]->net) - wl_iw_event(dhd->iflist[*ifidx]->net, event, *data); - } -#endif /* defined(CONFIG_WIRELESS_EXT) */ - - if (IS_CFG80211_FAVORITE()) { - ASSERT(dhd->iflist[*ifidx] != NULL); - ASSERT(dhd->iflist[*ifidx]->net != NULL); - if (dhd->iflist[*ifidx]->net) - wl_cfg80211_event(dhd->iflist[*ifidx]->net, event, - *data); - } + if (drvr_priv->iflist[*ifidx]->net) + brcmf_cfg80211_event(drvr_priv->iflist[*ifidx]->net, + event, *data); return bcmerror; } -/* send up locally generated event */ -void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data) +int brcmf_netdev_reset(struct net_device *dev, u8 flag) { - switch (be32_to_cpu(event->event_type)) { - default: - break; - } -} + struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(dev); -void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar) -{ - struct dhd_info *dhdinfo = dhd->info; - dhd_os_sdunlock(dhd); - wait_event_interruptible_timeout(dhdinfo->ctrl_wait, - (*lockvar == false), HZ * 2); - dhd_os_sdlock(dhd); - return; -} - -void dhd_wait_event_wakeup(dhd_pub_t *dhd) -{ - struct dhd_info *dhdinfo = dhd->info; - if (waitqueue_active(&dhdinfo->ctrl_wait)) - wake_up_interruptible(&dhdinfo->ctrl_wait); - return; -} - -int dhd_dev_reset(struct net_device *dev, u8 flag) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - /* Turning off watchdog */ - if (flag) - dhd_os_wd_timer(&dhd->pub, 0); - - dhd_bus_devreset(&dhd->pub, flag); - - /* Turning on watchdog back */ - if (!flag) - dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms); - DHD_ERROR(("%s: WLAN OFF DONE\n", __func__)); + brcmf_bus_devreset(&drvr_priv->pub, flag); return 1; } -int net_os_set_suspend_disable(struct net_device *dev, int val) +static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv) { - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - int ret = 0; - - if (dhd) { - ret = dhd->pub.suspend_disable_flag; - dhd->pub.suspend_disable_flag = val; - } - return ret; -} - -int net_os_set_suspend(struct net_device *dev, int val) -{ - int ret = 0; -#if defined(CONFIG_HAS_EARLYSUSPEND) - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - if (dhd) { - dhd_os_proto_block(&dhd->pub); - ret = dhd_set_suspend(val, &dhd->pub); - dhd_os_proto_unblock(&dhd->pub); - } -#endif /* defined(CONFIG_HAS_EARLYSUSPEND) */ - return ret; -} - -int net_os_set_dtim_skip(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev); - - if (dhd) - dhd->pub.dtim_skip = val; - - return 0; -} - -int net_os_set_packet_filter(struct net_device *dev, int val) -{ - dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev); - int ret = 0; - - /* Packet filtering is set only if we still in early-suspend and - * we need either to turn it ON or turn it OFF - * We can always turn it OFF in case of early-suspend, but we turn it - * back ON only if suspend_disable_flag was not set - */ - if (dhd && dhd->pub.up) { - dhd_os_proto_block(&dhd->pub); - if (dhd->pub.in_suspend) { - if (!val || (val && !dhd->pub.suspend_disable_flag)) - dhd_set_packet_filter(val, &dhd->pub); - } - dhd_os_proto_unblock(&dhd->pub); - } - return ret; -} - -void dhd_dev_init_ioctl(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - dhd_preinit_ioctls(&dhd->pub); -} - -#ifdef PNO_SUPPORT -/* Linux wrapper to call common dhd_pno_clean */ -int dhd_dev_pno_reset(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return dhd_pno_clean(&dhd->pub); -} - -/* Linux wrapper to call common dhd_pno_enable */ -int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return dhd_pno_enable(&dhd->pub, pfn_enabled); -} - -/* Linux wrapper to call common dhd_pno_set */ -int -dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t *ssids_local, int nssid, - unsigned char scan_fr) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return dhd_pno_set(&dhd->pub, ssids_local, nssid, scan_fr); -} - -/* Linux wrapper to get pno status */ -int dhd_dev_get_pno_status(struct net_device *dev) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); - - return dhd_pno_get_status(&dhd->pub); -} - -#endif /* PNO_SUPPORT */ - -static int dhd_get_pend_8021x_cnt(dhd_info_t *dhd) -{ - return atomic_read(&dhd->pend_8021x_cnt); + return atomic_read(&drvr_priv->pend_8021x_cnt); } #define MAX_WAIT_FOR_8021X_TX 10 -int dhd_wait_pend8021x(struct net_device *dev) +int brcmf_netdev_wait_pend8021x(struct net_device *dev) { - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); + struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(dev); int timeout = 10 * HZ / 1000; int ntimes = MAX_WAIT_FOR_8021X_TX; - int pend = dhd_get_pend_8021x_cnt(dhd); + int pend = brcmf_get_pend_8021x_cnt(drvr_priv); while (ntimes && pend) { if (pend) { @@ -2815,20 +1694,13 @@ int dhd_wait_pend8021x(struct net_device *dev) set_current_state(TASK_RUNNING); ntimes--; } - pend = dhd_get_pend_8021x_cnt(dhd); + pend = brcmf_get_pend_8021x_cnt(drvr_priv); } return pend; } -void wl_os_wd_timer(struct net_device *ndev, uint wdtick) -{ - dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(ndev); - - dhd_os_wd_timer(&dhd->pub, wdtick); -} - -#ifdef DHD_DEBUG -int write_to_file(dhd_pub_t *dhd, u8 *buf, int size) +#ifdef BCMDBG +int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size) { int ret = 0; struct file *fp; @@ -2842,7 +1714,7 @@ int write_to_file(dhd_pub_t *dhd, u8 *buf, int size) /* open file to write */ fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640); if (!fp) { - DHD_ERROR(("%s: open file error\n", __func__)); + BRCMF_ERROR(("%s: open file error\n", __func__)); ret = -1; goto exit; } @@ -2861,4 +1733,4 @@ int write_to_file(dhd_pub_t *dhd, u8 *buf, int size) return ret; } -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c deleted file mode 100644 index c66f1c2941e2..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include - -int setScheduler(struct task_struct *p, int policy, struct sched_param *param) -{ - int rc = 0; - rc = sched_setscheduler(p, policy, param); - return rc; -} diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h index 030d5ffb0e83..ff788b37afdc 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h @@ -14,11 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _dhd_proto_h_ -#define _dhd_proto_h_ - -#include -#include +#ifndef _BRCMF_PROTO_H_ +#define _BRCMF_PROTO_H_ #ifndef IOCTL_RESP_TIMEOUT #define IOCTL_RESP_TIMEOUT 2000 /* In milli second */ @@ -29,62 +26,50 @@ #endif /* - * Exported from the dhd protocol module (dhd_cdc, dhd_rndis) + * Exported from the brcmf protocol module (brcmf_cdc) */ /* Linkage, sets prot link and updates hdrlen in pub */ -extern int dhd_prot_attach(dhd_pub_t *dhdp); +extern int brcmf_proto_attach(struct brcmf_pub *drvr); -/* Unlink, frees allocated protocol memory (including dhd_prot) */ -extern void dhd_prot_detach(dhd_pub_t *dhdp); +/* Unlink, frees allocated protocol memory (including brcmf_proto) */ +extern void brcmf_proto_detach(struct brcmf_pub *drvr); /* Initialize protocol: sync w/dongle state. * Sets dongle media info (iswl, drv_version, mac address). */ -extern int dhd_prot_init(dhd_pub_t *dhdp); +extern int brcmf_proto_init(struct brcmf_pub *drvr); /* Stop protocol: sync w/dongle state. */ -extern void dhd_prot_stop(dhd_pub_t *dhdp); +extern void brcmf_proto_stop(struct brcmf_pub *drvr); /* Add any protocol-specific data header. * Caller must reserve prot_hdrlen prepend space. */ -extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, struct sk_buff *txp); +extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, + struct sk_buff *txp); /* Remove any protocol-specific data header. */ -extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, struct sk_buff *rxp); +extern int brcmf_proto_hdrpull(struct brcmf_pub *, int *ifidx, + struct sk_buff *rxp); /* Use protocol to issue ioctl to dongle */ -extern int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, - void *buf, int len); - -/* Check for and handle local prot-specific iovar commands */ -extern int dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, - bool set); +extern int brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx, + struct brcmf_ioctl *ioc, void *buf, int len); /* Add prot dump output to a buffer */ -extern void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf); +extern void brcmf_proto_dump(struct brcmf_pub *drvr, + struct brcmu_strbuf *strbuf); /* Update local copy of dongle statistics */ -extern void dhd_prot_dstats(dhd_pub_t *dhdp); +extern void brcmf_proto_dstats(struct brcmf_pub *drvr); -extern int dhd_ioctl(dhd_pub_t *dhd_pub, dhd_ioctl_t *ioc, void *buf, - uint buflen); +extern int brcmf_c_ioctl(struct brcmf_pub *drvr, struct brcmf_c_ioctl *ioc, + void *buf, uint buflen); -extern int dhd_preinit_ioctls(dhd_pub_t *dhd); +extern int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr); -/******************************** - * For version-string expansion * - */ -#if defined(BDC) -#define DHD_PROTOCOL "bdc" -#elif defined(CDC) -#define DHD_PROTOCOL "cdc" -#elif defined(RNDIS) -#define DHD_PROTOCOL "rndis" -#else -#define DHD_PROTOCOL "unknown" -#endif /* proto */ +extern int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx, + uint cmd, void *buf, uint len); -#endif /* _dhd_proto_h_ */ +#endif /* _BRCMF_PROTO_H_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 8cbfeae464b1..7fa95b6213c5 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -16,47 +16,146 @@ #include #include +#include #include #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdio_host.h" -#ifdef BCMEMBEDIMAGE -#include BCMEMBEDIMAGE -#endif /* BCMEMBEDIMAGE */ +/* register access macros */ +#ifndef __BIG_ENDIAN +#ifndef __mips__ +#define R_REG(r, typ) \ + brcmf_sdcard_reg_read(NULL, (r), sizeof(typ)) +#else /* __mips__ */ +#define R_REG(r, typ) \ + ({ \ + __typeof(*(r)) __osl_v; \ + __asm__ __volatile__("sync"); \ + __osl_v = brcmf_sdcard_reg_read(NULL, (r),\ + sizeof(typ)); \ + __asm__ __volatile__("sync"); \ + __osl_v; \ + }) +#endif /* __mips__ */ -#include -#include +#else /* __BIG_ENDIAN */ +#define R_REG(r, typ) \ + brcmf_sdcard_reg_read(NULL, (r), sizeof(typ)) +#endif /* __BIG_ENDIAN */ -#include -#ifdef DHD_DEBUG -#include -#include -#endif /* DHD_DEBUG */ -#include -#include +#define OR_REG(r, v, typ) \ + brcmf_sdcard_reg_write(NULL, (r), sizeof(typ), R_REG(r, typ) | (v)) -#include -#include -#include -#include +#ifdef BCMDBG -#include +/* ARM trap handling */ -#include -#include -#include -#include -#include -#include -#include +/* Trap types defined by ARM (see arminc.h) */ + +#if defined(__ARM_ARCH_4T__) +#define MAX_TRAP_TYPE (TR_FIQ + 1) +#elif defined(__ARM_ARCH_7M__) +#define MAX_TRAP_TYPE (TR_ISR + ARMCM3_NUMINTS) +#endif /* __ARM_ARCH_7M__ */ + +/* The trap structure is defined here as offsets for assembly */ +#define TR_TYPE 0x00 +#define TR_EPC 0x04 +#define TR_CPSR 0x08 +#define TR_SPSR 0x0c +#define TR_REGS 0x10 +#define TR_REG(n) (TR_REGS + (n) * 4) +#define TR_SP TR_REG(13) +#define TR_LR TR_REG(14) +#define TR_PC TR_REG(15) + +#define TRAP_T_SIZE 80 + +struct brcmf_trap { + u32 type; + u32 epc; + u32 cpsr; + u32 spsr; + u32 r0; + u32 r1; + u32 r2; + u32 r3; + u32 r4; + u32 r5; + u32 r6; + u32 r7; + u32 r8; + u32 r9; + u32 r10; + u32 r11; + u32 r12; + u32 r13; + u32 r14; + u32 pc; +}; + +#define CBUF_LEN (128) + +struct rte_log { + u32 buf; /* Can't be pointer on (64-bit) hosts */ + uint buf_size; + uint idx; + char *_buf_compat; /* Redundant pointer for backward compat. */ +}; + +struct rte_console { + /* Virtual UART + * When there is no UART (e.g. Quickturn), + * the host should write a complete + * input line directly into cbuf and then write + * the length into vcons_in. + * This may also be used when there is a real UART + * (at risk of conflicting with + * the real UART). vcons_out is currently unused. + */ + volatile uint vcons_in; + volatile uint vcons_out; + + /* Output (logging) buffer + * Console output is written to a ring buffer log_buf at index log_idx. + * The host may read the output when it sees log_idx advance. + * Output will be lost if the output wraps around faster than the host + * polls. + */ + struct rte_log log; + + /* Console input line buffer + * Characters are read one at a time into cbuf + * until is received, then + * the buffer is processed as a command line. + * Also used for virtual UART. + */ + uint cbuf_idx; + char cbuf[CBUF_LEN]; +}; + +#endif /* BCMDBG */ +#include + +#include "dhd.h" +#include "dhd_bus.h" +#include "dhd_proto.h" +#include "dhd_dbg.h" #include -#ifndef DHDSDIO_MEM_DUMP_FNAME -#define DHDSDIO_MEM_DUMP_FNAME "mem_dump" -#endif - #define TXQLEN 2048 /* bulk tx queue length */ #define TXHI (TXQLEN - 256) /* turn on flow control above TXHI */ #define TXLOW (TXHI - 256) /* turn off flow control below TXLOW */ @@ -64,47 +163,239 @@ #define TXRETRIES 2 /* # of retries for tx frames */ -#if defined(CONFIG_MACH_SANDGATE2G) -#define DHD_RXBOUND 250 /* Default for max rx frames in - one scheduling */ -#else -#define DHD_RXBOUND 50 /* Default for max rx frames in - one scheduling */ -#endif /* defined(CONFIG_MACH_SANDGATE2G) */ - -#define DHD_TXBOUND 20 /* Default for max tx frames in +#define BRCMF_RXBOUND 50 /* Default for max rx frames in one scheduling */ -#define DHD_TXMINMAX 1 /* Max tx frames if rx still pending */ +#define BRCMF_TXBOUND 20 /* Default for max tx frames in + one scheduling */ + +#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */ #define MEMBLOCK 2048 /* Block size used for downloading of dongle image */ #define MAX_DATA_BUF (32 * 1024) /* Must be large enough to hold biggest possible glom */ -/* Packet alignment for most efficient SDIO (can change based on platform) */ -#ifndef DHD_SDALIGN -#define DHD_SDALIGN 32 -#endif -#if !ISPOWEROF2(DHD_SDALIGN) -#error DHD_SDALIGN is not a power of 2! +#ifndef BRCMF_FIRSTREAD +#define BRCMF_FIRSTREAD 32 #endif -#ifndef DHD_FIRSTREAD -#define DHD_FIRSTREAD 32 -#endif -#if !ISPOWEROF2(DHD_FIRSTREAD) -#error DHD_FIRSTREAD is not a power of 2! +#if !ISPOWEROF2(BRCMF_FIRSTREAD) +#error BRCMF_FIRSTREAD is not a power of 2! #endif +/* SBSDIO_DEVICE_CTL */ +#define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when + * receiving CMD53 + */ +#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 /* 1: assertion of sdio interrupt is + * synchronous to the sdio clock + */ +#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04 /* 1: mask all interrupts to host + * except the chipActive (rev 8) + */ +#define SBSDIO_DEVCTL_PADS_ISO 0x08 /* 1: isolate internal sdio signals, put + * external pads in tri-state; requires + * sdio bus power cycle to clear (rev 9) + */ +#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Force SD->SB reset mapping (rev 11) */ +#define SBSDIO_DEVCTL_RST_CORECTL 0x00 /* Determined by CoreControl bit */ +#define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force backplane reset */ +#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* Force no backplane reset */ + +/* SBSDIO_FUNC1_CHIPCLKCSR */ +#define SBSDIO_FORCE_ALP 0x01 /* Force ALP request to backplane */ +#define SBSDIO_FORCE_HT 0x02 /* Force HT request to backplane */ +#define SBSDIO_FORCE_ILP 0x04 /* Force ILP request to backplane */ +#define SBSDIO_ALP_AVAIL_REQ 0x08 /* Make ALP ready (power up xtal) */ +#define SBSDIO_HT_AVAIL_REQ 0x10 /* Make HT ready (power up PLL) */ +#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 /* Squelch clock requests from HW */ +#define SBSDIO_ALP_AVAIL 0x40 /* Status: ALP is ready */ +#define SBSDIO_HT_AVAIL 0x80 /* Status: HT is ready */ + +#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) +#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) +#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) +#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) +#define SBSDIO_CLKAV(regval, alponly) (SBSDIO_ALPAV(regval) && \ + (alponly ? 1 : SBSDIO_HTAV(regval))) +/* direct(mapped) cis space */ +#define SBSDIO_CIS_BASE_COMMON 0x1000 /* MAPPED common CIS address */ +#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */ +#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF /* cis offset addr is < 17 bits */ + +#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 /* manfid tuple length, include tuple, + * link bytes + */ + +/* intstatus */ +#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */ +#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */ +#define I_SMB_SW2 (1 << 2) /* To SB Mail S/W interrupt 2 */ +#define I_SMB_SW3 (1 << 3) /* To SB Mail S/W interrupt 3 */ +#define I_SMB_SW_MASK 0x0000000f /* To SB Mail S/W interrupts mask */ +#define I_SMB_SW_SHIFT 0 /* To SB Mail S/W interrupts shift */ +#define I_HMB_SW0 (1 << 4) /* To Host Mail S/W interrupt 0 */ +#define I_HMB_SW1 (1 << 5) /* To Host Mail S/W interrupt 1 */ +#define I_HMB_SW2 (1 << 6) /* To Host Mail S/W interrupt 2 */ +#define I_HMB_SW3 (1 << 7) /* To Host Mail S/W interrupt 3 */ +#define I_HMB_SW_MASK 0x000000f0 /* To Host Mail S/W interrupts mask */ +#define I_HMB_SW_SHIFT 4 /* To Host Mail S/W interrupts shift */ +#define I_WR_OOSYNC (1 << 8) /* Write Frame Out Of Sync */ +#define I_RD_OOSYNC (1 << 9) /* Read Frame Out Of Sync */ +#define I_PC (1 << 10) /* descriptor error */ +#define I_PD (1 << 11) /* data error */ +#define I_DE (1 << 12) /* Descriptor protocol Error */ +#define I_RU (1 << 13) /* Receive descriptor Underflow */ +#define I_RO (1 << 14) /* Receive fifo Overflow */ +#define I_XU (1 << 15) /* Transmit fifo Underflow */ +#define I_RI (1 << 16) /* Receive Interrupt */ +#define I_BUSPWR (1 << 17) /* SDIO Bus Power Change (rev 9) */ +#define I_XMTDATA_AVAIL (1 << 23) /* bits in fifo */ +#define I_XI (1 << 24) /* Transmit Interrupt */ +#define I_RF_TERM (1 << 25) /* Read Frame Terminate */ +#define I_WF_TERM (1 << 26) /* Write Frame Terminate */ +#define I_PCMCIA_XU (1 << 27) /* PCMCIA Transmit FIFO Underflow */ +#define I_SBINT (1 << 28) /* sbintstatus Interrupt */ +#define I_CHIPACTIVE (1 << 29) /* chip from doze to active state */ +#define I_SRESET (1 << 30) /* CCCR RES interrupt */ +#define I_IOE2 (1U << 31) /* CCCR IOE2 Bit Changed */ +#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU) +#define I_DMA (I_RI | I_XI | I_ERRORS) + +/* corecontrol */ +#define CC_CISRDY (1 << 0) /* CIS Ready */ +#define CC_BPRESEN (1 << 1) /* CCCR RES signal */ +#define CC_F2RDY (1 << 2) /* set CCCR IOR2 bit */ +#define CC_CLRPADSISO (1 << 3) /* clear SDIO pads isolation */ +#define CC_XMTDATAAVAIL_MODE (1 << 4) +#define CC_XMTDATAAVAIL_CTRL (1 << 5) + +/* SDA_FRAMECTRL */ +#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */ +#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */ +#define SFC_CRC4WOOS (1 << 2) /* CRC error for write out of sync */ +#define SFC_ABORTALL (1 << 3) /* Abort all in-progress frames */ + +/* HW frame tag */ +#define SDPCM_FRAMETAG_LEN 4 /* 2 bytes len, 2 bytes check val */ + /* Total length of frame header for dongle protocol */ #define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN) #ifdef SDTEST -#define SDPCM_RESERVE (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN) +#define SDPCM_RESERVE (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + BRCMF_SDALIGN) #else -#define SDPCM_RESERVE (SDPCM_HDRLEN + DHD_SDALIGN) +#define SDPCM_RESERVE (SDPCM_HDRLEN + BRCMF_SDALIGN) #endif +/* + * Software allocation of To SB Mailbox resources + */ + +/* tosbmailbox bits corresponding to intstatus bits */ +#define SMB_NAK (1 << 0) /* Frame NAK */ +#define SMB_INT_ACK (1 << 1) /* Host Interrupt ACK */ +#define SMB_USE_OOB (1 << 2) /* Use OOB Wakeup */ +#define SMB_DEV_INT (1 << 3) /* Miscellaneous Interrupt */ + +/* tosbmailboxdata */ +#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version */ + +/* + * Software allocation of To Host Mailbox resources + */ + +/* intstatus bits */ +#define I_HMB_FC_STATE I_HMB_SW0 /* Flow Control State */ +#define I_HMB_FC_CHANGE I_HMB_SW1 /* Flow Control State Changed */ +#define I_HMB_FRAME_IND I_HMB_SW2 /* Frame Indication */ +#define I_HMB_HOST_INT I_HMB_SW3 /* Miscellaneous Interrupt */ + +/* tohostmailboxdata */ +#define HMB_DATA_NAKHANDLED 1 /* retransmit NAK'd frame */ +#define HMB_DATA_DEVREADY 2 /* talk to host after enable */ +#define HMB_DATA_FC 4 /* per prio flowcontrol update flag */ +#define HMB_DATA_FWREADY 8 /* fw ready for protocol activity */ + +#define HMB_DATA_FCDATA_MASK 0xff000000 +#define HMB_DATA_FCDATA_SHIFT 24 + +#define HMB_DATA_VERSION_MASK 0x00ff0000 +#define HMB_DATA_VERSION_SHIFT 16 + +/* + * Software-defined protocol header + */ + +/* Current protocol version */ +#define SDPCM_PROT_VERSION 4 + +/* SW frame header */ +#define SDPCM_PACKET_SEQUENCE(p) (((u8 *)p)[0] & 0xff) + +#define SDPCM_CHANNEL_MASK 0x00000f00 +#define SDPCM_CHANNEL_SHIFT 8 +#define SDPCM_PACKET_CHANNEL(p) (((u8 *)p)[1] & 0x0f) + +#define SDPCM_NEXTLEN_OFFSET 2 + +/* Data Offset from SOF (HW Tag, SW Tag, Pad) */ +#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */ +#define SDPCM_DOFFSET_VALUE(p) (((u8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff) +#define SDPCM_DOFFSET_MASK 0xff000000 +#define SDPCM_DOFFSET_SHIFT 24 +#define SDPCM_FCMASK_OFFSET 4 /* Flow control */ +#define SDPCM_FCMASK_VALUE(p) (((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff) +#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */ +#define SDPCM_WINDOW_VALUE(p) (((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff) + +#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */ + +/* logical channel numbers */ +#define SDPCM_CONTROL_CHANNEL 0 /* Control channel Id */ +#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */ +#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */ +#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets */ +#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */ + +#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for 8bit frame seq */ + +#define SDPCM_GLOMDESC(p) (((u8 *)p)[1] & 0x80) + +/* For TEST_CHANNEL packets, define another 4-byte header */ +#define SDPCM_TEST_HDRLEN 4 /* + * Generally: Cmd(1), Ext(1), Len(2); + * Semantics of Ext byte depend on + * command. Len is current or requested + * frame length, not including test + * header; sent little-endian. + */ +#define SDPCM_TEST_DISCARD 0x01 /* Receiver discards. Ext:pattern id. */ +#define SDPCM_TEST_ECHOREQ 0x02 /* Echo request. Ext:pattern id. */ +#define SDPCM_TEST_ECHORSP 0x03 /* Echo response. Ext:pattern id. */ +#define SDPCM_TEST_BURST 0x04 /* + * Receiver to send a burst. + * Ext is a frame count + */ +#define SDPCM_TEST_SEND 0x05 /* + * Receiver sets send mode. + * Ext is boolean on/off + */ + +/* Handy macro for filling in datagen packets with a pattern */ +#define SDPCM_TEST_FILL(byteno, id) ((u8)(id + byteno)) + +/* + * Shared structure between dongle and the host. + * The structure contains pointers to trap or assert information. + */ +#define SDPCM_SHARED_VERSION 0x0002 +#define SDPCM_SHARED_VERSION_MASK 0x00FF +#define SDPCM_SHARED_ASSERT_BUILT 0x0100 +#define SDPCM_SHARED_ASSERT 0x0200 +#define SDPCM_SHARED_TRAP 0x0400 + + /* Space for header read, limit for data packets */ #ifndef MAX_HDR_READ #define MAX_HDR_READ 32 @@ -116,7 +407,7 @@ #define MAX_RX_DATASZ 2048 /* Maximum milliseconds to wait for F2 to come up */ -#define DHD_WAIT_F2RDY 3000 +#define BRCMF_WAIT_F2RDY 3000 /* Bump up limit on waiting for HT to account for first startup; * if the image is doing a CRC calculation before programming the PMU @@ -129,13 +420,48 @@ #endif /* Value for ChipClockCSR during initial setup */ -#define DHD_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | \ +#define BRCMF_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | \ SBSDIO_ALP_AVAIL_REQ) -#define DHD_INIT_CLKCTL2 (SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP) /* Flags for SDH calls */ #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) +/* sbimstate */ +#define SBIM_IBE 0x20000 /* inbanderror */ +#define SBIM_TO 0x40000 /* timeout */ +#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ +#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ + +/* sbtmstatelow */ +#define SBTML_RESET 0x0001 /* reset */ +#define SBTML_REJ_MASK 0x0006 /* reject field */ +#define SBTML_REJ 0x0002 /* reject */ +#define SBTML_TMPREJ 0x0004 /* temporary reject, for error recovery */ + +#define SBTML_SICF_SHIFT 16 /* Shift to locate the SI control flags in sbtml */ + +/* sbtmstatehigh */ +#define SBTMH_SERR 0x0001 /* serror */ +#define SBTMH_INT 0x0002 /* interrupt */ +#define SBTMH_BUSY 0x0004 /* busy */ +#define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */ + +#define SBTMH_SISF_SHIFT 16 /* Shift to locate the SI status flags in sbtmh */ + +/* sbidlow */ +#define SBIDL_INIT 0x80 /* initiator */ + +/* sbidhigh */ +#define SBIDH_RC_MASK 0x000f /* revision code */ +#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ +#define SBIDH_RCE_SHIFT 8 +#define SBCOREREV(sbidh) \ + ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) +#define SBIDH_CC_MASK 0x8ff0 /* core code */ +#define SBIDH_CC_SHIFT 4 +#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ +#define SBIDH_VC_SHIFT 16 + /* * Conversion of 802.1D priority to precedence level */ @@ -143,21 +469,130 @@ (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? \ ((prio^2)) : (prio)) -DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep); -extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, - uint len); +BRCMF_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep); -#ifdef DHD_DEBUG +/* + * Core reg address translation. + * Both macro's returns a 32 bits byte address on the backplane bus. + */ +#define CORE_CC_REG(base, field) (base + offsetof(chipcregs_t, field)) +#define CORE_BUS_REG(base, field) \ + (base + offsetof(struct sdpcmd_regs, field)) +#define CORE_SB(base, field) \ + (base + SBCONFIGOFF + offsetof(struct sbconfig, field)) + +/* core registers */ +struct sdpcmd_regs { + u32 corecontrol; /* 0x00, rev8 */ + u32 corestatus; /* rev8 */ + u32 PAD[1]; + u32 biststatus; /* rev8 */ + + /* PCMCIA access */ + u16 pcmciamesportaladdr; /* 0x010, rev8 */ + u16 PAD[1]; + u16 pcmciamesportalmask; /* rev8 */ + u16 PAD[1]; + u16 pcmciawrframebc; /* rev8 */ + u16 PAD[1]; + u16 pcmciaunderflowtimer; /* rev8 */ + u16 PAD[1]; + + /* interrupt */ + u32 intstatus; /* 0x020, rev8 */ + u32 hostintmask; /* rev8 */ + u32 intmask; /* rev8 */ + u32 sbintstatus; /* rev8 */ + u32 sbintmask; /* rev8 */ + u32 funcintmask; /* rev4 */ + u32 PAD[2]; + u32 tosbmailbox; /* 0x040, rev8 */ + u32 tohostmailbox; /* rev8 */ + u32 tosbmailboxdata; /* rev8 */ + u32 tohostmailboxdata; /* rev8 */ + + /* synchronized access to registers in SDIO clock domain */ + u32 sdioaccess; /* 0x050, rev8 */ + u32 PAD[3]; + + /* PCMCIA frame control */ + u8 pcmciaframectrl; /* 0x060, rev8 */ + u8 PAD[3]; + u8 pcmciawatermark; /* rev8 */ + u8 PAD[155]; + + /* interrupt batching control */ + u32 intrcvlazy; /* 0x100, rev8 */ + u32 PAD[3]; + + /* counters */ + u32 cmd52rd; /* 0x110, rev8 */ + u32 cmd52wr; /* rev8 */ + u32 cmd53rd; /* rev8 */ + u32 cmd53wr; /* rev8 */ + u32 abort; /* rev8 */ + u32 datacrcerror; /* rev8 */ + u32 rdoutofsync; /* rev8 */ + u32 wroutofsync; /* rev8 */ + u32 writebusy; /* rev8 */ + u32 readwait; /* rev8 */ + u32 readterm; /* rev8 */ + u32 writeterm; /* rev8 */ + u32 PAD[40]; + u32 clockctlstatus; /* rev8 */ + u32 PAD[7]; + + u32 PAD[128]; /* DMA engines */ + + /* SDIO/PCMCIA CIS region */ + char cis[512]; /* 0x400-0x5ff, rev6 */ + + /* PCMCIA function control registers */ + char pcmciafcr[256]; /* 0x600-6ff, rev6 */ + u16 PAD[55]; + + /* PCMCIA backplane access */ + u16 backplanecsr; /* 0x76E, rev6 */ + u16 backplaneaddr0; /* rev6 */ + u16 backplaneaddr1; /* rev6 */ + u16 backplaneaddr2; /* rev6 */ + u16 backplaneaddr3; /* rev6 */ + u16 backplanedata0; /* rev6 */ + u16 backplanedata1; /* rev6 */ + u16 backplanedata2; /* rev6 */ + u16 backplanedata3; /* rev6 */ + u16 PAD[31]; + + /* sprom "size" & "blank" info */ + u16 spromstatus; /* 0x7BE, rev2 */ + u32 PAD[464]; + + u16 PAD[0x80]; +}; + +#ifdef BCMDBG /* Device console log buffer state */ -typedef struct dhd_console { +struct brcmf_console { uint count; /* Poll interval msec counter */ uint log_addr; /* Log struct address (fixed) */ - hndrte_log_t log; /* Log struct (host copy) */ + struct rte_log log; /* Log struct (host copy) */ uint bufsize; /* Size of log buffer */ u8 *buf; /* Log buffer (host copy) */ uint last; /* Last buffer read index */ -} dhd_console_t; -#endif /* DHD_DEBUG */ +}; +#endif /* BCMDBG */ + +struct sdpcm_shared { + u32 flags; + u32 trap_addr; + u32 assert_exp_addr; + u32 assert_file_addr; + u32 assert_line; + u32 console_addr; /* Address of struct rte_console */ + u32 msgtrace_addr; + u8 tag[32]; +}; + /* misc chip info needed by some of the routines */ struct chip_info { @@ -166,7 +601,7 @@ struct chip_info { u32 cccorebase; u32 ccrev; u32 cccaps; - u32 buscorebase; + u32 buscorebase; /* 32 bits backplane bus address */ u32 buscorerev; u32 buscoretype; u32 ramcorebase; @@ -176,19 +611,14 @@ struct chip_info { }; /* Private data for SDIO bus interaction */ -typedef struct dhd_bus { - dhd_pub_t *dhd; +struct brcmf_bus { + struct brcmf_pub *drvr; - bcmsdh_info_t *sdh; /* Handle for BCMSDH calls */ + struct brcmf_sdio_card *card; /* Handle for sdio card calls */ struct chip_info *ci; /* Chip info struct */ char *vars; /* Variables (from CIS and/or other) */ uint varsz; /* Size of variables buffer */ - u32 sbaddr; /* Current SB window pointer (-1, invalid) */ - sdpcmd_regs_t *regs; /* Registers for SDIO core */ - uint sdpcmrev; /* SDIO core revision */ - uint armrev; /* CPU core revision */ - uint ramrev; /* SOCRAM core revision */ u32 ramsize; /* Size of RAM in SOCRAM (bytes) */ u32 orig_ramsize; /* Size of RAM in SOCRAM (bytes) */ @@ -198,10 +628,7 @@ typedef struct dhd_bus { bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */ bool fcstate; /* State of dongle flow-control */ - u16 cl_devid; /* cached devid for dhdsdio_probe_attach() */ - char *fw_path; /* module_param: path to firmware image */ - char *nv_path; /* module_param: path to nvram vars file */ - const char *nvram_params; /* user specified nvram params. */ + u16 cl_devid; /* cached devid for brcmf_sdio_probe_attach() */ uint blocksize; /* Block size of SDIO transfers */ uint roundup; /* Max roundup limit */ @@ -211,7 +638,7 @@ typedef struct dhd_bus { u8 tx_seq; /* Transmit sequence number (next) */ u8 tx_max; /* Maximum transmit sequence allowed */ - u8 hdrbuf[MAX_HDR_READ + DHD_SDALIGN]; + u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN]; u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */ u16 nextlen; /* Next Read Len from last header */ u8 rx_seq; /* Receive sequence number (expected) */ @@ -241,27 +668,23 @@ typedef struct dhd_bus { uint polltick; /* Tick counter */ uint pollcnt; /* Count of active polls */ -#ifdef DHD_DEBUG - dhd_console_t console; /* Console output polling support */ +#ifdef BCMDBG + struct brcmf_console console; /* Console output polling support */ uint console_addr; /* Console address from shared struct */ -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ - uint regfails; /* Count of R_REG/W_REG failures */ + uint regfails; /* Count of R_REG failures */ uint clkstate; /* State of sd and backplane clock(s) */ bool activity; /* Activity flag for clock down */ s32 idletime; /* Control for activity timeout */ s32 idlecount; /* Activity timeout counter */ s32 idleclock; /* How to set bus driver when idle */ - s32 sd_divisor; /* Speed control to bus driver */ - s32 sd_mode; /* Mode control to bus driver */ - s32 sd_rxchain; /* If bcmsdh api accepts PKT chains */ - bool use_rxchain; /* If dhd should use PKT chains */ + s32 sd_rxchain; + bool use_rxchain; /* If brcmf should use PKT chains */ bool sleeping; /* Is SDIO bus sleeping? */ bool rxflow_mode; /* Rx flow control mode */ bool rxflow; /* Is rx flow control on */ - uint prev_rxlim_hit; /* Is prev rx limit exceeded - (per dpc schedule) */ bool alp_only; /* Don't use HT clock (ALP only) */ /* Field to decide if rx of control frames happen in rxbuf or lb-pool */ bool usebufpool; @@ -313,7 +736,68 @@ typedef struct dhd_bus { u8 *ctrl_frame_buf; u32 ctrl_frame_len; bool ctrl_frame_stat; -} dhd_bus_t; + + spinlock_t txqlock; + wait_queue_head_t ctrl_wait; + + struct timer_list timer; + struct completion watchdog_wait; + struct task_struct *watchdog_tsk; + bool wd_timer_valid; + + struct tasklet_struct tasklet; + struct task_struct *dpc_tsk; + struct completion dpc_wait; + + bool threads_only; + struct semaphore sdsem; + spinlock_t sdlock; + + const char *fw_name; + const struct firmware *firmware; + const char *nv_name; + u32 fw_ptr; +}; + +struct sbconfig { + u32 PAD[2]; + u32 sbipsflag; /* initiator port ocp slave flag */ + u32 PAD[3]; + u32 sbtpsflag; /* target port ocp slave flag */ + u32 PAD[11]; + u32 sbtmerrloga; /* (sonics >= 2.3) */ + u32 PAD; + u32 sbtmerrlog; /* (sonics >= 2.3) */ + u32 PAD[3]; + u32 sbadmatch3; /* address match3 */ + u32 PAD; + u32 sbadmatch2; /* address match2 */ + u32 PAD; + u32 sbadmatch1; /* address match1 */ + u32 PAD[7]; + u32 sbimstate; /* initiator agent state */ + u32 sbintvec; /* interrupt mask */ + u32 sbtmstatelow; /* target state */ + u32 sbtmstatehigh; /* target state */ + u32 sbbwa0; /* bandwidth allocation table0 */ + u32 PAD; + u32 sbimconfiglow; /* initiator configuration */ + u32 sbimconfighigh; /* initiator configuration */ + u32 sbadmatch0; /* address match0 */ + u32 PAD; + u32 sbtmconfiglow; /* target configuration */ + u32 sbtmconfighigh; /* target configuration */ + u32 sbbconfig; /* broadcast configuration */ + u32 PAD; + u32 sbbstate; /* broadcast state */ + u32 PAD[3]; + u32 sbactcnfg; /* activate configuration */ + u32 PAD[3]; + u32 sbflagst; /* current sbflags */ + u32 PAD[3]; + u32 sbidlow; /* identification */ + u32 sbidhigh; /* identification */ +}; /* clkstate */ #define CLK_NONE 0 @@ -321,29 +805,45 @@ typedef struct dhd_bus { #define CLK_PENDING 2 /* Not used yet */ #define CLK_AVAIL 3 -#define DHD_NOPMU(dhd) (false) +#define BRCMF_NOPMU(brcmf) (false) -#ifdef DHD_DEBUG +#ifdef BCMDBG static int qcount[NUMPRIO]; static int tx_packets[NUMPRIO]; -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ /* Deferred transmit */ -const uint dhd_deferred_tx = 1; +uint brcmf_deferred_tx = 1; +module_param(brcmf_deferred_tx, uint, 0); -extern uint dhd_watchdog_ms; -extern void dhd_os_wd_timer(void *bus, uint wdtick); +/* Watchdog thread priority, -1 to use kernel timer */ +int brcmf_watchdog_prio = 97; +module_param(brcmf_watchdog_prio, int, 0); + +/* Watchdog interval */ +uint brcmf_watchdog_ms = 10; +module_param(brcmf_watchdog_ms, uint, 0); + +/* DPC thread priority, -1 to use tasklet */ +int brcmf_dpc_prio = 98; +module_param(brcmf_dpc_prio, int, 0); + +#ifdef BCMDBG +/* Console poll interval */ +uint brcmf_console_ms; +module_param(brcmf_console_ms, uint, 0); +#endif /* BCMDBG */ /* Tx/Rx bounds */ -uint dhd_txbound; -uint dhd_rxbound; -uint dhd_txminmax; +uint brcmf_txbound; +uint brcmf_rxbound; +uint brcmf_txminmax; /* override the RAM size if possible */ #define DONGLE_MIN_MEMSIZE (128 * 1024) -int dhd_dongle_memsize; +int brcmf_dongle_memsize; -static bool dhd_alignctl; +static bool brcmf_alignctl; static bool sd1idle; @@ -351,9 +851,7 @@ static bool retrydata; #define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata) static const uint watermark = 8; -static const uint firstread = DHD_FIRSTREAD; - -#define HDATLEN (firstread - (SDPCM_HDRLEN)) +static const uint firstread = BRCMF_FIRSTREAD; /* Retry count for register access failures */ static const uint retry_limit = 2; @@ -363,20 +861,11 @@ static bool forcealign; #define ALIGNMENT 4 -#if defined(OOB_INTR_ONLY) && defined(HW_OOB) -extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable); -#endif - -#if defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) -#error OOB_INTR_ONLY is NOT working with SDIO_ISR_THREAD -#endif /* defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) */ #define PKTALIGN(_p, _len, _align) \ do { \ uint datalign; \ datalign = (unsigned long)((_p)->data); \ datalign = roundup(datalign, (_align)) - datalign; \ - ASSERT(datalign < (_align)); \ - ASSERT((_p)->len >= ((_len) + datalign)); \ if (datalign) \ skb_pull((_p), datalign); \ __skb_trim((_p), (_len)); \ @@ -386,146 +875,166 @@ extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable); static const uint max_roundup = 512; /* Try doing readahead */ -static bool dhd_readahead; +static bool brcmf_readahead; /* To check if there's window offered */ #define DATAOK(bus) \ (((u8)(bus->tx_max - bus->tx_seq) != 0) && \ (((u8)(bus->tx_max - bus->tx_seq) & 0x80) == 0)) -/* Macros to get register read/write status */ -/* NOTE: these assume a local dhdsdio_bus_t *bus! */ -#define R_SDREG(regvar, regaddr, retryvar) \ -do { \ - retryvar = 0; \ - do { \ - regvar = R_REG(regaddr); \ - } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \ - if (retryvar) { \ - bus->regfails += (retryvar-1); \ - if (retryvar > retry_limit) { \ - DHD_ERROR(("%s: FAILED" #regvar "READ, LINE %d\n", \ - __func__, __LINE__)); \ - regvar = 0; \ - } \ - } \ -} while (0) +/* + * Reads a register in the SDIO hardware block. This block occupies a series of + * adresses on the 32 bit backplane bus. + */ +static void +r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) +{ + *retryvar = 0; + do { + *regvar = R_REG(bus->ci->buscorebase + reg_offset, u32); + } while (brcmf_sdcard_regfail(bus->card) && + (++(*retryvar) <= retry_limit)); + if (*retryvar) { + bus->regfails += (*retryvar-1); + if (*retryvar > retry_limit) { + BRCMF_ERROR(("FAILED READ %Xh\n", reg_offset)); + *regvar = 0; + } + } +} -#define W_SDREG(regval, regaddr, retryvar) \ -do { \ - retryvar = 0; \ - do { \ - W_REG(regaddr, regval); \ - } while (bcmsdh_regfail(bus->sdh) && (++retryvar <= retry_limit)); \ - if (retryvar) { \ - bus->regfails += (retryvar-1); \ - if (retryvar > retry_limit) \ - DHD_ERROR(("%s: FAILED REGISTER WRITE, LINE %d\n", \ - __func__, __LINE__)); \ - } \ -} while (0) +static void +w_sdreg32(struct brcmf_bus *bus, u32 regval, u32 reg_offset, u32 *retryvar) +{ + *retryvar = 0; + do { + brcmf_sdcard_reg_write(NULL, bus->ci->buscorebase + reg_offset, + sizeof(u32), regval); + } while (brcmf_sdcard_regfail(bus->card) && + (++(*retryvar) <= retry_limit)); + if (*retryvar) { + bus->regfails += (*retryvar-1); + if (*retryvar > retry_limit) + BRCMF_ERROR(("FAILED REGISTER WRITE" + " %Xh\n", reg_offset)); + } +} -#define DHD_BUS SDIO_BUS +#define BRCMF_BUS SDIO_BUS #define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND) #define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) #ifdef SDTEST -static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq); -static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start); +static void brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, void *pkt, uint seq); +static void brcmf_sdbrcm_sdtest_set(struct brcmf_bus *bus, bool start); #endif -#ifdef DHD_DEBUG -static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size); -static int dhdsdio_mem_dump(dhd_bus_t *bus); -#endif /* DHD_DEBUG */ -static int dhdsdio_download_state(dhd_bus_t *bus, bool enter); +#ifdef BCMDBG +static int brcmf_sdbrcm_bus_console_in(struct brcmf_pub *drvr, + unsigned char *msg, uint msglen); +static int brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, u8 *data, uint size); +static int brcmf_sdbrcm_mem_dump(struct brcmf_bus *bus); +#endif /* BCMDBG */ +static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter); -static void dhdsdio_release(dhd_bus_t *bus); -static void dhdsdio_release_malloc(dhd_bus_t *bus); -static void dhdsdio_disconnect(void *ptr); -static bool dhdsdio_chipmatch(u16 chipid); -static bool dhdsdio_probe_attach(dhd_bus_t *bus, void *sdh, - void *regsva, u16 devid); -static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh); -static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh); -static void dhdsdio_release_dongle(dhd_bus_t *bus); +static void brcmf_sdbrcm_release(struct brcmf_bus *bus); +static void brcmf_sdbrcm_release_malloc(struct brcmf_bus *bus); +static void brcmf_sdbrcm_disconnect(void *ptr); +static bool brcmf_sdbrcm_chipmatch(u16 chipid); +static bool brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, void *card, + u32 regsva, u16 devid); +static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus, void *card); +static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus, void *card); +static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus); -static uint process_nvram_vars(char *varbuf, uint len); +static uint brcmf_process_nvram_vars(char *varbuf, uint len); -static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size); -static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, +static void brcmf_sdbrcm_setmemsize(struct brcmf_bus *bus, int mem_size); +static int brcmf_sdbrcm_send_buf(struct brcmf_bus *bus, u32 addr, uint fn, uint flags, u8 *buf, uint nbytes, - struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete, + struct sk_buff *pkt, + void (*complete)(void *handle, int status, + bool sync_waiting), void *handle); -static bool dhdsdio_download_firmware(struct dhd_bus *bus, void *sdh); -static int _dhdsdio_download_firmware(struct dhd_bus *bus); +static bool brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus, void *card); +static int _brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus); -static int dhdsdio_download_code_file(struct dhd_bus *bus, char *image_path); -static int dhdsdio_download_nvram(struct dhd_bus *bus); -#ifdef BCMEMBEDIMAGE -static int dhdsdio_download_code_array(struct dhd_bus *bus); -#endif -static void dhdsdio_chip_disablecore(bcmsdh_info_t *sdh, u32 corebase); -static int dhdsdio_chip_attach(struct dhd_bus *bus, void *regs); -static void dhdsdio_chip_resetcore(bcmsdh_info_t *sdh, u32 corebase); -static void dhdsdio_sdiod_drive_strength_init(struct dhd_bus *bus, +static int brcmf_sdbrcm_download_code_file(struct brcmf_bus *bus); +static int brcmf_sdbrcm_download_nvram(struct brcmf_bus *bus); + +static void +brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_card *card, u32 corebase); + +static int brcmf_sdbrcm_chip_attach(struct brcmf_bus *bus, u32 regs); + +static void +brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_card *card, u32 corebase); + +static void brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus, u32 drivestrength); -static void dhdsdio_chip_detach(struct dhd_bus *bus); +static void brcmf_sdbrcm_chip_detach(struct brcmf_bus *bus); +static void brcmf_sdbrcm_wait_for_event(struct brcmf_bus *bus, bool *lockvar); +static void brcmf_sdbrcm_wait_event_wakeup(struct brcmf_bus *bus); +static void brcmf_sdbrcm_watchdog(unsigned long data); +static int brcmf_sdbrcm_watchdog_thread(void *data); +static int brcmf_sdbrcm_dpc_thread(void *data); +static void brcmf_sdbrcm_dpc_tasklet(unsigned long data); +static void brcmf_sdbrcm_sched_dpc(struct brcmf_bus *bus); +static void brcmf_sdbrcm_sdlock(struct brcmf_bus *bus); +static void brcmf_sdbrcm_sdunlock(struct brcmf_bus *bus); +static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_bus *bus); /* Packet free applicable unconditionally for sdio and sdspi. * Conditional if bufpool was present for gspi bus. */ -static void dhdsdio_pktfree2(dhd_bus_t *bus, struct sk_buff *pkt) +static void brcmf_sdbrcm_pktfree2(struct brcmf_bus *bus, struct sk_buff *pkt) { - dhd_os_sdlock_rxq(bus->dhd); if ((bus->bus != SPI_BUS) || bus->usebufpool) - bcm_pkt_buf_free_skb(pkt); - dhd_os_sdunlock_rxq(bus->dhd); + brcmu_pkt_buf_free_skb(pkt); } -static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size) +static void brcmf_sdbrcm_setmemsize(struct brcmf_bus *bus, int mem_size) { s32 min_size = DONGLE_MIN_MEMSIZE; /* Restrict the memsize to user specified limit */ - DHD_ERROR(("user: Restrict the dongle ram size to %d, min %d\n", - dhd_dongle_memsize, min_size)); - if ((dhd_dongle_memsize > min_size) && - (dhd_dongle_memsize < (s32) bus->orig_ramsize)) - bus->ramsize = dhd_dongle_memsize; + BRCMF_ERROR(("user: Restrict the dongle ram size to %d, min %d\n", + brcmf_dongle_memsize, min_size)); + if ((brcmf_dongle_memsize > min_size) && + (brcmf_dongle_memsize < (s32) bus->orig_ramsize)) + bus->ramsize = brcmf_dongle_memsize; } -static int dhdsdio_set_siaddr_window(dhd_bus_t *bus, u32 address) +static int brcmf_sdbrcm_set_siaddr_window(struct brcmf_bus *bus, u32 address) { int err = 0; - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); if (!err) - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, + SBSDIO_FUNC1_SBADDRMID, (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); if (!err) - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, - (address >> 24) & SBSDIO_SBADDRHIGH_MASK, - &err); + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, + SBSDIO_FUNC1_SBADDRHIGH, + (address >> 24) & SBSDIO_SBADDRHIGH_MASK, + &err); return err; } /* Turn backplane clock on or off */ -static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) +static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok) { int err; u8 clkctl, clkreq, devctl; - bcmsdh_info_t *sdh; + struct brcmf_sdio_card *card; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); -#if defined(OOB_INTR_ONLY) - pendok = false; -#endif clkctl = 0; - sdh = bus->sdh; + card = bus->card; if (on) { /* Request HT Avail */ @@ -536,99 +1045,93 @@ static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) && (bus->ci->chiprev == 0)) clkreq |= SBSDIO_FORCE_ALP; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - clkreq, &err); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); if (err) { - DHD_ERROR(("%s: HT Avail request error: %d\n", - __func__, err)); + BRCMF_ERROR(("%s: HT Avail request error: %d\n", + __func__, err)); return -EBADE; } if (pendok && ((bus->ci->buscoretype == PCMCIA_CORE_ID) && (bus->ci->buscorerev == 9))) { u32 dummy, retries; - R_SDREG(dummy, &bus->regs->clockctlstatus, retries); + r_sdreg32(bus, &dummy, + offsetof(struct sdpcmd_regs, clockctlstatus), + &retries); } /* Check current status */ - clkctl = - bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - &err); + clkctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err) { - DHD_ERROR(("%s: HT Avail read error: %d\n", - __func__, err)); + BRCMF_ERROR(("%s: HT Avail read error: %d\n", + __func__, err)); return -EBADE; } /* Go to pending and await interrupt if appropriate */ if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { /* Allow only clock-available interrupt */ - devctl = - bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - &err); + devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, &err); if (err) { - DHD_ERROR(("%s: Devctl error setting CA: %d\n", - __func__, err)); + BRCMF_ERROR(("%s: Devctl error setting CA:" + " %d\n", __func__, err)); return -EBADE; } devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - devctl, &err); - DHD_INFO(("CLKCTL: set PENDING\n")); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, devctl, &err); + BRCMF_INFO(("CLKCTL: set PENDING\n")); bus->clkstate = CLK_PENDING; return 0; } else if (bus->clkstate == CLK_PENDING) { /* Cancel CA-only interrupt filter */ devctl = - bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - &err); + brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, &err); devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, devctl, &err); } /* Otherwise, wait here (polling) for HT Avail */ if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - SPINWAIT_SLEEP(sdioh_spinwait_sleep, - ((clkctl = - bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, - &err)), - !SBSDIO_CLKAV(clkctl, bus->alp_only)), - PMU_MAX_TRANSITION_DLY); + BRCMF_SPINWAIT_SLEEP(sdioh_spinwait_sleep, + ((clkctl = + brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + &err)), + !SBSDIO_CLKAV(clkctl, bus->alp_only)), + PMU_MAX_TRANSITION_DLY); } if (err) { - DHD_ERROR(("%s: HT Avail request error: %d\n", - __func__, err)); + BRCMF_ERROR(("%s: HT Avail request error: %d\n", + __func__, err)); return -EBADE; } if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - DHD_ERROR(("%s: HT Avail timeout (%d): clkctl 0x%02x\n", - __func__, PMU_MAX_TRANSITION_DLY, clkctl)); + BRCMF_ERROR(("%s: HT Avail timeout (%d): " + "clkctl 0x%02x\n", __func__, + PMU_MAX_TRANSITION_DLY, clkctl)); return -EBADE; } /* Mark clock available */ bus->clkstate = CLK_AVAIL; - DHD_INFO(("CLKCTL: turned ON\n")); + BRCMF_INFO(("CLKCTL: turned ON\n")); -#if defined(DHD_DEBUG) - if (bus->alp_only == true) { -#if !defined(BCMLXSDMMC) - if (!SBSDIO_ALPONLY(clkctl)) { - DHD_ERROR(("%s: HT Clock, when ALP Only\n", - __func__)); - } -#endif /* !defined(BCMLXSDMMC) */ - } else { +#if defined(BCMDBG) + if (bus->alp_only != true) { if (SBSDIO_ALPONLY(clkctl)) { - DHD_ERROR(("%s: HT Clock should be on.\n", - __func__)); + BRCMF_ERROR(("%s: HT Clock should be on.\n", + __func__)); } } -#endif /* defined (DHD_DEBUG) */ +#endif /* defined (BCMDBG) */ bus->activity = true; } else { @@ -636,21 +1139,20 @@ static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) if (bus->clkstate == CLK_PENDING) { /* Cancel CA-only interrupt filter */ - devctl = - bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - &err); + devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, &err); devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, devctl, &err); } bus->clkstate = CLK_SDONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - clkreq, &err); - DHD_INFO(("CLKCTL: turned OFF\n")); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); + BRCMF_INFO(("CLKCTL: turned OFF\n")); if (err) { - DHD_ERROR(("%s: Failed access turning clock off: %d\n", - __func__, err)); + BRCMF_ERROR(("%s: Failed access turning clock off:" + " %d\n", __func__, err)); return -EBADE; } } @@ -658,105 +1160,31 @@ static int dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) } /* Change idle/active SD state */ -static int dhdsdio_sdclk(dhd_bus_t *bus, bool on) +static int brcmf_sdbrcm_sdclk(struct brcmf_bus *bus, bool on) { - int err; - s32 iovalue; + BRCMF_TRACE(("%s: Enter\n", __func__)); - DHD_TRACE(("%s: Enter\n", __func__)); - - if (on) { - if (bus->idleclock == DHD_IDLE_STOP) { - /* Turn on clock and restore mode */ - iovalue = 1; - err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0, - &iovalue, sizeof(iovalue), true); - if (err) { - DHD_ERROR(("%s: error enabling sd_clock: %d\n", - __func__, err)); - return -EBADE; - } - - iovalue = bus->sd_mode; - err = bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, - &iovalue, sizeof(iovalue), true); - if (err) { - DHD_ERROR(("%s: error changing sd_mode: %d\n", - __func__, err)); - return -EBADE; - } - } else if (bus->idleclock != DHD_IDLE_ACTIVE) { - /* Restore clock speed */ - iovalue = bus->sd_divisor; - err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, - &iovalue, sizeof(iovalue), true); - if (err) { - DHD_ERROR(("%s: error restoring sd_divisor: %d\n", - __func__, err)); - return -EBADE; - } - } + if (on) bus->clkstate = CLK_SDONLY; - } else { - /* Stop or slow the SD clock itself */ - if ((bus->sd_divisor == -1) || (bus->sd_mode == -1)) { - DHD_TRACE(("%s: can't idle clock, divisor %d mode %d\n", - __func__, bus->sd_divisor, bus->sd_mode)); - return -EBADE; - } - if (bus->idleclock == DHD_IDLE_STOP) { - if (sd1idle) { - /* Change to SD1 mode and turn off clock */ - iovalue = 1; - err = - bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, - 0, &iovalue, - sizeof(iovalue), true); - if (err) { - DHD_ERROR(("%s: error changing sd_clock: %d\n", - __func__, err)); - return -EBADE; - } - } - - iovalue = 0; - err = bcmsdh_iovar_op(bus->sdh, "sd_clock", NULL, 0, - &iovalue, sizeof(iovalue), true); - if (err) { - DHD_ERROR(("%s: error disabling sd_clock: %d\n", - __func__, err)); - return -EBADE; - } - } else if (bus->idleclock != DHD_IDLE_ACTIVE) { - /* Set divisor to idle value */ - iovalue = bus->idleclock; - err = bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, - &iovalue, sizeof(iovalue), true); - if (err) { - DHD_ERROR(("%s: error changing sd_divisor: %d\n", - __func__, err)); - return -EBADE; - } - } + else bus->clkstate = CLK_NONE; - } return 0; } /* Transition SD and backplane clock readiness */ -static int dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) +static int brcmf_sdbrcm_clkctl(struct brcmf_bus *bus, uint target, bool pendok) { -#ifdef DHD_DEBUG +#ifdef BCMDBG uint oldstate = bus->clkstate; -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); /* Early exit if we're already there */ if (bus->clkstate == target) { if (target == CLK_AVAIL) { - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); + brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms); bus->activity = true; } return 0; @@ -766,50 +1194,50 @@ static int dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) case CLK_AVAIL: /* Make sure SD clock is available */ if (bus->clkstate == CLK_NONE) - dhdsdio_sdclk(bus, true); + brcmf_sdbrcm_sdclk(bus, true); /* Now request HT Avail on the backplane */ - dhdsdio_htclk(bus, true, pendok); - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); + brcmf_sdbrcm_htclk(bus, true, pendok); + brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms); bus->activity = true; break; case CLK_SDONLY: /* Remove HT request, or bring up SD clock */ if (bus->clkstate == CLK_NONE) - dhdsdio_sdclk(bus, true); + brcmf_sdbrcm_sdclk(bus, true); else if (bus->clkstate == CLK_AVAIL) - dhdsdio_htclk(bus, false, false); + brcmf_sdbrcm_htclk(bus, false, false); else - DHD_ERROR(("dhdsdio_clkctl: request for %d -> %d\n", - bus->clkstate, target)); - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); + BRCMF_ERROR(("brcmf_sdbrcm_clkctl: request for %d -> %d" + "\n", bus->clkstate, target)); + brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms); break; case CLK_NONE: /* Make sure to remove HT request */ if (bus->clkstate == CLK_AVAIL) - dhdsdio_htclk(bus, false, false); + brcmf_sdbrcm_htclk(bus, false, false); /* Now remove the SD clock */ - dhdsdio_sdclk(bus, false); - dhd_os_wd_timer(bus->dhd, 0); + brcmf_sdbrcm_sdclk(bus, false); + brcmf_sdbrcm_wd_timer(bus, 0); break; } -#ifdef DHD_DEBUG - DHD_INFO(("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate)); -#endif /* DHD_DEBUG */ +#ifdef BCMDBG + BRCMF_INFO(("brcmf_sdbrcm_clkctl: %d -> %d\n", + oldstate, bus->clkstate)); +#endif /* BCMDBG */ return 0; } -int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) +int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) { - bcmsdh_info_t *sdh = bus->sdh; - sdpcmd_regs_t *regs = bus->regs; + struct brcmf_sdio_card *card = bus->card; uint retries = 0; - DHD_INFO(("dhdsdio_bussleep: request %s (currently %s)\n", - (sleep ? "SLEEP" : "WAKE"), - (bus->sleeping ? "SLEEP" : "WAKE"))); + BRCMF_INFO(("brcmf_sdbrcm_bussleep: request %s (currently %s)\n", + (sleep ? "SLEEP" : "WAKE"), + (bus->sleeping ? "SLEEP" : "WAKE"))); /* Done if we're already in the requested state */ if (sleep == bus->sleeping) @@ -822,27 +1250,31 @@ int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) return -EBUSY; /* Disable SDIO interrupts (no longer interested) */ - bcmsdh_intr_disable(bus->sdh); + brcmf_sdcard_intr_disable(bus->card); /* Make sure the controller has the bus up */ - dhdsdio_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); /* Tell device to start using OOB wakeup */ - W_SDREG(SMB_USE_OOB, ®s->tosbmailbox, retries); + w_sdreg32(bus, SMB_USE_OOB, + offsetof(struct sdpcmd_regs, tosbmailbox), &retries); if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n")); + BRCMF_ERROR(("CANNOT SIGNAL CHIP, " + "WILL NOT WAKE UP!!\n")); /* Turn off our contribution to the HT clock request */ - dhdsdio_clkctl(bus, CLK_SDONLY, false); + brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); /* Isolate the bus */ if (bus->ci->chip != BCM4329_CHIP_ID && bus->ci->chip != BCM4319_CHIP_ID) { - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - SBSDIO_DEVCTL_PADS_ISO, NULL); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, + SBSDIO_DEVCTL_PADS_ISO, NULL); } /* Change state */ @@ -851,82 +1283,55 @@ int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep) } else { /* Waking up: bus power up is ok, set local state */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - 0, NULL); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); /* Force pad isolation off if possible (in case power never toggled) */ if ((bus->ci->buscoretype == PCMCIA_CORE_ID) && (bus->ci->buscorerev >= 10)) - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0, - NULL); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, 0, NULL); /* Make sure the controller has the bus up */ - dhdsdio_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); /* Send misc interrupt to indicate OOB not needed */ - W_SDREG(0, ®s->tosbmailboxdata, retries); + w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, tosbmailboxdata), + &retries); if (retries <= retry_limit) - W_SDREG(SMB_DEV_INT, ®s->tosbmailbox, retries); + w_sdreg32(bus, SMB_DEV_INT, + offsetof(struct sdpcmd_regs, tosbmailbox), + &retries); if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n")); + BRCMF_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n")); /* Make sure we have SD bus access */ - dhdsdio_clkctl(bus, CLK_SDONLY, false); + brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); /* Change state */ bus->sleeping = false; /* Enable interrupts again */ - if (bus->intr && (bus->dhd->busstate == DHD_BUS_DATA)) { + if (bus->intr && (bus->drvr->busstate == BRCMF_BUS_DATA)) { bus->intdis = false; - bcmsdh_intr_enable(bus->sdh); + brcmf_sdcard_intr_enable(bus->card); } } return 0; } -#if defined(OOB_INTR_ONLY) -void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable) -{ -#if defined(HW_OOB) - bcmsdh_enable_hw_oob_intr(bus->sdh, enable); -#else - sdpcmd_regs_t *regs = bus->regs; - uint retries = 0; - - dhdsdio_clkctl(bus, CLK_AVAIL, false); - if (enable == true) { - - /* Tell device to start using OOB wakeup */ - W_SDREG(SMB_USE_OOB, ®s->tosbmailbox, retries); - if (retries > retry_limit) - DHD_ERROR(("CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n")); - - } else { - /* Send misc interrupt to indicate OOB not needed */ - W_SDREG(0, ®s->tosbmailboxdata, retries); - if (retries <= retry_limit) - W_SDREG(SMB_DEV_INT, ®s->tosbmailbox, retries); - } - - /* Turn off our contribution to the HT clock request */ - dhdsdio_clkctl(bus, CLK_SDONLY, false); -#endif /* !defined(HW_OOB) */ -} -#endif /* defined(OOB_INTR_ONLY) */ - #define BUS_WAKE(bus) \ do { \ if ((bus)->sleeping) \ - dhdsdio_bussleep((bus), false); \ + brcmf_sdbrcm_bussleep((bus), false); \ } while (0); /* Writes a HW/SW header into the packet and sends it. */ /* Assumes: (a) header space already there, (b) caller holds lock */ -static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, +static int brcmf_sdbrcm_txpkt(struct brcmf_bus *bus, struct sk_buff *pkt, uint chan, bool free_pkt) { int ret; @@ -934,15 +1339,15 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, u16 len, pad = 0; u32 swheader; uint retries = 0; - bcmsdh_info_t *sdh; + struct brcmf_sdio_card *card; struct sk_buff *new; int i; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - sdh = bus->sdh; + card = bus->card; - if (bus->dhd->dongle_reset) { + if (bus->drvr->dongle_reset) { ret = -EPERM; goto done; } @@ -950,40 +1355,39 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, frame = (u8 *) (pkt->data); /* Add alignment padding, allocate new packet if needed */ - pad = ((unsigned long)frame % DHD_SDALIGN); + pad = ((unsigned long)frame % BRCMF_SDALIGN); if (pad) { if (skb_headroom(pkt) < pad) { - DHD_INFO(("%s: insufficient headroom %d for %d pad\n", - __func__, skb_headroom(pkt), pad)); - bus->dhd->tx_realloc++; - new = bcm_pkt_buf_get_skb(pkt->len + DHD_SDALIGN); + BRCMF_INFO(("%s: insufficient headroom %d for %d pad\n", + __func__, skb_headroom(pkt), pad)); + bus->drvr->tx_realloc++; + new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN); if (!new) { - DHD_ERROR(("%s: couldn't allocate new %d-byte " - "packet\n", - __func__, pkt->len + DHD_SDALIGN)); + BRCMF_ERROR(("%s: couldn't allocate new " + "%d-byte packet\n", __func__, + pkt->len + BRCMF_SDALIGN)); ret = -ENOMEM; goto done; } - PKTALIGN(new, pkt->len, DHD_SDALIGN); + PKTALIGN(new, pkt->len, BRCMF_SDALIGN); memcpy(new->data, pkt->data, pkt->len); if (free_pkt) - bcm_pkt_buf_free_skb(pkt); + brcmu_pkt_buf_free_skb(pkt); /* free the pkt if canned one is not used */ free_pkt = true; pkt = new; frame = (u8 *) (pkt->data); - ASSERT(((unsigned long)frame % DHD_SDALIGN) == 0); + /* precondition: (frame % BRCMF_SDALIGN) == 0) */ pad = 0; } else { skb_push(pkt, pad); frame = (u8 *) (pkt->data); - - ASSERT((pad + SDPCM_HDRLEN) <= (int)(pkt->len)); + /* precondition: pad + SDPCM_HDRLEN <= pkt->len */ memset(frame, 0, pad + SDPCM_HDRLEN); } } - ASSERT(pad < DHD_SDALIGN); + /* precondition: pad < BRCMF_SDALIGN */ /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ len = (u16) (pkt->len); @@ -999,14 +1403,14 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN); put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); -#ifdef DHD_DEBUG +#ifdef BCMDBG tx_packets[pkt->priority]++; - if (DHD_BYTES_ON() && - (((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || - (DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) { + if (BRCMF_BYTES_ON() && + (((BRCMF_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || + (BRCMF_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) { printk(KERN_DEBUG "Tx Frame:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len); - } else if (DHD_HDRS_ON()) { + } else if (BRCMF_HDRS_ON()) { printk(KERN_DEBUG "TxHdr:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, min_t(u16, len, 16)); @@ -1017,53 +1421,40 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { u16 pad = bus->blocksize - (len % bus->blocksize); if ((pad <= bus->roundup) && (pad < bus->blocksize)) -#ifdef NOTUSED - if (pad <= skb_tailroom(pkt)) -#endif /* NOTUSED */ len += pad; - } else if (len % DHD_SDALIGN) { - len += DHD_SDALIGN - (len % DHD_SDALIGN); + } else if (len % BRCMF_SDALIGN) { + len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN); } /* Some controllers have trouble with odd bytes -- round to even */ if (forcealign && (len & (ALIGNMENT - 1))) { -#ifdef NOTUSED - if (skb_tailroom(pkt)) -#endif len = roundup(len, ALIGNMENT); -#ifdef NOTUSED - else - DHD_ERROR(("%s: sending unrounded %d-byte packet\n", - __func__, len)); -#endif } do { - ret = - dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, - F2SYNC, frame, len, pkt, NULL, NULL); + ret = brcmf_sdbrcm_send_buf(bus, brcmf_sdcard_cur_sbwad(card), + SDIO_FUNC_2, F2SYNC, frame, len, pkt, NULL, NULL); bus->f2txdata++; - ASSERT(ret != -BCME_PENDING); if (ret < 0) { /* On failure, abort the command and terminate the frame */ - DHD_INFO(("%s: sdio error %d, abort command and " - "terminate frame.\n", __func__, ret)); + BRCMF_INFO(("%s: sdio error %d, abort command and " + "terminate frame.\n", __func__, ret)); bus->tx_sderrs++; - bcmsdh_abort(sdh, SDIO_FUNC_2); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, + brcmf_sdcard_abort(card, SDIO_FUNC_2); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); bus->f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, + hi = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, + lo = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, SBSDIO_FUNC1_WFRAMEBCLO, NULL); bus->f1regdata += 2; @@ -1080,22 +1471,22 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, done: /* restore pkt buffer pointer before calling tx complete routine */ skb_pull(pkt, SDPCM_HDRLEN + pad); - dhd_os_sdunlock(bus->dhd); - dhd_txcomplete(bus->dhd, pkt, ret != 0); - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); + brcmf_txcomplete(bus->drvr, pkt, ret != 0); + brcmf_sdbrcm_sdlock(bus); if (free_pkt) - bcm_pkt_buf_free_skb(pkt); + brcmu_pkt_buf_free_skb(pkt); return ret; } -int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt) +int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *pkt) { int ret = -EBADE; uint datalen, prec; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); datalen = pkt->len; @@ -1115,79 +1506,80 @@ int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt) /* Add space for the header */ skb_push(pkt, SDPCM_HDRLEN); - ASSERT(IS_ALIGNED((unsigned long)(pkt->data), 2)); + /* precondition: IS_ALIGNED((unsigned long)(pkt->data), 2) */ prec = PRIO2PREC((pkt->priority & PRIOMASK)); /* Check for existing queue, current flow-control, pending event, or pending clock */ - if (dhd_deferred_tx || bus->fcstate || pktq_len(&bus->txq) + if (brcmf_deferred_tx || bus->fcstate || pktq_len(&bus->txq) || bus->dpc_sched || (!DATAOK(bus)) || (bus->flowcontrol & NBITVAL(prec)) || (bus->clkstate != CLK_AVAIL)) { - DHD_TRACE(("%s: deferring pktq len %d\n", __func__, - pktq_len(&bus->txq))); + BRCMF_TRACE(("%s: deferring pktq len %d\n", __func__, + pktq_len(&bus->txq))); bus->fcqueued++; /* Priority based enq */ - dhd_os_sdlock_txq(bus->dhd); - if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == false) { + spin_lock_bh(&bus->txqlock); + if (brcmf_c_prec_enq(bus->drvr, &bus->txq, pkt, prec) == false) { skb_pull(pkt, SDPCM_HDRLEN); - dhd_txcomplete(bus->dhd, pkt, false); - bcm_pkt_buf_free_skb(pkt); - DHD_ERROR(("%s: out of bus->txq !!!\n", __func__)); + brcmf_txcomplete(bus->drvr, pkt, false); + brcmu_pkt_buf_free_skb(pkt); + BRCMF_ERROR(("%s: out of bus->txq !!!\n", __func__)); ret = -ENOSR; } else { ret = 0; } - dhd_os_sdunlock_txq(bus->dhd); + spin_unlock_bh(&bus->txqlock); if (pktq_len(&bus->txq) >= TXHI) - dhd_txflowcontrol(bus->dhd, 0, ON); + brcmf_txflowcontrol(bus->drvr, 0, ON); -#ifdef DHD_DEBUG +#ifdef BCMDBG if (pktq_plen(&bus->txq, prec) > qcount[prec]) qcount[prec] = pktq_plen(&bus->txq, prec); #endif /* Schedule DPC if needed to send queued packet(s) */ - if (dhd_deferred_tx && !bus->dpc_sched) { + if (brcmf_deferred_tx && !bus->dpc_sched) { bus->dpc_sched = true; - dhd_sched_dpc(bus->dhd); + brcmf_sdbrcm_sched_dpc(bus); } } else { /* Lock: we're about to use shared data/code (and SDIO) */ - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdlock(bus); /* Otherwise, send it now */ BUS_WAKE(bus); /* Make sure back plane ht clk is on, no pending allowed */ - dhdsdio_clkctl(bus, CLK_AVAIL, true); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true); #ifndef SDTEST - DHD_TRACE(("%s: calling txpkt\n", __func__)); - ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); + BRCMF_TRACE(("%s: calling txpkt\n", __func__)); + ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); #else - ret = dhdsdio_txpkt(bus, pkt, + ret = brcmf_sdbrcm_txpkt(bus, pkt, (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL), true); #endif if (ret) - bus->dhd->tx_errors++; + bus->drvr->tx_errors++; else - bus->dhd->dstats.tx_bytes += datalen; + bus->drvr->dstats.tx_bytes += datalen; - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { + if (bus->idletime == BRCMF_IDLE_IMMEDIATE && + !bus->dpc_sched) { bus->activity = false; - dhdsdio_clkctl(bus, CLK_NONE, true); + brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); } - dhd_os_sdunlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); } return ret; } -static uint dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) +static uint brcmf_sdbrcm_sendfromq(struct brcmf_bus *bus, uint maxframes) { struct sk_buff *pkt; u32 intstatus = 0; @@ -1197,42 +1589,43 @@ static uint dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) uint datalen; u8 tx_prec_map; - dhd_pub_t *dhd = bus->dhd; - sdpcmd_regs_t *regs = bus->regs; + struct brcmf_pub *drvr = bus->drvr; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); tx_prec_map = ~bus->flowcontrol; /* Send frames until the limit or some other event */ for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) { - dhd_os_sdlock_txq(bus->dhd); - pkt = bcm_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out); + spin_lock_bh(&bus->txqlock); + pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out); if (pkt == NULL) { - dhd_os_sdunlock_txq(bus->dhd); + spin_unlock_bh(&bus->txqlock); break; } - dhd_os_sdunlock_txq(bus->dhd); + spin_unlock_bh(&bus->txqlock); datalen = pkt->len - SDPCM_HDRLEN; #ifndef SDTEST - ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); + ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); #else - ret = dhdsdio_txpkt(bus, pkt, + ret = brcmf_sdbrcm_txpkt(bus, pkt, (bus->ext_loop ? SDPCM_TEST_CHANNEL : SDPCM_DATA_CHANNEL), true); #endif if (ret) - bus->dhd->tx_errors++; + bus->drvr->tx_errors++; else - bus->dhd->dstats.tx_bytes += datalen; + bus->drvr->dstats.tx_bytes += datalen; /* In poll mode, need to check for other events */ if (!bus->intr && cnt) { /* Check device status, signal pending interrupt */ - R_SDREG(intstatus, ®s->intstatus, retries); + r_sdreg32(bus, &intstatus, + offsetof(struct sdpcmd_regs, intstatus), + &retries); bus->f2txdata++; - if (bcmsdh_regfail(bus->sdh)) + if (brcmf_sdcard_regfail(bus->card)) break; if (intstatus & bus->hostintmask) bus->ipend = true; @@ -1240,27 +1633,28 @@ static uint dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) } /* Deflow-control stack if needed */ - if (dhd->up && (dhd->busstate == DHD_BUS_DATA) && - dhd->txoff && (pktq_len(&bus->txq) < TXLOW)) - dhd_txflowcontrol(dhd, 0, OFF); + if (drvr->up && (drvr->busstate == BRCMF_BUS_DATA) && + drvr->txoff && (pktq_len(&bus->txq) < TXLOW)) + brcmf_txflowcontrol(drvr, 0, OFF); return cnt; } -int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) +int +brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen) { u8 *frame; u16 len; u32 swheader; uint retries = 0; - bcmsdh_info_t *sdh = bus->sdh; + struct brcmf_sdio_card *card = bus->card; u8 doff = 0; int ret = -1; int i; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - if (bus->dhd->dongle_reset) + if (bus->drvr->dongle_reset) return -EIO; /* Back the pointer to make a room for bus header */ @@ -1268,15 +1662,15 @@ int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) len = (msglen += SDPCM_HDRLEN); /* Add alignment padding (optional for ctl frames) */ - if (dhd_alignctl) { - doff = ((unsigned long)frame % DHD_SDALIGN); + if (brcmf_alignctl) { + doff = ((unsigned long)frame % BRCMF_SDALIGN); if (doff) { frame -= doff; len += doff; msglen += doff; memset(frame, 0, doff + SDPCM_HDRLEN); } - ASSERT(doff < DHD_SDALIGN); + /* precondition: doff < BRCMF_SDALIGN */ } doff += SDPCM_HDRLEN; @@ -1285,23 +1679,23 @@ int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) u16 pad = bus->blocksize - (len % bus->blocksize); if ((pad <= bus->roundup) && (pad < bus->blocksize)) len += pad; - } else if (len % DHD_SDALIGN) { - len += DHD_SDALIGN - (len % DHD_SDALIGN); + } else if (len % BRCMF_SDALIGN) { + len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN); } /* Satisfy length-alignment requirements */ if (forcealign && (len & (ALIGNMENT - 1))) len = roundup(len, ALIGNMENT); - ASSERT(IS_ALIGNED((unsigned long)frame, 2)); + /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ /* Need to lock here to protect txseq and SDIO tx calls */ - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdlock(bus); BUS_WAKE(bus); /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ *(u16 *) frame = cpu_to_le16((u16) msglen); @@ -1317,31 +1711,33 @@ int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); if (!DATAOK(bus)) { - DHD_INFO(("%s: No bus credit bus->tx_max %d, bus->tx_seq %d\n", - __func__, bus->tx_max, bus->tx_seq)); + BRCMF_INFO(("%s: No bus credit bus->tx_max %d," + " bus->tx_seq %d\n", __func__, + bus->tx_max, bus->tx_seq)); bus->ctrl_frame_stat = true; /* Send from dpc */ bus->ctrl_frame_buf = frame; bus->ctrl_frame_len = len; - dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat); + brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat); if (bus->ctrl_frame_stat == false) { - DHD_INFO(("%s: ctrl_frame_stat == false\n", __func__)); + BRCMF_INFO(("%s: ctrl_frame_stat == false\n", + __func__)); ret = 0; } else { - DHD_INFO(("%s: ctrl_frame_stat == true\n", __func__)); + BRCMF_INFO(("%s: ctrl_frame_stat == true\n", __func__)); ret = -1; } } if (ret == -1) { -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_CTL_ON()) { +#ifdef BCMDBG + if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { printk(KERN_DEBUG "Tx Frame:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len); - } else if (DHD_HDRS_ON()) { + } else if (BRCMF_HDRS_ON()) { printk(KERN_DEBUG "TxHdr:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, min_t(u16, len, 16)); @@ -1350,35 +1746,35 @@ int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) do { bus->ctrl_frame_stat = false; - ret = - dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), - SDIO_FUNC_2, F2SYNC, frame, len, - NULL, NULL, NULL); - - ASSERT(ret != -BCME_PENDING); + ret = brcmf_sdbrcm_send_buf(bus, + brcmf_sdcard_cur_sbwad(card), SDIO_FUNC_2, + F2SYNC, frame, len, NULL, NULL, NULL); if (ret < 0) { /* On failure, abort the command and terminate the frame */ - DHD_INFO(("%s: sdio error %d, abort command and terminate frame.\n", - __func__, ret)); + BRCMF_INFO(("%s: sdio error %d, abort command " + "and terminate frame.\n", + __func__, ret)); bus->tx_sderrs++; - bcmsdh_abort(sdh, SDIO_FUNC_2); + brcmf_sdcard_abort(card, SDIO_FUNC_2); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); bus->f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, + hi = brcmf_sdcard_cfg_read(card, + SDIO_FUNC_1, SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, + lo = brcmf_sdcard_cfg_read(card, + SDIO_FUNC_1, SBSDIO_FUNC1_WFRAMEBCLO, - NULL); + NULL); bus->f1regdata += 2; if ((hi == 0) && (lo == 0)) break; @@ -1392,67 +1788,67 @@ int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) } while ((ret < 0) && retries++ < TXRETRIES); } - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { + if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) { bus->activity = false; - dhdsdio_clkctl(bus, CLK_NONE, true); + brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); } - dhd_os_sdunlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); if (ret) - bus->dhd->tx_ctlerrs++; + bus->drvr->tx_ctlerrs++; else - bus->dhd->tx_ctlpkts++; + bus->drvr->tx_ctlpkts++; return ret ? -EIO : 0; } -int dhd_bus_rxctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) +int brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen) { int timeleft; uint rxlen = 0; bool pending; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - if (bus->dhd->dongle_reset) + if (bus->drvr->dongle_reset) return -EIO; /* Wait until control frame is available */ - timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->rxlen, &pending); + timeleft = brcmf_os_ioctl_resp_wait(bus->drvr, &bus->rxlen, &pending); - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdlock(bus); rxlen = bus->rxlen; memcpy(msg, bus->rxctl, min(msglen, rxlen)); bus->rxlen = 0; - dhd_os_sdunlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); if (rxlen) { - DHD_CTL(("%s: resumed on rxctl frame, got %d expected %d\n", - __func__, rxlen, msglen)); + BRCMF_CTL(("%s: resumed on rxctl frame, got %d expected %d\n", + __func__, rxlen, msglen)); } else if (timeleft == 0) { - DHD_ERROR(("%s: resumed on timeout\n", __func__)); -#ifdef DHD_DEBUG - dhd_os_sdlock(bus->dhd); - dhdsdio_checkdied(bus, NULL, 0); - dhd_os_sdunlock(bus->dhd); -#endif /* DHD_DEBUG */ + BRCMF_ERROR(("%s: resumed on timeout\n", __func__)); +#ifdef BCMDBG + brcmf_sdbrcm_sdlock(bus); + brcmf_sdbrcm_checkdied(bus, NULL, 0); + brcmf_sdbrcm_sdunlock(bus); +#endif /* BCMDBG */ } else if (pending == true) { - DHD_CTL(("%s: cancelled\n", __func__)); + BRCMF_CTL(("%s: cancelled\n", __func__)); return -ERESTARTSYS; } else { - DHD_CTL(("%s: resumed for unknown reason?\n", __func__)); -#ifdef DHD_DEBUG - dhd_os_sdlock(bus->dhd); - dhdsdio_checkdied(bus, NULL, 0); - dhd_os_sdunlock(bus->dhd); -#endif /* DHD_DEBUG */ + BRCMF_CTL(("%s: resumed for unknown reason?\n", __func__)); +#ifdef BCMDBG + brcmf_sdbrcm_sdlock(bus); + brcmf_sdbrcm_checkdied(bus, NULL, 0); + brcmf_sdbrcm_sdunlock(bus); +#endif /* BCMDBG */ } if (rxlen) - bus->dhd->rx_ctlpkts++; + bus->drvr->rx_ctlpkts++; else - bus->dhd->rx_ctlerrs++; + bus->drvr->rx_ctlerrs++; return rxlen ? (int)rxlen : -ETIMEDOUT; } @@ -1466,8 +1862,10 @@ enum { IOV_SDCIS, IOV_MEMBYTES, IOV_MEMSIZE, -#ifdef DHD_DEBUG +#ifdef BCMDBG IOV_CHECKDIED, + IOV_CONS, + IOV_DCONSOLE_POLL, #endif IOV_DOWNLOAD, IOV_FORCEEVEN, @@ -1490,10 +1888,11 @@ enum { IOV_IDLECLOCK, IOV_SD1IDLE, IOV_SLEEP, + IOV_WDTICK, IOV_VARS }; -const bcm_iovar_t dhdsdio_iovars[] = { +const struct brcmu_iovar brcmf_sdio_iovars[] = { {"intr", IOV_INTR, 0, IOVT_BOOL, 0}, {"sleep", IOV_SLEEP, 0, IOVT_BOOL, 0}, {"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0}, @@ -1510,12 +1909,17 @@ const bcm_iovar_t dhdsdio_iovars[] = { {"alignctl", IOV_ALIGNCTL, 0, IOVT_BOOL, 0}, {"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0}, {"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0}, -#ifdef DHD_DEBUG - {"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(sdreg_t)} + {"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0}, +#ifdef BCMDBG + {"cons", IOV_CONS, 0, IOVT_BUFFER, 0} , - {"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(sdreg_t)} + {"dconpoll", IOV_DCONSOLE_POLL, 0, IOVT_UINT32, 0} , - {"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN} + {"sdreg", IOV_SDREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)} + , + {"sbreg", IOV_SBREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)} + , + {"sd_cis", IOV_SDCIS, 0, IOVT_BUFFER, BRCMF_IOCTL_MAXLEN} , {"forcealign", IOV_FORCEEVEN, 0, IOVT_BOOL, 0} , @@ -1527,15 +1931,13 @@ const bcm_iovar_t dhdsdio_iovars[] = { , {"cpu", IOV_CPU, 0, IOVT_BOOL, 0} , -#ifdef DHD_DEBUG {"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0} , -#endif /* DHD_DEBUG */ -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ #ifdef SDTEST {"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0} , - {"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(dhd_pktgen_t)} + {"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(struct brcmf_pktgen)} , #endif /* SDTEST */ @@ -1543,122 +1945,122 @@ const bcm_iovar_t dhdsdio_iovars[] = { }; static void -dhd_dump_pct(struct bcmstrbuf *strbuf, char *desc, uint num, uint div) +brcmf_dump_pct(struct brcmu_strbuf *strbuf, char *desc, uint num, uint div) { uint q1, q2; if (!div) { - bcm_bprintf(strbuf, "%s N/A", desc); + brcmu_bprintf(strbuf, "%s N/A", desc); } else { q1 = num / div; q2 = (100 * (num - (q1 * div))) / div; - bcm_bprintf(strbuf, "%s %d.%02d", desc, q1, q2); + brcmu_bprintf(strbuf, "%s %d.%02d", desc, q1, q2); } } -void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) +void brcmf_sdbrcm_bus_dump(struct brcmf_pub *drvr, struct brcmu_strbuf *strbuf) { - dhd_bus_t *bus = dhdp->bus; + struct brcmf_bus *bus = drvr->bus; - bcm_bprintf(strbuf, "Bus SDIO structure:\n"); - bcm_bprintf(strbuf, + brcmu_bprintf(strbuf, "Bus SDIO structure:\n"); + brcmu_bprintf(strbuf, "hostintmask 0x%08x intstatus 0x%08x sdpcm_ver %d\n", bus->hostintmask, bus->intstatus, bus->sdpcm_ver); - bcm_bprintf(strbuf, + brcmu_bprintf(strbuf, "fcstate %d qlen %d tx_seq %d, max %d, rxskip %d rxlen %d rx_seq %d\n", bus->fcstate, pktq_len(&bus->txq), bus->tx_seq, bus->tx_max, bus->rxskip, bus->rxlen, bus->rx_seq); - bcm_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n", + brcmu_bprintf(strbuf, "intr %d intrcount %d lastintrs %d spurious %d\n", bus->intr, bus->intrcount, bus->lastintrs, bus->spurious); - bcm_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n", + brcmu_bprintf(strbuf, "pollrate %d pollcnt %d regfails %d\n", bus->pollrate, bus->pollcnt, bus->regfails); - bcm_bprintf(strbuf, "\nAdditional counters:\n"); - bcm_bprintf(strbuf, + brcmu_bprintf(strbuf, "\nAdditional counters:\n"); + brcmu_bprintf(strbuf, "tx_sderrs %d fcqueued %d rxrtx %d rx_toolong %d rxc_errors %d\n", bus->tx_sderrs, bus->fcqueued, bus->rxrtx, bus->rx_toolong, bus->rxc_errors); - bcm_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n", + brcmu_bprintf(strbuf, "rx_hdrfail %d badhdr %d badseq %d\n", bus->rx_hdrfail, bus->rx_badhdr, bus->rx_badseq); - bcm_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n", bus->fc_rcvd, - bus->fc_xoff, bus->fc_xon); - bcm_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n", + brcmu_bprintf(strbuf, "fc_rcvd %d, fc_xoff %d, fc_xon %d\n", + bus->fc_rcvd, bus->fc_xoff, bus->fc_xon); + brcmu_bprintf(strbuf, "rxglomfail %d, rxglomframes %d, rxglompkts %d\n", bus->rxglomfail, bus->rxglomframes, bus->rxglompkts); - bcm_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs %d\n", - (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs, - bus->f2rxdata, bus->f2txdata, bus->f1regdata); + brcmu_bprintf(strbuf, "f2rx (hdrs/data) %d (%d/%d), f2tx %d f1regs" + " %d\n", + (bus->f2rxhdrs + bus->f2rxdata), bus->f2rxhdrs, + bus->f2rxdata, bus->f2txdata, bus->f1regdata); { - dhd_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->dhd->rx_packets, + brcmf_dump_pct(strbuf, "\nRx: pkts/f2rd", bus->drvr->rx_packets, (bus->f2rxhdrs + bus->f2rxdata)); - dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->rx_packets, + brcmf_dump_pct(strbuf, ", pkts/f1sd", bus->drvr->rx_packets, bus->f1regdata); - dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->rx_packets, + brcmf_dump_pct(strbuf, ", pkts/sd", bus->drvr->rx_packets, (bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata)); - dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->rx_packets, + brcmf_dump_pct(strbuf, ", pkts/int", bus->drvr->rx_packets, bus->intrcount); - bcm_bprintf(strbuf, "\n"); + brcmu_bprintf(strbuf, "\n"); - dhd_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts), - bus->dhd->rx_packets); - dhd_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts, + brcmf_dump_pct(strbuf, "Rx: glom pct", (100 * bus->rxglompkts), + bus->drvr->rx_packets); + brcmf_dump_pct(strbuf, ", pkts/glom", bus->rxglompkts, bus->rxglomframes); - bcm_bprintf(strbuf, "\n"); + brcmu_bprintf(strbuf, "\n"); - dhd_dump_pct(strbuf, "Tx: pkts/f2wr", bus->dhd->tx_packets, + brcmf_dump_pct(strbuf, "Tx: pkts/f2wr", bus->drvr->tx_packets, bus->f2txdata); - dhd_dump_pct(strbuf, ", pkts/f1sd", bus->dhd->tx_packets, + brcmf_dump_pct(strbuf, ", pkts/f1sd", bus->drvr->tx_packets, bus->f1regdata); - dhd_dump_pct(strbuf, ", pkts/sd", bus->dhd->tx_packets, + brcmf_dump_pct(strbuf, ", pkts/sd", bus->drvr->tx_packets, (bus->f2txdata + bus->f1regdata)); - dhd_dump_pct(strbuf, ", pkts/int", bus->dhd->tx_packets, + brcmf_dump_pct(strbuf, ", pkts/int", bus->drvr->tx_packets, bus->intrcount); - bcm_bprintf(strbuf, "\n"); + brcmu_bprintf(strbuf, "\n"); - dhd_dump_pct(strbuf, "Total: pkts/f2rw", - (bus->dhd->tx_packets + bus->dhd->rx_packets), + brcmf_dump_pct(strbuf, "Total: pkts/f2rw", + (bus->drvr->tx_packets + bus->drvr->rx_packets), (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata)); - dhd_dump_pct(strbuf, ", pkts/f1sd", - (bus->dhd->tx_packets + bus->dhd->rx_packets), + brcmf_dump_pct(strbuf, ", pkts/f1sd", + (bus->drvr->tx_packets + bus->drvr->rx_packets), bus->f1regdata); - dhd_dump_pct(strbuf, ", pkts/sd", - (bus->dhd->tx_packets + bus->dhd->rx_packets), + brcmf_dump_pct(strbuf, ", pkts/sd", + (bus->drvr->tx_packets + bus->drvr->rx_packets), (bus->f2txdata + bus->f2rxhdrs + bus->f2rxdata + bus->f1regdata)); - dhd_dump_pct(strbuf, ", pkts/int", - (bus->dhd->tx_packets + bus->dhd->rx_packets), + brcmf_dump_pct(strbuf, ", pkts/int", + (bus->drvr->tx_packets + bus->drvr->rx_packets), bus->intrcount); - bcm_bprintf(strbuf, "\n\n"); + brcmu_bprintf(strbuf, "\n\n"); } #ifdef SDTEST if (bus->pktgen_count) { - bcm_bprintf(strbuf, "pktgen config and count:\n"); - bcm_bprintf(strbuf, + brcmu_bprintf(strbuf, "pktgen config and count:\n"); + brcmu_bprintf(strbuf, "freq %d count %d print %d total %d min %d len %d\n", bus->pktgen_freq, bus->pktgen_count, bus->pktgen_print, bus->pktgen_total, bus->pktgen_minlen, bus->pktgen_maxlen); - bcm_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n", + brcmu_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n", bus->pktgen_sent, bus->pktgen_rcvd, bus->pktgen_fail); } #endif /* SDTEST */ -#ifdef DHD_DEBUG - bcm_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n", - bus->dpc_sched, - (bcmsdh_intr_pending(bus->sdh) ? " " : " not ")); - bcm_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize, +#ifdef BCMDBG + brcmu_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n", + bus->dpc_sched, " not "); + brcmu_bprintf(strbuf, "blocksize %d roundup %d\n", bus->blocksize, bus->roundup); -#endif /* DHD_DEBUG */ - bcm_bprintf(strbuf, +#endif /* BCMDBG */ + brcmu_bprintf(strbuf, "clkstate %d activity %d idletime %d idlecount %d sleeping %d\n", bus->clkstate, bus->activity, bus->idletime, bus->idlecount, bus->sleeping); } -void dhd_bus_clearcounts(dhd_pub_t *dhdp) +void brcmf_bus_clearcounts(struct brcmf_pub *drvr) { - dhd_bus_t *bus = (dhd_bus_t *) dhdp->bus; + struct brcmf_bus *bus = (struct brcmf_bus *) drvr->bus; bus->intrcount = bus->lastintrs = bus->spurious = bus->regfails = 0; bus->rxrtx = bus->rx_toolong = bus->rxc_errors = 0; @@ -1669,11 +2071,11 @@ void dhd_bus_clearcounts(dhd_pub_t *dhdp) } #ifdef SDTEST -static int dhdsdio_pktgen_get(dhd_bus_t *bus, u8 *arg) +static int brcmf_sdbrcm_pktgen_get(struct brcmf_bus *bus, u8 *arg) { - dhd_pktgen_t pktgen; + struct brcmf_pktgen pktgen; - pktgen.version = DHD_PKTGEN_VERSION; + pktgen.version = BRCMF_PKTGEN_VERSION; pktgen.freq = bus->pktgen_freq; pktgen.count = bus->pktgen_count; pktgen.print = bus->pktgen_print; @@ -1691,13 +2093,13 @@ static int dhdsdio_pktgen_get(dhd_bus_t *bus, u8 *arg) return 0; } -static int dhdsdio_pktgen_set(dhd_bus_t *bus, u8 *arg) +static int brcmf_sdbrcm_pktgen_set(struct brcmf_bus *bus, u8 *arg) { - dhd_pktgen_t pktgen; + struct brcmf_pktgen pktgen; uint oldcnt, oldmode; memcpy(&pktgen, arg, sizeof(pktgen)); - if (pktgen.version != DHD_PKTGEN_VERSION) + if (pktgen.version != BRCMF_PKTGEN_VERSION) return -EINVAL; oldcnt = bus->pktgen_count; @@ -1725,7 +2127,7 @@ static int dhdsdio_pktgen_set(dhd_bus_t *bus, u8 *arg) #endif /* SDTEST */ static int -dhdsdio_membytes(dhd_bus_t *bus, bool write, u32 address, u8 *data, +brcmf_sdbrcm_membytes(struct brcmf_bus *bus, bool write, u32 address, u8 *data, uint size) { int bcmerror = 0; @@ -1740,21 +2142,22 @@ dhdsdio_membytes(dhd_bus_t *bus, bool write, u32 address, u8 *data, dsize = size; /* Set the backplane window to include the start address */ - bcmerror = dhdsdio_set_siaddr_window(bus, address); + bcmerror = brcmf_sdbrcm_set_siaddr_window(bus, address); if (bcmerror) { - DHD_ERROR(("%s: window change failed\n", __func__)); + BRCMF_ERROR(("%s: window change failed\n", __func__)); goto xfer_done; } /* Do the transfer(s) */ while (size) { - DHD_INFO(("%s: %s %d bytes at offset 0x%08x in window 0x%08x\n", - __func__, (write ? "write" : "read"), dsize, - sdaddr, (address & SBSDIO_SBWINDOW_MASK))); + BRCMF_INFO(("%s: %s %d bytes at offset 0x%08x in window" + " 0x%08x\n", __func__, (write ? "write" : "read"), + dsize, sdaddr, (address & SBSDIO_SBWINDOW_MASK))); bcmerror = - bcmsdh_rwdata(bus->sdh, write, sdaddr, data, dsize); + brcmf_sdcard_rwdata(bus->card, write, sdaddr, data, dsize); if (bcmerror) { - DHD_ERROR(("%s: membytes transfer failed\n", __func__)); + BRCMF_ERROR(("%s: membytes transfer failed\n", + __func__)); break; } @@ -1763,10 +2166,10 @@ dhdsdio_membytes(dhd_bus_t *bus, bool write, u32 address, u8 *data, if (size) { data += dsize; address += dsize; - bcmerror = dhdsdio_set_siaddr_window(bus, address); + bcmerror = brcmf_sdbrcm_set_siaddr_window(bus, address); if (bcmerror) { - DHD_ERROR(("%s: window change failed\n", - __func__)); + BRCMF_ERROR(("%s: window change failed\n", + __func__)); break; } sdaddr = 0; @@ -1776,43 +2179,45 @@ dhdsdio_membytes(dhd_bus_t *bus, bool write, u32 address, u8 *data, xfer_done: /* Return the window to backplane enumeration space for core access */ - if (dhdsdio_set_siaddr_window(bus, bcmsdh_cur_sbwad(bus->sdh))) { - DHD_ERROR(("%s: FAILED to set window back to 0x%x\n", - __func__, bcmsdh_cur_sbwad(bus->sdh))); + if (brcmf_sdbrcm_set_siaddr_window(bus, + brcmf_sdcard_cur_sbwad(bus->card))) { + BRCMF_ERROR(("%s: FAILED to set window back to 0x%x\n", + __func__, brcmf_sdcard_cur_sbwad(bus->card))); } return bcmerror; } -#ifdef DHD_DEBUG -static int dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) +#ifdef BCMDBG +static int brcmf_sdbrcm_readshared(struct brcmf_bus *bus, struct sdpcm_shared *sh) { u32 addr; int rv; /* Read last word in memory to determine address of sdpcm_shared structure */ - rv = dhdsdio_membytes(bus, false, bus->ramsize - 4, (u8 *)&addr, 4); + rv = brcmf_sdbrcm_membytes(bus, false, bus->ramsize - 4, (u8 *)&addr, + 4); if (rv < 0) return rv; addr = le32_to_cpu(addr); - DHD_INFO(("sdpcm_shared address 0x%08X\n", addr)); + BRCMF_INFO(("sdpcm_shared address 0x%08X\n", addr)); /* * Check if addr is valid. * NVRAM length at the end of memory should have been overwritten. */ if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) { - DHD_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n", - __func__, addr)); + BRCMF_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n", + __func__, addr)); return -EBADE; } - /* Read hndrte_shared structure */ - rv = dhdsdio_membytes(bus, false, addr, (u8 *) sh, - sizeof(sdpcm_shared_t)); + /* Read rte_shared structure */ + rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *) sh, + sizeof(struct sdpcm_shared)); if (rv < 0) return rv; @@ -1826,28 +2231,28 @@ static int dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh) sh->msgtrace_addr = le32_to_cpu(sh->msgtrace_addr); if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) { - DHD_ERROR(("%s: sdpcm_shared version %d in dhd " - "is different than sdpcm_shared version %d in dongle\n", - __func__, SDPCM_SHARED_VERSION, - sh->flags & SDPCM_SHARED_VERSION_MASK)); + BRCMF_ERROR(("%s: sdpcm_shared version %d in brcmf " + "is different than sdpcm_shared version %d in dongle\n", + __func__, SDPCM_SHARED_VERSION, + sh->flags & SDPCM_SHARED_VERSION_MASK)); return -EBADE; } return 0; } -static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size) +static int brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, u8 *data, uint size) { int bcmerror = 0; uint msize = 512; char *mbuffer = NULL; uint maxstrlen = 256; char *str = NULL; - trap_t tr; - sdpcm_shared_t sdpcm_shared; - struct bcmstrbuf strbuf; + struct brcmf_trap tr; + struct sdpcm_shared sdpcm_shared; + struct brcmu_strbuf strbuf; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); if (data == NULL) { /* @@ -1857,8 +2262,8 @@ static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size) size = msize; mbuffer = data = kmalloc(msize, GFP_ATOMIC); if (mbuffer == NULL) { - DHD_ERROR(("%s: kmalloc(%d) failed\n", __func__, - msize)); + BRCMF_ERROR(("%s: kmalloc(%d) failed\n", __func__, + msize)); bcmerror = -ENOMEM; goto done; } @@ -1866,18 +2271,18 @@ static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size) str = kmalloc(maxstrlen, GFP_ATOMIC); if (str == NULL) { - DHD_ERROR(("%s: kmalloc(%d) failed\n", __func__, maxstrlen)); + BRCMF_ERROR(("%s: kmalloc(%d) failed\n", __func__, maxstrlen)); bcmerror = -ENOMEM; goto done; } - bcmerror = dhdsdio_readshared(bus, &sdpcm_shared); + bcmerror = brcmf_sdbrcm_readshared(bus, &sdpcm_shared); if (bcmerror < 0) goto done; - bcm_binit(&strbuf, data, size); + brcmu_binit(&strbuf, data, size); - bcm_bprintf(&strbuf, + brcmu_bprintf(&strbuf, "msgtrace address : 0x%08X\nconsole address : 0x%08X\n", sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr); @@ -1886,7 +2291,7 @@ static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size) * (Avoids conflict with real asserts for programmatic * parsing of output.) */ - bcm_bprintf(&strbuf, "Assrt not built in dongle\n"); + brcmu_bprintf(&strbuf, "Assrt not built in dongle\n"); } if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) == @@ -1895,49 +2300,49 @@ static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size) * (Avoids conflict with real asserts for programmatic * parsing of output.) */ - bcm_bprintf(&strbuf, "No trap%s in dongle", + brcmu_bprintf(&strbuf, "No trap%s in dongle", (sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) ? "/assrt" : ""); } else { if (sdpcm_shared.flags & SDPCM_SHARED_ASSERT) { /* Download assert */ - bcm_bprintf(&strbuf, "Dongle assert"); + brcmu_bprintf(&strbuf, "Dongle assert"); if (sdpcm_shared.assert_exp_addr != 0) { str[0] = '\0'; - bcmerror = dhdsdio_membytes(bus, false, + bcmerror = brcmf_sdbrcm_membytes(bus, false, sdpcm_shared.assert_exp_addr, (u8 *) str, maxstrlen); if (bcmerror < 0) goto done; str[maxstrlen - 1] = '\0'; - bcm_bprintf(&strbuf, " expr \"%s\"", str); + brcmu_bprintf(&strbuf, " expr \"%s\"", str); } if (sdpcm_shared.assert_file_addr != 0) { str[0] = '\0'; - bcmerror = dhdsdio_membytes(bus, false, + bcmerror = brcmf_sdbrcm_membytes(bus, false, sdpcm_shared.assert_file_addr, (u8 *) str, maxstrlen); if (bcmerror < 0) goto done; str[maxstrlen - 1] = '\0'; - bcm_bprintf(&strbuf, " file \"%s\"", str); + brcmu_bprintf(&strbuf, " file \"%s\"", str); } - bcm_bprintf(&strbuf, " line %d ", + brcmu_bprintf(&strbuf, " line %d ", sdpcm_shared.assert_line); } if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) { - bcmerror = dhdsdio_membytes(bus, false, + bcmerror = brcmf_sdbrcm_membytes(bus, false, sdpcm_shared.trap_addr, (u8 *)&tr, - sizeof(trap_t)); + sizeof(struct brcmf_trap)); if (bcmerror < 0) goto done; - bcm_bprintf(&strbuf, + brcmu_bprintf(&strbuf, "Dongle trap type 0x%x @ epc 0x%x, cpsr 0x%x, spsr 0x%x, sp 0x%x," "lp 0x%x, rpc 0x%x Trap offset 0x%x, " "r0 0x%x, r1 0x%x, r2 0x%x, r3 0x%x, r4 0x%x, r5 0x%x, r6 0x%x, r7 0x%x\n", @@ -1949,14 +2354,14 @@ static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size) } if (sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) - DHD_ERROR(("%s: %s\n", __func__, strbuf.origbuf)); + BRCMF_ERROR(("%s: %s\n", __func__, strbuf.origbuf)); -#ifdef DHD_DEBUG +#ifdef BCMDBG if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) { /* Mem dump to a file on device */ - dhdsdio_mem_dump(bus); + brcmf_sdbrcm_mem_dump(bus); } -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ done: kfree(mbuffer); @@ -1965,7 +2370,7 @@ static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size) return bcmerror; } -static int dhdsdio_mem_dump(dhd_bus_t *bus) +static int brcmf_sdbrcm_mem_dump(struct brcmf_bus *bus) { int ret = 0; int size; /* Full mem size */ @@ -1977,7 +2382,7 @@ static int dhdsdio_mem_dump(dhd_bus_t *bus) size = bus->ramsize; buf = kmalloc(size, GFP_ATOMIC); if (!buf) { - DHD_ERROR(("%s: Out of memory (%d bytes)\n", __func__, size)); + BRCMF_ERROR(("%s: Out of memory (%d bytes)\n", __func__, size)); return -1; } @@ -1986,9 +2391,10 @@ static int dhdsdio_mem_dump(dhd_bus_t *bus) databuf = buf; while (size) { read_size = min(MEMBLOCK, size); - ret = dhdsdio_membytes(bus, false, start, databuf, read_size); + ret = brcmf_sdbrcm_membytes(bus, false, start, databuf, + read_size); if (ret) { - DHD_ERROR(("%s: Error membytes %d\n", __func__, ret)); + BRCMF_ERROR(("%s: Error membytes %d\n", __func__, ret)); kfree(buf); return -1; } @@ -2002,20 +2408,20 @@ static int dhdsdio_mem_dump(dhd_bus_t *bus) printk(KERN_DEBUG "Done\n"); /* free buf before return !!! */ - if (write_to_file(bus->dhd, buf, bus->ramsize)) { - DHD_ERROR(("%s: Error writing to files\n", __func__)); + if (brcmf_write_to_file(bus->drvr, buf, bus->ramsize)) { + BRCMF_ERROR(("%s: Error writing to files\n", __func__)); return -1; } - /* buf free handled in write_to_file, not here */ + /* buf free handled in brcmf_write_to_file, not here */ return 0; } #define CONSOLE_LINE_MAX 192 -static int dhdsdio_readconsole(dhd_bus_t *bus) +static int brcmf_sdbrcm_readconsole(struct brcmf_bus *bus) { - dhd_console_t *c = &bus->console; + struct brcmf_console *c = &bus->console; u8 line[CONSOLE_LINE_MAX], ch; u32 n, idx, addr; int rv; @@ -2025,8 +2431,8 @@ static int dhdsdio_readconsole(dhd_bus_t *bus) return 0; /* Read console log struct */ - addr = bus->console_addr + offsetof(hndrte_cons_t, log); - rv = dhdsdio_membytes(bus, false, addr, (u8 *)&c->log, + addr = bus->console_addr + offsetof(struct rte_console, log); + rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&c->log, sizeof(c->log)); if (rv < 0) return rv; @@ -2052,7 +2458,7 @@ static int dhdsdio_readconsole(dhd_bus_t *bus) /* Read the console buffer */ addr = le32_to_cpu(c->log.buf); - rv = dhdsdio_membytes(bus, false, addr, c->buf, c->bufsize); + rv = brcmf_sdbrcm_membytes(bus, false, addr, c->buf, c->bufsize); if (rv < 0) return rv; @@ -2088,16 +2494,16 @@ static int dhdsdio_readconsole(dhd_bus_t *bus) return 0; } -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ -int dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len) +int brcmf_sdbrcm_downloadvars(struct brcmf_bus *bus, void *arg, int len) { int bcmerror = 0; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); /* Basic sanity checks */ - if (bus->dhd->up) { + if (bus->drvr->up) { bcmerror = -EISCONN; goto err; } @@ -2124,7 +2530,7 @@ int dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len) } static int -dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, +brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 actionid, const char *name, void *params, int plen, void *arg, int len, int val_size) { @@ -2132,11 +2538,11 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, s32 int_val = 0; bool bool_val = 0; - DHD_TRACE(("%s: Enter, action %d name %s params %p plen %d arg %p " - "len %d val_size %d\n", - __func__, actionid, name, params, plen, arg, len, val_size)); + BRCMF_TRACE(("%s: Enter, action %d name %s params %p plen %d arg %p " + "len %d val_size %d\n", __func__, actionid, name, params, + plen, arg, len, val_size)); - bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid)); + bcmerror = brcmu_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid)); if (bcmerror != 0) goto exit; @@ -2146,10 +2552,10 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, bool_val = (int_val != 0) ? true : false; /* Some ioctls use the bus */ - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdlock(bus); /* Check if dongle is in reset. If so, only allow DEVRESET iovars */ - if (bus->dhd->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) || + if (bus->drvr->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) || actionid == IOV_GVAL(IOV_DEVRESET))) { bcmerror = -EPERM; goto exit; @@ -2158,7 +2564,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, /* Handle sleep stuff before any clock mucking */ if (vi->varid == IOV_SLEEP) { if (IOV_ISSET(actionid)) { - bcmerror = dhdsdio_bussleep(bus, bool_val); + bcmerror = brcmf_sdbrcm_bussleep(bus, bool_val); } else { int_val = (s32) bus->sleeping; memcpy(arg, &int_val, val_size); @@ -2167,9 +2573,9 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, } /* Request clock to allow SDIO accesses */ - if (!bus->dhd->dongle_reset) { + if (!bus->drvr->dongle_reset) { BUS_WAKE(bus); - dhdsdio_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); } switch (actionid) { @@ -2181,15 +2587,13 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_SVAL(IOV_INTR): bus->intr = bool_val; bus->intdis = false; - if (bus->dhd->up) { + if (bus->drvr->up) { + BRCMF_INTR(("%s: %s SDIO interrupts\n", __func__, + bus->intr ? "enable" : "disable")); if (bus->intr) { - DHD_INTR(("%s: enable SDIO device interrupts\n", - __func__)); - bcmsdh_intr_enable(bus->sdh); + brcmf_sdcard_intr_enable(bus->card); } else { - DHD_INTR(("%s: disable SDIO interrupts\n", - __func__)); - bcmsdh_intr_disable(bus->sdh); + brcmf_sdcard_intr_disable(bus->card); } } break; @@ -2210,7 +2614,7 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, break; case IOV_SVAL(IOV_IDLETIME): - if ((int_val < 0) && (int_val != DHD_IDLE_IMMEDIATE)) + if ((int_val < 0) && (int_val != BRCMF_IDLE_IMMEDIATE)) bcmerror = -EINVAL; else bus->idletime = int_val; @@ -2243,8 +2647,6 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, bool set = (actionid == IOV_SVAL(IOV_MEMBYTES)); - ASSERT(plen >= 2 * sizeof(int)); - address = (u32) int_val; memcpy(&int_val, (char *)params + sizeof(int_val), sizeof(int_val)); @@ -2253,25 +2655,25 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, /* Do some validation */ dsize = set ? plen - (2 * sizeof(int)) : len; if (dsize < size) { - DHD_ERROR(("%s: error on %s membytes, addr " - "0x%08x size %d dsize %d\n", - __func__, (set ? "set" : "get"), - address, size, dsize)); + BRCMF_ERROR(("%s: error on %s membytes, addr " + "0x%08x size %d dsize %d\n", + __func__, (set ? "set" : "get"), + address, size, dsize)); bcmerror = -EINVAL; break; } - DHD_INFO(("%s: Request to %s %d bytes at address " - "0x%08x\n", - __func__, (set ? "write" : "read"), size, address)); + BRCMF_INFO(("%s: Request to %s %d bytes at address " + "0x%08x\n", __func__, + (set ? "write" : "read"), size, address)); /* If we know about SOCRAM, check for a fit */ if ((bus->orig_ramsize) && ((address > bus->orig_ramsize) || (address + size > bus->orig_ramsize))) { - DHD_ERROR(("%s: ramsize 0x%08x doesn't have %d " - "bytes at 0x%08x\n", - __func__, bus->orig_ramsize, size, address)); + BRCMF_ERROR(("%s: ramsize 0x%08x doesn't have" + " %d bytes at 0x%08x\n", __func__, + bus->orig_ramsize, size, address)); bcmerror = -EINVAL; break; } @@ -2282,8 +2684,8 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, 2 * sizeof(int) : (u8 *) arg; /* Call to do the transfer */ - bcmerror = - dhdsdio_membytes(bus, set, address, data, size); + bcmerror = brcmf_sdbrcm_membytes(bus, set, address, + data, size); break; } @@ -2294,33 +2696,33 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, break; case IOV_GVAL(IOV_SDIOD_DRIVE): - int_val = (s32) dhd_sdiod_drive_strength; + int_val = (s32) brcmf_sdiod_drive_strength; memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_SDIOD_DRIVE): - dhd_sdiod_drive_strength = int_val; - dhdsdio_sdiod_drive_strength_init(bus, - dhd_sdiod_drive_strength); + brcmf_sdiod_drive_strength = int_val; + brcmf_sdbrcm_sdiod_drive_strength_init(bus, + brcmf_sdiod_drive_strength); break; case IOV_SVAL(IOV_DOWNLOAD): - bcmerror = dhdsdio_download_state(bus, bool_val); + bcmerror = brcmf_sdbrcm_download_state(bus, bool_val); break; case IOV_SVAL(IOV_VARS): - bcmerror = dhdsdio_downloadvars(bus, arg, len); + bcmerror = brcmf_sdbrcm_downloadvars(bus, arg, len); break; case IOV_GVAL(IOV_READAHEAD): - int_val = (s32) dhd_readahead; + int_val = (s32) brcmf_readahead; memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_READAHEAD): - if (bool_val && !dhd_readahead) + if (bool_val && !brcmf_readahead) bus->nextlen = 0; - dhd_readahead = bool_val; + brcmf_readahead = bool_val; break; case IOV_GVAL(IOV_SDRXCHAIN): @@ -2335,40 +2737,56 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, bus->use_rxchain = bool_val; break; case IOV_GVAL(IOV_ALIGNCTL): - int_val = (s32) dhd_alignctl; + int_val = (s32) brcmf_alignctl; memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_ALIGNCTL): - dhd_alignctl = bool_val; + brcmf_alignctl = bool_val; break; case IOV_GVAL(IOV_SDALIGN): - int_val = DHD_SDALIGN; + int_val = BRCMF_SDALIGN; memcpy(arg, &int_val, val_size); break; -#ifdef DHD_DEBUG +#ifdef BCMDBG case IOV_GVAL(IOV_VARS): if (bus->varsz < (uint) len) memcpy(arg, bus->vars, bus->varsz); else bcmerror = -EOVERFLOW; break; -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ + +#ifdef BCMDBG + case IOV_GVAL(IOV_DCONSOLE_POLL): + int_val = (s32) brcmf_console_ms; + memcpy(arg, &int_val, val_size); + break; + + case IOV_SVAL(IOV_DCONSOLE_POLL): + brcmf_console_ms = (uint) int_val; + break; + + case IOV_SVAL(IOV_CONS): + if (len > 0) + bcmerror = brcmf_sdbrcm_bus_console_in(bus->drvr, + arg, len - 1); + break; -#ifdef DHD_DEBUG case IOV_GVAL(IOV_SDREG): { - sdreg_t *sd_ptr; + struct brcmf_sdreg *sd_ptr; u32 addr, size; - sd_ptr = (sdreg_t *) params; + sd_ptr = (struct brcmf_sdreg *) params; - addr = (unsigned long)bus->regs + sd_ptr->offset; + addr = bus->ci->buscorebase + sd_ptr->offset; size = sd_ptr->func; - int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size); - if (bcmsdh_regfail(bus->sdh)) + int_val = (s32) brcmf_sdcard_reg_read(bus->card, addr, + size); + if (brcmf_sdcard_regfail(bus->card)) bcmerror = -EIO; memcpy(arg, &int_val, sizeof(s32)); break; @@ -2376,15 +2794,16 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_SVAL(IOV_SDREG): { - sdreg_t *sd_ptr; + struct brcmf_sdreg *sd_ptr; u32 addr, size; - sd_ptr = (sdreg_t *) params; + sd_ptr = (struct brcmf_sdreg *) params; - addr = (unsigned long)bus->regs + sd_ptr->offset; + addr = bus->ci->buscorebase + sd_ptr->offset; size = sd_ptr->func; - bcmsdh_reg_write(bus->sdh, addr, size, sd_ptr->value); - if (bcmsdh_regfail(bus->sdh)) + brcmf_sdcard_reg_write(bus->card, addr, size, + sd_ptr->value); + if (brcmf_sdcard_regfail(bus->card)) bcmerror = -EIO; break; } @@ -2393,15 +2812,16 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, (not SDIO core) */ case IOV_GVAL(IOV_SBREG): { - sdreg_t sdreg; + struct brcmf_sdreg sdreg; u32 addr, size; memcpy(&sdreg, params, sizeof(sdreg)); addr = SI_ENUM_BASE + sdreg.offset; size = sdreg.func; - int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size); - if (bcmsdh_regfail(bus->sdh)) + int_val = (s32) brcmf_sdcard_reg_read(bus->card, addr, + size); + if (brcmf_sdcard_regfail(bus->card)) bcmerror = -EIO; memcpy(arg, &int_val, sizeof(s32)); break; @@ -2409,15 +2829,16 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, case IOV_SVAL(IOV_SBREG): { - sdreg_t sdreg; + struct brcmf_sdreg sdreg; u32 addr, size; memcpy(&sdreg, params, sizeof(sdreg)); addr = SI_ENUM_BASE + sdreg.offset; size = sdreg.func; - bcmsdh_reg_write(bus->sdh, addr, size, sdreg.value); - if (bcmsdh_regfail(bus->sdh)) + brcmf_sdcard_reg_write(bus->card, addr, size, + sdreg.value); + if (brcmf_sdcard_regfail(bus->card)) bcmerror = -EIO; break; } @@ -2427,15 +2848,15 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, *(char *)arg = 0; strcat(arg, "\nFunc 0\n"); - bcmsdh_cis_read(bus->sdh, 0x10, + brcmf_sdcard_cis_read(bus->card, 0x10, (u8 *) arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); strcat(arg, "\nFunc 1\n"); - bcmsdh_cis_read(bus->sdh, 0x11, + brcmf_sdcard_cis_read(bus->card, 0x11, (u8 *) arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); strcat(arg, "\nFunc 2\n"); - bcmsdh_cis_read(bus->sdh, 0x12, + brcmf_sdcard_cis_read(bus->card, 0x12, (u8 *) arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); break; @@ -2451,32 +2872,32 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, break; case IOV_GVAL(IOV_TXBOUND): - int_val = (s32) dhd_txbound; + int_val = (s32) brcmf_txbound; memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_TXBOUND): - dhd_txbound = (uint) int_val; + brcmf_txbound = (uint) int_val; break; case IOV_GVAL(IOV_RXBOUND): - int_val = (s32) dhd_rxbound; + int_val = (s32) brcmf_rxbound; memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_RXBOUND): - dhd_rxbound = (uint) int_val; + brcmf_rxbound = (uint) int_val; break; case IOV_GVAL(IOV_TXMINMAX): - int_val = (s32) dhd_txminmax; + int_val = (s32) brcmf_txminmax; memcpy(arg, &int_val, val_size); break; case IOV_SVAL(IOV_TXMINMAX): - dhd_txminmax = (uint) int_val; + brcmf_txminmax = (uint) int_val; break; -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ #ifdef SDTEST case IOV_GVAL(IOV_EXTLOOP): @@ -2489,62 +2910,75 @@ dhdsdio_doiovar(dhd_bus_t *bus, const bcm_iovar_t *vi, u32 actionid, break; case IOV_GVAL(IOV_PKTGEN): - bcmerror = dhdsdio_pktgen_get(bus, arg); + bcmerror = brcmf_sdbrcm_pktgen_get(bus, arg); break; case IOV_SVAL(IOV_PKTGEN): - bcmerror = dhdsdio_pktgen_set(bus, arg); + bcmerror = brcmf_sdbrcm_pktgen_set(bus, arg); break; #endif /* SDTEST */ case IOV_SVAL(IOV_DEVRESET): - DHD_TRACE(("%s: Called set IOV_DEVRESET=%d dongle_reset=%d " - "busstate=%d\n", - __func__, bool_val, bus->dhd->dongle_reset, - bus->dhd->busstate)); + BRCMF_TRACE(("%s: Called set IOV_DEVRESET=%d dongle_reset=%d " + "busstate=%d\n", + __func__, bool_val, bus->drvr->dongle_reset, + bus->drvr->busstate)); - dhd_bus_devreset(bus->dhd, (u8) bool_val); + brcmf_bus_devreset(bus->drvr, (u8) bool_val); break; case IOV_GVAL(IOV_DEVRESET): - DHD_TRACE(("%s: Called get IOV_DEVRESET\n", __func__)); + BRCMF_TRACE(("%s: Called get IOV_DEVRESET\n", __func__)); /* Get its status */ - int_val = (bool) bus->dhd->dongle_reset; + int_val = (bool) bus->drvr->dongle_reset; memcpy(arg, &int_val, val_size); break; + case IOV_GVAL(IOV_WDTICK): + int_val = (s32) brcmf_watchdog_ms; + memcpy(arg, &int_val, val_size); + break; + + case IOV_SVAL(IOV_WDTICK): + if (!bus->drvr->up) { + bcmerror = -ENOLINK; + break; + } + brcmf_sdbrcm_wd_timer(bus, (uint) int_val); + break; + default: bcmerror = -ENOTSUPP; break; } exit: - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { + if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) { bus->activity = false; - dhdsdio_clkctl(bus, CLK_NONE, true); + brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); } - dhd_os_sdunlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); if (actionid == IOV_SVAL(IOV_DEVRESET) && bool_val == false) - dhd_preinit_ioctls((dhd_pub_t *) bus->dhd); + brcmf_c_preinit_ioctls(bus->drvr); return bcmerror; } -static int dhdsdio_write_vars(dhd_bus_t *bus) +static int brcmf_sdbrcm_write_vars(struct brcmf_bus *bus) { int bcmerror = 0; u32 varsize; u32 varaddr; u8 *vbuffer; u32 varsizew; -#ifdef DHD_DEBUG +#ifdef BCMDBG char *nvram_ularray; -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ /* Even if there are no vars are to be written, we still need to set the ramsize. */ @@ -2560,10 +2994,10 @@ static int dhdsdio_write_vars(dhd_bus_t *bus) /* Write the vars list */ bcmerror = - dhdsdio_membytes(bus, true, varaddr, vbuffer, varsize); -#ifdef DHD_DEBUG + brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize); +#ifdef BCMDBG /* Verify NVRAM bytes */ - DHD_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize)); + BRCMF_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize)); nvram_ularray = kmalloc(varsize, GFP_ATOMIC); if (!nvram_ularray) return -ENOMEM; @@ -2573,30 +3007,31 @@ static int dhdsdio_write_vars(dhd_bus_t *bus) /* Read the vars list to temp buffer for comparison */ bcmerror = - dhdsdio_membytes(bus, false, varaddr, nvram_ularray, + brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray, varsize); if (bcmerror) { - DHD_ERROR(("%s: error %d on reading %d nvram bytes at " - "0x%08x\n", __func__, bcmerror, varsize, varaddr)); + BRCMF_ERROR(("%s: error %d on reading %d nvram bytes" + " at 0x%08x\n", __func__, bcmerror, + varsize, varaddr)); } /* Compare the org NVRAM with the one read from RAM */ if (memcmp(vbuffer, nvram_ularray, varsize)) { - DHD_ERROR(("%s: Downloaded NVRAM image is corrupted.\n", - __func__)); + BRCMF_ERROR(("%s: Downloaded NVRAM image is " + "corrupted.\n", __func__)); } else - DHD_ERROR(("%s: Download/Upload/Compare of NVRAM ok.\n", - __func__)); + BRCMF_ERROR(("%s: Download/Upload/Compare of" + " NVRAM ok.\n", __func__)); kfree(nvram_ularray); -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ kfree(vbuffer); } /* adjust to the user specified RAM */ - DHD_INFO(("Physical memory size: %d, usable memory size: %d\n", - bus->orig_ramsize, bus->ramsize)); - DHD_INFO(("Vars are at %d, orig varsize is %d\n", varaddr, varsize)); + BRCMF_INFO(("Physical memory size: %d, usable memory size: %d\n", + bus->orig_ramsize, bus->ramsize)); + BRCMF_INFO(("Vars are at %d, orig varsize is %d\n", varaddr, varsize)); varsize = ((bus->orig_ramsize - 4) - varaddr); /* @@ -2612,17 +3047,17 @@ static int dhdsdio_write_vars(dhd_bus_t *bus) varsizew = cpu_to_le32(varsizew); } - DHD_INFO(("New varsize is %d, length token=0x%08x\n", varsize, - varsizew)); + BRCMF_INFO(("New varsize is %d, length token=0x%08x\n", varsize, + varsizew)); /* Write the length token to the last word */ - bcmerror = dhdsdio_membytes(bus, true, (bus->orig_ramsize - 4), + bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->orig_ramsize - 4), (u8 *)&varsizew, 4); return bcmerror; } -static int dhdsdio_download_state(dhd_bus_t *bus, bool enter) +static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) { uint retries; u32 regdata; @@ -2634,139 +3069,114 @@ static int dhdsdio_download_state(dhd_bus_t *bus, bool enter) if (enter) { bus->alp_only = true; - dhdsdio_chip_disablecore(bus->sdh, bus->ci->armcorebase); + brcmf_sdbrcm_chip_disablecore(bus->card, bus->ci->armcorebase); - dhdsdio_chip_resetcore(bus->sdh, bus->ci->ramcorebase); + brcmf_sdbrcm_chip_resetcore(bus->card, bus->ci->ramcorebase); /* Clear the top bit of memory */ if (bus->ramsize) { u32 zeros = 0; - dhdsdio_membytes(bus, true, bus->ramsize - 4, + brcmf_sdbrcm_membytes(bus, true, bus->ramsize - 4, (u8 *)&zeros, 4); } } else { - regdata = bcmsdh_reg_read(bus->sdh, + regdata = brcmf_sdcard_reg_read(bus->card, CORE_SB(bus->ci->ramcorebase, sbtmstatelow), 4); regdata &= (SBTML_RESET | SBTML_REJ_MASK | (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); if ((SICF_CLOCK_EN << SBTML_SICF_SHIFT) != regdata) { - DHD_ERROR(("%s: SOCRAM core is down after reset?\n", - __func__)); + BRCMF_ERROR(("%s: SOCRAM core is down after reset?\n", + __func__)); bcmerror = -EBADE; goto fail; } - bcmerror = dhdsdio_write_vars(bus); + bcmerror = brcmf_sdbrcm_write_vars(bus); if (bcmerror) { - DHD_ERROR(("%s: no vars written to RAM\n", __func__)); + BRCMF_ERROR(("%s: no vars written to RAM\n", __func__)); bcmerror = 0; } - W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries); + w_sdreg32(bus, 0xFFFFFFFF, + offsetof(struct sdpcmd_regs, intstatus), &retries); - dhdsdio_chip_resetcore(bus->sdh, bus->ci->armcorebase); + brcmf_sdbrcm_chip_resetcore(bus->card, bus->ci->armcorebase); /* Allow HT Clock now that the ARM is running. */ bus->alp_only = false; - bus->dhd->busstate = DHD_BUS_LOAD; + bus->drvr->busstate = BRCMF_BUS_LOAD; } fail: return bcmerror; } int -dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, - void *params, int plen, void *arg, int len, bool set) +brcmf_sdbrcm_bus_iovar_op(struct brcmf_pub *drvr, const char *name, + void *params, int plen, void *arg, int len, bool set) { - dhd_bus_t *bus = dhdp->bus; - const bcm_iovar_t *vi = NULL; + struct brcmf_bus *bus = drvr->bus; + const struct brcmu_iovar *vi = NULL; int bcmerror = 0; int val_size; u32 actionid; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - ASSERT(name); - ASSERT(len >= 0); + if (name == NULL || len <= 0) + return -EINVAL; - /* Get MUST have return space */ - ASSERT(set || (arg && len)); + /* Set does not take qualifiers */ + if (set && (params || plen)) + return -EINVAL; - /* Set does NOT take qualifiers */ - ASSERT(!set || (!params && !plen)); + /* Get must have return space;*/ + if (!set && !(arg && len)) + return -EINVAL; /* Look up var locally; if not found pass to host driver */ - vi = bcm_iovar_lookup(dhdsdio_iovars, name); + vi = brcmu_iovar_lookup(brcmf_sdio_iovars, name); if (vi == NULL) { - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdlock(bus); BUS_WAKE(bus); /* Turn on clock in case SD command needs backplane */ - dhdsdio_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); - bcmerror = - bcmsdh_iovar_op(bus->sdh, name, params, plen, arg, len, - set); + bcmerror = brcmf_sdcard_iovar_op(bus->card, name, params, plen, + arg, len, set); - /* Check for bus configuration changes of interest */ - - /* If it was divisor change, read the new one */ - if (set && strcmp(name, "sd_divisor") == 0) { - if (bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0, - &bus->sd_divisor, sizeof(s32), - false) != 0) { - bus->sd_divisor = -1; - DHD_ERROR(("%s: fail on %s get\n", __func__, - name)); - } else { - DHD_INFO(("%s: noted %s update, value now %d\n", - __func__, name, bus->sd_divisor)); - } - } - /* If it was a mode change, read the new one */ - if (set && strcmp(name, "sd_mode") == 0) { - if (bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0, - &bus->sd_mode, sizeof(s32), - false) != 0) { - bus->sd_mode = -1; - DHD_ERROR(("%s: fail on %s get\n", __func__, - name)); - } else { - DHD_INFO(("%s: noted %s update, value now %d\n", - __func__, name, bus->sd_mode)); - } - } /* Similar check for blocksize change */ if (set && strcmp(name, "sd_blocksize") == 0) { s32 fnum = 2; - if (bcmsdh_iovar_op - (bus->sdh, "sd_blocksize", &fnum, sizeof(s32), + if (brcmf_sdcard_iovar_op + (bus->card, "sd_blocksize", &fnum, sizeof(s32), &bus->blocksize, sizeof(s32), false) != 0) { bus->blocksize = 0; - DHD_ERROR(("%s: fail on %s get\n", __func__, - "sd_blocksize")); + BRCMF_ERROR(("%s: fail on %s get\n", __func__, + "sd_blocksize")); } else { - DHD_INFO(("%s: noted %s update, value now %d\n", - __func__, "sd_blocksize", - bus->blocksize)); + BRCMF_INFO(("%s: noted sd_blocksize update," + " value now %d\n", __func__, + bus->blocksize)); } } bus->roundup = min(max_roundup, bus->blocksize); - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { + if (bus->idletime == BRCMF_IDLE_IMMEDIATE && + !bus->dpc_sched) { bus->activity = false; - dhdsdio_clkctl(bus, CLK_NONE, true); + brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); } - dhd_os_sdunlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); goto exit; } - DHD_CTL(("%s: %s %s, len %d plen %d\n", __func__, - name, (set ? "set" : "get"), len, plen)); + BRCMF_CTL(("%s: %s %s, len %d plen %d\n", __func__, + name, (set ? "set" : "get"), len, plen)); /* set up 'params' pointer in case this is a set command so that * the convenience int and bool code can be common to set and get @@ -2785,168 +3195,188 @@ dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name, val_size = sizeof(int); actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - bcmerror = - dhdsdio_doiovar(bus, vi, actionid, name, params, plen, arg, len, - val_size); + bcmerror = brcmf_sdbrcm_doiovar(bus, vi, actionid, name, params, plen, + arg, len, val_size); exit: return bcmerror; } -void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) +void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex) { u32 local_hostintmask; u8 saveclk; uint retries; int err; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); if (enforce_mutex) - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdlock(bus); BUS_WAKE(bus); /* Enable clock for device interrupts */ - dhdsdio_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); + + if (bus->watchdog_tsk) { + send_sig(SIGTERM, bus->watchdog_tsk, 1); + kthread_stop(bus->watchdog_tsk); + bus->watchdog_tsk = NULL; + } + + if (bus->dpc_tsk) { + send_sig(SIGTERM, bus->dpc_tsk, 1); + kthread_stop(bus->dpc_tsk); + bus->dpc_tsk = NULL; + } else + tasklet_kill(&bus->tasklet); /* Disable and clear interrupts at the chip level also */ - W_SDREG(0, &bus->regs->hostintmask, retries); + w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask), &retries); local_hostintmask = bus->hostintmask; bus->hostintmask = 0; /* Change our idea of bus state */ - bus->dhd->busstate = DHD_BUS_DOWN; + bus->drvr->busstate = BRCMF_BUS_DOWN; /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = - bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - &err); + saveclk = brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (!err) { - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + (saveclk | SBSDIO_FORCE_HT), &err); } if (err) { - DHD_ERROR(("%s: Failed to force clock for F2: err %d\n", - __func__, err)); + BRCMF_ERROR(("%s: Failed to force clock for F2: err %d\n", + __func__, err)); } /* Turn off the bus (F2), free any pending packets */ - DHD_INTR(("%s: disable SDIO interrupts\n", __func__)); - bcmsdh_intr_disable(bus->sdh); - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, + BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__)); + brcmf_sdcard_intr_disable(bus->card); + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_0, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1, NULL); /* Clear any pending interrupts now that F2 is disabled */ - W_SDREG(local_hostintmask, &bus->regs->intstatus, retries); + w_sdreg32(bus, local_hostintmask, + offsetof(struct sdpcmd_regs, intstatus), &retries); /* Turn off the backplane clock (only) */ - dhdsdio_clkctl(bus, CLK_SDONLY, false); + brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); /* Clear the data packet queues */ - bcm_pktq_flush(&bus->txq, true, NULL, NULL); + brcmu_pktq_flush(&bus->txq, true, NULL, NULL); /* Clear any held glomming stuff */ if (bus->glomd) - bcm_pkt_buf_free_skb(bus->glomd); + brcmu_pkt_buf_free_skb(bus->glomd); if (bus->glom) - bcm_pkt_buf_free_skb(bus->glom); + brcmu_pkt_buf_free_skb(bus->glom); bus->glom = bus->glomd = NULL; /* Clear rx control and wake any waiters */ bus->rxlen = 0; - dhd_os_ioctl_resp_wake(bus->dhd); + brcmf_os_ioctl_resp_wake(bus->drvr); /* Reset some F2 state stuff */ bus->rxskip = false; bus->tx_seq = bus->rx_seq = 0; if (enforce_mutex) - dhd_os_sdunlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); } -int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex) +int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr, bool enforce_mutex) { - dhd_bus_t *bus = dhdp->bus; - dhd_timeout_t tmo; + struct brcmf_bus *bus = drvr->bus; + struct brcmf_timeout tmo; uint retries = 0; u8 ready, enable; int err, ret = 0; u8 saveclk; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - ASSERT(bus->dhd); - if (!bus->dhd) + /* try to download image and nvram to the dongle */ + if (drvr->busstate == BRCMF_BUS_DOWN) { + if (!(brcmf_sdbrcm_download_firmware(bus, bus->card))) + return -1; + } + + if (!bus->drvr) return 0; + /* Start the watchdog timer */ + bus->drvr->tickcnt = 0; + brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms); + if (enforce_mutex) - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdlock(bus); /* Make sure backplane clock is on, needed to generate F2 interrupt */ - dhdsdio_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); if (bus->clkstate != CLK_AVAIL) goto exit; /* Force clocks on backplane to be sure F2 interrupt propagates */ saveclk = - bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - &err); + brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (!err) { - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + (saveclk | SBSDIO_FORCE_HT), &err); } if (err) { - DHD_ERROR(("%s: Failed to force clock for F2: err %d\n", - __func__, err)); + BRCMF_ERROR(("%s: Failed to force clock for F2: err %d\n", + __func__, err)); goto exit; } /* Enable function 2 (frame transfers) */ - W_SDREG((SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT), - &bus->regs->tosbmailboxdata, retries); + w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, + offsetof(struct sdpcmd_regs, tosbmailboxdata), &retries); enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2); - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, NULL); + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_0, SDIO_CCCR_IOEx, enable, + NULL); /* Give the dongle some time to do its thing and set IOR2 */ - dhd_timeout_start(&tmo, DHD_WAIT_F2RDY * 1000); + brcmf_timeout_start(&tmo, BRCMF_WAIT_F2RDY * 1000); ready = 0; - while (ready != enable && !dhd_timeout_expired(&tmo)) - ready = - bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IORDY, - NULL); + while (ready != enable && !brcmf_timeout_expired(&tmo)) + ready = brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_0, + SDIO_CCCR_IORx, NULL); - DHD_INFO(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n", - __func__, enable, ready, tmo.elapsed)); + BRCMF_INFO(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n", + __func__, enable, ready, tmo.elapsed)); /* If F2 successfully enabled, set core and enable interrupts */ if (ready == enable) { /* Set up the interrupt mask and enable interrupts */ bus->hostintmask = HOSTINTMASK; - W_SDREG(bus->hostintmask, - (unsigned int *)CORE_BUS_REG(bus->ci->buscorebase, - hostintmask), retries); + w_sdreg32(bus, bus->hostintmask, + offsetof(struct sdpcmd_regs, hostintmask), &retries); - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK, + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_WATERMARK, (u8) watermark, &err); /* Set bus state according to enable result */ - dhdp->busstate = DHD_BUS_DATA; - - /* bcmsdh_intr_unmask(bus->sdh); */ + drvr->busstate = BRCMF_BUS_DATA; bus->intdis = false; if (bus->intr) { - DHD_INTR(("%s: enable SDIO device interrupts\n", - __func__)); - bcmsdh_intr_enable(bus->sdh); + BRCMF_INTR(("%s: enable SDIO device interrupts\n", + __func__)); + brcmf_sdcard_intr_enable(bus->card); } else { - DHD_INTR(("%s: disable SDIO interrupts\n", __func__)); - bcmsdh_intr_disable(bus->sdh); + BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__)); + brcmf_sdcard_intr_disable(bus->card); } } @@ -2954,75 +3384,90 @@ int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex) else { /* Disable F2 again */ enable = SDIO_FUNC_ENABLE_1; - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, enable, - NULL); + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_0, SDIO_CCCR_IOEx, + enable, NULL); } /* Restore previous clock setting */ - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); +#if defined(OOB_INTR_ONLY) + /* Host registration for OOB interrupt */ + if (brcmf_sdio_register_oob_intr(bus->dhd)) { + brcmf_sdbrcm_wd_timer(bus, 0); + BRCMF_ERROR(("%s Host failed to resgister for OOB\n", + __func__)); + ret = -ENODEV; + goto exit; + } + + /* Enable oob at firmware */ + brcmf_sdbrcm_enable_oob_intr(bus, true); +#endif /* defined(OOB_INTR_ONLY) */ + /* If we didn't come up, turn off backplane clock */ - if (dhdp->busstate != DHD_BUS_DATA) - dhdsdio_clkctl(bus, CLK_NONE, false); + if (drvr->busstate != BRCMF_BUS_DATA) + brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); exit: if (enforce_mutex) - dhd_os_sdunlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); return ret; } -static void dhdsdio_rxfail(dhd_bus_t *bus, bool abort, bool rtx) +static void brcmf_sdbrcm_rxfail(struct brcmf_bus *bus, bool abort, bool rtx) { - bcmsdh_info_t *sdh = bus->sdh; - sdpcmd_regs_t *regs = bus->regs; + struct brcmf_sdio_card *card = bus->card; uint retries = 0; u16 lastrbc; u8 hi, lo; int err; - DHD_ERROR(("%s: %sterminate frame%s\n", __func__, - (abort ? "abort command, " : ""), - (rtx ? ", send NAK" : ""))); + BRCMF_ERROR(("%s: %sterminate frame%s\n", __func__, + (abort ? "abort command, " : ""), + (rtx ? ", send NAK" : ""))); if (abort) - bcmsdh_abort(sdh, SDIO_FUNC_2); + brcmf_sdcard_abort(card, SDIO_FUNC_2); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, - &err); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, + SFC_RF_TERM, &err); bus->f1regdata++; /* Wait until the packet has been flushed (device/FIFO stable) */ for (lastrbc = retries = 0xffff; retries > 0; retries--) { - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCHI, - NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCLO, - NULL); + hi = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + SBSDIO_FUNC1_RFRAMEBCHI, NULL); + lo = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + SBSDIO_FUNC1_RFRAMEBCLO, NULL); bus->f1regdata += 2; if ((hi == 0) && (lo == 0)) break; if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) { - DHD_ERROR(("%s: count growing: last 0x%04x now " - "0x%04x\n", - __func__, lastrbc, ((hi << 8) + lo))); + BRCMF_ERROR(("%s: count growing: last 0x%04x now " + "0x%04x\n", + __func__, lastrbc, ((hi << 8) + lo))); } lastrbc = (hi << 8) + lo; } if (!retries) { - DHD_ERROR(("%s: count never zeroed: last 0x%04x\n", - __func__, lastrbc)); + BRCMF_ERROR(("%s: count never zeroed: last 0x%04x\n", + __func__, lastrbc)); } else { - DHD_INFO(("%s: flush took %d iterations\n", __func__, - (0xffff - retries))); + BRCMF_INFO(("%s: flush took %d iterations\n", __func__, + (0xffff - retries))); } if (rtx) { bus->rxrtx++; - W_SDREG(SMB_NAK, ®s->tosbmailbox, retries); + w_sdreg32(bus, SMB_NAK, + offsetof(struct sdpcmd_regs, tosbmailbox), &retries); + bus->f1regdata++; if (retries <= retry_limit) bus->rxskip = true; @@ -3032,35 +3477,33 @@ static void dhdsdio_rxfail(dhd_bus_t *bus, bool abort, bool rtx) bus->nextlen = 0; /* If we can't reach the device, signal failure */ - if (err || bcmsdh_regfail(sdh)) - bus->dhd->busstate = DHD_BUS_DOWN; + if (err || brcmf_sdcard_regfail(card)) + bus->drvr->busstate = BRCMF_BUS_DOWN; } static void -dhdsdio_read_control(dhd_bus_t *bus, u8 *hdr, uint len, uint doff) +brcmf_sdbrcm_read_control(struct brcmf_bus *bus, u8 *hdr, uint len, uint doff) { - bcmsdh_info_t *sdh = bus->sdh; + struct brcmf_sdio_card *card = bus->card; uint rdlen, pad; int sdret; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); /* Control data already received in aligned rxctl */ if ((bus->bus == SPI_BUS) && (!bus->usebufpool)) goto gotpkt; - ASSERT(bus->rxbuf); /* Set rxctl for frame (w/optional alignment) */ bus->rxctl = bus->rxbuf; - if (dhd_alignctl) { + if (brcmf_alignctl) { bus->rxctl += firstread; - pad = ((unsigned long)bus->rxctl % DHD_SDALIGN); + pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN); if (pad) - bus->rxctl += (DHD_SDALIGN - pad); + bus->rxctl += (BRCMF_SDALIGN - pad); bus->rxctl -= firstread; } - ASSERT(bus->rxctl >= bus->rxbuf); /* Copy the already-read portion over */ memcpy(bus->rxctl, hdr, firstread); @@ -3078,10 +3521,10 @@ dhdsdio_read_control(dhd_bus_t *bus, u8 *hdr, uint len, uint doff) if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { pad = bus->blocksize - (rdlen % bus->blocksize); if ((pad <= bus->roundup) && (pad < bus->blocksize) && - ((len + pad) < bus->dhd->maxctl)) + ((len + pad) < bus->drvr->maxctl)) rdlen += pad; - } else if (rdlen % DHD_SDALIGN) { - rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); + } else if (rdlen % BRCMF_SDALIGN) { + rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN); } /* Satisfy length-alignment requirements */ @@ -3089,44 +3532,44 @@ dhdsdio_read_control(dhd_bus_t *bus, u8 *hdr, uint len, uint doff) rdlen = roundup(rdlen, ALIGNMENT); /* Drop if the read is too big or it exceeds our maximum */ - if ((rdlen + firstread) > bus->dhd->maxctl) { - DHD_ERROR(("%s: %d-byte control read exceeds %d-byte buffer\n", - __func__, rdlen, bus->dhd->maxctl)); - bus->dhd->rx_errors++; - dhdsdio_rxfail(bus, false, false); + if ((rdlen + firstread) > bus->drvr->maxctl) { + BRCMF_ERROR(("%s: %d-byte control read exceeds %d-byte" + " buffer\n", __func__, rdlen, bus->drvr->maxctl)); + bus->drvr->rx_errors++; + brcmf_sdbrcm_rxfail(bus, false, false); goto done; } - if ((len - doff) > bus->dhd->maxctl) { - DHD_ERROR(("%s: %d-byte ctl frame (%d-byte ctl data) exceeds " - "%d-byte limit\n", - __func__, len, (len - doff), bus->dhd->maxctl)); - bus->dhd->rx_errors++; + if ((len - doff) > bus->drvr->maxctl) { + BRCMF_ERROR(("%s: %d-byte ctl frame (%d-byte ctl data) exceeds " + "%d-byte limit\n", + __func__, len, (len - doff), bus->drvr->maxctl)); + bus->drvr->rx_errors++; bus->rx_toolong++; - dhdsdio_rxfail(bus, false, false); + brcmf_sdbrcm_rxfail(bus, false, false); goto done; } /* Read remainder of frame body into the rxctl buffer */ - sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, + sdret = brcmf_sdcard_recv_buf(card, brcmf_sdcard_cur_sbwad(card), + SDIO_FUNC_2, F2SYNC, (bus->rxctl + firstread), rdlen, NULL, NULL, NULL); bus->f2rxdata++; - ASSERT(sdret != -BCME_PENDING); /* Control frame failures need retransmission */ if (sdret < 0) { - DHD_ERROR(("%s: read %d control bytes failed: %d\n", - __func__, rdlen, sdret)); - bus->rxc_errors++; /* dhd.rx_ctlerrs is higher level */ - dhdsdio_rxfail(bus, true, true); + BRCMF_ERROR(("%s: read %d control bytes failed: %d\n", + __func__, rdlen, sdret)); + bus->rxc_errors++; + brcmf_sdbrcm_rxfail(bus, true, true); goto done; } gotpkt: -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_CTL_ON()) { +#ifdef BCMDBG + if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { printk(KERN_DEBUG "RxCtrl:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len); } @@ -3138,10 +3581,10 @@ dhdsdio_read_control(dhd_bus_t *bus, u8 *hdr, uint len, uint doff) done: /* Awake any waiters */ - dhd_os_ioctl_resp_wake(bus->dhd); + brcmf_os_ioctl_resp_wake(bus->drvr); } -static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) +static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) { u16 dlen, totlen; u8 *dptr, num = 0; @@ -3159,19 +3602,18 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) /* If packets, issue read(s) and send up packet chain */ /* Return sequence numbers consumed? */ - DHD_TRACE(("dhdsdio_rxglom: start: glomd %p glom %p\n", bus->glomd, - bus->glom)); + BRCMF_TRACE(("brcmf_sdbrcm_rxglom: start: glomd %p glom %p\n", + bus->glomd, bus->glom)); /* If there's a descriptor, generate the packet chain */ if (bus->glomd) { - dhd_os_sdlock_rxq(bus->dhd); - pfirst = plast = pnext = NULL; dlen = (u16) (bus->glomd->len); dptr = bus->glomd->data; if (!dlen || (dlen & 1)) { - DHD_ERROR(("%s: bad glomd len(%d), ignore descriptor\n", - __func__, dlen)); + BRCMF_ERROR(("%s: bad glomd len(%d)," + " ignore descriptor\n", + __func__, dlen)); dlen = 0; } @@ -3182,14 +3624,15 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) dptr += sizeof(u16); if ((sublen < SDPCM_HDRLEN) || ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) { - DHD_ERROR(("%s: descriptor len %d bad: %d\n", - __func__, num, sublen)); + BRCMF_ERROR(("%s: descriptor len %d bad: %d\n", + __func__, num, sublen)); pnext = NULL; break; } - if (sublen % DHD_SDALIGN) { - DHD_ERROR(("%s: sublen %d not multiple of %d\n", - __func__, sublen, DHD_SDALIGN)); + if (sublen % BRCMF_SDALIGN) { + BRCMF_ERROR(("%s: sublen %d not multiple of" + " %d\n", __func__, sublen, + BRCMF_SDALIGN)); usechain = false; } totlen += sublen; @@ -3203,123 +3646,120 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) } /* Allocate/chain packet for next subframe */ - pnext = bcm_pkt_buf_get_skb(sublen + DHD_SDALIGN); + pnext = brcmu_pkt_buf_get_skb(sublen + BRCMF_SDALIGN); if (pnext == NULL) { - DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed, " - "num %d len %d\n", __func__, - num, sublen)); + BRCMF_ERROR(("%s: bcm_pkt_buf_get_skb failed, " + "num %d len %d\n", __func__, + num, sublen)); break; } - ASSERT(!(pnext->prev)); if (!pfirst) { - ASSERT(!plast); pfirst = plast = pnext; } else { - ASSERT(plast); plast->next = pnext; plast = pnext; } /* Adhere to start alignment requirements */ - PKTALIGN(pnext, sublen, DHD_SDALIGN); + PKTALIGN(pnext, sublen, BRCMF_SDALIGN); } /* If all allocations succeeded, save packet chain in bus structure */ if (pnext) { - DHD_GLOM(("%s: allocated %d-byte packet chain for %d " - "subframes\n", __func__, totlen, num)); - if (DHD_GLOM_ON() && bus->nextlen) { + BRCMF_GLOM(("%s: allocated %d-byte packet chain for %d " + "subframes\n", __func__, totlen, num)); + if (BRCMF_GLOM_ON() && bus->nextlen) { if (totlen != bus->nextlen) { - DHD_GLOM(("%s: glomdesc mismatch: nextlen %d glomdesc %d " "rxseq %d\n", - __func__, bus->nextlen, - totlen, rxseq)); + BRCMF_GLOM(("%s: glomdesc mismatch: " + "nextlen %d glomdesc %d " + "rxseq %d\n", __func__, + bus->nextlen, + totlen, rxseq)); } } bus->glom = pfirst; pfirst = pnext = NULL; } else { if (pfirst) - bcm_pkt_buf_free_skb(pfirst); + brcmu_pkt_buf_free_skb(pfirst); bus->glom = NULL; num = 0; } /* Done with descriptor packet */ - bcm_pkt_buf_free_skb(bus->glomd); + brcmu_pkt_buf_free_skb(bus->glomd); bus->glomd = NULL; bus->nextlen = 0; - - dhd_os_sdunlock_rxq(bus->dhd); } /* Ok -- either we just generated a packet chain, or had one from before */ if (bus->glom) { - if (DHD_GLOM_ON()) { - DHD_GLOM(("%s: try superframe read, packet chain:\n", - __func__)); + if (BRCMF_GLOM_ON()) { + BRCMF_GLOM(("%s: try superframe read, packet chain:\n", + __func__)); for (pnext = bus->glom; pnext; pnext = pnext->next) { - DHD_GLOM((" %p: %p len 0x%04x (%d)\n", - pnext, (u8 *) (pnext->data), - pnext->len, pnext->len)); + BRCMF_GLOM((" %p: %p len 0x%04x (%d)\n", + pnext, (u8 *) (pnext->data), + pnext->len, pnext->len)); } } pfirst = bus->glom; - dlen = (u16) bcm_pkttotlen(pfirst); + dlen = (u16) brcmu_pkttotlen(pfirst); /* Do an SDIO read for the superframe. Configurable iovar to * read directly into the chained packet, or allocate a large * packet and and copy into the chain. */ if (usechain) { - errcode = bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2, + errcode = brcmf_sdcard_recv_buf(bus->card, + brcmf_sdcard_cur_sbwad(bus->card), + SDIO_FUNC_2, F2SYNC, (u8 *) pfirst->data, dlen, pfirst, NULL, NULL); } else if (bus->dataptr) { - errcode = bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2, + errcode = brcmf_sdcard_recv_buf(bus->card, + brcmf_sdcard_cur_sbwad(bus->card), + SDIO_FUNC_2, F2SYNC, bus->dataptr, dlen, NULL, NULL, NULL); - sublen = (u16) bcm_pktfrombuf(pfirst, 0, dlen, + sublen = (u16) brcmu_pktfrombuf(pfirst, 0, dlen, bus->dataptr); if (sublen != dlen) { - DHD_ERROR(("%s: FAILED TO COPY, dlen %d sublen %d\n", - __func__, dlen, sublen)); + BRCMF_ERROR(("%s: FAILED TO COPY, dlen %d " + "sublen %d\n", + __func__, dlen, sublen)); errcode = -1; } pnext = NULL; } else { - DHD_ERROR(("COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n", - dlen)); + BRCMF_ERROR(("COULDN'T ALLOC %d-BYTE GLOM, " + "FORCE FAILURE\n", dlen)); errcode = -1; } bus->f2rxdata++; - ASSERT(errcode != -BCME_PENDING); /* On failure, kill the superframe, allow a couple retries */ if (errcode < 0) { - DHD_ERROR(("%s: glom read of %d bytes failed: %d\n", - __func__, dlen, errcode)); - bus->dhd->rx_errors++; + BRCMF_ERROR(("%s: glom read of %d bytes failed: %d\n", + __func__, dlen, errcode)); + bus->drvr->rx_errors++; if (bus->glomerr++ < 3) { - dhdsdio_rxfail(bus, true, true); + brcmf_sdbrcm_rxfail(bus, true, true); } else { bus->glomerr = 0; - dhdsdio_rxfail(bus, true, false); - dhd_os_sdlock_rxq(bus->dhd); - bcm_pkt_buf_free_skb(bus->glom); - dhd_os_sdunlock_rxq(bus->dhd); + brcmf_sdbrcm_rxfail(bus, true, false); + brcmu_pkt_buf_free_skb(bus->glom); bus->rxglomfail++; bus->glom = NULL; } return 0; } -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { +#ifdef BCMDBG + if (BRCMF_GLOM_ON()) { printk(KERN_DEBUG "SUPERFRAME:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, pfirst->data, min_t(int, pfirst->len, 48)); @@ -3335,8 +3775,8 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - DHD_INFO(("%s: nextlen too large (%d) seq %d\n", - __func__, bus->nextlen, seq)); + BRCMF_INFO(("%s: nextlen too large (%d) seq %d\n", + __func__, bus->nextlen, seq)); bus->nextlen = 0; } doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); @@ -3344,47 +3784,48 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) errcode = 0; if ((u16)~(sublen ^ check)) { - DHD_ERROR(("%s (superframe): HW hdr error: len/check " - "0x%04x/0x%04x\n", __func__, sublen, check)); + BRCMF_ERROR(("%s (superframe): HW hdr error: len/check " + "0x%04x/0x%04x\n", __func__, sublen, + check)); errcode = -1; } else if (roundup(sublen, bus->blocksize) != dlen) { - DHD_ERROR(("%s (superframe): len 0x%04x, rounded " - "0x%04x, expect 0x%04x\n", - __func__, sublen, - roundup(sublen, bus->blocksize), dlen)); + BRCMF_ERROR(("%s (superframe): len 0x%04x, rounded " + "0x%04x, expect 0x%04x\n", + __func__, sublen, + roundup(sublen, bus->blocksize), dlen)); errcode = -1; } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) != SDPCM_GLOM_CHANNEL) { - DHD_ERROR(("%s (superframe): bad channel %d\n", + BRCMF_ERROR(("%s (superframe): bad channel %d\n", __func__, SDPCM_PACKET_CHANNEL(&dptr [SDPCM_FRAMETAG_LEN]))); errcode = -1; } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) { - DHD_ERROR(("%s (superframe): got second descriptor?\n", - __func__)); + BRCMF_ERROR(("%s (superframe): got 2nd descriptor?\n", + __func__)); errcode = -1; } else if ((doff < SDPCM_HDRLEN) || (doff > (pfirst->len - SDPCM_HDRLEN))) { - DHD_ERROR(("%s (superframe): Bad data offset %d: HW %d " - "pkt %d min %d\n", - __func__, doff, sublen, - pfirst->len, SDPCM_HDRLEN)); + BRCMF_ERROR(("%s (superframe): Bad data offset %d: " + "HW %d pkt %d min %d\n", + __func__, doff, sublen, + pfirst->len, SDPCM_HDRLEN)); errcode = -1; } /* Check sequence number of superframe SW header */ if (rxseq != seq) { - DHD_INFO(("%s: (superframe) rx_seq %d, expected %d\n", - __func__, seq, rxseq)); + BRCMF_INFO(("%s: (superframe) rx_seq %d, expected %d\n", + __func__, seq, rxseq)); bus->rx_badseq++; rxseq = seq; } /* Check window for sanity */ if ((u8) (txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: unlikely tx max %d with tx_seq %d\n", - __func__, txmax, bus->tx_seq)); + BRCMF_ERROR(("%s: unlikely tx max %d with tx_seq %d\n", + __func__, txmax, bus->tx_seq)); txmax = bus->tx_seq + 2; } bus->tx_max = txmax; @@ -3402,8 +3843,8 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) check = get_unaligned_le16(dptr + sizeof(u16)); chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { +#ifdef BCMDBG + if (BRCMF_GLOM_ON()) { printk(KERN_DEBUG "subframe:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, dptr, 32); @@ -3411,24 +3852,25 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) #endif if ((u16)~(sublen ^ check)) { - DHD_ERROR(("%s (subframe %d): HW hdr error: " - "len/check 0x%04x/0x%04x\n", - __func__, num, sublen, check)); + BRCMF_ERROR(("%s (subframe %d): HW hdr error: " + "len/check 0x%04x/0x%04x\n", + __func__, num, sublen, check)); errcode = -1; } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) { - DHD_ERROR(("%s (subframe %d): length mismatch: " - "len 0x%04x, expect 0x%04x\n", - __func__, num, sublen, dlen)); + BRCMF_ERROR(("%s (subframe %d): length mismatch" + ": len 0x%04x, expect 0x%04x\n", + __func__, num, sublen, dlen)); errcode = -1; } else if ((chan != SDPCM_DATA_CHANNEL) && (chan != SDPCM_EVENT_CHANNEL)) { - DHD_ERROR(("%s (subframe %d): bad channel %d\n", - __func__, num, chan)); + BRCMF_ERROR(("%s (subframe %d): bad channel" + " %d\n", __func__, num, chan)); errcode = -1; } else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) { - DHD_ERROR(("%s (subframe %d): Bad data offset %d: HW %d min %d\n", - __func__, num, doff, sublen, - SDPCM_HDRLEN)); + BRCMF_ERROR(("%s (subframe %d): Bad data offset" + " %d: HW %d min %d\n", + __func__, num, doff, sublen, + SDPCM_HDRLEN)); errcode = -1; } } @@ -3439,13 +3881,11 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) if (bus->glomerr++ < 3) { /* Restore superframe header space */ skb_push(pfirst, sfdoff); - dhdsdio_rxfail(bus, true, true); + brcmf_sdbrcm_rxfail(bus, true, true); } else { bus->glomerr = 0; - dhdsdio_rxfail(bus, true, false); - dhd_os_sdlock_rxq(bus->dhd); - bcm_pkt_buf_free_skb(bus->glom); - dhd_os_sdunlock_rxq(bus->dhd); + brcmf_sdbrcm_rxfail(bus, true, false); + brcmu_pkt_buf_free_skb(bus->glom); bus->rxglomfail++; bus->glom = NULL; } @@ -3458,7 +3898,6 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) bus->glom = NULL; plast = NULL; - dhd_os_sdlock_rxq(bus->dhd); for (num = 0; pfirst; rxseq++, pfirst = pnext) { pnext = pfirst->next; pfirst->next = NULL; @@ -3469,22 +3908,22 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); - DHD_GLOM(("%s: Get subframe %d, %p(%p/%d), sublen %d " - "chan %d seq %d\n", - __func__, num, pfirst, pfirst->data, - pfirst->len, sublen, chan, seq)); + BRCMF_GLOM(("%s: Get subframe %d, %p(%p/%d), sublen %d " + "chan %d seq %d\n", + __func__, num, pfirst, pfirst->data, + pfirst->len, sublen, chan, seq)); - ASSERT((chan == SDPCM_DATA_CHANNEL) - || (chan == SDPCM_EVENT_CHANNEL)); + /* precondition: chan == SDPCM_DATA_CHANNEL || + chan == SDPCM_EVENT_CHANNEL */ if (rxseq != seq) { - DHD_GLOM(("%s: rx_seq %d, expected %d\n", - __func__, seq, rxseq)); + BRCMF_GLOM(("%s: rx_seq %d, expected %d\n", + __func__, seq, rxseq)); bus->rx_badseq++; rxseq = seq; } -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { +#ifdef BCMDBG + if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { printk(KERN_DEBUG "Rx Subframe Data:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, dptr, dlen); @@ -3495,24 +3934,22 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) skb_pull(pfirst, doff); if (pfirst->len == 0) { - bcm_pkt_buf_free_skb(pfirst); + brcmu_pkt_buf_free_skb(pfirst); if (plast) { plast->next = pnext; } else { - ASSERT(save_pfirst == pfirst); save_pfirst = pnext; } continue; - } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pfirst) != - 0) { - DHD_ERROR(("%s: rx protocol error\n", - __func__)); - bus->dhd->rx_errors++; - bcm_pkt_buf_free_skb(pfirst); + } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx, pfirst) + != 0) { + BRCMF_ERROR(("%s: rx protocol error\n", + __func__)); + bus->drvr->rx_errors++; + brcmu_pkt_buf_free_skb(pfirst); if (plast) { plast->next = pnext; } else { - ASSERT(save_pfirst == pfirst); save_pfirst = pnext; } continue; @@ -3524,24 +3961,23 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) plast = pfirst; num++; -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { - DHD_GLOM(("%s subframe %d to stack, %p(%p/%d) " - "nxt/lnk %p/%p\n", - __func__, num, pfirst, pfirst->data, - pfirst->len, pfirst->next, - pfirst->prev)); +#ifdef BCMDBG + if (BRCMF_GLOM_ON()) { + BRCMF_GLOM(("%s subframe %d to stack, %p" + "(%p/%d) nxt/lnk %p/%p\n", + __func__, num, pfirst, pfirst->data, + pfirst->len, pfirst->next, + pfirst->prev)); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, pfirst->data, min_t(int, pfirst->len, 32)); } -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ } - dhd_os_sdunlock_rxq(bus->dhd); if (num) { - dhd_os_sdunlock(bus->dhd); - dhd_rx_frame(bus->dhd, ifidx, save_pfirst, num); - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); + brcmf_rx_frame(bus->drvr, ifidx, save_pfirst, num); + brcmf_sdbrcm_sdlock(bus); } bus->rxglomframes++; @@ -3551,9 +3987,10 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) } /* Return true if there may be more frames to read */ -static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) +static uint +brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) { - bcmsdh_info_t *sdh = bus->sdh; + struct brcmf_sdio_card *card = bus->card; u16 len, check; /* Extracted hardware header fields */ u8 chan, seq, doff; /* Extracted software header fields */ @@ -3564,7 +4001,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) u16 rdlen; /* Total number of bytes to read */ u8 rxseq; /* Next sequence number to expect */ uint rxleft = 0; /* Remaining number of frames allowed */ - int sdret; /* Return code from bcmsdh calls */ + int sdret; /* Return code from calls */ u8 txmax; /* Maximum tx sequence offered */ bool len_consistent; /* Result of comparing readahead len and len from hw-hdr */ @@ -3572,17 +4009,15 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) int ifidx = 0; uint rxcount = 0; /* Total frames read */ -#if defined(DHD_DEBUG) || defined(SDTEST) +#if defined(BCMDBG) || defined(SDTEST) bool sdtest = false; /* To limit message spew from test mode */ #endif - DHD_TRACE(("%s: Enter\n", __func__)); - - ASSERT(maxframes); + BRCMF_TRACE(("%s: Enter\n", __func__)); #ifdef SDTEST /* Allow pktgen to override maxframes */ - if (bus->pktgen_count && (bus->pktgen_mode == DHD_PKTGEN_RECV)) { + if (bus->pktgen_count && (bus->pktgen_mode == BRCMF_PKTGEN_RECV)) { maxframes = bus->pktgen_count; sdtest = true; } @@ -3592,23 +4027,23 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) *finished = false; for (rxseq = bus->rx_seq, rxleft = maxframes; - !bus->rxskip && rxleft && bus->dhd->busstate != DHD_BUS_DOWN; + !bus->rxskip && rxleft && bus->drvr->busstate != BRCMF_BUS_DOWN; rxseq++, rxleft--) { /* Handle glomming separately */ if (bus->glom || bus->glomd) { u8 cnt; - DHD_GLOM(("%s: calling rxglom: glomd %p, glom %p\n", - __func__, bus->glomd, bus->glom)); - cnt = dhdsdio_rxglom(bus, rxseq); - DHD_GLOM(("%s: rxglom returned %d\n", __func__, cnt)); + BRCMF_GLOM(("%s: calling rxglom: glomd %p, glom %p\n", + __func__, bus->glomd, bus->glom)); + cnt = brcmf_sdbrcm_rxglom(bus, rxseq); + BRCMF_GLOM(("%s: rxglom returned %d\n", __func__, cnt)); rxseq += cnt - 1; rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1; continue; } /* Try doing single read if we can */ - if (dhd_readahead && bus->nextlen) { + if (brcmf_readahead && bus->nextlen) { u16 nextlen = bus->nextlen; bus->nextlen = 0; @@ -3628,9 +4063,9 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) && ((rdlen + pad + firstread) < MAX_RX_DATASZ)) rdlen += pad; - } else if (rdlen % DHD_SDALIGN) { + } else if (rdlen % BRCMF_SDALIGN) { rdlen += - DHD_SDALIGN - (rdlen % DHD_SDALIGN); + BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN); } } @@ -3645,42 +4080,40 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) * or non-data frame. */ /* Allocate a packet buffer */ - dhd_os_sdlock_rxq(bus->dhd); - pkt = bcm_pkt_buf_get_skb(rdlen + DHD_SDALIGN); + pkt = brcmu_pkt_buf_get_skb(rdlen + BRCMF_SDALIGN); if (!pkt) { if (bus->bus == SPI_BUS) { bus->usebufpool = false; bus->rxctl = bus->rxbuf; - if (dhd_alignctl) { + if (brcmf_alignctl) { bus->rxctl += firstread; pad = ((unsigned long)bus->rxctl % - DHD_SDALIGN); + BRCMF_SDALIGN); if (pad) bus->rxctl += - (DHD_SDALIGN - pad); + (BRCMF_SDALIGN - pad); bus->rxctl -= firstread; } - ASSERT(bus->rxctl >= bus->rxbuf); rxbuf = bus->rxctl; /* Read the entire frame */ - sdret = bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(sdh), - SDIO_FUNC_2, F2SYNC, - rxbuf, rdlen, - NULL, NULL, NULL); + sdret = brcmf_sdcard_recv_buf(card, + brcmf_sdcard_cur_sbwad(card), + SDIO_FUNC_2, F2SYNC, + rxbuf, rdlen, + NULL, NULL, NULL); bus->f2rxdata++; - ASSERT(sdret != -BCME_PENDING); /* Control frame failures need retransmission */ if (sdret < 0) { - DHD_ERROR(("%s: read %d control bytes failed: %d\n", - __func__, - rdlen, sdret)); + BRCMF_ERROR(("%s: read %d " + "control bytes " + "failed: %d\n", + __func__, + rdlen, sdret)); /* dhd.rx_ctlerrs is higher */ bus->rxc_errors++; - dhd_os_sdunlock_rxq(bus->dhd); - dhdsdio_rxfail(bus, true, + brcmf_sdbrcm_rxfail(bus, true, (bus->bus == SPI_BUS) ? false : true); @@ -3689,50 +4122,45 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) } else { /* Give up on data, request rtx of events */ - DHD_ERROR(("%s (nextlen): " - "bcm_pkt_buf_get_skb failed:" - " len %d rdlen %d expected" - " rxseq %d\n", __func__, - len, rdlen, rxseq)); - /* Just go try again w/normal - header read */ - dhd_os_sdunlock_rxq(bus->dhd); + BRCMF_ERROR(("%s (nextlen): " + "brcmu_pkt_buf_get_skb " + "failed:" + " len %d rdlen %d expected" + " rxseq %d\n", __func__, + len, rdlen, rxseq)); continue; } } else { if (bus->bus == SPI_BUS) bus->usebufpool = true; - ASSERT(!(pkt->prev)); - PKTALIGN(pkt, rdlen, DHD_SDALIGN); + PKTALIGN(pkt, rdlen, BRCMF_SDALIGN); rxbuf = (u8 *) (pkt->data); /* Read the entire frame */ - sdret = bcmsdh_recv_buf(bus, - bcmsdh_cur_sbwad(sdh), + sdret = brcmf_sdcard_recv_buf(card, + brcmf_sdcard_cur_sbwad(card), SDIO_FUNC_2, F2SYNC, rxbuf, rdlen, pkt, NULL, NULL); bus->f2rxdata++; - ASSERT(sdret != -BCME_PENDING); if (sdret < 0) { - DHD_ERROR(("%s (nextlen): read %d bytes failed: %d\n", - __func__, rdlen, sdret)); - bcm_pkt_buf_free_skb(pkt); - bus->dhd->rx_errors++; - dhd_os_sdunlock_rxq(bus->dhd); + BRCMF_ERROR(("%s (nextlen): read %d" + " bytes failed: %d\n", + __func__, rdlen, sdret)); + brcmu_pkt_buf_free_skb(pkt); + bus->drvr->rx_errors++; /* Force retry w/normal header read. * Don't attempt NAK for * gSPI */ - dhdsdio_rxfail(bus, true, + brcmf_sdbrcm_rxfail(bus, true, (bus->bus == SPI_BUS) ? false : true); continue; } } - dhd_os_sdunlock_rxq(bus->dhd); /* Now check the header */ memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN); @@ -3743,29 +4171,29 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) /* All zeros means readahead info was bad */ if (!(len | check)) { - DHD_INFO(("%s (nextlen): read zeros in HW " - "header???\n", __func__)); - dhdsdio_pktfree2(bus, pkt); + BRCMF_INFO(("%s (nextlen): read zeros in HW " + "header???\n", __func__)); + brcmf_sdbrcm_pktfree2(bus, pkt); continue; } /* Validate check bytes */ if ((u16)~(len ^ check)) { - DHD_ERROR(("%s (nextlen): HW hdr error:" - " nextlen/len/check" - " 0x%04x/0x%04x/0x%04x\n", - __func__, nextlen, len, check)); + BRCMF_ERROR(("%s (nextlen): HW hdr error:" + " nextlen/len/check" + " 0x%04x/0x%04x/0x%04x\n", + __func__, nextlen, len, check)); bus->rx_badhdr++; - dhdsdio_rxfail(bus, false, false); - dhdsdio_pktfree2(bus, pkt); + brcmf_sdbrcm_rxfail(bus, false, false); + brcmf_sdbrcm_pktfree2(bus, pkt); continue; } /* Validate frame length */ if (len < SDPCM_HDRLEN) { - DHD_ERROR(("%s (nextlen): HW hdr length " - "invalid: %d\n", __func__, len)); - dhdsdio_pktfree2(bus, pkt); + BRCMF_ERROR(("%s (nextlen): HW hdr length " + "invalid: %d\n", __func__, len)); + brcmf_sdbrcm_pktfree2(bus, pkt); continue; } @@ -3774,13 +4202,14 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) if (len_consistent) { /* Mismatch, force retry w/normal header (may be >4K) */ - DHD_ERROR(("%s (nextlen): mismatch, " - "nextlen %d len %d rnd %d; " - "expected rxseq %d\n", - __func__, nextlen, - len, roundup(len, 16), rxseq)); - dhdsdio_rxfail(bus, true, (bus->bus != SPI_BUS)); - dhdsdio_pktfree2(bus, pkt); + BRCMF_ERROR(("%s (nextlen): mismatch, " + "nextlen %d len %d rnd %d; " + "expected rxseq %d\n", + __func__, nextlen, + len, roundup(len, 16), rxseq)); + brcmf_sdbrcm_rxfail(bus, true, + bus->bus != SPI_BUS); + brcmf_sdbrcm_pktfree2(bus, pkt); continue; } @@ -3798,12 +4227,13 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - DHD_INFO(("%s (nextlen): got frame w/nextlen too large" " (%d), seq %d\n", - __func__, bus->nextlen, seq)); + BRCMF_INFO(("%s (nextlen): got frame w/nextlen" + " too large (%d), seq %d\n", + __func__, bus->nextlen, seq)); bus->nextlen = 0; } - bus->dhd->rx_readahead_cnt++; + bus->drvr->rx_readahead_cnt++; /* Handle Flow Control */ fcbits = SDPCM_FCMASK_VALUE( @@ -3822,27 +4252,27 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) /* Check and update sequence number */ if (rxseq != seq) { - DHD_INFO(("%s (nextlen): rx_seq %d, expected " - "%d\n", __func__, seq, rxseq)); + BRCMF_INFO(("%s (nextlen): rx_seq %d, expected " + "%d\n", __func__, seq, rxseq)); bus->rx_badseq++; rxseq = seq; } /* Check window for sanity */ if ((u8) (txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: got unlikely tx max %d with " - "tx_seq %d\n", - __func__, txmax, bus->tx_seq)); + BRCMF_ERROR(("%s: got unlikely tx max %d with " + "tx_seq %d\n", + __func__, txmax, bus->tx_seq)); txmax = bus->tx_seq + 2; } bus->tx_max = txmax; -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { +#ifdef BCMDBG + if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { printk(KERN_DEBUG "Rx Data:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxbuf, len); - } else if (DHD_HDRS_ON()) { + } else if (BRCMF_HDRS_ON()) { printk(KERN_DEBUG "RxHdr:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxhdr, SDPCM_HDRLEN); @@ -3851,31 +4281,35 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) if (chan == SDPCM_CONTROL_CHANNEL) { if (bus->bus == SPI_BUS) { - dhdsdio_read_control(bus, rxbuf, len, - doff); + brcmf_sdbrcm_read_control(bus, rxbuf, + len, doff); } else { - DHD_ERROR(("%s (nextlen): readahead on control" " packet %d?\n", - __func__, seq)); + BRCMF_ERROR(("%s (nextlen): readahead" + " on control packet %d?\n", + __func__, seq)); /* Force retry w/normal header read */ bus->nextlen = 0; - dhdsdio_rxfail(bus, false, true); + brcmf_sdbrcm_rxfail(bus, false, true); } - dhdsdio_pktfree2(bus, pkt); + brcmf_sdbrcm_pktfree2(bus, pkt); continue; } if ((bus->bus == SPI_BUS) && !bus->usebufpool) { - DHD_ERROR(("Received %d bytes on %d channel. Running out of " "rx pktbuf's or not yet malloced.\n", - len, chan)); + BRCMF_ERROR(("Received %d bytes on %d channel." + " Running out of " "rx pktbuf's or" + " not yet malloced.\n", + len, chan)); continue; } /* Validate data offset */ if ((doff < SDPCM_HDRLEN) || (doff > len)) { - DHD_ERROR(("%s (nextlen): bad data offset %d: HW len %d min %d\n", - __func__, doff, len, SDPCM_HDRLEN)); - dhdsdio_rxfail(bus, false, false); - dhdsdio_pktfree2(bus, pkt); + BRCMF_ERROR(("%s (nextlen): bad data offset %d:" + " HW len %d min %d\n", __func__, + doff, len, SDPCM_HDRLEN)); + brcmf_sdbrcm_rxfail(bus, false, false); + brcmf_sdbrcm_pktfree2(bus, pkt); continue; } @@ -3887,21 +4321,21 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) break; /* Read frame header (hardware and software) */ - sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), + sdret = brcmf_sdcard_recv_buf(card, + brcmf_sdcard_cur_sbwad(card), SDIO_FUNC_2, F2SYNC, bus->rxhdr, firstread, NULL, NULL, NULL); bus->f2rxhdrs++; - ASSERT(sdret != -BCME_PENDING); if (sdret < 0) { - DHD_ERROR(("%s: RXHEADER FAILED: %d\n", __func__, - sdret)); + BRCMF_ERROR(("%s: RXHEADER FAILED: %d\n", __func__, + sdret)); bus->rx_hdrfail++; - dhdsdio_rxfail(bus, true, true); + brcmf_sdbrcm_rxfail(bus, true, true); continue; } -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() || DHD_HDRS_ON()) { +#ifdef BCMDBG + if (BRCMF_BYTES_ON() || BRCMF_HDRS_ON()) { printk(KERN_DEBUG "RxHdr:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxhdr, SDPCM_HDRLEN); @@ -3920,17 +4354,17 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) /* Validate check bytes */ if ((u16) ~(len ^ check)) { - DHD_ERROR(("%s: HW hdr err: len/check 0x%04x/0x%04x\n", - __func__, len, check)); + BRCMF_ERROR(("%s: HW hdr err: len/check " + "0x%04x/0x%04x\n", __func__, len, check)); bus->rx_badhdr++; - dhdsdio_rxfail(bus, false, false); + brcmf_sdbrcm_rxfail(bus, false, false); continue; } /* Validate frame length */ if (len < SDPCM_HDRLEN) { - DHD_ERROR(("%s: HW hdr length invalid: %d\n", - __func__, len)); + BRCMF_ERROR(("%s: HW hdr length invalid: %d\n", + __func__, len)); continue; } @@ -3942,12 +4376,11 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) /* Validate data offset */ if ((doff < SDPCM_HDRLEN) || (doff > len)) { - DHD_ERROR(("%s: Bad data offset %d: HW len %d, min %d " - "seq %d\n", - __func__, doff, len, SDPCM_HDRLEN, seq)); + BRCMF_ERROR(("%s: Bad data offset %d: HW len %d," + " min %d seq %d\n", __func__, doff, + len, SDPCM_HDRLEN, seq)); bus->rx_badhdr++; - ASSERT(0); - dhdsdio_rxfail(bus, false, false); + brcmf_sdbrcm_rxfail(bus, false, false); continue; } @@ -3955,9 +4388,9 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) bus->nextlen = bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - DHD_INFO(("%s (nextlen): got frame w/nextlen too large " - "(%d), seq %d\n", - __func__, bus->nextlen, seq)); + BRCMF_INFO(("%s (nextlen): got frame w/nextlen too" + " large (%d), seq %d\n", + __func__, bus->nextlen, seq)); bus->nextlen = 0; } @@ -3977,30 +4410,29 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) /* Check and update sequence number */ if (rxseq != seq) { - DHD_INFO(("%s: rx_seq %d, expected %d\n", __func__, - seq, rxseq)); + BRCMF_INFO(("%s: rx_seq %d, expected %d\n", __func__, + seq, rxseq)); bus->rx_badseq++; rxseq = seq; } /* Check window for sanity */ if ((u8) (txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: unlikely tx max %d with tx_seq %d\n", - __func__, txmax, bus->tx_seq)); + BRCMF_ERROR(("%s: unlikely tx max %d with tx_seq %d\n", + __func__, txmax, bus->tx_seq)); txmax = bus->tx_seq + 2; } bus->tx_max = txmax; /* Call a separate function for control frames */ if (chan == SDPCM_CONTROL_CHANNEL) { - dhdsdio_read_control(bus, bus->rxhdr, len, doff); + brcmf_sdbrcm_read_control(bus, bus->rxhdr, len, doff); continue; } - ASSERT((chan == SDPCM_DATA_CHANNEL) - || (chan == SDPCM_EVENT_CHANNEL) - || (chan == SDPCM_TEST_CHANNEL) - || (chan == SDPCM_GLOM_CHANNEL)); + /* precondition: chan is either SDPCM_DATA_CHANNEL, + SDPCM_EVENT_CHANNEL, SDPCM_TEST_CHANNEL or + SDPCM_GLOM_CHANNEL */ /* Length to read */ rdlen = (len > firstread) ? (len - firstread) : 0; @@ -4012,8 +4444,8 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) if ((pad <= bus->roundup) && (pad < bus->blocksize) && ((rdlen + pad + firstread) < MAX_RX_DATASZ)) rdlen += pad; - } else if (rdlen % DHD_SDALIGN) { - rdlen += DHD_SDALIGN - (rdlen % DHD_SDALIGN); + } else if (rdlen % BRCMF_SDALIGN) { + rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN); } /* Satisfy length-alignment requirements */ @@ -4022,54 +4454,45 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) if ((rdlen + firstread) > MAX_RX_DATASZ) { /* Too long -- skip this frame */ - DHD_ERROR(("%s: too long: len %d rdlen %d\n", - __func__, len, rdlen)); - bus->dhd->rx_errors++; + BRCMF_ERROR(("%s: too long: len %d rdlen %d\n", + __func__, len, rdlen)); + bus->drvr->rx_errors++; bus->rx_toolong++; - dhdsdio_rxfail(bus, false, false); + brcmf_sdbrcm_rxfail(bus, false, false); continue; } - dhd_os_sdlock_rxq(bus->dhd); - pkt = bcm_pkt_buf_get_skb(rdlen + firstread + DHD_SDALIGN); + pkt = brcmu_pkt_buf_get_skb(rdlen + firstread + BRCMF_SDALIGN); if (!pkt) { /* Give up on data, request rtx of events */ - DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed: rdlen %d " - "chan %d\n", __func__, rdlen, chan)); - bus->dhd->rx_dropped++; - dhd_os_sdunlock_rxq(bus->dhd); - dhdsdio_rxfail(bus, false, RETRYCHAN(chan)); + BRCMF_ERROR(("%s: brcmu_pkt_buf_get_skb failed:" + " rdlen %d chan %d\n", __func__, rdlen, + chan)); + bus->drvr->rx_dropped++; + brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(chan)); continue; } - dhd_os_sdunlock_rxq(bus->dhd); - - ASSERT(!(pkt->prev)); /* Leave room for what we already read, and align remainder */ - ASSERT(firstread < pkt->len); skb_pull(pkt, firstread); - PKTALIGN(pkt, rdlen, DHD_SDALIGN); + PKTALIGN(pkt, rdlen, BRCMF_SDALIGN); /* Read the remaining frame data */ - sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, - F2SYNC, ((u8 *) (pkt->data)), rdlen, - pkt, NULL, NULL); + sdret = brcmf_sdcard_recv_buf(card, + brcmf_sdcard_cur_sbwad(card), + SDIO_FUNC_2, F2SYNC, ((u8 *) (pkt->data)), + rdlen, pkt, NULL, NULL); bus->f2rxdata++; - ASSERT(sdret != -BCME_PENDING); if (sdret < 0) { - DHD_ERROR(("%s: read %d %s bytes failed: %d\n", - __func__, rdlen, - ((chan == - SDPCM_EVENT_CHANNEL) ? "event" : ((chan == - SDPCM_DATA_CHANNEL) - ? "data" : "test")), - sdret)); - dhd_os_sdlock_rxq(bus->dhd); - bcm_pkt_buf_free_skb(pkt); - dhd_os_sdunlock_rxq(bus->dhd); - bus->dhd->rx_errors++; - dhdsdio_rxfail(bus, true, RETRYCHAN(chan)); + BRCMF_ERROR(("%s: read %d %s bytes failed: %d\n", + __func__, rdlen, + ((chan == SDPCM_EVENT_CHANNEL) ? "event" + : ((chan == SDPCM_DATA_CHANNEL) ? "data" + : "test")), sdret)); + brcmu_pkt_buf_free_skb(pkt); + bus->drvr->rx_errors++; + brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(chan)); continue; } @@ -4077,8 +4500,8 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) skb_push(pkt, firstread); memcpy(pkt->data, bus->rxhdr, firstread); -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { +#ifdef BCMDBG + if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { printk(KERN_DEBUG "Rx Data:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, pkt->data, len); @@ -4089,10 +4512,10 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) /* Save superframe descriptor and allocate packet frame */ if (chan == SDPCM_GLOM_CHANNEL) { if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { - DHD_GLOM(("%s: glom descriptor, %d bytes:\n", - __func__, len)); -#ifdef DHD_DEBUG - if (DHD_GLOM_ON()) { + BRCMF_GLOM(("%s: glom descriptor, %d bytes:\n", + __func__, len)); +#ifdef BCMDBG + if (BRCMF_GLOM_ON()) { printk(KERN_DEBUG "Glom Data:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -4100,13 +4523,12 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) } #endif __skb_trim(pkt, len); - ASSERT(doff == SDPCM_HDRLEN); skb_pull(pkt, SDPCM_HDRLEN); bus->glomd = pkt; } else { - DHD_ERROR(("%s: glom superframe w/o " - "descriptor!\n", __func__)); - dhdsdio_rxfail(bus, false, false); + BRCMF_ERROR(("%s: glom superframe w/o " + "descriptor!\n", __func__)); + brcmf_sdbrcm_rxfail(bus, false, false); } continue; } @@ -4118,39 +4540,35 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) #ifdef SDTEST /* Test channel packets are processed separately */ if (chan == SDPCM_TEST_CHANNEL) { - dhdsdio_testrcv(bus, pkt, seq); + brcmf_sdbrcm_checkdied(bus, pkt, seq); continue; } #endif /* SDTEST */ if (pkt->len == 0) { - dhd_os_sdlock_rxq(bus->dhd); - bcm_pkt_buf_free_skb(pkt); - dhd_os_sdunlock_rxq(bus->dhd); + brcmu_pkt_buf_free_skb(pkt); continue; - } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt) != 0) { - DHD_ERROR(("%s: rx protocol error\n", __func__)); - dhd_os_sdlock_rxq(bus->dhd); - bcm_pkt_buf_free_skb(pkt); - dhd_os_sdunlock_rxq(bus->dhd); - bus->dhd->rx_errors++; + } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx, pkt) != 0) { + BRCMF_ERROR(("%s: rx protocol error\n", __func__)); + brcmu_pkt_buf_free_skb(pkt); + bus->drvr->rx_errors++; continue; } /* Unlock during rx call */ - dhd_os_sdunlock(bus->dhd); - dhd_rx_frame(bus->dhd, ifidx, pkt, 1); - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); + brcmf_rx_frame(bus->drvr, ifidx, pkt, 1); + brcmf_sdbrcm_sdlock(bus); } rxcount = maxframes - rxleft; -#ifdef DHD_DEBUG +#ifdef BCMDBG /* Message if we hit the limit */ if (!rxleft && !sdtest) - DHD_DATA(("%s: hit rx limit of %d frames\n", __func__, - maxframes)); + BRCMF_DATA(("%s: hit rx limit of %d frames\n", __func__, + maxframes)); else -#endif /* DHD_DEBUG */ - DHD_DATA(("%s: processed %d frames\n", __func__, rxcount)); +#endif /* BCMDBG */ + BRCMF_DATA(("%s: processed %d frames\n", __func__, rxcount)); /* Back off rxseq if awaiting rtx, update rx_seq */ if (bus->rxskip) rxseq--; @@ -4159,28 +4577,30 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) return rxcount; } -static u32 dhdsdio_hostmail(dhd_bus_t *bus) +static u32 brcmf_sdbrcm_hostmail(struct brcmf_bus *bus) { - sdpcmd_regs_t *regs = bus->regs; u32 intstatus = 0; u32 hmb_data; u8 fcbits; uint retries = 0; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); /* Read mailbox data and ack that we did so */ - R_SDREG(hmb_data, ®s->tohostmailboxdata, retries); + r_sdreg32(bus, &hmb_data, + offsetof(struct sdpcmd_regs, tohostmailboxdata), &retries); + if (retries <= retry_limit) - W_SDREG(SMB_INT_ACK, ®s->tosbmailbox, retries); + w_sdreg32(bus, SMB_INT_ACK, + offsetof(struct sdpcmd_regs, tosbmailbox), &retries); bus->f1regdata += 2; /* Dongle recomposed rx frames, accept them again */ if (hmb_data & HMB_DATA_NAKHANDLED) { - DHD_INFO(("Dongle reports NAK handled, expect rtx of %d\n", - bus->rx_seq)); + BRCMF_INFO(("Dongle reports NAK handled, expect rtx of %d\n", + bus->rx_seq)); if (!bus->rxskip) - DHD_ERROR(("%s: unexpected NAKHANDLED!\n", __func__)); + BRCMF_ERROR(("%s: unexpected NAKHANDLED!\n", __func__)); bus->rxskip = false; intstatus |= I_HMB_FRAME_IND; @@ -4194,12 +4614,12 @@ static u32 dhdsdio_hostmail(dhd_bus_t *bus) (hmb_data & HMB_DATA_VERSION_MASK) >> HMB_DATA_VERSION_SHIFT; if (bus->sdpcm_ver != SDPCM_PROT_VERSION) - DHD_ERROR(("Version mismatch, dongle reports %d, " - "expecting %d\n", - bus->sdpcm_ver, SDPCM_PROT_VERSION)); + BRCMF_ERROR(("Version mismatch, dongle reports %d, " + "expecting %d\n", + bus->sdpcm_ver, SDPCM_PROT_VERSION)); else - DHD_INFO(("Dongle ready, protocol version %d\n", - bus->sdpcm_ver)); + BRCMF_INFO(("Dongle ready, protocol version %d\n", + bus->sdpcm_ver)); } /* @@ -4227,78 +4647,74 @@ static u32 dhdsdio_hostmail(dhd_bus_t *bus) HMB_DATA_FC | HMB_DATA_FWREADY | HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) { - DHD_ERROR(("Unknown mailbox data content: 0x%02x\n", hmb_data)); + BRCMF_ERROR(("Unknown mailbox data content: 0x%02x\n", + hmb_data)); } return intstatus; } -bool dhdsdio_dpc(dhd_bus_t *bus) +static bool brcmf_sdbrcm_dpc(struct brcmf_bus *bus) { - bcmsdh_info_t *sdh = bus->sdh; - sdpcmd_regs_t *regs = bus->regs; + struct brcmf_sdio_card *card = bus->card; u32 intstatus, newstatus = 0; uint retries = 0; - uint rxlimit = dhd_rxbound; /* Rx frames to read before resched */ - uint txlimit = dhd_txbound; /* Tx frames to send before resched */ + uint rxlimit = brcmf_rxbound; /* Rx frames to read before resched */ + uint txlimit = brcmf_txbound; /* Tx frames to send before resched */ uint framecnt = 0; /* Temporary counter of tx/rx frames */ bool rxdone = true; /* Flag for no more read data */ bool resched = false; /* Flag indicating resched wanted */ - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); /* Start with leftover status bits */ intstatus = bus->intstatus; - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdlock(bus); /* If waiting for HTAVAIL, check status */ if (bus->clkstate == CLK_PENDING) { int err; u8 clkctl, devctl = 0; -#ifdef DHD_DEBUG +#ifdef BCMDBG /* Check for inconsistent device control */ - devctl = - bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); + devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, &err); if (err) { - DHD_ERROR(("%s: error reading DEVCTL: %d\n", - __func__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; - } else { - ASSERT(devctl & SBSDIO_DEVCTL_CA_INT_ONLY); + BRCMF_ERROR(("%s: error reading DEVCTL: %d\n", + __func__, err)); + bus->drvr->busstate = BRCMF_BUS_DOWN; } -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ /* Read CSR, if clock on switch to AVAIL, else ignore */ - clkctl = - bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - &err); + clkctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err) { - DHD_ERROR(("%s: error reading CSR: %d\n", __func__, - err)); - bus->dhd->busstate = DHD_BUS_DOWN; + BRCMF_ERROR(("%s: error reading CSR: %d\n", __func__, + err)); + bus->drvr->busstate = BRCMF_BUS_DOWN; } - DHD_INFO(("DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", devctl, - clkctl)); + BRCMF_INFO(("DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", + devctl, clkctl)); if (SBSDIO_HTAV(clkctl)) { - devctl = - bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - &err); + devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, &err); if (err) { - DHD_ERROR(("%s: error reading DEVCTL: %d\n", - __func__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; + BRCMF_ERROR(("%s: error reading DEVCTL: %d\n", + __func__, err)); + bus->drvr->busstate = BRCMF_BUS_DOWN; } devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + SBSDIO_DEVICE_CTL, devctl, &err); if (err) { - DHD_ERROR(("%s: error writing DEVCTL: %d\n", - __func__, err)); - bus->dhd->busstate = DHD_BUS_DOWN; + BRCMF_ERROR(("%s: error writing DEVCTL: %d\n", + __func__, err)); + bus->drvr->busstate = BRCMF_BUS_DOWN; } bus->clkstate = CLK_AVAIL; } else { @@ -4309,21 +4725,24 @@ bool dhdsdio_dpc(dhd_bus_t *bus) BUS_WAKE(bus); /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, true); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true); if (bus->clkstate == CLK_PENDING) goto clkwait; /* Pending interrupt indicates new device status */ if (bus->ipend) { bus->ipend = false; - R_SDREG(newstatus, ®s->intstatus, retries); + r_sdreg32(bus, &newstatus, + offsetof(struct sdpcmd_regs, intstatus), &retries); bus->f1regdata++; - if (bcmsdh_regfail(bus->sdh)) + if (brcmf_sdcard_regfail(bus->card)) newstatus = 0; newstatus &= bus->hostintmask; bus->fcstate = !!(newstatus & I_HMB_FC_STATE); if (newstatus) { - W_SDREG(newstatus, ®s->intstatus, retries); + w_sdreg32(bus, newstatus, + offsetof(struct sdpcmd_regs, intstatus), + &retries); bus->f1regdata++; } } @@ -4338,8 +4757,11 @@ bool dhdsdio_dpc(dhd_bus_t *bus) */ if (intstatus & I_HMB_FC_CHANGE) { intstatus &= ~I_HMB_FC_CHANGE; - W_SDREG(I_HMB_FC_CHANGE, ®s->intstatus, retries); - R_SDREG(newstatus, ®s->intstatus, retries); + w_sdreg32(bus, I_HMB_FC_CHANGE, + offsetof(struct sdpcmd_regs, intstatus), &retries); + + r_sdreg32(bus, &newstatus, + offsetof(struct sdpcmd_regs, intstatus), &retries); bus->f1regdata += 2; bus->fcstate = !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); @@ -4349,28 +4771,28 @@ bool dhdsdio_dpc(dhd_bus_t *bus) /* Handle host mailbox indication */ if (intstatus & I_HMB_HOST_INT) { intstatus &= ~I_HMB_HOST_INT; - intstatus |= dhdsdio_hostmail(bus); + intstatus |= brcmf_sdbrcm_hostmail(bus); } /* Generally don't ask for these, can get CRC errors... */ if (intstatus & I_WR_OOSYNC) { - DHD_ERROR(("Dongle reports WR_OOSYNC\n")); + BRCMF_ERROR(("Dongle reports WR_OOSYNC\n")); intstatus &= ~I_WR_OOSYNC; } if (intstatus & I_RD_OOSYNC) { - DHD_ERROR(("Dongle reports RD_OOSYNC\n")); + BRCMF_ERROR(("Dongle reports RD_OOSYNC\n")); intstatus &= ~I_RD_OOSYNC; } if (intstatus & I_SBINT) { - DHD_ERROR(("Dongle reports SBINT\n")); + BRCMF_ERROR(("Dongle reports SBINT\n")); intstatus &= ~I_SBINT; } /* Would be active due to wake-wlan in gSPI */ if (intstatus & I_CHIPACTIVE) { - DHD_INFO(("Dongle reports CHIPACTIVE\n")); + BRCMF_INFO(("Dongle reports CHIPACTIVE\n")); intstatus &= ~I_CHIPACTIVE; } @@ -4380,7 +4802,7 @@ bool dhdsdio_dpc(dhd_bus_t *bus) /* On frame indication, read available frames */ if (PKT_AVAILABLE()) { - framecnt = dhdsdio_readframes(bus, rxlimit, &rxdone); + framecnt = brcmf_sdbrcm_readframes(bus, rxlimit, &rxdone); if (rxdone || bus->rxskip) intstatus &= ~I_HMB_FRAME_IND; rxlimit -= min(framecnt, rxlimit); @@ -4390,51 +4812,45 @@ bool dhdsdio_dpc(dhd_bus_t *bus) bus->intstatus = intstatus; clkwait: -#if defined(OOB_INTR_ONLY) - bcmsdh_oob_intr_set(1); -#endif /* (OOB_INTR_ONLY) */ /* Re-enable interrupts to detect new device events (mailbox, rx frame) * or clock availability. (Allows tx loop to check ipend if desired.) * (Unless register access seems hosed, as we may not be able to ACK...) */ - if (bus->intr && bus->intdis && !bcmsdh_regfail(sdh)) { - DHD_INTR(("%s: enable SDIO interrupts, rxdone %d framecnt %d\n", - __func__, rxdone, framecnt)); + if (bus->intr && bus->intdis && !brcmf_sdcard_regfail(card)) { + BRCMF_INTR(("%s: enable SDIO interrupts, rxdone %d" + " framecnt %d\n", __func__, rxdone, framecnt)); bus->intdis = false; - bcmsdh_intr_enable(sdh); + brcmf_sdcard_intr_enable(card); } if (DATAOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) { int ret, i; - ret = - dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, - F2SYNC, (u8 *) bus->ctrl_frame_buf, - (u32) bus->ctrl_frame_len, NULL, - NULL, NULL); - ASSERT(ret != -BCME_PENDING); + ret = brcmf_sdbrcm_send_buf(bus, brcmf_sdcard_cur_sbwad(card), + SDIO_FUNC_2, F2SYNC, (u8 *) bus->ctrl_frame_buf, + (u32) bus->ctrl_frame_len, NULL, NULL, NULL); if (ret < 0) { /* On failure, abort the command and terminate the frame */ - DHD_INFO(("%s: sdio error %d, abort command and " - "terminate frame.\n", __func__, ret)); + BRCMF_INFO(("%s: sdio error %d, abort command and " + "terminate frame.\n", __func__, ret)); bus->tx_sderrs++; - bcmsdh_abort(sdh, SDIO_FUNC_2); + brcmf_sdcard_abort(card, SDIO_FUNC_2); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); bus->f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; - hi = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, + hi = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, + lo = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, SBSDIO_FUNC1_WFRAMEBCLO, NULL); bus->f1regdata += 2; @@ -4446,16 +4862,16 @@ bool dhdsdio_dpc(dhd_bus_t *bus) if (ret == 0) bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - DHD_INFO(("Return_dpc value is : %d\n", ret)); + BRCMF_INFO(("Return_dpc value is : %d\n", ret)); bus->ctrl_frame_stat = false; - dhd_wait_event_wakeup(bus->dhd); + brcmf_sdbrcm_wait_event_wakeup(bus); } /* Send queued frames (limit 1 if rx may still be pending) */ else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate && - bcm_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit + brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit && DATAOK(bus)) { - framecnt = rxdone ? txlimit : min(txlimit, dhd_txminmax); - framecnt = dhdsdio_sendfromq(bus, framecnt); + framecnt = rxdone ? txlimit : min(txlimit, brcmf_txminmax); + framecnt = brcmf_sdbrcm_sendfromq(bus, framecnt); txlimit -= framecnt; } @@ -4463,18 +4879,20 @@ bool dhdsdio_dpc(dhd_bus_t *bus) else await next interrupt */ /* On failed register access, all bets are off: no resched or interrupts */ - if ((bus->dhd->busstate == DHD_BUS_DOWN) || bcmsdh_regfail(sdh)) { - DHD_ERROR(("%s: failed backplane access over SDIO, halting " - "operation %d\n", __func__, bcmsdh_regfail(sdh))); - bus->dhd->busstate = DHD_BUS_DOWN; + if ((bus->drvr->busstate == BRCMF_BUS_DOWN) || + brcmf_sdcard_regfail(card)) { + BRCMF_ERROR(("%s: failed backplane access over SDIO, halting " + "operation %d\n", __func__, + brcmf_sdcard_regfail(card))); + bus->drvr->busstate = BRCMF_BUS_DOWN; bus->intstatus = 0; } else if (bus->clkstate == CLK_PENDING) { - DHD_INFO(("%s: rescheduled due to CLK_PENDING awaiting " - "I_CHIPACTIVE interrupt\n", __func__)); + BRCMF_INFO(("%s: rescheduled due to CLK_PENDING awaiting " + "I_CHIPACTIVE interrupt\n", __func__)); resched = true; } else if (bus->intstatus || bus->ipend || - (!bus->fcstate && bcm_pktq_mlen(&bus->txq, ~bus->flowcontrol) && - DATAOK(bus)) || PKT_AVAILABLE()) { + (!bus->fcstate && brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) + && DATAOK(bus)) || PKT_AVAILABLE()) { resched = true; } @@ -4482,42 +4900,31 @@ bool dhdsdio_dpc(dhd_bus_t *bus) /* If we're done for now, turn off clock request. */ if ((bus->clkstate != CLK_PENDING) - && bus->idletime == DHD_IDLE_IMMEDIATE) { + && bus->idletime == BRCMF_IDLE_IMMEDIATE) { bus->activity = false; - dhdsdio_clkctl(bus, CLK_NONE, false); + brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); } - dhd_os_sdunlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); return resched; } -bool dhd_bus_dpc(struct dhd_bus *bus) +void brcmf_sdbrcm_isr(void *arg) { - bool resched; + struct brcmf_bus *bus = (struct brcmf_bus *) arg; + struct brcmf_sdio_card *card; - /* Call the DPC directly. */ - DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __func__)); - resched = dhdsdio_dpc(bus); - - return resched; -} - -void dhdsdio_isr(void *arg) -{ - dhd_bus_t *bus = (dhd_bus_t *) arg; - bcmsdh_info_t *sdh; - - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); if (!bus) { - DHD_ERROR(("%s : bus is null pointer , exit\n", __func__)); + BRCMF_ERROR(("%s : bus is null pointer , exit\n", __func__)); return; } - sdh = bus->sdh; + card = bus->card; - if (bus->dhd->busstate == DHD_BUS_DOWN) { - DHD_ERROR(("%s : bus is down. we have nothing to do\n", + if (bus->drvr->busstate == BRCMF_BUS_DOWN) { + BRCMF_ERROR(("%s : bus is down. we have nothing to do\n", __func__)); return; } @@ -4527,54 +4934,55 @@ void dhdsdio_isr(void *arg) /* Shouldn't get this interrupt if we're sleeping? */ if (bus->sleeping) { - DHD_ERROR(("INTERRUPT WHILE SLEEPING??\n")); + BRCMF_ERROR(("INTERRUPT WHILE SLEEPING??\n")); return; } /* Disable additional interrupts (is this needed now)? */ if (bus->intr) - DHD_INTR(("%s: disable SDIO interrupts\n", __func__)); + BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__)); else - DHD_ERROR(("dhdsdio_isr() w/o interrupt configured!\n")); + BRCMF_ERROR(("brcmf_sdbrcm_isr() w/o interrupt configured!\n")); - bcmsdh_intr_disable(sdh); + brcmf_sdcard_intr_disable(card); bus->intdis = true; #if defined(SDIO_ISR_THREAD) - DHD_TRACE(("Calling dhdsdio_dpc() from %s\n", __func__)); - while (dhdsdio_dpc(bus)) + BRCMF_TRACE(("Calling brcmf_sdbrcm_dpc() from %s\n", __func__)); + while (brcmf_sdbrcm_dpc(bus)) ; #else bus->dpc_sched = true; - dhd_sched_dpc(bus->dhd); + brcmf_sdbrcm_sched_dpc(bus); #endif } #ifdef SDTEST -static void dhdsdio_pktgen_init(dhd_bus_t *bus) +static void brcmf_sdbrcm_pktgen_init(struct brcmf_bus *bus) { /* Default to specified length, or full range */ - if (dhd_pktgen_len) { - bus->pktgen_maxlen = min(dhd_pktgen_len, MAX_PKTGEN_LEN); + if (brcmf_pktgen_len) { + bus->pktgen_maxlen = min(brcmf_pktgen_len, + BRCMF_MAX_PKTGEN_LEN); bus->pktgen_minlen = bus->pktgen_maxlen; } else { - bus->pktgen_maxlen = MAX_PKTGEN_LEN; + bus->pktgen_maxlen = BRCMF_MAX_PKTGEN_LEN; bus->pktgen_minlen = 0; } bus->pktgen_len = (u16) bus->pktgen_minlen; /* Default to per-watchdog burst with 10s print time */ bus->pktgen_freq = 1; - bus->pktgen_print = 10000 / dhd_watchdog_ms; - bus->pktgen_count = (dhd_pktgen * dhd_watchdog_ms + 999) / 1000; + bus->pktgen_print = 10000 / brcmf_watchdog_ms; + bus->pktgen_count = (brcmf_pktgen * brcmf_watchdog_ms + 999) / 1000; /* Default to echo mode */ - bus->pktgen_mode = DHD_PKTGEN_ECHO; + bus->pktgen_mode = BRCMF_PKTGEN_ECHO; bus->pktgen_stop = 1; } -static void dhdsdio_pktgen(dhd_bus_t *bus) +static void brcmf_sdbrcm_pktgen(struct brcmf_bus *bus) { struct sk_buff *pkt; u8 *data; @@ -4590,9 +4998,9 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) } /* For recv mode, just make sure dongle has started sending */ - if (bus->pktgen_mode == DHD_PKTGEN_RECV) { + if (bus->pktgen_mode == BRCMF_PKTGEN_RECV) { if (!bus->pktgen_rcvd) - dhdsdio_sdtest_set(bus, true); + brcmf_sdbrcm_sdtest_set(bus, true); return; } @@ -4607,39 +5015,39 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) /* Allocate an appropriate-sized packet */ len = bus->pktgen_len; - pkt = bcm_pkt_buf_get_skb( - (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN), + pkt = brcmu_pkt_buf_get_skb( + len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + BRCMF_SDALIGN, true); if (!pkt) { - DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed!\n", - __func__)); + BRCMF_ERROR(("%s: brcmu_pkt_buf_get_skb failed!\n", + __func__)); break; } PKTALIGN(pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), - DHD_SDALIGN); + BRCMF_SDALIGN); data = (u8 *) (pkt->data) + SDPCM_HDRLEN; /* Write test header cmd and extra based on mode */ switch (bus->pktgen_mode) { - case DHD_PKTGEN_ECHO: + case BRCMF_PKTGEN_ECHO: *data++ = SDPCM_TEST_ECHOREQ; *data++ = (u8) bus->pktgen_sent; break; - case DHD_PKTGEN_SEND: + case BRCMF_PKTGEN_SEND: *data++ = SDPCM_TEST_DISCARD; *data++ = (u8) bus->pktgen_sent; break; - case DHD_PKTGEN_RXBURST: + case BRCMF_PKTGEN_RXBURST: *data++ = SDPCM_TEST_BURST; *data++ = (u8) bus->pktgen_count; break; default: - DHD_ERROR(("Unrecognized pktgen mode %d\n", - bus->pktgen_mode)); - bcm_pkt_buf_free_skb(pkt, true); + BRCMF_ERROR(("Unrecognized pktgen mode %d\n", + bus->pktgen_mode)); + brcmu_pkt_buf_free_skb(pkt, true); bus->pktgen_count = 0; return; } @@ -4654,17 +5062,17 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) *data++ = SDPCM_TEST_FILL(fillbyte, (u8) bus->pktgen_sent); -#ifdef DHD_DEBUG - if (DHD_BYTES_ON() && DHD_DATA_ON()) { +#ifdef BCMDBG + if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { data = (u8 *) (pkt->data) + SDPCM_HDRLEN; - printk(KERN_DEBUG "dhdsdio_pktgen: Tx Data:\n"); + printk(KERN_DEBUG "brcmf_sdbrcm_pktgen: Tx Data:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data, pkt->len - SDPCM_HDRLEN); } #endif /* Send it */ - if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true)) { + if (brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true)) { bus->pktgen_fail++; if (bus->pktgen_stop && bus->pktgen_stop == bus->pktgen_fail) @@ -4677,24 +5085,24 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) bus->pktgen_len = (u16) bus->pktgen_minlen; /* Special case for burst mode: just send one request! */ - if (bus->pktgen_mode == DHD_PKTGEN_RXBURST) + if (bus->pktgen_mode == BRCMF_PKTGEN_RXBURST) break; } } -static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) +static void brcmf_sdbrcm_sdtest_set(struct brcmf_bus *bus, bool start) { struct sk_buff *pkt; u8 *data; /* Allocate the packet */ - pkt = bcm_pkt_buf_get_skb(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + - DHD_SDALIGN, true); + pkt = brcmu_pkt_buf_get_skb(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + + BRCMF_SDALIGN, true); if (!pkt) { - DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed!\n", __func__)); + BRCMF_ERROR(("%s: brcmu_pkt_buf_get_skb failed!\n", __func__)); return; } - PKTALIGN(pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); + PKTALIGN(pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), BRCMF_SDALIGN); data = (u8 *) (pkt->data) + SDPCM_HDRLEN; /* Fill in the test header */ @@ -4704,11 +5112,12 @@ static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) *data++ = (bus->pktgen_maxlen >> 8); /* Send it */ - if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true)) + if (brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true)) bus->pktgen_fail++; } -static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) +static void +brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, struct sk_buff *pkt, uint seq) { u8 *data; uint pktlen; @@ -4721,9 +5130,9 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) /* Check for min length */ pktlen = pkt->len; if (pktlen < SDPCM_TEST_HDRLEN) { - DHD_ERROR(("dhdsdio_restrcv: toss runt frame, pktlen %d\n", - pktlen)); - bcm_pkt_buf_free_skb(pkt, false); + BRCMF_ERROR(("brcmf_sdbrcm_checkdied: toss runt frame, pktlen " + "%d\n", pktlen)); + brcmu_pkt_buf_free_skb(pkt, false); return; } @@ -4738,10 +5147,11 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) if (cmd == SDPCM_TEST_DISCARD || cmd == SDPCM_TEST_ECHOREQ || cmd == SDPCM_TEST_ECHORSP) { if (pktlen != len + SDPCM_TEST_HDRLEN) { - DHD_ERROR(("dhdsdio_testrcv: frame length mismatch, " - "pktlen %d seq %d" " cmd %d extra %d len %d\n", - pktlen, seq, cmd, extra, len)); - bcm_pkt_buf_free_skb(pkt, false); + BRCMF_ERROR(("brcmf_sdbrcm_checkdied: frame length " + "mismatch, pktlen %d seq %d" + " cmd %d extra %d len %d\n", + pktlen, seq, cmd, extra, len)); + brcmu_pkt_buf_free_skb(pkt, false); return; } } @@ -4752,76 +5162,80 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) /* Rx->Tx turnaround ok (even on NDIS w/current implementation) */ *(u8 *) (pkt->data) = SDPCM_TEST_ECHORSP; - if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true) == 0) { + if (brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true) == 0) bus->pktgen_sent++; - } else { + else { bus->pktgen_fail++; - bcm_pkt_buf_free_skb(pkt, false); + brcmu_pkt_buf_free_skb(pkt, false); } bus->pktgen_rcvd++; break; case SDPCM_TEST_ECHORSP: if (bus->ext_loop) { - bcm_pkt_buf_free_skb(pkt, false); + brcmu_pkt_buf_free_skb(pkt, false); bus->pktgen_rcvd++; break; } for (offset = 0; offset < len; offset++, data++) { if (*data != SDPCM_TEST_FILL(offset, extra)) { - DHD_ERROR(("dhdsdio_testrcv: echo data mismatch: " "offset %d (len %d) expect 0x%02x rcvd 0x%02x\n", - offset, len, - SDPCM_TEST_FILL(offset, extra), *data)); + BRCMF_ERROR(("brcmf_sdbrcm_checkdied: echo" + " data mismatch: " + "offset %d (len %d) " + "expect 0x%02x rcvd 0x%02x\n", + offset, len, + SDPCM_TEST_FILL(offset, extra), + *data)); break; } } - bcm_pkt_buf_free_skb(pkt, false); + brcmu_pkt_buf_free_skb(pkt, false); bus->pktgen_rcvd++; break; case SDPCM_TEST_DISCARD: - bcm_pkt_buf_free_skb(pkt, false); + brcmu_pkt_buf_free_skb(pkt, false); bus->pktgen_rcvd++; break; case SDPCM_TEST_BURST: case SDPCM_TEST_SEND: default: - DHD_INFO(("dhdsdio_testrcv: unsupported or unknown command, " - "pktlen %d seq %d" " cmd %d extra %d len %d\n", - pktlen, seq, cmd, extra, len)); - bcm_pkt_buf_free_skb(pkt, false); + BRCMF_INFO(("brcmf_sdbrcm_checkdied: unsupported or unknown " + "command, pktlen %d seq %d" " cmd %d extra %d" + " len %d\n", pktlen, seq, cmd, extra, len)); + brcmu_pkt_buf_free_skb(pkt, false); break; } /* For recv mode, stop at limie (and tell dongle to stop sending) */ - if (bus->pktgen_mode == DHD_PKTGEN_RECV) { + if (bus->pktgen_mode == BRCMF_PKTGEN_RECV) { if (bus->pktgen_total && (bus->pktgen_rcvd >= bus->pktgen_total)) { bus->pktgen_count = 0; - dhdsdio_sdtest_set(bus, false); + brcmf_sdbrcm_sdtest_set(bus, false); } } } #endif /* SDTEST */ -extern bool dhd_bus_watchdog(dhd_pub_t *dhdp) +extern bool brcmf_sdbrcm_bus_watchdog(struct brcmf_pub *drvr) { - dhd_bus_t *bus; + struct brcmf_bus *bus; - DHD_TIMER(("%s: Enter\n", __func__)); + BRCMF_TIMER(("%s: Enter\n", __func__)); - bus = dhdp->bus; + bus = drvr->bus; - if (bus->dhd->dongle_reset) + if (bus->drvr->dongle_reset) return false; /* Ignore the timer if simulating bus down */ if (bus->sleeping) return false; - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdlock(bus); /* Poll period: check device if appropriate. */ if (bus->poll && (++bus->polltick >= bus->pollrate)) { @@ -4835,9 +5249,9 @@ extern bool dhd_bus_watchdog(dhd_pub_t *dhdp) if (!bus->dpc_sched) { u8 devpend; - devpend = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, - SDIOD_CCCR_INTPEND, - NULL); + devpend = brcmf_sdcard_cfg_read(bus->card, + SDIO_FUNC_0, SDIO_CCCR_INTx, + NULL); intstatus = devpend & (INTR_STATUS_FUNC1 | INTR_STATUS_FUNC2); @@ -4849,10 +5263,10 @@ extern bool dhd_bus_watchdog(dhd_pub_t *dhdp) bus->pollcnt++; bus->ipend = true; if (bus->intr) - bcmsdh_intr_disable(bus->sdh); + brcmf_sdcard_intr_disable(bus->card); bus->dpc_sched = true; - dhd_sched_dpc(bus->dhd); + brcmf_sdbrcm_sched_dpc(bus); } } @@ -4860,28 +5274,28 @@ extern bool dhd_bus_watchdog(dhd_pub_t *dhdp) /* Update interrupt tracking */ bus->lastintrs = bus->intrcount; } -#ifdef DHD_DEBUG +#ifdef BCMDBG /* Poll for console output periodically */ - if (dhdp->busstate == DHD_BUS_DATA && dhd_console_ms != 0) { - bus->console.count += dhd_watchdog_ms; - if (bus->console.count >= dhd_console_ms) { - bus->console.count -= dhd_console_ms; + if (drvr->busstate == BRCMF_BUS_DATA && brcmf_console_ms != 0) { + bus->console.count += brcmf_watchdog_ms; + if (bus->console.count >= brcmf_console_ms) { + bus->console.count -= brcmf_console_ms; /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, false); - if (dhdsdio_readconsole(bus) < 0) - dhd_console_ms = 0; /* On error, + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); + if (brcmf_sdbrcm_readconsole(bus) < 0) + brcmf_console_ms = 0; /* On error, stop trying */ } } -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ #ifdef SDTEST /* Generate packets if configured */ if (bus->pktgen_count && (++bus->pktgen_tick >= bus->pktgen_freq)) { /* Make sure backplane clock is on */ - dhdsdio_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); bus->pktgen_tick = 0; - dhdsdio_pktgen(bus); + brcmf_sdbrcm_pktgen(bus); } #endif @@ -4891,22 +5305,23 @@ extern bool dhd_bus_watchdog(dhd_pub_t *dhdp) bus->idlecount = 0; if (bus->activity) { bus->activity = false; - dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); + brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms); } else { - dhdsdio_clkctl(bus, CLK_NONE, false); + brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); } } } - dhd_os_sdunlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); return bus->ipend; } -#ifdef DHD_DEBUG -extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen) +#ifdef BCMDBG +static int brcmf_sdbrcm_bus_console_in(struct brcmf_pub *drvr, + unsigned char *msg, uint msglen) { - dhd_bus_t *bus = dhdp->bus; + struct brcmf_bus *bus = drvr->bus; u32 addr, val; int rv; struct sk_buff *pkt; @@ -4916,88 +5331,59 @@ extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen) return -ENOTSUPP; /* Exclusive bus access */ - dhd_os_sdlock(bus->dhd); + brcmf_sdbrcm_sdlock(bus); /* Don't allow input if dongle is in reset */ - if (bus->dhd->dongle_reset) { - dhd_os_sdunlock(bus->dhd); + if (bus->drvr->dongle_reset) { + brcmf_sdbrcm_sdunlock(bus); return -EPERM; } /* Request clock to allow SDIO accesses */ BUS_WAKE(bus); /* No pend allowed since txpkt is called later, ht clk has to be on */ - dhdsdio_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); /* Zero cbuf_index */ - addr = bus->console_addr + offsetof(hndrte_cons_t, cbuf_idx); + addr = bus->console_addr + offsetof(struct rte_console, cbuf_idx); val = cpu_to_le32(0); - rv = dhdsdio_membytes(bus, true, addr, (u8 *)&val, sizeof(val)); + rv = brcmf_sdbrcm_membytes(bus, true, addr, (u8 *)&val, sizeof(val)); if (rv < 0) goto done; /* Write message into cbuf */ - addr = bus->console_addr + offsetof(hndrte_cons_t, cbuf); - rv = dhdsdio_membytes(bus, true, addr, (u8 *)msg, msglen); + addr = bus->console_addr + offsetof(struct rte_console, cbuf); + rv = brcmf_sdbrcm_membytes(bus, true, addr, (u8 *)msg, msglen); if (rv < 0) goto done; /* Write length into vcons_in */ - addr = bus->console_addr + offsetof(hndrte_cons_t, vcons_in); + addr = bus->console_addr + offsetof(struct rte_console, vcons_in); val = cpu_to_le32(msglen); - rv = dhdsdio_membytes(bus, true, addr, (u8 *)&val, sizeof(val)); + rv = brcmf_sdbrcm_membytes(bus, true, addr, (u8 *)&val, sizeof(val)); if (rv < 0) goto done; /* Bump dongle by sending an empty event pkt. * sdpcm_sendup (RX) checks for virtual console input. */ - pkt = bcm_pkt_buf_get_skb(4 + SDPCM_RESERVE); + pkt = brcmu_pkt_buf_get_skb(4 + SDPCM_RESERVE); if ((pkt != NULL) && bus->clkstate == CLK_AVAIL) - dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, true); + brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, true); done: - if ((bus->idletime == DHD_IDLE_IMMEDIATE) && !bus->dpc_sched) { + if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) { bus->activity = false; - dhdsdio_clkctl(bus, CLK_NONE, true); + brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); } - dhd_os_sdunlock(bus->dhd); + brcmf_sdbrcm_sdunlock(bus); return rv; } -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ -#ifdef DHD_DEBUG -static void dhd_dump_cis(uint fn, u8 *cis) -{ - uint byte, tag, tdata; - DHD_INFO(("Function %d CIS:\n", fn)); - - for (tdata = byte = 0; byte < SBSDIO_CIS_SIZE_LIMIT; byte++) { - if ((byte % 16) == 0) - DHD_INFO((" ")); - DHD_INFO(("%02x ", cis[byte])); - if ((byte % 16) == 15) - DHD_INFO(("\n")); - if (!tdata--) { - tag = cis[byte]; - if (tag == 0xff) - break; - else if (!tag) - tdata = 0; - else if ((byte + 1) < SBSDIO_CIS_SIZE_LIMIT) - tdata = cis[byte + 1] + 1; - else - DHD_INFO(("]")); - } - } - if ((byte % 16) != 15) - DHD_INFO(("\n")); -} -#endif /* DHD_DEBUG */ - -static bool dhdsdio_chipmatch(u16 chipid) +static bool brcmf_sdbrcm_chipmatch(u16 chipid) { if (chipid == BCM4325_CHIP_ID) return true; @@ -5008,12 +5394,12 @@ static bool dhdsdio_chipmatch(u16 chipid) return false; } -static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, - u16 slot, u16 func, uint bustype, void *regsva, - void *sdh) +static void *brcmf_sdbrcm_probe(u16 venid, u16 devid, u16 bus_no, + u16 slot, u16 func, uint bustype, u32 regsva, + void *card) { int ret; - dhd_bus_t *bus; + struct brcmf_bus *bus; /* Init global variables at run-time, not as part of the declaration. * This is required to support init/de-init of the driver. @@ -5023,26 +5409,26 @@ static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, * first time that the driver is initialized vs subsequent * initializations. */ - dhd_txbound = DHD_TXBOUND; - dhd_rxbound = DHD_RXBOUND; - dhd_alignctl = true; + brcmf_txbound = BRCMF_TXBOUND; + brcmf_rxbound = BRCMF_RXBOUND; + brcmf_alignctl = true; sd1idle = true; - dhd_readahead = true; + brcmf_readahead = true; retrydata = false; - dhd_dongle_memsize = 0; - dhd_txminmax = DHD_TXMINMAX; + brcmf_dongle_memsize = 0; + brcmf_txminmax = BRCMF_TXMINMAX; forcealign = true; - dhd_common_init(); + brcmf_c_init(); - DHD_TRACE(("%s: Enter\n", __func__)); - DHD_INFO(("%s: venid 0x%04x devid 0x%04x\n", __func__, venid, devid)); + BRCMF_TRACE(("%s: Enter\n", __func__)); + BRCMF_INFO(("%s: venid 0x%04x devid 0x%04x\n", __func__, venid, devid)); - /* We make assumptions about address window mappings */ - ASSERT((unsigned long)regsva == SI_ENUM_BASE); + /* We make an assumption about address window mappings: + * regsva == SI_ENUM_BASE*/ - /* BCMSDH passes venid and devid based on CIS parsing -- but + /* SDIO car passes venid and devid based on CIS parsing -- but * low-power start * means early parse could fail, so here we should get either an ID * we recognize OR (-1) indicating we must request power first. @@ -5053,7 +5439,7 @@ static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, case PCI_VENDOR_ID_BROADCOM: break; default: - DHD_ERROR(("%s: unknown vendor: 0x%04x\n", __func__, venid)); + BRCMF_ERROR(("%s: unknown vendor: 0x%04x\n", __func__, venid)); return NULL; } @@ -5062,104 +5448,156 @@ static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, case BCM4325_D11DUAL_ID: /* 4325 802.11a/g id */ case BCM4325_D11G_ID: /* 4325 802.11g 2.4Ghz band id */ case BCM4325_D11A_ID: /* 4325 802.11a 5Ghz band id */ - DHD_INFO(("%s: found 4325 Dongle\n", __func__)); + BRCMF_INFO(("%s: found 4325 Dongle\n", __func__)); break; case BCM4329_D11NDUAL_ID: /* 4329 802.11n dualband device */ case BCM4329_D11N2G_ID: /* 4329 802.11n 2.4G device */ case BCM4329_D11N5G_ID: /* 4329 802.11n 5G device */ case 0x4329: - DHD_INFO(("%s: found 4329 Dongle\n", __func__)); + BRCMF_INFO(("%s: found 4329 Dongle\n", __func__)); break; case BCM4319_D11N_ID: /* 4319 802.11n id */ case BCM4319_D11N2G_ID: /* 4319 802.11n2g id */ case BCM4319_D11N5G_ID: /* 4319 802.11n5g id */ - DHD_INFO(("%s: found 4319 Dongle\n", __func__)); + BRCMF_INFO(("%s: found 4319 Dongle\n", __func__)); break; case 0: - DHD_INFO(("%s: allow device id 0, will check chip internals\n", - __func__)); + BRCMF_INFO(("%s: allow device id 0, will check chip" + " internals\n", __func__)); break; default: - DHD_ERROR(("%s: skipping 0x%04x/0x%04x, not a dongle\n", - __func__, venid, devid)); + BRCMF_ERROR(("%s: skipping 0x%04x/0x%04x, not a dongle\n", + __func__, venid, devid)); return NULL; } /* Allocate private bus interface state */ - bus = kzalloc(sizeof(dhd_bus_t), GFP_ATOMIC); + bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC); if (!bus) { - DHD_ERROR(("%s: kmalloc of dhd_bus_t failed\n", __func__)); + BRCMF_ERROR(("%s: kmalloc of struct dhd_bus failed\n", + __func__)); goto fail; } - bus->sdh = sdh; + bus->card = card; bus->cl_devid = (u16) devid; - bus->bus = DHD_BUS; + bus->bus = BRCMF_BUS; bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; bus->usebufpool = false; /* Use bufpool if allocated, else use locally malloced rxbuf */ /* attempt to attach to the dongle */ - if (!(dhdsdio_probe_attach(bus, sdh, regsva, devid))) { - DHD_ERROR(("%s: dhdsdio_probe_attach failed\n", __func__)); + if (!(brcmf_sdbrcm_probe_attach(bus, card, regsva, devid))) { + BRCMF_ERROR(("%s: brcmf_sdbrcm_probe_attach failed\n", + __func__)); goto fail; } - /* Attach to the dhd/OS/network interface */ - bus->dhd = dhd_attach(bus, SDPCM_RESERVE); - if (!bus->dhd) { - DHD_ERROR(("%s: dhd_attach failed\n", __func__)); + spin_lock_init(&bus->txqlock); + init_waitqueue_head(&bus->ctrl_wait); + + /* Set up the watchdog timer */ + init_timer(&bus->timer); + bus->timer.data = (unsigned long)bus; + bus->timer.function = brcmf_sdbrcm_watchdog; + + /* Initialize thread based operation and lock */ + if ((brcmf_watchdog_prio >= 0) && (brcmf_dpc_prio >= 0)) { + bus->threads_only = true; + sema_init(&bus->sdsem, 1); + } else { + bus->threads_only = false; + spin_lock_init(&bus->sdlock); + } + + if (brcmf_dpc_prio >= 0) { + /* Initialize watchdog thread */ + init_completion(&bus->watchdog_wait); + bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, + bus, "brcmf_watchdog"); + if (IS_ERR(bus->watchdog_tsk)) { + printk(KERN_WARNING + "brcmf_watchdog thread failed to start\n"); + bus->watchdog_tsk = NULL; + } + } else + bus->watchdog_tsk = NULL; + + /* Set up the bottom half handler */ + if (brcmf_dpc_prio >= 0) { + /* Initialize DPC thread */ + init_completion(&bus->dpc_wait); + bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread, + bus, "brcmf_dpc"); + if (IS_ERR(bus->dpc_tsk)) { + printk(KERN_WARNING + "brcmf_dpc thread failed to start\n"); + bus->dpc_tsk = NULL; + } + } else { + tasklet_init(&bus->tasklet, brcmf_sdbrcm_dpc_tasklet, + (unsigned long)bus); + bus->dpc_tsk = NULL; + } + + /* Attach to the brcmf/OS/network interface */ + bus->drvr = brcmf_attach(bus, SDPCM_RESERVE); + if (!bus->drvr) { + BRCMF_ERROR(("%s: brcmf_attach failed\n", __func__)); goto fail; } /* Allocate buffers */ - if (!(dhdsdio_probe_malloc(bus, sdh))) { - DHD_ERROR(("%s: dhdsdio_probe_malloc failed\n", __func__)); + if (!(brcmf_sdbrcm_probe_malloc(bus, card))) { + BRCMF_ERROR(("%s: brcmf_sdbrcm_probe_malloc failed\n", + __func__)); goto fail; } - if (!(dhdsdio_probe_init(bus, sdh))) { - DHD_ERROR(("%s: dhdsdio_probe_init failed\n", __func__)); + if (!(brcmf_sdbrcm_probe_init(bus, card))) { + BRCMF_ERROR(("%s: brcmf_sdbrcm_probe_init failed\n", __func__)); goto fail; } /* Register interrupt callback, but mask it (not operational yet). */ - DHD_INTR(("%s: disable SDIO interrupts (not interested yet)\n", - __func__)); - bcmsdh_intr_disable(sdh); - ret = bcmsdh_intr_reg(sdh, dhdsdio_isr, bus); + BRCMF_INTR(("%s: disable SDIO interrupts (not interested yet)\n", + __func__)); + brcmf_sdcard_intr_disable(card); + ret = brcmf_sdcard_intr_reg(card, brcmf_sdbrcm_isr, bus); if (ret != 0) { - DHD_ERROR(("%s: FAILED: bcmsdh_intr_reg returned %d\n", - __func__, ret)); + BRCMF_ERROR(("%s: FAILED: sdcard_intr_reg returned %d\n", + __func__, ret)); goto fail; } - DHD_INTR(("%s: registered SDIO interrupt function ok\n", __func__)); + BRCMF_INTR(("%s: registered SDIO interrupt function ok\n", __func__)); - DHD_INFO(("%s: completed!!\n", __func__)); + BRCMF_INFO(("%s: completed!!\n", __func__)); /* if firmware path present try to download and bring up bus */ - ret = dhd_bus_start(bus->dhd); + ret = brcmf_bus_start(bus->drvr); if (ret != 0) { if (ret == -ENOLINK) { - DHD_ERROR(("%s: dongle is not responding\n", __func__)); + BRCMF_ERROR(("%s: dongle is not responding\n", + __func__)); goto fail; } } /* Ok, have the per-port tell the stack we're open for business */ - if (dhd_net_attach(bus->dhd, 0) != 0) { - DHD_ERROR(("%s: Net attach failed!!\n", __func__)); + if (brcmf_net_attach(bus->drvr, 0) != 0) { + BRCMF_ERROR(("%s: Net attach failed!!\n", __func__)); goto fail; } return bus; fail: - dhdsdio_release(bus); + brcmf_sdbrcm_release(bus); return NULL; } static bool -dhdsdio_probe_attach(struct dhd_bus *bus, void *sdh, void *regsva, u16 devid) +brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, void *card, u32 regsva, + u16 devid) { u8 clkctl = 0; int err = 0; @@ -5167,130 +5605,81 @@ dhdsdio_probe_attach(struct dhd_bus *bus, void *sdh, void *regsva, u16 devid) bus->alp_only = true; /* Return the window to backplane enumeration space for core access */ - if (dhdsdio_set_siaddr_window(bus, SI_ENUM_BASE)) - DHD_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n", __func__)); + if (brcmf_sdbrcm_set_siaddr_window(bus, SI_ENUM_BASE)) + BRCMF_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n", + __func__)); -#ifdef DHD_DEBUG +#ifdef BCMDBG printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n", - bcmsdh_reg_read(bus->sdh, SI_ENUM_BASE, 4)); + brcmf_sdcard_reg_read(bus->card, SI_ENUM_BASE, 4)); -#endif /* DHD_DEBUG */ +#endif /* BCMDBG */ /* - * Force PLL off until dhdsdio_chip_attach() + * Force PLL off until brcmf_sdbrcm_chip_attach() * programs PLL control regs */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - DHD_INIT_CLKCTL1, &err); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, + BRCMF_INIT_CLKCTL1, &err); if (!err) clkctl = - bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - &err); + brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (err || ((clkctl & ~SBSDIO_AVBITS) != DHD_INIT_CLKCTL1)) { - DHD_ERROR(("dhdsdio_probe: ChipClkCSR access: err %d wrote " - "0x%02x read 0x%02x\n", - err, DHD_INIT_CLKCTL1, clkctl)); - goto fail; - } -#ifdef DHD_DEBUG - if (DHD_INFO_ON()) { - uint fn, numfn; - u8 *cis[SDIOD_MAX_IOFUNCS]; - int err = 0; - - numfn = bcmsdh_query_iofnum(sdh); - ASSERT(numfn <= SDIOD_MAX_IOFUNCS); - - /* Make sure ALP is available before trying to read CIS */ - SPINWAIT(((clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, - NULL)), - !SBSDIO_ALPAV(clkctl)), PMU_MAX_TRANSITION_DLY); - - /* Now request ALP be put on the bus */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - DHD_INIT_CLKCTL2, &err); - udelay(65); - - for (fn = 0; fn <= numfn; fn++) { - cis[fn] = kzalloc(SBSDIO_CIS_SIZE_LIMIT, GFP_ATOMIC); - if (!cis[fn]) { - DHD_INFO(("dhdsdio_probe: fn %d cis malloc " - "failed\n", fn)); - break; - } - - err = bcmsdh_cis_read(sdh, fn, cis[fn], - SBSDIO_CIS_SIZE_LIMIT); - if (err) { - DHD_INFO(("dhdsdio_probe: fn %d cis read " - "err %d\n", fn, err)); - kfree(cis[fn]); - break; - } - dhd_dump_cis(fn, cis[fn]); - } - - while (fn-- > 0) { - ASSERT(cis[fn]); - kfree(cis[fn]); - } - - if (err) { - DHD_ERROR(("dhdsdio_probe: error read/parsing CIS\n")); - goto fail; - } - } -#endif /* DHD_DEBUG */ - - if (dhdsdio_chip_attach(bus, regsva)) { - DHD_ERROR(("%s: dhdsdio_chip_attach failed!\n", __func__)); + if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { + BRCMF_ERROR(("brcmf_sdbrcm_probe: ChipClkCSR access: err %d" + " wrote 0x%02x read 0x%02x\n", + err, BRCMF_INIT_CLKCTL1, clkctl)); goto fail; } - bcmsdh_chipinfo(sdh, bus->ci->chip, bus->ci->chiprev); - - if (!dhdsdio_chipmatch((u16) bus->ci->chip)) { - DHD_ERROR(("%s: unsupported chip: 0x%04x\n", - __func__, bus->ci->chip)); + if (brcmf_sdbrcm_chip_attach(bus, regsva)) { + BRCMF_ERROR(("%s: brcmf_sdbrcm_chip_attach failed!\n", + __func__)); goto fail; } - dhdsdio_sdiod_drive_strength_init(bus, dhd_sdiod_drive_strength); + if (!brcmf_sdbrcm_chipmatch((u16) bus->ci->chip)) { + BRCMF_ERROR(("%s: unsupported chip: 0x%04x\n", + __func__, bus->ci->chip)); + goto fail; + } + + brcmf_sdbrcm_sdiod_drive_strength_init(bus, brcmf_sdiod_drive_strength); /* Get info on the ARM and SOCRAM cores... */ - if (!DHD_NOPMU(bus)) { - bus->armrev = SBCOREREV(bcmsdh_reg_read(bus->sdh, - CORE_SB(bus->ci->armcorebase, sbidhigh), 4)); + if (!BRCMF_NOPMU(bus)) { + brcmf_sdcard_reg_read(bus->card, + CORE_SB(bus->ci->armcorebase, sbidhigh), 4); bus->orig_ramsize = bus->ci->ramsize; if (!(bus->orig_ramsize)) { - DHD_ERROR(("%s: failed to find SOCRAM memory!\n", - __func__)); + BRCMF_ERROR(("%s: failed to find SOCRAM memory!\n", + __func__)); goto fail; } bus->ramsize = bus->orig_ramsize; - if (dhd_dongle_memsize) - dhd_dongle_setmemsize(bus, dhd_dongle_memsize); + if (brcmf_dongle_memsize) + brcmf_sdbrcm_setmemsize(bus, brcmf_dongle_memsize); - DHD_ERROR(("DHD: dongle ram size is set to %d(orig %d)\n", - bus->ramsize, bus->orig_ramsize)); + BRCMF_ERROR(("DHD: dongle ram size is set to %d(orig %d)\n", + bus->ramsize, bus->orig_ramsize)); } - bus->regs = (void *)bus->ci->buscorebase; - /* Set core control so an SDIO reset does a backplane reset */ - OR_REG(&bus->regs->corecontrol, CC_BPRESEN); + OR_REG(bus->ci->buscorebase + offsetof(struct sdpcmd_regs, + corecontrol), + CC_BPRESEN, u32); - bcm_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); + brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); /* Locate an appropriately-aligned portion of hdrbuf */ - bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], DHD_SDALIGN); + bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], + BRCMF_SDALIGN); /* Set the poll and/or interrupt flags */ - bus->intr = (bool) dhd_intr; - bus->poll = (bool) dhd_poll; + bus->intr = (bool) brcmf_intr; + bus->poll = (bool) brcmf_poll; if (bus->poll) bus->pollrate = 1; @@ -5300,18 +5689,18 @@ dhdsdio_probe_attach(struct dhd_bus *bus, void *sdh, void *regsva, u16 devid) return false; } -static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh) +static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus, void *card) { - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - if (bus->dhd->maxctl) { + if (bus->drvr->maxctl) { bus->rxblen = - roundup((bus->dhd->maxctl + SDPCM_HDRLEN), - ALIGNMENT) + DHD_SDALIGN; + roundup((bus->drvr->maxctl + SDPCM_HDRLEN), + ALIGNMENT) + BRCMF_SDALIGN; bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); if (!(bus->rxbuf)) { - DHD_ERROR(("%s: kmalloc of %d-byte rxbuf failed\n", - __func__, bus->rxblen)); + BRCMF_ERROR(("%s: kmalloc of %d-byte rxbuf failed\n", + __func__, bus->rxblen)); goto fail; } } @@ -5319,8 +5708,8 @@ static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh) /* Allocate buffer to receive glomed packet */ bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC); if (!(bus->databuf)) { - DHD_ERROR(("%s: kmalloc of %d-byte databuf failed\n", - __func__, MAX_DATA_BUF)); + BRCMF_ERROR(("%s: kmalloc of %d-byte databuf failed\n", + __func__, MAX_DATA_BUF)); /* release rxbuf which was already located as above */ if (!bus->rxblen) kfree(bus->rxbuf); @@ -5328,10 +5717,9 @@ static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh) } /* Align the buffer */ - if ((unsigned long)bus->databuf % DHD_SDALIGN) - bus->dataptr = - bus->databuf + (DHD_SDALIGN - - ((unsigned long)bus->databuf % DHD_SDALIGN)); + if ((unsigned long)bus->databuf % BRCMF_SDALIGN) + bus->dataptr = bus->databuf + (BRCMF_SDALIGN - + ((unsigned long)bus->databuf % BRCMF_SDALIGN)); else bus->dataptr = bus->databuf; @@ -5341,181 +5729,145 @@ static bool dhdsdio_probe_malloc(dhd_bus_t *bus, void *sdh) return false; } -static bool dhdsdio_probe_init(dhd_bus_t *bus, void *sdh) +static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus, void *card) { s32 fnum; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); #ifdef SDTEST - dhdsdio_pktgen_init(bus); + brcmf_sdbrcm_pktgen_init(bus); #endif /* SDTEST */ /* Disable F2 to clear any intermediate frame state on the dongle */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, SDIO_FUNC_ENABLE_1, - NULL); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_0, SDIO_CCCR_IOEx, + SDIO_FUNC_ENABLE_1, NULL); - bus->dhd->busstate = DHD_BUS_DOWN; + bus->drvr->busstate = BRCMF_BUS_DOWN; bus->sleeping = false; bus->rxflow = false; - bus->prev_rxlim_hit = 0; /* Done with backplane-dependent accesses, can drop clock... */ - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); + brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, + NULL); /* ...and initialize clock/power states */ bus->clkstate = CLK_SDONLY; - bus->idletime = (s32) dhd_idletime; - bus->idleclock = DHD_IDLE_ACTIVE; - - /* Query the SD clock speed */ - if (bcmsdh_iovar_op(sdh, "sd_divisor", NULL, 0, - &bus->sd_divisor, sizeof(s32), - false) != 0) { - DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_divisor")); - bus->sd_divisor = -1; - } else { - DHD_INFO(("%s: Initial value for %s is %d\n", - __func__, "sd_divisor", bus->sd_divisor)); - } - - /* Query the SD bus mode */ - if (bcmsdh_iovar_op(sdh, "sd_mode", NULL, 0, - &bus->sd_mode, sizeof(s32), false) != 0) { - DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_mode")); - bus->sd_mode = -1; - } else { - DHD_INFO(("%s: Initial value for %s is %d\n", - __func__, "sd_mode", bus->sd_mode)); - } + bus->idletime = (s32) brcmf_idletime; + bus->idleclock = BRCMF_IDLE_ACTIVE; /* Query the F2 block size, set roundup accordingly */ fnum = 2; - if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fnum, sizeof(s32), + if (brcmf_sdcard_iovar_op(card, "sd_blocksize", &fnum, sizeof(s32), &bus->blocksize, sizeof(s32), false) != 0) { bus->blocksize = 0; - DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_blocksize")); + BRCMF_ERROR(("%s: fail on %s get\n", __func__, "sd_blocksize")); } else { - DHD_INFO(("%s: Initial value for %s is %d\n", - __func__, "sd_blocksize", bus->blocksize)); + BRCMF_INFO(("%s: Initial value for %s is %d\n", + __func__, "sd_blocksize", bus->blocksize)); } bus->roundup = min(max_roundup, bus->blocksize); /* Query if bus module supports packet chaining, default to use if supported */ - if (bcmsdh_iovar_op(sdh, "sd_rxchain", NULL, 0, + if (brcmf_sdcard_iovar_op(card, "sd_rxchain", NULL, 0, &bus->sd_rxchain, sizeof(s32), false) != 0) { bus->sd_rxchain = false; } else { - DHD_INFO(("%s: bus module (through bcmsdh API) %s chaining\n", - __func__, - (bus->sd_rxchain ? "supports" : "does not support"))); + BRCMF_INFO(("%s: bus module (through sdiocard API) %s" + " chaining\n", __func__, bus->sd_rxchain + ? "supports" : "does not support")); } bus->use_rxchain = (bool) bus->sd_rxchain; return true; } -bool -dhd_bus_download_firmware(struct dhd_bus *bus, char *fw_path, char *nv_path) -{ - bool ret; - bus->fw_path = fw_path; - bus->nv_path = nv_path; - - ret = dhdsdio_download_firmware(bus, bus->sdh); - - return ret; -} - static bool -dhdsdio_download_firmware(struct dhd_bus *bus, void *sdh) +brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus, void *card) { bool ret; /* Download the firmware */ - dhdsdio_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); - ret = _dhdsdio_download_firmware(bus) == 0; + ret = _brcmf_sdbrcm_download_firmware(bus) == 0; - dhdsdio_clkctl(bus, CLK_SDONLY, false); + brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); return ret; } /* Detach and free everything */ -static void dhdsdio_release(dhd_bus_t *bus) +static void brcmf_sdbrcm_release(struct brcmf_bus *bus) { - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); if (bus) { /* De-register interrupt handler */ - bcmsdh_intr_disable(bus->sdh); - bcmsdh_intr_dereg(bus->sdh); + brcmf_sdcard_intr_disable(bus->card); + brcmf_sdcard_intr_dereg(bus->card); - if (bus->dhd) { - dhd_detach(bus->dhd); - dhdsdio_release_dongle(bus); - bus->dhd = NULL; + if (bus->drvr) { + brcmf_detach(bus->drvr); + brcmf_sdbrcm_release_dongle(bus); + bus->drvr = NULL; } - dhdsdio_release_malloc(bus); + brcmf_sdbrcm_release_malloc(bus); kfree(bus); } - DHD_TRACE(("%s: Disconnected\n", __func__)); + BRCMF_TRACE(("%s: Disconnected\n", __func__)); } -static void dhdsdio_release_malloc(dhd_bus_t *bus) +static void brcmf_sdbrcm_release_malloc(struct brcmf_bus *bus) { - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - if (bus->dhd && bus->dhd->dongle_reset) + if (bus->drvr && bus->drvr->dongle_reset) return; - if (bus->rxbuf) { - kfree(bus->rxbuf); - bus->rxctl = bus->rxbuf = NULL; - bus->rxlen = 0; - } + kfree(bus->rxbuf); + bus->rxctl = bus->rxbuf = NULL; + bus->rxlen = 0; kfree(bus->databuf); bus->databuf = NULL; } -static void dhdsdio_release_dongle(dhd_bus_t *bus) +static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus) { - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - if (bus->dhd && bus->dhd->dongle_reset) + if (bus->drvr && bus->drvr->dongle_reset) return; if (bus->ci) { - dhdsdio_clkctl(bus, CLK_AVAIL, false); - dhdsdio_clkctl(bus, CLK_NONE, false); - dhdsdio_chip_detach(bus); + brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); + brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); + brcmf_sdbrcm_chip_detach(bus); if (bus->vars && bus->varsz) kfree(bus->vars); bus->vars = NULL; } - DHD_TRACE(("%s: Disconnected\n", __func__)); + BRCMF_TRACE(("%s: Disconnected\n", __func__)); } -static void dhdsdio_disconnect(void *ptr) +static void brcmf_sdbrcm_disconnect(void *ptr) { - dhd_bus_t *bus = (dhd_bus_t *)ptr; + struct brcmf_bus *bus = (struct brcmf_bus *)ptr; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); if (bus) { - ASSERT(bus->dhd); - dhdsdio_release(bus); + brcmf_sdbrcm_release(bus); } - DHD_TRACE(("%s: Disconnected\n", __func__)); + BRCMF_TRACE(("%s: Disconnected\n", __func__)); } /* Register/Unregister functions are called by the main DHD entry @@ -5523,147 +5875,78 @@ static void dhdsdio_disconnect(void *ptr) * order to look for or await the device. */ -static bcmsdh_driver_t dhd_sdio = { - dhdsdio_probe, - dhdsdio_disconnect +static struct brcmf_sdioh_driver brcmf_sdio = { + brcmf_sdbrcm_probe, + brcmf_sdbrcm_disconnect }; -int dhd_bus_register(void) +int brcmf_bus_register(void) { - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - return bcmsdh_register(&dhd_sdio); + /* Sanity check on the module parameters */ + do { + /* Both watchdog and DPC as tasklets are ok */ + if ((brcmf_watchdog_prio < 0) && (brcmf_dpc_prio < 0)) + break; + + /* If both watchdog and DPC are threads, TX must be deferred */ + if ((brcmf_watchdog_prio >= 0) && (brcmf_dpc_prio >= 0) + && brcmf_deferred_tx) + break; + + BRCMF_ERROR(("Invalid module parameters.\n")); + return -EINVAL; + } while (0); + + return brcmf_sdio_register(&brcmf_sdio); } -void dhd_bus_unregister(void) +void brcmf_bus_unregister(void) { - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); - bcmsdh_unregister(); + brcmf_sdio_unregister(); } -#ifdef BCMEMBEDIMAGE -static int dhdsdio_download_code_array(struct dhd_bus *bus) +static int brcmf_sdbrcm_download_code_file(struct brcmf_bus *bus) { - int bcmerror = -1; - int offset = 0; - - DHD_INFO(("%s: download embedded firmware...\n", __func__)); - - /* Download image */ - while ((offset + MEMBLOCK) < sizeof(dlarray)) { - bcmerror = - dhdsdio_membytes(bus, true, offset, dlarray + offset, - MEMBLOCK); - if (bcmerror) { - DHD_ERROR(("%s: error %d on writing %d membytes at " - "0x%08x\n", - __func__, bcmerror, MEMBLOCK, offset)); - goto err; - } - - offset += MEMBLOCK; - } - - if (offset < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, true, offset, - dlarray + offset, - sizeof(dlarray) - offset); - if (bcmerror) { - DHD_ERROR(("%s: error %d on writing %d membytes at " - "0x%08x\n", __func__, bcmerror, - sizeof(dlarray) - offset, offset)); - goto err; - } - } -#ifdef DHD_DEBUG - /* Upload and compare the downloaded code */ - { - unsigned char *ularray; - - ularray = kmalloc(bus->ramsize, GFP_ATOMIC); - if (!ularray) { - bcmerror = -ENOMEM; - goto err; - } - /* Upload image to verify downloaded contents. */ - offset = 0; - memset(ularray, 0xaa, bus->ramsize); - while ((offset + MEMBLOCK) < sizeof(dlarray)) { - bcmerror = - dhdsdio_membytes(bus, false, offset, - ularray + offset, MEMBLOCK); - if (bcmerror) { - DHD_ERROR(("%s: error %d on reading %d membytes" - " at 0x%08x\n", - __func__, bcmerror, MEMBLOCK, offset)); - goto free; - } - - offset += MEMBLOCK; - } - - if (offset < sizeof(dlarray)) { - bcmerror = dhdsdio_membytes(bus, false, offset, - ularray + offset, - sizeof(dlarray) - offset); - if (bcmerror) { - DHD_ERROR(("%s: error %d on reading %d membytes at 0x%08x\n", - __func__, bcmerror, - sizeof(dlarray) - offset, offset)); - goto free; - } - } - - if (memcmp(dlarray, ularray, sizeof(dlarray))) { - DHD_ERROR(("%s: Downloaded image is corrupted.\n", - __func__)); - ASSERT(0); - goto free; - } else - DHD_ERROR(("%s: Download/Upload/Compare succeeded.\n", - __func__)); -free: - kfree(ularray); - } -#endif /* DHD_DEBUG */ - -err: - return bcmerror; -} -#endif /* BCMEMBEDIMAGE */ - -static int dhdsdio_download_code_file(struct dhd_bus *bus, char *fw_path) -{ - int bcmerror = -1; int offset = 0; uint len; - void *image = NULL; u8 *memblock = NULL, *memptr; + int ret; - DHD_INFO(("%s: download firmware %s\n", __func__, fw_path)); + BRCMF_INFO(("%s: Enter\n", __func__)); - image = dhd_os_open_image(fw_path); - if (image == NULL) - goto err; + bus->fw_name = BCM4329_FW_NAME; + ret = request_firmware(&bus->firmware, bus->fw_name, + &gInstance->func[2]->dev); + if (ret) { + BRCMF_ERROR(("%s: Fail to request firmware %d\n", + __func__, ret)); + return ret; + } + bus->fw_ptr = 0; - memptr = memblock = kmalloc(MEMBLOCK + DHD_SDALIGN, GFP_ATOMIC); + memptr = memblock = kmalloc(MEMBLOCK + BRCMF_SDALIGN, GFP_ATOMIC); if (memblock == NULL) { - DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", - __func__, MEMBLOCK)); + BRCMF_ERROR(("%s: Failed to allocate memory %d bytes\n", + __func__, MEMBLOCK)); + ret = -ENOMEM; goto err; } - if ((u32)(unsigned long)memblock % DHD_SDALIGN) - memptr += - (DHD_SDALIGN - ((u32)(unsigned long)memblock % DHD_SDALIGN)); + if ((u32)(unsigned long)memblock % BRCMF_SDALIGN) + memptr += (BRCMF_SDALIGN - + ((u32)(unsigned long)memblock % BRCMF_SDALIGN)); /* Download image */ while ((len = - dhd_os_get_image_block((char *)memptr, MEMBLOCK, image))) { - bcmerror = dhdsdio_membytes(bus, true, offset, memptr, len); - if (bcmerror) { - DHD_ERROR(("%s: error %d on writing %d membytes at " - "0x%08x\n", __func__, bcmerror, MEMBLOCK, offset)); + brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) { + ret = brcmf_sdbrcm_membytes(bus, true, offset, memptr, len); + if (ret) { + BRCMF_ERROR(("%s: error %d on writing %d membytes at " + "0x%08x\n", __func__, ret, MEMBLOCK, + offset)); goto err; } @@ -5673,10 +5956,10 @@ static int dhdsdio_download_code_file(struct dhd_bus *bus, char *fw_path) err: kfree(memblock); - if (image) - dhd_os_close_image(image); + release_firmware(bus->firmware); + bus->fw_ptr = 0; - return bcmerror; + return ret; } /* @@ -5688,7 +5971,7 @@ static int dhdsdio_download_code_file(struct dhd_bus *bus, char *fw_path) * by two NULs. */ -static uint process_nvram_vars(char *varbuf, uint len) +static uint brcmf_process_nvram_vars(char *varbuf, uint len) { char *dp; bool findNewline; @@ -5730,162 +6013,86 @@ static uint process_nvram_vars(char *varbuf, uint len) return buf_len; } -/* - EXAMPLE: nvram_array - nvram_arry format: - name=value - Use carriage return at the end of each assignment, - and an empty string with - carriage return at the end of array. - - For example: - unsigned char nvram_array[] = {"name1=value1\n", - "name2=value2\n", "\n"}; - Hex values start with 0x, and mac addr format: xx:xx:xx:xx:xx:xx. - - Search "EXAMPLE: nvram_array" to see how the array is activated. -*/ - -void dhd_bus_set_nvram_params(struct dhd_bus *bus, const char *nvram_params) +static int brcmf_sdbrcm_download_nvram(struct brcmf_bus *bus) { - bus->nvram_params = nvram_params; -} - -static int dhdsdio_download_nvram(struct dhd_bus *bus) -{ - int bcmerror = -1; uint len; - void *image = NULL; char *memblock = NULL; char *bufp; - char *nv_path; - bool nvram_file_exists; + int ret; - nv_path = bus->nv_path; - - nvram_file_exists = ((nv_path != NULL) && (nv_path[0] != '\0')); - if (!nvram_file_exists && (bus->nvram_params == NULL)) - return 0; - - if (nvram_file_exists) { - image = dhd_os_open_image(nv_path); - if (image == NULL) - goto err; + bus->nv_name = BCM4329_NV_NAME; + ret = request_firmware(&bus->firmware, bus->nv_name, + &gInstance->func[2]->dev); + if (ret) { + BRCMF_ERROR(("%s: Fail to request nvram %d\n", __func__, ret)); + return ret; } + bus->fw_ptr = 0; memblock = kmalloc(MEMBLOCK, GFP_ATOMIC); if (memblock == NULL) { - DHD_ERROR(("%s: Failed to allocate memory %d bytes\n", - __func__, MEMBLOCK)); + BRCMF_ERROR(("%s: Failed to allocate memory %d bytes\n", + __func__, MEMBLOCK)); + ret = -ENOMEM; goto err; } - /* Download variables */ - if (nvram_file_exists) { - len = dhd_os_get_image_block(memblock, MEMBLOCK, image); - } else { - len = strlen(bus->nvram_params); - ASSERT(len <= MEMBLOCK); - if (len > MEMBLOCK) - len = MEMBLOCK; - memcpy(memblock, bus->nvram_params, len); - } + len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus); if (len > 0 && len < MEMBLOCK) { bufp = (char *)memblock; bufp[len] = 0; - len = process_nvram_vars(bufp, len); + len = brcmf_process_nvram_vars(bufp, len); bufp += len; *bufp++ = 0; if (len) - bcmerror = dhdsdio_downloadvars(bus, memblock, len + 1); - if (bcmerror) { - DHD_ERROR(("%s: error downloading vars: %d\n", - __func__, bcmerror)); - } + ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1); + if (ret) + BRCMF_ERROR(("%s: error downloading vars: %d\n", + __func__, ret)); } else { - DHD_ERROR(("%s: error reading nvram file: %d\n", - __func__, len)); - bcmerror = -EIO; + BRCMF_ERROR(("%s: error reading nvram file: %d\n", + __func__, len)); + ret = -EIO; } err: kfree(memblock); - if (image) - dhd_os_close_image(image); + release_firmware(bus->firmware); + bus->fw_ptr = 0; - return bcmerror; + return ret; } -static int _dhdsdio_download_firmware(struct dhd_bus *bus) +static int _brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus) { int bcmerror = -1; - bool embed = false; /* download embedded firmware */ - bool dlok = false; /* download firmware succeeded */ - - /* Out immediately if no image to download */ - if ((bus->fw_path == NULL) || (bus->fw_path[0] == '\0')) { -#ifdef BCMEMBEDIMAGE - embed = true; -#else - return bcmerror; -#endif - } - /* Keep arm in reset */ - if (dhdsdio_download_state(bus, true)) { - DHD_ERROR(("%s: error placing ARM core in reset\n", __func__)); + if (brcmf_sdbrcm_download_state(bus, true)) { + BRCMF_ERROR(("%s: error placing ARM core in reset\n", + __func__)); goto err; } /* External image takes precedence if specified */ - if ((bus->fw_path != NULL) && (bus->fw_path[0] != '\0')) { - if (dhdsdio_download_code_file(bus, bus->fw_path)) { - DHD_ERROR(("%s: dongle image file download failed\n", - __func__)); -#ifdef BCMEMBEDIMAGE - embed = true; -#else - goto err; -#endif - } else { - embed = false; - dlok = true; - } - } -#ifdef BCMEMBEDIMAGE - if (embed) { - if (dhdsdio_download_code_array(bus)) { - DHD_ERROR(("%s: dongle image array download failed\n", - __func__)); - goto err; - } else { - dlok = true; - } - } -#endif - if (!dlok) { - DHD_ERROR(("%s: dongle image download failed\n", __func__)); + if (brcmf_sdbrcm_download_code_file(bus)) { + BRCMF_ERROR(("%s: dongle image file download failed\n", + __func__)); goto err; } - /* EXAMPLE: nvram_array */ - /* If a valid nvram_arry is specified as above, it can be passed - down to dongle */ - /* dhd_bus_set_nvram_params(bus, (char *)&nvram_array); */ - /* External nvram takes precedence if specified */ - if (dhdsdio_download_nvram(bus)) { - DHD_ERROR(("%s: dongle nvram file download failed\n", - __func__)); + if (brcmf_sdbrcm_download_nvram(bus)) { + BRCMF_ERROR(("%s: dongle nvram file download failed\n", + __func__)); } /* Take arm out of reset */ - if (dhdsdio_download_state(bus, false)) { - DHD_ERROR(("%s: error getting out of ARM core reset\n", - __func__)); + if (brcmf_sdbrcm_download_state(bus, false)) { + BRCMF_ERROR(("%s: error getting out of ARM core reset\n", + __func__)); goto err; } @@ -5897,110 +6104,83 @@ static int _dhdsdio_download_firmware(struct dhd_bus *bus) static int -dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags, +brcmf_sdbrcm_send_buf(struct brcmf_bus *bus, u32 addr, uint fn, uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt, - bcmsdh_cmplt_fn_t complete, void *handle) + void (*complete)(void *handle, int status, + bool sync_waiting), + void *handle) { - return bcmsdh_send_buf - (bus->sdh, addr, fn, flags, buf, nbytes, pkt, complete, + return brcmf_sdcard_send_buf + (bus->card, addr, fn, flags, buf, nbytes, pkt, complete, handle); } -uint dhd_bus_chip(struct dhd_bus *bus) -{ - ASSERT(bus->ci != NULL); - return bus->ci->chip; -} - -void *dhd_bus_pub(struct dhd_bus *bus) -{ - return bus->dhd; -} - -void *dhd_bus_txq(struct dhd_bus *bus) -{ - return &bus->txq; -} - -uint dhd_bus_hdrlen(struct dhd_bus *bus) -{ - return SDPCM_HDRLEN; -} - -int dhd_bus_devreset(dhd_pub_t *dhdp, u8 flag) +int brcmf_bus_devreset(struct brcmf_pub *drvr, u8 flag) { int bcmerror = 0; - dhd_bus_t *bus; + struct brcmf_bus *bus; - bus = dhdp->bus; + bus = drvr->bus; if (flag == true) { - if (!bus->dhd->dongle_reset) { + brcmf_sdbrcm_wd_timer(bus, 0); + if (!bus->drvr->dongle_reset) { /* Expect app to have torn down any connection before calling */ /* Stop the bus, disable F2 */ - dhd_bus_stop(bus, false); + brcmf_sdbrcm_bus_stop(bus, false); /* Clean tx/rx buffer pointers, detach from the dongle */ - dhdsdio_release_dongle(bus); + brcmf_sdbrcm_release_dongle(bus); - bus->dhd->dongle_reset = true; - bus->dhd->up = false; + bus->drvr->dongle_reset = true; + bus->drvr->up = false; - DHD_TRACE(("%s: WLAN OFF DONE\n", __func__)); + BRCMF_TRACE(("%s: WLAN OFF DONE\n", __func__)); /* App can now remove power from device */ } else bcmerror = -EIO; } else { /* App must have restored power to device before calling */ - DHD_TRACE(("\n\n%s: == WLAN ON ==\n", __func__)); + BRCMF_TRACE(("\n\n%s: == WLAN ON ==\n", __func__)); - if (bus->dhd->dongle_reset) { + if (bus->drvr->dongle_reset) { /* Turn on WLAN */ - /* Reset SD client */ - bcmsdh_reset(bus->sdh); /* Attempt to re-attach & download */ - if (dhdsdio_probe_attach(bus, bus->sdh, - (u32 *) SI_ENUM_BASE, - bus->cl_devid)) { + if (brcmf_sdbrcm_probe_attach(bus, bus->card, + SI_ENUM_BASE, + bus->cl_devid)) { /* Attempt to download binary to the dongle */ - if (dhdsdio_probe_init - (bus, bus->sdh) - && dhdsdio_download_firmware(bus, - bus->sdh)) { - + if (brcmf_sdbrcm_probe_init(bus, bus->card)) { /* Re-init bus, enable F2 transfer */ - dhd_bus_init((dhd_pub_t *) bus->dhd, - false); + brcmf_sdbrcm_bus_init(bus->drvr, false); -#if defined(OOB_INTR_ONLY) - dhd_enable_oob_intr(bus, true); -#endif /* defined(OOB_INTR_ONLY) */ + bus->drvr->dongle_reset = false; + bus->drvr->up = true; - bus->dhd->dongle_reset = false; - bus->dhd->up = true; - - DHD_TRACE(("%s: WLAN ON DONE\n", - __func__)); + BRCMF_TRACE(("%s: WLAN ON DONE\n", + __func__)); } else bcmerror = -EIO; } else bcmerror = -EIO; } else { bcmerror = -EISCONN; - DHD_ERROR(("%s: Set DEVRESET=false invoked when device " - "is on\n", __func__)); + BRCMF_ERROR(("%s: Set DEVRESET=false invoked when" + " device is on\n", __func__)); bcmerror = -EIO; } + brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms); } return bcmerror; } static int -dhdsdio_chip_recognition(bcmsdh_info_t *sdh, struct chip_info *ci, void *regs) +brcmf_sdbrcm_chip_recognition(struct brcmf_sdio_card *card, + struct chip_info *ci, u32 regs) { u32 regdata; @@ -6010,13 +6190,14 @@ dhdsdio_chip_recognition(bcmsdh_info_t *sdh, struct chip_info *ci, void *regs) * For different chiptypes or old sdio hosts w/o chipcommon, * other ways of recognition should be added here. */ - ci->cccorebase = (u32)regs; - regdata = bcmsdh_reg_read(sdh, CORE_CC_REG(ci->cccorebase, chipid), 4); + ci->cccorebase = regs; + regdata = brcmf_sdcard_reg_read(card, + CORE_CC_REG(ci->cccorebase, chipid), 4); ci->chip = regdata & CID_ID_MASK; ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; - DHD_INFO(("%s: chipid=0x%x chiprev=%d\n", - __func__, ci->chip, ci->chiprev)); + BRCMF_INFO(("%s: chipid=0x%x chiprev=%d\n", + __func__, ci->chip, ci->chiprev)); /* Address of cores for new chips should be added here */ switch (ci->chip) { @@ -6027,126 +6208,127 @@ dhdsdio_chip_recognition(bcmsdh_info_t *sdh, struct chip_info *ci, void *regs) ci->ramsize = BCM4329_RAMSIZE; break; default: - DHD_ERROR(("%s: chipid 0x%x is not supported\n", - __func__, ci->chip)); + BRCMF_ERROR(("%s: chipid 0x%x is not supported\n", + __func__, ci->chip)); return -ENODEV; } - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_SB(ci->cccorebase, sbidhigh), 4); ci->ccrev = SBCOREREV(regdata); - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_CC_REG(ci->cccorebase, pmucapabilities), 4); ci->pmurev = regdata & PCAP_REV_MASK; - regdata = bcmsdh_reg_read(sdh, CORE_SB(ci->buscorebase, sbidhigh), 4); + regdata = brcmf_sdcard_reg_read(card, + CORE_SB(ci->buscorebase, sbidhigh), 4); ci->buscorerev = SBCOREREV(regdata); ci->buscoretype = (regdata & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT; - DHD_INFO(("%s: ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n", - __func__, ci->ccrev, ci->pmurev, - ci->buscorerev, ci->buscoretype)); + BRCMF_INFO(("%s: ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n", + __func__, ci->ccrev, ci->pmurev, + ci->buscorerev, ci->buscoretype)); /* get chipcommon capabilites */ - ci->cccaps = bcmsdh_reg_read(sdh, + ci->cccaps = brcmf_sdcard_reg_read(card, CORE_CC_REG(ci->cccorebase, capabilities), 4); return 0; } static void -dhdsdio_chip_disablecore(bcmsdh_info_t *sdh, u32 corebase) +brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_card *card, u32 corebase) { u32 regdata; - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbtmstatelow), 4); if (regdata & SBTML_RESET) return; - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbtmstatelow), 4); if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) { /* * set target reject and spin until busy is clear * (preserve core-specific bits) */ - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbtmstatelow), 4); - bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4, + brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4, regdata | SBTML_REJ); - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbtmstatelow), 4); udelay(1); - SPINWAIT((bcmsdh_reg_read(sdh, + SPINWAIT((brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbtmstatehigh), 4) & SBTMH_BUSY), 100000); - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbtmstatehigh), 4); if (regdata & SBTMH_BUSY) - DHD_ERROR(("%s: ARM core still busy\n", __func__)); + BRCMF_ERROR(("%s: ARM core still busy\n", __func__)); - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbidlow), 4); if (regdata & SBIDL_INIT) { - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbimstate), 4) | SBIM_RJ; - bcmsdh_reg_write(sdh, + brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbimstate), 4, regdata); - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbimstate), 4); udelay(1); - SPINWAIT((bcmsdh_reg_read(sdh, + SPINWAIT((brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbimstate), 4) & SBIM_BY), 100000); } /* set reset and reject while enabling the clocks */ - bcmsdh_reg_write(sdh, + brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4, (((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | SBTML_REJ | SBTML_RESET)); - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbtmstatelow), 4); udelay(10); /* clear the initiator reject bit */ - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbidlow), 4); if (regdata & SBIDL_INIT) { - regdata = bcmsdh_reg_read(sdh, + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbimstate), 4) & ~SBIM_RJ; - bcmsdh_reg_write(sdh, + brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbimstate), 4, regdata); } } /* leave reset and reject asserted */ - bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4, + brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4, (SBTML_REJ | SBTML_RESET)); udelay(1); } static int -dhdsdio_chip_attach(struct dhd_bus *bus, void *regs) +brcmf_sdbrcm_chip_attach(struct brcmf_bus *bus, u32 regs) { struct chip_info *ci; int err; u8 clkval, clkset; - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); /* alloc chip_info_t */ ci = kmalloc(sizeof(struct chip_info), GFP_ATOMIC); if (NULL == ci) { - DHD_ERROR(("%s: malloc failed!\n", __func__)); + BRCMF_ERROR(("%s: malloc failed!\n", __func__)); return -ENOMEM; } @@ -6155,48 +6337,48 @@ dhdsdio_chip_attach(struct dhd_bus *bus, void *regs) /* bus/core/clk setup for register access */ /* Try forcing SDIO core to do ALPAvail request only */ clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); if (err) { - DHD_ERROR(("%s: error writing for HT off\n", __func__)); + BRCMF_ERROR(("%s: error writing for HT off\n", __func__)); goto fail; } /* If register supported, wait for ALPAvail and then force ALP */ /* This may take up to 15 milliseconds */ - clkval = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, + clkval = brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL); if ((clkval & ~SBSDIO_AVBITS) == clkset) { SPINWAIT(((clkval = - bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, + brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)), PMU_MAX_TRANSITION_DLY); if (!SBSDIO_ALPAV(clkval)) { - DHD_ERROR(("%s: timeout on ALPAV wait, clkval 0x%02x\n", - __func__, clkval)); + BRCMF_ERROR(("%s: timeout on ALPAV wait," + " clkval 0x%02x\n", __func__, clkval)); err = -EBUSY; goto fail; } clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); udelay(65); } else { - DHD_ERROR(("%s: ChipClkCSR access: wrote 0x%02x read 0x%02x\n", - __func__, clkset, clkval)); + BRCMF_ERROR(("%s: ChipClkCSR access: wrote 0x%02x" + " read 0x%02x\n", __func__, clkset, clkval)); err = -EACCES; goto fail; } /* Also, disable the extra SDIO pull-ups */ - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0, - NULL); + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, + 0, NULL); - err = dhdsdio_chip_recognition(bus->sdh, ci, regs); + err = brcmf_sdbrcm_chip_recognition(bus->card, ci, regs); if (err) goto fail; @@ -6204,24 +6386,24 @@ dhdsdio_chip_attach(struct dhd_bus *bus, void *regs) * Make sure any on-chip ARM is off (in case strapping is wrong), * or downloaded code was already running. */ - dhdsdio_chip_disablecore(bus->sdh, ci->armcorebase); + brcmf_sdbrcm_chip_disablecore(bus->card, ci->armcorebase); - bcmsdh_reg_write(bus->sdh, + brcmf_sdcard_reg_write(bus->card, CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0); - bcmsdh_reg_write(bus->sdh, + brcmf_sdcard_reg_write(bus->card, CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0); /* Disable F2 to clear any intermediate frame state on the dongle */ - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN, + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_0, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1, NULL); /* WAR: cmd52 backplane read so core HW will drop ALPReq */ - clkval = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1, + clkval = brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1, 0, NULL); /* Done with backplane-dependent accesses, can drop clock... */ - bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, - NULL); + brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, + 0, NULL); bus->ci = ci; return 0; @@ -6232,7 +6414,7 @@ dhdsdio_chip_attach(struct dhd_bus *bus, void *regs) } static void -dhdsdio_chip_resetcore(bcmsdh_info_t *sdh, u32 corebase) +brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_card *card, u32 corebase) { u32 regdata; @@ -6240,35 +6422,37 @@ dhdsdio_chip_resetcore(bcmsdh_info_t *sdh, u32 corebase) * Must do the disable sequence first to work for * arbitrary current core state. */ - dhdsdio_chip_disablecore(sdh, corebase); + brcmf_sdbrcm_chip_disablecore(card, corebase); /* * Now do the initialization sequence. * set reset while enabling the clock and * forcing them on throughout the core */ - bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4, + brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4, ((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | SBTML_RESET); udelay(1); - regdata = bcmsdh_reg_read(sdh, CORE_SB(corebase, sbtmstatehigh), 4); + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbtmstatehigh), + 4); if (regdata & SBTMH_SERR) - bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatehigh), 4, 0); + brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatehigh), + 4, 0); - regdata = bcmsdh_reg_read(sdh, CORE_SB(corebase, sbimstate), 4); + regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbimstate), 4); if (regdata & (SBIM_IBE | SBIM_TO)) - bcmsdh_reg_write(sdh, CORE_SB(corebase, sbimstate), 4, + brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbimstate), 4, regdata & ~(SBIM_IBE | SBIM_TO)); /* clear reset and allow it to propagate throughout the core */ - bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4, + brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4, (SICF_FGC << SBTML_SICF_SHIFT) | (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); udelay(1); /* leave clock enabled */ - bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4, + brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4, (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); udelay(1); } @@ -6316,7 +6500,7 @@ static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = { #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) static void -dhdsdio_sdiod_drive_strength_init(struct dhd_bus *bus, u32 drivestrength) { +brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus, u32 drivestrength) { struct sdiod_drive_str *str_tab = NULL; u32 str_mask = 0; u32 str_shift = 0; @@ -6343,10 +6527,10 @@ dhdsdio_sdiod_drive_strength_init(struct dhd_bus *bus, u32 drivestrength) { str_shift = 11; break; default: - DHD_ERROR(("No SDIO Drive strength init" - "done for chip %s rev %d pmurev %d\n", - bcm_chipname(bus->ci->chip, chn, 8), - bus->ci->chiprev, bus->ci->pmurev)); + BRCMF_ERROR(("No SDIO Drive strength init" + "done for chip %s rev %d pmurev %d\n", + brcmu_chipname(bus->ci->chip, chn, 8), + bus->ci->chiprev, bus->ci->pmurev)); break; } @@ -6362,28 +6546,227 @@ dhdsdio_sdiod_drive_strength_init(struct dhd_bus *bus, u32 drivestrength) { } } - bcmsdh_reg_write(bus->sdh, + brcmf_sdcard_reg_write(bus->card, CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4, 1); - cc_data_temp = bcmsdh_reg_read(bus->sdh, + cc_data_temp = brcmf_sdcard_reg_read(bus->card, CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4); cc_data_temp &= ~str_mask; drivestrength_sel <<= str_shift; cc_data_temp |= drivestrength_sel; - bcmsdh_reg_write(bus->sdh, + brcmf_sdcard_reg_write(bus->card, CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4, cc_data_temp); - DHD_INFO(("SDIO: %dmA drive strength selected, set to 0x%08x\n", - drivestrength, cc_data_temp)); + BRCMF_INFO(("SDIO: %dmA drive strength selected, " + "set to 0x%08x\n", drivestrength, cc_data_temp)); } } static void -dhdsdio_chip_detach(struct dhd_bus *bus) +brcmf_sdbrcm_chip_detach(struct brcmf_bus *bus) { - DHD_TRACE(("%s: Enter\n", __func__)); + BRCMF_TRACE(("%s: Enter\n", __func__)); kfree(bus->ci); bus->ci = NULL; } + +static void +brcmf_sdbrcm_wait_for_event(struct brcmf_bus *bus, bool *lockvar) +{ + brcmf_sdbrcm_sdunlock(bus); + wait_event_interruptible_timeout(bus->ctrl_wait, + (*lockvar == false), HZ * 2); + brcmf_sdbrcm_sdlock(bus); + return; +} + +static void +brcmf_sdbrcm_wait_event_wakeup(struct brcmf_bus *bus) +{ + if (waitqueue_active(&bus->ctrl_wait)) + wake_up_interruptible(&bus->ctrl_wait); + return; +} + +static int +brcmf_sdbrcm_watchdog_thread(void *data) +{ + struct brcmf_bus *bus = (struct brcmf_bus *)data; + + /* This thread doesn't need any user-level access, + * so get rid of all our resources + */ + if (brcmf_watchdog_prio > 0) { + struct sched_param param; + param.sched_priority = (brcmf_watchdog_prio < MAX_RT_PRIO) ? + brcmf_watchdog_prio : (MAX_RT_PRIO - 1); + sched_setscheduler(current, SCHED_FIFO, ¶m); + } + + allow_signal(SIGTERM); + /* Run until signal received */ + while (1) { + if (kthread_should_stop()) + break; + if (!wait_for_completion_interruptible(&bus->watchdog_wait)) { + if (bus->drvr->dongle_reset == false) + brcmf_sdbrcm_bus_watchdog(bus->drvr); + /* Count the tick for reference */ + bus->drvr->tickcnt++; + } else + break; + } + return 0; +} + +static void +brcmf_sdbrcm_watchdog(unsigned long data) +{ + struct brcmf_bus *bus = (struct brcmf_bus *)data; + + if (brcmf_watchdog_prio >= 0) { + if (bus->watchdog_tsk) + complete(&bus->watchdog_wait); + else + return; + } else { + brcmf_sdbrcm_bus_watchdog(bus->drvr); + + /* Count the tick for reference */ + bus->drvr->tickcnt++; + } + + /* Reschedule the watchdog */ + if (bus->wd_timer_valid) + mod_timer(&bus->timer, jiffies + brcmf_watchdog_ms * HZ / 1000); +} + +void +brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick) +{ + static uint save_ms; + + /* don't start the wd until fw is loaded */ + if (bus->drvr->busstate == BRCMF_BUS_DOWN) + return; + + /* Totally stop the timer */ + if (!wdtick && bus->wd_timer_valid == true) { + del_timer_sync(&bus->timer); + bus->wd_timer_valid = false; + save_ms = wdtick; + return; + } + + if (wdtick) { + brcmf_watchdog_ms = (uint) wdtick; + + if (save_ms != brcmf_watchdog_ms) { + if (bus->wd_timer_valid == true) + /* Stop timer and restart at new value */ + del_timer_sync(&bus->timer); + + /* Create timer again when watchdog period is + dynamically changed or in the first instance + */ + bus->timer.expires = + jiffies + brcmf_watchdog_ms * HZ / 1000; + add_timer(&bus->timer); + + } else { + /* Re arm the timer, at last watchdog period */ + mod_timer(&bus->timer, + jiffies + brcmf_watchdog_ms * HZ / 1000); + } + + bus->wd_timer_valid = true; + save_ms = wdtick; + } +} + +static int brcmf_sdbrcm_dpc_thread(void *data) +{ + struct brcmf_bus *bus = (struct brcmf_bus *) data; + + /* This thread doesn't need any user-level access, + * so get rid of all our resources + */ + if (brcmf_dpc_prio > 0) { + struct sched_param param; + param.sched_priority = (brcmf_dpc_prio < MAX_RT_PRIO) ? + brcmf_dpc_prio : (MAX_RT_PRIO - 1); + sched_setscheduler(current, SCHED_FIFO, ¶m); + } + + allow_signal(SIGTERM); + /* Run until signal received */ + while (1) { + if (kthread_should_stop()) + break; + if (!wait_for_completion_interruptible(&bus->dpc_wait)) { + /* Call bus dpc unless it indicated down + (then clean stop) */ + if (bus->drvr->busstate != BRCMF_BUS_DOWN) { + if (brcmf_sdbrcm_dpc(bus)) + complete(&bus->dpc_wait); + } else { + brcmf_sdbrcm_bus_stop(bus, true); + } + } else + break; + } + return 0; +} + +static void brcmf_sdbrcm_dpc_tasklet(unsigned long data) +{ + struct brcmf_bus *bus = (struct brcmf_bus *) data; + + /* Call bus dpc unless it indicated down (then clean stop) */ + if (bus->drvr->busstate != BRCMF_BUS_DOWN) { + if (brcmf_sdbrcm_dpc(bus)) + tasklet_schedule(&bus->tasklet); + } else + brcmf_sdbrcm_bus_stop(bus, true); +} + +static void brcmf_sdbrcm_sched_dpc(struct brcmf_bus *bus) +{ + if (bus->dpc_tsk) { + complete(&bus->dpc_wait); + return; + } + + tasklet_schedule(&bus->tasklet); +} + +static void brcmf_sdbrcm_sdlock(struct brcmf_bus *bus) +{ + if (bus->threads_only) + down(&bus->sdsem); + else + spin_lock_bh(&bus->sdlock); +} + +static void brcmf_sdbrcm_sdunlock(struct brcmf_bus *bus) +{ + if (bus->threads_only) + up(&bus->sdsem); + else + spin_unlock_bh(&bus->sdlock); +} + +static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_bus *bus) +{ + if (bus->firmware->size < bus->fw_ptr + len) + len = bus->firmware->size - bus->fw_ptr; + + memcpy(buf, &bus->firmware->data[bus->fw_ptr], len); + bus->fw_ptr += len; + return len; +} + +MODULE_FIRMWARE(BCM4329_FW_NAME); +MODULE_FIRMWARE(BCM4329_NV_NAME); diff --git a/drivers/staging/brcm80211/brcmfmac/dhdioctl.h b/drivers/staging/brcm80211/brcmfmac/dhdioctl.h deleted file mode 100644 index f0ba53558ccd..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/dhdioctl.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _dhdioctl_h_ -#define _dhdioctl_h_ - -/* Linux network driver ioctl encoding */ -typedef struct dhd_ioctl { - uint cmd; /* common ioctl definition */ - void *buf; /* pointer to user buffer */ - uint len; /* length of user buffer */ - bool set; /* get or set request (optional) */ - uint used; /* bytes read or written (optional) */ - uint needed; /* bytes needed (optional) */ - uint driver; /* to identify target driver */ -} dhd_ioctl_t; - -/* per-driver magic numbers */ -#define DHD_IOCTL_MAGIC 0x00444944 - -/* bump this number if you change the ioctl interface */ -#define DHD_IOCTL_VERSION 1 - -#define DHD_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ -#define DHD_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ - -/* common ioctl definitions */ -#define DHD_GET_MAGIC 0 -#define DHD_GET_VERSION 1 -#define DHD_GET_VAR 2 -#define DHD_SET_VAR 3 - -/* message levels */ -#define DHD_ERROR_VAL 0x0001 -#define DHD_TRACE_VAL 0x0002 -#define DHD_INFO_VAL 0x0004 -#define DHD_DATA_VAL 0x0008 -#define DHD_CTL_VAL 0x0010 -#define DHD_TIMER_VAL 0x0020 -#define DHD_HDRS_VAL 0x0040 -#define DHD_BYTES_VAL 0x0080 -#define DHD_INTR_VAL 0x0100 -#define DHD_LOG_VAL 0x0200 -#define DHD_GLOM_VAL 0x0400 -#define DHD_EVENT_VAL 0x0800 -#define DHD_BTA_VAL 0x1000 -#define DHD_ISCAN_VAL 0x2000 - -#ifdef SDTEST -/* For pktgen iovar */ -typedef struct dhd_pktgen { - uint version; /* To allow structure change tracking */ - uint freq; /* Max ticks between tx/rx attempts */ - uint count; /* Test packets to send/rcv each attempt */ - uint print; /* Print counts every attempts */ - uint total; /* Total packets (or bursts) */ - uint minlen; /* Minimum length of packets to send */ - uint maxlen; /* Maximum length of packets to send */ - uint numsent; /* Count of test packets sent */ - uint numrcvd; /* Count of test packets received */ - uint numfail; /* Count of test send failures */ - uint mode; /* Test mode (type of test packets) */ - uint stop; /* Stop after this many tx failures */ -} dhd_pktgen_t; - -/* Version in case structure changes */ -#define DHD_PKTGEN_VERSION 2 - -/* Type of test packets to use */ -#define DHD_PKTGEN_ECHO 1 /* Send echo requests */ -#define DHD_PKTGEN_SEND 2 /* Send discard packets */ -#define DHD_PKTGEN_RXBURST 3 /* Request dongle send N packets */ -#define DHD_PKTGEN_RECV 4 /* Continuous rx from continuous - tx dongle */ -#endif /* SDTEST */ - -/* Enter idle immediately (no timeout) */ -#define DHD_IDLE_IMMEDIATE (-1) - -/* Values for idleclock iovar: other values are the sd_divisor to use - when idle */ -#define DHD_IDLE_ACTIVE 0 /* Do not request any SD clock change - when idle */ -#define DHD_IDLE_STOP (-1) /* Request SD clock be stopped - (and use SD1 mode) */ - -#endif /* _dhdioctl_h_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/dngl_stats.h b/drivers/staging/brcm80211/brcmfmac/dngl_stats.h deleted file mode 100644 index 699cbffa9c4b..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/dngl_stats.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _dngl_stats_h_ -#define _dngl_stats_h_ - -typedef struct { - 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; /* packets dropped by dongle */ - unsigned long tx_dropped; /* packets dropped by dongle */ - unsigned long multicast; /* multicast packets received */ -} dngl_stats_t; - -#endif /* _dngl_stats_h_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h b/drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h deleted file mode 100644 index 28f092c9e027..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/hndrte_armtrap.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _hndrte_armtrap_h -#define _hndrte_armtrap_h - -/* ARM trap handling */ - -/* Trap types defined by ARM (see arminc.h) */ - -/* Trap locations in lo memory */ -#define TRAP_STRIDE 4 -#define FIRST_TRAP TR_RST -#define LAST_TRAP (TR_FIQ * TRAP_STRIDE) - -#if defined(__ARM_ARCH_4T__) -#define MAX_TRAP_TYPE (TR_FIQ + 1) -#elif defined(__ARM_ARCH_7M__) -#define MAX_TRAP_TYPE (TR_ISR + ARMCM3_NUMINTS) -#endif /* __ARM_ARCH_7M__ */ - -/* The trap structure is defined here as offsets for assembly */ -#define TR_TYPE 0x00 -#define TR_EPC 0x04 -#define TR_CPSR 0x08 -#define TR_SPSR 0x0c -#define TR_REGS 0x10 -#define TR_REG(n) (TR_REGS + (n) * 4) -#define TR_SP TR_REG(13) -#define TR_LR TR_REG(14) -#define TR_PC TR_REG(15) - -#define TRAP_T_SIZE 80 - -#ifndef _LANGUAGE_ASSEMBLY - -typedef struct _trap_struct { - u32 type; - u32 epc; - u32 cpsr; - u32 spsr; - u32 r0; - u32 r1; - u32 r2; - u32 r3; - u32 r4; - u32 r5; - u32 r6; - u32 r7; - u32 r8; - u32 r9; - u32 r10; - u32 r11; - u32 r12; - u32 r13; - u32 r14; - u32 pc; -} trap_t; - -#endif /* !_LANGUAGE_ASSEMBLY */ - -#endif /* _hndrte_armtrap_h */ diff --git a/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h b/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h deleted file mode 100644 index 4df3eecaa83b..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/hndrte_cons.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef _hndrte_cons_h -#define _hndrte_cons_h - -#define CBUF_LEN (128) - -#define LOG_BUF_LEN 1024 - -typedef struct { - u32 buf; /* Can't be pointer on (64-bit) hosts */ - uint buf_size; - uint idx; - char *_buf_compat; /* Redundant pointer for backward compat. */ -} hndrte_log_t; - -typedef struct { - /* Virtual UART - * When there is no UART (e.g. Quickturn), - * the host should write a complete - * input line directly into cbuf and then write - * the length into vcons_in. - * This may also be used when there is a real UART - * (at risk of conflicting with - * the real UART). vcons_out is currently unused. - */ - volatile uint vcons_in; - volatile uint vcons_out; - - /* Output (logging) buffer - * Console output is written to a ring buffer log_buf at index log_idx. - * The host may read the output when it sees log_idx advance. - * Output will be lost if the output wraps around faster than the host - * polls. - */ - hndrte_log_t log; - - /* Console input line buffer - * Characters are read one at a time into cbuf - * until is received, then - * the buffer is processed as a command line. - * Also used for virtual UART. - */ - uint cbuf_idx; - char cbuf[CBUF_LEN]; -} hndrte_cons_t; - -#endif /* _hndrte_cons_h */ - diff --git a/drivers/staging/brcm80211/brcmfmac/msgtrace.h b/drivers/staging/brcm80211/brcmfmac/msgtrace.h deleted file mode 100644 index d654671a5a30..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/msgtrace.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _MSGTRACE_H -#define _MSGTRACE_H - -#define MSGTRACE_VERSION 1 - -/* Message trace header */ -typedef struct msgtrace_hdr { - u8 version; - u8 spare; - u16 len; /* Len of the trace */ - u32 seqnum; /* Sequence number of message. Useful - * if the messsage has been lost - * because of DMA error or a bus reset - * (ex: SDIO Func2) - */ - u32 discarded_bytes; /* Number of discarded bytes because of - trace overflow */ - u32 discarded_printf; /* Number of discarded printf - because of trace overflow */ -} __attribute__((packed)) msgtrace_hdr_t; - -#define MSGTRACE_HDRLEN sizeof(msgtrace_hdr_t) - -/* The hbus driver generates traces when sending a trace message. - * This causes endless traces. - * This flag must be set to true in any hbus traces. - * The flag is reset in the function msgtrace_put. - * This prevents endless traces but generates hasardous - * lost of traces only in bus device code. - * It is recommendat to set this flag in macro SD_TRACE - * but not in SD_ERROR for avoiding missing - * hbus error traces. hbus error trace should not generates endless traces. - */ -extern bool msgtrace_hbus_trace; - -typedef void (*msgtrace_func_send_t) (void *hdl1, void *hdl2, u8 *hdr, - u16 hdrlen, u8 *buf, - u16 buflen); - -extern void msgtrace_sent(void); -extern void msgtrace_put(char *buf, int count); -extern void msgtrace_init(void *hdl1, void *hdl2, - msgtrace_func_send_t func_send); - -#endif /* _MSGTRACE_H */ diff --git a/drivers/staging/brcm80211/brcmfmac/sdio_host.h b/drivers/staging/brcm80211/brcmfmac/sdio_host.h new file mode 100644 index 000000000000..d34547215060 --- /dev/null +++ b/drivers/staging/brcm80211/brcmfmac/sdio_host.h @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BRCM_SDH_H_ +#define _BRCM_SDH_H_ + +#include +extern const uint brcmf_sdio_msglevel; + +#define SDIO_FUNC_0 0 +#define SDIO_FUNC_1 1 +#define SDIO_FUNC_2 2 + +#define SDIOD_FBR_SIZE 0x100 + +/* io_en */ +#define SDIO_FUNC_ENABLE_1 0x02 +#define SDIO_FUNC_ENABLE_2 0x04 + +/* io_rdys */ +#define SDIO_FUNC_READY_1 0x02 +#define SDIO_FUNC_READY_2 0x04 + +/* intr_status */ +#define INTR_STATUS_FUNC1 0x2 +#define INTR_STATUS_FUNC2 0x4 + +/* Maximum number of I/O funcs */ +#define SDIOD_MAX_IOFUNCS 7 + +#define SBSDIO_NUM_FUNCTION 3 /* as of sdiod rev 0, supports 3 functions */ + +/* function 1 miscellaneous registers */ +#define SBSDIO_SPROM_CS 0x10000 /* sprom command and status */ +#define SBSDIO_SPROM_INFO 0x10001 /* sprom info register */ +#define SBSDIO_SPROM_DATA_LOW 0x10002 /* sprom indirect access data byte 0 */ +#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* sprom indirect access data byte 1 */ +#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* sprom indirect access addr byte 0 */ +#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* sprom indirect access addr byte 0 */ +#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu (gpio) output */ +#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu (gpio) enable */ +#define SBSDIO_WATERMARK 0x10008 /* rev < 7, watermark for sdio device */ +#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */ + +/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */ +#define SBSDIO_FUNC1_SBADDRLOW 0x1000A /* SB Address Window Low (b15) */ +#define SBSDIO_FUNC1_SBADDRMID 0x1000B /* SB Address Window Mid (b23:b16) */ +#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C /* SB Address Window High (b31:b24) */ +#define SBSDIO_FUNC1_FRAMECTRL 0x1000D /* Frame Control (frame term/abort) */ +#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E /* ChipClockCSR (ALP/HT ctl/status) */ +#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F /* SdioPullUp (on cmd, d0-d2) */ +#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 /* Write Frame Byte Count Low */ +#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A /* Write Frame Byte Count High */ +#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count Low */ +#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C /* Read Frame Byte Count High */ + +#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */ +#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */ + +/* function 1 OCP space */ +#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */ +#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000 +#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */ + +/* some duplication with sbsdpcmdev.h here */ +/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */ +#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */ +#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */ +#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */ +#define SBSDIO_SBWINDOW_MASK 0xffff8000 /* Address bits from SBADDR regs */ + +#define SDIOH_READ 0 /* Read request */ +#define SDIOH_WRITE 1 /* Write request */ + +#define SDIOH_DATA_FIX 0 /* Fixed addressing */ +#define SDIOH_DATA_INC 1 /* Incremental addressing */ + +/* internal return code */ +#define SUCCESS 0 +#define ERROR 1 + +/* forward declarations */ +struct brcmf_sdio_card; + +struct brcmf_sdreg { + int func; + int offset; + int value; +}; + +struct sdioh_info { + struct osl_info *osh; /* osh handler */ + bool client_intr_enabled; /* interrupt connnected flag */ + bool intr_handler_valid; /* client driver interrupt handler valid */ + void (*intr_handler)(void *); /* registered interrupt handler */ + void *intr_handler_arg; /* argument to call interrupt handler */ + u16 intmask; /* Current active interrupts */ + void *sdos_info; /* Pointer to per-OS private data */ + + uint irq; /* Client irq */ + int intrcount; /* Client interrupts */ + bool sd_blockmode; /* sd_blockmode == false => 64 Byte Cmd 53s. */ + /* Must be on for sd_multiblock to be effective */ + bool use_client_ints; /* If this is false, make sure to restore */ + int client_block_size[SDIOD_MAX_IOFUNCS]; /* Blocksize */ + u8 num_funcs; /* Supported funcs on client */ + u32 com_cis_ptr; + u32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; + uint max_dma_len; + uint max_dma_descriptors; /* DMA Descriptors supported by this controller. */ + /* SDDMA_DESCRIPTOR SGList[32]; *//* Scatter/Gather DMA List */ +}; + +struct brcmf_sdmmc_instance { + struct sdioh_info *sd; + struct sdio_func *func[SDIOD_MAX_IOFUNCS]; + u32 host_claimed; +}; + +/* Attach and build an interface to the underlying SD host driver. + * - Allocates resources (structs, arrays, mem, OS handles, etc) needed by + * brcmf_sdcard. + * - Returns the sdio card handle and virtual address base for register access. + * The returned handle should be used in all subsequent calls, but the bcmsh + * implementation may maintain a single "default" handle (e.g. the first or + * most recent one) to enable single-instance implementations to pass NULL. + */ +extern struct brcmf_sdio_card* +brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq); + +/* Detach - freeup resources allocated in attach */ +extern int brcmf_sdcard_detach(struct brcmf_sdio_card *card); + +/* Enable/disable SD interrupt */ +extern int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card); +extern int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card); + +/* Register/deregister device interrupt handler. */ +extern int +brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card, + void (*fn)(void *), void *argh); + +extern int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card); + +/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface). + * fn: function number + * addr: unmodified SDIO-space address + * data: data byte to write + * err: pointer to error code (or NULL) + */ +extern u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint func, + u32 addr, int *err); +extern void brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint func, + u32 addr, u8 data, int *err); + +/* Read/Write 4bytes from/to cfg space */ +extern u32 +brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num, + u32 addr, int *err); + +extern void brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card, + uint fnc_num, u32 addr, + u32 data, int *err); + +/* Read CIS content for specified function. + * fn: function whose CIS is being requested (0 is common CIS) + * cis: pointer to memory location to place results + * length: number of bytes to read + * Internally, this routine uses the values from the cis base regs (0x9-0xB) + * to form an SDIO-space address to read the data from. + */ +extern int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, + u8 *cis, uint length); + +/* Synchronous access to device (client) core registers via CMD53 to F1. + * addr: backplane address (i.e. >= regsva from attach) + * size: register width in bytes (2 or 4) + * data: data for register write + */ +extern u32 +brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size); + +extern u32 +brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size, + u32 data); + +/* Indicate if last reg read/write failed */ +extern bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card); + +/* Buffer transfer to/from device (client) core via cmd53. + * fn: function number + * addr: backplane address (i.e. >= regsva from attach) + * flags: backplane width, address increment, sync/async + * buf: pointer to memory data buffer + * nbytes: number of bytes to transfer to/from buf + * pkt: pointer to packet associated with buf (if any) + * complete: callback function for command completion (async only) + * handle: handle for completion callback (first arg in callback) + * Returns 0 or error code. + * NOTE: Async operation is not currently supported. + */ +extern int +brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes, void *pkt, + void (*complete)(void *handle, int status, + bool sync_waiting), + void *handle); +extern int +brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt, + void (*complete)(void *handle, int status, + bool sync_waiting), + void *handle); + +/* Flags bits */ +#define SDIO_REQ_4BYTE 0x1 /* Four-byte target (backplane) width (vs. two-byte) */ +#define SDIO_REQ_FIXED 0x2 /* Fixed address (FIFO) (vs. incrementing address) */ +#define SDIO_REQ_ASYNC 0x4 /* Async request (vs. sync request) */ + +/* Pending (non-error) return code */ +#define BCME_PENDING 1 + +/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only). + * rw: read or write (0/1) + * addr: direct SDIO address + * buf: pointer to memory data buffer + * nbytes: number of bytes to transfer to/from buf + * Returns 0 or error code. + */ +extern int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr, + u8 *buf, uint nbytes); + +/* Issue an abort to the specified function */ +extern int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn); + +/* Returns the "Device ID" of target device on the SDIO bus. */ +extern int brcmf_sdcard_query_device(struct brcmf_sdio_card *card); + +/* Miscellaneous knob tweaker. */ +extern int brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name, + void *params, int plen, void *arg, int len, + bool set); + +/* helper functions */ + +/* callback functions */ +struct brcmf_sdioh_driver { + /* attach to device */ + void *(*attach) (u16 vend_id, u16 dev_id, u16 bus, u16 slot, + u16 func, uint bustype, u32 regsva, void *param); + /* detach from device */ + void (*detach) (void *ch); +}; + +struct sdioh_info; + +/* platform specific/high level functions */ +extern int brcmf_sdio_function_init(void); +extern int brcmf_sdio_register(struct brcmf_sdioh_driver *driver); +extern void brcmf_sdio_unregister(void); +extern void brcmf_sdio_function_cleanup(void); +extern int brcmf_sdio_probe(struct device *dev); +extern int brcmf_sdio_remove(struct device *dev); + +/* Function to return current window addr */ +extern u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card); + +/* Allocate/init/free per-OS private data */ +extern int brcmf_sdioh_osinit(struct sdioh_info *sd); +extern void brcmf_sdioh_osfree(struct sdioh_info *sd); + +/* Core interrupt enable/disable of device interrupts */ +extern void brcmf_sdioh_dev_intr_on(struct sdioh_info *sd); +extern void brcmf_sdioh_dev_intr_off(struct sdioh_info *sd); + +/* attach, return handler on success, NULL if failed. + * The handler shall be provided by all subsequent calls. No local cache + * cfghdl points to the starting address of pci device mapped memory + */ +extern struct sdioh_info *brcmf_sdioh_attach(void *cfghdl, uint irq); +extern int brcmf_sdioh_detach(struct sdioh_info *si); + +extern int +brcmf_sdioh_interrupt_register(struct sdioh_info *si, + void (*sdioh_cb_fn)(void *), void *argh); + +extern int brcmf_sdioh_interrupt_deregister(struct sdioh_info *si); + +/* enable or disable SD interrupt */ +extern int +brcmf_sdioh_interrupt_set(struct sdioh_info *si, bool enable_disable); + +/* read or write one byte using cmd52 */ +extern int +brcmf_sdioh_request_byte(struct sdioh_info *si, uint rw, uint fnc, uint addr, + u8 *byte); + +/* read or write 2/4 bytes using cmd53 */ +extern int +brcmf_sdioh_request_word(struct sdioh_info *si, uint cmd_type, + uint rw, uint fnc, uint addr, + u32 *word, uint nbyte); + +/* read or write any buffer using cmd53 */ +extern int +brcmf_sdioh_request_buffer(struct sdioh_info *si, uint pio_dma, + uint fix_inc, uint rw, uint fnc_num, + u32 addr, uint regwidth, + u32 buflen, u8 *buffer, struct sk_buff *pkt); + +/* get cis data */ +extern int +brcmf_sdioh_cis_read(struct sdioh_info *si, uint fuc, u8 *cis, u32 length); + +extern int +brcmf_sdioh_cfg_read(struct sdioh_info *si, uint fuc, u32 addr, u8 *data); +extern int +brcmf_sdioh_cfg_write(struct sdioh_info *si, uint fuc, u32 addr, u8 *data); + +/* handle iovars */ +extern int brcmf_sdioh_iovar_op(struct sdioh_info *si, const char *name, + void *params, int plen, void *arg, int len, bool set); + +/* Issue abort to the specified function and clear controller as needed */ +extern int brcmf_sdioh_abort(struct sdioh_info *si, uint fnc); + +/* Watchdog timer interface for pm ops */ +extern void brcmf_sdio_wdtmr_enable(bool enable); + +extern uint sd_msglevel; /* Debug message level */ + +extern struct brcmf_sdmmc_instance *gInstance; + +#endif /* _BRCM_SDH_H_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/sdioh.h b/drivers/staging/brcm80211/brcmfmac/sdioh.h deleted file mode 100644 index f96aaf9cec74..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/sdioh.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SDIOH_H -#define _SDIOH_H - -#define SD_SysAddr 0x000 -#define SD_BlockSize 0x004 -#define SD_BlockCount 0x006 -#define SD_Arg0 0x008 -#define SD_Arg1 0x00A -#define SD_TransferMode 0x00C -#define SD_Command 0x00E -#define SD_Response0 0x010 -#define SD_Response1 0x012 -#define SD_Response2 0x014 -#define SD_Response3 0x016 -#define SD_Response4 0x018 -#define SD_Response5 0x01A -#define SD_Response6 0x01C -#define SD_Response7 0x01E -#define SD_BufferDataPort0 0x020 -#define SD_BufferDataPort1 0x022 -#define SD_PresentState 0x024 -#define SD_HostCntrl 0x028 -#define SD_PwrCntrl 0x029 -#define SD_BlockGapCntrl 0x02A -#define SD_WakeupCntrl 0x02B -#define SD_ClockCntrl 0x02C -#define SD_TimeoutCntrl 0x02E -#define SD_SoftwareReset 0x02F -#define SD_IntrStatus 0x030 -#define SD_ErrorIntrStatus 0x032 -#define SD_IntrStatusEnable 0x034 -#define SD_ErrorIntrStatusEnable 0x036 -#define SD_IntrSignalEnable 0x038 -#define SD_ErrorIntrSignalEnable 0x03A -#define SD_CMD12ErrorStatus 0x03C -#define SD_Capabilities 0x040 -#define SD_Capabilities_Reserved 0x044 -#define SD_MaxCurCap 0x048 -#define SD_MaxCurCap_Reserved 0x04C -#define SD_ADMA_SysAddr 0x58 -#define SD_SlotInterruptStatus 0x0FC -#define SD_HostControllerVersion 0x0FE - -/* SD specific registers in PCI config space */ -#define SD_SlotInfo 0x40 - -#endif /* _SDIOH_H */ diff --git a/drivers/staging/brcm80211/brcmfmac/sdiovar.h b/drivers/staging/brcm80211/brcmfmac/sdiovar.h deleted file mode 100644 index d1cfa5f0a982..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/sdiovar.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _sdiovar_h_ -#define _sdiovar_h_ - -typedef struct sdreg { - int func; - int offset; - int value; -} sdreg_t; - -/* Common msglevel constants */ -#define SDH_ERROR_VAL 0x0001 /* Error */ -#define SDH_TRACE_VAL 0x0002 /* Trace */ -#define SDH_INFO_VAL 0x0004 /* Info */ -#define SDH_DEBUG_VAL 0x0008 /* Debug */ -#define SDH_DATA_VAL 0x0010 /* Data */ -#define SDH_CTRL_VAL 0x0020 /* Control Regs */ -#define SDH_LOG_VAL 0x0040 /* Enable bcmlog */ -#define SDH_DMA_VAL 0x0080 /* DMA */ - -#define NUM_PREV_TRANSACTIONS 16 - -#endif /* _sdiovar_h_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 1827b0bf9201..821206d3e536 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -16,336 +16,325 @@ #include #include - -#include - -#include - -#include -#include -#include -#include - +#include #include #include #include #include #include #include -#include - -#include #include -#include -#include +#include +#include +#include -void sdioh_sdio_set_host_pm_flags(int flag); +#include +#include +#include +#include "dhd.h" +#include "wl_cfg80211.h" static struct sdio_func *cfg80211_sdio_func; -static struct wl_dev *wl_cfg80211_dev; +static struct brcmf_cfg80211_dev *cfg80211_dev; static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; -u32 wl_dbg_level = WL_DBG_ERR; - -#define WL_4329_FW_FILE "brcm/bcm4329-fullmac-4.bin" -#define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt" +u32 brcmf_dbg_level = WL_DBG_ERR; /* ** cfg80211_ops api/callback list */ -static s32 wl_cfg80211_change_iface(struct wiphy *wiphy, - struct net_device *ndev, - enum nl80211_iftype type, u32 *flags, - struct vif_params *params); -static s32 __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, - struct cfg80211_scan_request *request, - struct cfg80211_ssid *this_ssid); -static s32 wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, - struct cfg80211_scan_request *request); -static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); -static s32 wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_ibss_params *params); -static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, - struct net_device *dev); -static s32 wl_cfg80211_get_station(struct wiphy *wiphy, - struct net_device *dev, u8 *mac, - struct station_info *sinfo); -static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, - struct net_device *dev, bool enabled, - s32 timeout); -static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, - struct net_device *dev, - const u8 *addr, - const struct cfg80211_bitrate_mask - *mask); -static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_connect_params *sme); -static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, - u16 reason_code); -static s32 wl_cfg80211_set_tx_power(struct wiphy *wiphy, +static s32 brcmf_cfg80211_change_iface(struct wiphy *wiphy, + struct net_device *ndev, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params); +static s32 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_scan_request *request, + struct cfg80211_ssid *this_ssid); +static s32 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_scan_request *request); +static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed); +static s32 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_ibss_params *params); +static s32 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, + struct net_device *dev); +static s32 brcmf_cfg80211_get_station(struct wiphy *wiphy, + struct net_device *dev, u8 *mac, + struct station_info *sinfo); +static s32 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *dev, bool enabled, + s32 timeout); +static s32 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, + struct net_device *dev, + const u8 *addr, + const struct cfg80211_bitrate_mask + *mask); +static int brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_connect_params *sme); +static s32 brcmf_cfg80211_disconnect(struct wiphy *wiphy, + struct net_device *dev, + u16 reason_code); +static s32 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type, s32 dbm); -static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm); -static s32 wl_cfg80211_config_default_key(struct wiphy *wiphy, +static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm); +static s32 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, bool unicast, bool multicast); -static s32 wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, +static s32 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params *params); -static s32 wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, +static s32 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, bool pairwise, const u8 *mac_addr); -static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, +static s32 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params * params)); -static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, +static s32 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx); -static s32 wl_cfg80211_resume(struct wiphy *wiphy); -static s32 wl_cfg80211_suspend(struct wiphy *wiphy); -static s32 wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, +static s32 brcmf_cfg80211_resume(struct wiphy *wiphy); +static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, + struct cfg80211_wowlan *wow); +static s32 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_pmksa *pmksa); -static s32 wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, +static s32 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_pmksa *pmksa); -static s32 wl_cfg80211_flush_pmksa(struct wiphy *wiphy, +static s32 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev); /* ** event & event Q handlers for cfg80211 interfaces */ -static s32 wl_create_event_handler(struct wl_priv *wl); -static void wl_destroy_event_handler(struct wl_priv *wl); -static s32 wl_event_handler(void *data); -static void wl_init_eq(struct wl_priv *wl); -static void wl_flush_eq(struct wl_priv *wl); -static void wl_lock_eq(struct wl_priv *wl); -static void wl_unlock_eq(struct wl_priv *wl); -static void wl_init_eq_lock(struct wl_priv *wl); -static void wl_init_eloop_handler(struct wl_event_loop *el); -static struct wl_event_q *wl_deq_event(struct wl_priv *wl); -static s32 wl_enq_event(struct wl_priv *wl, u32 type, - const wl_event_msg_t *msg, void *data); -static void wl_put_event(struct wl_event_q *e); -static void wl_wakeup_event(struct wl_priv *wl); -static s32 wl_notify_connect_status(struct wl_priv *wl, - struct net_device *ndev, - const wl_event_msg_t *e, void *data); -static s32 wl_notify_roaming_status(struct wl_priv *wl, - struct net_device *ndev, - const wl_event_msg_t *e, void *data); -static s32 wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); -static s32 wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data, - bool completed); -static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); -static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data); +static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv); +static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_event_handler(void *data); +static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv); +static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv); +static void brcmf_lock_eq(struct brcmf_cfg80211_priv *cfg_priv); +static void brcmf_unlock_eq(struct brcmf_cfg80211_priv *cfg_priv); +static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv *cfg_priv); +static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el); +static struct brcmf_cfg80211_event_q * +brcmf_deq_event(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 type, + const struct brcmf_event_msg *msg, void *data); +static void brcmf_put_event(struct brcmf_cfg80211_event_q *e); +static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *ndev, + const struct brcmf_event_msg *e, + void *data); +static s32 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *ndev, + const struct brcmf_event_msg *e, + void *data); +static s32 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *ndev, + const struct brcmf_event_msg *e, + void *data); +static s32 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *ndev, + const struct brcmf_event_msg *e, void *data, + bool completed); +static s32 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *ndev, + const struct brcmf_event_msg *e, void *data); +static s32 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *ndev, + const struct brcmf_event_msg *e, void *data); /* ** register/deregister sdio function */ -struct sdio_func *wl_cfg80211_get_sdio_func(void); -static void wl_clear_sdio_func(void); +static void brcmf_clear_sdio_func(void); /* ** ioctl utilites */ -static s32 wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf, +static s32 brcmf_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf, s32 buf_len); -static __used s32 wl_dev_bufvar_set(struct net_device *dev, s8 *name, +static __used s32 brcmf_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len); -static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val); -static s32 wl_dev_intvar_get(struct net_device *dev, s8 *name, +static s32 brcmf_dev_intvar_set(struct net_device *dev, s8 *name, s32 val); +static s32 brcmf_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval); -static s32 wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, +static s32 brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len); /* ** cfg80211 set_wiphy_params utilities */ -static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold); -static s32 wl_set_rts(struct net_device *dev, u32 frag_threshold); -static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l); +static s32 brcmf_set_frag(struct net_device *dev, u32 frag_threshold); +static s32 brcmf_set_rts(struct net_device *dev, u32 frag_threshold); +static s32 brcmf_set_retry(struct net_device *dev, u32 retry, bool l); /* ** wl profile utilities */ -static s32 wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, - void *data, s32 item); -static void *wl_read_prof(struct wl_priv *wl, s32 item); -static void wl_init_prof(struct wl_profile *prof); +static s32 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv, + const struct brcmf_event_msg *e, + void *data, s32 item); +static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item); +static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof); /* ** cfg80211 connect utilites */ -static s32 wl_set_wpa_version(struct net_device *dev, +static s32 brcmf_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme); -static s32 wl_set_auth_type(struct net_device *dev, +static s32 brcmf_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme); -static s32 wl_set_set_cipher(struct net_device *dev, +static s32 brcmf_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme); -static s32 wl_set_key_mgmt(struct net_device *dev, +static s32 brcmf_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme); -static s32 wl_set_set_sharedkey(struct net_device *dev, +static s32 brcmf_set_set_sharedkey(struct net_device *dev, struct cfg80211_connect_params *sme); -static s32 wl_get_assoc_ies(struct wl_priv *wl); -static void wl_clear_assoc_ies(struct wl_priv *wl); -static void wl_ch_to_chanspec(int ch, - struct wl_join_params *join_params, size_t *join_params_size); +static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv); +static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv); +static void brcmf_ch_to_chanspec(int ch, + struct brcmf_join_params *join_params, size_t *join_params_size); /* ** information element utilities */ -static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v); -static s32 wl_mode_to_nl80211_iftype(s32 mode); -static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface, +static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv, + u8 t, u8 l, u8 *v); +static s32 brcmf_mode_to_nl80211_iftype(s32 mode); +static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface, struct device *dev); -static void wl_free_wdev(struct wl_priv *wl); -static s32 wl_inform_bss(struct wl_priv *wl); -static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi); -static s32 wl_update_bss_info(struct wl_priv *wl); -static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, +static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, + struct brcmf_bss_info *bi); +static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, const u8 *mac_addr, struct key_params *params); /* ** key indianess swap utilities */ -static void swap_key_from_BE(struct wl_wsec_key *key); -static void swap_key_to_BE(struct wl_wsec_key *key); +static void swap_key_from_BE(struct brcmf_wsec_key *key); +static void swap_key_to_BE(struct brcmf_wsec_key *key); /* -** wl_priv memory init/deinit utilities +** brcmf_cfg80211_priv memory init/deinit utilities */ -static s32 wl_init_priv_mem(struct wl_priv *wl); -static void wl_deinit_priv_mem(struct wl_priv *wl); +static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv); +static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv); -static void wl_delay(u32 ms); +static void brcmf_delay(u32 ms); /* ** store/restore cfg80211 instance data */ -static void wl_set_drvdata(struct wl_dev *dev, void *data); -static void *wl_get_drvdata(struct wl_dev *dev); +static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data); +static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev); /* ** ibss mode utilities */ -static bool wl_is_ibssmode(struct wl_priv *wl); +static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv); /* ** dongle up/down , default configuration utilities */ -static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e); -static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e); -static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e); -static void wl_link_down(struct wl_priv *wl); -static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype); -static s32 __wl_cfg80211_up(struct wl_priv *wl); -static s32 __wl_cfg80211_down(struct wl_priv *wl); -static s32 wl_dongle_probecap(struct wl_priv *wl); -static void wl_init_conf(struct wl_conf *conf); +static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv, + const struct brcmf_event_msg *e); +static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv, + const struct brcmf_event_msg *e); +static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv, + const struct brcmf_event_msg *e); +static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype); +static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv); +static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv); +static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf); /* ** dongle configuration utilities */ -#ifndef EMBEDDED_PLATFORM -static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype); -static s32 wl_dongle_country(struct net_device *ndev, u8 ccode); -static s32 wl_dongle_up(struct net_device *ndev, u32 up); -static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode); -static s32 wl_dongle_glom(struct net_device *ndev, u32 glom, - u32 dongle_align); -static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe, - s32 arp_ol); -static s32 wl_pattern_atoh(s8 *src, s8 *dst); -static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode); -static s32 wl_update_wiphybands(struct wl_priv *wl); -#endif /* !EMBEDDED_PLATFORM */ - -static s32 wl_dongle_eventmsg(struct net_device *ndev); -static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, - s32 scan_unassoc_time, s32 scan_passive_time); -static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock); -static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar, +static s32 brcmf_dongle_eventmsg(struct net_device *ndev); +static s32 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, + s32 scan_unassoc_time, s32 scan_passive_time); +static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv, + bool need_lock); +static s32 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout); /* ** iscan handler */ -static void wl_iscan_timer(unsigned long data); -static void wl_term_iscan(struct wl_priv *wl); -static s32 wl_init_iscan(struct wl_priv *wl); -static s32 wl_iscan_thread(void *data); -static s32 wl_dev_iovar_setbuf(struct net_device *dev, s8 *iovar, +static void brcmf_iscan_timer(unsigned long data); +static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_iscan_thread(void *data); +static s32 brcmf_dev_iovar_setbuf(struct net_device *dev, s8 *iovar, void *param, s32 paramlen, void *bufptr, s32 buflen); -static s32 wl_dev_iovar_getbuf(struct net_device *dev, s8 *iovar, +static s32 brcmf_dev_iovar_getbuf(struct net_device *dev, s8 *iovar, void *param, s32 paramlen, void *bufptr, s32 buflen); -static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, - u16 action); -static s32 wl_do_iscan(struct wl_priv *wl); -static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan); -static s32 wl_invoke_iscan(struct wl_priv *wl); -static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status, - struct wl_scan_results **bss_list); -static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted); -static void wl_init_iscan_eloop(struct wl_iscan_eloop *el); -static s32 wl_iscan_done(struct wl_priv *wl); -static s32 wl_iscan_pending(struct wl_priv *wl); -static s32 wl_iscan_inprogress(struct wl_priv *wl); -static s32 wl_iscan_aborted(struct wl_priv *wl); - -/* -** fw/nvram downloading handler -*/ -static void wl_init_fw(struct wl_fw_ctrl *fw); +static s32 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan, + struct brcmf_ssid *ssid, u16 action); +static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan); +static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, + u32 *status, + struct brcmf_scan_results **bss_list); +static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, + bool aborted); +static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el); +static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv); +static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv); /* * find most significant bit set */ -static __used u32 wl_find_msb(u16 bit16); +static __used u32 brcmf_find_msb(u16 bit16); /* * update pmklist to dongle */ -static __used s32 wl_update_pmklist(struct net_device *dev, - struct wl_pmk_list *pmk_list, s32 err); +static __used s32 brcmf_update_pmklist(struct net_device *dev, + struct brcmf_cfg80211_pmk_list *pmk_list, + s32 err); -static void wl_set_mpc(struct net_device *ndev, int mpc); +static void brcmf_set_mpc(struct net_device *ndev, int mpc); /* * debufs support */ -static int wl_debugfs_add_netdev_params(struct wl_priv *wl); -static void wl_debugfs_remove_netdev(struct wl_priv *wl); +static int +brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv); +static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv); -#define WL_PRIV_GET() \ +#define WL_PRIV_GET() \ ({ \ - struct wl_iface *ci; \ - if (unlikely(!(wl_cfg80211_dev && \ - (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \ + struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg80211_dev); \ + if (unlikely(!ci)) { \ WL_ERR("wl_cfg80211_dev is unavailable\n"); \ BUG(); \ - } \ - ci_to_wl(ci); \ + } \ + ci->cfg_priv; \ }) #define CHECK_SYS_UP() \ do { \ - struct wl_priv *wl = wiphy_to_wl(wiphy); \ - if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \ + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); \ + if (unlikely(!test_bit(WL_STATUS_READY, &cfg_priv->status))) { \ WL_INFO("device is not ready : status (%d)\n", \ - (int)wl->status); \ + (int)cfg_priv->status); \ return -EIO; \ } \ } while (0) -extern int dhd_wait_pend8021x(struct net_device *dev); #define CHAN2G(_channel, _freq, _flags) { \ .band = IEEE80211_BAND_2GHZ, \ .center_freq = (_freq), \ @@ -373,18 +362,18 @@ extern int dhd_wait_pend8021x(struct net_device *dev); } static struct ieee80211_rate __wl_rates[] = { - RATETAB_ENT(WLC_RATE_1M, 0), - RATETAB_ENT(WLC_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE), - RATETAB_ENT(WLC_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE), - RATETAB_ENT(WLC_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE), - RATETAB_ENT(WLC_RATE_6M, 0), - RATETAB_ENT(WLC_RATE_9M, 0), - RATETAB_ENT(WLC_RATE_12M, 0), - RATETAB_ENT(WLC_RATE_18M, 0), - RATETAB_ENT(WLC_RATE_24M, 0), - RATETAB_ENT(WLC_RATE_36M, 0), - RATETAB_ENT(WLC_RATE_48M, 0), - RATETAB_ENT(WLC_RATE_54M, 0), + RATETAB_ENT(BRCM_RATE_1M, 0), + RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE), + RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE), + RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE), + RATETAB_ENT(BRCM_RATE_6M, 0), + RATETAB_ENT(BRCM_RATE_9M, 0), + RATETAB_ENT(BRCM_RATE_12M, 0), + RATETAB_ENT(BRCM_RATE_18M, 0), + RATETAB_ENT(BRCM_RATE_24M, 0), + RATETAB_ENT(BRCM_RATE_36M, 0), + RATETAB_ENT(BRCM_RATE_48M, 0), + RATETAB_ENT(BRCM_RATE_54M, 0), }; #define wl_a_rates (__wl_rates + 4) @@ -521,7 +510,7 @@ static const u32 __wl_cipher_suites[] = { WLAN_CIPHER_SUITE_AES_CMAC, }; -static void swap_key_from_BE(struct wl_wsec_key *key) +static void swap_key_from_BE(struct brcmf_wsec_key *key) { key->index = cpu_to_le32(key->index); key->len = cpu_to_le32(key->len); @@ -532,7 +521,7 @@ static void swap_key_from_BE(struct wl_wsec_key *key) key->iv_initialized = cpu_to_le32(key->iv_initialized); } -static void swap_key_to_BE(struct wl_wsec_key *key) +static void swap_key_to_BE(struct brcmf_wsec_key *key) { key->index = le32_to_cpu(key->index); key->len = le32_to_cpu(key->len); @@ -544,10 +533,10 @@ static void swap_key_to_BE(struct wl_wsec_key *key) } static s32 -wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len) +brcmf_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len) { struct ifreq ifr; - struct wl_ioctl ioc; + struct brcmf_ioctl ioc; mm_segment_t fs; s32 err = 0; @@ -567,11 +556,11 @@ wl_dev_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len) } static s32 -wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, +brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, enum nl80211_iftype type, u32 *flags, struct vif_params *params) { - struct wl_priv *wl = wiphy_to_wl(wiphy); + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); struct wireless_dev *wdev; s32 infra = 0; s32 err = 0; @@ -586,11 +575,11 @@ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, type); return -EOPNOTSUPP; case NL80211_IFTYPE_ADHOC: - wl->conf->mode = WL_MODE_IBSS; + cfg_priv->conf->mode = WL_MODE_IBSS; infra = 0; break; case NL80211_IFTYPE_STATION: - wl->conf->mode = WL_MODE_BSS; + cfg_priv->conf->mode = WL_MODE_BSS; infra = 1; break; default: @@ -599,7 +588,7 @@ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, } infra = cpu_to_le32(infra); - err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra)); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_INFRA, &infra, sizeof(infra)); if (unlikely(err)) { WL_ERR("WLC_SET_INFRA error (%d)\n", err); err = -EAGAIN; @@ -609,7 +598,7 @@ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, } WL_INFO("IF Type = %s\n", - (wl->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra"); + (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra"); done: WL_TRACE("Exit\n"); @@ -617,7 +606,8 @@ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, return err; } -static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid) +static void wl_iscan_prep(struct brcmf_scan_params *params, + struct brcmf_ssid *ssid) { memcpy(params->bssid, ether_bcast, ETH_ALEN); params->bss_type = DOT11_BSSTYPE_ANY; @@ -633,58 +623,59 @@ static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid) params->passive_time = cpu_to_le32(params->passive_time); params->home_time = cpu_to_le32(params->home_time); if (ssid && ssid->SSID_len) - memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t)); + memcpy(¶ms->ssid, ssid, sizeof(struct brcmf_ssid)); } static s32 -wl_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param, +brcmf_dev_iovar_setbuf(struct net_device *dev, s8 * iovar, void *param, s32 paramlen, void *bufptr, s32 buflen) { s32 iolen; - iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); + iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen); BUG_ON(!iolen); - return wl_dev_ioctl(dev, WLC_SET_VAR, bufptr, iolen); + return brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, bufptr, iolen); } static s32 -wl_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param, +brcmf_dev_iovar_getbuf(struct net_device *dev, s8 * iovar, void *param, s32 paramlen, void *bufptr, s32 buflen) { s32 iolen; - iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); + iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen); BUG_ON(!iolen); - return wl_dev_ioctl(dev, WLC_GET_VAR, bufptr, buflen); + return brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, bufptr, buflen); } static s32 -wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action) +brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan, + struct brcmf_ssid *ssid, u16 action) { - s32 params_size = - (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params)); - struct wl_iscan_params *params; + s32 params_size = (BRCMF_SCAN_PARAMS_FIXED_SIZE + + offsetof(struct brcmf_iscan_params, params)); + struct brcmf_iscan_params *params; s32 err = 0; if (ssid && ssid->SSID_len) - params_size += sizeof(struct wlc_ssid); + params_size += sizeof(struct brcmf_ssid); params = kzalloc(params_size, GFP_KERNEL); if (unlikely(!params)) return -ENOMEM; - BUG_ON(params_size >= WLC_IOCTL_SMLEN); + BUG_ON(params_size >= BRCMF_C_IOCTL_SMLEN); wl_iscan_prep(¶ms->params, ssid); - params->version = cpu_to_le32(ISCAN_REQ_VERSION); + params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION); params->action = cpu_to_le16(action); params->scan_duration = cpu_to_le16(0); - /* params_size += offsetof(wl_iscan_params_t, params); */ - err = wl_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size, - iscan->ioctl_buf, WLC_IOCTL_SMLEN); + /* params_size += offsetof(struct brcmf_iscan_params, params); */ + err = brcmf_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size, + iscan->ioctl_buf, BRCMF_C_IOCTL_SMLEN); if (unlikely(err)) { if (err == -EBUSY) { WL_INFO("system busy : iscan canceled\n"); @@ -696,11 +687,11 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action) return err; } -static s32 wl_do_iscan(struct wl_priv *wl) +static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); - struct net_device *ndev = wl_to_ndev(wl); - struct wlc_ssid ssid; + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); + struct net_device *ndev = cfg_to_ndev(cfg_priv); + struct brcmf_ssid ssid; s32 passive_scan; s32 err = 0; @@ -709,16 +700,16 @@ static s32 wl_do_iscan(struct wl_priv *wl) iscan->state = WL_ISCAN_STATE_SCANING; - passive_scan = wl->active_scan ? 0 : 1; - err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN, + passive_scan = cfg_priv->active_scan ? 0 : 1; + err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN, &passive_scan, sizeof(passive_scan)); if (unlikely(err)) { WL_ERR("error (%d)\n", err); return err; } - wl_set_mpc(ndev, 0); - wl->iscan_kickstart = true; - wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START); + brcmf_set_mpc(ndev, 0); + cfg_priv->iscan_kickstart = true; + brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START); mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); iscan->timer_on = 1; @@ -726,30 +717,30 @@ static s32 wl_do_iscan(struct wl_priv *wl) } static s32 -__wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, +__brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_scan_request *request, struct cfg80211_ssid *this_ssid) { - struct wl_priv *wl = ndev_to_wl(ndev); + struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); struct cfg80211_ssid *ssids; - struct wl_scan_req *sr = wl_to_sr(wl); + struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int; s32 passive_scan; bool iscan_req; bool spec_scan; s32 err = 0; - if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) { - WL_ERR("Scanning already : status (%d)\n", (int)wl->status); + if (unlikely(test_bit(WL_STATUS_SCANNING, &cfg_priv->status))) { + WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status); return -EAGAIN; } - if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) { - WL_ERR("Scanning being aborted : status (%d)\n", - (int)wl->status); + if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status))) { + WL_ERR("Scanning being aborted : status (%lu)\n", + cfg_priv->status); return -EAGAIN; } - if (test_bit(WL_STATUS_CONNECTING, &wl->status)) { - WL_ERR("Connecting : status (%d)\n", - (int)wl->status); + if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) { + WL_ERR("Connecting : status (%lu)\n", + cfg_priv->status); return -EAGAIN; } @@ -758,7 +749,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, if (request) { /* scan bss */ ssids = request->ssids; - if (wl->iscan_on && (!ssids || !ssids->ssid_len)) + if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len)) iscan_req = true; } else { /* scan in ibss */ @@ -766,10 +757,10 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, ssids = this_ssid; } - wl->scan_request = request; - set_bit(WL_STATUS_SCANNING, &wl->status); + cfg_priv->scan_request = request; + set_bit(WL_STATUS_SCANNING, &cfg_priv->status); if (iscan_req) { - err = wl_do_iscan(wl); + err = brcmf_do_iscan(cfg_priv); if (likely(!err)) return err; else @@ -788,15 +779,15 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, WL_SCAN("Broadcast scan\n"); } - passive_scan = wl->active_scan ? 0 : 1; - err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN, + passive_scan = cfg_priv->active_scan ? 0 : 1; + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_PASSIVE_SCAN, &passive_scan, sizeof(passive_scan)); if (unlikely(err)) { WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); goto scan_out; } - wl_set_mpc(ndev, 0); - err = wl_dev_ioctl(ndev, WLC_SCAN, &sr->ssid, + brcmf_set_mpc(ndev, 0); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN, &sr->ssid, sizeof(sr->ssid)); if (err) { if (err == -EBUSY) { @@ -805,7 +796,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, } else { WL_ERR("WLC_SCAN error (%d)\n", err); } - wl_set_mpc(ndev, 1); + brcmf_set_mpc(ndev, 1); goto scan_out; } } @@ -813,13 +804,13 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, return 0; scan_out: - clear_bit(WL_STATUS_SCANNING, &wl->status); - wl->scan_request = NULL; + clear_bit(WL_STATUS_SCANNING, &cfg_priv->status); + cfg_priv->scan_request = NULL; return err; } static s32 -wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, +brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_scan_request *request) { s32 err = 0; @@ -828,7 +819,7 @@ wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, CHECK_SYS_UP(); - err = __wl_cfg80211_scan(wiphy, ndev, request, NULL); + err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL); if (unlikely(err)) WL_ERR("scan error (%d)\n", err); @@ -836,17 +827,18 @@ wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, return err; } -static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val) +static s32 brcmf_dev_intvar_set(struct net_device *dev, s8 *name, s32 val) { - s8 buf[WLC_IOCTL_SMLEN]; + s8 buf[BRCMF_C_IOCTL_SMLEN]; u32 len; s32 err = 0; val = cpu_to_le32(val); - len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf)); + len = brcmu_mkiovar(name, (char *)(&val), sizeof(val), buf, + sizeof(buf)); BUG_ON(!len); - err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len); + err = brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, buf, len); if (unlikely(err)) WL_ERR("error (%d)\n", err); @@ -854,10 +846,10 @@ static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val) } static s32 -wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval) +brcmf_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval) { union { - s8 buf[WLC_IOCTL_SMLEN]; + s8 buf[BRCMF_C_IOCTL_SMLEN]; s32 val; } var; u32 len; @@ -865,10 +857,10 @@ wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval) s32 err = 0; len = - bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), + brcmu_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), sizeof(var.buf)); BUG_ON(!len); - err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len); + err = brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, &var, len); if (unlikely(err)) WL_ERR("error (%d)\n", err); @@ -877,35 +869,35 @@ wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval) return err; } -static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold) +static s32 brcmf_set_rts(struct net_device *dev, u32 rts_threshold) { s32 err = 0; - err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold); + err = brcmf_dev_intvar_set(dev, "rtsthresh", rts_threshold); if (unlikely(err)) WL_ERR("Error (%d)\n", err); return err; } -static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold) +static s32 brcmf_set_frag(struct net_device *dev, u32 frag_threshold) { s32 err = 0; - err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold); + err = brcmf_dev_intvar_set(dev, "fragthresh", frag_threshold); if (unlikely(err)) WL_ERR("Error (%d)\n", err); return err; } -static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l) +static s32 brcmf_set_retry(struct net_device *dev, u32 retry, bool l) { s32 err = 0; - u32 cmd = (l ? WLC_SET_LRL : WLC_SET_SRL); + u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL); retry = cpu_to_le32(retry); - err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry)); + err = brcmf_dev_ioctl(dev, cmd, &retry, sizeof(retry)); if (unlikely(err)) { WL_ERR("cmd (%d) , error (%d)\n", cmd, err); return err; @@ -913,40 +905,40 @@ static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l) return err; } -static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) +static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) { - struct wl_priv *wl = wiphy_to_wl(wiphy); - struct net_device *ndev = wl_to_ndev(wl); + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); + struct net_device *ndev = cfg_to_ndev(cfg_priv); s32 err = 0; WL_TRACE("Enter\n"); CHECK_SYS_UP(); if (changed & WIPHY_PARAM_RTS_THRESHOLD && - (wl->conf->rts_threshold != wiphy->rts_threshold)) { - wl->conf->rts_threshold = wiphy->rts_threshold; - err = wl_set_rts(ndev, wl->conf->rts_threshold); + (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) { + cfg_priv->conf->rts_threshold = wiphy->rts_threshold; + err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold); if (!err) goto done; } if (changed & WIPHY_PARAM_FRAG_THRESHOLD && - (wl->conf->frag_threshold != wiphy->frag_threshold)) { - wl->conf->frag_threshold = wiphy->frag_threshold; - err = wl_set_frag(ndev, wl->conf->frag_threshold); + (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) { + cfg_priv->conf->frag_threshold = wiphy->frag_threshold; + err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold); if (!err) goto done; } if (changed & WIPHY_PARAM_RETRY_LONG - && (wl->conf->retry_long != wiphy->retry_long)) { - wl->conf->retry_long = wiphy->retry_long; - err = wl_set_retry(ndev, wl->conf->retry_long, true); + && (cfg_priv->conf->retry_long != wiphy->retry_long)) { + cfg_priv->conf->retry_long = wiphy->retry_long; + err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true); if (!err) goto done; } if (changed & WIPHY_PARAM_RETRY_SHORT - && (wl->conf->retry_short != wiphy->retry_short)) { - wl->conf->retry_short = wiphy->retry_short; - err = wl_set_retry(ndev, wl->conf->retry_short, false); + && (cfg_priv->conf->retry_short != wiphy->retry_short)) { + cfg_priv->conf->retry_short = wiphy->retry_short; + err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false); if (!err) goto done; } @@ -957,11 +949,11 @@ static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) } static s32 -wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, +brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) { - struct wl_priv *wl = wiphy_to_wl(wiphy); - struct wl_join_params join_params; + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); + struct brcmf_join_params join_params; size_t join_params_size = 0; s32 err = 0; s32 wsec = 0; @@ -977,6 +969,8 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, return -EOPNOTSUPP; } + set_bit(WL_STATUS_CONNECTING, &cfg_priv->status); + if (params->bssid) WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n", params->bssid[0], params->bssid[1], params->bssid[2], @@ -1018,7 +1012,7 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, if (params->privacy) wsec |= WEP_ENABLED; - err = wl_dev_intvar_set(dev, "wsec", wsec); + err = brcmf_dev_intvar_set(dev, "wsec", wsec); if (unlikely(err)) { WL_ERR("wsec failed (%d)\n", err); goto done; @@ -1030,14 +1024,14 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, else bcnprd = cpu_to_le32(100); - err = wl_dev_ioctl(dev, WLC_SET_BCNPRD, &bcnprd, sizeof(bcnprd)); + err = brcmf_dev_ioctl(dev, BRCM_SET_BCNPRD, &bcnprd, sizeof(bcnprd)); if (unlikely(err)) { WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err); goto done; } /* Configure required join parameter */ - memset(&join_params, 0, sizeof(wl_join_params_t)); + memset(&join_params, 0, sizeof(struct brcmf_join_params)); /* SSID */ join_params.ssid.SSID_len = @@ -1045,67 +1039,69 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, memcpy(join_params.ssid.SSID, params->ssid, join_params.ssid.SSID_len); join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len); join_params_size = sizeof(join_params.ssid); - wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID); + brcmf_update_prof(cfg_priv, NULL, &join_params.ssid, WL_PROF_SSID); /* BSSID */ if (params->bssid) { memcpy(join_params.params.bssid, params->bssid, ETH_ALEN); - join_params_size = - sizeof(join_params.ssid) + WL_ASSOC_PARAMS_FIXED_SIZE; + join_params_size = sizeof(join_params.ssid) + + BRCMF_ASSOC_PARAMS_FIXED_SIZE; } else { memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); } - wl_update_prof(wl, NULL, &join_params.params.bssid, WL_PROF_BSSID); + brcmf_update_prof(cfg_priv, NULL, + &join_params.params.bssid, WL_PROF_BSSID); /* Channel */ if (params->channel) { u32 target_channel; - wl->channel = + cfg_priv->channel = ieee80211_frequency_to_channel( params->channel->center_freq); if (params->channel_fixed) { /* adding chanspec */ - wl_ch_to_chanspec(wl->channel, + brcmf_ch_to_chanspec(cfg_priv->channel, &join_params, &join_params_size); } /* set channel for starter */ - target_channel = cpu_to_le32(wl->channel); - err = wl_dev_ioctl(dev, WLC_SET_CHANNEL, + target_channel = cpu_to_le32(cfg_priv->channel); + err = brcmf_dev_ioctl(dev, BRCM_SET_CHANNEL, &target_channel, sizeof(target_channel)); if (unlikely(err)) { WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err); goto done; } } else - wl->channel = 0; + cfg_priv->channel = 0; - wl->ibss_starter = false; + cfg_priv->ibss_starter = false; - err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size); + err = brcmf_dev_ioctl(dev, BRCMF_C_SET_SSID, + &join_params, join_params_size); if (unlikely(err)) { WL_ERR("WLC_SET_SSID failed (%d)\n", err); goto done; } - set_bit(WL_STATUS_CONNECTING, &wl->status); - done: + if (err) + clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); WL_TRACE("Exit\n"); return err; } -static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) +static s32 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) { - struct wl_priv *wl = wiphy_to_wl(wiphy); + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); s32 err = 0; WL_TRACE("Enter\n"); CHECK_SYS_UP(); - wl_link_down(wl); + brcmf_link_down(cfg_priv); WL_TRACE("Exit\n"); @@ -1113,10 +1109,10 @@ static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) } static s32 -wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) +brcmf_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) { - struct wl_priv *wl = ndev_to_wl(dev); - struct wl_security *sec; + struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev); + struct brcmf_cfg80211_security *sec; s32 val = 0; s32 err = 0; @@ -1127,21 +1123,21 @@ wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) else val = WPA_AUTH_DISABLED; WL_CONN("setting wpa_auth to 0x%0x\n", val); - err = wl_dev_intvar_set(dev, "wpa_auth", val); + err = brcmf_dev_intvar_set(dev, "wpa_auth", val); if (unlikely(err)) { WL_ERR("set wpa_auth failed (%d)\n", err); return err; } - sec = wl_read_prof(wl, WL_PROF_SEC); + sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); sec->wpa_versions = sme->crypto.wpa_versions; return err; } static s32 -wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) +brcmf_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) { - struct wl_priv *wl = ndev_to_wl(dev); - struct wl_security *sec; + struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev); + struct brcmf_cfg80211_security *sec; s32 val = 0; s32 err = 0; @@ -1166,21 +1162,21 @@ wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) break; } - err = wl_dev_intvar_set(dev, "auth", val); + err = brcmf_dev_intvar_set(dev, "auth", val); if (unlikely(err)) { WL_ERR("set auth failed (%d)\n", err); return err; } - sec = wl_read_prof(wl, WL_PROF_SEC); + sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); sec->auth_type = sme->auth_type; return err; } static s32 -wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) +brcmf_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) { - struct wl_priv *wl = ndev_to_wl(dev); - struct wl_security *sec; + struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev); + struct brcmf_cfg80211_security *sec; s32 pval = 0; s32 gval = 0; s32 err = 0; @@ -1229,13 +1225,13 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) } WL_CONN("pval (%d) gval (%d)\n", pval, gval); - err = wl_dev_intvar_set(dev, "wsec", pval | gval); + err = brcmf_dev_intvar_set(dev, "wsec", pval | gval); if (unlikely(err)) { WL_ERR("error (%d)\n", err); return err; } - sec = wl_read_prof(wl, WL_PROF_SEC); + sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0]; sec->cipher_group = sme->crypto.cipher_group; @@ -1243,15 +1239,15 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) } static s32 -wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) +brcmf_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) { - struct wl_priv *wl = ndev_to_wl(dev); - struct wl_security *sec; + struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev); + struct brcmf_cfg80211_security *sec; s32 val = 0; s32 err = 0; if (sme->crypto.n_akm_suites) { - err = wl_dev_intvar_get(dev, "wpa_auth", &val); + err = brcmf_dev_intvar_get(dev, "wpa_auth", &val); if (unlikely(err)) { WL_ERR("could not get wpa_auth (%d)\n", err); return err; @@ -1285,31 +1281,31 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) } WL_CONN("setting wpa_auth to %d\n", val); - err = wl_dev_intvar_set(dev, "wpa_auth", val); + err = brcmf_dev_intvar_set(dev, "wpa_auth", val); if (unlikely(err)) { WL_ERR("could not set wpa_auth (%d)\n", err); return err; } } - sec = wl_read_prof(wl, WL_PROF_SEC); + sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); sec->wpa_auth = sme->crypto.akm_suites[0]; return err; } static s32 -wl_set_set_sharedkey(struct net_device *dev, +brcmf_set_set_sharedkey(struct net_device *dev, struct cfg80211_connect_params *sme) { - struct wl_priv *wl = ndev_to_wl(dev); - struct wl_security *sec; - struct wl_wsec_key key; + struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev); + struct brcmf_cfg80211_security *sec; + struct brcmf_wsec_key key; s32 val; s32 err = 0; WL_CONN("key len (%d)\n", sme->key_len); if (sme->key_len) { - sec = wl_read_prof(wl, WL_PROF_SEC); + sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n", sec->wpa_versions, sec->cipher_pairwise); if (! @@ -1325,7 +1321,7 @@ wl_set_set_sharedkey(struct net_device *dev, return -EINVAL; } memcpy(key.data, sme->key, key.len); - key.flags = WL_PRIMARY_KEY; + key.flags = BRCMF_PRIMARY_KEY; switch (sec->cipher_pairwise) { case WLAN_CIPHER_SUITE_WEP40: key.algo = CRYPTO_ALGO_WEP1; @@ -1343,7 +1339,7 @@ wl_set_set_sharedkey(struct net_device *dev, key.len, key.index, key.algo); WL_CONN("key \"%s\"\n", key.data); swap_key_from_BE(&key); - err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, + err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { WL_ERR("WLC_SET_KEY error (%d)\n", err); @@ -1352,7 +1348,7 @@ wl_set_set_sharedkey(struct net_device *dev, if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) { WL_CONN("set auth_type to shared key\n"); val = 1; /* shared key */ - err = wl_dev_intvar_set(dev, "auth", val); + err = brcmf_dev_intvar_set(dev, "auth", val); if (unlikely(err)) { WL_ERR("set auth failed (%d)\n", err); return err; @@ -1364,12 +1360,12 @@ wl_set_set_sharedkey(struct net_device *dev, } static s32 -wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, +brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { - struct wl_priv *wl = wiphy_to_wl(wiphy); + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); struct ieee80211_channel *chan = sme->channel; - struct wl_join_params join_params; + struct brcmf_join_params join_params; size_t join_params_size; s32 err = 0; @@ -1382,37 +1378,49 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, return -EOPNOTSUPP; } + set_bit(WL_STATUS_CONNECTING, &cfg_priv->status); + if (chan) { - wl->channel = + cfg_priv->channel = ieee80211_frequency_to_channel(chan->center_freq); WL_CONN("channel (%d), center_req (%d)\n", - wl->channel, chan->center_freq); + cfg_priv->channel, chan->center_freq); } else - wl->channel = 0; + cfg_priv->channel = 0; WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len); - err = wl_set_wpa_version(dev, sme); - if (unlikely(err)) - return err; + err = brcmf_set_wpa_version(dev, sme); + if (err) { + WL_ERR("wl_set_wpa_version failed (%d)\n", err); + goto done; + } - err = wl_set_auth_type(dev, sme); - if (unlikely(err)) - return err; + err = brcmf_set_auth_type(dev, sme); + if (err) { + WL_ERR("wl_set_auth_type failed (%d)\n", err); + goto done; + } - err = wl_set_set_cipher(dev, sme); - if (unlikely(err)) - return err; + err = brcmf_set_set_cipher(dev, sme); + if (err) { + WL_ERR("wl_set_set_cipher failed (%d)\n", err); + goto done; + } - err = wl_set_key_mgmt(dev, sme); - if (unlikely(err)) - return err; + err = brcmf_set_key_mgmt(dev, sme); + if (err) { + WL_ERR("wl_set_key_mgmt failed (%d)\n", err); + goto done; + } - err = wl_set_set_sharedkey(dev, sme); - if (unlikely(err)) - return err; + err = brcmf_set_set_sharedkey(dev, sme); + if (err) { + WL_ERR("wl_set_set_sharedkey failed (%d)\n", err); + goto done; + } - wl_update_prof(wl, NULL, sme->bssid, WL_PROF_BSSID); + brcmf_update_prof(cfg_priv, NULL, sme->bssid, WL_PROF_BSSID); /* ** Join with specific BSSID and cached SSID ** If SSID is zero join based on BSSID only @@ -1423,7 +1431,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len); memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len); join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len); - wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID); + brcmf_update_prof(cfg_priv, NULL, &join_params.ssid, WL_PROF_SSID); if (sme->bssid) memcpy(join_params.params.bssid, sme->bssid, ETH_ALEN); @@ -1435,52 +1443,54 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, join_params.ssid.SSID, join_params.ssid.SSID_len); } - wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size); - err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size); - if (unlikely(err)) { - WL_ERR("error (%d)\n", err); - return err; - } - set_bit(WL_STATUS_CONNECTING, &wl->status); + brcmf_ch_to_chanspec(cfg_priv->channel, + &join_params, &join_params_size); + err = brcmf_dev_ioctl(dev, BRCMF_C_SET_SSID, + &join_params, join_params_size); + if (err) + WL_ERR("WLC_SET_SSID failed (%d)\n", err); +done: + if (err) + clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); WL_TRACE("Exit\n"); return err; } static s32 -wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, +brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code) { - struct wl_priv *wl = wiphy_to_wl(wiphy); - scb_val_t scbval; + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); + struct brcmf_scb_val scbval; s32 err = 0; WL_TRACE("Enter. Reason code = %d\n", reason_code); CHECK_SYS_UP(); - clear_bit(WL_STATUS_CONNECTED, &wl->status); + clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status); scbval.val = reason_code; - memcpy(&scbval.ea, wl_read_prof(wl, WL_PROF_BSSID), ETH_ALEN); + memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN); scbval.val = cpu_to_le32(scbval.val); - err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval, - sizeof(scb_val_t)); + err = brcmf_dev_ioctl(dev, BRCMF_C_DISASSOC, &scbval, + sizeof(struct brcmf_scb_val)); if (unlikely(err)) WL_ERR("error (%d)\n", err); - wl->link_up = false; + cfg_priv->link_up = false; WL_TRACE("Exit\n"); return err; } static s32 -wl_cfg80211_set_tx_power(struct wiphy *wiphy, +brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type, s32 dbm) { - struct wl_priv *wl = wiphy_to_wl(wiphy); - struct net_device *ndev = wl_to_ndev(wl); + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); + struct net_device *ndev = cfg_to_ndev(cfg_priv); u16 txpwrmw; s32 err = 0; s32 disable = 0; @@ -1509,7 +1519,7 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy, /* Make sure radio is off or on as far as software is concerned */ disable = WL_RADIO_SW_DISABLE << 16; disable = cpu_to_le32(disable); - err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable)); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_RADIO, &disable, sizeof(disable)); if (unlikely(err)) WL_ERR("WLC_SET_RADIO error (%d)\n", err); @@ -1517,21 +1527,21 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy, txpwrmw = 0xffff; else txpwrmw = (u16) dbm; - err = wl_dev_intvar_set(ndev, "qtxpower", - (s32) (bcm_mw_to_qdbm(txpwrmw))); + err = brcmf_dev_intvar_set(ndev, "qtxpower", + (s32) (brcmu_mw_to_qdbm(txpwrmw))); if (unlikely(err)) WL_ERR("qtxpower error (%d)\n", err); - wl->conf->tx_power = dbm; + cfg_priv->conf->tx_power = dbm; done: WL_TRACE("Exit\n"); return err; } -static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) +static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) { - struct wl_priv *wl = wiphy_to_wl(wiphy); - struct net_device *ndev = wl_to_ndev(wl); + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); + struct net_device *ndev = cfg_to_ndev(cfg_priv); s32 txpwrdbm; u8 result; s32 err = 0; @@ -1539,14 +1549,14 @@ static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) WL_TRACE("Enter\n"); CHECK_SYS_UP(); - err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm); + err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm); if (unlikely(err)) { WL_ERR("error (%d)\n", err); goto done; } result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE); - *dbm = (s32) bcm_qdbm_to_mw(result); + *dbm = (s32) brcmu_qdbm_to_mw(result); done: WL_TRACE("Exit\n"); @@ -1554,7 +1564,7 @@ static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) } static s32 -wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, +brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, bool unicast, bool multicast) { u32 index; @@ -1565,7 +1575,7 @@ wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, WL_CONN("key index (%d)\n", key_idx); CHECK_SYS_UP(); - err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)); + err = brcmf_dev_ioctl(dev, BRCMF_C_GET_WSEC, &wsec, sizeof(wsec)); if (unlikely(err)) { WL_ERR("WLC_GET_WSEC error (%d)\n", err); goto done; @@ -1576,7 +1586,7 @@ wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, /* Just select a new current key */ index = (u32) key_idx; index = cpu_to_le32(index); - err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index, + err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY_PRIMARY, &index, sizeof(index)); if (unlikely(err)) WL_ERR("error (%d)\n", err); @@ -1587,10 +1597,10 @@ wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, } static s32 -wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, +brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, const u8 *mac_addr, struct key_params *params) { - struct wl_wsec_key key; + struct brcmf_wsec_key key; s32 err = 0; memset(&key, 0, sizeof(key)); @@ -1604,7 +1614,7 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, if (key.len == 0) { /* key delete */ swap_key_from_BE(&key); - err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); + err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { WL_ERR("key delete error (%d)\n", err); return err; @@ -1663,8 +1673,8 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, } swap_key_from_BE(&key); - dhd_wait_pend8021x(dev); - err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); + brcmf_netdev_wait_pend8021x(dev); + err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { WL_ERR("WLC_SET_KEY error (%d)\n", err); return err; @@ -1674,11 +1684,11 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, } static s32 -wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, +brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params *params) { - struct wl_wsec_key key; + struct brcmf_wsec_key key; s32 val; s32 wsec; s32 err = 0; @@ -1690,7 +1700,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, if (mac_addr) { WL_TRACE("Exit"); - return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params); + return brcmf_add_keyext(wiphy, dev, key_idx, mac_addr, params); } memset(&key, 0, sizeof(key)); @@ -1704,7 +1714,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, } memcpy(key.data, params->key, key.len); - key.flags = WL_PRIMARY_KEY; + key.flags = BRCMF_PRIMARY_KEY; switch (params->cipher) { case WLAN_CIPHER_SUITE_WEP40: key.algo = CRYPTO_ALGO_WEP1; @@ -1737,21 +1747,21 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, /* Set the new key/index */ swap_key_from_BE(&key); - err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); + err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { WL_ERR("WLC_SET_KEY error (%d)\n", err); goto done; } val = WEP_ENABLED; - err = wl_dev_intvar_get(dev, "wsec", &wsec); + err = brcmf_dev_intvar_get(dev, "wsec", &wsec); if (unlikely(err)) { WL_ERR("get wsec error (%d)\n", err); goto done; } wsec &= ~(WEP_ENABLED); wsec |= val; - err = wl_dev_intvar_set(dev, "wsec", wsec); + err = brcmf_dev_intvar_set(dev, "wsec", wsec); if (unlikely(err)) { WL_ERR("set wsec error (%d)\n", err); goto done; @@ -1759,7 +1769,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, val = 1; /* assume shared key. otherwise 0 */ val = cpu_to_le32(val); - err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)); + err = brcmf_dev_ioctl(dev, BRCMF_C_SET_AUTH, &val, sizeof(val)); if (unlikely(err)) WL_ERR("WLC_SET_AUTH error (%d)\n", err); done: @@ -1768,10 +1778,10 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, } static s32 -wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, +brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, bool pairwise, const u8 *mac_addr) { - struct wl_wsec_key key; + struct brcmf_wsec_key key; s32 err = 0; s32 val; s32 wsec; @@ -1781,13 +1791,13 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, memset(&key, 0, sizeof(key)); key.index = (u32) key_idx; - key.flags = WL_PRIMARY_KEY; + key.flags = BRCMF_PRIMARY_KEY; key.algo = CRYPTO_ALGO_OFF; WL_CONN("key index (%d)\n", key_idx); /* Set the new key/index */ swap_key_from_BE(&key); - err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); + err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { if (err == -EINVAL) { if (key.index >= DOT11_MAX_DEFAULT_KEYS) @@ -1802,7 +1812,7 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, } val = 0; - err = wl_dev_intvar_get(dev, "wsec", &wsec); + err = brcmf_dev_intvar_get(dev, "wsec", &wsec); if (unlikely(err)) { WL_ERR("get wsec error (%d)\n", err); /* Ignore this error, may happen during DISASSOC */ @@ -1811,7 +1821,7 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, } wsec &= ~(WEP_ENABLED); wsec |= val; - err = wl_dev_intvar_set(dev, "wsec", wsec); + err = brcmf_dev_intvar_set(dev, "wsec", wsec); if (unlikely(err)) { WL_ERR("set wsec error (%d)\n", err); /* Ignore this error, may happen during DISASSOC */ @@ -1821,7 +1831,7 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, val = 0; /* assume open key. otherwise 1 */ val = cpu_to_le32(val); - err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)); + err = brcmf_dev_ioctl(dev, BRCMF_C_SET_AUTH, &val, sizeof(val)); if (unlikely(err)) { WL_ERR("WLC_SET_AUTH error (%d)\n", err); /* Ignore this error, may happen during DISASSOC */ @@ -1833,14 +1843,14 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, } static s32 -wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, +brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params * params)) { struct key_params params; - struct wl_wsec_key key; - struct wl_priv *wl = wiphy_to_wl(wiphy); - struct wl_security *sec; + struct brcmf_wsec_key key; + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); + struct brcmf_cfg80211_security *sec; s32 wsec; s32 err = 0; @@ -1855,7 +1865,7 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, params.key_len = (u8) min_t(u8, WLAN_MAX_KEY_LEN, key.len); memcpy(params.key, key.data, params.key_len); - err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)); + err = brcmf_dev_ioctl(dev, BRCMF_C_GET_WSEC, &wsec, sizeof(wsec)); if (unlikely(err)) { WL_ERR("WLC_GET_WSEC error (%d)\n", err); /* Ignore this error, may happen during DISASSOC */ @@ -1865,7 +1875,7 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, wsec = le32_to_cpu(wsec); switch (wsec) { case WEP_ENABLED: - sec = wl_read_prof(wl, WL_PROF_SEC); + sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { params.cipher = WLAN_CIPHER_SUITE_WEP40; WL_CONN("WLAN_CIPHER_SUITE_WEP40\n"); @@ -1895,7 +1905,7 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, } static s32 -wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, +brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx) { WL_INFO("Not supported\n"); @@ -1905,15 +1915,15 @@ wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, } static s32 -wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, +brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, u8 *mac, struct station_info *sinfo) { - struct wl_priv *wl = wiphy_to_wl(wiphy); - scb_val_t scb_val; + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); + struct brcmf_scb_val scb_val; int rssi; s32 rate; s32 err = 0; - u8 *bssid = wl_read_prof(wl, WL_PROF_BSSID); + u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID); WL_TRACE("Enter\n"); CHECK_SYS_UP(); @@ -1930,7 +1940,7 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, } /* Report the current tx rate */ - err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)); + err = brcmf_dev_ioctl(dev, BRCMF_C_GET_RATE, &rate, sizeof(rate)); if (err) { WL_ERR("Could not get rate (%d)\n", err); } else { @@ -1940,10 +1950,10 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, WL_CONN("Rate %d Mbps\n", rate / 2); } - if (test_bit(WL_STATUS_CONNECTED, &wl->status)) { + if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { scb_val.val = 0; - err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val, - sizeof(scb_val_t)); + err = brcmf_dev_ioctl(dev, BRCMF_C_GET_RSSI, &scb_val, + sizeof(struct brcmf_scb_val)); if (unlikely(err)) { WL_ERR("Could not get rssi (%d)\n", err); } @@ -1959,7 +1969,7 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, } static s32 -wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, +brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, s32 timeout) { s32 pm; @@ -1972,7 +1982,7 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, pm = cpu_to_le32(pm); WL_INFO("power save %s\n", (pm ? "enabled" : "disabled")); - err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); + err = brcmf_dev_ioctl(dev, BRCMF_C_SET_PM, &pm, sizeof(pm)); if (unlikely(err)) { if (err == -ENODEV) WL_ERR("net_device is not ready yet\n"); @@ -1983,7 +1993,7 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, return err; } -static __used u32 wl_find_msb(u16 bit16) +static __used u32 brcmf_find_msb(u16 bit16) { u32 ret = 0; @@ -2011,7 +2021,7 @@ static __used u32 wl_find_msb(u16 bit16) } static s32 -wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, +brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, const u8 *addr, const struct cfg80211_bitrate_mask *mask) { @@ -2028,7 +2038,7 @@ wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, /* addr param is always NULL. ignore it */ /* Get current rateset */ - err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, + err = brcmf_dev_ioctl(dev, BRCM_GET_CURR_RATESET, &rateset, sizeof(rateset)); if (unlikely(err)) { WL_ERR("could not get current rateset (%d)\n", err); @@ -2037,9 +2047,9 @@ wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, rateset.count = le32_to_cpu(rateset.count); - legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy); + legacy = brcmf_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy); if (!legacy) - legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy); + legacy = brcmf_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy); val = wl_g_rates[legacy - 1].bitrate * 100000; @@ -2057,8 +2067,8 @@ wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, * Set rate override, * Since the is a/b/g-blind, both a/bg_rate are enforced. */ - err_bg = wl_dev_intvar_set(dev, "bg_rate", rate); - err_a = wl_dev_intvar_set(dev, "a_rate", rate); + err_bg = brcmf_dev_intvar_set(dev, "bg_rate", rate); + err_a = brcmf_dev_intvar_set(dev, "a_rate", rate); if (unlikely(err_bg && err_a)) { WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a); err = err_bg | err_a; @@ -2069,10 +2079,9 @@ wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, return err; } -static s32 wl_cfg80211_resume(struct wiphy *wiphy) +static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) { - struct wl_priv *wl = wiphy_to_wl(wiphy); - struct net_device *ndev = wl_to_ndev(wl); + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); /* * Check for WL_STATUS_READY before any function call which @@ -2082,23 +2091,21 @@ static s32 wl_cfg80211_resume(struct wiphy *wiphy) WL_TRACE("Enter\n"); #if defined(CONFIG_PM_SLEEP) - atomic_set(&dhd_mmc_suspend, false); + atomic_set(&brcmf_mmc_suspend, false); #endif /* defined(CONFIG_PM_SLEEP) */ - if (test_bit(WL_STATUS_READY, &wl->status)) { - /* Turn on Watchdog timer */ - wl_os_wd_timer(ndev, dhd_watchdog_ms); - wl_invoke_iscan(wiphy_to_wl(wiphy)); - } + if (test_bit(WL_STATUS_READY, &cfg_priv->status)) + brcmf_invoke_iscan(wiphy_to_cfg(wiphy)); WL_TRACE("Exit\n"); return 0; } -static s32 wl_cfg80211_suspend(struct wiphy *wiphy) +static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, + struct cfg80211_wowlan *wow) { - struct wl_priv *wl = wiphy_to_wl(wiphy); - struct net_device *ndev = wl_to_ndev(wl); + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); + struct net_device *ndev = cfg_to_ndev(cfg_priv); WL_TRACE("Enter\n"); @@ -2112,11 +2119,12 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy) * While going to suspend if associated with AP disassociate * from AP to save power while system is in suspended state */ - if (test_bit(WL_STATUS_CONNECTED, &wl->status) && - test_bit(WL_STATUS_READY, &wl->status)) { + if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) || + test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) && + test_bit(WL_STATUS_READY, &cfg_priv->status)) { WL_INFO("Disassociating from AP" " while entering suspend state\n"); - wl_link_down(wl); + brcmf_link_down(cfg_priv); /* * Make sure WPA_Supplicant receives all the event @@ -2124,37 +2132,31 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy) * the state fw and WPA_Supplicant state consistent */ rtnl_unlock(); - wl_delay(500); + brcmf_delay(500); rtnl_lock(); } - set_bit(WL_STATUS_SCAN_ABORTING, &wl->status); - if (test_bit(WL_STATUS_READY, &wl->status)) - wl_term_iscan(wl); + set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status); + if (test_bit(WL_STATUS_READY, &cfg_priv->status)) + brcmf_term_iscan(cfg_priv); - if (wl->scan_request) { + if (cfg_priv->scan_request) { /* Indidate scan abort to cfg80211 layer */ WL_INFO("Terminating scan in progress\n"); - cfg80211_scan_done(wl->scan_request, true); - wl->scan_request = NULL; + cfg80211_scan_done(cfg_priv->scan_request, true); + cfg_priv->scan_request = NULL; } - clear_bit(WL_STATUS_SCANNING, &wl->status); - clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status); - clear_bit(WL_STATUS_CONNECTING, &wl->status); - clear_bit(WL_STATUS_CONNECTED, &wl->status); - - /* Inform SDIO stack not to switch off power to the chip */ - sdioh_sdio_set_host_pm_flags(MMC_PM_KEEP_POWER); + clear_bit(WL_STATUS_SCANNING, &cfg_priv->status); + clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status); /* Turn off watchdog timer */ - if (test_bit(WL_STATUS_READY, &wl->status)) { - WL_INFO("Terminate watchdog timer and enable MPC\n"); - wl_set_mpc(ndev, 1); - wl_os_wd_timer(ndev, 0); + if (test_bit(WL_STATUS_READY, &cfg_priv->status)) { + WL_INFO("Enable MPC\n"); + brcmf_set_mpc(ndev, 1); } #if defined(CONFIG_PM_SLEEP) - atomic_set(&dhd_mmc_suspend, true); + atomic_set(&brcmf_mmc_suspend, true); #endif /* defined(CONFIG_PM_SLEEP) */ WL_TRACE("Exit\n"); @@ -2163,8 +2165,8 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy) } static __used s32 -wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, - s32 err) +brcmf_update_pmklist(struct net_device *dev, + struct brcmf_cfg80211_pmk_list *pmk_list, s32 err) { int i, j; @@ -2177,55 +2179,51 @@ wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, } if (likely(!err)) - wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list, + brcmf_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list, sizeof(*pmk_list)); return err; } static s32 -wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_pmksa *pmksa) +brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_pmksa *pmksa) { - struct wl_priv *wl = wiphy_to_wl(wiphy); + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); + struct _pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids; s32 err = 0; int i; WL_TRACE("Enter\n"); CHECK_SYS_UP(); - for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) - if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, - ETH_ALEN)) + for (i = 0; i < pmkids->npmkid; i++) + if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN)) break; if (i < WL_NUM_PMKIDS_MAX) { - memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid, - ETH_ALEN); - memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid, - WLAN_PMKID_LEN); - if (i == wl->pmk_list->pmkids.npmkid) - wl->pmk_list->pmkids.npmkid++; + memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN); + memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN); + if (i == pmkids->npmkid) + pmkids->npmkid++; } else err = -EINVAL; WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n", - &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID); + pmkids->pmkid[pmkids->npmkid].BSSID); for (i = 0; i < WLAN_PMKID_LEN; i++) - WL_CONN("%02x\n", - wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid]. - PMKID[i]); + WL_CONN("%02x\n", pmkids->pmkid[pmkids->npmkid].PMKID[i]); - err = wl_update_pmklist(dev, wl->pmk_list, err); + err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err); WL_TRACE("Exit\n"); return err; } static s32 -wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, +brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_pmksa *pmksa) { - struct wl_priv *wl = wiphy_to_wl(wiphy); + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); struct _pmkid_list pmkid; s32 err = 0; int i; @@ -2240,28 +2238,29 @@ wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, for (i = 0; i < WLAN_PMKID_LEN; i++) WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]); - for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) + for (i = 0; i < cfg_priv->pmk_list->pmkids.npmkid; i++) if (!memcmp - (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, + (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID, ETH_ALEN)) break; - if ((wl->pmk_list->pmkids.npmkid > 0) - && (i < wl->pmk_list->pmkids.npmkid)) { - memset(&wl->pmk_list->pmkids.pmkid[i], 0, sizeof(pmkid_t)); - for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) { - memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, - &wl->pmk_list->pmkids.pmkid[i + 1].BSSID, + if ((cfg_priv->pmk_list->pmkids.npmkid > 0) + && (i < cfg_priv->pmk_list->pmkids.npmkid)) { + memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0, + sizeof(pmkid_t)); + for (; i < (cfg_priv->pmk_list->pmkids.npmkid - 1); i++) { + memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID, + &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID, ETH_ALEN); - memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, - &wl->pmk_list->pmkids.pmkid[i + 1].PMKID, + memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID, + &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID, WLAN_PMKID_LEN); } - wl->pmk_list->pmkids.npmkid--; + cfg_priv->pmk_list->pmkids.npmkid--; } else err = -EINVAL; - err = wl_update_pmklist(dev, wl->pmk_list, err); + err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err); WL_TRACE("Exit\n"); return err; @@ -2269,16 +2268,16 @@ wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, } static s32 -wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev) +brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev) { - struct wl_priv *wl = wiphy_to_wl(wiphy); + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); s32 err = 0; WL_TRACE("Enter\n"); CHECK_SYS_UP(); - memset(wl->pmk_list, 0, sizeof(*wl->pmk_list)); - err = wl_update_pmklist(dev, wl->pmk_list, err); + memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list)); + err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err); WL_TRACE("Exit\n"); return err; @@ -2286,31 +2285,31 @@ wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev) } static struct cfg80211_ops wl_cfg80211_ops = { - .change_virtual_intf = wl_cfg80211_change_iface, - .scan = wl_cfg80211_scan, - .set_wiphy_params = wl_cfg80211_set_wiphy_params, - .join_ibss = wl_cfg80211_join_ibss, - .leave_ibss = wl_cfg80211_leave_ibss, - .get_station = wl_cfg80211_get_station, - .set_tx_power = wl_cfg80211_set_tx_power, - .get_tx_power = wl_cfg80211_get_tx_power, - .add_key = wl_cfg80211_add_key, - .del_key = wl_cfg80211_del_key, - .get_key = wl_cfg80211_get_key, - .set_default_key = wl_cfg80211_config_default_key, - .set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key, - .set_power_mgmt = wl_cfg80211_set_power_mgmt, - .set_bitrate_mask = wl_cfg80211_set_bitrate_mask, - .connect = wl_cfg80211_connect, - .disconnect = wl_cfg80211_disconnect, - .suspend = wl_cfg80211_suspend, - .resume = wl_cfg80211_resume, - .set_pmksa = wl_cfg80211_set_pmksa, - .del_pmksa = wl_cfg80211_del_pmksa, - .flush_pmksa = wl_cfg80211_flush_pmksa + .change_virtual_intf = brcmf_cfg80211_change_iface, + .scan = brcmf_cfg80211_scan, + .set_wiphy_params = brcmf_cfg80211_set_wiphy_params, + .join_ibss = brcmf_cfg80211_join_ibss, + .leave_ibss = brcmf_cfg80211_leave_ibss, + .get_station = brcmf_cfg80211_get_station, + .set_tx_power = brcmf_cfg80211_set_tx_power, + .get_tx_power = brcmf_cfg80211_get_tx_power, + .add_key = brcmf_cfg80211_add_key, + .del_key = brcmf_cfg80211_del_key, + .get_key = brcmf_cfg80211_get_key, + .set_default_key = brcmf_cfg80211_config_default_key, + .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key, + .set_power_mgmt = brcmf_cfg80211_set_power_mgmt, + .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask, + .connect = brcmf_cfg80211_connect, + .disconnect = brcmf_cfg80211_disconnect, + .suspend = brcmf_cfg80211_suspend, + .resume = brcmf_cfg80211_resume, + .set_pmksa = brcmf_cfg80211_set_pmksa, + .del_pmksa = brcmf_cfg80211_del_pmksa, + .flush_pmksa = brcmf_cfg80211_flush_pmksa }; -static s32 wl_mode_to_nl80211_iftype(s32 mode) +static s32 brcmf_mode_to_nl80211_iftype(s32 mode) { s32 err = 0; @@ -2326,7 +2325,7 @@ static s32 wl_mode_to_nl80211_iftype(s32 mode) return err; } -static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface, +static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface, struct device *dev) { struct wireless_dev *wdev; @@ -2338,7 +2337,8 @@ static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface, return ERR_PTR(-ENOMEM); } wdev->wiphy = - wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface); + wiphy_new(&wl_cfg80211_ops, + sizeof(struct brcmf_cfg80211_priv) + sizeof_iface); if (unlikely(!wdev->wiphy)) { WL_ERR("Couldn not allocate wiphy device\n"); err = -ENOMEM; @@ -2384,9 +2384,9 @@ static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface, return ERR_PTR(err); } -static void wl_free_wdev(struct wl_priv *wl) +static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv) { - struct wireless_dev *wdev = wl_to_wdev(wl); + struct wireless_dev *wdev = cfg_to_wdev(cfg_priv); if (unlikely(!wdev)) { WL_ERR("wdev is invalid\n"); @@ -2395,18 +2395,18 @@ static void wl_free_wdev(struct wl_priv *wl) wiphy_unregister(wdev->wiphy); wiphy_free(wdev->wiphy); kfree(wdev); - wl_to_wdev(wl) = NULL; + cfg_to_wdev(cfg_priv) = NULL; } -static s32 wl_inform_bss(struct wl_priv *wl) +static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_scan_results *bss_list; - struct wl_bss_info *bi = NULL; /* must be initialized */ + struct brcmf_scan_results *bss_list; + struct brcmf_bss_info *bi = NULL; /* must be initialized */ s32 err = 0; int i; - bss_list = wl->bss_list; - if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) { + bss_list = cfg_priv->bss_list; + if (unlikely(bss_list->version != BRCMF_BSS_INFO_VERSION)) { WL_ERR("Version %d != WL_BSS_INFO_VERSION\n", bss_list->version); return -EOPNOTSUPP; @@ -2414,7 +2414,7 @@ static s32 wl_inform_bss(struct wl_priv *wl) WL_SCAN("scanned AP count (%d)\n", bss_list->count); bi = next_bss(bss_list, bi); for_each_bss(bss_list, bi, i) { - err = wl_inform_single_bss(wl, bi); + err = brcmf_inform_single_bss(cfg_priv, bi); if (unlikely(err)) break; } @@ -2422,9 +2422,10 @@ static s32 wl_inform_bss(struct wl_priv *wl) } -static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) +static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, + struct brcmf_bss_info *bi) { - struct wiphy *wiphy = wl_to_wiphy(wl); + struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); struct ieee80211_channel *notify_channel; struct cfg80211_bss *bss; struct ieee80211_supported_band *band; @@ -2482,12 +2483,12 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) return err; } -static s32 -wl_inform_ibss(struct wl_priv *wl, struct net_device *dev, const u8 *bssid) +static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *dev, const u8 *bssid) { - struct wiphy *wiphy = wl_to_wiphy(wl); + struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); struct ieee80211_channel *notify_channel; - struct wl_bss_info *bi = NULL; + struct brcmf_bss_info *bi = NULL; struct ieee80211_supported_band *band; u8 *buf = NULL; s32 err = 0; @@ -2511,13 +2512,13 @@ wl_inform_ibss(struct wl_priv *wl, struct net_device *dev, const u8 *bssid) *(u32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX); - err = wl_dev_ioctl(dev, WLC_GET_BSS_INFO, buf, WL_BSS_INFO_MAX); + err = brcmf_dev_ioctl(dev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX); if (unlikely(err)) { WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err); goto CleanUp; } - bi = (wl_bss_info_t *)(buf + 4); + bi = (struct brcmf_bss_info *)(buf + 4); channel = bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); @@ -2556,45 +2557,48 @@ wl_inform_ibss(struct wl_priv *wl, struct net_device *dev, const u8 *bssid) return err; } -static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e) +static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv, + const struct brcmf_event_msg *e) { u32 event = be32_to_cpu(e->event_type); u32 status = be32_to_cpu(e->status); - if (event == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) { + if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { WL_CONN("Processing set ssid\n"); - wl->link_up = true; + cfg_priv->link_up = true; return true; } return false; } -static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e) +static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv, + const struct brcmf_event_msg *e) { u32 event = be32_to_cpu(e->event_type); u16 flags = be16_to_cpu(e->flags); - if (event == WLC_E_LINK && (!(flags & WLC_EVENT_MSG_LINK))) { + if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) { WL_CONN("Processing link down\n"); return true; } return false; } -static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e) +static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv, + const struct brcmf_event_msg *e) { u32 event = be32_to_cpu(e->event_type); u32 status = be32_to_cpu(e->status); - u16 flags = be16_to_cpu(e->flags); - if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS) { + if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) { WL_CONN("Processing Link %s & no network found\n", - flags & WLC_EVENT_MSG_LINK ? "up" : "down"); + be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ? + "up" : "down"); return true; } - if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS) { + if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) { WL_CONN("Processing connecting & no network found\n"); return true; } @@ -2603,142 +2607,153 @@ static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e) } static s32 -wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) +brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *ndev, + const struct brcmf_event_msg *e, void *data) { s32 err = 0; - if (wl_is_linkup(wl, e)) { + if (brcmf_is_linkup(cfg_priv, e)) { WL_CONN("Linkup\n"); - if (wl_is_ibssmode(wl)) { - wl_update_prof(wl, NULL, (void *)e->addr, + if (brcmf_is_ibssmode(cfg_priv)) { + brcmf_update_prof(cfg_priv, NULL, (void *)e->addr, WL_PROF_BSSID); - wl_inform_ibss(wl, ndev, e->addr); + wl_inform_ibss(cfg_priv, ndev, e->addr); cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); - clear_bit(WL_STATUS_CONNECTING, &wl->status); - set_bit(WL_STATUS_CONNECTED, &wl->status); + clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); + set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); } else - wl_bss_connect_done(wl, ndev, e, data, true); - } else if (wl_is_linkdown(wl, e)) { + brcmf_bss_connect_done(cfg_priv, ndev, e, data, true); + } else if (brcmf_is_linkdown(cfg_priv, e)) { WL_CONN("Linkdown\n"); - if (wl_is_ibssmode(wl)) { + if (brcmf_is_ibssmode(cfg_priv)) { + clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); if (test_and_clear_bit(WL_STATUS_CONNECTED, - &wl->status)) - wl_link_down(wl); + &cfg_priv->status)) + brcmf_link_down(cfg_priv); } else { + brcmf_bss_connect_done(cfg_priv, ndev, e, data, false); if (test_and_clear_bit(WL_STATUS_CONNECTED, - &wl->status)) { + &cfg_priv->status)) { cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL); - wl_link_down(wl); + brcmf_link_down(cfg_priv); } } - wl_init_prof(wl->profile); - } else if (wl_is_nonetwork(wl, e)) { - if (wl_is_ibssmode(wl)) - clear_bit(WL_STATUS_CONNECTING, &wl->status); + brcmf_init_prof(cfg_priv->profile); + } else if (brcmf_is_nonetwork(cfg_priv, e)) { + if (brcmf_is_ibssmode(cfg_priv)) + clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); else - wl_bss_connect_done(wl, ndev, e, data, false); + brcmf_bss_connect_done(cfg_priv, ndev, e, data, false); } return err; } static s32 -wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) +brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *ndev, + const struct brcmf_event_msg *e, void *data) { s32 err = 0; u32 event = be32_to_cpu(e->event_type); u32 status = be32_to_cpu(e->status); - if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) { - if (test_bit(WL_STATUS_CONNECTED, &wl->status)) - wl_bss_roaming_done(wl, ndev, e, data); + if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { + if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) + brcmf_bss_roaming_done(cfg_priv, ndev, e, data); else - wl_bss_connect_done(wl, ndev, e, data, true); + brcmf_bss_connect_done(cfg_priv, ndev, e, data, true); } return err; } static __used s32 -wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len) +brcmf_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len) { - struct wl_priv *wl = ndev_to_wl(dev); + struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev); u32 buflen; - buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX); + buflen = brcmu_mkiovar(name, buf, len, cfg_priv->ioctl_buf, + WL_IOCTL_LEN_MAX); BUG_ON(!buflen); - return wl_dev_ioctl(dev, WLC_SET_VAR, wl->ioctl_buf, buflen); + return brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, cfg_priv->ioctl_buf, + buflen); } static s32 -wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf, +brcmf_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf, s32 buf_len) { - struct wl_priv *wl = ndev_to_wl(dev); + struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev); u32 len; s32 err = 0; - len = bcm_mkiovar(name, NULL, 0, wl->ioctl_buf, WL_IOCTL_LEN_MAX); + len = brcmu_mkiovar(name, NULL, 0, cfg_priv->ioctl_buf, + WL_IOCTL_LEN_MAX); BUG_ON(!len); - err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf, + err = brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, (void *)cfg_priv->ioctl_buf, WL_IOCTL_LEN_MAX); if (unlikely(err)) { WL_ERR("error (%d)\n", err); return err; } - memcpy(buf, wl->ioctl_buf, buf_len); + memcpy(buf, cfg_priv->ioctl_buf, buf_len); return err; } -static s32 wl_get_assoc_ies(struct wl_priv *wl) +static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv) { - struct net_device *ndev = wl_to_ndev(wl); - struct wl_assoc_ielen *assoc_info; - struct wl_connect_info *conn_info = wl_to_conn(wl); + struct net_device *ndev = cfg_to_ndev(cfg_priv); + struct brcmf_cfg80211_assoc_ielen *assoc_info; + struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); u32 req_len; u32 resp_len; s32 err = 0; - wl_clear_assoc_ies(wl); + brcmf_clear_assoc_ies(cfg_priv); - err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf, + err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf, WL_ASSOC_INFO_MAX); if (unlikely(err)) { WL_ERR("could not get assoc info (%d)\n", err); return err; } - assoc_info = (struct wl_assoc_ielen *)wl->extra_buf; + assoc_info = (struct brcmf_cfg80211_assoc_ielen *)cfg_priv->extra_buf; req_len = assoc_info->req_len; resp_len = assoc_info->resp_len; if (req_len) { - err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf, - WL_ASSOC_INFO_MAX); + err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies", + cfg_priv->extra_buf, + WL_ASSOC_INFO_MAX); if (unlikely(err)) { WL_ERR("could not get assoc req (%d)\n", err); return err; } conn_info->req_ie_len = req_len; conn_info->req_ie = - kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL); + kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len, + GFP_KERNEL); } else { conn_info->req_ie_len = 0; conn_info->req_ie = NULL; } if (resp_len) { - err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf, - WL_ASSOC_INFO_MAX); + err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies", + cfg_priv->extra_buf, + WL_ASSOC_INFO_MAX); if (unlikely(err)) { WL_ERR("could not get assoc resp (%d)\n", err); return err; } conn_info->resp_ie_len = resp_len; conn_info->resp_ie = - kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL); + kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len, + GFP_KERNEL); } else { conn_info->resp_ie_len = 0; conn_info->resp_ie = NULL; @@ -2749,9 +2764,9 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl) return err; } -static void wl_clear_assoc_ies(struct wl_priv *wl) +static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_connect_info *conn_info = wl_to_conn(wl); + struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); kfree(conn_info->req_ie); conn_info->req_ie = NULL; @@ -2762,7 +2777,7 @@ static void wl_clear_assoc_ies(struct wl_priv *wl) } -static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, +static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params, size_t *join_params_size) { chanspec_t chanspec = 0; @@ -2779,7 +2794,7 @@ static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, chanspec |= WL_CHANSPEC_BW_20; chanspec |= WL_CHANSPEC_CTL_SB_NONE; - *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE + + *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE + join_params->params.chanspec_num * sizeof(chanspec_t); join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; @@ -2796,11 +2811,11 @@ static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, } } -static s32 wl_update_bss_info(struct wl_priv *wl) +static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_bss_info *bi; - struct wlc_ssid *ssid; - struct bcm_tlv *tim; + struct brcmf_bss_info *bi; + struct brcmf_ssid *ssid; + struct brcmu_tlv *tim; u16 beacon_interval; u8 dtim_period; size_t ie_len; @@ -2808,21 +2823,21 @@ static s32 wl_update_bss_info(struct wl_priv *wl) s32 err = 0; WL_TRACE("Enter\n"); - if (wl_is_ibssmode(wl)) + if (brcmf_is_ibssmode(cfg_priv)) return err; - ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID); + ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID); - *(u32 *)wl->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX); - err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO, - wl->extra_buf, WL_EXTRA_BUF_MAX); + *(u32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX); + err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO, + cfg_priv->extra_buf, WL_EXTRA_BUF_MAX); if (unlikely(err)) { WL_ERR("Could not get bss info %d\n", err); goto update_bss_info_out; } - bi = (struct wl_bss_info *)(wl->extra_buf + 4); - err = wl_inform_single_bss(wl, bi); + bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4); + err = brcmf_inform_single_bss(cfg_priv, bi); if (unlikely(err)) goto update_bss_info_out; @@ -2830,7 +2845,7 @@ static s32 wl_update_bss_info(struct wl_priv *wl) ie_len = bi->ie_length; beacon_interval = cpu_to_le16(bi->beacon_period); - tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM); + tim = brcmu_parse_tlvs(ie, ie_len, WLAN_EID_TIM); if (tim) dtim_period = tim->data[1]; else { @@ -2840,7 +2855,8 @@ static s32 wl_update_bss_info(struct wl_priv *wl) * so we speficially query dtim information to dongle. */ u32 var; - err = wl_dev_intvar_get(wl_to_ndev(wl), "dtim_assoc", &var); + err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv), + "dtim_assoc", &var); if (unlikely(err)) { WL_ERR("wl dtim_assoc failed (%d)\n", err); goto update_bss_info_out; @@ -2848,8 +2864,8 @@ static s32 wl_update_bss_info(struct wl_priv *wl) dtim_period = (u8)var; } - wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT); - wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD); + brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT); + brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD); update_bss_info_out: WL_TRACE("Exit"); @@ -2857,54 +2873,59 @@ static s32 wl_update_bss_info(struct wl_priv *wl) } static s32 -wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) +brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *ndev, + const struct brcmf_event_msg *e, void *data) { - struct wl_connect_info *conn_info = wl_to_conn(wl); + struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); s32 err = 0; WL_TRACE("Enter\n"); - wl_get_assoc_ies(wl); - wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID); - wl_update_bss_info(wl); + brcmf_get_assoc_ies(cfg_priv); + brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID); + brcmf_update_bss_info(cfg_priv); cfg80211_roamed(ndev, NULL, - (u8 *)wl_read_prof(wl, WL_PROF_BSSID), + (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID), conn_info->req_ie, conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); WL_CONN("Report roaming result\n"); - set_bit(WL_STATUS_CONNECTED, &wl->status); + set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); WL_TRACE("Exit\n"); return err; } static s32 -wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data, bool completed) +brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *ndev, const struct brcmf_event_msg *e, + void *data, bool completed) { - struct wl_connect_info *conn_info = wl_to_conn(wl); + struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); s32 err = 0; WL_TRACE("Enter\n"); - if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) { + if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) { if (completed) { - wl_get_assoc_ies(wl); - wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID); - wl_update_bss_info(wl); + brcmf_get_assoc_ies(cfg_priv); + brcmf_update_prof(cfg_priv, NULL, &e->addr, + WL_PROF_BSSID); + brcmf_update_bss_info(cfg_priv); } cfg80211_connect_result(ndev, - (u8 *)wl_read_prof(wl, WL_PROF_BSSID), + (u8 *)brcmf_read_prof(cfg_priv, + WL_PROF_BSSID), conn_info->req_ie, conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len, - completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT, + completed ? WLAN_STATUS_SUCCESS : + WLAN_STATUS_AUTH_TIMEOUT, GFP_KERNEL); if (completed) - set_bit(WL_STATUS_CONNECTED, &wl->status); + set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); WL_CONN("Report connect result - connection %s\n", completed ? "succeeded" : "failed"); } @@ -2913,14 +2934,15 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, } static s32 -wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) +brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *ndev, + const struct brcmf_event_msg *e, void *data) { u16 flags = be16_to_cpu(e->flags); enum nl80211_key_type key_type; rtnl_lock(); - if (flags & WLC_EVENT_MSG_GROUP) + if (flags & BRCMF_EVENT_MSG_GROUP) key_type = NL80211_KEYTYPE_GROUP; else key_type = NL80211_KEYTYPE_PAIRWISE; @@ -2933,30 +2955,32 @@ wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev, } static s32 -wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, - const wl_event_msg_t *e, void *data) +brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv, + struct net_device *ndev, + const struct brcmf_event_msg *e, void *data) { - struct channel_info channel_inform; - struct wl_scan_results *bss_list; + struct brcmf_channel_info channel_inform; + struct brcmf_scan_results *bss_list; u32 len = WL_SCAN_BUF_MAX; s32 err = 0; bool scan_abort = false; WL_TRACE("Enter\n"); - if (wl->iscan_on && wl->iscan_kickstart) { + if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) { WL_TRACE("Exit\n"); - return wl_wakeup_iscan(wl_to_iscan(wl)); + return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv)); } - if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) { + if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, + &cfg_priv->status))) { WL_ERR("Scan complete while device not scanning\n"); scan_abort = true; err = -EINVAL; goto scan_done_out; } - err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform, + err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel_inform, sizeof(channel_inform)); if (unlikely(err)) { WL_ERR("scan busy (%d)\n", err); @@ -2969,12 +2993,12 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, WL_CONN("channel_inform.scan_channel (%d)\n", channel_inform.scan_channel); } - wl->bss_list = wl->scan_results; - bss_list = wl->bss_list; + cfg_priv->bss_list = cfg_priv->scan_results; + bss_list = cfg_priv->bss_list; memset(bss_list, 0, len); bss_list->buflen = cpu_to_le32(len); - err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN_RESULTS, bss_list, len); if (unlikely(err)) { WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); err = -EINVAL; @@ -2985,18 +3009,18 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, bss_list->version = le32_to_cpu(bss_list->version); bss_list->count = le32_to_cpu(bss_list->count); - err = wl_inform_bss(wl); + err = brcmf_inform_bss(cfg_priv); if (err) { scan_abort = true; goto scan_done_out; } scan_done_out: - if (wl->scan_request) { + if (cfg_priv->scan_request) { WL_SCAN("calling cfg80211_scan_done\n"); - cfg80211_scan_done(wl->scan_request, scan_abort); - wl_set_mpc(ndev, 1); - wl->scan_request = NULL; + cfg80211_scan_done(cfg_priv->scan_request, scan_abort); + brcmf_set_mpc(ndev, 1); + cfg_priv->scan_request = NULL; } WL_TRACE("Exit\n"); @@ -3004,7 +3028,7 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, return err; } -static void wl_init_conf(struct wl_conf *conf) +static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) { conf->mode = (u32)-1; conf->frag_threshold = (u32)-1; @@ -3014,70 +3038,66 @@ static void wl_init_conf(struct wl_conf *conf) conf->tx_power = -1; } -static void wl_init_prof(struct wl_profile *prof) +static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof) { memset(prof, 0, sizeof(*prof)); } -static void wl_init_eloop_handler(struct wl_event_loop *el) +static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el) { memset(el, 0, sizeof(*el)); - el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status; - el->handler[WLC_E_LINK] = wl_notify_connect_status; - el->handler[WLC_E_ROAM] = wl_notify_roaming_status; - el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status; - el->handler[WLC_E_SET_SSID] = wl_notify_connect_status; + el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status; + el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status; + el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status; + el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status; + el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status; } -static s32 wl_init_priv_mem(struct wl_priv *wl) +static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv) { - wl->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); - if (unlikely(!wl->scan_results)) { + cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); + if (unlikely(!cfg_priv->scan_results)) { WL_ERR("Scan results alloc failed\n"); goto init_priv_mem_out; } - wl->conf = kzalloc(sizeof(*wl->conf), GFP_KERNEL); - if (unlikely(!wl->conf)) { + cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL); + if (unlikely(!cfg_priv->conf)) { WL_ERR("wl_conf alloc failed\n"); goto init_priv_mem_out; } - wl->profile = kzalloc(sizeof(*wl->profile), GFP_KERNEL); - if (unlikely(!wl->profile)) { + cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL); + if (unlikely(!cfg_priv->profile)) { WL_ERR("wl_profile alloc failed\n"); goto init_priv_mem_out; } - wl->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); - if (unlikely(!wl->bss_info)) { + cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); + if (unlikely(!cfg_priv->bss_info)) { WL_ERR("Bss information alloc failed\n"); goto init_priv_mem_out; } - wl->scan_req_int = kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL); - if (unlikely(!wl->scan_req_int)) { + cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int), + GFP_KERNEL); + if (unlikely(!cfg_priv->scan_req_int)) { WL_ERR("Scan req alloc failed\n"); goto init_priv_mem_out; } - wl->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL); - if (unlikely(!wl->ioctl_buf)) { + cfg_priv->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL); + if (unlikely(!cfg_priv->ioctl_buf)) { WL_ERR("Ioctl buf alloc failed\n"); goto init_priv_mem_out; } - wl->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); - if (unlikely(!wl->extra_buf)) { + cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); + if (unlikely(!cfg_priv->extra_buf)) { WL_ERR("Extra buf alloc failed\n"); goto init_priv_mem_out; } - wl->iscan = kzalloc(sizeof(*wl->iscan), GFP_KERNEL); - if (unlikely(!wl->iscan)) { + cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL); + if (unlikely(!cfg_priv->iscan)) { WL_ERR("Iscan buf alloc failed\n"); goto init_priv_mem_out; } - wl->fw = kzalloc(sizeof(*wl->fw), GFP_KERNEL); - if (unlikely(!wl->fw)) { - WL_ERR("fw object alloc failed\n"); - goto init_priv_mem_out; - } - wl->pmk_list = kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL); - if (unlikely(!wl->pmk_list)) { + cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL); + if (unlikely(!cfg_priv->pmk_list)) { WL_ERR("pmk list alloc failed\n"); goto init_priv_mem_out; } @@ -3085,61 +3105,60 @@ static s32 wl_init_priv_mem(struct wl_priv *wl) return 0; init_priv_mem_out: - wl_deinit_priv_mem(wl); + brcmf_deinit_priv_mem(cfg_priv); return -ENOMEM; } -static void wl_deinit_priv_mem(struct wl_priv *wl) +static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv) { - kfree(wl->scan_results); - wl->scan_results = NULL; - kfree(wl->bss_info); - wl->bss_info = NULL; - kfree(wl->conf); - wl->conf = NULL; - kfree(wl->profile); - wl->profile = NULL; - kfree(wl->scan_req_int); - wl->scan_req_int = NULL; - kfree(wl->ioctl_buf); - wl->ioctl_buf = NULL; - kfree(wl->extra_buf); - wl->extra_buf = NULL; - kfree(wl->iscan); - wl->iscan = NULL; - kfree(wl->fw); - wl->fw = NULL; - kfree(wl->pmk_list); - wl->pmk_list = NULL; + kfree(cfg_priv->scan_results); + cfg_priv->scan_results = NULL; + kfree(cfg_priv->bss_info); + cfg_priv->bss_info = NULL; + kfree(cfg_priv->conf); + cfg_priv->conf = NULL; + kfree(cfg_priv->profile); + cfg_priv->profile = NULL; + kfree(cfg_priv->scan_req_int); + cfg_priv->scan_req_int = NULL; + kfree(cfg_priv->ioctl_buf); + cfg_priv->ioctl_buf = NULL; + kfree(cfg_priv->extra_buf); + cfg_priv->extra_buf = NULL; + kfree(cfg_priv->iscan); + cfg_priv->iscan = NULL; + kfree(cfg_priv->pmk_list); + cfg_priv->pmk_list = NULL; } -static s32 wl_create_event_handler(struct wl_priv *wl) +static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv) { - sema_init(&wl->event_sync, 0); - wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler"); - if (IS_ERR(wl->event_tsk)) { - wl->event_tsk = NULL; + sema_init(&cfg_priv->event_sync, 0); + cfg_priv->event_tsk = kthread_run(brcmf_event_handler, cfg_priv, + "wl_event_handler"); + if (IS_ERR(cfg_priv->event_tsk)) { + cfg_priv->event_tsk = NULL; WL_ERR("failed to create event thread\n"); return -ENOMEM; } return 0; } -static void wl_destroy_event_handler(struct wl_priv *wl) +static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv) { - if (wl->event_tsk) { - send_sig(SIGTERM, wl->event_tsk, 1); - kthread_stop(wl->event_tsk); - wl->event_tsk = NULL; + if (cfg_priv->event_tsk) { + send_sig(SIGTERM, cfg_priv->event_tsk, 1); + kthread_stop(cfg_priv->event_tsk); + cfg_priv->event_tsk = NULL; } } -static void wl_term_iscan(struct wl_priv *wl) +static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); - if (wl->iscan_on && iscan->tsk) { + if (cfg_priv->iscan_on && iscan->tsk) { iscan->state = WL_ISCAN_STATE_IDLE; send_sig(SIGTERM, iscan->tsk, 1); kthread_stop(iscan->tsk); @@ -3147,26 +3166,28 @@ static void wl_term_iscan(struct wl_priv *wl) } } -static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted) +static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, + bool aborted) { - struct wl_priv *wl = iscan_to_wl(iscan); - struct net_device *ndev = wl_to_ndev(wl); + struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan); + struct net_device *ndev = cfg_to_ndev(cfg_priv); - if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) { + if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, + &cfg_priv->status))) { WL_ERR("Scan complete while device not scanning\n"); return; } - if (likely(wl->scan_request)) { + if (likely(cfg_priv->scan_request)) { WL_SCAN("ISCAN Completed scan: %s\n", aborted ? "Aborted" : "Done"); - cfg80211_scan_done(wl->scan_request, aborted); - wl_set_mpc(ndev, 1); - wl->scan_request = NULL; + cfg80211_scan_done(cfg_priv->scan_request, aborted); + brcmf_set_mpc(ndev, 1); + cfg_priv->scan_request = NULL; } - wl->iscan_kickstart = false; + cfg_priv->iscan_kickstart = false; } -static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan) +static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan) { if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) { WL_SCAN("wake up iscan\n"); @@ -3178,25 +3199,25 @@ static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan) } static s32 -wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status, - struct wl_scan_results **bss_list) +brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status, + struct brcmf_scan_results **bss_list) { - struct wl_iscan_results list; - struct wl_scan_results *results; - struct wl_iscan_results *list_buf; + struct brcmf_iscan_results list; + struct brcmf_scan_results *results; + struct brcmf_iscan_results *list_buf; s32 err = 0; memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX); - list_buf = (struct wl_iscan_results *)iscan->scan_buf; + list_buf = (struct brcmf_iscan_results *)iscan->scan_buf; results = &list_buf->results; - results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; + results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE; results->version = 0; results->count = 0; memset(&list, 0, sizeof(list)); list.results.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX); - err = wl_dev_iovar_getbuf(iscan->dev, "iscanresults", &list, - WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf, + err = brcmf_dev_iovar_getbuf(iscan->dev, "iscanresults", &list, + BRCMF_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf, WL_ISCAN_BUF_MAX); if (unlikely(err)) { WL_ERR("error (%d)\n", err); @@ -3213,23 +3234,23 @@ wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status, return err; } -static s32 wl_iscan_done(struct wl_priv *wl) +static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_iscan_ctrl *iscan = wl->iscan; + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; s32 err = 0; iscan->state = WL_ISCAN_STATE_IDLE; rtnl_lock(); - wl_inform_bss(wl); - wl_notify_iscan_complete(iscan, false); + brcmf_inform_bss(cfg_priv); + brcmf_notify_iscan_complete(iscan, false); rtnl_unlock(); return err; } -static s32 wl_iscan_pending(struct wl_priv *wl) +static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_iscan_ctrl *iscan = wl->iscan; + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; s32 err = 0; /* Reschedule the timer */ @@ -3239,14 +3260,14 @@ static s32 wl_iscan_pending(struct wl_priv *wl) return err; } -static s32 wl_iscan_inprogress(struct wl_priv *wl) +static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_iscan_ctrl *iscan = wl->iscan; + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; s32 err = 0; rtnl_lock(); - wl_inform_bss(wl); - wl_run_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); + brcmf_inform_bss(cfg_priv); + brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE); rtnl_unlock(); /* Reschedule the timer */ mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); @@ -3255,31 +3276,32 @@ static s32 wl_iscan_inprogress(struct wl_priv *wl) return err; } -static s32 wl_iscan_aborted(struct wl_priv *wl) +static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_iscan_ctrl *iscan = wl->iscan; + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; s32 err = 0; iscan->state = WL_ISCAN_STATE_IDLE; rtnl_lock(); - wl_notify_iscan_complete(iscan, true); + brcmf_notify_iscan_complete(iscan, true); rtnl_unlock(); return err; } -static s32 wl_iscan_thread(void *data) +static s32 brcmf_iscan_thread(void *data) { struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 }; - struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data; - struct wl_priv *wl = iscan_to_wl(iscan); - struct wl_iscan_eloop *el = &iscan->el; + struct brcmf_cfg80211_iscan_ctrl *iscan = + (struct brcmf_cfg80211_iscan_ctrl *)data; + struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan); + struct brcmf_cfg80211_iscan_eloop *el = &iscan->el; u32 status; int err = 0; sched_setscheduler(current, SCHED_FIFO, ¶m); allow_signal(SIGTERM); - status = WL_SCAN_RESULTS_PARTIAL; + status = BRCMF_SCAN_RESULTS_PARTIAL; while (likely(!down_interruptible(&iscan->sync))) { if (kthread_should_stop()) break; @@ -3288,13 +3310,14 @@ static s32 wl_iscan_thread(void *data) iscan->timer_on = 0; } rtnl_lock(); - err = wl_get_iscan_results(iscan, &status, &wl->bss_list); + err = brcmf_get_iscan_results(iscan, &status, + &cfg_priv->bss_list); if (unlikely(err)) { - status = WL_SCAN_RESULTS_ABORTED; + status = BRCMF_SCAN_RESULTS_ABORTED; WL_ERR("Abort iscan\n"); } rtnl_unlock(); - el->handler[status] (wl); + el->handler[status](cfg_priv); } if (iscan->timer_on) { del_timer_sync(&iscan->timer); @@ -3305,26 +3328,27 @@ static s32 wl_iscan_thread(void *data) return 0; } -static void wl_iscan_timer(unsigned long data) +static void brcmf_iscan_timer(unsigned long data) { - struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data; + struct brcmf_cfg80211_iscan_ctrl *iscan = + (struct brcmf_cfg80211_iscan_ctrl *)data; if (iscan) { iscan->timer_on = 0; WL_SCAN("timer expired\n"); - wl_wakeup_iscan(iscan); + brcmf_wakeup_iscan(iscan); } } -static s32 wl_invoke_iscan(struct wl_priv *wl) +static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); int err = 0; - if (wl->iscan_on && !iscan->tsk) { + if (cfg_priv->iscan_on && !iscan->tsk) { iscan->state = WL_ISCAN_STATE_IDLE; sema_init(&iscan->sync, 0); - iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan"); + iscan->tsk = kthread_run(brcmf_iscan_thread, iscan, "wl_iscan"); if (IS_ERR(iscan->tsk)) { WL_ERR("Could not create iscan thread\n"); iscan->tsk = NULL; @@ -3335,228 +3359,228 @@ static s32 wl_invoke_iscan(struct wl_priv *wl) return err; } -static void wl_init_iscan_eloop(struct wl_iscan_eloop *el) +static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el) { memset(el, 0, sizeof(*el)); - el->handler[WL_SCAN_RESULTS_SUCCESS] = wl_iscan_done; - el->handler[WL_SCAN_RESULTS_PARTIAL] = wl_iscan_inprogress; - el->handler[WL_SCAN_RESULTS_PENDING] = wl_iscan_pending; - el->handler[WL_SCAN_RESULTS_ABORTED] = wl_iscan_aborted; - el->handler[WL_SCAN_RESULTS_NO_MEM] = wl_iscan_aborted; + el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done; + el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress; + el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending; + el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted; + el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted; } -static s32 wl_init_iscan(struct wl_priv *wl) +static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_iscan_ctrl *iscan = wl_to_iscan(wl); + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); int err = 0; - if (wl->iscan_on) { - iscan->dev = wl_to_ndev(wl); + if (cfg_priv->iscan_on) { + iscan->dev = cfg_to_ndev(cfg_priv); iscan->state = WL_ISCAN_STATE_IDLE; - wl_init_iscan_eloop(&iscan->el); + brcmf_init_iscan_eloop(&iscan->el); iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS; init_timer(&iscan->timer); iscan->timer.data = (unsigned long) iscan; - iscan->timer.function = wl_iscan_timer; + iscan->timer.function = brcmf_iscan_timer; sema_init(&iscan->sync, 0); - iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan"); + iscan->tsk = kthread_run(brcmf_iscan_thread, iscan, "wl_iscan"); if (IS_ERR(iscan->tsk)) { WL_ERR("Could not create iscan thread\n"); iscan->tsk = NULL; return -ENOMEM; } - iscan->data = wl; + iscan->data = cfg_priv; } return err; } -static void wl_init_fw(struct wl_fw_ctrl *fw) +static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv) { - fw->status = 0; /* init fw loading status. - 0 means nothing was loaded yet */ -} - -static s32 wl_init_priv(struct wl_priv *wl) -{ - struct wiphy *wiphy = wl_to_wiphy(wl); + struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); s32 err = 0; - wl->scan_request = NULL; - wl->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT); - wl->iscan_on = true; /* iscan on & off switch. + cfg_priv->scan_request = NULL; + cfg_priv->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT); + cfg_priv->iscan_on = true; /* iscan on & off switch. we enable iscan per default */ - wl->roam_on = false; /* roam on & off switch. + cfg_priv->roam_on = false; /* roam on & off switch. we enable roam per default */ - wl->iscan_kickstart = false; - wl->active_scan = true; /* we do active scan for + cfg_priv->iscan_kickstart = false; + cfg_priv->active_scan = true; /* we do active scan for specific scan per default */ - wl->dongle_up = false; /* dongle is not up yet */ - wl_init_eq(wl); - err = wl_init_priv_mem(wl); + cfg_priv->dongle_up = false; /* dongle is not up yet */ + brcmf_init_eq(cfg_priv); + err = brcmf_init_priv_mem(cfg_priv); if (unlikely(err)) return err; - if (unlikely(wl_create_event_handler(wl))) + if (unlikely(brcmf_create_event_handler(cfg_priv))) return -ENOMEM; - wl_init_eloop_handler(&wl->el); - mutex_init(&wl->usr_sync); - err = wl_init_iscan(wl); + brcmf_init_eloop_handler(&cfg_priv->el); + mutex_init(&cfg_priv->usr_sync); + err = brcmf_init_iscan(cfg_priv); if (unlikely(err)) return err; - wl_init_fw(wl->fw); - wl_init_conf(wl->conf); - wl_init_prof(wl->profile); - wl_link_down(wl); + brcmf_init_conf(cfg_priv->conf); + brcmf_init_prof(cfg_priv->profile); + brcmf_link_down(cfg_priv); return err; } -static void wl_deinit_priv(struct wl_priv *wl) +static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv) { - wl_destroy_event_handler(wl); - wl->dongle_up = false; /* dongle down */ - wl_flush_eq(wl); - wl_link_down(wl); - wl_term_iscan(wl); - wl_deinit_priv_mem(wl); + brcmf_destroy_event_handler(cfg_priv); + cfg_priv->dongle_up = false; /* dongle down */ + brcmf_flush_eq(cfg_priv); + brcmf_link_down(cfg_priv); + brcmf_term_iscan(cfg_priv); + brcmf_deinit_priv_mem(cfg_priv); } -s32 wl_cfg80211_attach(struct net_device *ndev, void *data) +s32 brcmf_cfg80211_attach(struct net_device *ndev, void *data) { struct wireless_dev *wdev; - struct wl_priv *wl; - struct wl_iface *ci; + struct brcmf_cfg80211_priv *cfg_priv; + struct brcmf_cfg80211_iface *ci; s32 err = 0; if (unlikely(!ndev)) { WL_ERR("ndev is invalid\n"); return -ENODEV; } - wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL); - if (unlikely(!wl_cfg80211_dev)) { + cfg80211_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL); + if (unlikely(!cfg80211_dev)) { WL_ERR("wl_cfg80211_dev is invalid\n"); return -ENOMEM; } - WL_INFO("func %p\n", wl_cfg80211_get_sdio_func()); - wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev); + WL_INFO("func %p\n", brcmf_cfg80211_get_sdio_func()); + wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), + &brcmf_cfg80211_get_sdio_func()->dev); if (IS_ERR(wdev)) return -ENOMEM; - wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS); - wl = wdev_to_wl(wdev); - wl->wdev = wdev; - wl->pub = data; - ci = (struct wl_iface *)wl_to_ci(wl); - ci->wl = wl; + wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS); + cfg_priv = wdev_to_cfg(wdev); + cfg_priv->wdev = wdev; + cfg_priv->pub = data; + ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci; + ci->cfg_priv = cfg_priv; ndev->ieee80211_ptr = wdev; SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); wdev->netdev = ndev; - err = wl_init_priv(wl); + err = wl_init_priv(cfg_priv); if (unlikely(err)) { WL_ERR("Failed to init iwm_priv (%d)\n", err); goto cfg80211_attach_out; } - wl_set_drvdata(wl_cfg80211_dev, ci); + brcmf_set_drvdata(cfg80211_dev, ci); return err; cfg80211_attach_out: - wl_free_wdev(wl); + brcmf_free_wdev(cfg_priv); return err; } -void wl_cfg80211_detach(void) +void brcmf_cfg80211_detach(void) { - struct wl_priv *wl; + struct brcmf_cfg80211_priv *cfg_priv; - wl = WL_PRIV_GET(); + cfg_priv = WL_PRIV_GET(); - wl_deinit_priv(wl); - wl_free_wdev(wl); - wl_set_drvdata(wl_cfg80211_dev, NULL); - kfree(wl_cfg80211_dev); - wl_cfg80211_dev = NULL; - wl_clear_sdio_func(); + wl_deinit_priv(cfg_priv); + brcmf_free_wdev(cfg_priv); + brcmf_set_drvdata(cfg80211_dev, NULL); + kfree(cfg80211_dev); + cfg80211_dev = NULL; + brcmf_clear_sdio_func(); } -static void wl_wakeup_event(struct wl_priv *wl) +static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv) { - up(&wl->event_sync); + up(&cfg_priv->event_sync); } -static s32 wl_event_handler(void *data) +static s32 brcmf_event_handler(void *data) { - struct wl_priv *wl = (struct wl_priv *)data; + struct brcmf_cfg80211_priv *cfg_priv = + (struct brcmf_cfg80211_priv *)data; struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 }; - struct wl_event_q *e; + struct brcmf_cfg80211_event_q *e; sched_setscheduler(current, SCHED_FIFO, ¶m); allow_signal(SIGTERM); - while (likely(!down_interruptible(&wl->event_sync))) { + while (likely(!down_interruptible(&cfg_priv->event_sync))) { if (kthread_should_stop()) break; - e = wl_deq_event(wl); + e = brcmf_deq_event(cfg_priv); if (unlikely(!e)) { WL_ERR("event queue empty...\n"); BUG(); } WL_INFO("event type (%d)\n", e->etype); - if (wl->el.handler[e->etype]) { - wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg, - e->edata); + if (cfg_priv->el.handler[e->etype]) { + cfg_priv->el.handler[e->etype](cfg_priv, + cfg_to_ndev(cfg_priv), + &e->emsg, e->edata); } else { WL_INFO("Unknown Event (%d): ignoring\n", e->etype); } - wl_put_event(e); + brcmf_put_event(e); } WL_INFO("was terminated\n"); return 0; } void -wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data) +brcmf_cfg80211_event(struct net_device *ndev, + const struct brcmf_event_msg *e, void *data) { u32 event_type = be32_to_cpu(e->event_type); - struct wl_priv *wl = ndev_to_wl(ndev); + struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); - if (likely(!wl_enq_event(wl, event_type, e, data))) - wl_wakeup_event(wl); + if (likely(!brcmf_enq_event(cfg_priv, event_type, e, data))) + brcmf_wakeup_event(cfg_priv); } -static void wl_init_eq(struct wl_priv *wl) +static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv) { - wl_init_eq_lock(wl); - INIT_LIST_HEAD(&wl->eq_list); + brcmf_init_eq_lock(cfg_priv); + INIT_LIST_HEAD(&cfg_priv->eq_list); } -static void wl_flush_eq(struct wl_priv *wl) +static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_event_q *e; + struct brcmf_cfg80211_event_q *e; - wl_lock_eq(wl); - while (!list_empty(&wl->eq_list)) { - e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list); + brcmf_lock_eq(cfg_priv); + while (!list_empty(&cfg_priv->eq_list)) { + e = list_first_entry(&cfg_priv->eq_list, + struct brcmf_cfg80211_event_q, eq_list); list_del(&e->eq_list); kfree(e); } - wl_unlock_eq(wl); + brcmf_unlock_eq(cfg_priv); } /* * retrieve first queued event from head */ -static struct wl_event_q *wl_deq_event(struct wl_priv *wl) +static struct brcmf_cfg80211_event_q *brcmf_deq_event( + struct brcmf_cfg80211_priv *cfg_priv) { - struct wl_event_q *e = NULL; + struct brcmf_cfg80211_event_q *e = NULL; - wl_lock_eq(wl); - if (likely(!list_empty(&wl->eq_list))) { - e = list_first_entry(&wl->eq_list, struct wl_event_q, eq_list); + brcmf_lock_eq(cfg_priv); + if (likely(!list_empty(&cfg_priv->eq_list))) { + e = list_first_entry(&cfg_priv->eq_list, + struct brcmf_cfg80211_event_q, eq_list); list_del(&e->eq_list); } - wl_unlock_eq(wl); + brcmf_unlock_eq(cfg_priv); return e; } @@ -3566,50 +3590,49 @@ static struct wl_event_q *wl_deq_event(struct wl_priv *wl) */ static s32 -wl_enq_event(struct wl_priv *wl, u32 event, const wl_event_msg_t *msg, - void *data) +brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event, + const struct brcmf_event_msg *msg, void *data) { - struct wl_event_q *e; + struct brcmf_cfg80211_event_q *e; s32 err = 0; - e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL); + e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL); if (unlikely(!e)) { WL_ERR("event alloc failed\n"); return -ENOMEM; } e->etype = event; - memcpy(&e->emsg, msg, sizeof(wl_event_msg_t)); - if (data) { - } - wl_lock_eq(wl); - list_add_tail(&e->eq_list, &wl->eq_list); - wl_unlock_eq(wl); + memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg)); + + brcmf_lock_eq(cfg_priv); + list_add_tail(&e->eq_list, &cfg_priv->eq_list); + brcmf_unlock_eq(cfg_priv); return err; } -static void wl_put_event(struct wl_event_q *e) +static void brcmf_put_event(struct brcmf_cfg80211_event_q *e) { kfree(e); } -void wl_cfg80211_sdio_func(void *func) +void brcmf_cfg80211_sdio_func(void *func) { cfg80211_sdio_func = (struct sdio_func *)func; } -static void wl_clear_sdio_func(void) +static void brcmf_clear_sdio_func(void) { cfg80211_sdio_func = NULL; } -struct sdio_func *wl_cfg80211_get_sdio_func(void) +struct sdio_func *brcmf_cfg80211_get_sdio_func(void) { return cfg80211_sdio_func; } -static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype) +static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype) { s32 infra = 0; s32 err = 0; @@ -3633,7 +3656,7 @@ static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype) return err; } infra = cpu_to_le32(infra); - err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra)); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_INFRA, &infra, sizeof(infra)); if (unlikely(err)) { WL_ERR("WLC_SET_INFRA error (%d)\n", err); return err; @@ -3642,253 +3665,48 @@ static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype) return 0; } -#ifndef EMBEDDED_PLATFORM -static s32 wl_dongle_country(struct net_device *ndev, u8 ccode) +static s32 brcmf_dongle_eventmsg(struct net_device *ndev) { - - s32 err = 0; - - return err; -} - -static s32 wl_dongle_up(struct net_device *ndev, u32 up) -{ - s32 err = 0; - - err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up)); - if (unlikely(err)) { - WL_ERR("WLC_UP error (%d)\n", err); - } - return err; -} - -static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode) -{ - s32 err = 0; - - err = wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode)); - if (unlikely(err)) { - WL_ERR("WLC_SET_PM error (%d)\n", err); - } - return err; -} - -static s32 -wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align) -{ - s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + - '\0' + bitvec */ - s32 err = 0; - - /* Match Host and Dongle rx alignment */ - bcm_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, - sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - if (unlikely(err)) { - WL_ERR("txglomalign error (%d)\n", err); - goto dongle_glom_out; - } - /* disable glom option per default */ - bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - if (unlikely(err)) { - WL_ERR("txglom error (%d)\n", err); - goto dongle_glom_out; - } -dongle_glom_out: - return err; -} - -static s32 -wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol) -{ - s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + - '\0' + bitvec */ - s32 err = 0; - - /* Set ARP offload */ - bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - if (err) { - if (err == -EOPNOTSUPP) - WL_INFO("arpoe is not supported\n"); - else - WL_ERR("arpoe error (%d)\n", err); - - goto dongle_offload_out; - } - bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - if (err) { - if (err == -EOPNOTSUPP) - WL_INFO("arp_ol is not supported\n"); - else - WL_ERR("arp_ol error (%d)\n", err); - - goto dongle_offload_out; - } - -dongle_offload_out: - return err; -} - -static s32 wl_pattern_atoh(s8 *src, s8 *dst) -{ - int i; - if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) { - WL_ERR("Mask invalid format. Needs to start with 0x\n"); - return -1; - } - src = src + 2; /* Skip past 0x */ - if (strlen(src) % 2 != 0) { - WL_ERR("Mask invalid format. Needs to be of even length\n"); - return -1; - } - for (i = 0; *src != '\0'; i++) { - char num[3]; - strncpy(num, src, 2); - num[2] = '\0'; - dst[i] = (u8) simple_strtoul(num, NULL, 16); - src += 2; - } - return i; -} - -static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode) -{ - s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + - '\0' + bitvec */ - const s8 *str; - struct wl_pkt_filter pkt_filter; - struct wl_pkt_filter *pkt_filterp; - s32 buf_len; - s32 str_len; - u32 mask_size; - u32 pattern_size; - s8 buf[256]; - s32 err = 0; - -/* add a default packet filter pattern */ - str = "pkt_filter_add"; - str_len = strlen(str); - strncpy(buf, str, str_len); - buf[str_len] = '\0'; - buf_len = str_len + 1; - - pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1); - - /* Parse packet filter id. */ - pkt_filter.id = cpu_to_le32(100); - - /* Parse filter polarity. */ - pkt_filter.negate_match = cpu_to_le32(0); - - /* Parse filter type. */ - pkt_filter.type = cpu_to_le32(0); - - /* Parse pattern filter offset. */ - pkt_filter.u.pattern.offset = cpu_to_le32(0); - - /* Parse pattern filter mask. */ - mask_size = cpu_to_le32(wl_pattern_atoh("0xff", - (char *)pkt_filterp->u.pattern. - mask_and_pattern)); - - /* Parse pattern filter pattern. */ - pattern_size = cpu_to_le32(wl_pattern_atoh("0x00", - (char *)&pkt_filterp->u. - pattern. - mask_and_pattern - [mask_size])); - - if (mask_size != pattern_size) { - WL_ERR("Mask and pattern not the same size\n"); - err = -EINVAL; - goto dongle_filter_out; - } - - pkt_filter.u.pattern.size_bytes = mask_size; - buf_len += WL_PKT_FILTER_FIXED_LEN; - buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); - - /* Keep-alive attributes are set in local - * variable (keep_alive_pkt), and - * then memcpy'ed into buffer (keep_alive_pktp) since there is no - * guarantee that the buffer is properly aligned. - */ - memcpy((char *)pkt_filterp, &pkt_filter, - WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN); - - err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len); - if (err) { - if (err == -EOPNOTSUPP) { - WL_INFO("filter not supported\n"); - } else { - WL_ERR("filter (%d)\n", err); - } - goto dongle_filter_out; - } - - /* set mode to allow pattern */ - bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf, - sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); - if (err) { - if (err == -EOPNOTSUPP) { - WL_INFO("filter_mode not supported\n"); - } else { - WL_ERR("filter_mode (%d)\n", err); - } - goto dongle_filter_out; - } - -dongle_filter_out: - return err; -} -#endif /* !EMBEDDED_PLATFORM */ - -static s32 wl_dongle_eventmsg(struct net_device *ndev) -{ - s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + - '\0' + bitvec */ - s8 eventmask[WL_EVENTING_MASK_LEN]; + /* Room for "event_msgs" + '\0' + bitvec */ + s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; + s8 eventmask[BRCMF_EVENTING_MASK_LEN]; s32 err = 0; WL_TRACE("Enter\n"); /* Setup event_msgs */ - bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, + brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf)); + err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf)); if (unlikely(err)) { WL_ERR("Get event_msgs error (%d)\n", err); goto dongle_eventmsg_out; } - memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN); + memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN); - setbit(eventmask, WLC_E_SET_SSID); - setbit(eventmask, WLC_E_ROAM); - setbit(eventmask, WLC_E_PRUNE); - setbit(eventmask, WLC_E_AUTH); - setbit(eventmask, WLC_E_REASSOC); - setbit(eventmask, WLC_E_REASSOC_IND); - setbit(eventmask, WLC_E_DEAUTH_IND); - setbit(eventmask, WLC_E_DISASSOC_IND); - setbit(eventmask, WLC_E_DISASSOC); - setbit(eventmask, WLC_E_JOIN); - setbit(eventmask, WLC_E_ASSOC_IND); - setbit(eventmask, WLC_E_PSK_SUP); - setbit(eventmask, WLC_E_LINK); - setbit(eventmask, WLC_E_NDIS_LINK); - setbit(eventmask, WLC_E_MIC_ERROR); - setbit(eventmask, WLC_E_PMKID_CACHE); - setbit(eventmask, WLC_E_TXFAIL); - setbit(eventmask, WLC_E_JOIN_START); - setbit(eventmask, WLC_E_SCAN_COMPLETE); + setbit(eventmask, BRCMF_E_SET_SSID); + setbit(eventmask, BRCMF_E_ROAM); + setbit(eventmask, BRCMF_E_PRUNE); + setbit(eventmask, BRCMF_E_AUTH); + setbit(eventmask, BRCMF_E_REASSOC); + setbit(eventmask, BRCMF_E_REASSOC_IND); + setbit(eventmask, BRCMF_E_DEAUTH_IND); + setbit(eventmask, BRCMF_E_DISASSOC_IND); + setbit(eventmask, BRCMF_E_DISASSOC); + setbit(eventmask, BRCMF_E_JOIN); + setbit(eventmask, BRCMF_E_ASSOC_IND); + setbit(eventmask, BRCMF_E_PSK_SUP); + setbit(eventmask, BRCMF_E_LINK); + setbit(eventmask, BRCMF_E_NDIS_LINK); + setbit(eventmask, BRCMF_E_MIC_ERROR); + setbit(eventmask, BRCMF_E_PMKID_CACHE); + setbit(eventmask, BRCMF_E_TXFAIL); + setbit(eventmask, BRCMF_E_JOIN_START); + setbit(eventmask, BRCMF_E_SCAN_COMPLETE); - bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, + brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); if (unlikely(err)) { WL_ERR("Set event_msgs error (%d)\n", err); goto dongle_eventmsg_out; @@ -3900,7 +3718,7 @@ static s32 wl_dongle_eventmsg(struct net_device *ndev) } static s32 -wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) +brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) { s8 iovbuf[32]; s32 roamtrigger[2]; @@ -3912,9 +3730,10 @@ wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) * off to report link down */ if (roamvar) { - bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, + brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout, sizeof(bcn_timeout), iovbuf, sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, + iovbuf, sizeof(iovbuf)); if (unlikely(err)) { WL_ERR("bcn_timeout error (%d)\n", err); goto dongle_rom_out; @@ -3926,17 +3745,17 @@ wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) * to take care of roaming */ WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On"); - bcm_mkiovar("roam_off", (char *)&roamvar, + brcmu_mkiovar("roam_off", (char *)&roamvar, sizeof(roamvar), iovbuf, sizeof(iovbuf)); - err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); if (unlikely(err)) { WL_ERR("roam_off error (%d)\n", err); goto dongle_rom_out; } roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL; - roamtrigger[1] = WLC_BAND_ALL; - err = wl_dev_ioctl(ndev, WLC_SET_ROAM_TRIGGER, + roamtrigger[1] = BRCM_BAND_ALL; + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_TRIGGER, (void *)roamtrigger, sizeof(roamtrigger)); if (unlikely(err)) { WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err); @@ -3944,8 +3763,8 @@ wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) } roam_delta[0] = WL_ROAM_DELTA; - roam_delta[1] = WLC_BAND_ALL; - err = wl_dev_ioctl(ndev, WLC_SET_ROAM_DELTA, + roam_delta[1] = BRCM_BAND_ALL; + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_DELTA, (void *)roam_delta, sizeof(roam_delta)); if (unlikely(err)) { WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err); @@ -3957,13 +3776,13 @@ wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) } static s32 -wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, +brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, s32 scan_unassoc_time, s32 scan_passive_time) { s32 err = 0; - err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time, - sizeof(scan_assoc_time)); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME, + &scan_assoc_time, sizeof(scan_assoc_time)); if (err) { if (err == -EOPNOTSUPP) WL_INFO("Scan assoc time is not supported\n"); @@ -3971,8 +3790,8 @@ wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, WL_ERR("Scan assoc time error (%d)\n", err); goto dongle_scantime_out; } - err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time, - sizeof(scan_unassoc_time)); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME, + &scan_unassoc_time, sizeof(scan_unassoc_time)); if (err) { if (err == -EOPNOTSUPP) WL_INFO("Scan unassoc time is not supported\n"); @@ -3981,8 +3800,8 @@ wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, goto dongle_scantime_out; } - err = wl_dev_ioctl(ndev, WLC_SET_SCAN_PASSIVE_TIME, &scan_passive_time, - sizeof(scan_passive_time)); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME, + &scan_passive_time, sizeof(scan_passive_time)); if (err) { if (err == -EOPNOTSUPP) WL_INFO("Scan passive time is not supported\n"); @@ -3995,54 +3814,34 @@ wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, return err; } -s32 wl_config_dongle(struct wl_priv *wl, bool need_lock) +s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv, bool need_lock) { -#ifndef DHD_SDALIGN -#define DHD_SDALIGN 32 -#endif struct net_device *ndev; struct wireless_dev *wdev; s32 err = 0; - if (wl->dongle_up) + if (cfg_priv->dongle_up) return err; - ndev = wl_to_ndev(wl); + ndev = cfg_to_ndev(cfg_priv); wdev = ndev->ieee80211_ptr; if (need_lock) rtnl_lock(); -#ifndef EMBEDDED_PLATFORM - err = wl_dongle_up(ndev, 0); - if (unlikely(err)) - goto default_conf_out; - err = wl_dongle_country(ndev, 0); - if (unlikely(err)) - goto default_conf_out; - err = wl_dongle_power(ndev, PM_FAST); - if (unlikely(err)) - goto default_conf_out; - err = wl_dongle_glom(ndev, 0, DHD_SDALIGN); - if (unlikely(err)) - goto default_conf_out; - - wl_dongle_offload(ndev, 1, 0xf); - wl_dongle_filter(ndev, 1); -#endif /* !EMBEDDED_PLATFORM */ - - wl_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, + brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); - err = wl_dongle_eventmsg(ndev); + err = brcmf_dongle_eventmsg(ndev); if (unlikely(err)) goto default_conf_out; - err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), WL_BEACON_TIMEOUT); + err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1), + WL_BEACON_TIMEOUT); if (unlikely(err)) goto default_conf_out; - err = wl_dongle_mode(ndev, wdev->iftype); + err = brcmf_dongle_mode(ndev, wdev->iftype); if (unlikely(err && err != -EINPROGRESS)) goto default_conf_out; - err = wl_dongle_probecap(wl); + err = brcmf_dongle_probecap(cfg_priv); if (unlikely(err)) goto default_conf_out; @@ -4052,21 +3851,21 @@ s32 wl_config_dongle(struct wl_priv *wl, bool need_lock) if (need_lock) rtnl_unlock(); - wl->dongle_up = true; + cfg_priv->dongle_up = true; return err; } -static s32 wl_update_wiphybands(struct wl_priv *wl) +static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv) { struct wiphy *wiphy; s32 phy_list; s8 phy; s32 err = 0; - err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list, - sizeof(phy_list)); + err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST, + &phy_list, sizeof(phy_list)); if (unlikely(err)) { WL_ERR("error (%d)\n", err); return err; @@ -4075,131 +3874,144 @@ static s32 wl_update_wiphybands(struct wl_priv *wl) phy = ((char *)&phy_list)[1]; WL_INFO("%c phy\n", phy); if (phy == 'n' || phy == 'a') { - wiphy = wl_to_wiphy(wl); + wiphy = cfg_to_wiphy(cfg_priv); wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n; } return err; } -static s32 __wl_cfg80211_up(struct wl_priv *wl) +static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv) { s32 err = 0; - set_bit(WL_STATUS_READY, &wl->status); + set_bit(WL_STATUS_READY, &cfg_priv->status); - wl_debugfs_add_netdev_params(wl); + brcmf_debugfs_add_netdev_params(cfg_priv); - err = wl_config_dongle(wl, false); + err = brcmf_config_dongle(cfg_priv, false); if (unlikely(err)) return err; - wl_invoke_iscan(wl); + brcmf_invoke_iscan(cfg_priv); return err; } -static s32 __wl_cfg80211_down(struct wl_priv *wl) +static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv) { - set_bit(WL_STATUS_SCAN_ABORTING, &wl->status); - wl_term_iscan(wl); - if (wl->scan_request) { - cfg80211_scan_done(wl->scan_request, true); - /* May need to perform this to cover rmmod */ - /* wl_set_mpc(wl_to_ndev(wl), 1); */ - wl->scan_request = NULL; - } - clear_bit(WL_STATUS_READY, &wl->status); - clear_bit(WL_STATUS_SCANNING, &wl->status); - clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status); - clear_bit(WL_STATUS_CONNECTING, &wl->status); - clear_bit(WL_STATUS_CONNECTED, &wl->status); + /* + * While going down, if associated with AP disassociate + * from AP to save power + */ + if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) || + test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) && + test_bit(WL_STATUS_READY, &cfg_priv->status)) { + WL_INFO("Disassociating from AP"); + brcmf_link_down(cfg_priv); - wl_debugfs_remove_netdev(wl); + /* Make sure WPA_Supplicant receives all the event + generated due to DISASSOC call to the fw to keep + the state fw and WPA_Supplicant state consistent + */ + rtnl_unlock(); + brcmf_delay(500); + rtnl_lock(); + } + + set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status); + brcmf_term_iscan(cfg_priv); + if (cfg_priv->scan_request) { + cfg80211_scan_done(cfg_priv->scan_request, true); + /* May need to perform this to cover rmmod */ + /* wl_set_mpc(cfg_to_ndev(wl), 1); */ + cfg_priv->scan_request = NULL; + } + clear_bit(WL_STATUS_READY, &cfg_priv->status); + clear_bit(WL_STATUS_SCANNING, &cfg_priv->status); + clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status); + + brcmf_debugfs_remove_netdev(cfg_priv); return 0; } -s32 wl_cfg80211_up(void) +s32 brcmf_cfg80211_up(void) { - struct wl_priv *wl; + struct brcmf_cfg80211_priv *cfg_priv; s32 err = 0; - wl = WL_PRIV_GET(); - mutex_lock(&wl->usr_sync); - err = __wl_cfg80211_up(wl); - mutex_unlock(&wl->usr_sync); + cfg_priv = WL_PRIV_GET(); + mutex_lock(&cfg_priv->usr_sync); + err = __brcmf_cfg80211_up(cfg_priv); + mutex_unlock(&cfg_priv->usr_sync); return err; } -s32 wl_cfg80211_down(void) +s32 brcmf_cfg80211_down(void) { - struct wl_priv *wl; + struct brcmf_cfg80211_priv *cfg_priv; s32 err = 0; - wl = WL_PRIV_GET(); - mutex_lock(&wl->usr_sync); - err = __wl_cfg80211_down(wl); - mutex_unlock(&wl->usr_sync); + cfg_priv = WL_PRIV_GET(); + mutex_lock(&cfg_priv->usr_sync); + err = __brcmf_cfg80211_down(cfg_priv); + mutex_unlock(&cfg_priv->usr_sync); return err; } -static s32 wl_dongle_probecap(struct wl_priv *wl) +static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv) { - s32 err = 0; - - err = wl_update_wiphybands(wl); - if (unlikely(err)) - return err; - - return err; + return wl_update_wiphybands(cfg_priv); } -static void *wl_read_prof(struct wl_priv *wl, s32 item) +static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item) { switch (item) { case WL_PROF_SEC: - return &wl->profile->sec; + return &cfg_priv->profile->sec; case WL_PROF_BSSID: - return &wl->profile->bssid; + return &cfg_priv->profile->bssid; case WL_PROF_SSID: - return &wl->profile->ssid; + return &cfg_priv->profile->ssid; } WL_ERR("invalid item (%d)\n", item); return NULL; } static s32 -wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data, - s32 item) +brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv, + const struct brcmf_event_msg *e, void *data, s32 item) { s32 err = 0; - struct wlc_ssid *ssid; + struct brcmf_ssid *ssid; switch (item) { case WL_PROF_SSID: - ssid = (wlc_ssid_t *) data; - memset(wl->profile->ssid.SSID, 0, - sizeof(wl->profile->ssid.SSID)); - memcpy(wl->profile->ssid.SSID, ssid->SSID, ssid->SSID_len); - wl->profile->ssid.SSID_len = ssid->SSID_len; + ssid = (struct brcmf_ssid *) data; + memset(cfg_priv->profile->ssid.SSID, 0, + sizeof(cfg_priv->profile->ssid.SSID)); + memcpy(cfg_priv->profile->ssid.SSID, + ssid->SSID, ssid->SSID_len); + cfg_priv->profile->ssid.SSID_len = ssid->SSID_len; break; case WL_PROF_BSSID: if (data) - memcpy(wl->profile->bssid, data, ETH_ALEN); + memcpy(cfg_priv->profile->bssid, data, ETH_ALEN); else - memset(wl->profile->bssid, 0, ETH_ALEN); + memset(cfg_priv->profile->bssid, 0, ETH_ALEN); break; case WL_PROF_SEC: - memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec)); + memcpy(&cfg_priv->profile->sec, data, + sizeof(cfg_priv->profile->sec)); break; case WL_PROF_BEACONINT: - wl->profile->beacon_interval = *(u16 *)data; + cfg_priv->profile->beacon_interval = *(u16 *)data; break; case WL_PROF_DTIMPERIOD: - wl->profile->dtim_period = *(u8 *)data; + cfg_priv->profile->dtim_period = *(u8 *)data; break; default: WL_ERR("unsupported item (%d)\n", item); @@ -4210,14 +4022,15 @@ wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data, return err; } -static bool wl_is_ibssmode(struct wl_priv *wl) +static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv) { - return wl->conf->mode == WL_MODE_IBSS; + return cfg_priv->conf->mode == WL_MODE_IBSS; } -static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v) +static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv, + u8 t, u8 l, u8 *v) { - struct wl_ie *ie = wl_to_ie(wl); + struct brcmf_cfg80211_ie *ie = &cfg_priv->ie; s32 err = 0; if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) { @@ -4232,42 +4045,40 @@ static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v) return err; } - -static void wl_link_down(struct wl_priv *wl) +static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv) { struct net_device *dev = NULL; s32 err = 0; WL_TRACE("Enter\n"); - clear_bit(WL_STATUS_CONNECTED, &wl->status); - if (wl->link_up) { - dev = wl_to_ndev(wl); + if (cfg_priv->link_up) { + dev = cfg_to_ndev(cfg_priv); WL_INFO("Call WLC_DISASSOC to stop excess roaming\n "); - err = wl_dev_ioctl(dev, WLC_DISASSOC, NULL, 0); + err = brcmf_dev_ioctl(dev, BRCMF_C_DISASSOC, NULL, 0); if (unlikely(err)) WL_ERR("WLC_DISASSOC failed (%d)\n", err); - wl->link_up = false; + cfg_priv->link_up = false; } WL_TRACE("Exit\n"); } -static void wl_lock_eq(struct wl_priv *wl) +static void brcmf_lock_eq(struct brcmf_cfg80211_priv *cfg_priv) { - spin_lock_irq(&wl->eq_lock); + spin_lock_irq(&cfg_priv->eq_lock); } -static void wl_unlock_eq(struct wl_priv *wl) +static void brcmf_unlock_eq(struct brcmf_cfg80211_priv *cfg_priv) { - spin_unlock_irq(&wl->eq_lock); + spin_unlock_irq(&cfg_priv->eq_lock); } -static void wl_init_eq_lock(struct wl_priv *wl) +static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv *cfg_priv) { - spin_lock_init(&wl->eq_lock); + spin_lock_init(&cfg_priv->eq_lock); } -static void wl_delay(u32 ms) +static void brcmf_delay(u32 ms) { if (ms < 1000 / HZ) { cond_resched(); @@ -4277,115 +4088,27 @@ static void wl_delay(u32 ms) } } -static void wl_set_drvdata(struct wl_dev *dev, void *data) +static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data) { dev->driver_data = data; } -static void *wl_get_drvdata(struct wl_dev *dev) +static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev) { - return dev->driver_data; + void *data = NULL; + + if (dev) + data = dev->driver_data; + return data; } -s32 wl_cfg80211_read_fw(s8 *buf, u32 size) -{ - const struct firmware *fw_entry; - struct wl_priv *wl; - - wl = WL_PRIV_GET(); - - fw_entry = wl->fw->fw_entry; - - if (fw_entry->size < wl->fw->ptr + size) - size = fw_entry->size - wl->fw->ptr; - - memcpy(buf, &fw_entry->data[wl->fw->ptr], size); - wl->fw->ptr += size; - return size; -} - -void wl_cfg80211_release_fw(void) -{ - struct wl_priv *wl; - - wl = WL_PRIV_GET(); - release_firmware(wl->fw->fw_entry); - wl->fw->ptr = 0; -} - -void *wl_cfg80211_request_fw(s8 *file_name) -{ - struct wl_priv *wl; - const struct firmware *fw_entry = NULL; - s32 err = 0; - - WL_INFO("file name : \"%s\"\n", file_name); - wl = WL_PRIV_GET(); - - if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) { - err = request_firmware(&wl->fw->fw_entry, file_name, - &wl_cfg80211_get_sdio_func()->dev); - if (unlikely(err)) { - WL_ERR("Could not download fw (%d)\n", err); - goto req_fw_out; - } - set_bit(WL_FW_LOADING_DONE, &wl->fw->status); - fw_entry = wl->fw->fw_entry; - if (fw_entry) { - WL_INFO("fw size (%zd), data (%p)\n", - fw_entry->size, fw_entry->data); - } - } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) { - err = request_firmware(&wl->fw->fw_entry, file_name, - &wl_cfg80211_get_sdio_func()->dev); - if (unlikely(err)) { - WL_ERR("Could not download nvram (%d)\n", err); - goto req_fw_out; - } - set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status); - fw_entry = wl->fw->fw_entry; - if (fw_entry) { - WL_INFO("nvram size (%zd), data (%p)\n", - fw_entry->size, fw_entry->data); - } - } else { - WL_INFO("Downloading already done. Nothing to do more\n"); - err = -EPERM; - } - -req_fw_out: - if (unlikely(err)) { - return NULL; - } - wl->fw->ptr = 0; - return (void *)fw_entry->data; -} - -s8 *wl_cfg80211_get_fwname(void) -{ - struct wl_priv *wl; - - wl = WL_PRIV_GET(); - strcpy(wl->fw->fw_name, WL_4329_FW_FILE); - return wl->fw->fw_name; -} - -s8 *wl_cfg80211_get_nvramname(void) -{ - struct wl_priv *wl; - - wl = WL_PRIV_GET(); - strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE); - return wl->fw->nvram_name; -} - -static void wl_set_mpc(struct net_device *ndev, int mpc) +static void brcmf_set_mpc(struct net_device *ndev, int mpc) { s32 err = 0; - struct wl_priv *wl = ndev_to_wl(ndev); + struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); - if (test_bit(WL_STATUS_READY, &wl->status)) { - err = wl_dev_intvar_set(ndev, "mpc", mpc); + if (test_bit(WL_STATUS_READY, &cfg_priv->status)) { + err = brcmf_dev_intvar_set(ndev, "mpc", mpc); if (unlikely(err)) { WL_ERR("fail to set mpc\n"); return; @@ -4394,24 +4117,25 @@ static void wl_set_mpc(struct net_device *ndev, int mpc) } } -static int wl_debugfs_add_netdev_params(struct wl_priv *wl) +static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv) { char buf[10+IFNAMSIZ]; struct dentry *fd; s32 err = 0; - sprintf(buf, "netdev:%s", wl_to_ndev(wl)->name); - wl->debugfsdir = debugfs_create_dir(buf, wl_to_wiphy(wl)->debugfsdir); + sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name); + cfg_priv->debugfsdir = debugfs_create_dir(buf, + cfg_to_wiphy(cfg_priv)->debugfsdir); - fd = debugfs_create_u16("beacon_int", S_IRUGO, wl->debugfsdir, - (u16 *)&wl->profile->beacon_interval); + fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir, + (u16 *)&cfg_priv->profile->beacon_interval); if (!fd) { err = -ENOMEM; goto err_out; } - fd = debugfs_create_u8("dtim_period", S_IRUGO, wl->debugfsdir, - (u8 *)&wl->profile->dtim_period); + fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir, + (u8 *)&cfg_priv->profile->dtim_period); if (!fd) { err = -ENOMEM; goto err_out; @@ -4421,8 +4145,8 @@ static int wl_debugfs_add_netdev_params(struct wl_priv *wl) return err; } -static void wl_debugfs_remove_netdev(struct wl_priv *wl) +static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv) { - debugfs_remove_recursive(wl->debugfsdir); - wl->debugfsdir = NULL; + debugfs_remove_recursive(cfg_priv->debugfsdir); + cfg_priv->debugfsdir = NULL; } diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h index d4bcc1edddb2..f26d08793ca8 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h @@ -17,15 +17,11 @@ #ifndef _wl_cfg80211_h_ #define _wl_cfg80211_h_ -#include -#include -#include - -struct wl_conf; -struct wl_iface; -struct wl_priv; -struct wl_security; -struct wl_ibss; +struct brcmf_cfg80211_conf; +struct brcmf_cfg80211_iface; +struct brcmf_cfg80211_priv; +struct brcmf_cfg80211_security; +struct brcmf_cfg80211_ibss; #define WL_DBG_NONE 0 #define WL_DBG_CONN (1 << 5) @@ -38,7 +34,7 @@ struct wl_ibss; #define WL_ERR(fmt, args...) \ do { \ - if (wl_dbg_level & WL_DBG_ERR) { \ + if (brcmf_dbg_level & WL_DBG_ERR) { \ if (net_ratelimit()) { \ printk(KERN_ERR "ERROR @%s : " fmt, \ __func__, ##args); \ @@ -49,7 +45,7 @@ do { \ #if (defined BCMDBG) #define WL_INFO(fmt, args...) \ do { \ - if (wl_dbg_level & WL_DBG_INFO) { \ + if (brcmf_dbg_level & WL_DBG_INFO) { \ if (net_ratelimit()) { \ printk(KERN_ERR "INFO @%s : " fmt, \ __func__, ##args); \ @@ -59,7 +55,7 @@ do { \ #define WL_TRACE(fmt, args...) \ do { \ - if (wl_dbg_level & WL_DBG_TRACE) { \ + if (brcmf_dbg_level & WL_DBG_TRACE) { \ if (net_ratelimit()) { \ printk(KERN_ERR "TRACE @%s : " fmt, \ __func__, ##args); \ @@ -69,7 +65,7 @@ do { \ #define WL_SCAN(fmt, args...) \ do { \ - if (wl_dbg_level & WL_DBG_SCAN) { \ + if (brcmf_dbg_level & WL_DBG_SCAN) { \ if (net_ratelimit()) { \ printk(KERN_ERR "SCAN @%s : " fmt, \ __func__, ##args); \ @@ -79,7 +75,7 @@ do { \ #define WL_CONN(fmt, args...) \ do { \ - if (wl_dbg_level & WL_DBG_CONN) { \ + if (brcmf_dbg_level & WL_DBG_CONN) { \ if (net_ratelimit()) { \ printk(KERN_ERR "CONN @%s : " fmt, \ __func__, ##args); \ @@ -94,15 +90,13 @@ do { \ #define WL_CONN(fmt, args...) #endif /* (defined BCMDBG) */ - -#define WL_SCAN_RETRY_MAX 3 /* used for ibss scan */ #define WL_NUM_SCAN_MAX 1 #define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used * for 2.6.33 kernel * or later */ -#define WL_SCAN_BUF_MAX (1024 * 8) -#define WL_TLV_INFO_MAX 1024 +#define WL_SCAN_BUF_MAX (1024 * 8) +#define WL_TLV_INFO_MAX 1024 #define WL_BSS_INFO_MAX 2048 #define WL_ASSOC_INFO_MAX 512 /* * needs to grab assoc info from dongle to @@ -112,15 +106,14 @@ do { \ #define WL_IOCTL_LEN_MAX 1024 #define WL_EXTRA_BUF_MAX 2048 #define WL_ISCAN_BUF_MAX 2048 /* - * the buf lengh can be WLC_IOCTL_MAXLEN (8K) + * the buf length can be BRCMF_C_IOCTL_MAXLEN * to reduce iteration */ #define WL_ISCAN_TIMER_INTERVAL_MS 3000 -#define WL_SCAN_ERSULTS_LAST (WL_SCAN_RESULTS_NO_MEM+1) +#define WL_SCAN_ERSULTS_LAST (BRCMF_SCAN_RESULTS_NO_MEM+1) #define WL_AP_MAX 256 /* virtually unlimitted as long * as kernel memory allows */ -#define WL_FILE_NAME_MAX 256 #define WL_ROAM_TRIGGER_LEVEL -75 #define WL_ROAM_DELTA 20 @@ -165,22 +158,8 @@ enum wl_iscan_state { WL_ISCAN_STATE_SCANING }; -/* fw downloading status */ -enum wl_fw_status { - WL_FW_LOADING_DONE, - WL_NVRAM_LOADING_DONE -}; - -/* beacon / probe_response */ -struct beacon_proberesp { - __le64 timestamp; - __le16 beacon_int; - __le16 capab_info; - u8 variable[0]; -} __attribute__ ((packed)); - /* dongle configuration */ -struct wl_conf { +struct brcmf_cfg80211_conf { u32 mode; /* adhoc , infrastructure or ap */ u32 frag_threshold; u32 rts_threshold; @@ -191,51 +170,43 @@ struct wl_conf { }; /* cfg80211 main event loop */ -struct wl_event_loop { - s32(*handler[WLC_E_LAST]) (struct wl_priv *wl, +struct brcmf_cfg80211_event_loop { + s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv, struct net_device *ndev, - const wl_event_msg_t *e, void *data); + const struct brcmf_event_msg *e, + void *data); }; /* representing interface of cfg80211 plane */ -struct wl_iface { - struct wl_priv *wl; +struct brcmf_cfg80211_iface { + struct brcmf_cfg80211_priv *cfg_priv; }; -struct wl_dev { +struct brcmf_cfg80211_dev { void *driver_data; /* to store cfg80211 object information */ }; -/* bss inform structure for cfg80211 interface */ -struct wl_cfg80211_bss_info { - u16 band; - u16 channel; - s16 rssi; - u16 frame_len; - u8 frame_buf[1]; -}; - /* basic structure of scan request */ -struct wl_scan_req { - struct wlc_ssid ssid; +struct brcmf_cfg80211_scan_req { + struct brcmf_ssid ssid; }; /* basic structure of information element */ -struct wl_ie { +struct brcmf_cfg80211_ie { u16 offset; u8 buf[WL_TLV_INFO_MAX]; }; /* event queue for cfg80211 main event */ -struct wl_event_q { +struct brcmf_cfg80211_event_q { struct list_head eq_list; u32 etype; - wl_event_msg_t emsg; + struct brcmf_event_msg emsg; s8 edata[1]; }; /* security information with currently associated ap */ -struct wl_security { +struct brcmf_cfg80211_security { u32 wpa_versions; u32 auth_type; u32 cipher_pairwise; @@ -244,7 +215,7 @@ struct wl_security { }; /* ibss information for currently joined ibss network */ -struct wl_ibss { +struct brcmf_cfg80211_ibss { u8 beacon_interval; /* in millisecond */ u8 atim; /* in millisecond */ s8 join_only; @@ -253,24 +224,25 @@ struct wl_ibss { }; /* dongle profile */ -struct wl_profile { +struct brcmf_cfg80211_profile { u32 mode; - struct wlc_ssid ssid; + struct brcmf_ssid ssid; u8 bssid[ETH_ALEN]; u16 beacon_interval; u8 dtim_period; - struct wl_security sec; - struct wl_ibss ibss; + struct brcmf_cfg80211_security sec; + struct brcmf_cfg80211_ibss ibss; s32 band; }; /* dongle iscan event loop */ -struct wl_iscan_eloop { - s32(*handler[WL_SCAN_ERSULTS_LAST]) (struct wl_priv *wl); +struct brcmf_cfg80211_iscan_eloop { + s32 (*handler[WL_SCAN_ERSULTS_LAST]) + (struct brcmf_cfg80211_priv *cfg_priv); }; /* dongle iscan controller */ -struct wl_iscan_ctrl { +struct brcmf_cfg80211_iscan_ctrl { struct net_device *dev; struct timer_list timer; u32 timer_ms; @@ -278,69 +250,57 @@ struct wl_iscan_ctrl { s32 state; struct task_struct *tsk; struct semaphore sync; - struct wl_iscan_eloop el; + struct brcmf_cfg80211_iscan_eloop el; void *data; - s8 ioctl_buf[WLC_IOCTL_SMLEN]; + s8 ioctl_buf[BRCMF_C_IOCTL_SMLEN]; s8 scan_buf[WL_ISCAN_BUF_MAX]; }; /* association inform */ -struct wl_connect_info { +struct brcmf_cfg80211_connect_info { u8 *req_ie; s32 req_ie_len; u8 *resp_ie; s32 resp_ie_len; }; -/* firmware /nvram downloading controller */ -struct wl_fw_ctrl { - const struct firmware *fw_entry; - unsigned long status; - u32 ptr; - s8 fw_name[WL_FILE_NAME_MAX]; - s8 nvram_name[WL_FILE_NAME_MAX]; -}; - /* assoc ie length */ -struct wl_assoc_ielen { +struct brcmf_cfg80211_assoc_ielen { u32 req_len; u32 resp_len; }; /* wpa2 pmk list */ -struct wl_pmk_list { +struct brcmf_cfg80211_pmk_list { pmkid_list_t pmkids; pmkid_t foo[MAXPMKID - 1]; }; /* dongle private data of cfg80211 interface */ -struct wl_priv { +struct brcmf_cfg80211_priv { struct wireless_dev *wdev; /* representing wl cfg80211 device */ - struct wl_conf *conf; /* dongle configuration */ + struct brcmf_cfg80211_conf *conf; /* dongle configuration */ struct cfg80211_scan_request *scan_request; /* scan request object */ - struct wl_event_loop el; /* main event loop */ + struct brcmf_cfg80211_event_loop el; /* main event loop */ struct list_head eq_list; /* used for event queue */ spinlock_t eq_lock; /* for event queue synchronization */ struct mutex usr_sync; /* maily for dongle up/down synchronization */ - struct wl_scan_results *bss_list; /* bss_list holding scanned + struct brcmf_scan_results *bss_list; /* bss_list holding scanned ap information */ - struct wl_scan_results *scan_results; - struct wl_scan_req *scan_req_int; /* scan request object for - internal purpose */ + struct brcmf_scan_results *scan_results; + struct brcmf_cfg80211_scan_req *scan_req_int; /* scan request object + for internal purpose */ struct wl_cfg80211_bss_info *bss_info; /* bss information for cfg80211 layer */ - struct wl_ie ie; /* information element object for + struct brcmf_cfg80211_ie ie; /* information element object for internal purpose */ struct semaphore event_sync; /* for synchronization of main event thread */ - struct wl_profile *profile; /* holding dongle profile */ - struct wl_iscan_ctrl *iscan; /* iscan controller */ - struct wl_connect_info conn_info; /* association information - container */ - struct wl_fw_ctrl *fw; /* control firwmare / nvram paramter - downloading */ - struct wl_pmk_list *pmk_list; /* wpa2 pmk list */ + struct brcmf_cfg80211_profile *profile; /* holding dongle profile */ + struct brcmf_cfg80211_iscan_ctrl *iscan; /* iscan controller */ + struct brcmf_cfg80211_connect_info conn_info; /* association info */ + struct brcmf_cfg80211_pmk_list *pmk_list; /* wpa2 pmk list */ struct task_struct *event_tsk; /* task of main event handler thread */ unsigned long status; /* current dongle status */ void *pub; @@ -361,26 +321,21 @@ struct wl_priv { u8 ci[0] __attribute__ ((__aligned__(NETDEV_ALIGN))); }; -#define wl_to_dev(w) (wiphy_dev(wl->wdev->wiphy)) -#define wl_to_wiphy(w) (w->wdev->wiphy) -#define wiphy_to_wl(w) ((struct wl_priv *)(wiphy_priv(w))) -#define wl_to_wdev(w) (w->wdev) -#define wdev_to_wl(w) ((struct wl_priv *)(wdev_priv(w))) -#define wl_to_ndev(w) (w->wdev->netdev) -#define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr)) -#define ci_to_wl(c) (ci->wl) -#define wl_to_ci(w) (&w->ci) -#define wl_to_sr(w) (w->scan_req_int) -#define wl_to_ie(w) (&w->ie) -#define iscan_to_wl(i) ((struct wl_priv *)(i->data)) -#define wl_to_iscan(w) (w->iscan) -#define wl_to_conn(w) (&w->conn_info) +#define cfg_to_wiphy(w) (w->wdev->wiphy) +#define wiphy_to_cfg(w) ((struct brcmf_cfg80211_priv *)(wiphy_priv(w))) +#define cfg_to_wdev(w) (w->wdev) +#define wdev_to_cfg(w) ((struct brcmf_cfg80211_priv *)(wdev_priv(w))) +#define cfg_to_ndev(w) (w->wdev->netdev) +#define ndev_to_cfg(n) (wdev_to_cfg(n->ieee80211_ptr)) +#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data)) +#define cfg_to_iscan(w) (w->iscan) +#define cfg_to_conn(w) (&w->conn_info) -static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, - struct wl_bss_info *bss) +static inline struct brcmf_bss_info *next_bss(struct brcmf_scan_results *list, + struct brcmf_bss_info *bss) { return bss = bss ? - (struct wl_bss_info *)((unsigned long)bss + + (struct brcmf_bss_info *)((unsigned long)bss + le32_to_cpu(bss->length)) : list->bss_info; } @@ -388,26 +343,14 @@ static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, #define for_each_bss(list, bss, __i) \ for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss)) -extern s32 wl_cfg80211_attach(struct net_device *ndev, void *data); -extern void wl_cfg80211_detach(void); +extern s32 brcmf_cfg80211_attach(struct net_device *ndev, void *data); +extern void brcmf_cfg80211_detach(void); /* event handler from dongle */ -extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e, - void *data); -extern void wl_cfg80211_sdio_func(void *func); /* set sdio function info */ -extern struct sdio_func *wl_cfg80211_get_sdio_func(void); /* set sdio function info */ -extern s32 wl_cfg80211_up(void); /* dongle up */ -extern s32 wl_cfg80211_down(void); /* dongle down */ -extern void wl_cfg80211_dbg_level(u32 level); /* set dongle - debugging level */ -extern void *wl_cfg80211_request_fw(s8 *file_name); /* request fw /nvram - downloading */ -extern s32 wl_cfg80211_read_fw(s8 *buf, u32 size); /* read fw - image */ -extern void wl_cfg80211_release_fw(void); /* release fw */ -extern s8 *wl_cfg80211_get_fwname(void); /* get firmware name for - the dongle */ -extern s8 *wl_cfg80211_get_nvramname(void); /* get nvram name for - the dongle */ -extern void wl_os_wd_timer(struct net_device *ndev, uint wdtick); +extern void brcmf_cfg80211_event(struct net_device *ndev, + const struct brcmf_event_msg *e, void *data); +extern void brcmf_cfg80211_sdio_func(void *func); /* set sdio function info */ +extern struct sdio_func *brcmf_cfg80211_get_sdio_func(void); +extern s32 brcmf_cfg80211_up(void); /* dongle up */ +extern s32 brcmf_cfg80211_down(void); /* dongle down */ #endif /* _wl_cfg80211_h_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c deleted file mode 100644 index 53e6a10655e1..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ /dev/null @@ -1,3689 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -typedef const struct si_pub si_t; - -#define WL_ERROR(fmt, args...) printk(fmt, ##args) -#define WL_TRACE(fmt, args...) no_printk(fmt, ##args) -#define WL_INFORM(fmt, args...) no_printk(fmt, ##args) -#define WL_WSEC(fmt, args...) no_printk(fmt, ##args) -#define WL_SCAN(fmt, args...) no_printk(fmt, ##args) - -#include - -#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | \ - TKIP_ENABLED | AES_ENABLED)) - -#include - -#define WL_IW_USE_ISCAN 1 -#define ENABLE_ACTIVE_PASSIVE_SCAN_SUPPRESS 1 - -bool g_set_essid_before_scan = true; - -#define WL_IW_IOCTL_CALL(func_call) \ - do { \ - func_call; \ - } while (0) - -static int g_onoff = G_WLAN_SET_ON; -wl_iw_extra_params_t g_wl_iw_params; - -extern bool wl_iw_conn_status_str(u32 event_type, u32 status, - u32 reason, char *stringBuf, uint buflen); - -#define MAX_WLIW_IOCTL_LEN 1024 - -#ifdef CONFIG_WIRELESS_EXT -extern int dhd_wait_pend8021x(struct net_device *dev); -#endif - -#if WIRELESS_EXT < 19 -#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) -#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) -#endif - -static void *g_scan; -static volatile uint g_scan_specified_ssid; -static wlc_ssid_t g_specific_ssid; - -static wlc_ssid_t g_ssid; - -#if defined(WL_IW_USE_ISCAN) -#define ISCAN_STATE_IDLE 0 -#define ISCAN_STATE_SCANING 1 - -#define WLC_IW_ISCAN_MAXLEN 2048 -typedef struct iscan_buf { - struct iscan_buf *next; - char iscan_buf[WLC_IW_ISCAN_MAXLEN]; -} iscan_buf_t; - -typedef struct iscan_info { - struct net_device *dev; - struct timer_list timer; - u32 timer_ms; - u32 timer_on; - int iscan_state; - iscan_buf_t *list_hdr; - iscan_buf_t *list_cur; - - struct task_struct *sysioc_tsk; - struct semaphore sysioc_sem; - -#if defined CSCAN - char ioctlbuf[WLC_IOCTL_MEDLEN]; -#else - char ioctlbuf[WLC_IOCTL_SMLEN]; -#endif - wl_iscan_params_t *iscan_ex_params_p; - int iscan_ex_param_size; -} iscan_info_t; -iscan_info_t *g_iscan; - -static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; - -/* Global ASSERT type flag */ -u32 g_assert_type; - -static void wl_iw_timerfunc(unsigned long data); -static void wl_iw_set_event_mask(struct net_device *dev); -static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action); -#endif /* defined(WL_IW_USE_ISCAN) */ - -static int -wl_iw_set_scan(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -static int -wl_iw_get_scan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra); - -static uint -wl_iw_get_scan_prep(wl_scan_results_t *list, - struct iw_request_info *info, char *extra, short max_size); - -static void swap_key_from_BE(wl_wsec_key_t *key) -{ - key->index = cpu_to_le32(key->index); - key->len = cpu_to_le32(key->len); - key->algo = cpu_to_le32(key->algo); - key->flags = cpu_to_le32(key->flags); - key->rxiv.hi = cpu_to_le32(key->rxiv.hi); - key->rxiv.lo = cpu_to_le16(key->rxiv.lo); - key->iv_initialized = cpu_to_le32(key->iv_initialized); -} - -static void swap_key_to_BE(wl_wsec_key_t *key) -{ - key->index = le32_to_cpu(key->index); - key->len = le32_to_cpu(key->len); - key->algo = le32_to_cpu(key->algo); - key->flags = le32_to_cpu(key->flags); - key->rxiv.hi = le32_to_cpu(key->rxiv.hi); - key->rxiv.lo = le16_to_cpu(key->rxiv.lo); - key->iv_initialized = le32_to_cpu(key->iv_initialized); -} - -static int dev_wlc_ioctl(struct net_device *dev, int cmd, void *arg, int len) -{ - struct ifreq ifr; - wl_ioctl_t ioc; - mm_segment_t fs; - int ret = -EINVAL; - - if (!dev) { - WL_ERROR("%s: dev is null\n", __func__); - return ret; - } - - WL_INFORM("\n%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, len:%d\n", - __func__, current->pid, cmd, arg, len); - - if (g_onoff == G_WLAN_SET_ON) { - memset(&ioc, 0, sizeof(ioc)); - ioc.cmd = cmd; - ioc.buf = arg; - ioc.len = len; - - strcpy(ifr.ifr_name, dev->name); - ifr.ifr_data = (caddr_t)&ioc; - - ret = dev_open(dev); - if (ret) { - WL_ERROR("%s: Error dev_open: %d\n", __func__, ret); - return ret; - } - - fs = get_fs(); - set_fs(get_ds()); - ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE); - set_fs(fs); - } else { - WL_TRACE("%s: call after driver stop : ignored\n", __func__); - } - return ret; -} - -static int dev_wlc_intvar_set(struct net_device *dev, char *name, int val) -{ - char buf[WLC_IOCTL_SMLEN]; - uint len; - - val = cpu_to_le32(val); - len = bcm_mkiovar(name, (char *)(&val), sizeof(val), buf, sizeof(buf)); - ASSERT(len); - - return dev_wlc_ioctl(dev, WLC_SET_VAR, buf, len); -} - -#if defined(WL_IW_USE_ISCAN) -static int -dev_iw_iovar_setbuf(struct net_device *dev, - char *iovar, - void *param, int paramlen, void *bufptr, int buflen) -{ - int iolen; - - iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); - ASSERT(iolen); - - if (iolen == 0) - return 0; - - return dev_wlc_ioctl(dev, WLC_SET_VAR, bufptr, iolen); -} - -static int -dev_iw_iovar_getbuf(struct net_device *dev, - char *iovar, - void *param, int paramlen, void *bufptr, int buflen) -{ - int iolen; - - iolen = bcm_mkiovar(iovar, param, paramlen, bufptr, buflen); - ASSERT(iolen); - - return dev_wlc_ioctl(dev, WLC_GET_VAR, bufptr, buflen); -} -#endif /* defined(WL_IW_USE_ISCAN) */ - -#if WIRELESS_EXT > 17 -static int -dev_wlc_bufvar_set(struct net_device *dev, char *name, char *buf, int len) -{ - static char ioctlbuf[MAX_WLIW_IOCTL_LEN]; - uint buflen; - - buflen = bcm_mkiovar(name, buf, len, ioctlbuf, sizeof(ioctlbuf)); - ASSERT(buflen); - - return dev_wlc_ioctl(dev, WLC_SET_VAR, ioctlbuf, buflen); -} -#endif /* WIRELESS_EXT > 17 */ - -static int -dev_wlc_bufvar_get(struct net_device *dev, char *name, char *buf, int buflen) -{ - static char ioctlbuf[MAX_WLIW_IOCTL_LEN]; - int error; - uint len; - - len = bcm_mkiovar(name, NULL, 0, ioctlbuf, sizeof(ioctlbuf)); - ASSERT(len); - error = - dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)ioctlbuf, - MAX_WLIW_IOCTL_LEN); - if (!error) - memcpy(buf, ioctlbuf, buflen); - - return error; -} - -static int dev_wlc_intvar_get(struct net_device *dev, char *name, int *retval) -{ - union { - char buf[WLC_IOCTL_SMLEN]; - int val; - } var; - int error; - - uint len; - uint data_null; - - len = - bcm_mkiovar(name, (char *)(&data_null), 0, (char *)(&var), - sizeof(var.buf)); - ASSERT(len); - error = dev_wlc_ioctl(dev, WLC_GET_VAR, (void *)&var, len); - - *retval = le32_to_cpu(var.val); - - return error; -} - -#if WIRELESS_EXT < 13 -struct iw_request_info { - __u16 cmd; - __u16 flags; -}; - -typedef int (*iw_handler) (struct net_device *dev, - struct iw_request_info *info, - void *wrqu, char *extra); -#endif - -static int -wl_iw_config_commit(struct net_device *dev, - struct iw_request_info *info, void *zwrq, char *extra) -{ - wlc_ssid_t ssid; - int error; - struct sockaddr bssid; - - WL_TRACE("%s: SIOCSIWCOMMIT\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)); - if (error) - return error; - - ssid.SSID_len = le32_to_cpu(ssid.SSID_len); - - if (!ssid.SSID_len) - return 0; - - memset(&bssid, 0, sizeof(struct sockaddr)); - error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETH_ALEN); - if (error) { - WL_ERROR("%s: WLC_REASSOC to %s failed\n", - __func__, ssid.SSID); - return error; - } - - return 0; -} - -static int -wl_iw_get_name(struct net_device *dev, - struct iw_request_info *info, char *cwrq, char *extra) -{ - WL_TRACE("%s: SIOCGIWNAME\n", dev->name); - - strcpy(cwrq, "IEEE 802.11-DS"); - - return 0; -} - -static int -wl_iw_set_freq(struct net_device *dev, - struct iw_request_info *info, struct iw_freq *fwrq, char *extra) -{ - int error, chan; - uint sf = 0; - - WL_TRACE("\n %s %s: SIOCSIWFREQ\n", __func__, dev->name); - - if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) { - chan = fwrq->m; - } else { - if (fwrq->e >= 6) { - fwrq->e -= 6; - while (fwrq->e--) - fwrq->m *= 10; - } else if (fwrq->e < 6) { - while (fwrq->e++ < 6) - fwrq->m /= 10; - } - if (fwrq->m > 4000 && fwrq->m < 5000) - sf = WF_CHAN_FACTOR_4_G; - - chan = bcm_mhz2channel(fwrq->m, sf); - } - chan = cpu_to_le32(chan); - - error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan)); - if (error) - return error; - - g_wl_iw_params.target_channel = chan; - return -EINPROGRESS; -} - -static int -wl_iw_get_freq(struct net_device *dev, - struct iw_request_info *info, struct iw_freq *fwrq, char *extra) -{ - channel_info_t ci; - int error; - - WL_TRACE("%s: SIOCGIWFREQ\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)); - if (error) - return error; - - fwrq->m = le32_to_cpu(ci.hw_channel); - fwrq->e = le32_to_cpu(0); - return 0; -} - -static int -wl_iw_set_mode(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, char *extra) -{ - int infra = 0, ap = 0, error = 0; - - WL_TRACE("%s: SIOCSIWMODE\n", dev->name); - - switch (*uwrq) { - case IW_MODE_MASTER: - infra = ap = 1; - break; - case IW_MODE_ADHOC: - case IW_MODE_AUTO: - break; - case IW_MODE_INFRA: - infra = 1; - break; - default: - return -EINVAL; - } - infra = cpu_to_le32(infra); - ap = cpu_to_le32(ap); - - error = dev_wlc_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(infra)); - if (error) - return error; - - error = dev_wlc_ioctl(dev, WLC_SET_AP, &ap, sizeof(ap)); - if (error) - return error; - - return -EINPROGRESS; -} - -static int -wl_iw_get_mode(struct net_device *dev, - struct iw_request_info *info, __u32 *uwrq, char *extra) -{ - int error, infra = 0, ap = 0; - - WL_TRACE("%s: SIOCGIWMODE\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra)); - if (error) - return error; - - error = dev_wlc_ioctl(dev, WLC_GET_AP, &ap, sizeof(ap)); - if (error) - return error; - - infra = le32_to_cpu(infra); - ap = le32_to_cpu(ap); - *uwrq = infra ? ap ? IW_MODE_MASTER : IW_MODE_INFRA : IW_MODE_ADHOC; - - return 0; -} - -static int -wl_iw_get_range(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - struct iw_range *range = (struct iw_range *)extra; - wl_u32_list_t *list; - wl_rateset_t rateset; - s8 *channels; - int error, i, k; - uint ch; - - int phytype; - int bw_cap = 0, sgi_tx = 0, nmode = 0; - channel_info_t ci; - u8 nrate_list2copy = 0; - u16 nrate_list[4][8] = { {13, 26, 39, 52, 78, 104, 117, 130}, - {14, 29, 43, 58, 87, 116, 130, 144}, - {27, 54, 81, 108, 162, 216, 243, 270}, - {30, 60, 90, 120, 180, 240, 270, 300} - }; - - WL_TRACE("%s: SIOCGIWRANGE\n", dev->name); - - if (!extra) - return -EINVAL; - - channels = kmalloc((MAXCHANNEL + 1) * 4, GFP_KERNEL); - if (!channels) { - WL_ERROR("Could not alloc channels\n"); - return -ENOMEM; - } - list = (wl_u32_list_t *) channels; - - dwrq->length = sizeof(struct iw_range); - memset(range, 0, sizeof(*range)); - - list->count = cpu_to_le32(MAXCHANNEL); - error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels, - (MAXCHANNEL + 1) * 4); - if (error) { - kfree(channels); - return error; - } - for (i = 0; i < le32_to_cpu(list->count) && i < IW_MAX_FREQUENCIES; - i++) { - range->freq[i].i = le32_to_cpu(list->element[i]); - - ch = le32_to_cpu(list->element[i]); - if (ch <= CH_MAX_2G_CHANNEL) { - range->freq[i].m = ieee80211_dsss_chan_to_freq(ch); - } else { - range->freq[i].m = ieee80211_ofdm_chan_to_freq( - WF_CHAN_FACTOR_5_G/2, ch); - } - range->freq[i].e = 6; - } - range->num_frequency = range->num_channels = i; - - range->max_qual.qual = 5; - range->max_qual.level = 0x100 - 200; - range->max_qual.noise = 0x100 - 200; - range->sensitivity = 65535; - -#if WIRELESS_EXT > 11 - range->avg_qual.qual = 3; - range->avg_qual.level = 0x100 + WL_IW_RSSI_GOOD; - range->avg_qual.noise = 0x100 - 75; -#endif - - error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, - sizeof(rateset)); - if (error) { - kfree(channels); - return error; - } - rateset.count = le32_to_cpu(rateset.count); - range->num_bitrates = rateset.count; - for (i = 0; i < rateset.count && i < IW_MAX_BITRATES; i++) - range->bitrate[i] = (rateset.rates[i] & 0x7f) * 500000; - dev_wlc_intvar_get(dev, "nmode", &nmode); - dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &phytype, sizeof(phytype)); - - if (nmode == 1 && phytype == WLC_PHY_TYPE_SSN) { - dev_wlc_intvar_get(dev, "mimo_bw_cap", &bw_cap); - dev_wlc_intvar_get(dev, "sgi_tx", &sgi_tx); - dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, - sizeof(channel_info_t)); - ci.hw_channel = le32_to_cpu(ci.hw_channel); - - if (bw_cap == 0 || (bw_cap == 2 && ci.hw_channel <= 14)) { - if (sgi_tx == 0) - nrate_list2copy = 0; - else - nrate_list2copy = 1; - } - if (bw_cap == 1 || (bw_cap == 2 && ci.hw_channel >= 36)) { - if (sgi_tx == 0) - nrate_list2copy = 2; - else - nrate_list2copy = 3; - } - range->num_bitrates += 8; - for (k = 0; i < range->num_bitrates; k++, i++) { - range->bitrate[i] = - (nrate_list[nrate_list2copy][k]) * 500000; - } - } - - error = dev_wlc_ioctl(dev, WLC_GET_PHYTYPE, &i, sizeof(i)); - if (error) { - kfree(channels); - return error; - } - i = le32_to_cpu(i); - if (i == WLC_PHY_TYPE_A) - range->throughput = 24000000; - else - range->throughput = 1500000; - - range->min_rts = 0; - range->max_rts = 2347; - range->min_frag = 256; - range->max_frag = 2346; - - range->max_encoding_tokens = DOT11_MAX_DEFAULT_KEYS; - range->num_encoding_sizes = 4; - range->encoding_size[0] = WLAN_KEY_LEN_WEP40; - range->encoding_size[1] = WLAN_KEY_LEN_WEP104; -#if WIRELESS_EXT > 17 - range->encoding_size[2] = WLAN_KEY_LEN_TKIP; -#else - range->encoding_size[2] = 0; -#endif - range->encoding_size[3] = WLAN_KEY_LEN_AES_CMAC; - - range->min_pmp = 0; - range->max_pmp = 0; - range->min_pmt = 0; - range->max_pmt = 0; - range->pmp_flags = 0; - range->pm_capa = 0; - - range->num_txpower = 2; - range->txpower[0] = 1; - range->txpower[1] = 255; - range->txpower_capa = IW_TXPOW_MWATT; - -#if WIRELESS_EXT > 10 - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 19; - - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT; - range->r_time_flags = 0; - range->min_retry = 1; - range->max_retry = 255; - range->min_r_time = 0; - range->max_r_time = 0; -#endif - -#if WIRELESS_EXT > 17 - range->enc_capa = IW_ENC_CAPA_WPA; - range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP; - range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP; - range->enc_capa |= IW_ENC_CAPA_WPA2; - - IW_EVENT_CAPA_SET_KERNEL(range->event_capa); - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP); - IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN); - IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP); - IW_EVENT_CAPA_SET(range->event_capa, IWEVMICHAELMICFAILURE); - IW_EVENT_CAPA_SET(range->event_capa, IWEVPMKIDCAND); -#endif /* WIRELESS_EXT > 17 */ - - kfree(channels); - - return 0; -} - -static int rssi_to_qual(int rssi) -{ - if (rssi <= WL_IW_RSSI_NO_SIGNAL) - return 0; - else if (rssi <= WL_IW_RSSI_VERY_LOW) - return 1; - else if (rssi <= WL_IW_RSSI_LOW) - return 2; - else if (rssi <= WL_IW_RSSI_GOOD) - return 3; - else if (rssi <= WL_IW_RSSI_VERY_GOOD) - return 4; - else - return 5; -} - -static int -wl_iw_set_spy(struct net_device *dev, - struct iw_request_info *info, struct iw_point *dwrq, char *extra) -{ - wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - struct sockaddr *addr = (struct sockaddr *)extra; - int i; - - WL_TRACE("%s: SIOCSIWSPY\n", dev->name); - - if (!extra) - return -EINVAL; - - iw->spy_num = min_t(int, ARRAY_SIZE(iw->spy_addr), dwrq->length); - for (i = 0; i < iw->spy_num; i++) - memcpy(iw->spy_addr[i], addr[i].sa_data, ETH_ALEN); - memset(iw->spy_qual, 0, sizeof(iw->spy_qual)); - - return 0; -} - -static int -wl_iw_get_spy(struct net_device *dev, - struct iw_request_info *info, struct iw_point *dwrq, char *extra) -{ - wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - struct sockaddr *addr = (struct sockaddr *)extra; - struct iw_quality *qual = (struct iw_quality *)&addr[iw->spy_num]; - int i; - - WL_TRACE("%s: SIOCGIWSPY\n", dev->name); - - if (!extra) - return -EINVAL; - - dwrq->length = iw->spy_num; - for (i = 0; i < iw->spy_num; i++) { - memcpy(addr[i].sa_data, iw->spy_addr[i], ETH_ALEN); - addr[i].sa_family = AF_UNIX; - memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality)); - iw->spy_qual[i].updated = 0; - } - - return 0; -} - -static int -wl_iw_ch_to_chanspec(int ch, wl_join_params_t *join_params, - int *join_params_size) -{ - chanspec_t chanspec = 0; - - if (ch != 0) { - join_params->params.chanspec_num = 1; - join_params->params.chanspec_list[0] = ch; - - if (join_params->params.chanspec_list[0]) - chanspec |= WL_CHANSPEC_BAND_2G; - else - chanspec |= WL_CHANSPEC_BAND_5G; - - chanspec |= WL_CHANSPEC_BW_20; - chanspec |= WL_CHANSPEC_CTL_SB_NONE; - - *join_params_size += WL_ASSOC_PARAMS_FIXED_SIZE + - join_params->params.chanspec_num * sizeof(chanspec_t); - - join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; - join_params->params.chanspec_list[0] |= chanspec; - join_params->params.chanspec_list[0] = - cpu_to_le16(join_params->params.chanspec_list[0]); - - join_params->params.chanspec_num = - cpu_to_le32(join_params->params.chanspec_num); - - WL_TRACE("%s join_params->params.chanspec_list[0]= %X\n", - __func__, join_params->params.chanspec_list[0]); - } - return 1; -} - -static int -wl_iw_set_wap(struct net_device *dev, - struct iw_request_info *info, struct sockaddr *awrq, char *extra) -{ - int error = -EINVAL; - wl_join_params_t join_params; - int join_params_size; - - WL_TRACE("%s: SIOCSIWAP\n", dev->name); - - if (awrq->sa_family != ARPHRD_ETHER) { - WL_ERROR("Invalid Header...sa_family\n"); - return -EINVAL; - } - - if (is_broadcast_ether_addr(awrq->sa_data) || - is_zero_ether_addr(awrq->sa_data)) { - scb_val_t scbval; - memset(&scbval, 0, sizeof(scb_val_t)); - (void)dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, - sizeof(scb_val_t)); - return 0; - } - - memset(&join_params, 0, sizeof(join_params)); - join_params_size = sizeof(join_params.ssid); - - memcpy(join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params.ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len); - memcpy(&join_params.params.bssid, awrq->sa_data, ETH_ALEN); - - WL_TRACE("%s target_channel=%d\n", - __func__, g_wl_iw_params.target_channel); - wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, - &join_params_size); - - error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, - join_params_size); - if (error) { - WL_ERROR("%s Invalid ioctl data=%d\n", __func__, error); - } - - if (g_ssid.SSID_len) { - WL_TRACE("%s: join SSID=%s BSSID=%pM ch=%d\n", - __func__, g_ssid.SSID, awrq->sa_data, - g_wl_iw_params.target_channel); - } - - memset(&g_ssid, 0, sizeof(g_ssid)); - return 0; -} - -static int -wl_iw_get_wap(struct net_device *dev, - struct iw_request_info *info, struct sockaddr *awrq, char *extra) -{ - WL_TRACE("%s: SIOCGIWAP\n", dev->name); - - awrq->sa_family = ARPHRD_ETHER; - memset(awrq->sa_data, 0, ETH_ALEN); - - (void)dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETH_ALEN); - - return 0; -} - -#if WIRELESS_EXT > 17 -static int -wl_iw_mlme(struct net_device *dev, - struct iw_request_info *info, struct sockaddr *awrq, char *extra) -{ - struct iw_mlme *mlme; - scb_val_t scbval; - int error = -EINVAL; - - WL_TRACE("%s: SIOCSIWMLME DISASSOC/DEAUTH\n", dev->name); - - mlme = (struct iw_mlme *)extra; - if (mlme == NULL) { - WL_ERROR("Invalid ioctl data\n"); - return error; - } - - scbval.val = mlme->reason_code; - memcpy(&scbval.ea, &mlme->addr.sa_data, ETH_ALEN); - - if (mlme->cmd == IW_MLME_DISASSOC) { - scbval.val = cpu_to_le32(scbval.val); - error = - dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, - sizeof(scb_val_t)); - } else if (mlme->cmd == IW_MLME_DEAUTH) { - scbval.val = cpu_to_le32(scbval.val); - error = - dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, - &scbval, sizeof(scb_val_t)); - } else { - WL_ERROR("Invalid ioctl data\n"); - return error; - } - - return error; -} -#endif /* WIRELESS_EXT > 17 */ - -#ifndef WL_IW_USE_ISCAN -static int -wl_iw_get_aplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wl_scan_results_t *list; - struct sockaddr *addr = (struct sockaddr *)extra; - struct iw_quality qual[IW_MAX_AP]; - wl_bss_info_t *bi = NULL; - int error, i; - uint buflen = dwrq->length; - - WL_TRACE("%s: SIOCGIWAPLIST\n", dev->name); - - if (!extra) - return -EINVAL; - - list = kzalloc(buflen, GFP_KERNEL); - if (!list) - return -ENOMEM; - list->buflen = cpu_to_le32(buflen); - error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen); - if (error) { - WL_ERROR("%d: Scan results error %d\n", __LINE__, error); - kfree(list); - return error; - } - list->buflen = le32_to_cpu(list->buflen); - list->version = le32_to_cpu(list->version); - list->count = le32_to_cpu(list->count); - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __func__, list->version); - kfree(list); - return -EINVAL; - } - - for (i = 0, dwrq->length = 0; - i < list->count && dwrq->length < IW_MAX_AP; i++) { - bi = bi ? (wl_bss_info_t *) ((unsigned long)bi + - le32_to_cpu(bi->length)) : list-> - bss_info; - ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <= - ((unsigned long)list + buflen)); - - if (!(le16_to_cpu(bi->capability) & WLAN_CAPABILITY_ESS)) - continue; - - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETH_ALEN); - addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = rssi_to_qual(le16_to_cpu(bi->RSSI)); - qual[dwrq->length].level = 0x100 + le16_to_cpu(bi->RSSI); - qual[dwrq->length].noise = 0x100 + bi->phy_noise; - -#if WIRELESS_EXT > 18 - qual[dwrq->length].updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -#else - qual[dwrq->length].updated = 7; -#endif - dwrq->length++; - } - - kfree(list); - - if (dwrq->length) { - memcpy(&addr[dwrq->length], qual, - sizeof(struct iw_quality) * dwrq->length); - dwrq->flags = 1; - } - - return 0; -} -#endif /* WL_IW_USE_ISCAN */ - -#ifdef WL_IW_USE_ISCAN -static int -wl_iw_iscan_get_aplist(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wl_scan_results_t *list; - iscan_buf_t *buf; - iscan_info_t *iscan = g_iscan; - - struct sockaddr *addr = (struct sockaddr *)extra; - struct iw_quality qual[IW_MAX_AP]; - wl_bss_info_t *bi = NULL; - int i; - - WL_TRACE("%s: SIOCGIWAPLIST\n", dev->name); - - if (!extra) - return -EINVAL; - - if ((!iscan) || (!iscan->sysioc_tsk)) { - WL_ERROR("%s error\n", __func__); - return 0; - } - - buf = iscan->list_hdr; - while (buf) { - list = &((wl_iscan_results_t *) buf->iscan_buf)->results; - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __func__, list->version); - return -EINVAL; - } - - bi = NULL; - for (i = 0, dwrq->length = 0; - i < list->count && dwrq->length < IW_MAX_AP; i++) { - bi = bi ? (wl_bss_info_t *) ((unsigned long)bi + - le32_to_cpu(bi->length)) : - list->bss_info; - ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <= - ((unsigned long)list + WLC_IW_ISCAN_MAXLEN)); - - if (!(le16_to_cpu(bi->capability) & - WLAN_CAPABILITY_ESS)) - continue; - - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, - ETH_ALEN); - addr[dwrq->length].sa_family = ARPHRD_ETHER; - qual[dwrq->length].qual = - rssi_to_qual(le16_to_cpu(bi->RSSI)); - qual[dwrq->length].level = 0x100 + - le16_to_cpu(bi->RSSI); - qual[dwrq->length].noise = 0x100 + bi->phy_noise; - -#if WIRELESS_EXT > 18 - qual[dwrq->length].updated = - IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; -#else - qual[dwrq->length].updated = 7; -#endif - - dwrq->length++; - } - buf = buf->next; - } - if (dwrq->length) { - memcpy(&addr[dwrq->length], qual, - sizeof(struct iw_quality) * dwrq->length); - dwrq->flags = 1; - } - - return 0; -} - -static int wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid) -{ - int err = 0; - - memcpy(params->bssid, ether_bcast, ETH_ALEN); - params->bss_type = DOT11_BSSTYPE_ANY; - params->scan_type = 0; - params->nprobes = -1; - params->active_time = -1; - params->passive_time = -1; - params->home_time = -1; - params->channel_num = 0; - - params->nprobes = cpu_to_le32(params->nprobes); - params->active_time = cpu_to_le32(params->active_time); - params->passive_time = cpu_to_le32(params->passive_time); - params->home_time = cpu_to_le32(params->home_time); - if (ssid && ssid->SSID_len) - memcpy(¶ms->ssid, ssid, sizeof(wlc_ssid_t)); - - return err; -} - -static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action) -{ - int err = 0; - - iscan->iscan_ex_params_p->version = cpu_to_le32(ISCAN_REQ_VERSION); - iscan->iscan_ex_params_p->action = cpu_to_le16(action); - iscan->iscan_ex_params_p->scan_duration = cpu_to_le16(0); - - WL_SCAN("%s : nprobes=%d\n", - __func__, iscan->iscan_ex_params_p->params.nprobes); - WL_SCAN("active_time=%d\n", - iscan->iscan_ex_params_p->params.active_time); - WL_SCAN("passive_time=%d\n", - iscan->iscan_ex_params_p->params.passive_time); - WL_SCAN("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time); - WL_SCAN("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type); - WL_SCAN("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type); - - (void)dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p, - iscan->iscan_ex_param_size, iscan->ioctlbuf, - sizeof(iscan->ioctlbuf)); - - return err; -} - -static void wl_iw_timerfunc(unsigned long data) -{ - iscan_info_t *iscan = (iscan_info_t *) data; - if (iscan) { - iscan->timer_on = 0; - if (iscan->iscan_state != ISCAN_STATE_IDLE) { - WL_TRACE("timer trigger\n"); - up(&iscan->sysioc_sem); - } - } -} - -static void wl_iw_set_event_mask(struct net_device *dev) -{ - char eventmask[WL_EVENTING_MASK_LEN]; - char iovbuf[WL_EVENTING_MASK_LEN + 12]; - - dev_iw_iovar_getbuf(dev, "event_msgs", "", 0, iovbuf, sizeof(iovbuf)); - memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN); - setbit(eventmask, WLC_E_SCAN_COMPLETE); - dev_iw_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, - iovbuf, sizeof(iovbuf)); -} - -static u32 wl_iw_iscan_get(iscan_info_t *iscan) -{ - iscan_buf_t *buf; - iscan_buf_t *ptr; - wl_iscan_results_t *list_buf; - wl_iscan_results_t list; - wl_scan_results_t *results; - u32 status; - int res = 0; - - MUTEX_LOCK_WL_SCAN_SET(); - if (iscan->list_cur) { - buf = iscan->list_cur; - iscan->list_cur = buf->next; - } else { - buf = kmalloc(sizeof(iscan_buf_t), GFP_KERNEL); - if (!buf) { - WL_ERROR("%s can't alloc iscan_buf_t : going to abort current iscan\n", - __func__); - MUTEX_UNLOCK_WL_SCAN_SET(); - return WL_SCAN_RESULTS_NO_MEM; - } - buf->next = NULL; - if (!iscan->list_hdr) - iscan->list_hdr = buf; - else { - ptr = iscan->list_hdr; - while (ptr->next) { - ptr = ptr->next; - } - ptr->next = buf; - } - } - memset(buf->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN); - list_buf = (wl_iscan_results_t *) buf->iscan_buf; - results = &list_buf->results; - results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE; - results->version = 0; - results->count = 0; - - memset(&list, 0, sizeof(list)); - list.results.buflen = cpu_to_le32(WLC_IW_ISCAN_MAXLEN); - res = dev_iw_iovar_getbuf(iscan->dev, - "iscanresults", - &list, - WL_ISCAN_RESULTS_FIXED_SIZE, - buf->iscan_buf, WLC_IW_ISCAN_MAXLEN); - if (res == 0) { - results->buflen = le32_to_cpu(results->buflen); - results->version = le32_to_cpu(results->version); - results->count = le32_to_cpu(results->count); - WL_TRACE("results->count = %d\n", results->count); - WL_TRACE("results->buflen = %d\n", results->buflen); - status = le32_to_cpu(list_buf->status); - } else { - WL_ERROR("%s returns error %d\n", __func__, res); - status = WL_SCAN_RESULTS_NO_MEM; - } - MUTEX_UNLOCK_WL_SCAN_SET(); - return status; -} - -static void wl_iw_force_specific_scan(iscan_info_t *iscan) -{ - WL_TRACE("%s force Specific SCAN for %s\n", - __func__, g_specific_ssid.SSID); - rtnl_lock(); - - (void)dev_wlc_ioctl(iscan->dev, WLC_SCAN, &g_specific_ssid, - sizeof(g_specific_ssid)); - - rtnl_unlock(); -} - -static void wl_iw_send_scan_complete(iscan_info_t *iscan) -{ -#ifndef SANDGATE2G - union iwreq_data wrqu; - - memset(&wrqu, 0, sizeof(wrqu)); - - wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL); - WL_TRACE("Send Event ISCAN complete\n"); -#endif -} - -static int _iscan_sysioc_thread(void *data) -{ - u32 status; - iscan_info_t *iscan = (iscan_info_t *) data; - static bool iscan_pass_abort = false; - - allow_signal(SIGTERM); - status = WL_SCAN_RESULTS_PARTIAL; - while (down_interruptible(&iscan->sysioc_sem) == 0) { - if (kthread_should_stop()) - break; - - if (iscan->timer_on) { - del_timer_sync(&iscan->timer); - iscan->timer_on = 0; - } - rtnl_lock(); - status = wl_iw_iscan_get(iscan); - rtnl_unlock(); - if (g_scan_specified_ssid && (iscan_pass_abort == true)) { - WL_TRACE("%s Get results from specific scan status = %d\n", - __func__, status); - wl_iw_send_scan_complete(iscan); - iscan_pass_abort = false; - status = -1; - } - - switch (status) { - case WL_SCAN_RESULTS_PARTIAL: - WL_TRACE("iscanresults incomplete\n"); - rtnl_lock(); - wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); - rtnl_unlock(); - mod_timer(&iscan->timer, - jiffies + iscan->timer_ms * HZ / 1000); - iscan->timer_on = 1; - break; - case WL_SCAN_RESULTS_SUCCESS: - WL_TRACE("iscanresults complete\n"); - iscan->iscan_state = ISCAN_STATE_IDLE; - wl_iw_send_scan_complete(iscan); - break; - case WL_SCAN_RESULTS_PENDING: - WL_TRACE("iscanresults pending\n"); - mod_timer(&iscan->timer, - jiffies + iscan->timer_ms * HZ / 1000); - iscan->timer_on = 1; - break; - case WL_SCAN_RESULTS_ABORTED: - WL_TRACE("iscanresults aborted\n"); - iscan->iscan_state = ISCAN_STATE_IDLE; - if (g_scan_specified_ssid == 0) - wl_iw_send_scan_complete(iscan); - else { - iscan_pass_abort = true; - wl_iw_force_specific_scan(iscan); - } - break; - case WL_SCAN_RESULTS_NO_MEM: - WL_TRACE("iscanresults can't alloc memory: skip\n"); - iscan->iscan_state = ISCAN_STATE_IDLE; - break; - default: - WL_TRACE("iscanresults returned unknown status %d\n", - status); - break; - } - } - - if (iscan->timer_on) { - del_timer_sync(&iscan->timer); - iscan->timer_on = 0; - } - return 0; -} -#endif /* WL_IW_USE_ISCAN */ - -static int -wl_iw_set_scan(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int error; - WL_TRACE("\n:%s dev:%s: SIOCSIWSCAN : SCAN\n", __func__, dev->name); - - g_set_essid_before_scan = false; -#if defined(CSCAN) - WL_ERROR("%s: Scan from SIOCGIWSCAN not supported\n", __func__); - return -EINVAL; -#endif - - if (g_onoff == G_WLAN_SET_OFF) - return 0; - - memset(&g_specific_ssid, 0, sizeof(g_specific_ssid)); -#ifndef WL_IW_USE_ISCAN - g_scan_specified_ssid = 0; -#endif - -#if WIRELESS_EXT > 17 - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; - if (g_scan_specified_ssid) { - WL_TRACE("%s Specific SCAN is not done ignore scan for = %s\n", - __func__, req->essid); - return -EBUSY; - } else { - g_specific_ssid.SSID_len = min_t(size_t, - sizeof(g_specific_ssid.SSID), - req->essid_len); - memcpy(g_specific_ssid.SSID, req->essid, - g_specific_ssid.SSID_len); - g_specific_ssid.SSID_len = - cpu_to_le32(g_specific_ssid.SSID_len); - g_scan_specified_ssid = 1; - WL_TRACE("### Specific scan ssid=%s len=%d\n", - g_specific_ssid.SSID, - g_specific_ssid.SSID_len); - } - } - } -#endif /* WIRELESS_EXT > 17 */ - error = dev_wlc_ioctl(dev, WLC_SCAN, &g_specific_ssid, - sizeof(g_specific_ssid)); - if (error) { - WL_TRACE("#### Set SCAN for %s failed with %d\n", - g_specific_ssid.SSID, error); - g_scan_specified_ssid = 0; - return -EBUSY; - } - - return 0; -} - -#ifdef WL_IW_USE_ISCAN -int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag) -{ - wlc_ssid_t ssid; - iscan_info_t *iscan = g_iscan; - - if (flag) - rtnl_lock(); - - wl_iw_set_event_mask(dev); - - WL_TRACE("+++: Set Broadcast ISCAN\n"); - memset(&ssid, 0, sizeof(ssid)); - - iscan->list_cur = iscan->list_hdr; - iscan->iscan_state = ISCAN_STATE_SCANING; - - memset(&iscan->iscan_ex_params_p->params, 0, - iscan->iscan_ex_param_size); - wl_iw_iscan_prep(&iscan->iscan_ex_params_p->params, &ssid); - wl_iw_iscan(iscan, &ssid, WL_SCAN_ACTION_START); - - if (flag) - rtnl_unlock(); - - mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); - - iscan->timer_on = 1; - - return 0; -} - -static int -wl_iw_iscan_set_scan(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - wlc_ssid_t ssid; - iscan_info_t *iscan = g_iscan; - - WL_TRACE("%s: SIOCSIWSCAN : ISCAN\n", dev->name); - -#if defined(CSCAN) - WL_ERROR("%s: Scan from SIOCGIWSCAN not supported\n", __func__); - return -EINVAL; -#endif - - if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE("%s: driver is not up yet after START\n", __func__); - return 0; - } -#ifdef PNO_SUPPORT - if (dhd_dev_get_pno_status(dev)) { - WL_ERROR("%s: Scan called when PNO is active\n", __func__); - } -#endif - - if ((!iscan) || (!iscan->sysioc_tsk)) - return wl_iw_set_scan(dev, info, wrqu, extra); - - if (g_scan_specified_ssid) { - WL_TRACE("%s Specific SCAN already running ignoring BC scan\n", - __func__); - return -EBUSY; - } - - memset(&ssid, 0, sizeof(ssid)); - -#if WIRELESS_EXT > 17 - if (wrqu->data.length == sizeof(struct iw_scan_req)) { - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct iw_scan_req *req = (struct iw_scan_req *)extra; - ssid.SSID_len = min_t(size_t, sizeof(ssid.SSID), - req->essid_len); - memcpy(ssid.SSID, req->essid, ssid.SSID_len); - ssid.SSID_len = cpu_to_le32(ssid.SSID_len); - } else { - g_scan_specified_ssid = 0; - - if (iscan->iscan_state == ISCAN_STATE_SCANING) { - WL_TRACE("%s ISCAN already in progress\n", - __func__); - return 0; - } - } - } -#endif /* WIRELESS_EXT > 17 */ - wl_iw_iscan_set_scan_broadcast_prep(dev, 0); - - return 0; -} -#endif /* WL_IW_USE_ISCAN */ - -#if WIRELESS_EXT > 17 -static bool ie_is_wpa_ie(u8 **wpaie, u8 **tlvs, int *tlvs_len) -{ - - u8 *ie = *wpaie; - - if ((ie[1] >= 6) && - !memcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) { - return true; - } - - ie += ie[1] + 2; - *tlvs_len -= (int)(ie - *tlvs); - *tlvs = ie; - return false; -} - -static bool ie_is_wps_ie(u8 **wpsie, u8 **tlvs, int *tlvs_len) -{ - - u8 *ie = *wpsie; - - if ((ie[1] >= 4) && - !memcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) { - return true; - } - - ie += ie[1] + 2; - *tlvs_len -= (int)(ie - *tlvs); - *tlvs = ie; - return false; -} -#endif /* WIRELESS_EXT > 17 */ - -static int -wl_iw_handle_scanresults_ies(char **event_p, char *end, - struct iw_request_info *info, wl_bss_info_t *bi) -{ -#if WIRELESS_EXT > 17 - struct iw_event iwe; - char *event; - - event = *event_p; - if (bi->ie_length) { - bcm_tlv_t *ie; - u8 *ptr = ((u8 *) bi) + sizeof(wl_bss_info_t); - int ptr_len = bi->ie_length; - - ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_RSN_ID); - if (ie) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = - IWE_STREAM_ADD_POINT(info, event, end, &iwe, - (char *)ie); - } - ptr = ((u8 *) bi) + sizeof(wl_bss_info_t); - - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { - if (ie_is_wps_ie(((u8 **)&ie), &ptr, &ptr_len)) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = - IWE_STREAM_ADD_POINT(info, event, end, &iwe, - (char *)ie); - break; - } - } - - ptr = ((u8 *) bi) + sizeof(wl_bss_info_t); - ptr_len = bi->ie_length; - while ((ie = bcm_parse_tlvs(ptr, ptr_len, DOT11_MNG_WPA_ID))) { - if (ie_is_wpa_ie(((u8 **)&ie), &ptr, &ptr_len)) { - iwe.cmd = IWEVGENIE; - iwe.u.data.length = ie->len + 2; - event = - IWE_STREAM_ADD_POINT(info, event, end, &iwe, - (char *)ie); - break; - } - } - - *event_p = event; - } -#endif /* WIRELESS_EXT > 17 */ - return 0; -} - -static uint -wl_iw_get_scan_prep(wl_scan_results_t *list, - struct iw_request_info *info, char *extra, short max_size) -{ - int i, j; - struct iw_event iwe; - wl_bss_info_t *bi = NULL; - char *event = extra, *end = extra + max_size - WE_ADD_EVENT_FIX, *value; - int ret = 0; - - ASSERT(list); - - for (i = 0; i < list->count && i < IW_MAX_AP; i++) { - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __func__, list->version); - return ret; - } - - bi = bi ? (wl_bss_info_t *)((unsigned long)bi + - le32_to_cpu(bi->length)) : list-> - bss_info; - - WL_TRACE("%s : %s\n", __func__, bi->SSID); - - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETH_ALEN); - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_ADDR_LEN); - iwe.u.data.length = le32_to_cpu(bi->SSID_len); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID); - - if (le16_to_cpu(bi->capability) & (WLAN_CAPABILITY_ESS | - WLAN_CAPABILITY_IBSS)) { - iwe.cmd = SIOCGIWMODE; - if (le16_to_cpu(bi->capability) & WLAN_CAPABILITY_ESS) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_UINT_LEN); - } - - iwe.cmd = SIOCGIWFREQ; - - if (CHSPEC_CHANNEL(bi->chanspec) <= CH_MAX_2G_CHANNEL) - iwe.u.freq.m = ieee80211_dsss_chan_to_freq( - CHSPEC_CHANNEL(bi->chanspec)); - else - iwe.u.freq.m = ieee80211_ofdm_chan_to_freq( - WF_CHAN_FACTOR_5_G/2, - CHSPEC_CHANNEL(bi->chanspec)); - - iwe.u.freq.e = 6; - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_FREQ_LEN); - - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(le16_to_cpu(bi->RSSI)); - iwe.u.qual.level = 0x100 + le16_to_cpu(bi->RSSI); - iwe.u.qual.noise = 0x100 + bi->phy_noise; - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_QUAL_LEN); - - wl_iw_handle_scanresults_ies(&event, end, info, bi); - - iwe.cmd = SIOCGIWENCODE; - if (le16_to_cpu(bi->capability) & WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - event = - IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event); - - if (bi->rateset.count) { - if (((event - extra) + - IW_EV_LCP_LEN) <= (unsigned long)end) { - value = event + IW_EV_LCP_LEN; - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = - 0; - for (j = 0; - j < bi->rateset.count - && j < IW_MAX_BITRATES; j++) { - iwe.u.bitrate.value = - (bi->rateset.rates[j] & 0x7f) * - 500000; - value = - IWE_STREAM_ADD_VALUE(info, event, - value, end, &iwe, - IW_EV_PARAM_LEN); - } - event = value; - } - } - } - - ret = event - extra; - if (ret < 0) { - WL_ERROR("==> Wrong size\n"); - ret = 0; - } - WL_TRACE("%s: size=%d bytes prepared\n", - __func__, (unsigned int)(event - extra)); - return (uint)ret; -} - -static int -wl_iw_get_scan(struct net_device *dev, - struct iw_request_info *info, struct iw_point *dwrq, char *extra) -{ - channel_info_t ci; - wl_scan_results_t *list_merge; - wl_scan_results_t *list = (wl_scan_results_t *) g_scan; - int error; - uint buflen_from_user = dwrq->length; - uint len = G_SCAN_RESULTS; - __u16 len_ret = 0; -#if defined(WL_IW_USE_ISCAN) - iscan_info_t *iscan = g_iscan; - iscan_buf_t *p_buf; -#endif - - WL_TRACE("%s: buflen_from_user %d:\n", dev->name, buflen_from_user); - - if (!extra) { - WL_TRACE("%s: wl_iw_get_scan return -EINVAL\n", dev->name); - return -EINVAL; - } - - error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)); - if (error) - return error; - ci.scan_channel = le32_to_cpu(ci.scan_channel); - if (ci.scan_channel) - return -EAGAIN; - - if (g_scan_specified_ssid) { - list = kmalloc(len, GFP_KERNEL); - if (!list) { - WL_TRACE("%s: wl_iw_get_scan return -ENOMEM\n", - dev->name); - g_scan_specified_ssid = 0; - return -ENOMEM; - } - } - - memset(list, 0, len); - list->buflen = cpu_to_le32(len); - error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, len); - if (error) { - WL_ERROR("%s: %s : Scan_results ERROR %d\n", - dev->name, __func__, error); - dwrq->length = len; - if (g_scan_specified_ssid) { - g_scan_specified_ssid = 0; - kfree(list); - } - return 0; - } - list->buflen = le32_to_cpu(list->buflen); - list->version = le32_to_cpu(list->version); - list->count = le32_to_cpu(list->count); - - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __func__, list->version); - if (g_scan_specified_ssid) { - g_scan_specified_ssid = 0; - kfree(list); - } - return -EINVAL; - } - - if (g_scan_specified_ssid) { - WL_TRACE("%s: Specified scan APs in the list =%d\n", - __func__, list->count); - len_ret = - (__u16) wl_iw_get_scan_prep(list, info, extra, - buflen_from_user); - kfree(list); - -#if defined(WL_IW_USE_ISCAN) - p_buf = iscan->list_hdr; - while (p_buf != iscan->list_cur) { - list_merge = - &((wl_iscan_results_t *) p_buf->iscan_buf)->results; - WL_TRACE("%s: Bcast APs list=%d\n", - __func__, list_merge->count); - if (list_merge->count > 0) - len_ret += - (__u16) wl_iw_get_scan_prep(list_merge, - info, extra + len_ret, - buflen_from_user - len_ret); - p_buf = p_buf->next; - } -#else - list_merge = (wl_scan_results_t *) g_scan; - WL_TRACE("%s: Bcast APs list=%d\n", - __func__, list_merge->count); - if (list_merge->count > 0) - len_ret += - (__u16) wl_iw_get_scan_prep(list_merge, info, - extra + len_ret, - buflen_from_user - - len_ret); -#endif /* defined(WL_IW_USE_ISCAN) */ - } else { - list = (wl_scan_results_t *) g_scan; - len_ret = - (__u16) wl_iw_get_scan_prep(list, info, extra, - buflen_from_user); - } - -#if defined(WL_IW_USE_ISCAN) - g_scan_specified_ssid = 0; -#endif - if ((len_ret + WE_ADD_EVENT_FIX) < buflen_from_user) - len = len_ret; - - dwrq->length = len; - dwrq->flags = 0; - - WL_TRACE("%s return to WE %d bytes APs=%d\n", - __func__, dwrq->length, list->count); - return 0; -} - -#if defined(WL_IW_USE_ISCAN) -static int -wl_iw_iscan_get_scan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wl_scan_results_t *list; - struct iw_event iwe; - wl_bss_info_t *bi = NULL; - int ii, j; - int apcnt; - char *event = extra, *end = extra + dwrq->length, *value; - iscan_info_t *iscan = g_iscan; - iscan_buf_t *p_buf; - u32 counter = 0; - u8 channel; - - WL_TRACE("%s %s buflen_from_user %d:\n", - dev->name, __func__, dwrq->length); - - if (!extra) { - WL_TRACE("%s: INVALID SIOCGIWSCAN GET bad parameter\n", - dev->name); - return -EINVAL; - } - - if ((!iscan) || (!iscan->sysioc_tsk)) { - WL_ERROR("%ssysioc_tsk\n", __func__); - return wl_iw_get_scan(dev, info, dwrq, extra); - } - - if (iscan->iscan_state == ISCAN_STATE_SCANING) { - WL_TRACE("%s: SIOCGIWSCAN GET still scanning\n", dev->name); - return -EAGAIN; - } - - WL_TRACE("%s: SIOCGIWSCAN GET broadcast results\n", dev->name); - apcnt = 0; - p_buf = iscan->list_hdr; - while (p_buf != iscan->list_cur) { - list = &((wl_iscan_results_t *) p_buf->iscan_buf)->results; - - counter += list->count; - - if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __func__, list->version); - return -EINVAL; - } - - bi = NULL; - for (ii = 0; ii < list->count && apcnt < IW_MAX_AP; - apcnt++, ii++) { - bi = bi ? (wl_bss_info_t *)((unsigned long)bi + - le32_to_cpu(bi->length)) : - list->bss_info; - ASSERT(((unsigned long)bi + le32_to_cpu(bi->length)) <= - ((unsigned long)list + WLC_IW_ISCAN_MAXLEN)); - - if (event + ETH_ALEN + bi->SSID_len + - IW_EV_UINT_LEN + IW_EV_FREQ_LEN + IW_EV_QUAL_LEN >= - end) - return -E2BIG; - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, - ETH_ALEN); - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_ADDR_LEN); - - iwe.u.data.length = le32_to_cpu(bi->SSID_len); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - event = - IWE_STREAM_ADD_POINT(info, event, end, &iwe, - bi->SSID); - - if (le16_to_cpu(bi->capability) & - (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) { - iwe.cmd = SIOCGIWMODE; - if (le16_to_cpu(bi->capability) & - WLAN_CAPABILITY_ESS) - iwe.u.mode = IW_MODE_INFRA; - else - iwe.u.mode = IW_MODE_ADHOC; - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_UINT_LEN); - } - - iwe.cmd = SIOCGIWFREQ; - channel = - (bi->ctl_ch == - 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch; - - if (channel <= CH_MAX_2G_CHANNEL) - iwe.u.freq.m = - ieee80211_dsss_chan_to_freq(channel); - else - iwe.u.freq.m = ieee80211_ofdm_chan_to_freq( - WF_CHAN_FACTOR_5_G/2, - channel); - - iwe.u.freq.e = 6; - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_FREQ_LEN); - - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = rssi_to_qual(le16_to_cpu(bi->RSSI)); - iwe.u.qual.level = 0x100 + le16_to_cpu(bi->RSSI); - iwe.u.qual.noise = 0x100 + bi->phy_noise; - event = - IWE_STREAM_ADD_EVENT(info, event, end, &iwe, - IW_EV_QUAL_LEN); - - wl_iw_handle_scanresults_ies(&event, end, info, bi); - - iwe.cmd = SIOCGIWENCODE; - if (le16_to_cpu(bi->capability) & - WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = - IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - event = - IWE_STREAM_ADD_POINT(info, event, end, &iwe, - (char *)event); - - if (bi->rateset.count) { - if (event + IW_MAX_BITRATES * IW_EV_PARAM_LEN >= - end) - return -E2BIG; - - value = event + IW_EV_LCP_LEN; - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = - 0; - for (j = 0; - j < bi->rateset.count - && j < IW_MAX_BITRATES; j++) { - iwe.u.bitrate.value = - (bi->rateset.rates[j] & 0x7f) * - 500000; - value = - IWE_STREAM_ADD_VALUE(info, event, - value, end, - &iwe, - IW_EV_PARAM_LEN); - } - event = value; - } - } - p_buf = p_buf->next; - } - - dwrq->length = event - extra; - dwrq->flags = 0; - - WL_TRACE("%s return to WE %d bytes APs=%d\n", - __func__, dwrq->length, counter); - - if (!dwrq->length) - return -EAGAIN; - - return 0; -} -#endif /* defined(WL_IW_USE_ISCAN) */ - -static int -wl_iw_set_essid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - int error; - wl_join_params_t join_params; - int join_params_size; - - WL_TRACE("%s: SIOCSIWESSID\n", dev->name); - - if (g_set_essid_before_scan) - return -EAGAIN; - - memset(&g_ssid, 0, sizeof(g_ssid)); - - CHECK_EXTRA_FOR_NULL(extra); - - if (dwrq->length && extra) { -#if WIRELESS_EXT > 20 - g_ssid.SSID_len = min_t(size_t, sizeof(g_ssid.SSID), - dwrq->length); -#else - g_ssid.SSID_len = min_t(size_t, sizeof(g_ssid.SSID), - dwrq->length - 1); -#endif - memcpy(g_ssid.SSID, extra, g_ssid.SSID_len); - } else { - g_ssid.SSID_len = 0; - } - g_ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len); - - memset(&join_params, 0, sizeof(join_params)); - join_params_size = sizeof(join_params.ssid); - - memcpy(&join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); - join_params.ssid.SSID_len = cpu_to_le32(g_ssid.SSID_len); - memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); - - wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, - &join_params_size); - - error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, - join_params_size); - if (error) - WL_ERROR("Invalid ioctl data=%d\n", error); - - if (g_ssid.SSID_len) { - WL_TRACE("%s: join SSID=%s ch=%d\n", - __func__, g_ssid.SSID, g_wl_iw_params.target_channel); - } - return 0; -} - -static int -wl_iw_get_essid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wlc_ssid_t ssid; - int error; - - WL_TRACE("%s: SIOCGIWESSID\n", dev->name); - - if (!extra) - return -EINVAL; - - error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)); - if (error) { - WL_ERROR("Error getting the SSID\n"); - return error; - } - - ssid.SSID_len = le32_to_cpu(ssid.SSID_len); - - memcpy(extra, ssid.SSID, ssid.SSID_len); - - dwrq->length = ssid.SSID_len; - - dwrq->flags = 1; - - return 0; -} - -static int -wl_iw_set_nick(struct net_device *dev, - struct iw_request_info *info, struct iw_point *dwrq, char *extra) -{ - wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - - WL_TRACE("%s: SIOCSIWNICKN\n", dev->name); - - if (!extra) - return -EINVAL; - - if (dwrq->length > sizeof(iw->nickname)) - return -E2BIG; - - memcpy(iw->nickname, extra, dwrq->length); - iw->nickname[dwrq->length - 1] = '\0'; - - return 0; -} - -static int -wl_iw_get_nick(struct net_device *dev, - struct iw_request_info *info, struct iw_point *dwrq, char *extra) -{ - wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - - WL_TRACE("%s: SIOCGIWNICKN\n", dev->name); - - if (!extra) - return -EINVAL; - - strcpy(extra, iw->nickname); - dwrq->length = strlen(extra) + 1; - - return 0; -} - -static int -wl_iw_set_rate(struct net_device *dev, - struct iw_request_info *info, struct iw_param *vwrq, char *extra) -{ - wl_rateset_t rateset; - int error, rate, i, error_bg, error_a; - - WL_TRACE("%s: SIOCSIWRATE\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, - sizeof(rateset)); - if (error) - return error; - - rateset.count = le32_to_cpu(rateset.count); - - if (vwrq->value < 0) - rate = rateset.rates[rateset.count - 1] & 0x7f; - else if (vwrq->value < rateset.count) - rate = rateset.rates[vwrq->value] & 0x7f; - else - rate = vwrq->value / 500000; - - if (vwrq->fixed) { - error_bg = dev_wlc_intvar_set(dev, "bg_rate", rate); - error_a = dev_wlc_intvar_set(dev, "a_rate", rate); - - if (error_bg && error_a) - return error_bg | error_a; - } else { - error_bg = dev_wlc_intvar_set(dev, "bg_rate", 0); - error_a = dev_wlc_intvar_set(dev, "a_rate", 0); - - if (error_bg && error_a) - return error_bg | error_a; - - for (i = 0; i < rateset.count; i++) - if ((rateset.rates[i] & 0x7f) > rate) - break; - rateset.count = cpu_to_le32(i); - - error = dev_wlc_ioctl(dev, WLC_SET_RATESET, &rateset, - sizeof(rateset)); - if (error) - return error; - } - - return 0; -} - -static int -wl_iw_get_rate(struct net_device *dev, - struct iw_request_info *info, struct iw_param *vwrq, char *extra) -{ - int error, rate; - - WL_TRACE("%s: SIOCGIWRATE\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)); - if (error) - return error; - rate = le32_to_cpu(rate); - vwrq->value = rate * 500000; - - return 0; -} - -static int -wl_iw_set_rts(struct net_device *dev, - struct iw_request_info *info, struct iw_param *vwrq, char *extra) -{ - int error, rts; - - WL_TRACE("%s: SIOCSIWRTS\n", dev->name); - - if (vwrq->disabled) - rts = DOT11_DEFAULT_RTS_LEN; - else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_RTS_LEN) - return -EINVAL; - else - rts = vwrq->value; - - error = dev_wlc_intvar_set(dev, "rtsthresh", rts); - if (error) - return error; - - return 0; -} - -static int -wl_iw_get_rts(struct net_device *dev, - struct iw_request_info *info, struct iw_param *vwrq, char *extra) -{ - int error, rts; - - WL_TRACE("%s: SIOCGIWRTS\n", dev->name); - - error = dev_wlc_intvar_get(dev, "rtsthresh", &rts); - if (error) - return error; - - vwrq->value = rts; - vwrq->disabled = (rts >= DOT11_DEFAULT_RTS_LEN); - vwrq->fixed = 1; - - return 0; -} - -static int -wl_iw_set_frag(struct net_device *dev, - struct iw_request_info *info, struct iw_param *vwrq, char *extra) -{ - int error, frag; - - WL_TRACE("%s: SIOCSIWFRAG\n", dev->name); - - if (vwrq->disabled) - frag = DOT11_DEFAULT_FRAG_LEN; - else if (vwrq->value < 0 || vwrq->value > DOT11_DEFAULT_FRAG_LEN) - return -EINVAL; - else - frag = vwrq->value; - - error = dev_wlc_intvar_set(dev, "fragthresh", frag); - if (error) - return error; - - return 0; -} - -static int -wl_iw_get_frag(struct net_device *dev, - struct iw_request_info *info, struct iw_param *vwrq, char *extra) -{ - int error, fragthreshold; - - WL_TRACE("%s: SIOCGIWFRAG\n", dev->name); - - error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold); - if (error) - return error; - - vwrq->value = fragthreshold; - vwrq->disabled = (fragthreshold >= DOT11_DEFAULT_FRAG_LEN); - vwrq->fixed = 1; - - return 0; -} - -static int -wl_iw_set_txpow(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error, disable; - u16 txpwrmw; - WL_TRACE("%s: SIOCSIWTXPOW\n", dev->name); - - disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0; - disable += WL_RADIO_SW_DISABLE << 16; - - disable = cpu_to_le32(disable); - error = dev_wlc_ioctl(dev, WLC_SET_RADIO, &disable, sizeof(disable)); - if (error) - return error; - - if (disable & WL_RADIO_SW_DISABLE) - return 0; - - if (!(vwrq->flags & IW_TXPOW_MWATT)) - return -EINVAL; - - if (vwrq->value < 0) - return 0; - - if (vwrq->value > 0xffff) - txpwrmw = 0xffff; - else - txpwrmw = (u16) vwrq->value; - - error = - dev_wlc_intvar_set(dev, "qtxpower", (int)(bcm_mw_to_qdbm(txpwrmw))); - return error; -} - -static int -wl_iw_get_txpow(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error, disable, txpwrdbm; - u8 result; - - WL_TRACE("%s: SIOCGIWTXPOW\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable)); - if (error) - return error; - - error = dev_wlc_intvar_get(dev, "qtxpower", &txpwrdbm); - if (error) - return error; - - disable = le32_to_cpu(disable); - result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE); - vwrq->value = (s32) bcm_qdbm_to_mw(result); - vwrq->fixed = 0; - vwrq->disabled = - (disable & (WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE)) ? 1 : 0; - vwrq->flags = IW_TXPOW_MWATT; - - return 0; -} - -#if WIRELESS_EXT > 10 -static int -wl_iw_set_retry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error, lrl, srl; - - WL_TRACE("%s: SIOCSIWRETRY\n", dev->name); - - if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME)) - return -EINVAL; - - if (vwrq->flags & IW_RETRY_LIMIT) { - -#if WIRELESS_EXT > 20 - if ((vwrq->flags & IW_RETRY_LONG) - || (vwrq->flags & IW_RETRY_MAX) - || !((vwrq->flags & IW_RETRY_SHORT) - || (vwrq->flags & IW_RETRY_MIN))) { -#else - if ((vwrq->flags & IW_RETRY_MAX) - || !(vwrq->flags & IW_RETRY_MIN)) { -#endif - lrl = cpu_to_le32(vwrq->value); - error = dev_wlc_ioctl(dev, WLC_SET_LRL, &lrl, - sizeof(lrl)); - if (error) - return error; - } -#if WIRELESS_EXT > 20 - if ((vwrq->flags & IW_RETRY_SHORT) - || (vwrq->flags & IW_RETRY_MIN) - || !((vwrq->flags & IW_RETRY_LONG) - || (vwrq->flags & IW_RETRY_MAX))) { -#else - if ((vwrq->flags & IW_RETRY_MIN) - || !(vwrq->flags & IW_RETRY_MAX)) { -#endif - srl = cpu_to_le32(vwrq->value); - error = dev_wlc_ioctl(dev, WLC_SET_SRL, &srl, - sizeof(srl)); - if (error) - return error; - } - } - return 0; -} - -static int -wl_iw_get_retry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error, lrl, srl; - - WL_TRACE("%s: SIOCGIWRETRY\n", dev->name); - - vwrq->disabled = 0; - - if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) - return -EINVAL; - - error = dev_wlc_ioctl(dev, WLC_GET_LRL, &lrl, sizeof(lrl)); - if (error) - return error; - - error = dev_wlc_ioctl(dev, WLC_GET_SRL, &srl, sizeof(srl)); - if (error) - return error; - - lrl = le32_to_cpu(lrl); - srl = le32_to_cpu(srl); - - if (vwrq->flags & IW_RETRY_MAX) { - vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - vwrq->value = lrl; - } else { - vwrq->flags = IW_RETRY_LIMIT; - vwrq->value = srl; - if (srl != lrl) - vwrq->flags |= IW_RETRY_MIN; - } - - return 0; -} -#endif /* WIRELESS_EXT > 10 */ - -static int -wl_iw_set_encode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wl_wsec_key_t key; - int error, val, wsec; - - WL_TRACE("%s: SIOCSIWENCODE\n", dev->name); - - memset(&key, 0, sizeof(key)); - - if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; - key.index++) { - val = cpu_to_le32(key.index); - error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, - sizeof(val)); - if (error) - return error; - val = le32_to_cpu(val); - if (val) - break; - } - if (key.index == DOT11_MAX_DEFAULT_KEYS) - key.index = 0; - } else { - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - if (key.index >= DOT11_MAX_DEFAULT_KEYS) - return -EINVAL; - } - - if (!extra || !dwrq->length || (dwrq->flags & IW_ENCODE_NOKEY)) { - val = cpu_to_le32(key.index); - error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &val, - sizeof(val)); - if (error) - return error; - } else { - key.len = dwrq->length; - - if (dwrq->length > sizeof(key.data)) - return -EINVAL; - - memcpy(key.data, extra, dwrq->length); - - key.flags = WL_PRIMARY_KEY; - switch (key.len) { - case WLAN_KEY_LEN_WEP40: - key.algo = CRYPTO_ALGO_WEP1; - break; - case WLAN_KEY_LEN_WEP104: - key.algo = CRYPTO_ALGO_WEP128; - break; - case WLAN_KEY_LEN_TKIP: - key.algo = CRYPTO_ALGO_TKIP; - break; - case WLAN_KEY_LEN_AES_CMAC: - key.algo = CRYPTO_ALGO_AES_CCM; - break; - default: - return -EINVAL; - } - - swap_key_from_BE(&key); - error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - if (error) - return error; - } - - val = (dwrq->flags & IW_ENCODE_DISABLED) ? 0 : WEP_ENABLED; - - error = dev_wlc_intvar_get(dev, "wsec", &wsec); - if (error) - return error; - - wsec &= ~(WEP_ENABLED); - wsec |= val; - - error = dev_wlc_intvar_set(dev, "wsec", wsec); - if (error) - return error; - - val = (dwrq->flags & IW_ENCODE_RESTRICTED) ? 1 : 0; - val = cpu_to_le32(val); - error = dev_wlc_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)); - if (error) - return error; - - return 0; -} - -static int -wl_iw_get_encode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wl_wsec_key_t key; - int error, val, wsec, auth; - - WL_TRACE("%s: SIOCGIWENCODE\n", dev->name); - - memset(&key, 0, sizeof(wl_wsec_key_t)); - - if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { - for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; - key.index++) { - val = key.index; - error = dev_wlc_ioctl(dev, WLC_GET_KEY_PRIMARY, &val, - sizeof(val)); - if (error) - return error; - val = le32_to_cpu(val); - if (val) - break; - } - } else - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - if (key.index >= DOT11_MAX_DEFAULT_KEYS) - key.index = 0; - - error = dev_wlc_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)); - if (error) - return error; - - error = dev_wlc_ioctl(dev, WLC_GET_AUTH, &auth, sizeof(auth)); - if (error) - return error; - - swap_key_to_BE(&key); - - wsec = le32_to_cpu(wsec); - auth = le32_to_cpu(auth); - dwrq->length = min_t(u16, WLAN_MAX_KEY_LEN, key.len); - - dwrq->flags = key.index + 1; - if (!(wsec & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))) - dwrq->flags |= IW_ENCODE_DISABLED; - - if (auth) - dwrq->flags |= IW_ENCODE_RESTRICTED; - - if (dwrq->length && extra) - memcpy(extra, key.data, dwrq->length); - - return 0; -} - -static int -wl_iw_set_power(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error, pm; - - WL_TRACE("%s: SIOCSIWPOWER\n", dev->name); - - pm = vwrq->disabled ? PM_OFF : PM_MAX; - - pm = cpu_to_le32(pm); - error = dev_wlc_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); - if (error) - return error; - - return 0; -} - -static int -wl_iw_get_power(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error, pm; - - WL_TRACE("%s: SIOCGIWPOWER\n", dev->name); - - error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)); - if (error) - return error; - - pm = le32_to_cpu(pm); - vwrq->disabled = pm ? 0 : 1; - vwrq->flags = IW_POWER_ALL_R; - - return 0; -} - -#if WIRELESS_EXT > 17 -static int -wl_iw_set_wpaie(struct net_device *dev, - struct iw_request_info *info, struct iw_point *iwp, char *extra) -{ - - WL_TRACE("%s: SIOCSIWGENIE\n", dev->name); - - CHECK_EXTRA_FOR_NULL(extra); - - dev_wlc_bufvar_set(dev, "wpaie", extra, iwp->length); - - return 0; -} - -static int -wl_iw_get_wpaie(struct net_device *dev, - struct iw_request_info *info, struct iw_point *iwp, char *extra) -{ - WL_TRACE("%s: SIOCGIWGENIE\n", dev->name); - iwp->length = 64; - dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length); - return 0; -} - -static int -wl_iw_set_encodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *dwrq, char *extra) -{ - wl_wsec_key_t key; - int error; - struct iw_encode_ext *iwe; - - WL_TRACE("%s: SIOCSIWENCODEEXT\n", dev->name); - - CHECK_EXTRA_FOR_NULL(extra); - - memset(&key, 0, sizeof(key)); - iwe = (struct iw_encode_ext *)extra; - - if (dwrq->flags & IW_ENCODE_DISABLED) { - - } - - key.index = 0; - if (dwrq->flags & IW_ENCODE_INDEX) - key.index = (dwrq->flags & IW_ENCODE_INDEX) - 1; - - key.len = iwe->key_len; - - if (!is_multicast_ether_addr(iwe->addr.sa_data)) - memcpy(&key.ea, &iwe->addr.sa_data, ETH_ALEN); - - if (key.len == 0) { - if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC("Changing the the primary Key to %d\n", - key.index); - key.index = cpu_to_le32(key.index); - error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, - &key.index, sizeof(key.index)); - if (error) - return error; - } else { - swap_key_from_BE(&key); - dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - } - } else { - if (iwe->key_len > sizeof(key.data)) - return -EINVAL; - - WL_WSEC("Setting the key index %d\n", key.index); - if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC("key is a Primary Key\n"); - key.flags = WL_PRIMARY_KEY; - } - - memcpy(key.data, iwe->key, iwe->key_len); - - if (iwe->alg == IW_ENCODE_ALG_TKIP) { - u8 keybuf[8]; - memcpy(keybuf, &key.data[24], sizeof(keybuf)); - memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); - memcpy(&key.data[16], keybuf, sizeof(keybuf)); - } - - if (iwe->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { - unsigned char *ivptr; - ivptr = (unsigned char *) iwe->rx_seq; - key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | - (ivptr[3] << 8) | ivptr[2]; - key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; - key.iv_initialized = true; - } - - switch (iwe->alg) { - case IW_ENCODE_ALG_NONE: - key.algo = CRYPTO_ALGO_OFF; - break; - case IW_ENCODE_ALG_WEP: - if (iwe->key_len == WLAN_KEY_LEN_WEP40) - key.algo = CRYPTO_ALGO_WEP1; - else - key.algo = CRYPTO_ALGO_WEP128; - break; - case IW_ENCODE_ALG_TKIP: - key.algo = CRYPTO_ALGO_TKIP; - break; - case IW_ENCODE_ALG_CCMP: - key.algo = CRYPTO_ALGO_AES_CCM; - break; - default: - break; - } - swap_key_from_BE(&key); - - dhd_wait_pend8021x(dev); - - error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); - if (error) - return error; - } - return 0; -} - -#if WIRELESS_EXT > 17 -struct { - pmkid_list_t pmkids; - pmkid_t foo[MAXPMKID - 1]; -} pmkid_list; - -static int -wl_iw_set_pmksa(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - struct iw_pmksa *iwpmksa; - uint i; - int ret = 0; - - WL_WSEC("%s: SIOCSIWPMKSA\n", dev->name); - - CHECK_EXTRA_FOR_NULL(extra); - - iwpmksa = (struct iw_pmksa *)extra; - - if (iwpmksa->cmd == IW_PMKSA_FLUSH) { - WL_WSEC("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n"); - memset((char *)&pmkid_list, 0, sizeof(pmkid_list)); - } - - else if (iwpmksa->cmd == IW_PMKSA_REMOVE) { - { - pmkid_list_t pmkid, *pmkidptr; - uint j; - pmkidptr = &pmkid; - - memcpy(&pmkidptr->pmkid[0].BSSID, - &iwpmksa->bssid.sa_data[0], - ETH_ALEN); - memcpy(&pmkidptr->pmkid[0].PMKID, - &iwpmksa->pmkid[0], - WLAN_PMKID_LEN); - - WL_WSEC("wl_iw_set_pmksa:IW_PMKSA_REMOVE:PMKID: " - "%pM = ", &pmkidptr->pmkid[0].BSSID); - for (j = 0; j < WLAN_PMKID_LEN; j++) - WL_WSEC("%02x ", pmkidptr->pmkid[0].PMKID[j]); - WL_WSEC("\n"); - } - - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!memcmp - (&iwpmksa->bssid.sa_data[0], - &pmkid_list.pmkids.pmkid[i].BSSID, ETH_ALEN)) - break; - - if ((pmkid_list.pmkids.npmkid > 0) - && (i < pmkid_list.pmkids.npmkid)) { - memset(&pmkid_list.pmkids.pmkid[i], 0, sizeof(pmkid_t)); - for (; i < (pmkid_list.pmkids.npmkid - 1); i++) { - memcpy(&pmkid_list.pmkids.pmkid[i].BSSID, - &pmkid_list.pmkids.pmkid[i + 1].BSSID, - ETH_ALEN); - memcpy(&pmkid_list.pmkids.pmkid[i].PMKID, - &pmkid_list.pmkids.pmkid[i + 1].PMKID, - WLAN_PMKID_LEN); - } - pmkid_list.pmkids.npmkid--; - } else - ret = -EINVAL; - } - - else if (iwpmksa->cmd == IW_PMKSA_ADD) { - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!memcmp - (&iwpmksa->bssid.sa_data[0], - &pmkid_list.pmkids.pmkid[i].BSSID, ETH_ALEN)) - break; - if (i < MAXPMKID) { - memcpy(&pmkid_list.pmkids.pmkid[i].BSSID, - &iwpmksa->bssid.sa_data[0], - ETH_ALEN); - memcpy(&pmkid_list.pmkids.pmkid[i].PMKID, - &iwpmksa->pmkid[0], - WLAN_PMKID_LEN); - if (i == pmkid_list.pmkids.npmkid) - pmkid_list.pmkids.npmkid++; - } else - ret = -EINVAL; - { - uint j; - uint k; - k = pmkid_list.pmkids.npmkid; - WL_WSEC("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %pM = ", - &pmkid_list.pmkids.pmkid[k].BSSID); - for (j = 0; j < WLAN_PMKID_LEN; j++) - WL_WSEC("%02x ", - pmkid_list.pmkids.pmkid[k].PMKID[j]); - WL_WSEC("\n"); - } - } - WL_WSEC("PRINTING pmkid LIST - No of elements %d\n", - pmkid_list.pmkids.npmkid); - for (i = 0; i < pmkid_list.pmkids.npmkid; i++) { - uint j; - WL_WSEC("PMKID[%d]: %pM = ", - i, &pmkid_list.pmkids.pmkid[i].BSSID); - for (j = 0; j < WLAN_PMKID_LEN; j++) - WL_WSEC("%02x ", pmkid_list.pmkids.pmkid[i].PMKID[j]); - WL_WSEC("\n"); - } - WL_WSEC("\n"); - - if (!ret) - ret = dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list, - sizeof(pmkid_list)); - return ret; -} -#endif /* WIRELESS_EXT > 17 */ - -static int -wl_iw_get_encodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - WL_TRACE("%s: SIOCGIWENCODEEXT\n", dev->name); - return 0; -} - -static int -wl_iw_set_wpaauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error = 0; - int paramid; - int paramval; - int val = 0; - wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - - WL_TRACE("%s: SIOCSIWAUTH\n", dev->name); - - paramid = vwrq->flags & IW_AUTH_INDEX; - paramval = vwrq->value; - - WL_TRACE("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n", - dev->name, paramid, paramval); - - switch (paramid) { - case IW_AUTH_WPA_VERSION: - if (paramval & IW_AUTH_WPA_VERSION_DISABLED) - val = WPA_AUTH_DISABLED; - else if (paramval & (IW_AUTH_WPA_VERSION_WPA)) - val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; - else if (paramval & IW_AUTH_WPA_VERSION_WPA2) - val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; - WL_INFORM("%s: %d: setting wpa_auth to 0x%0x\n", - __func__, __LINE__, val); - error = dev_wlc_intvar_set(dev, "wpa_auth", val); - if (error) - return error; - break; - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - if (paramval & (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) - val = WEP_ENABLED; - if (paramval & IW_AUTH_CIPHER_TKIP) - val = TKIP_ENABLED; - if (paramval & IW_AUTH_CIPHER_CCMP) - val = AES_ENABLED; - - if (paramid == IW_AUTH_CIPHER_PAIRWISE) { - iw->pwsec = val; - val |= iw->gwsec; - } else { - iw->gwsec = val; - val |= iw->pwsec; - } - - if (iw->privacy_invoked && !val) { - WL_WSEC("%s: %s: 'Privacy invoked' true but clearing wsec, assuming we're a WPS enrollee\n", - dev->name, __func__); - error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", - true); - if (error) { - WL_WSEC("Failed to set is_WPS_enrollee\n"); - return error; - } - } else if (val) { - error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", - false); - if (error) { - WL_WSEC("Failed to clear is_WPS_enrollee\n"); - return error; - } - } - - error = dev_wlc_intvar_set(dev, "wsec", val); - if (error) - return error; - - break; - - case IW_AUTH_KEY_MGMT: - error = dev_wlc_intvar_get(dev, "wpa_auth", &val); - if (error) - return error; - - if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { - if (paramval & IW_AUTH_KEY_MGMT_PSK) - val = WPA_AUTH_PSK; - else - val = WPA_AUTH_UNSPECIFIED; - } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { - if (paramval & IW_AUTH_KEY_MGMT_PSK) - val = WPA2_AUTH_PSK; - else - val = WPA2_AUTH_UNSPECIFIED; - } - WL_INFORM("%s: %d: setting wpa_auth to %d\n", - __func__, __LINE__, val); - error = dev_wlc_intvar_set(dev, "wpa_auth", val); - if (error) - return error; - - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - dev_wlc_bufvar_set(dev, "tkip_countermeasures", - (char *)¶mval, 1); - break; - - case IW_AUTH_80211_AUTH_ALG: - WL_INFORM("Setting the D11auth %d\n", paramval); - if (paramval == IW_AUTH_ALG_OPEN_SYSTEM) - val = 0; - else if (paramval == IW_AUTH_ALG_SHARED_KEY) - val = 1; - else if (paramval == - (IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY)) - val = 2; - else - error = 1; - if (!error) { - error = dev_wlc_intvar_set(dev, "auth", val); - if (error) - return error; - } - break; - - case IW_AUTH_WPA_ENABLED: - if (paramval == 0) { - iw->pwsec = 0; - iw->gwsec = 0; - error = dev_wlc_intvar_get(dev, "wsec", &val); - if (error) - return error; - if (val & (TKIP_ENABLED | AES_ENABLED)) { - val &= ~(TKIP_ENABLED | AES_ENABLED); - dev_wlc_intvar_set(dev, "wsec", val); - } - val = 0; - WL_INFORM("%s: %d: setting wpa_auth to %d\n", - __func__, __LINE__, val); - dev_wlc_intvar_set(dev, "wpa_auth", 0); - return error; - } - break; - - case IW_AUTH_DROP_UNENCRYPTED: - dev_wlc_bufvar_set(dev, "wsec_restrict", (char *)¶mval, 1); - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - dev_wlc_bufvar_set(dev, "rx_unencrypted_eapol", - (char *)¶mval, 1); - break; - -#if WIRELESS_EXT > 17 - case IW_AUTH_ROAMING_CONTROL: - WL_INFORM("%s: IW_AUTH_ROAMING_CONTROL\n", __func__); - break; - case IW_AUTH_PRIVACY_INVOKED: - { - int wsec; - - if (paramval == 0) { - iw->privacy_invoked = false; - error = dev_wlc_intvar_set(dev, - "is_WPS_enrollee", false); - if (error) { - WL_WSEC("Failed to clear iovar is_WPS_enrollee\n"); - return error; - } - } else { - iw->privacy_invoked = true; - error = dev_wlc_intvar_get(dev, "wsec", &wsec); - if (error) - return error; - - if (!(IW_WSEC_ENABLED(wsec))) { - error = dev_wlc_intvar_set(dev, - "is_WPS_enrollee", - true); - if (error) { - WL_WSEC("Failed to set iovar is_WPS_enrollee\n"); - return error; - } - } else { - error = dev_wlc_intvar_set(dev, - "is_WPS_enrollee", - false); - if (error) { - WL_WSEC("Failed to clear is_WPS_enrollee\n"); - return error; - } - } - } - break; - } -#endif /* WIRELESS_EXT > 17 */ - default: - break; - } - return 0; -} - -#define VAL_PSK(_val) (((_val) & WPA_AUTH_PSK) || ((_val) & WPA2_AUTH_PSK)) - -static int -wl_iw_get_wpaauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *vwrq, char *extra) -{ - int error; - int paramid; - int paramval = 0; - int val; - wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - - WL_TRACE("%s: SIOCGIWAUTH\n", dev->name); - - paramid = vwrq->flags & IW_AUTH_INDEX; - - switch (paramid) { - case IW_AUTH_WPA_VERSION: - error = dev_wlc_intvar_get(dev, "wpa_auth", &val); - if (error) - return error; - if (val & (WPA_AUTH_NONE | WPA_AUTH_DISABLED)) - paramval = IW_AUTH_WPA_VERSION_DISABLED; - else if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) - paramval = IW_AUTH_WPA_VERSION_WPA; - else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) - paramval = IW_AUTH_WPA_VERSION_WPA2; - break; - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - if (paramid == IW_AUTH_CIPHER_PAIRWISE) - val = iw->pwsec; - else - val = iw->gwsec; - - paramval = 0; - if (val) { - if (val & WEP_ENABLED) - paramval |= - (IW_AUTH_CIPHER_WEP40 | - IW_AUTH_CIPHER_WEP104); - if (val & TKIP_ENABLED) - paramval |= (IW_AUTH_CIPHER_TKIP); - if (val & AES_ENABLED) - paramval |= (IW_AUTH_CIPHER_CCMP); - } else - paramval = IW_AUTH_CIPHER_NONE; - break; - case IW_AUTH_KEY_MGMT: - error = dev_wlc_intvar_get(dev, "wpa_auth", &val); - if (error) - return error; - if (VAL_PSK(val)) - paramval = IW_AUTH_KEY_MGMT_PSK; - else - paramval = IW_AUTH_KEY_MGMT_802_1X; - - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - dev_wlc_bufvar_get(dev, "tkip_countermeasures", - (char *)¶mval, 1); - break; - - case IW_AUTH_DROP_UNENCRYPTED: - dev_wlc_bufvar_get(dev, "wsec_restrict", (char *)¶mval, 1); - break; - - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - dev_wlc_bufvar_get(dev, "rx_unencrypted_eapol", - (char *)¶mval, 1); - break; - - case IW_AUTH_80211_AUTH_ALG: - error = dev_wlc_intvar_get(dev, "auth", &val); - if (error) - return error; - if (!val) - paramval = IW_AUTH_ALG_OPEN_SYSTEM; - else - paramval = IW_AUTH_ALG_SHARED_KEY; - break; - case IW_AUTH_WPA_ENABLED: - error = dev_wlc_intvar_get(dev, "wpa_auth", &val); - if (error) - return error; - if (val) - paramval = true; - else - paramval = false; - break; -#if WIRELESS_EXT > 17 - case IW_AUTH_ROAMING_CONTROL: - WL_ERROR("%s: IW_AUTH_ROAMING_CONTROL\n", __func__); - break; - case IW_AUTH_PRIVACY_INVOKED: - paramval = iw->privacy_invoked; - break; - -#endif - } - vwrq->value = paramval; - return 0; -} -#endif /* WIRELESS_EXT > 17 */ - -static const iw_handler wl_iw_handler[] = { - (iw_handler) wl_iw_config_commit, - (iw_handler) wl_iw_get_name, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_freq, - (iw_handler) wl_iw_get_freq, - (iw_handler) wl_iw_set_mode, - (iw_handler) wl_iw_get_mode, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_get_range, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_spy, - (iw_handler) wl_iw_get_spy, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_wap, - (iw_handler) wl_iw_get_wap, -#if WIRELESS_EXT > 17 - (iw_handler) wl_iw_mlme, -#else - (iw_handler) NULL, -#endif -#if defined(WL_IW_USE_ISCAN) - (iw_handler) wl_iw_iscan_get_aplist, -#else - (iw_handler) wl_iw_get_aplist, -#endif -#if WIRELESS_EXT > 13 -#if defined(WL_IW_USE_ISCAN) - (iw_handler) wl_iw_iscan_set_scan, - (iw_handler) wl_iw_iscan_get_scan, -#else - (iw_handler) wl_iw_set_scan, - (iw_handler) wl_iw_get_scan, -#endif -#else - (iw_handler) NULL, - (iw_handler) NULL, -#endif /* WIRELESS_EXT > 13 */ - (iw_handler) wl_iw_set_essid, - (iw_handler) wl_iw_get_essid, - (iw_handler) wl_iw_set_nick, - (iw_handler) wl_iw_get_nick, - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_rate, - (iw_handler) wl_iw_get_rate, - (iw_handler) wl_iw_set_rts, - (iw_handler) wl_iw_get_rts, - (iw_handler) wl_iw_set_frag, - (iw_handler) wl_iw_get_frag, - (iw_handler) wl_iw_set_txpow, - (iw_handler) wl_iw_get_txpow, -#if WIRELESS_EXT > 10 - (iw_handler) wl_iw_set_retry, - (iw_handler) wl_iw_get_retry, -#endif - (iw_handler) wl_iw_set_encode, - (iw_handler) wl_iw_get_encode, - (iw_handler) wl_iw_set_power, - (iw_handler) wl_iw_get_power, -#if WIRELESS_EXT > 17 - (iw_handler) NULL, - (iw_handler) NULL, - (iw_handler) wl_iw_set_wpaie, - (iw_handler) wl_iw_get_wpaie, - (iw_handler) wl_iw_set_wpaauth, - (iw_handler) wl_iw_get_wpaauth, - (iw_handler) wl_iw_set_encodeext, - (iw_handler) wl_iw_get_encodeext, - (iw_handler) wl_iw_set_pmksa, -#endif /* WIRELESS_EXT > 17 */ -}; - -#if WIRELESS_EXT > 12 - -const struct iw_handler_def wl_iw_handler_def = { - .num_standard = ARRAY_SIZE(wl_iw_handler), - .standard = (iw_handler *) wl_iw_handler, - .num_private = 0, - .num_private_args = 0, - .private = 0, - .private_args = 0, - -#if WIRELESS_EXT >= 19 - .get_wireless_stats = NULL, -#endif -}; -#endif /* WIRELESS_EXT > 12 */ - -int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct iwreq *wrq = (struct iwreq *)rq; - struct iw_request_info info; - iw_handler handler; - char *extra = NULL; - int token_size = 1, max_tokens = 0, ret = 0; - - WL_TRACE("\n%s, cmd:%x alled via dhd->do_ioctl()entry point\n", - __func__, cmd); - if (cmd < SIOCIWFIRST || - IW_IOCTL_IDX(cmd) >= ARRAY_SIZE(wl_iw_handler)) { - WL_ERROR("%s: error in cmd=%x : out of range\n", - __func__, cmd); - return -EOPNOTSUPP; - } - - handler = wl_iw_handler[IW_IOCTL_IDX(cmd)]; - if (!handler) { - WL_ERROR("%s: error in cmd=%x : not supported\n", - __func__, cmd); - return -EOPNOTSUPP; - } - - switch (cmd) { - - case SIOCSIWESSID: - case SIOCGIWESSID: - case SIOCSIWNICKN: - case SIOCGIWNICKN: - max_tokens = IW_ESSID_MAX_SIZE + 1; - break; - - case SIOCSIWENCODE: - case SIOCGIWENCODE: -#if WIRELESS_EXT > 17 - case SIOCSIWENCODEEXT: - case SIOCGIWENCODEEXT: -#endif - max_tokens = wrq->u.data.length; - break; - - case SIOCGIWRANGE: - max_tokens = sizeof(struct iw_range) + 500; - break; - - case SIOCGIWAPLIST: - token_size = - sizeof(struct sockaddr) + sizeof(struct iw_quality); - max_tokens = IW_MAX_AP; - break; - -#if WIRELESS_EXT > 13 - case SIOCGIWSCAN: -#if defined(WL_IW_USE_ISCAN) - if (g_iscan) - max_tokens = wrq->u.data.length; - else -#endif - max_tokens = IW_SCAN_MAX_DATA; - break; -#endif /* WIRELESS_EXT > 13 */ - - case SIOCSIWSPY: - token_size = sizeof(struct sockaddr); - max_tokens = IW_MAX_SPY; - break; - - case SIOCGIWSPY: - token_size = - sizeof(struct sockaddr) + sizeof(struct iw_quality); - max_tokens = IW_MAX_SPY; - break; - -#if WIRELESS_EXT > 17 - case SIOCSIWPMKSA: - case SIOCSIWGENIE: -#endif - case SIOCSIWPRIV: - max_tokens = wrq->u.data.length; - break; - } - - if (max_tokens && wrq->u.data.pointer) { - if (wrq->u.data.length > max_tokens) { - WL_ERROR("%s: error in cmd=%x wrq->u.data.length=%d > max_tokens=%d\n", - __func__, cmd, wrq->u.data.length, max_tokens); - return -E2BIG; - } - extra = kmalloc(max_tokens * token_size, GFP_KERNEL); - if (!extra) - return -ENOMEM; - - if (copy_from_user - (extra, wrq->u.data.pointer, - wrq->u.data.length * token_size)) { - kfree(extra); - return -EFAULT; - } - } - - info.cmd = cmd; - info.flags = 0; - - ret = handler(dev, &info, &wrq->u, extra); - - if (extra) { - if (copy_to_user - (wrq->u.data.pointer, extra, - wrq->u.data.length * token_size)) { - kfree(extra); - return -EFAULT; - } - - kfree(extra); - } - - return ret; -} - -bool -wl_iw_conn_status_str(u32 event_type, u32 status, u32 reason, - char *stringBuf, uint buflen) -{ - typedef struct conn_fail_event_map_t { - u32 inEvent; - u32 inStatus; - u32 inReason; - const char *outName; - const char *outCause; - } conn_fail_event_map_t; - -#define WL_IW_DONT_CARE 9999 - const conn_fail_event_map_t event_map[] = { - {WLC_E_SET_SSID, WLC_E_STATUS_SUCCESS, WL_IW_DONT_CARE, - "Conn", "Success"}, - {WLC_E_SET_SSID, WLC_E_STATUS_NO_NETWORKS, WL_IW_DONT_CARE, - "Conn", "NoNetworks"}, - {WLC_E_SET_SSID, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "ConfigMismatch"}, - {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_PRUNE_ENCR_MISMATCH, - "Conn", "EncrypMismatch"}, - {WLC_E_PRUNE, WL_IW_DONT_CARE, WLC_E_RSN_MISMATCH, - "Conn", "RsnMismatch"}, - {WLC_E_AUTH, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE, - "Conn", "AuthTimeout"}, - {WLC_E_AUTH, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "AuthFail"}, - {WLC_E_AUTH, WLC_E_STATUS_NO_ACK, WL_IW_DONT_CARE, - "Conn", "AuthNoAck"}, - {WLC_E_REASSOC, WLC_E_STATUS_FAIL, WL_IW_DONT_CARE, - "Conn", "ReassocFail"}, - {WLC_E_REASSOC, WLC_E_STATUS_TIMEOUT, WL_IW_DONT_CARE, - "Conn", "ReassocTimeout"}, - {WLC_E_REASSOC, WLC_E_STATUS_ABORT, WL_IW_DONT_CARE, - "Conn", "ReassocAbort"}, - {WLC_E_PSK_SUP, WLC_SUP_KEYED, WL_IW_DONT_CARE, - "Sup", "ConnSuccess"}, - {WLC_E_PSK_SUP, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Sup", "WpaHandshakeFail"}, - {WLC_E_DEAUTH_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "Deauth"}, - {WLC_E_DISASSOC_IND, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "DisassocInd"}, - {WLC_E_DISASSOC, WL_IW_DONT_CARE, WL_IW_DONT_CARE, - "Conn", "Disassoc"} - }; - - const char *name = ""; - const char *cause = NULL; - int i; - - for (i = 0; i < sizeof(event_map) / sizeof(event_map[0]); i++) { - const conn_fail_event_map_t *row = &event_map[i]; - if (row->inEvent == event_type && - (row->inStatus == status - || row->inStatus == WL_IW_DONT_CARE) - && (row->inReason == reason - || row->inReason == WL_IW_DONT_CARE)) { - name = row->outName; - cause = row->outCause; - break; - } - } - - if (cause) { - memset(stringBuf, 0, buflen); - snprintf(stringBuf, buflen, "%s %s %02d %02d", - name, cause, status, reason); - WL_INFORM("Connection status: %s\n", stringBuf); - return true; - } else { - return false; - } -} - -#if WIRELESS_EXT > 14 - -static bool -wl_iw_check_conn_fail(wl_event_msg_t *e, char *stringBuf, uint buflen) -{ - u32 event = be32_to_cpu(e->event_type); - u32 status = be32_to_cpu(e->status); - u32 reason = be32_to_cpu(e->reason); - - if (wl_iw_conn_status_str(event, status, reason, stringBuf, buflen)) { - return true; - } else - return false; -} -#endif - -#ifndef IW_CUSTOM_MAX -#define IW_CUSTOM_MAX 256 -#endif - -void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) -{ -#if WIRELESS_EXT > 13 - union iwreq_data wrqu; - char extra[IW_CUSTOM_MAX + 1]; - int cmd = 0; - u32 event_type = be32_to_cpu(e->event_type); - u16 flags = be16_to_cpu(e->flags); - u32 datalen = be32_to_cpu(e->datalen); - u32 status = be32_to_cpu(e->status); - wl_iw_t *iw; - u32 toto; - memset(&wrqu, 0, sizeof(wrqu)); - memset(extra, 0, sizeof(extra)); - iw = 0; - - if (!dev) { - WL_ERROR("%s: dev is null\n", __func__); - return; - } - - iw = *(wl_iw_t **) netdev_priv(dev); - - WL_TRACE("%s: dev=%s event=%d\n", __func__, dev->name, event_type); - - switch (event_type) { - case WLC_E_TXFAIL: - cmd = IWEVTXDROP; - memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - break; -#if WIRELESS_EXT > 14 - case WLC_E_JOIN: - case WLC_E_ASSOC_IND: - case WLC_E_REASSOC_IND: - memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - cmd = IWEVREGISTERED; - break; - case WLC_E_DEAUTH_IND: - case WLC_E_DISASSOC_IND: - cmd = SIOCGIWAP; - memset(wrqu.addr.sa_data, 0, ETH_ALEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - memset(&extra, 0, ETH_ALEN); - break; - case WLC_E_LINK: - case WLC_E_NDIS_LINK: - cmd = SIOCGIWAP; - if (!(flags & WLC_EVENT_MSG_LINK)) { - memset(wrqu.addr.sa_data, 0, ETH_ALEN); - memset(&extra, 0, ETH_ALEN); - } else { - memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN); - WL_TRACE("Link UP\n"); - - } - wrqu.addr.sa_family = ARPHRD_ETHER; - break; - case WLC_E_ACTION_FRAME: - cmd = IWEVCUSTOM; - if (datalen + 1 <= sizeof(extra)) { - wrqu.data.length = datalen + 1; - extra[0] = WLC_E_ACTION_FRAME; - memcpy(&extra[1], data, datalen); - WL_TRACE("WLC_E_ACTION_FRAME len %d\n", - wrqu.data.length); - } - break; - - case WLC_E_ACTION_FRAME_COMPLETE: - cmd = IWEVCUSTOM; - memcpy(&toto, data, 4); - if (sizeof(status) + 1 <= sizeof(extra)) { - wrqu.data.length = sizeof(status) + 1; - extra[0] = WLC_E_ACTION_FRAME_COMPLETE; - memcpy(&extra[1], &status, sizeof(status)); - WL_TRACE("wl_iw_event status %d PacketId %d\n", status, - toto); - WL_TRACE("WLC_E_ACTION_FRAME_COMPLETE len %d\n", - wrqu.data.length); - } - break; -#endif /* WIRELESS_EXT > 14 */ -#if WIRELESS_EXT > 17 - case WLC_E_MIC_ERROR: - { - struct iw_michaelmicfailure *micerrevt = - (struct iw_michaelmicfailure *)&extra; - cmd = IWEVMICHAELMICFAILURE; - wrqu.data.length = sizeof(struct iw_michaelmicfailure); - if (flags & WLC_EVENT_MSG_GROUP) - micerrevt->flags |= IW_MICFAILURE_GROUP; - else - micerrevt->flags |= IW_MICFAILURE_PAIRWISE; - memcpy(micerrevt->src_addr.sa_data, &e->addr, - ETH_ALEN); - micerrevt->src_addr.sa_family = ARPHRD_ETHER; - - break; - } - case WLC_E_PMKID_CACHE: - { - if (data) { - struct iw_pmkid_cand *iwpmkidcand = - (struct iw_pmkid_cand *)&extra; - pmkid_cand_list_t *pmkcandlist; - pmkid_cand_t *pmkidcand; - int count; - - cmd = IWEVPMKIDCAND; - pmkcandlist = data; - count = get_unaligned_be32(&pmkcandlist-> - npmkid_cand); - ASSERT(count >= 0); - wrqu.data.length = sizeof(struct iw_pmkid_cand); - pmkidcand = pmkcandlist->pmkid_cand; - while (count) { - memset(iwpmkidcand, 0, - sizeof(struct iw_pmkid_cand)); - if (pmkidcand->preauth) - iwpmkidcand->flags |= - IW_PMKID_CAND_PREAUTH; - memcpy(&iwpmkidcand->bssid.sa_data, - &pmkidcand->BSSID, - ETH_ALEN); -#ifndef SANDGATE2G - wireless_send_event(dev, cmd, &wrqu, - extra); -#endif - pmkidcand++; - count--; - } - } - return; - } -#endif /* WIRELESS_EXT > 17 */ - - case WLC_E_SCAN_COMPLETE: -#if defined(WL_IW_USE_ISCAN) - if ((g_iscan) && (g_iscan->sysioc_tsk) && - (g_iscan->iscan_state != ISCAN_STATE_IDLE)) { - up(&g_iscan->sysioc_sem); - } else { - cmd = SIOCGIWSCAN; - wrqu.data.length = strlen(extra); - WL_TRACE("Event WLC_E_SCAN_COMPLETE from specific scan %d\n", - g_iscan->iscan_state); - } -#else - cmd = SIOCGIWSCAN; - wrqu.data.length = strlen(extra); - WL_TRACE("Event WLC_E_SCAN_COMPLETE\n"); -#endif - break; - - case WLC_E_PFN_NET_FOUND: - { - wlc_ssid_t *ssid; - ssid = (wlc_ssid_t *) data; - WL_ERROR("%s Event WLC_E_PFN_NET_FOUND, send %s up : find %s len=%d\n", - __func__, PNO_EVENT_UP, - ssid->SSID, ssid->SSID_len); - cmd = IWEVCUSTOM; - memset(&wrqu, 0, sizeof(wrqu)); - strcpy(extra, PNO_EVENT_UP); - wrqu.data.length = strlen(extra); - } - break; - - default: - WL_TRACE("Unknown Event %d: ignoring\n", event_type); - break; - } -#ifndef SANDGATE2G - if (cmd) { - if (cmd == SIOCGIWSCAN) - wireless_send_event(dev, cmd, &wrqu, NULL); - else - wireless_send_event(dev, cmd, &wrqu, extra); - } -#endif - -#if WIRELESS_EXT > 14 - memset(extra, 0, sizeof(extra)); - if (wl_iw_check_conn_fail(e, extra, sizeof(extra))) { - cmd = IWEVCUSTOM; - wrqu.data.length = strlen(extra); -#ifndef SANDGATE2G - wireless_send_event(dev, cmd, &wrqu, extra); -#endif - } -#endif /* WIRELESS_EXT > 14 */ -#endif /* WIRELESS_EXT > 13 */ -} - -int wl_iw_attach(struct net_device *dev, void *dhdp) -{ - int params_size; - wl_iw_t *iw; -#if defined(WL_IW_USE_ISCAN) - iscan_info_t *iscan = NULL; - - if (!dev) - return 0; - - memset(&g_wl_iw_params, 0, sizeof(wl_iw_extra_params_t)); - -#ifdef CSCAN - params_size = - (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params)) + - (WL_NUMCHANNELS * sizeof(u16)) + - WL_SCAN_PARAMS_SSID_MAX * sizeof(wlc_ssid_t); -#else - params_size = - (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params)); -#endif - iscan = kzalloc(sizeof(iscan_info_t), GFP_KERNEL); - - if (!iscan) - return -ENOMEM; - - iscan->iscan_ex_params_p = kmalloc(params_size, GFP_KERNEL); - if (!iscan->iscan_ex_params_p) { - kfree(iscan); - return -ENOMEM; - } - iscan->iscan_ex_param_size = params_size; - iscan->sysioc_tsk = NULL; - - g_iscan = iscan; - iscan->dev = dev; - iscan->iscan_state = ISCAN_STATE_IDLE; - - iscan->timer_ms = 3000; - init_timer(&iscan->timer); - iscan->timer.data = (unsigned long) iscan; - iscan->timer.function = wl_iw_timerfunc; - - sema_init(&iscan->sysioc_sem, 0); - iscan->sysioc_tsk = kthread_run(_iscan_sysioc_thread, iscan, - "_iscan_sysioc"); - if (IS_ERR(iscan->sysioc_tsk)) { - iscan->sysioc_tsk = NULL; - return -ENOMEM; - } -#endif /* defined(WL_IW_USE_ISCAN) */ - - iw = *(wl_iw_t **) netdev_priv(dev); - iw->pub = (dhd_pub_t *) dhdp; - MUTEX_LOCK_INIT(iw->pub); - MUTEX_LOCK_WL_SCAN_SET_INIT(); -#ifdef SOFTAP - priv_dev = dev; - MUTEX_LOCK_SOFTAP_SET_INIT(iw->pub); -#endif - g_scan = kzalloc(G_SCAN_RESULTS, GFP_KERNEL); - if (!g_scan) - return -ENOMEM; - - g_scan_specified_ssid = 0; - - return 0; -} - -void wl_iw_detach(void) -{ -#if defined(WL_IW_USE_ISCAN) - iscan_buf_t *buf; - iscan_info_t *iscan = g_iscan; - - if (!iscan) - return; - if (iscan->sysioc_tsk) { - send_sig(SIGTERM, iscan->sysioc_tsk, 1); - kthread_stop(iscan->sysioc_tsk); - iscan->sysioc_tsk = NULL; - } - - MUTEX_LOCK_WL_SCAN_SET(); - while (iscan->list_hdr) { - buf = iscan->list_hdr->next; - kfree(iscan->list_hdr); - iscan->list_hdr = buf; - } - MUTEX_UNLOCK_WL_SCAN_SET(); - kfree(iscan->iscan_ex_params_p); - kfree(iscan); - g_iscan = NULL; -#endif /* WL_IW_USE_ISCAN */ - - kfree(g_scan); - - g_scan = NULL; -} - -#if defined(BCMDBG) -void osl_assert(char *exp, char *file, int line) -{ - char tempbuf[256]; - char *basename; - - basename = strrchr(file, '/'); - /* skip the '/' */ - if (basename) - basename++; - - if (!basename) - basename = file; - - snprintf(tempbuf, 256, - "assertion \"%s\" failed: file \"%s\", line %d\n", exp, - basename, line); - - /* - * Print assert message and give it time to - * be written to /var/log/messages - */ - if (!in_interrupt()) { - const int delay = 3; - printk(KERN_ERR "%s", tempbuf); - printk(KERN_ERR "panic in %d seconds\n", delay); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(delay * HZ); - } - - switch (g_assert_type) { - case 0: - panic(KERN_ERR "%s", tempbuf); - break; - case 1: - printk(KERN_ERR "%s", tempbuf); - BUG(); - break; - case 2: - printk(KERN_ERR "%s", tempbuf); - break; - default: - break; - } -} -#endif /* defined(BCMDBG) */ diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.h b/drivers/staging/brcm80211/brcmfmac/wl_iw.h deleted file mode 100644 index fe06174cee7d..000000000000 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wl_iw_h_ -#define _wl_iw_h_ - -#include - -#include - -#define WL_SCAN_PARAMS_SSID_MAX 10 -#define GET_SSID "SSID=" -#define GET_CHANNEL "CH=" -#define GET_NPROBE "NPROBE=" -#define GET_ACTIVE_ASSOC_DWELL "ACTIVE=" -#define GET_PASSIVE_ASSOC_DWELL "PASSIVE=" -#define GET_HOME_DWELL "HOME=" -#define GET_SCAN_TYPE "TYPE=" - -#define BAND_GET_CMD "BANDGET" -#define BAND_SET_CMD "BANDSET" -#define DTIM_SKIP_GET_CMD "DTIMSKIPGET" -#define DTIM_SKIP_SET_CMD "DTIMSKIPSET" -#define SETSUSPEND_CMD "SETSUSPENDOPT" -#define PNOSSIDCLR_SET_CMD "PNOSSIDCLR" -#define PNOSETUP_SET_CMD "PNOSETUP" -#define PNOENABLE_SET_CMD "PNOFORCE" -#define PNODEBUG_SET_CMD "PNODEBUG" - -typedef struct wl_iw_extra_params { - int target_channel; -} wl_iw_extra_params_t; - -#define WL_IW_RSSI_MINVAL -200 -#define WL_IW_RSSI_NO_SIGNAL -91 -#define WL_IW_RSSI_VERY_LOW -80 -#define WL_IW_RSSI_LOW -70 -#define WL_IW_RSSI_GOOD -68 -#define WL_IW_RSSI_VERY_GOOD -58 -#define WL_IW_RSSI_EXCELLENT -57 -#define WL_IW_RSSI_INVALID 0 -#define MAX_WX_STRING 80 -#define WL_IW_SET_ACTIVE_SCAN (SIOCIWFIRSTPRIV+1) -#define WL_IW_GET_RSSI (SIOCIWFIRSTPRIV+3) -#define WL_IW_SET_PASSIVE_SCAN (SIOCIWFIRSTPRIV+5) -#define WL_IW_GET_LINK_SPEED (SIOCIWFIRSTPRIV+7) -#define WL_IW_GET_CURR_MACADDR (SIOCIWFIRSTPRIV+9) -#define WL_IW_SET_STOP (SIOCIWFIRSTPRIV+11) -#define WL_IW_SET_START (SIOCIWFIRSTPRIV+13) - -#define WL_SET_AP_CFG (SIOCIWFIRSTPRIV+15) -#define WL_AP_STA_LIST (SIOCIWFIRSTPRIV+17) -#define WL_AP_MAC_FLTR (SIOCIWFIRSTPRIV+19) -#define WL_AP_BSS_START (SIOCIWFIRSTPRIV+21) -#define AP_LPB_CMD (SIOCIWFIRSTPRIV+23) -#define WL_AP_STOP (SIOCIWFIRSTPRIV+25) -#define WL_FW_RELOAD (SIOCIWFIRSTPRIV+27) -#define WL_COMBO_SCAN (SIOCIWFIRSTPRIV+29) -#define WL_AP_SPARE3 (SIOCIWFIRSTPRIV+31) -#define G_SCAN_RESULTS (8*1024) -#define WE_ADD_EVENT_FIX 0x80 -#define G_WLAN_SET_ON 0 -#define G_WLAN_SET_OFF 1 - -#define CHECK_EXTRA_FOR_NULL(extra) \ -if (!extra) { \ - WL_ERROR("%s: error : extra is null pointer\n", __func__); \ - return -EINVAL; \ -} - -typedef struct wl_iw { - char nickname[IW_ESSID_MAX_SIZE]; - - struct iw_statistics wstats; - - int spy_num; - u32 pwsec; - u32 gwsec; - bool privacy_invoked; - - u8 spy_addr[IW_MAX_SPY][ETH_ALEN]; - struct iw_quality spy_qual[IW_MAX_SPY]; - void *wlinfo; - dhd_pub_t *pub; -} wl_iw_t; - -#if WIRELESS_EXT > 12 -#include -extern const struct iw_handler_def wl_iw_handler_def; -#endif - -extern int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -extern void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data); -extern int wl_iw_get_wireless_stats(struct net_device *dev, - struct iw_statistics *wstats); -int wl_iw_attach(struct net_device *dev, void *dhdp); -void wl_iw_detach(void); -extern int net_os_set_suspend_disable(struct net_device *dev, int val); -extern int net_os_set_suspend(struct net_device *dev, int val); -extern int net_os_set_dtim_skip(struct net_device *dev, int val); -extern int net_os_set_packet_filter(struct net_device *dev, int val); - -#define IWE_STREAM_ADD_EVENT(info, stream, ends, iwe, extra) \ - iwe_stream_add_event(info, stream, ends, iwe, extra) -#define IWE_STREAM_ADD_VALUE(info, event, value, ends, iwe, event_len) \ - iwe_stream_add_value(info, event, value, ends, iwe, event_len) -#define IWE_STREAM_ADD_POINT(info, stream, ends, iwe, extra) \ - iwe_stream_add_point(info, stream, ends, iwe, extra) - -extern int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled); -extern int dhd_pno_clean(dhd_pub_t *dhd); -extern int dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t *ssids_local, int nssid, - unsigned char scan_fr); -extern int dhd_pno_get_status(dhd_pub_t *dhd); -extern int dhd_dev_pno_reset(struct net_device *dev); -extern int dhd_dev_pno_set(struct net_device *dev, wlc_ssid_t *ssids_local, - int nssid, unsigned char scan_fr); -extern int dhd_dev_pno_enable(struct net_device *dev, int pfn_enabled); -extern int dhd_dev_get_pno_status(struct net_device *dev); - -#define PNO_TLV_PREFIX 'S' -#define PNO_TLV_VERSION 1 -#define PNO_TLV_SUBVERSION 0 -#define PNO_TLV_RESERVED 0 -#define PNO_TLV_TYPE_SSID_IE 'S' -#define PNO_TLV_TYPE_TIME 'T' -#define PNO_EVENT_UP "PNO_EVENT" - -#endif /* _wl_iw_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index 8d75fe19ca9a..1ea3e0c48f3e 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -28,30 +28,29 @@ ccflags-y := \ -Idrivers/staging/brcm80211/include BRCMSMAC_OFILES := \ - wl_mac80211.o \ - wl_ucode_loader.o \ - wlc_alloc.o \ - wlc_ampdu.o \ - wlc_antsel.o \ - wlc_bmac.o \ - wlc_channel.o \ - wlc_main.o \ - wlc_phy_shim.o \ - wlc_pmu.o \ - wlc_rate.o \ - wlc_stf.o \ + mac80211_if.o \ + ucode_loader.o \ + alloc.o \ + ampdu.o \ + antsel.o \ + bmac.o \ + channel.o \ + main.o \ + phy_shim.o \ + pmu.o \ + rate.o \ + stf.o \ aiutils.o \ - phy/wlc_phy_cmn.o \ - phy/wlc_phy_lcn.o \ - phy/wlc_phy_n.o \ - phy/wlc_phytbl_lcn.o \ - phy/wlc_phytbl_n.o \ - phy/wlc_phy_qmath.o \ - bcmotp.o \ - bcmsrom.o \ - hnddma.o \ - nicpci.o \ - nvram.o + phy/phy_cmn.o \ + phy/phy_lcn.o \ + phy/phy_n.o \ + phy/phytbl_lcn.o \ + phy/phytbl_n.o \ + phy/phy_qmath.o \ + otp.o \ + srom.o \ + dma.o \ + nicpci.o MODULEPFX := brcmsmac diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.c b/drivers/staging/brcm80211/brcmsmac/aiutils.c index a61185f70a7c..a25901e9981b 100644 --- a/drivers/staging/brcm80211/brcmsmac/aiutils.c +++ b/drivers/staging/brcm80211/brcmsmac/aiutils.c @@ -13,36 +13,354 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - #include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -/* ********** from siutils.c *********** */ -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include "types.h" +#include "pub.h" +#include "pmu.h" +#include "srom.h" +#include "nicpci.h" +#include "aiutils.h" + +/* slow_clk_ctl */ +#define SCC_SS_MASK 0x00000007 /* slow clock source mask */ +#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */ +#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */ +#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */ +#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ +#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, + * 0: LPO is enabled + */ +#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, + * 0: power logic control + */ +#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors + * PLL clock disable requests from core + */ +#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't + * disable crystal when appropriate + */ +#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ +#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ +#define SCC_CD_SHIFT 16 + +/* system_clk_ctl */ +#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */ +#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */ +#define SYCC_FP 0x00000004 /* ForcePLLOn */ +#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */ +#define SYCC_HR 0x00000010 /* Force HT */ +#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */ +#define SYCC_CD_SHIFT 16 + +#define CST4329_SPROM_OTP_SEL_MASK 0x00000003 +#define CST4329_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ +#define CST4329_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ +#define CST4329_OTP_SEL 2 /* OTP is powered up, no SPROM */ +#define CST4329_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */ +#define CST4329_SPI_SDIO_MODE_MASK 0x00000004 +#define CST4329_SPI_SDIO_MODE_SHIFT 2 + +/* 43224 chip-specific ChipControl register bits */ +#define CCTRL43224_GPIO_TOGGLE 0x8000 +#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 /* 12 mA drive strength */ +#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 /* 12 mA drive strength for later 43224s */ + +/* 43236 Chip specific ChipStatus register bits */ +#define CST43236_SFLASH_MASK 0x00000040 +#define CST43236_OTP_MASK 0x00000080 +#define CST43236_HSIC_MASK 0x00000100 /* USB/HSIC */ +#define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */ +#define CST43236_BOOT_MASK 0x00001800 +#define CST43236_BOOT_SHIFT 11 +#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ +#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */ +#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */ +#define CST43236_BOOT_FROM_INVALID 3 + +/* 4331 chip-specific ChipControl register bits */ +#define CCTRL4331_BT_COEXIST (1<<0) /* 0 disable */ +#define CCTRL4331_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ +#define CCTRL4331_EXT_LNA (1<<2) /* 0 disable */ +#define CCTRL4331_SPROM_GPIO13_15 (1<<3) /* sprom/gpio13-15 mux */ +#define CCTRL4331_EXTPA_EN (1<<4) /* 0 ext pa disable, 1 ext pa enabled */ +#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) /* set drive out GPIO_CLK on sprom_cs pin */ +#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) /* use sprom_cs pin as PCIE mdio interface */ +#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) /* aband extpa will be at gpio2/5 and sprom_dout */ +#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) /* override core control on pipe_AuxClkEnable */ +#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) /* override core control on pipe_AuxPowerDown */ +#define CCTRL4331_PCIE_AUXCLKEN (1<<10) /* pcie_auxclkenable */ +#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) /* pcie_pipe_pllpowerdown */ +#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) /* enable bt_shd0 at gpio4 */ +#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* enable bt_shd1 at gpio5 */ + +/* 4331 Chip specific ChipStatus register bits */ +#define CST4331_XTAL_FREQ 0x00000001 /* crystal frequency 20/40Mhz */ +#define CST4331_SPROM_PRESENT 0x00000002 +#define CST4331_OTP_PRESENT 0x00000004 +#define CST4331_LDO_RF 0x00000008 +#define CST4331_LDO_PAR 0x00000010 + +/* 4319 chip-specific ChipStatus register bits */ +#define CST4319_SPI_CPULESSUSB 0x00000001 +#define CST4319_SPI_CLK_POL 0x00000002 +#define CST4319_SPI_CLK_PH 0x00000008 +#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 /* gpio [7:6], SDIO CIS selection */ +#define CST4319_SPROM_OTP_SEL_SHIFT 6 +#define CST4319_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */ +#define CST4319_SPROM_SEL 0x00000040 /* use SPROM, OTP is powered up */ +#define CST4319_OTP_SEL 0x00000080 /* use OTP, OTP is powered up */ +#define CST4319_OTP_PWRDN 0x000000c0 /* use SPROM, OTP is powered down */ +#define CST4319_SDIO_USB_MODE 0x00000100 /* gpio [8], sdio/usb mode */ +#define CST4319_REMAP_SEL_MASK 0x00000600 +#define CST4319_ILPDIV_EN 0x00000800 +#define CST4319_XTAL_PD_POL 0x00001000 +#define CST4319_LPO_SEL 0x00002000 +#define CST4319_RES_INIT_MODE 0x0000c000 +#define CST4319_PALDO_EXTPNP 0x00010000 /* PALDO is configured with external PNP */ +#define CST4319_CBUCK_MODE_MASK 0x00060000 +#define CST4319_CBUCK_MODE_BURST 0x00020000 +#define CST4319_CBUCK_MODE_LPBURST 0x00060000 +#define CST4319_RCAL_VALID 0x01000000 +#define CST4319_RCAL_VALUE_MASK 0x3e000000 +#define CST4319_RCAL_VALUE_SHIFT 25 + +/* 4336 chip-specific ChipStatus register bits */ +#define CST4336_SPI_MODE_MASK 0x00000001 +#define CST4336_SPROM_PRESENT 0x00000002 +#define CST4336_OTP_PRESENT 0x00000004 +#define CST4336_ARMREMAP_0 0x00000008 +#define CST4336_ILPDIV_EN_MASK 0x00000010 +#define CST4336_ILPDIV_EN_SHIFT 4 +#define CST4336_XTAL_PD_POL_MASK 0x00000020 +#define CST4336_XTAL_PD_POL_SHIFT 5 +#define CST4336_LPO_SEL_MASK 0x00000040 +#define CST4336_LPO_SEL_SHIFT 6 +#define CST4336_RES_INIT_MODE_MASK 0x00000180 +#define CST4336_RES_INIT_MODE_SHIFT 7 +#define CST4336_CBUCK_MODE_MASK 0x00000600 +#define CST4336_CBUCK_MODE_SHIFT 9 + +/* 4313 chip-specific ChipStatus register bits */ +#define CST4313_SPROM_PRESENT 1 +#define CST4313_OTP_PRESENT 2 +#define CST4313_SPROM_OTP_SEL_MASK 0x00000002 +#define CST4313_SPROM_OTP_SEL_SHIFT 0 + +/* 4313 Chip specific ChipControl register bits */ +#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */ #define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \ (sih->chiprev == 0) && \ (sii->coreid[sii->curidx] == MIPS74K_CORE_ID)) +/* Manufacturer Ids */ +#define MFGID_ARM 0x43b +#define MFGID_BRCM 0x4bf +#define MFGID_MIPS 0x4a7 + +/* Enumeration ROM registers */ +#define ER_EROMENTRY 0x000 +#define ER_REMAPCONTROL 0xe00 +#define ER_REMAPSELECT 0xe04 +#define ER_MASTERSELECT 0xe10 +#define ER_ITCR 0xf00 +#define ER_ITIP 0xf04 + +/* Erom entries */ +#define ER_TAG 0xe +#define ER_TAG1 0x6 +#define ER_VALID 1 +#define ER_CI 0 +#define ER_MP 2 +#define ER_ADD 4 +#define ER_END 0xe +#define ER_BAD 0xffffffff + +/* EROM CompIdentA */ +#define CIA_MFG_MASK 0xfff00000 +#define CIA_MFG_SHIFT 20 +#define CIA_CID_MASK 0x000fff00 +#define CIA_CID_SHIFT 8 +#define CIA_CCL_MASK 0x000000f0 +#define CIA_CCL_SHIFT 4 + +/* EROM CompIdentB */ +#define CIB_REV_MASK 0xff000000 +#define CIB_REV_SHIFT 24 +#define CIB_NSW_MASK 0x00f80000 +#define CIB_NSW_SHIFT 19 +#define CIB_NMW_MASK 0x0007c000 +#define CIB_NMW_SHIFT 14 +#define CIB_NSP_MASK 0x00003e00 +#define CIB_NSP_SHIFT 9 +#define CIB_NMP_MASK 0x000001f0 +#define CIB_NMP_SHIFT 4 + +/* EROM AddrDesc */ +#define AD_ADDR_MASK 0xfffff000 +#define AD_SP_MASK 0x00000f00 +#define AD_SP_SHIFT 8 +#define AD_ST_MASK 0x000000c0 +#define AD_ST_SHIFT 6 +#define AD_ST_SLAVE 0x00000000 +#define AD_ST_BRIDGE 0x00000040 +#define AD_ST_SWRAP 0x00000080 +#define AD_ST_MWRAP 0x000000c0 +#define AD_SZ_MASK 0x00000030 +#define AD_SZ_SHIFT 4 +#define AD_SZ_4K 0x00000000 +#define AD_SZ_8K 0x00000010 +#define AD_SZ_16K 0x00000020 +#define AD_SZ_SZD 0x00000030 +#define AD_AG32 0x00000008 +#define AD_ADDR_ALIGN 0x00000fff +#define AD_SZ_BASE 0x00001000 /* 4KB */ + +/* EROM SizeDesc */ +#define SD_SZ_MASK 0xfffff000 +#define SD_SG32 0x00000008 +#define SD_SZ_ALIGN 0x00000fff + +#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ +#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal power-up */ +#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL power-down */ + +/* power control defines */ +#define PLL_DELAY 150 /* us pll on delay */ +#define FREF_DELAY 200 /* us fref change delay */ +#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ + +/* resetctrl */ +#define AIRC_RESET 1 + +struct aidmp { + u32 oobselina30; /* 0x000 */ + u32 oobselina74; /* 0x004 */ + u32 PAD[6]; + u32 oobselinb30; /* 0x020 */ + u32 oobselinb74; /* 0x024 */ + u32 PAD[6]; + u32 oobselinc30; /* 0x040 */ + u32 oobselinc74; /* 0x044 */ + u32 PAD[6]; + u32 oobselind30; /* 0x060 */ + u32 oobselind74; /* 0x064 */ + u32 PAD[38]; + u32 oobselouta30; /* 0x100 */ + u32 oobselouta74; /* 0x104 */ + u32 PAD[6]; + u32 oobseloutb30; /* 0x120 */ + u32 oobseloutb74; /* 0x124 */ + u32 PAD[6]; + u32 oobseloutc30; /* 0x140 */ + u32 oobseloutc74; /* 0x144 */ + u32 PAD[6]; + u32 oobseloutd30; /* 0x160 */ + u32 oobseloutd74; /* 0x164 */ + u32 PAD[38]; + u32 oobsynca; /* 0x200 */ + u32 oobseloutaen; /* 0x204 */ + u32 PAD[6]; + u32 oobsyncb; /* 0x220 */ + u32 oobseloutben; /* 0x224 */ + u32 PAD[6]; + u32 oobsyncc; /* 0x240 */ + u32 oobseloutcen; /* 0x244 */ + u32 PAD[6]; + u32 oobsyncd; /* 0x260 */ + u32 oobseloutden; /* 0x264 */ + u32 PAD[38]; + u32 oobaextwidth; /* 0x300 */ + u32 oobainwidth; /* 0x304 */ + u32 oobaoutwidth; /* 0x308 */ + u32 PAD[5]; + u32 oobbextwidth; /* 0x320 */ + u32 oobbinwidth; /* 0x324 */ + u32 oobboutwidth; /* 0x328 */ + u32 PAD[5]; + u32 oobcextwidth; /* 0x340 */ + u32 oobcinwidth; /* 0x344 */ + u32 oobcoutwidth; /* 0x348 */ + u32 PAD[5]; + u32 oobdextwidth; /* 0x360 */ + u32 oobdinwidth; /* 0x364 */ + u32 oobdoutwidth; /* 0x368 */ + u32 PAD[37]; + u32 ioctrlset; /* 0x400 */ + u32 ioctrlclear; /* 0x404 */ + u32 ioctrl; /* 0x408 */ + u32 PAD[61]; + u32 iostatus; /* 0x500 */ + u32 PAD[127]; + u32 ioctrlwidth; /* 0x700 */ + u32 iostatuswidth; /* 0x704 */ + u32 PAD[62]; + u32 resetctrl; /* 0x800 */ + u32 resetstatus; /* 0x804 */ + u32 resetreadid; /* 0x808 */ + u32 resetwriteid; /* 0x80c */ + u32 PAD[60]; + u32 errlogctrl; /* 0x900 */ + u32 errlogdone; /* 0x904 */ + u32 errlogstatus; /* 0x908 */ + u32 errlogaddrlo; /* 0x90c */ + u32 errlogaddrhi; /* 0x910 */ + u32 errlogid; /* 0x914 */ + u32 errloguser; /* 0x918 */ + u32 errlogflags; /* 0x91c */ + u32 PAD[56]; + u32 intstatus; /* 0xa00 */ + u32 PAD[127]; + u32 config; /* 0xe00 */ + u32 PAD[63]; + u32 itcr; /* 0xf00 */ + u32 PAD[3]; + u32 itipooba; /* 0xf10 */ + u32 itipoobb; /* 0xf14 */ + u32 itipoobc; /* 0xf18 */ + u32 itipoobd; /* 0xf1c */ + u32 PAD[4]; + u32 itipoobaout; /* 0xf30 */ + u32 itipoobbout; /* 0xf34 */ + u32 itipoobcout; /* 0xf38 */ + u32 itipoobdout; /* 0xf3c */ + u32 PAD[4]; + u32 itopooba; /* 0xf50 */ + u32 itopoobb; /* 0xf54 */ + u32 itopoobc; /* 0xf58 */ + u32 itopoobd; /* 0xf5c */ + u32 PAD[4]; + u32 itopoobain; /* 0xf70 */ + u32 itopoobbin; /* 0xf74 */ + u32 itopoobcin; /* 0xf78 */ + u32 itopoobdin; /* 0xf7c */ + u32 PAD[4]; + u32 itopreset; /* 0xf90 */ + u32 PAD[15]; + u32 peripherialid4; /* 0xfd0 */ + u32 peripherialid5; /* 0xfd4 */ + u32 peripherialid6; /* 0xfd8 */ + u32 peripherialid7; /* 0xfdc */ + u32 peripherialid0; /* 0xfe0 */ + u32 peripherialid1; /* 0xfe4 */ + u32 peripherialid2; /* 0xfe8 */ + u32 peripherialid3; /* 0xfec */ + u32 componentid0; /* 0xff0 */ + u32 componentid1; /* 0xff4 */ + u32 componentid2; /* 0xff8 */ + u32 componentid3; /* 0xffc */ +}; + /* EROM parsing */ static u32 -get_erom_ent(si_t *sih, u32 **eromptr, u32 mask, u32 match) +get_erom_ent(struct si_pub *sih, u32 **eromptr, u32 mask, u32 match) { u32 ent; uint inv = 0, nom = 0; @@ -77,7 +395,7 @@ get_erom_ent(si_t *sih, u32 **eromptr, u32 mask, u32 match) } static u32 -get_asd(si_t *sih, u32 **eromptr, uint sp, uint ad, uint st, +get_asd(struct si_pub *sih, u32 **eromptr, uint sp, uint ad, uint st, u32 *addrl, u32 *addrh, u32 *sizel, u32 *sizeh) { u32 asd, sz, szd; @@ -111,14 +429,14 @@ get_asd(si_t *sih, u32 **eromptr, uint sp, uint ad, uint st, return asd; } -static void ai_hwfixup(si_info_t *sii) +static void ai_hwfixup(struct si_info *sii) { } /* parse the enumeration rom to identify all cores */ -void ai_scan(si_t *sih, void *regs, uint devid) +void ai_scan(struct si_pub *sih, void *regs) { - si_info_t *sii = SI_INFO(sih); + struct si_info *sii = SI_INFO(sih); chipcregs_t *cc = (chipcregs_t *) regs; u32 erombase, *eromptr, *eromlim; @@ -319,9 +637,9 @@ void ai_scan(si_t *sih, void *regs, uint devid) /* This function changes the logical "focus" to the indicated core. * Return the current core's virtual address. */ -void *ai_setcoreidx(si_t *sih, uint coreidx) +void *ai_setcoreidx(struct si_pub *sih, uint coreidx) { - si_info_t *sii = SI_INFO(sih); + struct si_info *sii = SI_INFO(sih); u32 addr = sii->coresba[coreidx]; u32 wrap = sii->wrapba[coreidx]; void *regs; @@ -368,15 +686,15 @@ void *ai_setcoreidx(si_t *sih, uint coreidx) } /* Return the number of address spaces in current core */ -int ai_numaddrspaces(si_t *sih) +int ai_numaddrspaces(struct si_pub *sih) { return 2; } /* Return the address of the nth address space in the current core */ -u32 ai_addrspace(si_t *sih, uint asidx) +u32 ai_addrspace(struct si_pub *sih, uint asidx) { - si_info_t *sii; + struct si_info *sii; uint cidx; sii = SI_INFO(sih); @@ -393,9 +711,9 @@ u32 ai_addrspace(si_t *sih, uint asidx) } /* Return the size of the nth address space in the current core */ -u32 ai_addrspacesize(si_t *sih, uint asidx) +u32 ai_addrspacesize(struct si_pub *sih, uint asidx) { - si_info_t *sii; + struct si_info *sii; uint cidx; sii = SI_INFO(sih); @@ -411,10 +729,10 @@ u32 ai_addrspacesize(si_t *sih, uint asidx) } } -uint ai_flag(si_t *sih) +uint ai_flag(struct si_pub *sih) { - si_info_t *sii; - aidmp_t *ai; + struct si_info *sii; + struct aidmp *ai; sii = SI_INFO(sih); if (BCM47162_DMP()) { @@ -426,13 +744,13 @@ uint ai_flag(si_t *sih) return R_REG(&ai->oobselouta30) & 0x1f; } -void ai_setint(si_t *sih, int siflag) +void ai_setint(struct si_pub *sih, int siflag) { } -uint ai_corevendor(si_t *sih) +uint ai_corevendor(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; u32 cia; sii = SI_INFO(sih); @@ -440,9 +758,9 @@ uint ai_corevendor(si_t *sih) return (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; } -uint ai_corerev(si_t *sih) +uint ai_corerev(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; u32 cib; sii = SI_INFO(sih); @@ -450,10 +768,10 @@ uint ai_corerev(si_t *sih) return (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; } -bool ai_iscoreup(si_t *sih) +bool ai_iscoreup(struct si_pub *sih) { - si_info_t *sii; - aidmp_t *ai; + struct si_info *sii; + struct aidmp *ai; sii = SI_INFO(sih); ai = sii->curwrap; @@ -463,10 +781,10 @@ bool ai_iscoreup(si_t *sih) && ((R_REG(&ai->resetctrl) & AIRC_RESET) == 0)); } -void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val) +void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val) { - si_info_t *sii; - aidmp_t *ai; + struct si_info *sii; + struct aidmp *ai; u32 w; sii = SI_INFO(sih); @@ -485,10 +803,10 @@ void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val) } } -u32 ai_core_cflags(si_t *sih, u32 mask, u32 val) +u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val) { - si_info_t *sii; - aidmp_t *ai; + struct si_info *sii; + struct aidmp *ai; u32 w; sii = SI_INFO(sih); @@ -508,10 +826,10 @@ u32 ai_core_cflags(si_t *sih, u32 mask, u32 val) return R_REG(&ai->ioctrl); } -u32 ai_core_sflags(si_t *sih, u32 mask, u32 val) +u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val) { - si_info_t *sii; - aidmp_t *ai; + struct si_info *sii; + struct aidmp *ai; u32 w; sii = SI_INFO(sih); @@ -532,19 +850,19 @@ u32 ai_core_sflags(si_t *sih, u32 mask, u32 val) /* *************** from siutils.c ************** */ /* local prototypes */ -static si_info_t *ai_doattach(si_info_t *sii, uint devid, void *regs, +static struct si_info *ai_doattach(struct si_info *sii, void *regs, uint bustype, void *sdh, char **vars, uint *varsz); -static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid, - void *sdh); -static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, +static bool ai_buscore_prep(struct si_info *sii, uint bustype); +static bool ai_buscore_setup(struct si_info *sii, chipcregs_t *cc, uint bustype, u32 savewin, uint *origidx, void *regs); -static void ai_nvram_process(si_info_t *sii, char *pvars); +static void ai_nvram_process(struct si_info *sii, char *pvars); /* dev path concatenation util */ -static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name); -static bool _ai_clkctl_cc(si_info_t *sii, uint mode); -static bool ai_ispcie(si_info_t *sii); +static char *ai_devpathvar(struct si_pub *sih, char *var, int len, + const char *name); +static bool _ai_clkctl_cc(struct si_info *sii, uint mode); +static bool ai_ispcie(struct si_info *sii); /* global variable to indicate reservation/release of gpio's */ static u32 ai_gpioreservation; @@ -558,19 +876,19 @@ static u32 ai_gpioreservation; * vars - pointer to a pointer area for "environment" variables * varsz - pointer to int to return the size of the vars */ -si_t *ai_attach(uint devid, void *regs, uint bustype, +struct si_pub *ai_attach(void *regs, uint bustype, void *sdh, char **vars, uint *varsz) { - si_info_t *sii; + struct si_info *sii; - /* alloc si_info_t */ - sii = kmalloc(sizeof(si_info_t), GFP_ATOMIC); + /* alloc struct si_info */ + sii = kmalloc(sizeof(struct si_info), GFP_ATOMIC); if (sii == NULL) { SI_ERROR(("si_attach: malloc failed!\n")); return NULL; } - if (ai_doattach(sii, devid, regs, bustype, sdh, vars, varsz) == + if (ai_doattach(sii, regs, bustype, sdh, vars, varsz) == NULL) { kfree(sii); return NULL; @@ -578,14 +896,13 @@ si_t *ai_attach(uint devid, void *regs, uint bustype, sii->vars = vars ? *vars : NULL; sii->varsz = varsz ? *varsz : 0; - return (si_t *) sii; + return (struct si_pub *) sii; } /* global kernel resource */ -static si_info_t ksii; +static struct si_info ksii; -static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid, - void *sdh) +static bool ai_buscore_prep(struct si_info *sii, uint bustype) { /* kludge to enable the clock on the 4306 which lacks a slowclock */ if (bustype == PCI_BUS && !ai_ispcie(sii)) @@ -593,7 +910,7 @@ static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid, return true; } -static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, +static bool ai_buscore_setup(struct si_info *sii, chipcregs_t *cc, uint bustype, u32 savewin, uint *origidx, void *regs) { bool pci, pcie; @@ -702,7 +1019,7 @@ static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, return true; } -static __used void ai_nvram_process(si_info_t *sii, char *pvars) +static __used void ai_nvram_process(struct si_info *sii, char *pvars) { uint w = 0; @@ -751,7 +1068,7 @@ static __used void ai_nvram_process(si_info_t *sii, char *pvars) sii->pub.boardflags = getintvar(pvars, "boardflags"); } -static si_info_t *ai_doattach(si_info_t *sii, uint devid, +static struct si_info *ai_doattach(struct si_info *sii, void *regs, uint bustype, void *pbus, char **vars, uint *varsz) { @@ -762,7 +1079,7 @@ static si_info_t *ai_doattach(si_info_t *sii, uint devid, uint socitype; uint origidx; - memset((unsigned char *) sii, 0, sizeof(si_info_t)); + memset((unsigned char *) sii, 0, sizeof(struct si_info)); savewin = 0; @@ -797,7 +1114,7 @@ static si_info_t *ai_doattach(si_info_t *sii, uint devid, sih->bustype = bustype; /* bus/core/clk setup for register access */ - if (!ai_buscore_prep(sii, bustype, devid, pbus)) { + if (!ai_buscore_prep(sii, bustype)) { SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype)); return NULL; @@ -823,7 +1140,7 @@ static si_info_t *ai_doattach(si_info_t *sii, uint devid, if (socitype == SOCI_AI) { SI_MSG(("Found chip type AI (0x%08x)\n", w)); /* pass chipc address instead of original core base */ - ai_scan(&sii->pub, (void *)cc, devid); + ai_scan(&sii->pub, (void *)cc); } else { SI_ERROR(("Found chip of unknown type (0x%08x)\n", w)); return NULL; @@ -840,28 +1157,6 @@ static si_info_t *ai_doattach(si_info_t *sii, uint devid, goto exit; } - /* assume current core is CC */ - if ((sii->pub.ccrev == 0x25) - && - ((sih->chip == BCM43236_CHIP_ID - || sih->chip == BCM43235_CHIP_ID - || sih->chip == BCM43238_CHIP_ID) - && (sii->pub.chiprev <= 2))) { - - if ((cc->chipstatus & CST43236_BP_CLK) != 0) { - uint clkdiv; - clkdiv = R_REG(&cc->clkdiv); - /* otp_clk_div is even number, 120/14 < 9mhz */ - clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT); - W_REG(&cc->clkdiv, clkdiv); - SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv)); - } - udelay(10); - } - - /* Init nvram from flash if it exists */ - nvram_init(); - /* Init nvram from sprom/otp if they exist */ if (srom_var_init (&sii->pub, bustype, regs, vars, varsz)) { @@ -901,8 +1196,7 @@ static si_info_t *ai_doattach(si_info_t *sii, uint devid, pcicore_attach(sii->pch, pvars, SI_DOATTACH); } - if ((sih->chip == BCM43224_CHIP_ID) || - (sih->chip == BCM43421_CHIP_ID)) { + if (sih->chip == BCM43224_CHIP_ID) { /* * enable 12 mA drive strenth for 43224 and * set chipControl register bit 15 @@ -933,11 +1227,6 @@ static si_info_t *ai_doattach(si_info_t *sii, uint devid, CCTRL_4313_12MA_LED_DRIVE); } - if (sih->chip == BCM4331_CHIP_ID) { - /* Enable Ext PA lines depending on chip package option */ - ai_chipcontrl_epa4331(sih, true); - } - return sii; exit: if (sih->bustype == PCI_BUS) { @@ -950,13 +1239,13 @@ static si_info_t *ai_doattach(si_info_t *sii, uint devid, } /* may be called with core in reset */ -void ai_detach(si_t *sih) +void ai_detach(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; uint idx; struct si_pub *si_local = NULL; - bcopy(&sih, &si_local, sizeof(si_t **)); + memcpy(&si_local, &sih, sizeof(struct si_pub **)); sii = SI_INFO(sih); @@ -970,8 +1259,6 @@ void ai_detach(si_t *sih) sii->regs[idx] = NULL; } - nvram_exit(); /* free up nvram buffers */ - if (sih->bustype == PCI_BUS) { if (sii->pch) pcicore_deinit(sii->pch); @@ -984,10 +1271,11 @@ void ai_detach(si_t *sih) /* register driver interrupt disabling and restoring callback functions */ void -ai_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, +ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn, + void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg) { - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); sii->intr_arg = intr_arg; @@ -1000,39 +1288,39 @@ ai_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn, sii->dev_coreid = sii->coreid[sii->curidx]; } -void ai_deregister_intr_callback(si_t *sih) +void ai_deregister_intr_callback(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); sii->intrsoff_fn = NULL; } -uint ai_coreid(si_t *sih) +uint ai_coreid(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); return sii->coreid[sii->curidx]; } -uint ai_coreidx(si_t *sih) +uint ai_coreidx(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); return sii->curidx; } -bool ai_backplane64(si_t *sih) +bool ai_backplane64(struct si_pub *sih) { return (sih->cccaps & CC_CAP_BKPLN64) != 0; } /* return index of coreid or BADIDX if not found */ -uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit) +uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit) { - si_info_t *sii; + struct si_info *sii; uint found; uint i; @@ -1056,7 +1344,7 @@ uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit) * Moreover, callers should keep interrupts off during switching * out of and back to d11 core. */ -void *ai_setcore(si_t *sih, uint coreid, uint coreunit) +void *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit) { uint idx; @@ -1068,10 +1356,11 @@ void *ai_setcore(si_t *sih, uint coreid, uint coreunit) } /* Turn off interrupt as required by ai_setcore, before switch core */ -void *ai_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) +void *ai_switch_core(struct si_pub *sih, uint coreid, uint *origidx, + uint *intr_val) { void *cc; - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); @@ -1093,9 +1382,9 @@ void *ai_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val) } /* restore coreidx and restore interrupt */ -void ai_restore_core(si_t *sih, uint coreid, uint intr_val) +void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val) { - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); if (SI_FAST(sii) @@ -1106,9 +1395,9 @@ void ai_restore_core(si_t *sih, uint coreid, uint intr_val) INTR_RESTORE(sii, intr_val); } -void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val) +void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val) { - si_info_t *sii = SI_INFO(sih); + struct si_info *sii = SI_INFO(sih); u32 *w = (u32 *) sii->curwrap; W_REG(w + (offset / 4), val); return; @@ -1124,14 +1413,15 @@ void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val) * Also, when using pci/pcie, we can optimize away the core switching for pci * registers and (on newer pci cores) chipcommon registers. */ -uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) +uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask, + uint val) { uint origidx = 0; u32 *r = NULL; uint w; uint intr_val = 0; bool fast = false; - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); @@ -1208,11 +1498,11 @@ uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) return w; } -void ai_core_disable(si_t *sih, u32 bits) +void ai_core_disable(struct si_pub *sih, u32 bits) { - si_info_t *sii; + struct si_info *sii; u32 dummy; - aidmp_t *ai; + struct aidmp *ai; sii = SI_INFO(sih); @@ -1235,10 +1525,10 @@ void ai_core_disable(si_t *sih, u32 bits) * bits - core specific bits that are set during and after reset sequence * resetbits - core specific bits that are set only during reset sequence */ -void ai_core_reset(si_t *sih, u32 bits, u32 resetbits) +void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits) { - si_info_t *sii; - aidmp_t *ai; + struct si_info *sii; + struct aidmp *ai; u32 dummy; sii = SI_INFO(sih); @@ -1264,7 +1554,7 @@ void ai_core_reset(si_t *sih, u32 bits, u32 resetbits) } /* return the slow clock source - LPO, XTAL, or PCI */ -static uint ai_slowclk_src(si_info_t *sii) +static uint ai_slowclk_src(struct si_info *sii) { chipcregs_t *cc; u32 val; @@ -1288,7 +1578,7 @@ static uint ai_slowclk_src(si_info_t *sii) * return the ILP (slowclock) min or max frequency * precondition: we've established the chip has dynamic clk control */ -static uint ai_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) +static uint ai_slowclk_freq(struct si_info *sii, bool max_freq, chipcregs_t *cc) { u32 slowclk; uint div; @@ -1322,7 +1612,7 @@ static uint ai_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc) return 0; } -static void ai_clkctl_setdelay(si_info_t *sii, void *chipcregs) +static void ai_clkctl_setdelay(struct si_info *sii, void *chipcregs) { chipcregs_t *cc = (chipcregs_t *) chipcregs; uint slowmaxfreq, pll_delay, slowclk; @@ -1352,9 +1642,9 @@ static void ai_clkctl_setdelay(si_info_t *sii, void *chipcregs) } /* initialize power control delay registers */ -void ai_clkctl_init(si_t *sih) +void ai_clkctl_init(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; uint origidx = 0; chipcregs_t *cc; bool fast; @@ -1390,9 +1680,9 @@ void ai_clkctl_init(si_t *sih) * return the value suitable for writing to the * dot11 core FAST_PWRUP_DELAY register */ -u16 ai_clkctl_fast_pwrup_delay(si_t *sih) +u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; uint origidx = 0; chipcregs_t *cc; uint slowminfreq; @@ -1438,9 +1728,9 @@ u16 ai_clkctl_fast_pwrup_delay(si_t *sih) } /* turn primary xtal and/or pll off/on */ -int ai_clkctl_xtal(si_t *sih, uint what, bool on) +int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on) { - si_info_t *sii; + struct si_info *sii; u32 in, out, outen; sii = SI_INFO(sih); @@ -1515,9 +1805,9 @@ int ai_clkctl_xtal(si_t *sih, uint what, bool on) * this is a wrapper over the next internal function * to allow flexible policy settings for outside caller */ -bool ai_clkctl_cc(si_t *sih, uint mode) +bool ai_clkctl_cc(struct si_pub *sih, uint mode) { - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); @@ -1532,7 +1822,7 @@ bool ai_clkctl_cc(si_t *sih, uint mode) } /* clk control mechanism through chipcommon, no policy checking */ -static bool _ai_clkctl_cc(si_info_t *sii, uint mode) +static bool _ai_clkctl_cc(struct si_info *sii, uint mode) { uint origidx = 0; chipcregs_t *cc; @@ -1624,7 +1914,7 @@ static bool _ai_clkctl_cc(si_info_t *sii, uint mode) } /* Build device path. Support SI, PCI, and JTAG for now. */ -int ai_devpath(si_t *sih, char *path, int size) +int ai_devpath(struct si_pub *sih, char *path, int size) { int slen; @@ -1657,7 +1947,7 @@ int ai_devpath(si_t *sih, char *path, int size) } /* Get a variable, but only if it has a devpath prefix */ -char *ai_getdevpathvar(si_t *sih, const char *name) +char *ai_getdevpathvar(struct si_pub *sih, const char *name) { char varname[SI_DEVPATH_BUFSZ + 32]; @@ -1667,7 +1957,7 @@ char *ai_getdevpathvar(si_t *sih, const char *name) } /* Get a variable, but only if it has a devpath prefix */ -int ai_getdevpathintvar(si_t *sih, const char *name) +int ai_getdevpathintvar(struct si_pub *sih, const char *name) { #if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS) return getintvar(NULL, name); @@ -1680,7 +1970,7 @@ int ai_getdevpathintvar(si_t *sih, const char *name) #endif } -char *ai_getnvramflvar(si_t *sih, const char *name) +char *ai_getnvramflvar(struct si_pub *sih, const char *name) { return getvar(NULL, name); } @@ -1690,7 +1980,8 @@ char *ai_getnvramflvar(si_t *sih, const char *name) * len == 0 or var is NULL, var is still returned. On overflow, the * first char will be set to '\0'. */ -static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name) +static char *ai_devpathvar(struct si_pub *sih, char *var, int len, + const char *name) { uint path_len; @@ -1710,7 +2001,7 @@ static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name) } /* return true if PCIE capability exists in the pci config space */ -static __used bool ai_ispcie(si_info_t *sii) +static bool ai_ispcie(struct si_info *sii) { u8 cap_ptr; @@ -1726,18 +2017,18 @@ static __used bool ai_ispcie(si_info_t *sii) return true; } -bool ai_pci_war16165(si_t *sih) +bool ai_pci_war16165(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); return PCI(sii) && (sih->buscorerev <= 10); } -void ai_pci_up(si_t *sih) +void ai_pci_up(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); @@ -1754,9 +2045,9 @@ void ai_pci_up(si_t *sih) } /* Unconfigure and/or apply various WARs when system is going to sleep mode */ -void ai_pci_sleep(si_t *sih) +void ai_pci_sleep(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); @@ -1764,9 +2055,9 @@ void ai_pci_sleep(si_t *sih) } /* Unconfigure and/or apply various WARs when going down */ -void ai_pci_down(si_t *sih) +void ai_pci_down(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); @@ -1785,10 +2076,10 @@ void ai_pci_down(si_t *sih) * Configure the pci core for pci client (NIC) action * coremask is the bitvec of cores by index to be enabled. */ -void ai_pci_setup(si_t *sih, uint coremask) +void ai_pci_setup(struct si_pub *sih, uint coremask) { - si_info_t *sii; - struct sbpciregs *pciregs = NULL; + struct si_info *sii; + void *regs = NULL; u32 siflag = 0, w; uint idx = 0; @@ -1805,7 +2096,7 @@ void ai_pci_setup(si_t *sih, uint coremask) siflag = ai_flag(sih); /* switch over to pci core */ - pciregs = ai_setcoreidx(sih, sii->pub.buscoreidx); + regs = ai_setcoreidx(sih, sii->pub.buscoreidx); } /* @@ -1823,16 +2114,7 @@ void ai_pci_setup(si_t *sih, uint coremask) } if (PCI(sii)) { - OR_REG(&pciregs->sbtopci2, - (SBTOPCI_PREF | SBTOPCI_BURST)); - if (sii->pub.buscorerev >= 11) { - OR_REG(&pciregs->sbtopci2, - SBTOPCI_RC_READMULTI); - w = R_REG(&pciregs->clkrun); - W_REG(&pciregs->clkrun, - (w | PCI_CLKRUN_DSBL)); - w = R_REG(&pciregs->clkrun); - } + pcicore_pci_setup(sii->pch, regs); /* switch back to previous core */ ai_setcoreidx(sih, idx); @@ -1843,38 +2125,20 @@ void ai_pci_setup(si_t *sih, uint coremask) * Fixup SROMless PCI device's configuration. * The current core may be changed upon return. */ -int ai_pci_fixcfg(si_t *sih) +int ai_pci_fixcfg(struct si_pub *sih) { - uint origidx, pciidx; - struct sbpciregs *pciregs = NULL; - sbpcieregs_t *pcieregs = NULL; + uint origidx; void *regs = NULL; - u16 val16, *reg16 = NULL; - si_info_t *sii = SI_INFO(sih); + struct si_info *sii = SI_INFO(sih); /* Fixup PI in SROM shadow area to enable the correct PCI core access */ /* save the current index */ origidx = ai_coreidx(&sii->pub); /* check 'pi' is correct and fix it if not */ - if (sii->pub.buscoretype == PCIE_CORE_ID) { - pcieregs = ai_setcore(&sii->pub, PCIE_CORE_ID, 0); - regs = pcieregs; - reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; - } else if (sii->pub.buscoretype == PCI_CORE_ID) { - pciregs = ai_setcore(&sii->pub, PCI_CORE_ID, 0); - regs = pciregs; - reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; - } - pciidx = ai_coreidx(&sii->pub); - val16 = R_REG(reg16); - if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16) pciidx) { - val16 = - (u16) (pciidx << SRSH_PI_SHIFT) | (val16 & - ~SRSH_PI_MASK); - W_REG(reg16, val16); - } + regs = ai_setcore(&sii->pub, sii->pub.buscoretype, 0); + pcicore_fixcfg(sii->pch, regs); /* restore the original index */ ai_setcoreidx(&sii->pub, origidx); @@ -1884,7 +2148,7 @@ int ai_pci_fixcfg(si_t *sih) } /* mask&set gpiocontrol bits */ -u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority) +u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val, u8 priority) { uint regoff; @@ -1904,9 +2168,9 @@ u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority) return ai_corereg(sih, SI_CC_IDX, regoff, mask, val); } -void ai_chipcontrl_epa4331(si_t *sih, bool on) +void ai_chipcontrl_epa4331(struct si_pub *sih, bool on) { - si_info_t *sii; + struct si_info *sii; chipcregs_t *cc; uint origidx; u32 val; @@ -1938,9 +2202,9 @@ void ai_chipcontrl_epa4331(si_t *sih, bool on) } /* Enable BT-COEX & Ex-PA for 4313 */ -void ai_epa_4313war(si_t *sih) +void ai_epa_4313war(struct si_pub *sih) { - si_info_t *sii; + struct si_info *sii; chipcregs_t *cc; uint origidx; @@ -1957,10 +2221,10 @@ void ai_epa_4313war(si_t *sih) } /* check if the device is removed */ -bool ai_deviceremoved(si_t *sih) +bool ai_deviceremoved(struct si_pub *sih) { u32 w; - si_info_t *sii; + struct si_info *sii; sii = SI_INFO(sih); @@ -1974,10 +2238,10 @@ bool ai_deviceremoved(si_t *sih) return false; } -bool ai_is_sprom_available(si_t *sih) +bool ai_is_sprom_available(struct si_pub *sih) { if (sih->ccrev >= 31) { - si_info_t *sii; + struct si_info *sii; uint origidx; chipcregs_t *cc; u32 sromctrl; @@ -1994,61 +2258,22 @@ bool ai_is_sprom_available(si_t *sih) } switch (sih->chip) { - case BCM4329_CHIP_ID: - return (sih->chipst & CST4329_SPROM_SEL) != 0; - case BCM4319_CHIP_ID: - return (sih->chipst & CST4319_SPROM_SEL) != 0; - case BCM4336_CHIP_ID: - return (sih->chipst & CST4336_SPROM_PRESENT) != 0; - case BCM4330_CHIP_ID: - return (sih->chipst & CST4330_SPROM_PRESENT) != 0; case BCM4313_CHIP_ID: return (sih->chipst & CST4313_SPROM_PRESENT) != 0; - case BCM4331_CHIP_ID: - return (sih->chipst & CST4331_SPROM_PRESENT) != 0; default: return true; } } -bool ai_is_otp_disabled(si_t *sih) +bool ai_is_otp_disabled(struct si_pub *sih) { switch (sih->chip) { - case BCM4329_CHIP_ID: - return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) == - CST4329_OTP_PWRDN; - case BCM4319_CHIP_ID: - return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) == - CST4319_OTP_PWRDN; - case BCM4336_CHIP_ID: - return (sih->chipst & CST4336_OTP_PRESENT) == 0; - case BCM4330_CHIP_ID: - return (sih->chipst & CST4330_OTP_PRESENT) == 0; case BCM4313_CHIP_ID: return (sih->chipst & CST4313_OTP_PRESENT) == 0; /* These chips always have their OTP on */ case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: - case BCM43421_CHIP_ID: - case BCM43235_CHIP_ID: - case BCM43236_CHIP_ID: - case BCM43238_CHIP_ID: - case BCM4331_CHIP_ID: default: return false; } } - -bool ai_is_otp_powered(si_t *sih) -{ - if (PMUCTL_ENAB(sih)) - return si_pmu_is_otp_powered(sih); - return true; -} - -void ai_otp_power(si_t *sih, bool on) -{ - if (PMUCTL_ENAB(sih)) - si_pmu_otp_power(sih, on); - udelay(1000); -} diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.h b/drivers/staging/brcm80211/brcmsmac/aiutils.h index b98099eaa621..e245c278bebc 100644 --- a/drivers/staging/brcm80211/brcmsmac/aiutils.h +++ b/drivers/staging/brcm80211/brcmsmac/aiutils.h @@ -14,18 +14,10 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _aiutils_h_ -#define _aiutils_h_ +#ifndef _BRCM_AIUTILS_H_ +#define _BRCM_AIUTILS_H_ -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - -/* Include the soci specific files */ -#include +#include "types.h" /* * SOC Interconnect Address Map. @@ -158,9 +150,7 @@ * maps all unused address ranges */ -/* There are TWO constants on all HND chips: SI_ENUM_BASE above, - * and chipcommon being the first core: - */ +/* chipcommon being the first core: */ #define SI_CC_IDX 0 /* SOC Interconnect types (aka chip types) */ @@ -225,7 +215,70 @@ #define BISZ_BSSEND_IDX 6 /* 6: bss end */ #define BISZ_SIZE 7 /* descriptor size in 32-bit integers */ -#define SI_INFO(sih) (si_info_t *)sih +#define CC_SROM_OTP 0x800 /* SROM/OTP address space */ + +/* gpiotimerval */ +#define GPIO_ONTIME_SHIFT 16 + +/* Fields in clkdiv */ +#define CLKD_OTP 0x000f0000 +#define CLKD_OTP_SHIFT 16 + +/* When Srom support present, fields in sromcontrol */ +#define SRC_START 0x80000000 +#define SRC_BUSY 0x80000000 +#define SRC_OPCODE 0x60000000 +#define SRC_OP_READ 0x00000000 +#define SRC_OP_WRITE 0x20000000 +#define SRC_OP_WRDIS 0x40000000 +#define SRC_OP_WREN 0x60000000 +#define SRC_OTPSEL 0x00000010 +#define SRC_LOCK 0x00000008 +#define SRC_SIZE_MASK 0x00000006 +#define SRC_SIZE_1K 0x00000000 +#define SRC_SIZE_4K 0x00000002 +#define SRC_SIZE_16K 0x00000004 +#define SRC_SIZE_SHIFT 1 +#define SRC_PRESENT 0x00000001 + +/* 4330 chip-specific ChipStatus register bits */ +#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) /* SDIO || gSPI */ +#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) /* USB || USBDA */ +#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) /* SDIO */ +#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) /* gSPI */ +#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) /* USB packet-oriented */ +#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) /* USB Direct Access */ +#define CST4330_OTP_PRESENT 0x00000010 +#define CST4330_LPO_AUTODET_EN 0x00000020 +#define CST4330_ARMREMAP_0 0x00000040 +#define CST4330_SPROM_PRESENT 0x00000080 /* takes priority over OTP if both set */ +#define CST4330_ILPDIV_EN 0x00000100 +#define CST4330_LPO_SEL 0x00000200 +#define CST4330_RES_INIT_MODE_SHIFT 10 +#define CST4330_RES_INIT_MODE_MASK 0x00000c00 +#define CST4330_CBUCK_MODE_SHIFT 12 +#define CST4330_CBUCK_MODE_MASK 0x00003000 +#define CST4330_CBUCK_POWER_OK 0x00004000 +#define CST4330_BB_PLL_LOCKED 0x00008000 + +/* Package IDs */ +#define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */ +#define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */ +#define BCM4717_PKG_ID 9 /* 4717 package id */ +#define BCM4718_PKG_ID 10 /* 4718 package id */ +#define HDLSIM_PKG_ID 14 /* HDL simulator package id */ +#define HWSIM_PKG_ID 15 /* Hardware simulator package id */ +#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */ + +/* these are router chips */ +#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */ +#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */ +#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */ +#define BCM5356_CHIP_ID 0x5356 /* 5356 chipcommon chipid */ +#define BCM5357_CHIP_ID 0x5357 /* 5357 chipcommon chipid */ + + +#define SI_INFO(sih) ((struct si_info *)sih) #define GOODCOREADDR(x, b) \ (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ @@ -314,13 +367,6 @@ struct si_pub { }; -/* - * for HIGH_ONLY driver, the si_t must be writable to allow states sync from - * BMAC to HIGH driver for monolithic driver, it is readonly to prevent accident - * change - */ -typedef const struct si_pub si_t; - /* * Many of the routines below take an 'sih' handle as their first arg. * Allocate this by calling si_attach(). Free it by calling si_detach(). @@ -363,8 +409,6 @@ typedef const struct si_pub si_t; #define SI_PCIDOWN 2 #define SI_PCIUP 3 -#define ISSIM_ENAB(sih) 0 - /* PMU clock/power control */ #if defined(BCMPMUCTL) #define PMUCTL_ENAB(sih) (BCMPMUCTL) @@ -404,16 +448,16 @@ typedef u32(*si_intrsoff_t) (void *intr_arg); typedef void (*si_intrsrestore_t) (void *intr_arg, u32 arg); typedef bool(*si_intrsenabled_t) (void *intr_arg); -typedef struct gpioh_item { +struct gpioh_item { void *arg; bool level; gpio_handler_t handler; u32 event; struct gpioh_item *next; -} gpioh_item_t; +}; /* misc si info needed by some of the routines */ -typedef struct si_info { +struct si_info { struct si_pub pub; /* back plane public state (must be first) */ void *pbus; /* handle to bus (pci/sdio/..) */ uint dev_coreid; /* the core provides driver functions */ @@ -424,10 +468,6 @@ typedef struct si_info { void *pch; /* PCI/E core handle */ - gpioh_item_t *gpioh_head; /* GPIO event handlers list */ - - bool memseg; /* flag to toggle MEM_SEG register */ - char *vars; uint varsz; @@ -450,97 +490,95 @@ typedef struct si_info { u32 cia[SI_MAXCORES]; /* erom cia entry for each core */ u32 cib[SI_MAXCORES]; /* erom cia entry for each core */ u32 oob_router; /* oob router registers for axi */ -} si_info_t; +}; /* AMBA Interconnect exported externs */ -extern void ai_scan(si_t *sih, void *regs, uint devid); +extern void ai_scan(struct si_pub *sih, void *regs); -extern uint ai_flag(si_t *sih); -extern void ai_setint(si_t *sih, int siflag); -extern uint ai_coreidx(si_t *sih); -extern uint ai_corevendor(si_t *sih); -extern uint ai_corerev(si_t *sih); -extern bool ai_iscoreup(si_t *sih); -extern void *ai_setcoreidx(si_t *sih, uint coreidx); -extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val); -extern void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val); -extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val); -extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, +extern uint ai_flag(struct si_pub *sih); +extern void ai_setint(struct si_pub *sih, int siflag); +extern uint ai_coreidx(struct si_pub *sih); +extern uint ai_corevendor(struct si_pub *sih); +extern uint ai_corerev(struct si_pub *sih); +extern bool ai_iscoreup(struct si_pub *sih); +extern void *ai_setcoreidx(struct si_pub *sih, uint coreidx); +extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val); +extern void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val); +extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val); +extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask, uint val); -extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits); -extern void ai_core_disable(si_t *sih, u32 bits); -extern int ai_numaddrspaces(si_t *sih); -extern u32 ai_addrspace(si_t *sih, uint asidx); -extern u32 ai_addrspacesize(si_t *sih, uint asidx); -extern void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val); +extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits); +extern void ai_core_disable(struct si_pub *sih, u32 bits); +extern int ai_numaddrspaces(struct si_pub *sih); +extern u32 ai_addrspace(struct si_pub *sih, uint asidx); +extern u32 ai_addrspacesize(struct si_pub *sih, uint asidx); +extern void ai_write_wrap_reg(struct si_pub *sih, u32 offset, u32 val); /* === exported functions === */ -extern si_t *ai_attach(uint pcidev, void *regs, uint bustype, +extern struct si_pub *ai_attach(void *regs, uint bustype, void *sdh, char **vars, uint *varsz); -extern void ai_detach(si_t *sih); -extern bool ai_pci_war16165(si_t *sih); +extern void ai_detach(struct si_pub *sih); +extern bool ai_pci_war16165(struct si_pub *sih); -extern uint ai_coreid(si_t *sih); -extern uint ai_corerev(si_t *sih); -extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, +extern uint ai_coreid(struct si_pub *sih); +extern uint ai_corerev(struct si_pub *sih); +extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask, uint val); -extern void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val); -extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val); -extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val); -extern bool ai_iscoreup(si_t *sih); -extern uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit); -extern void *ai_setcoreidx(si_t *sih, uint coreidx); -extern void *ai_setcore(si_t *sih, uint coreid, uint coreunit); -extern void *ai_switch_core(si_t *sih, uint coreid, uint *origidx, +extern void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val); +extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val); +extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val); +extern bool ai_iscoreup(struct si_pub *sih); +extern uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit); +extern void *ai_setcoreidx(struct si_pub *sih, uint coreidx); +extern void *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit); +extern void *ai_switch_core(struct si_pub *sih, uint coreid, uint *origidx, uint *intr_val); -extern void ai_restore_core(si_t *sih, uint coreid, uint intr_val); -extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits); -extern void ai_core_disable(si_t *sih, u32 bits); -extern u32 ai_alp_clock(si_t *sih); -extern u32 ai_ilp_clock(si_t *sih); -extern void ai_pci_setup(si_t *sih, uint coremask); -extern void ai_setint(si_t *sih, int siflag); -extern bool ai_backplane64(si_t *sih); -extern void ai_register_intr_callback(si_t *sih, void *intrsoff_fn, +extern void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val); +extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits); +extern void ai_core_disable(struct si_pub *sih, u32 bits); +extern u32 ai_alp_clock(struct si_pub *sih); +extern u32 ai_ilp_clock(struct si_pub *sih); +extern void ai_pci_setup(struct si_pub *sih, uint coremask); +extern void ai_setint(struct si_pub *sih, int siflag); +extern bool ai_backplane64(struct si_pub *sih); +extern void ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg); -extern void ai_deregister_intr_callback(si_t *sih); -extern void ai_clkctl_init(si_t *sih); -extern u16 ai_clkctl_fast_pwrup_delay(si_t *sih); -extern bool ai_clkctl_cc(si_t *sih, uint mode); -extern int ai_clkctl_xtal(si_t *sih, uint what, bool on); -extern bool ai_deviceremoved(si_t *sih); -extern u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val, +extern void ai_deregister_intr_callback(struct si_pub *sih); +extern void ai_clkctl_init(struct si_pub *sih); +extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih); +extern bool ai_clkctl_cc(struct si_pub *sih, uint mode); +extern int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on); +extern bool ai_deviceremoved(struct si_pub *sih); +extern u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val, u8 priority); /* OTP status */ -extern bool ai_is_otp_disabled(si_t *sih); -extern bool ai_is_otp_powered(si_t *sih); -extern void ai_otp_power(si_t *sih, bool on); +extern bool ai_is_otp_disabled(struct si_pub *sih); /* SPROM availability */ -extern bool ai_is_sprom_available(si_t *sih); +extern bool ai_is_sprom_available(struct si_pub *sih); /* * Build device path. Path size must be >= SI_DEVPATH_BUFSZ. * The returned path is NULL terminated and has trailing '/'. * Return 0 on success, nonzero otherwise. */ -extern int ai_devpath(si_t *sih, char *path, int size); +extern int ai_devpath(struct si_pub *sih, char *path, int size); /* Read variable with prepending the devpath to the name */ -extern char *ai_getdevpathvar(si_t *sih, const char *name); -extern int ai_getdevpathintvar(si_t *sih, const char *name); +extern char *ai_getdevpathvar(struct si_pub *sih, const char *name); +extern int ai_getdevpathintvar(struct si_pub *sih, const char *name); -extern void ai_pci_sleep(si_t *sih); -extern void ai_pci_down(si_t *sih); -extern void ai_pci_up(si_t *sih); -extern int ai_pci_fixcfg(si_t *sih); +extern void ai_pci_sleep(struct si_pub *sih); +extern void ai_pci_down(struct si_pub *sih); +extern void ai_pci_up(struct si_pub *sih); +extern int ai_pci_fixcfg(struct si_pub *sih); -extern void ai_chipcontrl_epa4331(si_t *sih, bool on); +extern void ai_chipcontrl_epa4331(struct si_pub *sih, bool on); /* Enable Ex-PA for 4313 */ -extern void ai_epa_4313war(si_t *sih); +extern void ai_epa_4313war(struct si_pub *sih); -char *ai_getnvramflvar(si_t *sih, const char *name); +char *ai_getnvramflvar(struct si_pub *sih, const char *name); -#endif /* _aiutils_h_ */ +#endif /* _BRCM_AIUTILS_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c b/drivers/staging/brcm80211/brcmsmac/alloc.c similarity index 51% rename from drivers/staging/brcm80211/brcmsmac/wlc_alloc.c rename to drivers/staging/brcm80211/brcmsmac/alloc.c index 82c64cd4486f..7f8dd7b396bf 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/alloc.c @@ -13,37 +13,21 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include -#include -#include -#include -#include +#include +#include "types.h" +#include "pub.h" +#include "main.h" +#include "alloc.h" -#include "d11.h" -#include "wlc_types.h" -#include "wlc_cfg.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "wlc_alloc.h" -#include "wl_dbg.h" -#include "wlc_rate.h" -#include "wlc_bsscfg.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_channel.h" -#include "wlc_main.h" - -static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit); -static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg); -static struct wlc_pub *wlc_pub_malloc(uint unit, +static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit); +static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg); +static struct brcms_pub *brcms_c_pub_malloc(uint unit, uint *err, uint devid); -static void wlc_pub_mfree(struct wlc_pub *pub); -static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid); +static void brcms_c_pub_mfree(struct brcms_pub *pub); +static void brcms_c_tunables_init(struct brcms_tunables *tunables, uint devid); -static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid) +static void brcms_c_tunables_init(struct brcms_tunables *tunables, uint devid) { tunables->ntxd = NTXD; tunables->nrxd = NRXD; @@ -52,33 +36,33 @@ static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid) tunables->maxscb = MAXSCB; tunables->ampdunummpdu = AMPDU_NUM_MPDU; tunables->maxpktcb = MAXPKTCB; - tunables->maxucodebss = WLC_MAX_UCODE_BSS; - tunables->maxucodebss4 = WLC_MAX_UCODE_BSS4; + tunables->maxucodebss = BRCMS_MAX_UCODE_BSS; + tunables->maxucodebss4 = BRCMS_MAX_UCODE_BSS4; tunables->maxbss = MAXBSS; - tunables->datahiwat = WLC_DATAHIWAT; - tunables->ampdudatahiwat = WLC_AMPDUDATAHIWAT; + tunables->datahiwat = BRCMS_DATAHIWAT; + tunables->ampdudatahiwat = BRCMS_AMPDUDATAHIWAT; tunables->rxbnd = RXBND; tunables->txsbnd = TXSBND; } -static struct wlc_pub *wlc_pub_malloc(uint unit, uint *err, uint devid) +static struct brcms_pub *brcms_c_pub_malloc(uint unit, uint *err, uint devid) { - struct wlc_pub *pub; + struct brcms_pub *pub; - pub = kzalloc(sizeof(struct wlc_pub), GFP_ATOMIC); + pub = kzalloc(sizeof(struct brcms_pub), GFP_ATOMIC); if (pub == NULL) { *err = 1001; goto fail; } - pub->tunables = kzalloc(sizeof(wlc_tunables_t), GFP_ATOMIC); + pub->tunables = kzalloc(sizeof(struct brcms_tunables), GFP_ATOMIC); if (pub->tunables == NULL) { *err = 1028; goto fail; } /* need to init the tunables now */ - wlc_tunables_init(pub->tunables, devid); + brcms_c_tunables_init(pub->tunables, devid); pub->multicast = kzalloc(ETH_ALEN * MAXMULTILIST, GFP_ATOMIC); if (pub->multicast == NULL) { @@ -89,11 +73,11 @@ static struct wlc_pub *wlc_pub_malloc(uint unit, uint *err, uint devid) return pub; fail: - wlc_pub_mfree(pub); + brcms_c_pub_mfree(pub); return NULL; } -static void wlc_pub_mfree(struct wlc_pub *pub) +static void brcms_c_pub_mfree(struct brcms_pub *pub) { if (pub == NULL) return; @@ -103,26 +87,26 @@ static void wlc_pub_mfree(struct wlc_pub *pub) kfree(pub); } -static struct wlc_bsscfg *wlc_bsscfg_malloc(uint unit) +static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit) { - struct wlc_bsscfg *cfg; + struct brcms_bss_cfg *cfg; - cfg = kzalloc(sizeof(struct wlc_bsscfg), GFP_ATOMIC); + cfg = kzalloc(sizeof(struct brcms_bss_cfg), GFP_ATOMIC); if (cfg == NULL) goto fail; - cfg->current_bss = kzalloc(sizeof(wlc_bss_info_t), GFP_ATOMIC); + cfg->current_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC); if (cfg->current_bss == NULL) goto fail; return cfg; fail: - wlc_bsscfg_mfree(cfg); + brcms_c_bsscfg_mfree(cfg); return NULL; } -static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg) +static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg) { if (cfg == NULL) return; @@ -132,8 +116,8 @@ static void wlc_bsscfg_mfree(struct wlc_bsscfg *cfg) kfree(cfg); } -static void wlc_bsscfg_ID_assign(struct wlc_info *wlc, - struct wlc_bsscfg *bsscfg) +static void brcms_c_bsscfg_ID_assign(struct brcms_c_info *wlc, + struct brcms_bss_cfg *bsscfg) { bsscfg->ID = wlc->next_bsscfg_ID; wlc->next_bsscfg_ID++; @@ -142,29 +126,27 @@ static void wlc_bsscfg_ID_assign(struct wlc_info *wlc, /* * The common driver entry routine. Error codes should be unique */ -struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) +struct brcms_c_info *brcms_c_attach_malloc(uint unit, uint *err, uint devid) { - struct wlc_info *wlc; + struct brcms_c_info *wlc; - wlc = kzalloc(sizeof(struct wlc_info), GFP_ATOMIC); + wlc = kzalloc(sizeof(struct brcms_c_info), GFP_ATOMIC); if (wlc == NULL) { *err = 1002; goto fail; } - wlc->hwrxoff = WL_HWRXOFF; - - /* allocate struct wlc_pub state structure */ - wlc->pub = wlc_pub_malloc(unit, err, devid); + /* allocate struct brcms_c_pub state structure */ + wlc->pub = brcms_c_pub_malloc(unit, err, devid); if (wlc->pub == NULL) { *err = 1003; goto fail; } wlc->pub->wlc = wlc; - /* allocate struct wlc_hw_info state structure */ + /* allocate struct brcms_hardware state structure */ - wlc->hw = kzalloc(sizeof(struct wlc_hw_info), GFP_ATOMIC); + wlc->hw = kzalloc(sizeof(struct brcms_hardware), GFP_ATOMIC); if (wlc->hw == NULL) { *err = 1005; goto fail; @@ -172,7 +154,7 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) wlc->hw->wlc = wlc; wlc->hw->bandstate[0] = - kzalloc(sizeof(struct wlc_hwband) * MAXBANDS, GFP_ATOMIC); + kzalloc(sizeof(struct brcms_hw_band) * MAXBANDS, GFP_ATOMIC); if (wlc->hw->bandstate[0] == NULL) { *err = 1006; goto fail; @@ -180,68 +162,62 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) int i; for (i = 1; i < MAXBANDS; i++) { - wlc->hw->bandstate[i] = (struct wlc_hwband *) + wlc->hw->bandstate[i] = (struct brcms_hw_band *) ((unsigned long)wlc->hw->bandstate[0] + - (sizeof(struct wlc_hwband) * i)); + (sizeof(struct brcms_hw_band) * i)); } } wlc->modulecb = - kzalloc(sizeof(struct modulecb) * WLC_MAXMODULES, GFP_ATOMIC); + kzalloc(sizeof(struct modulecb) * BRCMS_MAXMODULES, GFP_ATOMIC); if (wlc->modulecb == NULL) { *err = 1009; goto fail; } - wlc->default_bss = kzalloc(sizeof(wlc_bss_info_t), GFP_ATOMIC); + wlc->default_bss = kzalloc(sizeof(struct brcms_bss_info), GFP_ATOMIC); if (wlc->default_bss == NULL) { *err = 1010; goto fail; } - wlc->cfg = wlc_bsscfg_malloc(unit); + wlc->cfg = brcms_c_bsscfg_malloc(unit); if (wlc->cfg == NULL) { *err = 1011; goto fail; } - wlc_bsscfg_ID_assign(wlc, wlc->cfg); - - wlc->pkt_callback = kzalloc(sizeof(struct pkt_cb) * - (wlc->pub->tunables->maxpktcb + 1), - GFP_ATOMIC); - if (wlc->pkt_callback == NULL) { - *err = 1013; - goto fail; - } + brcms_c_bsscfg_ID_assign(wlc, wlc->cfg); wlc->wsec_def_keys[0] = - kzalloc(sizeof(wsec_key_t) * WLC_DEFAULT_KEYS, GFP_ATOMIC); + kzalloc(sizeof(struct wsec_key) * BRCMS_DEFAULT_KEYS, + GFP_ATOMIC); if (wlc->wsec_def_keys[0] == NULL) { *err = 1015; goto fail; } else { int i; - for (i = 1; i < WLC_DEFAULT_KEYS; i++) { - wlc->wsec_def_keys[i] = (wsec_key_t *) + for (i = 1; i < BRCMS_DEFAULT_KEYS; i++) { + wlc->wsec_def_keys[i] = (struct wsec_key *) ((unsigned long)wlc->wsec_def_keys[0] + - (sizeof(wsec_key_t) * i)); + (sizeof(struct wsec_key) * i)); } } - wlc->protection = kzalloc(sizeof(struct wlc_protection), GFP_ATOMIC); + wlc->protection = kzalloc(sizeof(struct brcms_protection), + GFP_ATOMIC); if (wlc->protection == NULL) { *err = 1016; goto fail; } - wlc->stf = kzalloc(sizeof(struct wlc_stf), GFP_ATOMIC); + wlc->stf = kzalloc(sizeof(struct brcms_stf), GFP_ATOMIC); if (wlc->stf == NULL) { *err = 1017; goto fail; } wlc->bandstate[0] = - kzalloc(sizeof(struct wlcband)*MAXBANDS, GFP_ATOMIC); + kzalloc(sizeof(struct brcms_band)*MAXBANDS, GFP_ATOMIC); if (wlc->bandstate[0] == NULL) { *err = 1025; goto fail; @@ -249,20 +225,20 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) int i; for (i = 1; i < MAXBANDS; i++) { - wlc->bandstate[i] = - (struct wlcband *) ((unsigned long)wlc->bandstate[0] - + (sizeof(struct wlcband)*i)); + wlc->bandstate[i] = (struct brcms_band *) + ((unsigned long)wlc->bandstate[0] + + (sizeof(struct brcms_band)*i)); } } - wlc->corestate = kzalloc(sizeof(struct wlccore), GFP_ATOMIC); + wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC); if (wlc->corestate == NULL) { *err = 1026; goto fail; } wlc->corestate->macstat_snapshot = - kzalloc(sizeof(macstat_t), GFP_ATOMIC); + kzalloc(sizeof(struct macstat), GFP_ATOMIC); if (wlc->corestate->macstat_snapshot == NULL) { *err = 1027; goto fail; @@ -271,20 +247,19 @@ struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid) return wlc; fail: - wlc_detach_mfree(wlc); + brcms_c_detach_mfree(wlc); return NULL; } -void wlc_detach_mfree(struct wlc_info *wlc) +void brcms_c_detach_mfree(struct brcms_c_info *wlc) { if (wlc == NULL) return; - wlc_bsscfg_mfree(wlc->cfg); - wlc_pub_mfree(wlc->pub); + brcms_c_bsscfg_mfree(wlc->cfg); + brcms_c_pub_mfree(wlc->pub); kfree(wlc->modulecb); kfree(wlc->default_bss); - kfree(wlc->pkt_callback); kfree(wlc->wsec_def_keys[0]); kfree(wlc->protection); kfree(wlc->stf); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h b/drivers/staging/brcm80211/brcmsmac/alloc.h similarity index 83% rename from drivers/staging/brcm80211/brcmsmac/wlc_alloc.h rename to drivers/staging/brcm80211/brcmsmac/alloc.h index 95f951eb2b2f..f465d3043030 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h +++ b/drivers/staging/brcm80211/brcmsmac/alloc.h @@ -14,5 +14,6 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -extern struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid); -extern void wlc_detach_mfree(struct wlc_info *wlc); +extern struct brcms_c_info *brcms_c_attach_malloc(uint unit, uint *err, + uint devid); +extern void brcms_c_detach_mfree(struct brcms_c_info *wlc); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/ampdu.c similarity index 77% rename from drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c rename to drivers/staging/brcm80211/brcmsmac/ampdu.c index 85ad70096056..fcaf61e3b134 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/ampdu.c @@ -13,30 +13,14 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include #include -#include -#include -#include -#include -#include -#include -#include - -#include "wlc_types.h" -#include "wlc_cfg.h" -#include "wlc_rate.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_antsel.h" -#include "wl_export.h" -#include "wl_dbg.h" -#include "wlc_channel.h" -#include "wlc_main.h" -#include "wlc_ampdu.h" +#include "rate.h" +#include "scb.h" +#include "phy/phy_hal.h" +#include "antsel.h" +#include "main.h" +#include "ampdu.h" #define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */ #define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */ @@ -76,7 +60,7 @@ * This allows to maintain a specific state independently of * how often and/or when the wlc counters are updated. */ -typedef struct wlc_fifo_info { +struct brcms_fifo_info { u16 ampdu_pld_size; /* number of bytes to be pre-loaded */ u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1]; /* per-mcs max # of mpdus in an ampdu */ u16 prev_txfunfl; /* num of underflows last read from the HW macstats counter */ @@ -84,11 +68,11 @@ typedef struct wlc_fifo_info { u32 accum_txampdu; /* num of tx ampdu since we modified pld params */ u32 prev_txampdu; /* previous reading of tx ampdu */ u32 dmaxferrate; /* estimated dma avg xfer rate in kbits/sec */ -} wlc_fifo_info_t; +}; /* AMPDU module specific state */ struct ampdu_info { - struct wlc_info *wlc; /* pointer to main wlc structure */ + struct brcms_c_info *wlc; /* pointer to main wlc structure */ int scb_handle; /* scb cubby handle to retrieve data from scb */ u8 ini_enable[AMPDU_MAX_SCB_TID]; /* per-tid initiator enable/disable of ampdu */ u8 ba_tx_wsize; /* Tx ba window size (in pdu) */ @@ -110,7 +94,8 @@ struct ampdu_info { u32 tx_max_funl; /* underflows should be kept such that * (tx_max_funfl*underflows) < tx frames */ - wlc_fifo_info_t fifo_tb[NUM_FFPLD_FIFO]; /* table of fifo infos */ + /* table of fifo infos */ + struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO]; }; @@ -126,35 +111,36 @@ struct cb_del_ampdu_pars { #define SCB_AMPDU_CUBBY(ampdu, scb) (&(scb->scb_ampdu)) #define SCB_AMPDU_INI(scb_ampdu, tid) (&(scb_ampdu->ini[tid])) -static void wlc_ffpld_init(struct ampdu_info *ampdu); -static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int f); -static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f); +static void brcms_c_ffpld_init(struct ampdu_info *ampdu); +static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int f); +static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f); -static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, - scb_ampdu_t *scb_ampdu, - u8 tid, bool override); -static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur); -static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb); -static void scb_ampdu_update_config_all(struct ampdu_info *ampdu); +static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, + u8 dur); +static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu, + struct scb *scb); +static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu); -#define wlc_ampdu_txflowcontrol(a, b, c) do {} while (0) +#define brcms_c_ampdu_txflowcontrol(a, b, c) do {} while (0) -static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, - struct scb *scb, - struct sk_buff *p, tx_status_t *txs, - u32 frmtxstatus, u32 frmtxstatus2); -static bool wlc_ampdu_cap(struct ampdu_info *ampdu); -static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on); +static void +brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, + struct scb *scb, + struct sk_buff *p, struct tx_status *txs, + u32 frmtxstatus, u32 frmtxstatus2); -struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) +static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu); +static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on); + +struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc) { struct ampdu_info *ampdu; int i; ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC); if (!ampdu) { - wiphy_err(wlc->wiphy, "wl%d: wlc_ampdu_attach: out of mem\n", - wlc->pub->unit); + wiphy_err(wlc->wiphy, "wl%d: brcms_c_ampdu_attach: out of mem" + "\n", wlc->pub->unit); return NULL; } ampdu->wlc = wlc; @@ -178,7 +164,7 @@ struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; /* bump max ampdu rcv size to 64k for all 11n devices except 4321A0 and 4321A1 */ - if (WLCISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2)) + if (BRCMS_ISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2)) ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K; else ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K; @@ -190,18 +176,18 @@ struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit; } - ampdu_update_max_txlen(ampdu, ampdu->dur); + brcms_c_scb_ampdu_update_max_txlen(ampdu, ampdu->dur); ampdu->mfbr = false; /* try to set ampdu to the default value */ - wlc_ampdu_set(ampdu, wlc->pub->_ampdu); + brcms_c_ampdu_set(ampdu, wlc->pub->_ampdu); ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL; - wlc_ffpld_init(ampdu); + brcms_c_ffpld_init(ampdu); return ampdu; } -void wlc_ampdu_detach(struct ampdu_info *ampdu) +void brcms_c_ampdu_detach(struct ampdu_info *ampdu) { int i; @@ -213,13 +199,14 @@ void wlc_ampdu_detach(struct ampdu_info *ampdu) kfree(ampdu->ini_free[i]); } - wlc_module_unregister(ampdu->wlc->pub, "ampdu", ampdu); + brcms_c_module_unregister(ampdu->wlc->pub, "ampdu", ampdu); kfree(ampdu); } -static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb) +static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu, + struct scb *scb) { - scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); + struct scb_ampdu *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); int i; scb_ampdu->max_pdu = (u8) ampdu->wlc->pub->tunables->ampdunummpdu; @@ -236,24 +223,24 @@ static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb) scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu, AMPDU_SCB_MAX_RELEASE); - if (scb_ampdu->max_rxlen) - scb_ampdu->release = - min_t(u8, scb_ampdu->release, scb_ampdu->max_rxlen / 1600); + if (scb_ampdu->max_rx_ampdu_bytes) + scb_ampdu->release = min_t(u8, scb_ampdu->release, + scb_ampdu->max_rx_ampdu_bytes / 1600); scb_ampdu->release = min(scb_ampdu->release, ampdu->fifo_tb[TX_AC_BE_FIFO]. mcs2ampdu_table[FFPLD_MAX_MCS]); } -static void scb_ampdu_update_config_all(struct ampdu_info *ampdu) +static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu) { - scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb); + brcms_c_scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb); } -static void wlc_ffpld_init(struct ampdu_info *ampdu) +static void brcms_c_ffpld_init(struct ampdu_info *ampdu) { int i, j; - wlc_fifo_info_t *fifo; + struct brcms_fifo_info *fifo; for (j = 0; j < NUM_FFPLD_FIFO; j++) { fifo = (ampdu->fifo_tb + j); @@ -274,7 +261,7 @@ static void wlc_ffpld_init(struct ampdu_info *ampdu) * Return 1 if pre-loading not active, -1 if not an underflow event, * 0 if pre-loading module took care of the event. */ -static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) +static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) { struct ampdu_info *ampdu = wlc->ampdu; u32 phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false); @@ -283,14 +270,14 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) u32 current_ampdu_cnt = 0; u16 max_pld_size; u32 new_txunfl; - wlc_fifo_info_t *fifo = (ampdu->fifo_tb + fid); + struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid); uint xmtfifo_sz; u16 cur_txunfl; /* return if we got here for a different reason than underflows */ - cur_txunfl = - wlc_read_shm(wlc, - M_UCODE_MACSTAT + offsetof(macstat_t, txfunfl[fid])); + cur_txunfl = brcms_c_read_shm(wlc, + M_UCODE_MACSTAT + + offsetof(struct macstat, txfunfl[fid])); new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); if (new_txunfl == 0) { BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n"); @@ -302,9 +289,8 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) return 1; /* check if fifo is big enough */ - if (wlc_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) { + if (brcms_c_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) return -1; - } if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd) return 1; @@ -356,7 +342,7 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) fifo->ampdu_pld_size = max_pld_size; /* update scb release size */ - scb_ampdu_update_config_all(ampdu); + brcms_c_scb_ampdu_update_config_all(ampdu); /* compute a new dma xfer rate for max_mpdu @ max mcs. @@ -383,22 +369,22 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1; /* recompute the table */ - wlc_ffpld_calc_mcs2ampdu_table(ampdu, fid); + brcms_c_ffpld_calc_mcs2ampdu_table(ampdu, fid); /* update scb release size */ - scb_ampdu_update_config_all(ampdu); + brcms_c_scb_ampdu_update_config_all(ampdu); } } fifo->accum_txfunfl = 0; return 0; } -static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f) +static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f) { int i; u32 phy_rate, dma_rate, tmp; u8 max_mpdu; - wlc_fifo_info_t *fifo = (ampdu->fifo_tb + f); + struct brcms_fifo_info *fifo = (ampdu->fifo_tb + f); /* recompute the dma rate */ /* note : we divide/multiply by 100 to avoid integer overflows */ @@ -425,47 +411,53 @@ static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f) } } -static void -wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, - uint prec) +void +brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, + u8 ba_wsize, /* negotiated ba window size (in pdu) */ + uint max_rx_ampdu_bytes) /* from ht_cap in beacon */ { - scb_ampdu_t *scb_ampdu; - scb_ampdu_tid_ini_t *ini; - u8 tid = (u8) (p->priority); - + struct scb_ampdu *scb_ampdu; + struct scb_ampdu_tid_ini *ini; + struct ampdu_info *ampdu = wlc->ampdu; + struct scb *scb = wlc->pub->global_scb; scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); - /* initialize initiator on first packet; sends addba req */ - ini = SCB_AMPDU_INI(scb_ampdu, tid); - if (ini->magic != INI_MAGIC) { - ini = wlc_ampdu_init_tid_ini(ampdu, scb_ampdu, tid, false); + if (!ampdu->ini_enable[tid]) { + wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n", + __func__, tid); + return; } - return; + + ini = SCB_AMPDU_INI(scb_ampdu, tid); + ini->tid = tid; + ini->scb = scb_ampdu->scb; + ini->ba_wsize = ba_wsize; + scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes; } int -wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, +brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, struct sk_buff **pdu, int prec) { - struct wlc_info *wlc; + struct brcms_c_info *wlc; struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; u8 tid, ndelim; int err = 0; - u8 preamble_type = WLC_GF_PREAMBLE; - u8 fbr_preamble_type = WLC_GF_PREAMBLE; - u8 rts_preamble_type = WLC_LONG_PREAMBLE; - u8 rts_fbr_preamble_type = WLC_LONG_PREAMBLE; + u8 preamble_type = BRCMS_GF_PREAMBLE; + u8 fbr_preamble_type = BRCMS_GF_PREAMBLE; + u8 rts_preamble_type = BRCMS_LONG_PREAMBLE; + u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE; bool rr = true, fbr = false; uint i, count = 0, fifo, seg_cnt = 0; u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0; - u32 ampdu_len, maxlen = 0; - d11txh_t *txh = NULL; + u32 ampdu_len, max_ampdu_bytes = 0; + struct d11txh *txh = NULL; u8 *plcp; struct ieee80211_hdr *h; struct scb *scb; - scb_ampdu_t *scb_ampdu; - scb_ampdu_tid_ini_t *ini; + struct scb_ampdu *scb_ampdu; + struct scb_ampdu_tid_ini *ini; u8 mcs = 0; bool use_rts = false, use_cts = false; ratespec_t rspec = 0, rspec_fallback = 0; @@ -473,7 +465,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; struct ieee80211_rts *rts; u8 rr_retry_limit; - wlc_fifo_info_t *f; + struct brcms_fifo_info *f; bool fbr_iscck; struct ieee80211_tx_info *tx_info; u16 qlen; @@ -493,16 +485,13 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, /* Let pressure continue to build ... */ qlen = pktq_plen(&qi->q, prec); - if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) { + if (ini->tx_in_transit > 0 && + qlen < min(scb_ampdu->max_pdu, ini->ba_wsize)) { + /* Collect multiple MPDU's to be sent in the next AMPDU */ return -EBUSY; } - wlc_ampdu_agg(ampdu, scb, p, tid); - - if (wlc->block_datafifo) { - wiphy_err(wiphy, "%s: Fifo blocked\n", __func__); - return -EBUSY; - } + /* at this point we intend to transmit an AMPDU */ rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; ampdu_len = 0; dma_len = 0; @@ -513,7 +502,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, txrate = tx_info->status.rates; if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - err = wlc_prep_pdu(wlc, p, &fifo); + err = brcms_c_prep_pdu(wlc, p, &fifo); } else { wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__); *pdu = NULL; @@ -523,7 +512,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, if (err) { if (err == -EBUSY) { - wiphy_err(wiphy, "wl%d: wlc_sendampdu: " + wiphy_err(wiphy, "wl%d: sendampdu: " "prep_xdu retry; seq 0x%x\n", wlc->pub->unit, seq); *pdu = p; @@ -531,14 +520,14 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, } /* error in the packet; reject it */ - wiphy_err(wiphy, "wl%d: wlc_sendampdu: prep_xdu " + wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu " "rejected; seq 0x%x\n", wlc->pub->unit, seq); *pdu = NULL; break; } /* pkt is good to be aggregated */ - txh = (d11txh_t *) p->data; + txh = (struct d11txh *) p->data; plcp = (u8 *) (txh + 1); h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; @@ -562,8 +551,8 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, } /* extract the length info */ - len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) - : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); + len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) + : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); /* retrieve null delimiter count */ ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; @@ -598,7 +587,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, len = roundup(len, 4); ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); - dma_len += (u16) bcm_pkttotlen(p); + dma_len += (u16) brcmu_pkttotlen(p); BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d" " seg_cnt %d null delim %d\n", @@ -627,19 +616,14 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; sgi = PLCP3_ISSGI(plcp3) ? 1 : 0; mcs = plcp0 & ~MIMO_PLCP_40MHZ; - maxlen = - min(scb_ampdu->max_rxlen, + max_ampdu_bytes = + min(scb_ampdu->max_rx_ampdu_bytes, ampdu->max_txlen[mcs][is40][sgi]); - /* XXX Fix me to honor real max_rxlen */ - /* can fix this as soon as ampdu_action() in mac80211.h - * gets extra u8buf_size par */ - maxlen = 64 * 1024; - if (is40) mimo_ctlchbw = - CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC) - ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; + CHSPEC_SB_UPPER(BRCMS_BAND_PI_RADIO_CHANSPEC) + ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; /* rebuild the rspec and rspec_fallback */ rspec = RSPEC_MIMORATE; @@ -663,11 +647,11 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, if (use_rts || use_cts) { rts_rspec = - wlc_rspec_to_rts_rspec(wlc, rspec, false, - mimo_ctlchbw); + brcms_c_rspec_to_rts_rspec(wlc, + rspec, false, mimo_ctlchbw); rts_rspec_fallback = - wlc_rspec_to_rts_rspec(wlc, rspec_fallback, - false, mimo_ctlchbw); + brcms_c_rspec_to_rts_rspec(wlc, + rspec_fallback, false, mimo_ctlchbw); } } @@ -693,14 +677,12 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && ((u8) (p->priority) == tid)) { - plen = - bcm_pkttotlen(p) + AMPDU_MAX_MPDU_OVERHEAD; + plen = brcmu_pkttotlen(p) + + AMPDU_MAX_MPDU_OVERHEAD; plen = max(scb_ampdu->min_len, plen); - if ((plen + ampdu_len) > maxlen) { + if ((plen + ampdu_len) > max_ampdu_bytes) { p = NULL; - wiphy_err(wiphy, "%s: Bogus plen #1\n", - __func__); continue; } @@ -711,7 +693,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, p = NULL; continue; } - p = bcm_pktq_pdeq(&qi->q, prec); + p = brcmu_pktq_pdeq(&qi->q, prec); } else { p = NULL; } @@ -722,7 +704,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, if (count) { /* patch up the last txh */ - txh = (d11txh_t *) pkt[count - 1]->data; + txh = (struct d11txh *) pkt[count - 1]->data; mcl = le16_to_cpu(txh->MacTxControlLow); mcl &= ~TXC_AMPDU_MASK; mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); @@ -735,30 +717,31 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, /* remove the pad len from last mpdu */ fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0); - len = fbr_iscck ? WLC_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) - : WLC_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); + len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) + : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); ampdu_len -= roundup(len, 4) - len; /* patch up the first txh & plcp */ - txh = (d11txh_t *) pkt[0]->data; + txh = (struct d11txh *) pkt[0]->data; plcp = (u8 *) (txh + 1); - WLC_SET_MIMO_PLCP_LEN(plcp, ampdu_len); + BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len); /* mark plcp to indicate ampdu */ - WLC_SET_MIMO_PLCP_AMPDU(plcp); + BRCMS_SET_MIMO_PLCP_AMPDU(plcp); /* reset the mixed mode header durations */ if (txh->MModeLen) { u16 mmodelen = - wlc_calc_lsig_len(wlc, rspec, ampdu_len); + brcms_c_calc_lsig_len(wlc, rspec, ampdu_len); txh->MModeLen = cpu_to_le16(mmodelen); - preamble_type = WLC_MM_PREAMBLE; + preamble_type = BRCMS_MM_PREAMBLE; } if (txh->MModeFbrLen) { u16 mmfbrlen = - wlc_calc_lsig_len(wlc, rspec_fallback, ampdu_len); + brcms_c_calc_lsig_len(wlc, rspec_fallback, + ampdu_len); txh->MModeFbrLen = cpu_to_le16(mmfbrlen); - fbr_preamble_type = WLC_MM_PREAMBLE; + fbr_preamble_type = BRCMS_MM_PREAMBLE; } /* set the preload length */ @@ -776,19 +759,19 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, rts = (struct ieee80211_rts *)&txh->rts_frame; if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == TXC_PREAMBLE_RTS_MAIN_SHORT) - rts_preamble_type = WLC_SHORT_PREAMBLE; + rts_preamble_type = BRCMS_SHORT_PREAMBLE; if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == TXC_PREAMBLE_RTS_FB_SHORT) - rts_fbr_preamble_type = WLC_SHORT_PREAMBLE; + rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE; durid = - wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec, + brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec, rspec, rts_preamble_type, preamble_type, ampdu_len, true); rts->duration = cpu_to_le16(durid); - durid = wlc_compute_rtscts_dur(wlc, use_cts, + durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec_fallback, rspec_fallback, rts_fbr_preamble_type, @@ -805,8 +788,8 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, if (fbr) { mch |= TXC_AMPDU_FBR; txh->MacTxControlHigh = cpu_to_le16(mch); - WLC_SET_MIMO_PLCP_AMPDU(plcp); - WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); + BRCMS_SET_MIMO_PLCP_AMPDU(plcp); + BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); } BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n", @@ -819,7 +802,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, "TXFID_RATE_PROBE_MASK!?\n", __func__); } for (i = 0; i < count; i++) - wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1), + brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1), ampdu->txpkt_weight); } @@ -828,12 +811,12 @@ wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, } void -wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, - struct sk_buff *p, tx_status_t *txs) +brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, + struct sk_buff *p, struct tx_status *txs) { - scb_ampdu_t *scb_ampdu; - struct wlc_info *wlc = ampdu->wlc; - scb_ampdu_tid_ini_t *ini; + struct scb_ampdu *scb_ampdu; + struct brcms_c_info *wlc = ampdu->wlc; + struct scb_ampdu_tid_ini *ini; u32 s1 = 0, s2 = 0; struct ieee80211_tx_info *tx_info; @@ -861,31 +844,32 @@ wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, if (likely(scb)) { scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); ini = SCB_AMPDU_INI(scb_ampdu, p->priority); - wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); + brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); } else { /* loop through all pkts and free */ u8 queue = txs->frameid & TXFID_QUEUE_MASK; - d11txh_t *txh; + struct d11txh *txh; u16 mcl; while (p) { tx_info = IEEE80211_SKB_CB(p); - txh = (d11txh_t *) p->data; + txh = (struct d11txh *) p->data; mcl = le16_to_cpu(txh->MacTxControlLow); - bcm_pkt_buf_free_skb(p); + brcmu_pkt_buf_free_skb(p); /* break out if last packet of ampdu */ if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) == TXC_AMPDU_LAST) break; p = GETNEXTTXP(wlc, queue); } - wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight); + brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight); } - wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini); + brcms_c_ampdu_txflowcontrol(wlc, scb_ampdu, ini); } static void -rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info, - tx_status_t *txs, u8 mcs) +brcms_c_ampdu_rate_status(struct brcms_c_info *wlc, + struct ieee80211_tx_info *tx_info, + struct tx_status *txs, u8 mcs) { struct ieee80211_tx_rate *txrate = tx_info->status.rates; int i; @@ -900,15 +884,15 @@ rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info, #define SHORTNAME "AMPDU status" static void -wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, - struct sk_buff *p, tx_status_t *txs, +brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, + struct sk_buff *p, struct tx_status *txs, u32 s1, u32 s2) { - scb_ampdu_t *scb_ampdu; - struct wlc_info *wlc = ampdu->wlc; - scb_ampdu_tid_ini_t *ini; + struct scb_ampdu *scb_ampdu; + struct brcms_c_info *wlc = ampdu->wlc; + struct scb_ampdu_tid_ini *ini; u8 bitmap[8], queue, tid; - d11txh_t *txh; + struct d11txh *txh; u8 *plcp; struct ieee80211_hdr *h; u16 seq, start_seq = 0, bindex, index, mcl; @@ -974,9 +958,9 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, wlc->default_bss->chanspec)); } else { if (supr_status != TX_STATUS_SUPR_FRAG) - wiphy_err(wiphy, "%s: wlc_ampdu_dotx" - "status:supr_status 0x%x\n", - __func__, supr_status); + wiphy_err(wiphy, "%s:" + "supr_status 0x%x\n", + __func__, supr_status); } /* no need to retry for badch; will fail again */ if (supr_status == TX_STATUS_SUPR_BADCH || @@ -988,29 +972,29 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, /* if there were underflows, but pre-loading is not active, notify rate adaptation. */ - if (wlc_ffpld_check_txfunfl(wlc, prio2fifo[tid]) - > 0) { + if (brcms_c_ffpld_check_txfunfl(wlc, + prio2fifo[tid]) > 0) { tx_error = true; } } } else if (txs->phyerr) { update_rate = false; - wiphy_err(wiphy, "wl%d: wlc_ampdu_dotxstatus: tx phy " + wiphy_err(wiphy, "wl%d: ampdu tx phy " "error (0x%x)\n", wlc->pub->unit, txs->phyerr); if (WL_ERROR_ON()) { - bcm_prpkt("txpkt (AMPDU)", p); - wlc_print_txdesc((d11txh_t *) p->data); + brcmu_prpkt("txpkt (AMPDU)", p); + brcms_c_print_txdesc((struct d11txh *) p->data); } - wlc_print_txstatus(txs); + brcms_c_print_txstatus(txs); } } /* loop through all pkts and retry if not acked */ while (p) { tx_info = IEEE80211_SKB_CB(p); - txh = (d11txh_t *) p->data; + txh = (struct d11txh *) p->data; mcl = le16_to_cpu(txh->MacTxControlLow); plcp = (u8 *) (txh + 1); h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); @@ -1037,7 +1021,8 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, /* ampdu_ack_len: number of acked aggregated frames */ /* ampdu_len: number of aggregated frames */ - rate_status(wlc, tx_info, txs, mcs); + brcms_c_ampdu_rate_status(wlc, tx_info, txs, + mcs); tx_info->flags |= IEEE80211_TX_STAT_ACK; tx_info->flags |= IEEE80211_TX_STAT_AMPDU; tx_info->status.ampdu_ack_len = @@ -1060,9 +1045,10 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ini->txretry[index]++; ini->tx_in_transit--; /* Use high prededence for retransmit to give some punch */ - /* wlc_txq_enq(wlc, scb, p, WLC_PRIO_TO_PREC(tid)); */ - wlc_txq_enq(wlc, scb, p, - WLC_PRIO_TO_HI_PREC(tid)); + /* brcms_c_txq_enq(wlc, scb, p, + * BRCMS_PRIO_TO_PREC(tid)); */ + brcms_c_txq_enq(wlc, scb, p, + BRCMS_PRIO_TO_HI_PREC(tid)); } else { /* Retry timeout */ ini->tx_in_transit--; @@ -1089,38 +1075,17 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, p = GETNEXTTXP(wlc, queue); } - wlc_send_q(wlc); + brcms_c_send_q(wlc); /* update rate state */ - antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel); + antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel); - wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight); + brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight); } -/* initialize the initiator code for tid */ -static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, - scb_ampdu_t *scb_ampdu, - u8 tid, bool override) +static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on) { - scb_ampdu_tid_ini_t *ini; - - /* check for per-tid control of ampdu */ - if (!ampdu->ini_enable[tid]) { - wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n", - __func__, tid); - return NULL; - } - - ini = SCB_AMPDU_INI(scb_ampdu, tid); - ini->tid = tid; - ini->scb = scb_ampdu->scb; - ini->magic = INI_MAGIC; - return ini; -} - -static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) -{ - struct wlc_info *wlc = ampdu->wlc; + struct brcms_c_info *wlc = ampdu->wlc; wlc->pub->_ampdu = false; @@ -1130,7 +1095,7 @@ static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) "nmode enabled\n", wlc->pub->unit); return -ENOTSUPP; } - if (!wlc_ampdu_cap(ampdu)) { + if (!brcms_c_ampdu_cap(ampdu)) { wiphy_err(ampdu->wlc->wiphy, "wl%d: device not " "ampdu capable\n", wlc->pub->unit); return -ENOTSUPP; @@ -1141,15 +1106,15 @@ static int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) return 0; } -static bool wlc_ampdu_cap(struct ampdu_info *ampdu) +static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu) { - if (WLC_PHY_11N_CAP(ampdu->wlc->band)) + if (BRCMS_PHY_11N_CAP(ampdu->wlc->band)) return true; else return false; } -static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur) +static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur) { u32 rate, mcs; @@ -1170,34 +1135,35 @@ static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur) } } -void wlc_ampdu_macaddr_upd(struct wlc_info *wlc) +void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc) { char template[T_RAM_ACCESS_SZ * 2]; /* driver needs to write the ta in the template; ta is at offset 16 */ memset(template, 0, sizeof(template)); memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN); - wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2), - template); + brcms_c_write_template_ram(wlc, (T_BA_TPL_BASE + 16), + (T_RAM_ACCESS_SZ * 2), + template); } -bool wlc_aggregatable(struct wlc_info *wlc, u8 tid) +bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid) { return wlc->ampdu->ini_enable[tid]; } -void wlc_ampdu_shm_upd(struct ampdu_info *ampdu) +void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu) { - struct wlc_info *wlc = ampdu->wlc; + struct brcms_c_info *wlc = ampdu->wlc; /* Extend ucode internal watchdog timer to match larger received frames */ if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) == IEEE80211_HT_MAX_AMPDU_64K) { - wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX); - wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX); + brcms_c_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX); + brcms_c_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX); } else { - wlc_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF); - wlc_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF); + brcms_c_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF); + brcms_c_write_shm(wlc, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF); } } @@ -1235,10 +1201,10 @@ static void dma_cb_fn_ampdu(void *txi, void *arg_a) * When a remote party is no longer available for ampdu communication, any * pending tx ampdu packets in the driver have to be flushed. */ -void wlc_ampdu_flush(struct wlc_info *wlc, +void brcms_c_ampdu_flush(struct brcms_c_info *wlc, struct ieee80211_sta *sta, u16 tid) { - struct wlc_txq_info *qi = wlc->pkt_queue; + struct brcms_txq_info *qi = wlc->pkt_queue; struct pktq *pq = &qi->q; int prec; struct cb_del_ampdu_pars ampdu_pars; @@ -1246,8 +1212,8 @@ void wlc_ampdu_flush(struct wlc_info *wlc, ampdu_pars.sta = sta; ampdu_pars.tid = tid; for (prec = 0; prec < pq->num_prec; prec++) { - bcm_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, + brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, (void *)&du_pars); } - wlc_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu); + brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_types.h b/drivers/staging/brcm80211/brcmsmac/ampdu.h similarity index 56% rename from drivers/staging/brcm80211/brcmsmac/wlc_types.h rename to drivers/staging/brcm80211/brcmsmac/ampdu.h index df6e04c6ac58..421f4ba7c63c 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_types.h +++ b/drivers/staging/brcm80211/brcmsmac/ampdu.h @@ -14,24 +14,17 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_types_h_ -#define _wlc_types_h_ +#ifndef _BRCM_AMPDU_H_ +#define _BRCM_AMPDU_H_ -/* forward declarations */ +extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc); +extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu); +extern int brcms_c_sendampdu(struct ampdu_info *ampdu, + struct brcms_txq_info *qi, + struct sk_buff **aggp, int prec); +extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, + struct sk_buff *p, struct tx_status *txs); +extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc); +extern void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu); -struct wlc_info; -struct wlc_hw_info; -struct wlc_if; -struct wl_if; -struct ampdu_info; -struct antsel_info; -struct bmac_pmq; - -struct d11init; - -#ifndef _hnddma_pub_ -#define _hnddma_pub_ -struct hnddma_pub; -#endif /* _hnddma_pub_ */ - -#endif /* _wlc_types_h_ */ +#endif /* _BRCM_AMPDU_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c b/drivers/staging/brcm80211/brcmsmac/antsel.c similarity index 73% rename from drivers/staging/brcm80211/brcmsmac/wlc_antsel.c rename to drivers/staging/brcm80211/brcmsmac/antsel.c index 111ef32b7ac4..c4e76c093ae9 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/antsel.c @@ -14,40 +14,29 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include +#include -#include -#include -#include +#include "types.h" +#include "bmac.h" +#include "main.h" +#include "phy_shim.h" +#include "antsel.h" -#include -#include -#include -#include -#include -#include -#include - -#include "d11.h" -#include "wlc_rate.h" -#include "wlc_key.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wl_dbg.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_bmac.h" -#include "wlc_channel.h" -#include "wlc_main.h" -#include "wl_export.h" -#include "wlc_phy_shim.h" -#include "wlc_antsel.h" +#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ +#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ +#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */ +#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */ +#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */ +#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */ /* useful macros */ -#define WLC_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf) -#define WLC_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf) -#define WLC_ANTIDX_11N(ant) (((WLC_ANTSEL_11N_0(ant)) << 2) + (WLC_ANTSEL_11N_1(ant))) -#define WLC_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) -#define WLC_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK) +#define BRCMS_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf) +#define BRCMS_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf) +#define BRCMS_ANTIDX_11N(ant) (((BRCMS_ANTSEL_11N_0(ant)) << 2) +\ + (BRCMS_ANTSEL_11N_1(ant))) +#define BRCMS_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) +#define BRCMS_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK) /* antenna switch */ /* defines for no boardlevel antenna diversity */ @@ -62,11 +51,12 @@ #define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */ /* static functions */ -static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel); -static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id); -static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg); -static void wlc_antsel_init_cfg(struct antsel_info *asi, - wlc_antselcfg_t *antsel, +static int brcms_c_antsel_cfgupd(struct antsel_info *asi, + struct brcms_antselcfg *antsel); +static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id); +static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg); +static void brcms_c_antsel_init_cfg(struct antsel_info *asi, + struct brcms_antselcfg *antsel, bool auto_sel); const u16 mimo_2x4_div_antselpat_tbl[] = { @@ -93,14 +83,14 @@ const u8 mimo_2x3_div_antselid_tbl[16] = { 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */ }; -struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc) +struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) { struct antsel_info *asi; asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); if (!asi) { - wiphy_err(wlc->wiphy, "wl%d: wlc_antsel_attach: out of mem\n", - wlc->pub->unit); + wiphy_err(wlc->wiphy, "wl%d: brcms_c_antsel_attach: out of " + "mem\n", wlc->pub->unit); return NULL; } @@ -129,7 +119,7 @@ struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc) asi->antsel_avail = false; } else { asi->antsel_avail = false; - wiphy_err(wlc->wiphy, "wlc_antsel_attach: 2o3 " + wiphy_err(wlc->wiphy, "antsel_attach: 2o3 " "board cfg invalid\n"); } break; @@ -148,30 +138,30 @@ struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc) } /* Set the antenna selection type for the low driver */ - wlc_bmac_antsel_type_set(wlc->hw, asi->antsel_type); + brcms_b_antsel_type_set(wlc->hw, asi->antsel_type); /* Init (auto/manual) antenna selection */ - wlc_antsel_init_cfg(asi, &asi->antcfg_11n, true); - wlc_antsel_init_cfg(asi, &asi->antcfg_cur, true); + brcms_c_antsel_init_cfg(asi, &asi->antcfg_11n, true); + brcms_c_antsel_init_cfg(asi, &asi->antcfg_cur, true); return asi; } -void wlc_antsel_detach(struct antsel_info *asi) +void brcms_c_antsel_detach(struct antsel_info *asi) { kfree(asi); } -void wlc_antsel_init(struct antsel_info *asi) +void brcms_c_antsel_init(struct antsel_info *asi) { if ((asi->antsel_type == ANTSEL_2x3) || (asi->antsel_type == ANTSEL_2x4)) - wlc_antsel_cfgupd(asi, &asi->antcfg_11n); + brcms_c_antsel_cfgupd(asi, &asi->antcfg_11n); } /* boardlevel antenna selection: init antenna selection structure */ static void -wlc_antsel_init_cfg(struct antsel_info *asi, wlc_antselcfg_t *antsel, +brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel, bool auto_sel) { if (asi->antsel_type == ANTSEL_2x3) { @@ -202,7 +192,7 @@ wlc_antsel_init_cfg(struct antsel_info *asi, wlc_antselcfg_t *antsel, } void -wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, +brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, u8 antselid, u8 fbantselid, u8 *antcfg, u8 *fbantcfg) { @@ -222,8 +212,8 @@ wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, } else { ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) { - *antcfg = wlc_antsel_id2antcfg(asi, antselid); - *fbantcfg = wlc_antsel_id2antcfg(asi, fbantselid); + *antcfg = brcms_c_antsel_id2antcfg(asi, antselid); + *fbantcfg = brcms_c_antsel_id2antcfg(asi, fbantselid); } else { *antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST]; @@ -234,7 +224,7 @@ wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, } /* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */ -u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel) +u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel) { u8 antselid = 0; @@ -253,7 +243,7 @@ u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel) } /* boardlevel antenna selection: convert id to ant_cfg */ -static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id) +static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id) { u8 antcfg = ANT_SELCFG_DEF_2x2; @@ -272,9 +262,9 @@ static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id) } /* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */ -static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg) +static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg) { - u8 idx = WLC_ANTIDX_11N(WLC_ANTSEL_11N(ant_cfg)); + u8 idx = BRCMS_ANTIDX_11N(BRCMS_ANTSEL_11N(ant_cfg)); u16 mimo_antsel = 0; if (asi->antsel_type == ANTSEL_2x4) { @@ -292,9 +282,10 @@ static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg) } /* boardlevel antenna selection: ucode interface control */ -static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel) +static int brcms_c_antsel_cfgupd(struct antsel_info *asi, + struct brcms_antselcfg *antsel) { - struct wlc_info *wlc = asi->wlc; + struct brcms_c_info *wlc = asi->wlc; u8 ant_cfg; u16 mimo_antsel; @@ -302,8 +293,8 @@ static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel) * (aka default TX) */ ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF]; - mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg); - wlc_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel); + mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg); + brcms_c_write_shm(wlc, M_MIMO_ANTSEL_TXDFLT, mimo_antsel); /* Update driver stats for currently selected default tx/rx antenna config */ asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg; @@ -311,8 +302,8 @@ static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel) * (aka default RX) */ ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF]; - mimo_antsel = wlc_antsel_antcfg2antsel(asi, ant_cfg); - wlc_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel); + mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg); + brcms_c_write_shm(wlc, M_MIMO_ANTSEL_RXDFLT, mimo_antsel); /* Update driver stats for currently selected default tx/rx antenna config */ asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg; diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h b/drivers/staging/brcm80211/brcmsmac/antsel.h similarity index 67% rename from drivers/staging/brcm80211/brcmsmac/wlc_antsel.h rename to drivers/staging/brcm80211/brcmsmac/antsel.h index 2470c73fc4ed..97ea3881a8ec 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_antsel.h +++ b/drivers/staging/brcm80211/brcmsmac/antsel.h @@ -14,16 +14,16 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_antsel_h_ -#define _wlc_antsel_h_ +#ifndef _BRCM_ANTSEL_H_ +#define _BRCM_ANTSEL_H_ -extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc); -extern void wlc_antsel_detach(struct antsel_info *asi); -extern void wlc_antsel_init(struct antsel_info *asi); -extern void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, +extern struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc); +extern void brcms_c_antsel_detach(struct antsel_info *asi); +extern void brcms_c_antsel_init(struct antsel_info *asi); +extern void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, u8 id, u8 fbid, u8 *antcfg, u8 *fbantcfg); -extern u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel); +extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel); -#endif /* _wlc_antsel_h_ */ +#endif /* _BRCM_ANTSEL_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/bcmotp.c b/drivers/staging/brcm80211/brcmsmac/bcmotp.c deleted file mode 100644 index d09628b5a88e..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/bcmotp.c +++ /dev/null @@ -1,936 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* - * There are two different OTP controllers so far: - * 1. new IPX OTP controller: chipc 21, >=23 - * 2. older HND OTP controller: chipc 12, 17, 22 - * - * Define BCMHNDOTP to include support for the HND OTP controller. - * Define BCMIPXOTP to include support for the IPX OTP controller. - * - * NOTE 1: More than one may be defined - * NOTE 2: If none are defined, the default is to include them all. - */ - -#if !defined(BCMHNDOTP) && !defined(BCMIPXOTP) -#define BCMHNDOTP 1 -#define BCMIPXOTP 1 -#endif - -#define OTPTYPE_HND(ccrev) ((ccrev) < 21 || (ccrev) == 22) -#define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23) - -#define OTPP_TRIES 10000000 /* # of tries for OTPP */ - -#ifdef BCMIPXOTP -#define MAXNUMRDES 9 /* Maximum OTP redundancy entries */ -#endif - -/* OTP common function type */ -typedef int (*otp_status_t) (void *oh); -typedef int (*otp_size_t) (void *oh); -typedef void *(*otp_init_t) (si_t *sih); -typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off); -typedef int (*otp_read_region_t) (si_t *sih, int region, u16 *data, - uint *wlen); -typedef int (*otp_nvread_t) (void *oh, char *data, uint *len); - -/* OTP function struct */ -typedef struct otp_fn_s { - otp_size_t size; - otp_read_bit_t read_bit; - otp_init_t init; - otp_read_region_t read_region; - otp_nvread_t nvread; - otp_status_t status; -} otp_fn_t; - -typedef struct { - uint ccrev; /* chipc revision */ - otp_fn_t *fn; /* OTP functions */ - si_t *sih; /* Saved sb handle */ - -#ifdef BCMIPXOTP - /* IPX OTP section */ - u16 wsize; /* Size of otp in words */ - u16 rows; /* Geometry */ - u16 cols; /* Geometry */ - u32 status; /* Flag bits (lock/prog/rv). - * (Reflected only when OTP is power cycled) - */ - u16 hwbase; /* hardware subregion offset */ - u16 hwlim; /* hardware subregion boundary */ - u16 swbase; /* software subregion offset */ - u16 swlim; /* software subregion boundary */ - u16 fbase; /* fuse subregion offset */ - u16 flim; /* fuse subregion boundary */ - int otpgu_base; /* offset to General Use Region */ -#endif /* BCMIPXOTP */ - -#ifdef BCMHNDOTP - /* HND OTP section */ - uint size; /* Size of otp in bytes */ - uint hwprot; /* Hardware protection bits */ - uint signvalid; /* Signature valid bits */ - int boundary; /* hw/sw boundary */ -#endif /* BCMHNDOTP */ -} otpinfo_t; - -static otpinfo_t otpinfo; - -/* - * IPX OTP Code - * - * Exported functions: - * ipxotp_status() - * ipxotp_size() - * ipxotp_init() - * ipxotp_read_bit() - * ipxotp_read_region() - * ipxotp_nvread() - * - */ - -#ifdef BCMIPXOTP - -#define HWSW_RGN(rgn) (((rgn) == OTP_HW_RGN) ? "h/w" : "s/w") - -/* OTP layout */ -/* CC revs 21, 24 and 27 OTP General Use Region word offset */ -#define REVA4_OTPGU_BASE 12 - -/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */ -#define REVB8_OTPGU_BASE 20 - -/* CC rev 36 OTP General Use Region word offset */ -#define REV36_OTPGU_BASE 12 - -/* Subregion word offsets in General Use region */ -#define OTPGU_HSB_OFF 0 -#define OTPGU_SFB_OFF 1 -#define OTPGU_CI_OFF 2 -#define OTPGU_P_OFF 3 -#define OTPGU_SROM_OFF 4 - -/* Flag bit offsets in General Use region */ -#define OTPGU_HWP_OFF 60 -#define OTPGU_SWP_OFF 61 -#define OTPGU_CIP_OFF 62 -#define OTPGU_FUSEP_OFF 63 -#define OTPGU_CIP_MSK 0x4000 -#define OTPGU_P_MSK 0xf000 -#define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16) - -/* OTP Size */ -#define OTP_SZ_FU_324 ((roundup(324, 8))/8) /* 324 bits */ -#define OTP_SZ_FU_288 (288/8) /* 288 bits */ -#define OTP_SZ_FU_216 (216/8) /* 216 bits */ -#define OTP_SZ_FU_72 (72/8) /* 72 bits */ -#define OTP_SZ_CHECKSUM (16/8) /* 16 bits */ -#define OTP4315_SWREG_SZ 178 /* 178 bytes */ -#define OTP_SZ_FU_144 (144/8) /* 144 bits */ - -static int ipxotp_status(void *oh) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - return (int)(oi->status); -} - -/* Return size in bytes */ -static int ipxotp_size(void *oh) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - return (int)oi->wsize * 2; -} - -static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn) -{ - otpinfo_t *oi; - - oi = (otpinfo_t *) oh; - - return R_REG(&cc->sromotp[wn]); -} - -static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - uint k, row, col; - u32 otpp, st; - - row = off / oi->cols; - col = off % oi->cols; - - otpp = OTPP_START_BUSY | - ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) | - ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | - ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK); - W_REG(&cc->otpprog, otpp); - - for (k = 0; - ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY) - && (k < OTPP_TRIES); k++) - ; - if (k >= OTPP_TRIES) { - return 0xffff; - } - if (st & OTPP_READERR) { - return 0xffff; - } - st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT; - - return (int)st; -} - -/* Calculate max HW/SW region byte size by subtracting fuse region and checksum size, - * osizew is oi->wsize (OTP size - GU size) in words - */ -static int ipxotp_max_rgnsz(si_t *sih, int osizew) -{ - int ret = 0; - - switch (sih->chip) { - case BCM43224_CHIP_ID: - case BCM43225_CHIP_ID: - ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM; - break; - case BCM4313_CHIP_ID: - ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM; - break; - default: - break; /* Don't know about this chip */ - } - - return ret; -} - -static void _ipxotp_init(otpinfo_t *oi, chipcregs_t *cc) -{ - uint k; - u32 otpp, st; - - /* record word offset of General Use Region for various chipcommon revs */ - if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24 - || oi->sih->ccrev == 27) { - oi->otpgu_base = REVA4_OTPGU_BASE; - } else if (oi->sih->ccrev == 36) { - /* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */ - if (oi->wsize >= 128) - oi->otpgu_base = REVB8_OTPGU_BASE; - else - oi->otpgu_base = REV36_OTPGU_BASE; - } else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) { - oi->otpgu_base = REVB8_OTPGU_BASE; - } - - /* First issue an init command so the status is up to date */ - otpp = - OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK); - - W_REG(&cc->otpprog, otpp); - for (k = 0; - ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY) - && (k < OTPP_TRIES); k++) - ; - if (k >= OTPP_TRIES) { - return; - } - - /* Read OTP lock bits and subregion programmed indication bits */ - oi->status = R_REG(&cc->otpstatus); - - if ((oi->sih->chip == BCM43224_CHIP_ID) - || (oi->sih->chip == BCM43225_CHIP_ID)) { - u32 p_bits; - p_bits = - (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) & - OTPGU_P_MSK) - >> OTPGU_P_SHIFT; - oi->status |= (p_bits << OTPS_GUP_SHIFT); - } - - /* - * h/w region base and fuse region limit are fixed to the top and - * the bottom of the general use region. Everything else can be flexible. - */ - oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF; - oi->hwlim = oi->wsize; - if (oi->status & OTPS_GUP_HW) { - oi->hwlim = - ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16; - oi->swbase = oi->hwlim; - } else - oi->swbase = oi->hwbase; - - /* subtract fuse and checksum from beginning */ - oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2; - - if (oi->status & OTPS_GUP_SW) { - oi->swlim = - ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16; - oi->fbase = oi->swlim; - } else - oi->fbase = oi->swbase; - - oi->flim = oi->wsize; -} - -static void *ipxotp_init(si_t *sih) -{ - uint idx; - chipcregs_t *cc; - otpinfo_t *oi; - - /* Make sure we're running IPX OTP */ - if (!OTPTYPE_IPX(sih->ccrev)) - return NULL; - - /* Make sure OTP is not disabled */ - if (ai_is_otp_disabled(sih)) - return NULL; - - /* Make sure OTP is powered up */ - if (!ai_is_otp_powered(sih)) - return NULL; - - oi = &otpinfo; - - /* Check for otp size */ - switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) { - case 0: - /* Nothing there */ - return NULL; - case 1: /* 32x64 */ - oi->rows = 32; - oi->cols = 64; - oi->wsize = 128; - break; - case 2: /* 64x64 */ - oi->rows = 64; - oi->cols = 64; - oi->wsize = 256; - break; - case 5: /* 96x64 */ - oi->rows = 96; - oi->cols = 64; - oi->wsize = 384; - break; - case 7: /* 16x64 *//* 1024 bits */ - oi->rows = 16; - oi->cols = 64; - oi->wsize = 64; - break; - default: - /* Don't know the geometry */ - return NULL; - } - - /* Retrieve OTP region info */ - idx = ai_coreidx(sih); - cc = ai_setcoreidx(sih, SI_CC_IDX); - - _ipxotp_init(oi, cc); - - ai_setcoreidx(sih, idx); - - return (void *)oi; -} - -static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - uint idx; - chipcregs_t *cc; - uint base, i, sz; - - /* Validate region selection */ - switch (region) { - case OTP_HW_RGN: - sz = (uint) oi->hwlim - oi->hwbase; - if (!(oi->status & OTPS_GUP_HW)) { - *wlen = sz; - return -ENODATA; - } - if (*wlen < sz) { - *wlen = sz; - return -EOVERFLOW; - } - base = oi->hwbase; - break; - case OTP_SW_RGN: - sz = ((uint) oi->swlim - oi->swbase); - if (!(oi->status & OTPS_GUP_SW)) { - *wlen = sz; - return -ENODATA; - } - if (*wlen < sz) { - *wlen = sz; - return -EOVERFLOW; - } - base = oi->swbase; - break; - case OTP_CI_RGN: - sz = OTPGU_CI_SZ; - if (!(oi->status & OTPS_GUP_CI)) { - *wlen = sz; - return -ENODATA; - } - if (*wlen < sz) { - *wlen = sz; - return -EOVERFLOW; - } - base = oi->otpgu_base + OTPGU_CI_OFF; - break; - case OTP_FUSE_RGN: - sz = (uint) oi->flim - oi->fbase; - if (!(oi->status & OTPS_GUP_FUSE)) { - *wlen = sz; - return -ENODATA; - } - if (*wlen < sz) { - *wlen = sz; - return -EOVERFLOW; - } - base = oi->fbase; - break; - case OTP_ALL_RGN: - sz = ((uint) oi->flim - oi->hwbase); - if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) { - *wlen = sz; - return -ENODATA; - } - if (*wlen < sz) { - *wlen = sz; - return -EOVERFLOW; - } - base = oi->hwbase; - break; - default: - return -EINVAL; - } - - idx = ai_coreidx(oi->sih); - cc = ai_setcoreidx(oi->sih, SI_CC_IDX); - - /* Read the data */ - for (i = 0; i < sz; i++) - data[i] = ipxotp_otpr(oh, cc, base + i); - - ai_setcoreidx(oi->sih, idx); - *wlen = sz; - return 0; -} - -static int ipxotp_nvread(void *oh, char *data, uint *len) -{ - return -ENOTSUPP; -} - -static otp_fn_t ipxotp_fn = { - (otp_size_t) ipxotp_size, - (otp_read_bit_t) ipxotp_read_bit, - - (otp_init_t) ipxotp_init, - (otp_read_region_t) ipxotp_read_region, - (otp_nvread_t) ipxotp_nvread, - - (otp_status_t) ipxotp_status -}; - -#endif /* BCMIPXOTP */ - -/* - * HND OTP Code - * - * Exported functions: - * hndotp_status() - * hndotp_size() - * hndotp_init() - * hndotp_read_bit() - * hndotp_read_region() - * hndotp_nvread() - * - */ - -#ifdef BCMHNDOTP - -/* Fields in otpstatus */ -#define OTPS_PROGFAIL 0x80000000 -#define OTPS_PROTECT 0x00000007 -#define OTPS_HW_PROTECT 0x00000001 -#define OTPS_SW_PROTECT 0x00000002 -#define OTPS_CID_PROTECT 0x00000004 -#define OTPS_RCEV_MSK 0x00003f00 -#define OTPS_RCEV_SHIFT 8 - -/* Fields in the otpcontrol register */ -#define OTPC_RECWAIT 0xff000000 -#define OTPC_PROGWAIT 0x00ffff00 -#define OTPC_PRW_SHIFT 8 -#define OTPC_MAXFAIL 0x00000038 -#define OTPC_VSEL 0x00000006 -#define OTPC_SELVL 0x00000001 - -/* OTP regions (Word offsets from otp size) */ -#define OTP_SWLIM_OFF (-4) -#define OTP_CIDBASE_OFF 0 -#define OTP_CIDLIM_OFF 4 - -/* Predefined OTP words (Word offset from otp size) */ -#define OTP_BOUNDARY_OFF (-4) -#define OTP_HWSIGN_OFF (-3) -#define OTP_SWSIGN_OFF (-2) -#define OTP_CIDSIGN_OFF (-1) -#define OTP_CID_OFF 0 -#define OTP_PKG_OFF 1 -#define OTP_FID_OFF 2 -#define OTP_RSV_OFF 3 -#define OTP_LIM_OFF 4 -#define OTP_RD_OFF 4 /* Redundancy row starts here */ -#define OTP_RC0_OFF 28 /* Redundancy control word 1 */ -#define OTP_RC1_OFF 32 /* Redundancy control word 2 */ -#define OTP_RC_LIM_OFF 36 /* Redundancy control word end */ - -#define OTP_HW_REGION OTPS_HW_PROTECT -#define OTP_SW_REGION OTPS_SW_PROTECT -#define OTP_CID_REGION OTPS_CID_PROTECT - -#if OTP_HW_REGION != OTP_HW_RGN -#error "incompatible OTP_HW_RGN" -#endif -#if OTP_SW_REGION != OTP_SW_RGN -#error "incompatible OTP_SW_RGN" -#endif -#if OTP_CID_REGION != OTP_CI_RGN -#error "incompatible OTP_CI_RGN" -#endif - -/* Redundancy entry definitions */ -#define OTP_RCE_ROW_SZ 6 -#define OTP_RCE_SIGN_MASK 0x7fff -#define OTP_RCE_ROW_MASK 0x3f -#define OTP_RCE_BITS 21 -#define OTP_RCE_SIGN_SZ 15 -#define OTP_RCE_BIT0 1 - -#define OTP_WPR 4 -#define OTP_SIGNATURE 0x578a -#define OTP_MAGIC 0x4e56 - -static int hndotp_status(void *oh) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - return (int)(oi->hwprot | oi->signvalid); -} - -static int hndotp_size(void *oh) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - return (int)(oi->size); -} - -static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn) -{ - volatile u16 *ptr; - - ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP); - return R_REG(&ptr[wn]); -} - -static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - volatile u16 *ptr; - - ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP); - - return R_REG(&ptr[(oi->size / 2) + woff]); -} - -static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx) -{ - uint k, row, col; - u32 otpp, st; - - row = idx / 65; - col = idx % 65; - - otpp = OTPP_START_BUSY | OTPP_READ | - ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | (col & OTPP_COL_MASK); - - W_REG(&cc->otpprog, otpp); - st = R_REG(&cc->otpprog); - for (k = 0; - ((st & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES); - k++) - st = R_REG(&cc->otpprog); - - if (k >= OTPP_TRIES) { - return 0xffff; - } - if (st & OTPP_READERR) { - return 0xffff; - } - st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT; - return (u16) st; -} - -static void *hndotp_init(si_t *sih) -{ - uint idx; - chipcregs_t *cc; - otpinfo_t *oi; - u32 cap = 0, clkdiv, otpdiv = 0; - void *ret = NULL; - - oi = &otpinfo; - - idx = ai_coreidx(sih); - - /* Check for otp */ - cc = ai_setcoreidx(sih, SI_CC_IDX); - if (cc != NULL) { - cap = R_REG(&cc->capabilities); - if ((cap & CC_CAP_OTPSIZE) == 0) { - /* Nothing there */ - goto out; - } - - if (!((oi->ccrev == 12) || (oi->ccrev == 17) - || (oi->ccrev == 22))) - return NULL; - - /* Read the OTP byte size. chipcommon rev >= 18 has RCE so the size is - * 8 row (64 bytes) smaller - */ - oi->size = - 1 << (((cap & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) - + CC_CAP_OTPSIZE_BASE); - if (oi->ccrev >= 18) - oi->size -= ((OTP_RC0_OFF - OTP_BOUNDARY_OFF) * 2); - - oi->hwprot = (int)(R_REG(&cc->otpstatus) & OTPS_PROTECT); - oi->boundary = -1; - - /* Check the region signature */ - if (hndotp_otproff(oi, cc, OTP_HWSIGN_OFF) == OTP_SIGNATURE) { - oi->signvalid |= OTP_HW_REGION; - oi->boundary = hndotp_otproff(oi, cc, OTP_BOUNDARY_OFF); - } - - if (hndotp_otproff(oi, cc, OTP_SWSIGN_OFF) == OTP_SIGNATURE) - oi->signvalid |= OTP_SW_REGION; - - if (hndotp_otproff(oi, cc, OTP_CIDSIGN_OFF) == OTP_SIGNATURE) - oi->signvalid |= OTP_CID_REGION; - - /* Set OTP clkdiv for stability */ - if (oi->ccrev == 22) - otpdiv = 12; - - if (otpdiv) { - clkdiv = R_REG(&cc->clkdiv); - clkdiv = - (clkdiv & ~CLKD_OTP) | (otpdiv << CLKD_OTP_SHIFT); - W_REG(&cc->clkdiv, clkdiv); - } - udelay(10); - - ret = (void *)oi; - } - - out: /* All done */ - ai_setcoreidx(sih, idx); - - return ret; -} - -static int hndotp_read_region(void *oh, int region, u16 *data, uint *wlen) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - u32 idx, st; - chipcregs_t *cc; - int i; - - - if (region != OTP_HW_REGION) { - /* - * Only support HW region - * (no active chips use HND OTP SW region) - * */ - return -ENOTSUPP; - } - - /* Region empty? */ - st = oi->hwprot | oi->signvalid; - if ((st & region) == 0) - return -ENODATA; - - *wlen = - ((int)*wlen < oi->boundary / 2) ? *wlen : (uint) oi->boundary / 2; - - idx = ai_coreidx(oi->sih); - cc = ai_setcoreidx(oi->sih, SI_CC_IDX); - - for (i = 0; i < (int)*wlen; i++) - data[i] = hndotp_otpr(oh, cc, i); - - ai_setcoreidx(oi->sih, idx); - - return 0; -} - -static int hndotp_nvread(void *oh, char *data, uint *len) -{ - int rc = 0; - otpinfo_t *oi = (otpinfo_t *) oh; - u32 base, bound, lim = 0, st; - int i, chunk, gchunks, tsz = 0; - u32 idx; - chipcregs_t *cc; - uint offset; - u16 *rawotp = NULL; - - /* save the orig core */ - idx = ai_coreidx(oi->sih); - cc = ai_setcoreidx(oi->sih, SI_CC_IDX); - - st = hndotp_status(oh); - if (!(st & (OTP_HW_REGION | OTP_SW_REGION))) { - rc = -1; - goto out; - } - - /* Read the whole otp so we can easily manipulate it */ - lim = hndotp_size(oh); - rawotp = kmalloc(lim, GFP_ATOMIC); - if (rawotp == NULL) { - rc = -2; - goto out; - } - for (i = 0; i < (int)(lim / 2); i++) - rawotp[i] = hndotp_otpr(oh, cc, i); - - if ((st & OTP_HW_REGION) == 0) { - /* This could be a programming failure in the first - * chunk followed by one or more good chunks - */ - for (i = 0; i < (int)(lim / 2); i++) - if (rawotp[i] == OTP_MAGIC) - break; - - if (i < (int)(lim / 2)) { - base = i; - bound = (i * 2) + rawotp[i + 1]; - } else { - rc = -3; - goto out; - } - } else { - bound = rawotp[(lim / 2) + OTP_BOUNDARY_OFF]; - - /* There are two cases: 1) The whole otp is used as nvram - * and 2) There is a hardware header followed by nvram. - */ - if (rawotp[0] == OTP_MAGIC) { - base = 0; - } else - base = bound; - } - - /* Find and copy the data */ - - chunk = 0; - gchunks = 0; - i = base / 2; - offset = 0; - while ((i < (int)(lim / 2)) && (rawotp[i] == OTP_MAGIC)) { - int dsz, rsz = rawotp[i + 1]; - - if (((i * 2) + rsz) >= (int)lim) { - /* Bad length, try to find another chunk anyway */ - rsz = 6; - } - if (crc_ccitt(CRC16_INIT_VALUE, (u8 *) &rawotp[i], rsz) == - CRC16_GOOD_VALUE) { - /* Good crc, copy the vars */ - gchunks++; - dsz = rsz - 6; - tsz += dsz; - if (offset + dsz >= *len) { - goto out; - } - memcpy(&data[offset], &rawotp[i + 2], dsz); - offset += dsz; - /* Remove extra null characters at the end */ - while (offset > 1 && - data[offset - 1] == 0 && data[offset - 2] == 0) - offset--; - i += rsz / 2; - } else { - /* bad length or crc didn't check, try to find the next set */ - if (rawotp[i + (rsz / 2)] == OTP_MAGIC) { - /* Assume length is good */ - i += rsz / 2; - } else { - while (++i < (int)(lim / 2)) - if (rawotp[i] == OTP_MAGIC) - break; - } - } - chunk++; - } - - *len = offset; - - out: - kfree(rawotp); - ai_setcoreidx(oi->sih, idx); - - return rc; -} - -static otp_fn_t hndotp_fn = { - (otp_size_t) hndotp_size, - (otp_read_bit_t) hndotp_read_bit, - - (otp_init_t) hndotp_init, - (otp_read_region_t) hndotp_read_region, - (otp_nvread_t) hndotp_nvread, - - (otp_status_t) hndotp_status -}; - -#endif /* BCMHNDOTP */ - -/* - * Common Code: Compiled for IPX / HND / AUTO - * otp_status() - * otp_size() - * otp_read_bit() - * otp_init() - * otp_read_region() - * otp_nvread() - */ - -int otp_status(void *oh) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - - return oi->fn->status(oh); -} - -int otp_size(void *oh) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - - return oi->fn->size(oh); -} - -u16 otp_read_bit(void *oh, uint offset) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - uint idx = ai_coreidx(oi->sih); - chipcregs_t *cc = ai_setcoreidx(oi->sih, SI_CC_IDX); - u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset); - ai_setcoreidx(oi->sih, idx); - return readBit; -} - -void *otp_init(si_t *sih) -{ - otpinfo_t *oi; - void *ret = NULL; - - oi = &otpinfo; - memset(oi, 0, sizeof(otpinfo_t)); - - oi->ccrev = sih->ccrev; - -#ifdef BCMIPXOTP - if (OTPTYPE_IPX(oi->ccrev)) - oi->fn = &ipxotp_fn; -#endif - -#ifdef BCMHNDOTP - if (OTPTYPE_HND(oi->ccrev)) - oi->fn = &hndotp_fn; -#endif - - if (oi->fn == NULL) { - return NULL; - } - - oi->sih = sih; - - ret = (oi->fn->init) (sih); - - return ret; -} - -int -otp_read_region(si_t *sih, int region, u16 *data, - uint *wlen) { - bool wasup = false; - void *oh; - int err = 0; - - wasup = ai_is_otp_powered(sih); - if (!wasup) - ai_otp_power(sih, true); - - if (!ai_is_otp_powered(sih) || ai_is_otp_disabled(sih)) { - err = -EPERM; - goto out; - } - - oh = otp_init(sih); - if (oh == NULL) { - err = -EBADE; - goto out; - } - - err = (((otpinfo_t *) oh)->fn->read_region) (oh, region, data, wlen); - - out: - if (!wasup) - ai_otp_power(sih, false); - - return err; -} - -int otp_nvread(void *oh, char *data, uint *len) -{ - otpinfo_t *oi = (otpinfo_t *) oh; - - return oi->fn->nvread(oh, data, len); -} diff --git a/drivers/staging/brcm80211/brcmsmac/bcmsrom.c b/drivers/staging/brcm80211/brcmsmac/bcmsrom.c deleted file mode 100644 index bbfc64204363..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/bcmsrom.c +++ /dev/null @@ -1,714 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \ - (((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \ - ((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \ - ((u8 *)curmap + PCI_BAR0_SPROM_OFFSET)) - -#if defined(BCMDBG) -#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */ -#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */ -#endif - -typedef struct varbuf { - char *base; /* pointer to buffer base */ - char *buf; /* pointer to current position */ - unsigned int size; /* current (residual) size in bytes */ -} varbuf_t; -extern char *_vars; -extern uint _varsz; - -static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *count); -static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b); -static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count); -static int initvars_flash_si(si_t *sih, char **vars, uint *count); -static int sprom_read_pci(si_t *sih, u16 *sprom, - uint wordoff, u16 *buf, uint nwords, bool check_crc); -#if defined(BCMNVRAMR) -static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz); -#endif -static u16 srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd, - uint wordoff, u16 data); - -static int initvars_table(char *start, char *end, - char **vars, uint *count); -static int initvars_flash(si_t *sih, char **vp, - uint len); - -/* Initialization of varbuf structure */ -static void varbuf_init(varbuf_t *b, char *buf, uint size) -{ - b->size = size; - b->base = b->buf = buf; -} - -/* append a null terminated var=value string */ -static int varbuf_append(varbuf_t *b, const char *fmt, ...) -{ - va_list ap; - int r; - size_t len; - char *s; - - if (b->size < 2) - return 0; - - va_start(ap, fmt); - r = vsnprintf(b->buf, b->size, fmt, ap); - va_end(ap); - - /* C99 snprintf behavior returns r >= size on overflow, - * others return -1 on overflow. - * All return -1 on format error. - * We need to leave room for 2 null terminations, one for the current var - * string, and one for final null of the var table. So check that the - * strlen written, r, leaves room for 2 chars. - */ - if ((r == -1) || (r > (int)(b->size - 2))) { - b->size = 0; - return 0; - } - - /* Remove any earlier occurrence of the same variable */ - s = strchr(b->buf, '='); - if (s != NULL) { - len = (size_t) (s - b->buf); - for (s = b->base; s < b->buf;) { - if ((memcmp(s, b->buf, len) == 0) && s[len] == '=') { - len = strlen(s) + 1; - memmove(s, (s + len), - ((b->buf + r + 1) - (s + len))); - b->buf -= len; - b->size += (unsigned int)len; - break; - } - - while (*s++) - ; - } - } - - /* skip over this string's null termination */ - r++; - b->size -= r; - b->buf += r; - - return r; -} - -/* - * Initialize local vars from the right source for this platform. - * Return 0 on success, nonzero on error. - */ -int srom_var_init(si_t *sih, uint bustype, void *curmap, - char **vars, uint *count) -{ - uint len; - - len = 0; - - if (vars == NULL || count == NULL) - return 0; - - *vars = NULL; - *count = 0; - - switch (bustype) { - case SI_BUS: - case JTAG_BUS: - return initvars_srom_si(sih, curmap, vars, count); - - case PCI_BUS: - if (curmap == NULL) - return -1; - - return initvars_srom_pci(sih, curmap, vars, count); - - default: - break; - } - return -1; -} - -/* In chips with chipcommon rev 32 and later, the srom is in chipcommon, - * not in the bus cores. - */ -static u16 -srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd, - uint wordoff, u16 data) -{ - chipcregs_t *cc = (chipcregs_t *) ccregs; - uint wait_cnt = 1000; - - if ((cmd == SRC_OP_READ) || (cmd == SRC_OP_WRITE)) { - W_REG(&cc->sromaddress, wordoff * 2); - if (cmd == SRC_OP_WRITE) - W_REG(&cc->sromdata, data); - } - - W_REG(&cc->sromcontrol, SRC_START | cmd); - - while (wait_cnt--) { - if ((R_REG(&cc->sromcontrol) & SRC_BUSY) == 0) - break; - } - - if (!wait_cnt) { - return 0xffff; - } - if (cmd == SRC_OP_READ) - return (u16) R_REG(&cc->sromdata); - else - return 0xffff; -} - -static inline void ltoh16_buf(u16 *buf, unsigned int size) -{ - for (size /= 2; size; size--) - *(buf + size) = le16_to_cpu(*(buf + size)); -} - -static inline void htol16_buf(u16 *buf, unsigned int size) -{ - for (size /= 2; size; size--) - *(buf + size) = cpu_to_le16(*(buf + size)); -} - -/* - * Read in and validate sprom. - * Return 0 on success, nonzero on error. - */ -static int -sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff, - u16 *buf, uint nwords, bool check_crc) -{ - int err = 0; - uint i; - void *ccregs = NULL; - - /* read the sprom */ - for (i = 0; i < nwords; i++) { - - if (sih->ccrev > 31 && ISSIM_ENAB(sih)) { - /* use indirect since direct is too slow on QT */ - if ((sih->cccaps & CC_CAP_SROM) == 0) - return 1; - - ccregs = (void *)((u8 *) sprom - CC_SROM_OTP); - buf[i] = - srom_cc_cmd(sih, ccregs, SRC_OP_READ, - wordoff + i, 0); - - } else { - if (ISSIM_ENAB(sih)) - buf[i] = R_REG(&sprom[wordoff + i]); - - buf[i] = R_REG(&sprom[wordoff + i]); - } - - } - - /* bypass crc checking for simulation to allow srom hack */ - if (ISSIM_ENAB(sih)) - return err; - - if (check_crc) { - - if (buf[0] == 0xffff) { - /* The hardware thinks that an srom that starts with 0xffff - * is blank, regardless of the rest of the content, so declare - * it bad. - */ - return 1; - } - - /* fixup the endianness so crc8 will pass */ - htol16_buf(buf, nwords * 2); - if (bcm_crc8((u8 *) buf, nwords * 2, CRC8_INIT_VALUE) != - CRC8_GOOD_VALUE) { - /* DBG only pci always read srom4 first, then srom8/9 */ - err = 1; - } - /* now correct the endianness of the byte array */ - ltoh16_buf(buf, nwords * 2); - } - return err; -} - -#if defined(BCMNVRAMR) -static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz) -{ - u8 *otp; - uint sz = OTP_SZ_MAX / 2; /* size in words */ - int err = 0; - - otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC); - if (otp == NULL) { - return -EBADE; - } - - err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz); - - memcpy(buf, otp, bufsz); - - kfree(otp); - - /* Check CRC */ - if (buf[0] == 0xffff) { - /* The hardware thinks that an srom that starts with 0xffff - * is blank, regardless of the rest of the content, so declare - * it bad. - */ - return 1; - } - - /* fixup the endianness so crc8 will pass */ - htol16_buf(buf, bufsz); - if (bcm_crc8((u8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) != - CRC8_GOOD_VALUE) { - err = 1; - } - /* now correct the endianness of the byte array */ - ltoh16_buf(buf, bufsz); - - return err; -} -#endif /* defined(BCMNVRAMR) */ -/* -* Create variable table from memory. -* Return 0 on success, nonzero on error. -*/ -static int initvars_table(char *start, char *end, - char **vars, uint *count) -{ - int c = (int)(end - start); - - /* do it only when there is more than just the null string */ - if (c > 1) { - char *vp = kmalloc(c, GFP_ATOMIC); - if (!vp) - return -ENOMEM; - memcpy(vp, start, c); - *vars = vp; - *count = c; - } else { - *vars = NULL; - *count = 0; - } - - return 0; -} - -/* - * Find variables with from flash. 'base' points to the beginning - * of the table upon enter and to the end of the table upon exit when success. - * Return 0 on success, nonzero on error. - */ -static int initvars_flash(si_t *sih, char **base, uint len) -{ - char *vp = *base; - char *flash; - int err; - char *s; - uint l, dl, copy_len; - char devpath[SI_DEVPATH_BUFSZ]; - - /* allocate memory and read in flash */ - flash = kmalloc(NVRAM_SPACE, GFP_ATOMIC); - if (!flash) - return -ENOMEM; - err = nvram_getall(flash, NVRAM_SPACE); - if (err) - goto exit; - - ai_devpath(sih, devpath, sizeof(devpath)); - - /* grab vars with the prefix in name */ - dl = strlen(devpath); - for (s = flash; s && *s; s += l + 1) { - l = strlen(s); - - /* skip non-matching variable */ - if (strncmp(s, devpath, dl)) - continue; - - /* is there enough room to copy? */ - copy_len = l - dl + 1; - if (len < copy_len) { - err = -EOVERFLOW; - goto exit; - } - - /* no prefix, just the name=value */ - strncpy(vp, &s[dl], copy_len); - vp += copy_len; - len -= copy_len; - } - - /* add null string as terminator */ - if (len < 1) { - err = -EOVERFLOW; - goto exit; - } - *vp++ = '\0'; - - *base = vp; - - exit: kfree(flash); - return err; -} - -/* - * Initialize nonvolatile variable table from flash. - * Return 0 on success, nonzero on error. - */ -static int initvars_flash_si(si_t *sih, char **vars, uint *count) -{ - char *vp, *base; - int err; - - base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC); - if (!vp) - return -ENOMEM; - - err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS); - if (err == 0) - err = initvars_table(base, vp, vars, count); - - kfree(base); - - return err; -} - -/* Parse SROM and create name=value pairs. 'srom' points to - * the SROM word array. 'off' specifies the offset of the - * first word 'srom' points to, which should be either 0 or - * SROM3_SWRG_OFF (full SROM or software region). - */ - -static uint mask_shift(u16 mask) -{ - uint i; - for (i = 0; i < (sizeof(mask) << 3); i++) { - if (mask & (1 << i)) - return i; - } - return 0; -} - -static uint mask_width(u16 mask) -{ - int i; - for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) { - if (mask & (1 << i)) - return (uint) (i - mask_shift(mask) + 1); - } - return 0; -} - -static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b) -{ - u16 w; - u32 val; - const sromvar_t *srv; - uint width; - uint flags; - u32 sr = (1 << sromrev); - - varbuf_append(b, "sromrev=%d", sromrev); - - for (srv = pci_sromvars; srv->name != NULL; srv++) { - const char *name; - - if ((srv->revmask & sr) == 0) - continue; - - if (srv->off < off) - continue; - - flags = srv->flags; - name = srv->name; - - /* This entry is for mfgc only. Don't generate param for it, */ - if (flags & SRFL_NOVAR) - continue; - - if (flags & SRFL_ETHADDR) { - u8 ea[ETH_ALEN]; - - ea[0] = (srom[srv->off - off] >> 8) & 0xff; - ea[1] = srom[srv->off - off] & 0xff; - ea[2] = (srom[srv->off + 1 - off] >> 8) & 0xff; - ea[3] = srom[srv->off + 1 - off] & 0xff; - ea[4] = (srom[srv->off + 2 - off] >> 8) & 0xff; - ea[5] = srom[srv->off + 2 - off] & 0xff; - - varbuf_append(b, "%s=%pM", name, ea); - } else { - w = srom[srv->off - off]; - val = (w & srv->mask) >> mask_shift(srv->mask); - width = mask_width(srv->mask); - - while (srv->flags & SRFL_MORE) { - srv++; - if (srv->off == 0 || srv->off < off) - continue; - - w = srom[srv->off - off]; - val += - ((w & srv->mask) >> mask_shift(srv-> - mask)) << - width; - width += mask_width(srv->mask); - } - - if ((flags & SRFL_NOFFS) - && ((int)val == (1 << width) - 1)) - continue; - - if (flags & SRFL_CCODE) { - if (val == 0) - varbuf_append(b, "ccode="); - else - varbuf_append(b, "ccode=%c%c", - (val >> 8), (val & 0xff)); - } - /* LED Powersave duty cycle has to be scaled: - *(oncount >> 24) (offcount >> 8) - */ - else if (flags & SRFL_LEDDC) { - u32 w32 = (((val >> 8) & 0xff) << 24) | /* oncount */ - (((val & 0xff)) << 8); /* offcount */ - varbuf_append(b, "leddc=%d", w32); - } else if (flags & SRFL_PRHEX) - varbuf_append(b, "%s=0x%x", name, val); - else if ((flags & SRFL_PRSIGN) - && (val & (1 << (width - 1)))) - varbuf_append(b, "%s=%d", name, - (int)(val | (~0 << width))); - else - varbuf_append(b, "%s=%u", name, val); - } - } - - if (sromrev >= 4) { - /* Do per-path variables */ - uint p, pb, psz; - - if (sromrev >= 8) { - pb = SROM8_PATH0; - psz = SROM8_PATH1 - SROM8_PATH0; - } else { - pb = SROM4_PATH0; - psz = SROM4_PATH1 - SROM4_PATH0; - } - - for (p = 0; p < MAX_PATH_SROM; p++) { - for (srv = perpath_pci_sromvars; srv->name != NULL; - srv++) { - if ((srv->revmask & sr) == 0) - continue; - - if (pb + srv->off < off) - continue; - - /* This entry is for mfgc only. Don't generate param for it, */ - if (srv->flags & SRFL_NOVAR) - continue; - - w = srom[pb + srv->off - off]; - val = (w & srv->mask) >> mask_shift(srv->mask); - width = mask_width(srv->mask); - - /* Cheating: no per-path var is more than 1 word */ - - if ((srv->flags & SRFL_NOFFS) - && ((int)val == (1 << width) - 1)) - continue; - - if (srv->flags & SRFL_PRHEX) - varbuf_append(b, "%s%d=0x%x", srv->name, - p, val); - else - varbuf_append(b, "%s%d=%d", srv->name, - p, val); - } - pb += psz; - } - } -} - -/* - * Initialize nonvolatile variable table from sprom. - * Return 0 on success, nonzero on error. - */ -static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) -{ - u16 *srom, *sromwindow; - u8 sromrev = 0; - u32 sr; - varbuf_t b; - char *vp, *base = NULL; - bool flash = false; - int err = 0; - - /* - * Apply CRC over SROM content regardless SROM is present or not, - * and use variable sromrev's existence in flash to decide - * if we should return an error when CRC fails or read SROM variables - * from flash. - */ - srom = kmalloc(SROM_MAX, GFP_ATOMIC); - if (!srom) - return -2; - - sromwindow = (u16 *) SROM_OFFSET(sih); - if (ai_is_sprom_available(sih)) { - err = - sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS, - true); - - if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) || - (((sih->buscoretype == PCIE_CORE_ID) - && (sih->buscorerev >= 6)) - || ((sih->buscoretype == PCI_CORE_ID) - && (sih->buscorerev >= 0xe)))) { - /* sromrev >= 4, read more */ - err = - sprom_read_pci(sih, sromwindow, 0, srom, - SROM4_WORDS, true); - sromrev = srom[SROM4_CRCREV] & 0xff; - } else if (err == 0) { - /* srom is good and is rev < 4 */ - /* top word of sprom contains version and crc8 */ - sromrev = srom[SROM_CRCREV] & 0xff; - /* bcm4401 sroms misprogrammed */ - if (sromrev == 0x10) - sromrev = 1; - } - } -#if defined(BCMNVRAMR) - /* Use OTP if SPROM not available */ - else { - err = otp_read_pci(sih, srom, SROM_MAX); - if (err == 0) - /* OTP only contain SROM rev8/rev9 for now */ - sromrev = srom[SROM4_CRCREV] & 0xff; - else - err = 1; - } -#else - else - err = 1; -#endif - - /* - * We want internal/wltest driver to come up with default - * sromvars so we can program a blank SPROM/OTP. - */ - if (err) { - char *value; - u32 val; - val = 0; - - value = ai_getdevpathvar(sih, "sromrev"); - if (value) { - sromrev = (u8) simple_strtoul(value, NULL, 0); - flash = true; - goto varscont; - } - - value = ai_getnvramflvar(sih, "sromrev"); - if (value) { - err = 0; - goto errout; - } - - { - err = -1; - goto errout; - } - } - - varscont: - /* Bitmask for the sromrev */ - sr = 1 << sromrev; - - /* srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, 9 */ - if ((sr & 0x33e) == 0) { - err = -2; - goto errout; - } - - base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC); - if (!vp) { - err = -2; - goto errout; - } - - /* read variables from flash */ - if (flash) { - err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS); - if (err) - goto errout; - goto varsdone; - } - - varbuf_init(&b, base, MAXSZ_NVRAM_VARS); - - /* parse SROM into name=value pairs. */ - _initvars_srom_pci(sromrev, srom, 0, &b); - - /* final nullbyte terminator */ - vp = b.buf; - *vp++ = '\0'; - - varsdone: - err = initvars_table(base, vp, vars, count); - - errout: - if (base) - kfree(base); - - kfree(srom); - return err; -} - - -static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *varsz) -{ - /* Search flash nvram section for srom variables */ - return initvars_flash_si(sih, vars, varsz); -} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c b/drivers/staging/brcm80211/brcmsmac/bmac.c similarity index 73% rename from drivers/staging/brcm80211/brcmsmac/wlc_bmac.c rename to drivers/staging/brcm80211/brcmsmac/bmac.c index 453492610613..b25c51705566 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c +++ b/drivers/staging/brcm80211/brcmsmac/bmac.c @@ -13,49 +13,20 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - - -#include -#include #include -#include -#include +#include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wlc_types.h" -#include "wlc_pmu.h" -#include "d11.h" -#include "wlc_cfg.h" -#include "wlc_rate.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "wlc_phy_shim.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_channel.h" -#include "wlc_main.h" -#include "wl_export.h" -#include "wl_ucode.h" -#include "wlc_antsel.h" -#include "pcie_core.h" -#include "wlc_alloc.h" -#include "wl_dbg.h" -#include "wlc_bmac.h" +#include +#include "types.h" +#include "rate.h" +#include "phy/phy_hal.h" +#include "channel.h" +#include "main.h" +#include "ucode_loader.h" +#include "mac80211_if.h" +#include "bmac.h" #define TIMER_INTERVAL_WATCHDOG_BMAC 1000 /* watchdog timer, in unit of ms */ @@ -67,7 +38,6 @@ #define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */ #ifndef BMAC_DUP_TO_REMOVE -#define WLC_RM_WAIT_TX_SUSPEND 4 /* Wait Tx Suspend */ #define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */ @@ -78,6 +48,9 @@ (void *)&(wlc_hw->regs->fifo64regs[fifonum].dmaxmt) : \ (void *)&(wlc_hw->regs->fifo64regs[fifonum].dmarcv)) +#define APHY_SLOT_TIME 9 +#define BPHY_SLOT_TIME 20 + /* * The following table lists the buffer memory allocated to xmt fifos in HW. * the size is in units of 256bytes(one block), total size is HW dependent @@ -97,82 +70,86 @@ static u16 xmtfifo_sz[][NFIFO] = { {9, 58, 22, 14, 14, 5}, /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */ }; -static void wlc_clkctl_clk(struct wlc_hw_info *wlc, uint mode); -static void wlc_coreinit(struct wlc_info *wlc); +static void brcms_b_clkctl_clk(struct brcms_hardware *wlc, uint mode); +static void brcms_b_coreinit(struct brcms_c_info *wlc); /* used by wlc_wakeucode_init() */ -static void wlc_write_inits(struct wlc_hw_info *wlc_hw, +static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, const struct d11init *inits); -static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], +static void brcms_ucode_write(struct brcms_hardware *wlc_hw, const u32 ucode[], const uint nbytes); -static void wlc_ucode_download(struct wlc_hw_info *wlc); -static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw); +static void brcms_ucode_download(struct brcms_hardware *wlc); +static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw); -/* used by wlc_dpc() */ -static bool wlc_bmac_dotxstatus(struct wlc_hw_info *wlc, tx_status_t *txs, - u32 s2); -static bool wlc_bmac_txstatus(struct wlc_hw_info *wlc, bool bound, bool *fatal); -static bool wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound); +/* used by brcms_c_dpc() */ +static bool brcms_b_dotxstatus(struct brcms_hardware *wlc, + struct tx_status *txs, u32 s2); +static bool brcms_b_txstatus(struct brcms_hardware *wlc, bool bound, + bool *fatal); +static bool brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound); -/* used by wlc_down() */ -static void wlc_flushqueues(struct wlc_info *wlc); +/* used by brcms_c_down() */ +static void brcms_c_flushqueues(struct brcms_c_info *wlc); -static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs); -static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw); -static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw); -static bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, +static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs); +static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw); +static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw); +static bool brcms_b_tx_fifo_suspended(struct brcms_hardware *wlc_hw, uint tx_fifo); -static void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo); -static void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo); +static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw, + uint tx_fifo); +static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, + uint tx_fifo); /* Low Level Prototypes */ -static int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw); -static void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw); -static void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want); -static u16 wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, +static int brcms_b_bandtype(struct brcms_hardware *wlc_hw); +static void brcms_b_info_init(struct brcms_hardware *wlc_hw); +static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want); +static u16 brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel); -static void wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, +static void brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v, u32 sel); -static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk); -static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme); -static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw); -static void wlc_ucode_bsinit(struct wlc_hw_info *wlc_hw); -static bool wlc_validboardtype(struct wlc_hw_info *wlc); -static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw); -static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw); -static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw); -static void wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init); -static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw); -static void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags); -static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw); -static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw); -static u32 wlc_wlintrsoff(struct wlc_info *wlc); -static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask); -static void wlc_gpio_init(struct wlc_info *wlc); -static void wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, - int len); -static void wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, - int len); -static void wlc_bmac_bsinit(struct wlc_info *wlc, chanspec_t chanspec); -static u32 wlc_setband_inact(struct wlc_info *wlc, uint bandunit); -static void wlc_bmac_setband(struct wlc_hw_info *wlc_hw, uint bandunit, +static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk); +static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme); +static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw); +static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw); +static bool brcms_c_validboardtype(struct brcms_hardware *wlc); +static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw); +static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw); +static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw); +static void brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init); +static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw); +static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool want, + mbool flags); +static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw); +static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw); +static u32 brcms_c_wlintrsoff(struct brcms_c_info *wlc); +static void brcms_c_wlintrsrestore(struct brcms_c_info *wlc, u32 macintmask); +static void brcms_c_gpio_init(struct brcms_c_info *wlc); +static void brcms_c_write_hw_bcntemplate0(struct brcms_hardware *wlc_hw, + void *bcn, int len); +static void brcms_c_write_hw_bcntemplate1(struct brcms_hardware *wlc_hw, + void *bcn, int len); +static void brcms_b_bsinit(struct brcms_c_info *wlc, chanspec_t chanspec); +static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit); +static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit, chanspec_t chanspec); -static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, +static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw, bool shortslot); -static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw); -static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, +static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw); +static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw, u8 rate); /* === Low Level functions === */ -void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot) +void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot) { wlc_hw->shortslot = shortslot; - if (BAND_2G(wlc_bmac_bandtype(wlc_hw)) && wlc_hw->up) { - wlc_suspend_mac_and_wait(wlc_hw->wlc); - wlc_bmac_update_slot_timing(wlc_hw, shortslot); - wlc_enable_mac(wlc_hw->wlc); + if (BAND_2G(brcms_b_bandtype(wlc_hw)) && wlc_hw->up) { + brcms_c_suspend_mac_and_wait(wlc_hw->wlc); + brcms_b_update_slot_timing(wlc_hw, shortslot); + brcms_c_enable_mac(wlc_hw->wlc); } } @@ -181,7 +158,7 @@ void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot) * or shortslot 11g (9us slots) * The PSM needs to be suspended for this call. */ -static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, +static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw, bool shortslot) { d11regs_t *regs; @@ -191,25 +168,25 @@ static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, if (shortslot) { /* 11g short slot: 11a timing */ W_REG(®s->ifs_slot, 0x0207); /* APHY_SLOT_TIME */ - wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME); + brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME); } else { /* 11g long slot: 11b timing */ W_REG(®s->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */ - wlc_bmac_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME); + brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME); } } -static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw) +static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) { struct wiphy *wiphy = wlc_hw->wlc->wiphy; /* init microcode host flags */ - wlc_write_mhf(wlc_hw, wlc_hw->band->mhfs); + brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs); /* do band-specific ucode IHR, SHM, and SCR inits */ if (D11REV_IS(wlc_hw->corerev, 23)) { - if (WLCISNPHY(wlc_hw->band)) { - wlc_write_inits(wlc_hw, d11n0bsinitvals16); + if (BRCMS_ISNPHY(wlc_hw->band)) { + brcms_c_write_inits(wlc_hw, d11n0bsinitvals16); } else { wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" " %d\n", __func__, wlc_hw->unit, @@ -217,8 +194,9 @@ static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw) } } else { if (D11REV_IS(wlc_hw->corerev, 24)) { - if (WLCISLCNPHY(wlc_hw->band)) { - wlc_write_inits(wlc_hw, d11lcn0bsinitvals24); + if (BRCMS_ISLCNPHY(wlc_hw->band)) { + brcms_c_write_inits(wlc_hw, + d11lcn0bsinitvals24); } else wiphy_err(wiphy, "%s: wl%d: unsupported phy in" " core rev %d\n", __func__, @@ -231,9 +209,10 @@ static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw) } /* switch to new band but leave it inactive */ -static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) +static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, + uint bandunit) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; u32 macintmask; BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); @@ -241,14 +220,14 @@ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0); /* disable interrupts */ - macintmask = wl_intrsoff(wlc->wl); + macintmask = brcms_intrsoff(wlc->wl); /* radio off */ wlc_phy_switch_radio(wlc_hw->band->pi, OFF); - wlc_bmac_core_phy_clk(wlc_hw, OFF); + brcms_b_core_phy_clk(wlc_hw, OFF); - wlc_setxband(wlc_hw, bandunit); + brcms_c_setxband(wlc_hw, bandunit); return macintmask; } @@ -259,14 +238,14 @@ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) * Param 'bound' indicates max. # frames to process before break out. */ static bool -wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) +brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) { struct sk_buff *p; struct sk_buff *head = NULL; struct sk_buff *tail = NULL; uint n = 0; uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1; - wlc_d11rxhdr_t *wlc_rxhdr = NULL; + struct brcms_d11rxhdr *wlc_rxhdr = NULL; BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* gather received frames */ @@ -292,12 +271,12 @@ wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) head = head->prev; p->prev = NULL; - wlc_rxhdr = (wlc_d11rxhdr_t *) p->data; + wlc_rxhdr = (struct brcms_d11rxhdr *) p->data; /* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */ wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr); - wlc_recv(wlc_hw->wlc, p); + brcms_c_recv(wlc_hw->wlc, p); } return n >= bound_limit; @@ -307,10 +286,10 @@ wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) * Return true if another dpc needs to be re-scheduled. false otherwise. * Param 'bounded' indicates if applicable loops should be bounded. */ -bool wlc_dpc(struct wlc_info *wlc, bool bounded) +bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) { u32 macintstatus; - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; bool fatal = false; struct wiphy *wiphy = wlc->wiphy; @@ -318,7 +297,7 @@ bool wlc_dpc(struct wlc_info *wlc, bool bounded) if (DEVICEREMOVED(wlc)) { wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return false; } @@ -333,18 +312,14 @@ bool wlc_dpc(struct wlc_info *wlc, bool bounded) /* BCN template is available */ /* ZZZ: Use AP_ACTIVE ? */ - if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub) || wlc->aps_associated) + if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub)) && (macintstatus & MI_BCNTPL)) { - wlc_update_beacon(wlc); - } - - /* PMQ entry addition */ - if (macintstatus & MI_PMQ) { + brcms_c_update_beacon(wlc); } /* tx status */ if (macintstatus & MI_TFS) { - if (wlc_bmac_txstatus(wlc->hw, bounded, &fatal)) + if (brcms_b_txstatus(wlc->hw, bounded, &fatal)) wlc->macintstatus |= MI_TFS; if (fatal) { wiphy_err(wiphy, "MI_TFS: fatal\n"); @@ -353,7 +328,7 @@ bool wlc_dpc(struct wlc_info *wlc, bool bounded) } if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) - wlc_tbtt(wlc, regs); + brcms_c_tbtt(wlc); /* ATIM window end */ if (macintstatus & MI_ATIMWINEND) { @@ -363,18 +338,13 @@ bool wlc_dpc(struct wlc_info *wlc, bool bounded) } /* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */ - if (macintstatus & MI_DMAINT) { - if (wlc_bmac_recv(wlc_hw, RX_FIFO, bounded)) { + if (macintstatus & MI_DMAINT) + if (brcms_b_recv(wlc_hw, RX_FIFO, bounded)) wlc->macintstatus |= MI_DMAINT; - } - } /* TX FIFO suspend/flush completion */ - if (macintstatus & MI_TXSTOP) { - if (wlc_bmac_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO)) { - /* wiphy_err(wiphy, "dpc: fifo_suspend_comlete\n"); */ - } - } + if (macintstatus & MI_TXSTOP) + brcms_b_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO); /* noise sample collected */ if (macintstatus & MI_BG_NOISE) { @@ -389,7 +359,7 @@ bool wlc_dpc(struct wlc_info *wlc, bool bounded) __func__, wlc_hw->sih->chip, wlc_hw->sih->chiprev); /* big hammer */ - wl_init(wlc->wl); + brcms_init(wlc->wl); } /* gptimer timeout */ @@ -400,26 +370,26 @@ bool wlc_dpc(struct wlc_info *wlc, bool bounded) if (macintstatus & MI_RFDISABLE) { BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the" " RF Disable Input\n", wlc_hw->unit); - wl_rfkill_set_hw_state(wlc->wl); + brcms_rfkill_set_hw_state(wlc->wl); } /* send any enq'd tx packets. Just makes sure to jump start tx */ if (!pktq_empty(&wlc->pkt_queue->q)) - wlc_send_q(wlc); + brcms_c_send_q(wlc); /* it isn't done and needs to be resched if macintstatus is non-zero */ return wlc->macintstatus != 0; fatal: - wl_init(wlc->wl); + brcms_init(wlc->wl); return wlc->macintstatus != 0; } /* common low-level watchdog code */ -void wlc_bmac_watchdog(void *arg) +void brcms_b_watchdog(void *arg) { - struct wlc_info *wlc = (struct wlc_info *) arg; - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_c_info *wlc = (struct brcms_c_info *) arg; + struct brcms_hardware *wlc_hw = wlc->hw; BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); @@ -430,7 +400,7 @@ void wlc_bmac_watchdog(void *arg) wlc_hw->now++; /* Check for FIFO error interrupts */ - wlc_bmac_fifoerrors(wlc_hw); + brcms_b_fifoerrors(wlc_hw); /* make sure RX dma has buffers */ dma_rxfill(wlc->hw->di[RX_FIFO]); @@ -439,7 +409,7 @@ void wlc_bmac_watchdog(void *arg) } void -wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, +brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, chanspec_t chanspec, bool mute, struct txpwr_limits *txpwr) { uint bandunit; @@ -450,18 +420,18 @@ wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, /* Switch bands if necessary */ if (NBANDS_HW(wlc_hw) > 1) { - bandunit = CHSPEC_WLCBANDUNIT(chanspec); + bandunit = CHSPEC_BANDUNIT(chanspec); if (wlc_hw->band->bandunit != bandunit) { - /* wlc_bmac_setband disables other bandunit, + /* brcms_b_setband disables other bandunit, * use light band switch if not up yet */ if (wlc_hw->up) { wlc_phy_chanspec_radio_set(wlc_hw-> bandstate[bandunit]-> pi, chanspec); - wlc_bmac_setband(wlc_hw, bandunit, chanspec); + brcms_b_setband(wlc_hw, bandunit, chanspec); } else { - wlc_setxband(wlc_hw, bandunit); + brcms_c_setxband(wlc_hw, bandunit); } } } @@ -478,26 +448,27 @@ wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); /* Update muting of the channel */ - wlc_bmac_mute(wlc_hw, mute, 0); + brcms_b_mute(wlc_hw, mute, 0); } } -int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, wlc_bmac_state_t *state) +int brcms_b_state_get(struct brcms_hardware *wlc_hw, + struct brcms_b_state *state) { state->machwcap = wlc_hw->machwcap; return 0; } -static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) +static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) { uint i; char name[8]; /* ucode host flag 2 needed for pio mode, independent of band and fifo */ u16 pio_mhf2 = 0; - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; uint unit = wlc_hw->unit; - wlc_tunables_t *tune = wlc->pub->tunables; + struct brcms_tunables *tune = wlc->pub->tunables; struct wiphy *wiphy = wlc->wiphy; /* name and offsets for dma_attach */ @@ -529,7 +500,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) NULL), DMAREG(wlc_hw, DMA_RX, 0), (wme ? tune->ntxd : 0), tune->nrxd, tune->rxbufsz, -1, tune->nrxbufpost, - WL_HWRXOFF, &wl_msg_level); + BRCMS_HWRXOFF, &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[0]); /* @@ -541,7 +512,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 1), NULL, tune->ntxd, 0, 0, -1, 0, 0, - &wl_msg_level); + &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[1]); /* @@ -552,7 +523,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 2), NULL, tune->ntxd, 0, 0, -1, 0, 0, - &wl_msg_level); + &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[2]); /* * FIFO 3 @@ -562,7 +533,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 3), NULL, tune->ntxd, 0, 0, -1, - 0, 0, &wl_msg_level); + 0, 0, &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[3]); /* Cleaner to leave this as if with AP defined */ @@ -581,12 +552,12 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) } /* initial ucode host flags */ - wlc_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2); + brcms_c_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2); return true; } -static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw) +static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw) { uint j; @@ -604,17 +575,17 @@ static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw) * initialize software state for each core and band * put the whole chip in reset(driver down state), no clock */ -int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, +int brcms_b_attach(struct brcms_c_info *wlc, u16 vendor, u16 device, uint unit, bool piomode, void *regsva, uint bustype, void *btparam) { - struct wlc_hw_info *wlc_hw; + struct brcms_hardware *wlc_hw; d11regs_t *regs; char *macaddr = NULL; char *vars; uint err = 0; uint j; bool wme = false; - shared_phy_params_t sha_params; + struct shared_phy_params sha_params; struct wiphy *wiphy = wlc->wiphy; BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, vendor, @@ -628,18 +599,18 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->band = wlc_hw->bandstate[0]; wlc_hw->_piomode = piomode; - /* populate struct wlc_hw_info with default values */ - wlc_bmac_info_init(wlc_hw); + /* populate struct brcms_hardware with default values */ + brcms_b_info_init(wlc_hw); /* * Do the hardware portion of the attach. * Also initialize software state that depends on the particular hardware * we are running. */ - wlc_hw->sih = ai_attach((uint) device, regsva, bustype, btparam, + wlc_hw->sih = ai_attach(regsva, bustype, btparam, &wlc_hw->vars, &wlc_hw->vars_size); if (wlc_hw->sih == NULL) { - wiphy_err(wiphy, "wl%d: wlc_bmac_attach: si_attach failed\n", + wiphy_err(wiphy, "wl%d: brcms_b_attach: si_attach failed\n", unit); err = 11; goto fail; @@ -674,8 +645,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, } /* verify again the device is supported */ - if (!wlc_chipmatch(vendor, device)) { - wiphy_err(wiphy, "wl%d: wlc_bmac_attach: Unsupported " + if (!brcms_c_chipmatch(vendor, device)) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported " "vendor/device (0x%x/0x%x)\n", unit, vendor, device); err = 12; @@ -695,7 +666,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc->regs = wlc_hw->regs; /* validate chip, chiprev and corerev */ - if (!wlc_isgoodchip(wlc_hw)) { + if (!brcms_c_isgoodchip(wlc_hw)) { err = 13; goto fail; } @@ -708,11 +679,11 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, * For PMU chips, the first wlc_clkctl_clk is no-op since core-clk is still false; * But it will be called again inside wlc_corereset, after d11 is out of reset. */ - wlc_clkctl_clk(wlc_hw, CLK_FAST); - wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); + brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); - if (!wlc_bmac_validate_chip_access(wlc_hw)) { - wiphy_err(wiphy, "wl%d: wlc_bmac_attach: validate_chip_access " + if (!brcms_b_validate_chip_access(wlc_hw)) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: validate_chip_access " "failed\n", unit); err = 14; goto fail; @@ -724,8 +695,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, if (j == BOARDREV_PROMOTABLE) j = BOARDREV_PROMOTED; wlc_hw->boardrev = (u16) j; - if (!wlc_validboardtype(wlc_hw)) { - wiphy_err(wiphy, "wl%d: wlc_bmac_attach: Unsupported Broadcom " + if (!brcms_c_validboardtype(wlc_hw)) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported Broadcom " "board type (0x%x)" " or revision level (0x%x)\n", unit, wlc_hw->sih->boardtype, wlc_hw->boardrev); err = 15; @@ -736,14 +707,15 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->boardflags2 = (u32) getintvar(vars, "boardflags2"); if (wlc_hw->boardflags & BFL_NOPLLDOWN) - wlc_bmac_pllreq(wlc_hw, true, WLC_PLLREQ_SHARED); + brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED); if ((wlc_hw->sih->bustype == PCI_BUS) && (ai_pci_war16165(wlc_hw->sih))) wlc->war16165 = true; /* check device id(srom, nvram etc.) to set bands */ - if (wlc_hw->deviceid == BCM43224_D11N_ID) { + if (wlc_hw->deviceid == BCM43224_D11N_ID || + wlc_hw->deviceid == BCM43224_D11N_ID_VEN1) { /* Dualband boards */ wlc_hw->_nbands = 2; } else @@ -752,8 +724,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, if ((wlc_hw->sih->chip == BCM43225_CHIP_ID)) wlc_hw->_nbands = 1; - /* BMAC_NOTE: remove init of pub values when wlc_attach() unconditionally does the - * init of these values + /* BMAC_NOTE: remove init of pub values when brcms_c_attach() + * unconditionally does the init of these values */ wlc->vendorid = wlc_hw->vendorid; wlc->deviceid = wlc_hw->deviceid; @@ -768,7 +740,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc); if (wlc_hw->physhim == NULL) { - wiphy_err(wiphy, "wl%d: wlc_bmac_attach: wlc_phy_shim_attach " + wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_shim_attach " "failed\n", unit); err = 25; goto fail; @@ -812,12 +784,12 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, if (IS_SINGLEBAND_5G(wlc_hw->deviceid)) j = BAND_5G_INDEX; - wlc_setxband(wlc_hw, j); + brcms_c_setxband(wlc_hw, j); wlc_hw->band->bandunit = j; - wlc_hw->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; + wlc_hw->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G; wlc->band->bandunit = j; - wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G; + wlc->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G; wlc->core->coreidx = ai_coreidx(wlc_hw->sih); wlc_hw->machwcap = R_REG(®s->machwcap); @@ -829,10 +801,10 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, /* Get a phy for this band */ wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh, - (void *)regs, wlc_bmac_bandtype(wlc_hw), vars, + (void *)regs, brcms_b_bandtype(wlc_hw), vars, wlc->wiphy); if (wlc_hw->band->pi == NULL) { - wiphy_err(wiphy, "wl%d: wlc_bmac_attach: wlc_phy_" + wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_" "attach failed\n", unit); err = 17; goto fail; @@ -851,19 +823,19 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_phy_get_coreflags(wlc_hw->band->pi); /* verify good phy_type & supported phy revision */ - if (WLCISNPHY(wlc_hw->band)) { + if (BRCMS_ISNPHY(wlc_hw->band)) { if (NCONF_HAS(wlc_hw->band->phyrev)) goto good_phy; else goto bad_phy; - } else if (WLCISLCNPHY(wlc_hw->band)) { + } else if (BRCMS_ISLCNPHY(wlc_hw->band)) { if (LCNCONF_HAS(wlc_hw->band->phyrev)) goto good_phy; else goto bad_phy; } else { bad_phy: - wiphy_err(wiphy, "wl%d: wlc_bmac_attach: unsupported " + wiphy_err(wiphy, "wl%d: brcms_b_attach: unsupported " "phy type/rev (%d/%d)\n", unit, wlc_hw->band->phytype, wlc_hw->band->phyrev); err = 18; @@ -887,25 +859,25 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->band->CWmin = APHY_CWMIN; wlc_hw->band->CWmax = PHY_CWMAX; - if (!wlc_bmac_attach_dmapio(wlc, j, wme)) { + if (!brcms_b_attach_dmapio(wlc, j, wme)) { err = 19; goto fail; } } /* disable core to match driver "down" state */ - wlc_coredisable(wlc_hw); + brcms_c_coredisable(wlc_hw); /* Match driver "down" state */ if (wlc_hw->sih->bustype == PCI_BUS) ai_pci_down(wlc_hw->sih); /* register sb interrupt callback functions */ - ai_register_intr_callback(wlc_hw->sih, (void *)wlc_wlintrsoff, - (void *)wlc_wlintrsrestore, NULL, wlc); + ai_register_intr_callback(wlc_hw->sih, (void *)brcms_c_wlintrsoff, + (void *)brcms_c_wlintrsrestore, NULL, wlc); /* turn off pll and xtal to match driver "down" state */ - wlc_bmac_xtal(wlc_hw, OFF); + brcms_b_xtal(wlc_hw, OFF); /* ********************************************************************* * The hardware is in the DOWN state at this point. D11 core @@ -918,17 +890,17 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, */ /* init etheraddr state variables */ - macaddr = wlc_get_macaddr(wlc_hw); + macaddr = brcms_c_get_macaddr(wlc_hw); if (macaddr == NULL) { - wiphy_err(wiphy, "wl%d: wlc_bmac_attach: macaddr not found\n", + wiphy_err(wiphy, "wl%d: brcms_b_attach: macaddr not found\n", unit); err = 21; goto fail; } - bcm_ether_atoe(macaddr, wlc_hw->etheraddr); + brcmu_ether_atoe(macaddr, wlc_hw->etheraddr); if (is_broadcast_ether_addr(wlc_hw->etheraddr) || is_zero_ether_addr(wlc_hw->etheraddr)) { - wiphy_err(wiphy, "wl%d: wlc_bmac_attach: bad macaddr %s\n", + wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr %s\n", unit, macaddr); err = 22; goto fail; @@ -942,19 +914,19 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, return err; fail: - wiphy_err(wiphy, "wl%d: wlc_bmac_attach: failed with err %d\n", unit, + wiphy_err(wiphy, "wl%d: brcms_b_attach: failed with err %d\n", unit, err); return err; } /* - * Initialize wlc_info default values ... + * Initialize brcms_c_info default values ... * may get overrides later in this function * BMAC_NOTES, move low out and resolve the dangling ones */ -static void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw) +static void brcms_b_info_init(struct brcms_hardware *wlc_hw) { - struct wlc_info *wlc = wlc_hw->wlc; + struct brcms_c_info *wlc = wlc_hw->wlc; /* set default sw macintmask value */ wlc->defmacintmask = DEF_MACINTMASK; @@ -974,11 +946,11 @@ static void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw) /* * low level detach */ -int wlc_bmac_detach(struct wlc_info *wlc) +int brcms_b_detach(struct brcms_c_info *wlc) { uint i; - struct wlc_hwband *band; - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hw_band *band; + struct brcms_hardware *wlc_hw = wlc->hw; int callbacks; callbacks = 0; @@ -993,7 +965,7 @@ int wlc_bmac_detach(struct wlc_info *wlc) ai_pci_sleep(wlc_hw->sih); } - wlc_bmac_detach_dmapio(wlc_hw); + brcms_b_detach_dmapio(wlc_hw); band = wlc_hw->band; for (i = 0; i < NBANDS_HW(wlc_hw); i++) { @@ -1006,7 +978,7 @@ int wlc_bmac_detach(struct wlc_info *wlc) } /* Free shared phy state */ - wlc_phy_shared_detach(wlc_hw->phy_sh); + kfree(wlc_hw->phy_sh); wlc_phy_shim_detach(wlc_hw->physhim); @@ -1023,61 +995,61 @@ int wlc_bmac_detach(struct wlc_info *wlc) } -void wlc_bmac_reset(struct wlc_hw_info *wlc_hw) +void brcms_b_reset(struct brcms_hardware *wlc_hw) { BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* reset the core */ if (!DEVICEREMOVED(wlc_hw->wlc)) - wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); + brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); /* purge the dma rings */ - wlc_flushqueues(wlc_hw->wlc); + brcms_c_flushqueues(wlc_hw->wlc); - wlc_reset_bmac_done(wlc_hw->wlc); + brcms_c_reset_bmac_done(wlc_hw->wlc); } void -wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, +brcms_b_init(struct brcms_hardware *wlc_hw, chanspec_t chanspec, bool mute) { u32 macintmask; bool fastclk; - struct wlc_info *wlc = wlc_hw->wlc; + struct brcms_c_info *wlc = wlc_hw->wlc; BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); /* disable interrupts */ - macintmask = wl_intrsoff(wlc->wl); + macintmask = brcms_intrsoff(wlc->wl); /* set up the specified band and chanspec */ - wlc_setxband(wlc_hw, CHSPEC_WLCBANDUNIT(chanspec)); + brcms_c_setxband(wlc_hw, CHSPEC_BANDUNIT(chanspec)); wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); /* do one-time phy inits and calibration */ wlc_phy_cal_init(wlc_hw->band->pi); /* core-specific initialization */ - wlc_coreinit(wlc); + brcms_b_coreinit(wlc); /* suspend the tx fifos and mute the phy for preism cac time */ if (mute) - wlc_bmac_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM); + brcms_b_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM); /* band-specific inits */ - wlc_bmac_bsinit(wlc, chanspec); + brcms_b_bsinit(wlc, chanspec); /* restore macintmask */ - wl_intrsrestore(wlc->wl, macintmask); + brcms_intrsrestore(wlc->wl, macintmask); - /* seed wake_override with WLC_WAKE_OVERRIDE_MACSUSPEND since the mac is suspended - * and wlc_enable_mac() will clear this override bit. + /* seed wake_override with BRCMS_WAKE_OVERRIDE_MACSUSPEND since the mac + * is suspended and brcms_c_enable_mac() will clear this override bit. */ - mboolset(wlc_hw->wake_override, WLC_WAKE_OVERRIDE_MACSUSPEND); + mboolset(wlc_hw->wake_override, BRCMS_WAKE_OVERRIDE_MACSUSPEND); /* * initialize mac_suspend_depth to 1 to match ucode initial suspended state @@ -1086,10 +1058,10 @@ wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, /* restore the clk */ if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); + brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); } -int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) +int brcms_b_up_prep(struct brcms_hardware *wlc_hw) { uint coremask; @@ -1097,14 +1069,14 @@ int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) /* * Enable pll and xtal, initialize the power control registers, - * and force fastclock for the remainder of wlc_up(). + * and force fastclock for the remainder of brcms_c_up(). */ - wlc_bmac_xtal(wlc_hw, ON); + brcms_b_xtal(wlc_hw, ON); ai_clkctl_init(wlc_hw->sih); - wlc_clkctl_clk(wlc_hw, CLK_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); /* - * Configure pci/pcmcia here instead of in wlc_attach() + * Configure pci/pcmcia here instead of in brcms_c_attach() * to allow mfg hotswap: down, hotswap (chip power cycle), up. */ coremask = (1 << wlc_hw->wlc->core->coreidx); @@ -1116,11 +1088,11 @@ int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) * Need to read the hwradio status here to cover the case where the system * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. */ - if (wlc_bmac_radio_read_hwdisabled(wlc_hw)) { + if (brcms_b_radio_read_hwdisabled(wlc_hw)) { /* put SB PCI in down state again */ if (wlc_hw->sih->bustype == PCI_BUS) ai_pci_down(wlc_hw->sih); - wlc_bmac_xtal(wlc_hw, OFF); + brcms_b_xtal(wlc_hw, OFF); return -ENOMEDIUM; } @@ -1128,12 +1100,12 @@ int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) ai_pci_up(wlc_hw->sih); /* reset the d11 core */ - wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); + brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); return 0; } -int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw) +int brcms_b_up_finish(struct brcms_hardware *wlc_hw) { BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); @@ -1141,12 +1113,12 @@ int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw) wlc_phy_hw_state_upd(wlc_hw->band->pi, true); /* FULLY enable dynamic power control and d11 core interrupt */ - wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); - wl_intrson(wlc_hw->wlc->wl); + brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); + brcms_intrson(wlc_hw->wlc->wl); return 0; } -int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw) +int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw) { bool dev_gone; uint callbacks = 0; @@ -1163,10 +1135,10 @@ int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw) wlc_hw->wlc->macintmask = 0; else { /* now disable interrupts */ - wl_intrsoff(wlc_hw->wlc->wl); + brcms_intrsoff(wlc_hw->wlc->wl); /* ensure we're running on the pll clock again */ - wlc_clkctl_clk(wlc_hw, CLK_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); } /* down phy at the last of this stage */ callbacks += wlc_phy_down(wlc_hw->band->pi); @@ -1174,7 +1146,7 @@ int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw) return callbacks; } -int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) +int brcms_b_down_finish(struct brcms_hardware *wlc_hw) { uint callbacks = 0; bool dev_gone; @@ -1195,51 +1167,51 @@ int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); /* reclaim any posted packets */ - wlc_flushqueues(wlc_hw->wlc); + brcms_c_flushqueues(wlc_hw->wlc); } else { /* Reset and disable the core */ if (ai_iscoreup(wlc_hw->sih)) { if (R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) - wlc_suspend_mac_and_wait(wlc_hw->wlc); - callbacks += wl_reset(wlc_hw->wlc->wl); - wlc_coredisable(wlc_hw); + brcms_c_suspend_mac_and_wait(wlc_hw->wlc); + callbacks += brcms_reset(wlc_hw->wlc->wl); + brcms_c_coredisable(wlc_hw); } /* turn off primary xtal and pll */ if (!wlc_hw->noreset) { if (wlc_hw->sih->bustype == PCI_BUS) ai_pci_down(wlc_hw->sih); - wlc_bmac_xtal(wlc_hw, OFF); + brcms_b_xtal(wlc_hw, OFF); } } return callbacks; } -void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw) +void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw) { /* delay before first read of ucode state */ udelay(40); /* wait until ucode is no longer asleep */ - SPINWAIT((wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) == + SPINWAIT((brcms_b_read_shm(wlc_hw, M_UCODE_DBGST) == DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly); } -void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea) +void brcms_b_hw_etheraddr(struct brcms_hardware *wlc_hw, u8 *ea) { memcpy(ea, wlc_hw->etheraddr, ETH_ALEN); } -static int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw) +static int brcms_b_bandtype(struct brcms_hardware *wlc_hw) { return wlc_hw->band->bandtype; } /* control chip clock to save power, enable dynamic clock or force fast clock */ -static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) +static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, uint mode) { if (PMUCTL_ENAB(wlc_hw->sih)) { /* new chips with PMU, CCS_FORCEHT will distribute the HT clock on backplane, @@ -1301,18 +1273,18 @@ static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) */ if (wlc_hw->forcefastclk) mboolset(wlc_hw->wake_override, - WLC_WAKE_OVERRIDE_FORCEFAST); + BRCMS_WAKE_OVERRIDE_FORCEFAST); else mboolclr(wlc_hw->wake_override, - WLC_WAKE_OVERRIDE_FORCEFAST); + BRCMS_WAKE_OVERRIDE_FORCEFAST); } } /* set initial host flags value */ static void -wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init) +brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; memset(mhfs, 0, MHFMAX * sizeof(u16)); @@ -1322,7 +1294,7 @@ wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init) if (wlc_hw->boardflags & BFL_NOPLLDOWN) mhfs[MHF1] |= MHF1_FORCEFASTCLK; - if (WLCISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) { + if (BRCMS_ISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) { mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR; mhfs[MHF1] |= MHF1_IQSWAP_WAR; } @@ -1334,13 +1306,13 @@ wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init) * pre-CLK changes should use wlc_write_mhf to get around the optimization * * - * bands values are: WLC_BAND_AUTO <--- Current band only - * WLC_BAND_5G <--- 5G band only - * WLC_BAND_2G <--- 2G band only - * WLC_BAND_ALL <--- All bands + * bands values are: BRCM_BAND_AUTO <--- Current band only + * BRCM_BAND_5G <--- 5G band only + * BRCM_BAND_2G <--- 2G band only + * BRCM_BAND_ALL <--- All bands */ void -wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, +brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val, int bands) { u16 save; @@ -1348,7 +1320,7 @@ wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, M_HOST_FLAGS5 }; - struct wlc_hwband *band; + struct brcms_hw_band *band; if ((val & ~mask) || idx >= MHFMAX) return; /* error condition */ @@ -1357,14 +1329,14 @@ wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, /* Current band only or all bands, * then set the band to current band */ - case WLC_BAND_AUTO: - case WLC_BAND_ALL: + case BRCM_BAND_AUTO: + case BRCM_BAND_ALL: band = wlc_hw->band; break; - case WLC_BAND_5G: + case BRCM_BAND_5G: band = wlc_hw->bandstate[BAND_5G_INDEX]; break; - case WLC_BAND_2G: + case BRCM_BAND_2G: band = wlc_hw->bandstate[BAND_2G_INDEX]; break; default: @@ -1380,11 +1352,11 @@ wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, */ if (wlc_hw->clk && (band->mhfs[idx] != save) && (band == wlc_hw->band)) - wlc_bmac_write_shm(wlc_hw, addr[idx], + brcms_b_write_shm(wlc_hw, addr[idx], (u16) band->mhfs[idx]); } - if (bands == WLC_BAND_ALL) { + if (bands == BRCM_BAND_ALL) { wlc_hw->bandstate[0]->mhfs[idx] = (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val; wlc_hw->bandstate[1]->mhfs[idx] = @@ -1392,20 +1364,20 @@ wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, } } -u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands) +u16 brcms_b_mhf_get(struct brcms_hardware *wlc_hw, u8 idx, int bands) { - struct wlc_hwband *band; + struct brcms_hw_band *band; if (idx >= MHFMAX) return 0; /* error condition */ switch (bands) { - case WLC_BAND_AUTO: + case BRCM_BAND_AUTO: band = wlc_hw->band; break; - case WLC_BAND_5G: + case BRCM_BAND_5G: band = wlc_hw->bandstate[BAND_5G_INDEX]; break; - case WLC_BAND_2G: + case BRCM_BAND_2G: band = wlc_hw->bandstate[BAND_2G_INDEX]; break; default: @@ -1418,7 +1390,7 @@ u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands) return band->mhfs[idx]; } -static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs) +static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs) { u8 idx; u16 addr[] = { @@ -1427,25 +1399,25 @@ static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs) }; for (idx = 0; idx < MHFMAX; idx++) { - wlc_bmac_write_shm(wlc_hw, addr[idx], mhfs[idx]); + brcms_b_write_shm(wlc_hw, addr[idx], mhfs[idx]); } } /* set the maccontrol register to desired reset state and * initialize the sw cache of the register */ -static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw) +static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw) { /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */ wlc_hw->maccontrol = 0; wlc_hw->suspended_fifos = 0; wlc_hw->wake_override = 0; wlc_hw->mute_override = 0; - wlc_bmac_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE); + brcms_b_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE); } /* set or clear maccontrol bits */ -void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val) +void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val) { u32 maccontrol; u32 new_maccontrol; @@ -1463,11 +1435,11 @@ void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val) wlc_hw->maccontrol = new_maccontrol; /* write the new values with overrides applied */ - wlc_mctrl_write(wlc_hw); + brcms_c_mctrl_write(wlc_hw); } /* write the software state of maccontrol and overrides to the maccontrol register */ -static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw) +static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw) { u32 maccontrol = wlc_hw->maccontrol; @@ -1484,7 +1456,8 @@ static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw) W_REG(&wlc_hw->regs->maccontrol, maccontrol); } -void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit) +void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw, + u32 override_bit) { if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) { mboolset(wlc_hw->wake_override, override_bit); @@ -1493,20 +1466,21 @@ void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit) mboolset(wlc_hw->wake_override, override_bit); - wlc_mctrl_write(wlc_hw); - wlc_bmac_wait_for_wake(wlc_hw); + brcms_c_mctrl_write(wlc_hw); + brcms_b_wait_for_wake(wlc_hw); return; } -void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit) +void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw, + u32 override_bit) { mboolclr(wlc_hw->wake_override, override_bit); if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) return; - wlc_mctrl_write(wlc_hw); + brcms_c_mctrl_write(wlc_hw); return; } @@ -1518,7 +1492,7 @@ void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit) * STA 0 1 <--- This will ensure no beacons * IBSS 0 0 */ -static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw) +static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw) { wlc_hw->mute_override = 1; @@ -1528,13 +1502,13 @@ static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw) if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) return; - wlc_mctrl_write(wlc_hw); + brcms_c_mctrl_write(wlc_hw); return; } /* Clear the override on AP and INFRA bits */ -static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw) +static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw) { if (wlc_hw->mute_override == 0) return; @@ -1547,14 +1521,14 @@ static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw) if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) return; - wlc_mctrl_write(wlc_hw); + brcms_c_mctrl_write(wlc_hw); } /* * Write a MAC address to the given match reg offset in the RXE match engine. */ void -wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, +brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset, const u8 *addr) { d11regs_t *regs; @@ -1562,7 +1536,7 @@ wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, u16 mac_m; u16 mac_h; - BCMMSG(wlc_hw->wlc->wiphy, "wl%d: wlc_bmac_set_addrmatch\n", + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n", wlc_hw->unit); regs = wlc_hw->regs; @@ -1579,7 +1553,7 @@ wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, } void -wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, +brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len, void *buf) { d11regs_t *regs; @@ -1611,7 +1585,7 @@ wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, } } -void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin) +void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin) { wlc_hw->band->CWmin = newmin; @@ -1620,7 +1594,7 @@ void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin) W_REG(&wlc_hw->regs->objdata, newmin); } -void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax) +void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax) { wlc_hw->band->CWmax = newmax; @@ -1629,124 +1603,126 @@ void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax) W_REG(&wlc_hw->regs->objdata, newmax); } -void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw) +void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw) { bool fastclk; /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); wlc_phy_bw_state_set(wlc_hw->band->pi, bw); - wlc_bmac_phy_reset(wlc_hw); + brcms_b_phy_reset(wlc_hw); wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi)); /* restore the clk */ if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); + brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); } static void -wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, int len) +brcms_c_write_hw_bcntemplate0(struct brcms_hardware *wlc_hw, void *bcn, + int len) { d11regs_t *regs = wlc_hw->regs; - wlc_bmac_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3, + brcms_b_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3, bcn); /* write beacon length to SCR */ - wlc_bmac_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len); + brcms_b_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len); /* mark beacon0 valid */ OR_REG(®s->maccommand, MCMD_BCN0VLD); } static void -wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, int len) +brcms_c_write_hw_bcntemplate1(struct brcms_hardware *wlc_hw, void *bcn, + int len) { d11regs_t *regs = wlc_hw->regs; - wlc_bmac_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3, + brcms_b_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3, bcn); /* write beacon length to SCR */ - wlc_bmac_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len); + brcms_b_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len); /* mark beacon1 valid */ OR_REG(®s->maccommand, MCMD_BCN1VLD); } /* mac is assumed to be suspended at this point */ void -wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, void *bcn, int len, - bool both) +brcms_b_write_hw_bcntemplates(struct brcms_hardware *wlc_hw, void *bcn, + int len, bool both) { d11regs_t *regs = wlc_hw->regs; if (both) { - wlc_write_hw_bcntemplate0(wlc_hw, bcn, len); - wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); + brcms_c_write_hw_bcntemplate0(wlc_hw, bcn, len); + brcms_c_write_hw_bcntemplate1(wlc_hw, bcn, len); } else { /* bcn 0 */ if (!(R_REG(®s->maccommand) & MCMD_BCN0VLD)) - wlc_write_hw_bcntemplate0(wlc_hw, bcn, len); + brcms_c_write_hw_bcntemplate0(wlc_hw, bcn, len); /* bcn 1 */ else if (! (R_REG(®s->maccommand) & MCMD_BCN1VLD)) - wlc_write_hw_bcntemplate1(wlc_hw, bcn, len); + brcms_c_write_hw_bcntemplate1(wlc_hw, bcn, len); } } -static void WLBANDINITFN(wlc_bmac_upd_synthpu) (struct wlc_hw_info *wlc_hw) +static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw) { u16 v; - struct wlc_info *wlc = wlc_hw->wlc; + struct brcms_c_info *wlc = wlc_hw->wlc; /* update SYNTHPU_DLY */ - if (WLCISLCNPHY(wlc->band)) { + if (BRCMS_ISLCNPHY(wlc->band)) { v = SYNTHPU_DLY_LPPHY_US; - } else if (WLCISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) { + } else if (BRCMS_ISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) { v = SYNTHPU_DLY_NPHY_US; } else { v = SYNTHPU_DLY_BPHY_US; } - wlc_bmac_write_shm(wlc_hw, M_SYNTHPU_DLY, v); + brcms_b_write_shm(wlc_hw, M_SYNTHPU_DLY, v); } /* band-specific init */ static void -WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) +brcms_b_bsinit(struct brcms_c_info *wlc, chanspec_t chanspec) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, wlc_hw->band->bandunit); - wlc_ucode_bsinit(wlc_hw); + brcms_c_ucode_bsinit(wlc_hw); wlc_phy_init(wlc_hw->band->pi, chanspec); - wlc_ucode_txant_set(wlc_hw); + brcms_c_ucode_txant_set(wlc_hw); /* cwmin is band-specific, update hardware with value for current band */ - wlc_bmac_set_cwmin(wlc_hw, wlc_hw->band->CWmin); - wlc_bmac_set_cwmax(wlc_hw, wlc_hw->band->CWmax); + brcms_b_set_cwmin(wlc_hw, wlc_hw->band->CWmin); + brcms_b_set_cwmax(wlc_hw, wlc_hw->band->CWmax); - wlc_bmac_update_slot_timing(wlc_hw, + brcms_b_update_slot_timing(wlc_hw, BAND_5G(wlc_hw->band-> bandtype) ? true : wlc_hw-> shortslot); /* write phytype and phyvers */ - wlc_bmac_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype); - wlc_bmac_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev); + brcms_b_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype); + brcms_b_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev); /* initialize the txphyctl1 rate table since shmem is shared between bands */ - wlc_upd_ofdm_pctl1_table(wlc_hw); + brcms_upd_ofdm_pctl1_table(wlc_hw); - wlc_bmac_upd_synthpu(wlc_hw); + brcms_b_upd_synthpu(wlc_hw); } -static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) +static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) { BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk); @@ -1771,7 +1747,7 @@ static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) } /* Perform a soft reset of the PHY PLL */ -void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw) +void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw) { BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); @@ -1790,12 +1766,12 @@ void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw) } /* light way to turn on phy clock without reset for NPHY only - * refer to wlc_bmac_core_phy_clk for full version + * refer to brcms_b_core_phy_clk for full version */ -void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk) +void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk) { /* support(necessary for NPHY and HYPHY) only */ - if (!WLCISNPHY(wlc_hw->band)) + if (!BRCMS_ISNPHY(wlc_hw->band)) return; if (ON == clk) @@ -1805,7 +1781,7 @@ void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk) } -void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk) +void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk) { if (ON == clk) ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE); @@ -1813,9 +1789,9 @@ void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk) ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0); } -void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) +void brcms_b_phy_reset(struct brcms_hardware *wlc_hw) { - wlc_phy_t *pih = wlc_hw->band->pi; + struct brcms_phy_pub *pih = wlc_hw->band->pi; u32 phy_bw_clkbits; bool phy_in_reset = false; @@ -1827,7 +1803,7 @@ void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi); /* Specific reset sequence required for NPHY rev 3 and 4 */ - if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) && + if (BRCMS_ISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) && NREV_LE(wlc_hw->band->phyrev, 4)) { /* Set the PHY bandwidth */ ai_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits); @@ -1835,7 +1811,7 @@ void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) udelay(1); /* Perform a soft reset of the PHY PLL */ - wlc_bmac_core_phypll_reset(wlc_hw); + brcms_b_core_phypll_reset(wlc_hw); /* reset the PHY */ ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE), @@ -1849,7 +1825,7 @@ void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) } udelay(2); - wlc_bmac_core_phy_clk(wlc_hw, ON); + brcms_b_core_phy_clk(wlc_hw, ON); if (pih) wlc_phy_anacore(pih, ON); @@ -1857,44 +1833,45 @@ void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) /* switch to and initialize new band */ static void -WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit, +brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit, chanspec_t chanspec) { - struct wlc_info *wlc = wlc_hw->wlc; + struct brcms_c_info *wlc = wlc_hw->wlc; u32 macintmask; /* Enable the d11 core before accessing it */ if (!ai_iscoreup(wlc_hw->sih)) { ai_core_reset(wlc_hw->sih, 0, 0); - wlc_mctrl_reset(wlc_hw); + brcms_c_mctrl_reset(wlc_hw); } - macintmask = wlc_setband_inact(wlc, bandunit); + macintmask = brcms_c_setband_inact(wlc, bandunit); if (!wlc_hw->up) return; - wlc_bmac_core_phy_clk(wlc_hw, ON); + brcms_b_core_phy_clk(wlc_hw, ON); /* band-specific initializations */ - wlc_bmac_bsinit(wlc, chanspec); + brcms_b_bsinit(wlc, chanspec); /* * If there are any pending software interrupt bits, * then replace these with a harmless nonzero value - * so wlc_dpc() will re-enable interrupts when done. + * so brcms_c_dpc() will re-enable interrupts when done. */ if (wlc->macintstatus) wlc->macintstatus = MI_DMAINT; /* restore macintmask */ - wl_intrsrestore(wlc->wl, macintmask); + brcms_intrsrestore(wlc->wl, macintmask); /* ucode should still be suspended.. */ WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0); } /* low-level band switch utility routine */ -void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit) +void brcms_c_setxband(struct brcms_hardware *wlc_hw, + uint bandunit) { BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, bandunit); @@ -1911,7 +1888,7 @@ void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit) } } -static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw) +static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw) { /* reject unsupported corerev */ @@ -1924,31 +1901,36 @@ static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw) return true; } -static bool wlc_validboardtype(struct wlc_hw_info *wlc_hw) +/* Validate some board info parameters */ +static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw) { - bool goodboard = true; uint boardrev = wlc_hw->boardrev; - if (boardrev == 0) - goodboard = false; - else if (boardrev > 0xff) { - uint brt = (boardrev & 0xf000) >> 12; - uint b0 = (boardrev & 0xf00) >> 8; - uint b1 = (boardrev & 0xf0) >> 4; - uint b2 = boardrev & 0xf; - - if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9) - || (b2 > 9)) - goodboard = false; - } + /* 4 bits each for board type, major, minor, and tiny version */ + uint brt = (boardrev & 0xf000) >> 12; + uint b0 = (boardrev & 0xf00) >> 8; + uint b1 = (boardrev & 0xf0) >> 4; + uint b2 = boardrev & 0xf; + /* voards from other vendors are always considered valid */ if (wlc_hw->sih->boardvendor != PCI_VENDOR_ID_BROADCOM) - return goodboard; + return true; - return goodboard; + /* do some boardrev sanity checks when boardvendor is Broadcom */ + if (boardrev == 0) + return false; + + if (boardrev <= 0xff) + return true; + + if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9) + || (b2 > 9)) + return false; + + return true; } -static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw) +static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw) { const char *varname = "macaddr"; char *macaddr; @@ -1978,14 +1960,14 @@ static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw) * this function could be called when driver is down and w/o clock * it operates on different registers depending on corerev and boardflag. */ -bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) +bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw) { bool v, clk, xtal; u32 resetbits = 0, flags = 0; xtal = wlc_hw->sbclk; if (!xtal) - wlc_bmac_xtal(wlc_hw, ON); + brcms_b_xtal(wlc_hw, ON); /* may need to take core out of reset first */ clk = wlc_hw->clk; @@ -1999,13 +1981,12 @@ bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || - (wlc_hw->sih->chip == BCM43225_CHIP_ID) || - (wlc_hw->sih->chip == BCM43421_CHIP_ID)) + (wlc_hw->sih->chip == BCM43225_CHIP_ID)) wlc_hw->regs = (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID, 0); ai_core_reset(wlc_hw->sih, flags, resetbits); - wlc_mctrl_reset(wlc_hw); + brcms_c_mctrl_reset(wlc_hw); } v = ((R_REG(&wlc_hw->regs->phydebug) & PDBG_RFD) != 0); @@ -2015,13 +1996,13 @@ bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) ai_core_disable(wlc_hw->sih, 0); if (!xtal) - wlc_bmac_xtal(wlc_hw, OFF); + brcms_b_xtal(wlc_hw, OFF); return v; } /* Initialize just the hardware when coming out of POR or S3/S5 system states */ -void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) +void brcms_b_hw_up(struct brcms_hardware *wlc_hw) { if (wlc_hw->wlc->pub->hw_up) return; @@ -2030,19 +2011,18 @@ void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) /* * Enable pll and xtal, initialize the power control registers, - * and force fastclock for the remainder of wlc_up(). + * and force fastclock for the remainder of brcms_c_up(). */ - wlc_bmac_xtal(wlc_hw, ON); + brcms_b_xtal(wlc_hw, ON); ai_clkctl_init(wlc_hw->sih); - wlc_clkctl_clk(wlc_hw, CLK_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); if (wlc_hw->sih->bustype == PCI_BUS) { ai_pci_fixcfg(wlc_hw->sih); /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || - (wlc_hw->sih->chip == BCM43225_CHIP_ID) || - (wlc_hw->sih->chip == BCM43421_CHIP_ID)) + (wlc_hw->sih->chip == BCM43225_CHIP_ID)) wlc_hw->regs = (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID, 0); @@ -2063,9 +2043,9 @@ void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) } } -static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo) +static bool wlc_dma_rxreset(struct brcms_hardware *wlc_hw, uint fifo) { - struct hnddma_pub *di = wlc_hw->di[fifo]; + struct dma_pub *di = wlc_hw->di[fifo]; return dma_rxreset(di); } @@ -2077,14 +2057,14 @@ static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo) * clear software macintstatus for fresh new start * one testing hack wlc_hw->noreset will bypass the d11/phy reset */ -void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) +void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) { d11regs_t *regs; uint i; bool fastclk; u32 resetbits = 0; - if (flags == WLC_USE_COREFLAGS) + if (flags == BRCMS_USE_COREFLAGS) flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); @@ -2094,7 +2074,7 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); /* reset the dma engines except first time thru */ if (ai_iscoreup(wlc_hw->sih)) { @@ -2115,7 +2095,7 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) /* if noreset, just stop the psm and return */ if (wlc_hw->noreset) { wlc_hw->wlc->macintstatus = 0; /* skip wl_dpc after down */ - wlc_bmac_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0); + brcms_b_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0); return; } @@ -2139,28 +2119,28 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) if (wlc_hw->band && wlc_hw->band->pi) wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true); - wlc_mctrl_reset(wlc_hw); + brcms_c_mctrl_reset(wlc_hw); if (PMUCTL_ENAB(wlc_hw->sih)) - wlc_clkctl_clk(wlc_hw, CLK_FAST); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); - wlc_bmac_phy_reset(wlc_hw); + brcms_b_phy_reset(wlc_hw); /* turn on PHY_PLL */ - wlc_bmac_core_phypll_ctl(wlc_hw, true); + brcms_b_core_phypll_ctl(wlc_hw, true); /* clear sw intstatus */ wlc_hw->wlc->macintstatus = 0; /* restore the clk setting */ if (!fastclk) - wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); + brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); } /* txfifo sizes needs to be modified(increased) since the newer cores * have more memory. */ -static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) +static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw) { d11regs_t *regs = wlc_hw->regs; u16 fifo_nu; @@ -2195,14 +2175,14 @@ static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) * need to propagate to shm location to be in sync since ucode/hw won't * do this */ - wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE0, + brcms_b_write_shm(wlc_hw, M_FIFOSIZE0, wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]); - wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE1, + brcms_b_write_shm(wlc_hw, M_FIFOSIZE1, wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]); - wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE2, + brcms_b_write_shm(wlc_hw, M_FIFOSIZE2, ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw-> xmtfifo_sz[TX_AC_BK_FIFO])); - wlc_bmac_write_shm(wlc_hw, M_FIFOSIZE3, + brcms_b_write_shm(wlc_hw, M_FIFOSIZE3, ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw-> xmtfifo_sz[TX_BCMC_FIFO])); } @@ -2215,9 +2195,9 @@ static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) * config other core registers * init dma */ -static void wlc_coreinit(struct wlc_info *wlc) +static void brcms_b_coreinit(struct brcms_c_info *wlc) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; d11regs_t *regs; u32 sflags; uint bcnint_us; @@ -2232,9 +2212,9 @@ static void wlc_coreinit(struct wlc_info *wlc) BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); /* reset PSM */ - wlc_bmac_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); + brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); - wlc_ucode_download(wlc_hw); + brcms_ucode_download(wlc_hw); /* * FIFOSZ fixup. driver wants to controls the fifo allocation. */ @@ -2242,7 +2222,7 @@ static void wlc_coreinit(struct wlc_info *wlc) /* let the PSM run to the suspended state, set mode to BSS STA */ W_REG(®s->macintstatus, -1); - wlc_bmac_mctrl(wlc_hw, ~0, + brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE)); /* wait for ucode to self-suspend after auto-init */ @@ -2252,20 +2232,20 @@ static void wlc_coreinit(struct wlc_info *wlc) wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-" "suspend!\n", wlc_hw->unit); - wlc_gpio_init(wlc); + brcms_c_gpio_init(wlc); sflags = ai_core_sflags(wlc_hw->sih, 0, 0); if (D11REV_IS(wlc_hw->corerev, 23)) { - if (WLCISNPHY(wlc_hw->band)) - wlc_write_inits(wlc_hw, d11n0initvals16); + if (BRCMS_ISNPHY(wlc_hw->band)) + brcms_c_write_inits(wlc_hw, d11n0initvals16); else wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" " %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } else if (D11REV_IS(wlc_hw->corerev, 24)) { - if (WLCISLCNPHY(wlc_hw->band)) { - wlc_write_inits(wlc_hw, d11lcn0initvals24); + if (BRCMS_ISLCNPHY(wlc_hw->band)) { + brcms_c_write_inits(wlc_hw, d11lcn0initvals24); } else { wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" " %d\n", __func__, wlc_hw->unit, @@ -2278,21 +2258,21 @@ static void wlc_coreinit(struct wlc_info *wlc) /* For old ucode, txfifo sizes needs to be modified(increased) */ if (fifosz_fixup == true) { - wlc_corerev_fifofixup(wlc_hw); + brcms_b_corerev_fifofixup(wlc_hw); } /* check txfifo allocations match between ucode and driver */ - buf[TX_AC_BE_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE0); + buf[TX_AC_BE_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE0); if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) { i = TX_AC_BE_FIFO; err = -1; } - buf[TX_AC_VI_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE1); + buf[TX_AC_VI_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE1); if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) { i = TX_AC_VI_FIFO; err = -1; } - buf[TX_AC_BK_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE2); + buf[TX_AC_BK_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE2); buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff; buf[TX_AC_BK_FIFO] &= 0xff; if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) { @@ -2303,7 +2283,7 @@ static void wlc_coreinit(struct wlc_info *wlc) i = TX_AC_VO_FIFO; err = -1; } - buf[TX_BCMC_FIFO] = wlc_bmac_read_shm(wlc_hw, M_FIFOSIZE3); + buf[TX_BCMC_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE3); buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff; buf[TX_BCMC_FIFO] &= 0xff; if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) { @@ -2326,14 +2306,14 @@ static void wlc_coreinit(struct wlc_info *wlc) /* band-specific inits done by wlc_bsinit() */ /* Set up frame burst size and antenna swap threshold init values */ - wlc_bmac_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST); - wlc_bmac_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT); + brcms_b_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST); + brcms_b_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT); /* enable one rx interrupt per received frame */ W_REG(®s->intrcvlazy[0], (1 << IRL_FC_SHIFT)); /* set the station mode (BSS STA) */ - wlc_bmac_mctrl(wlc_hw, + brcms_b_mctrl(wlc_hw, (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP), (MCTL_INFRA | MCTL_DISCARD_PMQ)); @@ -2347,19 +2327,19 @@ static void wlc_coreinit(struct wlc_info *wlc) W_REG(®s->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK); /* allow the MAC to control the PHY clock (dynamic on/off) */ - wlc_bmac_macphyclk_set(wlc_hw, ON); + brcms_b_macphyclk_set(wlc_hw, ON); /* program dynamic clock control fast powerup delay register */ wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih); W_REG(®s->scc_fastpwrup_dly, wlc->fastpwrup_dly); /* tell the ucode the corerev */ - wlc_bmac_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev); + brcms_b_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev); /* tell the ucode MAC capabilities */ - wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_L, + brcms_b_write_shm(wlc_hw, M_MACHW_CAP_L, (u16) (wlc_hw->machwcap & 0xffff)); - wlc_bmac_write_shm(wlc_hw, M_MACHW_CAP_H, + brcms_b_write_shm(wlc_hw, M_MACHW_CAP_H, (u16) ((wlc_hw-> machwcap >> 16) & 0xffff)); @@ -2372,8 +2352,8 @@ static void wlc_coreinit(struct wlc_info *wlc) W_REG(®s->objdata, wlc_hw->LRL); /* write rate fallback retry limits */ - wlc_bmac_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL); - wlc_bmac_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL); + brcms_b_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL); + brcms_b_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL); AND_REG(®s->ifs_ctl, 0x0FFF); W_REG(®s->ifs_aifsn, EDCF_AIFSN_MIN); @@ -2405,7 +2385,7 @@ static void wlc_coreinit(struct wlc_info *wlc) * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889 */ -void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode) +void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode) { d11regs_t *regs; regs = wlc_hw->regs; @@ -2422,7 +2402,7 @@ void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode) W_REG(®s->tsf_clk_frac_l, 0x8889); W_REG(®s->tsf_clk_frac_h, 0x8); } - } else if (WLCISLCNPHY(wlc_hw->band)) { + } else if (BRCMS_ISLCNPHY(wlc_hw->band)) { if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */ W_REG(®s->tsf_clk_frac_l, 0x7CE0); W_REG(®s->tsf_clk_frac_h, 0xC); @@ -2434,16 +2414,16 @@ void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode) } /* Initialize GPIOs that are controlled by D11 core */ -static void wlc_gpio_init(struct wlc_info *wlc) +static void brcms_c_gpio_init(struct brcms_c_info *wlc) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; d11regs_t *regs; u32 gc, gm; regs = wlc_hw->regs; /* use GPIO select 0 to get all gpio signals from the gpio out reg */ - wlc_bmac_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0); + brcms_b_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0); /* * Common GPIO setup: @@ -2458,10 +2438,10 @@ static void wlc_gpio_init(struct wlc_info *wlc) /* Allocate GPIOs for mimo antenna diversity feature */ if (wlc_hw->antsel_type == ANTSEL_2x3) { /* Enable antenna diversity, use 2x3 mode */ - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, - MHF3_ANTSEL_EN, WLC_BAND_ALL); - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, - MHF3_ANTSEL_MODE, WLC_BAND_ALL); + brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, + MHF3_ANTSEL_EN, BRCM_BAND_ALL); + brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, + MHF3_ANTSEL_MODE, BRCM_BAND_ALL); /* init superswitch control */ wlc_phy_antsel_init(wlc_hw->band->pi, false); @@ -2478,13 +2458,13 @@ static void wlc_gpio_init(struct wlc_info *wlc) (BOARD_GPIO_12 | BOARD_GPIO_13)); /* Enable antenna diversity, use 2x4 mode */ - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, - MHF3_ANTSEL_EN, WLC_BAND_ALL); - wlc_bmac_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0, - WLC_BAND_ALL); + brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, + MHF3_ANTSEL_EN, BRCM_BAND_ALL); + brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0, + BRCM_BAND_ALL); /* Configure the desired clock to be 4Mhz */ - wlc_bmac_write_shm(wlc_hw, M_ANTSEL_CLKDIV, + brcms_b_write_shm(wlc_hw, M_ANTSEL_CLKDIV, ANTSEL_CLKDIV_4MHZ); } @@ -2496,17 +2476,17 @@ static void wlc_gpio_init(struct wlc_info *wlc) ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY); } -static void wlc_ucode_download(struct wlc_hw_info *wlc_hw) +static void brcms_ucode_download(struct brcms_hardware *wlc_hw) { - struct wlc_info *wlc; + struct brcms_c_info *wlc; wlc = wlc_hw->wlc; if (wlc_hw->ucode_loaded) return; if (D11REV_IS(wlc_hw->corerev, 23)) { - if (WLCISNPHY(wlc_hw->band)) { - wlc_ucode_write(wlc_hw, bcm43xx_16_mimo, + if (BRCMS_ISNPHY(wlc_hw->band)) { + brcms_ucode_write(wlc_hw, bcm43xx_16_mimo, bcm43xx_16_mimosz); wlc_hw->ucode_loaded = true; } else @@ -2514,8 +2494,8 @@ static void wlc_ucode_download(struct wlc_hw_info *wlc_hw) "corerev %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } else if (D11REV_IS(wlc_hw->corerev, 24)) { - if (WLCISLCNPHY(wlc_hw->band)) { - wlc_ucode_write(wlc_hw, bcm43xx_24_lcn, + if (BRCMS_ISLCNPHY(wlc_hw->band)) { + brcms_ucode_write(wlc_hw, bcm43xx_24_lcn, bcm43xx_24_lcnsz); wlc_hw->ucode_loaded = true; } else { @@ -2526,7 +2506,7 @@ static void wlc_ucode_download(struct wlc_hw_info *wlc_hw) } } -static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], +static void brcms_ucode_write(struct brcms_hardware *wlc_hw, const u32 ucode[], const uint nbytes) { d11regs_t *regs = wlc_hw->regs; uint i; @@ -2542,7 +2522,7 @@ static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], W_REG(®s->objdata, ucode[i]); } -static void wlc_write_inits(struct wlc_hw_info *wlc_hw, +static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, const struct d11init *inits) { int i; @@ -2562,24 +2542,24 @@ static void wlc_write_inits(struct wlc_hw_info *wlc_hw, } } -static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw) +static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw) { u16 phyctl; u16 phytxant = wlc_hw->bmac_phytxant; u16 mask = PHY_TXC_ANT_MASK; /* set the Probe Response frame phy control word */ - phyctl = wlc_bmac_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS); + phyctl = brcms_b_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS); phyctl = (phyctl & ~mask) | phytxant; - wlc_bmac_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl); + brcms_b_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl); /* set the Response (ACK/CTS) frame phy control word */ - phyctl = wlc_bmac_read_shm(wlc_hw, M_RSP_PCTLWD); + phyctl = brcms_b_read_shm(wlc_hw, M_RSP_PCTLWD); phyctl = (phyctl & ~mask) | phytxant; - wlc_bmac_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl); + brcms_b_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl); } -void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant) +void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant) { /* update sw state */ wlc_hw->bmac_phytxant = phytxant; @@ -2587,16 +2567,16 @@ void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant) /* push to ucode if up */ if (!wlc_hw->up) return; - wlc_ucode_txant_set(wlc_hw); + brcms_c_ucode_txant_set(wlc_hw); } -u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw) +u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw) { return (u16) wlc_hw->wlc->stf->txant; } -void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, u8 antsel_type) +void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type) { wlc_hw->antsel_type = antsel_type; @@ -2604,7 +2584,7 @@ void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, u8 antsel_type) wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); } -void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) +void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) { bool fatal = false; uint unit; @@ -2660,7 +2640,7 @@ void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) } if (fatal) { - wlc_fatal_error(wlc_hw->wlc); /* big hammer */ + brcms_c_fatal_error(wlc_hw->wlc); /* big hammer */ break; } else W_REG(®s->intctrlregs[idx].intstatus, @@ -2668,9 +2648,9 @@ void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) } } -void wlc_intrson(struct wlc_info *wlc) +void brcms_c_intrson(struct brcms_c_info *wlc) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; wlc->macintmask = wlc->defmacintmask; W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); } @@ -2680,25 +2660,25 @@ void wlc_intrson(struct wlc_info *wlc) * but also because per-port code may require sync with valid interrupt. */ -static u32 wlc_wlintrsoff(struct wlc_info *wlc) +static u32 brcms_c_wlintrsoff(struct brcms_c_info *wlc) { if (!wlc->hw->up) return 0; - return wl_intrsoff(wlc->wl); + return brcms_intrsoff(wlc->wl); } -static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask) +static void brcms_c_wlintrsrestore(struct brcms_c_info *wlc, u32 macintmask) { if (!wlc->hw->up) return; - wl_intrsrestore(wlc->wl, macintmask); + brcms_intrsrestore(wlc->wl, macintmask); } -u32 wlc_intrsoff(struct wlc_info *wlc) +u32 brcms_c_intrsoff(struct brcms_c_info *wlc) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; u32 macintmask; if (!wlc_hw->clk) @@ -2715,9 +2695,9 @@ u32 wlc_intrsoff(struct wlc_info *wlc) return wlc->macintstatus ? 0 : macintmask; } -void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) +void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; if (!wlc_hw->clk) return; @@ -2725,43 +2705,44 @@ void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); } -static void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) +static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, mbool flags) { u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; if (on) { /* suspend tx fifos */ - wlc_bmac_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); - wlc_bmac_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); - wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO); - wlc_bmac_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO); + brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); + brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); + brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO); + brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO); /* zero the address match register so we do not send ACKs */ - wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, + brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, null_ether_addr); } else { /* resume tx fifos */ if (!wlc_hw->wlc->tx_suspended) { - wlc_bmac_tx_fifo_resume(wlc_hw, TX_DATA_FIFO); + brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO); } - wlc_bmac_tx_fifo_resume(wlc_hw, TX_CTL_FIFO); - wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO); - wlc_bmac_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO); + brcms_b_tx_fifo_resume(wlc_hw, TX_CTL_FIFO); + brcms_b_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO); + brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO); /* Restore address */ - wlc_bmac_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, + brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, wlc_hw->etheraddr); } wlc_phy_mute_upd(wlc_hw->band->pi, on, flags); if (on) - wlc_ucode_mute_override_set(wlc_hw); + brcms_c_ucode_mute_override_set(wlc_hw); else - wlc_ucode_mute_override_clear(wlc_hw); + brcms_c_ucode_mute_override_clear(wlc_hw); } -int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks) +int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, + uint *blocks) { if (fifo >= NFIFO) return -EINVAL; @@ -2771,7 +2752,7 @@ int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks) return 0; } -/* wlc_bmac_tx_fifo_suspended: +/* brcms_b_tx_fifo_suspended: * Check the MAC's tx suspend status for a tx fifo. * * When the MAC acknowledges a tx suspend, it indicates that no more @@ -2780,7 +2761,8 @@ int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks) * be pulling data into a tx fifo, by the time the MAC acks the suspend * request. */ -static bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo) +static bool brcms_b_tx_fifo_suspended(struct brcms_hardware *wlc_hw, + uint tx_fifo) { /* check that a suspend has been requested and is no longer pending */ @@ -2799,7 +2781,8 @@ static bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo) return false; } -static void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo) +static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw, + uint tx_fifo) { u8 fifo = 1 << tx_fifo; @@ -2811,7 +2794,8 @@ static void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo) /* force the core awake only if not already */ if (wlc_hw->suspended_fifos == 0) - wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_TXFIFO); + brcms_c_ucode_wake_override_set(wlc_hw, + BRCMS_WAKE_OVERRIDE_TXFIFO); wlc_hw->suspended_fifos |= fifo; @@ -2820,20 +2804,22 @@ static void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo) * which may result in mismatch between ucode and driver * so suspend the mac before suspending the FIFO */ - if (WLC_PHY_11N_CAP(wlc_hw->band)) - wlc_suspend_mac_and_wait(wlc_hw->wlc); + if (BRCMS_PHY_11N_CAP(wlc_hw->band)) + brcms_c_suspend_mac_and_wait(wlc_hw->wlc); dma_txsuspend(wlc_hw->di[tx_fifo]); - if (WLC_PHY_11N_CAP(wlc_hw->band)) - wlc_enable_mac(wlc_hw->wlc); + if (BRCMS_PHY_11N_CAP(wlc_hw->band)) + brcms_c_enable_mac(wlc_hw->wlc); } } -static void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo) +static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, + uint tx_fifo) { - /* BMAC_NOTE: WLC_TX_FIFO_ENAB is done in wlc_dpc() for DMA case but need to be done - * here for PIO otherwise the watchdog will catch the inconsistency and fire + /* BMAC_NOTE: BRCMS_TX_FIFO_ENAB is done in brcms_c_dpc() for DMA case + * but need to be done here for PIO otherwise the watchdog will catch + * the inconsistency and fire */ /* Two clients of this code, 11h Quiet period and scanning. */ if (wlc_hw->di[tx_fifo]) @@ -2845,8 +2831,8 @@ static void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo) else { wlc_hw->suspended_fifos &= ~(1 << tx_fifo); if (wlc_hw->suspended_fifos == 0) - wlc_ucode_wake_override_clear(wlc_hw, - WLC_WAKE_OVERRIDE_TXFIFO); + brcms_c_ucode_wake_override_clear(wlc_hw, + BRCMS_WAKE_OVERRIDE_TXFIFO); } } @@ -2858,9 +2844,9 @@ static void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo) * 0 if the interrupt is not for us, or we are in some special cases; * device interrupt status bits otherwise. */ -static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) +static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 macintstatus; @@ -2915,7 +2901,7 @@ static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) /* Update wlc->macintstatus and wlc->intstatus[]. */ /* Return true if they are updated successfully. false otherwise */ -bool wlc_intrsupd(struct wlc_info *wlc) +bool brcms_c_intrsupd(struct brcms_c_info *wlc) { u32 macintstatus; @@ -2935,12 +2921,12 @@ bool wlc_intrsupd(struct wlc_info *wlc) /* * First-level interrupt processing. * Return true if this was our interrupt, false otherwise. - * *wantdpc will be set to true if further wlc_dpc() processing is required, + * *wantdpc will be set to true if further brcms_c_dpc() processing is required, * false otherwise. */ -bool wlc_isr(struct wlc_info *wlc, bool *wantdpc) +bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; u32 macintstatus; *wantdpc = false; @@ -2969,7 +2955,8 @@ bool wlc_isr(struct wlc_info *wlc, bool *wantdpc) } static bool -wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2) +brcms_b_dotxstatus(struct brcms_hardware *wlc_hw, struct tx_status *txs, + u32 s2) { /* discard intermediate indications for ucode with one legitimate case: * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent @@ -2981,19 +2968,19 @@ wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2) return false; } - return wlc_dotxstatus(wlc_hw->wlc, txs, s2); + return brcms_c_dotxstatus(wlc_hw->wlc, txs, s2); } /* process tx completion events in BMAC * Return true if more tx status need to be processed. false otherwise. */ static bool -wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) +brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) { bool morepending = false; - struct wlc_info *wlc = wlc_hw->wlc; + struct brcms_c_info *wlc = wlc_hw->wlc; d11regs_t *regs; - tx_status_t txstatus, *txs; + struct tx_status txstatus, *txs; u32 s1, s2; uint n = 0; /* @@ -3023,7 +3010,7 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT; txs->lasttxtime = 0; - *fatal = wlc_bmac_dotxstatus(wlc_hw, txs, s2); + *fatal = brcms_b_dotxstatus(wlc_hw, txs, s2); /* !give others some time to run! */ if (++n >= max_tx_num) @@ -3037,14 +3024,14 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) morepending = true; if (!pktq_empty(&wlc->pkt_queue->q)) - wlc_send_q(wlc); + brcms_c_send_q(wlc); return morepending; } -void wlc_suspend_mac_and_wait(struct wlc_info *wlc) +void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 mc, mi; struct wiphy *wiphy = wlc->wiphy; @@ -3060,14 +3047,14 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) return; /* force the core awake */ - wlc_ucode_wake_override_set(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); + brcms_c_ucode_wake_override_set(wlc_hw, BRCMS_WAKE_OVERRIDE_MACSUSPEND); mc = R_REG(®s->maccontrol); if (mc == 0xffffffff) { wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return; } WARN_ON(mc & MCTL_PSM_JMP_0); @@ -3078,20 +3065,20 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) if (mi == 0xffffffff) { wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return; } WARN_ON(mi & MI_MACSSPNDD); - wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, 0); + brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, 0); SPINWAIT(!(R_REG(®s->macintstatus) & MI_MACSSPNDD), - WLC_MAX_MAC_SUSPEND); + BRCMS_MAX_MAC_SUSPEND); if (!(R_REG(®s->macintstatus) & MI_MACSSPNDD)) { wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" " and MI_MACSSPNDD is still not on.\n", - wlc_hw->unit, WLC_MAX_MAC_SUSPEND); + wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND); wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " "psm_brc 0x%04x\n", wlc_hw->unit, R_REG(®s->psmdebug), @@ -3103,7 +3090,7 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) if (mc == 0xffffffff) { wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return; } WARN_ON(mc & MCTL_PSM_JMP_0); @@ -3111,9 +3098,9 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) WARN_ON(mc & MCTL_EN_MAC); } -void wlc_enable_mac(struct wlc_info *wlc) +void brcms_c_enable_mac(struct brcms_c_info *wlc) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 mc, mi; @@ -3132,7 +3119,7 @@ void wlc_enable_mac(struct wlc_info *wlc) WARN_ON(mc & MCTL_EN_MAC); WARN_ON(!(mc & MCTL_PSM_RUN)); - wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC); + brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC); W_REG(®s->macintstatus, MI_MACSSPNDD); mc = R_REG(®s->maccontrol); @@ -3143,44 +3130,46 @@ void wlc_enable_mac(struct wlc_info *wlc) mi = R_REG(®s->macintstatus); WARN_ON(mi & MI_MACSSPNDD); - wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); + brcms_c_ucode_wake_override_clear(wlc_hw, + BRCMS_WAKE_OVERRIDE_MACSUSPEND); } -static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw) +static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw) { u8 rate; u8 rates[8] = { - WLC_RATE_6M, WLC_RATE_9M, WLC_RATE_12M, WLC_RATE_18M, - WLC_RATE_24M, WLC_RATE_36M, WLC_RATE_48M, WLC_RATE_54M + BRCM_RATE_6M, BRCM_RATE_9M, BRCM_RATE_12M, BRCM_RATE_18M, + BRCM_RATE_24M, BRCM_RATE_36M, BRCM_RATE_48M, BRCM_RATE_54M }; u16 entry_ptr; u16 pctl1; uint i; - if (!WLC_PHY_11N_CAP(wlc_hw->band)) + if (!BRCMS_PHY_11N_CAP(wlc_hw->band)) return; /* walk the phy rate table and update the entries */ for (i = 0; i < ARRAY_SIZE(rates); i++) { rate = rates[i]; - entry_ptr = wlc_bmac_ofdm_ratetable_offset(wlc_hw, rate); + entry_ptr = brcms_b_ofdm_ratetable_offset(wlc_hw, rate); /* read the SHM Rate Table entry OFDM PCTL1 values */ pctl1 = - wlc_bmac_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS); + brcms_b_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS); /* modify the value */ pctl1 &= ~PHY_TXC1_MODE_MASK; pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT); /* Update the SHM Rate Table entry OFDM PCTL1 values */ - wlc_bmac_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS, + brcms_b_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS, pctl1); } } -static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, u8 rate) +static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw, + u8 rate) { uint i; u8 plcp_rate = 0; @@ -3190,14 +3179,14 @@ static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, u8 rate) }; /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */ const struct plcp_signal_rate_lookup rate_lookup[] = { - {WLC_RATE_6M, 0xB}, - {WLC_RATE_9M, 0xF}, - {WLC_RATE_12M, 0xA}, - {WLC_RATE_18M, 0xE}, - {WLC_RATE_24M, 0x9}, - {WLC_RATE_36M, 0xD}, - {WLC_RATE_48M, 0x8}, - {WLC_RATE_54M, 0xC} + {BRCM_RATE_6M, 0xB}, + {BRCM_RATE_9M, 0xF}, + {BRCM_RATE_12M, 0xA}, + {BRCM_RATE_18M, 0xE}, + {BRCM_RATE_24M, 0x9}, + {BRCM_RATE_36M, 0xD}, + {BRCM_RATE_48M, 0x8}, + {BRCM_RATE_54M, 0xC} }; for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) { @@ -3210,19 +3199,19 @@ static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, u8 rate) /* Find the SHM pointer to the rate table entry by looking in the * Direct-map Table */ - return 2 * wlc_bmac_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2)); + return 2 * brcms_b_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2)); } -void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode) +void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode) { wlc_hw->hw_stf_ss_opmode = stf_mode; if (wlc_hw->clk) - wlc_upd_ofdm_pctl1_table(wlc_hw); + brcms_upd_ofdm_pctl1_table(wlc_hw); } void -wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, +brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr, u32 *tsf_h_ptr) { d11regs_t *regs = wlc_hw->regs; @@ -3234,7 +3223,7 @@ wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, return; } -static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) +static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw) { d11regs_t *regs; u32 w, val; @@ -3299,7 +3288,7 @@ static bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) #define PHYPLL_WAIT_US 100000 -void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) +void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) { d11regs_t *regs; u32 tmp; @@ -3351,7 +3340,7 @@ void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) } } -void wlc_coredisable(struct wlc_hw_info *wlc_hw) +void brcms_c_coredisable(struct brcms_hardware *wlc_hw) { bool dev_gone; @@ -3372,7 +3361,7 @@ void wlc_coredisable(struct wlc_hw_info *wlc_hw) wlc_phy_anacore(wlc_hw->band->pi, OFF); /* turn off PHYPLL to save power */ - wlc_bmac_core_phypll_ctl(wlc_hw, false); + brcms_b_core_phypll_ctl(wlc_hw, false); /* No need to set wlc->pub->radio_active = OFF * because this function needs down capability and @@ -3389,7 +3378,7 @@ void wlc_coredisable(struct wlc_hw_info *wlc_hw) } /* power both the pll and external oscillator on/off */ -static void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want) +static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want) { BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want); @@ -3408,9 +3397,9 @@ static void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want) } } -static void wlc_flushqueues(struct wlc_info *wlc) +static void brcms_c_flushqueues(struct brcms_c_info *wlc) { - struct wlc_hw_info *wlc_hw = wlc->hw; + struct brcms_hardware *wlc_hw = wlc->hw; uint i; wlc->txpend16165war = 0; @@ -3418,7 +3407,7 @@ static void wlc_flushqueues(struct wlc_info *wlc) /* free any posted tx packets */ for (i = 0; i < NFIFO; i++) if (wlc_hw->di[i]) { - dma_txreclaim(wlc_hw->di[i], HNDDMA_RANGE_ALL); + dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL); TXPKTPENDCLR(wlc, i); BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i); } @@ -3427,18 +3416,18 @@ static void wlc_flushqueues(struct wlc_info *wlc) dma_rxreclaim(wlc_hw->di[RX_FIFO]); } -u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset) +u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset) { - return wlc_bmac_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL); + return brcms_b_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL); } -void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v) +void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v) { - wlc_bmac_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL); + brcms_b_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL); } static u16 -wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel) +brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel) { d11regs_t *regs = wlc_hw->regs; volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; @@ -3457,7 +3446,8 @@ wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel) } static void -wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, u16 v, u32 sel) +brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v, + u32 sel) { d11regs_t *regs = wlc_hw->regs; volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; @@ -3478,8 +3468,8 @@ wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, u16 v, u32 sel) * 'sel' selects the type of memory */ void -wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf, - int len, u32 sel) +brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset, + const void *buf, int len, u32 sel) { u16 v; const u8 *p = (const u8 *)buf; @@ -3490,7 +3480,7 @@ wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf, for (i = 0; i < len; i += 2) { v = p[i] | (p[i + 1] << 8); - wlc_bmac_write_objmem(wlc_hw, offset + i, v, sel); + brcms_b_write_objmem(wlc_hw, offset + i, v, sel); } } @@ -3500,7 +3490,7 @@ wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf, * 'sel' selects the type of memory */ void -wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf, +brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf, int len, u32 sel) { u16 v; @@ -3511,13 +3501,14 @@ wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf, return; for (i = 0; i < len; i += 2) { - v = wlc_bmac_read_objmem(wlc_hw, offset + i, sel); + v = brcms_b_read_objmem(wlc_hw, offset + i, sel); p[i] = v & 0xFF; p[i + 1] = (v >> 8) & 0xFF; } } -void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len) +void brcms_b_copyfrom_vars(struct brcms_hardware *wlc_hw, char **buf, + uint *len) { BCMMSG(wlc_hw->wlc->wiphy, "nvram vars totlen=%d\n", wlc_hw->vars_size); @@ -3526,7 +3517,7 @@ void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len) *len = wlc_hw->vars_size; } -void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL) +void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw, u16 SRL, u16 LRL) { wlc_hw->SRL = SRL; wlc_hw->LRL = LRL; @@ -3544,7 +3535,7 @@ void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL) } } -void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) +void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, mbool req_bit) { if (set) { if (mboolisset(wlc_hw->pllreq, req_bit)) @@ -3552,9 +3543,9 @@ void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) mboolset(wlc_hw->pllreq, req_bit); - if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) { + if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) { if (!wlc_hw->sbclk) { - wlc_bmac_xtal(wlc_hw, ON); + brcms_b_xtal(wlc_hw, ON); } } } else { @@ -3563,9 +3554,9 @@ void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) mboolclr(wlc_hw->pllreq, req_bit); - if (mboolisset(wlc_hw->pllreq, WLC_PLLREQ_FLIP)) { + if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) { if (wlc_hw->sbclk) { - wlc_bmac_xtal(wlc_hw, OFF); + brcms_b_xtal(wlc_hw, OFF); } } } @@ -3573,13 +3564,12 @@ void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) return; } -u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate) +u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) { u16 table_ptr; u8 phy_rate, index; /* get the phy specific rate encoding for the PLCP SIGNAL field */ - /* XXX4321 fixup needed ? */ if (IS_OFDM(rate)) table_ptr = M_RT_DIRMAP_A; else @@ -3588,16 +3578,16 @@ u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate) /* for a given rate, the LS-nibble of the PLCP SIGNAL field is * the index into the rate table. */ - phy_rate = rate_info[rate] & WLC_RATE_MASK; + phy_rate = rate_info[rate] & BRCMS_RATE_MASK; index = phy_rate & 0xf; /* Find the SHM pointer to the rate table entry by looking in the * Direct-map Table */ - return 2 * wlc_bmac_read_shm(wlc_hw, table_ptr + (index * 2)); + return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2)); } -void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail) +void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail) { wlc_hw->antsel_avail = antsel_avail; } diff --git a/drivers/staging/brcm80211/brcmsmac/bmac.h b/drivers/staging/brcm80211/brcmsmac/bmac.h new file mode 100644 index 000000000000..3c9ad4f3bd22 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/bmac.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef _BRCM_BOTTOM_MAC_H_ +#define _BRCM_BOTTOM_MAC_H_ + +#include +#include "types.h" + +/* dup state between BMAC(struct brcms_hardware) and HIGH(struct brcms_c_info) + driver */ +struct brcms_b_state { + u32 machwcap; /* mac hw capibility */ + u32 preamble_ovr; /* preamble override */ +}; + +enum { + IOV_BMAC_DIAG, + IOV_BMAC_SBGPIOTIMERVAL, + IOV_BMAC_SBGPIOOUT, + IOV_BMAC_CCGPIOCTRL, /* CC GPIOCTRL REG */ + IOV_BMAC_CCGPIOOUT, /* CC GPIOOUT REG */ + IOV_BMAC_CCGPIOOUTEN, /* CC GPIOOUTEN REG */ + IOV_BMAC_CCGPIOIN, /* CC GPIOIN REG */ + IOV_BMAC_WPSGPIO, /* WPS push button GPIO pin */ + IOV_BMAC_OTPDUMP, + IOV_BMAC_OTPSTAT, + IOV_BMAC_PCIEASPM, /* obfuscation clkreq/aspm control */ + IOV_BMAC_PCIEADVCORRMASK, /* advanced correctable error mask */ + IOV_BMAC_PCIECLKREQ, /* PCIE 1.1 clockreq enab support */ + IOV_BMAC_PCIELCREG, /* PCIE LCREG */ + IOV_BMAC_SBGPIOTIMERMASK, + IOV_BMAC_RFDISABLEDLY, + IOV_BMAC_PCIEREG, /* PCIE REG */ + IOV_BMAC_PCICFGREG, /* PCI Config register */ + IOV_BMAC_PCIESERDESREG, /* PCIE SERDES REG (dev, 0}offset) */ + IOV_BMAC_PCIEGPIOOUT, /* PCIEOUT REG */ + IOV_BMAC_PCIEGPIOOUTEN, /* PCIEOUTEN REG */ + IOV_BMAC_PCIECLKREQENCTRL, /* clkreqenctrl REG (PCIE REV > 6.0 */ + IOV_BMAC_DMALPBK, + IOV_BMAC_CCREG, + IOV_BMAC_COREREG, + IOV_BMAC_SDCIS, + IOV_BMAC_SDIO_DRIVE, + IOV_BMAC_OTPW, + IOV_BMAC_NVOTPW, + IOV_BMAC_SROM, + IOV_BMAC_SRCRC, + IOV_BMAC_CIS_SOURCE, + IOV_BMAC_CISVAR, + IOV_BMAC_OTPLOCK, + IOV_BMAC_OTP_CHIPID, + IOV_BMAC_CUSTOMVAR1, + IOV_BMAC_BOARDFLAGS, + IOV_BMAC_BOARDFLAGS2, + IOV_BMAC_WPSLED, + IOV_BMAC_NVRAM_SOURCE, + IOV_BMAC_OTP_RAW_READ, + IOV_BMAC_LAST +}; + +extern int brcms_b_attach(struct brcms_c_info *wlc, u16 vendor, u16 device, + uint unit, bool piomode, void *regsva, uint bustype, + void *btparam); +extern int brcms_b_detach(struct brcms_c_info *wlc); +extern void brcms_b_watchdog(void *arg); + +/* up/down, reset, clk */ +extern void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, + uint offset, const void *buf, int len, + u32 sel); +extern void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, + void *buf, int len, u32 sel); +#define brcms_b_copyfrom_shm(wlc_hw, offset, buf, len) \ + brcms_b_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) +#define brcms_b_copyto_shm(wlc_hw, offset, buf, len) \ + brcms_b_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) + +extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw); +extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on); +extern void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk); +extern void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk); +extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw); +extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags); +extern void brcms_b_reset(struct brcms_hardware *wlc_hw); +extern void brcms_b_init(struct brcms_hardware *wlc_hw, chanspec_t chanspec, + bool mute); +extern int brcms_b_up_prep(struct brcms_hardware *wlc_hw); +extern int brcms_b_up_finish(struct brcms_hardware *wlc_hw); +extern int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw); +extern int brcms_b_down_finish(struct brcms_hardware *wlc_hw); +extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode); + +/* chanspec, ucode interface */ +extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, + chanspec_t chanspec, + bool mute, struct txpwr_limits *txpwr); + +extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, + uint *blocks); +extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, + u16 val, int bands); +extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val); +extern u16 brcms_b_mhf_get(struct brcms_hardware *wlc_hw, u8 idx, int bands); +extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant); +extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw); +extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, + u8 antsel_type); +extern int brcms_b_state_get(struct brcms_hardware *wlc_hw, + struct brcms_b_state *state); +extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, + u16 v); +extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset); +extern void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, + int offset, int len, void *buf); +extern void brcms_b_copyfrom_vars(struct brcms_hardware *wlc_hw, char **buf, + uint *len); + +extern void brcms_b_hw_etheraddr(struct brcms_hardware *wlc_hw, + u8 *ea); + +extern bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw); +extern void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, + bool shortslot); +extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, + u8 stf_mode); + +extern void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw); + +extern void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw, + u32 override_bit); +extern void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw, + u32 override_bit); + +extern void brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, + int match_reg_offset, + const u8 *addr); +extern void brcms_b_write_hw_bcntemplates(struct brcms_hardware *wlc_hw, + void *bcn, int len, bool both); + +extern void brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr, + u32 *tsf_h_ptr); +extern void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin); +extern void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax); + +extern void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw, u16 SRL, + u16 LRL); + +extern void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw); + + +/* API for BMAC driver (e.g. wlc_phy.c etc) */ + +extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw); +extern void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, + mbool req_bit); +extern void brcms_b_hw_up(struct brcms_hardware *wlc_hw); +extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate); +extern void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, + u32 antsel_avail); + +#endif /* _BRCM_BOTTOM_MAC_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c b/drivers/staging/brcm80211/brcmsmac/channel.c similarity index 69% rename from drivers/staging/brcm80211/brcmsmac/wlc_channel.c rename to drivers/staging/brcm80211/brcmsmac/channel.c index a3a2bf9b4f12..f59693e1d8a2 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.c +++ b/drivers/staging/brcm80211/brcmsmac/channel.c @@ -14,109 +14,99 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include #include -#include -#include +#include -#include -#include -#include -#include -#include -#include +#include +#include "pub.h" +#include "phy/phy_hal.h" +#include "bmac.h" +#include "main.h" +#include "stf.h" +#include "channel.h" -#include "wlc_types.h" -#include "d11.h" -#include "wlc_cfg.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_bmac.h" -#include "wlc_rate.h" -#include "wlc_channel.h" -#include "wlc_main.h" -#include "wlc_stf.h" -#include "wl_dbg.h" - -#define VALID_CHANNEL20_DB(wlc, val) wlc_valid_channel20_db((wlc)->cmi, val) +#define VALID_CHANNEL20_DB(wlc, val) brcms_c_valid_channel20_db((wlc)->cmi, val) #define VALID_CHANNEL20_IN_BAND(wlc, bandunit, val) \ - wlc_valid_channel20_in_band((wlc)->cmi, bandunit, val) -#define VALID_CHANNEL20(wlc, val) wlc_valid_channel20((wlc)->cmi, val) + brcms_c_valid_channel20_in_band((wlc)->cmi, bandunit, val) +#define VALID_CHANNEL20(wlc, val) brcms_c_valid_channel20((wlc)->cmi, val) -typedef struct wlc_cm_band { - u8 locale_flags; /* locale_info_t flags */ +struct brcms_cm_band { + u8 locale_flags; /* struct locale_info flags */ chanvec_t valid_channels; /* List of valid channels in the country */ const chanvec_t *restricted_channels; /* List of restricted use channels */ const chanvec_t *radar_channels; /* List of radar sensitive channels */ u8 PAD[8]; -} wlc_cm_band_t; +}; -struct wlc_cm_info { - struct wlc_pub *pub; - struct wlc_info *wlc; - char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */ +struct brcms_cm_info { + struct brcms_pub *pub; + struct brcms_c_info *wlc; + char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */ uint srom_regrev; /* Regulatory Rev for the SROM ccode */ - const country_info_t *country; /* current country def */ - char ccode[WLC_CNTRY_BUF_SZ]; /* current internal Country Code */ + const struct country_info *country; /* current country def */ + char ccode[BRCM_CNTRY_BUF_SZ]; /* current internal Country Code */ uint regrev; /* current Regulatory Revision */ - char country_abbrev[WLC_CNTRY_BUF_SZ]; /* current advertised ccode */ - wlc_cm_band_t bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */ + char country_abbrev[BRCM_CNTRY_BUF_SZ]; /* current advertised ccode */ + /* per-band state (one per phy/radio) */ + struct brcms_cm_band bandstate[MAXBANDS]; /* quiet channels currently for radar sensitivity or 11h support */ chanvec_t quiet_channels; /* channels on which we cannot transmit */ }; -static int wlc_channels_init(wlc_cm_info_t *wlc_cm, - const country_info_t *country); -static void wlc_set_country_common(wlc_cm_info_t *wlc_cm, +static int brcms_c_channels_init(struct brcms_cm_info *wlc_cm, + const struct country_info *country); +static void brcms_c_set_country_common(struct brcms_cm_info *wlc_cm, const char *country_abbrev, const char *ccode, uint regrev, - const country_info_t *country); -static int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode); -static int wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, + const struct country_info *country); +static int brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, + const char *ccode); +static int brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm, const char *country_abbrev, const char *ccode, int regrev); -static int wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode, - char *mapped_ccode, uint *mapped_regrev); -static const country_info_t *wlc_country_lookup_direct(const char *ccode, - uint regrev); -static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, - const char *ccode, - char *mapped_ccode, - uint *mapped_regrev); -static void wlc_channels_commit(wlc_cm_info_t *wlc_cm); -static void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm); -static bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec); -static bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val); -static bool wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, - uint val); -static bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val); -static const country_info_t *wlc_country_lookup(struct wlc_info *wlc, - const char *ccode); -static void wlc_locale_get_channels(const locale_info_t *locale, +static int brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, + const char *ccode, + char *mapped_ccode, uint *mapped_regrev); + +static const struct country_info * +brcms_c_country_lookup_direct(const char *ccode, uint regrev); + +static const struct country_info * +brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, + const char *ccode, char *mapped_ccode, + uint *mapped_regrev); + +static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm); +static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm); +static bool brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, + chanspec_t chspec); +static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val); +static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm, + uint bandunit, uint val); +static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val); + +static const struct country_info * +brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode); + +static void brcms_c_locale_get_channels(const struct locale_info *locale, chanvec_t *valid_channels); -static const locale_info_t *wlc_get_locale_2g(u8 locale_idx); -static const locale_info_t *wlc_get_locale_5g(u8 locale_idx); -static bool wlc_japan(struct wlc_info *wlc); -static bool wlc_japan_ccode(const char *ccode); -static void wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t * - wlc_cm, - struct - txpwr_limits - *txpwr, - u8 - local_constraint_qdbm); -static void wlc_locale_add_channels(chanvec_t *target, +static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx); +static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx); +static bool brcms_c_japan(struct brcms_c_info *wlc); +static bool brcms_c_japan_ccode(const char *ccode); +static void brcms_c_channel_min_txpower_limits_with_local_constraint( + struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr, + u8 local_constraint_qdbm); +static void brcms_c_locale_add_channels(chanvec_t *target, const chanvec_t *channels); -static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx); -static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx); +static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx); +static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx); /* QDB() macro takes a dB value and converts to a quarter dB value */ #ifdef QDB #undef QDB #endif -#define QDB(n) ((n) * WLC_TXPWR_DB_FACTOR) +#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) /* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */ @@ -398,7 +388,7 @@ static const chanvec_t *g_table_locale_base[] = { &locale_5g_HIGH4 }; -static void wlc_locale_add_channels(chanvec_t *target, +static void brcms_c_locale_add_channels(chanvec_t *target, const chanvec_t *channels) { u8 i; @@ -407,7 +397,7 @@ static void wlc_locale_add_channels(chanvec_t *target, } } -static void wlc_locale_get_channels(const locale_info_t *locale, +static void brcms_c_locale_get_channels(const struct locale_info *locale, chanvec_t *channels) { u8 i; @@ -416,7 +406,7 @@ static void wlc_locale_get_channels(const locale_info_t *locale, for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) { if (locale->valid_channels & (1 << i)) { - wlc_locale_add_channels(channels, + brcms_c_locale_add_channels(channels, g_table_locale_base[i]); } } @@ -425,43 +415,43 @@ static void wlc_locale_get_channels(const locale_info_t *locale, /* * Locale Definitions - 2.4 GHz */ -static const locale_info_t locale_i = { /* locale i. channel 1 - 13 */ +static const struct locale_info locale_i = { /* locale i. channel 1 - 13 */ LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13, LOCALE_RADAR_SET_NONE, LOCALE_RESTRICTED_SET_2G_SHORT, {QDB(19), QDB(19), QDB(19), QDB(19), QDB(19), QDB(19)}, {20, 20, 20, 0}, - WLC_EIRP + BRCMS_EIRP }; /* * Locale Definitions - 5 GHz */ -static const locale_info_t locale_11 = { +static const struct locale_info locale_11 = { /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */ LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165, LOCALE_RADAR_SET_1, LOCALE_RESTRICTED_NONE, {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)}, {23, 23, 23, 30, 30}, - WLC_EIRP | WLC_DFS_EU + BRCMS_EIRP | BRCMS_DFS_EU }; #define LOCALE_2G_IDX_i 0 -static const locale_info_t *g_locale_2g_table[] = { +static const struct locale_info *g_locale_2g_table[] = { &locale_i }; #define LOCALE_5G_IDX_11 0 -static const locale_info_t *g_locale_5g_table[] = { +static const struct locale_info *g_locale_5g_table[] = { &locale_11 }; /* * MIMO Locale Definitions - 2.4 GHz */ -static const locale_mimo_info_t locale_bn = { +static const struct locale_mimo_info locale_bn = { {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13)}, @@ -474,21 +464,21 @@ static const locale_mimo_info_t locale_bn = { /* locale mimo 2g indexes */ #define LOCALE_MIMO_IDX_bn 0 -static const locale_mimo_info_t *g_mimo_2g_table[] = { +static const struct locale_mimo_info *g_mimo_2g_table[] = { &locale_bn }; /* * MIMO Locale Definitions - 5 GHz */ -static const locale_mimo_info_t locale_11n = { +static const struct locale_mimo_info locale_11n = { { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)}, {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)}, 0 }; #define LOCALE_MIMO_IDX_11n 0 -static const locale_mimo_info_t *g_mimo_5g_table[] = { +static const struct locale_mimo_info *g_mimo_5g_table[] = { &locale_11n }; @@ -510,8 +500,8 @@ static const locale_mimo_info_t *g_mimo_5g_table[] = { #define LOCALES(band2, band5, mimo2, mimo5) {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)} static const struct { - char abbrev[WLC_CNTRY_BUF_SZ]; /* country abbreviation */ - country_info_t country; + char abbrev[BRCM_CNTRY_BUF_SZ]; /* country abbreviation */ + struct country_info country; } cntry_locales[] = { { "X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */ @@ -594,7 +584,7 @@ struct chan20_info chan20_info[] = { }; #endif /* SUPPORT_40MHZ */ -static const locale_info_t *wlc_get_locale_2g(u8 locale_idx) +static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) { return NULL; /* error condition */ @@ -602,7 +592,7 @@ static const locale_info_t *wlc_get_locale_2g(u8 locale_idx) return g_locale_2g_table[locale_idx]; } -static const locale_info_t *wlc_get_locale_5g(u8 locale_idx) +static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) { return NULL; /* error condition */ @@ -610,7 +600,7 @@ static const locale_info_t *wlc_get_locale_5g(u8 locale_idx) return g_locale_5g_table[locale_idx]; } -static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx) +static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) { return NULL; @@ -618,7 +608,7 @@ static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx) return g_mimo_2g_table[locale_idx]; } -static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx) +static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) { return NULL; @@ -626,17 +616,17 @@ static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx) return g_mimo_5g_table[locale_idx]; } -wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) +struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) { - wlc_cm_info_t *wlc_cm; - char country_abbrev[WLC_CNTRY_BUF_SZ]; - const country_info_t *country; - struct wlc_pub *pub = wlc->pub; + struct brcms_cm_info *wlc_cm; + char country_abbrev[BRCM_CNTRY_BUF_SZ]; + const struct country_info *country; + struct brcms_pub *pub = wlc->pub; char *ccode; BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); - wlc_cm = kzalloc(sizeof(wlc_cm_info_t), GFP_ATOMIC); + wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC); if (wlc_cm == NULL) { wiphy_err(wlc->wiphy, "wl%d: %s: out of memory", pub->unit, __func__); @@ -649,31 +639,33 @@ wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) /* store the country code for passing up as a regulatory hint */ ccode = getvar(wlc->pub->vars, "ccode"); if (ccode) { - strncpy(wlc->pub->srom_ccode, ccode, WLC_CNTRY_BUF_SZ - 1); + strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1); } /* internal country information which must match regulatory constraints in firmware */ - memset(country_abbrev, 0, WLC_CNTRY_BUF_SZ); + memset(country_abbrev, 0, BRCM_CNTRY_BUF_SZ); strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1); - country = wlc_country_lookup(wlc, country_abbrev); + country = brcms_c_country_lookup(wlc, country_abbrev); /* save default country for exiting 11d regulatory mode */ - strncpy(wlc->country_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1); + strncpy(wlc->country_default, country_abbrev, BRCM_CNTRY_BUF_SZ - 1); /* initialize autocountry_default to driver default */ - strncpy(wlc->autocountry_default, "X2", WLC_CNTRY_BUF_SZ - 1); + strncpy(wlc->autocountry_default, "X2", BRCM_CNTRY_BUF_SZ - 1); - wlc_set_countrycode(wlc_cm, country_abbrev); + brcms_c_set_countrycode(wlc_cm, country_abbrev); return wlc_cm; } -void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm) +void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm) { kfree(wlc_cm); } -u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) +u8 +brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm, + uint bandunit) { return wlc_cm->bandstate[bandunit].locale_flags; } @@ -681,20 +673,21 @@ u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) /* set the driver's current country and regulatory information using a country code * as the source. Lookup built in country information found with the country code. */ -static int wlc_set_countrycode(wlc_cm_info_t *wlc_cm, const char *ccode) +static int +brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode) { - char country_abbrev[WLC_CNTRY_BUF_SZ]; - strncpy(country_abbrev, ccode, WLC_CNTRY_BUF_SZ); - return wlc_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1); + char country_abbrev[BRCM_CNTRY_BUF_SZ]; + strncpy(country_abbrev, ccode, BRCM_CNTRY_BUF_SZ); + return brcms_c_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1); } static int -wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, +brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm, const char *country_abbrev, const char *ccode, int regrev) { - const country_info_t *country; - char mapped_ccode[WLC_CNTRY_BUF_SZ]; + const struct country_info *country; + char mapped_ccode[BRCM_CNTRY_BUF_SZ]; uint mapped_regrev; /* if regrev is -1, lookup the mapped country code, @@ -703,12 +696,12 @@ wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, if (regrev == -1) { /* map the country code to a built-in country code, regrev, and country_info */ country = - wlc_countrycode_map(wlc_cm, ccode, mapped_ccode, + brcms_c_countrycode_map(wlc_cm, ccode, mapped_ccode, &mapped_regrev); } else { /* find the matching built-in country definition */ - country = wlc_country_lookup_direct(ccode, regrev); - strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ); + country = brcms_c_country_lookup_direct(ccode, regrev); + strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ); mapped_regrev = regrev; } @@ -716,7 +709,7 @@ wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, return -EINVAL; /* set the driver state for the country */ - wlc_set_country_common(wlc_cm, country_abbrev, mapped_ccode, + brcms_c_set_country_common(wlc_cm, country_abbrev, mapped_ccode, mapped_regrev, country); return 0; @@ -726,49 +719,49 @@ wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, * as the source. Look up built in country information found with the country code. */ static void -wlc_set_country_common(wlc_cm_info_t *wlc_cm, +brcms_c_set_country_common(struct brcms_cm_info *wlc_cm, const char *country_abbrev, const char *ccode, uint regrev, - const country_info_t *country) + const struct country_info *country) { - const locale_mimo_info_t *li_mimo; - const locale_info_t *locale; - struct wlc_info *wlc = wlc_cm->wlc; - char prev_country_abbrev[WLC_CNTRY_BUF_SZ]; + const struct locale_mimo_info *li_mimo; + const struct locale_info *locale; + struct brcms_c_info *wlc = wlc_cm->wlc; + char prev_country_abbrev[BRCM_CNTRY_BUF_SZ]; /* save current country state */ wlc_cm->country = country; - memset(&prev_country_abbrev, 0, WLC_CNTRY_BUF_SZ); + memset(&prev_country_abbrev, 0, BRCM_CNTRY_BUF_SZ); strncpy(prev_country_abbrev, wlc_cm->country_abbrev, - WLC_CNTRY_BUF_SZ - 1); + BRCM_CNTRY_BUF_SZ - 1); - strncpy(wlc_cm->country_abbrev, country_abbrev, WLC_CNTRY_BUF_SZ - 1); - strncpy(wlc_cm->ccode, ccode, WLC_CNTRY_BUF_SZ - 1); + strncpy(wlc_cm->country_abbrev, country_abbrev, BRCM_CNTRY_BUF_SZ - 1); + strncpy(wlc_cm->ccode, ccode, BRCM_CNTRY_BUF_SZ - 1); wlc_cm->regrev = regrev; /* disable/restore nmode based on country regulations */ - li_mimo = wlc_get_mimo_2g(country->locale_mimo_2G); - if (li_mimo && (li_mimo->flags & WLC_NO_MIMO)) { - wlc_set_nmode(wlc, OFF); + li_mimo = brcms_c_get_mimo_2g(country->locale_mimo_2G); + if (li_mimo && (li_mimo->flags & BRCMS_NO_MIMO)) { + brcms_c_set_nmode(wlc, OFF); wlc->stf->no_cddstbc = true; } else { wlc->stf->no_cddstbc = false; if (N_ENAB(wlc->pub) != wlc->protection->nmode_user) - wlc_set_nmode(wlc, wlc->protection->nmode_user); + brcms_c_set_nmode(wlc, wlc->protection->nmode_user); } - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); + brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); + brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); /* set or restore gmode as required by regulatory */ - locale = wlc_get_locale_2g(country->locale_2G); - if (locale && (locale->flags & WLC_NO_OFDM)) { - wlc_set_gmode(wlc, GMODE_LEGACY_B, false); + locale = brcms_c_get_locale_2g(country->locale_2G); + if (locale && (locale->flags & BRCMS_NO_OFDM)) { + brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false); } else { - wlc_set_gmode(wlc, wlc->protection->gmode_user, false); + brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); } - wlc_channels_init(wlc_cm, country); + brcms_c_channels_init(wlc_cm, country); return; } @@ -776,40 +769,39 @@ wlc_set_country_common(wlc_cm_info_t *wlc_cm, /* Lookup a country info structure from a null terminated country code * The lookup is case sensitive. */ -static const country_info_t *wlc_country_lookup(struct wlc_info *wlc, - const char *ccode) +static const struct country_info * +brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode) { - const country_info_t *country; - char mapped_ccode[WLC_CNTRY_BUF_SZ]; + const struct country_info *country; + char mapped_ccode[BRCM_CNTRY_BUF_SZ]; uint mapped_regrev; /* map the country code to a built-in country code, regrev, and country_info struct */ - country = - wlc_countrycode_map(wlc->cmi, ccode, mapped_ccode, &mapped_regrev); + country = brcms_c_countrycode_map(wlc->cmi, ccode, mapped_ccode, + &mapped_regrev); return country; } -static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, - const char *ccode, - char *mapped_ccode, - uint *mapped_regrev) +static const struct country_info * +brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode, + char *mapped_ccode, uint *mapped_regrev) { - struct wlc_info *wlc = wlc_cm->wlc; - const country_info_t *country; + struct brcms_c_info *wlc = wlc_cm->wlc; + const struct country_info *country; uint srom_regrev = wlc_cm->srom_regrev; const char *srom_ccode = wlc_cm->srom_ccode; int mapped; /* check for currently supported ccode size */ - if (strlen(ccode) > (WLC_CNTRY_BUF_SZ - 1)) { + if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) { wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for " "match\n", wlc->pub->unit, __func__, ccode); return NULL; } /* default mapping is the given ccode and regrev 0 */ - strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ); + strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ); *mapped_regrev = 0; /* If the desired country code matches the srom country code, @@ -822,25 +814,25 @@ static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__); } else { mapped = - wlc_country_aggregate_map(wlc_cm, ccode, mapped_ccode, + brcms_c_country_aggregate_map(wlc_cm, ccode, mapped_ccode, mapped_regrev); } /* find the matching built-in country definition */ - country = wlc_country_lookup_direct(mapped_ccode, *mapped_regrev); + country = brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev); /* if there is not an exact rev match, default to rev zero */ if (country == NULL && *mapped_regrev != 0) { *mapped_regrev = 0; country = - wlc_country_lookup_direct(mapped_ccode, *mapped_regrev); + brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev); } return country; } static int -wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode, +brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode, char *mapped_ccode, uint *mapped_regrev) { return false; @@ -849,8 +841,8 @@ wlc_country_aggregate_map(wlc_cm_info_t *wlc_cm, const char *ccode, /* Lookup a country info structure from a null terminated country * abbreviation and regrev directly with no translation. */ -static const country_info_t *wlc_country_lookup_direct(const char *ccode, - uint regrev) +static const struct country_info * +brcms_c_country_lookup_direct(const char *ccode, uint regrev) { uint size, i; @@ -872,26 +864,27 @@ static const country_info_t *wlc_country_lookup_direct(const char *ccode, } static int -wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) +brcms_c_channels_init(struct brcms_cm_info *wlc_cm, + const struct country_info *country) { - struct wlc_info *wlc = wlc_cm->wlc; + struct brcms_c_info *wlc = wlc_cm->wlc; uint i, j; - struct wlcband *band; - const locale_info_t *li; + struct brcms_band *band; + const struct locale_info *li; chanvec_t sup_chan; - const locale_mimo_info_t *li_mimo; + const struct locale_mimo_info *li_mimo; band = wlc->band; for (i = 0; i < NBANDS(wlc); i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { li = BAND_5G(band->bandtype) ? - wlc_get_locale_5g(country->locale_5G) : - wlc_get_locale_2g(country->locale_2G); + brcms_c_get_locale_5g(country->locale_5G) : + brcms_c_get_locale_2g(country->locale_2G); wlc_cm->bandstate[band->bandunit].locale_flags = li->flags; li_mimo = BAND_5G(band->bandtype) ? - wlc_get_mimo_5g(country->locale_mimo_5G) : - wlc_get_mimo_2g(country->locale_mimo_2G); + brcms_c_get_mimo_5g(country->locale_mimo_5G) : + brcms_c_get_mimo_2g(country->locale_mimo_2G); /* merge the mimo non-mimo locale flags */ wlc_cm->bandstate[band->bandunit].locale_flags |= @@ -907,7 +900,7 @@ wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) */ wlc_phy_chanspec_band_validch(band->pi, band->bandtype, &sup_chan); - wlc_locale_get_channels(li, + brcms_c_locale_get_channels(li, &wlc_cm->bandstate[band->bandunit]. valid_channels); for (j = 0; j < sizeof(chanvec_t); j++) @@ -915,8 +908,8 @@ wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) vec[j] &= sup_chan.vec[j]; } - wlc_quiet_channels_reset(wlc_cm); - wlc_channels_commit(wlc_cm); + brcms_c_quiet_channels_reset(wlc_cm); + brcms_c_channels_commit(wlc_cm); return 0; } @@ -924,9 +917,9 @@ wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) /* Update the radio state (enable/disable) and tx power targets * based on a new set of channel/regulatory information */ -static void wlc_channels_commit(wlc_cm_info_t *wlc_cm) +static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm) { - struct wlc_info *wlc = wlc_cm->wlc; + struct brcms_c_info *wlc = wlc_cm->wlc; uint chan; struct txpwr_limits txpwr; @@ -959,25 +952,24 @@ static void wlc_channels_commit(wlc_cm_info_t *wlc_cm) */ if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) { wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, - wlc_japan(wlc) ? true : + brcms_c_japan(wlc) ? true : false); } if (wlc->pub->up && chan != INVCHANNEL) { - wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); - wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, - &txpwr, - WLC_TXPWR_MAX); + brcms_c_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); + brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm, + &txpwr, BRCMS_TXPWR_MAX); wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); } } /* reset the quiet channels vector to the union of the restricted and radar channel sets */ -static void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) +static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm) { - struct wlc_info *wlc = wlc_cm->wlc; + struct brcms_c_info *wlc = wlc_cm->wlc; uint i, j; - struct wlcband *band; + struct brcms_band *band; const chanvec_t *chanvec; memset(&wlc_cm->quiet_channels, 0, sizeof(chanvec_t)); @@ -994,7 +986,8 @@ static void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) } } -static bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) +static bool +brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, chanspec_t chspec) { return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ? (isset @@ -1011,9 +1004,9 @@ static bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) /* Is the channel valid for the current locale? (but don't consider channels not * available due to bandlocking) */ -static bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val) +static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val) { - struct wlc_info *wlc = wlc_cm->wlc; + struct brcms_c_info *wlc = wlc_cm->wlc; return VALID_CHANNEL20(wlc, val) || (!wlc->bandlocked @@ -1021,17 +1014,17 @@ static bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val) } /* Is the channel valid for the current locale and specified band? */ -static bool -wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val) +static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm, + uint bandunit, uint val) { return ((val < MAXCHANNEL) && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val)); } /* Is the channel valid for the current locale and current band? */ -static bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val) +static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val) { - struct wlc_info *wlc = wlc_cm->wlc; + struct brcms_c_info *wlc = wlc_cm->wlc; return ((val < MAXCHANNEL) && isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec, @@ -1039,10 +1032,9 @@ static bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val) } static void -wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm, - struct txpwr_limits *txpwr, - u8 - local_constraint_qdbm) +brcms_c_channel_min_txpower_limits_with_local_constraint( + struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr, + u8 local_constraint_qdbm) { int j; @@ -1057,66 +1049,66 @@ wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm, } /* 20 MHz Legacy OFDM CDD */ - for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) { txpwr->ofdm_cdd[j] = min(txpwr->ofdm_cdd[j], local_constraint_qdbm); } /* 40 MHz Legacy OFDM SISO */ - for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) { txpwr->ofdm_40_siso[j] = min(txpwr->ofdm_40_siso[j], local_constraint_qdbm); } /* 40 MHz Legacy OFDM CDD */ - for (j = 0; j < WLC_NUM_RATES_OFDM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) { txpwr->ofdm_40_cdd[j] = min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm); } /* 20MHz MCS 0-7 SISO */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) { txpwr->mcs_20_siso[j] = min(txpwr->mcs_20_siso[j], local_constraint_qdbm); } /* 20MHz MCS 0-7 CDD */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) { txpwr->mcs_20_cdd[j] = min(txpwr->mcs_20_cdd[j], local_constraint_qdbm); } /* 20MHz MCS 0-7 STBC */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) { txpwr->mcs_20_stbc[j] = min(txpwr->mcs_20_stbc[j], local_constraint_qdbm); } /* 20MHz MCS 8-15 MIMO */ - for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++) + for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++) txpwr->mcs_20_mimo[j] = min(txpwr->mcs_20_mimo[j], local_constraint_qdbm); /* 40MHz MCS 0-7 SISO */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) { txpwr->mcs_40_siso[j] = min(txpwr->mcs_40_siso[j], local_constraint_qdbm); } /* 40MHz MCS 0-7 CDD */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) { txpwr->mcs_40_cdd[j] = min(txpwr->mcs_40_cdd[j], local_constraint_qdbm); } /* 40MHz MCS 0-7 STBC */ - for (j = 0; j < WLC_NUM_RATES_MCS_1_STREAM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) { txpwr->mcs_40_stbc[j] = min(txpwr->mcs_40_stbc[j], local_constraint_qdbm); } /* 40MHz MCS 8-15 MIMO */ - for (j = 0; j < WLC_NUM_RATES_MCS_2_STREAM; j++) + for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++) txpwr->mcs_40_mimo[j] = min(txpwr->mcs_40_mimo[j], local_constraint_qdbm); @@ -1126,162 +1118,172 @@ wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm_info_t *wlc_cm, } void -wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, +brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, u8 local_constraint_qdbm) { - struct wlc_info *wlc = wlc_cm->wlc; + struct brcms_c_info *wlc = wlc_cm->wlc; struct txpwr_limits txpwr; - wlc_channel_reg_limits(wlc_cm, chanspec, &txpwr); + brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); - wlc_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, + brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, local_constraint_qdbm); - wlc_bmac_set_chanspec(wlc->hw, chanspec, - (wlc_quiet_chanspec(wlc_cm, chanspec) != 0), + brcms_b_set_chanspec(wlc->hw, chanspec, + (brcms_c_quiet_chanspec(wlc_cm, chanspec) != 0), &txpwr); } #ifdef POWER_DBG -static void wlc_phy_txpower_limits_dump(txpwr_limits_t *txpwr) +static void wlc_phy_txpower_limits_dump(struct txpwr_limits *txpwr) { int i; char buf[80]; char fraction[4][4] = { " ", ".25", ".5 ", ".75" }; sprintf(buf, "CCK "); - for (i = 0; i < WLC_NUM_RATES_CCK; i++) { + for (i = 0; i < BRCMS_NUM_RATES_CCK; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->cck[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->cck[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->cck[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->cck[i] % BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "20 MHz OFDM SISO "); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->ofdm[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->ofdm[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm[i] % BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "20 MHz OFDM CDD "); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->ofdm_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm_cdd[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->ofdm_cdd[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm_cdd[i] % BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "40 MHz OFDM SISO "); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->ofdm_40_siso[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm_40_siso[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->ofdm_40_siso[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm_40_siso[i] % + BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "40 MHz OFDM CDD "); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->ofdm_40_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->ofdm_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->ofdm_40_cdd[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->ofdm_40_cdd[i] % + BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "20 MHz MCS0-7 SISO "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->mcs_20_siso[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_siso[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->mcs_20_siso[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_siso[i] % + BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "20 MHz MCS0-7 CDD "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->mcs_20_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_cdd[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->mcs_20_cdd[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_cdd[i] % + BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "20 MHz MCS0-7 STBC "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->mcs_20_stbc[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_stbc[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->mcs_20_stbc[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_stbc[i] % + BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "20 MHz MCS8-15 SDM "); - for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->mcs_20_mimo[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_20_mimo[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->mcs_20_mimo[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_20_mimo[i] % + BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "40 MHz MCS0-7 SISO "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->mcs_40_siso[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_siso[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->mcs_40_siso[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_siso[i] % + BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "40 MHz MCS0-7 CDD "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->mcs_40_cdd[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_cdd[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->mcs_40_cdd[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_cdd[i] % + BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "40 MHz MCS0-7 STBC "); - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->mcs_40_stbc[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_stbc[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->mcs_40_stbc[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_stbc[i] % + BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "40 MHz MCS8-15 SDM "); - for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) { sprintf(buf[strlen(buf)], " %2d%s", - txpwr->mcs_40_mimo[i] / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs_40_mimo[i] % WLC_TXPWR_DB_FACTOR]); + txpwr->mcs_40_mimo[i] / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->mcs_40_mimo[i] % + BRCMS_TXPWR_DB_FACTOR]); } printk(KERN_DEBUG "%s\n", buf); printk(KERN_DEBUG "MCS32 %2d%s\n", - txpwr->mcs32 / WLC_TXPWR_DB_FACTOR, - fraction[txpwr->mcs32 % WLC_TXPWR_DB_FACTOR]); + txpwr->mcs32 / BRCMS_TXPWR_DB_FACTOR, + fraction[txpwr->mcs32 % BRCMS_TXPWR_DB_FACTOR]); } #endif /* POWER_DBG */ void -wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, - txpwr_limits_t *txpwr) +brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, + struct txpwr_limits *txpwr) { - struct wlc_info *wlc = wlc_cm->wlc; + struct brcms_c_info *wlc = wlc_cm->wlc; uint i; uint chan; int maxpwr; int delta; - const country_info_t *country; - struct wlcband *band; - const locale_info_t *li; + const struct country_info *country; + struct brcms_band *band; + const struct locale_info *li; int conducted_max; int conducted_ofdm_max; - const locale_mimo_info_t *li_mimo; + const struct locale_mimo_info *li_mimo; int maxpwr20, maxpwr40; int maxpwr_idx; uint j; - memset(txpwr, 0, sizeof(txpwr_limits_t)); + memset(txpwr, 0, sizeof(struct txpwr_limits)); - if (!wlc_valid_chanspec_db(wlc_cm, chanspec)) { - country = wlc_country_lookup(wlc, wlc->autocountry_default); + if (!brcms_c_valid_chanspec_db(wlc_cm, chanspec)) { + country = brcms_c_country_lookup(wlc, wlc->autocountry_default); if (country == NULL) return; } else { @@ -1289,16 +1291,16 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, } chan = CHSPEC_CHANNEL(chanspec); - band = wlc->bandstate[CHSPEC_WLCBANDUNIT(chanspec)]; + band = wlc->bandstate[CHSPEC_BANDUNIT(chanspec)]; li = BAND_5G(band->bandtype) ? - wlc_get_locale_5g(country->locale_5G) : - wlc_get_locale_2g(country->locale_2G); + brcms_c_get_locale_5g(country->locale_5G) : + brcms_c_get_locale_2g(country->locale_2G); li_mimo = BAND_5G(band->bandtype) ? - wlc_get_mimo_5g(country->locale_mimo_5G) : - wlc_get_mimo_2g(country->locale_mimo_2G); + brcms_c_get_mimo_5g(country->locale_mimo_5G) : + brcms_c_get_mimo_2g(country->locale_mimo_2G); - if (li->flags & WLC_EIRP) { + if (li->flags & BRCMS_EIRP) { delta = band->antgain; } else { delta = 0; @@ -1319,7 +1321,7 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, maxpwr = max(maxpwr, 0); maxpwr = min(maxpwr, conducted_max); - for (i = 0; i < WLC_NUM_RATES_CCK; i++) + for (i = 0; i < BRCMS_NUM_RATES_CCK; i++) txpwr->cck[i] = (u8) maxpwr; } @@ -1339,11 +1341,10 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, if (BAND_2G(band->bandtype)) maxpwr = min_t(int, maxpwr, txpwr->cck[0]); - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) txpwr->ofdm[i] = (u8) maxpwr; - } - for (i = 0; i < WLC_NUM_RATES_OFDM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { /* OFDM 40 MHz SISO has the same power as the corresponding MCS0-7 rate unless * overriden by the locale specific code. We set this value to 0 as a * flag (presumably 0 dBm isn't a possibility) and then copy the MCS0-7 value @@ -1357,7 +1358,7 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, } /* MIMO/HT specific limits */ - if (li_mimo->flags & WLC_EIRP) { + if (li_mimo->flags & BRCMS_EIRP) { delta = band->antgain; } else { delta = 0; @@ -1379,7 +1380,7 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, maxpwr40 = max(maxpwr40, 0); /* Fill in the MCS 0-7 (SISO) rates */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { /* 20 MHz has the same power as the corresponding OFDM rate unless * overriden by the locale specific code. @@ -1389,7 +1390,7 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, } /* Fill in the MCS 0-7 CDD rates */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { txpwr->mcs_20_cdd[i] = (u8) maxpwr20; txpwr->mcs_40_cdd[i] = (u8) maxpwr40; } @@ -1405,20 +1406,20 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, } } - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { txpwr->mcs_20_siso[i] = (u8) maxpwr20; txpwr->mcs_40_siso[i] = (u8) maxpwr40; } } /* Fill in the MCS 0-7 STBC rates */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { txpwr->mcs_20_stbc[i] = 0; txpwr->mcs_40_stbc[i] = 0; } /* Fill in the MCS 8-15 SDM rates */ - for (i = 0; i < WLC_NUM_RATES_MCS_2_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) { txpwr->mcs_20_mimo[i] = (u8) maxpwr20; txpwr->mcs_40_mimo[i] = (u8) maxpwr40; } @@ -1426,7 +1427,7 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, /* Fill in MCS32 */ txpwr->mcs32 = (u8) maxpwr40; - for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) { + for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) { if (txpwr->ofdm_40_cdd[i] == 0) txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; if (i == 0) { @@ -1440,12 +1441,12 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, * provided explicitly. */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { if (txpwr->mcs_40_siso[i] == 0) txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i]; } - for (i = 0, j = 0; i < WLC_NUM_RATES_OFDM; i++, j++) { + for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) { if (txpwr->ofdm_40_siso[i] == 0) txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; if (i == 0) { @@ -1458,7 +1459,7 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, /* Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding STBC values if they weren't * provided explicitly. */ - for (i = 0; i < WLC_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { if (txpwr->mcs_20_stbc[i] == 0) txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i]; @@ -1473,13 +1474,13 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, } /* Returns true if currently set country is Japan or variant */ -static bool wlc_japan(struct wlc_info *wlc) +static bool brcms_c_japan(struct brcms_c_info *wlc) { - return wlc_japan_ccode(wlc->cmi->country_abbrev); + return brcms_c_japan_ccode(wlc->cmi->country_abbrev); } /* JP, J1 - J10 are Japan ccodes */ -static bool wlc_japan_ccode(const char *ccode) +static bool brcms_c_japan_ccode(const char *ccode) { return (ccode[0] == 'J' && (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9'))); @@ -1490,20 +1491,21 @@ static bool wlc_japan_ccode(const char *ccode) * are valid 20MZH channels in this locale and they are also a legal HT combination */ static bool -wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband) +brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, chanspec_t chspec, + bool dualband) { - struct wlc_info *wlc = wlc_cm->wlc; + struct brcms_c_info *wlc = wlc_cm->wlc; u8 channel = CHSPEC_CHANNEL(chspec); /* check the chanspec */ - if (bcm_chspec_malformed(chspec)) { + if (brcmu_chspec_malformed(chspec)) { wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n", wlc->pub->unit, chspec); return false; } if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) != - CHSPEC_WLCBANDUNIT(chspec)) + CHSPEC_BANDUNIT(chspec)) return false; /* Check a 20Mhz channel */ @@ -1517,12 +1519,12 @@ wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband) /* We know we are now checking a 40MHZ channel, so we should only be here * for NPHYS */ - if (WLCISNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) { + if (BRCMS_ISNPHY(wlc->band) || BRCMS_ISSSLPNPHY(wlc->band)) { u8 upper_sideband = 0, idx; u8 num_ch20_entries = sizeof(chan20_info) / sizeof(struct chan20_info); - if (!VALID_40CHANSPEC_IN_BAND(wlc, CHSPEC_WLCBANDUNIT(chspec))) + if (!VALID_40CHANSPEC_IN_BAND(wlc, CHSPEC_BANDUNIT(chspec))) return false; if (dualband) { @@ -1551,7 +1553,7 @@ wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband) return false; } -bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec) +bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, chanspec_t chspec) { - return wlc_valid_chanspec_ext(wlc_cm, chspec, true); + return brcms_c_valid_chanspec_ext(wlc_cm, chspec, true); } diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h b/drivers/staging/brcm80211/brcmsmac/channel.h similarity index 57% rename from drivers/staging/brcm80211/brcmsmac/wlc_channel.h rename to drivers/staging/brcm80211/brcmsmac/channel.h index b8dec5b39d85..d22f2f5f592d 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_channel.h +++ b/drivers/staging/brcm80211/brcmsmac/channel.h @@ -14,12 +14,12 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _WLC_CHANNEL_H_ -#define _WLC_CHANNEL_H_ +#ifndef _BRCM_CHANNEL_H_ +#define _BRCM_CHANNEL_H_ -#define WLC_TXPWR_DB_FACTOR 4 /* conversion for phy txpwr cacluations that use .25 dB units */ +/* conversion for phy txpwr calculations that use .25 dB units */ +#define BRCMS_TXPWR_DB_FACTOR 4 -struct wlc_info; /* maxpwr mapping to 5GHz band channels: * maxpwr[0] - channels [34-48] @@ -47,43 +47,56 @@ struct wlc_info; #define CHANNEL_POWER_IDX_5G(c) \ (((c) < 52) ? 0 : (((c) < 62) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4)))) -#define WLC_MAXPWR_TBL_SIZE 6 /* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */ -#define WLC_MAXPWR_MIMO_TBL_SIZE 14 /* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */ +/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */ +#define BRCMS_MAXPWR_TBL_SIZE 6 +/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */ +#define BRCMS_MAXPWR_MIMO_TBL_SIZE 14 + +#define NBANDS(wlc) ((wlc)->pub->_nbands) +#define NBANDS_PUB(pub) ((pub)->_nbands) +#define NBANDS_HW(hw) ((hw)->_nbands) + +#define IS_SINGLEBAND_5G(device) 0 /* locale channel and power info. */ -typedef struct { +struct locale_info { u32 valid_channels; - u8 radar_channels; /* List of radar sensitive channels */ - u8 restricted_channels; /* List of channels used only if APs are detected */ - s8 maxpwr[WLC_MAXPWR_TBL_SIZE]; /* Max tx pwr in qdBm for each sub-band */ + /* List of radar sensitive channels */ + u8 radar_channels; + /* List of channels used only if APs are detected */ + u8 restricted_channels; + /* Max tx pwr in qdBm for each sub-band */ + s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE]; s8 pub_maxpwr[BAND_5G_PWR_LVLS]; /* Country IE advertised max tx pwr in dBm * per sub-band */ u8 flags; -} locale_info_t; +}; /* bits for locale_info flags */ -#define WLC_PEAK_CONDUCTED 0x00 /* Peak for locals */ -#define WLC_EIRP 0x01 /* Flag for EIRP */ -#define WLC_DFS_TPC 0x02 /* Flag for DFS TPC */ -#define WLC_NO_OFDM 0x04 /* Flag for No OFDM */ -#define WLC_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */ -#define WLC_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */ -#define WLC_RADAR_TYPE_EU 0x20 /* Flag for EU */ -#define WLC_DFS_FCC WLC_DFS_TPC /* Flag for DFS FCC */ -#define WLC_DFS_EU (WLC_DFS_TPC | WLC_RADAR_TYPE_EU) /* Flag for DFS EU */ +#define BRCMS_PEAK_CONDUCTED 0x00 /* Peak for locals */ +#define BRCMS_EIRP 0x01 /* Flag for EIRP */ +#define BRCMS_DFS_TPC 0x02 /* Flag for DFS TPC */ +#define BRCMS_NO_OFDM 0x04 /* Flag for No OFDM */ +#define BRCMS_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */ +#define BRCMS_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */ +#define BRCMS_RADAR_TYPE_EU 0x20 /* Flag for EU */ +#define BRCMS_DFS_FCC BRCMS_DFS_TPC /* Flag for DFS FCC */ +#define BRCMS_DFS_EU (BRCMS_DFS_TPC | BRCMS_RADAR_TYPE_EU) /* Flag for DFS EU */ -#define ISDFS_EU(fl) (((fl) & WLC_DFS_EU) == WLC_DFS_EU) +#define ISDFS_EU(fl) (((fl) & BRCMS_DFS_EU) == BRCMS_DFS_EU) /* locale per-channel tx power limits for MIMO frames * maxpwr arrays are index by channel for 2.4 GHz limits, and * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel) */ -typedef struct { - s8 maxpwr20[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 20 MHz power limits, qdBm units */ - s8 maxpwr40[WLC_MAXPWR_MIMO_TBL_SIZE]; /* tx 40 MHz power limits, qdBm units */ +struct locale_mimo_info { + /* tx 20 MHz power limits, qdBm units */ + s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE]; + /* tx 40 MHz power limits, qdBm units */ + s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE]; u8 flags; -} locale_mimo_info_t; +}; extern const chanvec_t chanvec_all_2G; extern const chanvec_t chanvec_all_5G; @@ -98,22 +111,21 @@ struct country_info { const u8 locale_mimo_5G; /* 5G mimo info */ }; -typedef struct country_info country_info_t; +extern struct brcms_cm_info * +brcms_c_channel_mgr_attach(struct brcms_c_info *wlc); -typedef struct wlc_cm_info wlc_cm_info_t; +extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm); -extern wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc); -extern void wlc_channel_mgr_detach(wlc_cm_info_t *wlc_cm); - -extern u8 wlc_channel_locale_flags_in_band(wlc_cm_info_t *wlc_cm, +extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm, uint bandunit); -extern bool wlc_valid_chanspec_db(wlc_cm_info_t *wlc_cm, chanspec_t chspec); +extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, + chanspec_t chspec); -extern void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, +extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, struct txpwr_limits *txpwr); -extern void wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, +extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, u8 local_constraint_qdbm); diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h index d91e4189a3e8..e7ff0e6f28e0 100644 --- a/drivers/staging/brcm80211/brcmsmac/d11.h +++ b/drivers/staging/brcm80211/brcmsmac/d11.h @@ -14,23 +14,14 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _D11_H -#define _D11_H +#ifndef _BRCM_D11_H_ +#define _BRCM_D11_H_ -#include +#include -#ifndef WL_RSSI_ANT_MAX -#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ -#elif WL_RSSI_ANT_MAX != 4 -#error "WL_RSSI_ANT_MAX does not match" -#endif - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif +#include +#include "pub.h" +#include "dma.h" #define BCN_TMPL_LEN 512 /* length of the BCN template area */ @@ -56,10 +47,16 @@ #define TX_DATA_FIFO TX_AC_BE_FIFO #define TX_CTL_FIFO TX_AC_VO_FIFO -typedef volatile struct { +#ifndef WL_RSSI_ANT_MAX +#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ +#elif WL_RSSI_ANT_MAX != 4 +#error "WL_RSSI_ANT_MAX does not match" +#endif + +struct intctrlregs { u32 intstatus; u32 intmask; -} intctrlregs_t; +}; /* PIO structure, * support two PIO format: 2 bytes access and 4 bytes access @@ -67,55 +64,53 @@ typedef volatile struct { * a pair of channels is defined for convenience */ /* 2byte-wide pio register set per channel(xmt or rcv) */ -typedef volatile struct { +struct pio2regs { u16 fifocontrol; u16 fifodata; u16 fifofree; /* only valid in xmt channel, not in rcv channel */ u16 PAD; -} pio2regs_t; +}; /* a pair of pio channels(tx and rx) */ -typedef volatile struct { +struct pio2regp { pio2regs_t tx; pio2regs_t rx; -} pio2regp_t; +}; /* 4byte-wide pio register set per channel(xmt or rcv) */ -typedef volatile struct { +struct pio4regs { u32 fifocontrol; u32 fifodata; -} pio4regs_t; +}; /* a pair of pio channels(tx and rx) */ -typedef volatile struct { +struct pio4regp { pio4regs_t tx; pio4regs_t rx; -} pio4regp_t; +}; /* read: 32-bit register that can be read as 32-bit or as 2 16-bit * write: only low 16b-it half can be written */ -typedef volatile union { +union pmqreg { u32 pmqhostdata; /* read only! */ struct { u16 pmqctrlstatus; /* read/write */ u16 PAD; } w; -} pmqreg_t; +}; -typedef volatile struct { +struct fifo64 { dma64regs_t dmaxmt; /* dma tx */ pio4regs_t piotx; /* pio tx */ dma64regs_t dmarcv; /* dma rx */ pio4regs_t piorx; /* pio rx */ -} fifo64_t; +}; /* * Host Interface Registers - * - primed from hnd_cores/dot11mac/systemC/registers/ihr.h - * - but definitely not complete */ -typedef volatile struct _d11regs { +struct d11regs { /* Device Control ("semi-standard host registers") */ u32 PAD[3]; /* 0x0 - 0x8 */ u32 biststatus; /* 0xC */ @@ -439,10 +434,7 @@ typedef volatile struct _d11regs { /* SHM *//* 0x800 - 0xEFE */ u16 PAD[0x380]; /* 0x800 - 0xEFE */ - - /* SB configuration registers: 0xF00 */ - sbconfig_t sbconfig; /* sb config regs occupy top 256 bytes */ -} d11regs_t; +}; #define PIHR_BASE 0x0400 /* byte address of packed IHR region */ @@ -629,12 +621,11 @@ typedef volatile struct _d11regs { #define ANA_11N_013 5 /* 802.11a PLCP header def */ -typedef struct ofdm_phy_hdr ofdm_phy_hdr_t; struct ofdm_phy_hdr { u8 rlpt[3]; /* rate, length, parity, tail */ u16 service; u8 pad; -} __attribute__((packed)); +} __packed; #define D11A_PHY_HDR_GRATE(phdr) ((phdr)->rlpt[0] & 0x0f) #define D11A_PHY_HDR_GRES(phdr) (((phdr)->rlpt[0] >> 4) & 0x01) @@ -664,13 +655,12 @@ struct ofdm_phy_hdr { #define D11A_PHY_PREHDR_TIME (D11A_PHY_PRE_TIME + D11A_PHY_HDR_TIME) /* 802.11b PLCP header def */ -typedef struct cck_phy_hdr cck_phy_hdr_t; struct cck_phy_hdr { u8 signal; u8 service; u16 length; u16 crc; -} __attribute__((packed)); +} __packed; #define D11B_PHY_HDR_LEN 6 @@ -691,17 +681,17 @@ struct cck_phy_hdr { #define MIMO_PLCP_40MHZ 0x80 /* 40 Hz frame */ #define MIMO_PLCP_AMPDU 0x08 /* ampdu */ -#define WLC_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8)) -#define WLC_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8)) -#define WLC_SET_MIMO_PLCP_LEN(plcp, len) \ +#define BRCMS_GET_CCK_PLCP_LEN(plcp) (plcp[4] + (plcp[5] << 8)) +#define BRCMS_GET_MIMO_PLCP_LEN(plcp) (plcp[1] + (plcp[2] << 8)) +#define BRCMS_SET_MIMO_PLCP_LEN(plcp, len) \ do { \ plcp[1] = len & 0xff; \ plcp[2] = ((len >> 8) & 0xff); \ } while (0); -#define WLC_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU) -#define WLC_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU) -#define WLC_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU) +#define BRCMS_SET_MIMO_PLCP_AMPDU(plcp) (plcp[3] |= MIMO_PLCP_AMPDU) +#define BRCMS_CLR_MIMO_PLCP_AMPDU(plcp) (plcp[3] &= ~MIMO_PLCP_AMPDU) +#define BRCMS_IS_MIMO_PLCP_AMPDU(plcp) (plcp[3] & MIMO_PLCP_AMPDU) /* The dot11a PLCP header is 5 bytes. To simplify the software (so that we * don't need e.g. different tx DMA headers for 11a and 11b), the PLCP header has @@ -710,7 +700,6 @@ struct cck_phy_hdr { #define D11_PHY_HDR_LEN 6 /* TX DMA buffer header */ -typedef struct d11txh d11txh_t; struct d11txh { u16 MacTxControlLow; /* 0x0 */ u16 MacTxControlHigh; /* 0x1 */ @@ -746,7 +735,7 @@ struct d11txh { u8 RTSPhyHeader[D11_PHY_HDR_LEN]; /* 0x2c - 0x2e */ struct ieee80211_rts rts_frame; /* 0x2f - 0x36 */ u16 PAD; /* 0x37 */ -} __attribute__((packed)); +} __packed; #define D11_TXH_LEN 112 /* bytes */ @@ -854,7 +843,6 @@ struct d11txh { #define ABI_MAS_MRT_ANT_PTN_MASK 0x000f /* tx status packet */ -typedef struct tx_status tx_status_t; struct tx_status { u16 framelen; u16 PAD; @@ -864,7 +852,7 @@ struct tx_status { u16 sequence; u16 phyerr; u16 ackphyrxsh; -} __attribute__((packed)); +} __packed; #define TXSTATUS_LEN 16 @@ -1160,25 +1148,25 @@ struct tx_status { #define M_TX_IDLE_BUSY_RATIO_X_16_OFDM (0x5A * 2) /* CW RSSI for LCNPHY */ -#define M_LCN_RSSI_0 0x1332 -#define M_LCN_RSSI_1 0x1338 -#define M_LCN_RSSI_2 0x133e -#define M_LCN_RSSI_3 0x1344 +#define M_LCN_RSSI_0 0x1332 +#define M_LCN_RSSI_1 0x1338 +#define M_LCN_RSSI_2 0x133e +#define M_LCN_RSSI_3 0x1344 /* SNR for LCNPHY */ -#define M_LCN_SNR_A_0 0x1334 -#define M_LCN_SNR_B_0 0x1336 +#define M_LCN_SNR_A_0 0x1334 +#define M_LCN_SNR_B_0 0x1336 -#define M_LCN_SNR_A_1 0x133a -#define M_LCN_SNR_B_1 0x133c +#define M_LCN_SNR_A_1 0x133a +#define M_LCN_SNR_B_1 0x133c -#define M_LCN_SNR_A_2 0x1340 -#define M_LCN_SNR_B_2 0x1342 +#define M_LCN_SNR_A_2 0x1340 +#define M_LCN_SNR_B_2 0x1342 -#define M_LCN_SNR_A_3 0x1346 -#define M_LCN_SNR_B_3 0x1348 +#define M_LCN_SNR_A_3 0x1346 +#define M_LCN_SNR_B_3 0x1348 -#define M_LCN_LAST_RESET (81*2) +#define M_LCN_LAST_RESET (81*2) #define M_LCN_LAST_LOC (63*2) #define M_LCNPHY_RESET_STATUS (4902) #define M_LCNPHY_DSC_TIME (0x98d*2) @@ -1247,7 +1235,6 @@ struct tx_status { #define MIMO_ANTSEL_WAIT 50 /* 50us wait */ #define MIMO_ANTSEL_OVERRIDE 0x8000 /* flag */ -typedef struct shm_acparams shm_acparams_t; struct shm_acparams { u16 txop; u16 cwmin; @@ -1258,7 +1245,7 @@ struct shm_acparams { u16 reggap; u16 status; u16 rsvd[8]; -} __attribute__((packed)); +} __packed; #define M_EDCF_QLEN (16 * 2) #define WME_STATUS_NEWAC (1 << 8) @@ -1292,7 +1279,7 @@ struct shm_acparams { /* Flags in M_HOST_FLAGS4 */ #define MHF4_BPHY_TXCORE0 0x0080 /* force bphy Tx on core 0 (board level WAR) */ -#define MHF4_EXTPA_ENABLE 0x4000 /* for 4313A0 FEM boards */ +#define MHF4_EXTPA_ENABLE 0x4000 /* for 4313A0 FEM boards */ /* Flags in M_HOST_FLAGS5 */ #define MHF5_4313_GPIOCTRL 0x0001 @@ -1306,7 +1293,6 @@ struct shm_acparams { #define PHY_NOISE_MASK 0x00ff /* Receive Frame Data Header for 802.11b DCF-only frames */ -typedef struct d11rxhdr d11rxhdr_t; struct d11rxhdr { u16 RxFrameSize; /* Actual byte length of the frame data received */ u16 PAD; @@ -1320,21 +1306,20 @@ struct d11rxhdr { u16 RxStatus2; /* extended MAC Rx status */ u16 RxTSFTime; /* RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY */ u16 RxChan; /* gain code, channel radio code, and phy type */ -} __attribute__((packed)); +} __packed; -#define RXHDR_LEN 24 /* sizeof d11rxhdr_t */ +#define RXHDR_LEN 24 /* sizeof struct d11rxhdr */ #define FRAMELEN(h) ((h)->RxFrameSize) -typedef struct wlc_d11rxhdr wlc_d11rxhdr_t; -struct wlc_d11rxhdr { - d11rxhdr_t rxhdr; +struct brcms_d11rxhdr { + struct d11rxhdr rxhdr; u32 tsf_l; /* TSF_L reading */ s8 rssi; /* computed instanteneous rssi in BMAC */ s8 rxpwr0; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */ s8 rxpwr1; /* obsoleted, place holder for legacy ROM code. use rxpwr[] */ s8 do_rssi_ma; /* do per-pkt sampling for per-antenna ma in HIGH */ s8 rxpwr[WL_RSSI_ANT_MAX]; /* rssi for supported antennas */ -} __attribute__((packed)); +} __packed; /* PhyRxStatus_0: */ #define PRXS0_FT_MASK 0x0003 /* NPHY only: CCK, OFDM, preN, N */ @@ -1473,7 +1458,7 @@ struct wlc_d11rxhdr { #define DBGST_ASLEEP 4 /* asleep (PS mode) */ /* Scratch Reg defs */ -typedef enum { +enum _ePsmScratchPadRegDefinitions { S_RSV0 = 0, S_RSV1, S_RSV2, @@ -1551,7 +1536,7 @@ typedef enum { S_MFGTEST_TMP0, /* Temp register used for RX test calculations 0x3D */ S_RXESN, /* Received end sequence number for A-MPDU BA 0x3E */ S_STREG6, /* 0x3F */ -} ePsmScratchPadRegDefinitions; +}; #define S_BEACON_INDX S_OLD_BREM #define S_PRS_INDX S_OLD_CWWIN @@ -1563,7 +1548,7 @@ typedef enum { #define SLOW_CTRL_FD (1 << 8) /* ucode mac statistic counters in shared memory */ -typedef struct macstat { +struct macstat { u16 txallfrm; /* 0x80 */ u16 txrtsfrm; /* 0x82 */ u16 txctsfrm; /* 0x84 */ @@ -1621,7 +1606,7 @@ typedef struct macstat { u16 phywatchdog; /* 0xfa # of phy watchdog events */ u16 PAD; u16 bphy_badplcp; /* bphy bad plcp */ -} macstat_t; +}; /* dot11 core-specific control flags */ #define SICF_PCLKE 0x0004 /* PHY clock enable */ @@ -1688,7 +1673,7 @@ typedef struct macstat { #define BPHY_PEAK_ENERGY_HI 0x34 #define BPHY_SYNC_CTL 0x35 #define BPHY_TX_PWR_CTRL 0x36 -#define BPHY_TX_EST_PWR 0x37 +#define BPHY_TX_EST_PWR 0x37 #define BPHY_STEP 0x38 #define BPHY_WARMUP 0x39 #define BPHY_LMS_CFF_READ 0x3a @@ -1770,4 +1755,21 @@ typedef struct macstat { #define SHM_BYT_CNT 0x2 /* IHR location */ #define MAX_BYT_CNT 0x600 /* Maximum frame len */ -#endif /* _D11_H */ +struct d11cnt { + u32 txfrag; + u32 txmulti; + u32 txfail; + u32 txretry; + u32 txretrie; + u32 rxdup; + u32 txrts; + u32 txnocts; + u32 txnoack; + u32 rxfrag; + u32 rxmulti; + u32 rxcrc; + u32 txfrmsnt; + u32 rxundec; +}; + +#endif /* _BRCM_D11_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/hnddma.c b/drivers/staging/brcm80211/brcmsmac/dma.c similarity index 70% rename from drivers/staging/brcm80211/brcmsmac/hnddma.c rename to drivers/staging/brcm80211/brcmsmac/dma.c index f607315f8143..ea17671efb63 100644 --- a/drivers/staging/brcm80211/brcmsmac/hnddma.c +++ b/drivers/staging/brcm80211/brcmsmac/dma.c @@ -13,27 +13,149 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - -#include -#include -#include +#include +#include +#include #include -#include -#include -#include -#include -#include - -#include -#include #if defined(__mips__) #include #endif -#ifdef BRCM_FULLMAC -#error "hnddma.c shouldn't be needed for FULLMAC" -#endif +#include +#include +#include "types.h" +#include "dma.h" + +/* + * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical address. + */ +#define D64RINGALIGN_BITS 13 +#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS) +#define D64RINGALIGN (1 << D64RINGALIGN_BITS) + +#define D64MAXDD (D64MAXRINGSZ / sizeof(struct dma64desc)) + +/* transmit channel control */ +#define D64_XC_XE 0x00000001 /* transmit enable */ +#define D64_XC_SE 0x00000002 /* transmit suspend request */ +#define D64_XC_LE 0x00000004 /* loopback enable */ +#define D64_XC_FL 0x00000010 /* flush request */ +#define D64_XC_PD 0x00000800 /* parity check disable */ +#define D64_XC_AE 0x00030000 /* address extension bits */ +#define D64_XC_AE_SHIFT 16 + +/* transmit descriptor table pointer */ +#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ + +/* transmit channel status */ +#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ +#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ +#define D64_XS0_XS_SHIFT 28 +#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ +#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ +#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ +#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ +#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ + +#define D64_XS1_AD_MASK 0x00001fff /* active descriptor */ +#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ +#define D64_XS1_XE_SHIFT 28 +#define D64_XS1_XE_NOERR 0x00000000 /* no error */ +#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ +#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ +#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ +#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ +#define D64_XS1_XE_COREE 0x50000000 /* core error */ + +/* receive channel control */ +#define D64_RC_RE 0x00000001 /* receive enable */ +#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ +#define D64_RC_RO_SHIFT 1 +#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ +#define D64_RC_SH 0x00000200 /* separate rx header descriptor enable */ +#define D64_RC_OC 0x00000400 /* overflow continue */ +#define D64_RC_PD 0x00000800 /* parity check disable */ +#define D64_RC_AE 0x00030000 /* address extension bits */ +#define D64_RC_AE_SHIFT 16 + +/* flags for dma controller */ +#define DMA_CTRL_PEN (1 << 0) /* partity enable */ +#define DMA_CTRL_ROC (1 << 1) /* rx overflow continue */ +#define DMA_CTRL_RXMULTI (1 << 2) /* allow rx scatter to multiple descriptors */ +#define DMA_CTRL_UNFRAMED (1 << 3) /* Unframed Rx/Tx data */ + +/* receive descriptor table pointer */ +#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ + +/* receive channel status */ +#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ +#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ +#define D64_RS0_RS_SHIFT 28 +#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ +#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ +#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ +#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ +#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ + +#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ +#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ +#define D64_RS1_RE_SHIFT 28 +#define D64_RS1_RE_NOERR 0x00000000 /* no error */ +#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ +#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ +#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ +#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ +#define D64_RS1_RE_COREE 0x50000000 /* core error */ + +/* fifoaddr */ +#define D64_FA_OFF_MASK 0xffff /* offset */ +#define D64_FA_SEL_MASK 0xf0000 /* select */ +#define D64_FA_SEL_SHIFT 16 +#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ +#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ +#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ +#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ +#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ +#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ +#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ +#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ +#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ +#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ + +/* descriptor control flags 1 */ +#define D64_CTRL_COREFLAGS 0x0ff00000 /* core specific flags */ +#define D64_CTRL1_EOT ((u32)1 << 28) /* end of descriptor table */ +#define D64_CTRL1_IOC ((u32)1 << 29) /* interrupt on completion */ +#define D64_CTRL1_EOF ((u32)1 << 30) /* end of frame */ +#define D64_CTRL1_SOF ((u32)1 << 31) /* start of frame */ + +/* descriptor control flags 2 */ +#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count. real data len must <= 16KB */ +#define D64_CTRL2_AE 0x00030000 /* address extension bits */ +#define D64_CTRL2_AE_SHIFT 16 +#define D64_CTRL2_PARITY 0x00040000 /* parity bit */ + +/* control flags in the range [27:20] are core-specific and not defined here */ +#define D64_CTRL_CORE_MASK 0x0ff00000 + +#define D64_RX_FRM_STS_LEN 0x0000ffff /* frame length mask */ +#define D64_RX_FRM_STS_OVFL 0x00800000 /* RxOverFlow */ +#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1 */ +#define D64_RX_FRM_STS_DATATYPE 0xf0000000 /* core-dependent data type */ + +#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */ +#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */ +#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */ +#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */ + +/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF). + * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL. + * There is a compile time check in wlc.c which ensure that this value is at least as big + * as TXOFF. This value is used in dma_rxfill (dma.c). + */ + +#define BCMEXTRAHDROOM 172 /* debug/trace */ #ifdef BCMDBG @@ -58,6 +180,15 @@ #define DMA_NONE(args) +typedef unsigned long dmaaddr_t; +#define PHYSADDRHI(_pa) (0) +#define PHYSADDRHISET(_pa, _val) +#define PHYSADDRLO(_pa) ((_pa)) +#define PHYSADDRLOSET(_pa, _val) \ + do { \ + (_pa) = (_val); \ + } while (0) + #define d64txregs dregs.d64_u.txregs_64 #define d64rxregs dregs.d64_u.rxregs_64 #define txd64 dregs.d64_u.txd_64 @@ -73,9 +204,33 @@ static uint dma_msg_level; #define R_SM(r) (*(r)) #define W_SM(r, v) (*(r) = (v)) +/* One physical DMA segment */ +struct dma_seg { + dmaaddr_t addr; + u32 length; +}; + +struct dma_seg_map { + void *oshdmah; /* Opaque handle for OSL to store its information */ + uint origsize; /* Size of the virtual packet */ + uint nsegs; + struct dma_seg segs[MAX_DMA_SEGS]; +}; + +/* + * DMA Descriptor + * Descriptors are only read by the hardware, never written back. + */ +struct dma64desc { + u32 ctrl1; /* misc control bits & bufcount */ + u32 ctrl2; /* buffer count and address extension */ + u32 addrlow; /* memory address of the date buffer, bits 31:0 */ + u32 addrhigh; /* memory address of the date buffer, bits 63:32 */ +}; + /* dma engine software state */ -typedef struct dma_info { - struct hnddma_pub hnddma; /* exported structure */ +struct dma_info { + struct dma_pub dma; /* exported structure */ uint *msg_level; /* message level pointer */ char name[MAXNAMEL]; /* callers name for diag msgs */ @@ -88,8 +243,10 @@ typedef struct dma_info { struct { dma64regs_t *txregs_64; /* 64-bit dma tx engine registers */ dma64regs_t *rxregs_64; /* 64-bit dma rx engine registers */ - dma64dd_t *txd_64; /* pointer to dma64 tx descriptor ring */ - dma64dd_t *rxd_64; /* pointer to dma64 rx descriptor ring */ + /* pointer to dma64 tx descriptor ring */ + struct dma64desc *txd_64; + /* pointer to dma64 rx descriptor ring */ + struct dma64desc *rxd_64; } d64_u; } dregs; @@ -99,7 +256,7 @@ typedef struct dma_info { u16 txin; /* index of next descriptor to reclaim */ u16 txout; /* index of next descriptor to post */ void **txp; /* pointer to parallel array of pointers to packets */ - hnddma_seg_map_t *txp_dmah; /* DMA MAP meta-data handle */ + struct dma_seg_map *txp_dmah; /* DMA MAP meta-data handle */ dmaaddr_t txdpa; /* Aligned physical address of descriptor ring */ dmaaddr_t txdpaorig; /* Original physical address of descriptor ring */ u16 txdalign; /* #bytes added to alloc'd mem to align txd */ @@ -113,7 +270,7 @@ typedef struct dma_info { u16 rxin; /* index of next descriptor to reclaim */ u16 rxout; /* index of next descriptor to post */ void **rxp; /* pointer to parallel array of pointers to packets */ - hnddma_seg_map_t *rxp_dmah; /* DMA MAP meta-data handle */ + struct dma_seg_map *rxp_dmah; /* DMA MAP meta-data handle */ dmaaddr_t rxdpa; /* Aligned physical address of descriptor ring */ dmaaddr_t rxdpaorig; /* Original physical address of descriptor ring */ u16 rxdalign; /* #bytes added to alloc'd mem to align rxd */ @@ -137,7 +294,7 @@ typedef struct dma_info { uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ uint dataoffsethigh; /* high 32 bits */ bool aligndesc_4k; /* descriptor base need to be aligned or not */ -} dma_info_t; +}; /* DMA Scatter-gather list is supported. Note this is limited to TX direction only */ #ifdef BCMDMASGLISTOSL @@ -169,65 +326,67 @@ typedef struct dma_info { #define PCI64ADDR_HIGH_SHIFT 31 /* address[63] */ /* Common prototypes */ -static bool _dma_isaddrext(dma_info_t *di); -static bool _dma_descriptor_align(dma_info_t *di); -static bool _dma_alloc(dma_info_t *di, uint direction); -static void _dma_detach(dma_info_t *di); -static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa); -static void _dma_rxinit(dma_info_t *di); -static void *_dma_rx(dma_info_t *di); -static bool _dma_rxfill(dma_info_t *di); -static void _dma_rxreclaim(dma_info_t *di); -static void _dma_rxenable(dma_info_t *di); -static void *_dma_getnextrxp(dma_info_t *di, bool forceall); -static void _dma_rx_param_get(dma_info_t *di, u16 *rxoffset, +static bool _dma_isaddrext(struct dma_info *di); +static bool _dma_descriptor_align(struct dma_info *di); +static bool _dma_alloc(struct dma_info *di, uint direction); +static void _dma_detach(struct dma_info *di); +static void _dma_ddtable_init(struct dma_info *di, uint direction, + dmaaddr_t pa); +static void _dma_rxinit(struct dma_info *di); +static void *_dma_rx(struct dma_info *di); +static bool _dma_rxfill(struct dma_info *di); +static void _dma_rxreclaim(struct dma_info *di); +static void _dma_rxenable(struct dma_info *di); +static void *_dma_getnextrxp(struct dma_info *di, bool forceall); +static void _dma_rx_param_get(struct dma_info *di, u16 *rxoffset, u16 *rxbufsize); -static void _dma_txblock(dma_info_t *di); -static void _dma_txunblock(dma_info_t *di); -static uint _dma_txactive(dma_info_t *di); -static uint _dma_rxactive(dma_info_t *di); -static uint _dma_txpending(dma_info_t *di); -static uint _dma_txcommitted(dma_info_t *di); +static void _dma_txblock(struct dma_info *di); +static void _dma_txunblock(struct dma_info *di); +static uint _dma_txactive(struct dma_info *di); +static uint _dma_rxactive(struct dma_info *di); +static uint _dma_txpending(struct dma_info *di); +static uint _dma_txcommitted(struct dma_info *di); -static void *_dma_peeknexttxp(dma_info_t *di); -static void *_dma_peeknextrxp(dma_info_t *di); -static unsigned long _dma_getvar(dma_info_t *di, const char *name); -static void _dma_counterreset(dma_info_t *di); -static void _dma_fifoloopbackenable(dma_info_t *di); -static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags); +static void *_dma_peeknexttxp(struct dma_info *di); +static void *_dma_peeknextrxp(struct dma_info *di); +static unsigned long _dma_getvar(struct dma_info *di, const char *name); +static void _dma_counterreset(struct dma_info *di); +static void _dma_fifoloopbackenable(struct dma_info *di); +static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags); static u8 dma_align_sizetobits(uint size); -static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size, +static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size, u16 *alignbits, uint *alloced, dmaaddr_t *descpa); /* Prototypes for 64-bit routines */ -static bool dma64_alloc(dma_info_t *di, uint direction); -static bool dma64_txreset(dma_info_t *di); -static bool dma64_rxreset(dma_info_t *di); -static bool dma64_txsuspendedidle(dma_info_t *di); -static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, bool commit); -static int dma64_txunframed(dma_info_t *di, void *p0, uint len, bool commit); -static void *dma64_getpos(dma_info_t *di, bool direction); -static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range); -static void *dma64_getnextrxp(dma_info_t *di, bool forceall); -static void dma64_txrotate(dma_info_t *di); +static bool dma64_alloc(struct dma_info *di, uint direction); +static bool dma64_txreset(struct dma_info *di); +static bool dma64_rxreset(struct dma_info *di); +static bool dma64_txsuspendedidle(struct dma_info *di); +static int dma64_txfast(struct dma_info *di, struct sk_buff *p0, bool commit); +static int dma64_txunframed(struct dma_info *di, void *p0, uint len, + bool commit); +static void *dma64_getpos(struct dma_info *di, bool direction); +static void *dma64_getnexttxp(struct dma_info *di, enum txd_range range); +static void *dma64_getnextrxp(struct dma_info *di, bool forceall); +static void dma64_txrotate(struct dma_info *di); -static bool dma64_rxidle(dma_info_t *di); -static void dma64_txinit(dma_info_t *di); -static bool dma64_txenabled(dma_info_t *di); -static void dma64_txsuspend(dma_info_t *di); -static void dma64_txresume(dma_info_t *di); -static bool dma64_txsuspended(dma_info_t *di); -static void dma64_txreclaim(dma_info_t *di, txd_range_t range); -static bool dma64_txstopped(dma_info_t *di); -static bool dma64_rxstopped(dma_info_t *di); -static bool dma64_rxenabled(dma_info_t *di); +static bool dma64_rxidle(struct dma_info *di); +static void dma64_txinit(struct dma_info *di); +static bool dma64_txenabled(struct dma_info *di); +static void dma64_txsuspend(struct dma_info *di); +static void dma64_txresume(struct dma_info *di); +static bool dma64_txsuspended(struct dma_info *di); +static void dma64_txreclaim(struct dma_info *di, enum txd_range range); +static bool dma64_txstopped(struct dma_info *di); +static bool dma64_rxstopped(struct dma_info *di); +static bool dma64_rxenabled(struct dma_info *di); static bool _dma64_addrext(dma64regs_t *dma64regs); static inline u32 parity32(u32 data); -const di_fcn_t dma64proc = { +const struct di_fcn_s dma64proc = { (di_detach_t) _dma_detach, (di_txinit_t) dma64_txinit, (di_txreset_t) dma64_txreset, @@ -274,16 +433,16 @@ const di_fcn_t dma64proc = { 39 }; -struct hnddma_pub *dma_attach(char *name, si_t *sih, +struct dma_pub *dma_attach(char *name, struct si_pub *sih, void *dmaregstx, void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, uint rxoffset, uint *msg_level) { - dma_info_t *di; + struct dma_info *di; uint size; /* allocate private info structure */ - di = kzalloc(sizeof(dma_info_t), GFP_ATOMIC); + di = kzalloc(sizeof(struct dma_info), GFP_ATOMIC); if (di == NULL) { #ifdef BCMDBG printk(KERN_ERR "dma_attach: out of memory\n"); @@ -299,20 +458,20 @@ struct hnddma_pub *dma_attach(char *name, si_t *sih, /* init dma reg pointer */ di->d64txregs = (dma64regs_t *) dmaregstx; di->d64rxregs = (dma64regs_t *) dmaregsrx; - di->hnddma.di_fn = (const di_fcn_t *)&dma64proc; + di->dma.di_fn = (const struct di_fcn_s *)&dma64proc; /* Default flags (which can be changed by the driver calling dma_ctrlflags * before enable): For backwards compatibility both Rx Overflow Continue * and Parity are DISABLED. * supports it. */ - di->hnddma.di_fn->ctrlflags(&di->hnddma, DMA_CTRL_ROC | DMA_CTRL_PEN, - 0); + di->dma.di_fn->ctrlflags(&di->dma, DMA_CTRL_ROC | DMA_CTRL_PEN, + 0); DMA_TRACE(("%s: dma_attach: %s flags 0x%x ntxd %d nrxd %d " "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " "dmaregstx %p dmaregsrx %p\n", name, "DMA64", - di->hnddma.dmactrlflags, ntxd, nrxd, rxbufsize, + di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx)); /* make a private copy of our callers name */ @@ -427,21 +586,21 @@ struct hnddma_pub *dma_attach(char *name, si_t *sih, /* allocate DMA mapping vectors */ if (DMASGLIST_ENAB) { if (ntxd) { - size = ntxd * sizeof(hnddma_seg_map_t); + size = ntxd * sizeof(struct dma_seg_map); di->txp_dmah = kzalloc(size, GFP_ATOMIC); if (di->txp_dmah == NULL) goto fail; } if (nrxd) { - size = nrxd * sizeof(hnddma_seg_map_t); + size = nrxd * sizeof(struct dma_seg_map); di->rxp_dmah = kzalloc(size, GFP_ATOMIC); if (di->rxp_dmah == NULL) goto fail; } } - return (struct hnddma_pub *) di; + return (struct dma_pub *) di; fail: _dma_detach(di); @@ -463,8 +622,8 @@ static inline u32 parity32(u32 data) #define DMA64_DD_PARITY(dd) parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2) static inline void -dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx, - u32 *flags, u32 bufcount) +dma64_dd_upd(struct dma_info *di, struct dma64desc *ddring, + dmaaddr_t pa, uint outidx, u32 *flags, u32 bufcount) { u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; @@ -497,7 +656,7 @@ dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx, W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); } - if (di->hnddma.dmactrlflags & DMA_CTRL_PEN) { + if (di->dma.dmactrlflags & DMA_CTRL_PEN) { if (DMA64_DD_PARITY(&ddring[outidx])) { W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY)); @@ -505,7 +664,7 @@ dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx, } } -static bool _dma_alloc(dma_info_t *di, uint direction) +static bool _dma_alloc(struct dma_info *di, uint direction) { return dma64_alloc(di, direction); } @@ -523,7 +682,7 @@ void *dma_alloc_consistent(struct pci_dev *pdev, uint size, u16 align_bits, } /* !! may be called with core in reset */ -static void _dma_detach(dma_info_t *di) +static void _dma_detach(struct dma_info *di) { DMA_TRACE(("%s: dma_detach\n", di->name)); @@ -553,7 +712,7 @@ static void _dma_detach(dma_info_t *di) } -static bool _dma_descriptor_align(dma_info_t *di) +static bool _dma_descriptor_align(struct dma_info *di) { u32 addrl; @@ -573,7 +732,7 @@ static bool _dma_descriptor_align(dma_info_t *di) } /* return true if this dma engine supports DmaExtendedAddrChanges, otherwise false */ -static bool _dma_isaddrext(dma_info_t *di) +static bool _dma_isaddrext(struct dma_info *di) { /* DMA64 supports full 32- or 64-bit operation. AE is always valid */ @@ -595,7 +754,7 @@ static bool _dma_isaddrext(dma_info_t *di) } /* initialize descriptor table base address */ -static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa) +static void _dma_ddtable_init(struct dma_info *di, uint direction, dmaaddr_t pa) { if (!di->aligndesc_4k) { if (direction == DMA_TX) @@ -644,14 +803,14 @@ static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa) } } -static void _dma_fifoloopbackenable(dma_info_t *di) +static void _dma_fifoloopbackenable(struct dma_info *di) { DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); OR_REG(&di->d64txregs->control, D64_XC_LE); } -static void _dma_rxinit(dma_info_t *di) +static void _dma_rxinit(struct dma_info *di) { DMA_TRACE(("%s: dma_rxinit\n", di->name)); @@ -662,7 +821,7 @@ static void _dma_rxinit(dma_info_t *di) /* clear rx descriptor ring */ memset((void *)di->rxd64, '\0', - (di->nrxd * sizeof(dma64dd_t))); + (di->nrxd * sizeof(struct dma64desc))); /* DMA engine with out alignment requirement requires table to be inited * before enabling the engine @@ -676,9 +835,9 @@ static void _dma_rxinit(dma_info_t *di) _dma_ddtable_init(di, DMA_RX, di->rxdpa); } -static void _dma_rxenable(dma_info_t *di) +static void _dma_rxenable(struct dma_info *di) { - uint dmactrlflags = di->hnddma.dmactrlflags; + uint dmactrlflags = di->dma.dmactrlflags; u32 control; DMA_TRACE(("%s: dma_rxenable\n", di->name)); @@ -698,7 +857,7 @@ static void _dma_rxenable(dma_info_t *di) } static void -_dma_rx_param_get(dma_info_t *di, u16 *rxoffset, u16 *rxbufsize) +_dma_rx_param_get(struct dma_info *di, u16 *rxoffset, u16 *rxbufsize) { /* the normal values fit into 16 bits */ *rxoffset = (u16) di->rxoffset; @@ -714,7 +873,7 @@ _dma_rx_param_get(dma_info_t *di, u16 *rxoffset, u16 *rxbufsize) * After it reaches the max size of buffer, the data continues in next DMA descriptor * buffer WITHOUT DMA header */ -static void *_dma_rx(dma_info_t *di) +static void *_dma_rx(struct dma_info *di) { struct sk_buff *p, *head, *tail; uint len; @@ -754,17 +913,17 @@ static void *_dma_rx(dma_info_t *di) B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, - dma64dd_t); + struct dma64desc); DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n", di->rxin, di->rxout, cur)); } #endif /* BCMDBG */ - if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { + if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); - bcm_pkt_buf_free_skb(head); - di->hnddma.rxgiants++; + brcmu_pkt_buf_free_skb(head); + di->dma.rxgiants++; goto next_frame; } } @@ -777,7 +936,7 @@ static void *_dma_rx(dma_info_t *di) * this will stall the rx dma and user might want to call rxfill again asap * This unlikely happens on memory-rich NIC, but often on memory-constrained dongle */ -static bool _dma_rxfill(dma_info_t *di) +static bool _dma_rxfill(struct dma_info *di) { struct sk_buff *p; u16 rxin, rxout; @@ -811,7 +970,7 @@ static bool _dma_rxfill(dma_info_t *di) size to be allocated */ - p = bcm_pkt_buf_get_skb(di->rxbufsize + extra_offset); + p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset); if (p == NULL) { DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", @@ -821,7 +980,7 @@ static bool _dma_rxfill(dma_info_t *di) di->name)); ring_empty = true; } - di->hnddma.rxnobuf++; + di->dma.rxnobuf++; break; } /* reserve an extra headroom, if applicable */ @@ -835,7 +994,7 @@ static bool _dma_rxfill(dma_info_t *di) if (DMASGLIST_ENAB) memset(&di->rxp_dmah[rxout], 0, - sizeof(hnddma_seg_map_t)); + sizeof(struct dma_seg_map)); pa = pci_map_single(di->pbus, p->data, di->rxbufsize, PCI_DMA_FROMDEVICE); @@ -857,13 +1016,13 @@ static bool _dma_rxfill(dma_info_t *di) /* update the chip lastdscr pointer */ W_REG(&di->d64rxregs->ptr, - di->rcvptrbase + I2B(rxout, dma64dd_t)); + di->rcvptrbase + I2B(rxout, struct dma64desc)); return ring_empty; } /* like getnexttxp but no reclaim */ -static void *_dma_peeknexttxp(dma_info_t *di) +static void *_dma_peeknexttxp(struct dma_info *di) { uint end, i; @@ -873,7 +1032,7 @@ static void *_dma_peeknexttxp(dma_info_t *di) end = B2I(((R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, - dma64dd_t); + struct dma64desc); for (i = di->txin; i != end; i = NEXTTXD(i)) if (di->txp[i]) @@ -883,7 +1042,7 @@ static void *_dma_peeknexttxp(dma_info_t *di) } /* like getnextrxp but not take off the ring */ -static void *_dma_peeknextrxp(dma_info_t *di) +static void *_dma_peeknextrxp(struct dma_info *di) { uint end, i; @@ -893,7 +1052,7 @@ static void *_dma_peeknextrxp(dma_info_t *di) end = B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, - dma64dd_t); + struct dma64desc); for (i = di->rxin; i != end; i = NEXTRXD(i)) if (di->rxp[i]) @@ -902,17 +1061,17 @@ static void *_dma_peeknextrxp(dma_info_t *di) return NULL; } -static void _dma_rxreclaim(dma_info_t *di) +static void _dma_rxreclaim(struct dma_info *di) { void *p; DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); while ((p = _dma_getnextrxp(di, true))) - bcm_pkt_buf_free_skb(p); + brcmu_pkt_buf_free_skb(p); } -static void *_dma_getnextrxp(dma_info_t *di, bool forceall) +static void *_dma_getnextrxp(struct dma_info *di, bool forceall) { if (di->nrxd == 0) return NULL; @@ -920,34 +1079,34 @@ static void *_dma_getnextrxp(dma_info_t *di, bool forceall) return dma64_getnextrxp(di, forceall); } -static void _dma_txblock(dma_info_t *di) +static void _dma_txblock(struct dma_info *di) { - di->hnddma.txavail = 0; + di->dma.txavail = 0; } -static void _dma_txunblock(dma_info_t *di) +static void _dma_txunblock(struct dma_info *di) { - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; } -static uint _dma_txactive(dma_info_t *di) +static uint _dma_txactive(struct dma_info *di) { return NTXDACTIVE(di->txin, di->txout); } -static uint _dma_txpending(dma_info_t *di) +static uint _dma_txpending(struct dma_info *di) { uint curr; curr = B2I(((R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, - dma64dd_t); + struct dma64desc); return NTXDACTIVE(curr, di->txout); } -static uint _dma_txcommitted(dma_info_t *di) +static uint _dma_txcommitted(struct dma_info *di) { uint ptr; uint txin = di->txin; @@ -955,27 +1114,27 @@ static uint _dma_txcommitted(dma_info_t *di) if (txin == di->txout) return 0; - ptr = B2I(R_REG(&di->d64txregs->ptr), dma64dd_t); + ptr = B2I(R_REG(&di->d64txregs->ptr), struct dma64desc); return NTXDACTIVE(di->txin, ptr); } -static uint _dma_rxactive(dma_info_t *di) +static uint _dma_rxactive(struct dma_info *di) { return NRXDACTIVE(di->rxin, di->rxout); } -static void _dma_counterreset(dma_info_t *di) +static void _dma_counterreset(struct dma_info *di) { /* reset all software counter */ - di->hnddma.rxgiants = 0; - di->hnddma.rxnobuf = 0; - di->hnddma.txnobuf = 0; + di->dma.rxgiants = 0; + di->dma.rxnobuf = 0; + di->dma.txnobuf = 0; } -static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags) +static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) { - uint dmactrlflags = di->hnddma.dmactrlflags; + uint dmactrlflags = di->dma.dmactrlflags; if (di == NULL) { DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name)); @@ -1004,16 +1163,16 @@ static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags) } } - di->hnddma.dmactrlflags = dmactrlflags; + di->dma.dmactrlflags = dmactrlflags; return dmactrlflags; } /* get the address of the var in order to change later */ -static unsigned long _dma_getvar(dma_info_t *di, const char *name) +static unsigned long _dma_getvar(struct dma_info *di, const char *name) { if (!strcmp(name, "&txavail")) - return (unsigned long)&(di->hnddma.txavail); + return (unsigned long)&(di->dma.txavail); return 0; } @@ -1033,7 +1192,7 @@ u8 dma_align_sizetobits(uint size) * descriptor ring size aligned location. This will ensure that the ring will * not cross page boundary */ -static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size, +static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size, u16 *alignbits, uint *alloced, dmaaddr_t *descpa) { @@ -1059,7 +1218,7 @@ static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size, /* 64-bit DMA functions */ -static void dma64_txinit(dma_info_t *di) +static void dma64_txinit(struct dma_info *di) { u32 control = D64_XC_XE; @@ -1069,10 +1228,10 @@ static void dma64_txinit(dma_info_t *di) return; di->txin = di->txout = 0; - di->hnddma.txavail = di->ntxd - 1; + di->dma.txavail = di->ntxd - 1; /* clear tx descriptor ring */ - memset((void *)di->txd64, '\0', (di->ntxd * sizeof(dma64dd_t))); + memset((void *)di->txd64, '\0', (di->ntxd * sizeof(struct dma64desc))); /* DMA engine with out alignment requirement requires table to be inited * before enabling the engine @@ -1080,7 +1239,7 @@ static void dma64_txinit(dma_info_t *di) if (!di->aligndesc_4k) _dma_ddtable_init(di, DMA_TX, di->txdpa); - if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0) + if ((di->dma.dmactrlflags & DMA_CTRL_PEN) == 0) control |= D64_XC_PD; OR_REG(&di->d64txregs->control, control); @@ -1091,7 +1250,7 @@ static void dma64_txinit(dma_info_t *di) _dma_ddtable_init(di, DMA_TX, di->txdpa); } -static bool dma64_txenabled(dma_info_t *di) +static bool dma64_txenabled(struct dma_info *di) { u32 xc; @@ -1100,7 +1259,7 @@ static bool dma64_txenabled(dma_info_t *di) return (xc != 0xffffffff) && (xc & D64_XC_XE); } -static void dma64_txsuspend(dma_info_t *di) +static void dma64_txsuspend(struct dma_info *di) { DMA_TRACE(("%s: dma_txsuspend\n", di->name)); @@ -1110,7 +1269,7 @@ static void dma64_txsuspend(dma_info_t *di) OR_REG(&di->d64txregs->control, D64_XC_SE); } -static void dma64_txresume(dma_info_t *di) +static void dma64_txresume(struct dma_info *di) { DMA_TRACE(("%s: dma_txresume\n", di->name)); @@ -1120,21 +1279,21 @@ static void dma64_txresume(dma_info_t *di) AND_REG(&di->d64txregs->control, ~D64_XC_SE); } -static bool dma64_txsuspended(dma_info_t *di) +static bool dma64_txsuspended(struct dma_info *di) { return (di->ntxd == 0) || ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE); } -static void dma64_txreclaim(dma_info_t *di, txd_range_t range) +static void dma64_txreclaim(struct dma_info *di, enum txd_range range) { void *p; DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, - (range == HNDDMA_RANGE_ALL) ? "all" : + (range == DMA_RANGE_ALL) ? "all" : ((range == - HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : + DMA_RANGE_TRANSMITTED) ? "transmitted" : "transferred"))); if (di->txin == di->txout) @@ -1142,24 +1301,24 @@ static void dma64_txreclaim(dma_info_t *di, txd_range_t range) while ((p = dma64_getnexttxp(di, range))) { /* For unframed data, we don't have any packets to free */ - if (!(di->hnddma.dmactrlflags & DMA_CTRL_UNFRAMED)) - bcm_pkt_buf_free_skb(p); + if (!(di->dma.dmactrlflags & DMA_CTRL_UNFRAMED)) + brcmu_pkt_buf_free_skb(p); } } -static bool dma64_txstopped(dma_info_t *di) +static bool dma64_txstopped(struct dma_info *di) { return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED); } -static bool dma64_rxstopped(dma_info_t *di) +static bool dma64_rxstopped(struct dma_info *di) { return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED); } -static bool dma64_alloc(dma_info_t *di, uint direction) +static bool dma64_alloc(struct dma_info *di, uint direction) { u16 size; uint ddlen; @@ -1168,7 +1327,7 @@ static bool dma64_alloc(dma_info_t *di, uint direction) u16 align; u16 align_bits; - ddlen = sizeof(dma64dd_t); + ddlen = sizeof(struct dma64desc); size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); align_bits = di->dmadesc_align; @@ -1182,7 +1341,8 @@ static bool dma64_alloc(dma_info_t *di, uint direction) return false; } align = (1 << align_bits); - di->txd64 = (dma64dd_t *) roundup((unsigned long)va, align); + di->txd64 = (struct dma64desc *) + roundup((unsigned long)va, align); di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va); PHYSADDRLOSET(di->txdpa, PHYSADDRLO(di->txdpaorig) + di->txdalign); @@ -1196,7 +1356,8 @@ static bool dma64_alloc(dma_info_t *di, uint direction) return false; } align = (1 << align_bits); - di->rxd64 = (dma64dd_t *) roundup((unsigned long)va, align); + di->rxd64 = (struct dma64desc *) + roundup((unsigned long)va, align); di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va); PHYSADDRLOSET(di->rxdpa, PHYSADDRLO(di->rxdpaorig) + di->rxdalign); @@ -1207,7 +1368,7 @@ static bool dma64_alloc(dma_info_t *di, uint direction) return true; } -static bool dma64_txreset(dma_info_t *di) +static bool dma64_txreset(struct dma_info *di) { u32 status; @@ -1232,7 +1393,7 @@ static bool dma64_txreset(dma_info_t *di) return status == D64_XS0_XS_DISABLED; } -static bool dma64_rxidle(dma_info_t *di) +static bool dma64_rxidle(struct dma_info *di) { DMA_TRACE(("%s: dma_rxidle\n", di->name)); @@ -1243,7 +1404,7 @@ static bool dma64_rxidle(dma_info_t *di) (R_REG(&di->d64rxregs->ptr) & D64_RS0_CD_MASK)); } -static bool dma64_rxreset(dma_info_t *di) +static bool dma64_rxreset(struct dma_info *di) { u32 status; @@ -1258,7 +1419,7 @@ static bool dma64_rxreset(dma_info_t *di) return status == D64_RS0_RS_DISABLED; } -static bool dma64_rxenabled(dma_info_t *di) +static bool dma64_rxenabled(struct dma_info *di) { u32 rc; @@ -1266,7 +1427,7 @@ static bool dma64_rxenabled(dma_info_t *di) return (rc != 0xffffffff) && (rc & D64_RC_RE); } -static bool dma64_txsuspendedidle(dma_info_t *di) +static bool dma64_txsuspendedidle(struct dma_info *di) { if (di->ntxd == 0) @@ -1286,7 +1447,7 @@ static bool dma64_txsuspendedidle(dma_info_t *di) * We return a pointer to the beginning of the DATA buffer of the current descriptor. * If DMA is idle, we return NULL. */ -static void *dma64_getpos(dma_info_t *di, bool direction) +static void *dma64_getpos(struct dma_info *di, bool direction) { void *va; bool idle; @@ -1296,12 +1457,12 @@ static void *dma64_getpos(dma_info_t *di, bool direction) cd_offset = R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK; idle = !NTXDACTIVE(di->txin, di->txout); - va = di->txp[B2I(cd_offset, dma64dd_t)]; + va = di->txp[B2I(cd_offset, struct dma64desc)]; } else { cd_offset = R_REG(&di->d64rxregs->status0) & D64_XS0_CD_MASK; idle = !NRXDACTIVE(di->rxin, di->rxout); - va = di->rxp[B2I(cd_offset, dma64dd_t)]; + va = di->rxp[B2I(cd_offset, struct dma64desc)]; } /* If DMA is IDLE, return NULL */ @@ -1316,12 +1477,13 @@ static void *dma64_getpos(dma_info_t *di, bool direction) /* TX of unframed data * * Adds a DMA ring descriptor for the data pointed to by "buf". - * This is for DMA of a buffer of data and is unlike other hnddma TX functions + * This is for DMA of a buffer of data and is unlike other dma TX functions * that take a pointer to a "packet" * Each call to this is results in a single descriptor being added for "len" bytes of * data starting at "buf", it doesn't handle chained buffers. */ -static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit) +static int +dma64_txunframed(struct dma_info *di, void *buf, uint len, bool commit) { u16 txout; u32 flags = 0; @@ -1355,18 +1517,18 @@ static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit) /* kick the chip */ if (commit) { W_REG(&di->d64txregs->ptr, - di->xmtptrbase + I2B(txout, dma64dd_t)); + di->xmtptrbase + I2B(txout, struct dma64desc)); } /* tx flow control */ - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; return 0; outoftxd: DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __func__)); - di->hnddma.txavail = 0; - di->hnddma.txnobuf++; + di->dma.txavail = 0; + di->dma.txnobuf++; return -1; } @@ -1374,7 +1536,7 @@ static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit) * WARNING: call must check the return value for error. * the error(toss frames) could be fatal and cause many subsequent hard to debug problems */ -static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, +static int dma64_txfast(struct dma_info *di, struct sk_buff *p0, bool commit) { struct sk_buff *p, *next; @@ -1394,7 +1556,7 @@ static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, */ for (p = p0; p; p = next) { uint nsegs, j; - hnddma_seg_map_t *map; + struct dma_seg_map *map; data = p->data; len = p->len; @@ -1410,7 +1572,7 @@ static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, /* get physical address of buffer start */ if (DMASGLIST_ENAB) memset(&di->txp_dmah[txout], 0, - sizeof(hnddma_seg_map_t)); + sizeof(struct dma_seg_map)); pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE); @@ -1471,41 +1633,41 @@ static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, /* kick the chip */ if (commit) W_REG(&di->d64txregs->ptr, - di->xmtptrbase + I2B(txout, dma64dd_t)); + di->xmtptrbase + I2B(txout, struct dma64desc)); /* tx flow control */ - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; return 0; outoftxd: DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name)); - bcm_pkt_buf_free_skb(p0); - di->hnddma.txavail = 0; - di->hnddma.txnobuf++; + brcmu_pkt_buf_free_skb(p0); + di->dma.txavail = 0; + di->dma.txnobuf++; return -1; } /* * Reclaim next completed txd (txds if using chained buffers) in the range * specified and return associated packet. - * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be + * If range is DMA_RANGE_TRANSMITTED, reclaim descriptors that have be * transmitted as noted by the hardware "CurrDescr" pointer. - * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be + * If range is DMA_RANGE_TRANSFERED, reclaim descriptors that have be * transferred by the DMA as noted by the hardware "ActiveDescr" pointer. - * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and + * If range is DMA_RANGE_ALL, reclaim all txd(s) posted to the ring and * return associated packet regardless of the value of hardware pointers. */ -static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range) +static void *dma64_getnexttxp(struct dma_info *di, enum txd_range range) { u16 start, end, i; u16 active_desc; void *txp; DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, - (range == HNDDMA_RANGE_ALL) ? "all" : + (range == DMA_RANGE_ALL) ? "all" : ((range == - HNDDMA_RANGE_TRANSMITTED) ? "transmitted" : + DMA_RANGE_TRANSMITTED) ? "transmitted" : "transferred"))); if (di->ntxd == 0) @@ -1514,24 +1676,23 @@ static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range) txp = NULL; start = di->txin; - if (range == HNDDMA_RANGE_ALL) + if (range == DMA_RANGE_ALL) end = di->txout; else { dma64regs_t *dregs = di->d64txregs; - end = - (u16) (B2I - (((R_REG(&dregs->status0) & + end = (u16) (B2I(((R_REG(&dregs->status0) & D64_XS0_CD_MASK) - - di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t)); + di->xmtptrbase) & D64_XS0_CD_MASK, + struct dma64desc)); - if (range == HNDDMA_RANGE_TRANSFERED) { + if (range == DMA_RANGE_TRANSFERED) { active_desc = (u16) (R_REG(&dregs->status1) & D64_XS1_AD_MASK); active_desc = (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK; - active_desc = B2I(active_desc, dma64dd_t); + active_desc = B2I(active_desc, struct dma64desc); if (end != active_desc) end = PREVTXD(active_desc); } @@ -1542,7 +1703,7 @@ static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range) for (i = start; i != end && !txp; i = NEXTTXD(i)) { dmaaddr_t pa; - hnddma_seg_map_t *map = NULL; + struct dma_seg_map *map = NULL; uint size, j, nsegs; PHYSADDRLOSET(pa, @@ -1579,7 +1740,7 @@ static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range) di->txin = i; /* tx flow control */ - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; return txp; @@ -1588,7 +1749,7 @@ static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range) return NULL; } -static void *dma64_getnextrxp(dma_info_t *di, bool forceall) +static void *dma64_getnextrxp(struct dma_info *di, bool forceall) { uint i, curr; void *rxp; @@ -1602,7 +1763,7 @@ static void *dma64_getnextrxp(dma_info_t *di, bool forceall) curr = B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) - - di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t); + di->rcvptrbase) & D64_RS0_CD_MASK, struct dma64desc); /* ignore curr if forceall */ if (!forceall && (i == curr)) @@ -1642,7 +1803,7 @@ static bool _dma64_addrext(dma64regs_t *dma64regs) /* * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). */ -static void dma64_txrotate(dma_info_t *di) +static void dma64_txrotate(struct dma_info *di) { u16 ad; uint nactive; @@ -1652,10 +1813,9 @@ static void dma64_txrotate(dma_info_t *di) u16 first, last; nactive = _dma_txactive(di); - ad = (u16) (B2I - ((((R_REG(&di->d64txregs->status1) & - D64_XS1_AD_MASK) - - di->xmtptrbase) & D64_XS1_AD_MASK), dma64dd_t)); + ad = (u16) (B2I((((R_REG(&di->d64txregs->status1) & + D64_XS1_AD_MASK) - di->xmtptrbase) & + D64_XS1_AD_MASK), struct dma64desc)); rot = TXD(ad - di->txin); /* full-ring case is a lot harder - don't worry about this */ @@ -1696,8 +1856,9 @@ static void dma64_txrotate(dma_info_t *di) /* Move the map */ if (DMASGLIST_ENAB) { memcpy(&di->txp_dmah[new], &di->txp_dmah[old], - sizeof(hnddma_seg_map_t)); - memset(&di->txp_dmah[old], 0, sizeof(hnddma_seg_map_t)); + sizeof(struct dma_seg_map)); + memset(&di->txp_dmah[old], 0, + sizeof(struct dma_seg_map)); } di->txp[old] = NULL; @@ -1706,14 +1867,14 @@ static void dma64_txrotate(dma_info_t *di) /* update txin and txout */ di->txin = ad; di->txout = TXD(di->txout + rot); - di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; /* kick the chip */ W_REG(&di->d64txregs->ptr, - di->xmtptrbase + I2B(di->txout, dma64dd_t)); + di->xmtptrbase + I2B(di->txout, struct dma64desc)); } -uint dma_addrwidth(si_t *sih, void *dmaregs) +uint dma_addrwidth(struct si_pub *sih, void *dmaregs) { /* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */ /* DMA engine is 64-bit capable */ @@ -1736,10 +1897,10 @@ uint dma_addrwidth(si_t *sih, void *dmaregs) * engine. This function calls a caller-supplied function for each packet in * the caller specified dma chain. */ -void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc) +void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc) (void *pkt, void *arg_a), void *arg_a) { - dma_info_t *di = (dma_info_t *) dmah; + struct dma_info *di = (struct dma_info *) dmah; uint i = di->txin; uint end = di->txout; struct sk_buff *skb; diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/brcmsmac/dma.h similarity index 61% rename from drivers/staging/brcm80211/include/hnddma.h rename to drivers/staging/brcm80211/brcmsmac/dma.h index fbbcb9b5ae62..9c8b9a6a557e 100644 --- a/drivers/staging/brcm80211/include/hnddma.h +++ b/drivers/staging/brcm80211/brcmsmac/dma.h @@ -14,13 +14,37 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _hnddma_h_ -#define _hnddma_h_ +#ifndef _BRCM_DMA_H_ +#define _BRCM_DMA_H_ -#ifndef _hnddma_pub_ -#define _hnddma_pub_ -struct hnddma_pub; -#endif /* _hnddma_pub_ */ +#include "types.h" /* forward structure declarations */ + +/* DMA structure: + * support two DMA engines: 32 bits address or 64 bit addressing + * basic DMA register set is per channel(transmit or receive) + * a pair of channels is defined for convenience + */ + +/* 32 bits addressing */ + +struct dma32diag { /* diag access */ + u32 fifoaddr; /* diag address */ + u32 fifodatalow; /* low 32bits of data */ + u32 fifodatahigh; /* high 32bits of data */ + u32 pad; /* reserved */ +}; + +/* 64 bits addressing */ + +/* dma registers per channel(xmt or rcv) */ +struct dma64regs { + u32 control; /* enable, et al */ + u32 ptr; /* last descriptor posted to chip */ + u32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ + u32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ + u32 status0; /* current descriptor, xmt state */ + u32 status1; /* active descriptor, xmt error */ +}; /* map/unmap direction */ #define DMA_TX 1 /* TX direction for DMA */ @@ -28,64 +52,64 @@ struct hnddma_pub; #define BUS_SWAP32(v) (v) /* range param for dma_getnexttxp() and dma_txreclaim */ -typedef enum txd_range { - HNDDMA_RANGE_ALL = 1, - HNDDMA_RANGE_TRANSMITTED, - HNDDMA_RANGE_TRANSFERED -} txd_range_t; +enum txd_range { + DMA_RANGE_ALL = 1, + DMA_RANGE_TRANSMITTED, + DMA_RANGE_TRANSFERED +}; /* dma function type */ -typedef void (*di_detach_t) (struct hnddma_pub *dmah); -typedef bool(*di_txreset_t) (struct hnddma_pub *dmah); -typedef bool(*di_rxreset_t) (struct hnddma_pub *dmah); -typedef bool(*di_rxidle_t) (struct hnddma_pub *dmah); -typedef void (*di_txinit_t) (struct hnddma_pub *dmah); -typedef bool(*di_txenabled_t) (struct hnddma_pub *dmah); -typedef void (*di_rxinit_t) (struct hnddma_pub *dmah); -typedef void (*di_txsuspend_t) (struct hnddma_pub *dmah); -typedef void (*di_txresume_t) (struct hnddma_pub *dmah); -typedef bool(*di_txsuspended_t) (struct hnddma_pub *dmah); -typedef bool(*di_txsuspendedidle_t) (struct hnddma_pub *dmah); -typedef int (*di_txfast_t) (struct hnddma_pub *dmah, struct sk_buff *p, +typedef void (*di_detach_t) (struct dma_pub *dmah); +typedef bool(*di_txreset_t) (struct dma_pub *dmah); +typedef bool(*di_rxreset_t) (struct dma_pub *dmah); +typedef bool(*di_rxidle_t) (struct dma_pub *dmah); +typedef void (*di_txinit_t) (struct dma_pub *dmah); +typedef bool(*di_txenabled_t) (struct dma_pub *dmah); +typedef void (*di_rxinit_t) (struct dma_pub *dmah); +typedef void (*di_txsuspend_t) (struct dma_pub *dmah); +typedef void (*di_txresume_t) (struct dma_pub *dmah); +typedef bool(*di_txsuspended_t) (struct dma_pub *dmah); +typedef bool(*di_txsuspendedidle_t) (struct dma_pub *dmah); +typedef int (*di_txfast_t) (struct dma_pub *dmah, struct sk_buff *p, bool commit); -typedef int (*di_txunframed_t) (struct hnddma_pub *dmah, void *p, uint len, +typedef int (*di_txunframed_t) (struct dma_pub *dmah, void *p, uint len, bool commit); -typedef void *(*di_getpos_t) (struct hnddma_pub *di, bool direction); -typedef void (*di_fifoloopbackenable_t) (struct hnddma_pub *dmah); -typedef bool(*di_txstopped_t) (struct hnddma_pub *dmah); -typedef bool(*di_rxstopped_t) (struct hnddma_pub *dmah); -typedef bool(*di_rxenable_t) (struct hnddma_pub *dmah); -typedef bool(*di_rxenabled_t) (struct hnddma_pub *dmah); -typedef void *(*di_rx_t) (struct hnddma_pub *dmah); -typedef bool(*di_rxfill_t) (struct hnddma_pub *dmah); -typedef void (*di_txreclaim_t) (struct hnddma_pub *dmah, txd_range_t range); -typedef void (*di_rxreclaim_t) (struct hnddma_pub *dmah); -typedef unsigned long (*di_getvar_t) (struct hnddma_pub *dmah, +typedef void *(*di_getpos_t) (struct dma_pub *di, bool direction); +typedef void (*di_fifoloopbackenable_t) (struct dma_pub *dmah); +typedef bool(*di_txstopped_t) (struct dma_pub *dmah); +typedef bool(*di_rxstopped_t) (struct dma_pub *dmah); +typedef bool(*di_rxenable_t) (struct dma_pub *dmah); +typedef bool(*di_rxenabled_t) (struct dma_pub *dmah); +typedef void *(*di_rx_t) (struct dma_pub *dmah); +typedef bool(*di_rxfill_t) (struct dma_pub *dmah); +typedef void (*di_txreclaim_t) (struct dma_pub *dmah, enum txd_range range); +typedef void (*di_rxreclaim_t) (struct dma_pub *dmah); +typedef unsigned long (*di_getvar_t) (struct dma_pub *dmah, const char *name); -typedef void *(*di_getnexttxp_t) (struct hnddma_pub *dmah, txd_range_t range); -typedef void *(*di_getnextrxp_t) (struct hnddma_pub *dmah, bool forceall); -typedef void *(*di_peeknexttxp_t) (struct hnddma_pub *dmah); -typedef void *(*di_peeknextrxp_t) (struct hnddma_pub *dmah); -typedef void (*di_rxparam_get_t) (struct hnddma_pub *dmah, u16 *rxoffset, +typedef void *(*di_getnexttxp_t) (struct dma_pub *dmah, enum txd_range range); +typedef void *(*di_getnextrxp_t) (struct dma_pub *dmah, bool forceall); +typedef void *(*di_peeknexttxp_t) (struct dma_pub *dmah); +typedef void *(*di_peeknextrxp_t) (struct dma_pub *dmah); +typedef void (*di_rxparam_get_t) (struct dma_pub *dmah, u16 *rxoffset, u16 *rxbufsize); -typedef void (*di_txblock_t) (struct hnddma_pub *dmah); -typedef void (*di_txunblock_t) (struct hnddma_pub *dmah); -typedef uint(*di_txactive_t) (struct hnddma_pub *dmah); -typedef void (*di_txrotate_t) (struct hnddma_pub *dmah); -typedef void (*di_counterreset_t) (struct hnddma_pub *dmah); -typedef uint(*di_ctrlflags_t) (struct hnddma_pub *dmah, uint mask, uint flags); -typedef char *(*di_dump_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b, +typedef void (*di_txblock_t) (struct dma_pub *dmah); +typedef void (*di_txunblock_t) (struct dma_pub *dmah); +typedef uint(*di_txactive_t) (struct dma_pub *dmah); +typedef void (*di_txrotate_t) (struct dma_pub *dmah); +typedef void (*di_counterreset_t) (struct dma_pub *dmah); +typedef uint(*di_ctrlflags_t) (struct dma_pub *dmah, uint mask, uint flags); +typedef char *(*di_dump_t) (struct dma_pub *dmah, struct brcmu_strbuf *b, bool dumpring); -typedef char *(*di_dumptx_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b, +typedef char *(*di_dumptx_t) (struct dma_pub *dmah, struct brcmu_strbuf *b, bool dumpring); -typedef char *(*di_dumprx_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b, +typedef char *(*di_dumprx_t) (struct dma_pub *dmah, struct brcmu_strbuf *b, bool dumpring); -typedef uint(*di_rxactive_t) (struct hnddma_pub *dmah); -typedef uint(*di_txpending_t) (struct hnddma_pub *dmah); -typedef uint(*di_txcommitted_t) (struct hnddma_pub *dmah); +typedef uint(*di_rxactive_t) (struct dma_pub *dmah); +typedef uint(*di_txpending_t) (struct dma_pub *dmah); +typedef uint(*di_txcommitted_t) (struct dma_pub *dmah); /* dma opsvec */ -typedef struct di_fcn_s { +struct di_fcn_s { di_detach_t detach; di_txinit_t txinit; di_txreset_t txreset; @@ -130,14 +154,14 @@ typedef struct di_fcn_s { di_txpending_t txpending; di_txcommitted_t txcommitted; uint endnum; -} di_fcn_t; +}; /* * Exported data structure (read-only) */ /* export structure */ -struct hnddma_pub { - const di_fcn_t *di_fn; /* DMA function pointers */ +struct dma_pub { + const struct di_fcn_s *di_fn; /* DMA function pointers */ uint txavail; /* # free tx descriptors */ uint dmactrlflags; /* dma control flags */ @@ -148,12 +172,12 @@ struct hnddma_pub { uint txnobuf; /* tx out of dma descriptors */ }; -extern struct hnddma_pub *dma_attach(char *name, si_t *sih, +extern struct dma_pub *dma_attach(char *name, struct si_pub *sih, void *dmaregstx, void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, uint rxoffset, uint *msg_level); -extern const di_fcn_t dma64proc; +extern const struct di_fcn_s dma64proc; #define dma_detach(di) (dma64proc.detach(di)) #define dma_txreset(di) (dma64proc.txreset(di)) @@ -201,8 +225,8 @@ extern const di_fcn_t dma64proc; * SB attach provides ability to probe backplane and dma core capabilities * This info is needed by DMA_ALLOC_CONSISTENT in dma attach */ -extern uint dma_addrwidth(si_t *sih, void *dmaregs); -void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc) +extern uint dma_addrwidth(struct si_pub *sih, void *dmaregs); +void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc) (void *pkt, void *arg_a), void *arg_a); /* @@ -223,4 +247,4 @@ static inline void dma_spin_for_len(uint len, struct sk_buff *head) #endif /* defined(__mips__) */ } -#endif /* _hnddma_h_ */ +#endif /* _BRCM_DMA_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c b/drivers/staging/brcm80211/brcmsmac/mac80211_if.c similarity index 67% rename from drivers/staging/brcm80211/brcmsmac/wl_mac80211.c rename to drivers/staging/brcm80211/brcmsmac/mac80211_if.c index 82612290b99b..d6de44e430d3 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c +++ b/drivers/staging/brcm80211/brcmsmac/mac80211_if.c @@ -16,44 +16,46 @@ #define __UNDEF_NO_VERSION__ -#include #include -#include -#include -#include #include #include #include #include #include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "phy/wlc_phy_int.h" +#include +#include "nicpci.h" +#include "phy/phy_int.h" #include "d11.h" -#include "wlc_types.h" -#include "wlc_cfg.h" -#include "phy/phy_version.h" -#include "wlc_key.h" -#include "wlc_channel.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wl_dbg.h" -#include "wl_export.h" -#include "wl_ucode.h" -#include "wl_mac80211.h" +#include "channel.h" +#include "scb.h" +#include "pub.h" +#include "ucode_loader.h" +#include "mac80211_if.h" #define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ -static void wl_timer(unsigned long data); -static void _wl_timer(struct wl_timer *t); +#define LOCK(wl) spin_lock_bh(&(wl)->lock) +#define UNLOCK(wl) spin_unlock_bh(&(wl)->lock) + +/* locking from inside brcms_isr */ +#define ISR_LOCK(wl, flags)\ + do {\ + spin_lock(&(wl)->isr_lock);\ + (void)(flags); } \ + while (0) + +#define ISR_UNLOCK(wl, flags)\ + do {\ + spin_unlock(&(wl)->isr_lock);\ + (void)(flags); } \ + while (0) + +/* locking under LOCK() to synchronize with brcms_isr */ +#define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags) +#define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags) + +static void brcms_timer(unsigned long data); +static void _brcms_timer(struct brcms_timer *t); static int ieee_hw_init(struct ieee80211_hw *hw); @@ -70,22 +72,20 @@ static int wl_linux_watchdog(void *ctx); FIF_OTHER_BSS | \ FIF_BCN_PRBRESP_PROMISC) -static int wl_found; +static int n_adapters_found; -#define WL_DEV_IF(dev) ((struct wl_if *)netdev_priv(dev)) -#define WL_INFO(dev) ((struct wl_info *)(WL_DEV_IF(dev)->wl)) -static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev); -static void wl_release_fw(struct wl_info *wl); +static int brcms_request_fw(struct brcms_info *wl, struct pci_dev *pdev); +static void brcms_release_fw(struct brcms_info *wl); /* local prototypes */ -static void wl_dpc(unsigned long data); -static irqreturn_t wl_isr(int irq, void *dev_id); +static void brcms_dpc(unsigned long data); +static irqreturn_t brcms_isr(int irq, void *dev_id); -static int __devinit wl_pci_probe(struct pci_dev *pdev, +static int __devinit brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -static void wl_remove(struct pci_dev *pdev); -static void wl_free(struct wl_info *wl); -static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br); +static void brcms_remove(struct pci_dev *pdev); +static void brcms_free(struct brcms_info *wl); +static void brcms_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br); MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); @@ -93,14 +93,16 @@ MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); MODULE_LICENSE("Dual BSD/GPL"); /* recognized PCI IDs */ -static struct pci_device_id wl_id_table[] = { +static DEFINE_PCI_DEVICE_TABLE(brcms_pci_id_table) = { {PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43225 2G */ {PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43224 DUAL */ {PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 4313 DUAL */ + /* 43224 Ven */ + {PCI_VENDOR_ID_BROADCOM, 0x0576, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, {0} }; -MODULE_DEVICE_TABLE(pci, wl_id_table); +MODULE_DEVICE_TABLE(pci, brcms_pci_id_table); #ifdef BCMDBG static int msglevel = 0xdeadbeef; @@ -113,88 +115,89 @@ module_param(phymsglevel, int, 0); #define WL_TO_HW(wl) (wl->pub->ieee_hw) /* MAC80211 callback functions */ -static int wl_ops_start(struct ieee80211_hw *hw); -static void wl_ops_stop(struct ieee80211_hw *hw); -static int wl_ops_add_interface(struct ieee80211_hw *hw, +static int brcms_ops_start(struct ieee80211_hw *hw); +static void brcms_ops_stop(struct ieee80211_hw *hw); +static int brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); -static void wl_ops_remove_interface(struct ieee80211_hw *hw, +static void brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); -static int wl_ops_config(struct ieee80211_hw *hw, u32 changed); -static void wl_ops_bss_info_changed(struct ieee80211_hw *hw, +static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed); +static void brcms_ops_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u32 changed); -static void wl_ops_configure_filter(struct ieee80211_hw *hw, +static void brcms_ops_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 multicast); -static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, +static int brcms_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); -static void wl_ops_sw_scan_start(struct ieee80211_hw *hw); -static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw); -static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf); -static int wl_ops_get_stats(struct ieee80211_hw *hw, +static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw); +static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw); +static void brcms_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf); +static int brcms_ops_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats); -static void wl_ops_sta_notify(struct ieee80211_hw *hw, +static void brcms_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, struct ieee80211_sta *sta); -static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, +static int brcms_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); -static u64 wl_ops_get_tsf(struct ieee80211_hw *hw); -static int wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw); +static int brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -static int wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta); -static int wl_ops_ampdu_action(struct ieee80211_hw *hw, +static int brcms_ops_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +static int brcms_ops_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size); -static void wl_ops_rfkill_poll(struct ieee80211_hw *hw); -static void wl_ops_flush(struct ieee80211_hw *hw, bool drop); +static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw); +static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop); -static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; - WL_LOCK(wl); + LOCK(wl); if (!wl->pub->up) { wiphy_err(wl->wiphy, "ops->tx called while down\n"); kfree_skb(skb); goto done; } - wlc_sendpkt_mac80211(wl->wlc, skb, hw); + brcms_c_sendpkt_mac80211(wl->wlc, skb, hw); done: - WL_UNLOCK(wl); + UNLOCK(wl); } -static int wl_ops_start(struct ieee80211_hw *hw) +static int brcms_ops_start(struct ieee80211_hw *hw) { - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; bool blocked; /* struct ieee80211_channel *curchan = hw->conf.channel; */ ieee80211_wake_queues(hw); - WL_LOCK(wl); - blocked = wl_rfkill_set_hw_state(wl); - WL_UNLOCK(wl); + LOCK(wl); + blocked = brcms_rfkill_set_hw_state(wl); + UNLOCK(wl); if (!blocked) wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); return 0; } -static void wl_ops_stop(struct ieee80211_hw *hw) +static void brcms_ops_stop(struct ieee80211_hw *hw) { ieee80211_stop_queues(hw); } static int -wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct wl_info *wl; + struct brcms_info *wl; int err; /* Just STA for now */ @@ -209,28 +212,28 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) } wl = HW_TO_WL(hw); - WL_LOCK(wl); - err = wl_up(wl); - WL_UNLOCK(wl); + LOCK(wl); + err = brcms_up(wl); + UNLOCK(wl); if (err != 0) { - wiphy_err(hw->wiphy, "%s: wl_up() returned %d\n", __func__, + wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, err); } return err; } static void -wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct wl_info *wl; + struct brcms_info *wl; wl = HW_TO_WL(hw); /* put driver in down state */ - WL_LOCK(wl); - wl_down(wl); - WL_UNLOCK(wl); + LOCK(wl); + brcms_down(wl); + UNLOCK(wl); } /* @@ -240,13 +243,13 @@ static int ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, enum nl80211_channel_type type) { - struct wl_info *wl = HW_TO_WL(hw); + struct brcms_info *wl = HW_TO_WL(hw); int err = 0; switch (type) { case NL80211_CHAN_HT20: case NL80211_CHAN_NO_HT: - err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value); + err = brcms_c_set(wl->wlc, BRCM_SET_CHANNEL, chan->hw_value); break; case NL80211_CHAN_HT40MINUS: case NL80211_CHAN_HT40PLUS: @@ -261,24 +264,24 @@ ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, return err; } -static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) +static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) { struct ieee80211_conf *conf = &hw->conf; - struct wl_info *wl = HW_TO_WL(hw); + struct brcms_info *wl = HW_TO_WL(hw); int err = 0; int new_int; struct wiphy *wiphy = hw->wiphy; - WL_LOCK(wl); + LOCK(wl); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { - if (wlc_iovar_setint - (wl->wlc, "bcn_li_bcn", conf->listen_interval)) { + if (brcms_c_set_par(wl->wlc, IOV_BCN_LI_BCN, + conf->listen_interval) < 0) { wiphy_err(wiphy, "%s: Error setting listen_interval\n", __func__); err = -EIO; goto config_out; } - wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int); + brcms_c_get_par(wl->wlc, IOV_BCN_LI_BCN, &new_int); } if (changed & IEEE80211_CONF_CHANGE_MONITOR) wiphy_err(wiphy, "%s: change monitor mode: %s (implement)\n", @@ -290,14 +293,14 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) "true" : "false"); if (changed & IEEE80211_CONF_CHANGE_POWER) { - if (wlc_iovar_setint - (wl->wlc, "qtxpower", conf->power_level * 4)) { + if (brcms_c_set_par(wl->wlc, IOV_QTXPOWER, + conf->power_level * 4) < 0) { wiphy_err(wiphy, "%s: Error setting power_level\n", __func__); err = -EIO; goto config_out; } - wlc_iovar_getint(wl->wlc, "qtxpower", &new_int); + brcms_c_get_par(wl->wlc, IOV_QTXPOWER, &new_int); if (new_int != (conf->power_level * 4)) wiphy_err(wiphy, "%s: Power level req != actual, %d %d" "\n", __func__, conf->power_level * 4, @@ -307,15 +310,15 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) err = ieee_set_channel(hw, conf->channel, conf->channel_type); } if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { - if (wlc_set - (wl->wlc, WLC_SET_SRL, + if (brcms_c_set + (wl->wlc, BRCM_SET_SRL, conf->short_frame_max_tx_count) < 0) { wiphy_err(wiphy, "%s: Error setting srl\n", __func__); err = -EIO; goto config_out; } - if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count) - < 0) { + if (brcms_c_set(wl->wlc, BRCM_SET_LRL, + conf->long_frame_max_tx_count) < 0) { wiphy_err(wiphy, "%s: Error setting lrl\n", __func__); err = -EIO; goto config_out; @@ -323,16 +326,16 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) } config_out: - WL_UNLOCK(wl); + UNLOCK(wl); return err; } static void -wl_ops_bss_info_changed(struct ieee80211_hw *hw, +brcms_ops_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u32 changed) { - struct wl_info *wl = HW_TO_WL(hw); + struct brcms_info *wl = HW_TO_WL(hw); struct wiphy *wiphy = hw->wiphy; int val; @@ -342,9 +345,9 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, */ wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME, __func__, info->assoc ? "" : "dis"); - WL_LOCK(wl); - wlc_associate_upd(wl->wlc, info->assoc); - WL_UNLOCK(wl); + LOCK(wl); + brcms_c_associate_upd(wl->wlc, info->assoc); + UNLOCK(wl); } if (changed & BSS_CHANGED_ERP_SLOT) { /* slot timing changed */ @@ -352,23 +355,23 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, val = 1; else val = 0; - WL_LOCK(wl); - wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val); - WL_UNLOCK(wl); + LOCK(wl); + brcms_c_set(wl->wlc, BRCMS_SET_SHORTSLOT_OVERRIDE, val); + UNLOCK(wl); } if (changed & BSS_CHANGED_HT) { /* 802.11n parameters changed */ u16 mode = info->ht_operation_mode; - WL_LOCK(wl); - wlc_protection_upd(wl->wlc, WLC_PROT_N_CFG, + LOCK(wl); + brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_CFG, mode & IEEE80211_HT_OP_MODE_PROTECTION); - wlc_protection_upd(wl->wlc, WLC_PROT_N_NONGF, + brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_NONGF, mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); - wlc_protection_upd(wl->wlc, WLC_PROT_N_OBSS, + brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_OBSS, mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT); - WL_UNLOCK(wl); + UNLOCK(wl); } if (changed & BSS_CHANGED_BASIC_RATES) { struct ieee80211_supported_band *bi; @@ -378,43 +381,43 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, int error; /* retrieve the current rates */ - WL_LOCK(wl); - error = wlc_ioctl(wl->wlc, WLC_GET_CURR_RATESET, + LOCK(wl); + error = brcms_c_ioctl(wl->wlc, BRCM_GET_CURR_RATESET, &rs, sizeof(rs), NULL); - WL_UNLOCK(wl); + UNLOCK(wl); if (error) { wiphy_err(wiphy, "%s: retrieve rateset failed: %d\n", __func__, error); return; } br_mask = info->basic_rates; - bi = hw->wiphy->bands[wlc_get_curband(wl->wlc)]; + bi = hw->wiphy->bands[brcms_c_get_curband(wl->wlc)]; for (i = 0; i < bi->n_bitrates; i++) { /* convert to internal rate value */ rate = (bi->bitrates[i].bitrate << 1) / 10; /* set/clear basic rate flag */ - wl_set_basic_rate(&rs, rate, br_mask & 1); + brcms_set_basic_rate(&rs, rate, br_mask & 1); br_mask >>= 1; } /* update the rate set */ - WL_LOCK(wl); - wlc_ioctl(wl->wlc, WLC_SET_RATESET, &rs, sizeof(rs), NULL); - WL_UNLOCK(wl); + LOCK(wl); + brcms_c_ioctl(wl->wlc, BRCM_SET_RATESET, &rs, sizeof(rs), NULL); + UNLOCK(wl); } if (changed & BSS_CHANGED_BEACON_INT) { /* Beacon interval changed */ - WL_LOCK(wl); - wlc_set(wl->wlc, WLC_SET_BCNPRD, info->beacon_int); - WL_UNLOCK(wl); + LOCK(wl); + brcms_c_set(wl->wlc, BRCM_SET_BCNPRD, info->beacon_int); + UNLOCK(wl); } if (changed & BSS_CHANGED_BSSID) { /* BSSID changed, for whatever reason (IBSS and managed mode) */ - WL_LOCK(wl); - wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, + LOCK(wl); + brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid); - WL_UNLOCK(wl); + UNLOCK(wl); } if (changed & BSS_CHANGED_BEACON) { /* Beacon data changed, retrieve new beacon (beaconing modes) */ @@ -450,20 +453,15 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__, info->qos ? "true" : "false"); } - if (changed & BSS_CHANGED_IDLE) { - /* Idle changed for this BSS/interface */ - wiphy_err(wiphy, "%s: BSS idle: %s (implement)\n", __func__, - info->idle ? "true" : "false"); - } return; } static void -wl_ops_configure_filter(struct ieee80211_hw *hw, +brcms_ops_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 multicast) { - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; struct wiphy *wiphy = hw->wiphy; changed_flags &= MAC_FILTERS; @@ -481,68 +479,68 @@ wl_ops_configure_filter(struct ieee80211_hw *hw, if (changed_flags & FIF_OTHER_BSS) wiphy_err(wiphy, "FIF_OTHER_BSS\n"); if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { - WL_LOCK(wl); + LOCK(wl); if (*total_flags & FIF_BCN_PRBRESP_PROMISC) { wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS; - wlc_mac_bcn_promisc_change(wl->wlc, 1); + brcms_c_mac_bcn_promisc_change(wl->wlc, 1); } else { - wlc_mac_bcn_promisc_change(wl->wlc, 0); + brcms_c_mac_bcn_promisc_change(wl->wlc, 0); wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS; } - WL_UNLOCK(wl); + UNLOCK(wl); } return; } static int -wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) +brcms_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) { return 0; } -static void wl_ops_sw_scan_start(struct ieee80211_hw *hw) +static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw) { - struct wl_info *wl = hw->priv; - WL_LOCK(wl); - wlc_scan_start(wl->wlc); - WL_UNLOCK(wl); + struct brcms_info *wl = hw->priv; + LOCK(wl); + brcms_c_scan_start(wl->wlc); + UNLOCK(wl); return; } -static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw) +static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw) { - struct wl_info *wl = hw->priv; - WL_LOCK(wl); - wlc_scan_stop(wl->wlc); - WL_UNLOCK(wl); + struct brcms_info *wl = hw->priv; + LOCK(wl); + brcms_c_scan_stop(wl->wlc); + UNLOCK(wl); return; } -static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf) +static void brcms_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf) { wiphy_err(hw->wiphy, "%s: Enter\n", __func__); return; } static int -wl_ops_get_stats(struct ieee80211_hw *hw, +brcms_ops_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) { - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; struct wl_cnt *cnt; - WL_LOCK(wl); + LOCK(wl); cnt = wl->pub->_cnt; stats->dot11ACKFailureCount = 0; stats->dot11RTSFailureCount = 0; stats->dot11FCSErrorCount = 0; stats->dot11RTSSuccessCount = 0; - WL_UNLOCK(wl); + UNLOCK(wl); return 0; } static void -wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +brcms_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, struct ieee80211_sta *sta) { switch (cmd) { @@ -555,32 +553,32 @@ wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } static int -wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, +brcms_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params) { - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; - WL_LOCK(wl); - wlc_wme_setparams(wl->wlc, queue, params, true); - WL_UNLOCK(wl); + LOCK(wl); + brcms_c_wme_setparams(wl->wlc, queue, params, true); + UNLOCK(wl); return 0; } -static u64 wl_ops_get_tsf(struct ieee80211_hw *hw) +static u64 brcms_ops_get_tsf(struct ieee80211_hw *hw) { wiphy_err(hw->wiphy, "%s: Enter\n", __func__); return 0; } static int -wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct scb *scb; int i; - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; /* Init the scb */ scb = (struct scb *)sta->drv_priv; @@ -594,7 +592,7 @@ wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, wl->pub->global_ampdu = &(scb->scb_ampdu); wl->pub->global_ampdu->scb = scb; wl->pub->global_ampdu->max_pdu = 16; - bcm_pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID, + brcmu_pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID, AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT); sta->ht_cap.ht_supported = true; @@ -609,21 +607,21 @@ wl_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } static int -wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +brcms_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { return 0; } static int -wl_ops_ampdu_action(struct ieee80211_hw *hw, +brcms_ops_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size) { struct scb *scb = (struct scb *)sta->drv_priv; - struct wl_info *wl = hw->priv; + struct brcms_info *wl = hw->priv; int status; if (WARN_ON(scb->magic != SCB_MAGIC)) @@ -634,27 +632,37 @@ wl_ops_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_RX_STOP: break; case IEEE80211_AMPDU_TX_START: - WL_LOCK(wl); - status = wlc_aggregatable(wl->wlc, tid); - WL_UNLOCK(wl); + LOCK(wl); + status = brcms_c_aggregatable(wl->wlc, tid); + UNLOCK(wl); if (!status) { wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n", tid); return -EINVAL; } - /* XXX: Use the starting sequence number provided ... */ + /* Future improvement: Use the starting sequence number provided ... */ *ssn = 0; ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_STOP: - WL_LOCK(wl); - wlc_ampdu_flush(wl->wlc, sta, tid); - WL_UNLOCK(wl); + LOCK(wl); + brcms_c_ampdu_flush(wl->wlc, sta, tid); + UNLOCK(wl); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: - /* Not sure what to do here */ + /* + * BA window size from ADDBA response ('buf_size') defines how + * many outstanding MPDUs are allowed for the BA stream by + * recipient and traffic class. 'ampdu_factor' gives maximum + * AMPDU size. + */ + LOCK(wl); + brcms_c_ampdu_tx_operational(wl->wlc, tid, buf_size, + (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + + sta->ht_cap.ampdu_factor)) - 1); + UNLOCK(wl); /* Power save wakeup */ break; default: @@ -665,58 +673,58 @@ wl_ops_ampdu_action(struct ieee80211_hw *hw, return 0; } -static void wl_ops_rfkill_poll(struct ieee80211_hw *hw) +static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw) { - struct wl_info *wl = HW_TO_WL(hw); + struct brcms_info *wl = HW_TO_WL(hw); bool blocked; - WL_LOCK(wl); - blocked = wlc_check_radio_disabled(wl->wlc); - WL_UNLOCK(wl); + LOCK(wl); + blocked = brcms_c_check_radio_disabled(wl->wlc); + UNLOCK(wl); wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); } -static void wl_ops_flush(struct ieee80211_hw *hw, bool drop) +static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop) { - struct wl_info *wl = HW_TO_WL(hw); + struct brcms_info *wl = HW_TO_WL(hw); no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false"); /* wait for packet queue and dma fifos to run empty */ - WL_LOCK(wl); - wlc_wait_for_tx_completion(wl->wlc, drop); - WL_UNLOCK(wl); + LOCK(wl); + brcms_c_wait_for_tx_completion(wl->wlc, drop); + UNLOCK(wl); } -static const struct ieee80211_ops wl_ops = { - .tx = wl_ops_tx, - .start = wl_ops_start, - .stop = wl_ops_stop, - .add_interface = wl_ops_add_interface, - .remove_interface = wl_ops_remove_interface, - .config = wl_ops_config, - .bss_info_changed = wl_ops_bss_info_changed, - .configure_filter = wl_ops_configure_filter, - .set_tim = wl_ops_set_tim, - .sw_scan_start = wl_ops_sw_scan_start, - .sw_scan_complete = wl_ops_sw_scan_complete, - .set_tsf = wl_ops_set_tsf, - .get_stats = wl_ops_get_stats, - .sta_notify = wl_ops_sta_notify, - .conf_tx = wl_ops_conf_tx, - .get_tsf = wl_ops_get_tsf, - .sta_add = wl_ops_sta_add, - .sta_remove = wl_ops_sta_remove, - .ampdu_action = wl_ops_ampdu_action, - .rfkill_poll = wl_ops_rfkill_poll, - .flush = wl_ops_flush, +static const struct ieee80211_ops brcms_ops = { + .tx = brcms_ops_tx, + .start = brcms_ops_start, + .stop = brcms_ops_stop, + .add_interface = brcms_ops_add_interface, + .remove_interface = brcms_ops_remove_interface, + .config = brcms_ops_config, + .bss_info_changed = brcms_ops_bss_info_changed, + .configure_filter = brcms_ops_configure_filter, + .set_tim = brcms_ops_set_tim, + .sw_scan_start = brcms_ops_sw_scan_start, + .sw_scan_complete = brcms_ops_sw_scan_complete, + .set_tsf = brcms_ops_set_tsf, + .get_stats = brcms_ops_get_stats, + .sta_notify = brcms_ops_sta_notify, + .conf_tx = brcms_ops_conf_tx, + .get_tsf = brcms_ops_get_tsf, + .sta_add = brcms_ops_sta_add, + .sta_remove = brcms_ops_sta_remove, + .ampdu_action = brcms_ops_ampdu_action, + .rfkill_poll = brcms_ops_rfkill_poll, + .flush = brcms_ops_flush, }; /* - * is called in wl_pci_probe() context, therefore no locking required. + * is called in brcms_pci_probe() context, therefore no locking required. */ -static int wl_set_hint(struct wl_info *wl, char *abbrev) +static int brcms_set_hint(struct brcms_info *wl, char *abbrev) { return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); } @@ -727,25 +735,25 @@ static int wl_set_hint(struct wl_info *wl, char *abbrev) * Attach to the WL device identified by vendor and device parameters. * regs is a host accessible memory address pointing to WL device registers. * - * wl_attach is not defined as static because in the case where no bus + * brcms_attach is not defined as static because in the case where no bus * is defined, wl_attach will never be called, and thus, gcc will issue * a warning that this function is defined but not used if we declare * it as static. * * - * is called in wl_pci_probe() context, therefore no locking required. + * is called in brcms_pci_probe() context, therefore no locking required. */ -static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, +static struct brcms_info *brcms_attach(u16 vendor, u16 device, + unsigned long regs, uint bustype, void *btparam, uint irq) { - struct wl_info *wl = NULL; + struct brcms_info *wl = NULL; int unit, err; - unsigned long base_addr; struct ieee80211_hw *hw; u8 perm[ETH_ALEN]; - unit = wl_found; + unit = n_adapters_found; err = 0; if (unit < 0) { @@ -763,15 +771,13 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, atomic_set(&wl->callbacks, 0); /* setup the bottom half handler */ - tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl); + tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl); base_addr = regs; - if (bustype == PCI_BUS) { - wl->piomode = false; - } else if (bustype == RPC_BUS) { + if (bustype == PCI_BUS || bustype == RPC_BUS) { /* Do nothing */ } else { bustype = PCI_BUS; @@ -788,42 +794,41 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, spin_lock_init(&wl->isr_lock); /* prepare ucode */ - if (wl_request_fw(wl, (struct pci_dev *)btparam) < 0) { + if (brcms_request_fw(wl, (struct pci_dev *)btparam) < 0) { wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in " "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); - wl_release_fw(wl); - wl_remove((struct pci_dev *)btparam); + brcms_release_fw(wl); + brcms_remove((struct pci_dev *)btparam); return NULL; } /* common load-time initialization */ - wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, + wl->wlc = brcms_c_attach((void *)wl, vendor, device, unit, false, wl->regsva, wl->bcm_bustype, btparam, &err); - wl_release_fw(wl); + brcms_release_fw(wl); if (!wl->wlc) { - wiphy_err(wl->wiphy, "%s: wlc_attach() failed with code %d\n", + wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n", KBUILD_MODNAME, err); goto fail; } - wl->pub = wlc_pub(wl->wlc); + wl->pub = brcms_c_pub(wl->wlc); wl->pub->ieee_hw = hw; - if (wlc_iovar_setint(wl->wlc, "mpc", 0)) { + if (brcms_c_set_par(wl->wlc, IOV_MPC, 0) < 0) { wiphy_err(wl->wiphy, "wl%d: Error setting MPC variable to 0\n", unit); } /* register our interrupt handler */ - if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { + if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); goto fail; } wl->irq = irq; /* register module */ - wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog, - NULL); + brcms_c_module_register(wl->pub, "linux", wl, wl_linux_watchdog, NULL); if (ieee_hw_init(hw)) { wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit, @@ -843,19 +848,19 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, } if (wl->pub->srom_ccode[0]) - err = wl_set_hint(wl, wl->pub->srom_ccode); + err = brcms_set_hint(wl, wl->pub->srom_ccode); else - err = wl_set_hint(wl, "US"); + err = brcms_set_hint(wl, "US"); if (err) { wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n", __func__, err); } - wl_found++; + n_adapters_found++; return wl; fail: - wl_free(wl); + brcms_free(wl); return NULL; } @@ -870,7 +875,7 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, .max_power = 19, \ } -static struct ieee80211_channel wl_2ghz_chantable[] = { +static struct ieee80211_channel brcms_2ghz_chantable[] = { CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS), CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS), @@ -902,7 +907,7 @@ static struct ieee80211_channel wl_2ghz_chantable[] = { .max_power = 21, \ } -static struct ieee80211_channel wl_5ghz_nphy_chantable[] = { +static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = { /* UNII-1 */ CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS), CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS), @@ -970,7 +975,7 @@ static struct ieee80211_channel wl_5ghz_nphy_chantable[] = { .hw_value = (rate100m / 5), \ } -static struct ieee80211_rate wl_legacy_ratetable[] = { +static struct ieee80211_rate legacy_ratetable[] = { RATE(10, 0), RATE(20, IEEE80211_RATE_SHORT_PREAMBLE), RATE(55, IEEE80211_RATE_SHORT_PREAMBLE), @@ -985,12 +990,12 @@ static struct ieee80211_rate wl_legacy_ratetable[] = { RATE(540, 0), }; -static struct ieee80211_supported_band wl_band_2GHz_nphy = { +static struct ieee80211_supported_band brcms_band_2GHz_nphy = { .band = IEEE80211_BAND_2GHZ, - .channels = wl_2ghz_chantable, - .n_channels = ARRAY_SIZE(wl_2ghz_chantable), - .bitrates = wl_legacy_ratetable, - .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable), + .channels = brcms_2ghz_chantable, + .n_channels = ARRAY_SIZE(brcms_2ghz_chantable), + .bitrates = legacy_ratetable, + .n_bitrates = ARRAY_SIZE(legacy_ratetable), .ht_cap = { /* from include/linux/ieee80211.h */ .cap = IEEE80211_HT_CAP_GRN_FLD | @@ -1007,12 +1012,12 @@ static struct ieee80211_supported_band wl_band_2GHz_nphy = { } }; -static struct ieee80211_supported_band wl_band_5GHz_nphy = { +static struct ieee80211_supported_band brcms_band_5GHz_nphy = { .band = IEEE80211_BAND_5GHZ, - .channels = wl_5ghz_nphy_chantable, - .n_channels = ARRAY_SIZE(wl_5ghz_nphy_chantable), - .bitrates = wl_legacy_ratetable + 4, - .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable) - 4, + .channels = brcms_5ghz_nphy_chantable, + .n_channels = ARRAY_SIZE(brcms_5ghz_nphy_chantable), + .bitrates = legacy_ratetable + 4, + .n_bitrates = ARRAY_SIZE(legacy_ratetable) - 4, .ht_cap = { /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */ .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */ @@ -1028,11 +1033,11 @@ static struct ieee80211_supported_band wl_band_5GHz_nphy = { }; /* - * is called in wl_pci_probe() context, therefore no locking required. + * is called in brcms_pci_probe() context, therefore no locking required. */ static int ieee_hw_rate_init(struct ieee80211_hw *hw) { - struct wl_info *wl = HW_TO_WL(hw); + struct brcms_info *wl = HW_TO_WL(hw); int has_5g; char phy_list[4]; @@ -1041,17 +1046,16 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; - if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) { + if (brcms_c_get(wl->wlc, BRCM_GET_PHYLIST, (int *)&phy_list) < 0) wiphy_err(hw->wiphy, "Phy list failed\n"); - } if (phy_list[0] == 'n' || phy_list[0] == 'c') { if (phy_list[0] == 'c') { /* Single stream */ - wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0; - wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72; + brcms_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0; + brcms_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72; } - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy; + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &brcms_band_2GHz_nphy; } else { return -EPERM; } @@ -1061,7 +1065,7 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) has_5g++; if (phy_list[0] == 'n' || phy_list[0] == 'c') { hw->wiphy->bands[IEEE80211_BAND_5GHZ] = - &wl_band_5GHz_nphy; + &brcms_band_5GHz_nphy; } else { return -EPERM; } @@ -1070,7 +1074,7 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) } /* - * is called in wl_pci_probe() context, therefore no locking required. + * is called in brcms_pci_probe() context, therefore no locking required. */ static int ieee_hw_init(struct ieee80211_hw *hw) { @@ -1079,13 +1083,8 @@ static int ieee_hw_init(struct ieee80211_hw *hw) | IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_AMPDU_AGGREGATION; - hw->extra_tx_headroom = wlc_get_header_len(); + hw->extra_tx_headroom = brcms_c_get_header_len(); hw->queues = N_TX_QUEUES; - /* FIXME: this doesn't seem to be used properly in minstrel_ht. - * mac80211/status.c:ieee80211_tx_status() checks this value, - * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate() - * appears to always set 3 rates - */ hw->max_rates = 2; /* Primary rate and 1 fallback rate */ hw->channel_change_time = 7 * 1000; /* channel change time is dependent on chip and band */ @@ -1101,15 +1100,15 @@ static int ieee_hw_init(struct ieee80211_hw *hw) * determines if a device is a WL device, and if so, attaches it. * * This function determines if a device pointed to by pdev is a WL device, - * and if so, performs a wl_attach() on it. + * and if so, performs a brcms_attach() on it. * * Perimeter lock is initialized in the course of this function. */ static int __devinit -wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int rc; - struct wl_info *wl; + struct brcms_info *wl; struct ieee80211_hw *hw; u32 val; @@ -1118,7 +1117,8 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) PCI_FUNC(pdev->devfn), pdev->irq); if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) || - (((pdev->device & 0xff00) != 0x4300) && + ((pdev->device != 0x0576) && + ((pdev->device & 0xff00) != 0x4300) && ((pdev->device & 0xff00) != 0x4700) && ((pdev->device < 43000) || (pdev->device > 43999)))) return -ENODEV; @@ -1136,7 +1136,7 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if ((val & 0x0000ff00) != 0) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops); + hw = ieee80211_alloc_hw(sizeof(struct brcms_info), &brcms_ops); if (!hw) { pr_err("%s: ieee80211_alloc_hw failed\n", __func__); return -ENOMEM; @@ -1148,43 +1148,44 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) memset(hw->priv, 0, sizeof(*wl)); - wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0), - PCI_BUS, pdev, pdev->irq); + wl = brcms_attach(pdev->vendor, pdev->device, + pci_resource_start(pdev, 0), PCI_BUS, pdev, + pdev->irq); if (!wl) { - pr_err("%s: %s: wl_attach failed!\n", KBUILD_MODNAME, + pr_err("%s: %s: brcms_attach failed!\n", KBUILD_MODNAME, __func__); return -ENODEV; } return 0; } -static int wl_suspend(struct pci_dev *pdev, pm_message_t state) +static int brcms_suspend(struct pci_dev *pdev, pm_message_t state) { - struct wl_info *wl; + struct brcms_info *wl; struct ieee80211_hw *hw; hw = pci_get_drvdata(pdev); wl = HW_TO_WL(hw); if (!wl) { wiphy_err(wl->wiphy, - "wl_suspend: pci_get_drvdata failed\n"); + "brcms_suspend: pci_get_drvdata failed\n"); return -ENODEV; } /* only need to flag hw is down for proper resume */ - WL_LOCK(wl); + LOCK(wl); wl->pub->hw_up = false; - WL_UNLOCK(wl); + UNLOCK(wl); pci_save_state(pdev); pci_disable_device(pdev); return pci_set_power_state(pdev, PCI_D3hot); } -static int wl_resume(struct pci_dev *pdev) +static int brcms_resume(struct pci_dev *pdev) { - struct wl_info *wl; + struct brcms_info *wl; struct ieee80211_hw *hw; int err = 0; u32 val; @@ -1193,7 +1194,7 @@ static int wl_resume(struct pci_dev *pdev) wl = HW_TO_WL(hw); if (!wl) { wiphy_err(wl->wiphy, - "wl: wl_resume: pci_get_drvdata failed\n"); + "wl: brcms_resume: pci_get_drvdata failed\n"); return -ENODEV; } @@ -1215,97 +1216,80 @@ static int wl_resume(struct pci_dev *pdev) /* * done. driver will be put in up state - * in wl_ops_add_interface() call. + * in brcms_ops_add_interface() call. */ return err; } /* -* called from both kernel as from wl_*() +* called from both kernel as from this kernel module. * precondition: perimeter lock is not acquired. */ -static void wl_remove(struct pci_dev *pdev) +static void brcms_remove(struct pci_dev *pdev) { - struct wl_info *wl; + struct brcms_info *wl; struct ieee80211_hw *hw; int status; hw = pci_get_drvdata(pdev); wl = HW_TO_WL(hw); if (!wl) { - pr_err("wl: wl_remove: pci_get_drvdata failed\n"); + pr_err("wl: brcms_remove: pci_get_drvdata failed\n"); return; } - WL_LOCK(wl); - status = wlc_chipmatch(pdev->vendor, pdev->device); - WL_UNLOCK(wl); + LOCK(wl); + status = brcms_c_chipmatch(pdev->vendor, pdev->device); + UNLOCK(wl); if (!status) { - wiphy_err(wl->wiphy, "wl: wl_remove: wlc_chipmatch failed\n"); + wiphy_err(wl->wiphy, "wl: brcms_remove: chipmatch " + "failed\n"); return; } if (wl->wlc) { wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); ieee80211_unregister_hw(hw); - WL_LOCK(wl); - wl_down(wl); - WL_UNLOCK(wl); + LOCK(wl); + brcms_down(wl); + UNLOCK(wl); } pci_disable_device(pdev); - wl_free(wl); + brcms_free(wl); pci_set_drvdata(pdev, NULL); ieee80211_free_hw(hw); } -static struct pci_driver wl_pci_driver = { +static struct pci_driver brcms_pci_driver = { .name = KBUILD_MODNAME, - .probe = wl_pci_probe, - .suspend = wl_suspend, - .resume = wl_resume, - .remove = __devexit_p(wl_remove), - .id_table = wl_id_table, + .probe = brcms_pci_probe, + .suspend = brcms_suspend, + .resume = brcms_resume, + .remove = __devexit_p(brcms_remove), + .id_table = brcms_pci_id_table, }; /** * This is the main entry point for the WL driver. * * This function determines if a device pointed to by pdev is a WL device, - * and if so, performs a wl_attach() on it. + * and if so, performs a brcms_attach() on it. * */ -static int __init wl_module_init(void) +static int __init brcms_module_init(void) { int error = -ENODEV; #ifdef BCMDBG if (msglevel != 0xdeadbeef) - wl_msg_level = msglevel; - else { - char *var = getvar(NULL, "wl_msglevel"); - if (var) { - unsigned long value; - - (void)strict_strtoul(var, 0, &value); - wl_msg_level = value; - } - } + brcm_msg_level = msglevel; if (phymsglevel != 0xdeadbeef) phyhal_msg_level = phymsglevel; - else { - char *var = getvar(NULL, "phy_msglevel"); - if (var) { - unsigned long value; - - (void)strict_strtoul(var, 0, &value); - phyhal_msg_level = value; - } - } #endif /* BCMDBG */ - error = pci_register_driver(&wl_pci_driver); + error = pci_register_driver(&brcms_pci_driver); if (!error) return 0; @@ -1321,14 +1305,14 @@ static int __init wl_module_init(void) * system. * */ -static void __exit wl_module_exit(void) +static void __exit brcms_module_exit(void) { - pci_unregister_driver(&wl_pci_driver); + pci_unregister_driver(&brcms_pci_driver); } -module_init(wl_module_init); -module_exit(wl_module_exit); +module_init(brcms_module_init); +module_exit(brcms_module_exit); /** * This function frees the WL per-device resources. @@ -1339,13 +1323,13 @@ module_exit(wl_module_exit); * precondition: can both be called locked and unlocked * */ -static void wl_free(struct wl_info *wl) +static void brcms_free(struct brcms_info *wl) { - struct wl_timer *t, *next; + struct brcms_timer *t, *next; /* free ucode data */ if (wl->fw.fw_cnt) - wl_ucode_data_free(); + brcms_ucode_data_free(); if (wl->irq) free_irq(wl->irq, wl); @@ -1353,12 +1337,12 @@ static void wl_free(struct wl_info *wl) tasklet_kill(&wl->tasklet); if (wl->pub) { - wlc_module_unregister(wl->pub, "linux", wl); + brcms_c_module_unregister(wl->pub, "linux", wl); } /* free common resources */ if (wl->wlc) { - wlc_detach(wl->wlc); + brcms_c_detach(wl->wlc); wl->wlc = NULL; wl->pub = NULL; } @@ -1390,7 +1374,7 @@ static void wl_free(struct wl_info *wl) } /* flags the given rate in rateset as requested */ -static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br) +static void brcms_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br) { u32 i; @@ -1399,9 +1383,9 @@ static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br) continue; if (is_br) - rs->rates[i] |= WLC_RATE_FLAG; + rs->rates[i] |= BRCMS_RATE_FLAG; else - rs->rates[i] &= WLC_RATE_MASK; + rs->rates[i] &= BRCMS_RATE_MASK; return; } } @@ -1409,8 +1393,8 @@ static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br) /* * precondition: perimeter lock has been acquired */ -void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, - int prio) +void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, + bool state, int prio) { wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__); } @@ -1418,21 +1402,21 @@ void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, /* * precondition: perimeter lock has been acquired */ -void wl_init(struct wl_info *wl) +void brcms_init(struct brcms_info *wl) { BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit); - wl_reset(wl); + brcms_reset(wl); - wlc_init(wl->wlc); + brcms_c_init(wl->wlc); } /* * precondition: perimeter lock has been acquired */ -uint wl_reset(struct wl_info *wl) +uint brcms_reset(struct brcms_info *wl) { BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit); - wlc_reset(wl->wlc); + brcms_c_reset(wl->wlc); /* dpc will not be rescheduled */ wl->resched = 0; @@ -1444,54 +1428,54 @@ uint wl_reset(struct wl_info *wl) * These are interrupt on/off entry points. Disable interrupts * during interrupt state transition. */ -void wl_intrson(struct wl_info *wl) +void brcms_intrson(struct brcms_info *wl) { unsigned long flags; INT_LOCK(wl, flags); - wlc_intrson(wl->wlc); + brcms_c_intrson(wl->wlc); INT_UNLOCK(wl, flags); } /* * precondition: perimeter lock has been acquired */ -bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth) +bool wl_alloc_dma_resources(struct brcms_info *wl, uint addrwidth) { return true; } -u32 wl_intrsoff(struct wl_info *wl) +u32 brcms_intrsoff(struct brcms_info *wl) { unsigned long flags; u32 status; INT_LOCK(wl, flags); - status = wlc_intrsoff(wl->wlc); + status = brcms_c_intrsoff(wl->wlc); INT_UNLOCK(wl, flags); return status; } -void wl_intrsrestore(struct wl_info *wl, u32 macintmask) +void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask) { unsigned long flags; INT_LOCK(wl, flags); - wlc_intrsrestore(wl->wlc, macintmask); + brcms_c_intrsrestore(wl->wlc, macintmask); INT_UNLOCK(wl, flags); } /* * precondition: perimeter lock has been acquired */ -int wl_up(struct wl_info *wl) +int brcms_up(struct brcms_info *wl) { int error = 0; if (wl->pub->up) return 0; - error = wlc_up(wl->wlc); + error = brcms_c_up(wl->wlc); return error; } @@ -1499,37 +1483,37 @@ int wl_up(struct wl_info *wl) /* * precondition: perimeter lock has been acquired */ -void wl_down(struct wl_info *wl) +void brcms_down(struct brcms_info *wl) { uint callbacks, ret_val = 0; /* call common down function */ - ret_val = wlc_down(wl->wlc); + ret_val = brcms_c_down(wl->wlc); callbacks = atomic_read(&wl->callbacks) - ret_val; /* wait for down callbacks to complete */ - WL_UNLOCK(wl); + UNLOCK(wl); /* For HIGH_only driver, it's important to actually schedule other work, * not just spin wait since everything runs at schedule level */ SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000); - WL_LOCK(wl); + LOCK(wl); } -static irqreturn_t wl_isr(int irq, void *dev_id) +static irqreturn_t brcms_isr(int irq, void *dev_id) { - struct wl_info *wl; + struct brcms_info *wl; bool ours, wantdpc; unsigned long flags; - wl = (struct wl_info *) dev_id; + wl = (struct brcms_info *) dev_id; - WL_ISRLOCK(wl, flags); + ISR_LOCK(wl, flags); /* call common first level interrupt handler */ - ours = wlc_isr(wl->wlc, &wantdpc); + ours = brcms_c_isr(wl->wlc, &wantdpc); if (ours) { /* if more to do... */ if (wantdpc) { @@ -1540,18 +1524,18 @@ static irqreturn_t wl_isr(int irq, void *dev_id) } } - WL_ISRUNLOCK(wl, flags); + ISR_UNLOCK(wl, flags); return IRQ_RETVAL(ours); } -static void wl_dpc(unsigned long data) +static void brcms_dpc(unsigned long data) { - struct wl_info *wl; + struct brcms_info *wl; - wl = (struct wl_info *) data; + wl = (struct brcms_info *) data; - WL_LOCK(wl); + LOCK(wl); /* call the common second level interrupt handler */ if (wl->pub->up) { @@ -1559,14 +1543,14 @@ static void wl_dpc(unsigned long data) unsigned long flags; INT_LOCK(wl, flags); - wlc_intrsupd(wl->wlc); + brcms_c_intrsupd(wl->wlc); INT_UNLOCK(wl, flags); } - wl->resched = wlc_dpc(wl->wlc, true); + wl->resched = brcms_c_dpc(wl->wlc, true); } - /* wlc_dpc() may bring the driver down */ + /* brcms_c_dpc() may bring the driver down */ if (!wl->pub->up) goto done; @@ -1575,27 +1559,27 @@ static void wl_dpc(unsigned long data) tasklet_schedule(&wl->tasklet); else { /* re-enable interrupts */ - wl_intrson(wl); + brcms_intrson(wl); } done: - WL_UNLOCK(wl); + UNLOCK(wl); } /* * is called by the kernel from software irq context */ -static void wl_timer(unsigned long data) +static void brcms_timer(unsigned long data) { - _wl_timer((struct wl_timer *) data); + _brcms_timer((struct brcms_timer *) data); } /* * precondition: perimeter lock is not acquired */ -static void _wl_timer(struct wl_timer *t) +static void _brcms_timer(struct brcms_timer *t) { - WL_LOCK(t->wl); + LOCK(t->wl); if (t->set) { if (t->periodic) { @@ -1611,7 +1595,7 @@ static void _wl_timer(struct wl_timer *t) atomic_dec(&t->wl->callbacks); - WL_UNLOCK(t->wl); + UNLOCK(t->wl); } /* @@ -1620,21 +1604,22 @@ static void _wl_timer(struct wl_timer *t) * * precondition: perimeter lock has been acquired */ -struct wl_timer *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), - void *arg, const char *name) +struct brcms_timer *brcms_init_timer(struct brcms_info *wl, + void (*fn) (void *arg), + void *arg, const char *name) { - struct wl_timer *t; + struct brcms_timer *t; - t = kzalloc(sizeof(struct wl_timer), GFP_ATOMIC); + t = kzalloc(sizeof(struct brcms_timer), GFP_ATOMIC); if (!t) { - wiphy_err(wl->wiphy, "wl%d: wl_init_timer: out of memory\n", + wiphy_err(wl->wiphy, "wl%d: brcms_init_timer: out of memory\n", wl->pub->unit); return 0; } init_timer(&t->timer); t->timer.data = (unsigned long) t; - t->timer.function = wl_timer; + t->timer.function = brcms_timer; t->wl = wl; t->fn = fn; t->arg = arg; @@ -1655,7 +1640,8 @@ struct wl_timer *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), * * precondition: perimeter lock has been acquired */ -void wl_add_timer(struct wl_info *wl, struct wl_timer *t, uint ms, int periodic) +void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *t, uint ms, + int periodic) { #ifdef BCMDBG if (t->set) { @@ -1677,7 +1663,7 @@ void wl_add_timer(struct wl_info *wl, struct wl_timer *t, uint ms, int periodic) * * precondition: perimeter lock has been acquired */ -bool wl_del_timer(struct wl_info *wl, struct wl_timer *t) +bool brcms_del_timer(struct brcms_info *wl, struct brcms_timer *t) { if (t->set) { t->set = false; @@ -1693,12 +1679,12 @@ bool wl_del_timer(struct wl_info *wl, struct wl_timer *t) /* * precondition: perimeter lock has been acquired */ -void wl_free_timer(struct wl_info *wl, struct wl_timer *t) +void brcms_free_timer(struct brcms_info *wl, struct brcms_timer *t) { - struct wl_timer *tmp; + struct brcms_timer *tmp; /* delete the timer in case it is active */ - wl_del_timer(wl, t); + brcms_del_timer(wl, t); if (wl->timers == t) { wl->timers = wl->timers->next; @@ -1735,13 +1721,13 @@ static int wl_linux_watchdog(void *ctx) return 0; } -struct wl_fw_hdr { +struct firmware_hdr { u32 offset; u32 len; u32 idx; }; -char *wl_firmwares[WL_MAX_FW] = { +char *brcms_firmwares[MAX_FW_IMAGES] = { "brcm/bcm43xx", NULL }; @@ -1749,13 +1735,13 @@ char *wl_firmwares[WL_MAX_FW] = { /* * precondition: perimeter lock has been acquired */ -int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) +int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) { int i, entry; const u8 *pdata; - struct wl_fw_hdr *hdr; + struct firmware_hdr *hdr; for (i = 0; i < wl->fw.fw_cnt; i++) { - hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data; + hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data; for (entry = 0; entry < wl->fw.hdr_num_entries[i]; entry++, hdr++) { if (hdr->idx == idx) { @@ -1779,16 +1765,16 @@ int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) } /* - * Precondition: Since this function is called in wl_pci_probe() context, + * Precondition: Since this function is called in brcms_pci_probe() context, * no locking is required. */ -int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) +int brcms_ucode_init_uint(struct brcms_info *wl, u32 *data, u32 idx) { int i, entry; const u8 *pdata; - struct wl_fw_hdr *hdr; + struct firmware_hdr *hdr; for (i = 0; i < wl->fw.fw_cnt; i++) { - hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data; + hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data; for (entry = 0; entry < wl->fw.hdr_num_entries[i]; entry++, hdr++) { if (hdr->idx == idx) { @@ -1808,21 +1794,21 @@ int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) } /* - * Precondition: Since this function is called in wl_pci_probe() context, + * Precondition: Since this function is called in brcms_pci_probe() context, * no locking is required. */ -static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) +static int brcms_request_fw(struct brcms_info *wl, struct pci_dev *pdev) { int status; struct device *device = &pdev->dev; char fw_name[100]; int i; - memset((void *)&wl->fw, 0, sizeof(struct wl_firmware)); - for (i = 0; i < WL_MAX_FW; i++) { - if (wl_firmwares[i] == NULL) + memset((void *)&wl->fw, 0, sizeof(struct brcms_firmware)); + for (i = 0; i < MAX_FW_IMAGES; i++) { + if (brcms_firmwares[i] == NULL) break; - sprintf(fw_name, "%s-%d.fw", wl_firmwares[i], + sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], UCODE_LOADER_API_VER); status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); if (status) { @@ -1830,7 +1816,7 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) KBUILD_MODNAME, fw_name); return status; } - sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i], + sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], UCODE_LOADER_API_VER); status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); if (status) { @@ -1839,28 +1825,28 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) return status; } wl->fw.hdr_num_entries[i] = - wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr)); + wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); } wl->fw.fw_cnt = i; - return wl_ucode_data_init(wl); + return brcms_ucode_data_init(wl); } /* * precondition: can both be called locked and unlocked */ -void wl_ucode_free_buf(void *p) +void brcms_ucode_free_buf(void *p) { kfree(p); } /* - * Precondition: Since this function is called in wl_pci_probe() context, + * Precondition: Since this function is called in brcms_pci_probe() context, * no locking is required. */ -static void wl_release_fw(struct wl_info *wl) +static void brcms_release_fw(struct brcms_info *wl) { int i; - for (i = 0; i < WL_MAX_FW; i++) { + for (i = 0; i < MAX_FW_IMAGES; i++) { release_firmware(wl->fw.fw_bin[i]); release_firmware(wl->fw.fw_hdr[i]); } @@ -1870,18 +1856,18 @@ static void wl_release_fw(struct wl_info *wl) /* * checks validity of all firmware images loaded from user space * - * Precondition: Since this function is called in wl_pci_probe() context, + * Precondition: Since this function is called in brcms_pci_probe() context, * no locking is required. */ -int wl_check_firmwares(struct wl_info *wl) +int brcms_check_firmwares(struct brcms_info *wl) { int i; int entry; int rc = 0; const struct firmware *fw; const struct firmware *fw_hdr; - struct wl_fw_hdr *ucode_hdr; - for (i = 0; i < WL_MAX_FW && rc == 0; i++) { + struct firmware_hdr *ucode_hdr; + for (i = 0; i < MAX_FW_IMAGES && rc == 0; i++) { fw = wl->fw.fw_bin[i]; fw_hdr = wl->fw.fw_hdr[i]; if (fw == NULL && fw_hdr == NULL) { @@ -1890,10 +1876,10 @@ int wl_check_firmwares(struct wl_info *wl) wiphy_err(wl->wiphy, "%s: invalid bin/hdr fw\n", __func__); rc = -EBADF; - } else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) { + } else if (fw_hdr->size % sizeof(struct firmware_hdr)) { wiphy_err(wl->wiphy, "%s: non integral fw hdr file " "size %zu/%zu\n", __func__, fw_hdr->size, - sizeof(struct wl_fw_hdr)); + sizeof(struct firmware_hdr)); rc = -EBADF; } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { wiphy_err(wl->wiphy, "%s: out of bounds fw file size " @@ -1901,7 +1887,7 @@ int wl_check_firmwares(struct wl_info *wl) rc = -EBADF; } else { /* check if ucode section overruns firmware image */ - ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data; + ucode_hdr = (struct firmware_hdr *)fw_hdr->data; for (entry = 0; entry < wl->fw.hdr_num_entries[i] && !rc; entry++, ucode_hdr++) { if (ucode_hdr->offset + ucode_hdr->len > @@ -1925,24 +1911,24 @@ int wl_check_firmwares(struct wl_info *wl) /* * precondition: perimeter lock has been acquired */ -bool wl_rfkill_set_hw_state(struct wl_info *wl) +bool brcms_rfkill_set_hw_state(struct brcms_info *wl) { - bool blocked = wlc_check_radio_disabled(wl->wlc); + bool blocked = brcms_c_check_radio_disabled(wl->wlc); - WL_UNLOCK(wl); + UNLOCK(wl); wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); if (blocked) wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy); - WL_LOCK(wl); + LOCK(wl); return blocked; } /* * precondition: perimeter lock has been acquired */ -void wl_msleep(struct wl_info *wl, uint ms) +void brcms_msleep(struct brcms_info *wl, uint ms) { - WL_UNLOCK(wl); + UNLOCK(wl); msleep(ms); - WL_LOCK(wl); + LOCK(wl); } diff --git a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h b/drivers/staging/brcm80211/brcmsmac/mac80211_if.h similarity index 50% rename from drivers/staging/brcm80211/brcmsmac/wl_mac80211.h rename to drivers/staging/brcm80211/brcmsmac/mac80211_if.h index f7a58b7a550a..5711e7c16b50 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h +++ b/drivers/staging/brcm80211/brcmsmac/mac80211_if.h @@ -14,8 +14,15 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wl_mac80211_h_ -#define _wl_mac80211_h_ +#ifndef _BRCM_MAC80211_IF_H_ +#define _BRCM_MAC80211_IF_H_ + +#include +#include + +/* softmac ioctl definitions */ +#define BRCMS_SET_SHORTSLOT_OVERRIDE 146 + #include @@ -23,35 +30,35 @@ * sleep so perimeter lock has to be a semaphore instead of spinlock. This requires timers to be * submitted to workqueue instead of being on kernel timer */ -struct wl_timer { +struct brcms_timer { struct timer_list timer; - struct wl_info *wl; + struct brcms_info *wl; void (*fn) (void *); void *arg; /* argument to fn */ uint ms; bool periodic; bool set; - struct wl_timer *next; + struct brcms_timer *next; #ifdef BCMDBG char *name; /* Description of the timer */ #endif }; -struct wl_if { +struct brcms_if { uint subunit; /* WDS/BSS unit */ struct pci_dev *pci_dev; }; -#define WL_MAX_FW 4 -struct wl_firmware { +#define MAX_FW_IMAGES 4 +struct brcms_firmware { u32 fw_cnt; - const struct firmware *fw_bin[WL_MAX_FW]; - const struct firmware *fw_hdr[WL_MAX_FW]; - u32 hdr_num_entries[WL_MAX_FW]; + const struct firmware *fw_bin[MAX_FW_IMAGES]; + const struct firmware *fw_hdr[MAX_FW_IMAGES]; + u32 hdr_num_entries[MAX_FW_IMAGES]; }; -struct wl_info { - struct wlc_pub *pub; /* pointer to public wlc state */ +struct brcms_info { + struct brcms_pub *pub; /* pointer to public wlc state */ void *wlc; /* pointer to private common os-independent data */ u32 magic; @@ -59,29 +66,45 @@ struct wl_info { spinlock_t lock; /* per-device perimeter lock */ spinlock_t isr_lock; /* per-device ISR synchronization lock */ + + /* bus type and regsva for unmap in brcms_free() */ uint bcm_bustype; /* bus type */ - bool piomode; /* set from insmod argument */ void *regsva; /* opaque chip registers virtual address */ + + /* timer related fields */ atomic_t callbacks; /* # outstanding callback functions */ - struct wl_timer *timers; /* timer cleanup queue */ + struct brcms_timer *timers; /* timer cleanup queue */ + struct tasklet_struct tasklet; /* dpc tasklet */ bool resched; /* dpc needs to be and is rescheduled */ #ifdef LINUXSTA_PS u32 pci_psstate[16]; /* pci ps-state save/restore */ #endif - struct wl_firmware fw; + struct brcms_firmware fw; struct wiphy *wiphy; }; -#define WL_LOCK(wl) spin_lock_bh(&(wl)->lock) -#define WL_UNLOCK(wl) spin_unlock_bh(&(wl)->lock) +/* misc callbacks */ +extern void brcms_init(struct brcms_info *wl); +extern uint brcms_reset(struct brcms_info *wl); +extern void brcms_intrson(struct brcms_info *wl); +extern u32 brcms_intrsoff(struct brcms_info *wl); +extern void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask); +extern int brcms_up(struct brcms_info *wl); +extern void brcms_down(struct brcms_info *wl); +extern void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, + bool state, int prio); +extern bool wl_alloc_dma_resources(struct brcms_info *wl, uint dmaddrwidth); +extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl); -/* locking from inside wl_isr */ -#define WL_ISRLOCK(wl, flags) do {spin_lock(&(wl)->isr_lock); (void)(flags); } while (0) -#define WL_ISRUNLOCK(wl, flags) do {spin_unlock(&(wl)->isr_lock); (void)(flags); } while (0) +/* timer functions */ +extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl, + void (*fn) (void *arg), void *arg, + const char *name); +extern void brcms_free_timer(struct brcms_info *wl, struct brcms_timer *timer); +extern void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *timer, + uint ms, int periodic); +extern bool brcms_del_timer(struct brcms_info *wl, struct brcms_timer *timer); +extern void brcms_msleep(struct brcms_info *wl, uint ms); -/* locking under WL_LOCK() to synchronize with wl_isr */ -#define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags) -#define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags) - -#endif /* _wl_mac80211_h_ */ +#endif /* _BRCM_MAC80211_IF_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.c b/drivers/staging/brcm80211/brcmsmac/main.c similarity index 56% rename from drivers/staging/brcm80211/brcmsmac/wlc_main.c rename to drivers/staging/brcm80211/brcmsmac/main.c index 4b4a31eff90c..1763c4535cd2 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.c +++ b/drivers/staging/brcm80211/brcmsmac/main.c @@ -13,47 +13,23 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include + #include #include -#include -#include -#include -#include -#include +#include #include -#include -#include -#include -#include -#include - -#include "wlc_pmu.h" -#include "d11.h" -#include "wlc_types.h" -#include "wlc_cfg.h" -#include "wlc_rate.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "wlc_bsscfg.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_channel.h" -#include "wlc_main.h" -#include "wlc_bmac.h" -#include "wlc_phy_hal.h" -#include "wlc_phy_shim.h" -#include "wlc_antsel.h" -#include "wlc_stf.h" -#include "wlc_ampdu.h" -#include "wl_export.h" -#include "wlc_alloc.h" -#include "wl_dbg.h" - -#include "wl_mac80211.h" +#include "rate.h" +#include "scb.h" +#include "phy/phy_hal.h" +#include "channel.h" +#include "bmac.h" +#include "antsel.h" +#include "stf.h" +#include "ampdu.h" +#include "alloc.h" +#include "mac80211_if.h" +#include "main.h" /* * WPA(2) definitions @@ -71,7 +47,6 @@ #define ALLPRIO -1 /* - * buffer length needed for wlc_format_ssid * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. */ #define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) @@ -79,11 +54,14 @@ #define TIMER_INTERVAL_WATCHDOG 1000 /* watchdog timer, in unit of ms */ #define TIMER_INTERVAL_RADIOCHK 800 /* radio monitor timer, in unit of ms */ -#ifndef WLC_MPC_MAX_DELAYCNT -#define WLC_MPC_MAX_DELAYCNT 10 /* Max MPC timeout, in unit of watchdog */ +/* Max MPC timeout, in unit of watchdog */ +#ifndef BRCMS_MPC_MAX_DELAYCNT +#define BRCMS_MPC_MAX_DELAYCNT 10 #endif -#define WLC_MPC_MIN_DELAYCNT 1 /* Min MPC timeout, in unit of watchdog */ -#define WLC_MPC_THRESHOLD 3 /* MPC count threshold level */ + +/* Min MPC timeout, in unit of watchdog */ +#define BRCMS_MPC_MIN_DELAYCNT 1 +#define BRCMS_MPC_THRESHOLD 3 /* MPC count threshold level */ #define BEACON_INTERVAL_DEFAULT 100 /* beacon interval, in unit of 1024TU */ #define DTIM_INTERVAL_DEFAULT 3 /* DTIM interval, in unit of beacon interval */ @@ -94,6 +72,94 @@ #define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */ +/* Software feature flag defines used by wlfeatureflag */ +#define WL_SWFL_NOHWRADIO 0x0004 +#define WL_SWFL_FLOWCONTROL 0x0008 /* Enable backpressure to OS stack */ +#define WL_SWFL_WLBSSSORT 0x0010 /* Per-port supports sorting of BSS */ + +/* n-mode support capability */ +/* 2x2 includes both 1x1 & 2x2 devices + * reserved #define 2 for future when we want to separate 1x1 & 2x2 and + * control it independently + */ +#define WL_11N_2x2 1 +#define WL_11N_3x3 3 +#define WL_11N_4x4 4 + +/* define 11n feature disable flags */ +#define WLFEATURE_DISABLE_11N 0x00000001 +#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 +#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 +#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 +#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 +#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 +#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 +#define WLFEATURE_DISABLE_11N_GF 0x00000080 + +#define EDCF_ACI_MASK 0x60 +#define EDCF_ACI_SHIFT 5 +#define EDCF_ECWMIN_MASK 0x0f +#define EDCF_ECWMAX_SHIFT 4 +#define EDCF_AIFSN_MASK 0x0f +#define EDCF_AIFSN_MAX 15 +#define EDCF_ECWMAX_MASK 0xf0 + +#define EDCF_AC_BE_TXOP_STA 0x0000 +#define EDCF_AC_BK_TXOP_STA 0x0000 +#define EDCF_AC_VO_ACI_STA 0x62 +#define EDCF_AC_VO_ECW_STA 0x32 +#define EDCF_AC_VI_ACI_STA 0x42 +#define EDCF_AC_VI_ECW_STA 0x43 +#define EDCF_AC_BK_ECW_STA 0xA4 +#define EDCF_AC_VI_TXOP_STA 0x005e +#define EDCF_AC_VO_TXOP_STA 0x002f +#define EDCF_AC_BE_ACI_STA 0x03 +#define EDCF_AC_BE_ECW_STA 0xA4 +#define EDCF_AC_BK_ACI_STA 0x27 +#define EDCF_AC_VO_TXOP_AP 0x002f + +#define EDCF_TXOP2USEC(txop) ((txop) << 5) +#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) + +#define APHY_SYMBOL_TIME 4 +#define APHY_PREAMBLE_TIME 16 +#define APHY_SIGNAL_TIME 4 +#define APHY_SIFS_TIME 16 +#define APHY_SERVICE_NBITS 16 +#define APHY_TAIL_NBITS 6 +#define BPHY_SIFS_TIME 10 +#define BPHY_PLCP_SHORT_TIME 96 + +#define PREN_PREAMBLE 24 +#define PREN_MM_EXT 12 +#define PREN_PREAMBLE_EXT 4 + +#define DOT11_MAC_HDR_LEN 24 +#define DOT11_ACK_LEN 10 +#define DOT11_BA_LEN 4 +#define DOT11_OFDM_SIGNAL_EXTENSION 6 +#define DOT11_MIN_FRAG_LEN 256 +#define DOT11_RTS_LEN 16 +#define DOT11_CTS_LEN 10 +#define DOT11_BA_BITMAP_LEN 128 +#define DOT11_MIN_BEACON_PERIOD 1 +#define DOT11_MAX_BEACON_PERIOD 0xFFFF +#define DOT11_MAXNUMFRAGS 16 +#define DOT11_MAX_FRAG_LEN 2346 + +#define BPHY_PLCP_TIME 192 +#define RIFS_11N_TIME 2 + +#define WME_VER 1 +#define WME_SUBTYPE_PARAM_IE 1 +#define WME_TYPE 2 +#define WME_OUI "\x00\x50\xf2" + +#define AC_BE 0 +#define AC_BK 1 +#define AC_VI 2 +#define AC_VO 3 + /* * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft * watchdog) it is not a wall clock and won't increment when driver is in "down" state @@ -101,26 +167,22 @@ * calibration and scb update */ -/* watchdog trigger mode: OSL timer or TBTT */ -#define WLC_WATCHDOG_TBTT(wlc) \ - (wlc->stas_associated > 0 && wlc->PM != PM_OFF && wlc->pub->align_wd_tbtt) - /* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */ -#define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid)) +#define BCMCFID(wlc, fid) brcms_b_write_shm((wlc)->hw, M_BCMC_FID, (fid)) -#define WLC_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \ +#define BRCMS_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \ (!AP_ENAB(wlc->pub)) && (wlc->war16165)) /* debug/trace */ -uint wl_msg_level = +uint brcm_msg_level = #if defined(BCMDBG) - WL_ERROR_VAL; + LOG_ERROR_VAL; #else - 0; + 0; #endif /* BCMDBG */ /* Find basic rate for a given rate */ -#define WLC_BASIC_RATE(wlc, rspec) (IS_MCS(rspec) ? \ +#define BRCMS_BASIC_RATE(wlc, rspec) (IS_MCS(rspec) ? \ (wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \ (wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK]) @@ -128,7 +190,7 @@ uint wl_msg_level = #define RFDISABLE_DEFAULT 10000000 /* rfdisable delay timer 500 ms, runs of ALP clock */ -#define WLC_TEMPSENSE_PERIOD 10 /* 10 second timeout */ +#define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ #define SCAN_IN_PROGRESS(x) 0 @@ -136,31 +198,9 @@ uint wl_msg_level = #ifdef BCMDBG /* pointer to most recently allocated wl/wlc */ -static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL); +static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); #endif -/* IOVar table */ - -/* Parameter IDs, for use only internally to wlc -- in the wlc_iovars - * table and by the wlc_doiovar() function. No ordering is imposed: - * the table is keyed by name, and the function uses a switch. - */ -enum { - IOV_MPC = 1, - IOV_RTSTHRESH, - IOV_QTXPOWER, - IOV_BCN_LI_BCN, /* Beacon listen interval in # of beacons */ - IOV_LAST /* In case of a need to check max ID number */ -}; - -const bcm_iovar_t wlc_iovars[] = { - {"mpc", IOV_MPC, (0), IOVT_BOOL, 0}, - {"rtsthresh", IOV_RTSTHRESH, (IOVF_WHL), IOVT_UINT16, 0}, - {"qtxpower", IOV_QTXPOWER, (IOVF_WHL), IOVT_UINT32, 0}, - {"bcn_li_bcn", IOV_BCN_LI_BCN, (0), IOVT_UINT8, 0}, - {NULL, 0, 0, 0, 0} -}; - const u8 prio2fifo[NUMPRIO] = { TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ @@ -177,35 +217,48 @@ const u8 prio2fifo[NUMPRIO] = { * Odd numbers are used for HI priority traffic at same precedence levels * These constants are used ONLY by wlc_prio2prec_map. Do not use them elsewhere. */ -#define _WLC_PREC_NONE 0 /* None = - */ -#define _WLC_PREC_BK 2 /* BK - Background */ -#define _WLC_PREC_BE 4 /* BE - Best-effort */ -#define _WLC_PREC_EE 6 /* EE - Excellent-effort */ -#define _WLC_PREC_CL 8 /* CL - Controlled Load */ -#define _WLC_PREC_VI 10 /* Vi - Video */ -#define _WLC_PREC_VO 12 /* Vo - Voice */ -#define _WLC_PREC_NC 14 /* NC - Network Control */ +#define _BRCMS_PREC_NONE 0 /* None = - */ +#define _BRCMS_PREC_BK 2 /* BK - Background */ +#define _BRCMS_PREC_BE 4 /* BE - Best-effort */ +#define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */ +#define _BRCMS_PREC_CL 8 /* CL - Controlled Load */ +#define _BRCMS_PREC_VI 10 /* Vi - Video */ +#define _BRCMS_PREC_VO 12 /* Vo - Voice */ +#define _BRCMS_PREC_NC 14 /* NC - Network Control */ + +#define MAXMACLIST 64 /* max # source MAC matches */ +#define BCN_TEMPLATE_COUNT 2 + +/* The BSS is generating beacons in HW */ +#define BRCMS_BSSCFG_HW_BCN 0x20 + +#define HWBCN_ENAB(cfg) (((cfg)->flags & BRCMS_BSSCFG_HW_BCN) != 0) + +#define MBSS_BCN_ENAB(cfg) 0 +#define MBSS_PRB_ENAB(cfg) 0 +#define SOFTBCN_ENAB(pub) (0) /* 802.1D Priority to precedence queue mapping */ const u8 wlc_prio2prec_map[] = { - _WLC_PREC_BE, /* 0 BE - Best-effort */ - _WLC_PREC_BK, /* 1 BK - Background */ - _WLC_PREC_NONE, /* 2 None = - */ - _WLC_PREC_EE, /* 3 EE - Excellent-effort */ - _WLC_PREC_CL, /* 4 CL - Controlled Load */ - _WLC_PREC_VI, /* 5 Vi - Video */ - _WLC_PREC_VO, /* 6 Vo - Voice */ - _WLC_PREC_NC, /* 7 NC - Network Control */ + _BRCMS_PREC_BE, /* 0 BE - Best-effort */ + _BRCMS_PREC_BK, /* 1 BK - Background */ + _BRCMS_PREC_NONE, /* 2 None = - */ + _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */ + _BRCMS_PREC_CL, /* 4 CL - Controlled Load */ + _BRCMS_PREC_VI, /* 5 Vi - Video */ + _BRCMS_PREC_VO, /* 6 Vo - Voice */ + _BRCMS_PREC_NC, /* 7 NC - Network Control */ }; -/* Sanity check for tx_prec_map and fifo synchup - * Either there are some packets pending for the fifo, else if fifo is empty then - * all the corresponding precmap bits should be set - */ -#define WLC_TX_FIFO_CHECK(wlc, fifo) (TXPKTPENDGET((wlc), (fifo)) || \ - (TXPKTPENDGET((wlc), (fifo)) == 0 && \ - ((wlc)->tx_prec_map & (wlc)->fifo2prec_map[(fifo)]) == \ - (wlc)->fifo2prec_map[(fifo)])) +/* Check if a particular BSS config is AP or STA */ +#define BSSCFG_AP(cfg) (0) +#define BSSCFG_STA(cfg) (1) +#define BSSCFG_IBSS(cfg) (!(cfg)->BSS) + +/* As above for all non-NULL BSS configs */ +#define FOREACH_BSS(wlc, idx, cfg) \ + for (idx = 0; (int) idx < BRCMS_MAXBSSCFG; idx++) \ + if ((cfg = (wlc)->bsscfg[idx])) /* TX FIFO number to WME/802.1E Access Category */ const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE }; @@ -213,13 +266,13 @@ const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE }; /* WME/802.1E Access Category to TX FIFO number */ static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 }; -static bool in_send_q = false; +static bool in_send_q; /* Shared memory location index for various AC params */ #define wme_shmemacindex(ac) wme_ac2fifo[ac] #ifdef BCMDBG -static const char *fifo_names[] = { +static const char * const fifo_names[] = { "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; #else static const char fifo_names[6][0]; @@ -233,148 +286,147 @@ static const u8 acbitmap2maxprio[] = { }; /* currently the best mechanism for determining SIFS is the band in use */ -#define SIFS(band) ((band)->bandtype == WLC_BAND_5G ? APHY_SIFS_TIME : BPHY_SIFS_TIME); - -/* value for # replay counters currently supported */ -#define WLC_REPLAY_CNTRS_VALUE WPA_CAP_16_REPLAY_CNTRS +#define SIFS(band) ((band)->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME : \ + BPHY_SIFS_TIME); /* local prototypes */ -static u16 wlc_d11hdrs_mac80211(struct wlc_info *wlc, +static u16 brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, struct sk_buff *p, struct scb *scb, uint frag, uint nfrags, uint queue, uint next_frag_len, - wsec_key_t *key, + struct wsec_key *key, ratespec_t rspec_override); -static void wlc_bss_default_init(struct wlc_info *wlc); -static void wlc_ucode_mac_upd(struct wlc_info *wlc); -static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, - struct wlcband *cur_band, u32 int_val); -static void wlc_tx_prec_map_init(struct wlc_info *wlc); -static void wlc_watchdog(void *arg); -static void wlc_watchdog_by_timer(void *arg); -static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate); -static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg); -static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, - const bcm_iovar_t *vi); -static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc); +static void brcms_c_bss_default_init(struct brcms_c_info *wlc); +static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc); +static ratespec_t mac80211_wlc_set_nrate(struct brcms_c_info *wlc, + struct brcms_band *cur_band, + u32 int_val); +static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc); +static void brcms_c_watchdog(void *arg); +static void brcms_c_watchdog_by_timer(void *arg); +static u16 brcms_c_rate_shm_offset(struct brcms_c_info *wlc, u8 rate); +static int brcms_c_set_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs_arg); +static u8 brcms_c_local_constraint_qdbm(struct brcms_c_info *wlc); /* send and receive */ -static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc); -static void wlc_txq_free(struct wlc_info *wlc, - struct wlc_txq_info *qi); -static void wlc_txflowcontrol_signal(struct wlc_info *wlc, - struct wlc_txq_info *qi, +static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc); +static void brcms_c_txq_free(struct brcms_c_info *wlc, + struct brcms_txq_info *qi); +static void brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc, + struct brcms_txq_info *qi, bool on, int prio); -static void wlc_txflowcontrol_reset(struct wlc_info *wlc); -static void wlc_compute_cck_plcp(struct wlc_info *wlc, ratespec_t rate, +static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc); +static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, ratespec_t rate, uint length, u8 *plcp); -static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); -static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); -static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, +static void brcms_c_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); +static void brcms_c_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); +static u16 brcms_c_compute_frame_dur(struct brcms_c_info *wlc, ratespec_t rate, u8 preamble_type, uint next_frag_len); -static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh); -static void wlc_recvctl(struct wlc_info *wlc, - d11rxhdr_t *rxh, struct sk_buff *p); -static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate, +static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc, + struct brcms_d11rxhdr *rxh); +static void brcms_c_recvctl(struct brcms_c_info *wlc, + struct d11rxhdr *rxh, struct sk_buff *p); +static uint brcms_c_calc_frame_len(struct brcms_c_info *wlc, ratespec_t rate, u8 preamble_type, uint dur); -static uint wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rate, +static uint brcms_c_calc_ack_time(struct brcms_c_info *wlc, ratespec_t rate, u8 preamble_type); -static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rate, +static uint brcms_c_calc_cts_time(struct brcms_c_info *wlc, ratespec_t rate, u8 preamble_type); /* interrupt, up/down, band */ -static void wlc_setband(struct wlc_info *wlc, uint bandunit); -static chanspec_t wlc_init_chanspec(struct wlc_info *wlc); -static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec); -static void wlc_bsinit(struct wlc_info *wlc); -static int wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, - bool writeToShm); -static void wlc_radio_hwdisable_upd(struct wlc_info *wlc); -static bool wlc_radio_monitor_start(struct wlc_info *wlc); -static void wlc_radio_timer(void *arg); -static void wlc_radio_enable(struct wlc_info *wlc); -static void wlc_radio_upd(struct wlc_info *wlc); +static void brcms_c_setband(struct brcms_c_info *wlc, uint bandunit); +static chanspec_t brcms_c_init_chanspec(struct brcms_c_info *wlc); +static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc, + chanspec_t chanspec); +static void brcms_c_bsinit(struct brcms_c_info *wlc); +static int brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, + bool isOFDM, bool writeToShm); +static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc); +static bool brcms_c_radio_monitor_start(struct brcms_c_info *wlc); +static void brcms_c_radio_timer(void *arg); +static void brcms_c_radio_enable(struct brcms_c_info *wlc); +static void brcms_c_radio_upd(struct brcms_c_info *wlc); /* scan, association, BSS */ -static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rate, +static uint brcms_c_calc_ba_time(struct brcms_c_info *wlc, ratespec_t rate, u8 preamble_type); -static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap); -static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val); -static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val); -static void wlc_war16165(struct wlc_info *wlc, bool tx); +static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap); +static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val); +static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val); +static void brcms_c_war16165(struct brcms_c_info *wlc, bool tx); -static void wlc_wme_retries_write(struct wlc_info *wlc); -static bool wlc_attach_stf_ant_init(struct wlc_info *wlc); -static uint wlc_attach_module(struct wlc_info *wlc); -static void wlc_detach_module(struct wlc_info *wlc); -static void wlc_timers_deinit(struct wlc_info *wlc); -static void wlc_down_led_upd(struct wlc_info *wlc); -static uint wlc_down_del_timer(struct wlc_info *wlc); -static void wlc_ofdm_rateset_war(struct wlc_info *wlc); -static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif); +static void brcms_c_wme_retries_write(struct brcms_c_info *wlc); +static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc); +static uint brcms_c_attach_module(struct brcms_c_info *wlc); +static void brcms_c_detach_module(struct brcms_c_info *wlc); +static void brcms_c_timers_deinit(struct brcms_c_info *wlc); +static void brcms_c_down_led_upd(struct brcms_c_info *wlc); +static uint brcms_c_down_del_timer(struct brcms_c_info *wlc); +static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc); +static int _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, + struct brcms_c_if *wlcif); /* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful */ -bool wlc_ps_allowed(struct wlc_info *wlc) +bool brcms_c_ps_allowed(struct brcms_c_info *wlc) { int idx; - struct wlc_bsscfg *cfg; + struct brcms_bss_cfg *cfg; /* disallow PS when one of the following global conditions meets */ - if (!wlc->pub->associated || !wlc->PMenabled || wlc->PM_override) + if (!wlc->pub->associated) return false; /* disallow PS when one of these meets when not scanning */ - if (!wlc->PMblocked) { - if (AP_ACTIVE(wlc) || wlc->monitor) - return false; - } + if (AP_ACTIVE(wlc) || wlc->monitor) + return false; - FOREACH_AS_STA(wlc, idx, cfg) { - /* disallow PS when one of the following bsscfg specific conditions meets */ - if (!cfg->BSS || !WLC_PORTOPEN(cfg)) - return false; + for (idx = 0; idx < BRCMS_MAXBSSCFG; idx++) { + cfg = wlc->bsscfg[idx]; + if (cfg && BSSCFG_STA(cfg) && cfg->associated) { + /* + * disallow PS when one of the following + * bsscfg specific conditions meets + */ + if (!cfg->BSS || !BRCMS_PORTOPEN(cfg)) + return false; - if (!cfg->dtim_programmed) - return false; + if (!cfg->dtim_programmed) + return false; + } } return true; } -void wlc_reset(struct wlc_info *wlc) +void brcms_c_reset(struct brcms_c_info *wlc) { BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); - wlc->check_for_unaligned_tbtt = false; - /* slurp up hw mac counters before core reset */ - wlc_statsupd(wlc); + brcms_c_statsupd(wlc); /* reset our snapshot of macstat counters */ memset((char *)wlc->core->macstat_snapshot, 0, - sizeof(macstat_t)); - - wlc_bmac_reset(wlc->hw); - wlc->txretried = 0; + sizeof(struct macstat)); + brcms_b_reset(wlc->hw); } -void wlc_fatal_error(struct wlc_info *wlc) +void brcms_c_fatal_error(struct brcms_c_info *wlc) { wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n", wlc->pub->unit); - wl_init(wlc->wl); + brcms_init(wlc->wl); } -/* Return the channel the driver should initialize during wlc_init. +/* Return the channel the driver should initialize during brcms_c_init. * the channel may have to be changed from the currently configured channel * if other configurations are in conflict (bandlocked, 11n mode disabled, * invalid channel for current country, etc.) */ -static chanspec_t wlc_init_chanspec(struct wlc_info *wlc) +static chanspec_t brcms_c_init_chanspec(struct brcms_c_info *wlc) { chanspec_t chanspec = 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | @@ -385,7 +437,7 @@ static chanspec_t wlc_init_chanspec(struct wlc_info *wlc) struct scb global_scb; -static void wlc_init_scb(struct wlc_info *wlc, struct scb *scb) +static void brcms_c_init_scb(struct brcms_c_info *wlc, struct scb *scb) { int i; scb->flags = SCB_WMECAP | SCB_HTCAP; @@ -393,12 +445,12 @@ static void wlc_init_scb(struct wlc_info *wlc, struct scb *scb) scb->seqnum[i] = 0; } -void wlc_init(struct wlc_info *wlc) +void brcms_c_init(struct brcms_c_info *wlc) { d11regs_t *regs; chanspec_t chanspec; int i; - struct wlc_bsscfg *bsscfg; + struct brcms_bss_cfg *bsscfg; bool mute = false; BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); @@ -411,27 +463,20 @@ void wlc_init(struct wlc_info *wlc) if (wlc->pub->associated) chanspec = wlc->home_chanspec; else - chanspec = wlc_init_chanspec(wlc); + chanspec = brcms_c_init_chanspec(wlc); - wlc_bmac_init(wlc->hw, chanspec, mute); - - wlc->seckeys = wlc_bmac_read_shm(wlc->hw, M_SECRXKEYS_PTR) * 2; - if (wlc->machwcap & MCAP_TKIPMIC) - wlc->tkmickeys = - wlc_bmac_read_shm(wlc->hw, M_TKMICKEYS_PTR) * 2; + brcms_b_init(wlc->hw, chanspec, mute); /* update beacon listen interval */ - wlc_bcn_li_upd(wlc); - wlc->bcn_wait_prd = - (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10); + brcms_c_bcn_li_upd(wlc); /* the world is new again, so is our reported rate */ - wlc_reprate_init(wlc); + brcms_c_reprate_init(wlc); /* write ethernet address to core */ FOREACH_BSS(wlc, i, bsscfg) { - wlc_set_mac(bsscfg); - wlc_set_bssid(bsscfg); + brcms_c_set_mac(bsscfg); + brcms_c_set_bssid(bsscfg); } /* Update tsf_cfprep if associated and up */ @@ -450,58 +495,56 @@ void wlc_init(struct wlc_info *wlc) (bi << CFPREP_CBI_SHIFT)); /* Update maccontrol PM related bits */ - wlc_set_ps_ctrl(wlc); + brcms_c_set_ps_ctrl(wlc); break; } } } - wlc_key_hw_init_all(wlc); + brcms_c_bandinit_ordered(wlc, chanspec); - wlc_bandinit_ordered(wlc, chanspec); - - wlc_init_scb(wlc, &global_scb); + brcms_c_init_scb(wlc, &global_scb); /* init probe response timeout */ - wlc_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout); + brcms_c_write_shm(wlc, M_PRS_MAXTIME, wlc->prb_resp_timeout); /* init max burst txop (framebursting) */ - wlc_write_shm(wlc, M_MBURST_TXOP, + brcms_c_write_shm(wlc, M_MBURST_TXOP, (wlc-> _rifs ? (EDCF_AC_VO_TXOP_AP << 5) : MAXFRAMEBURST_TXOP)); /* initialize maximum allowed duty cycle */ - wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true); - wlc_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true); + brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true); + brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true); /* Update some shared memory locations related to max AMPDU size allowed to received */ - wlc_ampdu_shm_upd(wlc->ampdu); + brcms_c_ampdu_shm_upd(wlc->ampdu); /* band-specific inits */ - wlc_bsinit(wlc); + brcms_c_bsinit(wlc); /* Enable EDCF mode (while the MAC is suspended) */ if (EDCF_ENAB(wlc->pub)) { OR_REG(®s->ifs_ctl, IFS_USEEDCF); - wlc_edcf_setparams(wlc, false); + brcms_c_edcf_setparams(wlc, false); } /* Init precedence maps for empty FIFOs */ - wlc_tx_prec_map_init(wlc); + brcms_c_tx_prec_map_init(wlc); /* read the ucode version if we have not yet done so */ if (wlc->ucode_rev == 0) { wlc->ucode_rev = - wlc_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16); - wlc->ucode_rev |= wlc_read_shm(wlc, M_BOM_REV_MINOR); + brcms_c_read_shm(wlc, M_BOM_REV_MAJOR) << NBITS(u16); + wlc->ucode_rev |= brcms_c_read_shm(wlc, M_BOM_REV_MINOR); } /* ..now really unleash hell (allow the MAC out of suspend) */ - wlc_enable_mac(wlc); + brcms_c_enable_mac(wlc); /* clear tx flow control */ - wlc_txflowcontrol_reset(wlc); + brcms_c_txflowcontrol_reset(wlc); /* clear tx data fifo suspends */ wlc->tx_suspended = false; @@ -510,39 +553,40 @@ void wlc_init(struct wlc_info *wlc) W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); /* initialize mpc delay */ - wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; + wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; /* * Initialize WME parameters; if they haven't been set by some other * mechanism (IOVar, etc) then read them from the hardware. */ - if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) { /* Uninitialized; read from HW */ + if (BRCMS_WME_RETRY_SHORT_GET(wlc, 0) == 0) { + /* Uninitialized; read from HW */ int ac; for (ac = 0; ac < AC_COUNT; ac++) { wlc->wme_retries[ac] = - wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac)); + brcms_c_read_shm(wlc, M_AC_TXLMT_ADDR(ac)); } } } -void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc) +void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc) { wlc->bcnmisc_monitor = promisc; - wlc_mac_bcn_promisc(wlc); + brcms_c_mac_bcn_promisc(wlc); } -void wlc_mac_bcn_promisc(struct wlc_info *wlc) +void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc) { if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) || wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor) - wlc_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC); + brcms_c_mctrl(wlc, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC); else - wlc_mctrl(wlc, MCTL_BCNS_PROMISC, 0); + brcms_c_mctrl(wlc, MCTL_BCNS_PROMISC, 0); } /* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */ -void wlc_mac_promisc(struct wlc_info *wlc) +void brcms_c_mac_promisc(struct brcms_c_info *wlc) { u32 promisc_bits = 0; @@ -550,21 +594,21 @@ void wlc_mac_promisc(struct wlc_info *wlc) * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit * since all BSS data traffic is directed at the AP */ - if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub) && !wlc->wet) + if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub)) promisc_bits |= MCTL_PROMISC; /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is - * handled in wlc_mac_bcn_promisc() + * handled in brcms_c_mac_bcn_promisc() */ if (MONITOR_ENAB(wlc)) promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL; - wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits); + brcms_c_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits); } /* push sw hps and wake state through hardware */ -void wlc_set_ps_ctrl(struct wlc_info *wlc) +void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) { u32 v1, v2; bool hps; @@ -579,12 +623,12 @@ void wlc_set_ps_ctrl(struct wlc_info *wlc) if (hps) v2 |= MCTL_HPS; - wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2); + brcms_c_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2); awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0)); if (!awake_before) - wlc_bmac_wait_for_wake(wlc->hw); + brcms_b_wait_for_wake(wlc->hw); } @@ -592,17 +636,17 @@ void wlc_set_ps_ctrl(struct wlc_info *wlc) * Write this BSS config's MAC address to core. * Updates RXE match engine. */ -int wlc_set_mac(struct wlc_bsscfg *cfg) +int brcms_c_set_mac(struct brcms_bss_cfg *cfg) { int err = 0; - struct wlc_info *wlc = cfg->wlc; + struct brcms_c_info *wlc = cfg->wlc; if (cfg == wlc->cfg) { /* enter the MAC addr into the RXE match registers */ - wlc_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr); + brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr); } - wlc_ampdu_macaddr_upd(wlc); + brcms_c_ampdu_macaddr_upd(wlc); return err; } @@ -610,17 +654,17 @@ int wlc_set_mac(struct wlc_bsscfg *cfg) /* Write the BSS config's BSSID address to core (set_bssid in d11procs.tcl). * Updates RXE match engine. */ -void wlc_set_bssid(struct wlc_bsscfg *cfg) +void brcms_c_set_bssid(struct brcms_bss_cfg *cfg) { - struct wlc_info *wlc = cfg->wlc; + struct brcms_c_info *wlc = cfg->wlc; /* if primary config, we need to update BSSID in RXE match registers */ if (cfg == wlc->cfg) { - wlc_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID); + brcms_c_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID); } #ifdef SUPPORT_HWKEYS else if (BSSCFG_STA(cfg) && cfg->BSS) { - wlc_rcmta_add_bssid(wlc, cfg); + brcms_c_rcmta_add_bssid(wlc, cfg); } #endif } @@ -629,14 +673,14 @@ void wlc_set_bssid(struct wlc_bsscfg *cfg) * Suspend the the MAC and update the slot timing * for standard 11b/g (20us slots) or shortslot 11g (9us slots). */ -void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot) +void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot) { int idx; - struct wlc_bsscfg *cfg; + struct brcms_bss_cfg *cfg; /* use the override if it is set */ - if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO) - shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON); + if (wlc->shortslot_override != BRCMS_SHORTSLOT_AUTO) + shortslot = (wlc->shortslot_override == BRCMS_SHORTSLOT_ON); if (wlc->shortslot == shortslot) return; @@ -654,27 +698,28 @@ void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot) WLAN_CAPABILITY_SHORT_SLOT_TIME; } - wlc_bmac_set_shortslot(wlc->hw, shortslot); + brcms_b_set_shortslot(wlc->hw, shortslot); } -static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc) +static u8 brcms_c_local_constraint_qdbm(struct brcms_c_info *wlc) { u8 local; s16 local_max; - local = WLC_TXPWR_MAX; + local = BRCMS_TXPWR_MAX; if (wlc->pub->associated && - (bcm_chspec_ctlchan(wlc->chanspec) == - bcm_chspec_ctlchan(wlc->home_chanspec))) { + (brcmu_chspec_ctlchan(wlc->chanspec) == + brcmu_chspec_ctlchan(wlc->home_chanspec))) { /* get the local power constraint if we are on the AP's * channel [802.11h, 7.3.2.13] */ - /* Clamp the value between 0 and WLC_TXPWR_MAX w/o overflowing the target */ + /* Clamp the value between 0 and BRCMS_TXPWR_MAX w/o + * overflowing the target */ local_max = (wlc->txpwr_local_max - - wlc->txpwr_local_constraint) * WLC_TXPWR_DB_FACTOR; - if (local_max > 0 && local_max < WLC_TXPWR_MAX) + wlc->txpwr_local_constraint) * BRCMS_TXPWR_DB_FACTOR; + if (local_max > 0 && local_max < BRCMS_TXPWR_MAX) return (u8) local_max; if (local_max < 0) return 0; @@ -684,11 +729,11 @@ static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc) } /* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */ -void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec) +void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, chanspec_t chanspec) { if (wlc->home_chanspec != chanspec) { int idx; - struct wlc_bsscfg *cfg; + struct brcms_bss_cfg *cfg; wlc->home_chanspec = chanspec; @@ -702,7 +747,8 @@ void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec) } } -static void wlc_set_phy_chanspec(struct wlc_info *wlc, chanspec_t chanspec) +static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc, + chanspec_t chanspec) { /* Save our copy of the chanspec */ wlc->chanspec = chanspec; @@ -710,24 +756,24 @@ static void wlc_set_phy_chanspec(struct wlc_info *wlc, chanspec_t chanspec) /* Set the chanspec and power limits for this locale after computing * any 11h local tx power constraints. */ - wlc_channel_set_chanspec(wlc->cmi, chanspec, - wlc_local_constraint_qdbm(wlc)); + brcms_c_channel_set_chanspec(wlc->cmi, chanspec, + brcms_c_local_constraint_qdbm(wlc)); if (wlc->stf->ss_algosel_auto) - wlc_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel, + brcms_c_stf_ss_algo_channel_get(wlc, &wlc->stf->ss_algo_channel, chanspec); - wlc_stf_ss_update(wlc, wlc->band); + brcms_c_stf_ss_update(wlc, wlc->band); } -void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) +void brcms_c_set_chanspec(struct brcms_c_info *wlc, chanspec_t chanspec) { uint bandunit; bool switchband = false; chanspec_t old_chanspec = wlc->chanspec; - if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) { + if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) { wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n", wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); return; @@ -735,7 +781,7 @@ void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) /* Switch bands if necessary */ if (NBANDS(wlc) > 1) { - bandunit = CHSPEC_WLCBANDUNIT(chanspec); + bandunit = CHSPEC_BANDUNIT(chanspec); if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { switchband = true; if (wlc->bandlocked) { @@ -745,263 +791,49 @@ void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) CHSPEC_CHANNEL(chanspec)); return; } - /* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ? - * if the setband updates (wlc_bsinit) use low level calls to inspect and - * set state, the state inspected may be from the wrong band, or the - * following wlc_bmac_set_chanspec() may undo the work. + /* + * should the setband call come after the + * brcms_b_chanspec() ? if the setband updates + * (brcms_c_bsinit) use low level calls to inspect and + * set state, the state inspected may be from the wrong + * band, or the following brcms_b_set_chanspec() may + * undo the work. */ - wlc_setband(wlc, bandunit); + brcms_c_setband(wlc, bandunit); } } /* sync up phy/radio chanspec */ - wlc_set_phy_chanspec(wlc, chanspec); + brcms_c_set_phy_chanspec(wlc, chanspec); /* init antenna selection */ if (CHSPEC_WLC_BW(old_chanspec) != CHSPEC_WLC_BW(chanspec)) { - wlc_antsel_init(wlc->asi); + brcms_c_antsel_init(wlc->asi); /* Fix the hardware rateset based on bw. * Mainly add MCS32 for 40Mhz, remove MCS 32 for 20Mhz */ - wlc_rateset_bw_mcs_filter(&wlc->band->hw_rateset, + brcms_c_rateset_bw_mcs_filter(&wlc->band->hw_rateset, wlc->band-> mimo_cap_40 ? CHSPEC_WLC_BW(chanspec) : 0); } /* update some mac configuration since chanspec changed */ - wlc_ucode_mac_upd(wlc); + brcms_c_ucode_mac_upd(wlc); } -#if defined(BCMDBG) -static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len) -{ - txpwr_limits_t txpwr; - tx_power_t power; - tx_power_legacy_t *old_power = NULL; - int r, c; - uint qdbm; - bool override; - - if (len == sizeof(tx_power_legacy_t)) - old_power = (tx_power_legacy_t *) pwr; - else if (len < sizeof(tx_power_t)) - return -EOVERFLOW; - - memset(&power, 0, sizeof(tx_power_t)); - - power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC; - if (wlc->pub->associated) - power.local_chanspec = wlc->home_chanspec; - - /* Return the user target tx power limits for the various rates. Note wlc_phy.c's - * public interface only implements getting and setting a single value for all of - * rates, so we need to fill the array ourselves. - */ - wlc_phy_txpower_get(wlc->band->pi, &qdbm, &override); - for (r = 0; r < WL_TX_POWER_RATES; r++) { - power.user_limit[r] = (u8) qdbm; - } - - power.local_max = wlc->txpwr_local_max * WLC_TXPWR_DB_FACTOR; - power.local_constraint = - wlc->txpwr_local_constraint * WLC_TXPWR_DB_FACTOR; - - power.antgain[0] = wlc->bandstate[BAND_2G_INDEX]->antgain; - power.antgain[1] = wlc->bandstate[BAND_5G_INDEX]->antgain; - - wlc_channel_reg_limits(wlc->cmi, power.chanspec, &txpwr); - -#if WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK -#error "WL_TX_POWER_CCK_NUM != WLC_NUM_RATES_CCK" -#endif - - /* CCK tx power limits */ - for (c = 0, r = WL_TX_POWER_CCK_FIRST; c < WL_TX_POWER_CCK_NUM; - c++, r++) - power.reg_limit[r] = txpwr.cck[c]; - -#if WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM -#error "WL_TX_POWER_OFDM_NUM != WLC_NUM_RATES_OFDM" -#endif - - /* 20 MHz OFDM SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM_FIRST; c < WL_TX_POWER_OFDM_NUM; - c++, r++) - power.reg_limit[r] = txpwr.ofdm[c]; - - if (WLC_PHY_11N_CAP(wlc->band)) { - - /* 20 MHz OFDM CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM20_CDD_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_cdd[c]; - - /* 40 MHz OFDM SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM40_SISO_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_40_siso[c]; - - /* 40 MHz OFDM CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_OFDM40_CDD_FIRST; - c < WL_TX_POWER_OFDM_NUM; c++, r++) - power.reg_limit[r] = txpwr.ofdm_40_cdd[c]; - -#if WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM -#error "WL_TX_POWER_MCS_1_STREAM_NUM != WLC_NUM_RATES_MCS_1_STREAM" -#endif - - /* 20MHz MCS0-7 SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_SISO_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_siso[c]; - - /* 20MHz MCS0-7 CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_CDD_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_cdd[c]; - - /* 20MHz MCS0-7 STBC tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_STBC_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_stbc[c]; - - /* 40MHz MCS0-7 SISO tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_SISO_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_siso[c]; - - /* 40MHz MCS0-7 CDD tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_CDD_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_cdd[c]; - - /* 40MHz MCS0-7 STBC tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_STBC_FIRST; - c < WLC_NUM_RATES_MCS_1_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_stbc[c]; - -#if WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM -#error "WL_TX_POWER_MCS_2_STREAM_NUM != WLC_NUM_RATES_MCS_2_STREAM" -#endif - - /* 20MHz MCS8-15 SDM tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS20_SDM_FIRST; - c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_20_mimo[c]; - - /* 40MHz MCS8-15 SDM tx power limits */ - for (c = 0, r = WL_TX_POWER_MCS40_SDM_FIRST; - c < WLC_NUM_RATES_MCS_2_STREAM; c++, r++) - power.reg_limit[r] = txpwr.mcs_40_mimo[c]; - - /* MCS 32 */ - power.reg_limit[WL_TX_POWER_MCS_32] = txpwr.mcs32; - } - - wlc_phy_txpower_get_current(wlc->band->pi, &power, - CHSPEC_CHANNEL(power.chanspec)); - - /* copy the tx_power_t struct to the return buffer, - * or convert to a tx_power_legacy_t struct - */ - if (!old_power) { - memcpy(pwr, &power, sizeof(tx_power_t)); - } else { - int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1; - - memset(old_power, 0, sizeof(tx_power_legacy_t)); - - old_power->txpwr_local_max = power.local_max; - old_power->txpwr_local_constraint = power.local_constraint; - if (CHSPEC_IS2G(power.chanspec)) { - old_power->txpwr_chan_reg_max = txpwr.cck[0]; - old_power->txpwr_est_Pout[band_idx] = - power.est_Pout_cck; - old_power->txpwr_est_Pout_gofdm = power.est_Pout[0]; - } else { - old_power->txpwr_chan_reg_max = txpwr.ofdm[0]; - old_power->txpwr_est_Pout[band_idx] = power.est_Pout[0]; - } - old_power->txpwr_antgain[0] = power.antgain[0]; - old_power->txpwr_antgain[1] = power.antgain[1]; - - for (r = 0; r < NUM_PWRCTRL_RATES; r++) { - old_power->txpwr_band_max[r] = power.user_limit[r]; - old_power->txpwr_limit[r] = power.reg_limit[r]; - old_power->txpwr_target[band_idx][r] = power.target[r]; - if (CHSPEC_IS2G(power.chanspec)) - old_power->txpwr_bphy_cck_max[r] = - power.board_limit[r]; - else - old_power->txpwr_aphy_max[r] = - power.board_limit[r]; - } - } - - return 0; -} -#endif /* defined(BCMDBG) */ - -static u32 wlc_watchdog_backup_bi(struct wlc_info *wlc) -{ - u32 bi; - bi = 2 * wlc->cfg->current_bss->dtim_period * - wlc->cfg->current_bss->beacon_period; - if (wlc->bcn_li_dtim) - bi *= wlc->bcn_li_dtim; - else if (wlc->bcn_li_bcn) - /* recalculate bi based on bcn_li_bcn */ - bi = 2 * wlc->bcn_li_bcn * wlc->cfg->current_bss->beacon_period; - - if (bi < 2 * TIMER_INTERVAL_WATCHDOG) - bi = 2 * TIMER_INTERVAL_WATCHDOG; - return bi; -} - -/* Change to run the watchdog either from a periodic timer or from tbtt handler. - * Call watchdog from tbtt handler if tbtt is true, watchdog timer otherwise. - */ -void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt) -{ - /* make sure changing watchdog driver is allowed */ - if (!wlc->pub->up || !wlc->pub->align_wd_tbtt) - return; - if (!tbtt && wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - } - - /* stop watchdog timer and use tbtt interrupt to drive watchdog */ - if (tbtt && wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - wlc->WDlast = OSL_SYSUPTIME(); - } - /* arm watchdog timer and drive the watchdog there */ - else if (!tbtt && !wlc->WDarmed) { - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, - true); - wlc->WDarmed = true; - } - if (tbtt && !wlc->WDarmed) { - wl_add_timer(wlc->wl, wlc->wdtimer, wlc_watchdog_backup_bi(wlc), - true); - wlc->WDarmed = true; - } -} - -ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs) +ratespec_t brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc, + wlc_rateset_t *rs) { ratespec_t lowest_basic_rspec; uint i; /* Use the lowest basic rate */ - lowest_basic_rspec = rs->rates[0] & WLC_RATE_MASK; + lowest_basic_rspec = rs->rates[0] & BRCMS_RATE_MASK; for (i = 0; i < rs->count; i++) { - if (rs->rates[i] & WLC_RATE_FLAG) { - lowest_basic_rspec = rs->rates[i] & WLC_RATE_MASK; + if (rs->rates[i] & BRCMS_RATE_FLAG) { + lowest_basic_rspec = rs->rates[i] & BRCMS_RATE_MASK; break; } } @@ -1018,63 +850,63 @@ ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs) /* This function changes the phytxctl for beacon based on current beacon ratespec AND txant * setting as per this table: * ratespec CCK ant = wlc->stf->txant - * OFDM ant = 3 + * OFDM ant = 3 */ -void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec) +void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, + ratespec_t bcn_rspec) { u16 phyctl; u16 phytxant = wlc->stf->phytxant; u16 mask = PHY_TXC_ANT_MASK; /* for non-siso rates or default setting, use the available chains */ - if (WLC_PHY_11N_CAP(wlc->band)) { - phytxant = wlc_stf_phytxchain_sel(wlc, bcn_rspec); - } + if (BRCMS_PHY_11N_CAP(wlc->band)) + phytxant = brcms_c_stf_phytxchain_sel(wlc, bcn_rspec); - phyctl = wlc_read_shm(wlc, M_BCN_PCTLWD); + phyctl = brcms_c_read_shm(wlc, M_BCN_PCTLWD); phyctl = (phyctl & ~mask) | phytxant; - wlc_write_shm(wlc, M_BCN_PCTLWD, phyctl); + brcms_c_write_shm(wlc, M_BCN_PCTLWD, phyctl); } /* centralized protection config change function to simplify debugging, no consistency checking * this should be called only on changes to avoid overhead in periodic function */ -void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) +void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val) { BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val); switch (idx) { - case WLC_PROT_G_SPEC: + case BRCMS_PROT_G_SPEC: wlc->protection->_g = (bool) val; break; - case WLC_PROT_G_OVR: + case BRCMS_PROT_G_OVR: wlc->protection->g_override = (s8) val; break; - case WLC_PROT_G_USER: + case BRCMS_PROT_G_USER: wlc->protection->gmode_user = (u8) val; break; - case WLC_PROT_OVERLAP: + case BRCMS_PROT_OVERLAP: wlc->protection->overlap = (s8) val; break; - case WLC_PROT_N_USER: + case BRCMS_PROT_N_USER: wlc->protection->nmode_user = (s8) val; break; - case WLC_PROT_N_CFG: + case BRCMS_PROT_N_CFG: wlc->protection->n_cfg = (s8) val; break; - case WLC_PROT_N_CFG_OVR: + case BRCMS_PROT_N_CFG_OVR: wlc->protection->n_cfg_override = (s8) val; break; - case WLC_PROT_N_NONGF: + case BRCMS_PROT_N_NONGF: wlc->protection->nongf = (bool) val; break; - case WLC_PROT_N_NONGF_OVR: + case BRCMS_PROT_N_NONGF_OVR: wlc->protection->nongf_override = (s8) val; break; - case WLC_PROT_N_PAM_OVR: + case BRCMS_PROT_N_PAM_OVR: wlc->protection->n_pam_override = (s8) val; break; - case WLC_PROT_N_OBSS: + case BRCMS_PROT_N_OBSS: wlc->protection->n_obss = (bool) val; break; @@ -1084,22 +916,22 @@ void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) } -static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val) +static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val) { wlc->ht_cap.cap_info &= ~(IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40); - wlc->ht_cap.cap_info |= (val & WLC_N_SGI_20) ? + wlc->ht_cap.cap_info |= (val & BRCMS_N_SGI_20) ? IEEE80211_HT_CAP_SGI_20 : 0; - wlc->ht_cap.cap_info |= (val & WLC_N_SGI_40) ? + wlc->ht_cap.cap_info |= (val & BRCMS_N_SGI_40) ? IEEE80211_HT_CAP_SGI_40 : 0; if (wlc->pub->up) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); + brcms_c_update_beacon(wlc); + brcms_c_update_probe_resp(wlc, true); } } -static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val) +static void brcms_c_ht_update_ldpc(struct brcms_c_info *wlc, s8 val) { wlc->stf->ldpc = val; @@ -1108,8 +940,8 @@ static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val) wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_LDPC_CODING; if (wlc->pub->up) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); + brcms_c_update_beacon(wlc); + brcms_c_update_probe_resp(wlc, true); wlc_phy_ldpc_override_set(wlc->band->pi, (val ? true : false)); } } @@ -1118,12 +950,12 @@ static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val) * ucode, hwmac update * Channel dependent updates for ucode and hw */ -static void wlc_ucode_mac_upd(struct wlc_info *wlc) +static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc) { /* enable or disable any active IBSSs depending on whether or not * we are on the home channel */ - if (wlc->home_chanspec == WLC_BAND_PI_RADIO_CHANSPEC) { + if (wlc->home_chanspec == BRCMS_BAND_PI_RADIO_CHANSPEC) { if (wlc->pub->associated) { /* BMAC_NOTE: This is something that should be fixed in ucode inits. * I think that the ucode inits set up the bcn templates and shm values @@ -1131,8 +963,8 @@ static void wlc_ucode_mac_upd(struct wlc_info *wlc) * to set up a beacon for testing, the test routines should write it down, * not expect the inits to populate a bogus beacon. */ - if (WLC_PHY_11N_CAP(wlc->band)) { - wlc_write_shm(wlc, M_BCN_TXTSF_OFFSET, + if (BRCMS_PHY_11N_CAP(wlc->band)) { + brcms_c_write_shm(wlc, M_BCN_TXTSF_OFFSET, wlc->band->bcntsfoff); } } @@ -1141,11 +973,12 @@ static void wlc_ucode_mac_upd(struct wlc_info *wlc) } /* update the various promisc bits */ - wlc_mac_bcn_promisc(wlc); - wlc_mac_promisc(wlc); + brcms_c_mac_bcn_promisc(wlc); + brcms_c_mac_promisc(wlc); } -static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) +static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc, + chanspec_t chanspec) { wlc_rateset_t default_rateset; uint parkband; @@ -1157,11 +990,12 @@ static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) * figure out the right band to park on */ if (wlc->bandlocked || NBANDS(wlc) == 1) { - parkband = wlc->band->bandunit; /* updated in wlc_bandlock() */ + /* updated in brcms_c_bandlock() */ + parkband = wlc->band->bandunit; band_order[0] = band_order[1] = parkband; } else { /* park on the band of the specified chanspec */ - parkband = CHSPEC_WLCBANDUNIT(chanspec); + parkband = CHSPEC_BANDUNIT(chanspec); /* order so that parkband initialize last */ band_order[0] = parkband ^ 1; @@ -1174,43 +1008,44 @@ static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) wlc->band = wlc->bandstate[j]; - wlc_default_rateset(wlc, &default_rateset); + brcms_default_rateset(wlc, &default_rateset); /* fill in hw_rate */ - wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset, - false, WLC_RATES_CCK_OFDM, WLC_RATE_MASK, + brcms_c_rateset_filter(&default_rateset, &wlc->band->hw_rateset, + false, BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK, (bool) N_ENAB(wlc->pub)); /* init basic rate lookup */ - wlc_rate_lookup_init(wlc, &default_rateset); + brcms_c_rate_lookup_init(wlc, &default_rateset); } /* sync up phy/radio chanspec */ - wlc_set_phy_chanspec(wlc, chanspec); + brcms_c_set_phy_chanspec(wlc, chanspec); } /* band-specific init */ -static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc) +static void brcms_c_bsinit(struct brcms_c_info *wlc) { BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc->pub->unit, wlc->band->bandunit); /* write ucode ACK/CTS rate table */ - wlc_set_ratetable(wlc); + brcms_c_set_ratetable(wlc); /* update some band specific mac configuration */ - wlc_ucode_mac_upd(wlc); + brcms_c_ucode_mac_upd(wlc); /* init antenna selection */ - wlc_antsel_init(wlc->asi); + brcms_c_antsel_init(wlc->asi); } /* switch to and initialize new band */ -static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit) +static void brcms_c_setband(struct brcms_c_info *wlc, + uint bandunit) { int idx; - struct wlc_bsscfg *cfg; + struct brcms_bss_cfg *cfg; wlc->band = wlc->bandstate[bandunit]; @@ -1218,19 +1053,22 @@ static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit) return; /* wait for at least one beacon before entering sleeping state */ - wlc->PMawakebcn = true; - FOREACH_AS_STA(wlc, idx, cfg) - cfg->PMawakebcn = true; - wlc_set_ps_ctrl(wlc); + for (idx = 0; idx < BRCMS_MAXBSSCFG; idx++) { + cfg = wlc->bsscfg[idx]; + if (cfg && BSSCFG_STA(cfg) && cfg->associated) + cfg->PMawakebcn = true; + } + brcms_c_set_ps_ctrl(wlc); /* band-specific initializations */ - wlc_bsinit(wlc); + brcms_c_bsinit(wlc); } /* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */ -void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe) +void +brcms_c_wme_initparams_sta(struct brcms_c_info *wlc, struct wme_param_ie *pe) { - static const wme_param_ie_t stadef = { + static const struct wme_param_ie stadef = { WME_OUI, WME_TYPE, WME_SUBTYPE_PARAM_IE, @@ -1251,12 +1089,12 @@ void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe) memcpy(pe, &stadef, sizeof(*pe)); } -void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, +void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, const struct ieee80211_tx_queue_params *params, bool suspend) { int i; - shm_acparams_t acp_shm; + struct shm_acparams acp_shm; u16 *shm_entry; /* Only apply params if the core is out of reset and has clocks */ @@ -1266,10 +1104,8 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, return; } - wlc->wme_admctl = 0; - do { - memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); + memset((char *)&acp_shm, 0, sizeof(struct shm_acparams)); /* fill in shm ac params struct */ acp_shm.txop = le16_to_cpu(params->txop); /* convert from units of 32us to us for ucode */ @@ -1283,7 +1119,7 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, if (acp_shm.aifs < EDCF_AIFSN_MIN || acp_shm.aifs > EDCF_AIFSN_MAX) { - wiphy_err(wlc->wiphy, "wl%d: wlc_edcf_setparams: bad " + wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad " "aifs %d\n", wlc->pub->unit, acp_shm.aifs); continue; } @@ -1295,7 +1131,7 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur; acp_shm.reggap = acp_shm.bslots + acp_shm.aifs; /* Indicate the new params to the ucode */ - acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO + + acp_shm.status = brcms_c_read_shm(wlc, (M_EDCF_QINFO + wme_shmemacindex(aci) * M_EDCF_QLEN + M_EDCF_STATUS_OFF)); @@ -1303,8 +1139,8 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, /* Fill in shm acparam table */ shm_entry = (u16 *) &acp_shm; - for (i = 0; i < (int)sizeof(shm_acparams_t); i += 2) - wlc_write_shm(wlc, + for (i = 0; i < (int)sizeof(struct shm_acparams); i += 2) + brcms_c_write_shm(wlc, M_EDCF_QINFO + wme_shmemacindex(aci) * M_EDCF_QLEN + i, *shm_entry++); @@ -1312,18 +1148,18 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, } while (0); if (suspend) - wlc_suspend_mac_and_wait(wlc); + brcms_c_suspend_mac_and_wait(wlc); if (suspend) - wlc_enable_mac(wlc); + brcms_c_enable_mac(wlc); } -void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend) +void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) { u16 aci; int i_ac; - edcf_acparam_t *edcf_acp; + struct edcf_acparam *edcf_acp; struct ieee80211_tx_queue_params txq_pars; struct ieee80211_tx_queue_params *params = &txq_pars; @@ -1334,15 +1170,11 @@ void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend) * STA uses AC params from wme_param_ie. */ - edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0]; + edcf_acp = (struct edcf_acparam *) &wlc->wme_param_ie.acparam[0]; for (i_ac = 0; i_ac < AC_COUNT; i_ac++, edcf_acp++) { /* find out which ac this set of params applies to */ aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; - /* set the admission control policy for this AC */ - if (edcf_acp->ACI & EDCF_ACM_MASK) { - wlc->wme_admctl |= 1 << aci; - } /* fill in shm ac params struct */ params->txop = edcf_acp->TXOP; @@ -1353,25 +1185,25 @@ void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend) /* CWmax = 2^(ECWmax) - 1 */ params->cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK) >> EDCF_ECWMAX_SHIFT); - wlc_wme_setparams(wlc, aci, params, suspend); + brcms_c_wme_setparams(wlc, aci, params, suspend); } if (suspend) - wlc_suspend_mac_and_wait(wlc); + brcms_c_suspend_mac_and_wait(wlc); if (AP_ENAB(wlc->pub) && WME_ENAB(wlc->pub)) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, false); + brcms_c_update_beacon(wlc); + brcms_c_update_probe_resp(wlc, false); } if (suspend) - wlc_enable_mac(wlc); + brcms_c_enable_mac(wlc); } -bool wlc_timers_init(struct wlc_info *wlc, int unit) +bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit) { - wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer, + wlc->wdtimer = brcms_init_timer(wlc->wl, brcms_c_watchdog_by_timer, wlc, "watchdog"); if (!wlc->wdtimer) { wiphy_err(wlc->wiphy, "wl%d: wl_init_timer for wdtimer " @@ -1379,7 +1211,7 @@ bool wlc_timers_init(struct wlc_info *wlc, int unit) goto fail; } - wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer, + wlc->radio_timer = brcms_init_timer(wlc->wl, brcms_c_radio_timer, wlc, "radio"); if (!wlc->radio_timer) { wiphy_err(wlc->wiphy, "wl%d: wl_init_timer for radio_timer " @@ -1394,44 +1226,35 @@ bool wlc_timers_init(struct wlc_info *wlc, int unit) } /* - * Initialize wlc_info default values ... + * Initialize brcms_c_info default values ... * may get overrides later in this function */ -void wlc_info_init(struct wlc_info *wlc, int unit) +void brcms_c_info_init(struct brcms_c_info *wlc, int unit) { int i; /* Assume the device is there until proven otherwise */ wlc->device_present = true; - /* set default power output percentage to 100 percent */ - wlc->txpwr_percent = 100; - /* Save our copy of the chanspec */ wlc->chanspec = CH20MHZ_CHSPEC(1); - /* initialize CCK preamble mode to unassociated state */ - wlc->shortpreamble = false; - - wlc->legacy_probe = true; - /* various 802.11g modes */ wlc->shortslot = false; - wlc->shortslot_override = WLC_SHORTSLOT_AUTO; + wlc->shortslot_override = BRCMS_SHORTSLOT_AUTO; - wlc->barker_overlap_control = true; - wlc->barker_preamble = WLC_BARKER_SHORT_ALLOWED; - wlc->txburst_limit_override = AUTO; + brcms_c_protection_upd(wlc, BRCMS_PROT_G_OVR, BRCMS_PROTECTION_AUTO); + brcms_c_protection_upd(wlc, BRCMS_PROT_G_SPEC, false); - wlc_protection_upd(wlc, WLC_PROT_G_OVR, WLC_PROTECTION_AUTO); - wlc_protection_upd(wlc, WLC_PROT_G_SPEC, false); + brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG_OVR, + BRCMS_PROTECTION_AUTO); + brcms_c_protection_upd(wlc, BRCMS_PROT_N_CFG, BRCMS_N_PROTECTION_OFF); + brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF_OVR, + BRCMS_PROTECTION_AUTO); + brcms_c_protection_upd(wlc, BRCMS_PROT_N_NONGF, false); + brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, AUTO); - wlc_protection_upd(wlc, WLC_PROT_N_CFG_OVR, WLC_PROTECTION_AUTO); - wlc_protection_upd(wlc, WLC_PROT_N_CFG, WLC_N_PROTECTION_OFF); - wlc_protection_upd(wlc, WLC_PROT_N_NONGF_OVR, WLC_PROTECTION_AUTO); - wlc_protection_upd(wlc, WLC_PROT_N_NONGF, false); - wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, AUTO); - - wlc_protection_upd(wlc, WLC_PROT_OVERLAP, WLC_PROTECTION_CTL_OVERLAP); + brcms_c_protection_upd(wlc, BRCMS_PROT_OVERLAP, + BRCMS_PROTECTION_CTL_OVERLAP); /* 802.11g draft 4.0 NonERP elt advertisement */ wlc->include_legacy_erp = true; @@ -1439,7 +1262,7 @@ void wlc_info_init(struct wlc_info *wlc, int unit) wlc->stf->ant_rx_ovr = ANT_RX_DIV_DEF; wlc->stf->txant = ANT_TX_DEF; - wlc->prb_resp_timeout = WLC_PRB_RESP_TIMEOUT; + wlc->prb_resp_timeout = BRCMS_PRB_RESP_TIMEOUT; wlc->usr_fragthresh = DOT11_DEFAULT_FRAG_LEN; for (i = 0; i < NFIFO; i++) @@ -1454,30 +1277,6 @@ void wlc_info_init(struct wlc_info *wlc, int unit) wlc->SRL = RETRY_SHORT_DEF; wlc->LRL = RETRY_LONG_DEF; - /* init PM state */ - wlc->PM = PM_OFF; /* User's setting of PM mode through IOCTL */ - wlc->PM_override = false; /* Prevents from going to PM if our AP is 'ill' */ - wlc->PMenabled = false; /* Current PM state */ - wlc->PMpending = false; /* Tracks whether STA indicated PM in the last attempt */ - wlc->PMblocked = false; /* To allow blocking going into PM during RM and scans */ - - /* In WMM Auto mode, PM is allowed if association is a UAPSD association */ - wlc->WME_PM_blocked = false; - - /* Init wme queuing method */ - wlc->wme_prec_queuing = false; - - /* Overrides for the core to stay awake under zillion conditions Look for STAY_AWAKE */ - wlc->wake = false; - /* Are we waiting for a response to PS-Poll that we sent */ - wlc->PSpoll = false; - - /* APSD defaults */ - wlc->wme_apsd = true; - wlc->apsd_sta_usp = false; - wlc->apsd_trigger_timeout = 0; /* disable the trigger timer */ - wlc->apsd_trigger_ac = AC_BITMAP_ALL; - /* Set flag to indicate that hw keys should be used when available. */ wlc->wsec_swkeys = false; @@ -1487,8 +1286,6 @@ void wlc_info_init(struct wlc_info *wlc, int unit) wlc->wsec_keys[i]->idx = (u8) i; } - wlc->_regulatory_domain = false; /* 802.11d */ - /* WME QoS mode is Auto by default */ wlc->pub->_wme = AUTO; @@ -1498,54 +1295,50 @@ void wlc_info_init(struct wlc_info *wlc, int unit) wlc->pub->_ampdu = AMPDU_AGG_HOST; wlc->pub->bcmerror = 0; - wlc->ibss_allowed = true; - wlc->ibss_coalesce_allowed = true; wlc->pub->_coex = ON; /* initialize mpc delay */ - wlc->mpc_delay_off = wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; - - wlc->pr80838_war = true; + wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; } -static bool wlc_state_bmac_sync(struct wlc_info *wlc) +static bool brcms_c_state_bmac_sync(struct brcms_c_info *wlc) { - wlc_bmac_state_t state_bmac; + struct brcms_b_state state_bmac; - if (wlc_bmac_state_get(wlc->hw, &state_bmac) != 0) + if (brcms_b_state_get(wlc->hw, &state_bmac) != 0) return false; wlc->machwcap = state_bmac.machwcap; - wlc_protection_upd(wlc, WLC_PROT_N_PAM_OVR, + brcms_c_protection_upd(wlc, BRCMS_PROT_N_PAM_OVR, (s8) state_bmac.preamble_ovr); return true; } -static uint wlc_attach_module(struct wlc_info *wlc) +static uint brcms_c_attach_module(struct brcms_c_info *wlc) { uint err = 0; uint unit; unit = wlc->pub->unit; - wlc->asi = wlc_antsel_attach(wlc); + wlc->asi = brcms_c_antsel_attach(wlc); if (wlc->asi == NULL) { - wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_antsel_attach " + wiphy_err(wlc->wiphy, "wl%d: attach: antsel_attach " "failed\n", unit); err = 44; goto fail; } - wlc->ampdu = wlc_ampdu_attach(wlc); + wlc->ampdu = brcms_c_ampdu_attach(wlc); if (wlc->ampdu == NULL) { - wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_ampdu_attach " + wiphy_err(wlc->wiphy, "wl%d: attach: ampdu_attach " "failed\n", unit); err = 50; goto fail; } - if ((wlc_stf_attach(wlc) != 0)) { - wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_stf_attach " + if ((brcms_c_stf_attach(wlc) != 0)) { + wiphy_err(wlc->wiphy, "wl%d: attach: stf_attach " "failed\n", unit); err = 68; goto fail; @@ -1554,28 +1347,28 @@ static uint wlc_attach_module(struct wlc_info *wlc) return err; } -struct wlc_pub *wlc_pub(void *wlc) +struct brcms_pub *brcms_c_pub(void *wlc) { - return ((struct wlc_info *) wlc)->pub; + return ((struct brcms_c_info *) wlc)->pub; } -#define CHIP_SUPPORTS_11N(wlc) 1 +#define CHIP_SUPPORTS_11N(wlc) 1 /* * The common driver entry routine. Error codes should be unique */ -void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, +void *brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit, bool piomode, void *regsva, uint bustype, void *btparam, uint *perr) { - struct wlc_info *wlc; + struct brcms_c_info *wlc; uint err = 0; uint j; - struct wlc_pub *pub; + struct brcms_pub *pub; uint n_disabled; - /* allocate struct wlc_info state and its substructures */ - wlc = (struct wlc_info *) wlc_attach_malloc(unit, &err, device); + /* allocate struct brcms_c_info state and its substructures */ + wlc = (struct brcms_c_info *) brcms_c_attach_malloc(unit, &err, device); if (wlc == NULL) goto fail; wlc->wiphy = wl->wiphy; @@ -1589,30 +1382,23 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, wlc->core = wlc->corestate; wlc->wl = wl; pub->unit = unit; - wlc->btparam = btparam; pub->_piomode = piomode; wlc->bandinit_pending = false; - /* By default restrict TKIP associations from 11n STA's */ - wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT; - /* populate struct wlc_info with default values */ - wlc_info_init(wlc, unit); + /* populate struct brcms_c_info with default values */ + brcms_c_info_init(wlc, unit); /* update sta/ap related parameters */ - wlc_ap_upd(wlc); + brcms_c_ap_upd(wlc); /* 11n_disable nvram */ n_disabled = getintvar(pub->vars, "11n_disable"); - /* register a module (to handle iovars) */ - wlc_module_register(wlc->pub, wlc_iovars, "wlc_iovars", wlc, - wlc_doiovar, NULL, NULL); - /* * low level attach steps(all hw accesses go * inside, no more in rest of the attach) */ - err = wlc_bmac_attach(wlc, vendor, device, unit, piomode, regsva, + err = brcms_b_attach(wlc, vendor, device, unit, piomode, regsva, bustype, btparam); if (err) goto fail; @@ -1620,15 +1406,15 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, /* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split, * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver */ - if (!wlc_state_bmac_sync(wlc)) { + if (!brcms_c_state_bmac_sync(wlc)) { err = 20; goto fail; } - pub->phy_11ncapable = WLC_PHY_11N_CAP(wlc->band); + pub->phy_11ncapable = BRCMS_PHY_11N_CAP(wlc->band); /* propagate *vars* from BMAC driver to high driver */ - wlc_bmac_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size); + brcms_b_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size); /* set maximum allowed duty cycle */ @@ -1637,10 +1423,10 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, wlc->tx_duty_cycle_cck = (u16) getintvar(pub->vars, "tx_duty_cycle_cck"); - wlc_stf_phy_chain_calc(wlc); + brcms_c_stf_phy_chain_calc(wlc); /* txchain 1: txant 0, txchain 2: txant 1 */ - if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) + if (BRCMS_ISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) wlc->stf->txant = wlc->stf->hw_txchain - 1; /* push to BMAC driver */ @@ -1654,7 +1440,7 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, wlc->core->txavail[i] = wlc->hw->txavail[i]; } - wlc_bmac_hw_etheraddr(wlc->hw, wlc->perm_etheraddr); + brcms_b_hw_etheraddr(wlc->hw, wlc->perm_etheraddr); memcpy(&pub->cur_etheraddr, &wlc->perm_etheraddr, ETH_ALEN); @@ -1665,7 +1451,7 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, wlc->band = wlc->bandstate[j]; - if (!wlc_attach_stf_ant_init(wlc)) { + if (!brcms_c_attach_stf_ant_init(wlc)) { err = 24; goto fail; } @@ -1677,18 +1463,19 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, /* init gmode value */ if (BAND_2G(wlc->band->bandtype)) { wlc->band->gmode = GMODE_AUTO; - wlc_protection_upd(wlc, WLC_PROT_G_USER, + brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, wlc->band->gmode); } /* init _n_enab supported mode */ - if (WLC_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) { + if (BRCMS_PHY_11N_CAP(wlc->band) && CHIP_SUPPORTS_11N(wlc)) { if (n_disabled & WLFEATURE_DISABLE_11N) { pub->_n_enab = OFF; - wlc_protection_upd(wlc, WLC_PROT_N_USER, OFF); + brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER, + OFF); } else { pub->_n_enab = SUPPORT_11N; - wlc_protection_upd(wlc, WLC_PROT_N_USER, + brcms_c_protection_upd(wlc, BRCMS_PROT_N_USER, ((pub->_n_enab == SUPPORT_11N) ? WL_11N_2x2 : WL_11N_3x3)); @@ -1696,48 +1483,48 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, } /* init per-band default rateset, depend on band->gmode */ - wlc_default_rateset(wlc, &wlc->band->defrateset); + brcms_default_rateset(wlc, &wlc->band->defrateset); - /* fill in hw_rateset (used early by WLC_SET_RATESET) */ - wlc_rateset_filter(&wlc->band->defrateset, + /* fill in hw_rateset (used early by BRCM_SET_RATESET) */ + brcms_c_rateset_filter(&wlc->band->defrateset, &wlc->band->hw_rateset, false, - WLC_RATES_CCK_OFDM, WLC_RATE_MASK, + BRCMS_RATES_CCK_OFDM, BRCMS_RATE_MASK, (bool) N_ENAB(wlc->pub)); } /* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */ - wlc_stf_phy_txant_upd(wlc); + brcms_c_stf_phy_txant_upd(wlc); /* attach each modules */ - err = wlc_attach_module(wlc); + err = brcms_c_attach_module(wlc); if (err != 0) goto fail; - if (!wlc_timers_init(wlc, unit)) { - wiphy_err(wl->wiphy, "wl%d: %s: wlc_init_timer failed\n", unit, + if (!brcms_c_timers_init(wlc, unit)) { + wiphy_err(wl->wiphy, "wl%d: %s: init_timer failed\n", unit, __func__); err = 32; goto fail; } /* depend on rateset, gmode */ - wlc->cmi = wlc_channel_mgr_attach(wlc); + wlc->cmi = brcms_c_channel_mgr_attach(wlc); if (!wlc->cmi) { - wiphy_err(wl->wiphy, "wl%d: %s: wlc_channel_mgr_attach failed" + wiphy_err(wl->wiphy, "wl%d: %s: channel_mgr_attach failed" "\n", unit, __func__); err = 33; goto fail; } /* init default when all parameters are ready, i.e. ->rateset */ - wlc_bss_default_init(wlc); + brcms_c_bss_default_init(wlc); /* * Complete the wlc default state initializations.. */ /* allocate our initial queue */ - wlc->pkt_queue = wlc_txq_alloc(wlc); + wlc->pkt_queue = brcms_c_txq_alloc(wlc); if (wlc->pkt_queue == NULL) { wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n", unit, __func__); @@ -1750,7 +1537,7 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, wlc->cfg->wlc = wlc; pub->txmaxpkts = MAXTXPKTS; - wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie); + brcms_c_wme_initparams_sta(wlc, &wlc->wme_param_ie); wlc->mimoft = FT_HT; wlc->ht_cap.cap_info = HT_CAP; @@ -1760,20 +1547,19 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, wlc->mimo_40txbw = AUTO; wlc->ofdm_40txbw = AUTO; wlc->cck_40txbw = AUTO; - wlc_update_mimo_band_bwcap(wlc, WLC_N_BW_20IN2G_40IN5G); - - /* Enable setting the RIFS Mode bit by default in HT Info IE */ - wlc->rifs_advert = AUTO; + brcms_c_update_mimo_band_bwcap(wlc, BRCMS_N_BW_20IN2G_40IN5G); /* Set default values of SGI */ - if (WLC_SGI_CAP_PHY(wlc)) { - wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); + if (BRCMS_SGI_CAP_PHY(wlc)) { + brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 | + BRCMS_N_SGI_40)); wlc->sgi_tx = AUTO; - } else if (WLCISSSLPNPHY(wlc->band)) { - wlc_ht_update_sgi_rx(wlc, (WLC_N_SGI_20 | WLC_N_SGI_40)); + } else if (BRCMS_ISSSLPNPHY(wlc->band)) { + brcms_c_ht_update_sgi_rx(wlc, (BRCMS_N_SGI_20 | + BRCMS_N_SGI_40)); wlc->sgi_tx = AUTO; } else { - wlc_ht_update_sgi_rx(wlc, 0); + brcms_c_ht_update_sgi_rx(wlc, 0); wlc->sgi_tx = OFF; } @@ -1784,7 +1570,7 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, wlc->sgi_tx = OFF; if (n_disabled & WLFEATURE_DISABLE_11N_SGI_RX) - wlc_ht_update_sgi_rx(wlc, 0); + brcms_c_ht_update_sgi_rx(wlc, 0); /* apply the stbc override from nvram conf */ if (n_disabled & WLFEATURE_DISABLE_11N_STBC_TX) { @@ -1793,23 +1579,15 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; } if (n_disabled & WLFEATURE_DISABLE_11N_STBC_RX) - wlc_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO); + brcms_c_stf_stbc_rx_set(wlc, HT_CAP_RX_STBC_NO); /* apply the GF override from nvram conf */ if (n_disabled & WLFEATURE_DISABLE_11N_GF) wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_GRN_FLD; /* initialize radio_mpc_disable according to wlc->mpc */ - wlc_radio_mpc_upd(wlc); - - if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) { - if ((getintvar(wlc->pub->vars, "aa2g") == 7) || - (getintvar(wlc->pub->vars, "aa5g") == 7)) { - wlc_bmac_antsel_set(wlc->hw, 1); - } - } else { - wlc_bmac_antsel_set(wlc->hw, wlc->asi->antsel_avail); - } + brcms_c_radio_mpc_upd(wlc); + brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail); if (perr) *perr = 0; @@ -1820,14 +1598,14 @@ void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n", unit, __func__, err); if (wlc) - wlc_detach(wlc); + brcms_c_detach(wlc); if (perr) *perr = err; return NULL; } -static void wlc_attach_antgain_init(struct wlc_info *wlc) +static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc) { uint unit; unit = wlc->pub->unit; @@ -1859,7 +1637,7 @@ static void wlc_attach_antgain_init(struct wlc_info *wlc) } } -static bool wlc_attach_stf_ant_init(struct wlc_info *wlc) +static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc) { int aa; uint unit; @@ -1894,49 +1672,51 @@ static bool wlc_attach_stf_ant_init(struct wlc_info *wlc) /* Compute Antenna Gain */ wlc->band->antgain = (s8) getintvar(vars, (BAND_5G(bandtype) ? "ag1" : "ag0")); - wlc_attach_antgain_init(wlc); + brcms_c_attach_antgain_init(wlc); return true; } -static void wlc_timers_deinit(struct wlc_info *wlc) +static void brcms_c_timers_deinit(struct brcms_c_info *wlc) { /* free timer state */ if (wlc->wdtimer) { - wl_free_timer(wlc->wl, wlc->wdtimer); + brcms_free_timer(wlc->wl, wlc->wdtimer); wlc->wdtimer = NULL; } if (wlc->radio_timer) { - wl_free_timer(wlc->wl, wlc->radio_timer); + brcms_free_timer(wlc->wl, wlc->radio_timer); wlc->radio_timer = NULL; } } -static void wlc_detach_module(struct wlc_info *wlc) +static void brcms_c_detach_module(struct brcms_c_info *wlc) { if (wlc->asi) { - wlc_antsel_detach(wlc->asi); + brcms_c_antsel_detach(wlc->asi); wlc->asi = NULL; } if (wlc->ampdu) { - wlc_ampdu_detach(wlc->ampdu); + brcms_c_ampdu_detach(wlc->ampdu); wlc->ampdu = NULL; } - wlc_stf_detach(wlc); + brcms_c_stf_detach(wlc); } /* * Return a count of the number of driver callbacks still pending. * - * General policy is that wlc_detach can only dealloc/free software states. It can NOT - * touch hardware registers since the d11core may be in reset and clock may not be available. - * One exception is sb register access, which is possible if crystal is turned on - * After "down" state, driver should avoid software timer with the exception of radio_monitor. + * General policy is that brcms_c_detach can only dealloc/free software states. + * It can NOT touch hardware registers since the d11core may be in reset and + * clock may not be available. + * One exception is sb register access, which is possible if crystal is turned + * on after "down" state, driver should avoid software timer with the exception + * of radio_monitor. */ -uint wlc_detach(struct wlc_info *wlc) +uint brcms_c_detach(struct brcms_c_info *wlc) { uint callbacks = 0; @@ -1945,70 +1725,47 @@ uint wlc_detach(struct wlc_info *wlc) BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); - callbacks += wlc_bmac_detach(wlc); + callbacks += brcms_b_detach(wlc); /* delete software timers */ - if (!wlc_radio_monitor_stop(wlc)) + if (!brcms_c_radio_monitor_stop(wlc)) callbacks++; - wlc_channel_mgr_detach(wlc->cmi); + brcms_c_channel_mgr_detach(wlc->cmi); - wlc_timers_deinit(wlc); + brcms_c_timers_deinit(wlc); - wlc_detach_module(wlc); + brcms_c_detach_module(wlc); - /* free other state */ - - -#ifdef BCMDBG - kfree(wlc->country_ie_override); - wlc->country_ie_override = NULL; -#endif /* BCMDBG */ - - { - /* free dumpcb list */ - struct dumpcb_s *prev, *ptr; - prev = ptr = wlc->dumpcb_head; - while (ptr) { - ptr = prev->next; - kfree(prev); - prev = ptr; - } - wlc->dumpcb_head = NULL; - } - - /* Detach from iovar manager */ - wlc_module_unregister(wlc->pub, "wlc_iovars", wlc); while (wlc->tx_queues != NULL) - wlc_txq_free(wlc, wlc->tx_queues); + brcms_c_txq_free(wlc, wlc->tx_queues); - wlc_detach_mfree(wlc); + brcms_c_detach_mfree(wlc); return callbacks; } /* update state that depends on the current value of "ap" */ -void wlc_ap_upd(struct wlc_info *wlc) +void brcms_c_ap_upd(struct brcms_c_info *wlc) { if (AP_ENAB(wlc->pub)) - wlc->PLCPHdr_override = WLC_PLCP_AUTO; /* AP: short not allowed, but not enforced */ + /* AP: short not allowed, but not enforced */ + wlc->PLCPHdr_override = BRCMS_PLCP_AUTO; else - wlc->PLCPHdr_override = WLC_PLCP_SHORT; /* STA-BSS; short capable */ - - /* disable vlan_mode on AP since some legacy STAs cannot rx tagged pkts */ - wlc->vlan_mode = AP_ENAB(wlc->pub) ? OFF : AUTO; + /* STA-BSS; short capable */ + wlc->PLCPHdr_override = BRCMS_PLCP_SHORT; /* fixup mpc */ wlc->mpc = true; } /* read hwdisable state and propagate to wlc flag */ -static void wlc_radio_hwdisable_upd(struct wlc_info *wlc) +static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc) { if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off) return; - if (wlc_bmac_radio_read_hwdisabled(wlc->hw)) { + if (brcms_b_radio_read_hwdisabled(wlc->hw)) { mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); } else { mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); @@ -2016,17 +1773,17 @@ static void wlc_radio_hwdisable_upd(struct wlc_info *wlc) } /* return true if Minimum Power Consumption should be entered, false otherwise */ -bool wlc_is_non_delay_mpc(struct wlc_info *wlc) +bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc) { return false; } -bool wlc_ismpc(struct wlc_info *wlc) +bool brcms_c_ismpc(struct brcms_c_info *wlc) { - return (wlc->mpc_delay_off == 0) && (wlc_is_non_delay_mpc(wlc)); + return (wlc->mpc_delay_off == 0) && (brcms_c_is_non_delay_mpc(wlc)); } -void wlc_radio_mpc_upd(struct wlc_info *wlc) +void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc) { bool mpc_radio, radio_state; @@ -2040,9 +1797,9 @@ void wlc_radio_mpc_upd(struct wlc_info *wlc) if (!wlc->pub->radio_disabled) return; mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); - wlc_radio_upd(wlc); + brcms_c_radio_upd(wlc); if (!wlc->pub->radio_disabled) - wlc_radio_monitor_stop(wlc); + brcms_c_radio_monitor_stop(wlc); return; } @@ -2054,17 +1811,17 @@ void wlc_radio_mpc_upd(struct wlc_info *wlc) radio_state = (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF : ON); - mpc_radio = (wlc_ismpc(wlc) == true) ? OFF : ON; + mpc_radio = (brcms_c_ismpc(wlc) == true) ? OFF : ON; if (radio_state == ON && mpc_radio == OFF) wlc->mpc_delay_off = wlc->mpc_dlycnt; else if (radio_state == OFF && mpc_radio == ON) { mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); - wlc_radio_upd(wlc); - if (wlc->mpc_offcnt < WLC_MPC_THRESHOLD) { - wlc->mpc_dlycnt = WLC_MPC_MAX_DELAYCNT; - } else - wlc->mpc_dlycnt = WLC_MPC_MIN_DELAYCNT; + brcms_c_radio_upd(wlc); + if (wlc->mpc_offcnt < BRCMS_MPC_THRESHOLD) + wlc->mpc_dlycnt = BRCMS_MPC_MAX_DELAYCNT; + else + wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts; } /* Below logic is meant to capture the transition from mpc off to mpc on for reasons @@ -2072,57 +1829,57 @@ void wlc_radio_mpc_upd(struct wlc_info *wlc) * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off */ if ((wlc->prev_non_delay_mpc == false) && - (wlc_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) { + (brcms_c_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) { wlc->mpc_delay_off = wlc->mpc_dlycnt; } - wlc->prev_non_delay_mpc = wlc_is_non_delay_mpc(wlc); + wlc->prev_non_delay_mpc = brcms_c_is_non_delay_mpc(wlc); } /* * centralized radio disable/enable function, * invoke radio enable/disable after updating hwradio status */ -static void wlc_radio_upd(struct wlc_info *wlc) +static void brcms_c_radio_upd(struct brcms_c_info *wlc) { if (wlc->pub->radio_disabled) { - wlc_radio_disable(wlc); + brcms_c_radio_disable(wlc); } else { - wlc_radio_enable(wlc); + brcms_c_radio_enable(wlc); } } /* maintain LED behavior in down state */ -static void wlc_down_led_upd(struct wlc_info *wlc) +static void brcms_c_down_led_upd(struct brcms_c_info *wlc) { /* maintain LEDs while in down state, turn on sbclk if not available yet */ /* turn on sbclk if necessary */ if (!AP_ENAB(wlc->pub)) { - wlc_pllreq(wlc, true, WLC_PLLREQ_FLIP); + brcms_c_pllreq(wlc, true, BRCMS_PLLREQ_FLIP); - wlc_pllreq(wlc, false, WLC_PLLREQ_FLIP); + brcms_c_pllreq(wlc, false, BRCMS_PLLREQ_FLIP); } } /* update hwradio status and return it */ -bool wlc_check_radio_disabled(struct wlc_info *wlc) +bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc) { - wlc_radio_hwdisable_upd(wlc); + brcms_c_radio_hwdisable_upd(wlc); return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ? true : false; } -void wlc_radio_disable(struct wlc_info *wlc) +void brcms_c_radio_disable(struct brcms_c_info *wlc) { if (!wlc->pub->up) { - wlc_down_led_upd(wlc); + brcms_c_down_led_upd(wlc); return; } - wlc_radio_monitor_start(wlc); - wl_down(wlc->wl); + brcms_c_radio_monitor_start(wlc); + brcms_down(wlc->wl); } -static void wlc_radio_enable(struct wlc_info *wlc) +static void brcms_c_radio_enable(struct brcms_c_info *wlc) { if (wlc->pub->up) return; @@ -2130,71 +1887,63 @@ static void wlc_radio_enable(struct wlc_info *wlc) if (DEVICEREMOVED(wlc)) return; - if (!wlc->down_override) { /* imposed by wl down/out ioctl */ - wl_up(wlc->wl); - } + brcms_up(wlc->wl); } /* periodical query hw radio button while driver is "down" */ -static void wlc_radio_timer(void *arg) +static void brcms_c_radio_timer(void *arg) { - struct wlc_info *wlc = (struct wlc_info *) arg; + struct brcms_c_info *wlc = (struct brcms_c_info *) arg; if (DEVICEREMOVED(wlc)) { wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return; } /* cap mpc off count */ - if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT) + if (wlc->mpc_offcnt < BRCMS_MPC_MAX_DELAYCNT) wlc->mpc_offcnt++; - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); + brcms_c_radio_hwdisable_upd(wlc); + brcms_c_radio_upd(wlc); } -static bool wlc_radio_monitor_start(struct wlc_info *wlc) +static bool brcms_c_radio_monitor_start(struct brcms_c_info *wlc) { /* Don't start the timer if HWRADIO feature is disabled */ if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO)) return true; wlc->radio_monitor = true; - wlc_pllreq(wlc, true, WLC_PLLREQ_RADIO_MON); - wl_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); + brcms_c_pllreq(wlc, true, BRCMS_PLLREQ_RADIO_MON); + brcms_add_timer(wlc->wl, wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, + true); return true; } -bool wlc_radio_monitor_stop(struct wlc_info *wlc) +bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc) { if (!wlc->radio_monitor) return true; wlc->radio_monitor = false; - wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON); - return wl_del_timer(wlc->wl, wlc->radio_timer); + brcms_c_pllreq(wlc, false, BRCMS_PLLREQ_RADIO_MON); + return brcms_del_timer(wlc->wl, wlc->radio_timer); } -static void wlc_watchdog_by_timer(void *arg) +static void brcms_c_watchdog_by_timer(void *arg) { - struct wlc_info *wlc = (struct wlc_info *) arg; - wlc_watchdog(arg); - if (WLC_WATCHDOG_TBTT(wlc)) { - /* set to normal osl watchdog period */ - wl_del_timer(wlc->wl, wlc->wdtimer); - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, - true); - } + brcms_c_watchdog(arg); } /* common watchdog code */ -static void wlc_watchdog(void *arg) +static void brcms_c_watchdog(void *arg) { - struct wlc_info *wlc = (struct wlc_info *) arg; + struct brcms_c_info *wlc = (struct brcms_c_info *) arg; int i; - struct wlc_bsscfg *cfg; + struct brcms_bss_cfg *cfg; BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); @@ -2204,7 +1953,7 @@ static void wlc_watchdog(void *arg) if (DEVICEREMOVED(wlc)) { wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return; } @@ -2216,26 +1965,26 @@ static void wlc_watchdog(void *arg) if (--wlc->mpc_delay_off == 0) { mboolset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); - if (wlc->mpc && wlc_ismpc(wlc)) + if (wlc->mpc && brcms_c_ismpc(wlc)) wlc->mpc_offcnt = 0; wlc->mpc_laston_ts = OSL_SYSUPTIME(); } } /* mpc sync */ - wlc_radio_mpc_upd(wlc); + brcms_c_radio_mpc_upd(wlc); /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */ - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); + brcms_c_radio_hwdisable_upd(wlc); + brcms_c_radio_upd(wlc); /* if radio is disable, driver may be down, quit here */ if (wlc->pub->radio_disabled) return; - wlc_bmac_watchdog(wlc); + brcms_b_watchdog(wlc); /* occasionally sample mac stat counters to detect 16-bit counter wrap */ if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0) - wlc_statsupd(wlc); + brcms_c_statsupd(wlc); /* Manage TKIP countermeasures timers */ FOREACH_BSS(wlc, i, cfg) { @@ -2248,21 +1997,21 @@ static void wlc_watchdog(void *arg) } /* Call any registered watchdog handlers */ - for (i = 0; i < WLC_MAXMODULES; i++) { + for (i = 0; i < BRCMS_MAXMODULES; i++) { if (wlc->modulecb[i].watchdog_fn) wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl); } - if (WLCISNPHY(wlc->band) && !wlc->pub->tempsense_disable && + if (BRCMS_ISNPHY(wlc->band) && !wlc->pub->tempsense_disable && ((wlc->pub->now - wlc->tempsense_lasttime) >= - WLC_TEMPSENSE_PERIOD)) { + BRCMS_TEMPSENSE_PERIOD)) { wlc->tempsense_lasttime = wlc->pub->now; - wlc_tempsense_upd(wlc); + brcms_c_tempsense_upd(wlc); } } /* make interface operational */ -int wlc_up(struct wlc_info *wlc) +int brcms_c_up(struct brcms_c_info *wlc) { BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); @@ -2271,7 +2020,7 @@ int wlc_up(struct wlc_info *wlc) return -ENOMEDIUM; if (!wlc->pub->hw_up) { - wlc_bmac_hw_up(wlc->hw); + brcms_b_hw_up(wlc->hw); wlc->pub->hw_up = true; } @@ -2279,11 +2028,11 @@ int wlc_up(struct wlc_info *wlc) && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) { if (wlc->pub->boardrev >= 0x1250 && (wlc->pub->boardflags & BFL_FEM_BT)) { - wlc_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL, - MHF5_4313_GPIOCTRL, WLC_BAND_ALL); + brcms_c_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL, + MHF5_4313_GPIOCTRL, BRCM_BAND_ALL); } else { - wlc_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, MHF4_EXTPA_ENABLE, - WLC_BAND_ALL); + brcms_c_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, + MHF4_EXTPA_ENABLE, BRCM_BAND_ALL); } } @@ -2291,17 +2040,17 @@ int wlc_up(struct wlc_info *wlc) * Need to read the hwradio status here to cover the case where the system * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS) - * don't call radio_update to avoid looping wlc_up. + * don't call radio_update to avoid looping brcms_c_up. * - * wlc_bmac_up_prep() returns either 0 or -BCME_RADIOOFF only + * brcms_b_up_prep() returns either 0 or -BCME_RADIOOFF only */ if (!wlc->pub->radio_disabled) { - int status = wlc_bmac_up_prep(wlc->hw); + int status = brcms_b_up_prep(wlc->hw); if (status == -ENOMEDIUM) { if (!mboolisset (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) { int idx; - struct wlc_bsscfg *bsscfg; + struct brcms_bss_cfg *bsscfg; mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); @@ -2309,9 +2058,9 @@ int wlc_up(struct wlc_info *wlc) if (!BSSCFG_STA(bsscfg) || !bsscfg->enable || !bsscfg->BSS) continue; - wiphy_err(wlc->wiphy, "wl%d.%d: wlc_up" + wiphy_err(wlc->wiphy, "wl%d.%d: up" ": rfdisable -> " - "wlc_bsscfg_disable()\n", + "bsscfg_disable()\n", wlc->pub->unit, idx); } } @@ -2319,78 +2068,78 @@ int wlc_up(struct wlc_info *wlc) } if (wlc->pub->radio_disabled) { - wlc_radio_monitor_start(wlc); + brcms_c_radio_monitor_start(wlc); return 0; } - /* wlc_bmac_up_prep has done wlc_corereset(). so clk is on, set it */ + /* brcms_b_up_prep has done brcms_c_corereset(). so clk is on, set it */ wlc->clk = true; - wlc_radio_monitor_stop(wlc); + brcms_c_radio_monitor_stop(wlc); /* Set EDCF hostflags */ if (EDCF_ENAB(wlc->pub)) { - wlc_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, WLC_BAND_ALL); + brcms_c_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, BRCM_BAND_ALL); } else { - wlc_mhf(wlc, MHF1, MHF1_EDCF, 0, WLC_BAND_ALL); + brcms_c_mhf(wlc, MHF1, MHF1_EDCF, 0, BRCM_BAND_ALL); } - if (WLC_WAR16165(wlc)) - wlc_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR, - WLC_BAND_ALL); + if (BRCMS_WAR16165(wlc)) + brcms_c_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR, + BRCM_BAND_ALL); - wl_init(wlc->wl); + brcms_init(wlc->wl); wlc->pub->up = true; if (wlc->bandinit_pending) { - wlc_suspend_mac_and_wait(wlc); - wlc_set_chanspec(wlc, wlc->default_bss->chanspec); + brcms_c_suspend_mac_and_wait(wlc); + brcms_c_set_chanspec(wlc, wlc->default_bss->chanspec); wlc->bandinit_pending = false; - wlc_enable_mac(wlc); + brcms_c_enable_mac(wlc); } - wlc_bmac_up_finish(wlc->hw); + brcms_b_up_finish(wlc->hw); /* other software states up after ISR is running */ /* start APs that were to be brought up but are not up yet */ - /* if (AP_ENAB(wlc->pub)) wlc_restart_ap(wlc->ap); */ + /* if (AP_ENAB(wlc->pub)) brcms_c_restart_ap(wlc->ap); */ /* Program the TX wme params with the current settings */ - wlc_wme_retries_write(wlc); + brcms_c_wme_retries_write(wlc); /* start one second watchdog timer */ - wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true); + brcms_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true); wlc->WDarmed = true; /* ensure antenna config is up to date */ - wlc_stf_phy_txant_upd(wlc); + brcms_c_stf_phy_txant_upd(wlc); /* ensure LDPC config is in sync */ - wlc_ht_update_ldpc(wlc, wlc->stf->ldpc); + brcms_c_ht_update_ldpc(wlc, wlc->stf->ldpc); return 0; } /* Initialize the base precedence map for dequeueing from txq based on WME settings */ -static void wlc_tx_prec_map_init(struct wlc_info *wlc) +static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc) { - wlc->tx_prec_map = WLC_PREC_BMP_ALL; + wlc->tx_prec_map = BRCMS_PREC_BMP_ALL; memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); /* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences * if either is full. */ if (!EDCF_ENAB(wlc->pub)) { - wlc->fifo2prec_map[TX_DATA_FIFO] = WLC_PREC_BMP_ALL; - wlc->fifo2prec_map[TX_CTL_FIFO] = WLC_PREC_BMP_ALL; + wlc->fifo2prec_map[TX_DATA_FIFO] = BRCMS_PREC_BMP_ALL; + wlc->fifo2prec_map[TX_CTL_FIFO] = BRCMS_PREC_BMP_ALL; } else { - wlc->fifo2prec_map[TX_AC_BK_FIFO] = WLC_PREC_BMP_AC_BK; - wlc->fifo2prec_map[TX_AC_BE_FIFO] = WLC_PREC_BMP_AC_BE; - wlc->fifo2prec_map[TX_AC_VI_FIFO] = WLC_PREC_BMP_AC_VI; - wlc->fifo2prec_map[TX_AC_VO_FIFO] = WLC_PREC_BMP_AC_VO; + wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK; + wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE; + wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI; + wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO; } } -static uint wlc_down_del_timer(struct wlc_info *wlc) +static uint brcms_c_down_del_timer(struct brcms_c_info *wlc) { uint callbacks = 0; @@ -2402,13 +2151,13 @@ static uint wlc_down_del_timer(struct wlc_info *wlc) * disable the hardware, free any transient buffer state. * Return a count of the number of driver callbacks still pending. */ -uint wlc_down(struct wlc_info *wlc) +uint brcms_c_down(struct brcms_c_info *wlc) { uint callbacks = 0; int i; bool dev_gone = false; - struct wlc_txq_info *qi; + struct brcms_txq_info *qi; BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); @@ -2424,12 +2173,12 @@ uint wlc_down(struct wlc_info *wlc) /* in between, mpc could try to bring down again.. */ wlc->going_down = true; - callbacks += wlc_bmac_down_prep(wlc->hw); + callbacks += brcms_b_bmac_down_prep(wlc->hw); dev_gone = DEVICEREMOVED(wlc); /* Call any registered down handlers */ - for (i = 0; i < WLC_MAXMODULES; i++) { + for (i = 0; i < BRCMS_MAXMODULES; i++) { if (wlc->modulecb[i].down_fn) callbacks += wlc->modulecb[i].down_fn(wlc->modulecb[i].hdl); @@ -2437,28 +2186,28 @@ uint wlc_down(struct wlc_info *wlc) /* cancel the watchdog timer */ if (wlc->WDarmed) { - if (!wl_del_timer(wlc->wl, wlc->wdtimer)) + if (!brcms_del_timer(wlc->wl, wlc->wdtimer)) callbacks++; wlc->WDarmed = false; } /* cancel all other timers */ - callbacks += wlc_down_del_timer(wlc); + callbacks += brcms_c_down_del_timer(wlc); wlc->pub->up = false; wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); /* clear txq flow control */ - wlc_txflowcontrol_reset(wlc); + brcms_c_txflowcontrol_reset(wlc); /* flush tx queues */ for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { - bcm_pktq_flush(&qi->q, true, NULL, NULL); + brcmu_pktq_flush(&qi->q, true, NULL, NULL); } - callbacks += wlc_bmac_down_finish(wlc->hw); + callbacks += brcms_b_down_finish(wlc->hw); - /* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */ + /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */ wlc->clk = false; wlc->going_down = false; @@ -2466,22 +2215,23 @@ uint wlc_down(struct wlc_info *wlc) } /* Set the current gmode configuration */ -int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) +int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) { int ret = 0; uint i; wlc_rateset_t rs; /* Default to 54g Auto */ - s8 shortslot = WLC_SHORTSLOT_AUTO; /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */ + /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */ + s8 shortslot = BRCMS_SHORTSLOT_AUTO; bool shortslot_restrict = false; /* Restrict association to stations that support shortslot */ - bool ignore_bcns = true; /* Ignore legacy beacons on the same channel */ bool ofdm_basic = false; /* Make 6, 12, and 24 basic rates */ - int preamble = WLC_PLCP_LONG; /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */ + /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */ + int preamble = BRCMS_PLCP_LONG; bool preamble_restrict = false; /* Restrict association to stations that support short * preambles */ - struct wlcband *band; + struct brcms_band *band; /* if N-support is enabled, allow Gmode set as long as requested * Gmode is not GMODE_LEGACY_B @@ -2490,22 +2240,22 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) return -ENOTSUPP; /* verify that we are dealing with 2G band and grab the band pointer */ - if (wlc->band->bandtype == WLC_BAND_2G) + if (wlc->band->bandtype == BRCM_BAND_2G) band = wlc->band; else if ((NBANDS(wlc) > 1) && - (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G)) + (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == BRCM_BAND_2G)) band = wlc->bandstate[OTHERBANDUNIT(wlc)]; else return -EINVAL; /* Legacy or bust when no OFDM is supported by regulatory */ - if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) & - WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B)) + if ((brcms_c_channel_locale_flags_in_band(wlc->cmi, band->bandunit) & + BRCMS_NO_OFDM) && (gmode != GMODE_LEGACY_B)) return -EINVAL; /* update configuration value */ if (config == true) - wlc_protection_upd(wlc, WLC_PROT_G_USER, gmode); + brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode); /* Clear supported rates filter */ memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t)); @@ -2515,14 +2265,15 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) switch (gmode) { case GMODE_LEGACY_B: - shortslot = WLC_SHORTSLOT_OFF; - wlc_rateset_copy(&gphy_legacy_rates, &rs); + shortslot = BRCMS_SHORTSLOT_OFF; + brcms_c_rateset_copy(&gphy_legacy_rates, &rs); break; case GMODE_LRS: if (AP_ENAB(wlc->pub)) - wlc_rateset_copy(&cck_rates, &wlc->sup_rates_override); + brcms_c_rateset_copy(&cck_rates, + &wlc->sup_rates_override); break; case GMODE_AUTO: @@ -2531,19 +2282,19 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) case GMODE_ONLY: ofdm_basic = true; - preamble = WLC_PLCP_SHORT; + preamble = BRCMS_PLCP_SHORT; preamble_restrict = true; break; case GMODE_PERFORMANCE: if (AP_ENAB(wlc->pub)) /* Put all rates into the Supported Rates element */ - wlc_rateset_copy(&cck_ofdm_rates, + brcms_c_rateset_copy(&cck_ofdm_rates, &wlc->sup_rates_override); - shortslot = WLC_SHORTSLOT_ON; + shortslot = BRCMS_SHORTSLOT_ON; shortslot_restrict = true; ofdm_basic = true; - preamble = WLC_PLCP_SHORT; + preamble = BRCMS_PLCP_SHORT; preamble_restrict = true; break; @@ -2562,7 +2313,7 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) band->gmode = gmode; if (band->rspec_override && !IS_CCK(band->rspec_override)) { band->rspec_override = 0; - wlc_reprate_init(wlc); + brcms_c_reprate_init(wlc); } if (band->mrspec_override && !IS_CCK(band->mrspec_override)) { band->mrspec_override = 0; @@ -2571,26 +2322,24 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) band->gmode = gmode; - wlc->ignore_bcns = ignore_bcns; - wlc->shortslot_override = shortslot; if (AP_ENAB(wlc->pub)) { /* wlc->ap->shortslot_restrict = shortslot_restrict; */ wlc->PLCPHdr_override = (preamble != - WLC_PLCP_LONG) ? WLC_PLCP_SHORT : WLC_PLCP_AUTO; + BRCMS_PLCP_LONG) ? BRCMS_PLCP_SHORT : BRCMS_PLCP_AUTO; } - if ((AP_ENAB(wlc->pub) && preamble != WLC_PLCP_LONG) - || preamble == WLC_PLCP_SHORT) + if ((AP_ENAB(wlc->pub) && preamble != BRCMS_PLCP_LONG) + || preamble == BRCMS_PLCP_SHORT) wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE; else wlc->default_bss->capability &= ~WLAN_CAPABILITY_SHORT_PREAMBLE; /* Update shortslot capability bit for AP and IBSS */ - if ((AP_ENAB(wlc->pub) && shortslot == WLC_SHORTSLOT_AUTO) || - shortslot == WLC_SHORTSLOT_ON) + if ((AP_ENAB(wlc->pub) && shortslot == BRCMS_SHORTSLOT_AUTO) || + shortslot == BRCMS_SHORTSLOT_ON) wlc->default_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME; else wlc->default_bss->capability &= @@ -2598,26 +2347,26 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) /* Use the default 11g rateset */ if (!rs.count) - wlc_rateset_copy(&cck_ofdm_rates, &rs); + brcms_c_rateset_copy(&cck_ofdm_rates, &rs); if (ofdm_basic) { for (i = 0; i < rs.count; i++) { - if (rs.rates[i] == WLC_RATE_6M - || rs.rates[i] == WLC_RATE_12M - || rs.rates[i] == WLC_RATE_24M) - rs.rates[i] |= WLC_RATE_FLAG; + if (rs.rates[i] == BRCM_RATE_6M + || rs.rates[i] == BRCM_RATE_12M + || rs.rates[i] == BRCM_RATE_24M) + rs.rates[i] |= BRCMS_RATE_FLAG; } } /* Set default bss rateset */ wlc->default_bss->rateset.count = rs.count; - memcpy(wlc->default_bss->rateset.rates, rs.rates, + memcpy(wlc->default_bss->rateset.rates, rs.rates, sizeof(wlc->default_bss->rateset.rates)); return ret; } -static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode) +static int brcms_c_nmode_validate(struct brcms_c_info *wlc, s32 nmode) { int err = 0; @@ -2629,7 +2378,7 @@ static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode) case AUTO: case WL_11N_2x2: case WL_11N_3x3: - if (!(WLC_PHY_11N_CAP(wlc->band))) + if (!(BRCMS_PHY_11N_CAP(wlc->band))) err = -EINVAL; break; @@ -2641,27 +2390,27 @@ static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode) return err; } -int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) +int brcms_c_set_nmode(struct brcms_c_info *wlc, s32 nmode) { uint i; int err; - err = wlc_nmode_validate(wlc, nmode); + err = brcms_c_nmode_validate(wlc, nmode); if (err) return err; switch (nmode) { case OFF: wlc->pub->_n_enab = OFF; - wlc->default_bss->flags &= ~WLC_BSS_HT; + wlc->default_bss->flags &= ~BRCMS_BSS_HT; /* delete the mcs rates from the default and hw ratesets */ - wlc_rateset_mcs_clear(&wlc->default_bss->rateset); + brcms_c_rateset_mcs_clear(&wlc->default_bss->rateset); for (i = 0; i < NBANDS(wlc); i++) { memset(wlc->bandstate[i]->hw_rateset.mcs, 0, MCSSET_LEN); if (IS_MCS(wlc->band->rspec_override)) { wlc->bandstate[i]->rspec_override = 0; - wlc_reprate_init(wlc); + brcms_c_reprate_init(wlc); } if (IS_MCS(wlc->band->mrspec_override)) wlc->bandstate[i]->mrspec_override = 0; @@ -2676,14 +2425,14 @@ int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) case WL_11N_2x2: case WL_11N_3x3: /* force GMODE_AUTO if NMODE is ON */ - wlc_set_gmode(wlc, GMODE_AUTO, true); + brcms_c_set_gmode(wlc, GMODE_AUTO, true); if (nmode == WL_11N_3x3) wlc->pub->_n_enab = SUPPORT_HT; else wlc->pub->_n_enab = SUPPORT_11N; - wlc->default_bss->flags |= WLC_BSS_HT; + wlc->default_bss->flags |= BRCMS_BSS_HT; /* add the mcs rates to the default and hw ratesets */ - wlc_rateset_mcs_build(&wlc->default_bss->rateset, + brcms_c_rateset_mcs_build(&wlc->default_bss->rateset, wlc->stf->txstreams); for (i = 0; i < NBANDS(wlc); i++) memcpy(wlc->bandstate[i]->hw_rateset.mcs, @@ -2697,7 +2446,7 @@ int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) return err; } -static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) +static int brcms_c_set_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs_arg) { wlc_rateset_t rs, new; uint bandunit; @@ -2705,13 +2454,13 @@ static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) memcpy(&rs, rs_arg, sizeof(wlc_rateset_t)); /* check for bad count value */ - if ((rs.count == 0) || (rs.count > WLC_NUMRATES)) + if ((rs.count == 0) || (rs.count > BRCMS_NUMRATES)) return -EINVAL; /* try the current band */ bandunit = wlc->band->bandunit; memcpy(&new, &rs, sizeof(wlc_rateset_t)); - if (wlc_rate_hwrs_filter_sort_validate + if (brcms_c_rate_hwrs_filter_sort_validate (&new, &wlc->bandstate[bandunit]->hw_rateset, true, wlc->stf->txstreams)) goto good; @@ -2720,7 +2469,7 @@ static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) if (IS_MBAND_UNLOCKED(wlc)) { bandunit = OTHERBANDUNIT(wlc); memcpy(&new, &rs, sizeof(wlc_rateset_t)); - if (wlc_rate_hwrs_filter_sort_validate(&new, + if (brcms_c_rate_hwrs_filter_sort_validate(&new, &wlc-> bandstate[bandunit]-> hw_rateset, true, @@ -2739,18 +2488,18 @@ static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) } /* simplified integer set interface for common ioctl handler */ -int wlc_set(struct wlc_info *wlc, int cmd, int arg) +int brcms_c_set(struct brcms_c_info *wlc, int cmd, int arg) { - return wlc_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL); + return brcms_c_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL); } /* simplified integer get interface for common ioctl handler */ -int wlc_get(struct wlc_info *wlc, int cmd, int *arg) +int brcms_c_get(struct brcms_c_info *wlc, int cmd, int *arg) { - return wlc_ioctl(wlc, cmd, arg, sizeof(int), NULL); + return brcms_c_ioctl(wlc, cmd, arg, sizeof(int), NULL); } -static void wlc_ofdm_rateset_war(struct wlc_info *wlc) +static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc) { u8 r; bool war = false; @@ -2766,28 +2515,25 @@ static void wlc_ofdm_rateset_war(struct wlc_info *wlc) } int -wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif) +brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, + struct brcms_c_if *wlcif) { - return _wlc_ioctl(wlc, cmd, arg, len, wlcif); + return _brcms_c_ioctl(wlc, cmd, arg, len, wlcif); } /* common ioctl handler. return: 0=ok, -1=error, positive=particular error */ static int -_wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif) +_brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, + struct brcms_c_if *wlcif) { int val, *pval; bool bool_val; int bcmerror; - d11regs_t *regs; - uint i; struct scb *nextscb; bool ta_ok; uint band; - rw_reg_t *r; - struct wlc_bsscfg *bsscfg; - wlc_bss_info_t *current_bss; + struct brcms_bss_cfg *bsscfg; + struct brcms_bss_info *current_bss; /* update bsscfg pointer */ bsscfg = wlc->cfg; @@ -2797,18 +2543,17 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, nextscb = NULL; ta_ok = false; band = 0; - r = NULL; /* If the device is turned off, then it's not "removed" */ if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) { wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, __func__); - wl_down(wlc->wl); + brcms_down(wlc->wl); return -EBADE; } /* default argument is generic integer */ - pval = arg ? (int *)arg:NULL; + pval = arg ? (int *)arg : NULL; /* This will prevent the misaligned access */ if (pval && (u32) len >= sizeof(val)) @@ -2819,64 +2564,17 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* bool conversion to avoid duplication below */ bool_val = val != 0; bcmerror = 0; - regs = wlc->regs; - /* A few commands don't need any arguments; all the others do. */ - switch (cmd) { - case WLC_UP: - case WLC_OUT: - case WLC_DOWN: - case WLC_DISASSOC: - case WLC_RESTART: - case WLC_REBOOT: - case WLC_START_CHANNEL_QA: - case WLC_INIT: - break; - - default: - if ((arg == NULL) || (len <= 0)) { - wiphy_err(wlc->wiphy, "wl%d: %s: Command %d needs " - "arguments\n", - wlc->pub->unit, __func__, cmd); - bcmerror = -EINVAL; - goto done; - } + if ((arg == NULL) || (len <= 0)) { + wiphy_err(wlc->wiphy, "wl%d: %s: Command %d needs arguments\n", + wlc->pub->unit, __func__, cmd); + bcmerror = -EINVAL; + goto done; } switch (cmd) { -#if defined(BCMDBG) - case WLC_GET_MSGLEVEL: - *pval = wl_msg_level; - break; - - case WLC_SET_MSGLEVEL: - wl_msg_level = val; - break; -#endif - - case WLC_GET_INSTANCE: - *pval = wlc->pub->unit; - break; - - case WLC_GET_CHANNEL:{ - channel_info_t *ci = (channel_info_t *) arg; - - if (len <= (int)sizeof(ci)) { - bcmerror = EOVERFLOW; - goto done; - } - - ci->hw_channel = - CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC); - ci->target_channel = - CHSPEC_CHANNEL(wlc->default_bss->chanspec); - ci->scan_channel = 0; - - break; - } - - case WLC_SET_CHANNEL:{ + case BRCM_SET_CHANNEL:{ chanspec_t chspec = CH20MHZ_CHSPEC(val); if (val < 0 || val > MAXCHANNEL) { @@ -2884,486 +2582,63 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; } - if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) { + if (!brcms_c_valid_chanspec_db(wlc->cmi, chspec)) { bcmerror = -EINVAL; break; } if (!wlc->pub->up && IS_MBAND_UNLOCKED(wlc)) { if (wlc->band->bandunit != - CHSPEC_WLCBANDUNIT(chspec)) + CHSPEC_BANDUNIT(chspec)) wlc->bandinit_pending = true; else wlc->bandinit_pending = false; } wlc->default_bss->chanspec = chspec; - /* wlc_BSSinit() will sanitize the rateset before using it.. */ + /* brcms_c_BSSinit() will sanitize the rateset before + * using it.. */ if (wlc->pub->up && - (WLC_BAND_PI_RADIO_CHANSPEC != chspec)) { - wlc_set_home_chanspec(wlc, chspec); - wlc_suspend_mac_and_wait(wlc); - wlc_set_chanspec(wlc, chspec); - wlc_enable_mac(wlc); + (BRCMS_BAND_PI_RADIO_CHANSPEC != chspec)) { + brcms_c_set_home_chanspec(wlc, chspec); + brcms_c_suspend_mac_and_wait(wlc); + brcms_c_set_chanspec(wlc, chspec); + brcms_c_enable_mac(wlc); } break; } -#if defined(BCMDBG) - case WLC_GET_UCFLAGS: - if (!wlc->pub->up) { - bcmerror = -ENOLINK; - break; - } - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val >= MHFMAX) { - bcmerror = -EINVAL; - break; - } - - *pval = wlc_bmac_mhf_get(wlc->hw, (u8) val, WLC_BAND_AUTO); - break; - - case WLC_SET_UCFLAGS: - if (!wlc->pub->up) { - bcmerror = -ENOLINK; - break; - } - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - i = (u16) val; - if (i >= MHFMAX) { - bcmerror = -EINVAL; - break; - } - - wlc_mhf(wlc, (u8) i, 0xffff, (u16) (val >> NBITS(u16)), - WLC_BAND_AUTO); - break; - - case WLC_GET_SHMEM: - ta_ok = true; - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val & 1) { - bcmerror = -EINVAL; - break; - } - - *pval = wlc_read_shm(wlc, (u16) val); - break; - - case WLC_SET_SHMEM: - ta_ok = true; - - /* optional band is stored in the second integer of incoming buffer */ - band = - (len < - (int)(2 * sizeof(int))) ? WLC_BAND_AUTO : ((int *)arg)[1]; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (val & 1) { - bcmerror = -EINVAL; - break; - } - - wlc_write_shm(wlc, (u16) val, - (u16) (val >> NBITS(u16))); - break; - - case WLC_R_REG: /* MAC registers */ - ta_ok = true; - r = (rw_reg_t *) arg; - band = WLC_BAND_AUTO; - - if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { - bcmerror = -EOVERFLOW; - break; - } - - if (len >= (int)sizeof(rw_reg_t)) - band = r->band; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if ((r->byteoff + r->size) > sizeof(d11regs_t)) { - bcmerror = -EINVAL; - break; - } - if (r->size == sizeof(u32)) - r->val = - R_REG((u32 *)((unsigned char *)(unsigned long)regs + - r->byteoff)); - else if (r->size == sizeof(u16)) - r->val = - R_REG((u16 *)((unsigned char *)(unsigned long)regs + - r->byteoff)); - else - bcmerror = -EINVAL; - break; - - case WLC_W_REG: - ta_ok = true; - r = (rw_reg_t *) arg; - band = WLC_BAND_AUTO; - - if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) { - bcmerror = -EOVERFLOW; - break; - } - - if (len >= (int)sizeof(rw_reg_t)) - band = r->band; - - /* bcmerror checking */ - bcmerror = wlc_iocregchk(wlc, band); - if (bcmerror) - break; - - if (r->byteoff + r->size > sizeof(d11regs_t)) { - bcmerror = -EINVAL; - break; - } - if (r->size == sizeof(u32)) - W_REG((u32 *)((unsigned char *)(unsigned long) regs + - r->byteoff), r->val); - else if (r->size == sizeof(u16)) - W_REG((u16 *)((unsigned char *)(unsigned long) regs + - r->byteoff), r->val); - else - bcmerror = -EINVAL; - break; -#endif /* BCMDBG */ - - case WLC_GET_TXANT: - *pval = wlc->stf->txant; - break; - - case WLC_SET_TXANT: - bcmerror = wlc_stf_ant_txant_validate(wlc, (s8) val); - if (bcmerror < 0) - break; - - wlc->stf->txant = (s8) val; - - /* if down, we are done */ - if (!wlc->pub->up) - break; - - wlc_suspend_mac_and_wait(wlc); - - wlc_stf_phy_txant_upd(wlc); - wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); - - wlc_enable_mac(wlc); - - break; - - case WLC_GET_ANTDIV:{ - u8 phy_antdiv; - - /* return configured value if core is down */ - if (!wlc->pub->up) { - *pval = wlc->stf->ant_rx_ovr; - - } else { - if (wlc_phy_ant_rxdiv_get - (wlc->band->pi, &phy_antdiv)) - *pval = (int)phy_antdiv; - else - *pval = (int)wlc->stf->ant_rx_ovr; - } - - break; - } - case WLC_SET_ANTDIV: - /* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */ - if ((val < -1) || (val > 3)) { - bcmerror = -EINVAL; - break; - } - - if (val == -1) - val = ANT_RX_DIV_DEF; - - wlc->stf->ant_rx_ovr = (u8) val; - wlc_phy_ant_rxdiv_set(wlc->band->pi, (u8) val); - break; - - case WLC_GET_RX_ANT:{ /* get latest used rx antenna */ - u16 rxstatus; - - if (!wlc->pub->up) { - bcmerror = -ENOLINK; - break; - } - - rxstatus = R_REG(&wlc->regs->phyrxstatus0); - if (rxstatus == 0xdead || rxstatus == (u16) -1) { - bcmerror = -EBADE; - break; - } - *pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; - break; - } - -#if defined(BCMDBG) - case WLC_GET_UCANTDIV: - if (!wlc->clk) { - bcmerror = -EIO; - break; - } - - *pval = - (wlc_bmac_mhf_get(wlc->hw, MHF1, WLC_BAND_AUTO) & - MHF1_ANTDIV); - break; - - case WLC_SET_UCANTDIV:{ - if (!wlc->pub->up) { - bcmerror = -ENOLINK; - break; - } - - /* if multiband, band must be locked */ - if (IS_MBAND_UNLOCKED(wlc)) { - bcmerror = -ENOMEDIUM; - break; - } - - wlc_mhf(wlc, MHF1, MHF1_ANTDIV, - (val ? MHF1_ANTDIV : 0), WLC_BAND_AUTO); - break; - } -#endif /* defined(BCMDBG) */ - - case WLC_GET_SRL: - *pval = wlc->SRL; - break; - - case WLC_SET_SRL: + case BRCM_SET_SRL: if (val >= 1 && val <= RETRY_SHORT_MAX) { int ac; wlc->SRL = (u16) val; - wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); + brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); for (ac = 0; ac < AC_COUNT; ac++) { - WLC_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL); + BRCMS_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL); } - wlc_wme_retries_write(wlc); + brcms_c_wme_retries_write(wlc); } else bcmerror = -EINVAL; break; - case WLC_GET_LRL: - *pval = wlc->LRL; - break; - - case WLC_SET_LRL: + case BRCM_SET_LRL: if (val >= 1 && val <= 255) { int ac; wlc->LRL = (u16) val; - wlc_bmac_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); + brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); for (ac = 0; ac < AC_COUNT; ac++) { - WLC_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL); + BRCMS_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL); } - wlc_wme_retries_write(wlc); + brcms_c_wme_retries_write(wlc); } else bcmerror = -EINVAL; break; - case WLC_GET_CWMIN: - *pval = wlc->band->CWmin; - break; - - case WLC_SET_CWMIN: - if (!wlc->clk) { - bcmerror = -EIO; - break; - } - - if (val >= 1 && val <= 255) { - wlc_set_cwmin(wlc, (u16) val); - } else - bcmerror = -EINVAL; - break; - - case WLC_GET_CWMAX: - *pval = wlc->band->CWmax; - break; - - case WLC_SET_CWMAX: - if (!wlc->clk) { - bcmerror = -EIO; - break; - } - - if (val >= 255 && val <= 2047) { - wlc_set_cwmax(wlc, (u16) val); - } else - bcmerror = -EINVAL; - break; - - case WLC_GET_RADIO: /* use mask if don't want to expose some internal bits */ - *pval = wlc->pub->radio_disabled; - break; - - case WLC_SET_RADIO:{ /* 32 bits input, higher 16 bits are mask, lower 16 bits are value to - * set - */ - u16 radiomask, radioval; - uint validbits = - WL_RADIO_SW_DISABLE | WL_RADIO_HW_DISABLE; - mbool new = 0; - - radiomask = (val & 0xffff0000) >> 16; - radioval = val & 0x0000ffff; - - if ((radiomask == 0) || (radiomask & ~validbits) - || (radioval & ~validbits) - || ((radioval & ~radiomask) != 0)) { - wiphy_err(wlc->wiphy, "SET_RADIO with wrong " - "bits 0x%x\n", val); - bcmerror = -EINVAL; - break; - } - - new = - (wlc->pub->radio_disabled & ~radiomask) | radioval; - wlc->pub->radio_disabled = new; - - wlc_radio_hwdisable_upd(wlc); - wlc_radio_upd(wlc); - break; - } - - case WLC_GET_PHYTYPE: - *pval = WLC_PHYTYPE(wlc->band->phytype); - break; - -#if defined(BCMDBG) - case WLC_GET_KEY: - if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc))) { - wl_wsec_key_t key; - - wsec_key_t *src_key = wlc->wsec_keys[val]; - - if (len < (int)sizeof(key)) { - bcmerror = -EOVERFLOW; - break; - } - - memset((char *)&key, 0, sizeof(key)); - if (src_key) { - key.index = src_key->id; - key.len = src_key->len; - memcpy(key.data, src_key->data, key.len); - key.algo = src_key->algo; - if (WSEC_SOFTKEY(wlc, src_key, bsscfg)) - key.flags |= WL_SOFT_KEY; - if (src_key->flags & WSEC_PRIMARY_KEY) - key.flags |= WL_PRIMARY_KEY; - - memcpy(key.ea, src_key->ea, ETH_ALEN); - } - - memcpy(arg, &key, sizeof(key)); - } else - bcmerror = -EINVAL; - break; -#endif /* defined(BCMDBG) */ - - case WLC_SET_KEY: - bcmerror = - wlc_iovar_op(wlc, "wsec_key", NULL, 0, arg, len, IOV_SET, - wlcif); - break; - - case WLC_GET_KEY_SEQ:{ - wsec_key_t *key; - - if (len < DOT11_WPA_KEY_RSC_LEN) { - bcmerror = -EOVERFLOW; - break; - } - - /* Return the key's tx iv as an EAPOL sequence counter. - * This will be used to supply the RSC value to a supplicant. - * The format is 8 bytes, with least significant in seq[0]. - */ - - key = WSEC_KEY(wlc, val); - if ((val >= 0) && (val < WLC_MAX_WSEC_KEYS(wlc)) && - (key != NULL)) { - u8 seq[DOT11_WPA_KEY_RSC_LEN]; - u16 lo; - u32 hi; - /* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */ - if ((bsscfg->WPA_auth & WPA_AUTH_NONE) && - is_zero_ether_addr(key->ea)) { - lo = bsscfg->wpa_none_txiv.lo; - hi = bsscfg->wpa_none_txiv.hi; - } else { - lo = key->txiv.lo; - hi = key->txiv.hi; - } - - /* format the buffer, low to high */ - seq[0] = lo & 0xff; - seq[1] = (lo >> 8) & 0xff; - seq[2] = hi & 0xff; - seq[3] = (hi >> 8) & 0xff; - seq[4] = (hi >> 16) & 0xff; - seq[5] = (hi >> 24) & 0xff; - seq[6] = 0; - seq[7] = 0; - - memcpy(arg, seq, sizeof(seq)); - } else { - bcmerror = -EINVAL; - } - break; - } - - case WLC_GET_CURR_RATESET:{ + case BRCM_GET_CURR_RATESET:{ wl_rateset_t *ret_rs = (wl_rateset_t *) arg; wlc_rateset_t *rs; @@ -3383,25 +2658,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; } - case WLC_GET_RATESET:{ - wlc_rateset_t rs; - wl_rateset_t *ret_rs = (wl_rateset_t *) arg; - - memset(&rs, 0, sizeof(wlc_rateset_t)); - wlc_default_rateset(wlc, (wlc_rateset_t *) &rs); - - if (len < (int)(rs.count + sizeof(rs.count))) { - bcmerror = -EOVERFLOW; - break; - } - - /* Copy only legacy rateset section */ - ret_rs->count = rs.count; - memcpy(&ret_rs->rates, &rs.rates, rs.count); - break; - } - - case WLC_SET_RATESET:{ + case BRCM_SET_RATESET:{ wlc_rateset_t rs; wl_rateset_t *in_rs = (wl_rateset_t *) arg; @@ -3410,7 +2667,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; } - if (in_rs->count > WLC_NUMRATES) { + if (in_rs->count > BRCMS_NUMRATES) { bcmerror = -ENOBUFS; break; } @@ -3433,149 +2690,24 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, MCSSET_LEN); } - bcmerror = wlc_set_rateset(wlc, &rs); + bcmerror = brcms_c_set_rateset(wlc, &rs); if (!bcmerror) - wlc_ofdm_rateset_war(wlc); + brcms_c_ofdm_rateset_war(wlc); break; } - case WLC_GET_BCNPRD: - if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) - *pval = current_bss->beacon_period; - else - *pval = wlc->default_bss->beacon_period; - break; - - case WLC_SET_BCNPRD: + case BRCM_SET_BCNPRD: /* range [1, 0xffff] */ if (val >= DOT11_MIN_BEACON_PERIOD - && val <= DOT11_MAX_BEACON_PERIOD) { + && val <= DOT11_MAX_BEACON_PERIOD) wlc->default_bss->beacon_period = (u16) val; - } else + else bcmerror = -EINVAL; break; - case WLC_GET_DTIMPRD: - if (BSSCFG_STA(bsscfg) && bsscfg->BSS && bsscfg->associated) - *pval = current_bss->dtim_period; - else - *pval = wlc->default_bss->dtim_period; - break; - - case WLC_SET_DTIMPRD: - /* range [1, 0xff] */ - if (val >= DOT11_MIN_DTIM_PERIOD - && val <= DOT11_MAX_DTIM_PERIOD) { - wlc->default_bss->dtim_period = (u8) val; - } else - bcmerror = -EINVAL; - break; - -#ifdef SUPPORT_PS - case WLC_GET_PM: - *pval = wlc->PM; - break; - - case WLC_SET_PM: - if ((val >= PM_OFF) && (val <= PM_MAX)) { - wlc->PM = (u8) val; - if (wlc->pub->up) { - } - /* Change watchdog driver to align watchdog with tbtt if possible */ - wlc_watchdog_upd(wlc, PS_ALLOWED(wlc)); - } else - bcmerror = -EBADE; - break; -#endif /* SUPPORT_PS */ - -#ifdef SUPPORT_PS -#ifdef BCMDBG - case WLC_GET_WAKE: - if (AP_ENAB(wlc->pub)) { - bcmerror = -BCME_NOTSTA; - break; - } - *pval = wlc->wake; - break; - - case WLC_SET_WAKE: - if (AP_ENAB(wlc->pub)) { - bcmerror = -BCME_NOTSTA; - break; - } - - wlc->wake = val ? true : false; - - /* if down, we're done */ - if (!wlc->pub->up) - break; - - /* apply to the mac */ - wlc_set_ps_ctrl(wlc); - break; -#endif /* BCMDBG */ -#endif /* SUPPORT_PS */ - - case WLC_GET_REVINFO: - bcmerror = wlc_get_revision_info(wlc, arg, (uint) len); - break; - - case WLC_GET_AP: - *pval = (int)AP_ENAB(wlc->pub); - break; - - case WLC_GET_ATIM: - if (bsscfg->associated) - *pval = (int)current_bss->atim_window; - else - *pval = (int)wlc->default_bss->atim_window; - break; - - case WLC_SET_ATIM: - wlc->default_bss->atim_window = (u32) val; - break; - -#ifdef SUPPORT_HWKEY - case WLC_GET_WSEC: - bcmerror = - wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_GET, - wlcif); - break; - - case WLC_SET_WSEC: - bcmerror = - wlc_iovar_op(wlc, "wsec", NULL, 0, arg, len, IOV_SET, - wlcif); - break; - - case WLC_GET_WPA_AUTH: - *pval = (int)bsscfg->WPA_auth; - break; - - case WLC_SET_WPA_AUTH: - /* change of WPA_Auth modifies the PS_ALLOWED state */ - if (BSSCFG_STA(bsscfg)) { - bsscfg->WPA_auth = (u16) val; - } else - bsscfg->WPA_auth = (u16) val; - break; -#endif /* SUPPORT_HWKEY */ - - case WLC_GET_BANDLIST: - /* count of number of bands, followed by each band type */ - *pval++ = NBANDS(wlc); - *pval++ = wlc->band->bandtype; - if (NBANDS(wlc) > 1) - *pval++ = wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype; - break; - - case WLC_GET_BAND: - *pval = wlc->bandlocked ? wlc->band->bandtype : WLC_BAND_AUTO; - break; - - case WLC_GET_PHYLIST: + case BRCM_GET_PHYLIST: { unsigned char *cp = arg; if (len < 3) { @@ -3583,28 +2715,19 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, break; } - if (WLCISNPHY(wlc->band)) { + if (BRCMS_ISNPHY(wlc->band)) *cp++ = 'n'; - } else if (WLCISLCNPHY(wlc->band)) { + else if (BRCMS_ISLCNPHY(wlc->band)) *cp++ = 'c'; - } else if (WLCISSSLPNPHY(wlc->band)) { + else if (BRCMS_ISSSLPNPHY(wlc->band)) *cp++ = 's'; - } *cp = '\0'; break; } - case WLC_GET_SHORTSLOT: - *pval = wlc->shortslot; - break; - - case WLC_GET_SHORTSLOT_OVERRIDE: - *pval = wlc->shortslot_override; - break; - - case WLC_SET_SHORTSLOT_OVERRIDE: - if ((val != WLC_SHORTSLOT_AUTO) && - (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) { + case BRCMS_SET_SHORTSLOT_OVERRIDE: + if (val != BRCMS_SHORTSLOT_AUTO && val != BRCMS_SHORTSLOT_OFF && + val != BRCMS_SHORTSLOT_ON) { bcmerror = -EINVAL; break; } @@ -3621,270 +2744,21 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* let watchdog or beacon processing update shortslot */ } else if (wlc->pub->up) { /* unassociated shortslot is off */ - wlc_switch_shortslot(wlc, false); + brcms_c_switch_shortslot(wlc, false); } else { - /* driver is down, so just update the wlc_info value */ - if (wlc->shortslot_override == WLC_SHORTSLOT_AUTO) { + /* driver is down, so just update the brcms_c_info + * value */ + if (wlc->shortslot_override == BRCMS_SHORTSLOT_AUTO) { wlc->shortslot = false; } else { wlc->shortslot = (wlc->shortslot_override == - WLC_SHORTSLOT_ON); + BRCMS_SHORTSLOT_ON); } } break; - case WLC_GET_LEGACY_ERP: - *pval = wlc->include_legacy_erp; - break; - - case WLC_SET_LEGACY_ERP: - if (wlc->include_legacy_erp == bool_val) - break; - - wlc->include_legacy_erp = bool_val; - - if (AP_ENAB(wlc->pub) && wlc->clk) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } - break; - - case WLC_GET_GMODE: - if (wlc->band->bandtype == WLC_BAND_2G) - *pval = wlc->band->gmode; - else if (NBANDS(wlc) > 1) - *pval = wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode; - break; - - case WLC_SET_GMODE: - if (!wlc->pub->associated) - bcmerror = wlc_set_gmode(wlc, (u8) val, true); - else { - bcmerror = -EISCONN; - break; - } - break; - - case WLC_GET_GMODE_PROTECTION: - *pval = wlc->protection->_g; - break; - - case WLC_GET_PROTECTION_CONTROL: - *pval = wlc->protection->overlap; - break; - - case WLC_SET_PROTECTION_CONTROL: - if ((val != WLC_PROTECTION_CTL_OFF) && - (val != WLC_PROTECTION_CTL_LOCAL) && - (val != WLC_PROTECTION_CTL_OVERLAP)) { - bcmerror = -EINVAL; - break; - } - - wlc_protection_upd(wlc, WLC_PROT_OVERLAP, (s8) val); - - /* Current g_protection will sync up to the specified control alg in watchdog - * if the driver is up and associated. - * If the driver is down or not associated, the control setting has no effect. - */ - break; - - case WLC_GET_GMODE_PROTECTION_OVERRIDE: - *pval = wlc->protection->g_override; - break; - - case WLC_SET_GMODE_PROTECTION_OVERRIDE: - if ((val != WLC_PROTECTION_AUTO) && - (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) { - bcmerror = -EINVAL; - break; - } - - wlc_protection_upd(wlc, WLC_PROT_G_OVR, (s8) val); - - break; - - case WLC_SET_SUP_RATESET_OVERRIDE:{ - wlc_rateset_t rs, new; - - /* copyin */ - if (len < (int)sizeof(wlc_rateset_t)) { - bcmerror = -EOVERFLOW; - break; - } - memcpy(&rs, arg, sizeof(wlc_rateset_t)); - - /* check for bad count value */ - if (rs.count > WLC_NUMRATES) { - bcmerror = -EINVAL; - break; - } - - /* this command is only appropriate for gmode operation */ - if (!(wlc->band->gmode || - ((NBANDS(wlc) > 1) - && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { - /* gmode only command when not in gmode */ - bcmerror = -EINVAL; - break; - } - - /* check for an empty rateset to clear the override */ - if (rs.count == 0) { - memset(&wlc->sup_rates_override, 0, - sizeof(wlc_rateset_t)); - break; - } - - /* - * validate rateset by comparing pre and - * post sorted against 11g hw rates - */ - wlc_rateset_filter(&rs, &new, false, - WLC_RATES_CCK_OFDM, WLC_RATE_MASK, - BSS_N_ENAB(wlc, bsscfg)); - wlc_rate_hwrs_filter_sort_validate(&new, - &cck_ofdm_rates, - false, - wlc->stf->txstreams); - if (rs.count != new.count) { - bcmerror = -EINVAL; - break; - } - - /* apply new rateset to the override */ - memcpy(&wlc->sup_rates_override, &new, - sizeof(wlc_rateset_t)); - - /* update bcn and probe resp if needed */ - if (wlc->pub->up && AP_ENAB(wlc->pub) - && wlc->pub->associated) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); - } - break; - } - - case WLC_GET_SUP_RATESET_OVERRIDE: - /* this command is only appropriate for gmode operation */ - if (!(wlc->band->gmode || - ((NBANDS(wlc) > 1) - && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) { - /* gmode only command when not in gmode */ - bcmerror = -EINVAL; - break; - } - if (len < (int)sizeof(wlc_rateset_t)) { - bcmerror = -EOVERFLOW; - break; - } - memcpy(arg, &wlc->sup_rates_override, sizeof(wlc_rateset_t)); - - break; - - case WLC_GET_PRB_RESP_TIMEOUT: - *pval = wlc->prb_resp_timeout; - break; - - case WLC_SET_PRB_RESP_TIMEOUT: - if (wlc->pub->up) { - bcmerror = -EISCONN; - break; - } - if (val < 0 || val >= 0xFFFF) { - bcmerror = -EINVAL; /* bad value */ - break; - } - wlc->prb_resp_timeout = (u16) val; - break; - - case WLC_GET_KEY_PRIMARY:{ - wsec_key_t *key; - - /* treat the 'val' parm as the key id */ - key = WSEC_BSS_DEFAULT_KEY(bsscfg); - if (key != NULL) { - *pval = key->id == val ? true : false; - } else { - bcmerror = -EINVAL; - } - break; - } - - case WLC_SET_KEY_PRIMARY:{ - wsec_key_t *key, *old_key; - - bcmerror = -EINVAL; - - /* treat the 'val' parm as the key id */ - for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) { - key = bsscfg->bss_def_keys[i]; - if (key != NULL && key->id == val) { - old_key = WSEC_BSS_DEFAULT_KEY(bsscfg); - if (old_key != NULL) - old_key->flags &= - ~WSEC_PRIMARY_KEY; - key->flags |= WSEC_PRIMARY_KEY; - bsscfg->wsec_index = i; - bcmerror = 0; - } - } - break; - } - -#ifdef BCMDBG - case WLC_INIT: - wl_init(wlc->wl); - break; -#endif - - case WLC_SET_VAR: - case WLC_GET_VAR:{ - char *name; - /* validate the name value */ - name = (char *)arg; - for (i = 0; i < (uint) len && *name != '\0'; - i++, name++) - ; - - if (i == (uint) len) { - bcmerror = -EOVERFLOW; - break; - } - i++; /* include the null in the string length */ - - if (cmd == WLC_GET_VAR) { - bcmerror = - wlc_iovar_op(wlc, arg, - (void *)((s8 *) arg + i), - len - i, arg, len, IOV_GET, - wlcif); - } else - bcmerror = - wlc_iovar_op(wlc, arg, NULL, 0, - (void *)((s8 *) arg + i), - len - i, IOV_SET, wlcif); - - break; - } - - case WLC_SET_WSEC_PMK: - bcmerror = -ENOTSUPP; - break; - -#if defined(BCMDBG) - case WLC_CURRENT_PWR: - if (!wlc->pub->up) - bcmerror = -ENOLINK; - else - bcmerror = wlc_get_current_txpwr(wlc, arg, len); - break; -#endif - - case WLC_LAST: - wiphy_err(wlc->wiphy, "%s: WLC_LAST\n", __func__); } done: @@ -3894,83 +2768,22 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, return bcmerror; } -#if defined(BCMDBG) -/* consolidated register access ioctl error checking */ -int wlc_iocregchk(struct wlc_info *wlc, uint band) -{ - /* if band is specified, it must be the current band */ - if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype)) - return -EINVAL; - - /* if multiband and band is not specified, band must be locked */ - if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc)) - return -ENOMEDIUM; - - /* must have core clocks */ - if (!wlc->clk) - return -EIO; - - return 0; -} -#endif /* defined(BCMDBG) */ - -/* Look up the given var name in the given table */ -static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table, - const char *name) -{ - const bcm_iovar_t *vi; - const char *lookup_name; - - /* skip any ':' delimited option prefixes */ - lookup_name = strrchr(name, ':'); - if (lookup_name != NULL) - lookup_name++; - else - lookup_name = name; - - for (vi = table; vi->name; vi++) { - if (!strcmp(vi->name, lookup_name)) - return vi; - } - /* ran to end of table */ - - return NULL; /* var name not found */ -} - -/* simplified integer get interface for common WLC_GET_VAR ioctl handler */ -int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg) -{ - return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(s32), IOV_GET, - NULL); -} - -/* simplified integer set interface for common WLC_SET_VAR ioctl handler */ -int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg) -{ - return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg), - IOV_SET, NULL); -} - /* - * register iovar table, watchdog and down handlers. - * calling function must keep 'iovars' until wlc_module_unregister is called. - * 'iovar' must have the last entry's name field being NULL as terminator. + * register watchdog and down handlers. */ -int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, - const char *name, void *hdl, iovar_fn_t i_fn, +int brcms_c_module_register(struct brcms_pub *pub, + const char *name, void *hdl, watchdog_fn_t w_fn, down_fn_t d_fn) { - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; + struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc; int i; /* find an empty entry and just add, no duplication check! */ - for (i = 0; i < WLC_MAXMODULES; i++) { + for (i = 0; i < BRCMS_MAXMODULES; i++) { if (wlc->modulecb[i].name[0] == '\0') { strncpy(wlc->modulecb[i].name, name, sizeof(wlc->modulecb[i].name) - 1); - wlc->modulecb[i].iovars = iovars; wlc->modulecb[i].hdl = hdl; - wlc->modulecb[i].iovar_fn = i_fn; wlc->modulecb[i].watchdog_fn = w_fn; wlc->modulecb[i].down_fn = d_fn; return 0; @@ -3981,15 +2794,16 @@ int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, } /* unregister module callbacks */ -int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl) +int +brcms_c_module_unregister(struct brcms_pub *pub, const char *name, void *hdl) { - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; + struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc; int i; if (wlc == NULL) return -ENODATA; - for (i = 0; i < WLC_MAXMODULES; i++) { + for (i = 0; i < BRCMS_MAXMODULES; i++) { if (!strcmp(wlc->modulecb[i].name, name) && (wlc->modulecb[i].hdl == hdl)) { memset(&wlc->modulecb[i], 0, sizeof(struct modulecb)); @@ -4002,7 +2816,7 @@ int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl) } /* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */ -static void wlc_wme_retries_write(struct wlc_info *wlc) +static void brcms_c_wme_retries_write(struct brcms_c_info *wlc) { int ac; @@ -4011,307 +2825,19 @@ static void wlc_wme_retries_write(struct wlc_info *wlc) return; for (ac = 0; ac < AC_COUNT; ac++) { - wlc_write_shm(wlc, M_AC_TXLMT_ADDR(ac), wlc->wme_retries[ac]); + brcms_c_write_shm(wlc, M_AC_TXLMT_ADDR(ac), + wlc->wme_retries[ac]); } } -/* Get or set an iovar. The params/p_len pair specifies any additional - * qualifying parameters (e.g. an "element index") for a get, while the - * arg/len pair is the buffer for the value to be set or retrieved. - * Operation (get/set) is specified by the last argument. - * interface context provided by wlcif - * - * All pointers may point into the same buffer. - */ -int -wlc_iovar_op(struct wlc_info *wlc, const char *name, - void *params, int p_len, void *arg, int len, - bool set, struct wlc_if *wlcif) -{ - int err = 0; - int val_size; - const bcm_iovar_t *vi = NULL; - u32 actionid; - int i; - - if (!set && (len == sizeof(int)) && - !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) { - wiphy_err(wlc->wiphy, "wl%d: %s unaligned get ptr for %s\n", - wlc->pub->unit, __func__, name); - return -ENOTSUPP; - } - - /* find the given iovar name */ - for (i = 0; i < WLC_MAXMODULES; i++) { - if (!wlc->modulecb[i].iovars) - continue; - vi = wlc_iovar_lookup(wlc->modulecb[i].iovars, name); - if (vi) - break; - } - /* iovar name not found */ - if (i >= WLC_MAXMODULES) { - return -ENOTSUPP; - } - - /* set up 'params' pointer in case this is a set command so that - * the convenience int and bool code can be common to set and get - */ - if (params == NULL) { - params = arg; - p_len = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - /* all other types are integer sized */ - val_size = sizeof(int); - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - - /* Do the actual parameter implementation */ - err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid, - name, params, p_len, arg, len, val_size, - wlcif); - return err; -} - -int -wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len, - bool set) -{ - struct wlc_info *wlc = (struct wlc_info *) pub->wlc; - int err = 0; - s32 int_val = 0; - - /* check generic condition flags */ - if (set) { - if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) || - ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) { - err = (wlc->pub->up ? -EISCONN : -ENOLINK); - } else if ((vi->flags & IOVF_SET_BAND) - && IS_MBAND_UNLOCKED(wlc)) { - err = -ENOMEDIUM; - } else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) { - err = -EIO; - } - } else { - if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) || - ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) { - err = (wlc->pub->up ? -EISCONN : -ENOLINK); - } else if ((vi->flags & IOVF_GET_BAND) - && IS_MBAND_UNLOCKED(wlc)) { - err = -ENOMEDIUM; - } else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) { - err = -EIO; - } - } - - if (err) - goto exit; - - /* length check on io buf */ - err = bcm_iovar_lencheck(vi, arg, len, set); - if (err) - goto exit; - - /* On set, check value ranges for integer types */ - if (set) { - switch (vi->type) { - case IOVT_BOOL: - case IOVT_INT8: - case IOVT_INT16: - case IOVT_INT32: - case IOVT_UINT8: - case IOVT_UINT16: - case IOVT_UINT32: - memcpy(&int_val, arg, sizeof(int)); - err = wlc_iovar_rangecheck(wlc, int_val, vi); - break; - } - } - exit: - return err; -} - -/* handler for iovar table wlc_iovars */ -/* - * IMPLEMENTATION NOTE: In order to avoid checking for get/set in each - * iovar case, the switch statement maps the iovar id into separate get - * and set values. If you add a new iovar to the switch you MUST use - * IOV_GVAL and/or IOV_SVAL in the case labels to avoid conflict with - * another case. - * Please use params for additional qualifying parameters. - */ -int -wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, - const char *name, void *params, uint p_len, void *arg, int len, - int val_size, struct wlc_if *wlcif) -{ - struct wlc_info *wlc = hdl; - struct wlc_bsscfg *bsscfg; - int err = 0; - s32 int_val = 0; - s32 int_val2 = 0; - s32 *ret_int_ptr; - bool bool_val; - bool bool_val2; - wlc_bss_info_t *current_bss; - - BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); - - bsscfg = NULL; - current_bss = NULL; - - err = wlc_iovar_check(wlc->pub, vi, arg, len, IOV_ISSET(actionid)); - if (err != 0) - return err; - - /* convenience int and bool vals for first 8 bytes of buffer */ - if (p_len >= (int)sizeof(int_val)) - memcpy(&int_val, params, sizeof(int_val)); - - if (p_len >= (int)sizeof(int_val) * 2) - memcpy(&int_val2, - (void *)((unsigned long)params + sizeof(int_val)), - sizeof(int_val)); - - /* convenience int ptr for 4-byte gets (requires int aligned arg) */ - ret_int_ptr = (s32 *) arg; - - bool_val = (int_val != 0) ? true : false; - bool_val2 = (int_val2 != 0) ? true : false; - - BCMMSG(wlc->wiphy, "wl%d: id %d\n", wlc->pub->unit, IOV_ID(actionid)); - /* Do the actual parameter implementation */ - switch (actionid) { - case IOV_SVAL(IOV_RTSTHRESH): - wlc->RTSThresh = int_val; - break; - - case IOV_GVAL(IOV_QTXPOWER):{ - uint qdbm; - bool override; - - err = wlc_phy_txpower_get(wlc->band->pi, &qdbm, - &override); - if (err != 0) - return err; - - /* Return qdbm units */ - *ret_int_ptr = - qdbm | (override ? WL_TXPWR_OVERRIDE : 0); - break; - } - - /* As long as override is false, this only sets the *user* targets. - User can twiddle this all he wants with no harm. - wlc_phy_txpower_set() explicitly sets override to false if - not internal or test. - */ - case IOV_SVAL(IOV_QTXPOWER):{ - u8 qdbm; - bool override; - - /* Remove override bit and clip to max qdbm value */ - qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff); - /* Extract override setting */ - override = (int_val & WL_TXPWR_OVERRIDE) ? true : false; - err = - wlc_phy_txpower_set(wlc->band->pi, qdbm, override); - break; - } - - case IOV_GVAL(IOV_MPC): - *ret_int_ptr = (s32) wlc->mpc; - break; - - case IOV_SVAL(IOV_MPC): - wlc->mpc = bool_val; - wlc_radio_mpc_upd(wlc); - - break; - - case IOV_GVAL(IOV_BCN_LI_BCN): - *ret_int_ptr = wlc->bcn_li_bcn; - break; - - case IOV_SVAL(IOV_BCN_LI_BCN): - wlc->bcn_li_bcn = (u8) int_val; - if (wlc->pub->up) - wlc_bcn_li_upd(wlc); - break; - - default: - wiphy_err(wlc->wiphy, "wl%d: %s: unsupported\n", - wlc->pub->unit, __func__); - err = -ENOTSUPP; - break; - } - - goto exit; /* avoid unused label warning */ - - exit: - return err; -} - -static int -wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi) -{ - int err = 0; - u32 min_val = 0; - u32 max_val = 0; - - /* Only ranged integers are checked */ - switch (vi->type) { - case IOVT_INT32: - max_val |= 0x7fffffff; - /* fall through */ - case IOVT_INT16: - max_val |= 0x00007fff; - /* fall through */ - case IOVT_INT8: - max_val |= 0x0000007f; - min_val = ~max_val; - if (vi->flags & IOVF_NTRL) - min_val = 1; - else if (vi->flags & IOVF_WHL) - min_val = 0; - /* Signed values are checked against max_val and min_val */ - if ((s32) val < (s32) min_val - || (s32) val > (s32) max_val) - err = -EINVAL; - break; - - case IOVT_UINT32: - max_val |= 0xffffffff; - /* fall through */ - case IOVT_UINT16: - max_val |= 0x0000ffff; - /* fall through */ - case IOVT_UINT8: - max_val |= 0x000000ff; - if (vi->flags & IOVF_NTRL) - min_val = 1; - if ((val < min_val) || (val > max_val)) - err = -EINVAL; - break; - } - - return err; -} - #ifdef BCMDBG -static const char *supr_reason[] = { +static const char * const supr_reason[] = { "None", "PMQ Entry", "Flush request", "Previous frag failure", "Channel mismatch", "Lifetime Expiry", "Underflow" }; -static void wlc_print_txs_status(u16 s) +static void brcms_c_print_txs_status(u16 s) { printk(KERN_DEBUG "[15:12] %d frame attempts\n", (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT); @@ -4331,7 +2857,7 @@ static void wlc_print_txs_status(u16 s) } #endif /* BCMDBG */ -void wlc_print_txstatus(tx_status_t *txs) +void brcms_c_print_txstatus(struct tx_status *txs) { #if defined(BCMDBG) u16 s = txs->status; @@ -4343,7 +2869,7 @@ void wlc_print_txstatus(tx_status_t *txs) printk(KERN_DEBUG "TxStatus: %04x", s); printk(KERN_DEBUG "\n"); - wlc_print_txs_status(s); + brcms_c_print_txs_status(s); printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime); printk(KERN_DEBUG "Seq: %04x ", txs->sequence); @@ -4356,10 +2882,10 @@ void wlc_print_txstatus(tx_status_t *txs) #endif /* defined(BCMDBG) */ } -void wlc_statsupd(struct wlc_info *wlc) +void brcms_c_statsupd(struct brcms_c_info *wlc) { int i; - macstat_t macstats; + struct macstat macstats; #ifdef BCMDBG u16 delta; u16 rxf0ovfl; @@ -4380,8 +2906,8 @@ void wlc_statsupd(struct wlc_info *wlc) #endif /* BCMDBG */ /* Read mac stats from contiguous shared memory */ - wlc_bmac_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT, - &macstats, sizeof(macstat_t)); + brcms_b_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT, + &macstats, sizeof(struct macstat)); #ifdef BCMDBG /* check for rx fifo 0 overflow */ @@ -4409,27 +2935,28 @@ void wlc_statsupd(struct wlc_info *wlc) } } -bool wlc_chipmatch(u16 vendor, u16 device) +bool brcms_c_chipmatch(u16 vendor, u16 device) { if (vendor != PCI_VENDOR_ID_BROADCOM) { - pr_err("wlc_chipmatch: unknown vendor id %04x\n", vendor); + pr_err("chipmatch: unknown vendor id %04x\n", vendor); return false; } + if (device == BCM43224_D11N_ID_VEN1) + return true; if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID)) return true; - if (device == BCM4313_D11N2G_ID) return true; if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) return true; - pr_err("wlc_chipmatch: unknown device id %04x\n", device); + pr_err("chipmatch: unknown device id %04x\n", device); return false; } #if defined(BCMDBG) -void wlc_print_txdesc(d11txh_t *txh) +void brcms_c_print_txdesc(struct d11txh *txh) { u16 mtcl = le16_to_cpu(txh->MacTxControlLow); u16 mtch = le16_to_cpu(txh->MacTxControlHigh); @@ -4465,7 +2992,7 @@ void wlc_print_txdesc(d11txh_t *txh) /* add plcp header along with txh descriptor */ printk(KERN_DEBUG "Raw TxDesc + plcp header:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - txh, sizeof(d11txh_t) + 48); + txh, sizeof(struct d11txh) + 48); printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl); printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch); @@ -4481,16 +3008,16 @@ void wlc_print_txdesc(d11txh_t *txh) printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); printk(KERN_DEBUG "\n"); - bcm_format_hex(hexbuf, iv, sizeof(txh->IV)); + brcmu_format_hex(hexbuf, iv, sizeof(txh->IV)); printk(KERN_DEBUG "SecIV: %s\n", hexbuf); - bcm_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); + brcmu_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); printk(KERN_DEBUG "RA: %s\n", hexbuf); printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); - bcm_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); + brcmu_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); - bcm_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); + brcmu_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); printk(KERN_DEBUG "PLCP: %s ", hexbuf); printk(KERN_DEBUG "DUR: %04x", fragdfb); printk(KERN_DEBUG "\n"); @@ -4506,16 +3033,16 @@ void wlc_print_txdesc(d11txh_t *txh) printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); - bcm_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); + brcmu_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); - bcm_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); + brcmu_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); printk(KERN_DEBUG "RTS Frame: %s", hexbuf); printk(KERN_DEBUG "\n"); } #endif /* defined(BCMDBG) */ #if defined(BCMDBG) -void wlc_print_rxh(d11rxhdr_t *rxh) +void brcms_c_print_rxh(struct d11rxhdr *rxh) { u16 len = rxh->RxFrameSize; u16 phystatus_0 = rxh->PhyRxStatus_0; @@ -4526,7 +3053,7 @@ void wlc_print_rxh(d11rxhdr_t *rxh) u16 macstatus2 = rxh->RxStatus2; char flagstr[64]; char lenbuf[20]; - static const bcm_bit_desc_t macstat_flags[] = { + static const struct brcmu_bit_desc macstat_flags[] = { {RXS_FCSERR, "FCSErr"}, {RXS_RESPFRAMETX, "Reply"}, {RXS_PBPRES, "PADDING"}, @@ -4537,9 +3064,10 @@ void wlc_print_rxh(d11rxhdr_t *rxh) }; printk(KERN_DEBUG "Raw RxDesc:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh, sizeof(d11rxhdr_t)); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh, + sizeof(struct d11rxhdr)); - bcm_format_flags(macstat_flags, macstatus1, flagstr, 64); + brcmu_format_flags(macstat_flags, macstatus1, flagstr, 64); snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); @@ -4554,35 +3082,9 @@ void wlc_print_rxh(d11rxhdr_t *rxh) } #endif /* defined(BCMDBG) */ -#if defined(BCMDBG) -int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) +static u16 brcms_c_rate_shm_offset(struct brcms_c_info *wlc, u8 rate) { - uint i, c; - char *p = buf; - char *endp = buf + SSID_FMT_BUF_LEN; - - if (ssid_len > IEEE80211_MAX_SSID_LEN) - ssid_len = IEEE80211_MAX_SSID_LEN; - - for (i = 0; i < ssid_len; i++) { - c = (uint) ssid[i]; - if (c == '\\') { - *p++ = '\\'; - *p++ = '\\'; - } else if (isprint((unsigned char) c)) { - *p++ = (char)c; - } else { - p += snprintf(p, (endp - p), "\\x%02X", c); - } - } - *p = '\0'; - return (int)(p - buf); -} -#endif /* defined(BCMDBG) */ - -static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) -{ - return wlc_bmac_rate_shm_offset(wlc->hw, rate); + return brcms_b_rate_shm_offset(wlc->hw, rate); } /* Callback for device removed */ @@ -4597,14 +3099,14 @@ static u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) * Returns true if packet consumed (queued), false if not. */ bool -wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec) +brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q, void *pkt, int prec) { - return wlc_prec_enq_head(wlc, q, pkt, prec, false); + return brcms_c_prec_enq_head(wlc, q, pkt, prec, false); } bool -wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, - int prec, bool head) +brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q, + struct sk_buff *pkt, int prec, bool head) { struct sk_buff *p; int eprec = -1; /* precedence to evict from */ @@ -4613,7 +3115,7 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, if (pktq_pfull(q, prec)) eprec = prec; else if (pktq_full(q)) { - p = bcm_pktq_peek_tail(q, &eprec); + p = brcmu_pktq_peek_tail(q, &eprec); if (eprec > prec) { wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d" "\n", __func__, eprec, prec); @@ -4635,41 +3137,41 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, } /* Evict packet according to discard policy */ - p = discard_oldest ? bcm_pktq_pdeq(q, eprec) : - bcm_pktq_pdeq_tail(q, eprec); - bcm_pkt_buf_free_skb(p); + p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) : + brcmu_pktq_pdeq_tail(q, eprec); + brcmu_pkt_buf_free_skb(p); } /* Enqueue */ if (head) - p = bcm_pktq_penq_head(q, prec, pkt); + p = brcmu_pktq_penq_head(q, prec, pkt); else - p = bcm_pktq_penq(q, prec, pkt); + p = brcmu_pktq_penq(q, prec, pkt); return true; } -void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, +void brcms_c_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, uint prec) { - struct wlc_info *wlc = (struct wlc_info *) ctx; - struct wlc_txq_info *qi = wlc->pkt_queue; /* Check me */ + struct brcms_c_info *wlc = (struct brcms_c_info *) ctx; + struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */ struct pktq *q = &qi->q; int prio; prio = sdu->priority; - if (!wlc_prec_enq(wlc, q, sdu, prec)) { + if (!brcms_c_prec_enq(wlc, q, sdu, prec)) { if (!EDCF_ENAB(wlc->pub) || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) - wiphy_err(wlc->wiphy, "wl%d: wlc_txq_enq: txq overflow" + wiphy_err(wlc->wiphy, "wl%d: txq_enq: txq overflow" "\n", wlc->pub->unit); /* - * XXX we might hit this condtion in case + * we might hit this condtion in case * packet flooding from mac80211 stack */ - bcm_pkt_buf_free_skb(sdu); + brcmu_pkt_buf_free_skb(sdu); } /* Check if flow control needs to be turned on after enqueuing the packet @@ -4679,18 +3181,18 @@ void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, if (!EDCF_ENAB(wlc->pub) || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { if (pktq_len(q) >= wlc->pub->tunables->datahiwat) { - wlc_txflowcontrol(wlc, qi, ON, ALLPRIO); + brcms_c_txflowcontrol(wlc, qi, ON, ALLPRIO); } } else if (wlc->pub->_priofc) { if (pktq_plen(q, wlc_prio2prec_map[prio]) >= wlc->pub->tunables->datahiwat) { - wlc_txflowcontrol(wlc, qi, ON, prio); + brcms_c_txflowcontrol(wlc, qi, ON, prio); } } } bool -wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, +brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, struct ieee80211_hw *hw) { u8 prio; @@ -4705,21 +3207,22 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, fifo = prio2fifo[prio]; pkt = sdu; if (unlikely - (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0))) + (brcms_c_d11hdrs_mac80211( + wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0))) return -EINVAL; - wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio)); - wlc_send_q(wlc); + brcms_c_txq_enq(wlc, scb, pkt, BRCMS_PRIO_TO_PREC(prio)); + brcms_c_send_q(wlc); return 0; } -void wlc_send_q(struct wlc_info *wlc) +void brcms_c_send_q(struct brcms_c_info *wlc) { struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; int prec; u16 prec_map; int err = 0, i, count; uint fifo; - struct wlc_txq_info *qi = wlc->pkt_queue; + struct brcms_txq_info *qi = wlc->pkt_queue; struct pktq *q = &qi->q; struct ieee80211_tx_info *tx_info; @@ -4733,22 +3236,23 @@ void wlc_send_q(struct wlc_info *wlc) /* Send all the enq'd pkts that we can. * Dequeue packets with precedence with empty HW fifo only */ - while (prec_map && (pkt[0] = bcm_pktq_mdeq(q, prec_map, &prec))) { + while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) { tx_info = IEEE80211_SKB_CB(pkt[0]); if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec); + err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec); } else { count = 1; - err = wlc_prep_pdu(wlc, pkt[0], &fifo); + err = brcms_c_prep_pdu(wlc, pkt[0], &fifo); if (!err) { for (i = 0; i < count; i++) { - wlc_txfifo(wlc, fifo, pkt[i], true, 1); + brcms_c_txfifo(wlc, fifo, pkt[i], true, + 1); } } } if (err == -EBUSY) { - bcm_pktq_penq_head(q, prec, pkt[0]); + brcmu_pktq_penq_head(q, prec, pkt[0]); /* If send failed due to any other reason than a change in * HW FIFO condition, quit. Otherwise, read the new prec_map! */ @@ -4761,17 +3265,17 @@ void wlc_send_q(struct wlc_info *wlc) /* Check if flow control needs to be turned off after sending the packet */ if (!EDCF_ENAB(wlc->pub) || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { - if (wlc_txflowcontrol_prio_isset(wlc, qi, ALLPRIO) + if (brcms_c_txflowcontrol_prio_isset(wlc, qi, ALLPRIO) && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) { - wlc_txflowcontrol(wlc, qi, OFF, ALLPRIO); + brcms_c_txflowcontrol(wlc, qi, OFF, ALLPRIO); } } else if (wlc->pub->_priofc) { int prio; for (prio = MAXPRIO; prio >= 0; prio--) { - if (wlc_txflowcontrol_prio_isset(wlc, qi, prio) && + if (brcms_c_txflowcontrol_prio_isset(wlc, qi, prio) && (pktq_plen(q, wlc_prio2prec_map[prio]) < wlc->pub->tunables->datahiwat / 2)) { - wlc_txflowcontrol(wlc, qi, OFF, prio); + brcms_c_txflowcontrol(wlc, qi, OFF, prio); } } } @@ -4784,8 +3288,8 @@ void wlc_send_q(struct wlc_info *wlc) * for MC frames so is used as part of the sequence number. */ static inline u16 -bcmc_fid_generate(struct wlc_info *wlc, struct wlc_bsscfg *bsscfg, - d11txh_t *txh) +bcmc_fid_generate(struct brcms_c_info *wlc, struct brcms_bss_cfg *bsscfg, + struct d11txh *txh) { u16 frameid; @@ -4800,13 +3304,13 @@ bcmc_fid_generate(struct wlc_info *wlc, struct wlc_bsscfg *bsscfg, } void -wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, - s8 txpktpend) +brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p, + bool commit, s8 txpktpend) { u16 frameid = INVALIDFID; - d11txh_t *txh; + struct d11txh *txh; - txh = (d11txh_t *) (p->data); + txh = (struct d11txh *) (p->data); /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update * ucode or BSS info as appropriate. @@ -4816,12 +3320,12 @@ wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, } - if (WLC_WAR16165(wlc)) - wlc_war16165(wlc, true); + if (BRCMS_WAR16165(wlc)) + brcms_c_war16165(wlc, true); /* Bump up pending count for if not using rpc. If rpc is used, this will be handled - * in wlc_bmac_txfifo() + * in brcms_b_txfifo() */ if (commit) { TXPKTPENDINC(wlc, fifo, txpktpend); @@ -4834,31 +3338,32 @@ wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, BCMCFID(wlc, frameid); if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) { - wiphy_err(wlc->wiphy, "wlc_txfifo: fatal, toss frames !!!\n"); + wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n"); } } void -wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp) +brcms_c_compute_plcp(struct brcms_c_info *wlc, ratespec_t rspec, + uint length, u8 *plcp) { if (IS_MCS(rspec)) { - wlc_compute_mimo_plcp(rspec, length, plcp); + brcms_c_compute_mimo_plcp(rspec, length, plcp); } else if (IS_OFDM(rspec)) { - wlc_compute_ofdm_plcp(rspec, length, plcp); + brcms_c_compute_ofdm_plcp(rspec, length, plcp); } else { - wlc_compute_cck_plcp(wlc, rspec, length, plcp); + brcms_c_compute_cck_plcp(wlc, rspec, length, plcp); } return; } /* Rate: 802.11 rate code, length: PSDU length in octets */ -static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp) +static void brcms_c_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp) { u8 mcs = (u8) (rspec & RSPEC_RATE_MASK); plcp[0] = mcs; if (RSPEC_IS40MHZ(rspec) || (mcs == 32)) plcp[0] |= MIMO_PLCP_40MHZ; - WLC_SET_MIMO_PLCP_LEN(plcp, length); + BRCMS_SET_MIMO_PLCP_LEN(plcp, length); plcp[3] = RSPEC_MIMOPLCP3(rspec); /* rspec already holds this byte */ plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */ plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */ @@ -4867,16 +3372,16 @@ static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp) /* Rate: 802.11 rate code, length: PSDU length in octets */ static void -wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) +brcms_c_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) { u8 rate_signal; u32 tmp = 0; int rate = RSPEC2RATE(rspec); /* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */ - rate_signal = rate_info[rate] & WLC_RATE_MASK; + rate_signal = rate_info[rate] & BRCMS_RATE_MASK; memset(plcp, 0, D11_PHY_HDR_LEN); - D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal); + D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal); tmp = (length & 0xfff) << 5; plcp[2] |= (tmp >> 16) & 0xff; @@ -4893,25 +3398,25 @@ wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) * Broken out for PRQ. */ -static void wlc_cck_plcp_set(struct wlc_info *wlc, int rate_500, uint length, - u8 *plcp) +static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500, + uint length, u8 *plcp) { u16 usec = 0; u8 le = 0; switch (rate_500) { - case WLC_RATE_1M: + case BRCM_RATE_1M: usec = length << 3; break; - case WLC_RATE_2M: + case BRCM_RATE_2M: usec = length << 2; break; - case WLC_RATE_5M5: + case BRCM_RATE_5M5: usec = (length << 4) / 11; if ((length << 4) - (usec * 11) > 0) usec++; break; - case WLC_RATE_11M: + case BRCM_RATE_11M: usec = (length << 3) / 11; if ((length << 3) - (usec * 11) > 0) { usec++; @@ -4921,9 +3426,9 @@ static void wlc_cck_plcp_set(struct wlc_info *wlc, int rate_500, uint length, break; default: - wiphy_err(wlc->wiphy, "wlc_cck_plcp_set: unsupported rate %d" + wiphy_err(wlc->wiphy, "brcms_c_cck_plcp_set: unsupported rate %d" "\n", rate_500); - rate_500 = WLC_RATE_1M; + rate_500 = BRCM_RATE_1M; usec = length << 3; break; } @@ -4940,15 +3445,15 @@ static void wlc_cck_plcp_set(struct wlc_info *wlc, int rate_500, uint length, } /* Rate: 802.11 rate code, length: PSDU length in octets */ -static void wlc_compute_cck_plcp(struct wlc_info *wlc, ratespec_t rspec, +static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, ratespec_t rspec, uint length, u8 *plcp) { int rate = RSPEC2RATE(rspec); - wlc_cck_plcp_set(wlc, rate, length, plcp); + brcms_c_cck_plcp_set(wlc, rate, length, plcp); } -/* wlc_compute_frame_dur() +/* brcms_c_compute_frame_dur() * * Calculate the 802.11 MAC header DUR field for MPDU * DUR for a single frame = 1 SIFS + 1 ACK @@ -4959,15 +3464,15 @@ static void wlc_compute_cck_plcp(struct wlc_info *wlc, ratespec_t rspec, * preamble_type use short/GF or long/MM PLCP header */ static u16 -wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, - uint next_frag_len) +brcms_c_compute_frame_dur(struct brcms_c_info *wlc, ratespec_t rate, + u8 preamble_type, uint next_frag_len) { u16 dur, sifs; sifs = SIFS(wlc->band); dur = sifs; - dur += (u16) wlc_calc_ack_time(wlc, rate, preamble_type); + dur += (u16) brcms_c_calc_ack_time(wlc, rate, preamble_type); if (next_frag_len) { /* Double the current DUR to get 2 SIFS + 2 ACKs */ @@ -4975,13 +3480,13 @@ wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, /* add another SIFS and the frag time */ dur += sifs; dur += - (u16) wlc_calc_frame_time(wlc, rate, preamble_type, + (u16) brcms_c_calc_frame_time(wlc, rate, preamble_type, next_frag_len); } return dur; } -/* wlc_compute_rtscts_dur() +/* brcms_c_compute_rtscts_dur() * * Calculate the 802.11 MAC header DUR field for an RTS or CTS frame * DUR for normal RTS/CTS w/ frame = 3 SIFS + 1 CTS + next frame time + 1 ACK @@ -4993,9 +3498,10 @@ wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, * frame_len next MPDU frame length in bytes */ u16 -wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate, - ratespec_t frame_rate, u8 rts_preamble_type, - u8 frame_preamble_type, uint frame_len, bool ba) +brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only, + ratespec_t rts_rate, + ratespec_t frame_rate, u8 rts_preamble_type, + u8 frame_preamble_type, uint frame_len, bool ba) { u16 dur, sifs; @@ -5004,38 +3510,38 @@ wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate, if (!cts_only) { /* RTS/CTS */ dur = 3 * sifs; dur += - (u16) wlc_calc_cts_time(wlc, rts_rate, + (u16) brcms_c_calc_cts_time(wlc, rts_rate, rts_preamble_type); } else { /* CTS-TO-SELF */ dur = 2 * sifs; } dur += - (u16) wlc_calc_frame_time(wlc, frame_rate, frame_preamble_type, + (u16) brcms_c_calc_frame_time(wlc, frame_rate, frame_preamble_type, frame_len); if (ba) dur += - (u16) wlc_calc_ba_time(wlc, frame_rate, - WLC_SHORT_PREAMBLE); + (u16) brcms_c_calc_ba_time(wlc, frame_rate, + BRCMS_SHORT_PREAMBLE); else dur += - (u16) wlc_calc_ack_time(wlc, frame_rate, + (u16) brcms_c_calc_ack_time(wlc, frame_rate, frame_preamble_type); return dur; } -u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) +u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, ratespec_t rspec) { u16 phyctl1 = 0; u16 bw; - if (WLCISLCNPHY(wlc->band)) { + if (BRCMS_ISLCNPHY(wlc->band)) { bw = PHY_TXC1_BW_20MHZ; } else { bw = RSPEC_GET_BW(rspec); /* 10Mhz is not supported yet */ if (bw < PHY_TXC1_BW_20MHZ) { - wiphy_err(wlc->wiphy, "wlc_phytxctl1_calc: bw %d is " + wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is " "not supported yet, set to 20L\n", bw); bw = PHY_TXC1_BW_20MHZ; } @@ -5048,8 +3554,8 @@ u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) phyctl1 = RSPEC_PHYTXBYTE2(rspec); /* set the upper byte of phyctl1 */ phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8); - } else if (IS_CCK(rspec) && !WLCISLCNPHY(wlc->band) - && !WLCISSSLPNPHY(wlc->band)) { + } else if (IS_CCK(rspec) && !BRCMS_ISLCNPHY(wlc->band) + && !BRCMS_ISSSLPNPHY(wlc->band)) { /* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ /* Eventually MIMOPHY would also be converted to this format */ /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ @@ -5057,9 +3563,9 @@ u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) } else { /* legacy OFDM/CCK */ s16 phycfg; /* get the phyctl byte from rate phycfg table */ - phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec)); + phycfg = brcms_c_rate_legacy_phyctl(RSPEC2RATE(rspec)); if (phycfg == -1) { - wiphy_err(wlc->wiphy, "wlc_phytxctl1_calc: wrong " + wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong " "legacy OFDM/CCK rate\n"); phycfg = 0; } @@ -5072,8 +3578,8 @@ u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) } ratespec_t -wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, - u16 mimo_ctlchbw) +brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, ratespec_t rspec, + bool use_rspec, u16 mimo_ctlchbw) { ratespec_t rts_rspec = 0; @@ -5083,21 +3589,21 @@ wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, } else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) { /* Use 11Mbps as the g protection RTS target rate and fallback. - * Use the WLC_BASIC_RATE() lookup to find the best basic rate under the - * target in case 11 Mbps is not Basic. + * Use the BRCMS_BASIC_RATE() lookup to find the best basic rate + * under the target in case 11 Mbps is not Basic. * 6 and 9 Mbps are not usually selected by rate selection, but even * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust. */ - rts_rspec = WLC_BASIC_RATE(wlc, WLC_RATE_11M); + rts_rspec = BRCMS_BASIC_RATE(wlc, BRCM_RATE_11M); } else { /* calculate RTS rate and fallback rate based on the frame rate * RTS must be sent at a basic rate since it is a * control frame, sec 9.6 of 802.11 spec */ - rts_rspec = WLC_BASIC_RATE(wlc, rspec); + rts_rspec = BRCMS_BASIC_RATE(wlc, rspec); } - if (WLC_PHY_11N_CAP(wlc->band)) { + if (BRCMS_PHY_11N_CAP(wlc->band)) { /* set rts txbw to correct side band */ rts_rspec &= ~RSPEC_BW_MASK; @@ -5119,7 +3625,7 @@ wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, } /* - * Add d11txh_t, cck_phy_hdr_t. + * Add struct d11txh, struct cck_phy_hdr. * * 'p' data must start with 802.11 MAC header * 'p' must allow enough bytes of local headers to be "pushed" onto the packet @@ -5128,25 +3634,25 @@ wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, * */ static u16 -wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, +brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, struct sk_buff *p, struct scb *scb, uint frag, uint nfrags, uint queue, uint next_frag_len, - wsec_key_t *key, ratespec_t rspec_override) + struct wsec_key *key, ratespec_t rspec_override) { struct ieee80211_hdr *h; - d11txh_t *txh; + struct d11txh *txh; u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; int len, phylen, rts_phylen; u16 mch, phyctl, xfts, mainrates; u16 seq = 0, mcl = 0, status = 0, frameid = 0; - ratespec_t rspec[2] = { WLC_RATE_1M, WLC_RATE_1M }, rts_rspec[2] = { - WLC_RATE_1M, WLC_RATE_1M}; + ratespec_t rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M }, rts_rspec[2] = { + BRCM_RATE_1M, BRCM_RATE_1M}; bool use_rts = false; bool use_cts = false; bool use_rifs = false; bool short_preamble[2] = { false, false }; - u8 preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; - u8 rts_preamble_type[2] = { WLC_LONG_PREAMBLE, WLC_LONG_PREAMBLE }; + u8 preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE }; + u8 rts_preamble_type[2] = { BRCMS_LONG_PREAMBLE, BRCMS_LONG_PREAMBLE }; u8 *rts_plcp, rts_plcp_fallback[D11_PHY_HDR_LEN]; struct ieee80211_rts *rts = NULL; bool qos; @@ -5171,7 +3677,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, qos = ieee80211_is_data_qos(h->frame_control); /* compute length of frame in bytes for use in PLCP computations */ - len = bcm_pkttotlen(p); + len = brcmu_pkttotlen(p); phylen = len + FCS_LEN; /* If WEP enabled, add room in phylen for the additional bytes of @@ -5190,7 +3696,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, plcp = skb_push(p, D11_PHY_HDR_LEN); /* add Broadcom tx descriptor header */ - txh = (d11txh_t *) skb_push(p, D11_TXH_LEN); + txh = (struct d11txh *) skb_push(p, D11_TXH_LEN); memset(txh, 0, D11_TXH_LEN); /* setup frameid */ @@ -5198,7 +3704,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* non-AP STA should never use BCMC queue */ if (queue == TX_BCMC_FIFO) { wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == " - "TX_BCMC!\n", WLCWLUNIT(wlc), __func__); + "TX_BCMC!\n", BRCMS_UNIT(wlc), __func__); frameid = bcmc_fid_generate(wlc, NULL, txh); } else { /* Increment the counter for first fragment */ @@ -5244,7 +3750,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ? true : false; } else { - rate_val[k] = WLC_RATE_1M; + rate_val[k] = BRCM_RATE_1M; } } else { rate_val[k] = txrate[k]->idx; @@ -5266,12 +3772,12 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* (1) RATE: determine and validate primary rate and fallback rates */ if (!RSPEC_ACTIVE(rspec[k])) { - rspec[k] = WLC_RATE_1M; + rspec[k] = BRCM_RATE_1M; } else { if (!is_multicast_ether_addr(h->addr1)) { /* set tx antenna config */ - wlc_antsel_antcfg_get(wlc->asi, false, false, 0, - 0, &antcfg, &fbantcfg); + brcms_c_antsel_antcfg_get(wlc->asi, false, + false, 0, 0, &antcfg, &fbantcfg); } } } @@ -5290,7 +3796,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* For SISO MCS use STBC if possible */ if (IS_MCS(rspec[k]) - && WLC_STF_SS_STBC_TX(wlc, scb)) { + && BRCMS_STF_SS_STBC_TX(wlc, scb)) { u8 stc; stc = 1; /* Nss for single stream is always 1 */ @@ -5304,11 +3810,11 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, } /* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */ - if (CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ) { + if (CHSPEC_WLC_BW(wlc->chanspec) == BRCMS_40_MHZ) { /* default txbw is 20in40 SB */ mimo_ctlchbw = mimo_txbw = - CHSPEC_SB_UPPER(WLC_BAND_PI_RADIO_CHANSPEC) - ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; + CHSPEC_SB_UPPER(BRCMS_BAND_PI_RADIO_CHANSPEC) + ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; if (IS_MCS(rspec[k])) { /* mcs 32 must be 40b/w DUP */ @@ -5357,15 +3863,15 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, rspec[k] &= ~RSPEC_SHORT_GI; #endif - mimo_preamble_type = WLC_MM_PREAMBLE; + mimo_preamble_type = BRCMS_MM_PREAMBLE; if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD) - mimo_preamble_type = WLC_GF_PREAMBLE; + mimo_preamble_type = BRCMS_GF_PREAMBLE; if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) && (!IS_MCS(rspec[k]))) { wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_" "RC_MCS != IS_MCS(rspec)\n", - WLCWLUNIT(wlc), __func__); + BRCMS_UNIT(wlc), __func__); } if (IS_MCS(rspec[k])) { @@ -5375,7 +3881,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if ((rspec[k] & RSPEC_SHORT_GI) && IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) { - preamble_type[k] = WLC_MM_PREAMBLE; + preamble_type[k] = BRCMS_MM_PREAMBLE; } } @@ -5383,7 +3889,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (!IS_MCS(rspec[0]) && (tx_info->control.rates[0]. flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) - preamble_type[k] = WLC_SHORT_PREAMBLE; + preamble_type[k] = BRCMS_SHORT_PREAMBLE; } } else { for (k = 0; k < hw->max_rates; k++) { @@ -5392,7 +3898,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT); /* for nphy, stf of ofdm frames must follow policies */ - if (WLCISNPHY(wlc->band) && IS_OFDM(rspec[k])) { + if (BRCMS_ISNPHY(wlc->band) && IS_OFDM(rspec[k])) { rspec[k] &= ~RSPEC_STF_MASK; rspec[k] |= phyctl1_stf << RSPEC_STF_SHIFT; } @@ -5409,9 +3915,10 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, (phylen > wlc->RTSThresh) && !is_multicast_ether_addr(h->addr1)) use_rts = true; - /* (3) PLCP: determine PLCP header and MAC duration, fill d11txh_t */ - wlc_compute_plcp(wlc, rspec[0], phylen, plcp); - wlc_compute_plcp(wlc, rspec[1], phylen, plcp_fallback); + /* (3) PLCP: determine PLCP header and MAC duration, + * fill struct d11txh */ + brcms_c_compute_plcp(wlc, rspec[0], phylen, plcp); + brcms_c_compute_plcp(wlc, rspec[1], phylen, plcp_fallback); memcpy(&txh->FragPLCPFallback, plcp_fallback, sizeof(txh->FragPLCPFallback)); @@ -5422,21 +3929,21 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, } /* MIMO-RATE: need validation ?? */ - mainrates = - IS_OFDM(rspec[0]) ? D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) plcp) : - plcp[0]; + mainrates = IS_OFDM(rspec[0]) ? + D11A_PHY_HDR_GRATE((struct ofdm_phy_hdr *) plcp) : + plcp[0]; /* DUR field for main rate */ if (!ieee80211_is_pspoll(h->frame_control) && !is_multicast_ether_addr(h->addr1) && !use_rifs) { durid = - wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0], + brcms_c_compute_frame_dur(wlc, rspec[0], preamble_type[0], next_frag_len); h->duration_id = cpu_to_le16(durid); } else if (use_rifs) { /* NAV protect to end of next max packet size */ durid = - (u16) wlc_calc_frame_time(wlc, rspec[0], + (u16) brcms_c_calc_frame_time(wlc, rspec[0], preamble_type[0], DOT11_MAX_FRAG_LEN); durid += RIFS_11N_TIME; @@ -5449,7 +3956,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, else if (is_multicast_ether_addr(h->addr1) || use_rifs) txh->FragDurFallback = 0; else { - durid = wlc_compute_frame_dur(wlc, rspec[1], + durid = brcms_c_compute_frame_dur(wlc, rspec[1], preamble_type[1], next_frag_len); txh->FragDurFallback = cpu_to_le16(durid); } @@ -5464,7 +3971,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (BAND_5G(wlc->band->bandtype)) mcl |= TXC_FREQBAND_5G; - if (CHSPEC_IS40(WLC_BAND_PI_RADIO_CHANSPEC)) + if (CHSPEC_IS40(BRCMS_BAND_PI_RADIO_CHANSPEC)) mcl |= TXC_BW_40; /* set AMIC bit if using hardware TKIP MIC */ @@ -5477,9 +3984,9 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, mch = 0; /* Set fallback rate preamble type */ - if ((preamble_type[1] == WLC_SHORT_PREAMBLE) || - (preamble_type[1] == WLC_GF_PREAMBLE)) { - if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M) + if ((preamble_type[1] == BRCMS_SHORT_PREAMBLE) || + (preamble_type[1] == BRCMS_GF_PREAMBLE)) { + if (RSPEC2RATE(rspec[1]) != BRCM_RATE_1M) mch |= TXC_PREAMBLE_DATA_FB_SHORT; } @@ -5508,29 +4015,30 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, txh->MaxABytes_FBR = cpu_to_le16(0); txh->MinMBytes = cpu_to_le16(0); - /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, furnish d11txh_t */ + /* (5) RTS/CTS: determine RTS/CTS PLCP header and MAC duration, + * furnish struct d11txh */ /* RTS PLCP header and RTS frame */ if (use_rts || use_cts) { if (use_rts && use_cts) use_cts = false; for (k = 0; k < 2; k++) { - rts_rspec[k] = wlc_rspec_to_rts_rspec(wlc, rspec[k], + rts_rspec[k] = brcms_c_rspec_to_rts_rspec(wlc, rspec[k], false, mimo_ctlchbw); } if (!IS_OFDM(rts_rspec[0]) && - !((RSPEC2RATE(rts_rspec[0]) == WLC_RATE_1M) || - (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { - rts_preamble_type[0] = WLC_SHORT_PREAMBLE; + !((RSPEC2RATE(rts_rspec[0]) == BRCM_RATE_1M) || + (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) { + rts_preamble_type[0] = BRCMS_SHORT_PREAMBLE; mch |= TXC_PREAMBLE_RTS_MAIN_SHORT; } if (!IS_OFDM(rts_rspec[1]) && - !((RSPEC2RATE(rts_rspec[1]) == WLC_RATE_1M) || - (wlc->PLCPHdr_override == WLC_PLCP_LONG))) { - rts_preamble_type[1] = WLC_SHORT_PREAMBLE; + !((RSPEC2RATE(rts_rspec[1]) == BRCM_RATE_1M) || + (wlc->PLCPHdr_override == BRCMS_PLCP_LONG))) { + rts_preamble_type[1] = BRCMS_SHORT_PREAMBLE; mch |= TXC_PREAMBLE_RTS_FB_SHORT; } @@ -5549,10 +4057,10 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, else rts_phylen = DOT11_RTS_LEN + FCS_LEN; - wlc_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp); + brcms_c_compute_plcp(wlc, rts_rspec[0], rts_phylen, rts_plcp); /* fallback rate version of RTS PLCP header */ - wlc_compute_plcp(wlc, rts_rspec[1], rts_phylen, + brcms_c_compute_plcp(wlc, rts_rspec[1], rts_phylen, rts_plcp_fallback); memcpy(&txh->RTSPLCPFallback, rts_plcp_fallback, sizeof(txh->RTSPLCPFallback)); @@ -5560,12 +4068,12 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* RTS frame fields... */ rts = (struct ieee80211_rts *)&txh->rts_frame; - durid = wlc_compute_rtscts_dur(wlc, use_cts, rts_rspec[0], + durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec[0], rspec[0], rts_preamble_type[0], preamble_type[0], phylen, false); rts->duration = cpu_to_le16(durid); /* fallback rate version of RTS DUR field */ - durid = wlc_compute_rtscts_dur(wlc, use_cts, + durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec[1], rspec[1], rts_preamble_type[1], preamble_type[1], phylen, false); @@ -5588,8 +4096,9 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, * high 8 bits: rts/cts rate/mcs */ mainrates |= (IS_OFDM(rts_rspec[0]) ? - D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) rts_plcp) : - rts_plcp[0]) << 8; + D11A_PHY_HDR_GRATE( + (struct ofdm_phy_hdr *) rts_plcp) : + rts_plcp[0]) << 8; } else { memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN); memset((char *)&txh->rts_frame, 0, @@ -5603,7 +4112,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* add null delimiter count */ if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) { txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = - wlc_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen); + brcm_c_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen); } #endif @@ -5618,34 +4127,34 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, xfts |= (FRAMETYPE(rts_rspec[0], wlc->mimoft) << XFTS_RTS_FT_SHIFT); xfts |= (FRAMETYPE(rts_rspec[1], wlc->mimoft) << XFTS_FBRRTS_FT_SHIFT); xfts |= - CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT; + CHSPEC_CHANNEL(BRCMS_BAND_PI_RADIO_CHANSPEC) << XFTS_CHANNEL_SHIFT; txh->XtraFrameTypes = cpu_to_le16(xfts); /* PhyTxControlWord */ phyctl = FRAMETYPE(rspec[0], wlc->mimoft); - if ((preamble_type[0] == WLC_SHORT_PREAMBLE) || - (preamble_type[0] == WLC_GF_PREAMBLE)) { - if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M) + if ((preamble_type[0] == BRCMS_SHORT_PREAMBLE) || + (preamble_type[0] == BRCMS_GF_PREAMBLE)) { + if (RSPEC2RATE(rspec[0]) != BRCM_RATE_1M) phyctl |= PHY_TXC_SHORT_HDR; } /* phytxant is properly bit shifted */ - phyctl |= wlc_stf_d11hdrs_phyctl_txant(wlc, rspec[0]); + phyctl |= brcms_c_stf_d11hdrs_phyctl_txant(wlc, rspec[0]); txh->PhyTxControlWord = cpu_to_le16(phyctl); /* PhyTxControlWord_1 */ - if (WLC_PHY_11N_CAP(wlc->band)) { + if (BRCMS_PHY_11N_CAP(wlc->band)) { u16 phyctl1 = 0; - phyctl1 = wlc_phytxctl1_calc(wlc, rspec[0]); + phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[0]); txh->PhyTxControlWord_1 = cpu_to_le16(phyctl1); - phyctl1 = wlc_phytxctl1_calc(wlc, rspec[1]); + phyctl1 = brcms_c_phytxctl1_calc(wlc, rspec[1]); txh->PhyTxControlWord_1_Fbr = cpu_to_le16(phyctl1); if (use_rts || use_cts) { - phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[0]); + phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[0]); txh->PhyTxControlWord_1_Rts = cpu_to_le16(phyctl1); - phyctl1 = wlc_phytxctl1_calc(wlc, rts_rspec[1]); + phyctl1 = brcms_c_phytxctl1_calc(wlc, rts_rspec[1]); txh->PhyTxControlWord_1_FbrRts = cpu_to_le16(phyctl1); } @@ -5654,15 +4163,17 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, * fill in non-zero MModeLen and/or MModeFbrLen * it will be unnecessary if they are separated */ - if (IS_MCS(rspec[0]) && (preamble_type[0] == WLC_MM_PREAMBLE)) { + if (IS_MCS(rspec[0]) && + (preamble_type[0] == BRCMS_MM_PREAMBLE)) { u16 mmodelen = - wlc_calc_lsig_len(wlc, rspec[0], phylen); + brcms_c_calc_lsig_len(wlc, rspec[0], phylen); txh->MModeLen = cpu_to_le16(mmodelen); } - if (IS_MCS(rspec[1]) && (preamble_type[1] == WLC_MM_PREAMBLE)) { + if (IS_MCS(rspec[1]) && + (preamble_type[1] == BRCMS_MM_PREAMBLE)) { u16 mmodefbrlen = - wlc_calc_lsig_len(wlc, rspec[1], phylen); + brcms_c_calc_lsig_len(wlc, rspec[1], phylen); txh->MModeFbrLen = cpu_to_le16(mmodefbrlen); } } @@ -5674,16 +4185,16 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* WME: Update TXOP threshold */ if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) { frag_dur = - wlc_calc_frame_time(wlc, rspec[0], preamble_type[0], - phylen); + brcms_c_calc_frame_time(wlc, rspec[0], + preamble_type[0], phylen); if (rts) { /* 1 RTS or CTS-to-self frame */ dur = - wlc_calc_cts_time(wlc, rts_rspec[0], + brcms_c_calc_cts_time(wlc, rts_rspec[0], rts_preamble_type[0]); dur_fallback = - wlc_calc_cts_time(wlc, rts_rspec[1], + brcms_c_calc_cts_time(wlc, rts_rspec[1], rts_preamble_type[1]); /* (SIFS + CTS) + SIFS + frame + SIFS + ACK */ dur += le16_to_cpu(rts->duration); @@ -5696,15 +4207,15 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* frame + SIFS + ACK */ dur = frag_dur; dur += - wlc_compute_frame_dur(wlc, rspec[0], + brcms_c_compute_frame_dur(wlc, rspec[0], preamble_type[0], 0); dur_fallback = - wlc_calc_frame_time(wlc, rspec[1], + brcms_c_calc_frame_time(wlc, rspec[1], preamble_type[1], phylen); dur_fallback += - wlc_compute_frame_dur(wlc, rspec[1], + brcms_c_compute_frame_dur(wlc, rspec[1], preamble_type[1], 0); } /* NEED to set TxFesTimeNormal (hard) */ @@ -5719,12 +4230,10 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, uint newfragthresh; newfragthresh = - wlc_calc_frame_len(wlc, rspec[0], - preamble_type[0], - (wlc-> - edcf_txop[ac] - - (dur - - frag_dur))); + brcms_c_calc_frame_len(wlc, + rspec[0], preamble_type[0], + (wlc->edcf_txop[ac] - + (dur - frag_dur))); /* range bound the fragthreshold */ if (newfragthresh < DOT11_MIN_FRAG_LEN) newfragthresh = @@ -5759,32 +4268,9 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, return 0; } -void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) +void brcms_c_tbtt(struct brcms_c_info *wlc) { - struct wlc_bsscfg *cfg = wlc->cfg; - - if (BSSCFG_STA(cfg)) { - /* run watchdog here if the watchdog timer is not armed */ - if (WLC_WATCHDOG_TBTT(wlc)) { - u32 cur, delta; - if (wlc->WDarmed) { - wl_del_timer(wlc->wl, wlc->wdtimer); - wlc->WDarmed = false; - } - - cur = OSL_SYSUPTIME(); - delta = cur > wlc->WDlast ? cur - wlc->WDlast : - (u32) ~0 - wlc->WDlast + cur + 1; - if (delta >= TIMER_INTERVAL_WATCHDOG) { - wlc_watchdog((void *)wlc); - wlc->WDlast = cur; - } - - wl_add_timer(wlc->wl, wlc->wdtimer, - wlc_watchdog_backup_bi(wlc), true); - wlc->WDarmed = true; - } - } + struct brcms_bss_cfg *cfg = wlc->cfg; if (!cfg->BSS) { /* DirFrmQ is now valid...defer setting until end of ATIM window */ @@ -5792,27 +4278,26 @@ void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) } } -static void wlc_war16165(struct wlc_info *wlc, bool tx) +static void brcms_c_war16165(struct brcms_c_info *wlc, bool tx) { if (tx) { /* the post-increment is used in STAY_AWAKE macro */ if (wlc->txpend16165war++ == 0) - wlc_set_ps_ctrl(wlc); + brcms_c_set_ps_ctrl(wlc); } else { wlc->txpend16165war--; if (wlc->txpend16165war == 0) - wlc_set_ps_ctrl(wlc); + brcms_c_set_ps_ctrl(wlc); } } -/* process an individual tx_status_t */ -/* WLC_HIGH_API */ +/* process an individual struct tx_status */ bool -wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) +brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs, u32 frm_tx2) { struct sk_buff *p; uint queue; - d11txh_t *txh; + struct d11txh *txh; struct scb *scb = NULL; bool free_pdu; int tx_rts, tx_frame_count, tx_rts_count; @@ -5845,21 +4330,21 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) } p = GETNEXTTXP(wlc, queue); - if (WLC_WAR16165(wlc)) - wlc_war16165(wlc, false); + if (BRCMS_WAR16165(wlc)) + brcms_c_war16165(wlc, false); if (p == NULL) goto fatal; - txh = (d11txh_t *) (p->data); + txh = (struct d11txh *) (p->data); mcl = le16_to_cpu(txh->MacTxControlLow); if (txs->phyerr) { if (WL_ERROR_ON()) { wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n", txs->phyerr, txh->MainRates); - wlc_print_txdesc(txh); + brcms_c_print_txdesc(txh); } - wlc_print_txstatus(txs); + brcms_c_print_txstatus(txs); } if (txs->frameid != cpu_to_le16(txh->TxFrameID)) @@ -5871,7 +4356,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) scb = (struct scb *)tx_info->control.sta->drv_priv; if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { - wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); + brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); return false; } @@ -5892,25 +4377,41 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) if (!lastframe) { wiphy_err(wlc->wiphy, "Not last frame!\n"); } else { - u16 sfbl, lfbl; - ieee80211_tx_info_clear_status(tx_info); + /* + * Set information to be consumed by Minstrel ht. + * + * The "fallback limit" is the number of tx attempts a given + * MPDU is sent at the "primary" rate. Tx attempts beyond that + * limit are sent at the "secondary" rate. + * A 'short frame' does not exceed RTS treshold. + */ + u16 sfbl, /* Short Frame Rate Fallback Limit */ + lfbl, /* Long Frame Rate Fallback Limit */ + fbl; + if (queue < AC_COUNT) { - sfbl = WLC_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]); - lfbl = WLC_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]); + sfbl = BRCMS_WME_RETRY_SFB_GET(wlc, wme_fifo2ac[queue]); + lfbl = BRCMS_WME_RETRY_LFB_GET(wlc, wme_fifo2ac[queue]); } else { sfbl = wlc->SFBL; lfbl = wlc->LFBL; } txrate = tx_info->status.rates; - /* FIXME: this should use a combination of sfbl, lfbl depending on frame length and RTS setting */ - if ((tx_frame_count > sfbl) && (txrate[1].idx >= 0)) { + if (txrate[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) + fbl = lfbl; + else + fbl = sfbl; + + ieee80211_tx_info_clear_status(tx_info); + + if ((tx_frame_count > fbl) && (txrate[1].idx >= 0)) { /* rate selection requested a fallback rate and we used it */ - txrate->count = lfbl; - txrate[1].count = tx_frame_count - lfbl; + txrate[0].count = fbl; + txrate[1].count = tx_frame_count - fbl; } else { /* rate selection did not request fallback rate, or we didn't need it */ - txrate->count = tx_frame_count; + txrate[0].count = tx_frame_count; /* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */ txrate[1].idx = -1; txrate[1].count = 0; @@ -5926,15 +4427,14 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) tx_info->flags |= IEEE80211_TX_STAT_ACK; } - totlen = bcm_pkttotlen(p); + totlen = brcmu_pkttotlen(p); free_pdu = true; - wlc_txfifo_complete(wlc, queue, 1); + brcms_c_txfifo_complete(wlc, queue, 1); if (lastframe) { p->next = NULL; p->prev = NULL; - wlc->txretried = 0; /* remove PLCP & Broadcom tx descriptor header */ skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_TXH_LEN); @@ -5948,48 +4448,42 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) fatal: if (p) - bcm_pkt_buf_free_skb(p); + brcmu_pkt_buf_free_skb(p); return true; } void -wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend) +brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend) { TXPKTPENDDEC(wlc, fifo, txpktpend); BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend, TXPKTPENDGET(wlc, fifo)); /* There is more room; mark precedences related to this FIFO sendable */ - WLC_TX_FIFO_ENAB(wlc, fifo); - - if (!TXPKTPENDTOT(wlc)) { - if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR) - wlc_bsscfg_tx_check(wlc); - } + BRCMS_TX_FIFO_ENAB(wlc, fifo); /* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */ if (AP_ENAB(wlc->pub) && - wlc->bcmcfifo_drain && !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) { - wlc->bcmcfifo_drain = false; - wlc_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, WLC_BAND_AUTO); + !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) { + brcms_c_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, BRCM_BAND_AUTO); } /* figure out which bsscfg is being worked on... */ } /* Update beacon listen interval in shared memory */ -void wlc_bcn_li_upd(struct wlc_info *wlc) +void brcms_c_bcn_li_upd(struct brcms_c_info *wlc) { if (AP_ENAB(wlc->pub)) return; /* wake up every DTIM is the default */ if (wlc->bcn_li_dtim == 1) - wlc_write_shm(wlc, M_BCN_LI, 0); + brcms_c_write_shm(wlc, M_BCN_LI, 0); else - wlc_write_shm(wlc, M_BCN_LI, + brcms_c_write_shm(wlc, M_BCN_LI, (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn); } @@ -6003,16 +4497,17 @@ void wlc_bcn_li_upd(struct wlc_info *wlc) * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->| * * The RxTSFTime are the lowest 16 bits and provided by the ucode. The - * tsf_l is filled in by wlc_bmac_recv, which is done earlier in the + * tsf_l is filled in by brcms_b_recv, which is done earlier in the * receive call sequence after rx interrupt. Only the higher 16 bits * are used. Finally, the tsf_h is read from the tsf register. */ -static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh) +static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc, + struct brcms_d11rxhdr *rxh) { u32 tsf_h, tsf_l; u16 rx_tsf_0_15, rx_tsf_16_31; - wlc_bmac_read_tsf(wlc->hw, &tsf_l, &tsf_h); + brcms_b_read_tsf(wlc->hw, &tsf_l, &tsf_h); rx_tsf_16_31 = (u16)(tsf_l >> 16); rx_tsf_0_15 = rxh->rxhdr.RxTSFTime; @@ -6031,20 +4526,21 @@ static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh) } static void -prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, +prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, + struct sk_buff *p, struct ieee80211_rx_status *rx_status) { - wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh; + struct brcms_d11rxhdr *wlc_rxh = (struct brcms_d11rxhdr *) rxh; int preamble; int channel; ratespec_t rspec; unsigned char *plcp; /* fill in TSF and flag its presence */ - rx_status->mactime = wlc_recover_tsf64(wlc, wlc_rxh); + rx_status->mactime = brcms_c_recover_tsf64(wlc, wlc_rxh); rx_status->flag |= RX_FLAG_MACTIME_MPDU; - channel = WLC_CHAN_CHANNEL(rxh->RxChan); + channel = BRCMS_CHAN_CHANNEL(rxh->RxChan); if (channel > 14) { rx_status->band = IEEE80211_BAND_5GHZ; @@ -6064,7 +4560,7 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, plcp = p->data; - rspec = wlc_compute_rspec(rxh, plcp); + rspec = brcms_c_compute_rspec(rxh, plcp); if (IS_MCS(rspec)) { rx_status->rate_idx = rspec & RSPEC_RATE_MASK; rx_status->flag |= RX_FLAG_HT; @@ -6072,40 +4568,40 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, rx_status->flag |= RX_FLAG_40MHZ; } else { switch (RSPEC2RATE(rspec)) { - case WLC_RATE_1M: + case BRCM_RATE_1M: rx_status->rate_idx = 0; break; - case WLC_RATE_2M: + case BRCM_RATE_2M: rx_status->rate_idx = 1; break; - case WLC_RATE_5M5: + case BRCM_RATE_5M5: rx_status->rate_idx = 2; break; - case WLC_RATE_11M: + case BRCM_RATE_11M: rx_status->rate_idx = 3; break; - case WLC_RATE_6M: + case BRCM_RATE_6M: rx_status->rate_idx = 4; break; - case WLC_RATE_9M: + case BRCM_RATE_9M: rx_status->rate_idx = 5; break; - case WLC_RATE_12M: + case BRCM_RATE_12M: rx_status->rate_idx = 6; break; - case WLC_RATE_18M: + case BRCM_RATE_18M: rx_status->rate_idx = 7; break; - case WLC_RATE_24M: + case BRCM_RATE_24M: rx_status->rate_idx = 8; break; - case WLC_RATE_36M: + case BRCM_RATE_36M: rx_status->rate_idx = 9; break; - case WLC_RATE_48M: + case BRCM_RATE_48M: rx_status->rate_idx = 10; break; - case WLC_RATE_54M: + case BRCM_RATE_54M: rx_status->rate_idx = 11; break; default: @@ -6141,7 +4637,8 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, } static void -wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p) +brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh, + struct sk_buff *p) { int len_mpdu; struct ieee80211_rx_status rx_status; @@ -6164,10 +4661,9 @@ wlc_recvctl(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p) * Return true if more frames need to be processed. false otherwise. * Param 'bound' indicates max. # frames to process before break out. */ -/* WLC_HIGH_API */ -void wlc_recv(struct wlc_info *wlc, struct sk_buff *p) +void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p) { - d11rxhdr_t *rxh; + struct d11rxhdr *rxh; struct ieee80211_hdr *h; uint len; bool is_amsdu; @@ -6175,10 +4671,10 @@ void wlc_recv(struct wlc_info *wlc, struct sk_buff *p) BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* frame starts with rxhdr */ - rxh = (d11rxhdr_t *) (p->data); + rxh = (struct d11rxhdr *) (p->data); /* strip off rxhdr */ - skb_pull(p, wlc->hwrxoff); + skb_pull(p, BRCMS_HWRXOFF); /* fixup rx header endianness */ rxh->RxFrameSize = le16_to_cpu(rxh->RxFrameSize); @@ -6196,7 +4692,7 @@ void wlc_recv(struct wlc_info *wlc, struct sk_buff *p) /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ if (rxh->RxStatus1 & RXS_PBPRES) { if (p->len < 2) { - wiphy_err(wlc->wiphy, "wl%d: wlc_recv: rcvd runt of " + wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of " "len %d\n", wlc->pub->unit, p->len); goto toss; } @@ -6248,11 +4744,11 @@ void wlc_recv(struct wlc_info *wlc, struct sk_buff *p) if (is_amsdu) goto toss; - wlc_recvctl(wlc, rxh, p); + brcms_c_recvctl(wlc, rxh, p); return; toss: - bcm_pkt_buf_free_skb(p); + brcmu_pkt_buf_free_skb(p); } /* calculate frame duration for Mixed-mode L-SIG spoofing, return @@ -6262,7 +4758,8 @@ void wlc_recv(struct wlc_info *wlc, struct sk_buff *p) * len = 3(nsyms + nstream + 3) - 3 */ u16 -wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) +brcms_c_calc_lsig_len(struct brcms_c_info *wlc, ratespec_t ratespec, + uint mac_len) { uint nsyms, len = 0, kNdps; @@ -6302,8 +4799,8 @@ wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) /* calculate frame duration of a given rate and length, return time in usec unit */ uint -wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, - uint mac_len) +brcms_c_calc_frame_time(struct brcms_c_info *wlc, ratespec_t ratespec, + u8 preamble_type, uint mac_len) { uint nsyms, dur = 0, Ndps, kNdps; uint rate = RSPEC2RATE(ratespec); @@ -6311,7 +4808,7 @@ wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, if (rate == 0) { wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit); - rate = WLC_RATE_1M; + rate = BRCM_RATE_1M; } BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n", @@ -6322,7 +4819,7 @@ wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec); dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT); - if (preamble_type == WLC_MM_PREAMBLE) + if (preamble_type == BRCMS_MM_PREAMBLE) dur += PREN_MM_EXT; /* 1000Ndbps = kbps * 4 */ kNdps = @@ -6361,7 +4858,7 @@ wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, mac_len = mac_len * 8 * 2; /* calc ceiling of bits/rate = microseconds of air time */ dur = (mac_len + rate - 1) / rate; - if (preamble_type & WLC_SHORT_PREAMBLE) + if (preamble_type & BRCMS_SHORT_PREAMBLE) dur += BPHY_PLCP_SHORT_TIME; else dur += BPHY_PLCP_TIME; @@ -6369,10 +4866,10 @@ wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, return dur; } -/* The opposite of wlc_calc_frame_time */ +/* The opposite of brcms_c_calc_frame_time */ static uint -wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, - uint dur) +brcms_c_calc_frame_len(struct brcms_c_info *wlc, ratespec_t ratespec, + u8 preamble_type, uint dur) { uint nsyms, mac_len, Ndps, kNdps; uint rate = RSPEC2RATE(ratespec); @@ -6405,7 +4902,7 @@ wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, ((nsyms * Ndps) - (APHY_SERVICE_NBITS + APHY_TAIL_NBITS)) / 8; } else { - if (preamble_type & WLC_SHORT_PREAMBLE) + if (preamble_type & BRCMS_SHORT_PREAMBLE) dur -= BPHY_PLCP_SHORT_TIME; else dur -= BPHY_PLCP_TIME; @@ -6417,22 +4914,24 @@ wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, } static uint -wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) +brcms_c_calc_ba_time(struct brcms_c_info *wlc, ratespec_t rspec, + u8 preamble_type) { BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, " "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type); /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than * or equal to the rate of the immediately previous frame in the FES */ - rspec = WLC_BASIC_RATE(wlc, rspec); + rspec = BRCMS_BASIC_RATE(wlc, rspec); /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */ - return wlc_calc_frame_time(wlc, rspec, preamble_type, + return brcms_c_calc_frame_time(wlc, rspec, preamble_type, (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN + FCS_LEN)); } static uint -wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) +brcms_c_calc_ack_time(struct brcms_c_info *wlc, ratespec_t rspec, + u8 preamble_type) { uint dur = 0; @@ -6441,24 +4940,25 @@ wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than * or equal to the rate of the immediately previous frame in the FES */ - rspec = WLC_BASIC_RATE(wlc, rspec); + rspec = BRCMS_BASIC_RATE(wlc, rspec); /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */ dur = - wlc_calc_frame_time(wlc, rspec, preamble_type, + brcms_c_calc_frame_time(wlc, rspec, preamble_type, (DOT11_ACK_LEN + FCS_LEN)); return dur; } static uint -wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) +brcms_c_calc_cts_time(struct brcms_c_info *wlc, ratespec_t rspec, + u8 preamble_type) { BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n", wlc->pub->unit, rspec, preamble_type); - return wlc_calc_ack_time(wlc, rspec, preamble_type); + return brcms_c_calc_ack_time(wlc, rspec, preamble_type); } /* derive wlc->band->basic_rate[] table from 'rateset' */ -void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) +void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, wlc_rateset_t *rateset) { u8 rate; u8 mandatory; @@ -6468,22 +4968,22 @@ void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) uint i; /* incoming rates are in 500kbps units as in 802.11 Supported Rates */ - memset(br, 0, WLC_MAXRATE + 1); + memset(br, 0, BRCM_MAXRATE + 1); /* For each basic rate in the rates list, make an entry in the * best basic lookup. */ for (i = 0; i < rateset->count; i++) { /* only make an entry for a basic rate */ - if (!(rateset->rates[i] & WLC_RATE_FLAG)) + if (!(rateset->rates[i] & BRCMS_RATE_FLAG)) continue; /* mask off basic bit */ - rate = (rateset->rates[i] & WLC_RATE_MASK); + rate = (rateset->rates[i] & BRCMS_RATE_MASK); - if (rate > WLC_MAXRATE) { - wiphy_err(wlc->wiphy, "wlc_rate_lookup_init: invalid " - "rate 0x%X in rate set\n", + if (rate > BRCM_MAXRATE) { + wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: " + "invalid rate 0x%X in rate set\n", rateset->rates[i]); continue; } @@ -6533,12 +5033,12 @@ void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) if (IS_OFDM(rate)) { /* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */ - if (rate >= WLC_RATE_24M) - mandatory = WLC_RATE_24M; - else if (rate >= WLC_RATE_12M) - mandatory = WLC_RATE_12M; + if (rate >= BRCM_RATE_24M) + mandatory = BRCM_RATE_24M; + else if (rate >= BRCM_RATE_12M) + mandatory = BRCM_RATE_12M; else - mandatory = WLC_RATE_6M; + mandatory = BRCM_RATE_6M; } else { /* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */ mandatory = rate; @@ -6548,7 +5048,8 @@ void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) } } -static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate) +static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate, + u8 basic_rate) { u8 phy_rate, index; u8 basic_phy_rate, basic_index; @@ -6565,27 +5066,27 @@ static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate) * for a given rate, the LS-nibble of the PLCP SIGNAL field is * the index into the rate table. */ - phy_rate = rate_info[rate] & WLC_RATE_MASK; - basic_phy_rate = rate_info[basic_rate] & WLC_RATE_MASK; + phy_rate = rate_info[rate] & BRCMS_RATE_MASK; + basic_phy_rate = rate_info[basic_rate] & BRCMS_RATE_MASK; index = phy_rate & 0xf; basic_index = basic_phy_rate & 0xf; /* Find the SHM pointer to the ACK rate entry by looking in the * Direct-map Table */ - basic_ptr = wlc_read_shm(wlc, (dir_table + basic_index * 2)); + basic_ptr = brcms_c_read_shm(wlc, (dir_table + basic_index * 2)); /* Update the SHM BSS-basic-rate-set mapping table with the pointer * to the correct basic rate for the given incoming rate */ - wlc_write_shm(wlc, (basic_table + index * 2), basic_ptr); + brcms_c_write_shm(wlc, (basic_table + index * 2), basic_ptr); } -static const wlc_rateset_t *wlc_rateset_get_hwrs(struct wlc_info *wlc) +static const wlc_rateset_t *brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc) { const wlc_rateset_t *rs_dflt; - if (WLC_PHY_11N_CAP(wlc->band)) { + if (BRCMS_PHY_11N_CAP(wlc->band)) { if (BAND_5G(wlc->band->bandtype)) rs_dflt = &ofdm_mimo_rates; else @@ -6598,48 +5099,48 @@ static const wlc_rateset_t *wlc_rateset_get_hwrs(struct wlc_info *wlc) return rs_dflt; } -void wlc_set_ratetable(struct wlc_info *wlc) +void brcms_c_set_ratetable(struct brcms_c_info *wlc) { const wlc_rateset_t *rs_dflt; wlc_rateset_t rs; u8 rate, basic_rate; uint i; - rs_dflt = wlc_rateset_get_hwrs(wlc); + rs_dflt = brcms_c_rateset_get_hwrs(wlc); - wlc_rateset_copy(rs_dflt, &rs); - wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); + brcms_c_rateset_copy(rs_dflt, &rs); + brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams); /* walk the phy rate table and update SHM basic rate lookup table */ for (i = 0; i < rs.count; i++) { - rate = rs.rates[i] & WLC_RATE_MASK; + rate = rs.rates[i] & BRCMS_RATE_MASK; - /* for a given rate WLC_BASIC_RATE returns the rate at + /* for a given rate BRCMS_BASIC_RATE returns the rate at * which a response ACK/CTS should be sent. */ - basic_rate = WLC_BASIC_RATE(wlc, rate); + basic_rate = BRCMS_BASIC_RATE(wlc, rate); if (basic_rate == 0) { /* This should only happen if we are using a * restricted rateset. */ - basic_rate = rs.rates[0] & WLC_RATE_MASK; + basic_rate = rs.rates[0] & BRCMS_RATE_MASK; } - wlc_write_rate_shm(wlc, rate, basic_rate); + brcms_c_write_rate_shm(wlc, rate, basic_rate); } } /* * Return true if the specified rate is supported by the specified band. - * WLC_BAND_AUTO indicates the current band. + * BRCM_BAND_AUTO indicates the current band. */ -bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band, +bool brcms_c_valid_rate(struct brcms_c_info *wlc, ratespec_t rspec, int band, bool verbose) { wlc_rateset_t *hw_rateset; uint i; - if ((band == WLC_BAND_AUTO) || (band == wlc->band->bandtype)) { + if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype)) { hw_rateset = &wlc->band->hw_rateset; } else if (NBANDS(wlc) > 1) { hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset; @@ -6661,40 +5162,38 @@ bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band, return true; error: if (verbose) { - wiphy_err(wlc->wiphy, "wl%d: wlc_valid_rate: rate spec 0x%x " + wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x " "not in hw_rateset\n", wlc->pub->unit, rspec); } return false; } -static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap) +static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap) { uint i; - struct wlcband *band; + struct brcms_band *band; for (i = 0; i < NBANDS(wlc); i++) { if (IS_SINGLEBAND_5G(wlc->deviceid)) i = BAND_5G_INDEX; band = wlc->bandstate[i]; - if (band->bandtype == WLC_BAND_5G) { - if ((bwcap == WLC_N_BW_40ALL) - || (bwcap == WLC_N_BW_20IN2G_40IN5G)) + if (band->bandtype == BRCM_BAND_5G) { + if ((bwcap == BRCMS_N_BW_40ALL) + || (bwcap == BRCMS_N_BW_20IN2G_40IN5G)) band->mimo_cap_40 = true; else band->mimo_cap_40 = false; } else { - if (bwcap == WLC_N_BW_40ALL) + if (bwcap == BRCMS_N_BW_40ALL) band->mimo_cap_40 = true; else band->mimo_cap_40 = false; } } - - wlc->mimo_band_bwcap = bwcap; } -void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) +void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len) { const wlc_rateset_t *rs_dflt; wlc_rateset_t rs; @@ -6706,32 +5205,31 @@ void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) sifs = SIFS(wlc->band); - rs_dflt = wlc_rateset_get_hwrs(wlc); + rs_dflt = brcms_c_rateset_get_hwrs(wlc); - wlc_rateset_copy(rs_dflt, &rs); - wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams); + brcms_c_rateset_copy(rs_dflt, &rs); + brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams); /* walk the phy rate table and update MAC core SHM basic rate table entries */ for (i = 0; i < rs.count; i++) { - rate = rs.rates[i] & WLC_RATE_MASK; + rate = rs.rates[i] & BRCMS_RATE_MASK; - entry_ptr = wlc_rate_shm_offset(wlc, rate); + entry_ptr = brcms_c_rate_shm_offset(wlc, rate); /* Calculate the Probe Response PLCP for the given rate */ - wlc_compute_plcp(wlc, rate, frame_len, plcp); + brcms_c_compute_plcp(wlc, rate, frame_len, plcp); /* Calculate the duration of the Probe Response frame plus SIFS for the MAC */ - dur = - (u16) wlc_calc_frame_time(wlc, rate, WLC_LONG_PREAMBLE, - frame_len); + dur = (u16) brcms_c_calc_frame_time(wlc, rate, + BRCMS_LONG_PREAMBLE, frame_len); dur += sifs; /* Update the SHM Rate Table entry Probe Response values */ - wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS, + brcms_c_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS, (u16) (plcp[0] + (plcp[1] << 8))); - wlc_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2, + brcms_c_write_shm(wlc, entry_ptr + M_RT_PRS_PLCP_POS + 2, (u16) (plcp[2] + (plcp[3] << 8))); - wlc_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur); + brcms_c_write_shm(wlc, entry_ptr + M_RT_PRS_DUR_POS, dur); } } @@ -6748,11 +5246,12 @@ void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) * and included up to, but not including, the 4 byte FCS. */ static void -wlc_bcn_prb_template(struct wlc_info *wlc, u16 type, ratespec_t bcn_rspec, - struct wlc_bsscfg *cfg, u16 *buf, int *len) +brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type, + ratespec_t bcn_rspec, + struct brcms_bss_cfg *cfg, u16 *buf, int *len) { static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; - cck_phy_hdr_t *plcp; + struct cck_phy_hdr *plcp; struct ieee80211_mgmt *h; int hdr_len, body_len; @@ -6767,12 +5266,12 @@ wlc_bcn_prb_template(struct wlc_info *wlc, u16 type, ratespec_t bcn_rspec, /* format PHY and MAC headers */ memset((char *)buf, 0, hdr_len); - plcp = (cck_phy_hdr_t *) buf; + plcp = (struct cck_phy_hdr *) buf; /* PLCP for Probe Response frames are filled in from core's rate table */ if (type == IEEE80211_STYPE_BEACON && !MBSS_BCN_ENAB(cfg)) { /* fill in PLCP */ - wlc_compute_plcp(wlc, bcn_rspec, + brcms_c_compute_plcp(wlc, bcn_rspec, (DOT11_MAC_HDR_LEN + body_len + FCS_LEN), (u8 *) plcp); @@ -6780,7 +5279,7 @@ wlc_bcn_prb_template(struct wlc_info *wlc, u16 type, ratespec_t bcn_rspec, /* "Regular" and 16 MBSS but not for 4 MBSS */ /* Update the phytxctl for the beacon based on the rspec */ if (!SOFTBCN_ENAB(cfg)) - wlc_beacon_phytxctl_txant_upd(wlc, bcn_rspec); + brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec); if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON) h = (struct ieee80211_mgmt *)&plcp[0]; @@ -6802,7 +5301,7 @@ wlc_bcn_prb_template(struct wlc_info *wlc, u16 type, ratespec_t bcn_rspec, return; } -int wlc_get_header_len() +int brcms_c_get_header_len() { return TXOFF; } @@ -6812,7 +5311,8 @@ int wlc_get_header_len() * template updated. * Otherwise, it updates the hardware template. */ -void wlc_bss_update_beacon(struct wlc_info *wlc, struct wlc_bsscfg *cfg) +void brcms_c_bss_update_beacon(struct brcms_c_info *wlc, + struct brcms_bss_cfg *cfg) { int len = BCN_TMPL_LEN; @@ -6846,31 +5346,31 @@ void wlc_bss_update_beacon(struct wlc_info *wlc, struct wlc_bsscfg *cfg) } wlc->bcn_rspec = - wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset); + brcms_c_lowest_basic_rspec(wlc, &cfg->current_bss->rateset); /* update the template and ucode shm */ - wlc_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON, + brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON, wlc->bcn_rspec, cfg, bcn, &len); - wlc_write_hw_bcntemplates(wlc, bcn, len, false); + brcms_c_write_hw_bcntemplates(wlc, bcn, len, false); } } /* * Update all beacons for the system. */ -void wlc_update_beacon(struct wlc_info *wlc) +void brcms_c_update_beacon(struct brcms_c_info *wlc) { int idx; - struct wlc_bsscfg *bsscfg; + struct brcms_bss_cfg *bsscfg; /* update AP or IBSS beacons */ FOREACH_BSS(wlc, idx, bsscfg) { if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) - wlc_bss_update_beacon(wlc, bsscfg); + brcms_c_bss_update_beacon(wlc, bsscfg); } } /* Write ssid into shared memory */ -void wlc_shm_ssid_upd(struct wlc_info *wlc, struct wlc_bsscfg *cfg) +void brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg) { u8 *ssidptr = cfg->SSID; u16 base = M_SSID; @@ -6880,27 +5380,28 @@ void wlc_shm_ssid_upd(struct wlc_info *wlc, struct wlc_bsscfg *cfg) memset(ssidbuf, 0, IEEE80211_MAX_SSID_LEN); memcpy(ssidbuf, ssidptr, cfg->SSID_len); - wlc_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN); + brcms_c_copyto_shm(wlc, base, ssidbuf, IEEE80211_MAX_SSID_LEN); if (!MBSS_BCN_ENAB(cfg)) - wlc_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len); + brcms_c_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len); } -void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend) +void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend) { int idx; - struct wlc_bsscfg *bsscfg; + struct brcms_bss_cfg *bsscfg; /* update AP or IBSS probe responses */ FOREACH_BSS(wlc, idx, bsscfg) { if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) - wlc_bss_update_probe_resp(wlc, bsscfg, suspend); + brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); } } void -wlc_bss_update_probe_resp(struct wlc_info *wlc, struct wlc_bsscfg *cfg, - bool suspend) +brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc, + struct brcms_bss_cfg *cfg, + bool suspend) { u16 prb_resp[BCN_TMPL_LEN / 2]; int len = BCN_TMPL_LEN; @@ -6909,49 +5410,51 @@ wlc_bss_update_probe_resp(struct wlc_info *wlc, struct wlc_bsscfg *cfg, if (!MBSS_PRB_ENAB(cfg)) { /* create the probe response template */ - wlc_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0, cfg, - prb_resp, &len); + brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0, + cfg, prb_resp, &len); if (suspend) - wlc_suspend_mac_and_wait(wlc); + brcms_c_suspend_mac_and_wait(wlc); /* write the probe response into the template region */ - wlc_bmac_write_template_ram(wlc->hw, T_PRS_TPL_BASE, + brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE, (len + 3) & ~3, prb_resp); /* write the length of the probe response frame (+PLCP/-FCS) */ - wlc_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len); + brcms_c_write_shm(wlc, M_PRB_RESP_FRM_LEN, (u16) len); /* write the SSID and SSID length */ - wlc_shm_ssid_upd(wlc, cfg); + brcms_c_shm_ssid_upd(wlc, cfg); /* * Write PLCP headers and durations for probe response frames at all rates. * Use the actual frame length covered by the PLCP header for the call to - * wlc_mod_prb_rsp_rate_table() by subtracting the PLCP len and adding the FCS. + * brcms_c_mod_prb_rsp_rate_table() by subtracting the PLCP len + * and adding the FCS. */ len += (-D11_PHY_HDR_LEN + FCS_LEN); - wlc_mod_prb_rsp_rate_table(wlc, (u16) len); + brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len); if (suspend) - wlc_enable_mac(wlc); + brcms_c_enable_mac(wlc); } else { /* Generating probe resp in sw; update local template */ /* error: No software probe response support without MBSS */ } } /* prepares pdu for transmission. returns BCM error codes */ -int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) +int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop) { uint fifo; - d11txh_t *txh; + struct d11txh *txh; struct ieee80211_hdr *h; struct scb *scb; - txh = (d11txh_t *) (pdu->data); + txh = (struct d11txh *) (pdu->data); h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); - /* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */ + /* get the pkt queue info. This was put at brcms_c_sendctl or + * brcms_c_send for PDU */ fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; scb = NULL; @@ -6961,87 +5464,49 @@ int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) /* return if insufficient dma resources */ if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) { /* Mark precedences related to this FIFO, unsendable */ - WLC_TX_FIFO_CLEAR(wlc, fifo); + BRCMS_TX_FIFO_CLEAR(wlc, fifo); return -EBUSY; } return 0; } /* init tx reported rate mechanism */ -void wlc_reprate_init(struct wlc_info *wlc) +void brcms_c_reprate_init(struct brcms_c_info *wlc) { int i; - struct wlc_bsscfg *bsscfg; + struct brcms_bss_cfg *bsscfg; FOREACH_BSS(wlc, i, bsscfg) { - wlc_bsscfg_reprate_init(bsscfg); + brcms_c_bsscfg_reprate_init(bsscfg); } } /* per bsscfg init tx reported rate mechanism */ -void wlc_bsscfg_reprate_init(struct wlc_bsscfg *bsscfg) +void brcms_c_bsscfg_reprate_init(struct brcms_bss_cfg *bsscfg) { bsscfg->txrspecidx = 0; memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec)); } -/* Retrieve a consolidated set of revision information, - * typically for the WLC_GET_REVINFO ioctl - */ -int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len) +void brcms_default_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs) { - wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf; - - if (len < WL_REV_INFO_LEGACY_LENGTH) - return -EOVERFLOW; - - rinfo->vendorid = wlc->vendorid; - rinfo->deviceid = wlc->deviceid; - rinfo->radiorev = (wlc->band->radiorev << IDCODE_REV_SHIFT) | - (wlc->band->radioid << IDCODE_ID_SHIFT); - rinfo->chiprev = wlc->pub->sih->chiprev; - rinfo->corerev = wlc->pub->corerev; - rinfo->boardid = wlc->pub->sih->boardtype; - rinfo->boardvendor = wlc->pub->sih->boardvendor; - rinfo->boardrev = wlc->pub->boardrev; - rinfo->ucoderev = wlc->ucode_rev; - rinfo->driverrev = EPI_VERSION_NUM; - rinfo->bus = wlc->pub->sih->bustype; - rinfo->chipnum = wlc->pub->sih->chip; - - if (len >= (offsetof(wlc_rev_info_t, chippkg))) { - rinfo->phytype = wlc->band->phytype; - rinfo->phyrev = wlc->band->phyrev; - rinfo->anarev = 0; /* obsolete stuff, suppress */ - } - - if (len >= sizeof(*rinfo)) { - rinfo->chippkg = wlc->pub->sih->chippkg; - } - - return 0; + brcms_c_rateset_default(rs, NULL, wlc->band->phytype, + wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL, + (bool) N_ENAB(wlc->pub), + CHSPEC_WLC_BW(wlc->default_bss->chanspec), + wlc->stf->txstreams); } -void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs) -{ - wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype, - false, WLC_RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), - CHSPEC_WLC_BW(wlc->default_bss->chanspec), - wlc->stf->txstreams); -} - -static void wlc_bss_default_init(struct wlc_info *wlc) +static void brcms_c_bss_default_init(struct brcms_c_info *wlc) { chanspec_t chanspec; - struct wlcband *band; - wlc_bss_info_t *bi = wlc->default_bss; + struct brcms_band *band; + struct brcms_bss_info *bi = wlc->default_bss; /* init default and target BSS with some sane initial values */ - memset((char *)(bi), 0, sizeof(wlc_bss_info_t)); - bi->beacon_period = ISSIM_ENAB(wlc->pub->sih) ? BEACON_INTERVAL_DEF_QT : - BEACON_INTERVAL_DEFAULT; - bi->dtim_period = ISSIM_ENAB(wlc->pub->sih) ? DTIM_INTERVAL_DEF_QT : - DTIM_INTERVAL_DEFAULT; + memset((char *)(bi), 0, sizeof(struct brcms_bss_info)); + bi->beacon_period = BEACON_INTERVAL_DEFAULT; + bi->dtim_period = DTIM_INTERVAL_DEFAULT; /* fill the default channel as the first valid channel * starting from the 2G channels @@ -7051,20 +5516,21 @@ static void wlc_bss_default_init(struct wlc_info *wlc) /* find the band of our default channel */ band = wlc->band; - if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_WLCBANDUNIT(chanspec)) + if (NBANDS(wlc) > 1 && band->bandunit != CHSPEC_BANDUNIT(chanspec)) band = wlc->bandstate[OTHERBANDUNIT(wlc)]; /* init bss rates to the band specific default rate set */ - wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype, - false, WLC_RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), - CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams); + brcms_c_rateset_default(&bi->rateset, NULL, band->phytype, + band->bandtype, false, BRCMS_RATE_MASK_FULL, + (bool) N_ENAB(wlc->pub), CHSPEC_WLC_BW(chanspec), + wlc->stf->txstreams); if (N_ENAB(wlc->pub)) - bi->flags |= WLC_BSS_HT; + bi->flags |= BRCMS_BSS_HT; } static ratespec_t -mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, +mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, u32 int_val) { u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; @@ -7085,7 +5551,7 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, /* mcs only allowed when nmode */ if (stf > PHY_TXC1_MODE_SDM) { wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n", - WLCWLUNIT(wlc), __func__); + BRCMS_UNIT(wlc), __func__); bcmerror = -EINVAL; goto done; } @@ -7096,7 +5562,7 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, ((stf != PHY_TXC1_MODE_SISO) && (stf != PHY_TXC1_MODE_CDD))) { wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs " - "32\n", WLCWLUNIT(wlc), __func__); + "32\n", BRCMS_UNIT(wlc), __func__); bcmerror = -EINVAL; goto done; } @@ -7106,16 +5572,16 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, if (stf != PHY_TXC1_MODE_SDM) { BCMMSG(wlc->wiphy, "wl%d: enabling " "SDM mode for mcs %d\n", - WLCWLUNIT(wlc), rate); + BRCMS_UNIT(wlc), rate); stf = PHY_TXC1_MODE_SDM; } } else { /* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */ if ((stf > PHY_TXC1_MODE_STBC) || - (!WLC_STBC_CAP_PHY(wlc) + (!BRCMS_STBC_CAP_PHY(wlc) && (stf == PHY_TXC1_MODE_STBC))) { wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC" - "\n", WLCWLUNIT(wlc), __func__); + "\n", BRCMS_UNIT(wlc), __func__); bcmerror = -EINVAL; goto done; } @@ -7123,28 +5589,28 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, } else if (IS_OFDM(rate)) { if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n", - WLCWLUNIT(wlc), __func__); + BRCMS_UNIT(wlc), __func__); bcmerror = -EINVAL; goto done; } } else if (IS_CCK(rate)) { - if ((cur_band->bandtype != WLC_BAND_2G) + if ((cur_band->bandtype != BRCM_BAND_2G) || (stf != PHY_TXC1_MODE_SISO)) { wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n", - WLCWLUNIT(wlc), __func__); + BRCMS_UNIT(wlc), __func__); bcmerror = -EINVAL; goto done; } } else { wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n", - WLCWLUNIT(wlc), __func__); + BRCMS_UNIT(wlc), __func__); bcmerror = -EINVAL; goto done; } /* make sure multiple antennae are available for non-siso rates */ if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO " - "request\n", WLCWLUNIT(wlc), __func__); + "request\n", BRCMS_UNIT(wlc), __func__); bcmerror = -EINVAL; goto done; } @@ -7169,7 +5635,7 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, rspec |= RSPEC_SHORT_GI; if ((rate != 0) - && !wlc_valid_rate(wlc, rspec, cur_band->bandtype, true)) { + && !brcms_c_valid_rate(wlc, rspec, cur_band->bandtype, true)) { return rate; } @@ -7180,7 +5646,7 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, /* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */ static int -wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, +brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM, bool writeToShm) { int idle_busy_ratio_x_16 = 0; @@ -7196,7 +5662,7 @@ wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle; /* Only write to shared memory when wl is up */ if (writeToShm) - wlc_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16); + brcms_c_write_shm(wlc, offset, (u16) idle_busy_ratio_x_16); if (isOFDM) wlc->tx_duty_cycle_ofdm = (u16) duty_cycle; @@ -7209,97 +5675,85 @@ wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, /* Read a single u16 from shared memory. * SHM 'offset' needs to be an even address */ -u16 wlc_read_shm(struct wlc_info *wlc, uint offset) +u16 brcms_c_read_shm(struct brcms_c_info *wlc, uint offset) { - return wlc_bmac_read_shm(wlc->hw, offset); + return brcms_b_read_shm(wlc->hw, offset); } /* Write a single u16 to shared memory. * SHM 'offset' needs to be an even address */ -void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v) +void brcms_c_write_shm(struct brcms_c_info *wlc, uint offset, u16 v) { - wlc_bmac_write_shm(wlc->hw, offset, v); + brcms_b_write_shm(wlc->hw, offset, v); } /* Copy a buffer to shared memory. * SHM 'offset' needs to be an even address and * Buffer length 'len' must be an even number of bytes */ -void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len) +void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset, const void *buf, + int len) { /* offset and len need to be even */ if (len <= 0 || (offset & 1) || (len & 1)) return; - wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); + brcms_b_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL); } /* wrapper BMAC functions to for HIGH driver access */ -void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val) +void brcms_c_mctrl(struct brcms_c_info *wlc, u32 mask, u32 val) { - wlc_bmac_mctrl(wlc->hw, mask, val); + brcms_b_mctrl(wlc->hw, mask, val); } -void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands) +void brcms_c_mhf(struct brcms_c_info *wlc, u8 idx, u16 mask, u16 val, int bands) { - wlc_bmac_mhf(wlc->hw, idx, mask, val, bands); + brcms_b_mhf(wlc->hw, idx, mask, val, bands); } -int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks) +int brcms_c_xmtfifo_sz_get(struct brcms_c_info *wlc, uint fifo, uint *blocks) { - return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks); + return brcms_b_xmtfifo_sz_get(wlc->hw, fifo, blocks); } -void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, +void brcms_c_write_template_ram(struct brcms_c_info *wlc, int offset, int len, void *buf) { - wlc_bmac_write_template_ram(wlc->hw, offset, len, buf); + brcms_b_write_template_ram(wlc->hw, offset, len, buf); } -void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, +void brcms_c_write_hw_bcntemplates(struct brcms_c_info *wlc, void *bcn, int len, bool both) { - wlc_bmac_write_hw_bcntemplates(wlc->hw, bcn, len, both); + brcms_b_write_hw_bcntemplates(wlc->hw, bcn, len, both); } void -wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, +brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset, const u8 *addr) { - wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr); + brcms_b_set_addrmatch(wlc->hw, match_reg_offset, addr); if (match_reg_offset == RCM_BSSID_OFFSET) memcpy(wlc->cfg->BSSID, addr, ETH_ALEN); } -void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin) +void brcms_c_pllreq(struct brcms_c_info *wlc, bool set, mbool req_bit) { - wlc->band->CWmin = newmin; - wlc_bmac_set_cwmin(wlc->hw, newmin); + brcms_b_pllreq(wlc->hw, set, req_bit); } -void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax) -{ - wlc->band->CWmax = newmax; - wlc_bmac_set_cwmax(wlc->hw, newmax); -} - -/* Search mem rw utilities */ - -void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit) -{ - wlc_bmac_pllreq(wlc->hw, set, req_bit); -} - -void wlc_reset_bmac_done(struct wlc_info *wlc) +void brcms_c_reset_bmac_done(struct brcms_c_info *wlc) { } /* check for the particular priority flow control bit being set */ bool -wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *q, - int prio) +brcms_c_txflowcontrol_prio_isset(struct brcms_c_info *wlc, + struct brcms_txq_info *q, + int prio) { uint prio_mask; @@ -7313,8 +5767,9 @@ wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *q, } /* propagate the flow control to all interfaces using the given tx queue */ -void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi, - bool on, int prio) +void brcms_c_txflowcontrol(struct brcms_c_info *wlc, + struct brcms_txq_info *qi, + bool on, int prio) { uint prio_bits; uint cur_bits; @@ -7351,12 +5806,13 @@ void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi, return; } - wlc_txflowcontrol_signal(wlc, qi, on, prio); + brcms_c_txflowcontrol_signal(wlc, qi, on, prio); } void -wlc_txflowcontrol_override(struct wlc_info *wlc, struct wlc_txq_info *qi, - bool on, uint override) +brcms_c_txflowcontrol_override(struct brcms_c_info *wlc, + struct brcms_txq_info *qi, + bool on, uint override) { uint prev_override; @@ -7374,7 +5830,7 @@ wlc_txflowcontrol_override(struct wlc_info *wlc, struct wlc_txq_info *qi, return; } - wlc_txflowcontrol_signal(wlc, qi, ON, ALLPRIO); + brcms_c_txflowcontrol_signal(wlc, qi, ON, ALLPRIO); } else { mboolclr(qi->stopped, override); /* clearing an override bit will only make a difference for @@ -7386,48 +5842,51 @@ wlc_txflowcontrol_override(struct wlc_info *wlc, struct wlc_txq_info *qi, } if (qi->stopped == 0) { - wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); + brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); } else { int prio; for (prio = MAXPRIO; prio >= 0; prio--) { if (!mboolisset(qi->stopped, NBITVAL(prio))) - wlc_txflowcontrol_signal(wlc, qi, OFF, - prio); + brcms_c_txflowcontrol_signal( + wlc, qi, OFF, prio); } } } } -static void wlc_txflowcontrol_reset(struct wlc_info *wlc) +static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc) { - struct wlc_txq_info *qi; + struct brcms_txq_info *qi; for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { if (qi->stopped) { - wlc_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); + brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); qi->stopped = 0; } } } static void -wlc_txflowcontrol_signal(struct wlc_info *wlc, struct wlc_txq_info *qi, bool on, - int prio) +brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc, + struct brcms_txq_info *qi, bool on, int prio) { - struct wlc_if *wlcif; +#ifdef NON_FUNCTIONAL + /* wlcif_list is never filled so this function is not functional */ + struct brcms_c_if *wlcif; for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) { - if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED) - wl_txflowcontrol(wlc->wl, wlcif->wlif, on, prio); + if (wlcif->qi == qi && wlcif->flags & BRCMS_IF_LINKED) + brcms_txflowcontrol(wlc->wl, wlcif->wlif, on, prio); } +#endif } -static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc) +static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc) { - struct wlc_txq_info *qi, *p; + struct brcms_txq_info *qi, *p; - qi = kzalloc(sizeof(struct wlc_txq_info), GFP_ATOMIC); + qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC); if (qi != NULL) { /* * Have enough room for control packets along with HI watermark @@ -7435,7 +5894,7 @@ static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc) * leave PS mode. The watermark for flowcontrol to OS packets * will remain the same */ - bcm_pktq_init(&qi->q, WLC_PREC_COUNT, + brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT, (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT + wlc->pub->psq_pkts_total); @@ -7452,9 +5911,10 @@ static struct wlc_txq_info *wlc_txq_alloc(struct wlc_info *wlc) return qi; } -static void wlc_txq_free(struct wlc_info *wlc, struct wlc_txq_info *qi) +static void brcms_c_txq_free(struct brcms_c_info *wlc, + struct brcms_txq_info *qi) { - struct wlc_txq_info *p; + struct brcms_txq_info *p; if (qi == NULL) return; @@ -7476,17 +5936,17 @@ static void wlc_txq_free(struct wlc_info *wlc, struct wlc_txq_info *qi) /* * Flag 'scan in progress' to withhold dynamic phy calibration */ -void wlc_scan_start(struct wlc_info *wlc) +void brcms_c_scan_start(struct brcms_c_info *wlc) { wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, true); } -void wlc_scan_stop(struct wlc_info *wlc) +void brcms_c_scan_stop(struct brcms_c_info *wlc) { wlc_phy_hold_upd(wlc->band->pi, PHY_HOLD_FOR_SCAN, false); } -void wlc_associate_upd(struct wlc_info *wlc, bool state) +void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state) { wlc->pub->associated = state; wlc->cfg->associated = state; @@ -7497,11 +5957,11 @@ void wlc_associate_upd(struct wlc_info *wlc, bool state) * AMPDU traffic, packets pending in hardware have to be invalidated so that * when later on hardware releases them, they can be handled appropriately. */ -void wlc_inval_dma_pkts(struct wlc_hw_info *hw, +void brcms_c_inval_dma_pkts(struct brcms_hardware *hw, struct ieee80211_sta *sta, void (*dma_callback_fn)) { - struct hnddma_pub *dmah; + struct dma_pub *dmah; int i; for (i = 0; i < NFIFO; i++) { dmah = hw->di[i]; @@ -7510,20 +5970,133 @@ void wlc_inval_dma_pkts(struct wlc_hw_info *hw, } } -int wlc_get_curband(struct wlc_info *wlc) +int brcms_c_get_curband(struct brcms_c_info *wlc) { return wlc->band->bandunit; } -void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop) +void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) { /* flush packet queue when requested */ if (drop) - bcm_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL); + brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL); /* wait for queue and DMA fifos to run dry */ while (!pktq_empty(&wlc->pkt_queue->q) || TXPKTPENDTOT(wlc) > 0) { - wl_msleep(wlc->wl, 1); + brcms_msleep(wlc->wl, 1); } } + +int brcms_c_set_par(struct brcms_c_info *wlc, enum wlc_par_id par_id, + int int_val) +{ + int err = 0; + + switch (par_id) { + case IOV_BCN_LI_BCN: + wlc->bcn_li_bcn = (u8) int_val; + if (wlc->pub->up) + brcms_c_bcn_li_upd(wlc); + break; + /* As long as override is false, this only sets the *user* + targets. User can twiddle this all he wants with no harm. + wlc_phy_txpower_set() explicitly sets override to false if + not internal or test. + */ + case IOV_QTXPOWER:{ + u8 qdbm; + bool override; + + /* Remove override bit and clip to max qdbm value */ + qdbm = (u8)min_t(u32, (int_val & ~WL_TXPWR_OVERRIDE), 0xff); + /* Extract override setting */ + override = (int_val & WL_TXPWR_OVERRIDE) ? true : false; + err = + wlc_phy_txpower_set(wlc->band->pi, qdbm, override); + break; + } + case IOV_MPC: + wlc->mpc = (bool)int_val; + brcms_c_radio_mpc_upd(wlc); + break; + default: + err = -ENOTSUPP; + } + return err; +} + +int brcms_c_get_par(struct brcms_c_info *wlc, enum wlc_par_id par_id, + int *ret_int_ptr) +{ + int err = 0; + + switch (par_id) { + case IOV_BCN_LI_BCN: + *ret_int_ptr = wlc->bcn_li_bcn; + break; + case IOV_QTXPOWER: { + uint qdbm; + bool override; + + err = wlc_phy_txpower_get(wlc->band->pi, &qdbm, + &override); + if (err != 0) + return err; + + /* Return qdbm units */ + *ret_int_ptr = + qdbm | (override ? WL_TXPWR_OVERRIDE : 0); + break; + } + case IOV_MPC: + *ret_int_ptr = (s32) wlc->mpc; + break; + default: + err = -ENOTSUPP; + } + return err; +} + +/* + * Search the name=value vars for a specific one and return its value. + * Returns NULL if not found. + */ +char *getvar(char *vars, const char *name) +{ + char *s; + int len; + + if (!name) + return NULL; + + len = strlen(name); + if (len == 0) + return NULL; + + /* first look in vars[] */ + for (s = vars; s && *s;) { + if ((memcmp(s, name, len) == 0) && (s[len] == '=')) + return &s[len + 1]; + + while (*s++) + ; + } + /* nothing found */ + return NULL; +} + +/* + * Search the vars for a specific one and return its value as + * an integer. Returns 0 if not found. + */ +int getintvar(char *vars, const char *name) +{ + char *val; + + val = getvar(vars, name); + if (val == NULL) + return 0; + + return simple_strtoul(val, NULL, 0); +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_main.h b/drivers/staging/brcm80211/brcmsmac/main.h similarity index 52% rename from drivers/staging/brcm80211/brcmsmac/wlc_main.h rename to drivers/staging/brcm80211/brcmsmac/main.h index fb48dfcb97d5..f204b1f47475 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_main.h +++ b/drivers/staging/brcm80211/brcmsmac/main.h @@ -14,33 +14,67 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_h_ -#define _wlc_h_ +#ifndef _BRCM_MAIN_H_ +#define _BRCM_MAIN_H_ + +#include + +#include +#include "types.h" +#include "d11.h" #define MA_WINDOW_SZ 8 /* moving average window size */ -#define WL_HWRXOFF 38 /* chip rx buffer offset */ +#define BRCMS_HWRXOFF 38 /* chip rx buffer offset */ #define INVCHANNEL 255 /* invalid channel */ -#define MAXCOREREV 28 /* max # supported core revisions (0 .. MAXCOREREV - 1) */ -#define WLC_MAXMODULES 22 /* max # wlc_module_register() calls */ +/* max # supported core revisions (0 .. MAXCOREREV - 1) */ +#define MAXCOREREV 28 +/* max # brcms_c_module_register() calls */ +#define BRCMS_MAXMODULES 22 -#define WLC_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) +#define SEQNUM_SHIFT 4 +#define AMPDU_DELIMITER_LEN 4 +#define SEQNUM_MAX 0x1000 + +#define APHY_CWMIN 15 +#define PHY_CWMAX 1023 + +#define EDCF_AIFSN_MIN 1 +#define FRAGNUM_MASK 0xF + +#define NTXRATE 64 /* # tx MPDUs rate is reported for */ + +#define BRCMS_BITSCNT(x) brcmu_bitcount((u8 *)&(x), sizeof(u8)) /* Maximum wait time for a MAC suspend */ -#define WLC_MAX_MAC_SUSPEND 83000 /* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */ +/* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */ +#define BRCMS_MAX_MAC_SUSPEND 83000 /* Probe Response timeout - responses for probe requests older that this are tossed, zero to disable */ -#define WLC_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */ +#define BRCMS_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */ /* transmit buffer max headroom for protocol headers */ #define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN) -/* For managing scan result lists */ -struct wlc_bss_list { - uint count; - bool beacon; /* set for beacon, cleared for probe response */ - wlc_bss_info_t *ptrs[MAXBSS]; -}; +#define AC_COUNT 4 + +/* Macros for doing definition and get/set of bitfields + * Usage example, e.g. a three-bit field (bits 4-6): + * #define _M BITFIELD_MASK(3) + * #define _S 4 + * ... + * regval = R_REG(osh, ®s->regfoo); + * field = GFIELD(regval, ); + * regval = SFIELD(regval, , 1); + * W_REG(osh, ®s->regfoo, regval); + */ +#define BITFIELD_MASK(width) \ + (((unsigned)1 << (width)) - 1) +#define GFIELD(val, field) \ + (((val) >> field ## _S) & field ## _M) +#define SFIELD(val, field, bits) \ + (((val) & (~(field ## _M << field ## _S))) | \ + ((unsigned)(bits) << field ## _S)) #define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */ @@ -52,26 +86,28 @@ struct wlc_bss_list { #define VALID_COREREV(corerev) CONF_HAS(D11CONF, corerev) /* values for shortslot_override */ -#define WLC_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */ -#define WLC_SHORTSLOT_OFF 0 /* Turn off short slot */ -#define WLC_SHORTSLOT_ON 1 /* Turn on short slot */ +#define BRCMS_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */ +#define BRCMS_SHORTSLOT_OFF 0 /* Turn off short slot */ +#define BRCMS_SHORTSLOT_ON 1 /* Turn on short slot */ /* value for short/long and mixmode/greenfield preamble */ - -#define WLC_LONG_PREAMBLE (0) -#define WLC_SHORT_PREAMBLE (1 << 0) -#define WLC_GF_PREAMBLE (1 << 1) -#define WLC_MM_PREAMBLE (1 << 2) -#define WLC_IS_MIMO_PREAMBLE(_pre) (((_pre) == WLC_GF_PREAMBLE) || ((_pre) == WLC_MM_PREAMBLE)) +#define BRCMS_LONG_PREAMBLE (0) +#define BRCMS_SHORT_PREAMBLE (1 << 0) +#define BRCMS_GF_PREAMBLE (1 << 1) +#define BRCMS_MM_PREAMBLE (1 << 2) +#define BRCMS_IS_MIMO_PREAMBLE(_pre) (((_pre) == BRCMS_GF_PREAMBLE) || \ + ((_pre) == BRCMS_MM_PREAMBLE)) /* values for barker_preamble */ -#define WLC_BARKER_SHORT_ALLOWED 0 /* Short pre-amble allowed */ +#define BRCMS_BARKER_SHORT_ALLOWED 0 /* Short pre-amble allowed */ /* A fifo is full. Clear precedences related to that FIFO */ -#define WLC_TX_FIFO_CLEAR(wlc, fifo) ((wlc)->tx_prec_map &= ~(wlc)->fifo2prec_map[fifo]) +#define BRCMS_TX_FIFO_CLEAR(wlc, fifo) \ + ((wlc)->tx_prec_map &= ~(wlc)->fifo2prec_map[fifo]) /* Fifo is NOT full. Enable precedences for that FIFO */ -#define WLC_TX_FIFO_ENAB(wlc, fifo) ((wlc)->tx_prec_map |= (wlc)->fifo2prec_map[fifo]) +#define BRCMS_TX_FIFO_ENAB(wlc, fifo) \ + ((wlc)->tx_prec_map |= (wlc)->fifo2prec_map[fifo]) /* TxFrameID */ /* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */ @@ -90,14 +126,14 @@ struct wlc_bss_list { /* if wpa is in use then portopen is true when the group key is plumbed otherwise it is always true */ #define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) -#define WLC_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \ +#define BRCMS_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \ ((bsscfg)->wsec & WSEC_SWFLAG))) -#define WLC_PORTOPEN(cfg) \ +#define BRCMS_PORTOPEN(cfg) \ (((cfg)->WPA_auth != WPA_AUTH_DISABLED && WSEC_ENABLED((cfg)->wsec)) ? \ (cfg)->wsec_portopen : true) -#define PS_ALLOWED(wlc) wlc_ps_allowed(wlc) +#define PS_ALLOWED(wlc) brcms_c_ps_allowed(wlc) #define DATA_BLOCK_TX_SUPR (1 << 4) @@ -105,11 +141,11 @@ struct wlc_bss_list { extern const u8 prio2fifo[]; /* Ucode MCTL_WAKE override bits */ -#define WLC_WAKE_OVERRIDE_CLKCTL 0x01 -#define WLC_WAKE_OVERRIDE_PHYREG 0x02 -#define WLC_WAKE_OVERRIDE_MACSUSPEND 0x04 -#define WLC_WAKE_OVERRIDE_TXFIFO 0x08 -#define WLC_WAKE_OVERRIDE_FORCEFAST 0x10 +#define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01 +#define BRCMS_WAKE_OVERRIDE_PHYREG 0x02 +#define BRCMS_WAKE_OVERRIDE_MACSUSPEND 0x04 +#define BRCMS_WAKE_OVERRIDE_TXFIFO 0x08 +#define BRCMS_WAKE_OVERRIDE_FORCEFAST 0x10 /* stuff pulled in from wlc.c */ @@ -136,7 +172,7 @@ extern const u8 prio2fifo[]; #define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */ #define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */ -/* Per-AC retry limit register definitions; uses bcmdefs.h bitfield macros */ +/* Per-AC retry limit register definitions; uses defs.h bitfield macros */ #define EDCF_SHORT_S 0 #define EDCF_SFB_S 4 #define EDCF_LONG_S 8 @@ -146,24 +182,34 @@ extern const u8 prio2fifo[]; #define EDCF_LONG_M BITFIELD_MASK(4) #define EDCF_LFB_M BITFIELD_MASK(4) -#define WLC_WME_RETRY_SHORT_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SHORT) -#define WLC_WME_RETRY_SFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_SFB) -#define WLC_WME_RETRY_LONG_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LONG) -#define WLC_WME_RETRY_LFB_GET(wlc, ac) GFIELD(wlc->wme_retries[ac], EDCF_LFB) +#define NFIFO 6 /* # tx/rx fifopairs */ -#define WLC_WME_RETRY_SHORT_SET(wlc, ac, val) \ +#define BRCMS_WME_RETRY_SHORT_GET(wlc, ac) \ + GFIELD(wlc->wme_retries[ac], EDCF_SHORT) +#define BRCMS_WME_RETRY_SFB_GET(wlc, ac) \ + GFIELD(wlc->wme_retries[ac], EDCF_SFB) +#define BRCMS_WME_RETRY_LONG_GET(wlc, ac) \ + GFIELD(wlc->wme_retries[ac], EDCF_LONG) +#define BRCMS_WME_RETRY_LFB_GET(wlc, ac) \ + GFIELD(wlc->wme_retries[ac], EDCF_LFB) + +#define BRCMS_WME_RETRY_SHORT_SET(wlc, ac, val) \ (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SHORT, val)) -#define WLC_WME_RETRY_SFB_SET(wlc, ac, val) \ +#define BRCMS_WME_RETRY_SFB_SET(wlc, ac, val) \ (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_SFB, val)) -#define WLC_WME_RETRY_LONG_SET(wlc, ac, val) \ +#define BRCMS_WME_RETRY_LONG_SET(wlc, ac, val) \ (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LONG, val)) -#define WLC_WME_RETRY_LFB_SET(wlc, ac, val) \ +#define BRCMS_WME_RETRY_LFB_SET(wlc, ac, val) \ (wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac], EDCF_LFB, val)) /* PLL requests */ -#define WLC_PLLREQ_SHARED 0x1 /* pll is shared on old chips */ -#define WLC_PLLREQ_RADIO_MON 0x2 /* hold pll for radio monitor register checking */ -#define WLC_PLLREQ_FLIP 0x4 /* hold/release pll for some short operation */ + +/* pll is shared on old chips */ +#define BRCMS_PLLREQ_SHARED 0x1 +/* hold pll for radio monitor register checking */ +#define BRCMS_PLLREQ_RADIO_MON 0x2 +/* hold/release pll for some short operation */ +#define BRCMS_PLLREQ_FLIP 0x4 /* * Macros to check if AP or STA is active. @@ -194,9 +240,9 @@ extern const u8 prio2fifo[]; (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \ (ai_deviceremoved(wlc->hw->sih))) -#define WLCWLUNIT(wlc) ((wlc)->pub->unit) +#define BRCMS_UNIT(wlc) ((wlc)->pub->unit) -struct wlc_protection { +struct brcms_protection { bool _g; /* use g spec protection, driver internal */ s8 g_override; /* override for use of g spec protection */ u8 gmode_user; /* user config gmode, operating band->gmode is different */ @@ -208,23 +254,10 @@ struct wlc_protection { s8 nongf_override; /* override for use of GF protection */ s8 n_pam_override; /* override for preamble: MM or GF */ bool n_obss; /* indicated OBSS Non-HT STA present */ - - uint longpre_detect_timeout; /* #sec until long preamble bcns gone */ - uint barker_detect_timeout; /* #sec until bcns signaling Barker long preamble */ - /* only is gone */ - uint ofdm_ibss_timeout; /* #sec until ofdm IBSS beacons gone */ - uint ofdm_ovlp_timeout; /* #sec until ofdm overlapping BSS bcns gone */ - uint nonerp_ibss_timeout; /* #sec until nonerp IBSS beacons gone */ - uint nonerp_ovlp_timeout; /* #sec until nonerp overlapping BSS bcns gone */ - uint g_ibss_timeout; /* #sec until bcns signaling Use_Protection gone */ - uint n_ibss_timeout; /* #sec until bcns signaling Use_OFDM_Protection gone */ - uint ht20in40_ovlp_timeout; /* #sec until 20MHz overlapping OPMODE gone */ - uint ht20in40_ibss_timeout; /* #sec until 20MHz-only HT station bcns gone */ - uint non_gf_ibss_timeout; /* #sec until non-GF bcns gone */ }; /* anything affects the single/dual streams/antenna operation */ -struct wlc_stf { +struct brcms_stf { u8 hw_txchain; /* HW txchain bitmap cfg */ u8 txchain; /* txchain bitmap being used */ u8 txstreams; /* number of txchains being used */ @@ -250,60 +283,106 @@ struct wlc_stf { s8 spatial_policy; }; -#define WLC_STF_SS_STBC_TX(wlc, scb) \ +#define BRCMS_STF_SS_STBC_TX(wlc, scb) \ (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \ (SCB_STBC_CAP((scb)) && \ (wlc)->band->band_stf_stbc_tx == AUTO && \ isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC)))) -#define WLC_STBC_CAP_PHY(wlc) (WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) +#define BRCMS_STBC_CAP_PHY(wlc) (BRCMS_ISNPHY(wlc->band) && \ + NREV_GE(wlc->band->phyrev, 3)) -#define WLC_SGI_CAP_PHY(wlc) ((WLCISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3)) || \ - WLCISLCNPHY(wlc->band)) +#define BRCMS_SGI_CAP_PHY(wlc) ((BRCMS_ISNPHY(wlc->band) && \ + NREV_GE(wlc->band->phyrev, 3)) || \ + BRCMS_ISLCNPHY(wlc->band)) -#define WLC_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT) -#define WLC_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) >> RXS_CHAN_ID_SHIFT) -#define WLC_RX_CHANNEL(rxh) (WLC_CHAN_CHANNEL((rxh)->RxChan)) +#define BRCMS_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) \ + >> RXS_CHAN_PHYTYPE_SHIFT) +#define BRCMS_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) \ + >> RXS_CHAN_ID_SHIFT) +#define BRCMS_RX_CHANNEL(rxh) (BRCMS_CHAN_CHANNEL((rxh)->RxChan)) -/* wlc_bss_info flag bit values */ -#define WLC_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ +/* brcms_bss_info flag bit values */ +#define BRCMS_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ -/* Flags used in wlc_txq_info.stopped */ +/* Flags used in brcms_c_txq_info.stopped */ #define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF /* per prio flow control bits */ #define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 /* stop txq enqueue for packet drain */ #define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 /* stop txq enqueue for ampdu flow control */ -#define WLC_HT_WEP_RESTRICT 0x01 /* restrict HT with WEP */ -#define WLC_HT_TKIP_RESTRICT 0x02 /* restrict HT with TKIP */ +#define BRCMS_HT_WEP_RESTRICT 0x01 /* restrict HT with WEP */ +#define BRCMS_HT_TKIP_RESTRICT 0x02 /* restrict HT with TKIP */ + +/* Maximum # of keys that wl driver supports in S/W. + * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS. + */ +#define WSEC_MAX_KEYS 54 /* Max # of keys (50 + 4 default keys) */ +#define BRCMS_DEFAULT_KEYS 4 /* Default # of keys */ + +/* +* Max # of keys currently supported: +* +* s/w keys if WSEC_SW(wlc->wsec). +* h/w keys otherwise. +*/ +#define BRCMS_MAX_WSEC_KEYS(wlc) WSEC_MAX_KEYS + +/* number of 802.11 default (non-paired, group keys) */ +#define WSEC_MAX_DEFAULT_KEYS 4 /* # of default keys */ + +struct wsec_iv { + u32 hi; /* upper 32 bits of IV */ + u16 lo; /* lower 16 bits of IV */ +}; + +#define BRCMS_NUMRXIVS 16 /* # rx IVs (one per 802.11e TID) */ + +struct wsec_key { + u8 ea[ETH_ALEN]; /* per station */ + u8 idx; /* key index in wsec_keys array */ + u8 id; /* key ID [0-3] */ + u8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ + u8 rcmta; /* rcmta entry index, same as idx by default */ + u16 flags; /* misc flags */ + u8 algo_hw; /* cache for hw register */ + u8 aes_mode; /* cache for hw register */ + s8 iv_len; /* IV length */ + s8 icv_len; /* ICV length */ + u32 len; /* key length..don't move this var */ + /* data is 4byte aligned */ + u8 data[WLAN_MAX_KEY_LEN]; /* key data */ + struct wsec_iv rxiv[BRCMS_NUMRXIVS]; /* Rx IV (one per TID) */ + struct wsec_iv txiv; /* Tx IV */ +}; /* * core state (mac) */ -struct wlccore { +struct brcms_core { uint coreidx; /* # sb enumerated core */ /* fifo */ uint *txavail[NFIFO]; /* # tx descriptors available */ s16 txpktpend[NFIFO]; /* tx admission control */ - macstat_t *macstat_snapshot; /* mac hw prev read values */ + struct macstat *macstat_snapshot; /* mac hw prev read values */ }; /* * band state (phy+ana+radio) */ -struct wlcband { - int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ +struct brcms_band { + int bandtype; /* BRCM_BAND_2G, BRCM_BAND_5G */ uint bandunit; /* bandstate[] index */ u16 phytype; /* phytype */ u16 phyrev; u16 radioid; u16 radiorev; - wlc_phy_t *pi; /* pointer to phy specific information */ + struct brcms_phy_pub *pi; /* pointer to phy specific information */ bool abgphy_encore; - u8 gmode; /* currently active gmode (see wlioctl.h) */ + u8 gmode; /* currently active gmode */ struct scb *hwrs_scb; /* permanent scb for hw rateset */ @@ -314,7 +393,7 @@ struct wlcband { u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */ s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */ wlc_rateset_t hw_rateset; /* rates supported by chip (phy-specific) */ - u8 basic_rate[WLC_MAXRATE + 1]; /* basic rates indexed by rate */ + u8 basic_rate[BRCM_MAXRATE + 1]; /* basic rates indexed by rate */ bool mimo_cap_40; /* 40 MHz cap enabled on this band */ s8 antgain; /* antenna gain from srom */ @@ -324,7 +403,7 @@ struct wlcband { }; /* tx completion callback takes 3 args */ -typedef void (*pkcb_fn_t) (struct wlc_info *wlc, uint txstatus, void *arg); +typedef void (*pkcb_fn_t) (struct brcms_c_info *wlc, uint txstatus, void *arg); struct pkt_cb { pkcb_fn_t fn; /* function to call when tx frame completes */ @@ -336,7 +415,7 @@ struct pkt_cb { /* module control blocks */ struct modulecb { char name[32]; /* module name : NULL indicates empty array member */ - const bcm_iovar_t *iovars; /* iovar table */ + const struct brcmu_iovar *iovars; /* iovar table */ void *hdl; /* handle passed when handler 'doiovar' is called */ watchdog_fn_t watchdog_fn; /* watchdog handler */ iovar_fn_t iovar_fn; /* iovar handler */ @@ -355,28 +434,46 @@ struct dumpcb_s { struct dumpcb_s *next; }; +struct edcf_acparam { + u8 ACI; + u8 ECW; + u16 TXOP; +} __packed; + +struct wme_param_ie { + u8 oui[3]; + u8 type; + u8 subtype; + u8 version; + u8 qosinfo; + u8 rsvd; + struct edcf_acparam acparam[AC_COUNT]; +} __packed; + /* virtual interface */ -struct wlc_if { - struct wlc_if *next; - u8 type; /* WLC_IFTYPE_BSS or WLC_IFTYPE_WDS */ +struct brcms_c_if { + struct brcms_c_if *next; + u8 type; /* BSS or WDS */ u8 index; /* assigned in wl_add_if(), index of the wlif if any, * not necessarily corresponding to bsscfg._idx or * AID2PVBMAP(scb). */ u8 flags; /* flags for the interface */ - struct wl_if *wlif; /* pointer to wlif */ - struct wlc_txq_info *qi; /* pointer to associated tx queue */ + struct brcms_if *wlif; /* pointer to wlif */ + struct brcms_txq_info *qi; /* pointer to associated tx queue */ union { - struct scb *scb; /* pointer to scb if WLC_IFTYPE_WDS */ - struct wlc_bsscfg *bsscfg; /* pointer to bsscfg if WLC_IFTYPE_BSS */ + /* pointer to scb if WDS */ + struct scb *scb; + /* pointer to bsscfg if BSS */ + struct brcms_bss_cfg *bsscfg; } u; }; -/* flags for the interface */ -#define WLC_IF_LINKED 0x02 /* this interface is linked to a wl_if */ +/* flags for the interface, this interface is linked to a brcms_if */ +#define BRCMS_IF_LINKED 0x02 -struct wlc_hwband { - int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ +struct brcms_hw_band { + int bandtype; /* BRCM_BAND_2G, BRCM_BAND_5G */ uint bandunit; /* bandstate[] index */ u16 mhfs[MHFMAX]; /* MHF array shadow */ u8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */ @@ -388,16 +485,16 @@ struct wlc_hwband { u16 phyrev; u16 radioid; u16 radiorev; - wlc_phy_t *pi; /* pointer to phy specific information */ + struct brcms_phy_pub *pi; /* pointer to phy specific information */ bool abgphy_encore; }; -struct wlc_hw_info { +struct brcms_hardware { bool _piomode; /* true if pio mode */ - struct wlc_info *wlc; + struct brcms_c_info *wlc; /* fifo */ - struct hnddma_pub *di[NFIFO]; /* hnddma handles, per fifo */ + struct dma_pub *di[NFIFO]; /* dma handles, per fifo */ uint unit; /* device instance number */ @@ -413,14 +510,15 @@ struct wlc_hw_info { u32 machwcap_backup; /* backup of machwcap */ u16 ucode_dbgsel; /* dbgsel for ucode debug(config gpio) */ - si_t *sih; /* SB handle (cookie for siutils calls) */ + struct si_pub *sih; /* SI handle (cookie for siutils calls) */ char *vars; /* "environment" name=value */ uint vars_size; /* size of vars, free vars on detach */ d11regs_t *regs; /* pointer to device registers */ void *physhim; /* phy shim layer handler */ void *phy_sh; /* pointer to shared phy state */ - struct wlc_hwband *band;/* pointer to active per-band state */ - struct wlc_hwband *bandstate[MAXBANDS];/* band state per phy/radio */ + struct brcms_hw_band *band;/* pointer to active per-band state */ + /* band state per phy/radio */ + struct brcms_hw_band *bandstate[MAXBANDS]; u16 bmac_phytxant; /* cache of high phytxant state */ bool shortslot; /* currently using 11g ShortSlot timing */ u16 SRL; /* 802.11 dot11ShortRetryLimit */ @@ -473,8 +571,8 @@ struct wlc_hw_info { * if they belong to the same flow of traffic from the device. For multi-channel * operation there are independent TX Queues for each channel. */ -struct wlc_txq_info { - struct wlc_txq_info *next; +struct brcms_txq_info { + struct brcms_txq_info *next; struct pktq q; uint stopped; /* tx flow control bits */ }; @@ -482,12 +580,13 @@ struct wlc_txq_info { /* * Principal common (os-independent) software data structure. */ -struct wlc_info { - struct wlc_pub *pub; /* pointer to wlc public state */ - struct wl_info *wl; /* pointer to os-specific private state */ +struct brcms_c_info { + struct brcms_pub *pub; /* pointer to wlc public state */ + struct brcms_info *wl; /* pointer to os-specific private state */ d11regs_t *regs; /* pointer to device registers */ - struct wlc_hw_info *hw; /* HW related state used primarily by BMAC */ + /* HW related state used primarily by BMAC */ + struct brcms_hardware *hw; /* clock */ int clkreq_override; /* setting for clkreq for PCIE : Auto, 0, 1 */ @@ -504,11 +603,11 @@ struct wlc_info { bool clk; /* core is out of reset and has clock */ /* multiband */ - struct wlccore *core; /* pointer to active io core */ - struct wlcband *band; /* pointer to active per-band state */ - struct wlccore *corestate; /* per-core state (one per hw core) */ + struct brcms_core *core; /* pointer to active io core */ + struct brcms_band *band; /* pointer to active per-band state */ + struct brcms_core *corestate; /* per-core state (one per hw core) */ /* per-band state (one per phy/radio): */ - struct wlcband *bandstate[MAXBANDS]; + struct brcms_band *bandstate[MAXBANDS]; bool war16165; /* PCI slow clock 16165 war flag */ @@ -526,9 +625,7 @@ struct wlc_info { struct ampdu_info *ampdu; /* ampdu module handler */ struct antsel_info *asi; /* antsel module handler */ - wlc_cm_info_t *cmi; /* channel manager module handler */ - - void *btparam; /* bus type specific cookie */ + struct brcms_cm_info *cmi; /* channel manager module handler */ uint vars_size; /* size of vars, free vars on detach */ @@ -544,25 +641,18 @@ struct wlc_info { bool bandinit_pending; /* track band init in auto band */ bool radio_monitor; /* radio timer is running */ - bool down_override; /* true=down */ bool going_down; /* down path intermediate variable */ bool mpc; /* enable minimum power consumption */ u8 mpc_dlycnt; /* # of watchdog cnt before turn disable radio */ u8 mpc_offcnt; /* # of watchdog cnt that radio is disabled */ u8 mpc_delay_off; /* delay radio disable by # of watchdog cnt */ - u8 prev_non_delay_mpc; /* prev state wlc_is_non_delay_mpc */ + u8 prev_non_delay_mpc; /* prev state brcms_c_is_non_delay_mpc */ - /* timer */ - struct wl_timer *wdtimer; /* timer for watchdog routine */ - uint fast_timer; /* Periodic timeout for 'fast' timer */ - uint slow_timer; /* Periodic timeout for 'slow' timer */ - uint glacial_timer; /* Periodic timeout for 'glacial' timer */ - uint phycal_mlo; /* last time measurelow calibration was done */ - uint phycal_txpower; /* last time txpower calibration was done */ - - struct wl_timer *radio_timer; /* timer for hw radio button monitor routine */ - struct wl_timer *pspoll_timer; /* periodic pspoll timer */ + /* timer for watchdog routine */ + struct brcms_timer *wdtimer; + /* timer for hw radio button monitor routine */ + struct brcms_timer *radio_timer; /* promiscuous */ bool monitor; /* monitor (MPDU sniffing) mode */ @@ -570,30 +660,11 @@ struct wlc_info { bool bcnmisc_scan; /* bcns promisc mode override for scan */ bool bcnmisc_monitor; /* bcns promisc mode override for monitor */ - u8 bcn_wait_prd; /* max waiting period (for beacon) in 1024TU */ - /* driver feature */ bool _rifs; /* enable per-packet rifs */ - s32 rifs_advert; /* RIFS mode advertisement */ s8 sgi_tx; /* sgi tx */ - bool wet; /* true if wireless ethernet bridging mode */ /* AP-STA synchronization, power save */ - bool check_for_unaligned_tbtt; /* check unaligned tbtt flag */ - bool PM_override; /* no power-save flag, override PM(user input) */ - bool PMenabled; /* current power-management state (CAM or PS) */ - bool PMpending; /* waiting for tx status with PM indicated set */ - bool PMblocked; /* block any PSPolling in PS mode, used to buffer - * AP traffic, also used to indicate in progress - * of scan, rm, etc. off home channel activity. - */ - bool PSpoll; /* whether there is an outstanding PS-Poll frame */ - u8 PM; /* power-management mode (CAM, PS or FASTPS) */ - bool PMawakebcn; /* bcn recvd during current waking state */ - - bool WME_PM_blocked; /* Can STA go to PM when in WME Auto mode */ - bool wake; /* host-specified PS-mode sleep state */ - u8 pspoll_prd; /* pspoll interval in milliseconds */ u8 bcn_li_bcn; /* beacon listen interval in # beacons */ u8 bcn_li_dtim; /* beacon listen interval in # dtims */ @@ -602,18 +673,16 @@ struct wlc_info { /* WME */ ac_bitmap_t wme_dp; /* Discard (oldest first) policy per AC */ - bool wme_apsd; /* enable Advanced Power Save Delivery */ - ac_bitmap_t wme_admctl; /* bit i set if AC i under admission control */ u16 edcf_txop[AC_COUNT]; /* current txop for each ac */ - wme_param_ie_t wme_param_ie; /* WME parameter info element, which on STA - * contains parameters in use locally, and on - * AP contains parameters advertised to STA - * in beacons and assoc responses. - */ - bool wme_prec_queuing; /* enable/disable non-wme STA prec queuing */ + + /* + * WME parameter info element, which on STA contains parameters in use + * locally, and on AP contains parameters advertised to STA in beacons + * and assoc responses. + */ + struct wme_param_ie wme_param_ie; u16 wme_retries[AC_COUNT]; /* per-AC retry limits */ - int vlan_mode; /* OK to use 802.1Q Tags (ON, OFF, AUTO) */ u16 tx_prec_map; /* Precedence map based on HW FIFO space */ u16 fifo2prec_map[NFIFO]; /* pointer to fifo2_prec map based on WME */ @@ -621,60 +690,36 @@ struct wlc_info { * BSS Configurations set of BSS configurations, idx 0 is default and * always valid */ - struct wlc_bsscfg *bsscfg[WLC_MAXBSSCFG]; - struct wlc_bsscfg *cfg; /* the primary bsscfg (can be AP or STA) */ - u8 stas_associated; /* count of ASSOCIATED STA bsscfgs */ - u8 aps_associated; /* count of UP AP bsscfgs */ - u8 block_datafifo; /* prohibit posting frames to data fifos */ - bool bcmcfifo_drain; /* TX_BCMC_FIFO is set to drain */ + struct brcms_bss_cfg *bsscfg[BRCMS_MAXBSSCFG]; + struct brcms_bss_cfg *cfg; /* the primary bsscfg (can be AP or STA) */ /* tx queue */ - struct wlc_txq_info *tx_queues; /* common TX Queue list */ + struct brcms_txq_info *tx_queues; /* common TX Queue list */ /* security */ - wsec_key_t *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */ - wsec_key_t *wsec_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ + struct wsec_key *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */ + /* default key storage */ + struct wsec_key *wsec_def_keys[BRCMS_DEFAULT_KEYS]; bool wsec_swkeys; /* indicates that all keys should be * treated as sw keys (used for debugging) */ struct modulecb *modulecb; - struct dumpcb_s *dumpcb_head; u8 mimoft; /* SIGN or 11N */ - u8 mimo_band_bwcap; /* bw cap per band type */ - s8 txburst_limit_override; /* tx burst limit override */ - u16 txburst_limit; /* tx burst limit value */ s8 cck_40txbw; /* 11N, cck tx b/w override when in 40MHZ mode */ s8 ofdm_40txbw; /* 11N, ofdm tx b/w override when in 40MHZ mode */ s8 mimo_40txbw; /* 11N, mimo tx b/w override when in 40MHZ mode */ /* HT CAP IE being advertised by this node: */ struct ieee80211_ht_cap ht_cap; - uint seckeys; /* 54 key table shm address */ - uint tkmickeys; /* 12 TKIP MIC key table shm address */ + struct brcms_bss_info *default_bss; /* configured BSS parameters */ - wlc_bss_info_t *default_bss; /* configured BSS parameters */ - - u16 AID; /* association ID */ - u16 counter; /* per-sdu monotonically increasing counter */ u16 mc_fid_counter; /* BC/MC FIFO frame ID counter */ - bool ibss_allowed; /* false, all IBSS will be ignored during a scan - * and the driver will not allow the creation of - * an IBSS network - */ - bool ibss_coalesce_allowed; - - char country_default[WLC_CNTRY_BUF_SZ]; /* saved country for leaving 802.11d - * auto-country mode - */ - char autocountry_default[WLC_CNTRY_BUF_SZ]; /* initial country for 802.11d - * auto-country mode - */ -#ifdef BCMDBG - bcm_tlv_t *country_ie_override; /* debug override of announced Country IE */ -#endif - + /* saved country for leaving 802.11d auto-country mode */ + char country_default[BRCM_CNTRY_BUF_SZ]; + /* initial country for 802.11d auto-country mode */ + char autocountry_default[BRCM_CNTRY_BUF_SZ]; u16 prb_resp_timeout; /* do not send prb resp if request older than this, * 0 = disable */ @@ -696,44 +741,17 @@ struct wlc_info { u16 LFBL; /* Long Frame Rate Fallback Limit */ /* network config */ - bool shortpreamble; /* currently operating with CCK ShortPreambles */ bool shortslot; /* currently using 11g ShortSlot timing */ - s8 barker_preamble; /* current Barker Preamble Mode */ s8 shortslot_override; /* 11g ShortSlot override */ bool include_legacy_erp; /* include Legacy ERP info elt ID 47 as well as g ID 42 */ - bool barker_overlap_control; /* true: be aware of overlapping BSSs for barker */ - bool ignore_bcns; /* override: ignore non shortslot bcns in a 11g network */ - bool legacy_probe; /* restricts probe requests to CCK rates */ - struct wlc_protection *protection; + struct brcms_protection *protection; s8 PLCPHdr_override; /* 802.11b Preamble Type override */ - struct wlc_stf *stf; - - struct pkt_cb *pkt_callback; /* tx completion callback handlers */ - - u32 txretried; /* tx retried number in one msdu */ + struct brcms_stf *stf; ratespec_t bcn_rspec; /* save bcn ratespec purpose */ - bool apsd_sta_usp; /* Unscheduled Service Period in progress on STA */ - struct wl_timer *apsd_trigger_timer; /* timer for wme apsd trigger frames */ - u32 apsd_trigger_timeout; /* timeout value for apsd_trigger_timer (in ms) - * 0 == disable - */ - ac_bitmap_t apsd_trigger_ac; /* Permissible Access Category in which APSD Null - * Trigger frames can be send - */ - u8 htphy_membership; /* HT PHY membership */ - - bool _regulatory_domain; /* 802.11d enabled? */ - - u8 mimops_PM; - - u8 txpwr_percent; /* power output percentage */ - - u8 ht_wsec_restriction; /* the restriction of HT with TKIP or WEP */ - uint tempsense_lasttime; u16 tx_duty_cycle_ofdm; /* maximum allowed duty cycle for OFDM */ @@ -741,30 +759,107 @@ struct wlc_info { u16 next_bsscfg_ID; - struct wlc_if *wlcif_list; /* linked list of wlc_if structs */ - struct wlc_txq_info *pkt_queue; /* txq for transmit packets */ + struct brcms_txq_info *pkt_queue; /* txq for transmit packets */ u32 mpc_dur; /* total time (ms) in mpc mode except for the * portion since radio is turned off last time */ u32 mpc_laston_ts; /* timestamp (ms) when radio is turned off last * time */ - bool pr80838_war; - uint hwrxoff; struct wiphy *wiphy; }; /* antsel module specific state */ struct antsel_info { - struct wlc_info *wlc; /* pointer to main wlc structure */ - struct wlc_pub *pub; /* pointer to public fn */ + struct brcms_c_info *wlc; /* pointer to main wlc structure */ + struct brcms_pub *pub; /* pointer to public fn */ u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board */ u8 antsel_antswitch; /* board level antenna switch type */ bool antsel_avail; /* Ant selection availability (SROM based) */ - wlc_antselcfg_t antcfg_11n; /* antenna configuration */ - wlc_antselcfg_t antcfg_cur; /* current antenna config (auto) */ + struct brcms_antselcfg antcfg_11n; /* antenna configuration */ + struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */ +}; + +/* BSS configuration state */ +struct brcms_bss_cfg { + struct brcms_c_info *wlc; /* wlc to which this bsscfg belongs to. */ + bool up; /* is this configuration up operational */ + bool enable; /* is this configuration enabled */ + bool associated; /* is BSS in ASSOCIATED state */ + bool BSS; /* infraustructure or adhac */ + bool dtim_programmed; + + u8 SSID_len; /* the length of SSID */ + u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */ + struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */ + s8 _idx; /* the index of this bsscfg, + * assigned at wlc_bsscfg_alloc() + */ + /* MAC filter */ + uint nmac; /* # of entries on maclist array */ + int macmode; /* allow/deny stations on maclist array */ + struct ether_addr *maclist; /* list of source MAC addrs to match */ + + /* security */ + u32 wsec; /* wireless security bitvec */ + s16 auth; /* 802.11 authentication: Open, Shared Key, WPA */ + s16 openshared; /* try Open auth first, then Shared Key */ + bool wsec_restrict; /* drop unencrypted packets if wsec is enabled */ + bool eap_restrict; /* restrict data until 802.1X auth succeeds */ + u16 WPA_auth; /* WPA: authenticated key management */ + bool wpa2_preauth; /* default is true, wpa_cap sets value */ + bool wsec_portopen; /* indicates keys are plumbed */ + /* global txiv for WPA_NONE, tkip and aes */ + struct wsec_iv wpa_none_txiv; + int wsec_index; /* 0-3: default tx key, -1: not set */ + /* default key storage: */ + struct wsec_key *bss_def_keys[BRCMS_DEFAULT_KEYS]; + + /* TKIP countermeasures */ + bool tkip_countermeasures; /* flags TKIP no-assoc period */ + u32 tk_cm_dt; /* detect timer */ + u32 tk_cm_bt; /* blocking timer */ + u32 tk_cm_bt_tmstmp; /* Timestamp when TKIP BT is activated */ + bool tk_cm_activate; /* activate countermeasures after EAPOL-Key sent */ + + u8 BSSID[ETH_ALEN]; /* BSSID (associated) */ + u8 cur_etheraddr[ETH_ALEN]; /* h/w address */ + u16 bcmc_fid; /* the last BCMC FID queued to TX_BCMC_FIFO */ + u16 bcmc_fid_shm; /* the last BCMC FID written to shared mem */ + + u32 flags; /* BSSCFG flags; see below */ + + u8 *bcn; /* AP beacon */ + uint bcn_len; /* AP beacon length */ + bool ar_disassoc; /* disassociated in associated recreation */ + + int auth_atmptd; /* auth type (open/shared) attempted */ + + pmkid_cand_t pmkid_cand[MAXPMKID]; /* PMKID candidate list */ + uint npmkid_cand; /* num PMKID candidates */ + pmkid_t pmkid[MAXPMKID]; /* PMKID cache */ + uint npmkid; /* num cached PMKIDs */ + + struct brcms_bss_info *current_bss; /* BSS parms in ASSOCIATED state */ + + /* PM states */ + bool PMawakebcn; /* bcn recvd during current waking state */ + bool PMpending; /* waiting for tx status with PM indicated set */ + bool priorPMstate; /* Detecting PM state transitions */ + bool PSpoll; /* whether there is an outstanding PS-Poll frame */ + + /* BSSID entry in RCMTA, use the wsec key management infrastructure to + * manage the RCMTA entries. + */ + struct wsec_key *rcmta; + + /* 'unique' ID of this bsscfg, assigned at bsscfg allocation */ + u16 ID; + + uint txrspecidx; /* index into tx rate circular buffer */ + ratespec_t txrspec[NTXRATE][2]; /* circular buffer of prev MPDUs tx rates */ }; #define CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX) @@ -773,7 +868,7 @@ struct antsel_info { #define IS_MBAND_UNLOCKED(wlc) \ ((NBANDS(wlc) > 1) && !(wlc)->bandlocked) -#define WLC_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi) +#define BRCMS_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi) /* sum the individual fifo tx pending packet counts */ #define TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \ @@ -784,156 +879,147 @@ struct antsel_info { #define TXPKTPENDCLR(wlc, fifo) ((wlc)->core->txpktpend[(fifo)] = 0) #define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)]) #define GETNEXTTXP(wlc, _queue) \ - dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED) + dma_getnexttxp((wlc)->hw->di[(_queue)], DMA_RANGE_TRANSMITTED) -#define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ +#define BRCMS_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ ((len1 == len2) && !memcmp(ssid1, ssid2, len1)) -extern void wlc_fatal_error(struct wlc_info *wlc); -extern void wlc_bmac_rpc_watchdog(struct wlc_info *wlc); -extern void wlc_recv(struct wlc_info *wlc, struct sk_buff *p); -extern bool wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2); -extern void wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, - bool commit, s8 txpktpend); -extern void wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend); -extern void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, - uint prec); -extern void wlc_info_init(struct wlc_info *wlc, int unit); -extern void wlc_print_txstatus(tx_status_t *txs); -extern int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks); -extern void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, - void *buf); -extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, - bool both); -extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin); -extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax); -extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit); -extern void wlc_reset_bmac_done(struct wlc_info *wlc); +extern void brcms_c_fatal_error(struct brcms_c_info *wlc); +extern void brcms_b_rpc_watchdog(struct brcms_c_info *wlc); +extern void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p); +extern bool brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs, + u32 frm_tx2); +extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, + struct sk_buff *p, + bool commit, s8 txpktpend); +extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, + s8 txpktpend); +extern void brcms_c_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, + uint prec); +extern void brcms_c_info_init(struct brcms_c_info *wlc, int unit); +extern void brcms_c_print_txstatus(struct tx_status *txs); +extern int brcms_c_xmtfifo_sz_get(struct brcms_c_info *wlc, uint fifo, + uint *blocks); +extern void brcms_c_write_template_ram(struct brcms_c_info *wlc, int offset, + int len, void *buf); +extern void brcms_c_write_hw_bcntemplates(struct brcms_c_info *wlc, void *bcn, + int len, bool both); +extern void brcms_c_pllreq(struct brcms_c_info *wlc, bool set, mbool req_bit); +extern void brcms_c_reset_bmac_done(struct brcms_c_info *wlc); #if defined(BCMDBG) -extern void wlc_print_rxh(d11rxhdr_t *rxh); -extern void wlc_print_hdrs(struct wlc_info *wlc, const char *prefix, u8 *frame, - d11txh_t *txh, d11rxhdr_t *rxh, uint len); -extern void wlc_print_txdesc(d11txh_t *txh); +extern void brcms_c_print_rxh(struct d11rxhdr *rxh); +extern void brcms_c_print_txdesc(struct d11txh *txh); #else -#define wlc_print_txdesc(a) -#endif -#if defined(BCMDBG) -extern void wlc_print_dot11_mac_hdr(u8 *buf, int len); +#define brcms_c_print_txdesc(a) #endif -extern void wlc_setxband(struct wlc_hw_info *wlc_hw, uint bandunit); -extern void wlc_coredisable(struct wlc_hw_info *wlc_hw); +extern void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit); +extern void brcms_c_coredisable(struct brcms_hardware *wlc_hw); -extern bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rate, int band, - bool verbose); -extern void wlc_ap_upd(struct wlc_info *wlc); +extern bool brcms_c_valid_rate(struct brcms_c_info *wlc, ratespec_t rate, + int band, bool verbose); +extern void brcms_c_ap_upd(struct brcms_c_info *wlc); /* helper functions */ -extern void wlc_shm_ssid_upd(struct wlc_info *wlc, struct wlc_bsscfg *cfg); -extern int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config); +extern void brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, + struct brcms_bss_cfg *cfg); +extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); -extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); -extern void wlc_mac_bcn_promisc(struct wlc_info *wlc); -extern void wlc_mac_promisc(struct wlc_info *wlc); -extern void wlc_txflowcontrol(struct wlc_info *wlc, struct wlc_txq_info *qi, - bool on, int prio); -extern void wlc_txflowcontrol_override(struct wlc_info *wlc, - struct wlc_txq_info *qi, +extern void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, + bool promisc); +extern void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc); +extern void brcms_c_mac_promisc(struct brcms_c_info *wlc); +extern void brcms_c_txflowcontrol(struct brcms_c_info *wlc, + struct brcms_txq_info *qi, + bool on, int prio); +extern void brcms_c_txflowcontrol_override(struct brcms_c_info *wlc, + struct brcms_txq_info *qi, bool on, uint override); -extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, - struct wlc_txq_info *qi, int prio); -extern void wlc_send_q(struct wlc_info *wlc); -extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo); +extern bool brcms_c_txflowcontrol_prio_isset(struct brcms_c_info *wlc, + struct brcms_txq_info *qi, + int prio); +extern void brcms_c_send_q(struct brcms_c_info *wlc); +extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, + uint *fifo); -extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, +extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, ratespec_t ratespec, uint mac_len); -extern ratespec_t wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, - bool use_rspec, u16 mimo_ctlchbw); -extern u16 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, - ratespec_t rts_rate, ratespec_t frame_rate, - u8 rts_preamble_type, - u8 frame_preamble_type, uint frame_len, - bool ba); +extern ratespec_t brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, + ratespec_t rspec, + bool use_rspec, u16 mimo_ctlchbw); +extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only, + ratespec_t rts_rate, + ratespec_t frame_rate, + u8 rts_preamble_type, + u8 frame_preamble_type, uint frame_len, + bool ba); -extern void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs); -extern void wlc_inval_dma_pkts(struct wlc_hw_info *hw, +extern void brcms_c_tbtt(struct brcms_c_info *wlc); +extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw, struct ieee80211_sta *sta, void (*dma_callback_fn)); -#if defined(BCMDBG) -extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie, - struct bcmstrbuf *b); -#endif - -extern void wlc_reprate_init(struct wlc_info *wlc); -extern void wlc_bsscfg_reprate_init(struct wlc_bsscfg *bsscfg); +extern void brcms_c_reprate_init(struct brcms_c_info *wlc); +extern void brcms_c_bsscfg_reprate_init(struct brcms_bss_cfg *bsscfg); /* Shared memory access */ -extern void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v); -extern u16 wlc_read_shm(struct wlc_info *wlc, uint offset); -extern void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, - int len); +extern void brcms_c_write_shm(struct brcms_c_info *wlc, uint offset, u16 v); +extern u16 brcms_c_read_shm(struct brcms_c_info *wlc, uint offset); +extern void brcms_c_copyto_shm(struct brcms_c_info *wlc, uint offset, + const void *buf, int len); -extern void wlc_update_beacon(struct wlc_info *wlc); -extern void wlc_bss_update_beacon(struct wlc_info *wlc, - struct wlc_bsscfg *bsscfg); +extern void brcms_c_update_beacon(struct brcms_c_info *wlc); +extern void brcms_c_bss_update_beacon(struct brcms_c_info *wlc, + struct brcms_bss_cfg *bsscfg); -extern void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend); -extern void wlc_bss_update_probe_resp(struct wlc_info *wlc, - struct wlc_bsscfg *cfg, bool suspend); - -extern bool wlc_ismpc(struct wlc_info *wlc); -extern bool wlc_is_non_delay_mpc(struct wlc_info *wlc); -extern void wlc_radio_mpc_upd(struct wlc_info *wlc); -extern bool wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, - int prec); -extern bool wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, +extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend); +extern void brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc, + struct brcms_bss_cfg *cfg, + bool suspend); +extern bool brcms_c_ismpc(struct brcms_c_info *wlc); +extern bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc); +extern void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc); +extern bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q, + void *pkt, int prec); +extern bool brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q, struct sk_buff *pkt, int prec, bool head); -extern u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec); -extern void wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rate, uint length, - u8 *plcp); -extern uint wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, - u8 preamble_type, uint mac_len); +extern u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, ratespec_t rspec); +extern void brcms_c_compute_plcp(struct brcms_c_info *wlc, ratespec_t rate, + uint length, u8 *plcp); +extern uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, + ratespec_t ratespec, + u8 preamble_type, uint mac_len); -extern void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec); +extern void brcms_c_set_chanspec(struct brcms_c_info *wlc, + chanspec_t chanspec); -extern bool wlc_timers_init(struct wlc_info *wlc, int unit); +extern bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit); -extern const bcm_iovar_t wlc_iovars[]; - -extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, - const char *name, void *params, uint p_len, void *arg, - int len, int val_size, struct wlc_if *wlcif); - -#if defined(BCMDBG) -extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len); -#endif - -extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode); -extern void wlc_mimops_action_ht_send(struct wlc_info *wlc, - struct wlc_bsscfg *bsscfg, +extern int brcms_c_set_nmode(struct brcms_c_info *wlc, s32 nmode); +extern void brcms_c_mimops_action_ht_send(struct brcms_c_info *wlc, + struct brcms_bss_cfg *bsscfg, u8 mimops_mode); -extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot); -extern void wlc_set_bssid(struct wlc_bsscfg *cfg); -extern void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend); +extern void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot); +extern void brcms_c_set_bssid(struct brcms_bss_cfg *cfg); +extern void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend); -extern void wlc_set_ratetable(struct wlc_info *wlc); -extern int wlc_set_mac(struct wlc_bsscfg *cfg); -extern void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, +extern void brcms_c_set_ratetable(struct brcms_c_info *wlc); +extern int brcms_c_set_mac(struct brcms_bss_cfg *cfg); +extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, ratespec_t bcn_rate); -extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len); -extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, - wlc_rateset_t *rs); -extern void wlc_radio_disable(struct wlc_info *wlc); -extern void wlc_bcn_li_upd(struct wlc_info *wlc); +extern void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, + uint frame_len); +extern ratespec_t brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc, + wlc_rateset_t *rs); +extern void brcms_c_radio_disable(struct brcms_c_info *wlc); +extern void brcms_c_bcn_li_upd(struct brcms_c_info *wlc); +extern void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, + chanspec_t chanspec); +extern bool brcms_c_ps_allowed(struct brcms_c_info *wlc); +extern bool brcms_c_stay_awake(struct brcms_c_info *wlc); +extern void brcms_c_wme_initparams_sta(struct brcms_c_info *wlc, + struct wme_param_ie *pe); -extern int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len); -extern void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec); -extern void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt); -extern bool wlc_ps_allowed(struct wlc_info *wlc); -extern bool wlc_stay_awake(struct wlc_info *wlc); -extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe); - -#endif /* _wlc_h_ */ +#endif /* _BRCM_MAIN_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/nicpci.c b/drivers/staging/brcm80211/brcmsmac/nicpci.c index 18b844a8d2fb..3d71c590fcef 100644 --- a/drivers/staging/brcm80211/brcmsmac/nicpci.c +++ b/drivers/staging/brcm80211/brcmsmac/nicpci.c @@ -14,78 +14,245 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -typedef struct { +#include +#include +#include +#include "aiutils.h" +#include "pub.h" +#include "nicpci.h" + +/* SPROM offsets */ +#define SRSH_ASPM_OFFSET 4 /* word 4 */ +#define SRSH_ASPM_ENB 0x18 /* bit 3, 4 */ +#define SRSH_ASPM_L1_ENB 0x10 /* bit 4 */ +#define SRSH_ASPM_L0s_ENB 0x8 /* bit 3 */ + +#define SRSH_PCIE_MISC_CONFIG 5 /* word 5 */ +#define SRSH_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */ +#define SRSH_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */ +#define SRSH_CLKREQ_ENB 0x0800 /* bit 11 */ +#define SRSH_BD_OFFSET 6 /* word 6 */ + +/* chipcontrol */ +#define CHIPCTRL_4321_PLL_DOWN 0x800000/* serdes PLL down override */ + +/* MDIO control */ +#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */ +#define MDIOCTL_DIVISOR_VAL 0x2 +#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */ +#define MDIOCTL_ACCESS_DONE 0x100 /* Transaction complete */ + +/* MDIO Data */ +#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */ +#define MDIODATA_TA 0x00020000 /* Turnaround */ + +#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */ +#define MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */ +#define MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */ +#define MDIODATA_DEVADDR_MASK 0x0f800000 + /* Physmedia devaddr Mask */ + +/* MDIO Data for older revisions < 10 */ +#define MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift */ +#define MDIODATA_REGADDR_MASK_OLD 0x003c0000 + /* Regaddr Mask */ +#define MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift */ +#define MDIODATA_DEVADDR_MASK_OLD 0x0fc00000 + /* Physmedia devaddr Mask */ + +/* Transactions flags */ +#define MDIODATA_WRITE 0x10000000 +#define MDIODATA_READ 0x20000000 +#define MDIODATA_START 0x40000000 + +#define MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */ +#define MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */ + +/* serdes regs (rev < 10) */ +#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */ +#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */ +#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */ + +/* SERDES RX registers */ +#define SERDES_RX_CTRL 1 /* Rx cntrl */ +#define SERDES_RX_TIMER1 2 /* Rx Timer1 */ +#define SERDES_RX_CDR 6 /* CDR */ +#define SERDES_RX_CDRBW 7 /* CDR BW */ +/* SERDES RX control register */ +#define SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */ +#define SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */ + +/* SERDES PLL registers */ +#define SERDES_PLL_CTRL 1 /* PLL control reg */ +#define PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */ + +/* Linkcontrol reg offset in PCIE Cap */ +#define PCIE_CAP_LINKCTRL_OFFSET 16 /* offset in pcie cap */ +#define PCIE_CAP_LCREG_ASPML0s 0x01 /* ASPM L0s in linkctrl */ +#define PCIE_CAP_LCREG_ASPML1 0x02 /* ASPM L1 in linkctrl */ +#define PCIE_CLKREQ_ENAB 0x100 /* CLKREQ Enab in linkctrl */ + +#define PCIE_ASPM_ENAB 3 /* ASPM L0s & L1 in linkctrl */ +#define PCIE_ASPM_L1_ENAB 2 /* ASPM L0s & L1 in linkctrl */ +#define PCIE_ASPM_L0s_ENAB 1 /* ASPM L0s & L1 in linkctrl */ +#define PCIE_ASPM_DISAB 0 /* ASPM L0s & L1 in linkctrl */ + +/* Power management threshold */ +#define PCIE_L1THRESHOLDTIME_MASK 0xFF00 /* bits 8 - 15 */ +#define PCIE_L1THRESHOLDTIME_SHIFT 8 /* PCIE_L1THRESHOLDTIME_SHIFT */ +#define PCIE_L1THRESHOLD_WARVAL 0x72 /* WAR value */ +#define PCIE_ASPMTIMER_EXTEND 0x01000000 + /* > rev7: + * enable extend ASPM timer + */ + +/* different register spaces to access thru pcie indirect access */ +#define PCIE_CONFIGREGS 1 /* Access to config space */ +#define PCIE_PCIEREGS 2 /* Access to pcie registers */ + +/* PCIE protocol PHY diagnostic registers */ +#define PCIE_PLP_STATUSREG 0x204 /* Status */ + +/* Status reg PCIE_PLP_STATUSREG */ +#define PCIE_PLP_POLARITYINV_STAT 0x10 + +/* PCIE protocol DLLP diagnostic registers */ +#define PCIE_DLLP_LCREG 0x100 /* Link Control */ +#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */ + +/* PCIE protocol TLP diagnostic registers */ +#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */ + +/* Sonics side: PCI core and host control registers */ +struct sbpciregs { + u32 control; /* PCI control */ + u32 PAD[3]; + u32 arbcontrol; /* PCI arbiter control */ + u32 clkrun; /* Clkrun Control (>=rev11) */ + u32 PAD[2]; + u32 intstatus; /* Interrupt status */ + u32 intmask; /* Interrupt mask */ + u32 sbtopcimailbox; /* Sonics to PCI mailbox */ + u32 PAD[9]; + u32 bcastaddr; /* Sonics broadcast address */ + u32 bcastdata; /* Sonics broadcast data */ + u32 PAD[2]; + u32 gpioin; /* ro: gpio input (>=rev2) */ + u32 gpioout; /* rw: gpio output (>=rev2) */ + u32 gpioouten; /* rw: gpio output enable (>= rev2) */ + u32 gpiocontrol; /* rw: gpio control (>= rev2) */ + u32 PAD[36]; + u32 sbtopci0; /* Sonics to PCI translation 0 */ + u32 sbtopci1; /* Sonics to PCI translation 1 */ + u32 sbtopci2; /* Sonics to PCI translation 2 */ + u32 PAD[189]; + u32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */ + u16 sprom[36]; /* SPROM shadow Area */ + u32 PAD[46]; +}; + +/* SB side: PCIE core and host control registers */ +struct sbpcieregs { + u32 control; /* host mode only */ + u32 PAD[2]; + u32 biststatus; /* bist Status: 0x00C */ + u32 gpiosel; /* PCIE gpio sel: 0x010 */ + u32 gpioouten; /* PCIE gpio outen: 0x14 */ + u32 PAD[2]; + u32 intstatus; /* Interrupt status: 0x20 */ + u32 intmask; /* Interrupt mask: 0x24 */ + u32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */ + u32 PAD[53]; + u32 sbtopcie0; /* sb to pcie translation 0: 0x100 */ + u32 sbtopcie1; /* sb to pcie translation 1: 0x104 */ + u32 sbtopcie2; /* sb to pcie translation 2: 0x108 */ + u32 PAD[5]; + + /* pcie core supports in direct access to config space */ + u32 configaddr; /* pcie config space access: Address field: 0x120 */ + u32 configdata; /* pcie config space access: Data field: 0x124 */ + + /* mdio access to serdes */ + u32 mdiocontrol; /* controls the mdio access: 0x128 */ + u32 mdiodata; /* Data to the mdio access: 0x12c */ + + /* pcie protocol phy/dllp/tlp register indirect access mechanism */ + u32 pcieindaddr; /* indirect access to + * the internal register: 0x130 + */ + u32 pcieinddata; /* Data to/from the internal regsiter: 0x134 */ + + u32 clkreqenctrl; /* >= rev 6, Clkreq rdma control : 0x138 */ + u32 PAD[177]; + u32 pciecfg[4][64]; /* 0x400 - 0x7FF, PCIE Cfg Space */ + u16 sprom[64]; /* SPROM shadow Area */ +}; + +struct pcicore_info { union { - sbpcieregs_t *pcieregs; + struct sbpcieregs *pcieregs; struct sbpciregs *pciregs; } regs; /* Memory mapped register to the core */ - si_t *sih; /* System interconnect handle */ + struct si_pub *sih; /* System interconnect handle */ struct pci_dev *dev; - u8 pciecap_lcreg_offset; /* PCIE capability LCreg offset in the config space */ + u8 pciecap_lcreg_offset;/* PCIE capability LCreg offset + * in the config space + */ bool pcie_pr42767; u8 pcie_polarity; u8 pcie_war_aspm_ovr; /* Override ASPM/Clkreq settings */ u8 pmecap_offset; /* PM Capability offset in the config space */ bool pmecap; /* Capable of generating PME */ -} pcicore_info_t; +}; /* debug/trace */ #define PCI_ERROR(args) -#define PCIE_PUB(sih) \ - (((sih)->bustype == PCI_BUS) && ((sih)->buscoretype == PCIE_CORE_ID)) +#define PCIE_PUB(sih) \ + (((sih)->bustype == PCI_BUS) && \ + ((sih)->buscoretype == PCIE_CORE_ID)) /* routines to access mdio slave device registers */ -static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk); -static int pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, +static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk); +static int pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write, uint *val); -static int pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint readdr, +static int pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint readdr, uint val); -static int pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint readdr, +static int pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint readdr, uint *ret_val); -static void pcie_extendL1timer(pcicore_info_t *pi, bool extend); -static void pcie_clkreq_upd(pcicore_info_t *pi, uint state); +static void pcie_extendL1timer(struct pcicore_info *pi, bool extend); +static void pcie_clkreq_upd(struct pcicore_info *pi, uint state); -static void pcie_war_aspm_clkreq(pcicore_info_t *pi); -static void pcie_war_serdes(pcicore_info_t *pi); -static void pcie_war_noplldown(pcicore_info_t *pi); -static void pcie_war_polarity(pcicore_info_t *pi); -static void pcie_war_pci_setup(pcicore_info_t *pi); +static void pcie_war_aspm_clkreq(struct pcicore_info *pi); +static void pcie_war_serdes(struct pcicore_info *pi); +static void pcie_war_noplldown(struct pcicore_info *pi); +static void pcie_war_polarity(struct pcicore_info *pi); +static void pcie_war_pci_setup(struct pcicore_info *pi); -static bool pcicore_pmecap(pcicore_info_t *pi); - -#define PCIE_ASPM(sih) ((PCIE_PUB(sih)) && (((sih)->buscorerev >= 3) && ((sih)->buscorerev <= 5))) +#define PCIE_ASPM(sih) \ + ((PCIE_PUB(sih)) && \ + (((sih)->buscorerev >= 3) && \ + ((sih)->buscorerev <= 5))) /* delay needed between the mdio control/ mdiodata register data access */ #define PR28829_DELAY() udelay(10) -/* Initialize the PCI core. It's caller's responsibility to make sure that this is done - * only once +/* Initialize the PCI core. + * It's caller's responsibility to make sure that this is done only once */ -void *pcicore_init(si_t *sih, void *pdev, void *regs) +void *pcicore_init(struct si_pub *sih, void *pdev, void *regs) { - pcicore_info_t *pi; + struct pcicore_info *pi; - /* alloc pcicore_info_t */ - pi = kzalloc(sizeof(pcicore_info_t), GFP_ATOMIC); + /* alloc struct pcicore_info */ + pi = kzalloc(sizeof(struct pcicore_info), GFP_ATOMIC); if (pi == NULL) { PCI_ERROR(("pci_attach: malloc failed!\n")); return NULL; @@ -96,23 +263,19 @@ void *pcicore_init(si_t *sih, void *pdev, void *regs) if (sih->buscoretype == PCIE_CORE_ID) { u8 cap_ptr; - pi->regs.pcieregs = (sbpcieregs_t *) regs; + pi->regs.pcieregs = regs; cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP, NULL, NULL); pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET; } else - pi->regs.pciregs = (struct sbpciregs *) regs; + pi->regs.pciregs = regs; return pi; } void pcicore_deinit(void *pch) { - pcicore_info_t *pi = (pcicore_info_t *) pch; - - if (pi == NULL) - return; - kfree(pi); + kfree(pch); } /* return cap_offset if requested capability exists in the PCI config space */ @@ -141,7 +304,9 @@ pcicore_find_pci_capability(void *dev, u8 req_cap_id, if (cap_ptr == 0x00) goto end; - /* loop thr'u the capability list and see if the pcie capabilty exists */ + /* loop thru the capability list + * and see if the pcie capability exists + */ pci_read_config_byte(dev, cap_ptr, &cap_id); @@ -151,18 +316,18 @@ pcicore_find_pci_capability(void *dev, u8 req_cap_id, break; pci_read_config_byte(dev, cap_ptr, &cap_id); } - if (cap_id != req_cap_id) { + if (cap_id != req_cap_id) goto end; - } + /* found the caller requested capability */ - if ((buf != NULL) && (buflen != NULL)) { + if (buf != NULL && buflen != NULL) { u8 cap_data; bufsize = *buflen; if (!bufsize) goto end; *buflen = 0; - /* copy the cpability data excluding cap ID and next ptr */ + /* copy the capability data excluding cap ID and next ptr */ cap_data = cap_ptr + 2; if ((bufsize + cap_data) > PCI_SZPCR) bufsize = PCI_SZPCR - cap_data; @@ -173,38 +338,34 @@ pcicore_find_pci_capability(void *dev, u8 req_cap_id, buf++; } } - end: +end: return cap_ptr; } /* ***** Register Access API */ -uint -pcie_readreg(sbpcieregs_t *pcieregs, uint addrtype, - uint offset) +static uint +pcie_readreg(struct sbpcieregs *pcieregs, uint addrtype, uint offset) { uint retval = 0xFFFFFFFF; switch (addrtype) { case PCIE_CONFIGREGS: - W_REG((&pcieregs->configaddr), offset); + W_REG(&pcieregs->configaddr, offset); (void)R_REG((&pcieregs->configaddr)); - retval = R_REG(&(pcieregs->configdata)); + retval = R_REG(&pcieregs->configdata); break; case PCIE_PCIEREGS: - W_REG(&(pcieregs->pcieindaddr), offset); - (void)R_REG((&pcieregs->pcieindaddr)); - retval = R_REG(&(pcieregs->pcieinddata)); - break; - default: + W_REG(&pcieregs->pcieindaddr, offset); + (void)R_REG(&pcieregs->pcieindaddr); + retval = R_REG(&pcieregs->pcieinddata); break; } return retval; } -uint -pcie_writereg(sbpcieregs_t *pcieregs, uint addrtype, - uint offset, uint val) +static uint +pcie_writereg(struct sbpcieregs *pcieregs, uint addrtype, uint offset, uint val) { switch (addrtype) { case PCIE_CONFIGREGS: @@ -221,26 +382,23 @@ pcie_writereg(sbpcieregs_t *pcieregs, uint addrtype, return 0; } -static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk) +static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk) { - sbpcieregs_t *pcieregs = pi->regs.pcieregs; + struct sbpcieregs *pcieregs = pi->regs.pcieregs; uint mdiodata, i = 0; uint pcie_serdes_spinwait = 200; - mdiodata = - MDIODATA_START | MDIODATA_WRITE | (MDIODATA_DEV_ADDR << - MDIODATA_DEVADDR_SHF) | - (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) | MDIODATA_TA | (blk << - 4); + mdiodata = (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | + (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) | + (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) | + (blk << 4)); W_REG(&pcieregs->mdiodata, mdiodata); PR28829_DELAY(); /* retry till the transaction is complete */ while (i < pcie_serdes_spinwait) { - if (R_REG(&(pcieregs->mdiocontrol)) & - MDIOCTL_ACCESS_DONE) { + if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE) break; - } udelay(1000); i++; } @@ -254,35 +412,36 @@ static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk) } static int -pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write, +pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write, uint *val) { - sbpcieregs_t *pcieregs = pi->regs.pcieregs; + struct sbpcieregs *pcieregs = pi->regs.pcieregs; uint mdiodata; uint i = 0; uint pcie_serdes_spinwait = 10; /* enable mdio access to SERDES */ - W_REG((&pcieregs->mdiocontrol), - MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); + W_REG(&pcieregs->mdiocontrol, MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); if (pi->sih->buscorerev >= 10) { - /* new serdes is slower in rw, using two layers of reg address mapping */ + /* new serdes is slower in rw, + * using two layers of reg address mapping + */ if (!pcie_mdiosetblock(pi, physmedia)) return 1; - mdiodata = (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) | - (regaddr << MDIODATA_REGADDR_SHF); + mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) | + (regaddr << MDIODATA_REGADDR_SHF)); pcie_serdes_spinwait *= 20; } else { - mdiodata = (physmedia << MDIODATA_DEVADDR_SHF_OLD) | - (regaddr << MDIODATA_REGADDR_SHF_OLD); + mdiodata = ((physmedia << MDIODATA_DEVADDR_SHF_OLD) | + (regaddr << MDIODATA_REGADDR_SHF_OLD)); } if (!write) mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA); else - mdiodata |= - (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | *val); + mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | + *val); W_REG(&pcieregs->mdiodata, mdiodata); @@ -290,16 +449,14 @@ pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write, /* retry till the transaction is complete */ while (i < pcie_serdes_spinwait) { - if (R_REG(&(pcieregs->mdiocontrol)) & - MDIOCTL_ACCESS_DONE) { + if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE) { if (!write) { PR28829_DELAY(); - *val = - (R_REG(&(pcieregs->mdiodata)) & - MDIODATA_MASK); + *val = (R_REG(&pcieregs->mdiodata) & + MDIODATA_MASK); } /* Disable mdio access to SERDES */ - W_REG((&pcieregs->mdiocontrol), 0); + W_REG(&pcieregs->mdiocontrol, 0); return 0; } udelay(1000); @@ -308,28 +465,29 @@ pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write, PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write)); /* Disable mdio access to SERDES */ - W_REG((&pcieregs->mdiocontrol), 0); + W_REG(&pcieregs->mdiocontrol, 0); return 1; } /* use the mdio interface to read from mdio slaves */ static int -pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint regaddr, uint *regval) +pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint regaddr, + uint *regval) { return pcie_mdioop(pi, physmedia, regaddr, false, regval); } /* use the mdio interface to write to mdio slaves */ static int -pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint regaddr, uint val) +pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint regaddr, uint val) { return pcie_mdioop(pi, physmedia, regaddr, true, &val); } /* ***** Support functions ***** */ -u8 pcie_clkreq(void *pch, u32 mask, u32 val) +static u8 pcie_clkreq(void *pch, u32 mask, u32 val) { - pcicore_info_t *pi = (pcicore_info_t *) pch; + struct pcicore_info *pi = pch; u32 reg_val; u8 offset; @@ -353,11 +511,11 @@ u8 pcie_clkreq(void *pch, u32 mask, u32 val) return 0; } -static void pcie_extendL1timer(pcicore_info_t *pi, bool extend) +static void pcie_extendL1timer(struct pcicore_info *pi, bool extend) { u32 w; - si_t *sih = pi->sih; - sbpcieregs_t *pcieregs = pi->regs.pcieregs; + struct si_pub *sih = pi->sih; + struct sbpcieregs *pcieregs = pi->regs.pcieregs; if (!PCIE_PUB(sih) || sih->buscorerev < 7) return; @@ -372,9 +530,9 @@ static void pcie_extendL1timer(pcicore_info_t *pi, bool extend) } /* centralized clkreq control policy */ -static void pcie_clkreq_upd(pcicore_info_t *pi, uint state) +static void pcie_clkreq_upd(struct pcicore_info *pi, uint state) { - si_t *sih = pi->sih; + struct si_pub *sih = pi->sih; switch (state) { case SI_DOATTACH: @@ -384,8 +542,8 @@ static void pcie_clkreq_upd(pcicore_info_t *pi, uint state) case SI_PCIDOWN: if (sih->buscorerev == 6) { /* turn on serdes PLL down */ ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_addr), ~0, - 0); + offsetof(chipcregs_t, chipcontrol_addr), + ~0, 0); ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_data), ~0x40, 0); @@ -396,8 +554,8 @@ static void pcie_clkreq_upd(pcicore_info_t *pi, uint state) case SI_PCIUP: if (sih->buscorerev == 6) { /* turn off serdes PLL down */ ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_addr), ~0, - 0); + offsetof(chipcregs_t, chipcontrol_addr), + ~0, 0); ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_data), ~0x40, 0x40); @@ -405,31 +563,28 @@ static void pcie_clkreq_upd(pcicore_info_t *pi, uint state) pcie_clkreq((void *)pi, 1, 0); } break; - default: - break; } } /* ***** PCI core WARs ***** */ /* Done only once at attach time */ -static void pcie_war_polarity(pcicore_info_t *pi) +static void pcie_war_polarity(struct pcicore_info *pi) { u32 w; if (pi->pcie_polarity != 0) return; - w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS, - PCIE_PLP_STATUSREG); + w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS, PCIE_PLP_STATUSREG); /* Detect the current polarity at attach and force that polarity and * disable changing the polarity */ if ((w & PCIE_PLP_POLARITYINV_STAT) == 0) - pi->pcie_polarity = (SERDES_RX_CTRL_FORCE); + pi->pcie_polarity = SERDES_RX_CTRL_FORCE; else - pi->pcie_polarity = - (SERDES_RX_CTRL_FORCE | SERDES_RX_CTRL_POLARITY); + pi->pcie_polarity = (SERDES_RX_CTRL_FORCE | + SERDES_RX_CTRL_POLARITY); } /* enable ASPM and CLKREQ if srom doesn't have it */ @@ -437,10 +592,10 @@ static void pcie_war_polarity(pcicore_info_t *pi) * : Coming out of 'standby'/'hibernate' * : If pcie_war_aspm_ovr state changed */ -static void pcie_war_aspm_clkreq(pcicore_info_t *pi) +static void pcie_war_aspm_clkreq(struct pcicore_info *pi) { - sbpcieregs_t *pcieregs = pi->regs.pcieregs; - si_t *sih = pi->sih; + struct sbpcieregs *pcieregs = pi->regs.pcieregs; + struct si_pub *sih = pi->sih; u16 val16, *reg16; u32 w; @@ -448,28 +603,23 @@ static void pcie_war_aspm_clkreq(pcicore_info_t *pi) return; /* bypass this on QT or VSIM */ - if (!ISSIM_ENAB(sih)) { + reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET]; + val16 = R_REG(reg16); - reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET]; - val16 = R_REG(reg16); + val16 &= ~SRSH_ASPM_ENB; + if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB) + val16 |= SRSH_ASPM_ENB; + else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB) + val16 |= SRSH_ASPM_L1_ENB; + else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB) + val16 |= SRSH_ASPM_L0s_ENB; - val16 &= ~SRSH_ASPM_ENB; - if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB) - val16 |= SRSH_ASPM_ENB; - else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB) - val16 |= SRSH_ASPM_L1_ENB; - else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB) - val16 |= SRSH_ASPM_L0s_ENB; + W_REG(reg16, val16); - W_REG(reg16, val16); - - pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, - &w); - w &= ~PCIE_ASPM_ENAB; - w |= pi->pcie_war_aspm_ovr; - pci_write_config_dword(pi->dev, - pi->pciecap_lcreg_offset, w); - } + pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w); + w &= ~PCIE_ASPM_ENAB; + w |= pi->pcie_war_aspm_ovr; + pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w); reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5]; val16 = R_REG(reg16); @@ -485,7 +635,7 @@ static void pcie_war_aspm_clkreq(pcicore_info_t *pi) /* Apply the polarity determined at the start */ /* Needs to happen when coming out of 'standby'/'hibernate' */ -static void pcie_war_serdes(pcicore_info_t *pi) +static void pcie_war_serdes(struct pcicore_info *pi) { u32 w = 0; @@ -502,9 +652,9 @@ static void pcie_war_serdes(pcicore_info_t *pi) /* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */ /* Needs to happen when coming out of 'standby'/'hibernate' */ -static void pcie_misc_config_fixup(pcicore_info_t *pi) +static void pcie_misc_config_fixup(struct pcicore_info *pi) { - sbpcieregs_t *pcieregs = pi->regs.pcieregs; + struct sbpcieregs *pcieregs = pi->regs.pcieregs; u16 val16, *reg16; reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG]; @@ -518,28 +668,28 @@ static void pcie_misc_config_fixup(pcicore_info_t *pi) /* quick hack for testing */ /* Needs to happen when coming out of 'standby'/'hibernate' */ -static void pcie_war_noplldown(pcicore_info_t *pi) +static void pcie_war_noplldown(struct pcicore_info *pi) { - sbpcieregs_t *pcieregs = pi->regs.pcieregs; + struct sbpcieregs *pcieregs = pi->regs.pcieregs; u16 *reg16; /* turn off serdes PLL down */ ai_corereg(pi->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol), CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN); - /* clear srom shadow backdoor */ + /* clear srom shadow backdoor */ reg16 = &pcieregs->sprom[SRSH_BD_OFFSET]; W_REG(reg16, 0); } /* Needs to happen when coming out of 'standby'/'hibernate' */ -static void pcie_war_pci_setup(pcicore_info_t *pi) +static void pcie_war_pci_setup(struct pcicore_info *pi) { - si_t *sih = pi->sih; - sbpcieregs_t *pcieregs = pi->regs.pcieregs; + struct si_pub *sih = pi->sih; + struct sbpcieregs *pcieregs = pi->regs.pcieregs; u32 w; - if ((sih->buscorerev == 0) || (sih->buscorerev == 1)) { + if (sih->buscorerev == 0 || sih->buscorerev == 1) { w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG); w |= 0x8; @@ -549,7 +699,7 @@ static void pcie_war_pci_setup(pcicore_info_t *pi) if (sih->buscorerev == 1) { w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG); - w |= (0x40); + w |= 0x40; pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w); } @@ -561,8 +711,8 @@ static void pcie_war_pci_setup(pcicore_info_t *pi) /* Change the L1 threshold for better performance */ w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); - w &= ~(PCIE_L1THRESHOLDTIME_MASK); - w |= (PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT); + w &= ~PCIE_L1THRESHOLDTIME_MASK; + w |= PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT; pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w); @@ -572,41 +722,25 @@ static void pcie_war_pci_setup(pcicore_info_t *pi) } else if (pi->sih->buscorerev == 7) pcie_war_noplldown(pi); - /* Note that the fix is actually in the SROM, that's why this is open-ended */ + /* Note that the fix is actually in the SROM, + * that's why this is open-ended + */ if (pi->sih->buscorerev >= 6) pcie_misc_config_fixup(pi); } -void pcie_war_ovr_aspm_update(void *pch, u8 aspm) -{ - pcicore_info_t *pi = (pcicore_info_t *) pch; - - if (!PCIE_ASPM(pi->sih)) - return; - - /* Validate */ - if (aspm > PCIE_ASPM_ENAB) - return; - - pi->pcie_war_aspm_ovr = aspm; - - /* Update the current state */ - pcie_war_aspm_clkreq(pi); -} - /* ***** Functions called during driver state changes ***** */ void pcicore_attach(void *pch, char *pvars, int state) { - pcicore_info_t *pi = (pcicore_info_t *) pch; - si_t *sih = pi->sih; + struct pcicore_info *pi = pch; + struct si_pub *sih = pi->sih; /* Determine if this board needs override */ if (PCIE_ASPM(sih)) { - if ((u32) getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR) { + if ((u32)getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR) pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB; - } else { + else pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB; - } } /* These need to happen in this order only */ @@ -622,7 +756,7 @@ void pcicore_attach(void *pch, char *pvars, int state) void pcicore_hwup(void *pch) { - pcicore_info_t *pi = (pcicore_info_t *) pch; + struct pcicore_info *pi = pch; if (!pi || !PCIE_PUB(pi->sih)) return; @@ -632,7 +766,7 @@ void pcicore_hwup(void *pch) void pcicore_up(void *pch, int state) { - pcicore_info_t *pi = (pcicore_info_t *) pch; + struct pcicore_info *pi = pch; if (!pi || !PCIE_PUB(pi->sih)) return; @@ -643,10 +777,12 @@ void pcicore_up(void *pch, int state) pcie_clkreq_upd(pi, state); } -/* When the device is going to enter D3 state (or the system is going to enter S3/S4 states */ +/* When the device is going to enter D3 state + * (or the system is going to enter S3/S4 states) + */ void pcicore_sleep(void *pch) { - pcicore_info_t *pi = (pcicore_info_t *) pch; + struct pcicore_info *pi = pch; u32 w; if (!pi || !PCIE_ASPM(pi->sih)) @@ -661,7 +797,7 @@ void pcicore_sleep(void *pch) void pcicore_down(void *pch, int state) { - pcicore_info_t *pi = (pcicore_info_t *) pch; + struct pcicore_info *pi = pch; if (!pi || !PCIE_PUB(pi->sih)) return; @@ -672,165 +808,43 @@ void pcicore_down(void *pch, int state) pcie_extendL1timer(pi, false); } -/* ***** Wake-on-wireless-LAN (WOWL) support functions ***** */ -/* Just uses PCI config accesses to find out, when needed before sb_attach is done */ -bool pcicore_pmecap_fast(void *pch) +/* precondition: current core is sii->buscoretype */ +void pcicore_fixcfg(void *pch, void *regs) { - pcicore_info_t *pi = (pcicore_info_t *) pch; - u8 cap_ptr; - u32 pmecap; + struct pcicore_info *pi = pch; + struct si_info *sii = SI_INFO(pi->sih); + struct sbpciregs *pciregs = regs; + struct sbpcieregs *pcieregs = regs; + u16 val16, *reg16 = NULL; + uint pciidx; - cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_PM, NULL, - NULL); - - if (!cap_ptr) - return false; - - pci_read_config_dword(pi->dev, cap_ptr, &pmecap); - - return (pmecap & (PCI_PM_CAP_PME_MASK << 16)) != 0; -} - -/* return true if PM capability exists in the pci config space - * Uses and caches the information using core handle - */ -static bool pcicore_pmecap(pcicore_info_t *pi) -{ - u8 cap_ptr; - u32 pmecap; - - if (!pi->pmecap_offset) { - cap_ptr = pcicore_find_pci_capability(pi->dev, - PCI_CAP_ID_PM, - NULL, NULL); - if (!cap_ptr) - return false; - - pi->pmecap_offset = cap_ptr; - - pci_read_config_dword(pi->dev, pi->pmecap_offset, - &pmecap); - - /* At least one state can generate PME */ - pi->pmecap = (pmecap & (PCI_PM_CAP_PME_MASK << 16)) != 0; + /* check 'pi' is correct and fix it if not */ + if (sii->pub.buscoretype == PCIE_CORE_ID) + reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; + else if (sii->pub.buscoretype == PCI_CORE_ID) + reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; + pciidx = ai_coreidx(&sii->pub); + val16 = R_REG(reg16); + if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16)pciidx) { + val16 = (u16)(pciidx << SRSH_PI_SHIFT) | + (val16 & ~SRSH_PI_MASK); + W_REG(reg16, val16); } - - return pi->pmecap; } -/* Enable PME generation */ -void pcicore_pmeen(void *pch) +/* precondition: current core is pci core */ +void pcicore_pci_setup(void *pch, void *regs) { - pcicore_info_t *pi = (pcicore_info_t *) pch; + struct pcicore_info *pi = pch; + struct sbpciregs *pciregs = regs; u32 w; - /* if not pmecapable return */ - if (!pcicore_pmecap(pi)) - return; + OR_REG(&pciregs->sbtopci2, SBTOPCI_PREF | SBTOPCI_BURST); - pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL, - &w); - w |= (PCI_PM_CTRL_PME_ENABLE); - pci_write_config_dword(pi->dev, - pi->pmecap_offset + PCI_PM_CTRL, w); -} - -/* - * Return true if PME status set - */ -bool pcicore_pmestat(void *pch) -{ - pcicore_info_t *pi = (pcicore_info_t *) pch; - u32 w; - - if (!pcicore_pmecap(pi)) - return false; - - pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL, - &w); - - return (w & PCI_PM_CTRL_PME_STATUS) == PCI_PM_CTRL_PME_STATUS; -} - -/* Disable PME generation, clear the PME status bit if set - */ -void pcicore_pmeclr(void *pch) -{ - pcicore_info_t *pi = (pcicore_info_t *) pch; - u32 w; - - if (!pcicore_pmecap(pi)) - return; - - pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL, - &w); - - PCI_ERROR(("pcicore_pci_pmeclr PMECSR : 0x%x\n", w)); - - /* PMESTAT is cleared by writing 1 to it */ - w &= ~(PCI_PM_CTRL_PME_ENABLE); - - pci_write_config_dword(pi->dev, - pi->pmecap_offset + PCI_PM_CTRL, w); -} - -u32 pcie_lcreg(void *pch, u32 mask, u32 val) -{ - pcicore_info_t *pi = (pcicore_info_t *) pch; - u8 offset; - u32 tmpval; - - offset = pi->pciecap_lcreg_offset; - if (!offset) - return 0; - - /* set operation */ - if (mask) - pci_write_config_dword(pi->dev, offset, val); - - pci_read_config_dword(pi->dev, offset, &tmpval); - return tmpval; -} - -u32 -pcicore_pciereg(void *pch, u32 offset, u32 mask, u32 val, uint type) -{ - u32 reg_val = 0; - pcicore_info_t *pi = (pcicore_info_t *) pch; - sbpcieregs_t *pcieregs = pi->regs.pcieregs; - - if (mask) { - PCI_ERROR(("PCIEREG: 0x%x writeval 0x%x\n", offset, val)); - pcie_writereg(pcieregs, type, offset, val); + if (SI_INFO(pi->sih)->pub.buscorerev >= 11) { + OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI); + w = R_REG(&pciregs->clkrun); + W_REG(&pciregs->clkrun, w | PCI_CLKRUN_DSBL); + w = R_REG(&pciregs->clkrun); } - - /* Should not read register 0x154 */ - if (pi->sih->buscorerev <= 5 && offset == PCIE_DLLP_PCIE11 - && type == PCIE_PCIEREGS) - return reg_val; - - reg_val = pcie_readreg(pcieregs, type, offset); - PCI_ERROR(("PCIEREG: 0x%x readval is 0x%x\n", offset, reg_val)); - - return reg_val; -} - -u32 -pcicore_pcieserdesreg(void *pch, u32 mdioslave, u32 offset, u32 mask, - u32 val) -{ - u32 reg_val = 0; - pcicore_info_t *pi = (pcicore_info_t *) pch; - - if (mask) { - PCI_ERROR(("PCIEMDIOREG: 0x%x writeval 0x%x\n", offset, val)); - pcie_mdiowrite(pi, mdioslave, offset, val); - } - - if (pcie_mdioread(pi, mdioslave, offset, ®_val)) - reg_val = 0xFFFFFFFF; - PCI_ERROR(("PCIEMDIOREG: dev 0x%x offset 0x%x read 0x%x\n", mdioslave, - offset, reg_val)); - - return reg_val; } diff --git a/drivers/staging/brcm80211/brcmsmac/nicpci.h b/drivers/staging/brcm80211/brcmsmac/nicpci.h new file mode 100644 index 000000000000..f71f842a2156 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/nicpci.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BRCM_NICPCI_H_ +#define _BRCM_NICPCI_H_ + +#include "types.h" + +/* PCI configuration address space size */ +#define PCI_SZPCR 256 + +/* Brcm PCI configuration registers */ +/* backplane address space accessed by BAR0 */ +#define PCI_BAR0_WIN 0x80 +/* sprom property control */ +#define PCI_SPROM_CONTROL 0x88 +/* mask of PCI and other cores interrupts */ +#define PCI_INT_MASK 0x94 +/* backplane core interrupt mask bits offset */ +#define PCI_SBIM_SHIFT 8 +/* backplane address space accessed by second 4KB of BAR0 */ +#define PCI_BAR0_WIN2 0xac +/* pci config space gpio input (>=rev3) */ +#define PCI_GPIO_IN 0xb0 +/* pci config space gpio output (>=rev3) */ +#define PCI_GPIO_OUT 0xb4 +/* pci config space gpio output enable (>=rev3) */ +#define PCI_GPIO_OUTEN 0xb8 + +/* bar0 + 4K accesses external sprom */ +#define PCI_BAR0_SPROM_OFFSET (4 * 1024) +/* bar0 + 6K accesses pci core registers */ +#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) +/* + * pci core SB registers are at the end of the + * 8KB window, so their address is the "regular" + * address plus 4K + */ +#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) +/* bar0 window size Match with corerev 13 */ +#define PCI_BAR0_WINSZ (16 * 1024) +/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */ +/* bar0 + 8K accesses pci/pcie core registers */ +#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) +/* bar0 + 12K accesses chipc core registers */ +#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) + +#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */ + +/* Sonics to PCI translation types */ +#define SBTOPCI_PREF 0x4 /* prefetch enable */ +#define SBTOPCI_BURST 0x8 /* burst enable */ +#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ + +/* PCI core index in SROM shadow area */ +#define SRSH_PI_OFFSET 0 /* first word */ +#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ +#define SRSH_PI_SHIFT 12 /* bit 15:12 */ + +extern void *pcicore_init(struct si_pub *sih, void *pdev, void *regs); +extern void pcicore_deinit(void *pch); +extern void pcicore_attach(void *pch, char *pvars, int state); +extern void pcicore_hwup(void *pch); +extern void pcicore_up(void *pch, int state); +extern void pcicore_sleep(void *pch); +extern void pcicore_down(void *pch, int state); +extern u8 pcicore_find_pci_capability(void *dev, u8 req_cap_id, + unsigned char *buf, u32 *buflen); +extern void pcicore_fixcfg(void *pch, void *regs); +extern void pcicore_pci_setup(void *pch, void *regs); + +#endif /* _BRCM_NICPCI_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/nvram.c b/drivers/staging/brcm80211/brcmsmac/nvram.c deleted file mode 100644 index 085ec0b9224f..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/nvram.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define NVR_MSG(x) - -typedef struct _vars { - struct _vars *next; - int bufsz; /* allocated size */ - int size; /* actual vars size */ - char *vars; -} vars_t; - -#define VARS_T_OH sizeof(vars_t) - -static vars_t *vars; - -#define NVRAM_FILE 1 - -static char *findvar(char *vars, char *lim, const char *name); - -int nvram_init(void) -{ - - /* Make sure we read nvram in flash just once before freeing the memory */ - if (vars != NULL) { - NVR_MSG(("nvram_init: called again without calling nvram_exit()\n")); - return 0; - } - return 0; -} - -int nvram_append(char *varlst, uint varsz) -{ - uint bufsz = VARS_T_OH; - vars_t *new; - - new = kmalloc(bufsz, GFP_ATOMIC); - if (new == NULL) - return -ENOMEM; - - new->vars = varlst; - new->bufsz = bufsz; - new->size = varsz; - new->next = vars; - vars = new; - - return 0; -} - -void nvram_exit(void) -{ - vars_t *this, *next; - - this = vars; - if (this) - kfree(this->vars); - - while (this) { - next = this->next; - kfree(this); - this = next; - } - vars = NULL; -} - -static char *findvar(char *vars, char *lim, const char *name) -{ - char *s; - int len; - - len = strlen(name); - - for (s = vars; (s < lim) && *s;) { - if ((memcmp(s, name, len) == 0) && (s[len] == '=')) - return &s[len + 1]; - - while (*s++) - ; - } - - return NULL; -} - -/* - * Search the name=value vars for a specific one and return its value. - * Returns NULL if not found. - */ -char *getvar(char *vars, const char *name) -{ - char *s; - int len; - - if (!name) - return NULL; - - len = strlen(name); - if (len == 0) - return NULL; - - /* first look in vars[] */ - for (s = vars; s && *s;) { - if ((memcmp(s, name, len) == 0) && (s[len] == '=')) - return &s[len + 1]; - - while (*s++) - ; - } - /* then query nvram */ - return nvram_get(name); -} - -/* - * Search the vars for a specific one and return its value as - * an integer. Returns 0 if not found. - */ -int getintvar(char *vars, const char *name) -{ - char *val; - - val = getvar(vars, name); - if (val == NULL) - return 0; - - return simple_strtoul(val, NULL, 0); -} - -char *nvram_get(const char *name) -{ - char *v = NULL; - vars_t *cur; - - for (cur = vars; cur; cur = cur->next) { - v = findvar(cur->vars, cur->vars + cur->size, name); - if (v) - break; - } - - return v; -} - -int nvram_set(const char *name, const char *value) -{ - return 0; -} - -int nvram_unset(const char *name) -{ - return 0; -} - -int nvram_reset(void) -{ - return 0; -} - -int nvram_commit(void) -{ - return 0; -} - -int nvram_getall(char *buf, int count) -{ - int len, resid = count; - vars_t *this; - - this = vars; - while (this) { - char *from, *lim, *to; - int acc; - - from = this->vars; - lim = (char *)(this->vars + this->size); - to = buf; - acc = 0; - while ((from < lim) && (*from)) { - len = strlen(from) + 1; - if (resid < (acc + len)) - return -EOVERFLOW; - memcpy(to, from, len); - acc += len; - from += len; - to += len; - } - - resid -= acc; - buf += acc; - this = this->next; - } - if (resid < 1) - return -EOVERFLOW; - *buf = '\0'; - return 0; -} diff --git a/drivers/staging/brcm80211/brcmsmac/otp.c b/drivers/staging/brcm80211/brcmsmac/otp.c new file mode 100644 index 000000000000..34253cf37812 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/otp.c @@ -0,0 +1,544 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include "aiutils.h" +#include "otp.h" + +#define OTPS_GUP_MASK 0x00000f00 +#define OTPS_GUP_SHIFT 8 +#define OTPS_GUP_HW 0x00000100 /* h/w subregion is programmed */ +#define OTPS_GUP_SW 0x00000200 /* s/w subregion is programmed */ +#define OTPS_GUP_CI 0x00000400 /* chipid/pkgopt subregion is programmed */ +#define OTPS_GUP_FUSE 0x00000800 /* fuse subregion is programmed */ + +/* Fields in otpprog in rev >= 21 */ +#define OTPP_COL_MASK 0x000000ff +#define OTPP_COL_SHIFT 0 +#define OTPP_ROW_MASK 0x0000ff00 +#define OTPP_ROW_SHIFT 8 +#define OTPP_OC_MASK 0x0f000000 +#define OTPP_OC_SHIFT 24 +#define OTPP_READERR 0x10000000 +#define OTPP_VALUE_MASK 0x20000000 +#define OTPP_VALUE_SHIFT 29 +#define OTPP_START_BUSY 0x80000000 +#define OTPP_READ 0x40000000 + +/* Opcodes for OTPP_OC field */ +#define OTPPOC_READ 0 +#define OTPPOC_BIT_PROG 1 +#define OTPPOC_VERIFY 3 +#define OTPPOC_INIT 4 +#define OTPPOC_SET 5 +#define OTPPOC_RESET 6 +#define OTPPOC_OCST 7 +#define OTPPOC_ROW_LOCK 8 +#define OTPPOC_PRESCN_TEST 9 + +#define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23) + +#define OTPP_TRIES 10000000 /* # of tries for OTPP */ + +#define MAXNUMRDES 9 /* Maximum OTP redundancy entries */ + +/* OTP common function type */ +typedef int (*otp_status_t) (void *oh); +typedef int (*otp_size_t) (void *oh); +typedef void *(*otp_init_t) (struct si_pub *sih); +typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off); +typedef int (*otp_read_region_t) (struct si_pub *sih, int region, u16 *data, + uint *wlen); +typedef int (*otp_nvread_t) (void *oh, char *data, uint *len); + +/* OTP function struct */ +struct otp_fn_s { + otp_size_t size; + otp_read_bit_t read_bit; + otp_init_t init; + otp_read_region_t read_region; + otp_nvread_t nvread; + otp_status_t status; +}; + +struct otpinfo { + uint ccrev; /* chipc revision */ + struct otp_fn_s *fn; /* OTP functions */ + struct si_pub *sih; /* Saved sb handle */ + + /* IPX OTP section */ + u16 wsize; /* Size of otp in words */ + u16 rows; /* Geometry */ + u16 cols; /* Geometry */ + u32 status; /* Flag bits (lock/prog/rv). + * (Reflected only when OTP is power cycled) + */ + u16 hwbase; /* hardware subregion offset */ + u16 hwlim; /* hardware subregion boundary */ + u16 swbase; /* software subregion offset */ + u16 swlim; /* software subregion boundary */ + u16 fbase; /* fuse subregion offset */ + u16 flim; /* fuse subregion boundary */ + int otpgu_base; /* offset to General Use Region */ +}; + +static struct otpinfo otpinfo; + +/* + * IPX OTP Code + * + * Exported functions: + * ipxotp_status() + * ipxotp_size() + * ipxotp_init() + * ipxotp_read_bit() + * ipxotp_read_region() + * ipxotp_nvread() + * + */ + +#define HWSW_RGN(rgn) (((rgn) == OTP_HW_RGN) ? "h/w" : "s/w") + +/* OTP layout */ +/* CC revs 21, 24 and 27 OTP General Use Region word offset */ +#define REVA4_OTPGU_BASE 12 + +/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */ +#define REVB8_OTPGU_BASE 20 + +/* CC rev 36 OTP General Use Region word offset */ +#define REV36_OTPGU_BASE 12 + +/* Subregion word offsets in General Use region */ +#define OTPGU_HSB_OFF 0 +#define OTPGU_SFB_OFF 1 +#define OTPGU_CI_OFF 2 +#define OTPGU_P_OFF 3 +#define OTPGU_SROM_OFF 4 + +/* Flag bit offsets in General Use region */ +#define OTPGU_HWP_OFF 60 +#define OTPGU_SWP_OFF 61 +#define OTPGU_CIP_OFF 62 +#define OTPGU_FUSEP_OFF 63 +#define OTPGU_CIP_MSK 0x4000 +#define OTPGU_P_MSK 0xf000 +#define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16) + +/* OTP Size */ +#define OTP_SZ_FU_324 ((roundup(324, 8))/8) /* 324 bits */ +#define OTP_SZ_FU_288 (288/8) /* 288 bits */ +#define OTP_SZ_FU_216 (216/8) /* 216 bits */ +#define OTP_SZ_FU_72 (72/8) /* 72 bits */ +#define OTP_SZ_CHECKSUM (16/8) /* 16 bits */ +#define OTP4315_SWREG_SZ 178 /* 178 bytes */ +#define OTP_SZ_FU_144 (144/8) /* 144 bits */ + +static int ipxotp_status(void *oh) +{ + struct otpinfo *oi = (struct otpinfo *) oh; + return (int)(oi->status); +} + +/* Return size in bytes */ +static int ipxotp_size(void *oh) +{ + struct otpinfo *oi = (struct otpinfo *) oh; + return (int)oi->wsize * 2; +} + +static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn) +{ + struct otpinfo *oi; + + oi = (struct otpinfo *) oh; + + return R_REG(&cc->sromotp[wn]); +} + +static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off) +{ + struct otpinfo *oi = (struct otpinfo *) oh; + uint k, row, col; + u32 otpp, st; + + row = off / oi->cols; + col = off % oi->cols; + + otpp = OTPP_START_BUSY | + ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) | + ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | + ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK); + W_REG(&cc->otpprog, otpp); + + for (k = 0; + ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY) + && (k < OTPP_TRIES); k++) + ; + if (k >= OTPP_TRIES) { + return 0xffff; + } + if (st & OTPP_READERR) { + return 0xffff; + } + st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT; + + return (int)st; +} + +/* Calculate max HW/SW region byte size by subtracting fuse region and checksum size, + * osizew is oi->wsize (OTP size - GU size) in words + */ +static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew) +{ + int ret = 0; + + switch (sih->chip) { + case BCM43224_CHIP_ID: + case BCM43225_CHIP_ID: + ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM; + break; + case BCM4313_CHIP_ID: + ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM; + break; + default: + break; /* Don't know about this chip */ + } + + return ret; +} + +static void _ipxotp_init(struct otpinfo *oi, chipcregs_t *cc) +{ + uint k; + u32 otpp, st; + + /* record word offset of General Use Region for various chipcommon revs */ + if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24 + || oi->sih->ccrev == 27) { + oi->otpgu_base = REVA4_OTPGU_BASE; + } else if (oi->sih->ccrev == 36) { + /* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */ + if (oi->wsize >= 128) + oi->otpgu_base = REVB8_OTPGU_BASE; + else + oi->otpgu_base = REV36_OTPGU_BASE; + } else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) { + oi->otpgu_base = REVB8_OTPGU_BASE; + } + + /* First issue an init command so the status is up to date */ + otpp = + OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK); + + W_REG(&cc->otpprog, otpp); + for (k = 0; + ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY) + && (k < OTPP_TRIES); k++) + ; + if (k >= OTPP_TRIES) { + return; + } + + /* Read OTP lock bits and subregion programmed indication bits */ + oi->status = R_REG(&cc->otpstatus); + + if ((oi->sih->chip == BCM43224_CHIP_ID) + || (oi->sih->chip == BCM43225_CHIP_ID)) { + u32 p_bits; + p_bits = + (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) & + OTPGU_P_MSK) + >> OTPGU_P_SHIFT; + oi->status |= (p_bits << OTPS_GUP_SHIFT); + } + + /* + * h/w region base and fuse region limit are fixed to the top and + * the bottom of the general use region. Everything else can be flexible. + */ + oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF; + oi->hwlim = oi->wsize; + if (oi->status & OTPS_GUP_HW) { + oi->hwlim = + ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16; + oi->swbase = oi->hwlim; + } else + oi->swbase = oi->hwbase; + + /* subtract fuse and checksum from beginning */ + oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2; + + if (oi->status & OTPS_GUP_SW) { + oi->swlim = + ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16; + oi->fbase = oi->swlim; + } else + oi->fbase = oi->swbase; + + oi->flim = oi->wsize; +} + +static void *ipxotp_init(struct si_pub *sih) +{ + uint idx; + chipcregs_t *cc; + struct otpinfo *oi; + + /* Make sure we're running IPX OTP */ + if (!OTPTYPE_IPX(sih->ccrev)) + return NULL; + + /* Make sure OTP is not disabled */ + if (ai_is_otp_disabled(sih)) + return NULL; + + /* OTP is always powered */ + oi = &otpinfo; + + /* Check for otp size */ + switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) { + case 0: + /* Nothing there */ + return NULL; + case 1: /* 32x64 */ + oi->rows = 32; + oi->cols = 64; + oi->wsize = 128; + break; + case 2: /* 64x64 */ + oi->rows = 64; + oi->cols = 64; + oi->wsize = 256; + break; + case 5: /* 96x64 */ + oi->rows = 96; + oi->cols = 64; + oi->wsize = 384; + break; + case 7: /* 16x64 *//* 1024 bits */ + oi->rows = 16; + oi->cols = 64; + oi->wsize = 64; + break; + default: + /* Don't know the geometry */ + return NULL; + } + + /* Retrieve OTP region info */ + idx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); + + _ipxotp_init(oi, cc); + + ai_setcoreidx(sih, idx); + + return (void *)oi; +} + +static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen) +{ + struct otpinfo *oi = (struct otpinfo *) oh; + uint idx; + chipcregs_t *cc; + uint base, i, sz; + + /* Validate region selection */ + switch (region) { + case OTP_HW_RGN: + sz = (uint) oi->hwlim - oi->hwbase; + if (!(oi->status & OTPS_GUP_HW)) { + *wlen = sz; + return -ENODATA; + } + if (*wlen < sz) { + *wlen = sz; + return -EOVERFLOW; + } + base = oi->hwbase; + break; + case OTP_SW_RGN: + sz = ((uint) oi->swlim - oi->swbase); + if (!(oi->status & OTPS_GUP_SW)) { + *wlen = sz; + return -ENODATA; + } + if (*wlen < sz) { + *wlen = sz; + return -EOVERFLOW; + } + base = oi->swbase; + break; + case OTP_CI_RGN: + sz = OTPGU_CI_SZ; + if (!(oi->status & OTPS_GUP_CI)) { + *wlen = sz; + return -ENODATA; + } + if (*wlen < sz) { + *wlen = sz; + return -EOVERFLOW; + } + base = oi->otpgu_base + OTPGU_CI_OFF; + break; + case OTP_FUSE_RGN: + sz = (uint) oi->flim - oi->fbase; + if (!(oi->status & OTPS_GUP_FUSE)) { + *wlen = sz; + return -ENODATA; + } + if (*wlen < sz) { + *wlen = sz; + return -EOVERFLOW; + } + base = oi->fbase; + break; + case OTP_ALL_RGN: + sz = ((uint) oi->flim - oi->hwbase); + if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) { + *wlen = sz; + return -ENODATA; + } + if (*wlen < sz) { + *wlen = sz; + return -EOVERFLOW; + } + base = oi->hwbase; + break; + default: + return -EINVAL; + } + + idx = ai_coreidx(oi->sih); + cc = ai_setcoreidx(oi->sih, SI_CC_IDX); + + /* Read the data */ + for (i = 0; i < sz; i++) + data[i] = ipxotp_otpr(oh, cc, base + i); + + ai_setcoreidx(oi->sih, idx); + *wlen = sz; + return 0; +} + +static int ipxotp_nvread(void *oh, char *data, uint *len) +{ + return -ENOTSUPP; +} + +static struct otp_fn_s ipxotp_fn = { + (otp_size_t) ipxotp_size, + (otp_read_bit_t) ipxotp_read_bit, + + (otp_init_t) ipxotp_init, + (otp_read_region_t) ipxotp_read_region, + (otp_nvread_t) ipxotp_nvread, + + (otp_status_t) ipxotp_status +}; + +/* + * otp_status() + * otp_size() + * otp_read_bit() + * otp_init() + * otp_read_region() + * otp_nvread() + */ + +int otp_status(void *oh) +{ + struct otpinfo *oi = (struct otpinfo *) oh; + + return oi->fn->status(oh); +} + +int otp_size(void *oh) +{ + struct otpinfo *oi = (struct otpinfo *) oh; + + return oi->fn->size(oh); +} + +u16 otp_read_bit(void *oh, uint offset) +{ + struct otpinfo *oi = (struct otpinfo *) oh; + uint idx = ai_coreidx(oi->sih); + chipcregs_t *cc = ai_setcoreidx(oi->sih, SI_CC_IDX); + u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset); + ai_setcoreidx(oi->sih, idx); + return readBit; +} + +void *otp_init(struct si_pub *sih) +{ + struct otpinfo *oi; + void *ret = NULL; + + oi = &otpinfo; + memset(oi, 0, sizeof(struct otpinfo)); + + oi->ccrev = sih->ccrev; + + if (OTPTYPE_IPX(oi->ccrev)) + oi->fn = &ipxotp_fn; + + if (oi->fn == NULL) { + return NULL; + } + + oi->sih = sih; + + ret = (oi->fn->init) (sih); + + return ret; +} + +int +otp_read_region(struct si_pub *sih, int region, u16 *data, + uint *wlen) { + void *oh; + int err = 0; + + if (ai_is_otp_disabled(sih)) { + err = -EPERM; + goto out; + } + + oh = otp_init(sih); + if (oh == NULL) { + err = -EBADE; + goto out; + } + + err = (((struct otpinfo *) oh)->fn->read_region) + (oh, region, data, wlen); + + out: + return err; +} + +int otp_nvread(void *oh, char *data, uint *len) +{ + struct otpinfo *oi = (struct otpinfo *) oh; + + return oi->fn->nvread(oh, data, len); +} diff --git a/drivers/staging/brcm80211/include/bcmotp.h b/drivers/staging/brcm80211/brcmsmac/otp.h similarity index 85% rename from drivers/staging/brcm80211/include/bcmotp.h rename to drivers/staging/brcm80211/brcmsmac/otp.h index 5803accaa479..f6d3a56acf1e 100644 --- a/drivers/staging/brcm80211/include/bcmotp.h +++ b/drivers/staging/brcm80211/brcmsmac/otp.h @@ -14,8 +14,10 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _bcmotp_h_ -#define _bcmotp_h_ +#ifndef _BRCM_OTP_H_ +#define _BRCM_OTP_H_ + +#include "types.h" /* OTP regions */ #define OTP_HW_RGN 1 @@ -37,8 +39,9 @@ extern int otp_status(void *oh); extern int otp_size(void *oh); extern u16 otp_read_bit(void *oh, uint offset); -extern void *otp_init(si_t *sih); -extern int otp_read_region(si_t *sih, int region, u16 *data, uint *wlen); +extern void *otp_init(struct si_pub *sih); +extern int otp_read_region(struct si_pub *sih, int region, u16 *data, + uint *wlen); extern int otp_nvread(void *oh, char *data, uint *len); -#endif /* _bcmotp_h_ */ +#endif /* _BRCM_OTP_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c similarity index 78% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c rename to drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c index 6cba4dfbc3dd..17012fbe9c97 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c @@ -14,35 +14,27 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include "phy_hal.h" +#include "phy_int.h" +#include "phy_radio.h" +#include "phy_lcn.h" +#include "phyreg_n.h" u32 phyhal_msg_level = PHYHAL_ERROR; -typedef struct _chan_info_basic { +struct chan_info_basic { u16 chan; u16 freq; -} chan_info_basic_t; - -static chan_info_basic_t chan_info_all[] = { +}; +static struct chan_info_basic chan_info_all[] = { {1, 2412}, {2, 2417}, {3, 2422}, @@ -117,41 +109,43 @@ u16 ltrn_list[PHY_LTRN_LIST_LEN] = { const u8 ofdm_rate_lookup[] = { - WLC_RATE_48M, - WLC_RATE_24M, - WLC_RATE_12M, - WLC_RATE_6M, - WLC_RATE_54M, - WLC_RATE_36M, - WLC_RATE_18M, - WLC_RATE_9M + BRCM_RATE_48M, + BRCM_RATE_24M, + BRCM_RATE_12M, + BRCM_RATE_6M, + BRCM_RATE_54M, + BRCM_RATE_36M, + BRCM_RATE_18M, + BRCM_RATE_9M }; #define PHY_WREG_LIMIT 24 -static void wlc_set_phy_uninitted(phy_info_t *pi); -static u32 wlc_phy_get_radio_ver(phy_info_t *pi); +static void wlc_set_phy_uninitted(struct brcms_phy *pi); +static u32 wlc_phy_get_radio_ver(struct brcms_phy *pi); static void wlc_phy_timercb_phycal(void *arg); -static bool wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr, +static bool wlc_phy_noise_calc_phy(struct brcms_phy *pi, u32 *cmplx_pwr, s8 *pwr_ant); -static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay); -static void wlc_phy_noise_cb(phy_info_t *pi, u8 channel, s8 noise_dbm); -static void wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, +static void wlc_phy_cal_perical_mphase_schedule(struct brcms_phy *pi, + uint delay); + +static void wlc_phy_noise_cb(struct brcms_phy *pi, u8 channel, s8 noise_dbm); +static void wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch); -static void wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, +static void wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *tp, chanspec_t); -static bool wlc_phy_cal_txpower_recalc_sw(phy_info_t *pi); +static bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi); -static s8 wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan, +static s8 wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band, u8 rate); -static void wlc_phy_upd_env_txpwr_rate_limits(phy_info_t *pi, u32 band); -static s8 wlc_phy_env_measure_vbat(phy_info_t *pi); -static s8 wlc_phy_env_measure_temperature(phy_info_t *pi); +static void wlc_phy_upd_env_txpwr_rate_limits(struct brcms_phy *pi, u32 band); +static s8 wlc_phy_env_measure_vbat(struct brcms_phy *pi); +static s8 wlc_phy_env_measure_temperature(struct brcms_phy *pi); -char *phy_getvar(phy_info_t *pi, const char *name) +char *phy_getvar(struct brcms_phy *pi, const char *name) { char *vars = pi->vars; char *s; @@ -172,10 +166,10 @@ char *phy_getvar(phy_info_t *pi, const char *name) ; } - return nvram_get(name); + return NULL; } -int phy_getintvar(phy_info_t *pi, const char *name) +int phy_getintvar(struct brcms_phy *pi, const char *name) { char *val; @@ -186,29 +180,29 @@ int phy_getintvar(phy_info_t *pi, const char *name) return simple_strtoul(val, NULL, 0); } -void wlc_phyreg_enter(wlc_phy_t *pih) +void wlc_phyreg_enter(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim); } -void wlc_phyreg_exit(wlc_phy_t *pih) +void wlc_phyreg_exit(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim); } -void wlc_radioreg_enter(wlc_phy_t *pih) +void wlc_radioreg_enter(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO); udelay(10); } -void wlc_radioreg_exit(wlc_phy_t *pih) +void wlc_radioreg_exit(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; volatile u16 dummy; dummy = R_REG(&pi->regs->phyversion); @@ -216,7 +210,7 @@ void wlc_radioreg_exit(wlc_phy_t *pih) wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0); } -u16 read_radio_reg(phy_info_t *pi, u16 addr) +u16 read_radio_reg(struct brcms_phy *pi, u16 addr) { u16 data; @@ -247,16 +241,10 @@ u16 read_radio_reg(phy_info_t *pi, u16 addr) if ((D11REV_GE(pi->sh->corerev, 24)) || (D11REV_IS(pi->sh->corerev, 22) && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { - W_REG(&pi->regs->radioregaddr, addr); -#ifdef __mips__ - (void)R_REG(&pi->regs->radioregaddr); -#endif + W_REG_FLUSH(&pi->regs->radioregaddr, addr); data = R_REG(&pi->regs->radioregdata); } else { - W_REG(&pi->regs->phy4waddr, addr); -#ifdef __mips__ - (void)R_REG(&pi->regs->phy4waddr); -#endif + W_REG_FLUSH(&pi->regs->phy4waddr, addr); #ifdef __ARM_ARCH_4T__ __asm__(" .align 4 "); @@ -272,7 +260,7 @@ u16 read_radio_reg(phy_info_t *pi, u16 addr) return data; } -void write_radio_reg(phy_info_t *pi, u16 addr, u16 val) +void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val) { if (NORADIO_ENAB(pi->pubpi)) return; @@ -281,16 +269,10 @@ void write_radio_reg(phy_info_t *pi, u16 addr, u16 val) (D11REV_IS(pi->sh->corerev, 22) && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { - W_REG(&pi->regs->radioregaddr, addr); -#ifdef __mips__ - (void)R_REG(&pi->regs->radioregaddr); -#endif + W_REG_FLUSH(&pi->regs->radioregaddr, addr); W_REG(&pi->regs->radioregdata, val); } else { - W_REG(&pi->regs->phy4waddr, addr); -#ifdef __mips__ - (void)R_REG(&pi->regs->phy4waddr); -#endif + W_REG_FLUSH(&pi->regs->phy4waddr, addr); W_REG(&pi->regs->phy4wdatalo, val); } @@ -302,7 +284,7 @@ void write_radio_reg(phy_info_t *pi, u16 addr, u16 val) } } -static u32 read_radio_id(phy_info_t *pi) +static u32 read_radio_id(struct brcms_phy *pi) { u32 id; @@ -312,29 +294,17 @@ static u32 read_radio_id(phy_info_t *pi) if (D11REV_GE(pi->sh->corerev, 24)) { u32 b0, b1, b2; - W_REG(&pi->regs->radioregaddr, 0); -#ifdef __mips__ - (void)R_REG(&pi->regs->radioregaddr); -#endif + W_REG_FLUSH(&pi->regs->radioregaddr, 0); b0 = (u32) R_REG(&pi->regs->radioregdata); - W_REG(&pi->regs->radioregaddr, 1); -#ifdef __mips__ - (void)R_REG(&pi->regs->radioregaddr); -#endif + W_REG_FLUSH(&pi->regs->radioregaddr, 1); b1 = (u32) R_REG(&pi->regs->radioregdata); - W_REG(&pi->regs->radioregaddr, 2); -#ifdef __mips__ - (void)R_REG(&pi->regs->radioregaddr); -#endif + W_REG_FLUSH(&pi->regs->radioregaddr, 2); b2 = (u32) R_REG(&pi->regs->radioregdata); id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4) & 0xf); } else { - W_REG(&pi->regs->phy4waddr, RADIO_IDCODE); -#ifdef __mips__ - (void)R_REG(&pi->regs->phy4waddr); -#endif + W_REG_FLUSH(&pi->regs->phy4waddr, RADIO_IDCODE); id = (u32) R_REG(&pi->regs->phy4wdatalo); id |= (u32) R_REG(&pi->regs->phy4wdatahi) << 16; } @@ -342,7 +312,7 @@ static u32 read_radio_id(phy_info_t *pi) return id; } -void and_radio_reg(phy_info_t *pi, u16 addr, u16 val) +void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val) { u16 rval; @@ -353,7 +323,7 @@ void and_radio_reg(phy_info_t *pi, u16 addr, u16 val) write_radio_reg(pi, addr, (rval & val)); } -void or_radio_reg(phy_info_t *pi, u16 addr, u16 val) +void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val) { u16 rval; @@ -364,7 +334,7 @@ void or_radio_reg(phy_info_t *pi, u16 addr, u16 val) write_radio_reg(pi, addr, (rval | val)); } -void xor_radio_reg(phy_info_t *pi, u16 addr, u16 mask) +void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask) { u16 rval; @@ -375,7 +345,7 @@ void xor_radio_reg(phy_info_t *pi, u16 addr, u16 mask) write_radio_reg(pi, addr, (rval ^ mask)); } -void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) +void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val) { u16 rval; @@ -386,35 +356,31 @@ void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) write_radio_reg(pi, addr, (rval & ~mask) | (val & mask)); } -void write_phy_channel_reg(phy_info_t *pi, uint val) +void write_phy_channel_reg(struct brcms_phy *pi, uint val) { W_REG(&pi->regs->phychannel, val); } -u16 read_phy_reg(phy_info_t *pi, u16 addr) +u16 read_phy_reg(struct brcms_phy *pi, u16 addr) { d11regs_t *regs; regs = pi->regs; - W_REG(®s->phyregaddr, addr); -#ifdef __mips__ - (void)R_REG(®s->phyregaddr); -#endif + W_REG_FLUSH(®s->phyregaddr, addr); pi->phy_wreg = 0; return R_REG(®s->phyregdata); } -void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) +void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val) { d11regs_t *regs; regs = pi->regs; #ifdef __mips__ - W_REG(®s->phyregaddr, addr); - (void)R_REG(®s->phyregaddr); + W_REG_FLUSH(®s->phyregaddr, addr); W_REG(®s->phyregdata, val); if (addr == 0x72) (void)R_REG(®s->phyregdata); @@ -430,53 +396,44 @@ void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) #endif } -void and_phy_reg(phy_info_t *pi, u16 addr, u16 val) +void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val) { d11regs_t *regs; regs = pi->regs; - W_REG(®s->phyregaddr, addr); -#ifdef __mips__ - (void)R_REG(®s->phyregaddr); -#endif + W_REG_FLUSH(®s->phyregaddr, addr); W_REG(®s->phyregdata, (R_REG(®s->phyregdata) & val)); pi->phy_wreg = 0; } -void or_phy_reg(phy_info_t *pi, u16 addr, u16 val) +void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val) { d11regs_t *regs; regs = pi->regs; - W_REG(®s->phyregaddr, addr); -#ifdef __mips__ - (void)R_REG(®s->phyregaddr); -#endif + W_REG_FLUSH(®s->phyregaddr, addr); W_REG(®s->phyregdata, (R_REG(®s->phyregdata) | val)); pi->phy_wreg = 0; } -void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) +void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val) { d11regs_t *regs; regs = pi->regs; - W_REG(®s->phyregaddr, addr); -#ifdef __mips__ - (void)R_REG(®s->phyregaddr); -#endif + W_REG_FLUSH(®s->phyregaddr, addr); W_REG(®s->phyregdata, ((R_REG(®s->phyregdata) & ~mask) | (val & mask))); pi->phy_wreg = 0; } -static void WLBANDINITFN(wlc_set_phy_uninitted) (phy_info_t *pi) +static void wlc_set_phy_uninitted(struct brcms_phy *pi) { int i, j; @@ -513,11 +470,11 @@ static void WLBANDINITFN(wlc_set_phy_uninitted) (phy_info_t *pi) } } -shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp) +struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp) { - shared_phy_t *sh; + struct shared_phy *sh; - sh = kzalloc(sizeof(shared_phy_t), GFP_ATOMIC); + sh = kzalloc(sizeof(struct shared_phy), GFP_ATOMIC); if (sh == NULL) { return NULL; } @@ -550,19 +507,14 @@ shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp) return sh; } -void wlc_phy_shared_detach(shared_phy_t *phy_sh) +struct brcms_phy_pub * +wlc_phy_attach(struct shared_phy *sh, void *regs, int bandtype, + char *vars, struct wiphy *wiphy) { - if (phy_sh) { - kfree(phy_sh); - } -} - -wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, - char *vars, struct wiphy *wiphy) -{ - phy_info_t *pi; + struct brcms_phy *pi; u32 sflags = 0; uint phyversion; + u32 idcode; int i; if (D11REV_IS(sh->corerev, 4)) @@ -584,7 +536,7 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, return &pi->pubpi_ro; } - pi = kzalloc(sizeof(phy_info_t), GFP_ATOMIC); + pi = kzalloc(sizeof(struct brcms_phy), GFP_ATOMIC); if (pi == NULL) { return NULL; } @@ -633,27 +585,19 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, } } - if (ISSIM_ENAB(pi->sh->sih)) { - pi->pubpi.radioid = NORADIO_ID; - pi->pubpi.radiorev = 5; - } else { - u32 idcode; + wlc_phy_anacore((struct brcms_phy_pub *) pi, ON); - wlc_phy_anacore((wlc_phy_t *) pi, ON); + idcode = wlc_phy_get_radio_ver(pi); + pi->pubpi.radioid = + (idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT; + pi->pubpi.radiorev = + (idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT; + pi->pubpi.radiover = + (idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT; + if (!VALID_RADIO(pi, pi->pubpi.radioid)) + goto err; - idcode = wlc_phy_get_radio_ver(pi); - pi->pubpi.radioid = - (idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT; - pi->pubpi.radiorev = - (idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT; - pi->pubpi.radiover = - (idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT; - if (!VALID_RADIO(pi, pi->pubpi.radioid)) { - goto err; - } - - wlc_phy_switch_radio((wlc_phy_t *) pi, OFF); - } + wlc_phy_switch_radio((struct brcms_phy_pub *) pi, OFF); wlc_set_phy_uninitted(pi); @@ -692,9 +636,9 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, pi->phynoise_polling = false; for (i = 0; i < TXP_NUM_RATES; i++) { - pi->txpwr_limit[i] = WLC_TXPWR_MAX; - pi->txpwr_env_limit[i] = WLC_TXPWR_MAX; - pi->tx_user_target[i] = WLC_TXPWR_MAX; + pi->txpwr_limit[i] = BRCMS_TXPWR_MAX; + pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX; + pi->tx_user_target[i] = BRCMS_TXPWR_MAX; } pi->radiopwr_override = RADIOPWR_OVERRIDE_DEF; @@ -727,7 +671,7 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, pi->vars = (char *)&pi->vars; - memcpy(&pi->pubpi_ro, &pi->pubpi, sizeof(wlc_phy_t)); + memcpy(&pi->pubpi_ro, &pi->pubpi, sizeof(struct brcms_phy_pub)); return &pi->pubpi_ro; @@ -736,9 +680,9 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, return NULL; } -void wlc_phy_detach(wlc_phy_t *pih) +void wlc_phy_detach(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; if (pih) { if (--pi->refcnt) { @@ -763,10 +707,10 @@ void wlc_phy_detach(wlc_phy_t *pih) } bool -wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype, u16 *phyrev, +wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev, u16 *radioid, u16 *radiover) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; *phytype = (u16) pi->pubpi.phy_type; *phyrev = (u16) pi->pubpi.phy_rev; *radioid = pi->pubpi.radioid; @@ -775,21 +719,21 @@ wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype, u16 *phyrev, return true; } -bool wlc_phy_get_encore(wlc_phy_t *pih) +bool wlc_phy_get_encore(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; return pi->pubpi.abgphy_encore; } -u32 wlc_phy_get_coreflags(wlc_phy_t *pih) +u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; return pi->pubpi.coreflags; } static void wlc_phy_timercb_phycal(void *arg) { - phy_info_t *pi = (phy_info_t *) arg; + struct brcms_phy *pi = (struct brcms_phy *) arg; uint delay = 5; if (PHY_PERICAL_MPHASE_PENDING(pi)) { @@ -810,9 +754,9 @@ static void wlc_phy_timercb_phycal(void *arg) } -void wlc_phy_anacore(wlc_phy_t *pih, bool on) +void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; if (ISNPHY(pi)) { if (on) { @@ -847,9 +791,9 @@ void wlc_phy_anacore(wlc_phy_t *pih, bool on) } } -u32 wlc_phy_clk_bwbits(wlc_phy_t *pih) +u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; u32 phy_bw_clkbits = 0; @@ -872,16 +816,16 @@ u32 wlc_phy_clk_bwbits(wlc_phy_t *pih) return phy_bw_clkbits; } -void WLBANDINITFN(wlc_phy_por_inform) (wlc_phy_t *ppi) +void wlc_phy_por_inform(struct brcms_phy_pub *ppi) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; pi->phy_init_por = true; } -void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock) +void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; pi->edcrs_threshold_lock = lock; @@ -891,16 +835,16 @@ void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock) write_phy_reg(pi, 0x22f, 0x3c0); } -void wlc_phy_initcal_enable(wlc_phy_t *pih, bool initcal) +void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; pi->do_initcal = initcal; } -void wlc_phy_hw_clk_state_upd(wlc_phy_t *pih, bool newstate) +void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; if (!pi || !pi->sh) return; @@ -908,9 +852,9 @@ void wlc_phy_hw_clk_state_upd(wlc_phy_t *pih, bool newstate) pi->sh->clk = newstate; } -void wlc_phy_hw_state_upd(wlc_phy_t *pih, bool newstate) +void wlc_phy_hw_state_upd(struct brcms_phy_pub *pih, bool newstate) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; if (!pi || !pi->sh) return; @@ -918,11 +862,11 @@ void wlc_phy_hw_state_upd(wlc_phy_t *pih, bool newstate) pi->sh->up = newstate; } -void WLBANDINITFN(wlc_phy_init) (wlc_phy_t *pih, chanspec_t chanspec) +void wlc_phy_init(struct brcms_phy_pub *pih, chanspec_t chanspec) { u32 mc; initfn_t phy_init = NULL; - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; if (pi->init_in_progress) return; @@ -957,7 +901,7 @@ void WLBANDINITFN(wlc_phy_init) (wlc_phy_t *pih, chanspec_t chanspec) pi->nphy_gain_boost = true; - wlc_phy_switch_radio((wlc_phy_t *) pi, ON); + wlc_phy_switch_radio((struct brcms_phy_pub *) pi, ON); (*phy_init) (pi); @@ -969,14 +913,14 @@ void WLBANDINITFN(wlc_phy_init) (wlc_phy_t *pih, chanspec_t chanspec) if (!(ISNPHY(pi))) wlc_phy_txpower_update_shm(pi); - wlc_phy_ant_rxdiv_set((wlc_phy_t *) pi, pi->sh->rx_antdiv); + wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi, pi->sh->rx_antdiv); pi->init_in_progress = false; } -void wlc_phy_cal_init(wlc_phy_t *pih) +void wlc_phy_cal_init(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; initfn_t cal_init = NULL; if (WARN((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) != 0, @@ -992,9 +936,9 @@ void wlc_phy_cal_init(wlc_phy_t *pih) } } -int wlc_phy_down(wlc_phy_t *pih) +int wlc_phy_down(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; int callbacks = 0; if (pi->phycal_timer @@ -1007,7 +951,7 @@ int wlc_phy_down(wlc_phy_t *pih) return callbacks; } -static u32 wlc_phy_get_radio_ver(phy_info_t *pi) +static u32 wlc_phy_get_radio_ver(struct brcms_phy *pi) { u32 ver; @@ -1017,7 +961,7 @@ static u32 wlc_phy_get_radio_ver(phy_info_t *pi) } void -wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset, +wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, uint tbl_offset, u16 tblAddr, u16 tblDataHi, u16 tblDataLo) { write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset); @@ -1025,19 +969,17 @@ wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset, pi->tbl_data_hi = tblDataHi; pi->tbl_data_lo = tblDataLo; - if ((pi->sh->chip == BCM43224_CHIP_ID || - pi->sh->chip == BCM43421_CHIP_ID) && - (pi->sh->chiprev == 1)) { + if (pi->sh->chip == BCM43224_CHIP_ID && + pi->sh->chiprev == 1) { pi->tbl_addr = tblAddr; pi->tbl_save_id = tbl_id; pi->tbl_save_offset = tbl_offset; } } -void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val) +void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val) { - if ((pi->sh->chip == BCM43224_CHIP_ID || - pi->sh->chip == BCM43421_CHIP_ID) && + if ((pi->sh->chip == BCM43224_CHIP_ID) && (pi->sh->chiprev == 1) && (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) { read_phy_reg(pi, pi->tbl_data_lo); @@ -1058,7 +1000,7 @@ void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val) } void -wlc_phy_write_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, +wlc_phy_write_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info, u16 tblAddr, u16 tblDataHi, u16 tblDataLo) { uint idx; @@ -1073,8 +1015,7 @@ wlc_phy_write_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, for (idx = 0; idx < ptbl_info->tbl_len; idx++) { - if ((pi->sh->chip == BCM43224_CHIP_ID || - pi->sh->chip == BCM43421_CHIP_ID) && + if ((pi->sh->chip == BCM43224_CHIP_ID) && (pi->sh->chiprev == 1) && (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) { read_phy_reg(pi, tblDataLo); @@ -1099,7 +1040,7 @@ wlc_phy_write_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, } void -wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, +wlc_phy_read_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info, u16 tblAddr, u16 tblDataHi, u16 tblDataLo) { uint idx; @@ -1114,8 +1055,7 @@ wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, for (idx = 0; idx < ptbl_info->tbl_len; idx++) { - if ((pi->sh->chip == BCM43224_CHIP_ID || - pi->sh->chip == BCM43421_CHIP_ID) && + if ((pi->sh->chip == BCM43224_CHIP_ID) && (pi->sh->chiprev == 1)) { (void)read_phy_reg(pi, tblDataLo); @@ -1138,7 +1078,8 @@ wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, } uint -wlc_phy_init_radio_regs_allbands(phy_info_t *pi, radio_20xx_regs_t *radioregs) +wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi, + struct radio_20xx_regs *radioregs) { uint i = 0; @@ -1155,7 +1096,7 @@ wlc_phy_init_radio_regs_allbands(phy_info_t *pi, radio_20xx_regs_t *radioregs) } uint -wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs, +wlc_phy_init_radio_regs(struct brcms_phy *pi, struct radio_regs *radioregs, u16 core_offset) { uint i = 0; @@ -1169,7 +1110,7 @@ wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs, address | core_offset, (u16) radioregs[i].init_a); if (ISNPHY(pi) && (++count % 4 == 0)) - WLC_PHY_WAR_PR51571(pi); + BRCMS_PHY_WAR_PR51571(pi); } } else { if (radioregs[i].do_init_g) { @@ -1178,7 +1119,7 @@ wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs, address | core_offset, (u16) radioregs[i].init_g); if (ISNPHY(pi) && (++count % 4 == 0)) - WLC_PHY_WAR_PR51571(pi); + BRCMS_PHY_WAR_PR51571(pi); } } @@ -1188,7 +1129,7 @@ wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs, return i; } -void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on) +void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on) { #define DUMMY_PKT_LEN 20 d11regs_t *regs = pi->regs; @@ -1243,11 +1184,6 @@ void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on) i = 0; count = ofdm ? 30 : 250; - - if (ISSIM_ENAB(pi->sh->sih)) { - count *= 100; - } - while ((i++ < count) && (R_REG(®s->txe_status) & (1 << 7))) { udelay(10); @@ -1271,9 +1207,9 @@ void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on) } } -void wlc_phy_hold_upd(wlc_phy_t *pih, mbool id, bool set) +void wlc_phy_hold_upd(struct brcms_phy_pub *pih, mbool id, bool set) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; if (set) { mboolset(pi->measure_hold, id); @@ -1284,9 +1220,9 @@ void wlc_phy_hold_upd(wlc_phy_t *pih, mbool id, bool set) return; } -void wlc_phy_mute_upd(wlc_phy_t *pih, bool mute, mbool flags) +void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, mbool flags) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; if (mute) { mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE); @@ -1299,9 +1235,9 @@ void wlc_phy_mute_upd(wlc_phy_t *pih, bool mute, mbool flags) return; } -void wlc_phy_clear_tssi(wlc_phy_t *pih) +void wlc_phy_clear_tssi(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; if (ISNPHY(pi)) { return; @@ -1313,14 +1249,14 @@ void wlc_phy_clear_tssi(wlc_phy_t *pih) } } -static bool wlc_phy_cal_txpower_recalc_sw(phy_info_t *pi) +static bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi) { return false; } -void wlc_phy_switch_radio(wlc_phy_t *pih, bool on) +void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; if (NORADIO_ENAB(pi->pubpi)) return; @@ -1361,37 +1297,37 @@ void wlc_phy_switch_radio(wlc_phy_t *pih, bool on) } } -u16 wlc_phy_bw_state_get(wlc_phy_t *ppi) +u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; return pi->bw; } -void wlc_phy_bw_state_set(wlc_phy_t *ppi, u16 bw) +void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; pi->bw = bw; } -void wlc_phy_chanspec_radio_set(wlc_phy_t *ppi, chanspec_t newch) +void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, chanspec_t newch) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; pi->radio_chanspec = newch; } -chanspec_t wlc_phy_chanspec_get(wlc_phy_t *ppi) +chanspec_t wlc_phy_chanspec_get(struct brcms_phy_pub *ppi) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; return pi->radio_chanspec; } -void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec) +void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, chanspec_t chanspec) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; u16 m_cur_channel; chansetfn_t chanspec_set = NULL; @@ -1424,7 +1360,7 @@ int wlc_phy_chanspec_freq2bandrange_lpssn(uint freq) return range; } -int wlc_phy_chanspec_bandrange_get(phy_info_t *pi, chanspec_t chanspec) +int wlc_phy_chanspec_bandrange_get(struct brcms_phy *pi, chanspec_t chanspec) { int range = -1; uint channel = CHSPEC_CHANNEL(chanspec); @@ -1439,9 +1375,10 @@ int wlc_phy_chanspec_bandrange_get(phy_info_t *pi, chanspec_t chanspec) return range; } -void wlc_phy_chanspec_ch14_widefilter_set(wlc_phy_t *ppi, bool wide_filter) +void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi, + bool wide_filter) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; pi->channel_14_wide_filter = wide_filter; @@ -1458,9 +1395,10 @@ int wlc_phy_channel2freq(uint channel) } void -wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band, chanvec_t *channels) +wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band, + chanvec_t *channels) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; uint i; uint channel; @@ -1473,15 +1411,15 @@ wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band, chanvec_t *channels) && (channel <= LAST_REF5_CHANNUM)) continue; - if (((band == WLC_BAND_2G) && (channel <= CH_MAX_2G_CHANNEL)) || - ((band == WLC_BAND_5G) && (channel > CH_MAX_2G_CHANNEL))) + if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) || + (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL)) setbit(channels->vec, channel); } } -chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band) +chanspec_t wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; uint i; uint channel; chanspec_t chspec; @@ -1505,7 +1443,7 @@ chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band) chspec = channel | WL_CHANSPEC_BW_40 | WL_CHANSPEC_CTL_SB_LOWER; - if (band == WLC_BAND_2G) + if (band == BRCM_BAND_2G) chspec |= WL_CHANSPEC_BAND_2G; else chspec |= WL_CHANSPEC_BAND_5G; @@ -1516,17 +1454,17 @@ chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band) && (channel <= LAST_REF5_CHANNUM)) continue; - if (((band == WLC_BAND_2G) && (channel <= CH_MAX_2G_CHANNEL)) || - ((band == WLC_BAND_5G) && (channel > CH_MAX_2G_CHANNEL))) + if ((band == BRCM_BAND_2G && channel <= CH_MAX_2G_CHANNEL) || + (band == BRCM_BAND_5G && channel > CH_MAX_2G_CHANNEL)) return chspec; } return (chanspec_t) INVCHANSPEC; } -int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override) +int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; *qdbm = pi->tx_user_target[0]; if (override != NULL) @@ -1534,41 +1472,42 @@ int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override) return 0; } -void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr) +void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi, + struct txpwr_limits *txpwr) { bool mac_enabled = false; - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; memcpy(&pi->tx_user_target[TXP_FIRST_CCK], - &txpwr->cck[0], WLC_NUM_RATES_CCK); + &txpwr->cck[0], BRCMS_NUM_RATES_CCK); memcpy(&pi->tx_user_target[TXP_FIRST_OFDM], - &txpwr->ofdm[0], WLC_NUM_RATES_OFDM); + &txpwr->ofdm[0], BRCMS_NUM_RATES_OFDM); memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_20_CDD], - &txpwr->ofdm_cdd[0], WLC_NUM_RATES_OFDM); + &txpwr->ofdm_cdd[0], BRCMS_NUM_RATES_OFDM); memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_SISO], - &txpwr->ofdm_40_siso[0], WLC_NUM_RATES_OFDM); + &txpwr->ofdm_40_siso[0], BRCMS_NUM_RATES_OFDM); memcpy(&pi->tx_user_target[TXP_FIRST_OFDM_40_CDD], - &txpwr->ofdm_40_cdd[0], WLC_NUM_RATES_OFDM); + &txpwr->ofdm_40_cdd[0], BRCMS_NUM_RATES_OFDM); memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SISO], - &txpwr->mcs_20_siso[0], WLC_NUM_RATES_MCS_1_STREAM); + &txpwr->mcs_20_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM); memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_CDD], - &txpwr->mcs_20_cdd[0], WLC_NUM_RATES_MCS_1_STREAM); + &txpwr->mcs_20_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM); memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_STBC], - &txpwr->mcs_20_stbc[0], WLC_NUM_RATES_MCS_1_STREAM); + &txpwr->mcs_20_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM); memcpy(&pi->tx_user_target[TXP_FIRST_MCS_20_SDM], - &txpwr->mcs_20_mimo[0], WLC_NUM_RATES_MCS_2_STREAM); + &txpwr->mcs_20_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM); memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SISO], - &txpwr->mcs_40_siso[0], WLC_NUM_RATES_MCS_1_STREAM); + &txpwr->mcs_40_siso[0], BRCMS_NUM_RATES_MCS_1_STREAM); memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_CDD], - &txpwr->mcs_40_cdd[0], WLC_NUM_RATES_MCS_1_STREAM); + &txpwr->mcs_40_cdd[0], BRCMS_NUM_RATES_MCS_1_STREAM); memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_STBC], - &txpwr->mcs_40_stbc[0], WLC_NUM_RATES_MCS_1_STREAM); + &txpwr->mcs_40_stbc[0], BRCMS_NUM_RATES_MCS_1_STREAM); memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SDM], - &txpwr->mcs_40_mimo[0], WLC_NUM_RATES_MCS_2_STREAM); + &txpwr->mcs_40_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM); if (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) mac_enabled = true; @@ -1583,9 +1522,9 @@ void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr) wlapi_enable_mac(pi->sh->physhim); } -int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override) +int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; int i; if (qdbm > 127) @@ -1619,13 +1558,13 @@ int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override) } void -wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint channel, u8 *min_pwr, +wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint channel, u8 *min_pwr, u8 *max_pwr, int txp_rate_idx) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; uint i; - *min_pwr = pi->min_txpower * WLC_TXPWR_DB_FACTOR; + *min_pwr = pi->min_txpower * BRCMS_TXPWR_DB_FACTOR; if (ISNPHY(pi)) { if (txp_rate_idx < 0) @@ -1639,7 +1578,7 @@ wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint channel, u8 *min_pwr, *max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx]; } else { - *max_pwr = WLC_TXPWR_MAX; + *max_pwr = BRCMS_TXPWR_MAX; if (txp_rate_idx < 0) txp_rate_idx = TXP_FIRST_OFDM; @@ -1669,10 +1608,10 @@ wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint channel, u8 *min_pwr, } void -wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan, u8 *max_txpwr, - u8 *min_txpwr) +wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan, + u8 *max_txpwr, u8 *min_txpwr) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; u8 tx_pwr_max = 0; u8 tx_pwr_min = 255; u8 max_num_rate; @@ -1700,27 +1639,27 @@ wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan, u8 *max_txpwr, } void -wlc_phy_txpower_boardlimit_band(wlc_phy_t *ppi, uint bandunit, s32 *max_pwr, - s32 *min_pwr, u32 *step_pwr) +wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, uint bandunit, + s32 *max_pwr, s32 *min_pwr, u32 *step_pwr) { return; } -u8 wlc_phy_txpower_get_target_min(wlc_phy_t *ppi) +u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; return pi->tx_power_min; } -u8 wlc_phy_txpower_get_target_max(wlc_phy_t *ppi) +u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; return pi->tx_power_max; } -void wlc_phy_txpower_recalc_target(phy_info_t *pi) +void wlc_phy_txpower_recalc_target(struct brcms_phy *pi) { u8 maxtxpwr, mintxpwr, rate, pactrl; uint target_chan; @@ -1731,7 +1670,7 @@ void wlc_phy_txpower_recalc_target(phy_info_t *pi) u8 max_num_rate; u8 start_rate = 0; chanspec_t chspec; - u32 band = CHSPEC2WLC_BAND(pi->radio_chanspec); + u32 band = CHSPEC2BAND(pi->radio_chanspec); initfn_t txpwr_recalc_fn = NULL; chspec = pi->radio_chanspec; @@ -1788,7 +1727,8 @@ void wlc_phy_txpower_recalc_target(phy_info_t *pi) { - wlc_phy_txpower_sromlimit((wlc_phy_t *) pi, target_chan, + wlc_phy_txpower_sromlimit((struct brcms_phy_pub *) pi, + target_chan, &mintxpwr, &maxtxpwr, rate); maxtxpwr = min(maxtxpwr, pi->txpwr_limit[rate]); @@ -1839,10 +1779,10 @@ void wlc_phy_txpower_recalc_target(phy_info_t *pi) } void -wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, struct txpwr_limits *txpwr, +wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr, chanspec_t chanspec) { - u8 tmp_txpwr_limit[2 * WLC_NUM_RATES_OFDM]; + u8 tmp_txpwr_limit[2 * BRCMS_NUM_RATES_OFDM]; u8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL; int rate_start_index = 0, rate1, rate2, k; @@ -1885,16 +1825,15 @@ wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, struct txpwr_limits *txpwr, break; } - for (rate2 = 0; rate2 < WLC_NUM_RATES_OFDM; rate2++) { + for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM; rate2++) { tmp_txpwr_limit[rate2] = 0; - tmp_txpwr_limit[WLC_NUM_RATES_OFDM + rate2] = + tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] = txpwr_ptr1[rate2]; } wlc_phy_mcs_to_ofdm_powers_nphy(tmp_txpwr_limit, 0, - WLC_NUM_RATES_OFDM - 1, - WLC_NUM_RATES_OFDM); + BRCMS_NUM_RATES_OFDM - 1, BRCMS_NUM_RATES_OFDM); for (rate1 = rate_start_index, rate2 = 0; - rate2 < WLC_NUM_RATES_OFDM; rate1++, rate2++) + rate2 < BRCMS_NUM_RATES_OFDM; rate1++, rate2++) pi->txpwr_limit[rate1] = min(txpwr_ptr2[rate2], tmp_txpwr_limit[rate2]); @@ -1927,16 +1866,15 @@ wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, struct txpwr_limits *txpwr, rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST; break; } - for (rate2 = 0; rate2 < WLC_NUM_RATES_OFDM; rate2++) { + for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM; rate2++) { tmp_txpwr_limit[rate2] = 0; - tmp_txpwr_limit[WLC_NUM_RATES_OFDM + rate2] = + tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] = txpwr_ptr1[rate2]; } wlc_phy_ofdm_to_mcs_powers_nphy(tmp_txpwr_limit, 0, - WLC_NUM_RATES_OFDM - 1, - WLC_NUM_RATES_OFDM); + BRCMS_NUM_RATES_OFDM - 1, BRCMS_NUM_RATES_OFDM); for (rate1 = rate_start_index, rate2 = 0; - rate2 < WLC_NUM_RATES_MCS_1_STREAM; + rate2 < BRCMS_NUM_RATES_MCS_1_STREAM; rate1++, rate2++) pi->txpwr_limit[rate1] = min(txpwr_ptr2[rate2], @@ -1957,7 +1895,7 @@ wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, struct txpwr_limits *txpwr, break; } for (rate1 = rate_start_index, rate2 = 0; - rate2 < WLC_NUM_RATES_MCS_1_STREAM; + rate2 < BRCMS_NUM_RATES_MCS_1_STREAM; rate1++, rate2++) pi->txpwr_limit[rate1] = txpwr_ptr1[rate2]; } @@ -1976,7 +1914,7 @@ wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, struct txpwr_limits *txpwr, break; } for (rate1 = rate_start_index, rate2 = 0; - rate2 < WLC_NUM_RATES_MCS_2_STREAM; + rate2 < BRCMS_NUM_RATES_MCS_2_STREAM; rate1++, rate2++) pi->txpwr_limit[rate1] = txpwr_ptr1[rate2]; } @@ -1991,23 +1929,23 @@ wlc_phy_txpower_reg_limit_calc(phy_info_t *pi, struct txpwr_limits *txpwr, } } -void wlc_phy_txpwr_percent_set(wlc_phy_t *ppi, u8 txpwr_percent) +void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; pi->txpwr_percent = txpwr_percent; } -void wlc_phy_machwcap_set(wlc_phy_t *ppi, u32 machwcap) +void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; pi->sh->machwcap = machwcap; } -void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end) +void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; u16 rxc; rxc = 0; @@ -2036,17 +1974,17 @@ void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end) } void -wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr, +wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr, chanspec_t chanspec) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec); if (ISLCNPHY(pi)) { int i, j; for (i = TXP_FIRST_OFDM_20_CDD, j = 0; - j < WLC_NUM_RATES_MCS_1_STREAM; i++, j++) { + j < BRCMS_NUM_RATES_MCS_1_STREAM; i++, j++) { if (txpwr->mcs_20_siso[j]) pi->txpwr_limit[i] = txpwr->mcs_20_siso[j]; else @@ -2061,21 +1999,21 @@ wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *txpwr, wlapi_enable_mac(pi->sh->physhim); } -void wlc_phy_ofdm_rateset_war(wlc_phy_t *pih, bool war) +void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; pi->ofdm_rateset_war = war; } -void wlc_phy_bf_preempt_enable(wlc_phy_t *pih, bool bf_preempt) +void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; pi->bf_preempt_4306 = bf_preempt; } -void wlc_phy_txpower_update_shm(phy_info_t *pi) +void wlc_phy_txpower_update_shm(struct brcms_phy *pi) { int j; if (ISNPHY(pi)) { @@ -2112,7 +2050,7 @@ void wlc_phy_txpower_update_shm(phy_info_t *pi) } wlapi_bmac_mhf(pi->sh->physhim, MHF2, MHF2_HWPWRCTL, - MHF2_HWPWRCTL, WLC_BAND_ALL); + MHF2_HWPWRCTL, BRCM_BAND_ALL); } else { int i; @@ -2126,9 +2064,9 @@ void wlc_phy_txpower_update_shm(phy_info_t *pi) } } -bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi) +bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; if (ISNPHY(pi)) { return pi->nphy_txpwrctrl; @@ -2137,9 +2075,9 @@ bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi) } } -void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl) +void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; bool cur_hwpwrctrl = pi->hwpwrctrl; bool suspend; @@ -2175,7 +2113,7 @@ void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl) } } -void wlc_phy_txpower_ipa_upd(phy_info_t *pi) +void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi) { if (NREV_GE(pi->pubpi.phy_rev, 3)) { @@ -2187,9 +2125,9 @@ void wlc_phy_txpower_ipa_upd(phy_info_t *pi) } } -static u32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi); +static u32 wlc_phy_txpower_est_power_nphy(struct brcms_phy *pi); -static u32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi) +static u32 wlc_phy_txpower_est_power_nphy(struct brcms_phy *pi) { s16 tx0_status, tx1_status; u16 estPower1, estPower2; @@ -2239,14 +2177,15 @@ static u32 wlc_phy_txpower_est_power_nphy(phy_info_t *pi) } void -wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power, uint channel) +wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power, + uint channel) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; uint rate, num_rates; u8 min_pwr, max_pwr; #if WL_TX_POWER_RATES != TXP_NUM_RATES -#error "tx_power_t struct out of sync with this fn" +#error "struct tx_power out of sync with this fn" #endif if (ISNPHY(pi)) { @@ -2280,9 +2219,9 @@ wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power, uint channel) u32 est_pout; wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_phyreg_enter((wlc_phy_t *) pi); + wlc_phyreg_enter((struct brcms_phy_pub *) pi); est_pout = wlc_phy_txpower_est_power_nphy(pi); - wlc_phyreg_exit((wlc_phy_t *) pi); + wlc_phyreg_exit((struct brcms_phy_pub *) pi); wlapi_enable_mac(pi->sh->physhim); power->est_Pout[0] = (est_pout >> 8) & 0xff; @@ -2308,8 +2247,7 @@ wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power, uint channel) power->tx_power_max_rate_ind[0] = pi->tx_power_max_rate_ind; power->tx_power_max_rate_ind[1] = pi->tx_power_max_rate_ind; - } else if (!pi->hwpwrctrl) { - } else if (pi->sh->up) { + } else if (pi->hwpwrctrl && pi->sh->up) { wlc_phyreg_enter(ppi); if (ISLCNPHY(pi)) { @@ -2336,44 +2274,23 @@ wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power, uint channel) } } -void wlc_phy_antsel_type_set(wlc_phy_t *ppi, u8 antsel_type) +void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; pi->antsel_type = antsel_type; } -bool wlc_phy_test_ison(wlc_phy_t *ppi) +bool wlc_phy_test_ison(struct brcms_phy_pub *ppi) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; return pi->phytest_on; } -bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, u8 *pval) +void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val) { - phy_info_t *pi = (phy_info_t *) ppi; - bool ret = true; - - wlc_phyreg_enter(ppi); - - if (ISNPHY(pi)) { - - ret = false; - } else if (ISLCNPHY(pi)) { - u16 crsctrl = read_phy_reg(pi, 0x410); - u16 div = crsctrl & (0x1 << 1); - *pval = (div | ((crsctrl & (0x1 << 0)) ^ (div >> 1))); - } - - wlc_phyreg_exit(ppi); - - return ret; -} - -void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val) -{ - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; bool suspend; pi->sh->rx_antdiv = val; @@ -2381,10 +2298,10 @@ void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val) if (!(ISNPHY(pi) && D11REV_IS(pi->sh->corerev, 16))) { if (val > ANT_RX_DIV_FORCE_1) wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, - MHF1_ANTDIV, WLC_BAND_ALL); + MHF1_ANTDIV, BRCM_BAND_ALL); else wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_ANTDIV, 0, - WLC_BAND_ALL); + BRCM_BAND_ALL); } if (ISNPHY(pi)) { @@ -2419,7 +2336,7 @@ void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val) } static bool -wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr, s8 *pwr_ant) +wlc_phy_noise_calc_phy(struct brcms_phy *pi, u32 *cmplx_pwr, s8 *pwr_ant) { s8 cmplx_pwr_dbm[PHY_CORE_MAX]; u8 i; @@ -2445,9 +2362,9 @@ wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr, s8 *pwr_ant) } static void -wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, u8 ch) +wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; bool sampling_in_progress = (pi->phynoise_state != 0); bool wait_for_intr = true; @@ -2528,7 +2445,7 @@ wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, u8 ch) OR_REG(&pi->regs->maccommand, MCMD_BG_NOISE); } else { - phy_iq_est_t est[PHY_CORE_MAX]; + struct phy_iq_est est[PHY_CORE_MAX]; u32 cmplx_pwr[PHY_CORE_MAX]; s8 noise_dbm_ant[PHY_CORE_MAX]; u16 log_num_samps, num_samps, classif_state = 0; @@ -2579,7 +2496,7 @@ wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, u8 ch) } -void wlc_phy_noise_sample_request_external(wlc_phy_t *pih) +void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *pih) { u8 channel; @@ -2588,7 +2505,7 @@ void wlc_phy_noise_sample_request_external(wlc_phy_t *pih) wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel); } -static void wlc_phy_noise_cb(phy_info_t *pi, u8 channel, s8 noise_dbm) +static void wlc_phy_noise_cb(struct brcms_phy *pi, u8 channel, s8 noise_dbm) { if (!pi->phynoise_state) return; @@ -2609,7 +2526,7 @@ static void wlc_phy_noise_cb(phy_info_t *pi, u8 channel, s8 noise_dbm) } -static s8 wlc_phy_noise_read_shmem(phy_info_t *pi) +static s8 wlc_phy_noise_read_shmem(struct brcms_phy *pi) { u32 cmplx_pwr[PHY_CORE_MAX]; s8 noise_dbm_ant[PHY_CORE_MAX]; @@ -2650,9 +2567,9 @@ static s8 wlc_phy_noise_read_shmem(phy_info_t *pi) } -void wlc_phy_noise_sample_intr(wlc_phy_t *pih) +void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; u16 jssi_aux; u8 channel = 0; s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; @@ -2761,28 +2678,28 @@ void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core) } } -void wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx) +void wlc_phy_rssi_compute(struct brcms_phy_pub *pih, void *ctx) { - wlc_d11rxhdr_t *wlc_rxhdr = (wlc_d11rxhdr_t *) ctx; - d11rxhdr_t *rxh = &wlc_rxhdr->rxhdr; + struct brcms_d11rxhdr *wlc_rxhdr = (struct brcms_d11rxhdr *) ctx; + struct d11rxhdr *rxh = &wlc_rxhdr->rxhdr; int rssi = le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_JSSI_MASK; uint radioid = pih->radioid; - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; if (NORADIO_ENAB(pi->pubpi)) { - rssi = WLC_RSSI_INVALID; + rssi = BRCMS_RSSI_INVALID; goto end; } if ((pi->sh->corerev >= 11) && !(le16_to_cpu(rxh->RxStatus2) & RXS_PHYRXST_VALID)) { - rssi = WLC_RSSI_INVALID; + rssi = BRCMS_RSSI_INVALID; goto end; } if (ISLCNPHY(pi)) { u8 gidx = (le16_to_cpu(rxh->PhyRxStatus_2) & 0xFC00) >> 10; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; if (rssi > 127) rssi -= 256; @@ -2810,20 +2727,20 @@ void wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx) wlc_rxhdr->rssi = (s8) rssi; } -void wlc_phy_freqtrack_start(wlc_phy_t *pih) +void wlc_phy_freqtrack_start(struct brcms_phy_pub *pih) { return; } -void wlc_phy_freqtrack_end(wlc_phy_t *pih) +void wlc_phy_freqtrack_end(struct brcms_phy_pub *pih) { return; } -void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag) +void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag) { - phy_info_t *pi; - pi = (phy_info_t *) ppi; + struct brcms_phy *pi; + pi = (struct brcms_phy *) ppi; if (ISLCNPHY(pi)) wlc_lcnphy_deaf_mode(pi, true); @@ -2831,9 +2748,9 @@ void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag) wlc_nphy_deaf_mode(pi, true); } -void wlc_phy_watchdog(wlc_phy_t *pih) +void wlc_phy_watchdog(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; bool delay_phy_cal = false; pi->sh->now++; @@ -2841,7 +2758,7 @@ void wlc_phy_watchdog(wlc_phy_t *pih) return; if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi))) { - wlc_phy_noise_sample_request((wlc_phy_t *) pi, + wlc_phy_noise_sample_request((struct brcms_phy_pub *) pi, PHY_NOISE_SAMPLE_MON, CHSPEC_CHANNEL(pi-> radio_chanspec)); @@ -2872,7 +2789,7 @@ void wlc_phy_watchdog(wlc_phy_t *pih) (pi->nphy_perical != PHY_PERICAL_MANUAL) && ((pi->sh->now - pi->nphy_perical_last) >= pi->sh->glacial_timer)) - wlc_phy_cal_perical((wlc_phy_t *) pi, + wlc_phy_cal_perical((struct brcms_phy_pub *) pi, PHY_PERICAL_WATCHDOG); wlc_phy_txpwr_papd_cal_nphy(pi); @@ -2896,9 +2813,9 @@ void wlc_phy_watchdog(wlc_phy_t *pih) } } -void wlc_phy_BSSinit(wlc_phy_t *pih, bool bonlyap, int rssi) +void wlc_phy_BSSinit(struct brcms_phy_pub *pih, bool bonlyap, int rssi) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; uint i; uint k; @@ -2994,7 +2911,7 @@ void wlc_phy_cordic(fixed theta, cs32 *val) val[0].q = val[0].q * signx; } -void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi) +void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi) { wlapi_del_timer(pi->sh->physhim, pi->phycal_timer); @@ -3003,7 +2920,8 @@ void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi) pi->mphase_txcal_cmdidx = 0; } -static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay) +static void +wlc_phy_cal_perical_mphase_schedule(struct brcms_phy *pi, uint delay) { if ((pi->nphy_perical != PHY_PERICAL_MPHASE) && @@ -3016,12 +2934,12 @@ static void wlc_phy_cal_perical_mphase_schedule(phy_info_t *pi, uint delay) wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0); } -void wlc_phy_cal_perical(wlc_phy_t *pih, u8 reason) +void wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason) { s16 nphy_currtemp = 0; s16 delta_temp = 0; bool do_periodic_cal = true; - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; if (!ISNPHY(pi)) return; @@ -3096,7 +3014,7 @@ void wlc_phy_cal_perical(wlc_phy_t *pih, u8 reason) } } -void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi) +void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi) { pi->mphase_cal_phase_id = MPHASE_CAL_STATE_INIT; pi->mphase_txcal_cmdidx = 0; @@ -3114,9 +3032,9 @@ u8 wlc_phy_nbits(s32 value) return nbits; } -void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain, u8 rxchain) +void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; pi->sh->hw_phytxchain = txchain; pi->sh->hw_phyrxchain = rxchain; @@ -3125,9 +3043,9 @@ void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain, u8 rxchain) pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain); } -void wlc_phy_stf_chain_set(wlc_phy_t *pih, u8 txchain, u8 rxchain) +void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; pi->sh->phytxchain = txchain; @@ -3137,19 +3055,19 @@ void wlc_phy_stf_chain_set(wlc_phy_t *pih, u8 txchain, u8 rxchain) pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain); } -void wlc_phy_stf_chain_get(wlc_phy_t *pih, u8 *txchain, u8 *rxchain) +void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; *txchain = pi->sh->phytxchain; *rxchain = pi->sh->phyrxchain; } -u8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih) +u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih) { s16 nphy_currtemp; u8 active_bitmap; - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33; @@ -3177,9 +3095,9 @@ u8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih) return active_bitmap; } -s8 wlc_phy_stf_ssmode_get(wlc_phy_t *pih, chanspec_t chanspec) +s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, chanspec_t chanspec) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; u8 siso_mcs_id, cdd_mcs_id; siso_mcs_id = @@ -3201,7 +3119,7 @@ const u8 *wlc_phy_get_ofdm_rate_lookup(void) return ofdm_rate_lookup; } -void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode) +void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode) { if ((pi->sh->chip == BCM4313_CHIP_ID) && (pi->sh->boardflags & BFL_FEM)) { @@ -3239,7 +3157,7 @@ void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode) } static s8 -wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan, u32 band, +wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band, u8 rate) { s8 offset = 0; @@ -3249,7 +3167,7 @@ wlc_user_txpwr_antport_to_rfport(phy_info_t *pi, uint chan, u32 band, return offset; } -static s8 wlc_phy_env_measure_vbat(phy_info_t *pi) +static s8 wlc_phy_env_measure_vbat(struct brcms_phy *pi) { if (ISLCNPHY(pi)) return wlc_lcnphy_vbatsense(pi, 0); @@ -3257,7 +3175,7 @@ static s8 wlc_phy_env_measure_vbat(phy_info_t *pi) return 0; } -static s8 wlc_phy_env_measure_temperature(phy_info_t *pi) +static s8 wlc_phy_env_measure_temperature(struct brcms_phy *pi) { if (ISLCNPHY(pi)) return wlc_lcnphy_tempsense_degree(pi, 0); @@ -3265,40 +3183,40 @@ static s8 wlc_phy_env_measure_temperature(phy_info_t *pi) return 0; } -static void wlc_phy_upd_env_txpwr_rate_limits(phy_info_t *pi, u32 band) +static void wlc_phy_upd_env_txpwr_rate_limits(struct brcms_phy *pi, u32 band) { u8 i; s8 temp, vbat; for (i = 0; i < TXP_NUM_RATES; i++) - pi->txpwr_env_limit[i] = WLC_TXPWR_MAX; + pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX; vbat = wlc_phy_env_measure_vbat(pi); temp = wlc_phy_env_measure_temperature(pi); } -void wlc_phy_ldpc_override_set(wlc_phy_t *ppi, bool ldpc) +void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool ldpc) { return; } void -wlc_phy_get_pwrdet_offsets(phy_info_t *pi, s8 *cckoffset, s8 *ofdmoffset) +wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset, s8 *ofdmoffset) { *cckoffset = 0; *ofdmoffset = 0; } -s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi, chanspec_t chanspec) +s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, chanspec_t chanspec) { return rssi; } -bool wlc_phy_txpower_ipa_ison(wlc_phy_t *ppi) +bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *ppi) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; if (ISNPHY(pi)) return wlc_phy_n_txpower_ipa_ison(pi); diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h new file mode 100644 index 000000000000..e27d9e95a2dc --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * phy_hal.h: functionality exported from the phy to higher layers + */ + +#ifndef _BRCM_PHY_HAL_H_ +#define _BRCM_PHY_HAL_H_ + +#include +#include +#include + +#define IDCODE_VER_MASK 0x0000000f +#define IDCODE_VER_SHIFT 0 +#define IDCODE_MFG_MASK 0x00000fff +#define IDCODE_MFG_SHIFT 0 +#define IDCODE_ID_MASK 0x0ffff000 +#define IDCODE_ID_SHIFT 12 +#define IDCODE_REV_MASK 0xf0000000 +#define IDCODE_REV_SHIFT 28 + +#define NORADIO_ID 0xe4f5 +#define NORADIO_IDCODE 0x4e4f5246 + +#define BCM2055_ID 0x2055 +#define BCM2055_IDCODE 0x02055000 +#define BCM2055A0_IDCODE 0x1205517f + +#define BCM2056_ID 0x2056 +#define BCM2056_IDCODE 0x02056000 +#define BCM2056A0_IDCODE 0x1205617f + +#define BCM2057_ID 0x2057 +#define BCM2057_IDCODE 0x02057000 +#define BCM2057A0_IDCODE 0x1205717f + +#define BCM2064_ID 0x2064 +#define BCM2064_IDCODE 0x02064000 +#define BCM2064A0_IDCODE 0x0206417f + +#define PHY_TPC_HW_OFF false +#define PHY_TPC_HW_ON true + +#define PHY_PERICAL_DRIVERUP 1 +#define PHY_PERICAL_WATCHDOG 2 +#define PHY_PERICAL_PHYINIT 3 +#define PHY_PERICAL_JOIN_BSS 4 +#define PHY_PERICAL_START_IBSS 5 +#define PHY_PERICAL_UP_BSS 6 +#define PHY_PERICAL_CHAN 7 +#define PHY_FULLCAL 8 + +#define PHY_PERICAL_DISABLE 0 +#define PHY_PERICAL_SPHASE 1 +#define PHY_PERICAL_MPHASE 2 +#define PHY_PERICAL_MANUAL 3 + +#define PHY_HOLD_FOR_ASSOC 1 +#define PHY_HOLD_FOR_SCAN 2 +#define PHY_HOLD_FOR_RM 4 +#define PHY_HOLD_FOR_PLT 8 +#define PHY_HOLD_FOR_MUTE 16 +#define PHY_HOLD_FOR_NOT_ASSOC 0x20 + +#define PHY_MUTE_FOR_PREISM 1 +#define PHY_MUTE_ALL 0xffffffff + +#define PHY_NOISE_FIXED_VAL (-95) +#define PHY_NOISE_FIXED_VAL_NPHY (-92) +#define PHY_NOISE_FIXED_VAL_LCNPHY (-92) + +#define PHY_MODE_CAL 0x0002 +#define PHY_MODE_NOISEM 0x0004 + +#define BRCMS_TXPWR_DB_FACTOR 4 + +/* a large TX Power as an init value to factor out of min() calculations, + * keep low enough to fit in an s8, units are .25 dBm + */ +#define BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ + +#define BRCMS_NUM_RATES_CCK 4 +#define BRCMS_NUM_RATES_OFDM 8 +#define BRCMS_NUM_RATES_MCS_1_STREAM 8 +#define BRCMS_NUM_RATES_MCS_2_STREAM 8 +#define BRCMS_NUM_RATES_MCS_3_STREAM 8 +#define BRCMS_NUM_RATES_MCS_4_STREAM 8 + +#define BRCMS_RSSI_INVALID 0 /* invalid RSSI value */ + +struct txpwr_limits { + u8 cck[BRCMS_NUM_RATES_CCK]; + u8 ofdm[BRCMS_NUM_RATES_OFDM]; + + u8 ofdm_cdd[BRCMS_NUM_RATES_OFDM]; + + u8 ofdm_40_siso[BRCMS_NUM_RATES_OFDM]; + u8 ofdm_40_cdd[BRCMS_NUM_RATES_OFDM]; + + u8 mcs_20_siso[BRCMS_NUM_RATES_MCS_1_STREAM]; + u8 mcs_20_cdd[BRCMS_NUM_RATES_MCS_1_STREAM]; + u8 mcs_20_stbc[BRCMS_NUM_RATES_MCS_1_STREAM]; + u8 mcs_20_mimo[BRCMS_NUM_RATES_MCS_2_STREAM]; + + u8 mcs_40_siso[BRCMS_NUM_RATES_MCS_1_STREAM]; + u8 mcs_40_cdd[BRCMS_NUM_RATES_MCS_1_STREAM]; + u8 mcs_40_stbc[BRCMS_NUM_RATES_MCS_1_STREAM]; + u8 mcs_40_mimo[BRCMS_NUM_RATES_MCS_2_STREAM]; + u8 mcs32; +}; + +struct tx_power { + u32 flags; + chanspec_t chanspec; /* txpwr report for this channel */ + chanspec_t local_chanspec; /* channel on which we are associated */ + u8 local_max; /* local max according to the AP */ + u8 local_constraint; /* local constraint according to the AP */ + s8 antgain[2]; /* Ant gain for each band - from SROM */ + u8 rf_cores; /* count of RF Cores being reported */ + u8 est_Pout[4]; /* Latest tx power out estimate per RF chain */ + u8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain + * without adjustment + */ + u8 est_Pout_cck; /* Latest CCK tx power out estimate */ + u8 tx_power_max[4]; /* Maximum target power among all rates */ + u8 tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */ + u8 user_limit[WL_TX_POWER_RATES]; /* User limit */ + u8 reg_limit[WL_TX_POWER_RATES]; /* Regulatory power limit */ + u8 board_limit[WL_TX_POWER_RATES]; /* Max power board can support (SROM) */ + u8 target[WL_TX_POWER_RATES]; /* Latest target power */ +}; + +struct tx_inst_power { + u8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ + u8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ +}; + +struct chanvec { + u8 vec[MAXCHANNEL / NBBY]; +}; + +struct shared_phy_params { + struct si_pub *sih; + void *physhim; + uint unit; + uint corerev; + uint bustype; + uint buscorerev; + char *vars; + u16 vid; + u16 did; + uint chip; + uint chiprev; + uint chippkg; + uint sromrev; + uint boardtype; + uint boardrev; + uint boardvendor; + u32 boardflags; + u32 boardflags2; +}; + + +extern struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp); +extern struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh, void *regs, + int bandtype, char *vars, struct wiphy *wiphy); +extern void wlc_phy_detach(struct brcms_phy_pub *ppi); + +extern bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, + u16 *phyrev, u16 *radioid, + u16 *radiover); +extern bool wlc_phy_get_encore(struct brcms_phy_pub *pih); +extern u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih); + +extern void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate); +extern void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate); +extern void wlc_phy_init(struct brcms_phy_pub *ppi, chanspec_t chanspec); +extern void wlc_phy_watchdog(struct brcms_phy_pub *ppi); +extern int wlc_phy_down(struct brcms_phy_pub *ppi); +extern u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih); +extern void wlc_phy_cal_init(struct brcms_phy_pub *ppi); +extern void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init); + +extern void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, + chanspec_t chanspec); +extern chanspec_t wlc_phy_chanspec_get(struct brcms_phy_pub *ppi); +extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, + chanspec_t newch); +extern u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi); +extern void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw); + +extern void wlc_phy_rssi_compute(struct brcms_phy_pub *pih, void *ctx); +extern void wlc_phy_por_inform(struct brcms_phy_pub *ppi); +extern void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi); +extern bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi); + +extern void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag); + +extern void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on); +extern void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on); + + +extern void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi); + +extern void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi, + bool wide_filter); +extern void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band, + chanvec_t *channels); +extern chanspec_t wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, + uint band); + +extern void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan, + u8 *_min_, u8 *_max_, int rate); +extern void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, + uint chan, u8 *_max_, u8 *_min_); +extern void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, + uint band, s32 *, s32 *, u32 *); +extern void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, + struct txpwr_limits *, + chanspec_t chanspec); +extern int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, + bool *override); +extern int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, + bool override); +extern void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi, + struct txpwr_limits *); +extern bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi); +extern void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, + bool hwpwrctrl); +extern u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi); +extern u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi); +extern bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih); + +extern void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, + u8 rxchain); +extern void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, + u8 rxchain); +extern void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, + u8 *rxchain); +extern u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih); +extern s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, + chanspec_t chanspec); +extern void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val); + +extern void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason); +extern void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi); +extern void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock); +extern void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi); + +extern void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val); +extern void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi); +extern void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, mbool id, bool val); +extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, mbool flags); + +extern void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type); + +extern void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, + struct tx_power *power, uint channel); + +extern void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal); +extern bool wlc_phy_test_ison(struct brcms_phy_pub *ppi); +extern void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, + u8 txpwr_percent); +extern void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war); +extern void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, + bool bf_preempt); +extern void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap); + +extern void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end); + +extern void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi); +extern void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi); + +extern const u8 *wlc_phy_get_ofdm_rate_lookup(void); + +extern s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi, + u8 mcs_offset); +extern s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset); +#endif /* _BRCM_PHY_HAL_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_int.h similarity index 66% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h rename to drivers/staging/brcm80211/brcmsmac/phy/phy_int.h index 10cbf520474f..a01b01ccd9ff 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_int.h @@ -14,15 +14,14 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_phy_int_h_ -#define _wlc_phy_int_h_ +#ifndef _BRCM_PHY_INT_H_ +#define _BRCM_PHY_INT_H_ -#include -#include -#include +#include +#include +#include -#include -#include +#define PHY_VERSION { 1, 82, 8, 0 } #define PHYHAL_ERROR 0x0001 #define PHYHAL_TRACE 0x0002 @@ -42,23 +41,29 @@ extern u32 phyhal_msg_level; #define LCNXN_BASEREV 16 -struct wlc_hw_info; -typedef struct phy_info phy_info_t; -typedef void (*initfn_t) (phy_info_t *); -typedef void (*chansetfn_t) (phy_info_t *, chanspec_t); -typedef int (*longtrnfn_t) (phy_info_t *, int); -typedef void (*txiqccgetfn_t) (phy_info_t *, u16 *, u16 *); -typedef void (*txiqccsetfn_t) (phy_info_t *, u16, u16); -typedef u16(*txloccgetfn_t) (phy_info_t *); -typedef void (*radioloftgetfn_t) (phy_info_t *, u8 *, u8 *, u8 *, +struct brcms_phy_srom_fem { + u8 tssipos; /* TSSI positive slope, 1: positive, 0: negative */ + u8 extpagain; /* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */ + u8 pdetrange; /* support 32 combinations of different Pdet dynamic ranges */ + u8 triso; /* TR switch isolation */ + u8 antswctrllut; /* antswctrl lookup table configuration: 32 possible choices */ +}; + +typedef void (*initfn_t) (struct brcms_phy *); +typedef void (*chansetfn_t) (struct brcms_phy *, chanspec_t); +typedef int (*longtrnfn_t) (struct brcms_phy *, int); +typedef void (*txiqccgetfn_t) (struct brcms_phy *, u16 *, u16 *); +typedef void (*txiqccsetfn_t) (struct brcms_phy *, u16, u16); +typedef u16(*txloccgetfn_t) (struct brcms_phy *); +typedef void (*radioloftgetfn_t) (struct brcms_phy *, u8 *, u8 *, u8 *, u8 *); -typedef s32(*rxsigpwrfn_t) (phy_info_t *, s32); -typedef void (*detachfn_t) (phy_info_t *); +typedef s32(*rxsigpwrfn_t) (struct brcms_phy *, s32); +typedef void (*detachfn_t) (struct brcms_phy *); #undef ISNPHY #undef ISLCNPHY #define ISNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_N) -#define ISLCNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN) +#define ISLCNPHY(pi) PHYTYPE_IS((pi)->pubpi.phy_type, PHY_TYPE_LCN) #define ISPHY_11N_CAP(pi) (ISNPHY(pi) || ISLCNPHY(pi)) @@ -215,7 +220,7 @@ enum { MPHASE_CAL_STATE_IDLETSSI }; -typedef enum { +enum phy_cal_mode { CAL_FULL, CAL_RECAL, CAL_CURRECAL, @@ -223,7 +228,7 @@ typedef enum { CAL_GCTRL, CAL_SOFT, CAL_DIGLO -} phy_cal_mode_t; +}; #define RDR_NTIERS 1 #define RDR_TIER_SIZE 64 @@ -248,7 +253,7 @@ typedef enum { #define PHY_CHAIN_TX_DISABLE_TEMP 115 #define PHY_HYSTERESIS_DELTATEMP 5 -#define PHY_BITSCNT(x) bcm_bitcount((u8 *)&(x), sizeof(u8)) +#define PHY_BITSCNT(x) brcmu_bitcount((u8 *)&(x), sizeof(u8)) #define MOD_PHY_REG(pi, phy_type, reg_name, field, value) \ mod_phy_reg(pi, phy_type##_##reg_name, phy_type##_##reg_name##_##field##_MASK, \ @@ -285,21 +290,21 @@ typedef enum { #define PHY_LTRN_LIST_LEN 64 extern u16 ltrn_list[PHY_LTRN_LIST_LEN]; -typedef struct _phy_table_info { +struct phy_table_info { uint table; int q; uint max; -} phy_table_info_t; +}; -typedef struct phytbl_info { +struct phytbl_info { const void *tbl_ptr; u32 tbl_len; u32 tbl_id; u32 tbl_offset; u32 tbl_width; -} phytbl_info_t; +}; -typedef struct { +struct interference_info { u8 curr_home_channel; u16 crsminpwrthld_40_stored; u16 crsminpwrthld_20L_stored; @@ -369,10 +374,9 @@ typedef struct { u16 radio_2057_core2_rssi_wb2_gc_stored; u16 radio_2057_core1_rssi_nb_gc_stored; u16 radio_2057_core2_rssi_nb_gc_stored; +}; -} interference_info_t; - -typedef struct { +struct aci_save_gphy { u16 rc_cal_ovr; u16 phycrsth1; u16 phycrsth2; @@ -406,21 +410,21 @@ typedef struct { u16 div_srch_gn_back; u16 ant_dwell; u16 ant_wr_settle; -} aci_save_gphy_t; +}; -typedef struct _lo_complex_t { +struct lo_complex_abgphy_info { s8 i; s8 q; -} lo_complex_abgphy_info_t; +}; -typedef struct _nphy_iq_comp { +struct nphy_iq_comp { s16 a0; s16 b0; s16 a1; s16 b1; -} nphy_iq_comp_t; +}; -typedef struct _nphy_txpwrindex { +struct nphy_txpwrindex { s8 index; s8 index_internal; s8 index_internal_save; @@ -431,20 +435,20 @@ typedef struct _nphy_txpwrindex { u16 iqcomp_a; u16 iqcomp_b; u16 locomp; -} phy_txpwrindex_t; +}; -typedef struct { +struct txiqcal_cache { u16 txcal_coeffs_2G[8]; u16 txcal_radio_regs_2G[8]; - nphy_iq_comp_t rxcal_coeffs_2G; + struct nphy_iq_comp rxcal_coeffs_2G; u16 txcal_coeffs_5G[8]; u16 txcal_radio_regs_5G[8]; - nphy_iq_comp_t rxcal_coeffs_5G; -} txiqcal_cache_t; + struct nphy_iq_comp rxcal_coeffs_5G; +}; -typedef struct _nphy_pwrctrl { +struct nphy_pwrctrl { s8 max_pwr_2g; s8 idle_targ_2g; s16 pwrdet_2g_a1; @@ -471,34 +475,34 @@ typedef struct _nphy_pwrctrl { s16 a1; s16 b0; s16 b1; -} phy_pwrctrl_t; +}; -typedef struct _nphy_txgains { +struct nphy_txgains { u16 txlpf[2]; u16 txgm[2]; u16 pga[2]; u16 pad[2]; u16 ipa[2]; -} nphy_txgains_t; +}; #define PHY_NOISEVAR_BUFSIZE 10 -typedef struct _nphy_noisevar_buf { +struct nphy_noisevar_buf { int bufcount; int tone_id[PHY_NOISEVAR_BUFSIZE]; u32 noise_vars[PHY_NOISEVAR_BUFSIZE]; u32 min_noise_vars[PHY_NOISEVAR_BUFSIZE]; -} phy_noisevar_buf_t; +}; -typedef struct { +struct rssical_cache { u16 rssical_radio_regs_2G[2]; u16 rssical_phyregs_2G[12]; u16 rssical_radio_regs_5G[2]; u16 rssical_phyregs_5G[12]; -} rssical_cache_t; +}; -typedef struct { +struct lcnphy_cal_results { u16 txiqlocal_a; u16 txiqlocal_b; @@ -522,12 +526,12 @@ typedef struct { u16 rxiqcal_coeff_a0; u16 rxiqcal_coeff_b0; -} lcnphy_cal_results_t; +}; struct shared_phy { - struct phy_info *phy_head; + struct brcms_phy *phy_head; uint unit; - si_t *sih; + struct si_pub *sih; void *physhim; uint corerev; u32 machwcap; @@ -561,7 +565,7 @@ struct shared_phy { bool _rifs_phy; }; -struct phy_pub { +struct brcms_phy_pub { uint phy_type; uint phy_rev; u8 phy_corenum; @@ -574,12 +578,6 @@ struct phy_pub { bool abgphy_encore; }; -struct phy_info_nphy; -typedef struct phy_info_nphy phy_info_nphy_t; - -struct phy_info_lcnphy; -typedef struct phy_info_lcnphy phy_info_lcnphy_t; - struct phy_func_ptr { initfn_t init; initfn_t calinit; @@ -594,23 +592,22 @@ struct phy_func_ptr { rxsigpwrfn_t rxsigpwr; detachfn_t detach; }; -typedef struct phy_func_ptr phy_func_ptr_t; -struct phy_info { - wlc_phy_t pubpi_ro; - shared_phy_t *sh; - phy_func_ptr_t pi_fptr; +struct brcms_phy { + struct brcms_phy_pub pubpi_ro; + struct shared_phy *sh; + struct phy_func_ptr pi_fptr; void *pi_ptr; union { - phy_info_lcnphy_t *pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcnphy; } u; bool user_txpwr_at_rfport; d11regs_t *regs; - struct phy_info *next; + struct brcms_phy *next; char *vars; - wlc_phy_t pubpi; + struct brcms_phy_pub pubpi; bool do_initcal; bool phytest_on; @@ -653,8 +650,8 @@ struct phy_info { s8 tx_power_offset[TXP_NUM_RATES]; u8 tx_power_target[TXP_NUM_RATES]; - srom_fem_t srom_fem2g; - srom_fem_t srom_fem5g; + struct brcms_phy_srom_fem srom_fem2g; + struct brcms_phy_srom_fem srom_fem5g; u8 tx_power_max; u8 tx_power_max_rate_ind; @@ -725,7 +722,8 @@ struct phy_info { u16 mintxbias; u16 mintxmag; - lo_complex_abgphy_info_t gphy_locomp_iq[STATIC_NUM_RF][STATIC_NUM_BB]; + struct lo_complex_abgphy_info gphy_locomp_iq + [STATIC_NUM_RF][STATIC_NUM_BB]; s8 stats_11b_txpower[STATIC_NUM_RF][STATIC_NUM_BB]; u16 gain_table[TX_GAIN_TABLE_LENGTH]; bool loopback_gain; @@ -783,8 +781,8 @@ struct phy_info { u32 nphy_bb_mult_save; u16 nphy_txiqlocal_bestc[11]; bool nphy_txiqlocal_coeffsvalid; - phy_txpwrindex_t nphy_txpwrindex[PHY_CORE_NUM_2]; - phy_pwrctrl_t nphy_pwrctrl_info[PHY_CORE_NUM_2]; + struct nphy_txpwrindex nphy_txpwrindex[PHY_CORE_NUM_2]; + struct nphy_pwrctrl nphy_pwrctrl_info[PHY_CORE_NUM_2]; u16 cck2gpo; u32 ofdm2gpo; u32 ofdm5gpo; @@ -852,8 +850,8 @@ struct phy_info { bool internal_tx_iqlo_cal_tapoff_intpa_nphy; s16 nphy_lastcal_temp; - txiqcal_cache_t calibration_cache; - rssical_cache_t rssical_cache; + struct txiqcal_cache calibration_cache; + struct rssical_cache rssical_cache; u8 nphy_txpwr_idx[2]; u8 nphy_papd_cal_type; @@ -884,7 +882,7 @@ struct phy_info { u8 nphy_txcal_pwr_idx[2]; u8 nphy_rxcal_pwr_idx[2]; u16 nphy_cal_orig_tx_gain[2]; - nphy_txgains_t nphy_cal_target_gain; + struct nphy_txgains nphy_cal_target_gain; u16 nphy_txcal_bbmult; u16 nphy_gmval; @@ -895,7 +893,7 @@ struct phy_info { bool nphy_aband_spurwar_en; u16 nphy_rccal_value; u16 nphy_crsminpwr[3]; - phy_noisevar_buf_t nphy_saved_noisevars; + struct nphy_noisevar_buf nphy_saved_noisevars; bool nphy_anarxlpf_adjusted; bool nphy_crsminpwr_adjusted; bool nphy_noisevars_adjusted; @@ -939,141 +937,145 @@ struct phy_info { struct wiphy *wiphy; }; -typedef s32 fixed; - -typedef struct _cs32 { +struct _cs32 { fixed q; fixed i; -} cs32; +}; -typedef struct radio_regs { +struct radio_regs { u16 address; u32 init_a; u32 init_g; u8 do_init_a; u8 do_init_g; -} radio_regs_t; +}; -typedef struct radio_20xx_regs { +struct radio_20xx_regs { u16 address; u8 init; u8 do_init; -} radio_20xx_regs_t; +}; -typedef struct lcnphy_radio_regs { +struct lcnphy_radio_regs { u16 address; u8 init_a; u8 init_g; u8 do_init_a; u8 do_init_g; -} lcnphy_radio_regs_t; +}; -extern lcnphy_radio_regs_t lcnphy_radio_regs_2064[]; -extern lcnphy_radio_regs_t lcnphy_radio_regs_2066[]; -extern radio_regs_t regs_2055[], regs_SYN_2056[], regs_TX_2056[], - regs_RX_2056[]; -extern radio_regs_t regs_SYN_2056_A1[], regs_TX_2056_A1[], regs_RX_2056_A1[]; -extern radio_regs_t regs_SYN_2056_rev5[], regs_TX_2056_rev5[], - regs_RX_2056_rev5[]; -extern radio_regs_t regs_SYN_2056_rev6[], regs_TX_2056_rev6[], - regs_RX_2056_rev6[]; -extern radio_regs_t regs_SYN_2056_rev7[], regs_TX_2056_rev7[], - regs_RX_2056_rev7[]; -extern radio_regs_t regs_SYN_2056_rev8[], regs_TX_2056_rev8[], - regs_RX_2056_rev8[]; -extern radio_20xx_regs_t regs_2057_rev4[], regs_2057_rev5[], regs_2057_rev5v1[]; -extern radio_20xx_regs_t regs_2057_rev7[], regs_2057_rev8[]; +extern struct lcnphy_radio_regs lcnphy_radio_regs_2064[]; +extern struct lcnphy_radio_regs lcnphy_radio_regs_2066[]; +extern struct radio_regs regs_2055[], regs_SYN_2056[], regs_TX_2056[], + regs_RX_2056[]; +extern struct radio_regs regs_SYN_2056_A1[], regs_TX_2056_A1[], + regs_RX_2056_A1[]; +extern struct radio_regs regs_SYN_2056_rev5[], regs_TX_2056_rev5[], + regs_RX_2056_rev5[]; +extern struct radio_regs regs_SYN_2056_rev6[], regs_TX_2056_rev6[], + regs_RX_2056_rev6[]; +extern struct radio_regs regs_SYN_2056_rev7[], regs_TX_2056_rev7[], + regs_RX_2056_rev7[]; +extern struct radio_regs regs_SYN_2056_rev8[], regs_TX_2056_rev8[], + regs_RX_2056_rev8[]; +extern struct radio_20xx_regs regs_2057_rev4[], regs_2057_rev5[], + regs_2057_rev5v1[]; +extern struct radio_20xx_regs regs_2057_rev7[], regs_2057_rev8[]; -extern char *phy_getvar(phy_info_t *pi, const char *name); -extern int phy_getintvar(phy_info_t *pi, const char *name); +extern char *phy_getvar(struct brcms_phy *pi, const char *name); +extern int phy_getintvar(struct brcms_phy *pi, const char *name); #define PHY_GETVAR(pi, name) phy_getvar(pi, name) #define PHY_GETINTVAR(pi, name) phy_getintvar(pi, name) -extern u16 read_phy_reg(phy_info_t *pi, u16 addr); -extern void write_phy_reg(phy_info_t *pi, u16 addr, u16 val); -extern void and_phy_reg(phy_info_t *pi, u16 addr, u16 val); -extern void or_phy_reg(phy_info_t *pi, u16 addr, u16 val); -extern void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val); +extern u16 read_phy_reg(struct brcms_phy *pi, u16 addr); +extern void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); +extern void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); +extern void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); +extern void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val); -extern u16 read_radio_reg(phy_info_t *pi, u16 addr); -extern void or_radio_reg(phy_info_t *pi, u16 addr, u16 val); -extern void and_radio_reg(phy_info_t *pi, u16 addr, u16 val); -extern void mod_radio_reg(phy_info_t *pi, u16 addr, u16 mask, +extern u16 read_radio_reg(struct brcms_phy *pi, u16 addr); +extern void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); +extern void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); +extern void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val); -extern void xor_radio_reg(phy_info_t *pi, u16 addr, u16 mask); +extern void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask); -extern void write_radio_reg(phy_info_t *pi, u16 addr, u16 val); +extern void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); -extern void wlc_phyreg_enter(wlc_phy_t *pih); -extern void wlc_phyreg_exit(wlc_phy_t *pih); -extern void wlc_radioreg_enter(wlc_phy_t *pih); -extern void wlc_radioreg_exit(wlc_phy_t *pih); +extern void wlc_phyreg_enter(struct brcms_phy_pub *pih); +extern void wlc_phyreg_exit(struct brcms_phy_pub *pih); +extern void wlc_radioreg_enter(struct brcms_phy_pub *pih); +extern void wlc_radioreg_exit(struct brcms_phy_pub *pih); -extern void wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, +extern void wlc_phy_read_table(struct brcms_phy *pi, + const struct phytbl_info *ptbl_info, u16 tblAddr, u16 tblDataHi, u16 tblDatalo); -extern void wlc_phy_write_table(phy_info_t *pi, - const phytbl_info_t *ptbl_info, u16 tblAddr, - u16 tblDataHi, u16 tblDatalo); -extern void wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset, - u16 tblAddr, u16 tblDataHi, +extern void wlc_phy_write_table(struct brcms_phy *pi, + const struct phytbl_info *ptbl_info, + u16 tblAddr, u16 tblDataHi, u16 tblDatalo); +extern void wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, + uint tbl_offset, u16 tblAddr, u16 tblDataHi, u16 tblDataLo); -extern void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val); +extern void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val); -extern void write_phy_channel_reg(phy_info_t *pi, uint val); -extern void wlc_phy_txpower_update_shm(phy_info_t *pi); +extern void write_phy_channel_reg(struct brcms_phy *pi, uint val); +extern void wlc_phy_txpower_update_shm(struct brcms_phy *pi); extern void wlc_phy_cordic(fixed theta, cs32 *val); extern u8 wlc_phy_nbits(s32 value); extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core); -extern uint wlc_phy_init_radio_regs_allbands(phy_info_t *pi, - radio_20xx_regs_t *radioregs); -extern uint wlc_phy_init_radio_regs(phy_info_t *pi, radio_regs_t *radioregs, +extern uint wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi, + struct radio_20xx_regs *radioregs); +extern uint wlc_phy_init_radio_regs(struct brcms_phy *pi, + struct radio_regs *radioregs, u16 core_offset); -extern void wlc_phy_txpower_ipa_upd(phy_info_t *pi); +extern void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi); -extern void wlc_phy_do_dummy_tx(phy_info_t *pi, bool ofdm, bool pa_on); +extern void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on); extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag); -extern void wlc_phy_cal_perical_mphase_reset(phy_info_t *pi); -extern void wlc_phy_cal_perical_mphase_restart(phy_info_t *pi); +extern void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi); +extern void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi); -extern bool wlc_phy_attach_nphy(phy_info_t *pi); -extern bool wlc_phy_attach_lcnphy(phy_info_t *pi); +extern bool wlc_phy_attach_nphy(struct brcms_phy *pi); +extern bool wlc_phy_attach_lcnphy(struct brcms_phy *pi); -extern void wlc_phy_detach_lcnphy(phy_info_t *pi); +extern void wlc_phy_detach_lcnphy(struct brcms_phy *pi); -extern void wlc_phy_init_nphy(phy_info_t *pi); -extern void wlc_phy_init_lcnphy(phy_info_t *pi); +extern void wlc_phy_init_nphy(struct brcms_phy *pi); +extern void wlc_phy_init_lcnphy(struct brcms_phy *pi); -extern void wlc_phy_cal_init_nphy(phy_info_t *pi); -extern void wlc_phy_cal_init_lcnphy(phy_info_t *pi); +extern void wlc_phy_cal_init_nphy(struct brcms_phy *pi); +extern void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi); -extern void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec); -extern void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec); -extern void wlc_phy_chanspec_set_fixup_lcnphy(phy_info_t *pi, +extern void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, + chanspec_t chanspec); +extern void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, + chanspec_t chanspec); +extern void wlc_phy_chanspec_set_fixup_lcnphy(struct brcms_phy *pi, chanspec_t chanspec); extern int wlc_phy_channel2freq(uint channel); extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint); -extern int wlc_phy_chanspec_bandrange_get(phy_info_t *, chanspec_t); +extern int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, chanspec_t); -extern void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode); -extern s8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi); +extern void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode); +extern s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi); -extern void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi); -extern void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi); -extern void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi); +extern void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi); +extern void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi); +extern void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi); -extern void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index); -extern void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable); -extern void wlc_lcnphy_stop_tx_tone(phy_info_t *pi); -extern void wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz, +extern void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index); +extern void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable); +extern void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi); +extern void wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, u16 max_val, bool iqcalmode); -extern void wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan, +extern void wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan, u8 *max_pwr, u8 rate_id); extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start, u8 rate_mcs_end, @@ -1083,21 +1085,21 @@ extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_end, u8 rate_mcs_start); -extern u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode); -extern s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode); -extern s8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode); -extern s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode); -extern void wlc_phy_carrier_suppress_lcnphy(phy_info_t *pi); -extern void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel); -extern void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode); -extern void wlc_2064_vco_cal(phy_info_t *pi); +extern u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode); +extern s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode); +extern s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode); +extern s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode); +extern void wlc_phy_carrier_suppress_lcnphy(struct brcms_phy *pi); +extern void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel); +extern void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode); +extern void wlc_2064_vco_cal(struct brcms_phy *pi); -extern void wlc_phy_txpower_recalc_target(phy_info_t *pi); +extern void wlc_phy_txpower_recalc_target(struct brcms_phy *pi); #define LCNPHY_TBL_ID_PAPDCOMPDELTATBL 0x18 #define LCNPHY_TX_POWER_TABLE_SIZE 128 #define LCNPHY_MAX_TX_POWER_INDEX (LCNPHY_TX_POWER_TABLE_SIZE - 1) -#define LCNPHY_TBL_ID_TXPWRCTL 0x07 +#define LCNPHY_TBL_ID_TXPWRCTL 0x07 #define LCNPHY_TX_PWR_CTRL_OFF 0 #define LCNPHY_TX_PWR_CTRL_SW (0x1 << 15) #define LCNPHY_TX_PWR_CTRL_HW ((0x1 << 15) | \ @@ -1106,36 +1108,39 @@ extern void wlc_phy_txpower_recalc_target(phy_info_t *pi); #define LCNPHY_TX_PWR_CTRL_TEMPBASED 0xE001 -extern void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti); -extern void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti); -extern void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, u16 a, u16 b); -extern void wlc_lcnphy_set_tx_locc(phy_info_t *pi, u16 didq); -extern void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, u16 *a, u16 *b); -extern u16 wlc_lcnphy_get_tx_locc(phy_info_t *pi); -extern void wlc_lcnphy_get_radio_loft(phy_info_t *pi, u8 *ei0, +extern void wlc_lcnphy_write_table(struct brcms_phy *pi, + const struct phytbl_info *pti); +extern void wlc_lcnphy_read_table(struct brcms_phy *pi, + struct phytbl_info *pti); +extern void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b); +extern void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq); +extern void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b); +extern u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi); +extern void wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, u8 *ei0, u8 *eq0, u8 *fi0, u8 *fq0); -extern void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode); -extern void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode); -extern bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi); -extern void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi); +extern void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode); +extern void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode); +extern bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi); +extern void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi); extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1); -extern void wlc_lcnphy_get_tssi(phy_info_t *pi, s8 *ofdm_pwr, +extern void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr, s8 *cck_pwr); -extern void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi); +extern void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi); -extern s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index); +extern s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index); #define NPHY_MAX_HPVGA1_INDEX 10 #define NPHY_DEF_HPVGA1_INDEXLIMIT 7 -typedef struct _phy_iq_est { +struct phy_iq_est { s32 iq_prod; u32 i_pwr; u32 q_pwr; -} phy_iq_est_t; +}; -extern void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable); -extern void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode); +extern void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi, + bool enable); +extern void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode); #define wlc_phy_write_table_nphy(pi, pti) wlc_phy_write_table(pi, pti, 0x72, \ 0x74, 0x73) @@ -1145,82 +1150,86 @@ extern void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode); 0x72, 0x74, 0x73) #define wlc_nphy_table_data_write(pi, w, v) wlc_phy_table_data_write((pi), (w), (v)) -extern void wlc_phy_table_read_nphy(phy_info_t *pi, u32, u32 l, u32 o, +extern void wlc_phy_table_read_nphy(struct brcms_phy *pi, u32, u32 l, u32 o, u32 w, void *d); -extern void wlc_phy_table_write_nphy(phy_info_t *pi, u32, u32, u32, +extern void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32, u32, const void *); #define PHY_IPA(pi) \ ((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \ (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec))) -#define WLC_PHY_WAR_PR51571(pi) \ +#define BRCMS_PHY_WAR_PR51571(pi) \ if (((pi)->sh->bustype == PCI_BUS) && NREV_LT((pi)->pubpi.phy_rev, 3)) \ (void)R_REG(&(pi)->regs->maccontrol) -extern void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype); -extern void wlc_phy_aci_reset_nphy(phy_info_t *pi); -extern void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en); +extern void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype); +extern void wlc_phy_aci_reset_nphy(struct brcms_phy *pi); +extern void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en); -extern u8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint chan); -extern void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on); +extern u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint chan); +extern void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on); -extern void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi); +extern void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi); -extern void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd); -extern s16 wlc_phy_tempsense_nphy(phy_info_t *pi); +extern void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd); +extern s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi); -extern u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val); +extern u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val); -extern void wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est, +extern void wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est, u16 num_samps, u8 wait_time, u8 wait_for_crs); -extern void wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, u8 write, - nphy_iq_comp_t *comp); -extern void wlc_phy_aci_and_noise_reduction_nphy(phy_info_t *pi); +extern void wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write, + struct nphy_iq_comp *comp); +extern void wlc_phy_aci_and_noise_reduction_nphy(struct brcms_phy *pi); -extern void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask); -extern u8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih); +extern void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, + u8 rxcore_bitmask); +extern u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih); -extern void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type); -extern void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi); -extern void wlc_phy_txpwr_apply_nphy(phy_info_t *pi); -extern void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi); -extern u16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi); +extern void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type); +extern void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi); +extern void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi); +extern void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi); +extern u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi); -extern nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi); -extern int wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain, +extern struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi); +extern int wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, + struct nphy_txgains target_gain, bool full, bool m); -extern int wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain, +extern int wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi, + struct nphy_txgains target_gain, u8 type, bool d); -extern void wlc_phy_txpwr_index_nphy(phy_info_t *pi, u8 core_mask, +extern void wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex, bool res); -extern void wlc_phy_rssisel_nphy(phy_info_t *pi, u8 core, u8 rssi_type); -extern int wlc_phy_poll_rssi_nphy(phy_info_t *pi, u8 rssi_type, +extern void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core, u8 rssi_type); +extern int wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, s32 *rssi_buf, u8 nsamps); -extern void wlc_phy_rssi_cal_nphy(phy_info_t *pi); -extern int wlc_phy_aci_scan_nphy(phy_info_t *pi); -extern void wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, s32 dBm_targetpower, - bool debug); -extern int wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, +extern void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi); +extern int wlc_phy_aci_scan_nphy(struct brcms_phy *pi); +extern void wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, + s32 dBm_targetpower, bool debug); +extern int wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, u8 mode, u8, bool); -extern void wlc_phy_stopplayback_nphy(phy_info_t *pi); -extern void wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf, +extern void wlc_phy_stopplayback_nphy(struct brcms_phy *pi); +extern void wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, u8 num_samps); -extern void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi); +extern void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi); -extern int wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh); +extern int wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, + struct brcms_d11rxhdr *wlc_rxh); #define NPHY_TESTPATTERN_BPHY_EVM 0 #define NPHY_TESTPATTERN_BPHY_RFCS 1 -extern void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, u8 rifs); +extern void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs); -void wlc_phy_get_pwrdet_offsets(phy_info_t *pi, s8 *cckoffset, +void wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset, s8 *ofdmoffset); -extern s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi, +extern s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, chanspec_t chanspec); -extern bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pih); -#endif /* _wlc_phy_int_h_ */ +extern bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pih); +#endif /* _BRCM_PHY_INT_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c similarity index 89% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c rename to drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c index b8864c5b7a19..6a3fbe67302f 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c @@ -14,28 +14,20 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include - -#include "wlc_phy_radio.h" -#include "wlc_phy_int.h" -#include "wlc_phy_qmath.h" -#include "wlc_phy_lcn.h" -#include "wlc_phytbl_lcn.h" +#include +#include +#include +#include "phy_qmath.h" +#include "phy_hal.h" +#include "phy_radio.h" +#include "phytbl_lcn.h" +#include "phy_lcn.h" #define PLL_2064_NDIV 90 -#define PLL_2064_LOW_END_VCO 3000 -#define PLL_2064_LOW_END_KVCO 27 +#define PLL_2064_LOW_END_VCO 3000 +#define PLL_2064_LOW_END_KVCO 27 #define PLL_2064_HIGH_END_VCO 4200 #define PLL_2064_HIGH_END_KVCO 68 #define PLL_2064_LOOP_BW_DOUBLER 200 @@ -46,7 +38,7 @@ #define PLL_2064_MHZ 1000000 #define PLL_2064_OPEN_LOOP_DELAY 5 -#define TEMPSENSE 1 +#define TEMPSENSE 1 #define VBATSENSE 2 #define NOISE_IF_UPD_CHK_INTERVAL 1 @@ -58,10 +50,10 @@ #define NOISE_IF_CHK 1 #define NOISE_IF_ON 2 -#define PAPD_BLANKING_PROFILE 3 +#define PAPD_BLANKING_PROFILE 3 #define PAPD2LUT 0 -#define PAPD_CORR_NORM 0 -#define PAPD_BLANKING_THRESHOLD 0 +#define PAPD_CORR_NORM 0 +#define PAPD_BLANKING_THRESHOLD 0 #define PAPD_STOP_AFTER_LAST_UPDATE 0 #define LCN_TARGET_PWR 60 @@ -116,9 +108,9 @@ #define LCNPHY_TBL_ID_SAMPLEPLAY 0x15 #define LCNPHY_TBL_ID_SAMPLEPLAY1 0x16 -#define LCNPHY_TX_PWR_CTRL_RATE_OFFSET 832 -#define LCNPHY_TX_PWR_CTRL_MAC_OFFSET 128 -#define LCNPHY_TX_PWR_CTRL_GAIN_OFFSET 192 +#define LCNPHY_TX_PWR_CTRL_RATE_OFFSET 832 +#define LCNPHY_TX_PWR_CTRL_MAC_OFFSET 128 +#define LCNPHY_TX_PWR_CTRL_GAIN_OFFSET 192 #define LCNPHY_TX_PWR_CTRL_IQ_OFFSET 320 #define LCNPHY_TX_PWR_CTRL_LO_OFFSET 448 #define LCNPHY_TX_PWR_CTRL_PWR_OFFSET 576 @@ -144,60 +136,55 @@ (0 != (read_phy_reg((pi), 0x43b) & (0x1 << 6))) #define wlc_lcnphy_total_tx_frames(pi) \ - wlapi_bmac_read_shm((pi)->sh->physhim, M_UCODE_MACSTAT + offsetof(macstat_t, txallfrm)) + wlapi_bmac_read_shm((pi)->sh->physhim, \ + M_UCODE_MACSTAT + offsetof(struct macstat, txallfrm)) -typedef struct { +struct lcnphy_txgains { u16 gm_gain; u16 pga_gain; u16 pad_gain; u16 dac_gain; -} lcnphy_txgains_t; +}; -typedef enum { +enum lcnphy_cal_mode { LCNPHY_CAL_FULL, LCNPHY_CAL_RECAL, LCNPHY_CAL_CURRECAL, LCNPHY_CAL_DIGCAL, LCNPHY_CAL_GCTRL -} lcnphy_cal_mode_t; +}; -typedef struct { - lcnphy_txgains_t gains; - bool useindex; - u8 index; -} lcnphy_txcalgains_t; - -typedef struct { +struct lcnphy_rx_iqcomp { u8 chan; s16 a; s16 b; -} lcnphy_rx_iqcomp_t; +}; -typedef struct { +struct lcnphy_spb_tone { s16 re; s16 im; -} lcnphy_spb_tone_t; +}; -typedef struct { +struct lcnphy_unsign16_struct { u16 re; u16 im; -} lcnphy_unsign16_struct; +}; -typedef struct { +struct lcnphy_iq_est { u32 iq_prod; u32 i_pwr; u32 q_pwr; -} lcnphy_iq_est_t; +}; -typedef struct { +struct lcnphy_sfo_cfg { u16 ptcentreTs20; u16 ptcentreFactor; -} lcnphy_sfo_cfg_t; +}; -typedef enum { +enum lcnphy_papd_cal_type { LCNPHY_PAPD_CAL_CW, LCNPHY_PAPD_CAL_OFDM -} lcnphy_papd_cal_type_t; +}; typedef u16 iqcal_gain_params_lcnphy[9]; @@ -214,7 +201,7 @@ static const u16 iqcal_gainparams_numgains_lcnphy[1] = { sizeof(*tbl_iqcal_gainparams_lcnphy_2G), }; -static const lcnphy_sfo_cfg_t lcnphy_sfo_cfg[] = { +static const struct lcnphy_sfo_cfg lcnphy_sfo_cfg[] = { {965, 1087}, {967, 1085}, {969, 1082}, @@ -280,7 +267,7 @@ u16 lcnphy_iqcal_ir_gainladder[] = { }; static const -lcnphy_spb_tone_t lcnphy_spb_tone_3750[] = { +struct lcnphy_spb_tone lcnphy_spb_tone_3750[] = { {88, 0}, {73, 49}, {34, 81}, @@ -373,7 +360,7 @@ u16 rxiq_cal_rf_reg[11] = { }; static const -lcnphy_rx_iqcomp_t lcnphy_rx_iqcomp_table_rev0[] = { +struct lcnphy_rx_iqcomp lcnphy_rx_iqcomp_table_rev0[] = { {1, 0, 0}, {2, 0, 0}, {3, 0, 0}, @@ -548,13 +535,7 @@ static const s8 lcnphy_gain_index_offset_for_rssi[] = { -2 }; -extern const u8 spur_tbl_rev0[]; -extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev1; -extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[]; -extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa; -extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250; - -typedef struct _chan_info_2064_lcnphy { +struct chan_info_2064_lcnphy { uint chan; uint freq; u8 logen_buftune; @@ -565,9 +546,9 @@ typedef struct _chan_info_2064_lcnphy { u8 pa_rxrf_lna1_freq_tune; u8 pa_rxrf_lna2_freq_tune; u8 rxrf_rxrf_spare1; -} chan_info_2064_lcnphy_t; +}; -static chan_info_2064_lcnphy_t chan_info_2064_lcnphy[] = { +static struct chan_info_2064_lcnphy chan_info_2064_lcnphy[] = { {1, 2412, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, {2, 2417, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, {3, 2422, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, @@ -584,7 +565,7 @@ static chan_info_2064_lcnphy_t chan_info_2064_lcnphy[] = { {14, 2484, 0x0B, 0x0A, 0x00, 0x07, 0x0A, 0x88, 0x88, 0x80}, }; -lcnphy_radio_regs_t lcnphy_radio_regs_2064[] = { +struct lcnphy_radio_regs lcnphy_radio_regs_2064[] = { {0x00, 0, 0, 0, 0}, {0x01, 0x64, 0x64, 0, 0}, {0x02, 0x20, 0x20, 0, 0}, @@ -896,9 +877,8 @@ lcnphy_radio_regs_t lcnphy_radio_regs_2064[] = { #define LCNPHY_NUM_DIG_FILT_COEFFS 16 #define LCNPHY_NUM_TX_DIG_FILTERS_CCK 13 -u16 - LCNPHY_txdigfiltcoeffs_cck[LCNPHY_NUM_TX_DIG_FILTERS_CCK] - [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = { +u16 LCNPHY_txdigfiltcoeffs_cck[LCNPHY_NUM_TX_DIG_FILTERS_CCK] + [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = { {0, 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778, 1582, 64, 128, 64,}, {1, 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608, 1863, 93, @@ -928,9 +908,8 @@ u16 }; #define LCNPHY_NUM_TX_DIG_FILTERS_OFDM 3 -u16 - LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM] - [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = { +u16 LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM] + [LCNPHY_NUM_DIG_FILT_COEFFS + 1] = { {0, 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0, 0x0, 0x278, 0xfea0, 0x80, 0x100, 0x80,}, {1, 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50, @@ -982,78 +961,83 @@ u16 static u32 wlc_lcnphy_qdiv_roundup(u32 divident, u32 divisor, u8 precision); -static void wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi, +static void wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, u16 ext_lna, u16 trsw, u16 biq2, u16 biq1, u16 tia, u16 lna2, u16 lna1); -static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi); -static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, u16 gain); -static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx); -static void wlc_lcnphy_set_bbmult(phy_info_t *pi, u8 m0); -static u8 wlc_lcnphy_get_bbmult(phy_info_t *pi); -static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains); -static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable); -static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi); -static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable); -static void wlc_lcnphy_set_tx_gain(phy_info_t *pi, - lcnphy_txgains_t *target_gains); -static bool wlc_lcnphy_rx_iq_est(phy_info_t *pi, u16 num_samps, - u8 wait_time, lcnphy_iq_est_t *iq_est); -static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, u16 num_samps); -static u16 wlc_lcnphy_get_pa_gain(phy_info_t *pi); -static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, u8 mode); -extern void wlc_lcnphy_tx_pwr_ctrl_init(wlc_phy_t *ppi); -static void wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi, +static void wlc_lcnphy_clear_tx_power_offsets(struct brcms_phy *pi); +static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain); +static void wlc_lcnphy_set_trsw_override(struct brcms_phy *pi, bool tx, + bool rx); +static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0); +static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi); +static void wlc_lcnphy_get_tx_gain(struct brcms_phy *pi, + struct lcnphy_txgains *gains); +static void wlc_lcnphy_set_tx_gain_override(struct brcms_phy *pi, bool bEnable); +static void wlc_lcnphy_toggle_afe_pwdn(struct brcms_phy *pi); +static void wlc_lcnphy_rx_gain_override_enable(struct brcms_phy *pi, + bool enable); +static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi, + struct lcnphy_txgains *target_gains); +static bool wlc_lcnphy_rx_iq_est(struct brcms_phy *pi, u16 num_samps, + u8 wait_time, struct lcnphy_iq_est *iq_est); +static bool wlc_lcnphy_calc_rx_iq_comp(struct brcms_phy *pi, u16 num_samps); +static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi); +static void wlc_lcnphy_afe_clk_init(struct brcms_phy *pi, u8 mode); +static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi); +static void wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel); -static void wlc_lcnphy_load_tx_gain_table(phy_info_t *pi, - const lcnphy_tx_gain_tbl_entry *g); +static void wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi, + const struct lcnphy_tx_gain_tbl_entry *g); -static void wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, +static void wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, u16 thresh, s16 *ptr, int mode); static int wlc_lcnphy_calc_floor(s16 coeff, int type); -static void wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi, +static void wlc_lcnphy_tx_iqlo_loopback(struct brcms_phy *pi, u16 *values_to_save); -static void wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi, +static void wlc_lcnphy_tx_iqlo_loopback_cleanup(struct brcms_phy *pi, u16 *values_to_save); -static void wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, s16 coeff_x, +static void wlc_lcnphy_set_cc(struct brcms_phy *pi, int cal_type, s16 coeff_x, s16 coeff_y); -static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type); -static void wlc_lcnphy_a1(phy_info_t *pi, int cal_type, +static struct lcnphy_unsign16_struct wlc_lcnphy_get_cc(struct brcms_phy *pi, + int cal_type); +static void wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type, int num_levels, int step_size_lg2); -static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi); +static void wlc_lcnphy_tx_iqlo_soft_cal_full(struct brcms_phy *pi); -static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi, +static void wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi, chanspec_t chanspec); -static void wlc_lcnphy_agc_temp_init(phy_info_t *pi); -static void wlc_lcnphy_temp_adj(phy_info_t *pi); -static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi); -static void wlc_lcnphy_baseband_init(phy_info_t *pi); -static void wlc_lcnphy_radio_init(phy_info_t *pi); -static void wlc_lcnphy_rc_cal(phy_info_t *pi); -static void wlc_lcnphy_rcal(phy_info_t *pi); -static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable); -static int wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm, +static void wlc_lcnphy_agc_temp_init(struct brcms_phy *pi); +static void wlc_lcnphy_temp_adj(struct brcms_phy *pi); +static void wlc_lcnphy_clear_papd_comptable(struct brcms_phy *pi); +static void wlc_lcnphy_baseband_init(struct brcms_phy *pi); +static void wlc_lcnphy_radio_init(struct brcms_phy *pi); +static void wlc_lcnphy_rc_cal(struct brcms_phy *pi); +static void wlc_lcnphy_rcal(struct brcms_phy *pi); +static void wlc_lcnphy_txrx_spur_avoidance_mode(struct brcms_phy *pi, + bool enable); +static int wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type); -static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, u16 a, u16 b); +static void wlc_lcnphy_set_rx_iq_comp(struct brcms_phy *pi, u16 a, u16 b); -void wlc_lcnphy_write_table(phy_info_t *pi, const phytbl_info_t *pti) +void wlc_lcnphy_write_table(struct brcms_phy *pi, const struct phytbl_info *pti) { wlc_phy_write_table(pi, pti, 0x455, 0x457, 0x456); } -void wlc_lcnphy_read_table(phy_info_t *pi, phytbl_info_t *pti) +void wlc_lcnphy_read_table(struct brcms_phy *pi, struct phytbl_info *pti) { wlc_phy_read_table(pi, pti, 0x455, 0x457, 0x456); } static void -wlc_lcnphy_common_read_table(phy_info_t *pi, u32 tbl_id, +wlc_lcnphy_common_read_table(struct brcms_phy *pi, u32 tbl_id, const void *tbl_ptr, u32 tbl_len, u32 tbl_width, u32 tbl_offset) { - phytbl_info_t tab; + struct phytbl_info tab; tab.tbl_id = tbl_id; tab.tbl_ptr = tbl_ptr; tab.tbl_len = tbl_len; @@ -1063,12 +1047,12 @@ wlc_lcnphy_common_read_table(phy_info_t *pi, u32 tbl_id, } static void -wlc_lcnphy_common_write_table(phy_info_t *pi, u32 tbl_id, +wlc_lcnphy_common_write_table(struct brcms_phy *pi, u32 tbl_id, const void *tbl_ptr, u32 tbl_len, u32 tbl_width, u32 tbl_offset) { - phytbl_info_t tab; + struct phytbl_info tab; tab.tbl_id = tbl_id; tab.tbl_ptr = tbl_ptr; tab.tbl_len = tbl_len; @@ -1123,10 +1107,10 @@ static int wlc_lcnphy_calc_floor(s16 coeff_x, int type) return k; } -s8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi) +s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi) { s8 index; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; if (txpwrctrl_off(pi)) index = pi_lcn->lcnphy_current_index; @@ -1139,16 +1123,16 @@ s8 wlc_lcnphy_get_current_tx_pwr_idx(phy_info_t *pi) return index; } -static u32 wlc_lcnphy_measure_digital_power(phy_info_t *pi, u16 nsamples) +static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples) { - lcnphy_iq_est_t iq_est = { 0, 0, 0 }; + struct lcnphy_iq_est iq_est = { 0, 0, 0 }; if (!wlc_lcnphy_rx_iq_est(pi, nsamples, 32, &iq_est)) return 0; return (iq_est.i_pwr + iq_est.q_pwr) / nsamples; } -void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel) +void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel) { u16 afectrlovr, afectrlovrval; afectrlovr = read_phy_reg(pi, 0x43b); @@ -1179,7 +1163,7 @@ void wlc_lcnphy_crsuprs(phy_info_t *pi, int channel) } } -static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi) +static void wlc_lcnphy_toggle_afe_pwdn(struct brcms_phy *pi) { u16 save_AfeCtrlOvrVal, save_AfeCtrlOvr; @@ -1196,7 +1180,8 @@ static void wlc_lcnphy_toggle_afe_pwdn(phy_info_t *pi) write_phy_reg(pi, 0x43b, save_AfeCtrlOvr); } -static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable) +static void +wlc_lcnphy_txrx_spur_avoidance_mode(struct brcms_phy *pi, bool enable) { if (enable) { write_phy_reg(pi, 0x942, 0x7); @@ -1215,11 +1200,11 @@ static void wlc_lcnphy_txrx_spur_avoidance_mode(phy_info_t *pi, bool enable) wlapi_switch_macfreq(pi->sh->physhim, enable); } -void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec) +void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, chanspec_t chanspec) { u8 channel = CHSPEC_CHANNEL(chanspec); - wlc_phy_chanspec_radio_set((wlc_phy_t *) pi, chanspec); + wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec); wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec); @@ -1252,7 +1237,7 @@ void wlc_phy_chanspec_set_lcnphy(phy_info_t *pi, chanspec_t chanspec) } -static void wlc_lcnphy_set_dac_gain(phy_info_t *pi, u16 dac_gain) +static void wlc_lcnphy_set_dac_gain(struct brcms_phy *pi, u16 dac_gain) { u16 dac_ctrl; @@ -1263,7 +1248,7 @@ static void wlc_lcnphy_set_dac_gain(phy_info_t *pi, u16 dac_gain) } -static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable) +static void wlc_lcnphy_set_tx_gain_override(struct brcms_phy *pi, bool bEnable) { u16 bit = bEnable ? 1 : 0; @@ -1274,7 +1259,7 @@ static void wlc_lcnphy_set_tx_gain_override(phy_info_t *pi, bool bEnable) mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6); } -static u16 wlc_lcnphy_get_pa_gain(phy_info_t *pi) +static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi) { u16 pa_gain; @@ -1285,8 +1270,8 @@ static u16 wlc_lcnphy_get_pa_gain(phy_info_t *pi) return pa_gain; } -static void -wlc_lcnphy_set_tx_gain(phy_info_t *pi, lcnphy_txgains_t *target_gains) +static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi, + struct lcnphy_txgains *target_gains) { u16 pa_gain = wlc_lcnphy_get_pa_gain(pi); @@ -1311,10 +1296,10 @@ wlc_lcnphy_set_tx_gain(phy_info_t *pi, lcnphy_txgains_t *target_gains) wlc_lcnphy_enable_tx_gain_override(pi); } -static void wlc_lcnphy_set_bbmult(phy_info_t *pi, u8 m0) +static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0) { u16 m0m1 = (u16) m0 << 8; - phytbl_info_t tab; + struct phytbl_info tab; tab.tbl_ptr = &m0m1; tab.tbl_len = 1; @@ -1324,10 +1309,10 @@ static void wlc_lcnphy_set_bbmult(phy_info_t *pi, u8 m0) wlc_lcnphy_write_table(pi, &tab); } -static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi) +static void wlc_lcnphy_clear_tx_power_offsets(struct brcms_phy *pi) { u32 data_buf[64]; - phytbl_info_t tab; + struct phytbl_info tab; memset(data_buf, 0, sizeof(data_buf)); @@ -1347,13 +1332,14 @@ static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi) wlc_lcnphy_write_table(pi, &tab); } -typedef enum { +enum lcnphy_tssi_mode { LCNPHY_TSSI_PRE_PA, LCNPHY_TSSI_POST_PA, LCNPHY_TSSI_EXT -} lcnphy_tssi_mode_t; +}; -static void wlc_lcnphy_set_tssi_mux(phy_info_t *pi, lcnphy_tssi_mode_t pos) +static void +wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos) { mod_phy_reg(pi, 0x4d7, (0x1 << 0), (0x1) << 0); @@ -1392,7 +1378,7 @@ static void wlc_lcnphy_set_tssi_mux(phy_info_t *pi, lcnphy_tssi_mode_t pos) } } -static u16 wlc_lcnphy_rfseq_tbl_adc_pwrup(phy_info_t *pi) +static u16 wlc_lcnphy_rfseq_tbl_adc_pwrup(struct brcms_phy *pi) { u16 N1, N2, N3, N4, N5, N6, N; N1 = ((read_phy_reg(pi, 0x4a5) & (0xff << 0)) @@ -1413,10 +1399,10 @@ static u16 wlc_lcnphy_rfseq_tbl_adc_pwrup(phy_info_t *pi) return N; } -static void wlc_lcnphy_pwrctrl_rssiparams(phy_info_t *pi) +static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi) { u16 auxpga_vmid, auxpga_vmid_temp, auxpga_gain_temp; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; auxpga_vmid = (2 << 8) | (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf; @@ -1457,9 +1443,9 @@ static void wlc_lcnphy_pwrctrl_rssiparams(phy_info_t *pi) mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5)); } -static void wlc_lcnphy_tssi_setup(phy_info_t *pi) +static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) { - phytbl_info_t tab; + struct phytbl_info tab; u32 rfseq, ind; tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; @@ -1571,10 +1557,10 @@ static void wlc_lcnphy_tssi_setup(phy_info_t *pi) wlc_lcnphy_pwrctrl_rssiparams(pi); } -void wlc_lcnphy_tx_pwr_update_npt(phy_info_t *pi) +void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi) { u16 tx_cnt, tx_total, npt; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; tx_total = wlc_lcnphy_total_tx_frames(pi); tx_cnt = tx_total - pi_lcn->lcnphy_tssi_tx_cnt; @@ -1601,9 +1587,9 @@ s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1) return p; } -static void wlc_lcnphy_txpower_reset_npt(phy_info_t *pi) +static void wlc_lcnphy_txpower_reset_npt(struct brcms_phy *pi) { - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) return; @@ -1611,18 +1597,18 @@ static void wlc_lcnphy_txpower_reset_npt(phy_info_t *pi) pi_lcn->lcnphy_tssi_npt = LCNPHY_TX_PWR_CTRL_START_NPT; } -void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi) +void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi) { - phytbl_info_t tab; - u32 rate_table[WLC_NUM_RATES_CCK + WLC_NUM_RATES_OFDM + - WLC_NUM_RATES_MCS_1_STREAM]; + struct phytbl_info tab; + u32 rate_table[BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM + + BRCMS_NUM_RATES_MCS_1_STREAM]; uint i, j; if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) return; for (i = 0, j = 0; i < ARRAY_SIZE(rate_table); i++, j++) { - if (i == WLC_NUM_RATES_CCK + WLC_NUM_RATES_OFDM) + if (i == BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM) j = TXP_FIRST_MCS_20_SISO; rate_table[i] = (u32) ((s32) (-pi->tx_power_offset[j])); @@ -1642,13 +1628,13 @@ void wlc_lcnphy_txpower_recalc_target(phy_info_t *pi) } } -static void wlc_lcnphy_set_tx_pwr_soft_ctrl(phy_info_t *pi, s8 index) +static void wlc_lcnphy_set_tx_pwr_soft_ctrl(struct brcms_phy *pi, s8 index) { u32 cck_offset[4] = { 22, 22, 22, 22 }; u32 ofdm_offset, reg_offset_cck; int i; u16 index2; - phytbl_info_t tab; + struct phytbl_info tab; if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) return; @@ -1695,13 +1681,13 @@ static void wlc_lcnphy_set_tx_pwr_soft_ctrl(phy_info_t *pi, s8 index) } -static s8 wlc_lcnphy_tempcompensated_txpwrctrl(phy_info_t *pi) +static s8 wlc_lcnphy_tempcompensated_txpwrctrl(struct brcms_phy *pi) { s8 index, delta_brd, delta_temp, new_index, tempcorrx; s16 manp, meas_temp, temp_diff; bool neg = 0; u16 temp; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) return pi_lcn->lcnphy_current_index; @@ -1760,7 +1746,7 @@ static s8 wlc_lcnphy_tempcompensated_txpwrctrl(phy_info_t *pi) return new_index; } -static u16 wlc_lcnphy_set_tx_pwr_ctrl_mode(phy_info_t *pi, u16 mode) +static u16 wlc_lcnphy_set_tx_pwr_ctrl_mode(struct brcms_phy *pi, u16 mode) { u16 current_mode = mode; @@ -1773,11 +1759,11 @@ static u16 wlc_lcnphy_set_tx_pwr_ctrl_mode(phy_info_t *pi, u16 mode) return current_mode; } -void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode) +void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode) { u16 old_mode = wlc_lcnphy_get_tx_pwr_ctrl(pi); s8 index; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode); old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode); @@ -1824,7 +1810,7 @@ void wlc_lcnphy_set_tx_pwr_ctrl(phy_info_t *pi, u16 mode) } } -static bool wlc_lcnphy_iqcal_wait(phy_info_t *pi) +static bool wlc_lcnphy_iqcal_wait(struct brcms_phy *pi) { uint delay_count = 0; @@ -1840,12 +1826,12 @@ static bool wlc_lcnphy_iqcal_wait(phy_info_t *pi) } static void -wlc_lcnphy_tx_iqlo_cal(phy_info_t *pi, - lcnphy_txgains_t *target_gains, - lcnphy_cal_mode_t cal_mode, bool keep_tone) +wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, + struct lcnphy_txgains *target_gains, + enum lcnphy_cal_mode cal_mode, bool keep_tone) { - lcnphy_txgains_t cal_gains, temp_gains; + struct lcnphy_txgains cal_gains, temp_gains; u16 hash; u8 band_idx; int j; @@ -1871,10 +1857,10 @@ wlc_lcnphy_tx_iqlo_cal(phy_info_t *pi, u16 tx_pwr_ctrl_old, save_txpwrctrlrfctrl2; u16 save_sslpnCalibClkEnCtrl, save_sslpnRxFeClkEnCtrl; bool tx_gain_override_old; - lcnphy_txgains_t old_gains; + struct lcnphy_txgains old_gains; uint i, n_cal_cmds = 0, n_cal_start = 0; u16 *values_to_save; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; if (NORADIO_ENAB(pi->pubpi)) return; @@ -2075,11 +2061,11 @@ wlc_lcnphy_tx_iqlo_cal(phy_info_t *pi, } -static void wlc_lcnphy_idle_tssi_est(wlc_phy_t *ppi) +static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) { bool suspend, tx_gain_override_old; - lcnphy_txgains_t old_gains; - phy_info_t *pi = (phy_info_t *) ppi; + struct lcnphy_txgains old_gains; + struct brcms_phy *pi = (struct brcms_phy *) ppi; u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB, idleTssi0_regvalue_2C; u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); @@ -2091,7 +2077,7 @@ static void wlc_lcnphy_idle_tssi_est(wlc_phy_t *ppi) idleTssi = read_phy_reg(pi, 0x4ab); suspend = (0 == - (R_REG(&((phy_info_t *) pi)->regs->maccontrol) & + (R_REG(&((struct brcms_phy *) pi)->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); @@ -2141,20 +2127,20 @@ static void wlc_lcnphy_idle_tssi_est(wlc_phy_t *ppi) wlapi_enable_mac(pi->sh->physhim); } -static void wlc_lcnphy_vbat_temp_sense_setup(phy_info_t *pi, u8 mode) +static void wlc_lcnphy_vbat_temp_sense_setup(struct brcms_phy *pi, u8 mode) { bool suspend; u16 save_txpwrCtrlEn; u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain; u16 auxpga_vmid; - phytbl_info_t tab; + struct phytbl_info tab; u32 val; u8 save_reg007, save_reg0FF, save_reg11F, save_reg005, save_reg025, save_reg112; u16 values_to_save[14]; s8 index; int i; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; udelay(999); save_reg007 = (u8) read_radio_reg(pi, RADIO_2064_REG007); @@ -2283,15 +2269,15 @@ static void wlc_lcnphy_vbat_temp_sense_setup(phy_info_t *pi, u8 mode) udelay(999); } -void WLBANDINITFN(wlc_lcnphy_tx_pwr_ctrl_init) (wlc_phy_t *ppi) +static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi) { - lcnphy_txgains_t tx_gains; + struct lcnphy_txgains tx_gains; u8 bbmult; - phytbl_info_t tab; + struct phytbl_info tab; s32 a1, b0, b1; s32 tssi, pwr, maxtargetpwr, mintargetpwr; bool suspend; - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); @@ -2361,10 +2347,10 @@ void WLBANDINITFN(wlc_lcnphy_tx_pwr_ctrl_init) (wlc_phy_t *ppi) wlapi_enable_mac(pi->sh->physhim); } -static u8 wlc_lcnphy_get_bbmult(phy_info_t *pi) +static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi) { u16 m0m1; - phytbl_info_t tab; + struct phytbl_info tab; tab.tbl_ptr = &m0m1; tab.tbl_len = 1; @@ -2376,7 +2362,7 @@ static u8 wlc_lcnphy_get_bbmult(phy_info_t *pi) return (u8) ((m0m1 & 0xff00) >> 8); } -static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, u16 gain) +static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain) { mod_phy_reg(pi, 0x4fb, LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK, @@ -2387,7 +2373,7 @@ static void wlc_lcnphy_set_pa_gain(phy_info_t *pi, u16 gain) } void -wlc_lcnphy_get_radio_loft(phy_info_t *pi, +wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, u8 *ei0, u8 *eq0, u8 *fi0, u8 *fq0) { *ei0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG089)); @@ -2396,7 +2382,8 @@ wlc_lcnphy_get_radio_loft(phy_info_t *pi, *fq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08C)); } -static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains) +static void +wlc_lcnphy_get_tx_gain(struct brcms_phy *pi, struct lcnphy_txgains *gains) { u16 dac_gain; @@ -2415,9 +2402,9 @@ static void wlc_lcnphy_get_tx_gain(phy_info_t *pi, lcnphy_txgains_t *gains) } } -void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, u16 a, u16 b) +void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b) { - phytbl_info_t tab; + struct phytbl_info tab; u16 iqcc[2]; iqcc[0] = a; @@ -2431,9 +2418,9 @@ void wlc_lcnphy_set_tx_iqcc(phy_info_t *pi, u16 a, u16 b) wlc_lcnphy_write_table(pi, &tab); } -void wlc_lcnphy_set_tx_locc(phy_info_t *pi, u16 didq) +void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq) { - phytbl_info_t tab; + struct phytbl_info tab; tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL; tab.tbl_width = 16; @@ -2443,14 +2430,14 @@ void wlc_lcnphy_set_tx_locc(phy_info_t *pi, u16 didq) wlc_lcnphy_write_table(pi, &tab); } -void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index) +void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index) { - phytbl_info_t tab; + struct phytbl_info tab; u16 a, b; u8 bb_mult; u32 bbmultiqcomp, txgain, locoeffs, rfpower; - lcnphy_txgains_t gains; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct lcnphy_txgains gains; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; pi_lcn->lcnphy_tx_power_idx_override = (s8) index; pi_lcn->lcnphy_current_index = (u8) index; @@ -2502,7 +2489,7 @@ void wlc_lcnphy_set_tx_pwr_by_index(phy_info_t *pi, int index) } } -static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx) +static void wlc_lcnphy_set_trsw_override(struct brcms_phy *pi, bool tx, bool rx) { mod_phy_reg(pi, 0x44d, @@ -2512,10 +2499,10 @@ static void wlc_lcnphy_set_trsw_override(phy_info_t *pi, bool tx, bool rx) or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0)); } -static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi) +static void wlc_lcnphy_clear_papd_comptable(struct brcms_phy *pi) { u32 j; - phytbl_info_t tab; + struct phytbl_info tab; u32 temp_offset[128]; tab.tbl_ptr = temp_offset; tab.tbl_len = 128; @@ -2532,7 +2519,7 @@ static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi) } static void -wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi, +wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, u16 trsw, u16 ext_lna, u16 biq2, @@ -2566,7 +2553,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(phy_info_t *pi, } -static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable) +static void +wlc_lcnphy_rx_gain_override_enable(struct brcms_phy *pi, bool enable) { u16 ebit = enable ? 1 : 0; @@ -2591,7 +2579,7 @@ static void wlc_lcnphy_rx_gain_override_enable(phy_info_t *pi, bool enable) } } -void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable) +void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable) { if (!bEnable) { @@ -2669,7 +2657,7 @@ void wlc_lcnphy_tx_pu(phy_info_t *pi, bool bEnable) } static void -wlc_lcnphy_run_samples(phy_info_t *pi, +wlc_lcnphy_run_samples(struct brcms_phy *pi, u16 num_samps, u16 num_loops, u16 wait, bool iqcalmode) { @@ -2695,7 +2683,7 @@ wlc_lcnphy_run_samples(phy_info_t *pi, or_radio_reg(pi, RADIO_2064_REG112, 0x6); } -void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode) +void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode) { u8 phybw40; @@ -2720,7 +2708,7 @@ void wlc_lcnphy_deaf_mode(phy_info_t *pi, bool mode) } void -wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz, u16 max_val, +wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, u16 max_val, bool iqcalmode) { u8 phy_bw; @@ -2730,8 +2718,8 @@ wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz, u16 max_val, cs32 tone_samp; u32 data_buf[64]; u16 i_samp, q_samp; - phytbl_info_t tab; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct phytbl_info tab; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; pi->phy_tx_tone_freq = f_kHz; @@ -2783,10 +2771,10 @@ wlc_lcnphy_start_tx_tone(phy_info_t *pi, s32 f_kHz, u16 max_val, wlc_lcnphy_run_samples(pi, num_samps, 0xffff, 0, iqcalmode); } -void wlc_lcnphy_stop_tx_tone(phy_info_t *pi) +void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi) { s16 playback_status; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; pi->phy_tx_tone_freq = 0; if (pi_lcn->lcnphy_spurmod) { @@ -2814,16 +2802,16 @@ void wlc_lcnphy_stop_tx_tone(phy_info_t *pi) wlc_lcnphy_deaf_mode(pi, false); } -static void wlc_lcnphy_clear_trsw_override(phy_info_t *pi) +static void wlc_lcnphy_clear_trsw_override(struct brcms_phy *pi) { and_phy_reg(pi, 0x44c, (u16) ~((0x1 << 1) | (0x1 << 0))); } -void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, u16 *a, u16 *b) +void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b) { u16 iqcc[2]; - phytbl_info_t tab; + struct phytbl_info tab; tab.tbl_ptr = iqcc; tab.tbl_len = 2; @@ -2836,9 +2824,9 @@ void wlc_lcnphy_get_tx_iqcc(phy_info_t *pi, u16 *a, u16 *b) *b = iqcc[1]; } -u16 wlc_lcnphy_get_tx_locc(phy_info_t *pi) +u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi) { - phytbl_info_t tab; + struct phytbl_info tab; u16 didq; tab.tbl_id = 0; @@ -2851,18 +2839,18 @@ u16 wlc_lcnphy_get_tx_locc(phy_info_t *pi) return didq; } -static void wlc_lcnphy_txpwrtbl_iqlo_cal(phy_info_t *pi) +static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi) { - lcnphy_txgains_t target_gains, old_gains; + struct lcnphy_txgains target_gains, old_gains; u8 save_bb_mult; u16 a, b, didq, save_pa_gain = 0; uint idx, SAVE_txpwrindex = 0xFF; u32 val; u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - phytbl_info_t tab; + struct phytbl_info tab; u8 ei0, eq0, fi0, fq0; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; wlc_lcnphy_get_tx_gain(pi, &old_gains); save_pa_gain = wlc_lcnphy_get_pa_gain(pi); @@ -2965,7 +2953,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(phy_info_t *pi) wlc_lcnphy_set_tx_pwr_by_index(pi, SAVE_txpwrindex); } -s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode) +s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode) { u16 tempsenseval1, tempsenseval2; s16 avg = 0; @@ -3010,13 +2998,13 @@ s16 wlc_lcnphy_tempsense_new(phy_info_t *pi, bool mode) return avg; } -u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode) +u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode) { u16 tempsenseval1, tempsenseval2; s32 avg = 0; bool suspend = 0; u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; if (NORADIO_ENAB(pi->pubpi)) return -1; @@ -3071,7 +3059,7 @@ u16 wlc_lcnphy_tempsense(phy_info_t *pi, bool mode) return (u16) avg; } -s8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode) +s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode) { s32 degree = wlc_lcnphy_tempsense_new(pi, mode); degree = @@ -3080,7 +3068,7 @@ s8 wlc_lcnphy_tempsense_degree(phy_info_t *pi, bool mode) return (s8) degree; } -s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode) +s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode) { u16 vbatsenseval; s32 avg = 0; @@ -3116,7 +3104,7 @@ s8 wlc_lcnphy_vbatsense(phy_info_t *pi, bool mode) return (s8) avg; } -static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, u8 mode) +static void wlc_lcnphy_afe_clk_init(struct brcms_phy *pi, u8 mode) { u8 phybw40; phybw40 = CHSPEC_IS40(pi->radio_chanspec); @@ -3131,9 +3119,9 @@ static void wlc_lcnphy_afe_clk_init(phy_info_t *pi, u8 mode) } static bool -wlc_lcnphy_rx_iq_est(phy_info_t *pi, +wlc_lcnphy_rx_iq_est(struct brcms_phy *pi, u16 num_samps, - u8 wait_time, lcnphy_iq_est_t *iq_est) + u8 wait_time, struct lcnphy_iq_est *iq_est) { int wait_count = 0; bool result = true; @@ -3177,17 +3165,17 @@ wlc_lcnphy_rx_iq_est(phy_info_t *pi, return result; } -static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, u16 num_samps) +static bool wlc_lcnphy_calc_rx_iq_comp(struct brcms_phy *pi, u16 num_samps) { #define LCNPHY_MIN_RXIQ_PWR 2 bool result; u16 a0_new, b0_new; - lcnphy_iq_est_t iq_est = { 0, 0, 0 }; + struct lcnphy_iq_est iq_est = { 0, 0, 0 }; s32 a, b, temp; s16 iq_nbits, qq_nbits, arsh, brsh; s32 iq; u32 ii, qq; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0); b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0); @@ -3263,11 +3251,12 @@ static bool wlc_lcnphy_calc_rx_iq_comp(phy_info_t *pi, u16 num_samps) } static bool -wlc_lcnphy_rx_iq_cal(phy_info_t *pi, const lcnphy_rx_iqcomp_t *iqcomp, +wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, + const struct lcnphy_rx_iqcomp *iqcomp, int iqcomp_sz, bool tx_switch, bool rx_switch, int module, int tx_gain_idx) { - lcnphy_txgains_t old_gains; + struct lcnphy_txgains old_gains; u16 tx_pwr_ctrl; u8 tx_gain_index_old = 0; bool result = false, tx_gain_override_old = false; @@ -3280,7 +3269,7 @@ wlc_lcnphy_rx_iq_cal(phy_info_t *pi, const lcnphy_rx_iqcomp_t *iqcomp, u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl; u16 values_to_save[11]; s16 *ptr; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC); if (NULL == ptr) { @@ -3431,18 +3420,18 @@ wlc_lcnphy_rx_iq_cal(phy_info_t *pi, const lcnphy_rx_iqcomp_t *iqcomp, return result; } -static void wlc_lcnphy_temp_adj(phy_info_t *pi) +static void wlc_lcnphy_temp_adj(struct brcms_phy *pi) { if (NORADIO_ENAB(pi->pubpi)) return; } -static void wlc_lcnphy_glacial_timer_based_cal(phy_info_t *pi) +static void wlc_lcnphy_glacial_timer_based_cal(struct brcms_phy *pi) { bool suspend; s8 index; u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) @@ -3462,17 +3451,17 @@ static void wlc_lcnphy_glacial_timer_based_cal(phy_info_t *pi) } -static void wlc_lcnphy_periodic_cal(phy_info_t *pi) +static void wlc_lcnphy_periodic_cal(struct brcms_phy *pi) { bool suspend, full_cal; - const lcnphy_rx_iqcomp_t *rx_iqcomp; + const struct lcnphy_rx_iqcomp *rx_iqcomp; int rx_iqcomp_sz; u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); s8 index; - phytbl_info_t tab; + struct phytbl_info tab; s32 a1, b0, b1; s32 tssi, pwr, maxtargetpwr, mintargetpwr; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; if (NORADIO_ENAB(pi->pubpi)) return; @@ -3506,7 +3495,7 @@ static void wlc_lcnphy_periodic_cal(phy_info_t *pi) if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) { - wlc_lcnphy_idle_tssi_est((wlc_phy_t *) pi); + wlc_lcnphy_idle_tssi_est((struct brcms_phy_pub *) pi); b0 = pi->txpa_2g[0]; b1 = pi->txpa_2g[1]; @@ -3534,11 +3523,11 @@ static void wlc_lcnphy_periodic_cal(phy_info_t *pi) wlapi_enable_mac(pi->sh->physhim); } -void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode) +void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode) { u16 temp_new; int temp1, temp2, temp_diff; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; switch (mode) { case PHY_PERICAL_CHAN: @@ -3568,12 +3557,13 @@ void wlc_lcnphy_calib_modes(phy_info_t *pi, uint mode) break; case LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL: if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) - wlc_lcnphy_tx_power_adjustment((wlc_phy_t *) pi); + wlc_lcnphy_tx_power_adjustment( + (struct brcms_phy_pub *) pi); break; } } -void wlc_lcnphy_get_tssi(phy_info_t *pi, s8 *ofdm_pwr, s8 *cck_pwr) +void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr, s8 *cck_pwr) { s8 cck_offset; u16 status; @@ -3595,16 +3585,17 @@ void wlc_lcnphy_get_tssi(phy_info_t *pi, s8 *ofdm_pwr, s8 *cck_pwr) } } -void WLBANDINITFN(wlc_phy_cal_init_lcnphy) (phy_info_t *pi) +void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi) { return; } -static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi, chanspec_t chanspec) +static void +wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi, chanspec_t chanspec) { u8 channel = CHSPEC_CHANNEL(chanspec); - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; if (NORADIO_ENAB(pi->pubpi)) return; @@ -3653,12 +3644,12 @@ static void wlc_lcnphy_set_chanspec_tweaks(phy_info_t *pi, chanspec_t chanspec) write_phy_reg(pi, 0x44a, 0x80); } -void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi) +void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi) { s8 index; u16 index2; - phy_info_t *pi = (phy_info_t *) ppi; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy *pi = (struct brcms_phy *) ppi; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && SAVE_txpwrctrl) { index = wlc_lcnphy_tempcompensated_txpwrctrl(pi); @@ -3670,7 +3661,7 @@ void wlc_lcnphy_tx_power_adjustment(wlc_phy_t *ppi) } } -static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, u16 a, u16 b) +static void wlc_lcnphy_set_rx_iq_comp(struct brcms_phy *pi, u16 a, u16 b) { mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0); @@ -3686,10 +3677,10 @@ static void wlc_lcnphy_set_rx_iq_comp(phy_info_t *pi, u16 a, u16 b) } -void WLBANDINITFN(wlc_phy_init_lcnphy) (phy_info_t *pi) +void wlc_phy_init_lcnphy(struct brcms_phy *pi) { u8 phybw40; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; phybw40 = CHSPEC_IS40(pi->radio_chanspec); pi_lcn->lcnphy_cal_counter = 0; @@ -3709,9 +3700,9 @@ void WLBANDINITFN(wlc_phy_init_lcnphy) (phy_info_t *pi) wlc_lcnphy_radio_init(pi); if (CHSPEC_IS2G(pi->radio_chanspec)) - wlc_lcnphy_tx_pwr_ctrl_init((wlc_phy_t *) pi); + wlc_lcnphy_tx_pwr_ctrl_init((struct brcms_phy_pub *) pi); - wlc_phy_chanspec_set((wlc_phy_t *) pi, pi->radio_chanspec); + wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec); si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9); @@ -3736,7 +3727,7 @@ void WLBANDINITFN(wlc_phy_init_lcnphy) (phy_info_t *pi) } static void -wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi, u16 *values_to_save) +wlc_lcnphy_tx_iqlo_loopback(struct brcms_phy *pi, u16 *values_to_save) { u16 vmid; int i; @@ -3829,14 +3820,14 @@ wlc_lcnphy_tx_iqlo_loopback(phy_info_t *pi, u16 *values_to_save) } static void -wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, u16 thresh, +wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, u16 thresh, s16 *ptr, int mode) { u32 curval1, curval2, stpptr, curptr, strptr, val; u16 sslpnCalibClkEnCtrl, timer; u16 old_sslpnCalibClkEnCtrl; s16 imag, real; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; timer = 0; old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); @@ -3905,9 +3896,9 @@ wlc_lcnphy_samp_cap(phy_info_t *pi, int clip_detect_algo, u16 thresh, W_REG(&pi->regs->psm_corectlsts, curval1); } -static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi) +static void wlc_lcnphy_tx_iqlo_soft_cal_full(struct brcms_phy *pi) { - lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4; + struct lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4; wlc_lcnphy_set_cc(pi, 0, 0, 0); wlc_lcnphy_set_cc(pi, 2, 0, 0); @@ -3928,7 +3919,7 @@ static void wlc_lcnphy_tx_iqlo_soft_cal_full(phy_info_t *pi) } static void -wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, s16 coeff_x, s16 coeff_y) +wlc_lcnphy_set_cc(struct brcms_phy *pi, int cal_type, s16 coeff_x, s16 coeff_y) { u16 di0dq0; u16 x, y, data_rf; @@ -3972,11 +3963,12 @@ wlc_lcnphy_set_cc(phy_info_t *pi, int cal_type, s16 coeff_x, s16 coeff_y) } } -static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type) +static struct lcnphy_unsign16_struct +wlc_lcnphy_get_cc(struct brcms_phy *pi, int cal_type) { u16 a, b, didq; u8 di0, dq0, ei, eq, fi, fq; - lcnphy_unsign16_struct cc; + struct lcnphy_unsign16_struct cc; cc.re = 0; cc.im = 0; switch (cal_type) { @@ -4007,11 +3999,12 @@ static lcnphy_unsign16_struct wlc_lcnphy_get_cc(phy_info_t *pi, int cal_type) } static void -wlc_lcnphy_a1(phy_info_t *pi, int cal_type, int num_levels, int step_size_lg2) +wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type, int num_levels, + int step_size_lg2) { - const lcnphy_spb_tone_t *phy_c1; - lcnphy_spb_tone_t phy_c2; - lcnphy_unsign16_struct phy_c3; + const struct lcnphy_spb_tone *phy_c1; + struct lcnphy_spb_tone phy_c2; + struct lcnphy_unsign16_struct phy_c3; int phy_c4, phy_c5, k, l, j, phy_c6; u16 phy_c7, phy_c8, phy_c9; s16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16; @@ -4205,7 +4198,7 @@ wlc_lcnphy_a1(phy_info_t *pi, int cal_type, int num_levels, int step_size_lg2) } static void -wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi, u16 *values_to_save) +wlc_lcnphy_tx_iqlo_loopback_cleanup(struct brcms_phy *pi, u16 *values_to_save) { int i; @@ -4220,11 +4213,10 @@ wlc_lcnphy_tx_iqlo_loopback_cleanup(phy_info_t *pi, u16 *values_to_save) } static void -WLBANDINITFN(wlc_lcnphy_load_tx_gain_table) (phy_info_t *pi, - const lcnphy_tx_gain_tbl_entry * - gain_table) { +wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi, + const struct lcnphy_tx_gain_tbl_entry *gain_table) { u32 j; - phytbl_info_t tab; + struct phytbl_info tab; u32 val; u16 pa_gain; u16 gm_gain; @@ -4256,9 +4248,9 @@ WLBANDINITFN(wlc_lcnphy_load_tx_gain_table) (phy_info_t *pi, } } -static void wlc_lcnphy_load_rfpower(phy_info_t *pi) +static void wlc_lcnphy_load_rfpower(struct brcms_phy *pi) { - phytbl_info_t tab; + struct phytbl_info tab; u32 val, bbmult, rfgain; u8 index; u8 scale_factor = 1; @@ -4305,11 +4297,11 @@ static void wlc_lcnphy_load_rfpower(phy_info_t *pi) } } -static void WLBANDINITFN(wlc_lcnphy_tbl_init) (phy_info_t *pi) +static void wlc_lcnphy_tbl_init(struct brcms_phy *pi) { uint idx; u8 phybw40; - phytbl_info_t tab; + struct phytbl_info tab; u32 val; phybw40 = CHSPEC_IS40(pi->radio_chanspec); @@ -4400,10 +4392,10 @@ static void WLBANDINITFN(wlc_lcnphy_tbl_init) (phy_info_t *pi) wlc_lcnphy_clear_papd_comptable(pi); } -static void WLBANDINITFN(wlc_lcnphy_rev0_baseband_init) (phy_info_t *pi) +static void wlc_lcnphy_rev0_baseband_init(struct brcms_phy *pi) { u16 afectrl1; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; write_radio_reg(pi, RADIO_2064_REG11C, 0x0); @@ -4447,7 +4439,7 @@ static void WLBANDINITFN(wlc_lcnphy_rev0_baseband_init) (phy_info_t *pi) } -static void WLBANDINITFN(wlc_lcnphy_rev2_baseband_init) (phy_info_t *pi) +static void wlc_lcnphy_rev2_baseband_init(struct brcms_phy *pi) { if (CHSPEC_IS5G(pi->radio_chanspec)) { mod_phy_reg(pi, 0x416, (0xff << 0), 80 << 0); @@ -4456,12 +4448,12 @@ static void WLBANDINITFN(wlc_lcnphy_rev2_baseband_init) (phy_info_t *pi) } } -static void wlc_lcnphy_agc_temp_init(phy_info_t *pi) +static void wlc_lcnphy_agc_temp_init(struct brcms_phy *pi) { s16 temp; - phytbl_info_t tab; + struct phytbl_info tab; u32 tableBuffer[2]; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; if (NORADIO_ENAB(pi->pubpi)) return; @@ -4517,7 +4509,7 @@ static void wlc_lcnphy_agc_temp_init(phy_info_t *pi) } -static void WLBANDINITFN(wlc_lcnphy_bu_tweaks) (phy_info_t *pi) +static void wlc_lcnphy_bu_tweaks(struct brcms_phy *pi) { if (NORADIO_ENAB(pi->pubpi)) return; @@ -4572,7 +4564,7 @@ static void WLBANDINITFN(wlc_lcnphy_bu_tweaks) (phy_info_t *pi) } } -static void WLBANDINITFN(wlc_lcnphy_baseband_init) (phy_info_t *pi) +static void wlc_lcnphy_baseband_init(struct brcms_phy *pi) { wlc_lcnphy_tbl_init(pi); @@ -4582,10 +4574,10 @@ static void WLBANDINITFN(wlc_lcnphy_baseband_init) (phy_info_t *pi) wlc_lcnphy_bu_tweaks(pi); } -static void WLBANDINITFN(wlc_radio_2064_init) (phy_info_t *pi) +static void wlc_radio_2064_init(struct brcms_phy *pi) { u32 i; - lcnphy_radio_regs_t *lcnphyregs = NULL; + struct lcnphy_radio_regs *lcnphyregs = NULL; lcnphyregs = lcnphy_radio_regs_2064; @@ -4643,7 +4635,7 @@ static void WLBANDINITFN(wlc_radio_2064_init) (phy_info_t *pi) wlc_lcnphy_rc_cal(pi); } -static void WLBANDINITFN(wlc_lcnphy_radio_init) (phy_info_t *pi) +static void wlc_lcnphy_radio_init(struct brcms_phy *pi) { if (NORADIO_ENAB(pi->pubpi)) return; @@ -4651,7 +4643,7 @@ static void WLBANDINITFN(wlc_lcnphy_radio_init) (phy_info_t *pi) wlc_radio_2064_init(pi); } -static void wlc_lcnphy_rcal(phy_info_t *pi) +static void wlc_lcnphy_rcal(struct brcms_phy *pi) { u8 rcal_value; @@ -4682,7 +4674,7 @@ static void wlc_lcnphy_rcal(phy_info_t *pi) and_radio_reg(pi, RADIO_2064_REG057, 0xFE); } -static void wlc_lcnphy_rc_cal(phy_info_t *pi) +static void wlc_lcnphy_rc_cal(struct brcms_phy *pi) { u8 dflt_rc_cal_val; u16 flt_val; @@ -4705,11 +4697,11 @@ static void wlc_lcnphy_rc_cal(phy_info_t *pi) return; } -static bool wlc_phy_txpwr_srom_read_lcnphy(phy_info_t *pi) +static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) { s8 txpwr = 0; int i; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; if (CHSPEC_IS2G(pi->radio_chanspec)) { u16 cckpo = 0; @@ -4811,7 +4803,7 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(phy_info_t *pi) pi_lcn->lcnphy_freqoffset_corr = (u8) PHY_GETINTVAR(pi, "freqoffset_corr"); if ((u8) getintvar(pi->vars, "aa2g") > 1) - wlc_phy_ant_rxdiv_set((wlc_phy_t *) pi, + wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi, (u8) getintvar(pi->vars, "aa2g")); } @@ -4827,7 +4819,7 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(phy_info_t *pi) return true; } -void wlc_2064_vco_cal(phy_info_t *pi) +void wlc_2064_vco_cal(struct brcms_phy *pi) { u8 calnrst; @@ -4843,10 +4835,10 @@ void wlc_2064_vco_cal(phy_info_t *pi) } static void -wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi, u8 channel) +wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel) { uint i; - const chan_info_2064_lcnphy_t *ci; + const struct chan_info_2064_lcnphy *ci; u8 rfpll_doubler = 0; u8 pll_pwrup, pll_pwrup_ovr; fixed qFxtal, qFref, qFvco, qFcal; @@ -5008,7 +5000,7 @@ wlc_lcnphy_radio_2064_channel_tune_4313(phy_info_t *pi, u8 channel) } } -bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi) +bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi) { if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) return 0; @@ -5017,7 +5009,7 @@ bool wlc_phy_tpc_isenabled_lcnphy(phy_info_t *pi) wlc_lcnphy_get_tx_pwr_ctrl((pi))); } -void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi) +void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi) { u16 pwr_ctrl; if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { @@ -5033,16 +5025,16 @@ void wlc_phy_txpower_recalc_target_lcnphy(phy_info_t *pi) return; } -void wlc_phy_detach_lcnphy(phy_info_t *pi) +void wlc_phy_detach_lcnphy(struct brcms_phy *pi) { kfree(pi->u.pi_lcnphy); } -bool wlc_phy_attach_lcnphy(phy_info_t *pi) +bool wlc_phy_attach_lcnphy(struct brcms_phy *pi) { - phy_info_lcnphy_t *pi_lcn; + struct brcms_phy_lcnphy *pi_lcn; - pi->u.pi_lcnphy = kzalloc(sizeof(phy_info_lcnphy_t), GFP_ATOMIC); + pi->u.pi_lcnphy = kzalloc(sizeof(struct brcms_phy_lcnphy), GFP_ATOMIC); if (pi->u.pi_lcnphy == NULL) { return false; } @@ -5085,7 +5077,7 @@ bool wlc_phy_attach_lcnphy(phy_info_t *pi) return true; } -static void wlc_lcnphy_set_rx_gain(phy_info_t *pi, u32 gain) +static void wlc_lcnphy_set_rx_gain(struct brcms_phy *pi, u32 gain) { u16 trsw, ext_lna, lna1, lna2, tia, biq0, biq1, gain0_15, gain16_19; @@ -5115,12 +5107,12 @@ static void wlc_lcnphy_set_rx_gain(phy_info_t *pi, u32 gain) wlc_lcnphy_rx_gain_override_enable(pi, true); } -static u32 wlc_lcnphy_get_receive_power(phy_info_t *pi, s32 *gain_index) +static u32 wlc_lcnphy_get_receive_power(struct brcms_phy *pi, s32 *gain_index) { u32 received_power = 0; s32 max_index = 0; u32 gain_code = 0; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; max_index = 36; if (*gain_index >= 0) @@ -5151,7 +5143,7 @@ static u32 wlc_lcnphy_get_receive_power(phy_info_t *pi, s32 *gain_index) return received_power; } -s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index) +s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index) { s32 gain = 0; s32 nominal_power_db; @@ -5159,7 +5151,7 @@ s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index) input_power_db; s32 received_power, temperature; uint freq; - phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; received_power = wlc_lcnphy_get_receive_power(pi, &gain_index); @@ -5223,7 +5215,7 @@ s32 wlc_lcnphy_rx_signal_power(phy_info_t *pi, s32 gain_index) } static int -wlc_lcnphy_load_tx_iir_filter(phy_info_t *pi, bool is_ofdm, s16 filt_type) +wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type) { s16 filt_index = -1; int j; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.h similarity index 94% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h rename to drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.h index b7bfc7230dfc..f4a8ab09da43 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.h @@ -14,10 +14,12 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_phy_lcn_h_ -#define _wlc_phy_lcn_h_ +#ifndef _BRCM_PHY_LCN_H_ +#define _BRCM_PHY_LCN_H_ -struct phy_info_lcnphy { +#include + +struct brcms_phy_lcnphy { int lcnphy_txrf_sp_9_override; u8 lcnphy_full_cal_channel; u8 lcnphy_cal_counter; @@ -98,7 +100,7 @@ struct phy_info_lcnphy { u16 lcnphy_extstxctrl1; s16 lcnphy_cck_dig_filt_type; s16 lcnphy_ofdm_dig_filt_type; - lcnphy_cal_results_t lcnphy_cal_results; + struct lcnphy_cal_results lcnphy_cal_results; u8 lcnphy_psat_pwr; u8 lcnphy_psat_indx; @@ -116,4 +118,4 @@ struct phy_info_lcnphy { uint lcnphy_aci_start_time; s8 lcnphy_tx_power_offset[TXP_NUM_RATES]; }; -#endif /* _wlc_phy_lcn_h_ */ +#endif /* _BRCM_PHY_LCN_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_n.c similarity index 97% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c rename to drivers/staging/brcm80211/brcmsmac/phy/phy_n.c index 71275094e810..f8e419239425 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_n.c @@ -14,23 +14,19 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include -#include #include -#include + +#include #include -#include -#include - -#include -#include - -#include -#include -#include -#include +#include +#include +#include +#include +#include "phy_int.h" +#include "phy_hal.h" +#include "phy_radio.h" +#include "phyreg_n.h" +#include "phytbl_n.h" #define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \ read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ @@ -141,7 +137,11 @@ #define NPHY_ADJUSTED_MINCRSPOWER 0x1e -typedef struct _nphy_iqcal_params { +/* 5357 Chip specific ChipControl register bits */ +#define CCTRL5357_EXTPA (1<<14) /* extPA in ChipControl 1, bit 14 */ +#define CCTRL5357_ANT_MUX_2o3 (1<<15) /* 2o3 in ChipControl 1, bit 15 */ + +struct nphy_iqcal_params { u16 txlpf; u16 txgm; u16 pga; @@ -149,20 +149,20 @@ typedef struct _nphy_iqcal_params { u16 ipa; u16 cal_gain; u16 ncorr[5]; -} nphy_iqcal_params_t; +}; -typedef struct _nphy_txiqcal_ladder { +struct nphy_txiqcal_ladder { u8 percent; u8 g_env; -} nphy_txiqcal_ladder_t; +}; -typedef struct { - nphy_txgains_t gains; +struct nphy_ipa_txcalgains { + struct nphy_txgains gains; bool useindex; u8 index; -} nphy_ipa_txcalgains_t; +}; -typedef struct nphy_papd_restore_state_t { +struct nphy_papd_restore_state { u16 fbmix[2]; u16 vga_master[2]; u16 intpa_master[2]; @@ -171,20 +171,20 @@ typedef struct nphy_papd_restore_state_t { u16 pwrup[2]; u16 atten[2]; u16 mm; -} nphy_papd_restore_state; +}; -typedef struct _nphy_ipa_txrxgain { +struct nphy_ipa_txrxgain { u16 hpvga; u16 lpf_biq1; u16 lpf_biq0; u16 lna2; u16 lna1; s8 txpwrindex; -} nphy_ipa_txrxgain_t; +}; #define NPHY_IPA_RXCAL_MAXGAININDEX (6 - 1) -nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz[] = { {0, 0, 0, 0, 0, 100}, +struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz[] = { {0, 0, 0, 0, 0, 100}, {0, 0, 0, 0, 0, 50}, {0, 0, 0, 0, 0, -1}, {0, 0, 0, 3, 0, -1}, @@ -192,7 +192,7 @@ nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz[] = { {0, 0, 0, 0, 0, 100}, {0, 2, 3, 3, 0, -1} }; -nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz[] = { {0, 0, 0, 0, 0, 128}, +struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz[] = { {0, 0, 0, 0, 0, 128}, {0, 0, 0, 0, 0, 70}, {0, 0, 0, 0, 0, 20}, {0, 0, 0, 3, 0, 20}, @@ -200,7 +200,8 @@ nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz[] = { {0, 0, 0, 0, 0, 128}, {0, 2, 3, 3, 0, 20} }; -nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = { {0, 0, 0, 0, 0, 100}, +struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = { +{0, 0, 0, 0, 0, 100}, {0, 0, 0, 0, 0, 50}, {0, 0, 0, 0, 0, -1}, {0, 0, 0, 3, 0, -1}, @@ -208,7 +209,8 @@ nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = { {0, 0, 0, 0, 0, 100}, {0, 0, 5, 3, 0, -1} }; -nphy_ipa_txrxgain_t nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = { {0, 0, 0, 0, 0, 10}, +struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = { +{0, 0, 0, 0, 0, 10}, {0, 0, 0, 1, 0, 10}, {0, 0, 1, 2, 0, 10}, {0, 0, 1, 3, 0, 10}, @@ -255,7 +257,7 @@ u16 NPHY_IPA_REV4_txdigi_filtcoeffs[][NPHY_NUM_DIG_FILT_COEFFS] = { 0x97, 0x12d, 0x97, 0x25a, 0xd10, 0x25a} }; -typedef struct _chan_info_nphy_2055 { +struct chan_info_nphy_2055 { u16 chan; u16 freq; uint unknown; @@ -287,9 +289,9 @@ typedef struct _chan_info_nphy_2055 { u16 PHY_BW4; u16 PHY_BW5; u16 PHY_BW6; -} chan_info_nphy_2055_t; +}; -typedef struct _chan_info_nphy_radio205x { +struct chan_info_nphy_radio205x { u16 chan; u16 freq; u8 RF_SYN_pll_vcocal1; @@ -335,9 +337,9 @@ typedef struct _chan_info_nphy_radio205x { u16 PHY_BW4; u16 PHY_BW5; u16 PHY_BW6; -} chan_info_nphy_radio205x_t; +}; -typedef struct _chan_info_nphy_radio2057 { +struct chan_info_nphy_radio2057 { u16 chan; u16 freq; u8 RF_vcocal_countval0; @@ -374,9 +376,9 @@ typedef struct _chan_info_nphy_radio2057 { u16 PHY_BW4; u16 PHY_BW5; u16 PHY_BW6; -} chan_info_nphy_radio2057_t; +}; -typedef struct _chan_info_nphy_radio2057_rev5 { +struct chan_info_nphy_radio2057_rev5 { u16 chan; u16 freq; u8 RF_vcocal_countval0; @@ -403,18 +405,18 @@ typedef struct _chan_info_nphy_radio2057_rev5 { u16 PHY_BW4; u16 PHY_BW5; u16 PHY_BW6; -} chan_info_nphy_radio2057_rev5_t; +}; -typedef struct nphy_sfo_cfg { +struct nphy_sfo_cfg { u16 PHY_BW1a; u16 PHY_BW2; u16 PHY_BW3; u16 PHY_BW4; u16 PHY_BW5; u16 PHY_BW6; -} nphy_sfo_cfg_t; +}; -static chan_info_nphy_2055_t chan_info_nphy_2055[] = { +static struct chan_info_nphy_2055 chan_info_nphy_2055[] = { { 184, 4920, 3280, 0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A, 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, 0x8F, 0xFF, 0x00, 0x0F, @@ -913,7 +915,7 @@ static chan_info_nphy_2055_t chan_info_nphy_2055[] = { 0x01, 0x80, 0x3E6, 0x3E2, 0x3DE, 0x41B, 0x41F, 0x424} }; -static chan_info_nphy_radio205x_t chan_info_nphyrev3_2056[] = { +static struct chan_info_nphy_radio205x chan_info_nphyrev3_2056[] = { { 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x7f, @@ -1536,7 +1538,7 @@ static chan_info_nphy_radio205x_t chan_info_nphyrev3_2056[] = { 0x0f, 0x00, 0x0d, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} }; -static chan_info_nphy_radio205x_t chan_info_nphyrev4_2056_A1[] = { +static struct chan_info_nphy_radio205x chan_info_nphyrev4_2056_A1[] = { { 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0e, 0x00, 0x7f, @@ -2159,7 +2161,7 @@ static chan_info_nphy_radio205x_t chan_info_nphyrev4_2056_A1[] = { 0x0f, 0x00, 0x0e, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} }; -static chan_info_nphy_radio205x_t chan_info_nphyrev5_2056v5[] = { +static struct chan_info_nphy_radio205x chan_info_nphyrev5_2056v5[] = { { 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, @@ -2782,7 +2784,7 @@ static chan_info_nphy_radio205x_t chan_info_nphyrev5_2056v5[] = { 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} }; -static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v6[] = { +static struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v6[] = { { 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, @@ -3405,7 +3407,7 @@ static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v6[] = { 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} }; -static chan_info_nphy_radio205x_t chan_info_nphyrev5n6_2056v7[] = { +static struct chan_info_nphy_radio205x chan_info_nphyrev5n6_2056v7[] = { { 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x00, 0x70, @@ -4028,7 +4030,7 @@ static chan_info_nphy_radio205x_t chan_info_nphyrev5n6_2056v7[] = { 0x0d, 0x00, 0x08, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} }; -static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v8[] = { +static struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v8[] = { { 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x04, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, @@ -4651,7 +4653,7 @@ static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v8[] = { 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} }; -static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v11[] = { +static struct chan_info_nphy_radio205x chan_info_nphyrev6_2056v11[] = { { 184, 4920, 0xff, 0x01, 0x01, 0x01, 0xec, 0x05, 0x05, 0x02, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x8f, 0x0f, 0x00, 0xff, 0xfe, 0x00, 0x09, 0x00, 0x77, @@ -5274,7 +5276,7 @@ static chan_info_nphy_radio205x_t chan_info_nphyrev6_2056v11[] = { 0x09, 0x00, 0x09, 0x03e6, 0x03e2, 0x03de, 0x041b, 0x041f, 0x0424} }; -static chan_info_nphy_radio2057_t chan_info_nphyrev7_2057_rev4[] = { +static struct chan_info_nphy_radio2057 chan_info_nphyrev7_2057_rev4[] = { { 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0xf3, 0x00, 0xef, 0x00, @@ -6137,7 +6139,7 @@ static chan_info_nphy_radio2057_t chan_info_nphyrev7_2057_rev4[] = { 0x0424} }; -static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev8_2057_rev5[] = { +static struct chan_info_nphy_radio2057_rev5 chan_info_nphyrev8_2057_rev5[] = { { 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1, @@ -6196,7 +6198,7 @@ static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev8_2057_rev5[] = { 0x041b, 0x041f, 0x0424} }; -static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev9_2057_rev5v1[] = { +static struct chan_info_nphy_radio2057_rev5 chan_info_nphyrev9_2057_rev5v1[] = { { 1, 2412, 0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 0x09, 0x0d, 0x08, 0x0e, 0x61, 0x03, 0xff, 0x61, 0x03, 0xff, 0x03c9, 0x03c5, 0x03c1, @@ -6255,7 +6257,7 @@ static chan_info_nphy_radio2057_rev5_t chan_info_nphyrev9_2057_rev5v1[] = { 0x041b, 0x041f, 0x0424} }; -static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev7[] = { +static struct chan_info_nphy_radio2057 chan_info_nphyrev8_2057_rev7[] = { { 184, 4920, 0x68, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xec, 0x01, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, @@ -6996,7 +6998,7 @@ static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev7[] = { 0x0424} }; -static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev8[] = { +static struct chan_info_nphy_radio2057 chan_info_nphyrev8_2057_rev8[] = { { 186, 4930, 0x6b, 0x16, 0x10, 0x0c, 0x0c, 0x0c, 0x30, 0xed, 0x01, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0x00, 0xd3, 0x0f, 0x0f, 0xd3, 0x00, 0xff, 0x00, @@ -7731,7 +7733,7 @@ static chan_info_nphy_radio2057_t chan_info_nphyrev8_2057_rev8[] = { 0x0424} }; -radio_regs_t regs_2055[] = { +struct radio_regs regs_2055[] = { {0x02, 0x80, 0x80, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0x27, 0x27, 0, 0}, @@ -7960,7 +7962,7 @@ radio_regs_t regs_2055[] = { {0xFFFF, 0, 0, 0, 0}, }; -radio_regs_t regs_SYN_2056[] = { +struct radio_regs regs_SYN_2056[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -8145,7 +8147,7 @@ radio_regs_t regs_SYN_2056[] = { {0xFFFF, 0, 0, 0, 0} }; -radio_regs_t regs_TX_2056[] = { +struct radio_regs regs_TX_2056[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -8294,7 +8296,7 @@ radio_regs_t regs_TX_2056[] = { {0xFFFF, 0, 0, 0, 0} }; -radio_regs_t regs_RX_2056[] = { +struct radio_regs regs_RX_2056[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -8445,7 +8447,7 @@ radio_regs_t regs_RX_2056[] = { {0xFFFF, 0, 0, 0, 0} }; -radio_regs_t regs_SYN_2056_A1[] = { +struct radio_regs regs_SYN_2056_A1[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -8630,7 +8632,7 @@ radio_regs_t regs_SYN_2056_A1[] = { {0xFFFF, 0, 0, 0, 0} }; -radio_regs_t regs_TX_2056_A1[] = { +struct radio_regs regs_TX_2056_A1[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -8779,7 +8781,7 @@ radio_regs_t regs_TX_2056_A1[] = { {0xFFFF, 0, 0, 0, 0} }; -radio_regs_t regs_RX_2056_A1[] = { +struct radio_regs regs_RX_2056_A1[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -8930,7 +8932,7 @@ radio_regs_t regs_RX_2056_A1[] = { {0xFFFF, 0, 0, 0, 0} }; -radio_regs_t regs_SYN_2056_rev5[] = { +struct radio_regs regs_SYN_2056_rev5[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -9115,7 +9117,7 @@ radio_regs_t regs_SYN_2056_rev5[] = { {0xFFFF, 0, 0, 0, 0} }; -radio_regs_t regs_TX_2056_rev5[] = { +struct radio_regs regs_TX_2056_rev5[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -9272,7 +9274,7 @@ radio_regs_t regs_TX_2056_rev5[] = { {0xFFFF, 0, 0, 0, 0} }; -radio_regs_t regs_RX_2056_rev5[] = { +struct radio_regs regs_RX_2056_rev5[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -9423,7 +9425,7 @@ radio_regs_t regs_RX_2056_rev5[] = { {0xFFFF, 0, 0, 0, 0} }; -radio_regs_t regs_SYN_2056_rev6[] = { +struct radio_regs regs_SYN_2056_rev6[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -9608,7 +9610,7 @@ radio_regs_t regs_SYN_2056_rev6[] = { {0xFFFF, 0, 0, 0, 0} }; -radio_regs_t regs_TX_2056_rev6[] = { +struct radio_regs regs_TX_2056_rev6[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -9765,7 +9767,7 @@ radio_regs_t regs_TX_2056_rev6[] = { {0xFFFF, 0, 0, 0, 0} }; -radio_regs_t regs_RX_2056_rev6[] = { +struct radio_regs regs_RX_2056_rev6[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -9916,7 +9918,7 @@ radio_regs_t regs_RX_2056_rev6[] = { {0xFFFF, 0, 0, 0, 0} }; -radio_regs_t regs_SYN_2056_rev7[] = { +struct radio_regs regs_SYN_2056_rev7[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -10101,7 +10103,7 @@ radio_regs_t regs_SYN_2056_rev7[] = { {0xFFFF, 0, 0, 0, 0}, }; -radio_regs_t regs_TX_2056_rev7[] = { +struct radio_regs regs_TX_2056_rev7[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -10258,7 +10260,7 @@ radio_regs_t regs_TX_2056_rev7[] = { {0xFFFF, 0, 0, 0, 0}, }; -radio_regs_t regs_RX_2056_rev7[] = { +struct radio_regs regs_RX_2056_rev7[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -10409,7 +10411,7 @@ radio_regs_t regs_RX_2056_rev7[] = { {0xFFFF, 0, 0, 0, 0}, }; -radio_regs_t regs_SYN_2056_rev8[] = { +struct radio_regs regs_SYN_2056_rev8[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -10594,7 +10596,7 @@ radio_regs_t regs_SYN_2056_rev8[] = { {0xFFFF, 0, 0, 0, 0}, }; -radio_regs_t regs_TX_2056_rev8[] = { +struct radio_regs regs_TX_2056_rev8[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -10751,7 +10753,7 @@ radio_regs_t regs_TX_2056_rev8[] = { {0xFFFF, 0, 0, 0, 0}, }; -radio_regs_t regs_RX_2056_rev8[] = { +struct radio_regs regs_RX_2056_rev8[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -10902,7 +10904,7 @@ radio_regs_t regs_RX_2056_rev8[] = { {0xFFFF, 0, 0, 0, 0}, }; -radio_regs_t regs_SYN_2056_rev11[] = { +struct radio_regs regs_SYN_2056_rev11[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -11087,7 +11089,7 @@ radio_regs_t regs_SYN_2056_rev11[] = { {0xFFFF, 0, 0, 0, 0}, }; -radio_regs_t regs_TX_2056_rev11[] = { +struct radio_regs regs_TX_2056_rev11[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -11244,7 +11246,7 @@ radio_regs_t regs_TX_2056_rev11[] = { {0xFFFF, 0, 0, 0, 0}, }; -radio_regs_t regs_RX_2056_rev11[] = { +struct radio_regs regs_RX_2056_rev11[] = { {0x02, 0, 0, 0, 0}, {0x03, 0, 0, 0, 0}, {0x04, 0, 0, 0, 0}, @@ -11395,7 +11397,7 @@ radio_regs_t regs_RX_2056_rev11[] = { {0xFFFF, 0, 0, 0, 0}, }; -radio_20xx_regs_t regs_2057_rev4[] = { +struct radio_20xx_regs regs_2057_rev4[] = { {0x00, 0x84, 0}, {0x01, 0, 0}, {0x02, 0x60, 0}, @@ -11785,7 +11787,7 @@ radio_20xx_regs_t regs_2057_rev4[] = { {0xFFFF, 0, 0}, }; -radio_20xx_regs_t regs_2057_rev5[] = { +struct radio_20xx_regs regs_2057_rev5[] = { {0x00, 0, 1}, {0x01, 0x57, 1}, {0x02, 0x20, 1}, @@ -12117,7 +12119,7 @@ radio_20xx_regs_t regs_2057_rev5[] = { {0xFFFF, 0, 0} }; -radio_20xx_regs_t regs_2057_rev5v1[] = { +struct radio_20xx_regs regs_2057_rev5v1[] = { {0x00, 0x15, 1}, {0x01, 0x57, 1}, {0x02, 0x20, 1}, @@ -12449,7 +12451,7 @@ radio_20xx_regs_t regs_2057_rev5v1[] = { {0xFFFF, 0, 0} }; -radio_20xx_regs_t regs_2057_rev7[] = { +struct radio_20xx_regs regs_2057_rev7[] = { {0x00, 0, 1}, {0x01, 0x57, 1}, {0x02, 0x20, 1}, @@ -12865,7 +12867,7 @@ radio_20xx_regs_t regs_2057_rev7[] = { {0xFFFF, 0, 0} }; -radio_20xx_regs_t regs_2057_rev8[] = { +struct radio_20xx_regs regs_2057_rev8[] = { {0x00, 0x8, 1}, {0x01, 0x57, 1}, {0x02, 0x20, 1}, @@ -14083,118 +14085,118 @@ static u8 ant_sw_ctrl_tbl_rev8_2057v7_core0[] = { static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = { 0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16 }; -static bool wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f, - chan_info_nphy_radio2057_t **t0, - chan_info_nphy_radio205x_t **t1, - chan_info_nphy_radio2057_rev5_t **t2, - chan_info_nphy_2055_t **t3); -static void wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chans, - const nphy_sfo_cfg_t *c); +static bool wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f, + struct chan_info_nphy_radio2057 **t0, + struct chan_info_nphy_radio205x **t1, + struct chan_info_nphy_radio2057_rev5 **t2, + struct chan_info_nphy_2055 **t3); +static void wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, chanspec_t chans, + const struct nphy_sfo_cfg *c); -static void wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi, +static void wlc_phy_adjust_rx_analpfbw_nphy(struct brcms_phy *pi, u16 reduction_factr); -static void wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *, - u32 *buf); -static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, u8 minpwr); -static void wlc_phy_txlpfbw_nphy(phy_info_t *pi); -static void wlc_phy_spurwar_nphy(phy_info_t *pi); +static void wlc_phy_adjust_min_noisevar_nphy(struct brcms_phy *pi, + int ntones, int *, u32 *buf); +static void wlc_phy_adjust_crsminpwr_nphy(struct brcms_phy *pi, u8 minpwr); +static void wlc_phy_txlpfbw_nphy(struct brcms_phy *pi); +static void wlc_phy_spurwar_nphy(struct brcms_phy *pi); -static void wlc_phy_radio_preinit_2055(phy_info_t *pi); -static void wlc_phy_radio_init_2055(phy_info_t *pi); -static void wlc_phy_radio_postinit_2055(phy_info_t *pi); -static void wlc_phy_radio_preinit_205x(phy_info_t *pi); -static void wlc_phy_radio_init_2056(phy_info_t *pi); -static void wlc_phy_radio_postinit_2056(phy_info_t *pi); -static void wlc_phy_radio_init_2057(phy_info_t *pi); -static void wlc_phy_radio_postinit_2057(phy_info_t *pi); -static void wlc_phy_workarounds_nphy(phy_info_t *pi); -static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi); -static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi); -static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi); -static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi); +static void wlc_phy_radio_preinit_2055(struct brcms_phy *pi); +static void wlc_phy_radio_init_2055(struct brcms_phy *pi); +static void wlc_phy_radio_postinit_2055(struct brcms_phy *pi); +static void wlc_phy_radio_preinit_205x(struct brcms_phy *pi); +static void wlc_phy_radio_init_2056(struct brcms_phy *pi); +static void wlc_phy_radio_postinit_2056(struct brcms_phy *pi); +static void wlc_phy_radio_init_2057(struct brcms_phy *pi); +static void wlc_phy_radio_postinit_2057(struct brcms_phy *pi); +static void wlc_phy_workarounds_nphy(struct brcms_phy *pi); +static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi); +static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi); +static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi); +static void wlc_phy_adjust_lnagaintbl_nphy(struct brcms_phy *pi); -static void wlc_phy_restore_rssical_nphy(phy_info_t *pi); -static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi); -static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi); -static int wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t tg, - u8 type, bool d); -static void wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rxcore, +static void wlc_phy_restore_rssical_nphy(struct brcms_phy *pi); +static void wlc_phy_reapply_txcal_coeffs_nphy(struct brcms_phy *pi); +static void wlc_phy_tx_iq_war_nphy(struct brcms_phy *pi); +static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi, + struct nphy_txgains tg, u8 type, bool d); +static void wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rxcore, u16 *rg, u8 type); -static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, s32 preamble); -static void wlc_phy_savecal_nphy(phy_info_t *pi); -static void wlc_phy_restorecal_nphy(phy_info_t *pi); -static void wlc_phy_resetcca_nphy(phy_info_t *pi); +static void wlc_phy_update_mimoconfig_nphy(struct brcms_phy *pi, s32 preamble); +static void wlc_phy_savecal_nphy(struct brcms_phy *pi); +static void wlc_phy_restorecal_nphy(struct brcms_phy *pi); +static void wlc_phy_resetcca_nphy(struct brcms_phy *pi); -static void wlc_phy_txpwrctrl_config_nphy(phy_info_t *pi); -static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi); -static void wlc_phy_precal_txgain_nphy(phy_info_t *pi); -static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, u16 core); +static void wlc_phy_txpwrctrl_config_nphy(struct brcms_phy *pi); +static void wlc_phy_internal_cal_txgain_nphy(struct brcms_phy *pi); +static void wlc_phy_precal_txgain_nphy(struct brcms_phy *pi); +static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core); -static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi); -static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi); -static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi); -static u16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi); -static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, u8 m0, u8 m1); -static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi); +static void wlc_phy_extpa_set_tx_digi_filts_nphy(struct brcms_phy *pi); +static void wlc_phy_ipa_set_tx_digi_filts_nphy(struct brcms_phy *pi); +static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi); +static u16 wlc_phy_ipa_get_bbmult_nphy(struct brcms_phy *pi); +static void wlc_phy_ipa_set_bbmult_nphy(struct brcms_phy *pi, u8 m0, u8 m1); +static u32 *wlc_phy_get_ipa_gaintbl_nphy(struct brcms_phy *pi); -static void wlc_phy_a1_nphy(phy_info_t *pi, u8 core, u32 winsz, u32, +static void wlc_phy_a1_nphy(struct brcms_phy *pi, u8 core, u32 winsz, u32, u32 e); -static u8 wlc_phy_a3_nphy(phy_info_t *pi, u8 start_gain, u8 core); -static void wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *, - phy_cal_mode_t, u8); -static void wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi, - nphy_papd_restore_state *state); -static void wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, - nphy_papd_restore_state *state, u8); +static u8 wlc_phy_a3_nphy(struct brcms_phy *pi, u8 start_gain, u8 core); +static void wlc_phy_a2_nphy(struct brcms_phy *pi, struct nphy_ipa_txcalgains *, + enum phy_cal_mode, u8); +static void wlc_phy_papd_cal_cleanup_nphy(struct brcms_phy *pi, + struct nphy_papd_restore_state *state); +static void wlc_phy_papd_cal_setup_nphy(struct brcms_phy *pi, + struct nphy_papd_restore_state *state, u8); -static void wlc_phy_clip_det_nphy(phy_info_t *pi, u8 write, u16 *vals); +static void wlc_phy_clip_det_nphy(struct brcms_phy *pi, u8 write, u16 *vals); -static void wlc_phy_set_rfseq_nphy(phy_info_t *pi, u8 cmd, u8 *evts, +static void wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *evts, u8 *dlys, u8 len); -static u16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, u16 offset); +static u16 wlc_phy_read_lpf_bw_ctl_nphy(struct brcms_phy *pi, u16 offset); static void -wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, u16 field, u16 value, +wlc_phy_rfctrl_override_nphy_rev7(struct brcms_phy *pi, u16 field, u16 value, u8 core_mask, u8 off, u8 override_id); -static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, u8 rssi_type); -static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi); +static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type); +static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi); -static bool wlc_phy_txpwr_srom_read_nphy(phy_info_t *pi); +static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi); static void wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, u16 *pwr_offset, u8 tmp_max_pwr, u8 rate_start, u8 rate_end); -static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi); -static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi); -static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi); -static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi); +static void wlc_phy_txpwr_limit_to_tbl_nphy(struct brcms_phy *pi); +static void wlc_phy_txpwrctrl_coeff_setup_nphy(struct brcms_phy *pi); +static void wlc_phy_txpwrctrl_idle_tssi_nphy(struct brcms_phy *pi); +static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi); -static bool wlc_phy_txpwr_ison_nphy(phy_info_t *pi); -static u8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, u8 core); -static void wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, u8 idx0, +static bool wlc_phy_txpwr_ison_nphy(struct brcms_phy *pi); +static u8 wlc_phy_txpwr_idx_cur_get_nphy(struct brcms_phy *pi, u8 core); +static void wlc_phy_txpwr_idx_cur_set_nphy(struct brcms_phy *pi, u8 idx0, u8 idx1); -static void wlc_phy_a4(phy_info_t *pi, bool full_cal); +static void wlc_phy_a4(struct brcms_phy *pi, bool full_cal); -static u16 wlc_phy_radio205x_rcal(phy_info_t *pi); +static u16 wlc_phy_radio205x_rcal(struct brcms_phy *pi); -static u16 wlc_phy_radio2057_rccal(phy_info_t *pi); +static u16 wlc_phy_radio2057_rccal(struct brcms_phy *pi); -static u16 wlc_phy_gen_load_samples_nphy(phy_info_t *pi, u32 f_kHz, +static u16 wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, u8 dac_test_mode); -static void wlc_phy_loadsampletable_nphy(phy_info_t *pi, cs32 *tone_buf, +static void wlc_phy_loadsampletable_nphy(struct brcms_phy *pi, cs32 *tone_buf, u16 num_samps); -static void wlc_phy_runsamples_nphy(phy_info_t *pi, u16 n, u16 lps, +static void wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 n, u16 lps, u16 wait, u8 iq, u8 dac_test_mode, bool modify_bbmult); -bool wlc_phy_bist_check_phy(wlc_phy_t *pih) +bool wlc_phy_bist_check_phy(struct brcms_phy_pub *pih) { - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; u32 phybist0, phybist1, phybist2, phybist3, phybist4; if (NREV_GE(pi->pubpi.phy_rev, 16)) @@ -14214,7 +14216,7 @@ bool wlc_phy_bist_check_phy(wlc_phy_t *pih) return false; } -static void WLBANDINITFN(wlc_phy_bphy_init_nphy) (phy_info_t *pi) +static void wlc_phy_bphy_init_nphy(struct brcms_phy *pi) { u16 addr, val; @@ -14243,10 +14245,10 @@ static void WLBANDINITFN(wlc_phy_bphy_init_nphy) (phy_info_t *pi) } void -wlc_phy_table_write_nphy(phy_info_t *pi, u32 id, u32 len, u32 offset, +wlc_phy_table_write_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset, u32 width, const void *data) { - mimophytbl_info_t tbl; + struct phytbl_info tbl; tbl.tbl_id = id; tbl.tbl_len = len; @@ -14257,10 +14259,10 @@ wlc_phy_table_write_nphy(phy_info_t *pi, u32 id, u32 len, u32 offset, } void -wlc_phy_table_read_nphy(phy_info_t *pi, u32 id, u32 len, u32 offset, +wlc_phy_table_read_nphy(struct brcms_phy *pi, u32 id, u32 len, u32 offset, u32 width, void *data) { - mimophytbl_info_t tbl; + struct phytbl_info tbl; tbl.tbl_id = id; tbl.tbl_len = len; @@ -14270,7 +14272,8 @@ wlc_phy_table_read_nphy(phy_info_t *pi, u32 id, u32 len, u32 offset, wlc_phy_read_table_nphy(pi, &tbl); } -static void WLBANDINITFN(wlc_phy_static_table_download_nphy) (phy_info_t *pi) +static void +wlc_phy_static_table_download_nphy(struct brcms_phy *pi) { uint idx; @@ -14293,7 +14296,7 @@ static void WLBANDINITFN(wlc_phy_static_table_download_nphy) (phy_info_t *pi) } } -static void WLBANDINITFN(wlc_phy_tbl_init_nphy) (phy_info_t *pi) +static void wlc_phy_tbl_init_nphy(struct brcms_phy *pi) { uint idx = 0; u8 antswctrllut; @@ -14415,13 +14418,13 @@ static void WLBANDINITFN(wlc_phy_tbl_init_nphy) (phy_info_t *pi) } static void -wlc_phy_write_txmacreg_nphy(phy_info_t *pi, u16 holdoff, u16 delay) +wlc_phy_write_txmacreg_nphy(struct brcms_phy *pi, u16 holdoff, u16 delay) { write_phy_reg(pi, 0x77, holdoff); write_phy_reg(pi, 0xb4, delay); } -void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, u8 rifs) +void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs) { u16 holdoff, delay; @@ -14442,7 +14445,7 @@ void wlc_phy_nphy_tkip_rifs_war(phy_info_t *pi, u8 rifs) } } -bool wlc_phy_attach_nphy(phy_info_t *pi) +bool wlc_phy_attach_nphy(struct brcms_phy *pi) { uint i; @@ -14467,7 +14470,7 @@ bool wlc_phy_attach_nphy(phy_info_t *pi) pi->n_preamble_override = AUTO; if (NREV_IS(pi->pubpi.phy_rev, 3) || NREV_IS(pi->pubpi.phy_rev, 4)) - pi->n_preamble_override = WLC_N_PREAMBLE_MIXEDMODE; + pi->n_preamble_override = BRCMS_N_PREAMBLE_MIXEDMODE; pi->nphy_txrx_chain = AUTO; pi->phy_scraminit = AUTO; @@ -14501,7 +14504,7 @@ bool wlc_phy_attach_nphy(phy_info_t *pi) return true; } -static void wlc_phy_txpwrctrl_config_nphy(phy_info_t *pi) +static void wlc_phy_txpwrctrl_config_nphy(struct brcms_phy *pi) { if (NREV_GE(pi->pubpi.phy_rev, 3)) { @@ -14521,11 +14524,11 @@ static void wlc_phy_txpwrctrl_config_nphy(phy_info_t *pi) pi->phy_5g_pwrgain = true; } -void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) +void wlc_phy_init_nphy(struct brcms_phy *pi) { u16 val; u16 clip1_ths[2]; - nphy_txgains_t target_gain; + struct nphy_txgains target_gain; u8 tx_pwr_ctrl_state; bool do_nphy_cal = false; uint core; @@ -14550,11 +14553,6 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) } } - if ((!PHY_IPA(pi)) && (pi->sh->chip == BCM5357_CHIP_ID)) { - si_pmu_chipcontrol(pi->sh->sih, 1, CCTRL5357_EXTPA, - CCTRL5357_EXTPA); - } - if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) && CHSPEC_IS40(pi->radio_chanspec)) { @@ -14707,12 +14705,10 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi); } else { if (CHSPEC_IS5G(pi->radio_chanspec)) { - if NREV_IS - (pi->pubpi.phy_rev, 3) { + if (NREV_IS(pi->pubpi.phy_rev, 3)) { tx_pwrctrl_tbl = nphy_tpc_5GHz_txgain_rev3; - } else if NREV_IS - (pi->pubpi.phy_rev, 4) { + } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { tx_pwrctrl_tbl = (pi->srom_fem5g.extpagain == 3) ? nphy_tpc_5GHz_txgain_HiPwrEPA : @@ -14834,7 +14830,7 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) } if (pi->sh->phyrxchain != 0x3) { - wlc_phy_rxcore_setstate_nphy((wlc_phy_t *) pi, + wlc_phy_rxcore_setstate_nphy((struct brcms_phy_pub *) pi, pi->sh->phyrxchain); } @@ -14873,7 +14869,8 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) target_gain = wlc_phy_get_tx_gain_nphy(pi); if (pi->antsel_type == ANTSEL_2x3) - wlc_phy_antsel_init((wlc_phy_t *) pi, true); + wlc_phy_antsel_init((struct brcms_phy_pub *) pi, + true); if (pi->nphy_perical != PHY_PERICAL_MPHASE) { wlc_phy_rssi_cal_nphy(pi); @@ -14903,7 +14900,7 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) } else if (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) { - wlc_phy_cal_perical((wlc_phy_t *) pi, + wlc_phy_cal_perical((struct brcms_phy_pub *) pi, PHY_PERICAL_PHYINIT); } } else { @@ -14927,14 +14924,13 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) } -static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, s32 preamble) +static void wlc_phy_update_mimoconfig_nphy(struct brcms_phy *pi, s32 preamble) { bool gf_preamble = false; u16 val; - if (preamble == WLC_N_PREAMBLE_GF) { + if (preamble == BRCMS_N_PREAMBLE_GF) gf_preamble = true; - } val = read_phy_reg(pi, 0xed); @@ -14946,7 +14942,7 @@ static void wlc_phy_update_mimoconfig_nphy(phy_info_t *pi, s32 preamble) write_phy_reg(pi, 0xed, val); } -static void wlc_phy_resetcca_nphy(phy_info_t *pi) +static void wlc_phy_resetcca_nphy(struct brcms_phy *pi) { u16 val; @@ -14962,7 +14958,7 @@ static void wlc_phy_resetcca_nphy(phy_info_t *pi) wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); } -void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en) +void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en) { u16 rfctrlintc_override_val; @@ -14991,21 +14987,21 @@ void wlc_phy_pa_override_nphy(phy_info_t *pi, bool en) } -void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi) +void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi) { u16 txrx_chain = (NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1); bool CoreActv_override = false; - if (pi->nphy_txrx_chain == WLC_N_TXRX_CHAIN0) { + if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN0) { txrx_chain = NPHY_RfseqCoreActv_TxRxChain0; CoreActv_override = true; if (NREV_LE(pi->pubpi.phy_rev, 2)) { and_phy_reg(pi, 0xa0, ~0x20); } - } else if (pi->nphy_txrx_chain == WLC_N_TXRX_CHAIN1) { + } else if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN1) { txrx_chain = NPHY_RfseqCoreActv_TxRxChain1; CoreActv_override = true; @@ -15026,12 +15022,12 @@ void wlc_phy_stf_chain_upd_nphy(phy_info_t *pi) } } -void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask) +void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask) { u16 regval; u16 tbl_buf[16]; uint i; - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; u16 tbl_opcode; bool suspend; @@ -15107,10 +15103,10 @@ void wlc_phy_rxcore_setstate_nphy(wlc_phy_t *pih, u8 rxcore_bitmask) wlapi_enable_mac(pi->sh->physhim); } -u8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih) +u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih) { u16 regval, rxen_bits; - phy_info_t *pi = (phy_info_t *) pih; + struct brcms_phy *pi = (struct brcms_phy *) pih; regval = read_phy_reg(pi, 0xa2); rxen_bits = (regval >> 4) & 0xf; @@ -15118,12 +15114,12 @@ u8 wlc_phy_rxcore_getstate_nphy(wlc_phy_t *pih) return (u8) rxen_bits; } -bool wlc_phy_n_txpower_ipa_ison(phy_info_t *pi) +bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pi) { return PHY_IPA(pi); } -static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi) +static void wlc_phy_txpwr_limit_to_tbl_nphy(struct brcms_phy *pi) { u8 idx, idx2, i, delta_ind; @@ -15217,11 +15213,12 @@ static void wlc_phy_txpwr_limit_to_tbl_nphy(phy_info_t *pi) } } -void wlc_phy_cal_init_nphy(phy_info_t *pi) +void wlc_phy_cal_init_nphy(struct brcms_phy *pi) { } -static void wlc_phy_war_force_trsw_to_R_cliplo_nphy(phy_info_t *pi, u8 core) +static void +wlc_phy_war_force_trsw_to_R_cliplo_nphy(struct brcms_phy *pi, u8 core) { if (core == PHY_CORE_0) { write_phy_reg(pi, 0x38, 0x4); @@ -15240,7 +15237,7 @@ static void wlc_phy_war_force_trsw_to_R_cliplo_nphy(phy_info_t *pi, u8 core) } } -static void wlc_phy_war_txchain_upd_nphy(phy_info_t *pi, u8 txchain) +static void wlc_phy_war_txchain_upd_nphy(struct brcms_phy *pi, u8 txchain) { u8 txchain0, txchain1; @@ -15255,7 +15252,7 @@ static void wlc_phy_war_txchain_upd_nphy(phy_info_t *pi, u8 txchain) } } -static void wlc_phy_workarounds_nphy(phy_info_t *pi) +static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) { u8 rfseq_rx2tx_events[] = { NPHY_RFSEQ_CMD_NOP, @@ -15374,9 +15371,7 @@ static void wlc_phy_workarounds_nphy(phy_info_t *pi) if (pi->phyhang_avoid) wlc_phy_stay_in_carriersearch_nphy(pi, true); - if (!ISSIM_ENAB(pi->sh->sih)) { - or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2); - } + or_phy_reg(pi, 0xb1, NPHY_IQFlip_ADC1 | NPHY_IQFlip_ADC2); if (NREV_GE(pi->pubpi.phy_rev, 7)) { @@ -16219,8 +16214,8 @@ static void wlc_phy_workarounds_nphy(phy_info_t *pi) if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK) { wlapi_bmac_mhf(pi->sh->physhim, MHF4, - MHF4_BPHY_TXCORE0, - MHF4_BPHY_TXCORE0, WLC_BAND_ALL); + MHF4_BPHY_TXCORE0, + MHF4_BPHY_TXCORE0, BRCM_BAND_ALL); } } } else { @@ -16288,7 +16283,7 @@ static void wlc_phy_workarounds_nphy(phy_info_t *pi) wlapi_bmac_mhf(pi->sh->physhim, MHF3, MHF3_NPHY_MLADV_WAR, MHF3_NPHY_MLADV_WAR, - WLC_BAND_ALL); + BRCM_BAND_ALL); } else if (NREV_IS(pi->pubpi.phy_rev, 2)) { write_phy_reg(pi, 0x1e3, 0x0); @@ -16330,7 +16325,7 @@ static void wlc_phy_workarounds_nphy(phy_info_t *pi) wlc_phy_stay_in_carriersearch_nphy(pi, false); } -static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi) +static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) { u16 w1th, hpf_code, currband; int ctr; @@ -16950,7 +16945,7 @@ static void wlc_phy_workarounds_nphy_gainctrl(phy_info_t *pi) } } -static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi) +static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi) { s8 lna1_gain_db[] = { 8, 13, 17, 22 }; s8 lna2_gain_db[] = { -2, 7, 11, 15 }; @@ -17005,7 +17000,7 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(phy_info_t *pi) } } -static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi) +static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) { u16 currband; s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; @@ -17211,7 +17206,7 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(phy_info_t *pi) } -static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi) +static void wlc_phy_adjust_lnagaintbl_nphy(struct brcms_phy *pi) { uint core; int ctr; @@ -17274,7 +17269,7 @@ static void wlc_phy_adjust_lnagaintbl_nphy(phy_info_t *pi) wlc_phy_stay_in_carriersearch_nphy(pi, false); } -void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on) +void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on) { if (on) { if (NREV_GE(pi->pubpi.phy_rev, 7)) { @@ -17284,14 +17279,14 @@ void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on) wlc_phy_radio_postinit_2057(pi); } - wlc_phy_chanspec_set((wlc_phy_t *) pi, + wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec); } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { wlc_phy_radio_preinit_205x(pi); wlc_phy_radio_init_2056(pi); wlc_phy_radio_postinit_2056(pi); - wlc_phy_chanspec_set((wlc_phy_t *) pi, + wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec); } else { wlc_phy_radio_preinit_2055(pi); @@ -17357,7 +17352,7 @@ void wlc_phy_switch_radio_nphy(phy_info_t *pi, bool on) } } -static void wlc_phy_radio_preinit_2055(phy_info_t *pi) +static void wlc_phy_radio_preinit_2055(struct brcms_phy *pi) { and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE); @@ -17366,12 +17361,12 @@ static void wlc_phy_radio_preinit_2055(phy_info_t *pi) or_phy_reg(pi, 0x78, RFCC_POR_FORCE); } -static void wlc_phy_radio_init_2055(phy_info_t *pi) +static void wlc_phy_radio_init_2055(struct brcms_phy *pi) { wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE); } -static void wlc_phy_radio_postinit_2055(phy_info_t *pi) +static void wlc_phy_radio_postinit_2055(struct brcms_phy *pi) { and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, @@ -17409,7 +17404,7 @@ static void wlc_phy_radio_postinit_2055(phy_info_t *pi) and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, ~(RADIO_2055_CAL_LPO_ENABLE)); - wlc_phy_chanspec_set((wlc_phy_t *) pi, pi->radio_chanspec); + wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec); write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9); write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9); @@ -17436,7 +17431,7 @@ static void wlc_phy_radio_postinit_2055(phy_info_t *pi) udelay(2); } -static void wlc_phy_radio_preinit_205x(phy_info_t *pi) +static void wlc_phy_radio_preinit_205x(struct brcms_phy *pi) { and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU); @@ -17447,11 +17442,11 @@ static void wlc_phy_radio_preinit_205x(phy_info_t *pi) } -static void wlc_phy_radio_init_2056(phy_info_t *pi) +static void wlc_phy_radio_init_2056(struct brcms_phy *pi) { - radio_regs_t *regs_SYN_2056_ptr = NULL; - radio_regs_t *regs_TX_2056_ptr = NULL; - radio_regs_t *regs_RX_2056_ptr = NULL; + struct radio_regs *regs_SYN_2056_ptr = NULL; + struct radio_regs *regs_TX_2056_ptr = NULL; + struct radio_regs *regs_RX_2056_ptr = NULL; if (NREV_IS(pi->pubpi.phy_rev, 3)) { regs_SYN_2056_ptr = regs_SYN_2056; @@ -17510,7 +17505,7 @@ static void wlc_phy_radio_init_2056(phy_info_t *pi) wlc_phy_init_radio_regs(pi, regs_RX_2056_ptr, (u16) RADIO_2056_RX1); } -static void wlc_phy_radio_postinit_2056(phy_info_t *pi) +static void wlc_phy_radio_postinit_2056(struct brcms_phy *pi) { mod_radio_reg(pi, RADIO_2056_SYN_COM_CTRL, 0xb, 0xb); @@ -17535,9 +17530,9 @@ static void wlc_phy_radio_postinit_2056(phy_info_t *pi) } } -static void wlc_phy_radio_init_2057(phy_info_t *pi) +static void wlc_phy_radio_init_2057(struct brcms_phy *pi) { - radio_20xx_regs_t *regs_2057_ptr = NULL; + struct radio_20xx_regs *regs_2057_ptr = NULL; if (NREV_IS(pi->pubpi.phy_rev, 7)) { @@ -17576,16 +17571,11 @@ static void wlc_phy_radio_init_2057(phy_info_t *pi) wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr); } -static void wlc_phy_radio_postinit_2057(phy_info_t *pi) +static void wlc_phy_radio_postinit_2057(struct brcms_phy *pi) { mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1); - if (pi->sh->chip == !BCM6362_CHIP_ID) { - - mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x2, 0x2); - } - mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78); mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80); mdelay(2); @@ -17601,16 +17591,16 @@ static void wlc_phy_radio_postinit_2057(phy_info_t *pi) } static bool -wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f, - chan_info_nphy_radio2057_t **t0, - chan_info_nphy_radio205x_t **t1, - chan_info_nphy_radio2057_rev5_t **t2, - chan_info_nphy_2055_t **t3) +wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f, + struct chan_info_nphy_radio2057 **t0, + struct chan_info_nphy_radio205x **t1, + struct chan_info_nphy_radio2057_rev5 **t2, + struct chan_info_nphy_2055 **t3) { uint i; - chan_info_nphy_radio2057_t *chan_info_tbl_p_0 = NULL; - chan_info_nphy_radio205x_t *chan_info_tbl_p_1 = NULL; - chan_info_nphy_radio2057_rev5_t *chan_info_tbl_p_2 = NULL; + struct chan_info_nphy_radio2057 *chan_info_tbl_p_0 = NULL; + struct chan_info_nphy_radio205x *chan_info_tbl_p_1 = NULL; + struct chan_info_nphy_radio2057_rev5 *chan_info_tbl_p_2 = NULL; u32 tbl_len = 0; int freq = 0; @@ -17769,13 +17759,13 @@ wlc_phy_chan2freq_nphy(phy_info_t *pi, uint channel, int *f, return false; } -u8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint channel) +u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint channel) { int freq; - chan_info_nphy_radio2057_t *t0 = NULL; - chan_info_nphy_radio205x_t *t1 = NULL; - chan_info_nphy_radio2057_rev5_t *t2 = NULL; - chan_info_nphy_2055_t *t3 = NULL; + struct chan_info_nphy_radio2057 *t0 = NULL; + struct chan_info_nphy_radio205x *t1 = NULL; + struct chan_info_nphy_radio2057_rev5 *t2 = NULL; + struct chan_info_nphy_2055 *t3 = NULL; if (NORADIO_ENAB(pi->pubpi)) return WL_CHAN_FREQ_RANGE_2G; @@ -17798,7 +17788,8 @@ u8 wlc_phy_get_chan_freq_range_nphy(phy_info_t *pi, uint channel) } static void -wlc_phy_chanspec_radio2055_setup(phy_info_t *pi, chan_info_nphy_2055_t *ci) +wlc_phy_chanspec_radio2055_setup(struct brcms_phy *pi, + struct chan_info_nphy_2055 *ci) { write_radio_reg(pi, RADIO_2055_PLL_REF, ci->RF_pll_ref); @@ -17806,21 +17797,21 @@ wlc_phy_chanspec_radio2055_setup(phy_info_t *pi, chan_info_nphy_2055_t *ci) write_radio_reg(pi, RADIO_2055_RF_PLL_MOD1, ci->RF_rf_pll_mod1); write_radio_reg(pi, RADIO_2055_VCO_CAP_TAIL, ci->RF_vco_cap_tail); - WLC_PHY_WAR_PR51571(pi); + BRCMS_PHY_WAR_PR51571(pi); write_radio_reg(pi, RADIO_2055_VCO_CAL1, ci->RF_vco_cal1); write_radio_reg(pi, RADIO_2055_VCO_CAL2, ci->RF_vco_cal2); write_radio_reg(pi, RADIO_2055_PLL_LF_C1, ci->RF_pll_lf_c1); write_radio_reg(pi, RADIO_2055_PLL_LF_R1, ci->RF_pll_lf_r1); - WLC_PHY_WAR_PR51571(pi); + BRCMS_PHY_WAR_PR51571(pi); write_radio_reg(pi, RADIO_2055_PLL_LF_C2, ci->RF_pll_lf_c2); write_radio_reg(pi, RADIO_2055_LGBUF_CEN_BUF, ci->RF_lgbuf_cen_buf); write_radio_reg(pi, RADIO_2055_LGEN_TUNE1, ci->RF_lgen_tune1); write_radio_reg(pi, RADIO_2055_LGEN_TUNE2, ci->RF_lgen_tune2); - WLC_PHY_WAR_PR51571(pi); + BRCMS_PHY_WAR_PR51571(pi); write_radio_reg(pi, RADIO_2055_CORE1_LGBUF_A_TUNE, ci->RF_core1_lgbuf_a_tune); @@ -17830,7 +17821,7 @@ wlc_phy_chanspec_radio2055_setup(phy_info_t *pi, chan_info_nphy_2055_t *ci) write_radio_reg(pi, RADIO_2055_CORE1_TX_PGA_PAD_TN, ci->RF_core1_tx_pga_pad_tn); - WLC_PHY_WAR_PR51571(pi); + BRCMS_PHY_WAR_PR51571(pi); write_radio_reg(pi, RADIO_2055_CORE1_TX_MX_BGTRIM, ci->RF_core1_tx_mx_bgtrim); @@ -17840,7 +17831,7 @@ wlc_phy_chanspec_radio2055_setup(phy_info_t *pi, chan_info_nphy_2055_t *ci) ci->RF_core2_lgbuf_g_tune); write_radio_reg(pi, RADIO_2055_CORE2_RXRF_REG1, ci->RF_core2_rxrf_reg1); - WLC_PHY_WAR_PR51571(pi); + BRCMS_PHY_WAR_PR51571(pi); write_radio_reg(pi, RADIO_2055_CORE2_TX_PGA_PAD_TN, ci->RF_core2_tx_pga_pad_tn); @@ -17852,7 +17843,7 @@ wlc_phy_chanspec_radio2055_setup(phy_info_t *pi, chan_info_nphy_2055_t *ci) write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x05); write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x45); - WLC_PHY_WAR_PR51571(pi); + BRCMS_PHY_WAR_PR51571(pi); write_radio_reg(pi, RADIO_2055_VCO_CAL10, 0x65); @@ -17860,10 +17851,10 @@ wlc_phy_chanspec_radio2055_setup(phy_info_t *pi, chan_info_nphy_2055_t *ci) } static void -wlc_phy_chanspec_radio2056_setup(phy_info_t *pi, - const chan_info_nphy_radio205x_t *ci) +wlc_phy_chanspec_radio2056_setup(struct brcms_phy *pi, + const struct chan_info_nphy_radio205x *ci) { - radio_regs_t *regs_SYN_2056_ptr = NULL; + struct radio_regs *regs_SYN_2056_ptr = NULL; write_radio_reg(pi, RADIO_2056_SYN_PLL_VCOCAL1 | RADIO_2056_SYN, @@ -17986,23 +17977,12 @@ wlc_phy_chanspec_radio2056_setup(phy_info_t *pi, write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN, 0x1f); - if ((pi->sh->chip == BCM4716_CHIP_ID) || - (pi->sh->chip == BCM47162_CHIP_ID)) { - - write_radio_reg(pi, - RADIO_2056_SYN_PLL_LOOPFILTER4 | - RADIO_2056_SYN, 0x14); - write_radio_reg(pi, - RADIO_2056_SYN_PLL_CP2 | - RADIO_2056_SYN, 0x00); - } else { - write_radio_reg(pi, - RADIO_2056_SYN_PLL_LOOPFILTER4 | - RADIO_2056_SYN, 0xb); - write_radio_reg(pi, - RADIO_2056_SYN_PLL_CP2 | - RADIO_2056_SYN, 0x14); - } + write_radio_reg(pi, + RADIO_2056_SYN_PLL_LOOPFILTER4 | + RADIO_2056_SYN, 0xb); + write_radio_reg(pi, + RADIO_2056_SYN_PLL_CP2 | + RADIO_2056_SYN, 0x14); } } @@ -18049,38 +18029,25 @@ wlc_phy_chanspec_radio2056_setup(phy_info_t *pi, WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, PADG_IDAC, 0xcc); - if ((pi->sh->chip == BCM4716_CHIP_ID) || - (pi->sh->chip == - BCM47162_CHIP_ID)) { - bias = 0x40; - cascbias = 0x45; - pag_boost_tune = 0x5; - pgag_boost_tune = 0x33; - padg_boost_tune = 0x77; - mixg_boost_tune = 0x55; - } else { - bias = 0x25; - cascbias = 0x20; + bias = 0x25; + cascbias = 0x20; - if ((pi->sh->chip == - BCM43224_CHIP_ID) - || (pi->sh->chip == - BCM43225_CHIP_ID) - || (pi->sh->chip == - BCM43421_CHIP_ID)) { - if (pi->sh->chippkg == - BCM43224_FAB_SMIC) { - bias = 0x2a; - cascbias = 0x38; - } + if ((pi->sh->chip == + BCM43224_CHIP_ID) + || (pi->sh->chip == + BCM43225_CHIP_ID)) { + if (pi->sh->chippkg == + BCM43224_FAB_SMIC) { + bias = 0x2a; + cascbias = 0x38; } - - pag_boost_tune = 0x4; - pgag_boost_tune = 0x03; - padg_boost_tune = 0x77; - mixg_boost_tune = 0x65; } + pag_boost_tune = 0x4; + pgag_boost_tune = 0x03; + padg_boost_tune = 0x77; + mixg_boost_tune = 0x65; + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, INTPAG_IMAIN_STAT, bias); WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, @@ -18178,8 +18145,7 @@ wlc_phy_chanspec_radio2056_setup(phy_info_t *pi, cascbias = 0x30; if ((pi->sh->chip == BCM43224_CHIP_ID) || - (pi->sh->chip == BCM43225_CHIP_ID) || - (pi->sh->chip == BCM43421_CHIP_ID)) { + (pi->sh->chip == BCM43225_CHIP_ID)) { if (pi->sh->chippkg == BCM43224_FAB_SMIC) { cascbias = 0x35; } @@ -18201,7 +18167,7 @@ wlc_phy_chanspec_radio2056_setup(phy_info_t *pi, wlc_phy_radio205x_vcocal_nphy(pi); } -void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi) +void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi) { if (NREV_GE(pi->pubpi.phy_rev, 7)) { mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_EN, 0x01, 0x0); @@ -18222,7 +18188,7 @@ void wlc_phy_radio205x_vcocal_nphy(phy_info_t *pi) #define MAX_205x_RCAL_WAITLOOPS 10000 -static u16 wlc_phy_radio205x_rcal(phy_info_t *pi) +static u16 wlc_phy_radio205x_rcal(struct brcms_phy *pi) { u16 rcal_reg = 0; int i; @@ -18328,9 +18294,9 @@ static u16 wlc_phy_radio205x_rcal(phy_info_t *pi) } static void -wlc_phy_chanspec_radio2057_setup(phy_info_t *pi, - const chan_info_nphy_radio2057_t *ci, - const chan_info_nphy_radio2057_rev5_t *ci2) +wlc_phy_chanspec_radio2057_setup(struct brcms_phy *pi, + const struct chan_info_nphy_radio2057 *ci, + const struct chan_info_nphy_radio2057_rev5 *ci2) { int coreNum; u16 txmix2g_tune_boost_pu = 0; @@ -18523,7 +18489,7 @@ wlc_phy_chanspec_radio2057_setup(phy_info_t *pi, wlc_phy_radio205x_vcocal_nphy(pi); } -static u16 wlc_phy_radio2057_rccal(phy_info_t *pi) +static u16 wlc_phy_radio2057_rccal(struct brcms_phy *pi) { u16 rccal_valid; int i; @@ -18607,7 +18573,7 @@ static u16 wlc_phy_radio2057_rccal(phy_info_t *pi) } static void -wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi, u16 reduction_factr) +wlc_phy_adjust_rx_analpfbw_nphy(struct brcms_phy *pi, u16 reduction_factr) { if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) && @@ -18635,8 +18601,8 @@ wlc_phy_adjust_rx_analpfbw_nphy(phy_info_t *pi, u16 reduction_factr) } static void -wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *tone_id_buf, - u32 *noise_var_buf) +wlc_phy_adjust_min_noisevar_nphy(struct brcms_phy *pi, int ntones, + int *tone_id_buf, u32 *noise_var_buf) { int i; u32 offset; @@ -18684,7 +18650,7 @@ wlc_phy_adjust_min_noisevar_nphy(phy_info_t *pi, int ntones, int *tone_id_buf, } } -static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, u8 minpwr) +static void wlc_phy_adjust_crsminpwr_nphy(struct brcms_phy *pi, u8 minpwr) { u16 regval; @@ -18735,7 +18701,7 @@ static void wlc_phy_adjust_crsminpwr_nphy(phy_info_t *pi, u8 minpwr) } } -static void wlc_phy_txlpfbw_nphy(phy_info_t *pi) +static void wlc_phy_txlpfbw_nphy(struct brcms_phy *pi) { u8 tx_lpf_bw = 0; @@ -18774,7 +18740,7 @@ static void wlc_phy_txlpfbw_nphy(phy_info_t *pi) } } -static void wlc_phy_spurwar_nphy(phy_info_t *pi) +static void wlc_phy_spurwar_nphy(struct brcms_phy *pi) { u16 cur_channel = 0; int nphy_adj_tone_id_buf[] = { 57, 58 }; @@ -18907,14 +18873,8 @@ static void wlc_phy_spurwar_nphy(phy_info_t *pi) case 38: case 102: case 118: - if ((pi->sh->chip == BCM4716_CHIP_ID) && - (pi->sh->chippkg == BCM4717_PKG_ID)) { - nphy_adj_tone_id_buf[0] = 32; - nphy_adj_noise_var_buf[0] = 0x21f; - } else { - nphy_adj_tone_id_buf[0] = 0; - nphy_adj_noise_var_buf[0] = 0x0; - } + nphy_adj_tone_id_buf[0] = 0; + nphy_adj_noise_var_buf[0] = 0x0; break; case 134: nphy_adj_tone_id_buf[0] = 32; @@ -18952,8 +18912,8 @@ static void wlc_phy_spurwar_nphy(phy_info_t *pi) } static void -wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, - const nphy_sfo_cfg_t *ci) +wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, chanspec_t chanspec, + const struct nphy_sfo_cfg *ci) { u16 val; @@ -19041,34 +19001,20 @@ wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, if (pi->nphy_aband_spurwar_en && ((val == 38) || (val == 102) - || (val == 118))) { - if ((pi->sh->chip == - BCM4716_CHIP_ID) - && (pi->sh->chippkg == - BCM4717_PKG_ID)) { - spuravoid = 0; - } else { - spuravoid = 1; - } - } + || (val == 118))) + spuravoid = 1; } } if (pi->phy_spuravoid == SPURAVOID_FORCEON) spuravoid = 1; - if ((pi->sh->chip == BCM4716_CHIP_ID) || - (pi->sh->chip == BCM47162_CHIP_ID)) { - si_pmu_spuravoid(pi->sh->sih, spuravoid); - } else { - wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false); - si_pmu_spuravoid(pi->sh->sih, spuravoid); - wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true); - } + wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false); + si_pmu_spuravoid(pi->sh->sih, spuravoid); + wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true); if ((pi->sh->chip == BCM43224_CHIP_ID) || - (pi->sh->chip == BCM43225_CHIP_ID) || - (pi->sh->chip == BCM43421_CHIP_ID)) { + (pi->sh->chip == BCM43225_CHIP_ID)) { if (spuravoid == 1) { @@ -19085,10 +19031,7 @@ wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, } } - if (!((pi->sh->chip == BCM4716_CHIP_ID) || - (pi->sh->chip == BCM47162_CHIP_ID))) { - wlapi_bmac_core_phypll_reset(pi->sh->physhim); - } + wlapi_bmac_core_phypll_reset(pi->sh->physhim); mod_phy_reg(pi, 0x01, (0x1 << 15), ((spuravoid > 0) ? (0x1 << 15) : 0)); @@ -19104,13 +19047,13 @@ wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, wlc_phy_spurwar_nphy(pi); } -void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec) +void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, chanspec_t chanspec) { int freq; - chan_info_nphy_radio2057_t *t0 = NULL; - chan_info_nphy_radio205x_t *t1 = NULL; - chan_info_nphy_radio2057_rev5_t *t2 = NULL; - chan_info_nphy_2055_t *t3 = NULL; + struct chan_info_nphy_radio2057 *t0 = NULL; + struct chan_info_nphy_radio205x *t1 = NULL; + struct chan_info_nphy_radio2057_rev5 *t2 = NULL; + struct chan_info_nphy_2055 *t3 = NULL; if (NORADIO_ENAB(pi->pubpi)) { return; @@ -19120,7 +19063,7 @@ void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec) (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3)) return; - wlc_phy_chanspec_radio_set((wlc_phy_t *) pi, chanspec); + wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec); if (CHSPEC_BW(chanspec) != pi->bw) wlapi_bmac_bw_set(pi->sh->physhim, CHSPEC_BW(chanspec)); @@ -19157,12 +19100,9 @@ void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec) wlc_phy_chanspec_radio2057_setup(pi, t0, t2); wlc_phy_chanspec_nphy_setup(pi, chanspec, - (pi->pubpi.radiorev == - 5) ? (const nphy_sfo_cfg_t - *)&(t2-> - PHY_BW1a) - : (const nphy_sfo_cfg_t *) - &(t0->PHY_BW1a)); + (pi->pubpi.radiorev == 5) ? + (const struct nphy_sfo_cfg *)&(t2->PHY_BW1a) : + (const struct nphy_sfo_cfg *)&(t0->PHY_BW1a)); } else { @@ -19173,8 +19113,7 @@ void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec) wlc_phy_chanspec_radio2056_setup(pi, t1); wlc_phy_chanspec_nphy_setup(pi, chanspec, - (const nphy_sfo_cfg_t *) - &(t1->PHY_BW1a)); + (const struct nphy_sfo_cfg *) &(t1->PHY_BW1a)); } } else { @@ -19185,13 +19124,13 @@ void wlc_phy_chanspec_set_nphy(phy_info_t *pi, chanspec_t chanspec) wlc_phy_chanspec_radio2055_setup(pi, t3); wlc_phy_chanspec_nphy_setup(pi, chanspec, - (const nphy_sfo_cfg_t *)&(t3-> + (const struct nphy_sfo_cfg *)&(t3-> PHY_BW1a)); } } -static void wlc_phy_savecal_nphy(phy_info_t *pi) +static void wlc_phy_savecal_nphy(struct brcms_phy *pi) { void *tbl_ptr; int coreNum; @@ -19340,7 +19279,7 @@ static void wlc_phy_savecal_nphy(phy_info_t *pi) wlc_phy_stay_in_carriersearch_nphy(pi, false); } -static void wlc_phy_restorecal_nphy(phy_info_t *pi) +static void wlc_phy_restorecal_nphy(struct brcms_phy *pi) { u16 *loft_comp; u16 txcal_coeffs_bphy[4]; @@ -19539,9 +19478,9 @@ static void wlc_phy_restorecal_nphy(phy_info_t *pi) } } -void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init) +void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init) { - phy_info_t *pi = (phy_info_t *) ppi; + struct brcms_phy *pi = (struct brcms_phy *) ppi; u16 mask = 0xfc00; u32 mc = 0; @@ -19599,7 +19538,7 @@ void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init) } } -u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val) +u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val) { u16 curr_ctl, new_ctl; bool suspended = false; @@ -19624,7 +19563,7 @@ u16 wlc_phy_classifier_nphy(phy_info_t *pi, u16 mask, u16 val) return new_ctl; } -static void wlc_phy_clip_det_nphy(phy_info_t *pi, u8 write, u16 *vals) +static void wlc_phy_clip_det_nphy(struct brcms_phy *pi, u8 write, u16 *vals) { if (write == 0) { @@ -19636,7 +19575,7 @@ static void wlc_phy_clip_det_nphy(phy_info_t *pi, u8 write, u16 *vals) } } -void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd) +void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd) { u16 trigger_mask, status_mask; u16 orig_RfseqCoreActv; @@ -19681,7 +19620,7 @@ void wlc_phy_force_rfseq_nphy(phy_info_t *pi, u8 cmd) } static void -wlc_phy_set_rfseq_nphy(phy_info_t *pi, u8 cmd, u8 *events, u8 *dlys, +wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys, u8 len) { u32 t1_offset, t2_offset; @@ -19712,7 +19651,7 @@ wlc_phy_set_rfseq_nphy(phy_info_t *pi, u8 cmd, u8 *events, u8 *dlys, wlc_phy_stay_in_carriersearch_nphy(pi, false); } -static u16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, u16 offset) +static u16 wlc_phy_read_lpf_bw_ctl_nphy(struct brcms_phy *pi, u16 offset) { u16 lpf_bw_ctl_val = 0; u16 rx2tx_lpf_rc_lut_offset = 0; @@ -19736,7 +19675,7 @@ static u16 wlc_phy_read_lpf_bw_ctl_nphy(phy_info_t *pi, u16 offset) } static void -wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, u16 field, u16 value, +wlc_phy_rfctrl_override_nphy_rev7(struct brcms_phy *pi, u16 field, u16 value, u8 core_mask, u8 off, u8 override_id) { u8 core_num; @@ -20006,7 +19945,7 @@ wlc_phy_rfctrl_override_nphy_rev7(phy_info_t *pi, u16 field, u16 value, } static void -wlc_phy_rfctrl_override_nphy(phy_info_t *pi, u16 field, u16 value, +wlc_phy_rfctrl_override_nphy(struct brcms_phy *pi, u16 field, u16 value, u8 core_mask, u8 off) { u8 core_num; @@ -20252,7 +20191,7 @@ wlc_phy_rfctrl_override_nphy(phy_info_t *pi, u16 field, u16 value, } static void -wlc_phy_rfctrl_override_1tomany_nphy(phy_info_t *pi, u16 cmd, u16 value, +wlc_phy_rfctrl_override_1tomany_nphy(struct brcms_phy *pi, u16 cmd, u16 value, u8 core_mask, u8 off) { u16 rfmxgain = 0, lpfgain = 0; @@ -20338,7 +20277,7 @@ wlc_phy_rfctrl_override_1tomany_nphy(phy_info_t *pi, u16 cmd, u16 value, } static void -wlc_phy_scale_offset_rssi_nphy(phy_info_t *pi, u16 scale, s8 offset, +wlc_phy_scale_offset_rssi_nphy(struct brcms_phy *pi, u16 scale, s8 offset, u8 coresel, u8 rail, u8 rssi_type) { u16 valuetostuff; @@ -20478,7 +20417,7 @@ wlc_phy_scale_offset_rssi_nphy(phy_info_t *pi, u16 scale, s8 offset, } } -void wlc_phy_rssisel_nphy(phy_info_t *pi, u8 core_code, u8 rssi_type) +void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type) { u16 mask, val; u16 afectrlovr_rssi_val, rfctrlcmd_rxen_val, rfctrlcmd_coresel_val, @@ -20782,7 +20721,7 @@ void wlc_phy_rssisel_nphy(phy_info_t *pi, u8 core_code, u8 rssi_type) } int -wlc_phy_poll_rssi_nphy(phy_info_t *pi, u8 rssi_type, s32 *rssi_buf, +wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, s32 *rssi_buf, u8 nsamps) { s16 rssi0, rssi1; @@ -20881,7 +20820,7 @@ wlc_phy_poll_rssi_nphy(phy_info_t *pi, u8 rssi_type, s32 *rssi_buf, return rssi_out_val; } -s16 wlc_phy_tempsense_nphy(phy_info_t *pi) +s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi) { u16 core1_txrf_iqcal1_save, core1_txrf_iqcal2_save; u16 core2_txrf_iqcal1_save, core2_txrf_iqcal2_save; @@ -21035,19 +20974,9 @@ s16 wlc_phy_tempsense_nphy(phy_info_t *pi) wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16, &auxADC_rssi_ctrlH_save); - if (pi->sh->chip == BCM5357_CHIP_ID) { - radio_temp[0] = (193 * (radio_temp[1] + radio_temp2[1]) - + 88 * (auxADC_Vl) - 27111 + - 128) / 256; - } else if (pi->sh->chip == BCM43236_CHIP_ID) { - radio_temp[0] = (198 * (radio_temp[1] + radio_temp2[1]) - + 91 * (auxADC_Vl) - 27243 + - 128) / 256; - } else { - radio_temp[0] = (179 * (radio_temp[1] + radio_temp2[1]) - + 82 * (auxADC_Vl) - 28861 + - 128) / 256; - } + radio_temp[0] = (179 * (radio_temp[1] + radio_temp2[1]) + + 82 * (auxADC_Vl) - 28861 + + 128) / 256; offset = (s16) pi->phy_tempsense_offset; @@ -21064,10 +20993,8 @@ s16 wlc_phy_tempsense_nphy(phy_info_t *pi) write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01); wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp, 1); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - } else { + if (NREV_LT(pi->pubpi.phy_rev, 7)) write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x05); - } wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1); if (NREV_GE(pi->pubpi.phy_rev, 7)) { @@ -21165,7 +21092,7 @@ s16 wlc_phy_tempsense_nphy(phy_info_t *pi) } static void -wlc_phy_set_rssi_2055_vcm(phy_info_t *pi, u8 rssi_type, u8 *vcm_buf) +wlc_phy_set_rssi_2055_vcm(struct brcms_phy *pi, u8 rssi_type, u8 *vcm_buf) { u8 core; @@ -21219,7 +21146,7 @@ wlc_phy_set_rssi_2055_vcm(phy_info_t *pi, u8 rssi_type, u8 *vcm_buf) } } -void wlc_phy_rssi_cal_nphy(phy_info_t *pi) +void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi) { if (NREV_GE(pi->pubpi.phy_rev, 3)) { @@ -21231,7 +21158,7 @@ void wlc_phy_rssi_cal_nphy(phy_info_t *pi) } } -static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, u8 rssi_type) +static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type) { s32 target_code; u16 classif_state; @@ -21439,9 +21366,9 @@ static void wlc_phy_rssi_cal_nphy_rev2(phy_info_t *pi, u8 rssi_type) } int -wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh) +wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, struct brcms_d11rxhdr *wlc_rxh) { - d11rxhdr_t *rxh = &wlc_rxh->rxhdr; + struct d11rxhdr *rxh = &wlc_rxh->rxhdr; s16 rxpwr, rxpwr0, rxpwr1; s16 phyRx0_l, phyRx2_l; @@ -21479,7 +21406,7 @@ wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh) } static void -wlc_phy_rfctrlintc_override_nphy(phy_info_t *pi, u8 field, u16 value, +wlc_phy_rfctrlintc_override_nphy(struct brcms_phy *pi, u8 field, u16 value, u8 core_code) { u16 mask; @@ -21714,7 +21641,7 @@ wlc_phy_rfctrlintc_override_nphy(phy_info_t *pi, u8 field, u16 value, } } -static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi) +static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi) { u16 classif_state; u16 clip_state[2]; @@ -21853,7 +21780,8 @@ static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi) } } - rxcore_state = wlc_phy_rxcore_getstate_nphy((wlc_phy_t *) pi); + rxcore_state = wlc_phy_rxcore_getstate_nphy( + (struct brcms_phy_pub *) pi); vcm_level_max = 8; @@ -22201,7 +22129,7 @@ static void wlc_phy_rssi_cal_nphy_rev3(phy_info_t *pi) wlc_phy_clip_det_nphy(pi, 1, clip_state); } -static void wlc_phy_restore_rssical_nphy(phy_info_t *pi) +static void wlc_phy_restore_rssical_nphy(struct brcms_phy *pi) { if (CHSPEC_IS2G(pi->radio_chanspec)) { if (pi->nphy_rssical_chanspec_2G == 0) @@ -22308,7 +22236,7 @@ static void wlc_phy_restore_rssical_nphy(phy_info_t *pi) } static u16 -wlc_phy_gen_load_samples_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, +wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, u8 dac_test_mode) { u8 phy_bw, is_phybw40; @@ -22357,7 +22285,7 @@ wlc_phy_gen_load_samples_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, } int -wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, +wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, u8 iqmode, u8 dac_test_mode, bool modify_bbmult) { u16 num_samps; @@ -22377,7 +22305,7 @@ wlc_phy_tx_tone_nphy(phy_info_t *pi, u32 f_kHz, u16 max_val, } static void -wlc_phy_loadsampletable_nphy(phy_info_t *pi, cs32 *tone_buf, +wlc_phy_loadsampletable_nphy(struct brcms_phy *pi, cs32 *tone_buf, u16 num_samps) { u16 t; @@ -22405,7 +22333,7 @@ wlc_phy_loadsampletable_nphy(phy_info_t *pi, cs32 *tone_buf, } static void -wlc_phy_runsamples_nphy(phy_info_t *pi, u16 num_samps, u16 loops, +wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 num_samps, u16 loops, u16 wait, u8 iqmode, u8 dac_test_mode, bool modify_bbmult) { @@ -22492,7 +22420,7 @@ wlc_phy_runsamples_nphy(phy_info_t *pi, u16 num_samps, u16 loops, write_phy_reg(pi, 0xa1, orig_RfseqCoreActv); } -void wlc_phy_stopplayback_nphy(phy_info_t *pi) +void wlc_phy_stopplayback_nphy(struct brcms_phy *pi) { u16 playback_status; u16 bb_mult; @@ -22534,11 +22462,11 @@ void wlc_phy_stopplayback_nphy(phy_info_t *pi) wlc_phy_stay_in_carriersearch_nphy(pi, false); } -nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi) +struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi) { u16 base_idx[2], curr_gain[2]; u8 core_no; - nphy_txgains_t target_gain; + struct nphy_txgains target_gain; u32 *tx_pwrctrl_tbl = NULL; if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) { @@ -22584,21 +22512,21 @@ nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi) } } } else { + uint phyrev = pi->pubpi.phy_rev; + base_idx[0] = (read_phy_reg(pi, 0x1ed) >> 8) & 0x7f; base_idx[1] = (read_phy_reg(pi, 0x1ee) >> 8) & 0x7f; for (core_no = 0; core_no < 2; core_no++) { - if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (NREV_GE(phyrev, 3)) { if (PHY_IPA(pi)) { tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi); } else { if (CHSPEC_IS5G(pi->radio_chanspec)) { - if NREV_IS - (pi->pubpi.phy_rev, 3) { + if (NREV_IS(phyrev, 3)) { tx_pwrctrl_tbl = nphy_tpc_5GHz_txgain_rev3; - } else if NREV_IS - (pi->pubpi.phy_rev, 4) { + } else if (NREV_IS(phyrev, 4)) { tx_pwrctrl_tbl = (pi->srom_fem5g. extpagain == @@ -22611,8 +22539,7 @@ nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi) nphy_tpc_5GHz_txgain_rev5; } } else { - if (NREV_GE - (pi->pubpi.phy_rev, 7)) { + if (NREV_GE(phyrev, 7)) { if (pi->pubpi. radiorev == 3) { tx_pwrctrl_tbl = @@ -22625,9 +22552,7 @@ nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi) } } else { - if (NREV_GE - (pi->pubpi.phy_rev, - 5) + if (NREV_GE(phyrev, 5) && (pi->srom_fem2g. extpagain == 3)) { @@ -22640,8 +22565,7 @@ nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi) } } } - if NREV_GE - (pi->pubpi.phy_rev, 7) { + if (NREV_GE(phyrev, 7)) { target_gain.ipa[core_no] = (tx_pwrctrl_tbl[base_idx[core_no]] >> 16) & 0x7; @@ -22692,9 +22616,9 @@ nphy_txgains_t wlc_phy_get_tx_gain_nphy(phy_info_t *pi) } static void -wlc_phy_iqcal_gainparams_nphy(phy_info_t *pi, u16 core_no, - nphy_txgains_t target_gain, - nphy_iqcal_params_t *params) +wlc_phy_iqcal_gainparams_nphy(struct brcms_phy *pi, u16 core_no, + struct nphy_txgains target_gain, + struct nphy_iqcal_params *params) { u8 k; int idx; @@ -22755,7 +22679,7 @@ wlc_phy_iqcal_gainparams_nphy(phy_info_t *pi, u16 core_no, } } -static void wlc_phy_txcal_radio_setup_nphy(phy_info_t *pi) +static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi) { u16 jtag_core, core; @@ -23065,7 +22989,7 @@ static void wlc_phy_txcal_radio_setup_nphy(phy_info_t *pi) } } -static void wlc_phy_txcal_radio_cleanup_nphy(phy_info_t *pi) +static void wlc_phy_txcal_radio_cleanup_nphy(struct brcms_phy *pi) { u16 jtag_core, core; @@ -23203,7 +23127,7 @@ static void wlc_phy_txcal_radio_cleanup_nphy(phy_info_t *pi) } } -static void wlc_phy_txcal_physetup_nphy(phy_info_t *pi) +static void wlc_phy_txcal_physetup_nphy(struct brcms_phy *pi) { u16 val, mask; @@ -23355,7 +23279,7 @@ static void wlc_phy_txcal_physetup_nphy(phy_info_t *pi) } } -static void wlc_phy_txcal_phycleanup_nphy(phy_info_t *pi) +static void wlc_phy_txcal_phycleanup_nphy(struct brcms_phy *pi) { u16 mask; @@ -23437,7 +23361,7 @@ static void wlc_phy_txcal_phycleanup_nphy(phy_info_t *pi) #define NPHY_TEST_TONE_FREQ_20MHz 2500 void -wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf, u8 num_samps) +wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, u8 num_samps) { u16 tssi_reg; s32 temp, pwrindex[2]; @@ -23456,7 +23380,7 @@ wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf, u8 num_samps) tssi_type = CHSPEC_IS5G(pi->radio_chanspec) ? - (u8)NPHY_RSSI_SEL_TSSI_5G:(u8)NPHY_RSSI_SEL_TSSI_2G; + (u8)NPHY_RSSI_SEL_TSSI_5G : (u8)NPHY_RSSI_SEL_TSSI_2G; wlc_phy_poll_rssi_nphy(pi, tssi_type, rssi_buf, num_samps); @@ -23484,7 +23408,7 @@ wlc_phy_est_tonepwr_nphy(phy_info_t *pi, s32 *qdBm_pwrbuf, u8 num_samps) (u32) pwrindex[1], 32, &qdBm_pwrbuf[1]); } -static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi) +static void wlc_phy_internal_cal_txgain_nphy(struct brcms_phy *pi) { u16 txcal_gain[2]; @@ -23508,7 +23432,7 @@ static void wlc_phy_internal_cal_txgain_nphy(phy_info_t *pi) txcal_gain); } -static void wlc_phy_precal_txgain_nphy(phy_info_t *pi) +static void wlc_phy_precal_txgain_nphy(struct brcms_phy *pi) { bool save_bbmult = false; u8 txcal_index_2057_rev5n7 = 0; @@ -23596,7 +23520,8 @@ static void wlc_phy_precal_txgain_nphy(phy_info_t *pi) } void -wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, s32 dBm_targetpower, bool debug) +wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, s32 dBm_targetpower, + bool debug) { int gainctrl_loopidx; uint core; @@ -23763,20 +23688,20 @@ wlc_phy_cal_txgainctrl_nphy(phy_info_t *pi, s32 dBm_targetpower, bool debug) wlc_phy_stay_in_carriersearch_nphy(pi, false); } -static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, u16 core) +static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core) { int index; u32 bbmult_scale; u16 bbmult; u16 tblentry; - nphy_txiqcal_ladder_t ladder_lo[] = { + struct nphy_txiqcal_ladder ladder_lo[] = { {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5}, {25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7} }; - nphy_txiqcal_ladder_t ladder_iq[] = { + struct nphy_txiqcal_ladder ladder_iq[] = { {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, {25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1}, {100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7} @@ -23805,9 +23730,9 @@ static void wlc_phy_update_txcal_ladder_nphy(phy_info_t *pi, u16 core) } } -void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) +void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) { - nphy_txgains_t target_gain; + struct nphy_txgains target_gain; u8 tx_pwr_ctrl_state; bool fullcal = true; bool restore_tx_gain = false; @@ -23842,7 +23767,7 @@ void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_phyreg_enter((wlc_phy_t *) pi); + wlc_phyreg_enter((struct brcms_phy_pub *) pi); if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) || (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_INIT)) { @@ -23865,7 +23790,7 @@ void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); if (pi->antsel_type == ANTSEL_2x3) - wlc_phy_antsel_init((wlc_phy_t *) pi, true); + wlc_phy_antsel_init((struct brcms_phy_pub *) pi, true); mphase = (pi->mphase_cal_phase_id != MPHASE_CAL_STATE_IDLE); if (!mphase) { @@ -23882,12 +23807,12 @@ void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) if (PHY_IPA(pi)) wlc_phy_a4(pi, true); - wlc_phyreg_exit((wlc_phy_t *) pi); + wlc_phyreg_exit((struct brcms_phy_pub *) pi); wlapi_enable_mac(pi->sh->physhim); wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000); wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_phyreg_enter((wlc_phy_t *) pi); + wlc_phyreg_enter((struct brcms_phy_pub *) pi); if (0 == wlc_phy_cal_rxiq_nphy(pi, target_gain, (pi-> @@ -24052,12 +23977,12 @@ void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype) } wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state); - wlc_phyreg_exit((wlc_phy_t *) pi); + wlc_phyreg_exit((struct brcms_phy_pub *) pi); wlapi_enable_mac(pi->sh->physhim); } int -wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain, +wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, bool fullcal, bool mphase) { u16 val; @@ -24072,7 +23997,7 @@ wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain, u16 tone_freq; u16 gain_save[2]; u16 cal_gain[2]; - nphy_iqcal_params_t cal_params[2]; + struct nphy_iqcal_params cal_params[2]; u32 tbl_len; void *tbl_ptr; bool ladder_updated[2]; @@ -24427,7 +24352,7 @@ wlc_phy_cal_txiqlo_nphy(phy_info_t *pi, nphy_txgains_t target_gain, return bcmerror; } -static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi) +static void wlc_phy_reapply_txcal_coeffs_nphy(struct brcms_phy *pi) { u16 tbl_buf[7]; @@ -24462,9 +24387,9 @@ static void wlc_phy_reapply_txcal_coeffs_nphy(phy_info_t *pi) } } -static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi) +static void wlc_phy_tx_iq_war_nphy(struct brcms_phy *pi) { - nphy_iq_comp_t tx_comp; + struct nphy_iq_comp tx_comp; wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, (void *)&tx_comp); @@ -24475,7 +24400,8 @@ static void wlc_phy_tx_iq_war_nphy(phy_info_t *pi) } void -wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, u8 write, nphy_iq_comp_t *pcomp) +wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write, + struct nphy_iq_comp *pcomp) { if (write) { write_phy_reg(pi, 0x9a, pcomp->a0); @@ -24491,8 +24417,8 @@ wlc_phy_rx_iq_coeffs_nphy(phy_info_t *pi, u8 write, nphy_iq_comp_t *pcomp) } void -wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est, u16 num_samps, - u8 wait_time, u8 wait_for_crs) +wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est, + u16 num_samps, u8 wait_time, u8 wait_for_crs) { u8 core; @@ -24525,11 +24451,11 @@ wlc_phy_rx_iq_est_nphy(phy_info_t *pi, phy_iq_est_t *est, u16 num_samps, } #define CAL_RETRY_CNT 2 -static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, u8 core_mask) +static void wlc_phy_calc_rx_iq_comp_nphy(struct brcms_phy *pi, u8 core_mask) { u8 curr_core; - phy_iq_est_t est[PHY_CORE_MAX]; - nphy_iq_comp_t old_comp, new_comp; + struct phy_iq_est est[PHY_CORE_MAX]; + struct nphy_iq_comp old_comp, new_comp; s32 iq = 0; u32 ii = 0, qq = 0; s16 iq_nbits, qq_nbits, brsh, arsh; @@ -24634,7 +24560,8 @@ static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, u8 core_mask) } if (bcmerror != 0) { - printk("%s: Failed, cnt = %d\n", __func__, cal_retry); + printk(KERN_DEBUG "%s: Failed, cnt = %d\n", __func__, + cal_retry); if (cal_retry < CAL_RETRY_CNT) { cal_retry++; @@ -24642,13 +24569,12 @@ static void wlc_phy_calc_rx_iq_comp_nphy(phy_info_t *pi, u8 core_mask) } new_comp = old_comp; - } else if (cal_retry > 0) { } wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp); } -static void wlc_phy_rxcal_radio_setup_nphy(phy_info_t *pi, u8 rx_core) +static void wlc_phy_rxcal_radio_setup_nphy(struct brcms_phy *pi, u8 rx_core) { u16 offtune_val; u16 bias_g = 0; @@ -24945,7 +24871,7 @@ static void wlc_phy_rxcal_radio_setup_nphy(phy_info_t *pi, u8 rx_core) } } -static void wlc_phy_rxcal_radio_cleanup_nphy(phy_info_t *pi, u8 rx_core) +static void wlc_phy_rxcal_radio_cleanup_nphy(struct brcms_phy *pi, u8 rx_core) { if (NREV_GE(pi->pubpi.phy_rev, 7)) { if (rx_core == PHY_CORE_0) { @@ -25115,7 +25041,7 @@ static void wlc_phy_rxcal_radio_cleanup_nphy(phy_info_t *pi, u8 rx_core) } } -static void wlc_phy_rxcal_physetup_nphy(phy_info_t *pi, u8 rx_core) +static void wlc_phy_rxcal_physetup_nphy(struct brcms_phy *pi, u8 rx_core) { u8 tx_core; u16 rx_antval, tx_antval; @@ -25242,7 +25168,7 @@ static void wlc_phy_rxcal_physetup_nphy(phy_info_t *pi, u8 rx_core) } } -static void wlc_phy_rxcal_phycleanup_nphy(phy_info_t *pi, u8 rx_core) +static void wlc_phy_rxcal_phycleanup_nphy(struct brcms_phy *pi, u8 rx_core) { write_phy_reg(pi, 0xa2, pi->tx_rx_cal_phy_saveregs[0]); @@ -25269,14 +25195,14 @@ static void wlc_phy_rxcal_phycleanup_nphy(phy_info_t *pi, u8 rx_core) } static void -wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rx_core, +wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core, u16 *rxgain, u8 cal_type) { u16 num_samps; - phy_iq_est_t est[PHY_CORE_MAX]; + struct phy_iq_est est[PHY_CORE_MAX]; u8 tx_core; - nphy_iq_comp_t save_comp, zero_comp; + struct nphy_iq_comp save_comp, zero_comp; u32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0, thresh_pwr = 10000; s16 desired_log2_pwr, actual_log2_pwr, delta_pwr; @@ -25285,7 +25211,7 @@ wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rx_core, s8 optim_gaintbl_index = 0, prev_gaintbl_index = 0; s8 curr_gaintbl_index = 3; u8 gainctrl_dirn = NPHY_RXCAL_GAIN_INIT; - nphy_ipa_txrxgain_t *nphy_rxcal_gaintbl; + struct nphy_ipa_txrxgain *nphy_rxcal_gaintbl; u16 hpvga, lpf_biq1, lpf_biq0, lna2, lna1; int fine_gain_idx; s8 txpwrindex; @@ -25477,14 +25403,14 @@ wlc_phy_rxcal_gainctrl_nphy_rev5(phy_info_t *pi, u8 rx_core, } static void -wlc_phy_rxcal_gainctrl_nphy(phy_info_t *pi, u8 rx_core, u16 *rxgain, +wlc_phy_rxcal_gainctrl_nphy(struct brcms_phy *pi, u8 rx_core, u16 *rxgain, u8 cal_type) { wlc_phy_rxcal_gainctrl_nphy_rev5(pi, rx_core, rxgain, cal_type); } static u8 -wlc_phy_rc_sweep_nphy(phy_info_t *pi, u8 core_idx, u8 loopback_type) +wlc_phy_rc_sweep_nphy(struct brcms_phy *pi, u8 core_idx, u8 loopback_type) { u32 target_bws[2] = { 9500, 21000 }; u32 ref_tones[2] = { 3000, 6000 }; @@ -25516,7 +25442,7 @@ wlc_phy_rc_sweep_nphy(phy_info_t *pi, u8 core_idx, u8 loopback_type) u16 rccal_val, last_rccal_val = 0, best_rccal_val = 0; u32 ref_iq_vals = 0, target_iq_vals = 0; u16 num_samps, log_num_samps = 10; - phy_iq_est_t est[PHY_CORE_MAX]; + struct phy_iq_est est[PHY_CORE_MAX]; if (NREV_GE(pi->pubpi.phy_rev, 7)) { return 0; @@ -25724,16 +25650,16 @@ wlc_phy_rc_sweep_nphy(phy_info_t *pi, u8 core_idx, u8 loopback_type) } #define WAIT_FOR_SCOPE 4000 -static int -wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t target_gain, - u8 cal_type, bool debug) +static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi, + struct nphy_txgains target_gain, + u8 cal_type, bool debug) { u16 orig_BBConfig; u8 core_no, rx_core; u8 best_rccal[2]; u16 gain_save[2]; u16 cal_gain[2]; - nphy_iqcal_params_t cal_params[2]; + struct nphy_iqcal_params cal_params[2]; u8 rxcore_state; s8 rxlpf_rccal_hpc, txlpf_rccal_lpc; s8 txlpf_idac; @@ -25760,7 +25686,8 @@ wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t target_gain, wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain); - rxcore_state = wlc_phy_rxcore_getstate_nphy((wlc_phy_t *) pi); + rxcore_state = wlc_phy_rxcore_getstate_nphy( + (struct brcms_phy_pub *) pi); for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) { @@ -25795,8 +25722,8 @@ wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t target_gain, if (rx_core == PHY_CORE_1) { if (rxcore_state == 1) { - wlc_phy_rxcore_setstate_nphy((wlc_phy_t - *) pi, 3); + wlc_phy_rxcore_setstate_nphy( + (struct brcms_phy_pub *) pi, 3); } wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, @@ -25807,9 +25734,9 @@ wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t target_gain, pi->nphy_rccal_value = best_rccal[rx_core]; if (rxcore_state == 1) { - wlc_phy_rxcore_setstate_nphy((wlc_phy_t - *) pi, - rxcore_state); + wlc_phy_rxcore_setstate_nphy( + (struct brcms_phy_pub *) pi, + rxcore_state); } } } @@ -25882,10 +25809,10 @@ wlc_phy_cal_rxiq_nphy_rev3(phy_info_t *pi, nphy_txgains_t target_gain, } static int -wlc_phy_cal_rxiq_nphy_rev2(phy_info_t *pi, nphy_txgains_t target_gain, - bool debug) +wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi, + struct nphy_txgains target_gain, bool debug) { - phy_iq_est_t est[PHY_CORE_MAX]; + struct phy_iq_est est[PHY_CORE_MAX]; u8 core_num, rx_core, tx_core; u16 lna_vals[] = { 0x3, 0x3, 0x1 }; u16 hpf1_vals[] = { 0x7, 0x2, 0x0 }; @@ -25901,7 +25828,7 @@ wlc_phy_cal_rxiq_nphy_rev2(phy_info_t *pi, nphy_txgains_t target_gain, u16 core_no; u16 gain_save[2]; u16 cal_gain[2]; - nphy_iqcal_params_t cal_params[2]; + struct nphy_iqcal_params cal_params[2]; u8 phy_bw; int bcmerror = 0; bool first_playtone = true; @@ -26108,7 +26035,7 @@ wlc_phy_cal_rxiq_nphy_rev2(phy_info_t *pi, nphy_txgains_t target_gain, } int -wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain, +wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, u8 cal_type, bool debug) { if (NREV_GE(pi->pubpi.phy_rev, 7)) { @@ -26123,7 +26050,7 @@ wlc_phy_cal_rxiq_nphy(phy_info_t *pi, nphy_txgains_t target_gain, } } -static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi) +static void wlc_phy_extpa_set_tx_digi_filts_nphy(struct brcms_phy *pi) { int j, type = 2; u16 addr_offset = 0x2c5; @@ -26134,7 +26061,7 @@ static void wlc_phy_extpa_set_tx_digi_filts_nphy(phy_info_t *pi) } } -static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi) +static void wlc_phy_ipa_set_tx_digi_filts_nphy(struct brcms_phy *pi) { int j, type; u16 addr_offset[] = { 0x186, 0x195, @@ -26172,7 +26099,7 @@ static void wlc_phy_ipa_set_tx_digi_filts_nphy(phy_info_t *pi) } } -static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi) +static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi) { int j; @@ -26189,7 +26116,7 @@ static void wlc_phy_ipa_restore_tx_digi_filts_nphy(phy_info_t *pi) } } -static u16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi) +static u16 wlc_phy_ipa_get_bbmult_nphy(struct brcms_phy *pi) { u16 m0m1; @@ -26198,7 +26125,7 @@ static u16 wlc_phy_ipa_get_bbmult_nphy(phy_info_t *pi) return m0m1; } -static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, u8 m0, u8 m1) +static void wlc_phy_ipa_set_bbmult_nphy(struct brcms_phy *pi, u8 m0, u8 m1) { u16 m0m1 = (u16) ((m0 << 8) | m1); @@ -26206,7 +26133,7 @@ static void wlc_phy_ipa_set_bbmult_nphy(phy_info_t *pi, u8 m0, u8 m1) wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1); } -static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi) +static u32 *wlc_phy_get_ipa_gaintbl_nphy(struct brcms_phy *pi) { u32 *tx_pwrctrl_tbl = NULL; @@ -26237,11 +26164,6 @@ static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi) } else if (NREV_IS(pi->pubpi.phy_rev, 6)) { tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6; - if (pi->sh->chip == BCM47162_CHIP_ID) { - - tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5; - } - } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5; @@ -26274,8 +26196,8 @@ static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi) } static void -wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, nphy_papd_restore_state *state, - u8 core) +wlc_phy_papd_cal_setup_nphy(struct brcms_phy *pi, + struct nphy_papd_restore_state *state, u8 core) { s32 tone_freq; u8 off_core; @@ -26544,7 +26466,8 @@ wlc_phy_papd_cal_setup_nphy(phy_info_t *pi, nphy_papd_restore_state *state, } static void -wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi, nphy_papd_restore_state *state) +wlc_phy_papd_cal_cleanup_nphy(struct brcms_phy *pi, + struct nphy_papd_restore_state *state) { u8 core; @@ -26670,7 +26593,7 @@ wlc_phy_papd_cal_cleanup_nphy(phy_info_t *pi, nphy_papd_restore_state *state) } static void -wlc_phy_a1_nphy(phy_info_t *pi, u8 core, u32 winsz, u32 start, +wlc_phy_a1_nphy(struct brcms_phy *pi, u8 core, u32 winsz, u32 start, u32 end) { u32 *buf, *src, *dst, sz; @@ -26722,15 +26645,15 @@ wlc_phy_a1_nphy(phy_info_t *pi, u8 core, u32 winsz, u32 start, } static void -wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *txgains, - phy_cal_mode_t cal_mode, u8 core) +wlc_phy_a2_nphy(struct brcms_phy *pi, struct nphy_ipa_txcalgains *txgains, + enum phy_cal_mode cal_mode, u8 core) { u16 phy_a1, phy_a2, phy_a3; u16 phy_a4, phy_a5; bool phy_a6; u8 phy_a7, m[2]; u32 phy_a8 = 0; - nphy_txgains_t phy_a9; + struct nphy_txgains phy_a9; if (NREV_LT(pi->pubpi.phy_rev, 3)) return; @@ -26781,11 +26704,8 @@ wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *txgains, phy_a2 = 63; if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->sh->chip == BCM6362_CHIP_ID) { - phy_a1 = 35; - phy_a3 = 35; - } else if ((pi->pubpi.radiorev == 4) - || (pi->pubpi.radiorev == 6)) { + if ((pi->pubpi.radiorev == 4) + || (pi->pubpi.radiorev == 6)) { phy_a1 = 30; phy_a3 = 30; } else { @@ -26891,16 +26811,10 @@ wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *txgains, if (txgains->useindex) { phy_a4 = 15 - ((txgains->index) >> 3); if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (NREV_GE(pi->pubpi.phy_rev, 6)) { + if (NREV_GE(pi->pubpi.phy_rev, 6)) phy_a5 = 0x00f7 | (phy_a4 << 8); - if (pi->sh->chip == - BCM47162_CHIP_ID) { - phy_a5 = - 0x10f7 | (phy_a4 << - 8); - } - } else + else if (NREV_IS(pi->pubpi.phy_rev, 5)) phy_a5 = 0x10f7 | (phy_a4 << 8); else @@ -27020,12 +26934,12 @@ wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *txgains, } } -static u8 wlc_phy_a3_nphy(phy_info_t *pi, u8 start_gain, u8 core) +static u8 wlc_phy_a3_nphy(struct brcms_phy *pi, u8 start_gain, u8 core) { int phy_a1; int phy_a2; bool phy_a3; - nphy_ipa_txcalgains_t phy_a4; + struct nphy_ipa_txcalgains phy_a4; bool phy_a5 = false; bool phy_a6 = true; s32 phy_a7, phy_a8; @@ -27181,10 +27095,10 @@ static u8 wlc_phy_a3_nphy(phy_info_t *pi, u8 start_gain, u8 core) } -static void wlc_phy_a4(phy_info_t *pi, bool full_cal) +static void wlc_phy_a4(struct brcms_phy *pi, bool full_cal) { - nphy_ipa_txcalgains_t phy_b1[2]; - nphy_papd_restore_state phy_b2; + struct nphy_ipa_txcalgains phy_b1[2]; + struct nphy_papd_restore_state phy_b2; bool phy_b3; u8 phy_b4; u8 phy_b5; @@ -27470,7 +27384,7 @@ static void wlc_phy_a4(phy_info_t *pi, bool full_cal) } } -void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi) +void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi) { uint core; u32 txgain; @@ -27528,20 +27442,20 @@ void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi) pi->nphy_txpwrindex[PHY_CORE_1].index_internal_save = txpi[1]; for (core = 0; core < pi->pubpi.phy_corenum; core++) { - if (NREV_GE(pi->pubpi.phy_rev, 3)) { + uint phyrev = pi->pubpi.phy_rev; + + if (NREV_GE(phyrev, 3)) { if (PHY_IPA(pi)) { u32 *tx_gaintbl = wlc_phy_get_ipa_gaintbl_nphy(pi); txgain = tx_gaintbl[txpi[core]]; } else { if (CHSPEC_IS5G(pi->radio_chanspec)) { - if NREV_IS - (pi->pubpi.phy_rev, 3) { + if (NREV_IS(phyrev, 3)) { txgain = nphy_tpc_5GHz_txgain_rev3 [txpi[core]]; - } else if NREV_IS - (pi->pubpi.phy_rev, 4) { + } else if (NREV_IS(phyrev, 4)) { txgain = (pi->srom_fem5g.extpagain == 3) ? @@ -27555,7 +27469,7 @@ void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi) [txpi[core]]; } } else { - if (NREV_GE(pi->pubpi.phy_rev, 5) && + if (NREV_GE(phyrev, 5) && (pi->srom_fem2g.extpagain == 3)) { txgain = nphy_tpc_txgain_HiPwrEPA @@ -27571,20 +27485,19 @@ void wlc_phy_txpwr_fixpower_nphy(phy_info_t *pi) txgain = nphy_tpc_txgain[txpi[core]]; } - if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (NREV_GE(phyrev, 3)) rad_gain = (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1); - } else { + else rad_gain = (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1); - } - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(phyrev, 7)) dac_gain = (txgain >> 8) & ((1 << (10 - 8 + 1)) - 1); - } else { + else dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1); - } + bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1); - if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (NREV_GE(phyrev, 3)) { mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : 0xa5), (0x1 << 8), (0x1 << 8)); } else { @@ -27682,7 +27595,7 @@ wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_start, } } -void wlc_phy_txpwr_apply_nphy(phy_info_t *pi) +void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi) { uint rate1, rate2, band_num; u8 tmp_bw40po = 0, tmp_cddpo = 0, tmp_stbcpo = 0; @@ -27880,7 +27793,7 @@ void wlc_phy_txpwr_apply_nphy(phy_info_t *pi) return; } -static void wlc_phy_txpwr_srom_read_ppr_nphy(phy_info_t *pi) +static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) { u16 bw40po, cddpo, stbcpo, bwduppo; uint band_num; @@ -28088,7 +28001,7 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(phy_info_t *pi) wlc_phy_txpwr_apply_nphy(pi); } -static bool wlc_phy_txpwr_srom_read_nphy(phy_info_t *pi) +static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi) { pi->antswitch = (u8) PHY_GETINTVAR(pi, "antswitch"); @@ -28148,7 +28061,7 @@ static bool wlc_phy_txpwr_srom_read_nphy(phy_info_t *pi) return true; } -void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi) +void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi) { u8 tx_pwr_ctrl_state; wlc_phy_txpwr_limit_to_tbl_nphy(pi); @@ -28168,7 +28081,7 @@ void wlc_phy_txpower_recalc_target_nphy(phy_info_t *pi) wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0); } -static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi) +static void wlc_phy_txpwrctrl_coeff_setup_nphy(struct brcms_phy *pi) { u32 idx; u16 iqloCalbuf[7]; @@ -28239,7 +28152,7 @@ static void wlc_phy_txpwrctrl_coeff_setup_nphy(phy_info_t *pi) wlc_phy_stay_in_carriersearch_nphy(pi, false); } -static void wlc_phy_ipa_internal_tssi_setup_nphy(phy_info_t *pi) +static void wlc_phy_ipa_internal_tssi_setup_nphy(struct brcms_phy *pi) { u8 core; @@ -28349,7 +28262,7 @@ static void wlc_phy_ipa_internal_tssi_setup_nphy(phy_info_t *pi) } } -static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi) +static void wlc_phy_txpwrctrl_idle_tssi_nphy(struct brcms_phy *pi) { s32 rssi_buf[4]; s32 int_val; @@ -28415,7 +28328,7 @@ static void wlc_phy_txpwrctrl_idle_tssi_nphy(phy_info_t *pi) } -static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi) +static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi) { u32 idx; s16 a1[2], b0[2], b1[2]; @@ -28652,13 +28565,13 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(phy_info_t *pi) wlc_phy_stay_in_carriersearch_nphy(pi, false); } -static bool wlc_phy_txpwr_ison_nphy(phy_info_t *pi) +static bool wlc_phy_txpwr_ison_nphy(struct brcms_phy *pi) { return read_phy_reg((pi), 0x1e7) & ((0x1 << 15) | (0x1 << 14) | (0x1 << 13)); } -static u8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, u8 core) +static u8 wlc_phy_txpwr_idx_cur_get_nphy(struct brcms_phy *pi, u8 core) { u16 tmp; tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee)); @@ -28668,7 +28581,7 @@ static u8 wlc_phy_txpwr_idx_cur_get_nphy(phy_info_t *pi, u8 core) } static void -wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, u8 idx0, u8 idx1) +wlc_phy_txpwr_idx_cur_set_nphy(struct brcms_phy *pi, u8 idx0, u8 idx1) { mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0); @@ -28676,7 +28589,7 @@ wlc_phy_txpwr_idx_cur_set_nphy(phy_info_t *pi, u8 idx0, u8 idx1) mod_phy_reg(pi, 0x222, (0xff << 0), idx1); } -u16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi) +u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi) { u16 tmp; u16 pwr_idx[2]; @@ -28698,7 +28611,7 @@ u16 wlc_phy_txpwr_idx_get_nphy(phy_info_t *pi) return tmp; } -void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi) +void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi) { if (PHY_IPA(pi) && (pi->nphy_force_papd_cal @@ -28714,7 +28627,7 @@ void wlc_phy_txpwr_papd_cal_nphy(phy_info_t *pi) } } -void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type) +void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type) { u16 mask = 0, val = 0, ishw = 0; u8 ctr; @@ -28783,7 +28696,7 @@ void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type) if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi)) wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR, - MHF1_IQSWAP_WAR, WLC_BAND_ALL); + MHF1_IQSWAP_WAR, BRCM_BAND_ALL); } else { @@ -28842,7 +28755,7 @@ void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type) if (NREV_LT(pi->pubpi.phy_rev, 2) && IS40MHZ(pi)) wlapi_bmac_mhf(pi->sh->physhim, MHF1, MHF1_IQSWAP_WAR, - 0x0, WLC_BAND_ALL); + 0x0, BRCM_BAND_ALL); if (PHY_IPA(pi)) { mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 : @@ -28860,7 +28773,7 @@ void wlc_phy_txpwrctrl_enable_nphy(phy_info_t *pi, u8 ctrl_type) } void -wlc_phy_txpwr_index_nphy(phy_info_t *pi, u8 core_mask, s8 txpwrindex, +wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex, bool restore_cals) { u8 core, txpwrctl_tbl; @@ -29099,7 +29012,7 @@ wlc_phy_txpwr_index_nphy(phy_info_t *pi, u8 core_mask, s8 txpwrindex, } void -wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan, u8 *max_pwr, +wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan, u8 *max_pwr, u8 txp_rate_idx) { u8 chan_freq_range; @@ -29126,7 +29039,7 @@ wlc_phy_txpower_sromlimit_get_nphy(phy_info_t *pi, uint chan, u8 *max_pwr, return; } -void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable) +void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi, bool enable) { u16 clip_off[] = { 0xffff, 0xffff }; @@ -29154,7 +29067,7 @@ void wlc_phy_stay_in_carriersearch_nphy(phy_info_t *pi, bool enable) } } -void wlc_nphy_deaf_mode(phy_info_t *pi, bool mode) +void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode) { wlapi_suspend_mac_and_wait(pi->sh->physhim); diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c similarity index 99% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c rename to drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c index c98176fd0aae..01ff0c8eb4b9 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c @@ -14,9 +14,7 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - -#include "wlc_phy_qmath.h" +#include "phy_qmath.h" /* Description: This function make 16 bit unsigned multiplication. To fit the output into diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.h similarity index 91% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h rename to drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.h index 3dcee1c4aa65..20e3783f921b 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.h @@ -14,8 +14,10 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef __QMATH_H__ -#define __QMATH_H__ +#ifndef _BRCM_QMATH_H_ +#define _BRCM_QMATH_H_ + +#include u16 qm_mulu16(u16 op1, u16 op2); @@ -37,4 +39,4 @@ s16 qm_norm32(s32 op); void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N); -#endif /* #ifndef __QMATH_H__ */ +#endif /* #ifndef _BRCM_QMATH_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_radio.h similarity index 99% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h rename to drivers/staging/brcm80211/brcmsmac/phy/phy_radio.h index 72176ae2882c..c3a675455ff5 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_radio.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_radio.h @@ -14,8 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _BCM20XX_H -#define _BCM20XX_H +#ifndef _BRCM_PHY_RADIO_H_ +#define _BRCM_PHY_RADIO_H_ #define RADIO_IDCODE 0x01 @@ -1530,4 +1530,4 @@ #define RADIO_2057_VCM_MASK 0x7 -#endif /* _BCM20XX_H */ +#endif /* _BRCM_PHY_RADIO_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h deleted file mode 100644 index 51a223880bcf..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/phy/phy_version.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef phy_version_h_ -#define phy_version_h_ - -#define PHY_MAJOR_VERSION 1 - -#define PHY_MINOR_VERSION 82 - -#define PHY_RC_NUMBER 8 - -#define PHY_INCREMENTAL_NUMBER 0 - -#define PHY_BUILD_NUMBER 0 - -#define PHY_VERSION { 1, 82, 8, 0 } - -#define PHY_VERSION_NUM 0x01520800 - -#define PHY_VERSION_STR "1.82.8.0" - -#endif /* phy_version_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h b/drivers/staging/brcm80211/brcmsmac/phy/phyreg_n.h similarity index 96% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h rename to drivers/staging/brcm80211/brcmsmac/phy/phyreg_n.h index 211bc3a842af..a97c3a799479 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phyreg_n.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phyreg_n.h @@ -123,13 +123,13 @@ #define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS 0xf #define NPHY_REV3_RFSEQ_CMD_END 0x1f -#define NPHY_RSSI_SEL_W1 0x0 -#define NPHY_RSSI_SEL_W2 0x1 -#define NPHY_RSSI_SEL_NB 0x2 -#define NPHY_RSSI_SEL_IQ 0x3 -#define NPHY_RSSI_SEL_TSSI_2G 0x4 -#define NPHY_RSSI_SEL_TSSI_5G 0x5 -#define NPHY_RSSI_SEL_TBD 0x6 +#define NPHY_RSSI_SEL_W1 0x0 +#define NPHY_RSSI_SEL_W2 0x1 +#define NPHY_RSSI_SEL_NB 0x2 +#define NPHY_RSSI_SEL_IQ 0x3 +#define NPHY_RSSI_SEL_TSSI_2G 0x4 +#define NPHY_RSSI_SEL_TSSI_5G 0x5 +#define NPHY_RSSI_SEL_TBD 0x6 #define NPHY_RAIL_I 0x0 #define NPHY_RAIL_Q 0x1 diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c similarity index 96% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c rename to drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c index 81c59b05482a..023d05aa97ad 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c @@ -14,10 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include -#include +#include +#include "phytbl_lcn.h" const u32 dot11lcn_gain_tbl_rev0[] = { 0x00000000, @@ -1507,7 +1505,7 @@ const u32 dot11lcn_gain_tbl_5G[] = { 0x00000000 }; -const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[] = { +const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[] = { {&dot11lcn_gain_tbl_rev0, sizeof(dot11lcn_gain_tbl_rev0) / sizeof(dot11lcn_gain_tbl_rev0[0]), 18, 0, 32} @@ -1522,7 +1520,7 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[] = { , }; -const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[] = { +const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev1[] = { {&dot11lcn_gain_tbl_rev1, sizeof(dot11lcn_gain_tbl_rev1) / sizeof(dot11lcn_gain_tbl_rev1[0]), 18, 0, 32} @@ -1537,7 +1535,7 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev1[] = { , }; -const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[] = { +const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[] = { {&dot11lcn_gain_tbl_2G, sizeof(dot11lcn_gain_tbl_2G) / sizeof(dot11lcn_gain_tbl_2G[0]), 18, 0, 32} @@ -1555,7 +1553,7 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[] = { 17, 0, 8} }; -const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[] = { +const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[] = { {&dot11lcn_gain_tbl_5G, sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0, 32} @@ -1573,7 +1571,7 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[] = { 17, 0, 8} }; -const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = { +const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = { {&dot11lcn_gain_tbl_extlna_2G, sizeof(dot11lcn_gain_tbl_extlna_2G) / sizeof(dot11lcn_gain_tbl_extlna_2G[0]), 18, 0, 32} @@ -1591,7 +1589,7 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[] = { sizeof(dot11lcn_gain_val_tbl_extlna_2G[0]), 17, 0, 8} }; -const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = { +const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = { {&dot11lcn_gain_tbl_5G, sizeof(dot11lcn_gain_tbl_5G) / sizeof(dot11lcn_gain_tbl_5G[0]), 18, 0, 32} @@ -1610,20 +1608,20 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[] = { }; const u32 dot11lcnphytbl_rx_gain_info_sz_rev0 = - sizeof(dot11lcnphytbl_rx_gain_info_rev0) / - sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]); + sizeof(dot11lcnphytbl_rx_gain_info_rev0) / + sizeof(dot11lcnphytbl_rx_gain_info_rev0[0]); const u32 dot11lcnphytbl_rx_gain_info_sz_rev1 = - sizeof(dot11lcnphytbl_rx_gain_info_rev1) / - sizeof(dot11lcnphytbl_rx_gain_info_rev1[0]); + sizeof(dot11lcnphytbl_rx_gain_info_rev1) / + sizeof(dot11lcnphytbl_rx_gain_info_rev1[0]); const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz = - sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) / - sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]); + sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2) / + sizeof(dot11lcnphytbl_rx_gain_info_2G_rev2[0]); const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz = - sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) / - sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]); + sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2) / + sizeof(dot11lcnphytbl_rx_gain_info_5G_rev2[0]); const u16 dot11lcn_min_sig_sq_tbl_rev0[] = { 0x014d, @@ -2775,7 +2773,7 @@ const u32 dot11lcn_papd_compdelta_tbl_rev0[] = { 0x00080000, }; -const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[] = { +const struct phytbl_info dot11lcnphytbl_info_rev0[] = { {&dot11lcn_min_sig_sq_tbl_rev0, sizeof(dot11lcn_min_sig_sq_tbl_rev0) / sizeof(dot11lcn_min_sig_sq_tbl_rev0[0]), 2, 0, 16} @@ -2834,34 +2832,35 @@ const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[] = { , }; -const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313 = { +const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313 = { &dot11lcn_sw_ctrl_tbl_4313_rev0, sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) / sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16 }; -const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa = { +const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa = { &dot11lcn_sw_ctrl_tbl_4313_epa_rev0, sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) / sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16 }; -const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = { +const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa = { &dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo, sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) / sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16 }; -const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = { +const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250 = { &dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0, sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0) / sizeof(dot11lcn_sw_ctrl_tbl_4313_bt_epa_p250_rev0[0]), 15, 0, 16 }; const u32 dot11lcnphytbl_info_sz_rev0 = - sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]); + sizeof(dot11lcnphytbl_info_rev0) / sizeof(dot11lcnphytbl_info_rev0[0]); -const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = { +const struct lcnphy_tx_gain_tbl_entry +dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = { {3, 0, 31, 0, 72,} , {3, 0, 31, 0, 70,} @@ -3120,7 +3119,7 @@ const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = { , }; -const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = { +const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = { {7, 0, 31, 0, 72,} , {7, 0, 31, 0, 70,} @@ -3379,7 +3378,7 @@ const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = { , }; -const lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = { +const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = { {255, 255, 0xf0, 0, 152,} , {255, 255, 0xf0, 0, 147,} diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.h similarity index 50% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h rename to drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.h index 5a64a988d107..5f75e16bf5a7 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_lcn.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.h @@ -14,36 +14,41 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -typedef phytbl_info_t dot11lcnphytbl_info_t; +#include +#include "phy_int.h" -extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_rev0[]; +extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[]; extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0; -extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313; -extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa; -extern const dot11lcnphytbl_info_t dot11lcn_sw_ctrl_tbl_info_4313_epa_combo; +extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313; +extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa; +extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa_combo; +extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa; +extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250; -extern const dot11lcnphytbl_info_t dot11lcnphytbl_info_rev0[]; +extern const struct phytbl_info dot11lcnphytbl_info_rev0[]; extern const u32 dot11lcnphytbl_info_sz_rev0; -extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_2G_rev2[]; +extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[]; extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz; -extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_5G_rev2[]; +extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[]; extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz; -extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[]; +extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[]; -extern const dot11lcnphytbl_info_t dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[]; +extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[]; -typedef struct { +struct lcnphy_tx_gain_tbl_entry { unsigned char gm; unsigned char pga; unsigned char pad; unsigned char dac; unsigned char bb_mult; -} lcnphy_tx_gain_tbl_entry; +}; -extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[]; -extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[]; +extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[]; -extern const lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[]; +extern const struct +lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[]; + +extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[]; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c similarity index 99% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c rename to drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c index 742df997a3b1..7f741f4868a6 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c @@ -14,11 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include - -#include -#include -#include +#include +#include "phytbl_n.h" const u32 frame_struct_rev0[] = { 0x08004a04, @@ -4439,7 +4436,7 @@ const u16 loft_lut_core1_rev0[] = { 0x0103, }; -const mimophytbl_info_t mimophytbl_info_rev0_volatile[] = { +const struct phytbl_info mimophytbl_info_rev0_volatile[] = { {&bdi_tbl_rev0, sizeof(bdi_tbl_rev0) / sizeof(bdi_tbl_rev0[0]), 21, 0, 16} , @@ -4487,7 +4484,7 @@ const mimophytbl_info_t mimophytbl_info_rev0_volatile[] = { , }; -const mimophytbl_info_t mimophytbl_info_rev0[] = { +const struct phytbl_info mimophytbl_info_rev0[] = { {&frame_struct_rev0, sizeof(frame_struct_rev0) / sizeof(frame_struct_rev0[0]), 10, 0, 32} , @@ -4538,10 +4535,10 @@ const mimophytbl_info_t mimophytbl_info_rev0[] = { }; const u32 mimophytbl_info_sz_rev0 = - sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]); + sizeof(mimophytbl_info_rev0) / sizeof(mimophytbl_info_rev0[0]); const u32 mimophytbl_info_sz_rev0_volatile = - sizeof(mimophytbl_info_rev0_volatile) / - sizeof(mimophytbl_info_rev0_volatile[0]); + sizeof(mimophytbl_info_rev0_volatile) / + sizeof(mimophytbl_info_rev0_volatile[0]); const u16 ant_swctrl_tbl_rev3[] = { 0x0082, @@ -9364,34 +9361,34 @@ const u32 papd_cal_scalars_tbl_core1_rev3[] = { 0x002606a4, }; -const mimophytbl_info_t mimophytbl_info_rev3_volatile[] = { +const struct phytbl_info mimophytbl_info_rev3_volatile[] = { {&ant_swctrl_tbl_rev3, sizeof(ant_swctrl_tbl_rev3) / sizeof(ant_swctrl_tbl_rev3[0]), 9, 0, 16} , }; -const mimophytbl_info_t mimophytbl_info_rev3_volatile1[] = { +const struct phytbl_info mimophytbl_info_rev3_volatile1[] = { {&ant_swctrl_tbl_rev3_1, sizeof(ant_swctrl_tbl_rev3_1) / sizeof(ant_swctrl_tbl_rev3_1[0]), 9, 0, 16} , }; -const mimophytbl_info_t mimophytbl_info_rev3_volatile2[] = { +const struct phytbl_info mimophytbl_info_rev3_volatile2[] = { {&ant_swctrl_tbl_rev3_2, sizeof(ant_swctrl_tbl_rev3_2) / sizeof(ant_swctrl_tbl_rev3_2[0]), 9, 0, 16} , }; -const mimophytbl_info_t mimophytbl_info_rev3_volatile3[] = { +const struct phytbl_info mimophytbl_info_rev3_volatile3[] = { {&ant_swctrl_tbl_rev3_3, sizeof(ant_swctrl_tbl_rev3_3) / sizeof(ant_swctrl_tbl_rev3_3[0]), 9, 0, 16} , }; -const mimophytbl_info_t mimophytbl_info_rev3[] = { +const struct phytbl_info mimophytbl_info_rev3[] = { {&frame_struct_rev3, sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32} , @@ -9478,19 +9475,19 @@ const mimophytbl_info_t mimophytbl_info_rev3[] = { }; const u32 mimophytbl_info_sz_rev3 = - sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]); + sizeof(mimophytbl_info_rev3) / sizeof(mimophytbl_info_rev3[0]); const u32 mimophytbl_info_sz_rev3_volatile = - sizeof(mimophytbl_info_rev3_volatile) / - sizeof(mimophytbl_info_rev3_volatile[0]); + sizeof(mimophytbl_info_rev3_volatile) / + sizeof(mimophytbl_info_rev3_volatile[0]); const u32 mimophytbl_info_sz_rev3_volatile1 = - sizeof(mimophytbl_info_rev3_volatile1) / - sizeof(mimophytbl_info_rev3_volatile1[0]); + sizeof(mimophytbl_info_rev3_volatile1) / + sizeof(mimophytbl_info_rev3_volatile1[0]); const u32 mimophytbl_info_sz_rev3_volatile2 = - sizeof(mimophytbl_info_rev3_volatile2) / - sizeof(mimophytbl_info_rev3_volatile2[0]); + sizeof(mimophytbl_info_rev3_volatile2) / + sizeof(mimophytbl_info_rev3_volatile2[0]); const u32 mimophytbl_info_sz_rev3_volatile3 = - sizeof(mimophytbl_info_rev3_volatile3) / - sizeof(mimophytbl_info_rev3_volatile3[0]); + sizeof(mimophytbl_info_rev3_volatile3) / + sizeof(mimophytbl_info_rev3_volatile3[0]); const u32 tmap_tbl_rev7[] = { 0x8a88aa80, @@ -10470,7 +10467,7 @@ const u32 papd_cal_scalars_tbl_core1_rev7[] = { 0x004e068c, }; -const mimophytbl_info_t mimophytbl_info_rev7[] = { +const struct phytbl_info mimophytbl_info_rev7[] = { {&frame_struct_rev3, sizeof(frame_struct_rev3) / sizeof(frame_struct_rev3[0]), 10, 0, 32} , @@ -10582,9 +10579,9 @@ const mimophytbl_info_t mimophytbl_info_rev7[] = { }; const u32 mimophytbl_info_sz_rev7 = - sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]); + sizeof(mimophytbl_info_rev7) / sizeof(mimophytbl_info_rev7[0]); -const mimophytbl_info_t mimophytbl_info_rev16[] = { +const struct phytbl_info mimophytbl_info_rev16[] = { {&noise_var_tbl_rev7, sizeof(noise_var_tbl_rev7) / sizeof(noise_var_tbl_rev7[0]), 16, 0, 32} , @@ -10629,4 +10626,4 @@ const mimophytbl_info_t mimophytbl_info_rev16[] = { }; const u32 mimophytbl_info_sz_rev16 = - sizeof(mimophytbl_info_rev16) / sizeof(mimophytbl_info_rev16[0]); + sizeof(mimophytbl_info_rev16) / sizeof(mimophytbl_info_rev16[0]); diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h similarity index 67% rename from drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h rename to drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h index 396122f5e50b..c5266cf23725 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phytbl_n.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h @@ -16,24 +16,25 @@ #define ANT_SWCTRL_TBL_REV3_IDX (0) -typedef phytbl_info_t mimophytbl_info_t; +#include +#include "phy_int.h" -extern const mimophytbl_info_t mimophytbl_info_rev0[], - mimophytbl_info_rev0_volatile[]; +extern const struct phytbl_info mimophytbl_info_rev0[], + mimophytbl_info_rev0_volatile[]; extern const u32 mimophytbl_info_sz_rev0, mimophytbl_info_sz_rev0_volatile; -extern const mimophytbl_info_t mimophytbl_info_rev3[], - mimophytbl_info_rev3_volatile[], mimophytbl_info_rev3_volatile1[], - mimophytbl_info_rev3_volatile2[], mimophytbl_info_rev3_volatile3[]; +extern const struct phytbl_info mimophytbl_info_rev3[], + mimophytbl_info_rev3_volatile[], mimophytbl_info_rev3_volatile1[], + mimophytbl_info_rev3_volatile2[], mimophytbl_info_rev3_volatile3[]; extern const u32 mimophytbl_info_sz_rev3, mimophytbl_info_sz_rev3_volatile, - mimophytbl_info_sz_rev3_volatile1, mimophytbl_info_sz_rev3_volatile2, - mimophytbl_info_sz_rev3_volatile3; + mimophytbl_info_sz_rev3_volatile1, mimophytbl_info_sz_rev3_volatile2, + mimophytbl_info_sz_rev3_volatile3; extern const u32 noise_var_tbl_rev3[]; -extern const mimophytbl_info_t mimophytbl_info_rev7[]; +extern const struct phytbl_info mimophytbl_info_rev7[]; extern const u32 mimophytbl_info_sz_rev7; extern const u32 noise_var_tbl_rev7[]; -extern const mimophytbl_info_t mimophytbl_info_rev16[]; +extern const struct phytbl_info mimophytbl_info_rev16[]; extern const u32 mimophytbl_info_sz_rev16; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h b/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h deleted file mode 100644 index 8939153efa56..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_phy_h_ -#define _wlc_phy_h_ - -#include -#include -#include -#include -#include /* struct wiphy */ - -#define IDCODE_VER_MASK 0x0000000f -#define IDCODE_VER_SHIFT 0 -#define IDCODE_MFG_MASK 0x00000fff -#define IDCODE_MFG_SHIFT 0 -#define IDCODE_ID_MASK 0x0ffff000 -#define IDCODE_ID_SHIFT 12 -#define IDCODE_REV_MASK 0xf0000000 -#define IDCODE_REV_SHIFT 28 - -#define NORADIO_ID 0xe4f5 -#define NORADIO_IDCODE 0x4e4f5246 - -#define BCM2055_ID 0x2055 -#define BCM2055_IDCODE 0x02055000 -#define BCM2055A0_IDCODE 0x1205517f - -#define BCM2056_ID 0x2056 -#define BCM2056_IDCODE 0x02056000 -#define BCM2056A0_IDCODE 0x1205617f - -#define BCM2057_ID 0x2057 -#define BCM2057_IDCODE 0x02057000 -#define BCM2057A0_IDCODE 0x1205717f - -#define BCM2064_ID 0x2064 -#define BCM2064_IDCODE 0x02064000 -#define BCM2064A0_IDCODE 0x0206417f - -#define PHY_TPC_HW_OFF false -#define PHY_TPC_HW_ON true - -#define PHY_PERICAL_DRIVERUP 1 -#define PHY_PERICAL_WATCHDOG 2 -#define PHY_PERICAL_PHYINIT 3 -#define PHY_PERICAL_JOIN_BSS 4 -#define PHY_PERICAL_START_IBSS 5 -#define PHY_PERICAL_UP_BSS 6 -#define PHY_PERICAL_CHAN 7 -#define PHY_FULLCAL 8 - -#define PHY_PERICAL_DISABLE 0 -#define PHY_PERICAL_SPHASE 1 -#define PHY_PERICAL_MPHASE 2 -#define PHY_PERICAL_MANUAL 3 - -#define PHY_HOLD_FOR_ASSOC 1 -#define PHY_HOLD_FOR_SCAN 2 -#define PHY_HOLD_FOR_RM 4 -#define PHY_HOLD_FOR_PLT 8 -#define PHY_HOLD_FOR_MUTE 16 -#define PHY_HOLD_FOR_NOT_ASSOC 0x20 - -#define PHY_MUTE_FOR_PREISM 1 -#define PHY_MUTE_ALL 0xffffffff - -#define PHY_NOISE_FIXED_VAL (-95) -#define PHY_NOISE_FIXED_VAL_NPHY (-92) -#define PHY_NOISE_FIXED_VAL_LCNPHY (-92) - -#define PHY_MODE_CAL 0x0002 -#define PHY_MODE_NOISEM 0x0004 - -#define WLC_TXPWR_DB_FACTOR 4 - -#define WLC_NUM_RATES_CCK 4 -#define WLC_NUM_RATES_OFDM 8 -#define WLC_NUM_RATES_MCS_1_STREAM 8 -#define WLC_NUM_RATES_MCS_2_STREAM 8 -#define WLC_NUM_RATES_MCS_3_STREAM 8 -#define WLC_NUM_RATES_MCS_4_STREAM 8 -typedef struct txpwr_limits { - u8 cck[WLC_NUM_RATES_CCK]; - u8 ofdm[WLC_NUM_RATES_OFDM]; - - u8 ofdm_cdd[WLC_NUM_RATES_OFDM]; - - u8 ofdm_40_siso[WLC_NUM_RATES_OFDM]; - u8 ofdm_40_cdd[WLC_NUM_RATES_OFDM]; - - u8 mcs_20_siso[WLC_NUM_RATES_MCS_1_STREAM]; - u8 mcs_20_cdd[WLC_NUM_RATES_MCS_1_STREAM]; - u8 mcs_20_stbc[WLC_NUM_RATES_MCS_1_STREAM]; - u8 mcs_20_mimo[WLC_NUM_RATES_MCS_2_STREAM]; - - u8 mcs_40_siso[WLC_NUM_RATES_MCS_1_STREAM]; - u8 mcs_40_cdd[WLC_NUM_RATES_MCS_1_STREAM]; - u8 mcs_40_stbc[WLC_NUM_RATES_MCS_1_STREAM]; - u8 mcs_40_mimo[WLC_NUM_RATES_MCS_2_STREAM]; - u8 mcs32; -} txpwr_limits_t; - -typedef struct { - u8 vec[MAXCHANNEL / NBBY]; -} chanvec_t; - -struct rpc_info; -typedef struct shared_phy shared_phy_t; - -struct phy_pub; - -typedef struct phy_pub wlc_phy_t; - -typedef struct shared_phy_params { - si_t *sih; - void *physhim; - uint unit; - uint corerev; - uint bustype; - uint buscorerev; - char *vars; - u16 vid; - u16 did; - uint chip; - uint chiprev; - uint chippkg; - uint sromrev; - uint boardtype; - uint boardrev; - uint boardvendor; - u32 boardflags; - u32 boardflags2; -} shared_phy_params_t; - - -extern shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp); -extern void wlc_phy_shared_detach(shared_phy_t *phy_sh); -extern wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, - char *vars, struct wiphy *wiphy); -extern void wlc_phy_detach(wlc_phy_t *ppi); - -extern bool wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype, - u16 *phyrev, u16 *radioid, - u16 *radiover); -extern bool wlc_phy_get_encore(wlc_phy_t *pih); -extern u32 wlc_phy_get_coreflags(wlc_phy_t *pih); - -extern void wlc_phy_hw_clk_state_upd(wlc_phy_t *ppi, bool newstate); -extern void wlc_phy_hw_state_upd(wlc_phy_t *ppi, bool newstate); -extern void wlc_phy_init(wlc_phy_t *ppi, chanspec_t chanspec); -extern void wlc_phy_watchdog(wlc_phy_t *ppi); -extern int wlc_phy_down(wlc_phy_t *ppi); -extern u32 wlc_phy_clk_bwbits(wlc_phy_t *pih); -extern void wlc_phy_cal_init(wlc_phy_t *ppi); -extern void wlc_phy_antsel_init(wlc_phy_t *ppi, bool lut_init); - -extern void wlc_phy_chanspec_set(wlc_phy_t *ppi, chanspec_t chanspec); -extern chanspec_t wlc_phy_chanspec_get(wlc_phy_t *ppi); -extern void wlc_phy_chanspec_radio_set(wlc_phy_t *ppi, chanspec_t newch); -extern u16 wlc_phy_bw_state_get(wlc_phy_t *ppi); -extern void wlc_phy_bw_state_set(wlc_phy_t *ppi, u16 bw); - -extern void wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx); -extern void wlc_phy_por_inform(wlc_phy_t *ppi); -extern void wlc_phy_noise_sample_intr(wlc_phy_t *ppi); -extern bool wlc_phy_bist_check_phy(wlc_phy_t *ppi); - -extern void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag); - -extern void wlc_phy_switch_radio(wlc_phy_t *ppi, bool on); -extern void wlc_phy_anacore(wlc_phy_t *ppi, bool on); - - -extern void wlc_phy_BSSinit(wlc_phy_t *ppi, bool bonlyap, int rssi); - -extern void wlc_phy_chanspec_ch14_widefilter_set(wlc_phy_t *ppi, - bool wide_filter); -extern void wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band, - chanvec_t *channels); -extern chanspec_t wlc_phy_chanspec_band_firstch(wlc_phy_t *ppi, uint band); - -extern void wlc_phy_txpower_sromlimit(wlc_phy_t *ppi, uint chan, - u8 *_min_, u8 *_max_, int rate); -extern void wlc_phy_txpower_sromlimit_max_get(wlc_phy_t *ppi, uint chan, - u8 *_max_, u8 *_min_); -extern void wlc_phy_txpower_boardlimit_band(wlc_phy_t *ppi, uint band, s32 *, - s32 *, u32 *); -extern void wlc_phy_txpower_limit_set(wlc_phy_t *ppi, struct txpwr_limits *, - chanspec_t chanspec); -extern int wlc_phy_txpower_get(wlc_phy_t *ppi, uint *qdbm, bool *override); -extern int wlc_phy_txpower_set(wlc_phy_t *ppi, uint qdbm, bool override); -extern void wlc_phy_txpower_target_set(wlc_phy_t *ppi, struct txpwr_limits *); -extern bool wlc_phy_txpower_hw_ctrl_get(wlc_phy_t *ppi); -extern void wlc_phy_txpower_hw_ctrl_set(wlc_phy_t *ppi, bool hwpwrctrl); -extern u8 wlc_phy_txpower_get_target_min(wlc_phy_t *ppi); -extern u8 wlc_phy_txpower_get_target_max(wlc_phy_t *ppi); -extern bool wlc_phy_txpower_ipa_ison(wlc_phy_t *pih); - -extern void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain, - u8 rxchain); -extern void wlc_phy_stf_chain_set(wlc_phy_t *pih, u8 txchain, - u8 rxchain); -extern void wlc_phy_stf_chain_get(wlc_phy_t *pih, u8 *txchain, - u8 *rxchain); -extern u8 wlc_phy_stf_chain_active_get(wlc_phy_t *pih); -extern s8 wlc_phy_stf_ssmode_get(wlc_phy_t *pih, chanspec_t chanspec); -extern void wlc_phy_ldpc_override_set(wlc_phy_t *ppi, bool val); - -extern void wlc_phy_cal_perical(wlc_phy_t *ppi, u8 reason); -extern void wlc_phy_noise_sample_request_external(wlc_phy_t *ppi); -extern void wlc_phy_edcrs_lock(wlc_phy_t *pih, bool lock); -extern void wlc_phy_cal_papd_recal(wlc_phy_t *ppi); - -extern void wlc_phy_ant_rxdiv_set(wlc_phy_t *ppi, u8 val); -extern bool wlc_phy_ant_rxdiv_get(wlc_phy_t *ppi, u8 *pval); -extern void wlc_phy_clear_tssi(wlc_phy_t *ppi); -extern void wlc_phy_hold_upd(wlc_phy_t *ppi, mbool id, bool val); -extern void wlc_phy_mute_upd(wlc_phy_t *ppi, bool val, mbool flags); - -extern void wlc_phy_antsel_type_set(wlc_phy_t *ppi, u8 antsel_type); - -extern void wlc_phy_txpower_get_current(wlc_phy_t *ppi, tx_power_t *power, - uint channel); - -extern void wlc_phy_initcal_enable(wlc_phy_t *pih, bool initcal); -extern bool wlc_phy_test_ison(wlc_phy_t *ppi); -extern void wlc_phy_txpwr_percent_set(wlc_phy_t *ppi, u8 txpwr_percent); -extern void wlc_phy_ofdm_rateset_war(wlc_phy_t *pih, bool war); -extern void wlc_phy_bf_preempt_enable(wlc_phy_t *pih, bool bf_preempt); -extern void wlc_phy_machwcap_set(wlc_phy_t *ppi, u32 machwcap); - -extern void wlc_phy_runbist_config(wlc_phy_t *ppi, bool start_end); - -extern void wlc_phy_freqtrack_start(wlc_phy_t *ppi); -extern void wlc_phy_freqtrack_end(wlc_phy_t *ppi); - -extern const u8 *wlc_phy_get_ofdm_rate_lookup(void); - -extern s8 wlc_phy_get_tx_power_offset_by_mcs(wlc_phy_t *ppi, - u8 mcs_offset); -extern s8 wlc_phy_get_tx_power_offset(wlc_phy_t *ppi, u8 tbl_offset); -#endif /* _wlc_phy_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy_shim.c b/drivers/staging/brcm80211/brcmsmac/phy_shim.c new file mode 100644 index 000000000000..82ecdcda271f --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy_shim.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This is "two-way" interface, acting as the SHIM layer between WL and PHY layer. + * WL driver can optinally call this translation layer to do some preprocessing, then reach PHY. + * On the PHY->WL driver direction, all calls go through this layer since PHY doesn't have the + * access to wlc_hw pointer. + */ +#include +#include + +#include "bmac.h" +#include "main.h" +#include "mac80211_if.h" +#include "phy_shim.h" + +/* PHY SHIM module specific state */ +struct phy_shim_info { + struct brcms_hardware *wlc_hw; /* pointer to main wlc_hw structure */ + void *wlc; /* pointer to main wlc structure */ + void *wl; /* pointer to os-specific private state */ +}; + +struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw, + void *wl, void *wlc) { + struct phy_shim_info *physhim = NULL; + + physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC); + if (!physhim) { + wiphy_err(wlc_hw->wlc->wiphy, + "wl%d: wlc_phy_shim_attach: out of mem\n", + wlc_hw->unit); + return NULL; + } + physhim->wlc_hw = wlc_hw; + physhim->wlc = wlc; + physhim->wl = wl; + + return physhim; +} + +void wlc_phy_shim_detach(struct phy_shim_info *physhim) +{ + kfree(physhim); +} + +struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, + void (*fn) (void *arg), void *arg, + const char *name) +{ + return (struct wlapi_timer *) + brcms_init_timer(physhim->wl, fn, arg, name); +} + +void wlapi_free_timer(struct phy_shim_info *physhim, struct wlapi_timer *t) +{ + brcms_free_timer(physhim->wl, (struct brcms_timer *)t); +} + +void +wlapi_add_timer(struct phy_shim_info *physhim, struct wlapi_timer *t, uint ms, + int periodic) +{ + brcms_add_timer(physhim->wl, (struct brcms_timer *)t, ms, periodic); +} + +bool wlapi_del_timer(struct phy_shim_info *physhim, struct wlapi_timer *t) +{ + return brcms_del_timer(physhim->wl, (struct brcms_timer *)t); +} + +void wlapi_intrson(struct phy_shim_info *physhim) +{ + brcms_intrson(physhim->wl); +} + +u32 wlapi_intrsoff(struct phy_shim_info *physhim) +{ + return brcms_intrsoff(physhim->wl); +} + +void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask) +{ + brcms_intrsrestore(physhim->wl, macintmask); +} + +void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v) +{ + brcms_b_write_shm(physhim->wlc_hw, offset, v); +} + +u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset) +{ + return brcms_b_read_shm(physhim->wlc_hw, offset); +} + +void +wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask, + u16 val, int bands) +{ + brcms_b_mhf(physhim->wlc_hw, idx, mask, val, bands); +} + +void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags) +{ + brcms_b_corereset(physhim->wlc_hw, flags); +} + +void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim) +{ + brcms_c_suspend_mac_and_wait(physhim->wlc); +} + +void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode) +{ + brcms_b_switch_macfreq(physhim->wlc_hw, spurmode); +} + +void wlapi_enable_mac(struct phy_shim_info *physhim) +{ + brcms_c_enable_mac(physhim->wlc); +} + +void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val) +{ + brcms_b_mctrl(physhim->wlc_hw, mask, val); +} + +void wlapi_bmac_phy_reset(struct phy_shim_info *physhim) +{ + brcms_b_phy_reset(physhim->wlc_hw); +} + +void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw) +{ + brcms_b_bw_set(physhim->wlc_hw, bw); +} + +u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim) +{ + return brcms_b_get_txant(physhim->wlc_hw); +} + +void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk) +{ + brcms_b_phyclk_fgc(physhim->wlc_hw, clk); +} + +void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk) +{ + brcms_b_macphyclk_set(physhim->wlc_hw, clk); +} + +void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on) +{ + brcms_b_core_phypll_ctl(physhim->wlc_hw, on); +} + +void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim) +{ + brcms_b_core_phypll_reset(physhim->wlc_hw); +} + +void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim) +{ + brcms_c_ucode_wake_override_set(physhim->wlc_hw, + BRCMS_WAKE_OVERRIDE_PHYREG); +} + +void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim) +{ + brcms_c_ucode_wake_override_clear(physhim->wlc_hw, + BRCMS_WAKE_OVERRIDE_PHYREG); +} + +void +wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int offset, + int len, void *buf) +{ + brcms_b_write_template_ram(physhim->wlc_hw, offset, len, buf); +} + +u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate) +{ + return brcms_b_rate_shm_offset(physhim->wlc_hw, rate); +} + +void wlapi_ucode_sample_init(struct phy_shim_info *physhim) +{ +} + +void +wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint offset, void *buf, + int len, u32 sel) +{ + brcms_b_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel); +} + +void +wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf, + int l, u32 sel) +{ + brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel); +} diff --git a/drivers/staging/brcm80211/brcmsmac/phy_shim.h b/drivers/staging/brcm80211/brcmsmac/phy_shim.h new file mode 100644 index 000000000000..2d12bb4400f1 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/phy_shim.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * phy_shim.h: stuff defined in phy_shim.c and included only by the phy + */ + +#ifndef _BRCM_PHY_SHIM_H_ +#define _BRCM_PHY_SHIM_H_ + +#include "types.h" + +#define RADAR_TYPE_NONE 0 /* Radar type None */ +#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */ +#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */ +#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */ +#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */ +#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */ +#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */ +#define RADAR_TYPE_BIN5 7 /* long pulse radar type */ +#define RADAR_TYPE_STG2 8 /* staggered-2 radar */ +#define RADAR_TYPE_STG3 9 /* staggered-3 radar */ +#define RADAR_TYPE_FRA 10 /* French radar */ + +/* French radar pulse widths */ +#define FRA_T1_20MHZ 52770 +#define FRA_T2_20MHZ 61538 +#define FRA_T3_20MHZ 66002 +#define FRA_T1_40MHZ 105541 +#define FRA_T2_40MHZ 123077 +#define FRA_T3_40MHZ 132004 +#define FRA_ERR_20MHZ 60 +#define FRA_ERR_40MHZ 120 + +#define ANTSEL_NA 0 /* No boardlevel selection available */ +#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */ +#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */ + +/* Rx Antenna diversity control values */ +#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ +#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ +#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ +#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ +#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ +#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ + +#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */ +#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */ +#define WL_ANT_IDX_1 0 /* antenna index 1 */ +#define WL_ANT_IDX_2 1 /* antenna index 2 */ + +/* values for n_preamble_type */ +#define BRCMS_N_PREAMBLE_MIXEDMODE 0 +#define BRCMS_N_PREAMBLE_GF 1 +#define BRCMS_N_PREAMBLE_GF_BRCM 2 + +#define WL_TX_POWER_RATES_LEGACY 45 +#define WL_TX_POWER_MCS20_FIRST 12 +#define WL_TX_POWER_MCS20_NUM 16 +#define WL_TX_POWER_MCS40_FIRST 28 +#define WL_TX_POWER_MCS40_NUM 17 + + +#define WL_TX_POWER_RATES 101 +#define WL_TX_POWER_CCK_FIRST 0 +#define WL_TX_POWER_CCK_NUM 4 +#define WL_TX_POWER_OFDM_FIRST 4 /* Index for first 20MHz OFDM SISO rate */ +#define WL_TX_POWER_OFDM20_CDD_FIRST 12 /* Index for first 20MHz OFDM CDD rate */ +#define WL_TX_POWER_OFDM40_SISO_FIRST 52 /* Index for first 40MHz OFDM SISO rate */ +#define WL_TX_POWER_OFDM40_CDD_FIRST 60 /* Index for first 40MHz OFDM CDD rate */ +#define WL_TX_POWER_OFDM_NUM 8 +#define WL_TX_POWER_MCS20_SISO_FIRST 20 /* Index for first 20MHz MCS SISO rate */ +#define WL_TX_POWER_MCS20_CDD_FIRST 28 /* Index for first 20MHz MCS CDD rate */ +#define WL_TX_POWER_MCS20_STBC_FIRST 36 /* Index for first 20MHz MCS STBC rate */ +#define WL_TX_POWER_MCS20_SDM_FIRST 44 /* Index for first 20MHz MCS SDM rate */ +#define WL_TX_POWER_MCS40_SISO_FIRST 68 /* Index for first 40MHz MCS SISO rate */ +#define WL_TX_POWER_MCS40_CDD_FIRST 76 /* Index for first 40MHz MCS CDD rate */ +#define WL_TX_POWER_MCS40_STBC_FIRST 84 /* Index for first 40MHz MCS STBC rate */ +#define WL_TX_POWER_MCS40_SDM_FIRST 92 /* Index for first 40MHz MCS SDM rate */ +#define WL_TX_POWER_MCS_1_STREAM_NUM 8 +#define WL_TX_POWER_MCS_2_STREAM_NUM 8 +#define WL_TX_POWER_MCS_32 100 /* Index for 40MHz rate MCS 32 */ +#define WL_TX_POWER_MCS_32_NUM 1 + +/* sslpnphy specifics */ +#define WL_TX_POWER_MCS20_SISO_FIRST_SSN 12 /* Index for first 20MHz MCS SISO rate */ + +/* struct tx_power::flags bits */ +#define WL_TX_POWER_F_ENABLED 1 +#define WL_TX_POWER_F_HW 2 +#define WL_TX_POWER_F_MIMO 4 +#define WL_TX_POWER_F_SISO 8 + +/* values to force tx/rx chain */ +#define BRCMS_N_TXRX_CHAIN0 0 +#define BRCMS_N_TXRX_CHAIN1 1 + +extern struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw, + void *wl, void *wlc); +extern void wlc_phy_shim_detach(struct phy_shim_info *physhim); + +/* PHY to WL utility functions */ +extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, + void (*fn) (void *arg), void *arg, + const char *name); +extern void wlapi_free_timer(struct phy_shim_info *physhim, + struct wlapi_timer *t); +extern void wlapi_add_timer(struct phy_shim_info *physhim, + struct wlapi_timer *t, uint ms, int periodic); +extern bool wlapi_del_timer(struct phy_shim_info *physhim, + struct wlapi_timer *t); +extern void wlapi_intrson(struct phy_shim_info *physhim); +extern u32 wlapi_intrsoff(struct phy_shim_info *physhim); +extern void wlapi_intrsrestore(struct phy_shim_info *physhim, + u32 macintmask); + +extern void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, + u16 v); +extern u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset); +extern void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, + u16 mask, u16 val, int bands); +extern void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags); +extern void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim); +extern void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode); +extern void wlapi_enable_mac(struct phy_shim_info *physhim); +extern void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, + u32 val); +extern void wlapi_bmac_phy_reset(struct phy_shim_info *physhim); +extern void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw); +extern void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk); +extern void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk); +extern void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on); +extern void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim); +extern void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info * + physhim); +extern void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info * + physhim); +extern void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o, + int len, void *buf); +extern u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, + u8 rate); +extern void wlapi_ucode_sample_init(struct phy_shim_info *physhim); +extern void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint, + void *buf, int, u32 sel); +extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint, + const void *buf, int, u32); + +extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim, + u32 phy_mode); +extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim); +#endif /* _BRCM_PHY_SHIM_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/pmu.c b/drivers/staging/brcm80211/brcmsmac/pmu.c new file mode 100644 index 000000000000..e8b2b81d2d04 --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/pmu.c @@ -0,0 +1,474 @@ +/* + * Copyright (c) 2011 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include "pub.h" +#include "aiutils.h" +#include "pmu.h" + +/* + * external LPO crystal frequency + */ +#define EXT_ILP_HZ 32768 + +/* + * Duration for ILP clock frequency measurment in milliseconds + * + * remark: 1000 must be an integer multiple of this duration + */ +#define ILP_CALC_DUR 10 + +/* Fields in pmucontrol */ +#define PCTL_ILP_DIV_MASK 0xffff0000 +#define PCTL_ILP_DIV_SHIFT 16 +#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */ +#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */ +#define PCTL_HT_REQ_EN 0x00000100 +#define PCTL_ALP_REQ_EN 0x00000080 +#define PCTL_XTALFREQ_MASK 0x0000007c +#define PCTL_XTALFREQ_SHIFT 2 +#define PCTL_ILP_DIV_EN 0x00000002 +#define PCTL_LPO_SEL 0x00000001 + +/* ILP clock */ +#define ILP_CLOCK 32000 + +/* ALP clock on pre-PMU chips */ +#define ALP_CLOCK 20000000 + +/* pmustatus */ +#define PST_EXTLPOAVAIL 0x0100 +#define PST_WDRESET 0x0080 +#define PST_INTPEND 0x0040 +#define PST_SBCLKST 0x0030 +#define PST_SBCLKST_ILP 0x0010 +#define PST_SBCLKST_ALP 0x0020 +#define PST_SBCLKST_HT 0x0030 +#define PST_ALPAVAIL 0x0008 +#define PST_HTAVAIL 0x0004 +#define PST_RESINIT 0x0003 + +/* PMU resource bit position */ +#define PMURES_BIT(bit) (1 << (bit)) + +/* PMU corerev and chip specific PLL controls. + * PMU_PLL_XX where is PMU corerev and is an arbitrary number + * to differentiate different PLLs controlled by the same PMU rev. + */ +/* pllcontrol registers */ +/* ndiv_pwrdn, pwrdn_ch, refcomp_pwrdn, dly_ch, p1div, p2div, _bypass_sdmod */ +#define PMU1_PLL0_PLLCTL0 0 +#define PMU1_PLL0_PLLCTL1 1 +#define PMU1_PLL0_PLLCTL2 2 +#define PMU1_PLL0_PLLCTL3 3 +#define PMU1_PLL0_PLLCTL4 4 +#define PMU1_PLL0_PLLCTL5 5 + +/* pmu XtalFreqRatio */ +#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF +#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000 +#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31 + +/* 4313 resources */ +#define RES4313_BB_PU_RSRC 0 +#define RES4313_ILP_REQ_RSRC 1 +#define RES4313_XTAL_PU_RSRC 2 +#define RES4313_ALP_AVAIL_RSRC 3 +#define RES4313_RADIO_PU_RSRC 4 +#define RES4313_BG_PU_RSRC 5 +#define RES4313_VREG1P4_PU_RSRC 6 +#define RES4313_AFE_PWRSW_RSRC 7 +#define RES4313_RX_PWRSW_RSRC 8 +#define RES4313_TX_PWRSW_RSRC 9 +#define RES4313_BB_PWRSW_RSRC 10 +#define RES4313_SYNTH_PWRSW_RSRC 11 +#define RES4313_MISC_PWRSW_RSRC 12 +#define RES4313_BB_PLL_PWRSW_RSRC 13 +#define RES4313_HT_AVAIL_RSRC 14 +#define RES4313_MACPHY_CLK_AVAIL_RSRC 15 + +/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */ +static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax) +{ + u32 min_mask = 0, max_mask = 0; + uint rsrcs; + + /* # resources */ + rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT; + + /* determine min/max rsrc masks */ + switch (sih->chip) { + case BCM43224_CHIP_ID: + case BCM43225_CHIP_ID: + /* ??? */ + break; + + case BCM4313_CHIP_ID: + min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) | + PMURES_BIT(RES4313_XTAL_PU_RSRC) | + PMURES_BIT(RES4313_ALP_AVAIL_RSRC) | + PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC); + max_mask = 0xffff; + break; + default: + break; + } + + *pmin = min_mask; + *pmax = max_mask; +} + +static void +si_pmu_spuravoid_pllupdate(struct si_pub *sih, chipcregs_t *cc, u8 spuravoid) +{ + u32 tmp = 0; + + switch (sih->chip) { + case BCM43224_CHIP_ID: + case BCM43225_CHIP_ID: + if (spuravoid == 1) { + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11500010); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x000C0C06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x0F600a08); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x2001E920); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888815); + } else { + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11100010); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x000c0c06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x03000a08); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x200005c0); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888815); + } + tmp = 1 << 10; + break; + + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); + W_REG(&cc->pllcontrol_data, 0x11100008); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); + W_REG(&cc->pllcontrol_data, 0x0c000c06); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); + W_REG(&cc->pllcontrol_data, 0x03000a08); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); + W_REG(&cc->pllcontrol_data, 0x00000000); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); + W_REG(&cc->pllcontrol_data, 0x200005c0); + W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); + W_REG(&cc->pllcontrol_data, 0x88888855); + + tmp = 1 << 10; + break; + + default: + /* bail out */ + return; + } + + tmp |= R_REG(&cc->pmucontrol); + W_REG(&cc->pmucontrol, tmp); +} + +u32 si_pmu_ilp_clock(struct si_pub *sih) +{ + static u32 ilpcycles_per_sec; + + if (!PMUCTL_ENAB(sih)) + return ILP_CLOCK; + + if (ilpcycles_per_sec == 0) { + u32 start, end, delta; + u32 origidx = ai_coreidx(sih); + chipcregs_t *cc = ai_setcoreidx(sih, SI_CC_IDX); + start = R_REG(&cc->pmutimer); + mdelay(ILP_CALC_DUR); + end = R_REG(&cc->pmutimer); + delta = end - start; + ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR); + ai_setcoreidx(sih, origidx); + } + + return ilpcycles_per_sec; +} + +u16 si_pmu_fast_pwrup_delay(struct si_pub *sih) +{ + uint delay = PMU_MAX_TRANSITION_DLY; + + switch (sih->chip) { + case BCM43224_CHIP_ID: + case BCM43225_CHIP_ID: + case BCM4313_CHIP_ID: + delay = 3700; + break; + default: + break; + } + + return (u16) delay; +} + +void si_pmu_sprom_enable(struct si_pub *sih, bool enable) +{ + chipcregs_t *cc; + uint origidx; + + /* Remember original core before switch to chipc */ + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); + + /* Return to original core */ + ai_setcoreidx(sih, origidx); +} + +/* Read/write a chipcontrol reg */ +u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val) +{ + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0, + reg); + return ai_corereg(sih, SI_CC_IDX, + offsetof(chipcregs_t, chipcontrol_data), mask, val); +} + +/* Read/write a regcontrol reg */ +u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val) +{ + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0, + reg); + return ai_corereg(sih, SI_CC_IDX, + offsetof(chipcregs_t, regcontrol_data), mask, val); +} + +/* Read/write a pllcontrol reg */ +u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val) +{ + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0, + reg); + return ai_corereg(sih, SI_CC_IDX, + offsetof(chipcregs_t, pllcontrol_data), mask, val); +} + +/* PMU PLL update */ +void si_pmu_pllupd(struct si_pub *sih) +{ + ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol), + PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD); +} + +/* query alp/xtal clock frequency */ +u32 si_pmu_alp_clock(struct si_pub *sih) +{ + u32 clock = ALP_CLOCK; + + /* bail out with default */ + if (!PMUCTL_ENAB(sih)) + return clock; + + switch (sih->chip) { + case BCM43224_CHIP_ID: + case BCM43225_CHIP_ID: + case BCM4313_CHIP_ID: + /* always 20Mhz */ + clock = 20000 * 1000; + break; + default: + break; + } + + return clock; +} + +void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid) +{ + chipcregs_t *cc; + uint origidx, intr_val; + + /* Remember original core before switch to chipc */ + cc = (chipcregs_t *) ai_switch_core(sih, CC_CORE_ID, &origidx, + &intr_val); + + /* update the pll changes */ + si_pmu_spuravoid_pllupdate(sih, cc, spuravoid); + + /* Return to original core */ + ai_restore_core(sih, origidx, intr_val); +} + +/* initialize PMU */ +void si_pmu_init(struct si_pub *sih) +{ + chipcregs_t *cc; + uint origidx; + + /* Remember original core before switch to chipc */ + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); + + if (sih->pmurev == 1) + AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT); + else if (sih->pmurev >= 2) + OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT); + + /* Return to original core */ + ai_setcoreidx(sih, origidx); +} + +/* initialize PMU chip controls and other chip level stuff */ +void si_pmu_chip_init(struct si_pub *sih) +{ + uint origidx; + + /* Gate off SPROM clock and chip select signals */ + si_pmu_sprom_enable(sih, false); + + /* Remember original core */ + origidx = ai_coreidx(sih); + + /* Return to original core */ + ai_setcoreidx(sih, origidx); +} + +/* initialize PMU switch/regulators */ +void si_pmu_swreg_init(struct si_pub *sih) +{ +} + +/* initialize PLL */ +void si_pmu_pll_init(struct si_pub *sih, uint xtalfreq) +{ + chipcregs_t *cc; + uint origidx; + + /* Remember original core before switch to chipc */ + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); + + switch (sih->chip) { + case BCM4313_CHIP_ID: + case BCM43224_CHIP_ID: + case BCM43225_CHIP_ID: + /* ??? */ + break; + default: + break; + } + + /* Return to original core */ + ai_setcoreidx(sih, origidx); +} + +/* initialize PMU resources */ +void si_pmu_res_init(struct si_pub *sih) +{ + chipcregs_t *cc; + uint origidx; + u32 min_mask = 0, max_mask = 0; + + /* Remember original core before switch to chipc */ + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); + + /* Determine min/max rsrc masks */ + si_pmu_res_masks(sih, &min_mask, &max_mask); + + /* It is required to program max_mask first and then min_mask */ + + /* Program max resource mask */ + + if (max_mask) + W_REG(&cc->max_res_mask, max_mask); + + /* Program min resource mask */ + + if (min_mask) + W_REG(&cc->min_res_mask, min_mask); + + /* Add some delay; allow resources to come up and settle. */ + mdelay(2); + + /* Return to original core */ + ai_setcoreidx(sih, origidx); +} + +u32 si_pmu_measure_alpclk(struct si_pub *sih) +{ + chipcregs_t *cc; + uint origidx; + u32 alp_khz; + + if (sih->pmurev < 10) + return 0; + + /* Remember original core before switch to chipc */ + origidx = ai_coreidx(sih); + cc = ai_setcoreidx(sih, SI_CC_IDX); + + if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) { + u32 ilp_ctr, alp_hz; + + /* + * Enable the reg to measure the freq, + * in case it was disabled before + */ + W_REG(&cc->pmu_xtalfreq, + 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT); + + /* Delay for well over 4 ILP clocks */ + udelay(1000); + + /* Read the latched number of ALP ticks per 4 ILP ticks */ + ilp_ctr = + R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK; + + /* + * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT + * bit to save power + */ + W_REG(&cc->pmu_xtalfreq, 0); + + /* Calculate ALP frequency */ + alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4; + + /* + * Round to nearest 100KHz, and at + * the same time convert to KHz + */ + alp_khz = (alp_hz + 50000) / 100000 * 100; + } else + alp_khz = 0; + + /* Return to original core */ + ai_setcoreidx(sih, origidx); + + return alp_khz; +} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h b/drivers/staging/brcm80211/brcmsmac/pmu.h similarity index 53% rename from drivers/staging/brcm80211/brcmsmac/wlc_pmu.h rename to drivers/staging/brcm80211/brcmsmac/pmu.h index bd5b809b2e31..0c7e48c4bcd8 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h +++ b/drivers/staging/brcm80211/brcmsmac/pmu.h @@ -15,13 +15,10 @@ */ -#ifndef WLC_PMU_H_ -#define WLC_PMU_H_ - -#include - -#include +#ifndef _BRCM_PMU_H_ +#define _BRCM_PMU_H_ +#include "types.h" /* * LDO selections used in si_pmu_set_ldo_voltage */ @@ -36,23 +33,20 @@ #define SET_LDO_VOLTAGE_LNLDO1 9 #define SET_LDO_VOLTAGE_LNLDO2_SEL 10 -extern void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage); -extern u16 si_pmu_fast_pwrup_delay(si_t *sih); -extern void si_pmu_sprom_enable(si_t *sih, bool enable); -extern u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val); -extern u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val); -extern u32 si_pmu_ilp_clock(si_t *sih); -extern u32 si_pmu_alp_clock(si_t *sih); -extern void si_pmu_pllupd(si_t *sih); -extern void si_pmu_spuravoid(si_t *sih, u8 spuravoid); -extern u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val); -extern void si_pmu_init(si_t *sih); -extern void si_pmu_chip_init(si_t *sih); -extern void si_pmu_pll_init(si_t *sih, u32 xtalfreq); -extern void si_pmu_res_init(si_t *sih); -extern void si_pmu_swreg_init(si_t *sih); -extern u32 si_pmu_measure_alpclk(si_t *sih); -extern bool si_pmu_is_otp_powered(si_t *sih); -extern void si_pmu_otp_power(si_t *sih, bool on); +extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih); +extern void si_pmu_sprom_enable(struct si_pub *sih, bool enable); +extern u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val); +extern u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val); +extern u32 si_pmu_ilp_clock(struct si_pub *sih); +extern u32 si_pmu_alp_clock(struct si_pub *sih); +extern void si_pmu_pllupd(struct si_pub *sih); +extern void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid); +extern u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val); +extern void si_pmu_init(struct si_pub *sih); +extern void si_pmu_chip_init(struct si_pub *sih); +extern void si_pmu_pll_init(struct si_pub *sih, u32 xtalfreq); +extern void si_pmu_res_init(struct si_pub *sih); +extern void si_pmu_swreg_init(struct si_pub *sih); +extern u32 si_pmu_measure_alpclk(struct si_pub *sih); -#endif /* WLC_PMU_H_ */ +#endif /* _BRCM_PMU_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h b/drivers/staging/brcm80211/brcmsmac/pub.h similarity index 58% rename from drivers/staging/brcm80211/brcmsmac/wlc_pub.h rename to drivers/staging/brcm80211/brcmsmac/pub.h index 9334deacda12..01d74609560f 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pub.h +++ b/drivers/staging/brcm80211/brcmsmac/pub.h @@ -14,10 +14,14 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_pub_h_ -#define _wlc_pub_h_ +#ifndef _BRCM_PUB_H_ +#define _BRCM_PUB_H_ -#define WLC_NUMRATES 16 /* max # of rates in a rateset */ +#include +#include "types.h" +#include "defs.h" + +#define BRCMS_NUMRATES 16 /* max # of rates in a rateset */ #define MAXMULTILIST 32 /* max # multicast addresses */ #define D11_PHY_HDR_LEN 6 /* Phy header length - 6 bytes */ @@ -32,36 +36,37 @@ #define PHY_TYPE_HT 7 /* Phy type 3-Stream N */ /* bw */ -#define WLC_10_MHZ 10 /* 10Mhz nphy channel bandwidth */ -#define WLC_20_MHZ 20 /* 20Mhz nphy channel bandwidth */ -#define WLC_40_MHZ 40 /* 40Mhz nphy channel bandwidth */ +#define BRCMS_10_MHZ 10 /* 10Mhz nphy channel bandwidth */ +#define BRCMS_20_MHZ 20 /* 20Mhz nphy channel bandwidth */ +#define BRCMS_40_MHZ 40 /* 40Mhz nphy channel bandwidth */ -#define CHSPEC_WLC_BW(chanspec) (CHSPEC_IS40(chanspec) ? WLC_40_MHZ : \ - CHSPEC_IS20(chanspec) ? WLC_20_MHZ : \ - WLC_10_MHZ) +#define CHSPEC_WLC_BW(chanspec) (CHSPEC_IS40(chanspec) ? BRCMS_40_MHZ : \ + CHSPEC_IS20(chanspec) ? BRCMS_20_MHZ : \ + BRCMS_10_MHZ) -#define WLC_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */ -#define WLC_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */ -#define WLC_RSSI_VERY_LOW -80 /* Very low quality cutoffs */ -#define WLC_RSSI_LOW -70 /* Low quality cutoffs */ -#define WLC_RSSI_GOOD -68 /* Good quality cutoffs */ -#define WLC_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */ -#define WLC_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */ +#define BRCMS_RSSI_MINVAL -200 /* Low value, e.g. for forcing roam */ +#define BRCMS_RSSI_NO_SIGNAL -91 /* NDIS RSSI link quality cutoffs */ +#define BRCMS_RSSI_VERY_LOW -80 /* Very low quality cutoffs */ +#define BRCMS_RSSI_LOW -70 /* Low quality cutoffs */ +#define BRCMS_RSSI_GOOD -68 /* Good quality cutoffs */ +#define BRCMS_RSSI_VERY_GOOD -58 /* Very good quality cutoffs */ +#define BRCMS_RSSI_EXCELLENT -57 /* Excellent quality cutoffs */ -#define WLC_PHYTYPE(_x) (_x) /* macro to perform WLC PHY -> D11 PHY TYPE, currently 1:1 */ +/* macro to perform PHY -> D11 PHY TYPE, currently 1:1 */ +#define BRCMS_PHYTYPE(_x) (_x) #define MA_WINDOW_SZ 8 /* moving average window size */ -#define WLC_SNR_INVALID 0 /* invalid SNR value */ +#define BRCMS_SNR_INVALID 0 /* invalid SNR value */ /* a large TX Power as an init value to factor out of min() calculations, * keep low enough to fit in an s8, units are .25 dBm */ -#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ +#define BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ /* rate related definitions */ -#define WLC_RATE_FLAG 0x80 /* Flag to indicate it is a basic rate */ -#define WLC_RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */ +#define BRCMS_RATE_FLAG 0x80 /* Flag to indicate it is a basic rate */ +#define BRCMS_RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */ /* legacy rx Antenna diversity for SISO rates */ #define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ @@ -96,9 +101,13 @@ #define AIDMAPSZ (roundup(MAXSCB, NBBY)/NBBY) /* aid bitmap size in bytes */ #endif /* AIDMAPSZ */ -struct ieee80211_tx_queue_params; +#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */ -typedef struct wlc_tunables { +#define WL_SPURAVOID_OFF 0 +#define WL_SPURAVOID_ON1 1 +#define WL_SPURAVOID_ON2 2 + +struct brcms_tunables { int ntxd; /* size of tx descriptor table */ int nrxd; /* size of rx descriptor table */ int rxbufsz; /* size of rx buffers to post */ @@ -114,14 +123,15 @@ typedef struct wlc_tunables { int rxbnd; /* max # of rx bufs to process before deferring to dpc */ int txsbnd; /* max # tx status to process in wlc_txstatus() */ int memreserved; /* memory reserved for BMAC's USB dma rx */ -} wlc_tunables_t; +}; -typedef struct wlc_rateset { +struct brcms_rateset { uint count; /* number of rates in rates[] */ - u8 rates[WLC_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ + /* rates in 500kbps units w/hi bit set if basic */ + u8 rates[BRCMS_NUMRATES]; u8 htphy_membership; /* HT PHY Membership */ u8 mcs[MCSSET_LEN]; /* supported mcs index bit map */ -} wlc_rateset_t; +}; struct rsn_parms { u8 flags; /* misc booleans (e.g., supported) */ @@ -134,7 +144,6 @@ struct rsn_parms { }; /* - * buffer length needed for wlc_format_ssid * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. */ #define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) @@ -152,8 +161,8 @@ struct rsn_parms { IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_GRN_FLD |\ IEEE80211_HT_CAP_MAX_AMSDU | IEEE80211_HT_CAP_DSSSCCK40) -/* wlc internal bss_info, wl external one is in wlioctl.h */ -typedef struct wlc_bss_info { +/* wlc internal bss_info */ +struct brcms_bss_info { u8 BSSID[ETH_ALEN]; /* network BSSID */ u16 flags; /* flags for internal attributes */ u8 SSID_len; /* the length of SSID */ @@ -168,7 +177,7 @@ typedef struct wlc_bss_info { u8 dtim_period; /* DTIM period */ s8 phy_noise; /* noise right after tx (in dBm) */ u16 capability; /* Capability information */ - u8 wme_qosinfo; /* QoS Info from WME IE; valid if WLC_BSS_WME flag set */ + u8 wme_qosinfo; /* QoS Info from WME IE; valid if BSS_WME flag set */ struct rsn_parms wpa; struct rsn_parms wpa2; u16 qbss_load_aac; /* qbss load available admission capacity */ @@ -176,21 +185,7 @@ typedef struct wlc_bss_info { u8 qbss_load_chan_free; /* indicates how free the channel is */ u8 mcipher; /* multicast cipher */ u8 wpacfg; /* wpa config index */ -} wlc_bss_info_t; - -/* forward declarations */ -struct wlc_if; - -/* wlc_ioctl error codes */ -#define WLC_ENOIOCTL 1 /* No such Ioctl */ -#define WLC_EINVAL 2 /* Invalid value */ -#define WLC_ETOOSMALL 3 /* Value too small */ -#define WLC_ETOOBIG 4 /* Value too big */ -#define WLC_ERANGE 5 /* Out of range */ -#define WLC_EDOWN 6 /* Down */ -#define WLC_EUP 7 /* Up */ -#define WLC_ENOMEM 8 /* No Memory */ -#define WLC_EBUSY 9 /* Busy */ +}; /* IOVar flags for common error checks */ #define IOVF_MFG (1<<3) /* flag for mfgtest iovars */ @@ -211,7 +206,7 @@ struct wlc_if; /* watchdog down and dump callback function proto's */ typedef int (*watchdog_fn_t) (void *handle); typedef int (*down_fn_t) (void *handle); -typedef int (*dump_fn_t) (void *handle, struct bcmstrbuf *b); +typedef int (*dump_fn_t) (void *handle, struct brcmu_strbuf *b); /* IOVar handler * @@ -222,14 +217,14 @@ typedef int (*dump_fn_t) (void *handle, struct bcmstrbuf *b); * params/plen - parameters and length for a get, input only. * arg/len - buffer and length for value to be set or retrieved, input or output. * vsize - value size, valid for integer type only. - * wlcif - interface context (wlc_if pointer) + * wlcif - interface context (brcms_c_if pointer) * * All pointers may point into the same buffer. */ -typedef int (*iovar_fn_t) (void *handle, const bcm_iovar_t *vi, +typedef int (*iovar_fn_t) (void *handle, const struct brcmu_iovar *vi, u32 actionid, const char *name, void *params, uint plen, void *arg, int alen, int vsize, - struct wlc_if *wlcif); + struct brcms_c_if *wlcif); #define MAC80211_PROMISC_BCNS (1 << 0) #define MAC80211_SCAN (1 << 1) @@ -238,20 +233,21 @@ typedef int (*iovar_fn_t) (void *handle, const bcm_iovar_t *vi, * Public portion of "common" os-independent state structure. * The wlc handle points at this. */ -struct wlc_pub { +struct brcms_pub { void *wlc; struct ieee80211_hw *ieee_hw; struct scb *global_scb; - scb_ampdu_t *global_ampdu; + struct scb_ampdu *global_ampdu; uint mac80211_state; uint unit; /* device instance number */ uint corerev; /* core revision */ - si_t *sih; /* SB handle (cookie for siutils calls) */ + struct si_pub *sih; /* SI handle (cookie for siutils calls) */ char *vars; /* "environment" name=value */ bool up; /* interface up and running */ bool hw_off; /* HW is off */ - wlc_tunables_t *tunables; /* tunables: ntxd, nrxd, maxscb, etc. */ + /* tunables: ntxd, nrxd, maxscb, etc. */ + struct brcms_tunables *tunables; bool hw_up; /* one time hw up/down(from boot or hibernation) */ bool _piomode; /* true if pio mode *//* BMAC_NOTE: NEED In both */ uint _nbands; /* # bands supported */ @@ -307,13 +303,10 @@ struct wlc_pub { u16 boardrev; /* version # of particular board */ u8 sromrev; /* version # of the srom */ - char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */ + char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */ u32 boardflags; /* Board specific flags from srom */ u32 boardflags2; /* More board flags if sromrev >= 4 */ bool tempsense_disable; /* disable periodic tempsense check */ - - bool _lmac; /* lmac module included and enabled */ - bool _lmacproto; /* lmac protocol module included and enabled */ bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */ bool _ampdumac; /* mac assist ampdu enabled or not */ @@ -321,7 +314,7 @@ struct wlc_pub { }; /* wl_monitor rx status per packet */ -typedef struct wl_rxsts { +struct wl_rxsts { uint pkterror; /* error flags per pkt */ uint phytype; /* 802.11 A/B/G ... */ uint channel; /* channel */ @@ -335,8 +328,8 @@ typedef struct wl_rxsts { uint preamble; /* Unknown, short, long */ uint encoding; /* Unknown, CCK, PBCC, OFDM */ uint nfrmtype; /* special 802.11n frames(AMPDU, AMSDU) */ - struct wl_if *wlif; /* wl interface */ -} wl_rxsts_t; + struct brcms_if *wlif; /* wl interface */ +}; /* status per error RX pkt */ #define WL_RXS_CRC_ERROR 0x00000001 /* CRC Error in packet */ @@ -371,13 +364,12 @@ typedef struct wl_rxsts { #define WL_RXS_NFRM_AMSDU_FIRST 0x00000004 /* first MSDU in A-MSDU */ #define WL_RXS_NFRM_AMSDU_SUB 0x00000008 /* subsequent MSDU(s) in A-MSDU */ -/* forward declare and use the struct notation so we don't have to - * have it defined if not necessary. - */ -struct wlc_info; -struct wlc_hw_info; -struct wlc_bsscfg; -struct wlc_if; +enum wlc_par_id { + IOV_MPC = 1, + IOV_RTSTHRESH, + IOV_QTXPOWER, + IOV_BCN_LI_BCN /* Beacon listen interval in # of beacons */ +}; /*********************************************** * Feature-related macros to optimize out code * @@ -426,149 +418,238 @@ struct wlc_if; #define PROMISC_ENAB(wlc) ((wlc)->promisc) -#define WLC_PREC_COUNT 16 /* Max precedence level implemented */ +#define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */ /* pri is priority encoded in the packet. This maps the Packet priority to * enqueue precedence as defined in wlc_prec_map */ extern const u8 wlc_prio2prec_map[]; -#define WLC_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7] +#define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7] /* This maps priority to one precedence higher - Used by PS-Poll response packets to * simulate enqueue-at-head operation, but still maintain the order on the queue */ -#define WLC_PRIO_TO_HI_PREC(pri) min(WLC_PRIO_TO_PREC(pri) + 1, WLC_PREC_COUNT - 1) +#define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\ + BRCMS_PREC_COUNT - 1) extern const u8 wme_fifo2ac[]; #define WME_PRIO2AC(prio) wme_fifo2ac[prio2fifo[(prio)]] /* Mask to describe all precedence levels */ -#define WLC_PREC_BMP_ALL MAXBITVAL(WLC_PREC_COUNT) +#define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT) /* Define a bitmap of precedences comprised by each AC */ -#define WLC_PREC_BMP_AC_BE (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BE)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \ - NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_EE)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_EE))) -#define WLC_PREC_BMP_AC_BK (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_BK)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \ - NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NONE)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NONE))) -#define WLC_PREC_BMP_AC_VI (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_CL)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \ - NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VI)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VI))) -#define WLC_PREC_BMP_AC_VO (NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_VO)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \ - NBITVAL(WLC_PRIO_TO_PREC(PRIO_8021D_NC)) | \ - NBITVAL(WLC_PRIO_TO_HI_PREC(PRIO_8021D_NC))) +#define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \ + NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE))) +#define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \ + NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE))) +#define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \ + NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI))) +#define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \ + NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC))) /* WME Support */ #define WME_ENAB(pub) ((pub)->_wme != OFF) #define WME_AUTO(wlc) ((wlc)->pub->_wme == AUTO) -#define WLC_USE_COREFLAGS 0xffffffff /* invalid core flags, use the saved coreflags */ +/* invalid core flags, use the saved coreflags */ +#define BRCMS_USE_COREFLAGS 0xffffffff /* network protection config */ -#define WLC_PROT_G_SPEC 1 /* SPEC g protection */ -#define WLC_PROT_G_OVR 2 /* SPEC g prot override */ -#define WLC_PROT_G_USER 3 /* gmode specified by user */ -#define WLC_PROT_OVERLAP 4 /* overlap */ -#define WLC_PROT_N_USER 10 /* nmode specified by user */ -#define WLC_PROT_N_CFG 11 /* n protection */ -#define WLC_PROT_N_CFG_OVR 12 /* n protection override */ -#define WLC_PROT_N_NONGF 13 /* non-GF protection */ -#define WLC_PROT_N_NONGF_OVR 14 /* non-GF protection override */ -#define WLC_PROT_N_PAM_OVR 15 /* n preamble override */ -#define WLC_PROT_N_OBSS 16 /* non-HT OBSS present */ +#define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */ +#define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */ +#define BRCMS_PROT_G_USER 3 /* gmode specified by user */ +#define BRCMS_PROT_OVERLAP 4 /* overlap */ +#define BRCMS_PROT_N_USER 10 /* nmode specified by user */ +#define BRCMS_PROT_N_CFG 11 /* n protection */ +#define BRCMS_PROT_N_CFG_OVR 12 /* n protection override */ +#define BRCMS_PROT_N_NONGF 13 /* non-GF protection */ +#define BRCMS_PROT_N_NONGF_OVR 14 /* non-GF protection override */ +#define BRCMS_PROT_N_PAM_OVR 15 /* n preamble override */ +#define BRCMS_PROT_N_OBSS 16 /* non-HT OBSS present */ + +/* + * 54g modes (basic bits may still be overridden) + * + * GMODE_LEGACY_B Rateset: 1b, 2b, 5.5, 11 + * Preamble: Long + * Shortslot: Off + * GMODE_AUTO Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 + * Extended Rateset: 6, 9, 12, 48 + * Preamble: Long + * Shortslot: Auto + * GMODE_ONLY Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54 + * Extended Rateset: 6b, 9, 12b, 48 + * Preamble: Short required + * Shortslot: Auto + * GMODE_B_DEFERRED Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 + * Extended Rateset: 6, 9, 12, 48 + * Preamble: Long + * Shortslot: On + * GMODE_PERFORMANCE Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54 + * Preamble: Short required + * Shortslot: On and required + * GMODE_LRS Rateset: 1b, 2b, 5.5b, 11b + * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54 + * Preamble: Long + * Shortslot: Auto + */ +#define GMODE_LEGACY_B 0 +#define GMODE_AUTO 1 +#define GMODE_ONLY 2 +#define GMODE_B_DEFERRED 3 +#define GMODE_PERFORMANCE 4 +#define GMODE_LRS 5 +#define GMODE_MAX 6 + +/* values for PLCPHdr_override */ +#define BRCMS_PLCP_AUTO -1 +#define BRCMS_PLCP_SHORT 0 +#define BRCMS_PLCP_LONG 1 + +/* values for g_protection_override and n_protection_override */ +#define BRCMS_PROTECTION_AUTO -1 +#define BRCMS_PROTECTION_OFF 0 +#define BRCMS_PROTECTION_ON 1 +#define BRCMS_PROTECTION_MMHDR_ONLY 2 +#define BRCMS_PROTECTION_CTS_ONLY 3 + +/* values for g_protection_control and n_protection_control */ +#define BRCMS_PROTECTION_CTL_OFF 0 +#define BRCMS_PROTECTION_CTL_LOCAL 1 +#define BRCMS_PROTECTION_CTL_OVERLAP 2 + +/* values for n_protection */ +#define BRCMS_N_PROTECTION_OFF 0 +#define BRCMS_N_PROTECTION_OPTIONAL 1 +#define BRCMS_N_PROTECTION_20IN40 2 +#define BRCMS_N_PROTECTION_MIXEDMODE 3 + +/* values for band specific 40MHz capabilities */ +#define BRCMS_N_BW_20ALL 0 +#define BRCMS_N_BW_40ALL 1 +#define BRCMS_N_BW_20IN2G_40IN5G 2 + +/* bitflags for SGI support (sgi_rx iovar) */ +#define BRCMS_N_SGI_20 0x01 +#define BRCMS_N_SGI_40 0x02 + +/* defines used by the nrate iovar */ +#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ +#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ +#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ +#define NRATE_STF_SHIFT 8 /* stf mode shift */ +#define NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ +#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */ +#define NRATE_SGI_MASK 0x00800000 /* sgi mode */ +#define NRATE_SGI_SHIFT 23 /* sgi mode */ +#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ +#define NRATE_LDPC_SHIFT 22 /* ldpc shift */ + +#define NRATE_STF_SISO 0 /* stf mode SISO */ +#define NRATE_STF_CDD 1 /* stf mode CDD */ +#define NRATE_STF_STBC 2 /* stf mode STBC */ +#define NRATE_STF_SDM 3 /* stf mode SDM */ + +#define ANT_SELCFG_MAX 4 /* max number of antenna configurations */ + +#define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */ + +struct brcms_antselcfg { + u8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */ + u8 num_antcfg; /* number of available antenna configurations */ +}; /* common functions for every port */ -extern void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit, - bool piomode, void *regsva, uint bustype, void *btparam, - uint *perr); -extern uint wlc_detach(struct wlc_info *wlc); -extern int wlc_up(struct wlc_info *wlc); -extern uint wlc_down(struct wlc_info *wlc); +extern void *brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, + uint unit, bool piomode, void *regsva, uint bustype, + void *btparam, uint *perr); +extern uint brcms_c_detach(struct brcms_c_info *wlc); +extern int brcms_c_up(struct brcms_c_info *wlc); +extern uint brcms_c_down(struct brcms_c_info *wlc); -extern int wlc_set(struct wlc_info *wlc, int cmd, int arg); -extern int wlc_get(struct wlc_info *wlc, int cmd, int *arg); -extern int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg); -extern int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg); -extern bool wlc_chipmatch(u16 vendor, u16 device); -extern void wlc_init(struct wlc_info *wlc); -extern void wlc_reset(struct wlc_info *wlc); +extern int brcms_c_set(struct brcms_c_info *wlc, int cmd, int arg); +extern int brcms_c_get(struct brcms_c_info *wlc, int cmd, int *arg); +extern bool brcms_c_chipmatch(u16 vendor, u16 device); +extern void brcms_c_init(struct brcms_c_info *wlc); +extern void brcms_c_reset(struct brcms_c_info *wlc); -extern void wlc_intrson(struct wlc_info *wlc); -extern u32 wlc_intrsoff(struct wlc_info *wlc); -extern void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask); -extern bool wlc_intrsupd(struct wlc_info *wlc); -extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc); -extern bool wlc_dpc(struct wlc_info *wlc, bool bounded); -extern bool wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, - struct ieee80211_hw *hw); -extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params, - int p_len, void *arg, int len, bool set, - struct wlc_if *wlcif); -extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, - struct wlc_if *wlcif); -extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid); +extern void brcms_c_intrson(struct brcms_c_info *wlc); +extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc); +extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask); +extern bool brcms_c_intrsupd(struct brcms_c_info *wlc); +extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc); +extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded); +extern bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, + struct sk_buff *sdu, + struct ieee80211_hw *hw); +extern int brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, + struct brcms_c_if *wlcif); +extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid); /* helper functions */ -extern void wlc_statsupd(struct wlc_info *wlc); -extern void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val); -extern int wlc_get_header_len(void); -extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); -extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, - const u8 *addr); -extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, +extern void brcms_c_statsupd(struct brcms_c_info *wlc); +extern void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, + int val); +extern int brcms_c_get_header_len(void); +extern void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, + bool promisc); +extern void brcms_c_set_addrmatch(struct brcms_c_info *wlc, + int match_reg_offset, + const u8 *addr); +extern void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, const struct ieee80211_tx_queue_params *arg, bool suspend); -extern struct wlc_pub *wlc_pub(void *wlc); +extern struct brcms_pub *brcms_c_pub(void *wlc); /* common functions for every port */ -extern void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, +extern void brcms_c_mhf(struct brcms_c_info *wlc, u8 idx, u16 mask, u16 val, int bands); -extern void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset); -extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs); +extern void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, + wlc_rateset_t *rateset); +extern void brcms_default_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs); -struct ieee80211_sta; -extern void wlc_ampdu_flush(struct wlc_info *wlc, struct ieee80211_sta *sta, - u16 tid); +extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc, + struct ieee80211_sta *sta, u16 tid); +extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, + u8 ba_wsize, uint max_rx_ampdu_bytes); +extern int brcms_c_set_par(struct brcms_c_info *wlc, enum wlc_par_id par_id, + int val); +extern int brcms_c_get_par(struct brcms_c_info *wlc, enum wlc_par_id par_id, + int *ret_int_ptr); +extern char *getvar(char *vars, const char *name); +extern int getintvar(char *vars, const char *name); /* wlc_phy.c helper functions */ -extern void wlc_set_ps_ctrl(struct wlc_info *wlc); -extern void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val); +extern void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc); +extern void brcms_c_mctrl(struct brcms_c_info *wlc, u32 mask, u32 val); -/* ioctl */ -extern int wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, - void *arg, - int len, bool set); - -extern int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, - const char *name, void *hdl, iovar_fn_t iovar_fn, +extern int brcms_c_module_register(struct brcms_pub *pub, + const char *name, void *hdl, watchdog_fn_t watchdog_fn, down_fn_t down_fn); -extern int wlc_module_unregister(struct wlc_pub *pub, const char *name, +extern int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, void *hdl); -extern void wlc_suspend_mac_and_wait(struct wlc_info *wlc); -extern void wlc_enable_mac(struct wlc_info *wlc); -extern void wlc_associate_upd(struct wlc_info *wlc, bool state); -extern void wlc_scan_start(struct wlc_info *wlc); -extern void wlc_scan_stop(struct wlc_info *wlc); -extern int wlc_get_curband(struct wlc_info *wlc); -extern void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop); - -#if defined(BCMDBG) -extern int wlc_iocregchk(struct wlc_info *wlc, uint band); -#endif +extern void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc); +extern void brcms_c_enable_mac(struct brcms_c_info *wlc); +extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state); +extern void brcms_c_scan_start(struct brcms_c_info *wlc); +extern void brcms_c_scan_stop(struct brcms_c_info *wlc); +extern int brcms_c_get_curband(struct brcms_c_info *wlc); +extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, + bool drop); /* helper functions */ -extern bool wlc_check_radio_disabled(struct wlc_info *wlc); -extern bool wlc_radio_monitor_stop(struct wlc_info *wlc); - -#if defined(BCMDBG) -extern int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len); -#endif +extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); +extern bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc); #define MAXBANDS 2 /* Maximum #of bands */ /* bandstate array indices */ @@ -579,6 +660,6 @@ extern int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) #define BAND_5G_NAME "5G" /* BMAC RPC: 7 u32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */ -#define WLC_RPCTX_PARAMS 32 +#define BRCMS_RPCTX_PARAMS 32 -#endif /* _wlc_pub_h_ */ +#endif /* _BRCM_PUB_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c b/drivers/staging/brcm80211/brcmsmac/rate.c similarity index 76% rename from drivers/staging/brcm80211/brcmsmac/wlc_rate.c rename to drivers/staging/brcm80211/brcmsmac/rate.c index 87b252d6a7f5..f0e4b99c2566 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.c +++ b/drivers/staging/brcm80211/brcmsmac/rate.c @@ -13,26 +13,16 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include -#include "wlc_types.h" #include "d11.h" -#include "wl_dbg.h" -#include "wlc_cfg.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_rate.h" +#include "pub.h" +#include "rate.h" /* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */ -const u8 rate_info[WLC_MAXRATE + 1] = { +const u8 rate_info[BRCM_MAXRATE + 1] = { /* 0 1 2 3 4 5 6 7 8 9 */ /* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10 */ 0x00, 0x37, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x00, @@ -48,134 +38,143 @@ const u8 rate_info[WLC_MAXRATE + 1] = { }; /* rates are in units of Kbps */ -const mcs_info_t mcs_table[MCS_TABLE_SIZE] = { +const struct brcms_mcs_info mcs_table[MCS_TABLE_SIZE] = { /* MCS 0: SS 1, MOD: BPSK, CR 1/2 */ {6500, 13500, CEIL(6500 * 10, 9), CEIL(13500 * 10, 9), 0x00, - WLC_RATE_6M}, + BRCM_RATE_6M}, /* MCS 1: SS 1, MOD: QPSK, CR 1/2 */ {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x08, - WLC_RATE_12M}, + BRCM_RATE_12M}, /* MCS 2: SS 1, MOD: QPSK, CR 3/4 */ {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x0A, - WLC_RATE_18M}, + BRCM_RATE_18M}, /* MCS 3: SS 1, MOD: 16QAM, CR 1/2 */ {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x10, - WLC_RATE_24M}, + BRCM_RATE_24M}, /* MCS 4: SS 1, MOD: 16QAM, CR 3/4 */ {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x12, - WLC_RATE_36M}, + BRCM_RATE_36M}, /* MCS 5: SS 1, MOD: 64QAM, CR 2/3 */ {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x19, - WLC_RATE_48M}, + BRCM_RATE_48M}, /* MCS 6: SS 1, MOD: 64QAM, CR 3/4 */ {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x1A, - WLC_RATE_54M}, + BRCM_RATE_54M}, /* MCS 7: SS 1, MOD: 64QAM, CR 5/6 */ {65000, 135000, CEIL(65000 * 10, 9), CEIL(135000 * 10, 9), 0x1C, - WLC_RATE_54M}, + BRCM_RATE_54M}, /* MCS 8: SS 2, MOD: BPSK, CR 1/2 */ {13000, 27000, CEIL(13000 * 10, 9), CEIL(27000 * 10, 9), 0x40, - WLC_RATE_6M}, + BRCM_RATE_6M}, /* MCS 9: SS 2, MOD: QPSK, CR 1/2 */ {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0x48, - WLC_RATE_12M}, + BRCM_RATE_12M}, /* MCS 10: SS 2, MOD: QPSK, CR 3/4 */ {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x4A, - WLC_RATE_18M}, + BRCM_RATE_18M}, /* MCS 11: SS 2, MOD: 16QAM, CR 1/2 */ {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0x50, - WLC_RATE_24M}, + BRCM_RATE_24M}, /* MCS 12: SS 2, MOD: 16QAM, CR 3/4 */ {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x52, - WLC_RATE_36M}, + BRCM_RATE_36M}, /* MCS 13: SS 2, MOD: 64QAM, CR 2/3 */ {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0x59, - WLC_RATE_48M}, + BRCM_RATE_48M}, /* MCS 14: SS 2, MOD: 64QAM, CR 3/4 */ {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x5A, - WLC_RATE_54M}, + BRCM_RATE_54M}, /* MCS 15: SS 2, MOD: 64QAM, CR 5/6 */ {130000, 270000, CEIL(130000 * 10, 9), CEIL(270000 * 10, 9), 0x5C, - WLC_RATE_54M}, + BRCM_RATE_54M}, /* MCS 16: SS 3, MOD: BPSK, CR 1/2 */ {19500, 40500, CEIL(19500 * 10, 9), CEIL(40500 * 10, 9), 0x80, - WLC_RATE_6M}, + BRCM_RATE_6M}, /* MCS 17: SS 3, MOD: QPSK, CR 1/2 */ {39000, 81000, CEIL(39000 * 10, 9), CEIL(81000 * 10, 9), 0x88, - WLC_RATE_12M}, + BRCM_RATE_12M}, /* MCS 18: SS 3, MOD: QPSK, CR 3/4 */ {58500, 121500, CEIL(58500 * 10, 9), CEIL(121500 * 10, 9), 0x8A, - WLC_RATE_18M}, + BRCM_RATE_18M}, /* MCS 19: SS 3, MOD: 16QAM, CR 1/2 */ {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0x90, - WLC_RATE_24M}, + BRCM_RATE_24M}, /* MCS 20: SS 3, MOD: 16QAM, CR 3/4 */ {117000, 243000, CEIL(117000 * 10, 9), CEIL(243000 * 10, 9), 0x92, - WLC_RATE_36M}, + BRCM_RATE_36M}, /* MCS 21: SS 3, MOD: 64QAM, CR 2/3 */ {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0x99, - WLC_RATE_48M}, + BRCM_RATE_48M}, /* MCS 22: SS 3, MOD: 64QAM, CR 3/4 */ {175500, 364500, CEIL(175500 * 10, 9), CEIL(364500 * 10, 9), 0x9A, - WLC_RATE_54M}, + BRCM_RATE_54M}, /* MCS 23: SS 3, MOD: 64QAM, CR 5/6 */ {195000, 405000, CEIL(195000 * 10, 9), CEIL(405000 * 10, 9), 0x9B, - WLC_RATE_54M}, + BRCM_RATE_54M}, /* MCS 24: SS 4, MOD: BPSK, CR 1/2 */ {26000, 54000, CEIL(26000 * 10, 9), CEIL(54000 * 10, 9), 0xC0, - WLC_RATE_6M}, + BRCM_RATE_6M}, /* MCS 25: SS 4, MOD: QPSK, CR 1/2 */ {52000, 108000, CEIL(52000 * 10, 9), CEIL(108000 * 10, 9), 0xC8, - WLC_RATE_12M}, + BRCM_RATE_12M}, /* MCS 26: SS 4, MOD: QPSK, CR 3/4 */ {78000, 162000, CEIL(78000 * 10, 9), CEIL(162000 * 10, 9), 0xCA, - WLC_RATE_18M}, + BRCM_RATE_18M}, /* MCS 27: SS 4, MOD: 16QAM, CR 1/2 */ {104000, 216000, CEIL(104000 * 10, 9), CEIL(216000 * 10, 9), 0xD0, - WLC_RATE_24M}, + BRCM_RATE_24M}, /* MCS 28: SS 4, MOD: 16QAM, CR 3/4 */ {156000, 324000, CEIL(156000 * 10, 9), CEIL(324000 * 10, 9), 0xD2, - WLC_RATE_36M}, + BRCM_RATE_36M}, /* MCS 29: SS 4, MOD: 64QAM, CR 2/3 */ {208000, 432000, CEIL(208000 * 10, 9), CEIL(432000 * 10, 9), 0xD9, - WLC_RATE_48M}, + BRCM_RATE_48M}, /* MCS 30: SS 4, MOD: 64QAM, CR 3/4 */ {234000, 486000, CEIL(234000 * 10, 9), CEIL(486000 * 10, 9), 0xDA, - WLC_RATE_54M}, + BRCM_RATE_54M}, /* MCS 31: SS 4, MOD: 64QAM, CR 5/6 */ {260000, 540000, CEIL(260000 * 10, 9), CEIL(540000 * 10, 9), 0xDB, - WLC_RATE_54M}, + BRCM_RATE_54M}, /* MCS 32: SS 1, MOD: BPSK, CR 1/2 */ - {0, 6000, 0, CEIL(6000 * 10, 9), 0x00, WLC_RATE_6M}, + {0, 6000, 0, CEIL(6000 * 10, 9), 0x00, BRCM_RATE_6M}, }; /* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams * Number of spatial streams: always 1 * other fields: refer to table 78 of section 17.3.2.2 of the original .11a standard */ -typedef struct legacy_phycfg { +struct legacy_phycfg { u32 rate_ofdm; /* ofdm mac rate */ u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */ -} legacy_phycfg_t; +}; #define LEGACY_PHYCFG_TABLE_SIZE 12 /* Number of legacy_rate_cfg entries in the table */ /* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ /* Eventually MIMOPHY would also be converted to this format */ /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ -static const legacy_phycfg_t legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = { - {WLC_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */ - {WLC_RATE_2M, 0x08}, /* CCK 2Mbps, data rate 1 */ - {WLC_RATE_5M5, 0x10}, /* CCK 5.5Mbps, data rate 2 */ - {WLC_RATE_11M, 0x18}, /* CCK 11Mbps, data rate 3 */ - {WLC_RATE_6M, 0x00}, /* OFDM 6Mbps, code rate 1/2, BPSK, 1 spatial stream */ - {WLC_RATE_9M, 0x02}, /* OFDM 9Mbps, code rate 3/4, BPSK, 1 spatial stream */ - {WLC_RATE_12M, 0x08}, /* OFDM 12Mbps, code rate 1/2, QPSK, 1 spatial stream */ - {WLC_RATE_18M, 0x0A}, /* OFDM 18Mbps, code rate 3/4, QPSK, 1 spatial stream */ - {WLC_RATE_24M, 0x10}, /* OFDM 24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */ - {WLC_RATE_36M, 0x12}, /* OFDM 36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */ - {WLC_RATE_48M, 0x19}, /* OFDM 48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */ - {WLC_RATE_54M, 0x1A}, /* OFDM 54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */ +static const struct +legacy_phycfg legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = { + {BRCM_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */ + {BRCM_RATE_2M, 0x08}, /* CCK 2Mbps, data rate 1 */ + {BRCM_RATE_5M5, 0x10}, /* CCK 5.5Mbps, data rate 2 */ + {BRCM_RATE_11M, 0x18}, /* CCK 11Mbps, data rate 3 */ + /* OFDM 6Mbps, code rate 1/2, BPSK, 1 spatial stream */ + {BRCM_RATE_6M, 0x00}, + /* OFDM 9Mbps, code rate 3/4, BPSK, 1 spatial stream */ + {BRCM_RATE_9M, 0x02}, + /* OFDM 12Mbps, code rate 1/2, QPSK, 1 spatial stream */ + {BRCM_RATE_12M, 0x08}, + /* OFDM 18Mbps, code rate 3/4, QPSK, 1 spatial stream */ + {BRCM_RATE_18M, 0x0A}, + /* OFDM 24Mbps, code rate 1/2, 16-QAM, 1 spatial stream */ + {BRCM_RATE_24M, 0x10}, + /* OFDM 36Mbps, code rate 3/4, 16-QAM, 1 spatial stream */ + {BRCM_RATE_36M, 0x12}, + /* OFDM 48Mbps, code rate 2/3, 64-QAM, 1 spatial stream */ + {BRCM_RATE_48M, 0x19}, + /* OFDM 54Mbps, code rate 3/4, 64-QAM, 1 spatial stream */ + {BRCM_RATE_54M, 0x1A}, }; /* Hardware rates (also encodes default basic rates) */ @@ -256,12 +255,10 @@ const wlc_rateset_t cck_rates = { 0x00, 0x00, 0x00, 0x00} }; -static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate); - /* check if rateset is valid. * if check_brate is true, rateset without a basic rate is considered NOT valid. */ -static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate) +static bool brcms_c_rateset_valid(wlc_rateset_t *rs, bool check_brate) { uint idx; @@ -273,13 +270,13 @@ static bool wlc_rateset_valid(wlc_rateset_t *rs, bool check_brate) /* error if no basic rates */ for (idx = 0; idx < rs->count; idx++) { - if (rs->rates[idx] & WLC_RATE_FLAG) + if (rs->rates[idx] & BRCMS_RATE_FLAG) return true; } return false; } -void wlc_rateset_mcs_upd(wlc_rateset_t *rs, u8 txstreams) +void brcms_c_rateset_mcs_upd(wlc_rateset_t *rs, u8 txstreams) { int i; for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++) @@ -290,11 +287,11 @@ void wlc_rateset_mcs_upd(wlc_rateset_t *rs, u8 txstreams) * and check if resulting rateset is valid. */ bool -wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, +brcms_c_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, const wlc_rateset_t *hw_rs, bool check_brate, u8 txstreams) { - u8 rateset[WLC_MAXRATE + 1]; + u8 rateset[BRCM_MAXRATE + 1]; u8 r; uint count; uint i; @@ -303,18 +300,17 @@ wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, count = rs->count; for (i = 0; i < count; i++) { - /* mask off "basic rate" bit, WLC_RATE_FLAG */ - r = (int)rs->rates[i] & WLC_RATE_MASK; - if ((r > WLC_MAXRATE) || (rate_info[r] == 0)) { + /* mask off "basic rate" bit, BRCMS_RATE_FLAG */ + r = (int)rs->rates[i] & BRCMS_RATE_MASK; + if ((r > BRCM_MAXRATE) || (rate_info[r] == 0)) continue; - } rateset[r] = rs->rates[i]; /* preserve basic bit! */ } /* fill out the rates in order, looking at only supported rates */ count = 0; for (i = 0; i < hw_rs->count; i++) { - r = hw_rs->rates[i] & WLC_RATE_MASK; + r = hw_rs->rates[i] & BRCMS_RATE_MASK; if (rateset[r]) rs->rates[count++] = rateset[r]; } @@ -325,14 +321,14 @@ wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, for (i = 0; i < MCSSET_LEN; i++) rs->mcs[i] = (rs->mcs[i] & hw_rs->mcs[i]); - if (wlc_rateset_valid(rs, check_brate)) + if (brcms_c_rateset_valid(rs, check_brate)) return true; else return false; } /* calculate the rate of a rx'd frame and return it as a ratespec */ -ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp) +ratespec_t brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp) { int phy_type; ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT; @@ -345,12 +341,13 @@ ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp) switch (rxh->PhyRxStatus_0 & PRXS0_FT_MASK) { case PRXS0_CCK: rspec = - CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal); + CCK_PHY2MAC_RATE( + ((struct cck_phy_hdr *) plcp)->signal); break; case PRXS0_OFDM: rspec = - OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)-> - rlpt[0]); + OFDM_PHY2MAC_RATE( + ((struct ofdm_phy_hdr *) plcp)->rlpt[0]); break; case PRXS0_PREN: rspec = (plcp[0] & MIMO_PLCP_MCS_MASK) | RSPEC_MIMORATE; @@ -370,15 +367,17 @@ ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp) rspec |= RSPEC_SHORT_GI; } else if ((phy_type == PHY_TYPE_A) || (rxh->PhyRxStatus_0 & PRXS0_OFDM)) - rspec = OFDM_PHY2MAC_RATE(((ofdm_phy_hdr_t *) plcp)->rlpt[0]); + rspec = OFDM_PHY2MAC_RATE( + ((struct ofdm_phy_hdr *) plcp)->rlpt[0]); else - rspec = CCK_PHY2MAC_RATE(((cck_phy_hdr_t *) plcp)->signal); + rspec = CCK_PHY2MAC_RATE( + ((struct cck_phy_hdr *) plcp)->signal); return rspec; } /* copy rateset src to dst as-is (no masking or sorting) */ -void wlc_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst) +void brcms_c_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst) { memcpy(dst, src, sizeof(wlc_rateset_t)); } @@ -393,7 +392,7 @@ void wlc_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst) * 'xmask' is the copy mask (typically 0x7f or 0xff). */ void -wlc_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only, +brcms_c_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only, u8 rates, uint xmask, bool mcsallow) { uint i; @@ -403,28 +402,28 @@ wlc_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only, count = 0; for (i = 0; i < src->count; i++) { r = src->rates[i]; - if (basic_only && !(r & WLC_RATE_FLAG)) + if (basic_only && !(r & BRCMS_RATE_FLAG)) continue; - if ((rates == WLC_RATES_CCK) && IS_OFDM((r & WLC_RATE_MASK))) + if (rates == BRCMS_RATES_CCK && IS_OFDM((r & BRCMS_RATE_MASK))) continue; - if ((rates == WLC_RATES_OFDM) && IS_CCK((r & WLC_RATE_MASK))) + if (rates == BRCMS_RATES_OFDM && IS_CCK((r & BRCMS_RATE_MASK))) continue; dst->rates[count++] = r & xmask; } dst->count = count; dst->htphy_membership = src->htphy_membership; - if (mcsallow && rates != WLC_RATES_CCK) + if (mcsallow && rates != BRCMS_RATES_CCK) memcpy(&dst->mcs[0], &src->mcs[0], MCSSET_LEN); else - wlc_rateset_mcs_clear(dst); + brcms_c_rateset_mcs_clear(dst); } /* select rateset for a given phy_type and bandtype and filter it, sort it * and fill rs_tgt with result */ void -wlc_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw, +brcms_c_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw, uint phy_type, int bandtype, bool cck_only, uint rate_mask, bool mcsallow, u8 bw, u8 txstreams) { @@ -435,10 +434,10 @@ wlc_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw, (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) || (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) { if (BAND_5G(bandtype)) { - rs_dflt = (bw == WLC_20_MHZ ? + rs_dflt = (bw == BRCMS_20_MHZ ? &ofdm_mimo_rates : &ofdm_40bw_mimo_rates); } else { - rs_dflt = (bw == WLC_20_MHZ ? + rs_dflt = (bw == BRCMS_20_MHZ ? &cck_ofdm_mimo_rates : &cck_ofdm_40bw_mimo_rates); } @@ -457,16 +456,16 @@ wlc_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw, if (!rs_hw) rs_hw = rs_dflt; - wlc_rateset_copy(rs_dflt, &rs_sel); - wlc_rateset_mcs_upd(&rs_sel, txstreams); - wlc_rateset_filter(&rs_sel, rs_tgt, false, - cck_only ? WLC_RATES_CCK : WLC_RATES_CCK_OFDM, + brcms_c_rateset_copy(rs_dflt, &rs_sel); + brcms_c_rateset_mcs_upd(&rs_sel, txstreams); + brcms_c_rateset_filter(&rs_sel, rs_tgt, false, + cck_only ? BRCMS_RATES_CCK : BRCMS_RATES_CCK_OFDM, rate_mask, mcsallow); - wlc_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false, + brcms_c_rate_hwrs_filter_sort_validate(rs_tgt, rs_hw, false, mcsallow ? txstreams : 1); } -s16 wlc_rate_legacy_phyctl(uint rate) +s16 brcms_c_rate_legacy_phyctl(uint rate) { uint i; for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++) @@ -476,23 +475,23 @@ s16 wlc_rate_legacy_phyctl(uint rate) return -1; } -void wlc_rateset_mcs_clear(wlc_rateset_t *rateset) +void brcms_c_rateset_mcs_clear(wlc_rateset_t *rateset) { uint i; for (i = 0; i < MCSSET_LEN; i++) rateset->mcs[i] = 0; } -void wlc_rateset_mcs_build(wlc_rateset_t *rateset, u8 txstreams) +void brcms_c_rateset_mcs_build(wlc_rateset_t *rateset, u8 txstreams) { memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN); - wlc_rateset_mcs_upd(rateset, txstreams); + brcms_c_rateset_mcs_upd(rateset, txstreams); } /* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */ -void wlc_rateset_bw_mcs_filter(wlc_rateset_t *rateset, u8 bw) +void brcms_c_rateset_bw_mcs_filter(wlc_rateset_t *rateset, u8 bw) { - if (bw == WLC_40_MHZ) + if (bw == BRCMS_40_MHZ) setbit(rateset->mcs, 32); else clrbit(rateset->mcs, 32); diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_rate.h b/drivers/staging/brcm80211/brcmsmac/rate.h similarity index 70% rename from drivers/staging/brcm80211/brcmsmac/wlc_rate.h rename to drivers/staging/brcm80211/brcmsmac/rate.h index 5575e83bdc69..dbfd3e5816d4 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_rate.h +++ b/drivers/staging/brcm80211/brcmsmac/rate.h @@ -14,31 +14,33 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _WLC_RATE_H_ -#define _WLC_RATE_H_ +#ifndef _BRCM_RATE_H_ +#define _BRCM_RATE_H_ + +#include "types.h" extern const u8 rate_info[]; -extern const struct wlc_rateset cck_ofdm_mimo_rates; -extern const struct wlc_rateset ofdm_mimo_rates; -extern const struct wlc_rateset cck_ofdm_rates; -extern const struct wlc_rateset ofdm_rates; -extern const struct wlc_rateset cck_rates; -extern const struct wlc_rateset gphy_legacy_rates; -extern const struct wlc_rateset wlc_lrs_rates; -extern const struct wlc_rateset rate_limit_1_2; +extern const struct brcms_rateset cck_ofdm_mimo_rates; +extern const struct brcms_rateset ofdm_mimo_rates; +extern const struct brcms_rateset cck_ofdm_rates; +extern const struct brcms_rateset ofdm_rates; +extern const struct brcms_rateset cck_rates; +extern const struct brcms_rateset gphy_legacy_rates; +extern const struct brcms_rateset wlc_lrs_rates; +extern const struct brcms_rateset rate_limit_1_2; -typedef struct mcs_info { +struct brcms_mcs_info { u32 phy_rate_20; /* phy rate in kbps [20Mhz] */ u32 phy_rate_40; /* phy rate in kbps [40Mhz] */ u32 phy_rate_20_sgi; /* phy rate in kbps [20Mhz] with SGI */ u32 phy_rate_40_sgi; /* phy rate in kbps [40Mhz] with SGI */ u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */ u8 leg_ofdm; /* matching legacy ofdm rate in 500bkps */ -} mcs_info_t; +}; -#define WLC_MAXMCS 32 /* max valid mcs index */ +#define BRCMS_MAXMCS 32 /* max valid mcs index */ #define MCS_TABLE_SIZE 33 /* Number of mcs entries in the table */ -extern const mcs_info_t mcs_table[]; +extern const struct brcms_mcs_info mcs_table[]; #define MCS_INVALID 0xFF #define MCS_CR_MASK 0x07 /* Code Rate bit mask */ @@ -55,14 +57,14 @@ extern const mcs_info_t mcs_table[]; #define VALID_MCS(_mcs) ((_mcs < MCS_TABLE_SIZE)) /* Macro to use the rate_info table */ -#define WLC_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */ +#define BRCMS_RATE_MASK_FULL 0xff /* Rate value mask with basic rate flag */ -#define WLC_RATE_500K_TO_BPS(rate) ((rate) * 500000) /* convert 500kbps to bps */ +/* convert 500kbps to bps */ +#define BRCMS_RATE_500K_TO_BPS(rate) ((rate) * 500000) /* rate spec : holds rate and mode specific information required to generate a tx frame. */ /* Legacy CCK and OFDM information is held in the same manner as was done in the past */ /* (in the lower byte) the upper 3 bytes primarily hold MIMO specific information */ -typedef u32 ratespec_t; /* rate spec bit fields */ #define RSPEC_RATE_MASK 0x0000007F /* Either 500Kbps units or MIMO MCS idx */ @@ -80,10 +82,10 @@ typedef u32 ratespec_t; #define RSPEC_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ #define RSPEC_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicates override rate only */ -#define WLC_HTPHY 127 /* HT PHY Membership */ +#define BRCMS_HTPHY 127 /* HT PHY Membership */ #define RSPEC_ACTIVE(rspec) (rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE)) -#define RSPEC2RATE(rspec) ((rspec & RSPEC_MIMORATE) ? \ +#define RSPEC2RATE(rspec) ((rspec & RSPEC_MIMORATE) ? \ MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec)) : \ (rspec & RSPEC_RATE_MASK)) /* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */ @@ -110,13 +112,14 @@ typedef u32 ratespec_t; #define PLCP3_STC_SHIFT 4 /* Rate info table; takes a legacy rate or ratespec_t */ -#define IS_MCS(r) (r & RSPEC_MIMORATE) -#define IS_OFDM(r) (!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & WLC_RATE_FLAG)) +#define IS_MCS(r) (r & RSPEC_MIMORATE) +#define IS_OFDM(r) (!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & \ + BRCMS_RATE_FLAG)) #define IS_CCK(r) (!IS_MCS(r) && ( \ - ((r) & WLC_RATE_MASK) == WLC_RATE_1M || \ - ((r) & WLC_RATE_MASK) == WLC_RATE_2M || \ - ((r) & WLC_RATE_MASK) == WLC_RATE_5M5 || \ - ((r) & WLC_RATE_MASK) == WLC_RATE_11M)) + ((r) & BRCMS_RATE_MASK) == BRCM_RATE_1M || \ + ((r) & BRCMS_RATE_MASK) == BRCM_RATE_2M || \ + ((r) & BRCMS_RATE_MASK) == BRCM_RATE_5M5 || \ + ((r) & BRCMS_RATE_MASK) == BRCM_RATE_11M)) #define IS_SINGLE_STREAM(mcs) (((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32)) #define CCK_RSPEC(cck) ((cck) & RSPEC_RATE_MASK) #define OFDM_RSPEC(ofdm) (((ofdm) & RSPEC_RATE_MASK) |\ @@ -132,38 +135,39 @@ extern const u8 ofdm_rate_lookup[]; #define OFDM_PHY2MAC_RATE(rlpt) (ofdm_rate_lookup[rlpt & 0x7]) #define CCK_PHY2MAC_RATE(signal) (signal/5) -/* Rates specified in wlc_rateset_filter() */ -#define WLC_RATES_CCK_OFDM 0 -#define WLC_RATES_CCK 1 -#define WLC_RATES_OFDM 2 - -/* use the stuct form instead of typedef to fix dependency problems */ -struct wlc_rateset; +/* Rates specified in brcms_c_rateset_filter() */ +#define BRCMS_RATES_CCK_OFDM 0 +#define BRCMS_RATES_CCK 1 +#define BRCMS_RATES_OFDM 2 /* sanitize, and sort a rateset with the basic bit(s) preserved, validate rateset */ -extern bool wlc_rate_hwrs_filter_sort_validate(struct wlc_rateset *rs, - const struct wlc_rateset *hw_rs, - bool check_brate, - u8 txstreams); +extern bool +brcms_c_rate_hwrs_filter_sort_validate(struct brcms_rateset *rs, + const struct brcms_rateset *hw_rs, + bool check_brate, u8 txstreams); /* copy rateset src to dst as-is (no masking or sorting) */ -extern void wlc_rateset_copy(const struct wlc_rateset *src, - struct wlc_rateset *dst); +extern void brcms_c_rateset_copy(const struct brcms_rateset *src, + struct brcms_rateset *dst); /* would be nice to have these documented ... */ -extern ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp); +extern ratespec_t brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp); -extern void wlc_rateset_filter(struct wlc_rateset *src, struct wlc_rateset *dst, - bool basic_only, u8 rates, uint xmask, - bool mcsallow); -extern void wlc_rateset_default(struct wlc_rateset *rs_tgt, - const struct wlc_rateset *rs_hw, uint phy_type, - int bandtype, bool cck_only, uint rate_mask, - bool mcsallow, u8 bw, u8 txstreams); -extern s16 wlc_rate_legacy_phyctl(uint rate); +extern void brcms_c_rateset_filter(struct brcms_rateset *src, + struct brcms_rateset *dst, bool basic_only, u8 rates, uint xmask, + bool mcsallow); -extern void wlc_rateset_mcs_upd(struct wlc_rateset *rs, u8 txstreams); -extern void wlc_rateset_mcs_clear(struct wlc_rateset *rateset); -extern void wlc_rateset_mcs_build(struct wlc_rateset *rateset, u8 txstreams); -extern void wlc_rateset_bw_mcs_filter(struct wlc_rateset *rateset, u8 bw); +extern void +brcms_c_rateset_default(struct brcms_rateset *rs_tgt, + const struct brcms_rateset *rs_hw, uint phy_type, + int bandtype, bool cck_only, uint rate_mask, + bool mcsallow, u8 bw, u8 txstreams); -#endif /* _WLC_RATE_H_ */ +extern s16 brcms_c_rate_legacy_phyctl(uint rate); + +extern void brcms_c_rateset_mcs_upd(struct brcms_rateset *rs, u8 txstreams); +extern void brcms_c_rateset_mcs_clear(struct brcms_rateset *rateset); +extern void brcms_c_rateset_mcs_build(struct brcms_rateset *rateset, + u8 txstreams); +extern void brcms_c_rateset_bw_mcs_filter(struct brcms_rateset *rateset, u8 bw); + +#endif /* _BRCM_RATE_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h b/drivers/staging/brcm80211/brcmsmac/scb.h similarity index 84% rename from drivers/staging/brcm80211/brcmsmac/wlc_scb.h rename to drivers/staging/brcm80211/brcmsmac/scb.h index f07a891d5d27..d6c8328554d0 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_scb.h +++ b/drivers/staging/brcm80211/brcmsmac/scb.h @@ -14,39 +14,44 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _wlc_scb_h_ -#define _wlc_scb_h_ +#ifndef _BRCM_SCB_H_ +#define _BRCM_SCB_H_ + +#include +#include +#include +#include "types.h" #define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ /* structure to store per-tid state for the ampdu initiator */ -typedef struct scb_ampdu_tid_ini { - u32 magic; +struct scb_ampdu_tid_ini { u8 tx_in_transit; /* number of pending mpdus in transit in driver */ u8 tid; /* initiator tid for easy lookup */ u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; /* tx retry count; indexed by seq modulo */ struct scb *scb; /* backptr for easy lookup */ -} scb_ampdu_tid_ini_t; + u8 ba_wsize; /* negotiated ba window size (in pdu) */ +}; #define AMPDU_MAX_SCB_TID NUMPRIO -typedef struct scb_ampdu { +struct scb_ampdu { struct scb *scb; /* back pointer for easy reference */ u8 mpdu_density; /* mpdu density */ u8 max_pdu; /* max pdus allowed in ampdu */ u8 release; /* # of mpdus released at a time */ u16 min_len; /* min mpdu len to support the density */ - u32 max_rxlen; /* max ampdu rcv length; 8k, 16k, 32k, 64k */ + u32 max_rx_ampdu_bytes; /* max ampdu rcv length; 8k, 16k, 32k, 64k */ struct pktq txq; /* sdu transmit queue pending aggregation */ /* This could easily be a ini[] pointer and we keep this info in wl itself instead * of having mac80211 hold it for us. Also could be made dynamic per tid instead of * static. */ - scb_ampdu_tid_ini_t ini[AMPDU_MAX_SCB_TID]; /* initiator info - per tid (NUMPRIO) */ -} scb_ampdu_t; + /* initiator info - per tid (NUMPRIO): */ + struct scb_ampdu_tid_ini ini[AMPDU_MAX_SCB_TID]; +}; -#define SCB_MAGIC 0xbeefcafe -#define INI_MAGIC 0xabcd1234 +#define SCB_MAGIC 0xbeefcafe /* station control block - one per remote MAC address */ struct scb { @@ -64,7 +69,7 @@ struct scb { */ u16 seqnum[NUMPRIO]; /* WME: driver maintained sw seqnum per priority */ - scb_ampdu_t scb_ampdu; /* AMPDU state including per tid info */ + struct scb_ampdu scb_ampdu; /* AMPDU state including per tid info */ }; /* scb flags */ @@ -77,4 +82,4 @@ struct scb { #define SCB_PS(a) NULL #define SCB_STBC_CAP(a) ((a)->flags & SCB_STBCCAP) #define SCB_AMPDU(a) true -#endif /* _wlc_scb_h_ */ +#endif /* _BRCM_SCB_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h b/drivers/staging/brcm80211/brcmsmac/srom.c similarity index 54% rename from drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h rename to drivers/staging/brcm80211/brcmsmac/srom.c index f4b3e61dc37d..f39442ed4ce7 100644 --- a/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h +++ b/drivers/staging/brcm80211/brcmsmac/srom.c @@ -14,19 +14,341 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _bcmsrom_tbl_h_ -#define _bcmsrom_tbl_h_ +#include +#include +#include +#include +#include -#include "wlioctl.h" +#include +#include +#include "nicpci.h" +#include "aiutils.h" +#include "otp.h" +#include "srom.h" -typedef struct { - const char *name; - u32 revmask; - u32 flags; - u16 off; - u16 mask; -} sromvar_t; +#define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \ + (((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \ + ((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \ + ((u8 *)curmap + PCI_BAR0_SPROM_OFFSET)) +#if defined(BCMDBG) +#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */ +#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */ +#endif + +/* Maximum srom: 6 Kilobits == 768 bytes */ +#define SROM_MAX 768 + +/* PCI fields */ +#define PCI_F0DEVID 48 + +#define SROM_WORDS 64 + +#define SROM_SSID 2 + +#define SROM_WL1LHMAXP 29 + +#define SROM_WL1LPAB0 30 +#define SROM_WL1LPAB1 31 +#define SROM_WL1LPAB2 32 + +#define SROM_WL1HPAB0 33 +#define SROM_WL1HPAB1 34 +#define SROM_WL1HPAB2 35 + +#define SROM_MACHI_IL0 36 +#define SROM_MACMID_IL0 37 +#define SROM_MACLO_IL0 38 +#define SROM_MACHI_ET1 42 +#define SROM_MACMID_ET1 43 +#define SROM_MACLO_ET1 44 +#define SROM3_MACHI 37 +#define SROM3_MACMID 38 +#define SROM3_MACLO 39 + +#define SROM_BXARSSI2G 40 +#define SROM_BXARSSI5G 41 + +#define SROM_TRI52G 42 +#define SROM_TRI5GHL 43 + +#define SROM_RXPO52G 45 + +#define SROM_AABREV 46 +/* Fields in AABREV */ +#define SROM_BR_MASK 0x00ff +#define SROM_CC_MASK 0x0f00 +#define SROM_CC_SHIFT 8 +#define SROM_AA0_MASK 0x3000 +#define SROM_AA0_SHIFT 12 +#define SROM_AA1_MASK 0xc000 +#define SROM_AA1_SHIFT 14 + +#define SROM_WL0PAB0 47 +#define SROM_WL0PAB1 48 +#define SROM_WL0PAB2 49 + +#define SROM_LEDBH10 50 +#define SROM_LEDBH32 51 + +#define SROM_WL10MAXP 52 + +#define SROM_WL1PAB0 53 +#define SROM_WL1PAB1 54 +#define SROM_WL1PAB2 55 + +#define SROM_ITT 56 + +#define SROM_BFL 57 +#define SROM_BFL2 28 +#define SROM3_BFL2 61 + +#define SROM_AG10 58 + +#define SROM_CCODE 59 + +#define SROM_OPO 60 + +#define SROM3_LEDDC 62 + +#define SROM_CRCREV 63 + +/* SROM Rev 4: Reallocate the software part of the srom to accommodate + * MIMO features. It assumes up to two PCIE functions and 440 bytes + * of usable srom i.e. the usable storage in chips with OTP that + * implements hardware redundancy. + */ + +#define SROM4_WORDS 220 + +#define SROM4_SIGN 32 +#define SROM4_SIGNATURE 0x5372 + +#define SROM4_BREV 33 + +#define SROM4_BFL0 34 +#define SROM4_BFL1 35 +#define SROM4_BFL2 36 +#define SROM4_BFL3 37 +#define SROM5_BFL0 37 +#define SROM5_BFL1 38 +#define SROM5_BFL2 39 +#define SROM5_BFL3 40 + +#define SROM4_MACHI 38 +#define SROM4_MACMID 39 +#define SROM4_MACLO 40 +#define SROM5_MACHI 41 +#define SROM5_MACMID 42 +#define SROM5_MACLO 43 + +#define SROM4_CCODE 41 +#define SROM4_REGREV 42 +#define SROM5_CCODE 34 +#define SROM5_REGREV 35 + +#define SROM4_LEDBH10 43 +#define SROM4_LEDBH32 44 +#define SROM5_LEDBH10 59 +#define SROM5_LEDBH32 60 + +#define SROM4_LEDDC 45 +#define SROM5_LEDDC 45 + +#define SROM4_AA 46 + +#define SROM4_AG10 47 +#define SROM4_AG32 48 + +#define SROM4_TXPID2G 49 +#define SROM4_TXPID5G 51 +#define SROM4_TXPID5GL 53 +#define SROM4_TXPID5GH 55 + +#define SROM4_TXRXC 61 +#define SROM4_TXCHAIN_MASK 0x000f +#define SROM4_TXCHAIN_SHIFT 0 +#define SROM4_RXCHAIN_MASK 0x00f0 +#define SROM4_RXCHAIN_SHIFT 4 +#define SROM4_SWITCH_MASK 0xff00 +#define SROM4_SWITCH_SHIFT 8 + +/* Per-path fields */ +#define MAX_PATH_SROM 4 +#define SROM4_PATH0 64 +#define SROM4_PATH1 87 +#define SROM4_PATH2 110 +#define SROM4_PATH3 133 + +#define SROM4_2G_ITT_MAXP 0 +#define SROM4_2G_PA 1 +#define SROM4_5G_ITT_MAXP 5 +#define SROM4_5GLH_MAXP 6 +#define SROM4_5G_PA 7 +#define SROM4_5GL_PA 11 +#define SROM4_5GH_PA 15 + +/* All the miriad power offsets */ +#define SROM4_2G_CCKPO 156 +#define SROM4_2G_OFDMPO 157 +#define SROM4_5G_OFDMPO 159 +#define SROM4_5GL_OFDMPO 161 +#define SROM4_5GH_OFDMPO 163 +#define SROM4_2G_MCSPO 165 +#define SROM4_5G_MCSPO 173 +#define SROM4_5GL_MCSPO 181 +#define SROM4_5GH_MCSPO 189 +#define SROM4_CDDPO 197 +#define SROM4_STBCPO 198 +#define SROM4_BW40PO 199 +#define SROM4_BWDUPPO 200 + +#define SROM4_CRCREV 219 + +/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6. + * This is acombined srom for both MIMO and SISO boards, usable in + * the .130 4Kilobit OTP with hardware redundancy. + */ +#define SROM8_BREV 65 + +#define SROM8_BFL0 66 +#define SROM8_BFL1 67 +#define SROM8_BFL2 68 +#define SROM8_BFL3 69 + +#define SROM8_MACHI 70 +#define SROM8_MACMID 71 +#define SROM8_MACLO 72 + +#define SROM8_CCODE 73 +#define SROM8_REGREV 74 + +#define SROM8_LEDBH10 75 +#define SROM8_LEDBH32 76 + +#define SROM8_LEDDC 77 + +#define SROM8_AA 78 + +#define SROM8_AG10 79 +#define SROM8_AG32 80 + +#define SROM8_TXRXC 81 + +#define SROM8_BXARSSI2G 82 +#define SROM8_BXARSSI5G 83 +#define SROM8_TRI52G 84 +#define SROM8_TRI5GHL 85 +#define SROM8_RXPO52G 86 + +#define SROM8_FEM2G 87 +#define SROM8_FEM5G 88 +#define SROM8_FEM_ANTSWLUT_MASK 0xf800 +#define SROM8_FEM_ANTSWLUT_SHIFT 11 +#define SROM8_FEM_TR_ISO_MASK 0x0700 +#define SROM8_FEM_TR_ISO_SHIFT 8 +#define SROM8_FEM_PDET_RANGE_MASK 0x00f8 +#define SROM8_FEM_PDET_RANGE_SHIFT 3 +#define SROM8_FEM_EXTPA_GAIN_MASK 0x0006 +#define SROM8_FEM_EXTPA_GAIN_SHIFT 1 +#define SROM8_FEM_TSSIPOS_MASK 0x0001 +#define SROM8_FEM_TSSIPOS_SHIFT 0 + +#define SROM8_THERMAL 89 + +/* Temp sense related entries */ +#define SROM8_MPWR_RAWTS 90 +#define SROM8_TS_SLP_OPT_CORRX 91 +/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */ +#define SROM8_FOC_HWIQ_IQSWP 92 + +/* Temperature delta for PHY calibration */ +#define SROM8_PHYCAL_TEMPDELTA 93 + +/* Per-path offsets & fields */ +#define SROM8_PATH0 96 +#define SROM8_PATH1 112 +#define SROM8_PATH2 128 +#define SROM8_PATH3 144 + +#define SROM8_2G_ITT_MAXP 0 +#define SROM8_2G_PA 1 +#define SROM8_5G_ITT_MAXP 4 +#define SROM8_5GLH_MAXP 5 +#define SROM8_5G_PA 6 +#define SROM8_5GL_PA 9 +#define SROM8_5GH_PA 12 + +/* All the miriad power offsets */ +#define SROM8_2G_CCKPO 160 + +#define SROM8_2G_OFDMPO 161 +#define SROM8_5G_OFDMPO 163 +#define SROM8_5GL_OFDMPO 165 +#define SROM8_5GH_OFDMPO 167 + +#define SROM8_2G_MCSPO 169 +#define SROM8_5G_MCSPO 177 +#define SROM8_5GL_MCSPO 185 +#define SROM8_5GH_MCSPO 193 + +#define SROM8_CDDPO 201 +#define SROM8_STBCPO 202 +#define SROM8_BW40PO 203 +#define SROM8_BWDUPPO 204 + +/* SISO PA parameters are in the path0 spaces */ +#define SROM8_SISO 96 + +/* Legacy names for SISO PA paramters */ +#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP) +#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA) +#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1) +#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2) +#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP) +#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP) +#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA) +#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1) +#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2) +#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA) +#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1) +#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2) +#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA) +#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1) +#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2) + +/* SROM REV 9 */ +#define SROM9_2GPO_CCKBW20 160 +#define SROM9_2GPO_CCKBW20UL 161 +#define SROM9_2GPO_LOFDMBW20 162 +#define SROM9_2GPO_LOFDMBW20UL 164 + +#define SROM9_5GLPO_LOFDMBW20 166 +#define SROM9_5GLPO_LOFDMBW20UL 168 +#define SROM9_5GMPO_LOFDMBW20 170 +#define SROM9_5GMPO_LOFDMBW20UL 172 +#define SROM9_5GHPO_LOFDMBW20 174 +#define SROM9_5GHPO_LOFDMBW20UL 176 + +#define SROM9_2GPO_MCSBW20 178 +#define SROM9_2GPO_MCSBW20UL 180 +#define SROM9_2GPO_MCSBW40 182 + +#define SROM9_5GLPO_MCSBW20 184 +#define SROM9_5GLPO_MCSBW20UL 186 +#define SROM9_5GLPO_MCSBW40 188 +#define SROM9_5GMPO_MCSBW20 190 +#define SROM9_5GMPO_MCSBW20UL 192 +#define SROM9_5GMPO_MCSBW40 194 +#define SROM9_5GHPO_MCSBW20 196 +#define SROM9_5GHPO_MCSBW20UL 198 +#define SROM9_5GHPO_MCSBW40 200 + +#define SROM9_PO_MCS32 202 +#define SROM9_PO_LOFDM40DUP 203 + +/* SROM flags (see sromvar_t) */ #define SRFL_MORE 1 /* value continues as described by the next entry */ #define SRFL_NOFFS 2 /* value bits can't be all one's */ #define SRFL_PRHEX 4 /* value is in hexdecimal format */ @@ -36,6 +358,23 @@ typedef struct { #define SRFL_LEDDC 0x40 /* value is an LED duty cycle */ #define SRFL_NOVAR 0x80 /* do not generate a nvram param, entry is for mfgc */ +/* Max. nvram variable table size */ +#define MAXSZ_NVRAM_VARS 4096 + +struct brcms_sromvar { + const char *name; + u32 revmask; + u32 flags; + u16 off; + u16 mask; +}; + +struct brcms_varbuf { + char *base; /* pointer to buffer base */ + char *buf; /* pointer to current position */ + unsigned int size; /* current (residual) size in bytes */ +}; + /* Assumptions: * - Ethernet address spans across 3 consective words * @@ -48,8 +387,7 @@ typedef struct { * - The last entry's name field must be NULL to indicate the end of the table. Other * entries must have non-NULL name. */ - -static const sromvar_t pci_sromvars[] = { +static const struct brcms_sromvar pci_sromvars[] = { {"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff}, {"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK}, {"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff}, @@ -393,7 +731,7 @@ static const sromvar_t pci_sromvars[] = { {NULL, 0, 0, 0, 0} }; -static const sromvar_t perpath_pci_sromvars[] = { +static const struct brcms_sromvar perpath_pci_sromvars[] = { {"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff}, {"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00}, {"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00}, @@ -437,77 +775,463 @@ static const sromvar_t perpath_pci_sromvars[] = { {NULL, 0, 0, 0, 0} }; -#if !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) -#define PHY_TYPE_N 4 /* N-Phy value */ -#define PHY_TYPE_LP 5 /* LP-Phy value */ -#endif /* !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */ -#if !defined(PHY_TYPE_NULL) -#define PHY_TYPE_NULL 0xf /* Invalid Phy value */ -#endif /* !defined(PHY_TYPE_NULL) */ +static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, + struct brcms_varbuf *b); +static int initvars_srom_pci(struct si_pub *sih, void *curmap, char **vars, + uint *count); +static int sprom_read_pci(struct si_pub *sih, u16 *sprom, + uint wordoff, u16 *buf, uint nwords, bool check_crc); +#if defined(BCMNVRAMR) +static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz); +#endif -typedef struct { - u16 phy_type; - u16 bandrange; - u16 chain; - const char *vars; -} pavars_t; +static int initvars_table(char *start, char *end, + char **vars, uint *count); -static const pavars_t pavars[] = { - /* NPHY */ - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 0, - "pa5glw0a0 pa5glw1a0 pa5glw2a0"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 1, - "pa5glw0a1 pa5glw1a1 pa5glw2a1"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 0, - "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 1, - "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"}, - /* LPPHY */ - {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"}, - {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"}, - {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"}, - {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"}, - {PHY_TYPE_NULL, 0, 0, ""} -}; +/* Initialization of varbuf structure */ +static void varbuf_init(struct brcms_varbuf *b, char *buf, uint size) +{ + b->size = size; + b->base = b->buf = buf; +} -typedef struct { - u16 phy_type; - u16 bandrange; - const char *vars; -} povars_t; +/* append a null terminated var=value string */ +static int varbuf_append(struct brcms_varbuf *b, const char *fmt, ...) +{ + va_list ap; + int r; + size_t len; + char *s; -static const povars_t povars[] = { - /* NPHY */ - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, - "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 " - "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, - "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 " - "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, - "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 " - "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"}, - {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, - "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 " - "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"}, - {PHY_TYPE_NULL, 0, ""} -}; + if (b->size < 2) + return 0; -typedef struct { - u8 tag; /* Broadcom subtag name */ - u8 len; /* Length field of the tuple, note that it includes the - * subtag name (1 byte): 1 + tuple content length - */ - const char *params; -} cis_tuple_t; + va_start(ap, fmt); + r = vsnprintf(b->buf, b->size, fmt, ap); + va_end(ap); -#define OTP_RAW (0xff - 1) /* Reserved tuple number for wrvar Raw input */ -#define OTP_VERS_1 (0xff - 2) /* CISTPL_VERS_1 */ -#define OTP_MANFID (0xff - 3) /* CISTPL_MANFID */ -#define OTP_RAW1 (0xff - 4) /* Like RAW, but comes first */ + /* C99 snprintf behavior returns r >= size on overflow, + * others return -1 on overflow. + * All return -1 on format error. + * We need to leave room for 2 null terminations, one for the current var + * string, and one for final null of the var table. So check that the + * strlen written, r, leaves room for 2 chars. + */ + if ((r == -1) || (r > (int)(b->size - 2))) { + b->size = 0; + return 0; + } -#endif /* _bcmsrom_tbl_h_ */ + /* Remove any earlier occurrence of the same variable */ + s = strchr(b->buf, '='); + if (s != NULL) { + len = (size_t) (s - b->buf); + for (s = b->base; s < b->buf;) { + if ((memcmp(s, b->buf, len) == 0) && s[len] == '=') { + len = strlen(s) + 1; + memmove(s, (s + len), + ((b->buf + r + 1) - (s + len))); + b->buf -= len; + b->size += (unsigned int)len; + break; + } + + while (*s++) + ; + } + } + + /* skip over this string's null termination */ + r++; + b->size -= r; + b->buf += r; + + return r; +} + +/* + * Initialize local vars from the right source for this platform. + * Return 0 on success, nonzero on error. + */ +int srom_var_init(struct si_pub *sih, uint bustype, void *curmap, + char **vars, uint *count) +{ + uint len; + + len = 0; + + if (vars == NULL || count == NULL) + return 0; + + *vars = NULL; + *count = 0; + + if (curmap != NULL && bustype == PCI_BUS) + return initvars_srom_pci(sih, curmap, vars, count); + + return -EINVAL; +} + +static inline void ltoh16_buf(u16 *buf, unsigned int size) +{ + for (size /= 2; size; size--) + *(buf + size) = le16_to_cpu(*(buf + size)); +} + +static inline void htol16_buf(u16 *buf, unsigned int size) +{ + for (size /= 2; size; size--) + *(buf + size) = cpu_to_le16(*(buf + size)); +} + +/* + * Read in and validate sprom. + * Return 0 on success, nonzero on error. + */ +static int +sprom_read_pci(struct si_pub *sih, u16 *sprom, uint wordoff, + u16 *buf, uint nwords, bool check_crc) +{ + int err = 0; + uint i; + + /* read the sprom */ + for (i = 0; i < nwords; i++) + buf[i] = R_REG(&sprom[wordoff + i]); + + if (check_crc) { + + if (buf[0] == 0xffff) { + /* The hardware thinks that an srom that starts with 0xffff + * is blank, regardless of the rest of the content, so declare + * it bad. + */ + return -ENODATA; + } + + /* fixup the endianness so crc8 will pass */ + htol16_buf(buf, nwords * 2); + if (brcmu_crc8((u8 *) buf, nwords * 2, CRC8_INIT_VALUE) != + CRC8_GOOD_VALUE) { + /* DBG only pci always read srom4 first, then srom8/9 */ + err = -EIO; + } + /* now correct the endianness of the byte array */ + ltoh16_buf(buf, nwords * 2); + } + return err; +} + +#if defined(BCMNVRAMR) +static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) +{ + u8 *otp; + uint sz = OTP_SZ_MAX / 2; /* size in words */ + int err = 0; + + otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC); + if (otp == NULL) { + return -ENOMEM; + } + + err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz); + + memcpy(buf, otp, bufsz); + + kfree(otp); + + /* Check CRC */ + if (buf[0] == 0xffff) { + /* The hardware thinks that an srom that starts with 0xffff + * is blank, regardless of the rest of the content, so declare + * it bad. + */ + return -ENODATA; + } + + /* fixup the endianness so crc8 will pass */ + htol16_buf(buf, bufsz); + if (brcmu_crc8((u8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) != + CRC8_GOOD_VALUE) { + err = -EIO; + } + /* now correct the endianness of the byte array */ + ltoh16_buf(buf, bufsz); + + return err; +} +#endif /* defined(BCMNVRAMR) */ +/* +* Create variable table from memory. +* Return 0 on success, nonzero on error. +*/ +static int initvars_table(char *start, char *end, + char **vars, uint *count) +{ + int c = (int)(end - start); + + /* do it only when there is more than just the null string */ + if (c > 1) { + char *vp = kmalloc(c, GFP_ATOMIC); + if (!vp) + return -ENOMEM; + memcpy(vp, start, c); + *vars = vp; + *count = c; + } else { + *vars = NULL; + *count = 0; + } + + return 0; +} + +/* Parse SROM and create name=value pairs. 'srom' points to + * the SROM word array. 'off' specifies the offset of the + * first word 'srom' points to, which should be either 0 or + * SROM3_SWRG_OFF (full SROM or software region). + */ + +static uint mask_shift(u16 mask) +{ + uint i; + for (i = 0; i < (sizeof(mask) << 3); i++) { + if (mask & (1 << i)) + return i; + } + return 0; +} + +static uint mask_width(u16 mask) +{ + int i; + for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) { + if (mask & (1 << i)) + return (uint) (i - mask_shift(mask) + 1); + } + return 0; +} + +static void +_initvars_srom_pci(u8 sromrev, u16 *srom, uint off, struct brcms_varbuf *b) +{ + u16 w; + u32 val; + const struct brcms_sromvar *srv; + uint width; + uint flags; + u32 sr = (1 << sromrev); + + varbuf_append(b, "sromrev=%d", sromrev); + + for (srv = pci_sromvars; srv->name != NULL; srv++) { + const char *name; + + if ((srv->revmask & sr) == 0) + continue; + + if (srv->off < off) + continue; + + flags = srv->flags; + name = srv->name; + + /* This entry is for mfgc only. Don't generate param for it, */ + if (flags & SRFL_NOVAR) + continue; + + if (flags & SRFL_ETHADDR) { + u8 ea[ETH_ALEN]; + + ea[0] = (srom[srv->off - off] >> 8) & 0xff; + ea[1] = srom[srv->off - off] & 0xff; + ea[2] = (srom[srv->off + 1 - off] >> 8) & 0xff; + ea[3] = srom[srv->off + 1 - off] & 0xff; + ea[4] = (srom[srv->off + 2 - off] >> 8) & 0xff; + ea[5] = srom[srv->off + 2 - off] & 0xff; + + varbuf_append(b, "%s=%pM", name, ea); + } else { + w = srom[srv->off - off]; + val = (w & srv->mask) >> mask_shift(srv->mask); + width = mask_width(srv->mask); + + while (srv->flags & SRFL_MORE) { + srv++; + if (srv->off == 0 || srv->off < off) + continue; + + w = srom[srv->off - off]; + val += + ((w & srv->mask) >> mask_shift(srv-> + mask)) << + width; + width += mask_width(srv->mask); + } + + if ((flags & SRFL_NOFFS) + && ((int)val == (1 << width) - 1)) + continue; + + if (flags & SRFL_CCODE) { + if (val == 0) + varbuf_append(b, "ccode="); + else + varbuf_append(b, "ccode=%c%c", + (val >> 8), (val & 0xff)); + } + /* LED Powersave duty cycle has to be scaled: + *(oncount >> 24) (offcount >> 8) + */ + else if (flags & SRFL_LEDDC) { + u32 w32 = (((val >> 8) & 0xff) << 24) | /* oncount */ + (((val & 0xff)) << 8); /* offcount */ + varbuf_append(b, "leddc=%d", w32); + } else if (flags & SRFL_PRHEX) + varbuf_append(b, "%s=0x%x", name, val); + else if ((flags & SRFL_PRSIGN) + && (val & (1 << (width - 1)))) + varbuf_append(b, "%s=%d", name, + (int)(val | (~0 << width))); + else + varbuf_append(b, "%s=%u", name, val); + } + } + + if (sromrev >= 4) { + /* Do per-path variables */ + uint p, pb, psz; + + if (sromrev >= 8) { + pb = SROM8_PATH0; + psz = SROM8_PATH1 - SROM8_PATH0; + } else { + pb = SROM4_PATH0; + psz = SROM4_PATH1 - SROM4_PATH0; + } + + for (p = 0; p < MAX_PATH_SROM; p++) { + for (srv = perpath_pci_sromvars; srv->name != NULL; + srv++) { + if ((srv->revmask & sr) == 0) + continue; + + if (pb + srv->off < off) + continue; + + /* This entry is for mfgc only. Don't generate param for it, */ + if (srv->flags & SRFL_NOVAR) + continue; + + w = srom[pb + srv->off - off]; + val = (w & srv->mask) >> mask_shift(srv->mask); + width = mask_width(srv->mask); + + /* Cheating: no per-path var is more than 1 word */ + + if ((srv->flags & SRFL_NOFFS) + && ((int)val == (1 << width) - 1)) + continue; + + if (srv->flags & SRFL_PRHEX) + varbuf_append(b, "%s%d=0x%x", srv->name, + p, val); + else + varbuf_append(b, "%s%d=%d", srv->name, + p, val); + } + pb += psz; + } + } +} + +/* + * Initialize nonvolatile variable table from sprom. + * Return 0 on success, nonzero on error. + */ +static int initvars_srom_pci(struct si_pub *sih, void *curmap, char **vars, + uint *count) +{ + u16 *srom, *sromwindow; + u8 sromrev = 0; + u32 sr; + struct brcms_varbuf b; + char *vp, *base = NULL; + int err = 0; + + /* + * Apply CRC over SROM content regardless SROM is present or not. + */ + srom = kmalloc(SROM_MAX, GFP_ATOMIC); + if (!srom) + return -ENOMEM; + + sromwindow = (u16 *) SROM_OFFSET(sih); + if (ai_is_sprom_available(sih)) { + err = sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS, + true); + + if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) || + (((sih->buscoretype == PCIE_CORE_ID) + && (sih->buscorerev >= 6)) + || ((sih->buscoretype == PCI_CORE_ID) + && (sih->buscorerev >= 0xe)))) { + /* sromrev >= 4, read more */ + err = sprom_read_pci(sih, sromwindow, 0, srom, + SROM4_WORDS, true); + sromrev = srom[SROM4_CRCREV] & 0xff; + } else if (err == 0) { + /* srom is good and is rev < 4 */ + /* top word of sprom contains version and crc8 */ + sromrev = srom[SROM_CRCREV] & 0xff; + /* bcm4401 sroms misprogrammed */ + if (sromrev == 0x10) + sromrev = 1; + } + } +#if defined(BCMNVRAMR) + /* Use OTP if SPROM not available */ + else { + err = otp_read_pci(sih, srom, SROM_MAX); + if (err == 0) + /* OTP only contain SROM rev8/rev9 for now */ + sromrev = srom[SROM4_CRCREV] & 0xff; + } +#else + else + err = -ENODEV; +#endif + + if (!err) { + /* Bitmask for the sromrev */ + sr = 1 << sromrev; + + /* srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, 9 */ + if ((sr & 0x33e) == 0) { + err = -EINVAL; + goto errout; + } + + base = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC); + if (!base) { + err = -ENOMEM; + goto errout; + } + + varbuf_init(&b, base, MAXSZ_NVRAM_VARS); + + /* parse SROM into name=value pairs. */ + _initvars_srom_pci(sromrev, srom, 0, &b); + + /* final nullbyte terminator */ + vp = b.buf; + *vp++ = '\0'; + + err = initvars_table(base, vp, vars, count); + kfree(base); + } + +errout: + kfree(srom); + return err; +} diff --git a/drivers/staging/brcm80211/include/bcmsrom.h b/drivers/staging/brcm80211/brcmsmac/srom.h similarity index 82% rename from drivers/staging/brcm80211/include/bcmsrom.h rename to drivers/staging/brcm80211/brcmsmac/srom.h index b2dc8951c5d2..efc4d1edd86d 100644 --- a/drivers/staging/brcm80211/include/bcmsrom.h +++ b/drivers/staging/brcm80211/brcmsmac/srom.h @@ -14,16 +14,16 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _bcmsrom_h_ -#define _bcmsrom_h_ +#ifndef _BRCM_SROM_H_ +#define _BRCM_SROM_H_ -#include +#include "types.h" /* Prototypes */ -extern int srom_var_init(si_t *sih, uint bus, void *curmap, +extern int srom_var_init(struct si_pub *sih, uint bus, void *curmap, char **vars, uint *count); -extern int srom_read(si_t *sih, uint bus, void *curmap, +extern int srom_read(struct si_pub *sih, uint bus, void *curmap, uint byteoff, uint nbytes, u16 *buf, bool check_crc); /* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP @@ -31,4 +31,4 @@ extern int srom_read(si_t *sih, uint bus, void *curmap, */ extern int srom_parsecis(u8 **pcis, uint ciscnt, char **vars, uint *count); -#endif /* _bcmsrom_h_ */ +#endif /* _BRCM_SROM_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c b/drivers/staging/brcm80211/brcmsmac/stf.c similarity index 70% rename from drivers/staging/brcm80211/brcmsmac/wlc_stf.c rename to drivers/staging/brcm80211/brcmsmac/stf.c index c4f58172182d..a55ff0101782 100644 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.c +++ b/drivers/staging/brcm80211/brcmsmac/stf.c @@ -14,47 +14,31 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include +#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "wlc_types.h" +#include "types.h" #include "d11.h" -#include "wl_dbg.h" -#include "wlc_cfg.h" -#include "wlc_rate.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "wlc_key.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_channel.h" -#include "wlc_main.h" -#include "wl_export.h" -#include "wlc_bmac.h" -#include "wlc_stf.h" +#include "rate.h" +#include "phy/phy_hal.h" +#include "channel.h" +#include "main.h" +#include "bmac.h" +#include "stf.h" #define MIN_SPATIAL_EXPANSION 0 #define MAX_SPATIAL_EXPANSION 1 -#define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \ +#define BRCMS_STF_SS_STBC_RX(wlc) (BRCMS_ISNPHY(wlc->band) && \ NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6)) -static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val); -static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 val); -static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val); -static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val); +static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val); +static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts, u8 val); +static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val); +static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val); -static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc); -static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); +static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); +static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, + ratespec_t rspec); #define NSTS_1 1 #define NSTS_2 2 @@ -68,10 +52,10 @@ const u8 txcore_default[5] = { (0x0f) /* For Nsts = 4, enable all cores */ }; -static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val) +static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val) { /* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */ - if (WLC_STF_SS_STBC_RX(wlc)) { + if (BRCMS_STF_SS_STBC_RX(wlc)) { if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO)) return; } @@ -80,15 +64,15 @@ static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val) wlc->ht_cap.cap_info |= (val << IEEE80211_HT_CAP_RX_STBC_SHIFT); if (wlc->pub->up) { - wlc_update_beacon(wlc); - wlc_update_probe_resp(wlc, true); + brcms_c_update_beacon(wlc); + brcms_c_update_probe_resp(wlc, true); } } /* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to turn on/off txchain */ -void wlc_tempsense_upd(struct wlc_info *wlc) +void brcms_c_tempsense_upd(struct brcms_c_info *wlc) { - wlc_phy_t *pi = wlc->band->pi; + struct brcms_phy_pub *pi = wlc->band->pi; uint active_chains, txchain; /* Check if the chip is too hot. Disable one Tx chain, if it is */ @@ -99,21 +83,21 @@ void wlc_tempsense_upd(struct wlc_info *wlc) if (wlc->stf->txchain == wlc->stf->hw_txchain) { if (txchain && (txchain < wlc->stf->hw_txchain)) { /* turn off 1 tx chain */ - wlc_stf_txchain_set(wlc, txchain, true); + brcms_c_stf_txchain_set(wlc, txchain, true); } } else if (wlc->stf->txchain < wlc->stf->hw_txchain) { if (txchain == wlc->stf->hw_txchain) { /* turn back on txchain */ - wlc_stf_txchain_set(wlc, txchain, true); + brcms_c_stf_txchain_set(wlc, txchain, true); } } } void -wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, u16 *ss_algo_channel, +brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel, chanspec_t chanspec) { - tx_power_t power; + struct tx_power power; u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id; /* Clear previous settings */ @@ -151,7 +135,7 @@ wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, u16 *ss_algo_channel, setbit(ss_algo_channel, PHY_TXC1_MODE_STBC); } -static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val) +static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val) { if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) { return false; @@ -161,7 +145,7 @@ static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val) return false; if ((int_val == OFF) || (wlc->stf->txstreams == 1) - || !WLC_STBC_CAP_PHY(wlc)) + || !BRCMS_STBC_CAP_PHY(wlc)) wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_TX_STBC; else wlc->ht_cap.cap_info |= IEEE80211_HT_CAP_TX_STBC; @@ -172,33 +156,34 @@ static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val) return true; } -bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val) +bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val) { if ((int_val != HT_CAP_RX_STBC_NO) && (int_val != HT_CAP_RX_STBC_ONE_STREAM)) { return false; } - if (WLC_STF_SS_STBC_RX(wlc)) { + if (BRCMS_STF_SS_STBC_RX(wlc)) { if ((int_val != HT_CAP_RX_STBC_NO) && (wlc->stf->rxstreams == 1)) return false; } - wlc_stf_stbc_rx_ht_update(wlc, int_val); + brcms_c_stf_stbc_rx_ht_update(wlc, int_val); return true; } -static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask) +static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts, + u8 core_mask) { BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n", wlc->pub->unit, Nsts, core_mask); - if (WLC_BITSCNT(core_mask) > wlc->stf->txstreams) { + if (BRCMS_BITSCNT(core_mask) > wlc->stf->txstreams) { core_mask = 0; } - if ((WLC_BITSCNT(core_mask) == wlc->stf->txstreams) && + if ((BRCMS_BITSCNT(core_mask) == wlc->stf->txstreams) && ((core_mask & ~wlc->stf->txchain) || !(core_mask & wlc->stf->txchain))) { core_mask = wlc->stf->txchain; @@ -211,18 +196,18 @@ static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask) * frames when 1 stream core map changed */ wlc->stf->phytxant = core_mask << PHY_TXC_ANT_SHIFT; - wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant); + brcms_b_txant_set(wlc->hw, wlc->stf->phytxant); if (wlc->clk) { - wlc_suspend_mac_and_wait(wlc); - wlc_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); - wlc_enable_mac(wlc); + brcms_c_suspend_mac_and_wait(wlc); + brcms_c_beacon_phytxctl_txant_upd(wlc, wlc->bcn_rspec); + brcms_c_enable_mac(wlc); } } return 0; } -static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val) +static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val) { int i; u8 core_mask = 0; @@ -233,12 +218,12 @@ static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val) for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { core_mask = (val == MAX_SPATIAL_EXPANSION) ? wlc->stf->txchain : txcore_default[i]; - wlc_stf_txcore_set(wlc, (u8) i, core_mask); + brcms_c_stf_txcore_set(wlc, (u8) i, core_mask); } return 0; } -int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) +int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force) { u8 txchain = (u8) int_val; u8 txstreams; @@ -252,7 +237,7 @@ int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) return -EINVAL; /* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */ - txstreams = (u8) WLC_BITSCNT(txchain); + txstreams = (u8) BRCMS_BITSCNT(txchain); if (txstreams > MAX_STREAMS_SUPPORTED) return -EINVAL; @@ -288,24 +273,24 @@ int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) wlc->stf->txchain = txchain; wlc->stf->txstreams = txstreams; - wlc_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx); - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); + brcms_c_stf_stbc_tx_set(wlc, wlc->band->band_stf_stbc_tx); + brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); + brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); wlc->stf->txant = (wlc->stf->txstreams == 1) ? ANT_TX_FORCE_0 : ANT_TX_DEF; - _wlc_stf_phy_txant_upd(wlc); + _brcms_c_stf_phy_txant_upd(wlc); wlc_phy_stf_chain_set(wlc->band->pi, wlc->stf->txchain, wlc->stf->rxchain); for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) - wlc_stf_txcore_set(wlc, (u8) i, txcore_default[i]); + brcms_c_stf_txcore_set(wlc, (u8) i, txcore_default[i]); return 0; } /* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */ -int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band) +int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band) { int ret_code = 0; u8 prev_stf_ss; @@ -314,7 +299,7 @@ int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band) prev_stf_ss = wlc->stf->ss_opmode; /* NOTE: opmode can only be SISO or CDD as STBC is decided on a per-packet basis */ - if (WLC_STBC_CAP_PHY(wlc) && + if (BRCMS_STBC_CAP_PHY(wlc) && wlc->stf->ss_algosel_auto && (wlc->stf->ss_algo_channel != (u16) -1)) { upd_stf_ss = (wlc->stf->no_cddstbc || (wlc->stf->txstreams == 1) @@ -331,72 +316,39 @@ int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band) } if (prev_stf_ss != upd_stf_ss) { wlc->stf->ss_opmode = upd_stf_ss; - wlc_bmac_band_stf_ss_set(wlc->hw, upd_stf_ss); + brcms_b_band_stf_ss_set(wlc->hw, upd_stf_ss); } return ret_code; } -int wlc_stf_attach(struct wlc_info *wlc) +int brcms_c_stf_attach(struct brcms_c_info *wlc) { wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO; wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD; - if (WLCISNPHY(wlc->band) && + if (BRCMS_ISNPHY(wlc->band) && (wlc_phy_txpower_hw_ctrl_get(wlc->band->pi) != PHY_TPC_HW_ON)) wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD; - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); - wlc_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); + brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); + brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); - wlc_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO); + brcms_c_stf_stbc_rx_ht_update(wlc, HT_CAP_RX_STBC_NO); wlc->bandstate[BAND_2G_INDEX]->band_stf_stbc_tx = OFF; wlc->bandstate[BAND_5G_INDEX]->band_stf_stbc_tx = OFF; - if (WLC_STBC_CAP_PHY(wlc)) { + if (BRCMS_STBC_CAP_PHY(wlc)) { wlc->stf->ss_algosel_auto = true; wlc->stf->ss_algo_channel = (u16) -1; /* Init the default value */ } return 0; } -void wlc_stf_detach(struct wlc_info *wlc) +void brcms_c_stf_detach(struct brcms_c_info *wlc) { } -int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val) -{ - int bcmerror = 0; - - /* when there is only 1 tx_streams, don't allow to change the txant */ - if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1)) - return ((val == wlc->stf->txant) ? bcmerror : -EINVAL); - - switch (val) { - case -1: - val = ANT_TX_DEF; - break; - case 0: - val = ANT_TX_FORCE_0; - break; - case 1: - val = ANT_TX_FORCE_1; - break; - case 3: - val = ANT_TX_LAST_RX; - break; - default: - bcmerror = -EINVAL; - break; - } - - if (bcmerror == 0) - wlc->stf->txant = (s8) val; - - return bcmerror; - -} - /* * Centralized txant update function. call it whenever wlc->stf->txant and/or wlc->stf->txchain * change @@ -411,24 +363,25 @@ int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val) * do tx-antenna selection for SISO transmissions * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 means both cores active */ -static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc) +static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc) { s8 txant; txant = (s8) wlc->stf->txant; - if (WLC_PHY_11N_CAP(wlc->band)) { + if (BRCMS_PHY_11N_CAP(wlc->band)) { if (txant == ANT_TX_FORCE_0) { wlc->stf->phytxant = PHY_TXC_ANT_0; } else if (txant == ANT_TX_FORCE_1) { wlc->stf->phytxant = PHY_TXC_ANT_1; - if (WLCISNPHY(wlc->band) && + if (BRCMS_ISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3) && NREV_LT(wlc->band->phyrev, 7)) { wlc->stf->phytxant = PHY_TXC_ANT_2; } } else { - if (WLCISLCNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band)) + if (BRCMS_ISLCNPHY(wlc->band) || + BRCMS_ISSSLPNPHY(wlc->band)) wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST; else { /* catch out of sync wlc->stf->txcore */ @@ -446,15 +399,15 @@ static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc) wlc->stf->phytxant = PHY_TXC_OLD_ANT_LAST; } - wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant); + brcms_b_txant_set(wlc->hw, wlc->stf->phytxant); } -void wlc_stf_phy_txant_upd(struct wlc_info *wlc) +void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc) { - _wlc_stf_phy_txant_upd(wlc); + _brcms_c_stf_phy_txant_upd(wlc); } -void wlc_stf_phy_chain_calc(struct wlc_info *wlc) +void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc) { /* get available rx/tx chains */ wlc->stf->hw_txchain = (u8) getintvar(wlc->pub->vars, "txchain"); @@ -462,7 +415,7 @@ void wlc_stf_phy_chain_calc(struct wlc_info *wlc) /* these parameter are intended to be used for all PHY types */ if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) { - if (WLCISNPHY(wlc->band)) { + if (BRCMS_ISNPHY(wlc->band)) { wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY; } else { wlc->stf->hw_txchain = TXCHAIN_DEF; @@ -470,10 +423,10 @@ void wlc_stf_phy_chain_calc(struct wlc_info *wlc) } wlc->stf->txchain = wlc->stf->hw_txchain; - wlc->stf->txstreams = (u8) WLC_BITSCNT(wlc->stf->hw_txchain); + wlc->stf->txstreams = (u8) BRCMS_BITSCNT(wlc->stf->hw_txchain); if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) { - if (WLCISNPHY(wlc->band)) { + if (BRCMS_ISNPHY(wlc->band)) { wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY; } else { wlc->stf->hw_rxchain = RXCHAIN_DEF; @@ -481,17 +434,18 @@ void wlc_stf_phy_chain_calc(struct wlc_info *wlc) } wlc->stf->rxchain = wlc->stf->hw_rxchain; - wlc->stf->rxstreams = (u8) WLC_BITSCNT(wlc->stf->hw_rxchain); + wlc->stf->rxstreams = (u8) BRCMS_BITSCNT(wlc->stf->hw_rxchain); /* initialize the txcore table */ memcpy(wlc->stf->txcore, txcore_default, sizeof(wlc->stf->txcore)); /* default spatial_policy */ wlc->stf->spatial_policy = MIN_SPATIAL_EXPANSION; - wlc_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION); + brcms_c_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION); } -static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) +static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, + ratespec_t rspec) { u16 phytxant = wlc->stf->phytxant; @@ -503,19 +457,19 @@ static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) return phytxant; } -u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) +u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, ratespec_t rspec) { - return _wlc_stf_phytxchain_sel(wlc, rspec); + return _brcms_c_stf_phytxchain_sel(wlc, rspec); } -u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec) +u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, ratespec_t rspec) { u16 phytxant = wlc->stf->phytxant; u16 mask = PHY_TXC_ANT_MASK; /* for non-siso rates or default setting, use the available chains */ - if (WLCISNPHY(wlc->band)) { - phytxant = _wlc_stf_phytxchain_sel(wlc, rspec); + if (BRCMS_ISNPHY(wlc->band)) { + phytxant = _brcms_c_stf_phytxchain_sel(wlc, rspec); mask = PHY_TXC_HTANT_MASK; } phytxant |= phytxant & mask; diff --git a/drivers/staging/brcm80211/brcmsmac/stf.h b/drivers/staging/brcm80211/brcmsmac/stf.h new file mode 100644 index 000000000000..06c2a399649e --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/stf.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BRCM_STF_H_ +#define _BRCM_STF_H_ + +#include "types.h" + +extern int brcms_c_stf_attach(struct brcms_c_info *wlc); +extern void brcms_c_stf_detach(struct brcms_c_info *wlc); + +extern void brcms_c_tempsense_upd(struct brcms_c_info *wlc); +extern void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, + u16 *ss_algo_channel, + chanspec_t chanspec); +extern int brcms_c_stf_ss_update(struct brcms_c_info *wlc, + struct brcms_band *band); +extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); +extern int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, + bool force); +extern bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val); +extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); +extern void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc); +extern u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, + ratespec_t rspec); +extern u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, + ratespec_t rspec); + +#endif /* _BRCM_STF_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/types.h b/drivers/staging/brcm80211/brcmsmac/types.h new file mode 100644 index 000000000000..bbf21897ae0e --- /dev/null +++ b/drivers/staging/brcm80211/brcmsmac/types.h @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BRCM_TYPES_H_ +#define _BRCM_TYPES_H_ + +#include + +/* Bus types */ +#define SI_BUS 0 /* SOC Interconnect */ +#define PCI_BUS 1 /* PCI target */ +#define SDIO_BUS 3 /* SDIO target */ +#define JTAG_BUS 4 /* JTAG */ +#define USB_BUS 5 /* USB (does not support R/W REG) */ +#define SPI_BUS 6 /* gSPI target */ +#define RPC_BUS 7 /* RPC target */ + +#define WL_CHAN_FREQ_RANGE_2G 0 +#define WL_CHAN_FREQ_RANGE_5GL 1 +#define WL_CHAN_FREQ_RANGE_5GM 2 +#define WL_CHAN_FREQ_RANGE_5GH 3 + +#define MAX_DMA_SEGS 4 + +/* boardflags */ +#define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */ +#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */ +#define BFL_FEM 0x00000800 /* Board supports the Front End Module */ +#define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */ +#define BFL_NOPA 0x00010000 /* Board has no PA */ +#define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */ +#define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */ +#define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */ +#define BFL_PALDO 0x02000000 /* Power topology uses PALDO */ +#define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ + +/* boardflags2 */ +#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */ +#define BFL2_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */ +#define BFL2_TXPWRCTRL_EN 0x00000004 /* Board permits enabling TX Power Control */ +#define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */ +#define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */ +#define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */ +#define BFL2_LEGACY 0x00000080 +#define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */ +#define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */ +#define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */ +#define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */ +#define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */ +#define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */ +#define BFL2_IPALVLSHIFT_3P3 0x00020000 +#define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */ +#define BFL2_XTALBUFOUTEN 0x00080000 /* Keep the buffered Xtal output from radio "ON" + * Most drivers will turn it off without this flag + * to save power. + */ + +/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ +#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ +#define BOARD_GPIO_12 0x1000 /* gpio 12 */ +#define BOARD_GPIO_13 0x2000 /* gpio 13 */ + +/* **** Core type/rev defaults **** */ +#define D11CONF 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 + * also need to update wlc.h MAXCOREREV + */ + +#define NCONF 0x000001ff /* Supported nphy revs: + * 0 4321a0 + * 1 4321a1 + * 2 4321b0/b1/c0/c1 + * 3 4322a0 + * 4 4322a1 + * 5 4716a0 + * 6 43222a0, 43224a0 + * 7 43226a0 + * 8 5357a0, 43236a0 + */ + +#define LCNCONF 0x00000007 /* Supported lcnphy revs: + * 0 4313a0, 4336a0, 4330a0 + * 1 + * 2 4330a0 + */ + +#define SSLPNCONF 0x0000000f /* Supported sslpnphy revs: + * 0 4329a0/k0 + * 1 4329b0/4329C0 + * 2 4319a0 + * 3 5356a0 + */ + +/******************************************************************** + * Phy/Core Configuration. Defines macros to to check core phy/rev * + * compile-time configuration. Defines default core support. * + * ****************************************************************** + */ + +/* Basic macros to check a configuration bitmask */ + +#define CONF_HAS(config, val) ((config) & (1 << (val))) +#define CONF_MSK(config, mask) ((config) & (mask)) +#define MSK_RANGE(low, hi) ((1 << ((hi)+1)) - (1 << (low))) +#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high))) + +#define CONF_IS(config, val) ((config) == (1 << (val))) +#define CONF_GE(config, val) ((config) & (0-(1 << (val)))) +#define CONF_GT(config, val) ((config) & (0-2*(1 << (val)))) +#define CONF_LT(config, val) ((config) & ((1 << (val))-1)) +#define CONF_LE(config, val) ((config) & (2*(1 << (val))-1)) + +/* Wrappers for some of the above, specific to config constants */ + +#define NCONF_HAS(val) CONF_HAS(NCONF, val) +#define NCONF_MSK(mask) CONF_MSK(NCONF, mask) +#define NCONF_IS(val) CONF_IS(NCONF, val) +#define NCONF_GE(val) CONF_GE(NCONF, val) +#define NCONF_GT(val) CONF_GT(NCONF, val) +#define NCONF_LT(val) CONF_LT(NCONF, val) +#define NCONF_LE(val) CONF_LE(NCONF, val) + +#define LCNCONF_HAS(val) CONF_HAS(LCNCONF, val) +#define LCNCONF_MSK(mask) CONF_MSK(LCNCONF, mask) +#define LCNCONF_IS(val) CONF_IS(LCNCONF, val) +#define LCNCONF_GE(val) CONF_GE(LCNCONF, val) +#define LCNCONF_GT(val) CONF_GT(LCNCONF, val) +#define LCNCONF_LT(val) CONF_LT(LCNCONF, val) +#define LCNCONF_LE(val) CONF_LE(LCNCONF, val) + +#define D11CONF_HAS(val) CONF_HAS(D11CONF, val) +#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask) +#define D11CONF_IS(val) CONF_IS(D11CONF, val) +#define D11CONF_GE(val) CONF_GE(D11CONF, val) +#define D11CONF_GT(val) CONF_GT(D11CONF, val) +#define D11CONF_LT(val) CONF_LT(D11CONF, val) +#define D11CONF_LE(val) CONF_LE(D11CONF, val) + +#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val) +#define PHYCONF_IS(val) CONF_IS(PHYTYPE, val) + +#define NREV_IS(var, val) (NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val)))) +#define NREV_GE(var, val) (NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val)))) +#define NREV_GT(var, val) (NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val)))) +#define NREV_LT(var, val) (NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val)))) +#define NREV_LE(var, val) (NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val)))) + +#define LCNREV_IS(var, val) (LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val)))) +#define LCNREV_GE(var, val) (LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val)))) +#define LCNREV_GT(var, val) (LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val)))) +#define LCNREV_LT(var, val) (LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val)))) +#define LCNREV_LE(var, val) (LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val)))) + +#define D11REV_IS(var, val) (D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val)))) +#define D11REV_GE(var, val) (D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val)))) +#define D11REV_GT(var, val) (D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val)))) +#define D11REV_LT(var, val) (D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val)))) +#define D11REV_LE(var, val) (D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val)))) + +#define PHYTYPE_IS(var, val) (PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val)))) + +/* Finally, early-exit from switch case if anyone wants it... */ + +#define CASECHECK(config, val) if (!(CONF_HAS(config, val))) break +#define CASEMSK(config, mask) if (!(CONF_MSK(config, mask))) break + +/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */ + +#define _PHYCONF_N (1 << PHY_TYPE_N) +#define _PHYCONF_LCN (1 << PHY_TYPE_LCN) +#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN) + +#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN) + +/* Utility macro to identify 802.11n (HT) capable PHYs */ +#define PHYTYPE_11N_CAP(phytype) \ + (PHYTYPE_IS(phytype, PHY_TYPE_N) || \ + PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \ + PHYTYPE_IS(phytype, PHY_TYPE_SSN)) + +/* Last but not least: shorter wlc-specific var checks */ +#define BRCMS_ISNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_N) +#define BRCMS_ISLCNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN) +#define BRCMS_ISSSLPNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN) + +#define BRCMS_PHY_11N_CAP(band) PHYTYPE_11N_CAP((band)->phytype) + +/********************************************************************** + * ------------- End of Core phy/rev configuration. ----------------- * + * ******************************************************************** + */ + +/************************************************* + * Defaults for tunables (e.g. sizing constants) + * + * For each new tunable, add a member to the end + * of struct brcms_tunables in brcms_c_pub.h to enable + * runtime checks of tunable values. (Directly + * using the macros in code invalidates ROM code) + * + * *********************************************** + */ +#define NTXD 256 /* Max # of entries in Tx FIFO based on 4kb page size */ +#define NRXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */ +#define NRXBUFPOST 32 /* try to keep this # rbufs posted to the chip */ +#define MAXSCB 32 /* Maximum SCBs in cache for STA */ +#define AMPDU_NUM_MPDU 16 /* max allowed number of mpdus in an ampdu (2 streams) */ + +/* Count of packet callback structures. either of following + * 1. Set to the number of SCBs since a STA + * can queue up a rate callback for each IBSS STA it knows about, and an AP can + * queue up an "are you there?" Null Data callback for each associated STA + * 2. controlled by tunable config file + */ +#define MAXPKTCB MAXSCB /* Max number of packet callbacks */ + +/* NetBSD also needs to keep track of this */ + +/* Number of BSS handled in ucode bcn/prb */ +#define BRCMS_MAX_UCODE_BSS (16) +/* Number of BSS handled in sw bcn/prb */ +#define BRCMS_MAX_UCODE_BSS4 (4) +/* max # BSS configs */ +#define BRCMS_MAXBSSCFG (1) +/* max # available networks */ +#define MAXBSS 64 +/* data msg txq hiwat mark */ +#define BRCMS_DATAHIWAT 50 +#define BRCMS_AMPDUDATAHIWAT 255 + +/* bounded rx loops */ +#define RXBND 8 /* max # frames to process in brcms_c_recv() */ +#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */ + +#define BAND_5G(bt) ((bt) == BRCM_BAND_5G) +#define BAND_2G(bt) ((bt) == BRCM_BAND_2G) + +#define BCMMSG(dev, fmt, args...) \ +do { \ + if (brcm_msg_level & LOG_TRACE_VAL) \ + wiphy_err(dev, "%s: " fmt, __func__, ##args); \ +} while (0) + +#define WL_ERROR_ON() (brcm_msg_level & LOG_ERROR_VAL) + +/* register access macros */ +#ifndef __BIG_ENDIAN +#ifndef __mips__ +#define R_REG(r) \ + ({\ + sizeof(*(r)) == sizeof(u8) ? \ + readb((u8 *)(r)) : \ + sizeof(*(r)) == sizeof(u16) ? readw((u16 *)(r)) : \ + readl((u32 *)(r)); \ + }) +#else /* __mips__ */ +#define R_REG(r) \ + ({ \ + __typeof(*(r)) __osl_v; \ + __asm__ __volatile__("sync"); \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + __osl_v = readb((u8 *)(r)); \ + break; \ + case sizeof(u16): \ + __osl_v = readw((u16 *)(r)); \ + break; \ + case sizeof(u32): \ + __osl_v = \ + readl((u32 *)(r)); \ + break; \ + } \ + __asm__ __volatile__("sync"); \ + __osl_v; \ + }) +#endif /* __mips__ */ + +#define W_REG(r, v) do { \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + writeb((u8)(v), (u8 *)(r)); break; \ + case sizeof(u16): \ + writew((u16)(v), (u16 *)(r)); break; \ + case sizeof(u32): \ + writel((u32)(v), (u32 *)(r)); break; \ + }; \ + } while (0) +#else /* __BIG_ENDIAN */ +#define R_REG(r) \ + ({ \ + __typeof(*(r)) __osl_v; \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + __osl_v = \ + readb((u8 *)((r)^3)); \ + break; \ + case sizeof(u16): \ + __osl_v = \ + readw((u16 *)((r)^2)); \ + break; \ + case sizeof(u32): \ + __osl_v = readl((u32 *)(r)); \ + break; \ + } \ + __osl_v; \ + }) + +#define W_REG(r, v) do { \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + writeb((u8)(v), \ + (u8 *)((r)^3)); break; \ + case sizeof(u16): \ + writew((u16)(v), \ + (u16 *)((r)^2)); break; \ + case sizeof(u32): \ + writel((u32)(v), \ + (u32 *)(r)); break; \ + } \ + } while (0) +#endif /* __BIG_ENDIAN */ + +#ifdef __mips__ +/* + * bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder + * transactions. As a fix, a read after write is performed on certain places + * in the code. Older chips and the newer 5357 family don't require this fix. + */ +#define W_REG_FLUSH(r, v) ({ W_REG((r), (v)); (void)R_REG(r); }) +#else +#define W_REG_FLUSH(r, v) W_REG((r), (v)) +#endif /* __mips__ */ + +#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) +#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) + +#define SET_REG(r, mask, val) \ + W_REG((r), ((R_REG(r) & ~(mask)) | (val))) + +/* multi-bool data type: set of bools, mbool is true if any is set */ +typedef u32 mbool; +#define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */ +#define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */ +#define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* true if one bool is set */ +#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) + +/* forward declarations */ +struct wiphy; +struct ieee80211_sta; +struct ieee80211_tx_queue_params; +struct brcms_info; +struct brcms_c_info; +struct brcms_hardware; +struct brcms_c_if; +struct brcmu_iovar; +struct brcmu_strbuf; +struct brcms_txq_info; +struct brcms_band; +struct dma_pub; +struct si_pub; +struct tx_status; +struct d11rxhdr; +struct brcms_d11rxhdr; +struct txpwr_limits; +struct brcms_phy; + +typedef volatile struct intctrlregs intctrlregs_t; +typedef volatile struct pio2regs pio2regs_t; +typedef volatile struct pio2regp pio2regp_t; +typedef volatile struct pio4regs pio4regs_t; +typedef volatile struct pio4regp pio4regp_t; +typedef volatile struct fifo64 fifo64_t; +typedef volatile struct d11regs d11regs_t; +typedef volatile struct dma32diag dma32diag_t; +typedef volatile struct dma64regs dma64regs_t; +typedef struct brcms_rateset wlc_rateset_t; +typedef u32 ratespec_t; +typedef struct chanvec chanvec_t; +typedef s32 fixed; +typedef struct _cs32 cs32; +typedef volatile union pmqreg pmqreg_t; + +/* brcm_msg_level is a bit vector with defs in defs.h */ +extern u32 brcm_msg_level; + +#endif /* _BRCM_TYPES_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c b/drivers/staging/brcm80211/brcmsmac/ucode_loader.c similarity index 50% rename from drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c rename to drivers/staging/brcm80211/brcmsmac/ucode_loader.c index cc00dd19746b..bf733fb18ce1 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_ucode_loader.c +++ b/drivers/staging/brcm80211/brcmsmac/ucode_loader.c @@ -14,9 +14,9 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include +#include +#include "types.h" +#include enum { D11UCODE_NAMETAG_START = 0, @@ -53,59 +53,63 @@ u32 bcm43xx_24_lcnsz; u32 *bcm43xx_bommajor; u32 *bcm43xx_bomminor; -int wl_ucode_data_init(struct wl_info *wl) +int brcms_ucode_data_init(struct brcms_info *wl) { int rc; - rc = wl_check_firmwares(wl); + rc = brcms_check_firmwares(wl); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24, - D11LCN0BSINITVALS24); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24, + rc = rc < 0 ? rc : + brcms_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24, + D11LCN0BSINITVALS24); + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11lcn0initvals24, D11LCN0INITVALS24); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24, - D11LCN1BSINITVALS24); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24, + rc = rc < 0 ? rc : + brcms_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24, + D11LCN1BSINITVALS24); + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11lcn1initvals24, D11LCN1INITVALS24); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24, - D11LCN2BSINITVALS24); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24, + rc = rc < 0 ? rc : + brcms_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24, + D11LCN2BSINITVALS24); + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11lcn2initvals24, D11LCN2INITVALS24); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16, - D11N0ABSINITVALS16); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16, + rc = rc < 0 ? rc : + brcms_ucode_init_buf(wl, (void **)&d11n0absinitvals16, + D11N0ABSINITVALS16); + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11n0bsinitvals16, D11N0BSINITVALS16); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0initvals16, + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&d11n0initvals16, D11N0INITVALS16); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo, + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo, D11UCODE_OVERSIGHT16_MIMO); - rc = rc < 0 ? rc : wl_ucode_init_uint(wl, &bcm43xx_16_mimosz, + rc = rc < 0 ? rc : brcms_ucode_init_uint(wl, &bcm43xx_16_mimosz, D11UCODE_OVERSIGHT16_MIMOSZ); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn, + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn, D11UCODE_OVERSIGHT24_LCN); - rc = rc < 0 ? rc : wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz, + rc = rc < 0 ? rc : brcms_ucode_init_uint(wl, &bcm43xx_24_lcnsz, D11UCODE_OVERSIGHT24_LCNSZ); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor, + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_bommajor, D11UCODE_OVERSIGHT_BOMMAJOR); - rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor, + rc = rc < 0 ? rc : brcms_ucode_init_buf(wl, (void **)&bcm43xx_bomminor, D11UCODE_OVERSIGHT_BOMMINOR); return rc; } -void wl_ucode_data_free(void) +void brcms_ucode_data_free(void) { - wl_ucode_free_buf((void *)d11lcn0bsinitvals24); - wl_ucode_free_buf((void *)d11lcn0initvals24); - wl_ucode_free_buf((void *)d11lcn1bsinitvals24); - wl_ucode_free_buf((void *)d11lcn1initvals24); - wl_ucode_free_buf((void *)d11lcn2bsinitvals24); - wl_ucode_free_buf((void *)d11lcn2initvals24); - wl_ucode_free_buf((void *)d11n0absinitvals16); - wl_ucode_free_buf((void *)d11n0bsinitvals16); - wl_ucode_free_buf((void *)d11n0initvals16); - wl_ucode_free_buf((void *)bcm43xx_16_mimo); - wl_ucode_free_buf((void *)bcm43xx_24_lcn); - wl_ucode_free_buf((void *)bcm43xx_bommajor); - wl_ucode_free_buf((void *)bcm43xx_bomminor); + brcms_ucode_free_buf((void *)d11lcn0bsinitvals24); + brcms_ucode_free_buf((void *)d11lcn0initvals24); + brcms_ucode_free_buf((void *)d11lcn1bsinitvals24); + brcms_ucode_free_buf((void *)d11lcn1initvals24); + brcms_ucode_free_buf((void *)d11lcn2bsinitvals24); + brcms_ucode_free_buf((void *)d11lcn2initvals24); + brcms_ucode_free_buf((void *)d11n0absinitvals16); + brcms_ucode_free_buf((void *)d11n0bsinitvals16); + brcms_ucode_free_buf((void *)d11n0initvals16); + brcms_ucode_free_buf((void *)bcm43xx_16_mimo); + brcms_ucode_free_buf((void *)bcm43xx_24_lcn); + brcms_ucode_free_buf((void *)bcm43xx_bommajor); + brcms_ucode_free_buf((void *)bcm43xx_bomminor); return; } diff --git a/drivers/staging/brcm80211/brcmsmac/wl_ucode.h b/drivers/staging/brcm80211/brcmsmac/ucode_loader.h similarity index 78% rename from drivers/staging/brcm80211/brcmsmac/wl_ucode.h rename to drivers/staging/brcm80211/brcmsmac/ucode_loader.h index 6933fda0e6a0..ca53deced7bf 100644 --- a/drivers/staging/brcm80211/brcmsmac/wl_ucode.h +++ b/drivers/staging/brcm80211/brcmsmac/ucode_loader.h @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "types.h" /* forward structure declarations */ + #define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */ #define MAX_FW_SIZE 150000 @@ -39,11 +41,12 @@ extern u32 bcm43xx_16_mimosz; extern u32 *bcm43xx_24_lcn; extern u32 bcm43xx_24_lcnsz; -extern int wl_ucode_data_init(struct wl_info *wl); -extern void wl_ucode_data_free(void); +extern int brcms_ucode_data_init(struct brcms_info *wl); +extern void brcms_ucode_data_free(void); -extern int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, unsigned int idx); -extern int wl_ucode_init_uint(struct wl_info *wl, unsigned *data, +extern int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, + unsigned int idx); +extern int brcms_ucode_init_uint(struct brcms_info *wl, unsigned *data, unsigned int idx); -extern void wl_ucode_free_buf(void *); -extern int wl_check_firmwares(struct wl_info *wl); +extern void brcms_ucode_free_buf(void *); +extern int brcms_check_firmwares(struct brcms_info *wl); diff --git a/drivers/staging/brcm80211/brcmsmac/wl_dbg.h b/drivers/staging/brcm80211/brcmsmac/wl_dbg.h deleted file mode 100644 index 5582de3ee721..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wl_dbg.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wl_dbg_h_ -#define _wl_dbg_h_ - -#include /* dev_err() */ - -/* wl_msg_level is a bit vector with defs in wlioctl.h */ -extern u32 wl_msg_level; - -#define BCMMSG(dev, fmt, args...) \ -do { \ - if (wl_msg_level & WL_TRACE_VAL) \ - wiphy_err(dev, "%s: " fmt, __func__, ##args); \ -} while (0) - -#ifdef BCMDBG - - -/* Extra message control for AMPDU debugging */ -#define WL_AMPDU_UPDN_VAL 0x00000001 /* Config up/down related */ -#define WL_AMPDU_ERR_VAL 0x00000002 /* Calls to beaocn update */ -#define WL_AMPDU_TX_VAL 0x00000004 /* Transmit data path */ -#define WL_AMPDU_RX_VAL 0x00000008 /* Receive data path */ -#define WL_AMPDU_CTL_VAL 0x00000010 /* TSF-related items */ -#define WL_AMPDU_HW_VAL 0x00000020 /* AMPDU_HW */ -#define WL_AMPDU_HWTXS_VAL 0x00000040 /* AMPDU_HWTXS */ -#define WL_AMPDU_HWDBG_VAL 0x00000080 /* AMPDU_DBG */ - -extern u32 wl_ampdu_dbg; - -#define WL_AMPDU_PRINT(level, fmt, args...) \ -do { \ - if (wl_ampdu_dbg & level) { \ - WL_AMPDU(fmt, ##args); \ - } \ -} while (0) - -#define WL_AMPDU_UPDN(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_UPDN_VAL, fmt, ##args) -#define WL_AMPDU_RX(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_RX_VAL, fmt, ##args) -#define WL_AMPDU_ERR(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_ERR_VAL, fmt, ##args) -#define WL_AMPDU_TX(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_TX_VAL, fmt, ##args) -#define WL_AMPDU_CTL(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_CTL_VAL, fmt, ##args) -#define WL_AMPDU_HW(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_HW_VAL, fmt, ##args) -#define WL_AMPDU_HWTXS(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_HWTXS_VAL, fmt, ##args) -#define WL_AMPDU_HWDBG(fmt, args...) \ - WL_AMPDU_PRINT(WL_AMPDU_HWDBG_VAL, fmt, ##args) -#define WL_AMPDU_ERR_ON() (wl_ampdu_dbg & WL_AMPDU_ERR_VAL) -#define WL_AMPDU_HW_ON() (wl_ampdu_dbg & WL_AMPDU_HW_VAL) -#define WL_AMPDU_HWTXS_ON() (wl_ampdu_dbg & WL_AMPDU_HWTXS_VAL) - -#else /* BCMDBG */ - - -#define WL_AMPDU_UPDN(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_RX(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_ERR(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_TX(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_CTL(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_HW(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_HWTXS(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_HWDBG(fmt, args...) no_printk(fmt, ##args) -#define WL_AMPDU_ERR_ON() 0 -#define WL_AMPDU_HW_ON() 0 -#define WL_AMPDU_HWTXS_ON() 0 - -#endif /* BCMDBG */ - -#define WL_ERROR_ON() (wl_msg_level & WL_ERROR_VAL) - -#endif /* _wl_dbg_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wl_export.h b/drivers/staging/brcm80211/brcmsmac/wl_export.h deleted file mode 100644 index 0fe0b24b586f..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wl_export.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wl_export_h_ -#define _wl_export_h_ - -/* misc callbacks */ -struct wl_info; -struct wl_if; -struct wlc_if; -extern void wl_init(struct wl_info *wl); -extern uint wl_reset(struct wl_info *wl); -extern void wl_intrson(struct wl_info *wl); -extern u32 wl_intrsoff(struct wl_info *wl); -extern void wl_intrsrestore(struct wl_info *wl, u32 macintmask); -extern int wl_up(struct wl_info *wl); -extern void wl_down(struct wl_info *wl); -extern void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, - int prio); -extern bool wl_alloc_dma_resources(struct wl_info *wl, uint dmaddrwidth); -extern bool wl_rfkill_set_hw_state(struct wl_info *wl); - -/* timer functions */ -struct wl_timer; -extern struct wl_timer *wl_init_timer(struct wl_info *wl, - void (*fn) (void *arg), void *arg, - const char *name); -extern void wl_free_timer(struct wl_info *wl, struct wl_timer *timer); -extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms, - int periodic); -extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer); -extern void wl_msleep(struct wl_info *wl, uint ms); - -#endif /* _wl_export_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h deleted file mode 100644 index 63d403b036f4..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_ampdu_h_ -#define _wlc_ampdu_h_ - -extern struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc); -extern void wlc_ampdu_detach(struct ampdu_info *ampdu); -extern int wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi, - struct sk_buff **aggp, int prec); -extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, - struct sk_buff *p, tx_status_t *txs); -extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc); -extern void wlc_ampdu_shm_upd(struct ampdu_info *ampdu); - -#endif /* _wlc_ampdu_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h b/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h deleted file mode 100644 index a5dccc273ac5..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef _wlc_bmac_h_ -#define _wlc_bmac_h_ - -/* XXXXX this interface is under wlc.c by design - * http://hwnbu-twiki.broadcom.com/bin/view/Mwgroup/WlBmacDesign - * - * high driver files(e.g. wlc_ampdu.c etc) - * wlc.h/wlc.c - * wlc_bmac.h/wlc_bmac.c - * - * So don't include this in files other than wlc.c, wlc_bmac* wl_rte.c(dongle port) and wl_phy.c - * create wrappers in wlc.c if needed - */ - -/* dup state between BMAC(struct wlc_hw_info) and HIGH(struct wlc_info) - driver */ -typedef struct wlc_bmac_state { - u32 machwcap; /* mac hw capibility */ - u32 preamble_ovr; /* preamble override */ -} wlc_bmac_state_t; - -enum { - IOV_BMAC_DIAG, - IOV_BMAC_SBGPIOTIMERVAL, - IOV_BMAC_SBGPIOOUT, - IOV_BMAC_CCGPIOCTRL, /* CC GPIOCTRL REG */ - IOV_BMAC_CCGPIOOUT, /* CC GPIOOUT REG */ - IOV_BMAC_CCGPIOOUTEN, /* CC GPIOOUTEN REG */ - IOV_BMAC_CCGPIOIN, /* CC GPIOIN REG */ - IOV_BMAC_WPSGPIO, /* WPS push button GPIO pin */ - IOV_BMAC_OTPDUMP, - IOV_BMAC_OTPSTAT, - IOV_BMAC_PCIEASPM, /* obfuscation clkreq/aspm control */ - IOV_BMAC_PCIEADVCORRMASK, /* advanced correctable error mask */ - IOV_BMAC_PCIECLKREQ, /* PCIE 1.1 clockreq enab support */ - IOV_BMAC_PCIELCREG, /* PCIE LCREG */ - IOV_BMAC_SBGPIOTIMERMASK, - IOV_BMAC_RFDISABLEDLY, - IOV_BMAC_PCIEREG, /* PCIE REG */ - IOV_BMAC_PCICFGREG, /* PCI Config register */ - IOV_BMAC_PCIESERDESREG, /* PCIE SERDES REG (dev, 0}offset) */ - IOV_BMAC_PCIEGPIOOUT, /* PCIEOUT REG */ - IOV_BMAC_PCIEGPIOOUTEN, /* PCIEOUTEN REG */ - IOV_BMAC_PCIECLKREQENCTRL, /* clkreqenctrl REG (PCIE REV > 6.0 */ - IOV_BMAC_DMALPBK, - IOV_BMAC_CCREG, - IOV_BMAC_COREREG, - IOV_BMAC_SDCIS, - IOV_BMAC_SDIO_DRIVE, - IOV_BMAC_OTPW, - IOV_BMAC_NVOTPW, - IOV_BMAC_SROM, - IOV_BMAC_SRCRC, - IOV_BMAC_CIS_SOURCE, - IOV_BMAC_CISVAR, - IOV_BMAC_OTPLOCK, - IOV_BMAC_OTP_CHIPID, - IOV_BMAC_CUSTOMVAR1, - IOV_BMAC_BOARDFLAGS, - IOV_BMAC_BOARDFLAGS2, - IOV_BMAC_WPSLED, - IOV_BMAC_NVRAM_SOURCE, - IOV_BMAC_OTP_RAW_READ, - IOV_BMAC_LAST -}; - -extern int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, - uint unit, bool piomode, void *regsva, uint bustype, - void *btparam); -extern int wlc_bmac_detach(struct wlc_info *wlc); -extern void wlc_bmac_watchdog(void *arg); - -/* up/down, reset, clk */ -extern void wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, - uint offset, const void *buf, int len, - u32 sel); -extern void wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, - void *buf, int len, u32 sel); -#define wlc_bmac_copyfrom_shm(wlc_hw, offset, buf, len) \ - wlc_bmac_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) -#define wlc_bmac_copyto_shm(wlc_hw, offset, buf, len) \ - wlc_bmac_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) - -extern void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on); -extern void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk); -extern void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk); -extern void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); -extern void wlc_bmac_reset(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, - bool mute); -extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw); -extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode); - -/* chanspec, ucode interface */ -extern void wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, - chanspec_t chanspec, - bool mute, struct txpwr_limits *txpwr); - -extern int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, - uint *blocks); -extern void wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, - u16 val, int bands); -extern void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val); -extern u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands); -extern void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant); -extern u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, - u8 antsel_type); -extern int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, - wlc_bmac_state_t *state); -extern void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v); -extern u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset); -extern void wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, - int len, void *buf); -extern void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, - uint *len); - -extern void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, - u8 *ea); - -extern bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot); -extern void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode); - -extern void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw); - -extern void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, - u32 override_bit); -extern void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, - u32 override_bit); - -extern void wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, - int match_reg_offset, - const u8 *addr); -extern void wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, - void *bcn, int len, bool both); - -extern void wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, - u32 *tsf_h_ptr); -extern void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin); -extern void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax); - -extern void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, - u16 LRL); - -extern void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw); - - -/* API for BMAC driver (e.g. wlc_phy.c etc) */ - -extern void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw); -extern void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, - mbool req_bit); -extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw); -extern u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate); -extern void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail); - -#endif /* _wlc_bmac_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h deleted file mode 100644 index 2572541bde9b..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WLC_BSSCFG_H_ -#define _WLC_BSSCFG_H_ - -/* Check if a particular BSS config is AP or STA */ -#define BSSCFG_AP(cfg) (0) -#define BSSCFG_STA(cfg) (1) - -#define BSSCFG_IBSS(cfg) (!(cfg)->BSS) - -#define NTXRATE 64 /* # tx MPDUs rate is reported for */ -#define MAXMACLIST 64 /* max # source MAC matches */ -#define BCN_TEMPLATE_COUNT 2 - -/* Iterator for "associated" STA bss configs: - (struct wlc_info *wlc, int idx, struct wlc_bsscfg *cfg) */ -#define FOREACH_AS_STA(wlc, idx, cfg) \ - for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ - if ((cfg = (wlc)->bsscfg[idx]) && BSSCFG_STA(cfg) && cfg->associated) - -/* As above for all non-NULL BSS configs */ -#define FOREACH_BSS(wlc, idx, cfg) \ - for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ - if ((cfg = (wlc)->bsscfg[idx])) - -/* BSS configuration state */ -struct wlc_bsscfg { - struct wlc_info *wlc; /* wlc to which this bsscfg belongs to. */ - bool up; /* is this configuration up operational */ - bool enable; /* is this configuration enabled */ - bool associated; /* is BSS in ASSOCIATED state */ - bool BSS; /* infraustructure or adhac */ - bool dtim_programmed; - - u8 SSID_len; /* the length of SSID */ - u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */ - struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */ - s8 _idx; /* the index of this bsscfg, - * assigned at wlc_bsscfg_alloc() - */ - /* MAC filter */ - uint nmac; /* # of entries on maclist array */ - int macmode; /* allow/deny stations on maclist array */ - struct ether_addr *maclist; /* list of source MAC addrs to match */ - - /* security */ - u32 wsec; /* wireless security bitvec */ - s16 auth; /* 802.11 authentication: Open, Shared Key, WPA */ - s16 openshared; /* try Open auth first, then Shared Key */ - bool wsec_restrict; /* drop unencrypted packets if wsec is enabled */ - bool eap_restrict; /* restrict data until 802.1X auth succeeds */ - u16 WPA_auth; /* WPA: authenticated key management */ - bool wpa2_preauth; /* default is true, wpa_cap sets value */ - bool wsec_portopen; /* indicates keys are plumbed */ - wsec_iv_t wpa_none_txiv; /* global txiv for WPA_NONE, tkip and aes */ - int wsec_index; /* 0-3: default tx key, -1: not set */ - wsec_key_t *bss_def_keys[WLC_DEFAULT_KEYS]; /* default key storage */ - - /* TKIP countermeasures */ - bool tkip_countermeasures; /* flags TKIP no-assoc period */ - u32 tk_cm_dt; /* detect timer */ - u32 tk_cm_bt; /* blocking timer */ - u32 tk_cm_bt_tmstmp; /* Timestamp when TKIP BT is activated */ - bool tk_cm_activate; /* activate countermeasures after EAPOL-Key sent */ - - u8 BSSID[ETH_ALEN]; /* BSSID (associated) */ - u8 cur_etheraddr[ETH_ALEN]; /* h/w address */ - u16 bcmc_fid; /* the last BCMC FID queued to TX_BCMC_FIFO */ - u16 bcmc_fid_shm; /* the last BCMC FID written to shared mem */ - - u32 flags; /* WLC_BSSCFG flags; see below */ - - u8 *bcn; /* AP beacon */ - uint bcn_len; /* AP beacon length */ - bool ar_disassoc; /* disassociated in associated recreation */ - - int auth_atmptd; /* auth type (open/shared) attempted */ - - pmkid_cand_t pmkid_cand[MAXPMKID]; /* PMKID candidate list */ - uint npmkid_cand; /* num PMKID candidates */ - pmkid_t pmkid[MAXPMKID]; /* PMKID cache */ - uint npmkid; /* num cached PMKIDs */ - - wlc_bss_info_t *current_bss; /* BSS parms in ASSOCIATED state */ - - /* PM states */ - bool PMawakebcn; /* bcn recvd during current waking state */ - bool PMpending; /* waiting for tx status with PM indicated set */ - bool priorPMstate; /* Detecting PM state transitions */ - bool PSpoll; /* whether there is an outstanding PS-Poll frame */ - - /* BSSID entry in RCMTA, use the wsec key management infrastructure to - * manage the RCMTA entries. - */ - wsec_key_t *rcmta; - - /* 'unique' ID of this bsscfg, assigned at bsscfg allocation */ - u16 ID; - - uint txrspecidx; /* index into tx rate circular buffer */ - ratespec_t txrspec[NTXRATE][2]; /* circular buffer of prev MPDUs tx rates */ -}; - -#define WLC_BSSCFG_11N_DISABLE 0x1000 /* Do not advertise .11n IEs for this BSS */ -#define WLC_BSSCFG_HW_BCN 0x20 /* The BSS is generating beacons in HW */ - -#define HWBCN_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0) -#define HWPRB_ENAB(cfg) (((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0) - -/* Extend N_ENAB to per-BSS */ -#define BSS_N_ENAB(wlc, cfg) \ - (N_ENAB((wlc)->pub) && !((cfg)->flags & WLC_BSSCFG_11N_DISABLE)) - -#define MBSS_BCN_ENAB(cfg) 0 -#define MBSS_PRB_ENAB(cfg) 0 -#define SOFTBCN_ENAB(pub) (0) -#define SOFTPRB_ENAB(pub) (0) -#define wlc_bsscfg_tx_check(a) do { } while (0); - -#endif /* _WLC_BSSCFG_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h b/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h deleted file mode 100644 index 85fbd0635310..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_cfg.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_cfg_h_ -#define _wlc_cfg_h_ - -#define NBANDS(wlc) ((wlc)->pub->_nbands) -#define NBANDS_PUB(pub) ((pub)->_nbands) -#define NBANDS_HW(hw) ((hw)->_nbands) - -#define IS_SINGLEBAND_5G(device) 0 - -/* **** Core type/rev defaults **** */ -#define D11_DEFAULT 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 - * also need to update wlc.h MAXCOREREV - */ - -#define NPHY_DEFAULT 0x000001ff /* Supported nphy revs: - * 0 4321a0 - * 1 4321a1 - * 2 4321b0/b1/c0/c1 - * 3 4322a0 - * 4 4322a1 - * 5 4716a0 - * 6 43222a0, 43224a0 - * 7 43226a0 - * 8 5357a0, 43236a0 - */ - -#define LCNPHY_DEFAULT 0x00000007 /* Supported lcnphy revs: - * 0 4313a0, 4336a0, 4330a0 - * 1 - * 2 4330a0 - */ - -#define SSLPNPHY_DEFAULT 0x0000000f /* Supported sslpnphy revs: - * 0 4329a0/k0 - * 1 4329b0/4329C0 - * 2 4319a0 - * 3 5356a0 - */ - - -/* For undefined values, use defaults */ -#ifndef D11CONF -#define D11CONF D11_DEFAULT -#endif -#ifndef NCONF -#define NCONF NPHY_DEFAULT -#endif -#ifndef LCNCONF -#define LCNCONF LCNPHY_DEFAULT -#endif - -#ifndef SSLPNCONF -#define SSLPNCONF SSLPNPHY_DEFAULT -#endif - -/******************************************************************** - * Phy/Core Configuration. Defines macros to to check core phy/rev * - * compile-time configuration. Defines default core support. * - * ****************************************************************** - */ - -/* Basic macros to check a configuration bitmask */ - -#define CONF_HAS(config, val) ((config) & (1 << (val))) -#define CONF_MSK(config, mask) ((config) & (mask)) -#define MSK_RANGE(low, hi) ((1 << ((hi)+1)) - (1 << (low))) -#define CONF_RANGE(config, low, hi) (CONF_MSK(config, MSK_RANGE(low, high))) - -#define CONF_IS(config, val) ((config) == (1 << (val))) -#define CONF_GE(config, val) ((config) & (0-(1 << (val)))) -#define CONF_GT(config, val) ((config) & (0-2*(1 << (val)))) -#define CONF_LT(config, val) ((config) & ((1 << (val))-1)) -#define CONF_LE(config, val) ((config) & (2*(1 << (val))-1)) - -/* Wrappers for some of the above, specific to config constants */ - -#define NCONF_HAS(val) CONF_HAS(NCONF, val) -#define NCONF_MSK(mask) CONF_MSK(NCONF, mask) -#define NCONF_IS(val) CONF_IS(NCONF, val) -#define NCONF_GE(val) CONF_GE(NCONF, val) -#define NCONF_GT(val) CONF_GT(NCONF, val) -#define NCONF_LT(val) CONF_LT(NCONF, val) -#define NCONF_LE(val) CONF_LE(NCONF, val) - -#define LCNCONF_HAS(val) CONF_HAS(LCNCONF, val) -#define LCNCONF_MSK(mask) CONF_MSK(LCNCONF, mask) -#define LCNCONF_IS(val) CONF_IS(LCNCONF, val) -#define LCNCONF_GE(val) CONF_GE(LCNCONF, val) -#define LCNCONF_GT(val) CONF_GT(LCNCONF, val) -#define LCNCONF_LT(val) CONF_LT(LCNCONF, val) -#define LCNCONF_LE(val) CONF_LE(LCNCONF, val) - -#define D11CONF_HAS(val) CONF_HAS(D11CONF, val) -#define D11CONF_MSK(mask) CONF_MSK(D11CONF, mask) -#define D11CONF_IS(val) CONF_IS(D11CONF, val) -#define D11CONF_GE(val) CONF_GE(D11CONF, val) -#define D11CONF_GT(val) CONF_GT(D11CONF, val) -#define D11CONF_LT(val) CONF_LT(D11CONF, val) -#define D11CONF_LE(val) CONF_LE(D11CONF, val) - -#define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val) -#define PHYCONF_IS(val) CONF_IS(PHYTYPE, val) - -#define NREV_IS(var, val) (NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val)))) -#define NREV_GE(var, val) (NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val)))) -#define NREV_GT(var, val) (NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val)))) -#define NREV_LT(var, val) (NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val)))) -#define NREV_LE(var, val) (NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val)))) - -#define LCNREV_IS(var, val) (LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val)))) -#define LCNREV_GE(var, val) (LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val)))) -#define LCNREV_GT(var, val) (LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val)))) -#define LCNREV_LT(var, val) (LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val)))) -#define LCNREV_LE(var, val) (LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val)))) - -#define D11REV_IS(var, val) (D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val)))) -#define D11REV_GE(var, val) (D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val)))) -#define D11REV_GT(var, val) (D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val)))) -#define D11REV_LT(var, val) (D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val)))) -#define D11REV_LE(var, val) (D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val)))) - -#define PHYTYPE_IS(var, val) (PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val)))) - -/* Finally, early-exit from switch case if anyone wants it... */ - -#define CASECHECK(config, val) if (!(CONF_HAS(config, val))) break -#define CASEMSK(config, mask) if (!(CONF_MSK(config, mask))) break - -#if (D11CONF ^ (D11CONF & D11_DEFAULT)) -#error "Unsupported MAC revision configured" -#endif -#if (NCONF ^ (NCONF & NPHY_DEFAULT)) -#error "Unsupported NPHY revision configured" -#endif -#if (LCNCONF ^ (LCNCONF & LCNPHY_DEFAULT)) -#error "Unsupported LPPHY revision configured" -#endif - -/* *** Consistency checks *** */ -#if !D11CONF -#error "No MAC revisions configured!" -#endif - -#if !NCONF && !LCNCONF && !SSLPNCONF -#error "No PHY configured!" -#endif - -/* Set up PHYTYPE automatically: (depends on PHY_TYPE_X, from d11.h) */ - -#define _PHYCONF_N (1 << PHY_TYPE_N) - -#if LCNCONF -#define _PHYCONF_LCN (1 << PHY_TYPE_LCN) -#else -#define _PHYCONF_LCN 0 -#endif /* LCNCONF */ - -#if SSLPNCONF -#define _PHYCONF_SSLPN (1 << PHY_TYPE_SSN) -#else -#define _PHYCONF_SSLPN 0 -#endif /* SSLPNCONF */ - -#define PHYTYPE (_PHYCONF_N | _PHYCONF_LCN | _PHYCONF_SSLPN) - -/* Utility macro to identify 802.11n (HT) capable PHYs */ -#define PHYTYPE_11N_CAP(phytype) \ - (PHYTYPE_IS(phytype, PHY_TYPE_N) || \ - PHYTYPE_IS(phytype, PHY_TYPE_LCN) || \ - PHYTYPE_IS(phytype, PHY_TYPE_SSN)) - -/* Last but not least: shorter wlc-specific var checks */ -#define WLCISNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_N) -#define WLCISLCNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_LCN) -#define WLCISSSLPNPHY(band) PHYTYPE_IS((band)->phytype, PHY_TYPE_SSN) - -#define WLC_PHY_11N_CAP(band) PHYTYPE_11N_CAP((band)->phytype) - -/********************************************************************** - * ------------- End of Core phy/rev configuration. ----------------- * - * ******************************************************************** - */ - -/************************************************* - * Defaults for tunables (e.g. sizing constants) - * - * For each new tunable, add a member to the end - * of wlc_tunables_t in wlc_pub.h to enable - * runtime checks of tunable values. (Directly - * using the macros in code invalidates ROM code) - * - * *********************************************** - */ -#ifndef NTXD -#define NTXD 256 /* Max # of entries in Tx FIFO based on 4kb page size */ -#endif /* NTXD */ -#ifndef NRXD -#define NRXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */ -#endif /* NRXD */ - -#ifndef NRXBUFPOST -#define NRXBUFPOST 32 /* try to keep this # rbufs posted to the chip */ -#endif /* NRXBUFPOST */ - -#ifndef MAXSCB /* station control blocks in cache */ -#define MAXSCB 32 /* Maximum SCBs in cache for STA */ -#endif /* MAXSCB */ - -#ifndef AMPDU_NUM_MPDU -#define AMPDU_NUM_MPDU 16 /* max allowed number of mpdus in an ampdu (2 streams) */ -#endif /* AMPDU_NUM_MPDU */ - -#ifndef AMPDU_NUM_MPDU_3STREAMS -#define AMPDU_NUM_MPDU_3STREAMS 32 /* max allowed number of mpdus in an ampdu for 3+ streams */ -#endif /* AMPDU_NUM_MPDU_3STREAMS */ - -/* Count of packet callback structures. either of following - * 1. Set to the number of SCBs since a STA - * can queue up a rate callback for each IBSS STA it knows about, and an AP can - * queue up an "are you there?" Null Data callback for each associated STA - * 2. controlled by tunable config file - */ -#ifndef MAXPKTCB -#define MAXPKTCB MAXSCB /* Max number of packet callbacks */ -#endif /* MAXPKTCB */ - -#ifndef CTFPOOLSZ -#define CTFPOOLSZ 128 -#endif /* CTFPOOLSZ */ - -/* NetBSD also needs to keep track of this */ -#define WLC_MAX_UCODE_BSS (16) /* Number of BSS handled in ucode bcn/prb */ -#define WLC_MAX_UCODE_BSS4 (4) /* Number of BSS handled in sw bcn/prb */ -#ifndef WLC_MAXBSSCFG -#define WLC_MAXBSSCFG (1) /* max # BSS configs */ -#endif /* WLC_MAXBSSCFG */ - -#ifndef MAXBSS -#define MAXBSS 64 /* max # available networks */ -#endif /* MAXBSS */ - -#ifndef WLC_DATAHIWAT -#define WLC_DATAHIWAT 50 /* data msg txq hiwat mark */ -#endif /* WLC_DATAHIWAT */ - -#ifndef WLC_AMPDUDATAHIWAT -#define WLC_AMPDUDATAHIWAT 255 -#endif /* WLC_AMPDUDATAHIWAT */ - -/* bounded rx loops */ -#ifndef RXBND -#define RXBND 8 /* max # frames to process in wlc_recv() */ -#endif /* RXBND */ -#ifndef TXSBND -#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */ -#endif /* TXSBND */ - -#define BAND_5G(bt) ((bt) == WLC_BAND_5G) -#define BAND_2G(bt) ((bt) == WLC_BAND_2G) - -#define WLBANDINITDATA(_data) _data -#define WLBANDINITFN(_fn) _fn - -#endif /* _wlc_cfg_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_key.h b/drivers/staging/brcm80211/brcmsmac/wlc_key.h deleted file mode 100644 index cab10c737937..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_key.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_key_h_ -#define _wlc_key_h_ - -struct scb; -struct wlc_info; -struct wlc_bsscfg; -/* Maximum # of keys that wl driver supports in S/W. - * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS. - */ -#define WSEC_MAX_KEYS 54 /* Max # of keys (50 + 4 default keys) */ -#define WLC_DEFAULT_KEYS 4 /* Default # of keys */ - -#define WSEC_MAX_WOWL_KEYS 5 /* Max keys in WOWL mode (1 + 4 default keys) */ - -#define WPA2_GTK_MAX 3 - -/* -* Max # of keys currently supported: -* -* s/w keys if WSEC_SW(wlc->wsec). -* h/w keys otherwise. -*/ -#define WLC_MAX_WSEC_KEYS(wlc) WSEC_MAX_KEYS - -/* number of 802.11 default (non-paired, group keys) */ -#define WSEC_MAX_DEFAULT_KEYS 4 /* # of default keys */ - -/* Max # of hardware keys supported */ -#define WLC_MAX_WSEC_HW_KEYS(wlc) WSEC_MAX_RCMTA_KEYS - -/* Max # of hardware TKIP MIC keys supported */ -#define WLC_MAX_TKMIC_HW_KEYS(wlc) (WSEC_MAX_TKMIC_ENGINE_KEYS) - -#define WSEC_HW_TKMIC_KEY(wlc, key, bsscfg) \ - ((((wlc)->machwcap & MCAP_TKIPMIC)) && \ - (key) && ((key)->algo == CRYPTO_ALGO_TKIP) && \ - !WSEC_SOFTKEY(wlc, key, bsscfg) && \ - WSEC_KEY_INDEX(wlc, key) >= WLC_DEFAULT_KEYS && \ - (WSEC_KEY_INDEX(wlc, key) < WSEC_MAX_TKMIC_ENGINE_KEYS)) - -/* index of key in key table */ -#define WSEC_KEY_INDEX(wlc, key) ((key)->idx) - -#define WSEC_SOFTKEY(wlc, key, bsscfg) (WLC_SW_KEYS(wlc, bsscfg) || \ - WSEC_KEY_INDEX(wlc, key) >= WLC_MAX_WSEC_HW_KEYS(wlc)) - -/* get a key, non-NULL only if key allocated and not clear */ -#define WSEC_KEY(wlc, i) (((wlc)->wsec_keys[i] && (wlc)->wsec_keys[i]->len) ? \ - (wlc)->wsec_keys[i] : NULL) - -#define WSEC_SCB_KEY_VALID(scb) (((scb)->key && (scb)->key->len) ? true : false) - -/* default key */ -#define WSEC_BSS_DEFAULT_KEY(bsscfg) (((bsscfg)->wsec_index == -1) ? \ - (struct wsec_key *)NULL:(bsscfg)->bss_def_keys[(bsscfg)->wsec_index]) - -/* Macros for key management in IBSS mode */ -#define WSEC_IBSS_MAX_PEERS 16 /* Max # of IBSS Peers */ -#define WSEC_IBSS_RCMTA_INDEX(idx) \ - (((idx - WSEC_MAX_DEFAULT_KEYS) % WSEC_IBSS_MAX_PEERS) + WSEC_MAX_DEFAULT_KEYS) - -/* contiguous # key slots for infrastructure mode STA */ -#define WSEC_BSS_STA_KEY_GROUP_SIZE 5 - -typedef struct wsec_iv { - u32 hi; /* upper 32 bits of IV */ - u16 lo; /* lower 16 bits of IV */ -} wsec_iv_t; - -#define WLC_NUMRXIVS 16 /* # rx IVs (one per 802.11e TID) */ - -typedef struct wsec_key { - u8 ea[ETH_ALEN]; /* per station */ - u8 idx; /* key index in wsec_keys array */ - u8 id; /* key ID [0-3] */ - u8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ - u8 rcmta; /* rcmta entry index, same as idx by default */ - u16 flags; /* misc flags */ - u8 algo_hw; /* cache for hw register */ - u8 aes_mode; /* cache for hw register */ - s8 iv_len; /* IV length */ - s8 icv_len; /* ICV length */ - u32 len; /* key length..don't move this var */ - /* data is 4byte aligned */ - u8 data[WLAN_MAX_KEY_LEN]; /* key data */ - wsec_iv_t rxiv[WLC_NUMRXIVS]; /* Rx IV (one per TID) */ - wsec_iv_t txiv; /* Tx IV */ - -} wsec_key_t; - -#define broken_roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) - -/* For use with wsec_key_t.flags */ - -#define WSEC_BS_UPDATE (1 << 0) /* Indicates hw needs key update on BS switch */ -#define WSEC_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ -#define WSEC_TKIP_ERROR (1 << 2) /* Provoke deliberate MIC error */ -#define WSEC_REPLAY_ERROR (1 << 3) /* Provoke deliberate replay */ -#define WSEC_IBSS_PEER_GROUP_KEY (1 << 7) /* Flag: group key for a IBSS PEER */ -#define WSEC_ICV_ERROR (1 << 8) /* Provoke deliberate ICV error */ - -#define wlc_key_insert(a, b, c, d, e, f, g, h, i, j) (-EBADE) -#define wlc_key_update(a, b, c) do {} while (0) -#define wlc_key_remove(a, b, c) do {} while (0) -#define wlc_key_remove_all(a, b) do {} while (0) -#define wlc_key_delete(a, b, c) do {} while (0) -#define wlc_scb_key_delete(a, b) do {} while (0) -#define wlc_key_lookup(a, b, c, d, e) (NULL) -#define wlc_key_hw_init_all(a) do {} while (0) -#define wlc_key_hw_init(a, b, c) do {} while (0) -#define wlc_key_hw_wowl_init(a, b, c, d) do {} while (0) -#define wlc_key_sw_wowl_update(a, b, c, d, e) do {} while (0) -#define wlc_key_sw_wowl_create(a, b, c) (-EBADE) -#define wlc_key_iv_update(a, b, c, d, e) do {(void)e; } while (0) -#define wlc_key_iv_init(a, b, c) do {} while (0) -#define wlc_key_set_error(a, b, c) (-EBADE) -#define wlc_key_dump_hw(a, b) (-EBADE) -#define wlc_key_dump_sw(a, b) (-EBADE) -#define wlc_key_defkeyflag(a) (0) -#define wlc_rcmta_add_bssid(a, b) do {} while (0) -#define wlc_rcmta_del_bssid(a, b) do {} while (0) -#define wlc_key_scb_delete(a, b) do {} while (0) - -#endif /* _wlc_key_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c deleted file mode 100644 index 16fea021f4a5..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * This is "two-way" interface, acting as the SHIM layer between WL and PHY layer. - * WL driver can optinally call this translation layer to do some preprocessing, then reach PHY. - * On the PHY->WL driver direction, all calls go through this layer since PHY doesn't have the - * access to wlc_hw pointer. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wlc_types.h" -#include "wl_dbg.h" -#include "wlc_cfg.h" -#include "d11.h" -#include "wlc_rate.h" -#include "wlc_scb.h" -#include "wlc_pub.h" -#include "phy/wlc_phy_hal.h" -#include "wlc_channel.h" -#include "bcmsrom.h" -#include "wlc_key.h" -#include "wlc_bmac.h" -#include "wlc_phy_hal.h" -#include "wl_export.h" -#include "wlc_main.h" -#include "wlc_phy_shim.h" - -/* PHY SHIM module specific state */ -struct wlc_phy_shim_info { - struct wlc_hw_info *wlc_hw; /* pointer to main wlc_hw structure */ - void *wlc; /* pointer to main wlc structure */ - void *wl; /* pointer to os-specific private state */ -}; - -wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, - void *wl, void *wlc) { - wlc_phy_shim_info_t *physhim = NULL; - - physhim = kzalloc(sizeof(wlc_phy_shim_info_t), GFP_ATOMIC); - if (!physhim) { - wiphy_err(wlc_hw->wlc->wiphy, - "wl%d: wlc_phy_shim_attach: out of mem\n", - wlc_hw->unit); - return NULL; - } - physhim->wlc_hw = wlc_hw; - physhim->wlc = wlc; - physhim->wl = wl; - - return physhim; -} - -void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim) -{ - kfree(physhim); -} - -struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim, - void (*fn) (void *arg), void *arg, - const char *name) -{ - return (struct wlapi_timer *)wl_init_timer(physhim->wl, fn, arg, name); -} - -void wlapi_free_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t) -{ - wl_free_timer(physhim->wl, (struct wl_timer *)t); -} - -void -wlapi_add_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t, uint ms, - int periodic) -{ - wl_add_timer(physhim->wl, (struct wl_timer *)t, ms, periodic); -} - -bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, struct wlapi_timer *t) -{ - return wl_del_timer(physhim->wl, (struct wl_timer *)t); -} - -void wlapi_intrson(wlc_phy_shim_info_t *physhim) -{ - wl_intrson(physhim->wl); -} - -u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim) -{ - return wl_intrsoff(physhim->wl); -} - -void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, u32 macintmask) -{ - wl_intrsrestore(physhim->wl, macintmask); -} - -void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, u16 v) -{ - wlc_bmac_write_shm(physhim->wlc_hw, offset, v); -} - -u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset) -{ - return wlc_bmac_read_shm(physhim->wlc_hw, offset); -} - -void -wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx, u16 mask, - u16 val, int bands) -{ - wlc_bmac_mhf(physhim->wlc_hw, idx, mask, val, bands); -} - -void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags) -{ - wlc_bmac_corereset(physhim->wlc_hw, flags); -} - -void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim) -{ - wlc_suspend_mac_and_wait(physhim->wlc); -} - -void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode) -{ - wlc_bmac_switch_macfreq(physhim->wlc_hw, spurmode); -} - -void wlapi_enable_mac(wlc_phy_shim_info_t *physhim) -{ - wlc_enable_mac(physhim->wlc); -} - -void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask, u32 val) -{ - wlc_bmac_mctrl(physhim->wlc_hw, mask, val); -} - -void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim) -{ - wlc_bmac_phy_reset(physhim->wlc_hw); -} - -void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw) -{ - wlc_bmac_bw_set(physhim->wlc_hw, bw); -} - -u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim) -{ - return wlc_bmac_get_txant(physhim->wlc_hw); -} - -void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk) -{ - wlc_bmac_phyclk_fgc(physhim->wlc_hw, clk); -} - -void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk) -{ - wlc_bmac_macphyclk_set(physhim->wlc_hw, clk); -} - -void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on) -{ - wlc_bmac_core_phypll_ctl(physhim->wlc_hw, on); -} - -void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim) -{ - wlc_bmac_core_phypll_reset(physhim->wlc_hw); -} - -void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t *physhim) -{ - wlc_ucode_wake_override_set(physhim->wlc_hw, WLC_WAKE_OVERRIDE_PHYREG); -} - -void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t *physhim) -{ - wlc_ucode_wake_override_clear(physhim->wlc_hw, - WLC_WAKE_OVERRIDE_PHYREG); -} - -void -wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int offset, - int len, void *buf) -{ - wlc_bmac_write_template_ram(physhim->wlc_hw, offset, len, buf); -} - -u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, u8 rate) -{ - return wlc_bmac_rate_shm_offset(physhim->wlc_hw, rate); -} - -void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim) -{ -} - -void -wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint offset, void *buf, - int len, u32 sel) -{ - wlc_bmac_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel); -} - -void -wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint offset, const void *buf, - int l, u32 sel) -{ - wlc_bmac_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel); -} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h b/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h deleted file mode 100644 index c151a5d8c693..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_phy_shim_h_ -#define _wlc_phy_shim_h_ - -#define RADAR_TYPE_NONE 0 /* Radar type None */ -#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */ -#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */ -#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */ -#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */ -#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */ -#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */ -#define RADAR_TYPE_BIN5 7 /* long pulse radar type */ -#define RADAR_TYPE_STG2 8 /* staggered-2 radar */ -#define RADAR_TYPE_STG3 9 /* staggered-3 radar */ -#define RADAR_TYPE_FRA 10 /* French radar */ - -/* French radar pulse widths */ -#define FRA_T1_20MHZ 52770 -#define FRA_T2_20MHZ 61538 -#define FRA_T3_20MHZ 66002 -#define FRA_T1_40MHZ 105541 -#define FRA_T2_40MHZ 123077 -#define FRA_T3_40MHZ 132004 -#define FRA_ERR_20MHZ 60 -#define FRA_ERR_40MHZ 120 - -#define ANTSEL_NA 0 /* No boardlevel selection available */ -#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */ -#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */ - -/* Rx Antenna diversity control values */ -#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ -#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ -#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ -#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ -#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ -#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ - -/* Forward declarations */ -struct wlc_hw_info; -typedef struct wlc_phy_shim_info wlc_phy_shim_info_t; - -extern wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, - void *wl, void *wlc); -extern void wlc_phy_shim_detach(wlc_phy_shim_info_t *physhim); - -/* PHY to WL utility functions */ -struct wlapi_timer; -extern struct wlapi_timer *wlapi_init_timer(wlc_phy_shim_info_t *physhim, - void (*fn) (void *arg), void *arg, - const char *name); -extern void wlapi_free_timer(wlc_phy_shim_info_t *physhim, - struct wlapi_timer *t); -extern void wlapi_add_timer(wlc_phy_shim_info_t *physhim, - struct wlapi_timer *t, uint ms, int periodic); -extern bool wlapi_del_timer(wlc_phy_shim_info_t *physhim, - struct wlapi_timer *t); -extern void wlapi_intrson(wlc_phy_shim_info_t *physhim); -extern u32 wlapi_intrsoff(wlc_phy_shim_info_t *physhim); -extern void wlapi_intrsrestore(wlc_phy_shim_info_t *physhim, - u32 macintmask); - -extern void wlapi_bmac_write_shm(wlc_phy_shim_info_t *physhim, uint offset, - u16 v); -extern u16 wlapi_bmac_read_shm(wlc_phy_shim_info_t *physhim, uint offset); -extern void wlapi_bmac_mhf(wlc_phy_shim_info_t *physhim, u8 idx, - u16 mask, u16 val, int bands); -extern void wlapi_bmac_corereset(wlc_phy_shim_info_t *physhim, u32 flags); -extern void wlapi_suspend_mac_and_wait(wlc_phy_shim_info_t *physhim); -extern void wlapi_switch_macfreq(wlc_phy_shim_info_t *physhim, u8 spurmode); -extern void wlapi_enable_mac(wlc_phy_shim_info_t *physhim); -extern void wlapi_bmac_mctrl(wlc_phy_shim_info_t *physhim, u32 mask, - u32 val); -extern void wlapi_bmac_phy_reset(wlc_phy_shim_info_t *physhim); -extern void wlapi_bmac_bw_set(wlc_phy_shim_info_t *physhim, u16 bw); -extern void wlapi_bmac_phyclk_fgc(wlc_phy_shim_info_t *physhim, bool clk); -extern void wlapi_bmac_macphyclk_set(wlc_phy_shim_info_t *physhim, bool clk); -extern void wlapi_bmac_core_phypll_ctl(wlc_phy_shim_info_t *physhim, bool on); -extern void wlapi_bmac_core_phypll_reset(wlc_phy_shim_info_t *physhim); -extern void wlapi_bmac_ucode_wake_override_phyreg_set(wlc_phy_shim_info_t * - physhim); -extern void wlapi_bmac_ucode_wake_override_phyreg_clear(wlc_phy_shim_info_t * - physhim); -extern void wlapi_bmac_write_template_ram(wlc_phy_shim_info_t *physhim, int o, - int len, void *buf); -extern u16 wlapi_bmac_rate_shm_offset(wlc_phy_shim_info_t *physhim, - u8 rate); -extern void wlapi_ucode_sample_init(wlc_phy_shim_info_t *physhim); -extern void wlapi_copyfrom_objmem(wlc_phy_shim_info_t *physhim, uint, - void *buf, int, u32 sel); -extern void wlapi_copyto_objmem(wlc_phy_shim_info_t *physhim, uint, - const void *buf, int, u32); - -extern void wlapi_high_update_phy_mode(wlc_phy_shim_info_t *physhim, - u32 phy_mode); -extern u16 wlapi_bmac_get_txant(wlc_phy_shim_info_t *physhim); -#endif /* _wlc_phy_shim_h_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c b/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c deleted file mode 100644 index 82986bd1ccfa..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c +++ /dev/null @@ -1,1929 +0,0 @@ -/* - * Copyright (c) 2011 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include "wlc_pmu.h" - -/* - * d11 slow to fast clock transition time in slow clock cycles - */ -#define D11SCC_SLOW2FAST_TRANSITION 2 - -/* - * external LPO crystal frequency - */ -#define EXT_ILP_HZ 32768 - -/* - * Duration for ILP clock frequency measurment in milliseconds - * - * remark: 1000 must be an integer multiple of this duration - */ -#define ILP_CALC_DUR 10 - -/* - * FVCO frequency - */ -#define FVCO_880 880000 /* 880MHz */ -#define FVCO_1760 1760000 /* 1760MHz */ -#define FVCO_1440 1440000 /* 1440MHz */ -#define FVCO_960 960000 /* 960MHz */ - -/* - * PMU crystal table indices for 1440MHz fvco - */ -#define PMU1_XTALTAB0_1440_12000K 0 -#define PMU1_XTALTAB0_1440_13000K 1 -#define PMU1_XTALTAB0_1440_14400K 2 -#define PMU1_XTALTAB0_1440_15360K 3 -#define PMU1_XTALTAB0_1440_16200K 4 -#define PMU1_XTALTAB0_1440_16800K 5 -#define PMU1_XTALTAB0_1440_19200K 6 -#define PMU1_XTALTAB0_1440_19800K 7 -#define PMU1_XTALTAB0_1440_20000K 8 -#define PMU1_XTALTAB0_1440_25000K 9 -#define PMU1_XTALTAB0_1440_26000K 10 -#define PMU1_XTALTAB0_1440_30000K 11 -#define PMU1_XTALTAB0_1440_37400K 12 -#define PMU1_XTALTAB0_1440_38400K 13 -#define PMU1_XTALTAB0_1440_40000K 14 -#define PMU1_XTALTAB0_1440_48000K 15 - -/* - * PMU crystal table indices for 960MHz fvco - */ -#define PMU1_XTALTAB0_960_12000K 0 -#define PMU1_XTALTAB0_960_13000K 1 -#define PMU1_XTALTAB0_960_14400K 2 -#define PMU1_XTALTAB0_960_15360K 3 -#define PMU1_XTALTAB0_960_16200K 4 -#define PMU1_XTALTAB0_960_16800K 5 -#define PMU1_XTALTAB0_960_19200K 6 -#define PMU1_XTALTAB0_960_19800K 7 -#define PMU1_XTALTAB0_960_20000K 8 -#define PMU1_XTALTAB0_960_25000K 9 -#define PMU1_XTALTAB0_960_26000K 10 -#define PMU1_XTALTAB0_960_30000K 11 -#define PMU1_XTALTAB0_960_37400K 12 -#define PMU1_XTALTAB0_960_38400K 13 -#define PMU1_XTALTAB0_960_40000K 14 -#define PMU1_XTALTAB0_960_48000K 15 - -/* - * PMU crystal table indices for 880MHz fvco - */ -#define PMU1_XTALTAB0_880_12000K 0 -#define PMU1_XTALTAB0_880_13000K 1 -#define PMU1_XTALTAB0_880_14400K 2 -#define PMU1_XTALTAB0_880_15360K 3 -#define PMU1_XTALTAB0_880_16200K 4 -#define PMU1_XTALTAB0_880_16800K 5 -#define PMU1_XTALTAB0_880_19200K 6 -#define PMU1_XTALTAB0_880_19800K 7 -#define PMU1_XTALTAB0_880_20000K 8 -#define PMU1_XTALTAB0_880_24000K 9 -#define PMU1_XTALTAB0_880_25000K 10 -#define PMU1_XTALTAB0_880_26000K 11 -#define PMU1_XTALTAB0_880_30000K 12 -#define PMU1_XTALTAB0_880_37400K 13 -#define PMU1_XTALTAB0_880_38400K 14 -#define PMU1_XTALTAB0_880_40000K 15 - -/* - * crystal frequency values - */ -#define XTAL_FREQ_24000MHZ 24000 -#define XTAL_FREQ_30000MHZ 30000 -#define XTAL_FREQ_37400MHZ 37400 -#define XTAL_FREQ_48000MHZ 48000 - -/* - * Resource dependancies mask change action - * - * @RES_DEPEND_SET: Override the dependancies mask - * @RES_DEPEND_ADD: Add to the dependancies mask - * @RES_DEPEND_REMOVE: Remove from the dependancies mask - */ -#define RES_DEPEND_SET 0 -#define RES_DEPEND_ADD 1 -#define RES_DEPEND_REMOVE -1 - -/* d11 slow to fast clock transition time in slow clock cycles */ -#define D11SCC_SLOW2FAST_TRANSITION 2 - -/* Setup resource up/down timers */ -typedef struct { - u8 resnum; - u16 updown; -} pmu_res_updown_t; - -/* Change resource dependancies masks */ -typedef struct { - u32 res_mask; /* resources (chip specific) */ - s8 action; /* action */ - u32 depend_mask; /* changes to the dependancies mask */ - bool(*filter) (si_t *sih); /* action is taken when filter is NULL or return true */ -} pmu_res_depend_t; - -/* setup pll and query clock speed */ -typedef struct { - u16 fref; - u8 xf; - u8 p1div; - u8 p2div; - u8 ndiv_int; - u32 ndiv_frac; -} pmu1_xtaltab0_t; - -/* - * prototypes used in resource tables - */ -static bool si_pmu_res_depfltr_bb(si_t *sih); -static bool si_pmu_res_depfltr_ncb(si_t *sih); -static bool si_pmu_res_depfltr_paldo(si_t *sih); -static bool si_pmu_res_depfltr_npaldo(si_t *sih); - -static const pmu_res_updown_t bcm4328a0_res_updown[] = { - { - RES4328_EXT_SWITCHER_PWM, 0x0101}, { - RES4328_BB_SWITCHER_PWM, 0x1f01}, { - RES4328_BB_SWITCHER_BURST, 0x010f}, { - RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, { - RES4328_ILP_REQUEST, 0x0202}, { - RES4328_RADIO_SWITCHER_PWM, 0x0f01}, { - RES4328_RADIO_SWITCHER_BURST, 0x0f01}, { - RES4328_ROM_SWITCH, 0x0101}, { - RES4328_PA_REF_LDO, 0x0f01}, { - RES4328_RADIO_LDO, 0x0f01}, { - RES4328_AFE_LDO, 0x0f01}, { - RES4328_PLL_LDO, 0x0f01}, { - RES4328_BG_FILTBYP, 0x0101}, { - RES4328_TX_FILTBYP, 0x0101}, { - RES4328_RX_FILTBYP, 0x0101}, { - RES4328_XTAL_PU, 0x0101}, { - RES4328_XTAL_EN, 0xa001}, { - RES4328_BB_PLL_FILTBYP, 0x0101}, { - RES4328_RF_PLL_FILTBYP, 0x0101}, { - RES4328_BB_PLL_PU, 0x0701} -}; - -static const pmu_res_depend_t bcm4328a0_res_depend[] = { - /* Adjust ILP request resource not to force ext/BB switchers into burst mode */ - { - PMURES_BIT(RES4328_ILP_REQUEST), - RES_DEPEND_SET, - PMURES_BIT(RES4328_EXT_SWITCHER_PWM) | - PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL} -}; - -static const pmu_res_updown_t bcm4325a0_res_updown_qt[] = { - { - RES4325_HT_AVAIL, 0x0300}, { - RES4325_BBPLL_PWRSW_PU, 0x0101}, { - RES4325_RFPLL_PWRSW_PU, 0x0101}, { - RES4325_ALP_AVAIL, 0x0100}, { - RES4325_XTAL_PU, 0x1000}, { - RES4325_LNLDO1_PU, 0x0800}, { - RES4325_CLDO_CBUCK_PWM, 0x0101}, { - RES4325_CBUCK_PWM, 0x0803} -}; - -static const pmu_res_updown_t bcm4325a0_res_updown[] = { - { - RES4325_XTAL_PU, 0x1501} -}; - -static const pmu_res_depend_t bcm4325a0_res_depend[] = { - /* Adjust OTP PU resource dependencies - remove BB BURST */ - { - PMURES_BIT(RES4325_OTP_PU), - RES_DEPEND_REMOVE, - PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL}, - /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */ - { - PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL), - RES_DEPEND_ADD, - PMURES_BIT(RES4325_BUCK_BOOST_BURST) | - PMURES_BIT(RES4325_BUCK_BOOST_PWM), si_pmu_res_depfltr_bb}, - /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */ - { - PMURES_BIT(RES4325_HT_AVAIL), - RES_DEPEND_ADD, - PMURES_BIT(RES4325_RX_PWRSW_PU) | - PMURES_BIT(RES4325_TX_PWRSW_PU) | - PMURES_BIT(RES4325_LOGEN_PWRSW_PU) | - PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL}, - /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */ - { - PMURES_BIT(RES4325_ILP_REQUEST) | - PMURES_BIT(RES4325_ABUCK_BURST) | - PMURES_BIT(RES4325_ABUCK_PWM) | - PMURES_BIT(RES4325_LNLDO1_PU) | - PMURES_BIT(RES4325C1_LNLDO2_PU) | - PMURES_BIT(RES4325_XTAL_PU) | - PMURES_BIT(RES4325_ALP_AVAIL) | - PMURES_BIT(RES4325_RX_PWRSW_PU) | - PMURES_BIT(RES4325_TX_PWRSW_PU) | - PMURES_BIT(RES4325_RFPLL_PWRSW_PU) | - PMURES_BIT(RES4325_LOGEN_PWRSW_PU) | - PMURES_BIT(RES4325_AFE_PWRSW_PU) | - PMURES_BIT(RES4325_BBPLL_PWRSW_PU) | - PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE, - PMURES_BIT(RES4325B0_CBUCK_LPOM) | - PMURES_BIT(RES4325B0_CBUCK_BURST) | - PMURES_BIT(RES4325B0_CBUCK_PWM), si_pmu_res_depfltr_ncb} -}; - -static const pmu_res_updown_t bcm4315a0_res_updown_qt[] = { - { - RES4315_HT_AVAIL, 0x0101}, { - RES4315_XTAL_PU, 0x0100}, { - RES4315_LNLDO1_PU, 0x0100}, { - RES4315_PALDO_PU, 0x0100}, { - RES4315_CLDO_PU, 0x0100}, { - RES4315_CBUCK_PWM, 0x0100}, { - RES4315_CBUCK_BURST, 0x0100}, { - RES4315_CBUCK_LPOM, 0x0100} -}; - -static const pmu_res_updown_t bcm4315a0_res_updown[] = { - { - RES4315_XTAL_PU, 0x2501} -}; - -static const pmu_res_depend_t bcm4315a0_res_depend[] = { - /* Adjust OTP PU resource dependencies - not need PALDO unless write */ - { - PMURES_BIT(RES4315_OTP_PU), - RES_DEPEND_REMOVE, - PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_npaldo}, - /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */ - { - PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL), - RES_DEPEND_ADD, - PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_paldo}, - /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */ - { - PMURES_BIT(RES4315_HT_AVAIL), - RES_DEPEND_ADD, - PMURES_BIT(RES4315_RX_PWRSW_PU) | - PMURES_BIT(RES4315_TX_PWRSW_PU) | - PMURES_BIT(RES4315_LOGEN_PWRSW_PU) | - PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL}, - /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */ - { - PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) | - PMURES_BIT(RES4315_LNLDO1_PU) | - PMURES_BIT(RES4315_OTP_PU) | - PMURES_BIT(RES4315_LNLDO2_PU) | - PMURES_BIT(RES4315_XTAL_PU) | - PMURES_BIT(RES4315_ALP_AVAIL) | - PMURES_BIT(RES4315_RX_PWRSW_PU) | - PMURES_BIT(RES4315_TX_PWRSW_PU) | - PMURES_BIT(RES4315_RFPLL_PWRSW_PU) | - PMURES_BIT(RES4315_LOGEN_PWRSW_PU) | - PMURES_BIT(RES4315_AFE_PWRSW_PU) | - PMURES_BIT(RES4315_BBPLL_PWRSW_PU) | - PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE, - PMURES_BIT(RES4315_CBUCK_LPOM) | - PMURES_BIT(RES4315_CBUCK_BURST) | - PMURES_BIT(RES4315_CBUCK_PWM), si_pmu_res_depfltr_ncb} -}; - - /* 4329 specific. needs to come back this issue later */ -static const pmu_res_updown_t bcm4329_res_updown[] = { - { - RES4329_XTAL_PU, 0x1501} -}; - -static const pmu_res_depend_t bcm4329_res_depend[] = { - /* Adjust HT Avail resource dependencies */ - { - PMURES_BIT(RES4329_HT_AVAIL), - RES_DEPEND_ADD, - PMURES_BIT(RES4329_CBUCK_LPOM) | - PMURES_BIT(RES4329_CBUCK_BURST) | - PMURES_BIT(RES4329_CBUCK_PWM) | - PMURES_BIT(RES4329_CLDO_PU) | - PMURES_BIT(RES4329_PALDO_PU) | - PMURES_BIT(RES4329_LNLDO1_PU) | - PMURES_BIT(RES4329_XTAL_PU) | - PMURES_BIT(RES4329_ALP_AVAIL) | - PMURES_BIT(RES4329_RX_PWRSW_PU) | - PMURES_BIT(RES4329_TX_PWRSW_PU) | - PMURES_BIT(RES4329_RFPLL_PWRSW_PU) | - PMURES_BIT(RES4329_LOGEN_PWRSW_PU) | - PMURES_BIT(RES4329_AFE_PWRSW_PU) | - PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL} -}; - -static const pmu_res_updown_t bcm4319a0_res_updown_qt[] = { - { - RES4319_HT_AVAIL, 0x0101}, { - RES4319_XTAL_PU, 0x0100}, { - RES4319_LNLDO1_PU, 0x0100}, { - RES4319_PALDO_PU, 0x0100}, { - RES4319_CLDO_PU, 0x0100}, { - RES4319_CBUCK_PWM, 0x0100}, { - RES4319_CBUCK_BURST, 0x0100}, { - RES4319_CBUCK_LPOM, 0x0100} -}; - -static const pmu_res_updown_t bcm4319a0_res_updown[] = { - { - RES4319_XTAL_PU, 0x3f01} -}; - -static const pmu_res_depend_t bcm4319a0_res_depend[] = { - /* Adjust OTP PU resource dependencies - not need PALDO unless write */ - { - PMURES_BIT(RES4319_OTP_PU), - RES_DEPEND_REMOVE, - PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_npaldo}, - /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */ - { - PMURES_BIT(RES4319_HT_AVAIL), - RES_DEPEND_ADD, - PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_paldo}, - /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */ - { - PMURES_BIT(RES4319_HT_AVAIL), - RES_DEPEND_ADD, - PMURES_BIT(RES4319_RX_PWRSW_PU) | - PMURES_BIT(RES4319_TX_PWRSW_PU) | - PMURES_BIT(RES4319_RFPLL_PWRSW_PU) | - PMURES_BIT(RES4319_LOGEN_PWRSW_PU) | - PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL} -}; - -static const pmu_res_updown_t bcm4336a0_res_updown_qt[] = { - { - RES4336_HT_AVAIL, 0x0101}, { - RES4336_XTAL_PU, 0x0100}, { - RES4336_CLDO_PU, 0x0100}, { - RES4336_CBUCK_PWM, 0x0100}, { - RES4336_CBUCK_BURST, 0x0100}, { - RES4336_CBUCK_LPOM, 0x0100} -}; - -static const pmu_res_updown_t bcm4336a0_res_updown[] = { - { - RES4336_HT_AVAIL, 0x0D01} -}; - -static const pmu_res_depend_t bcm4336a0_res_depend[] = { - /* Just a dummy entry for now */ - { - PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL} -}; - -static const pmu_res_updown_t bcm4330a0_res_updown_qt[] = { - { - RES4330_HT_AVAIL, 0x0101}, { - RES4330_XTAL_PU, 0x0100}, { - RES4330_CLDO_PU, 0x0100}, { - RES4330_CBUCK_PWM, 0x0100}, { - RES4330_CBUCK_BURST, 0x0100}, { - RES4330_CBUCK_LPOM, 0x0100} -}; - -static const pmu_res_updown_t bcm4330a0_res_updown[] = { - { - RES4330_HT_AVAIL, 0x0e02} -}; - -static const pmu_res_depend_t bcm4330a0_res_depend[] = { - /* Just a dummy entry for now */ - { - PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL} -}; - -/* the following table is based on 1440Mhz fvco */ -static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = { - { - 12000, 1, 1, 1, 0x78, 0x0}, { - 13000, 2, 1, 1, 0x6E, 0xC4EC4E}, { - 14400, 3, 1, 1, 0x64, 0x0}, { - 15360, 4, 1, 1, 0x5D, 0xC00000}, { - 16200, 5, 1, 1, 0x58, 0xE38E38}, { - 16800, 6, 1, 1, 0x55, 0xB6DB6D}, { - 19200, 7, 1, 1, 0x4B, 0}, { - 19800, 8, 1, 1, 0x48, 0xBA2E8B}, { - 20000, 9, 1, 1, 0x48, 0x0}, { - 25000, 10, 1, 1, 0x39, 0x999999}, { - 26000, 11, 1, 1, 0x37, 0x627627}, { - 30000, 12, 1, 1, 0x30, 0x0}, { - 37400, 13, 2, 1, 0x4D, 0x15E76}, { - 38400, 13, 2, 1, 0x4B, 0x0}, { - 40000, 14, 2, 1, 0x48, 0x0}, { - 48000, 15, 2, 1, 0x3c, 0x0}, { - 0, 0, 0, 0, 0, 0} -}; - -static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = { - { - 12000, 1, 1, 1, 0x50, 0x0}, { - 13000, 2, 1, 1, 0x49, 0xD89D89}, { - 14400, 3, 1, 1, 0x42, 0xAAAAAA}, { - 15360, 4, 1, 1, 0x3E, 0x800000}, { - 16200, 5, 1, 1, 0x39, 0x425ED0}, { - 16800, 6, 1, 1, 0x39, 0x249249}, { - 19200, 7, 1, 1, 0x32, 0x0}, { - 19800, 8, 1, 1, 0x30, 0x7C1F07}, { - 20000, 9, 1, 1, 0x30, 0x0}, { - 25000, 10, 1, 1, 0x26, 0x666666}, { - 26000, 11, 1, 1, 0x24, 0xEC4EC4}, { - 30000, 12, 1, 1, 0x20, 0x0}, { - 37400, 13, 2, 1, 0x33, 0x563EF9}, { - 38400, 14, 2, 1, 0x32, 0x0}, { - 40000, 15, 2, 1, 0x30, 0x0}, { - 48000, 16, 2, 1, 0x28, 0x0}, { - 0, 0, 0, 0, 0, 0} -}; - -static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = { - { - 12000, 1, 3, 22, 0x9, 0xFFFFEF}, { - 13000, 2, 1, 6, 0xb, 0x483483}, { - 14400, 3, 1, 10, 0xa, 0x1C71C7}, { - 15360, 4, 1, 5, 0xb, 0x755555}, { - 16200, 5, 1, 10, 0x5, 0x6E9E06}, { - 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, { - 19200, 7, 1, 4, 0xb, 0x755555}, { - 19800, 8, 1, 11, 0x4, 0xA57EB}, { - 20000, 9, 1, 11, 0x4, 0x0}, { - 24000, 10, 3, 11, 0xa, 0x0}, { - 25000, 11, 5, 16, 0xb, 0x0}, { - 26000, 12, 1, 1, 0x21, 0xD89D89}, { - 30000, 13, 3, 8, 0xb, 0x0}, { - 37400, 14, 3, 1, 0x46, 0x969696}, { - 38400, 15, 1, 1, 0x16, 0xEAAAAA}, { - 40000, 16, 1, 2, 0xb, 0}, { - 0, 0, 0, 0, 0, 0} -}; - -/* the following table is based on 880Mhz fvco */ -static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = { - { - 12000, 1, 3, 22, 0x9, 0xFFFFEF}, { - 13000, 2, 1, 6, 0xb, 0x483483}, { - 14400, 3, 1, 10, 0xa, 0x1C71C7}, { - 15360, 4, 1, 5, 0xb, 0x755555}, { - 16200, 5, 1, 10, 0x5, 0x6E9E06}, { - 16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, { - 19200, 7, 1, 4, 0xb, 0x755555}, { - 19800, 8, 1, 11, 0x4, 0xA57EB}, { - 20000, 9, 1, 11, 0x4, 0x0}, { - 24000, 10, 3, 11, 0xa, 0x0}, { - 25000, 11, 5, 16, 0xb, 0x0}, { - 26000, 12, 1, 2, 0x10, 0xEC4EC4}, { - 30000, 13, 3, 8, 0xb, 0x0}, { - 33600, 14, 1, 2, 0xd, 0x186186}, { - 38400, 15, 1, 2, 0xb, 0x755555}, { - 40000, 16, 1, 2, 0xb, 0}, { - 0, 0, 0, 0, 0, 0} -}; - -/* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */ -static bool si_pmu_res_depfltr_bb(si_t *sih) -{ - return (sih->boardflags & BFL_BUCKBOOST) != 0; -} - -/* true if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */ -static bool si_pmu_res_depfltr_ncb(si_t *sih) -{ - - return (sih->boardflags & BFL_NOCBUCK) != 0; -} - -/* true if the power topology uses the PALDO */ -static bool si_pmu_res_depfltr_paldo(si_t *sih) -{ - return (sih->boardflags & BFL_PALDO) != 0; -} - -/* true if the power topology doesn't use the PALDO */ -static bool si_pmu_res_depfltr_npaldo(si_t *sih) -{ - return (sih->boardflags & BFL_PALDO) == 0; -} - -/* Return dependancies (direct or all/indirect) for the given resources */ -static u32 -si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs, - bool all) -{ - u32 deps = 0; - u32 i; - - for (i = 0; i <= PMURES_MAX_RESNUM; i++) { - if (!(rsrcs & PMURES_BIT(i))) - continue; - W_REG(&cc->res_table_sel, i); - deps |= R_REG(&cc->res_dep_mask); - } - - return !all ? deps : (deps - ? (deps | - si_pmu_res_deps(sih, cc, deps, - true)) : 0); -} - -/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */ -static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax) -{ - u32 min_mask = 0, max_mask = 0; - uint rsrcs; - char *val; - - /* # resources */ - rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT; - - /* determine min/max rsrc masks */ - switch (sih->chip) { - case BCM43224_CHIP_ID: - case BCM43225_CHIP_ID: - case BCM43421_CHIP_ID: - case BCM43235_CHIP_ID: - case BCM43236_CHIP_ID: - case BCM43238_CHIP_ID: - case BCM4331_CHIP_ID: - case BCM6362_CHIP_ID: - /* ??? */ - break; - - case BCM4329_CHIP_ID: - /* 4329 spedific issue. Needs to come back this issue later */ - /* Down to save the power. */ - min_mask = - PMURES_BIT(RES4329_CBUCK_LPOM) | - PMURES_BIT(RES4329_CLDO_PU); - /* Allow (but don't require) PLL to turn on */ - max_mask = 0x3ff63e; - break; - case BCM4319_CHIP_ID: - /* We only need a few resources to be kept on all the time */ - min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) | - PMURES_BIT(RES4319_CLDO_PU); - - /* Allow everything else to be turned on upon requests */ - max_mask = ~(~0 << rsrcs); - break; - case BCM4336_CHIP_ID: - /* Down to save the power. */ - min_mask = - PMURES_BIT(RES4336_CBUCK_LPOM) | PMURES_BIT(RES4336_CLDO_PU) - | PMURES_BIT(RES4336_LDO3P3_PU) | PMURES_BIT(RES4336_OTP_PU) - | PMURES_BIT(RES4336_DIS_INT_RESET_PD); - /* Allow (but don't require) PLL to turn on */ - max_mask = 0x1ffffff; - break; - - case BCM4330_CHIP_ID: - /* Down to save the power. */ - min_mask = - PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU) - | PMURES_BIT(RES4330_DIS_INT_RESET_PD) | - PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU); - /* Allow (but don't require) PLL to turn on */ - max_mask = 0xfffffff; - break; - - case BCM4313_CHIP_ID: - min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) | - PMURES_BIT(RES4313_XTAL_PU_RSRC) | - PMURES_BIT(RES4313_ALP_AVAIL_RSRC) | - PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC); - max_mask = 0xffff; - break; - default: - break; - } - - /* Apply nvram override to min mask */ - val = getvar(NULL, "rmin"); - if (val != NULL) { - min_mask = (u32) simple_strtoul(val, NULL, 0); - } - /* Apply nvram override to max mask */ - val = getvar(NULL, "rmax"); - if (val != NULL) { - max_mask = (u32) simple_strtoul(val, NULL, 0); - } - - *pmin = min_mask; - *pmax = max_mask; -} - -/* Return up time in ILP cycles for the given resource. */ -static uint -si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) { - u32 deps; - uint up, i, dup, dmax; - u32 min_mask = 0, max_mask = 0; - - /* uptime of resource 'rsrc' */ - W_REG(&cc->res_table_sel, rsrc); - up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff; - - /* direct dependancies of resource 'rsrc' */ - deps = si_pmu_res_deps(sih, cc, PMURES_BIT(rsrc), false); - for (i = 0; i <= PMURES_MAX_RESNUM; i++) { - if (!(deps & PMURES_BIT(i))) - continue; - deps &= ~si_pmu_res_deps(sih, cc, PMURES_BIT(i), true); - } - si_pmu_res_masks(sih, &min_mask, &max_mask); - deps &= ~min_mask; - - /* max uptime of direct dependancies */ - dmax = 0; - for (i = 0; i <= PMURES_MAX_RESNUM; i++) { - if (!(deps & PMURES_BIT(i))) - continue; - dup = si_pmu_res_uptime(sih, cc, (u8) i); - if (dmax < dup) - dmax = dup; - } - - return up + dmax + PMURES_UP_TRANSITION; -} - -static void -si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid) -{ - u32 tmp = 0; - u8 phypll_offset = 0; - u8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 }; - u8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc }; - - switch (sih->chip) { - case BCM5357_CHIP_ID: - case BCM43235_CHIP_ID: - case BCM43236_CHIP_ID: - case BCM43238_CHIP_ID: - - /* - * BCM5357 needs to touch PLL1_PLLCTL[02], - * so offset PLL0_PLLCTL[02] by 6 - */ - phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0; - - /* RMW only the P1 divider */ - W_REG(&cc->pllcontrol_addr, - PMU1_PLL0_PLLCTL0 + phypll_offset); - tmp = R_REG(&cc->pllcontrol_data); - tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK)); - tmp |= - (bcm5357_bcm43236_p1div[spuravoid] << - PMU1_PLL0_PC0_P1DIV_SHIFT); - W_REG(&cc->pllcontrol_data, tmp); - - /* RMW only the int feedback divider */ - W_REG(&cc->pllcontrol_addr, - PMU1_PLL0_PLLCTL2 + phypll_offset); - tmp = R_REG(&cc->pllcontrol_data); - tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK); - tmp |= - (bcm5357_bcm43236_ndiv[spuravoid]) << - PMU1_PLL0_PC2_NDIV_INT_SHIFT; - W_REG(&cc->pllcontrol_data, tmp); - - tmp = 1 << 10; - break; - - case BCM4331_CHIP_ID: - if (spuravoid == 2) { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11500014); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x0FC00a08); - } else if (spuravoid == 1) { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11500014); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x0F600a08); - } else { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11100014); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x03000a08); - } - tmp = 1 << 10; - break; - - case BCM43224_CHIP_ID: - case BCM43225_CHIP_ID: - case BCM43421_CHIP_ID: - case BCM6362_CHIP_ID: - if (spuravoid == 1) { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11500010); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x000C0C06); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x0F600a08); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(&cc->pllcontrol_data, 0x00000000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(&cc->pllcontrol_data, 0x2001E920); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888815); - } else { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11100010); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x000c0c06); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x03000a08); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(&cc->pllcontrol_data, 0x00000000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(&cc->pllcontrol_data, 0x200005c0); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888815); - } - tmp = 1 << 10; - break; - - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11100008); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x0c000c06); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x03000a08); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(&cc->pllcontrol_data, 0x00000000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(&cc->pllcontrol_data, 0x200005c0); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888855); - - tmp = 1 << 10; - break; - - case BCM4716_CHIP_ID: - case BCM4748_CHIP_ID: - case BCM47162_CHIP_ID: - if (spuravoid == 1) { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11500060); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x080C0C06); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x0F600000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(&cc->pllcontrol_data, 0x00000000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(&cc->pllcontrol_data, 0x2001E924); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888815); - } else { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11100060); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x080c0c06); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x03000000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - W_REG(&cc->pllcontrol_data, 0x00000000); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(&cc->pllcontrol_data, 0x200005c0); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888815); - } - - tmp = 3 << 9; - break; - - case BCM4319_CHIP_ID: - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x11100070); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x1014140a); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888854); - - if (spuravoid == 1) { - /* spur_avoid ON, so enable 41/82/164Mhz clock mode */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x05201828); - } else { - /* enable 40/80/160Mhz clock mode */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x05001828); - } - break; - case BCM4336_CHIP_ID: - /* Looks like these are only for default xtal freq 26MHz */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - W_REG(&cc->pllcontrol_data, 0x02100020); - - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - W_REG(&cc->pllcontrol_data, 0x0C0C0C0C); - - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - W_REG(&cc->pllcontrol_data, 0x01240C0C); - - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - W_REG(&cc->pllcontrol_data, 0x202C2820); - - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - W_REG(&cc->pllcontrol_data, 0x88888825); - - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - if (spuravoid == 1) - W_REG(&cc->pllcontrol_data, 0x00EC4EC4); - else - W_REG(&cc->pllcontrol_data, 0x00762762); - - tmp = PCTL_PLL_PLLCTL_UPD; - break; - - default: - /* bail out */ - return; - } - - tmp |= R_REG(&cc->pmucontrol); - W_REG(&cc->pmucontrol, tmp); -} - -/* select default xtal frequency for each chip */ -static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih) -{ - switch (sih->chip) { - case BCM4329_CHIP_ID: - /* Default to 38400Khz */ - return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K]; - case BCM4319_CHIP_ID: - /* Default to 30000Khz */ - return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K]; - case BCM4336_CHIP_ID: - /* Default to 26000Khz */ - return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K]; - case BCM4330_CHIP_ID: - /* Default to 37400Khz */ - if (CST4330_CHIPMODE_SDIOD(sih->chipst)) - return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K]; - else - return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K]; - default: - break; - } - return NULL; -} - -/* select xtal table for each chip */ -static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih) -{ - switch (sih->chip) { - case BCM4329_CHIP_ID: - return pmu1_xtaltab0_880_4329; - case BCM4319_CHIP_ID: - return pmu1_xtaltab0_1440; - case BCM4336_CHIP_ID: - return pmu1_xtaltab0_960; - case BCM4330_CHIP_ID: - if (CST4330_CHIPMODE_SDIOD(sih->chipst)) - return pmu1_xtaltab0_960; - else - return pmu1_xtaltab0_1440; - default: - break; - } - return NULL; -} - -/* query alp/xtal clock frequency */ -static u32 -si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc) -{ - const pmu1_xtaltab0_t *xt; - u32 xf; - - /* Find the frequency in the table */ - xf = (R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> - PCTL_XTALFREQ_SHIFT; - for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++) - if (xt->xf == xf) - break; - /* Could not find it so assign a default value */ - if (xt == NULL || xt->fref == 0) - xt = si_pmu1_xtaldef0(sih); - return xt->fref * 1000; -} - -/* select default pll fvco for each chip */ -static u32 si_pmu1_pllfvco0(si_t *sih) -{ - switch (sih->chip) { - case BCM4329_CHIP_ID: - return FVCO_880; - case BCM4319_CHIP_ID: - return FVCO_1440; - case BCM4336_CHIP_ID: - return FVCO_960; - case BCM4330_CHIP_ID: - if (CST4330_CHIPMODE_SDIOD(sih->chipst)) - return FVCO_960; - else - return FVCO_1440; - default: - break; - } - return 0; -} - -static void si_pmu_set_4330_plldivs(si_t *sih) -{ - u32 FVCO = si_pmu1_pllfvco0(sih) / 1000; - u32 m1div, m2div, m3div, m4div, m5div, m6div; - u32 pllc1, pllc2; - - m2div = m3div = m4div = m6div = FVCO / 80; - m5div = FVCO / 160; - - if (CST4330_CHIPMODE_SDIOD(sih->chipst)) - m1div = FVCO / 80; - else - m1div = FVCO / 90; - pllc1 = - (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div << - PMU1_PLL0_PC1_M2DIV_SHIFT) | - (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div << - PMU1_PLL0_PC1_M4DIV_SHIFT); - si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1); - - pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0); - pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK); - pllc2 |= - ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) | - (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT)); - si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2); -} - -/* Set up PLL registers in the PMU as per the crystal speed. - * XtalFreq field in pmucontrol register being 0 indicates the PLL - * is not programmed and the h/w default is assumed to work, in which - * case the xtal frequency is unknown to the s/w so we need to call - * si_pmu1_xtaldef0() wherever it is needed to return a default value. - */ -static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal) -{ - const pmu1_xtaltab0_t *xt; - u32 tmp; - u32 buf_strength = 0; - u8 ndiv_mode = 1; - - /* Use h/w default PLL config */ - if (xtal == 0) { - return; - } - - /* Find the frequency in the table */ - for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++) - if (xt->fref == xtal) - break; - - /* Check current PLL state, bail out if it has been programmed or - * we don't know how to program it. - */ - if (xt == NULL || xt->fref == 0) { - return; - } - /* for 4319 bootloader already programs the PLL but bootloader does not - * program the PLL4 and PLL5. So Skip this check for 4319 - */ - if ((((R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> - PCTL_XTALFREQ_SHIFT) == xt->xf) && - !((sih->chip == BCM4319_CHIP_ID) - || (sih->chip == BCM4330_CHIP_ID))) - return; - - switch (sih->chip) { - case BCM4329_CHIP_ID: - /* Change the BBPLL drive strength to 8 for all channels */ - buf_strength = 0x888888; - AND_REG(&cc->min_res_mask, - ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | - PMURES_BIT(RES4329_HT_AVAIL))); - AND_REG(&cc->max_res_mask, - ~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) | - PMURES_BIT(RES4329_HT_AVAIL))); - SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL, - PMU_MAX_TRANSITION_DLY); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - if (xt->fref == 38400) - tmp = 0x200024C0; - else if (xt->fref == 37400) - tmp = 0x20004500; - else if (xt->fref == 26000) - tmp = 0x200024C0; - else - tmp = 0x200005C0; /* Chip Dflt Settings */ - W_REG(&cc->pllcontrol_data, tmp); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - tmp = - R_REG(&cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK; - if ((xt->fref == 38400) || (xt->fref == 37400) - || (xt->fref == 26000)) - tmp |= 0x15; - else - tmp |= 0x25; /* Chip Dflt Settings */ - W_REG(&cc->pllcontrol_data, tmp); - break; - - case BCM4319_CHIP_ID: - /* Change the BBPLL drive strength to 2 for all channels */ - buf_strength = 0x222222; - - /* Make sure the PLL is off */ - /* WAR65104: Disable the HT_AVAIL resource first and then - * after a delay (more than downtime for HT_AVAIL) remove the - * BBPLL resource; backplane clock moves to ALP from HT. - */ - AND_REG(&cc->min_res_mask, - ~(PMURES_BIT(RES4319_HT_AVAIL))); - AND_REG(&cc->max_res_mask, - ~(PMURES_BIT(RES4319_HT_AVAIL))); - - udelay(100); - AND_REG(&cc->min_res_mask, - ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU))); - AND_REG(&cc->max_res_mask, - ~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU))); - - udelay(100); - SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL, - PMU_MAX_TRANSITION_DLY); - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4); - tmp = 0x200005c0; - W_REG(&cc->pllcontrol_data, tmp); - break; - - case BCM4336_CHIP_ID: - AND_REG(&cc->min_res_mask, - ~(PMURES_BIT(RES4336_HT_AVAIL) | - PMURES_BIT(RES4336_MACPHY_CLKAVAIL))); - AND_REG(&cc->max_res_mask, - ~(PMURES_BIT(RES4336_HT_AVAIL) | - PMURES_BIT(RES4336_MACPHY_CLKAVAIL))); - udelay(100); - SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL, - PMU_MAX_TRANSITION_DLY); - break; - - case BCM4330_CHIP_ID: - AND_REG(&cc->min_res_mask, - ~(PMURES_BIT(RES4330_HT_AVAIL) | - PMURES_BIT(RES4330_MACPHY_CLKAVAIL))); - AND_REG(&cc->max_res_mask, - ~(PMURES_BIT(RES4330_HT_AVAIL) | - PMURES_BIT(RES4330_MACPHY_CLKAVAIL))); - udelay(100); - SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL, - PMU_MAX_TRANSITION_DLY); - break; - - default: - break; - } - - /* Write p1div and p2div to pllcontrol[0] */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0); - tmp = R_REG(&cc->pllcontrol_data) & - ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK); - tmp |= - ((xt-> - p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) | - ((xt-> - p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK); - W_REG(&cc->pllcontrol_data, tmp); - - if ((sih->chip == BCM4330_CHIP_ID)) - si_pmu_set_4330_plldivs(sih); - - if ((sih->chip == BCM4329_CHIP_ID) - && (sih->chiprev == 0)) { - - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); - tmp = R_REG(&cc->pllcontrol_data); - tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK); - tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL; - W_REG(&cc->pllcontrol_data, tmp); - } - if ((sih->chip == BCM4319_CHIP_ID) || - (sih->chip == BCM4336_CHIP_ID) || - (sih->chip == BCM4330_CHIP_ID)) - ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB; - else - ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH; - - /* Write ndiv_int and ndiv_mode to pllcontrol[2] */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2); - tmp = R_REG(&cc->pllcontrol_data) & - ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK); - tmp |= - ((xt-> - ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) & - PMU1_PLL0_PC2_NDIV_INT_MASK) | ((ndiv_mode << - PMU1_PLL0_PC2_NDIV_MODE_SHIFT) & - PMU1_PLL0_PC2_NDIV_MODE_MASK); - W_REG(&cc->pllcontrol_data, tmp); - - /* Write ndiv_frac to pllcontrol[3] */ - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3); - tmp = R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK; - tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) & - PMU1_PLL0_PC3_NDIV_FRAC_MASK); - W_REG(&cc->pllcontrol_data, tmp); - - /* Write clock driving strength to pllcontrol[5] */ - if (buf_strength) { - W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5); - tmp = - R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK; - tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT); - W_REG(&cc->pllcontrol_data, tmp); - } - - /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs - * to be updated. - */ - if ((sih->chip == BCM4319_CHIP_ID) - && (xt->fref != XTAL_FREQ_30000MHZ)) { - W_REG(&cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2); - tmp = - R_REG(&cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK; - if (xt->fref == XTAL_FREQ_24000MHZ) { - tmp |= - (CCTL_4319USB_24MHZ_PLL_SEL << - CCTL_4319USB_XTAL_SEL_SHIFT); - } else if (xt->fref == XTAL_FREQ_48000MHZ) { - tmp |= - (CCTL_4319USB_48MHZ_PLL_SEL << - CCTL_4319USB_XTAL_SEL_SHIFT); - } - W_REG(&cc->chipcontrol_data, tmp); - } - - /* Flush deferred pll control registers writes */ - if (sih->pmurev >= 2) - OR_REG(&cc->pmucontrol, PCTL_PLL_PLLCTL_UPD); - - /* Write XtalFreq. Set the divisor also. */ - tmp = R_REG(&cc->pmucontrol) & - ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK); - tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) & - PCTL_ILP_DIV_MASK) | - ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK); - - if ((sih->chip == BCM4329_CHIP_ID) - && sih->chiprev == 0) { - /* clear the htstretch before clearing HTReqEn */ - AND_REG(&cc->clkstretch, ~CSTRETCH_HT); - tmp &= ~PCTL_HT_REQ_EN; - } - - W_REG(&cc->pmucontrol, tmp); -} - -u32 si_pmu_ilp_clock(si_t *sih) -{ - static u32 ilpcycles_per_sec; - - if (ISSIM_ENAB(sih) || !PMUCTL_ENAB(sih)) - return ILP_CLOCK; - - if (ilpcycles_per_sec == 0) { - u32 start, end, delta; - u32 origidx = ai_coreidx(sih); - chipcregs_t *cc = ai_setcoreidx(sih, SI_CC_IDX); - start = R_REG(&cc->pmutimer); - mdelay(ILP_CALC_DUR); - end = R_REG(&cc->pmutimer); - delta = end - start; - ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR); - ai_setcoreidx(sih, origidx); - } - - return ilpcycles_per_sec; -} - -void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage) -{ - u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0; - u8 addr = 0; - - switch (sih->chip) { - case BCM4336_CHIP_ID: - switch (ldo) { - case SET_LDO_VOLTAGE_CLDO_PWM: - addr = 4; - rc_shift = 1; - mask = 0xf; - break; - case SET_LDO_VOLTAGE_CLDO_BURST: - addr = 4; - rc_shift = 5; - mask = 0xf; - break; - case SET_LDO_VOLTAGE_LNLDO1: - addr = 4; - rc_shift = 17; - mask = 0xf; - break; - default: - return; - } - break; - case BCM4330_CHIP_ID: - switch (ldo) { - case SET_LDO_VOLTAGE_CBUCK_PWM: - addr = 3; - rc_shift = 0; - mask = 0x1f; - break; - default: - return; - } - break; - default: - return; - } - - shift = sr_cntl_shift + rc_shift; - - ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), - ~0, addr); - ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_data), - mask << shift, (voltage & mask) << shift); -} - -u16 si_pmu_fast_pwrup_delay(si_t *sih) -{ - uint delay = PMU_MAX_TRANSITION_DLY; - chipcregs_t *cc; - uint origidx; -#ifdef BCMDBG - char chn[8]; - chn[0] = 0; /* to suppress compile error */ -#endif - - /* Remember original core before switch to chipc */ - origidx = ai_coreidx(sih); - cc = ai_setcoreidx(sih, SI_CC_IDX); - - switch (sih->chip) { - case BCM43224_CHIP_ID: - case BCM43225_CHIP_ID: - case BCM43421_CHIP_ID: - case BCM43235_CHIP_ID: - case BCM43236_CHIP_ID: - case BCM43238_CHIP_ID: - case BCM4331_CHIP_ID: - case BCM6362_CHIP_ID: - case BCM4313_CHIP_ID: - delay = ISSIM_ENAB(sih) ? 70 : 3700; - break; - case BCM4329_CHIP_ID: - if (ISSIM_ENAB(sih)) - delay = 70; - else { - u32 ilp = si_pmu_ilp_clock(sih); - delay = - (si_pmu_res_uptime(sih, cc, RES4329_HT_AVAIL) + - D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - - 1) / ilp); - delay = (11 * delay) / 10; - } - break; - case BCM4319_CHIP_ID: - delay = ISSIM_ENAB(sih) ? 70 : 3700; - break; - case BCM4336_CHIP_ID: - if (ISSIM_ENAB(sih)) - delay = 70; - else { - u32 ilp = si_pmu_ilp_clock(sih); - delay = - (si_pmu_res_uptime(sih, cc, RES4336_HT_AVAIL) + - D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - - 1) / ilp); - delay = (11 * delay) / 10; - } - break; - case BCM4330_CHIP_ID: - if (ISSIM_ENAB(sih)) - delay = 70; - else { - u32 ilp = si_pmu_ilp_clock(sih); - delay = - (si_pmu_res_uptime(sih, cc, RES4330_HT_AVAIL) + - D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp - - 1) / ilp); - delay = (11 * delay) / 10; - } - break; - default: - break; - } - /* Return to original core */ - ai_setcoreidx(sih, origidx); - - return (u16) delay; -} - -void si_pmu_sprom_enable(si_t *sih, bool enable) -{ - chipcregs_t *cc; - uint origidx; - - /* Remember original core before switch to chipc */ - origidx = ai_coreidx(sih); - cc = ai_setcoreidx(sih, SI_CC_IDX); - - /* Return to original core */ - ai_setcoreidx(sih, origidx); -} - -/* Read/write a chipcontrol reg */ -u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val) -{ - ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0, - reg); - return ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), mask, val); -} - -/* Read/write a regcontrol reg */ -u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val) -{ - ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0, - reg); - return ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, regcontrol_data), mask, val); -} - -/* Read/write a pllcontrol reg */ -u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val) -{ - ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0, - reg); - return ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, pllcontrol_data), mask, val); -} - -/* PMU PLL update */ -void si_pmu_pllupd(si_t *sih) -{ - ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol), - PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD); -} - -/* query alp/xtal clock frequency */ -u32 si_pmu_alp_clock(si_t *sih) -{ - chipcregs_t *cc; - uint origidx; - u32 clock = ALP_CLOCK; - - /* bail out with default */ - if (!PMUCTL_ENAB(sih)) - return clock; - - /* Remember original core before switch to chipc */ - origidx = ai_coreidx(sih); - cc = ai_setcoreidx(sih, SI_CC_IDX); - - switch (sih->chip) { - case BCM43224_CHIP_ID: - case BCM43225_CHIP_ID: - case BCM43421_CHIP_ID: - case BCM43235_CHIP_ID: - case BCM43236_CHIP_ID: - case BCM43238_CHIP_ID: - case BCM4331_CHIP_ID: - case BCM6362_CHIP_ID: - case BCM4716_CHIP_ID: - case BCM4748_CHIP_ID: - case BCM47162_CHIP_ID: - case BCM4313_CHIP_ID: - case BCM5357_CHIP_ID: - /* always 20Mhz */ - clock = 20000 * 1000; - break; - case BCM4329_CHIP_ID: - case BCM4319_CHIP_ID: - case BCM4336_CHIP_ID: - case BCM4330_CHIP_ID: - - clock = si_pmu1_alpclk0(sih, cc); - break; - case BCM5356_CHIP_ID: - /* always 25Mhz */ - clock = 25000 * 1000; - break; - default: - break; - } - - /* Return to original core */ - ai_setcoreidx(sih, origidx); - return clock; -} - -void si_pmu_spuravoid(si_t *sih, u8 spuravoid) -{ - chipcregs_t *cc; - uint origidx, intr_val; - u32 tmp = 0; - - /* Remember original core before switch to chipc */ - cc = (chipcregs_t *) ai_switch_core(sih, CC_CORE_ID, &origidx, - &intr_val); - - /* force the HT off */ - if (sih->chip == BCM4336_CHIP_ID) { - tmp = R_REG(&cc->max_res_mask); - tmp &= ~RES4336_HT_AVAIL; - W_REG(&cc->max_res_mask, tmp); - /* wait for the ht to really go away */ - SPINWAIT(((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0), - 10000); - } - - /* update the pll changes */ - si_pmu_spuravoid_pllupdate(sih, cc, spuravoid); - - /* enable HT back on */ - if (sih->chip == BCM4336_CHIP_ID) { - tmp = R_REG(&cc->max_res_mask); - tmp |= RES4336_HT_AVAIL; - W_REG(&cc->max_res_mask, tmp); - } - - /* Return to original core */ - ai_restore_core(sih, origidx, intr_val); -} - -/* initialize PMU */ -void si_pmu_init(si_t *sih) -{ - chipcregs_t *cc; - uint origidx; - - /* Remember original core before switch to chipc */ - origidx = ai_coreidx(sih); - cc = ai_setcoreidx(sih, SI_CC_IDX); - - if (sih->pmurev == 1) - AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT); - else if (sih->pmurev >= 2) - OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT); - - if ((sih->chip == BCM4329_CHIP_ID) && (sih->chiprev == 2)) { - /* Fix for 4329b0 bad LPOM state. */ - W_REG(&cc->regcontrol_addr, 2); - OR_REG(&cc->regcontrol_data, 0x100); - - W_REG(&cc->regcontrol_addr, 3); - OR_REG(&cc->regcontrol_data, 0x4); - } - - /* Return to original core */ - ai_setcoreidx(sih, origidx); -} - -/* initialize PMU chip controls and other chip level stuff */ -void si_pmu_chip_init(si_t *sih) -{ - uint origidx; - - /* Gate off SPROM clock and chip select signals */ - si_pmu_sprom_enable(sih, false); - - /* Remember original core */ - origidx = ai_coreidx(sih); - - /* Return to original core */ - ai_setcoreidx(sih, origidx); -} - -/* initialize PMU switch/regulators */ -void si_pmu_swreg_init(si_t *sih) -{ - switch (sih->chip) { - case BCM4336_CHIP_ID: - /* Reduce CLDO PWM output voltage to 1.2V */ - si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_PWM, 0xe); - /* Reduce CLDO BURST output voltage to 1.2V */ - si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_BURST, - 0xe); - /* Reduce LNLDO1 output voltage to 1.2V */ - si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_LNLDO1, 0xe); - if (sih->chiprev == 0) - si_pmu_regcontrol(sih, 2, 0x400000, 0x400000); - break; - - case BCM4330_CHIP_ID: - /* CBUCK Voltage is 1.8 by default and set that to 1.5 */ - si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CBUCK_PWM, 0); - break; - default: - break; - } -} - -/* initialize PLL */ -void si_pmu_pll_init(si_t *sih, uint xtalfreq) -{ - chipcregs_t *cc; - uint origidx; - - /* Remember original core before switch to chipc */ - origidx = ai_coreidx(sih); - cc = ai_setcoreidx(sih, SI_CC_IDX); - - switch (sih->chip) { - case BCM4329_CHIP_ID: - if (xtalfreq == 0) - xtalfreq = 38400; - si_pmu1_pllinit0(sih, cc, xtalfreq); - break; - case BCM4313_CHIP_ID: - case BCM43224_CHIP_ID: - case BCM43225_CHIP_ID: - case BCM43421_CHIP_ID: - case BCM43235_CHIP_ID: - case BCM43236_CHIP_ID: - case BCM43238_CHIP_ID: - case BCM4331_CHIP_ID: - case BCM6362_CHIP_ID: - /* ??? */ - break; - case BCM4319_CHIP_ID: - case BCM4336_CHIP_ID: - case BCM4330_CHIP_ID: - si_pmu1_pllinit0(sih, cc, xtalfreq); - break; - default: - break; - } - - /* Return to original core */ - ai_setcoreidx(sih, origidx); -} - -/* initialize PMU resources */ -void si_pmu_res_init(si_t *sih) -{ - chipcregs_t *cc; - uint origidx; - const pmu_res_updown_t *pmu_res_updown_table = NULL; - uint pmu_res_updown_table_sz = 0; - const pmu_res_depend_t *pmu_res_depend_table = NULL; - uint pmu_res_depend_table_sz = 0; - u32 min_mask = 0, max_mask = 0; - char name[8], *val; - uint i, rsrcs; - - /* Remember original core before switch to chipc */ - origidx = ai_coreidx(sih); - cc = ai_setcoreidx(sih, SI_CC_IDX); - - switch (sih->chip) { - case BCM4329_CHIP_ID: - /* Optimize resources up/down timers */ - if (ISSIM_ENAB(sih)) { - pmu_res_updown_table = NULL; - pmu_res_updown_table_sz = 0; - } else { - pmu_res_updown_table = bcm4329_res_updown; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4329_res_updown); - } - /* Optimize resources dependencies */ - pmu_res_depend_table = bcm4329_res_depend; - pmu_res_depend_table_sz = ARRAY_SIZE(bcm4329_res_depend); - break; - - case BCM4319_CHIP_ID: - /* Optimize resources up/down timers */ - if (ISSIM_ENAB(sih)) { - pmu_res_updown_table = bcm4319a0_res_updown_qt; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4319a0_res_updown_qt); - } else { - pmu_res_updown_table = bcm4319a0_res_updown; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4319a0_res_updown); - } - /* Optimize resources dependancies masks */ - pmu_res_depend_table = bcm4319a0_res_depend; - pmu_res_depend_table_sz = ARRAY_SIZE(bcm4319a0_res_depend); - break; - - case BCM4336_CHIP_ID: - /* Optimize resources up/down timers */ - if (ISSIM_ENAB(sih)) { - pmu_res_updown_table = bcm4336a0_res_updown_qt; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4336a0_res_updown_qt); - } else { - pmu_res_updown_table = bcm4336a0_res_updown; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4336a0_res_updown); - } - /* Optimize resources dependancies masks */ - pmu_res_depend_table = bcm4336a0_res_depend; - pmu_res_depend_table_sz = ARRAY_SIZE(bcm4336a0_res_depend); - break; - - case BCM4330_CHIP_ID: - /* Optimize resources up/down timers */ - if (ISSIM_ENAB(sih)) { - pmu_res_updown_table = bcm4330a0_res_updown_qt; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4330a0_res_updown_qt); - } else { - pmu_res_updown_table = bcm4330a0_res_updown; - pmu_res_updown_table_sz = - ARRAY_SIZE(bcm4330a0_res_updown); - } - /* Optimize resources dependancies masks */ - pmu_res_depend_table = bcm4330a0_res_depend; - pmu_res_depend_table_sz = ARRAY_SIZE(bcm4330a0_res_depend); - break; - - default: - break; - } - - /* # resources */ - rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT; - - /* Program up/down timers */ - while (pmu_res_updown_table_sz--) { - W_REG(&cc->res_table_sel, - pmu_res_updown_table[pmu_res_updown_table_sz].resnum); - W_REG(&cc->res_updn_timer, - pmu_res_updown_table[pmu_res_updown_table_sz].updown); - } - /* Apply nvram overrides to up/down timers */ - for (i = 0; i < rsrcs; i++) { - snprintf(name, sizeof(name), "r%dt", i); - val = getvar(NULL, name); - if (val == NULL) - continue; - W_REG(&cc->res_table_sel, (u32) i); - W_REG(&cc->res_updn_timer, - (u32) simple_strtoul(val, NULL, 0)); - } - - /* Program resource dependencies table */ - while (pmu_res_depend_table_sz--) { - if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL - && !(pmu_res_depend_table[pmu_res_depend_table_sz]. - filter) (sih)) - continue; - for (i = 0; i < rsrcs; i++) { - if ((pmu_res_depend_table[pmu_res_depend_table_sz]. - res_mask & PMURES_BIT(i)) == 0) - continue; - W_REG(&cc->res_table_sel, i); - switch (pmu_res_depend_table[pmu_res_depend_table_sz]. - action) { - case RES_DEPEND_SET: - W_REG(&cc->res_dep_mask, - pmu_res_depend_table - [pmu_res_depend_table_sz].depend_mask); - break; - case RES_DEPEND_ADD: - OR_REG(&cc->res_dep_mask, - pmu_res_depend_table - [pmu_res_depend_table_sz].depend_mask); - break; - case RES_DEPEND_REMOVE: - AND_REG(&cc->res_dep_mask, - ~pmu_res_depend_table - [pmu_res_depend_table_sz].depend_mask); - break; - default: - break; - } - } - } - /* Apply nvram overrides to dependancies masks */ - for (i = 0; i < rsrcs; i++) { - snprintf(name, sizeof(name), "r%dd", i); - val = getvar(NULL, name); - if (val == NULL) - continue; - W_REG(&cc->res_table_sel, (u32) i); - W_REG(&cc->res_dep_mask, - (u32) simple_strtoul(val, NULL, 0)); - } - - /* Determine min/max rsrc masks */ - si_pmu_res_masks(sih, &min_mask, &max_mask); - - /* It is required to program max_mask first and then min_mask */ - - /* Program max resource mask */ - - if (max_mask) - W_REG(&cc->max_res_mask, max_mask); - - /* Program min resource mask */ - - if (min_mask) - W_REG(&cc->min_res_mask, min_mask); - - /* Add some delay; allow resources to come up and settle. */ - mdelay(2); - - /* Return to original core */ - ai_setcoreidx(sih, origidx); -} - -u32 si_pmu_measure_alpclk(si_t *sih) -{ - chipcregs_t *cc; - uint origidx; - u32 alp_khz; - - if (sih->pmurev < 10) - return 0; - - /* Remember original core before switch to chipc */ - origidx = ai_coreidx(sih); - cc = ai_setcoreidx(sih, SI_CC_IDX); - - if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) { - u32 ilp_ctr, alp_hz; - - /* - * Enable the reg to measure the freq, - * in case it was disabled before - */ - W_REG(&cc->pmu_xtalfreq, - 1U << PMU_XTALFREQ_REG_MEASURE_SHIFT); - - /* Delay for well over 4 ILP clocks */ - udelay(1000); - - /* Read the latched number of ALP ticks per 4 ILP ticks */ - ilp_ctr = - R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK; - - /* - * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT - * bit to save power - */ - W_REG(&cc->pmu_xtalfreq, 0); - - /* Calculate ALP frequency */ - alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4; - - /* - * Round to nearest 100KHz, and at - * the same time convert to KHz - */ - alp_khz = (alp_hz + 50000) / 100000 * 100; - } else - alp_khz = 0; - - /* Return to original core */ - ai_setcoreidx(sih, origidx); - - return alp_khz; -} - -bool si_pmu_is_otp_powered(si_t *sih) -{ - uint idx; - chipcregs_t *cc; - bool st; - - /* Remember original core before switch to chipc */ - idx = ai_coreidx(sih); - cc = ai_setcoreidx(sih, SI_CC_IDX); - - switch (sih->chip) { - case BCM4329_CHIP_ID: - st = (R_REG(&cc->res_state) & PMURES_BIT(RES4329_OTP_PU)) - != 0; - break; - case BCM4319_CHIP_ID: - st = (R_REG(&cc->res_state) & PMURES_BIT(RES4319_OTP_PU)) - != 0; - break; - case BCM4336_CHIP_ID: - st = (R_REG(&cc->res_state) & PMURES_BIT(RES4336_OTP_PU)) - != 0; - break; - case BCM4330_CHIP_ID: - st = (R_REG(&cc->res_state) & PMURES_BIT(RES4330_OTP_PU)) - != 0; - break; - - /* These chip doesn't use PMU bit to power up/down OTP. OTP always on. - * Use OTP_INIT command to reset/refresh state. - */ - case BCM43224_CHIP_ID: - case BCM43225_CHIP_ID: - case BCM43421_CHIP_ID: - case BCM43236_CHIP_ID: - case BCM43235_CHIP_ID: - case BCM43238_CHIP_ID: - st = true; - break; - default: - st = true; - break; - } - - /* Return to original core */ - ai_setcoreidx(sih, idx); - return st; -} - -/* power up/down OTP through PMU resources */ -void si_pmu_otp_power(si_t *sih, bool on) -{ - chipcregs_t *cc; - uint origidx; - u32 rsrcs = 0; /* rsrcs to turn on/off OTP power */ - - /* Don't do anything if OTP is disabled */ - if (ai_is_otp_disabled(sih)) - return; - - /* Remember original core before switch to chipc */ - origidx = ai_coreidx(sih); - cc = ai_setcoreidx(sih, SI_CC_IDX); - - switch (sih->chip) { - case BCM4329_CHIP_ID: - rsrcs = PMURES_BIT(RES4329_OTP_PU); - break; - case BCM4319_CHIP_ID: - rsrcs = PMURES_BIT(RES4319_OTP_PU); - break; - case BCM4336_CHIP_ID: - rsrcs = PMURES_BIT(RES4336_OTP_PU); - break; - case BCM4330_CHIP_ID: - rsrcs = PMURES_BIT(RES4330_OTP_PU); - break; - default: - break; - } - - if (rsrcs != 0) { - u32 otps; - - /* Figure out the dependancies (exclude min_res_mask) */ - u32 deps = si_pmu_res_deps(sih, cc, rsrcs, true); - u32 min_mask = 0, max_mask = 0; - si_pmu_res_masks(sih, &min_mask, &max_mask); - deps &= ~min_mask; - /* Turn on/off the power */ - if (on) { - OR_REG(&cc->min_res_mask, (rsrcs | deps)); - SPINWAIT(!(R_REG(&cc->res_state) & rsrcs), - PMU_MAX_TRANSITION_DLY); - } else { - AND_REG(&cc->min_res_mask, ~(rsrcs | deps)); - } - - SPINWAIT((((otps = R_REG(&cc->otpstatus)) & OTPS_READY) != - (on ? OTPS_READY : 0)), 100); - } - - /* Return to original core */ - ai_setcoreidx(sih, origidx); -} diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h b/drivers/staging/brcm80211/brcmsmac/wlc_stf.h deleted file mode 100644 index 2b1180b128a8..000000000000 --- a/drivers/staging/brcm80211/brcmsmac/wlc_stf.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_stf_h_ -#define _wlc_stf_h_ - -extern int wlc_stf_attach(struct wlc_info *wlc); -extern void wlc_stf_detach(struct wlc_info *wlc); - -extern void wlc_tempsense_upd(struct wlc_info *wlc); -extern void wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, - u16 *ss_algo_channel, - chanspec_t chanspec); -extern int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band); -extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); -extern int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force); -extern bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val); - -extern int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val); -extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); -extern void wlc_stf_phy_chain_calc(struct wlc_info *wlc); -extern u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); -extern u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec); - -#endif /* _wlc_stf_h_ */ diff --git a/drivers/staging/brcm80211/util/Makefile b/drivers/staging/brcm80211/brcmutil/Makefile similarity index 94% rename from drivers/staging/brcm80211/util/Makefile rename to drivers/staging/brcm80211/brcmutil/Makefile index f9b36cafdc87..6403423c0212 100644 --- a/drivers/staging/brcm80211/util/Makefile +++ b/drivers/staging/brcm80211/brcmutil/Makefile @@ -16,12 +16,12 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ccflags-y := \ - -Idrivers/staging/brcm80211/util \ + -Idrivers/staging/brcm80211/brcmutil \ -Idrivers/staging/brcm80211/include BRCMUTIL_OFILES := \ - bcmutils.o \ - bcmwifi.o + utils.o \ + wifi.o MODULEPFX := brcmutil diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/brcmutil/utils.c similarity index 82% rename from drivers/staging/brcm80211/util/bcmutils.c rename to drivers/staging/brcm80211/brcmutil/utils.c index 43e5bb3aec02..37b6b7797793 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/brcmutil/utils.c @@ -14,27 +14,15 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities."); MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); MODULE_LICENSE("Dual BSD/GPL"); -struct sk_buff *bcm_pkt_buf_get_skb(uint len) +struct sk_buff *brcmu_pkt_buf_get_skb(uint len) { struct sk_buff *skb; @@ -46,10 +34,10 @@ struct sk_buff *bcm_pkt_buf_get_skb(uint len) return skb; } -EXPORT_SYMBOL(bcm_pkt_buf_get_skb); +EXPORT_SYMBOL(brcmu_pkt_buf_get_skb); /* Free the driver packet. Free the tag if present */ -void bcm_pkt_buf_free_skb(struct sk_buff *skb) +void brcmu_pkt_buf_free_skb(struct sk_buff *skb) { struct sk_buff *nskb; int nest = 0; @@ -74,11 +62,11 @@ void bcm_pkt_buf_free_skb(struct sk_buff *skb) skb = nskb; } } -EXPORT_SYMBOL(bcm_pkt_buf_free_skb); +EXPORT_SYMBOL(brcmu_pkt_buf_free_skb); /* copy a buffer into a pkt buffer chain */ -uint bcm_pktfrombuf(struct sk_buff *p, uint offset, int len, +uint brcmu_pktfrombuf(struct sk_buff *p, uint offset, int len, unsigned char *buf) { uint n, ret = 0; @@ -105,10 +93,10 @@ uint bcm_pktfrombuf(struct sk_buff *p, uint offset, int len, return ret; } -EXPORT_SYMBOL(bcm_pktfrombuf); +EXPORT_SYMBOL(brcmu_pktfrombuf); /* return total length of buffer chain */ -uint bcm_pkttotlen(struct sk_buff *p) +uint brcmu_pkttotlen(struct sk_buff *p) { uint total; @@ -117,13 +105,13 @@ uint bcm_pkttotlen(struct sk_buff *p) total += p->len; return total; } -EXPORT_SYMBOL(bcm_pkttotlen); +EXPORT_SYMBOL(brcmu_pkttotlen); /* * osl multiple-precedence packet queue * hi_prec is always >= the number of the highest non-empty precedence */ -struct sk_buff *bcm_pktq_penq(struct pktq *pq, int prec, +struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, struct sk_buff *p) { struct pktq_prec *q; @@ -148,9 +136,9 @@ struct sk_buff *bcm_pktq_penq(struct pktq *pq, int prec, return p; } -EXPORT_SYMBOL(bcm_pktq_penq); +EXPORT_SYMBOL(brcmu_pktq_penq); -struct sk_buff *bcm_pktq_penq_head(struct pktq *pq, int prec, +struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, struct sk_buff *p) { struct pktq_prec *q; @@ -174,9 +162,9 @@ struct sk_buff *bcm_pktq_penq_head(struct pktq *pq, int prec, return p; } -EXPORT_SYMBOL(bcm_pktq_penq_head); +EXPORT_SYMBOL(brcmu_pktq_penq_head); -struct sk_buff *bcm_pktq_pdeq(struct pktq *pq, int prec) +struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec) { struct pktq_prec *q; struct sk_buff *p; @@ -199,9 +187,9 @@ struct sk_buff *bcm_pktq_pdeq(struct pktq *pq, int prec) return p; } -EXPORT_SYMBOL(bcm_pktq_pdeq); +EXPORT_SYMBOL(brcmu_pktq_pdeq); -struct sk_buff *bcm_pktq_pdeq_tail(struct pktq *pq, int prec) +struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec) { struct pktq_prec *q; struct sk_buff *p, *prev; @@ -227,10 +215,10 @@ struct sk_buff *bcm_pktq_pdeq_tail(struct pktq *pq, int prec) return p; } -EXPORT_SYMBOL(bcm_pktq_pdeq_tail); +EXPORT_SYMBOL(brcmu_pktq_pdeq_tail); void -bcm_pktq_pflush(struct pktq *pq, int prec, bool dir, +brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, void *arg) { struct pktq_prec *q; @@ -246,7 +234,7 @@ bcm_pktq_pflush(struct pktq *pq, int prec, bool dir, else prev->prev = p->prev; p->prev = NULL; - bcm_pkt_buf_free_skb(p); + brcmu_pkt_buf_free_skb(p); q->len--; pq->len--; p = (head ? q->head : prev->prev); @@ -260,18 +248,18 @@ bcm_pktq_pflush(struct pktq *pq, int prec, bool dir, q->tail = NULL; } } -EXPORT_SYMBOL(bcm_pktq_pflush); +EXPORT_SYMBOL(brcmu_pktq_pflush); -void bcm_pktq_flush(struct pktq *pq, bool dir, +void brcmu_pktq_flush(struct pktq *pq, bool dir, ifpkt_cb_t fn, void *arg) { int prec; for (prec = 0; prec < pq->num_prec; prec++) - bcm_pktq_pflush(pq, prec, dir, fn, arg); + brcmu_pktq_pflush(pq, prec, dir, fn, arg); } -EXPORT_SYMBOL(bcm_pktq_flush); +EXPORT_SYMBOL(brcmu_pktq_flush); -void bcm_pktq_init(struct pktq *pq, int num_prec, int max_len) +void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len) { int prec; @@ -286,9 +274,9 @@ void bcm_pktq_init(struct pktq *pq, int num_prec, int max_len) for (prec = 0; prec < num_prec; prec++) pq->q[prec].max = pq->max; } -EXPORT_SYMBOL(bcm_pktq_init); +EXPORT_SYMBOL(brcmu_pktq_init); -struct sk_buff *bcm_pktq_peek_tail(struct pktq *pq, int *prec_out) +struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out) { int prec; @@ -304,10 +292,10 @@ struct sk_buff *bcm_pktq_peek_tail(struct pktq *pq, int *prec_out) return pq->q[prec].tail; } -EXPORT_SYMBOL(bcm_pktq_peek_tail); +EXPORT_SYMBOL(brcmu_pktq_peek_tail); /* Return sum of lengths of a specific set of precedences */ -int bcm_pktq_mlen(struct pktq *pq, uint prec_bmp) +int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp) { int prec, len; @@ -319,10 +307,10 @@ int bcm_pktq_mlen(struct pktq *pq, uint prec_bmp) return len; } -EXPORT_SYMBOL(bcm_pktq_mlen); +EXPORT_SYMBOL(brcmu_pktq_mlen); /* Priority dequeue from a specific set of precedences */ -struct sk_buff *bcm_pktq_mdeq(struct pktq *pq, uint prec_bmp, +struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) { struct pktq_prec *q; @@ -360,10 +348,10 @@ struct sk_buff *bcm_pktq_mdeq(struct pktq *pq, uint prec_bmp, return p; } -EXPORT_SYMBOL(bcm_pktq_mdeq); +EXPORT_SYMBOL(brcmu_pktq_mdeq); /* parse a xx:xx:xx:xx:xx:xx format ethernet address */ -int bcm_ether_atoe(char *p, u8 *ea) +int brcmu_ether_atoe(char *p, u8 *ea) { int i = 0; @@ -375,11 +363,11 @@ int bcm_ether_atoe(char *p, u8 *ea) return i == 6; } -EXPORT_SYMBOL(bcm_ether_atoe); +EXPORT_SYMBOL(brcmu_ether_atoe); #if defined(BCMDBG) /* pretty hex print a pkt buffer chain */ -void bcm_prpkt(const char *msg, struct sk_buff *p0) +void brcmu_prpkt(const char *msg, struct sk_buff *p0) { struct sk_buff *p; @@ -389,13 +377,14 @@ void bcm_prpkt(const char *msg, struct sk_buff *p0) for (p = p0; p; p = p->next) print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len); } -EXPORT_SYMBOL(bcm_prpkt); +EXPORT_SYMBOL(brcmu_prpkt); #endif /* defined(BCMDBG) */ /* iovar table lookup */ -const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name) +const struct brcmu_iovar *brcmu_iovar_lookup(const struct brcmu_iovar *table, + const char *name) { - const bcm_iovar_t *vi; + const struct brcmu_iovar *vi; const char *lookup_name; /* skip any ':' delimited option prefixes */ @@ -413,9 +402,10 @@ const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name) return NULL; /* var name not found */ } -EXPORT_SYMBOL(bcm_iovar_lookup); +EXPORT_SYMBOL(brcmu_iovar_lookup); -int bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) +int brcmu_iovar_lencheck(const struct brcmu_iovar *vi, void *arg, int len, + bool set) { int bcmerror = 0; @@ -458,7 +448,7 @@ int bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) return bcmerror; } -EXPORT_SYMBOL(bcm_iovar_lencheck); +EXPORT_SYMBOL(brcmu_iovar_lencheck); /******************************************************************************* * crc8 @@ -517,29 +507,29 @@ static const u8 crc8_table[256] = { 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F }; -u8 bcm_crc8(u8 *pdata, /* pointer to array of data to process */ +u8 brcmu_crc8(u8 *pdata, /* pointer to array of data to process */ uint nbytes, /* number of input data bytes to process */ u8 crc /* either CRC8_INIT_VALUE or previous return value */ - ) { + ) { /* loop over the buffer data */ while (nbytes-- > 0) crc = crc8_table[(crc ^ *pdata++) & 0xff]; return crc; } -EXPORT_SYMBOL(bcm_crc8); +EXPORT_SYMBOL(brcmu_crc8); /* * Traverse a string of 1-byte tag/1-byte length/variable-length value * triples, returning a pointer to the substring whose first element * matches tag */ -bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key) +struct brcmu_tlv *brcmu_parse_tlvs(void *buf, int buflen, uint key) { - bcm_tlv_t *elt; + struct brcmu_tlv *elt; int totlen; - elt = (bcm_tlv_t *) buf; + elt = (struct brcmu_tlv *) buf; totlen = buflen; /* find tagged parameter */ @@ -550,18 +540,19 @@ bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key) if ((elt->id == key) && (totlen >= (len + 2))) return elt; - elt = (bcm_tlv_t *) ((u8 *) elt + (len + 2)); + elt = (struct brcmu_tlv *) ((u8 *) elt + (len + 2)); totlen -= (len + 2); } return NULL; } -EXPORT_SYMBOL(bcm_parse_tlvs); +EXPORT_SYMBOL(brcmu_parse_tlvs); #if defined(BCMDBG) int -bcm_format_flags(const bcm_bit_desc_t *bd, u32 flags, char *buf, int len) +brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags, char *buf, + int len) { int i; char *p = buf; @@ -612,10 +603,10 @@ bcm_format_flags(const bcm_bit_desc_t *bd, u32 flags, char *buf, int len) return (int)(p - buf); } -EXPORT_SYMBOL(bcm_format_flags); +EXPORT_SYMBOL(brcmu_format_flags); /* print bytes formatted as hex to a string. return the resulting string length */ -int bcm_format_hex(char *str, const void *bytes, int len) +int brcmu_format_hex(char *str, const void *bytes, int len) { int i; char *p = str; @@ -627,10 +618,10 @@ int bcm_format_hex(char *str, const void *bytes, int len) } return (int)(p - str); } -EXPORT_SYMBOL(bcm_format_hex); +EXPORT_SYMBOL(brcmu_format_hex); #endif /* defined(BCMDBG) */ -char *bcm_chipname(uint chipid, char *buf, uint len) +char *brcmu_chipname(uint chipid, char *buf, uint len) { const char *fmt; @@ -638,9 +629,9 @@ char *bcm_chipname(uint chipid, char *buf, uint len) snprintf(buf, len, fmt, chipid); return buf; } -EXPORT_SYMBOL(bcm_chipname); +EXPORT_SYMBOL(brcmu_chipname); -uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) +uint brcmu_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) { uint len; @@ -657,7 +648,7 @@ uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) return len; } -EXPORT_SYMBOL(bcm_mkiovar); +EXPORT_SYMBOL(brcmu_mkiovar); /* Quarter dBm units to mW * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 @@ -681,7 +672,7 @@ EXPORT_SYMBOL(bcm_mkiovar); #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */ static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { -/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ +/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, @@ -689,7 +680,7 @@ static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 }; -u16 bcm_qdbm_to_mw(u8 qdbm) +u16 brcmu_qdbm_to_mw(u8 qdbm) { uint factor = 1; int idx = qdbm - QDBM_OFFSET; @@ -712,9 +703,9 @@ u16 bcm_qdbm_to_mw(u8 qdbm) */ return (nqdBm_to_mW_map[idx] + factor / 2) / factor; } -EXPORT_SYMBOL(bcm_qdbm_to_mw); +EXPORT_SYMBOL(brcmu_qdbm_to_mw); -u8 bcm_mw_to_qdbm(u16 mw) +u8 brcmu_mw_to_qdbm(u16 mw) { u8 qdbm; int offset; @@ -744,9 +735,9 @@ u8 bcm_mw_to_qdbm(u16 mw) return qdbm; } -EXPORT_SYMBOL(bcm_mw_to_qdbm); +EXPORT_SYMBOL(brcmu_mw_to_qdbm); -uint bcm_bitcount(u8 *bitmap, uint length) +uint brcmu_bitcount(u8 *bitmap, uint length) { uint bitcount = 0, i; u8 tmp; @@ -759,18 +750,18 @@ uint bcm_bitcount(u8 *bitmap, uint length) } return bitcount; } -EXPORT_SYMBOL(bcm_bitcount); +EXPORT_SYMBOL(brcmu_bitcount); -/* Initialization of bcmstrbuf structure */ -void bcm_binit(struct bcmstrbuf *b, char *buf, uint size) +/* Initialization of brcmu_strbuf structure */ +void brcmu_binit(struct brcmu_strbuf *b, char *buf, uint size) { b->origsize = b->size = size; b->origbuf = b->buf = buf; } -EXPORT_SYMBOL(bcm_binit); +EXPORT_SYMBOL(brcmu_binit); /* Buffer sprintf wrapper to guard against buffer overflow */ -int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) +int brcmu_bprintf(struct brcmu_strbuf *b, const char *fmt, ...) { va_list ap; int r; @@ -780,7 +771,7 @@ int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) /* Non Ansi C99 compliant returns -1, * Ansi compliant return r >= b->size, - * bcmstdlib returns 0, handle all + * stdlib returns 0, handle all */ if ((r == -1) || (r >= (int)b->size) || (r == 0)) { b->size = 0; @@ -793,4 +784,4 @@ int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) return r; } -EXPORT_SYMBOL(bcm_bprintf); +EXPORT_SYMBOL(brcmu_bprintf); diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/brcmutil/wifi.c similarity index 91% rename from drivers/staging/brcm80211/util/bcmwifi.c rename to drivers/staging/brcm80211/brcmutil/wifi.c index 955a3ab1a827..b9ffe8682a27 100644 --- a/drivers/staging/brcm80211/util/bcmwifi.c +++ b/drivers/staging/brcm80211/brcmutil/wifi.c @@ -13,12 +13,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include -#include -#include -#include -#include +#include /* * Verify the chanspec is using a legal set of parameters, i.e. that the @@ -26,7 +21,7 @@ * combination could be legal given any set of circumstances. * RETURNS: true is the chanspec is malformed, false if it looks good. */ -bool bcm_chspec_malformed(chanspec_t chanspec) +bool brcmu_chspec_malformed(chanspec_t chanspec) { /* must be 2G or 5G band */ if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec)) @@ -46,14 +41,14 @@ bool bcm_chspec_malformed(chanspec_t chanspec) return false; } -EXPORT_SYMBOL(bcm_chspec_malformed); +EXPORT_SYMBOL(brcmu_chspec_malformed); /* * This function returns the channel number that control traffic is being sent on, for legacy * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ * sideband depending on the chanspec selected */ -u8 bcm_chspec_ctlchan(chanspec_t chspec) +u8 brcmu_chspec_ctlchan(chanspec_t chspec) { u8 ctl_chan; @@ -76,7 +71,7 @@ u8 bcm_chspec_ctlchan(chanspec_t chspec) return ctl_chan; } -EXPORT_SYMBOL(bcm_chspec_ctlchan); +EXPORT_SYMBOL(brcmu_chspec_ctlchan); /* * Return the channel number for a given frequency and base frequency. @@ -97,7 +92,7 @@ EXPORT_SYMBOL(bcm_chspec_ctlchan); * * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 */ -int bcm_mhz2channel(uint freq, uint start_factor) +int brcmu_mhz2channel(uint freq, uint start_factor) { int ch = -1; uint base; @@ -133,5 +128,4 @@ int bcm_mhz2channel(uint freq, uint start_factor) return ch; } -EXPORT_SYMBOL(bcm_mhz2channel); - +EXPORT_SYMBOL(brcmu_mhz2channel); diff --git a/drivers/staging/brcm80211/include/aidmp.h b/drivers/staging/brcm80211/include/aidmp.h deleted file mode 100644 index 7e0ce8f24348..000000000000 --- a/drivers/staging/brcm80211/include/aidmp.h +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _AIDMP_H -#define _AIDMP_H - -/* Manufacturer Ids */ -#define MFGID_ARM 0x43b -#define MFGID_BRCM 0x4bf -#define MFGID_MIPS 0x4a7 - -/* Component Classes */ -#define CC_SIM 0 -#define CC_EROM 1 -#define CC_CORESIGHT 9 -#define CC_VERIF 0xb -#define CC_OPTIMO 0xd -#define CC_GEN 0xe -#define CC_PRIMECELL 0xf - -/* Enumeration ROM registers */ -#define ER_EROMENTRY 0x000 -#define ER_REMAPCONTROL 0xe00 -#define ER_REMAPSELECT 0xe04 -#define ER_MASTERSELECT 0xe10 -#define ER_ITCR 0xf00 -#define ER_ITIP 0xf04 - -/* Erom entries */ -#define ER_TAG 0xe -#define ER_TAG1 0x6 -#define ER_VALID 1 -#define ER_CI 0 -#define ER_MP 2 -#define ER_ADD 4 -#define ER_END 0xe -#define ER_BAD 0xffffffff - -/* EROM CompIdentA */ -#define CIA_MFG_MASK 0xfff00000 -#define CIA_MFG_SHIFT 20 -#define CIA_CID_MASK 0x000fff00 -#define CIA_CID_SHIFT 8 -#define CIA_CCL_MASK 0x000000f0 -#define CIA_CCL_SHIFT 4 - -/* EROM CompIdentB */ -#define CIB_REV_MASK 0xff000000 -#define CIB_REV_SHIFT 24 -#define CIB_NSW_MASK 0x00f80000 -#define CIB_NSW_SHIFT 19 -#define CIB_NMW_MASK 0x0007c000 -#define CIB_NMW_SHIFT 14 -#define CIB_NSP_MASK 0x00003e00 -#define CIB_NSP_SHIFT 9 -#define CIB_NMP_MASK 0x000001f0 -#define CIB_NMP_SHIFT 4 - -/* EROM MasterPortDesc */ -#define MPD_MUI_MASK 0x0000ff00 -#define MPD_MUI_SHIFT 8 -#define MPD_MP_MASK 0x000000f0 -#define MPD_MP_SHIFT 4 - -/* EROM AddrDesc */ -#define AD_ADDR_MASK 0xfffff000 -#define AD_SP_MASK 0x00000f00 -#define AD_SP_SHIFT 8 -#define AD_ST_MASK 0x000000c0 -#define AD_ST_SHIFT 6 -#define AD_ST_SLAVE 0x00000000 -#define AD_ST_BRIDGE 0x00000040 -#define AD_ST_SWRAP 0x00000080 -#define AD_ST_MWRAP 0x000000c0 -#define AD_SZ_MASK 0x00000030 -#define AD_SZ_SHIFT 4 -#define AD_SZ_4K 0x00000000 -#define AD_SZ_8K 0x00000010 -#define AD_SZ_16K 0x00000020 -#define AD_SZ_SZD 0x00000030 -#define AD_AG32 0x00000008 -#define AD_ADDR_ALIGN 0x00000fff -#define AD_SZ_BASE 0x00001000 /* 4KB */ - -/* EROM SizeDesc */ -#define SD_SZ_MASK 0xfffff000 -#define SD_SG32 0x00000008 -#define SD_SZ_ALIGN 0x00000fff - -#ifndef _LANGUAGE_ASSEMBLY - -typedef volatile struct _aidmp { - u32 oobselina30; /* 0x000 */ - u32 oobselina74; /* 0x004 */ - u32 PAD[6]; - u32 oobselinb30; /* 0x020 */ - u32 oobselinb74; /* 0x024 */ - u32 PAD[6]; - u32 oobselinc30; /* 0x040 */ - u32 oobselinc74; /* 0x044 */ - u32 PAD[6]; - u32 oobselind30; /* 0x060 */ - u32 oobselind74; /* 0x064 */ - u32 PAD[38]; - u32 oobselouta30; /* 0x100 */ - u32 oobselouta74; /* 0x104 */ - u32 PAD[6]; - u32 oobseloutb30; /* 0x120 */ - u32 oobseloutb74; /* 0x124 */ - u32 PAD[6]; - u32 oobseloutc30; /* 0x140 */ - u32 oobseloutc74; /* 0x144 */ - u32 PAD[6]; - u32 oobseloutd30; /* 0x160 */ - u32 oobseloutd74; /* 0x164 */ - u32 PAD[38]; - u32 oobsynca; /* 0x200 */ - u32 oobseloutaen; /* 0x204 */ - u32 PAD[6]; - u32 oobsyncb; /* 0x220 */ - u32 oobseloutben; /* 0x224 */ - u32 PAD[6]; - u32 oobsyncc; /* 0x240 */ - u32 oobseloutcen; /* 0x244 */ - u32 PAD[6]; - u32 oobsyncd; /* 0x260 */ - u32 oobseloutden; /* 0x264 */ - u32 PAD[38]; - u32 oobaextwidth; /* 0x300 */ - u32 oobainwidth; /* 0x304 */ - u32 oobaoutwidth; /* 0x308 */ - u32 PAD[5]; - u32 oobbextwidth; /* 0x320 */ - u32 oobbinwidth; /* 0x324 */ - u32 oobboutwidth; /* 0x328 */ - u32 PAD[5]; - u32 oobcextwidth; /* 0x340 */ - u32 oobcinwidth; /* 0x344 */ - u32 oobcoutwidth; /* 0x348 */ - u32 PAD[5]; - u32 oobdextwidth; /* 0x360 */ - u32 oobdinwidth; /* 0x364 */ - u32 oobdoutwidth; /* 0x368 */ - u32 PAD[37]; - u32 ioctrlset; /* 0x400 */ - u32 ioctrlclear; /* 0x404 */ - u32 ioctrl; /* 0x408 */ - u32 PAD[61]; - u32 iostatus; /* 0x500 */ - u32 PAD[127]; - u32 ioctrlwidth; /* 0x700 */ - u32 iostatuswidth; /* 0x704 */ - u32 PAD[62]; - u32 resetctrl; /* 0x800 */ - u32 resetstatus; /* 0x804 */ - u32 resetreadid; /* 0x808 */ - u32 resetwriteid; /* 0x80c */ - u32 PAD[60]; - u32 errlogctrl; /* 0x900 */ - u32 errlogdone; /* 0x904 */ - u32 errlogstatus; /* 0x908 */ - u32 errlogaddrlo; /* 0x90c */ - u32 errlogaddrhi; /* 0x910 */ - u32 errlogid; /* 0x914 */ - u32 errloguser; /* 0x918 */ - u32 errlogflags; /* 0x91c */ - u32 PAD[56]; - u32 intstatus; /* 0xa00 */ - u32 PAD[127]; - u32 config; /* 0xe00 */ - u32 PAD[63]; - u32 itcr; /* 0xf00 */ - u32 PAD[3]; - u32 itipooba; /* 0xf10 */ - u32 itipoobb; /* 0xf14 */ - u32 itipoobc; /* 0xf18 */ - u32 itipoobd; /* 0xf1c */ - u32 PAD[4]; - u32 itipoobaout; /* 0xf30 */ - u32 itipoobbout; /* 0xf34 */ - u32 itipoobcout; /* 0xf38 */ - u32 itipoobdout; /* 0xf3c */ - u32 PAD[4]; - u32 itopooba; /* 0xf50 */ - u32 itopoobb; /* 0xf54 */ - u32 itopoobc; /* 0xf58 */ - u32 itopoobd; /* 0xf5c */ - u32 PAD[4]; - u32 itopoobain; /* 0xf70 */ - u32 itopoobbin; /* 0xf74 */ - u32 itopoobcin; /* 0xf78 */ - u32 itopoobdin; /* 0xf7c */ - u32 PAD[4]; - u32 itopreset; /* 0xf90 */ - u32 PAD[15]; - u32 peripherialid4; /* 0xfd0 */ - u32 peripherialid5; /* 0xfd4 */ - u32 peripherialid6; /* 0xfd8 */ - u32 peripherialid7; /* 0xfdc */ - u32 peripherialid0; /* 0xfe0 */ - u32 peripherialid1; /* 0xfe4 */ - u32 peripherialid2; /* 0xfe8 */ - u32 peripherialid3; /* 0xfec */ - u32 componentid0; /* 0xff0 */ - u32 componentid1; /* 0xff4 */ - u32 componentid2; /* 0xff8 */ - u32 componentid3; /* 0xffc */ -} aidmp_t; - -#endif /* _LANGUAGE_ASSEMBLY */ - -/* Out-of-band Router registers */ -#define OOB_BUSCONFIG 0x020 -#define OOB_STATUSA 0x100 -#define OOB_STATUSB 0x104 -#define OOB_STATUSC 0x108 -#define OOB_STATUSD 0x10c -#define OOB_ENABLEA0 0x200 -#define OOB_ENABLEA1 0x204 -#define OOB_ENABLEA2 0x208 -#define OOB_ENABLEA3 0x20c -#define OOB_ENABLEB0 0x280 -#define OOB_ENABLEB1 0x284 -#define OOB_ENABLEB2 0x288 -#define OOB_ENABLEB3 0x28c -#define OOB_ENABLEC0 0x300 -#define OOB_ENABLEC1 0x304 -#define OOB_ENABLEC2 0x308 -#define OOB_ENABLEC3 0x30c -#define OOB_ENABLED0 0x380 -#define OOB_ENABLED1 0x384 -#define OOB_ENABLED2 0x388 -#define OOB_ENABLED3 0x38c -#define OOB_ITCR 0xf00 -#define OOB_ITIPOOBA 0xf10 -#define OOB_ITIPOOBB 0xf14 -#define OOB_ITIPOOBC 0xf18 -#define OOB_ITIPOOBD 0xf1c -#define OOB_ITOPOOBA 0xf30 -#define OOB_ITOPOOBB 0xf34 -#define OOB_ITOPOOBC 0xf38 -#define OOB_ITOPOOBD 0xf3c - -/* DMP wrapper registers */ -#define AI_OOBSELINA30 0x000 -#define AI_OOBSELINA74 0x004 -#define AI_OOBSELINB30 0x020 -#define AI_OOBSELINB74 0x024 -#define AI_OOBSELINC30 0x040 -#define AI_OOBSELINC74 0x044 -#define AI_OOBSELIND30 0x060 -#define AI_OOBSELIND74 0x064 -#define AI_OOBSELOUTA30 0x100 -#define AI_OOBSELOUTA74 0x104 -#define AI_OOBSELOUTB30 0x120 -#define AI_OOBSELOUTB74 0x124 -#define AI_OOBSELOUTC30 0x140 -#define AI_OOBSELOUTC74 0x144 -#define AI_OOBSELOUTD30 0x160 -#define AI_OOBSELOUTD74 0x164 -#define AI_OOBSYNCA 0x200 -#define AI_OOBSELOUTAEN 0x204 -#define AI_OOBSYNCB 0x220 -#define AI_OOBSELOUTBEN 0x224 -#define AI_OOBSYNCC 0x240 -#define AI_OOBSELOUTCEN 0x244 -#define AI_OOBSYNCD 0x260 -#define AI_OOBSELOUTDEN 0x264 -#define AI_OOBAEXTWIDTH 0x300 -#define AI_OOBAINWIDTH 0x304 -#define AI_OOBAOUTWIDTH 0x308 -#define AI_OOBBEXTWIDTH 0x320 -#define AI_OOBBINWIDTH 0x324 -#define AI_OOBBOUTWIDTH 0x328 -#define AI_OOBCEXTWIDTH 0x340 -#define AI_OOBCINWIDTH 0x344 -#define AI_OOBCOUTWIDTH 0x348 -#define AI_OOBDEXTWIDTH 0x360 -#define AI_OOBDINWIDTH 0x364 -#define AI_OOBDOUTWIDTH 0x368 - -#if defined(__BIG_ENDIAN) && defined(BCMHND74K) -/* Selective swapped defines for those registers we need in - * big-endian code. - */ -#define AI_IOCTRLSET 0x404 -#define AI_IOCTRLCLEAR 0x400 -#define AI_IOCTRL 0x40c -#define AI_IOSTATUS 0x504 -#define AI_RESETCTRL 0x804 -#define AI_RESETSTATUS 0x800 - -#else /* !__BIG_ENDIAN || !BCMHND74K */ - -#define AI_IOCTRLSET 0x400 -#define AI_IOCTRLCLEAR 0x404 -#define AI_IOCTRL 0x408 -#define AI_IOSTATUS 0x500 -#define AI_RESETCTRL 0x800 -#define AI_RESETSTATUS 0x804 - -#endif /* __BIG_ENDIAN && BCMHND74K */ - -#define AI_IOCTRLWIDTH 0x700 -#define AI_IOSTATUSWIDTH 0x704 - -#define AI_RESETREADID 0x808 -#define AI_RESETWRITEID 0x80c -#define AI_ERRLOGCTRL 0xa00 -#define AI_ERRLOGDONE 0xa04 -#define AI_ERRLOGSTATUS 0xa08 -#define AI_ERRLOGADDRLO 0xa0c -#define AI_ERRLOGADDRHI 0xa10 -#define AI_ERRLOGID 0xa14 -#define AI_ERRLOGUSER 0xa18 -#define AI_ERRLOGFLAGS 0xa1c -#define AI_INTSTATUS 0xa00 -#define AI_CONFIG 0xe00 -#define AI_ITCR 0xf00 -#define AI_ITIPOOBA 0xf10 -#define AI_ITIPOOBB 0xf14 -#define AI_ITIPOOBC 0xf18 -#define AI_ITIPOOBD 0xf1c -#define AI_ITIPOOBAOUT 0xf30 -#define AI_ITIPOOBBOUT 0xf34 -#define AI_ITIPOOBCOUT 0xf38 -#define AI_ITIPOOBDOUT 0xf3c -#define AI_ITOPOOBA 0xf50 -#define AI_ITOPOOBB 0xf54 -#define AI_ITOPOOBC 0xf58 -#define AI_ITOPOOBD 0xf5c -#define AI_ITOPOOBAIN 0xf70 -#define AI_ITOPOOBBIN 0xf74 -#define AI_ITOPOOBCIN 0xf78 -#define AI_ITOPOOBDIN 0xf7c -#define AI_ITOPRESET 0xf90 -#define AI_PERIPHERIALID4 0xfd0 -#define AI_PERIPHERIALID5 0xfd4 -#define AI_PERIPHERIALID6 0xfd8 -#define AI_PERIPHERIALID7 0xfdc -#define AI_PERIPHERIALID0 0xfe0 -#define AI_PERIPHERIALID1 0xfe4 -#define AI_PERIPHERIALID2 0xfe8 -#define AI_PERIPHERIALID3 0xfec -#define AI_COMPONENTID0 0xff0 -#define AI_COMPONENTID1 0xff4 -#define AI_COMPONENTID2 0xff8 -#define AI_COMPONENTID3 0xffc - -/* resetctrl */ -#define AIRC_RESET 1 - -/* config */ -#define AICFG_OOB 0x00000020 -#define AICFG_IOS 0x00000010 -#define AICFG_IOC 0x00000008 -#define AICFG_TO 0x00000004 -#define AICFG_ERRL 0x00000002 -#define AICFG_RST 0x00000001 - -#endif /* _AIDMP_H */ diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h deleted file mode 100644 index 55631f367436..000000000000 --- a/drivers/staging/brcm80211/include/bcmdefs.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _bcmdefs_h_ -#define _bcmdefs_h_ - -#define SI_BUS 0 -#define PCI_BUS 1 -#define PCMCIA_BUS 2 -#define SDIO_BUS 3 -#define JTAG_BUS 4 -#define USB_BUS 5 -#define SPI_BUS 6 - - -#ifndef OFF -#define OFF 0 -#endif - -#ifndef ON -#define ON 1 /* ON = 1 */ -#endif - -#define AUTO (-1) /* Auto = -1 */ - -/* Bus types */ -#define SI_BUS 0 /* SOC Interconnect */ -#define PCI_BUS 1 /* PCI target */ -#define SDIO_BUS 3 /* SDIO target */ -#define JTAG_BUS 4 /* JTAG */ -#define USB_BUS 5 /* USB (does not support R/W REG) */ -#define SPI_BUS 6 /* gSPI target */ -#define RPC_BUS 7 /* RPC target */ - - -/* Defines for DMA Address Width - Shared between OSL and HNDDMA */ -#define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */ -#define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */ -#define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */ - -#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */ -#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */ -#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */ -#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */ - -#ifdef BCMDMA64OSL -typedef struct { - u32 loaddr; - u32 hiaddr; -} dma64addr_t; - -typedef dma64addr_t dmaaddr_t; -#define PHYSADDRHI(_pa) ((_pa).hiaddr) -#define PHYSADDRHISET(_pa, _val) \ - do { \ - (_pa).hiaddr = (_val); \ - } while (0) -#define PHYSADDRLO(_pa) ((_pa).loaddr) -#define PHYSADDRLOSET(_pa, _val) \ - do { \ - (_pa).loaddr = (_val); \ - } while (0) - -#else -typedef unsigned long dmaaddr_t; -#define PHYSADDRHI(_pa) (0) -#define PHYSADDRHISET(_pa, _val) -#define PHYSADDRLO(_pa) ((_pa)) -#define PHYSADDRLOSET(_pa, _val) \ - do { \ - (_pa) = (_val); \ - } while (0) -#endif /* BCMDMA64OSL */ - -/* One physical DMA segment */ -typedef struct { - dmaaddr_t addr; - u32 length; -} hnddma_seg_t; - -#define MAX_DMA_SEGS 4 - -typedef struct { - void *oshdmah; /* Opaque handle for OSL to store its information */ - uint origsize; /* Size of the virtual packet */ - uint nsegs; - hnddma_seg_t segs[MAX_DMA_SEGS]; -} hnddma_seg_map_t; - -/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF). - * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL. - * There is a compile time check in wlc.c which ensure that this value is at least as big - * as TXOFF. This value is used in dma_rxfill (hnddma.c). - */ - -#define BCMEXTRAHDROOM 172 - -/* Macros for doing definition and get/set of bitfields - * Usage example, e.g. a three-bit field (bits 4-6): - * #define _M BITFIELD_MASK(3) - * #define _S 4 - * ... - * regval = R_REG(osh, ®s->regfoo); - * field = GFIELD(regval, ); - * regval = SFIELD(regval, , 1); - * W_REG(osh, ®s->regfoo, regval); - */ -#define BITFIELD_MASK(width) \ - (((unsigned)1 << (width)) - 1) -#define GFIELD(val, field) \ - (((val) >> field ## _S) & field ## _M) -#define SFIELD(val, field, bits) \ - (((val) & (~(field ## _M << field ## _S))) | \ - ((unsigned)(bits) << field ## _S)) - -/* - * Priority definitions according 802.1D - */ -#define PRIO_8021D_NONE 2 -#define PRIO_8021D_BK 1 -#define PRIO_8021D_BE 0 -#define PRIO_8021D_EE 3 -#define PRIO_8021D_CL 4 -#define PRIO_8021D_VI 5 -#define PRIO_8021D_VO 6 -#define PRIO_8021D_NC 7 -#define MAXPRIO 7 -#define NUMPRIO (MAXPRIO + 1) - -/* Max. nvram variable table size */ -#define MAXSZ_NVRAM_VARS 4096 - -/* handle forward declaration */ -struct wl_info; -struct wlc_bsscfg; - -#endif /* _bcmdefs_h_ */ diff --git a/drivers/staging/brcm80211/include/bcmdevs.h b/drivers/staging/brcm80211/include/bcmdevs.h deleted file mode 100644 index 26947efa83e8..000000000000 --- a/drivers/staging/brcm80211/include/bcmdevs.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _BCMDEVS_H -#define _BCMDEVS_H - -#define BCM4325_D11DUAL_ID 0x431b -#define BCM4325_D11G_ID 0x431c -#define BCM4325_D11A_ID 0x431d - -#define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */ -#define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */ -#define BCM4329_D11NDUAL_ID 0x432e - -#define BCM4319_D11N_ID 0x4337 /* 4319 802.11n dualband device */ -#define BCM4319_D11N2G_ID 0x4338 /* 4319 802.11n 2.4G device */ -#define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */ - -#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */ - -#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */ - -#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */ -#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */ - -#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ - -/* Chip IDs */ -#define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */ -#define BCM4319_CHIP_ID 0x4319 /* 4319 chip id */ - -#define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */ -#define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */ -#define BCM43421_CHIP_ID 43421 /* 43421 chipcommon chipid */ -#define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */ -#define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */ -#define BCM43238_CHIP_ID 43238 /* 43238 chipcommon chipid */ -#define BCM4329_CHIP_ID 0x4329 /* 4329 chipcommon chipid */ -#define BCM4325_CHIP_ID 0x4325 /* 4325 chipcommon chipid */ -#define BCM4331_CHIP_ID 0x4331 /* 4331 chipcommon chipid */ -#define BCM4336_CHIP_ID 0x4336 /* 4336 chipcommon chipid */ -#define BCM4330_CHIP_ID 0x4330 /* 4330 chipcommon chipid */ -#define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */ - -/* these are router chips */ -#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */ -#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */ -#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */ -#define BCM5356_CHIP_ID 0x5356 /* 5356 chipcommon chipid */ -#define BCM5357_CHIP_ID 0x5357 /* 5357 chipcommon chipid */ - -/* Package IDs */ -#define BCM4329_289PIN_PKG_ID 0 /* 4329 289-pin package id */ -#define BCM4329_182PIN_PKG_ID 1 /* 4329N 182-pin package id */ -#define BCM4717_PKG_ID 9 /* 4717 package id */ -#define BCM4718_PKG_ID 10 /* 4718 package id */ -#define HDLSIM_PKG_ID 14 /* HDL simulator package id */ -#define HWSIM_PKG_ID 15 /* Hardware simulator package id */ -#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */ - -/* boardflags */ -#define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */ -#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */ -#define BFL_FEM 0x00000800 /* Board supports the Front End Module */ -#define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */ -#define BFL_NOPA 0x00010000 /* Board has no PA */ -#define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */ -#define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */ -#define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */ -#define BFL_PALDO 0x02000000 /* Power topology uses PALDO */ -#define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ - -/* boardflags2 */ -#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */ -#define BFL2_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */ -#define BFL2_TXPWRCTRL_EN 0x00000004 /* Board permits enabling TX Power Control */ -#define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */ -#define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */ -#define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */ -#define BFL2_LEGACY 0x00000080 -#define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */ -#define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */ -#define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */ -#define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */ -#define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */ -#define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */ -#define BFL2_IPALVLSHIFT_3P3 0x00020000 -#define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */ -#define BFL2_XTALBUFOUTEN 0x00080000 /* Keep the buffered Xtal output from radio "ON" - * Most drivers will turn it off without this flag - * to save power. - */ - -/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ -#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ -#define BOARD_GPIO_12 0x1000 /* gpio 12 */ -#define BOARD_GPIO_13 0x2000 /* gpio 13 */ - -#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ -#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal power-up */ -#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL power-down */ - -/* power control defines */ -#define PLL_DELAY 150 /* us pll on delay */ -#define FREF_DELAY 200 /* us fref change delay */ -#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ - -/* Reference board types */ -#define SPI_BOARD 0x0402 - -#endif /* _BCMDEVS_H */ diff --git a/drivers/staging/brcm80211/include/bcmnvram.h b/drivers/staging/brcm80211/include/bcmnvram.h deleted file mode 100644 index 12645ddf000d..000000000000 --- a/drivers/staging/brcm80211/include/bcmnvram.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _bcmnvram_h_ -#define _bcmnvram_h_ - -#ifndef _LANGUAGE_ASSEMBLY - -#include - -struct nvram_header { - u32 magic; - u32 len; - u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ - u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ - u32 config_ncdl; /* ncdl values for memc */ -}; - -/* - * Initialize NVRAM access. May be unnecessary or undefined on certain - * platforms. - */ -extern int nvram_init(void); - -/* - * Append a chunk of nvram variables to the global list - */ -extern int nvram_append(char *vars, uint varsz); - -/* - * Check for reset button press for restoring factory defaults. - */ -extern int nvram_reset(void); - -/* - * Disable NVRAM access. May be unnecessary or undefined on certain - * platforms. - */ -extern void nvram_exit(void); - -/* - * Get the value of an NVRAM variable. The pointer returned may be - * invalid after a set. - * @param name name of variable to get - * @return value of variable or NULL if undefined - */ -extern char *nvram_get(const char *name); - -/* - * Get the value of an NVRAM variable. - * @param name name of variable to get - * @return value of variable or NUL if undefined - */ -#define nvram_safe_get(name) (nvram_get(name) ? : "") - -/* - * Match an NVRAM variable. - * @param name name of variable to match - * @param match value to compare against value of variable - * @return true if variable is defined and its value is string equal - * to match or false otherwise - */ -static inline int nvram_match(char *name, char *match) -{ - const char *value = nvram_get(name); - return value && !strcmp(value, match); -} - -/* - * Inversely match an NVRAM variable. - * @param name name of variable to match - * @param match value to compare against value of variable - * @return true if variable is defined and its value is not string - * equal to invmatch or false otherwise - */ -static inline int nvram_invmatch(char *name, char *invmatch) -{ - const char *value = nvram_get(name); - return value && strcmp(value, invmatch); -} - -/* - * Set the value of an NVRAM variable. The name and value strings are - * copied into private storage. Pointers to previously set values - * may become invalid. The new value may be immediately - * retrieved but will not be permanently stored until a commit. - * @param name name of variable to set - * @param value value of variable - * @return 0 on success and errno on failure - */ -extern int nvram_set(const char *name, const char *value); - -/* - * Unset an NVRAM variable. Pointers to previously set values - * remain valid until a set. - * @param name name of variable to unset - * @return 0 on success and errno on failure - * NOTE: use nvram_commit to commit this change to flash. - */ -extern int nvram_unset(const char *name); - -/* - * Commit NVRAM variables to permanent storage. All pointers to values - * may be invalid after a commit. - * NVRAM values are undefined after a commit. - * @return 0 on success and errno on failure - */ -extern int nvram_commit(void); - -/* - * Get all NVRAM variables (format name=value\0 ... \0\0). - * @param buf buffer to store variables - * @param count size of buffer in bytes - * @return 0 on success and errno on failure - */ -extern int nvram_getall(char *nvram_buf, int count); - -#endif /* _LANGUAGE_ASSEMBLY */ - -/* variable access */ -extern char *getvar(char *vars, const char *name); -extern int getintvar(char *vars, const char *name); - -/* The NVRAM version number stored as an NVRAM variable */ -#define NVRAM_SOFTWARE_VERSION "1" - -#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ -#define NVRAM_CLEAR_MAGIC 0x0 -#define NVRAM_INVALID_MAGIC 0xFFFFFFFF -#define NVRAM_VERSION 1 -#define NVRAM_HEADER_SIZE 20 -#define NVRAM_SPACE 0x8000 - -#define NVRAM_MAX_VALUE_LEN 255 -#define NVRAM_MAX_PARAM_LEN 64 - -#define NVRAM_CRC_START_POSITION 9 /* magic, len, crc8 to be skipped */ -#define NVRAM_CRC_VER_MASK 0xffffff00 /* for crc_ver_init */ - -#endif /* _bcmnvram_h_ */ diff --git a/drivers/staging/brcm80211/include/bcmsdh.h b/drivers/staging/brcm80211/include/bcmsdh.h deleted file mode 100644 index 3b57dc13b1de..000000000000 --- a/drivers/staging/brcm80211/include/bcmsdh.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _bcmsdh_h_ -#define _bcmsdh_h_ - -#include -#define BCMSDH_ERROR_VAL 0x0001 /* Error */ -#define BCMSDH_INFO_VAL 0x0002 /* Info */ -extern const uint bcmsdh_msglevel; - -#ifdef BCMDBG -#define BCMSDH_ERROR(x) \ - do { \ - if ((bcmsdh_msglevel & BCMSDH_ERROR_VAL) && net_ratelimit()) \ - printk x; \ - } while (0) -#define BCMSDH_INFO(x) \ - do { \ - if ((bcmsdh_msglevel & BCMSDH_INFO_VAL) && net_ratelimit()) \ - printk x; \ - } while (0) -#else /* BCMDBG */ -#define BCMSDH_ERROR(x) -#define BCMSDH_INFO(x) -#endif /* BCMDBG */ - -/* forward declarations */ -typedef struct bcmsdh_info bcmsdh_info_t; -typedef void (*bcmsdh_cb_fn_t) (void *); - -/* Attach and build an interface to the underlying SD host driver. - * - Allocates resources (structs, arrays, mem, OS handles, etc) needed by bcmsdh. - * - Returns the bcmsdh handle and virtual address base for register access. - * The returned handle should be used in all subsequent calls, but the bcmsh - * implementation may maintain a single "default" handle (e.g. the first or - * most recent one) to enable single-instance implementations to pass NULL. - */ -extern bcmsdh_info_t *bcmsdh_attach(void *cfghdl, void **regsva, uint irq); - -/* Detach - freeup resources allocated in attach */ -extern int bcmsdh_detach(void *sdh); - -/* Query if SD device interrupts are enabled */ -extern bool bcmsdh_intr_query(void *sdh); - -/* Enable/disable SD interrupt */ -extern int bcmsdh_intr_enable(void *sdh); -extern int bcmsdh_intr_disable(void *sdh); - -/* Register/deregister device interrupt handler. */ -extern int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh); -extern int bcmsdh_intr_dereg(void *sdh); - -#if defined(DHD_DEBUG) -/* Query pending interrupt status from the host controller */ -extern bool bcmsdh_intr_pending(void *sdh); -#endif -extern int bcmsdh_claim_host_and_lock(void *sdh); -extern int bcmsdh_release_host_and_unlock(void *sdh); - -/* Register a callback to be called if and when bcmsdh detects - * device removal. No-op in the case of non-removable/hardwired devices. - */ -extern int bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh); - -/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface). - * fn: function number - * addr: unmodified SDIO-space address - * data: data byte to write - * err: pointer to error code (or NULL) - */ -extern u8 bcmsdh_cfg_read(void *sdh, uint func, u32 addr, int *err); -extern void bcmsdh_cfg_write(void *sdh, uint func, u32 addr, u8 data, - int *err); - -/* Read/Write 4bytes from/to cfg space */ -extern u32 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, u32 addr, - int *err); -extern void bcmsdh_cfg_write_word(void *sdh, uint fnc_num, u32 addr, - u32 data, int *err); - -/* Read CIS content for specified function. - * fn: function whose CIS is being requested (0 is common CIS) - * cis: pointer to memory location to place results - * length: number of bytes to read - * Internally, this routine uses the values from the cis base regs (0x9-0xB) - * to form an SDIO-space address to read the data from. - */ -extern int bcmsdh_cis_read(void *sdh, uint func, u8 *cis, uint length); - -/* Synchronous access to device (client) core registers via CMD53 to F1. - * addr: backplane address (i.e. >= regsva from attach) - * size: register width in bytes (2 or 4) - * data: data for register write - */ -extern u32 bcmsdh_reg_read(void *sdh, u32 addr, uint size); -extern u32 bcmsdh_reg_write(void *sdh, u32 addr, uint size, u32 data); - -/* Indicate if last reg read/write failed */ -extern bool bcmsdh_regfail(void *sdh); - -/* Buffer transfer to/from device (client) core via cmd53. - * fn: function number - * addr: backplane address (i.e. >= regsva from attach) - * flags: backplane width, address increment, sync/async - * buf: pointer to memory data buffer - * nbytes: number of bytes to transfer to/from buf - * pkt: pointer to packet associated with buf (if any) - * complete: callback function for command completion (async only) - * handle: handle for completion callback (first arg in callback) - * Returns 0 or error code. - * NOTE: Async operation is not currently supported. - */ -typedef void (*bcmsdh_cmplt_fn_t) (void *handle, int status, bool sync_waiting); -extern int bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags, - u8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle); -extern int bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags, - u8 *buf, uint nbytes, struct sk_buff *pkt, - bcmsdh_cmplt_fn_t complete, void *handle); - -/* Flags bits */ -#define SDIO_REQ_4BYTE 0x1 /* Four-byte target (backplane) width (vs. two-byte) */ -#define SDIO_REQ_FIXED 0x2 /* Fixed address (FIFO) (vs. incrementing address) */ -#define SDIO_REQ_ASYNC 0x4 /* Async request (vs. sync request) */ - -/* Pending (non-error) return code */ -#define BCME_PENDING 1 - -/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only). - * rw: read or write (0/1) - * addr: direct SDIO address - * buf: pointer to memory data buffer - * nbytes: number of bytes to transfer to/from buf - * Returns 0 or error code. - */ -extern int bcmsdh_rwdata(void *sdh, uint rw, u32 addr, u8 *buf, - uint nbytes); - -/* Issue an abort to the specified function */ -extern int bcmsdh_abort(void *sdh, uint fn); - -/* Start SDIO Host Controller communication */ -extern int bcmsdh_start(void *sdh, int stage); - -/* Stop SDIO Host Controller communication */ -extern int bcmsdh_stop(void *sdh); - -/* Returns the "Device ID" of target device on the SDIO bus. */ -extern int bcmsdh_query_device(void *sdh); - -/* Returns the number of IO functions reported by the device */ -extern uint bcmsdh_query_iofnum(void *sdh); - -/* Miscellaneous knob tweaker. */ -extern int bcmsdh_iovar_op(void *sdh, const char *name, - void *params, int plen, void *arg, int len, - bool set); - -/* Reset and reinitialize the device */ -extern int bcmsdh_reset(bcmsdh_info_t *sdh); - -/* helper functions */ - -extern void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); - -/* callback functions */ -typedef struct { - /* attach to device */ - void *(*attach) (u16 vend_id, u16 dev_id, u16 bus, u16 slot, - u16 func, uint bustype, void *regsva, void *param); - /* detach from device */ - void (*detach) (void *ch); -} bcmsdh_driver_t; - -/* platform specific/high level functions */ -extern int bcmsdh_register(bcmsdh_driver_t *driver); -extern void bcmsdh_unregister(void); -extern bool bcmsdh_chipmatch(u16 vendor, u16 device); -extern void bcmsdh_device_remove(void *sdh); - -/* Function to pass device-status bits to DHD. */ -extern u32 bcmsdh_get_dstatus(void *sdh); - -/* Function to return current window addr */ -extern u32 bcmsdh_cur_sbwad(void *sdh); - -/* Function to pass chipid and rev to lower layers for controlling pr's */ -extern void bcmsdh_chipinfo(void *sdh, u32 chip, u32 chiprev); - -#endif /* _bcmsdh_h_ */ diff --git a/drivers/staging/brcm80211/include/bcmsdpcm.h b/drivers/staging/brcm80211/include/bcmsdpcm.h deleted file mode 100644 index 5175e67a6d28..000000000000 --- a/drivers/staging/brcm80211/include/bcmsdpcm.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _bcmsdpcm_h_ -#define _bcmsdpcm_h_ - -/* - * Software allocation of To SB Mailbox resources - */ - -/* intstatus bits */ -#define I_SMB_NAK I_SMB_SW0 /* To SB Mailbox Frame NAK */ -#define I_SMB_INT_ACK I_SMB_SW1 /* To SB Mailbox Host Interrupt ACK */ -#define I_SMB_USE_OOB I_SMB_SW2 /* To SB Mailbox Use OOB Wakeup */ -#define I_SMB_DEV_INT I_SMB_SW3 /* To SB Mailbox Miscellaneous Interrupt */ - -#define I_TOSBMAIL (I_SMB_NAK | I_SMB_INT_ACK | I_SMB_USE_OOB | I_SMB_DEV_INT) - -/* tosbmailbox bits corresponding to intstatus bits */ -#define SMB_NAK (1 << 0) /* To SB Mailbox Frame NAK */ -#define SMB_INT_ACK (1 << 1) /* To SB Mailbox Host Interrupt ACK */ -#define SMB_USE_OOB (1 << 2) /* To SB Mailbox Use OOB Wakeup */ -#define SMB_DEV_INT (1 << 3) /* To SB Mailbox Miscellaneous Interrupt */ -#define SMB_MASK 0x0000000f /* To SB Mailbox Mask */ - -/* tosbmailboxdata */ -#define SMB_DATA_VERSION_MASK 0x00ff0000 /* host protocol version (sent with F2 enable) */ -#define SMB_DATA_VERSION_SHIFT 16 /* host protocol version (sent with F2 enable) */ - -/* - * Software allocation of To Host Mailbox resources - */ - -/* intstatus bits */ -#define I_HMB_FC_STATE I_HMB_SW0 /* To Host Mailbox Flow Control State */ -#define I_HMB_FC_CHANGE I_HMB_SW1 /* To Host Mailbox Flow Control State Changed */ -#define I_HMB_FRAME_IND I_HMB_SW2 /* To Host Mailbox Frame Indication */ -#define I_HMB_HOST_INT I_HMB_SW3 /* To Host Mailbox Miscellaneous Interrupt */ - -#define I_TOHOSTMAIL (I_HMB_FC_CHANGE | I_HMB_FRAME_IND | I_HMB_HOST_INT) - -/* tohostmailbox bits corresponding to intstatus bits */ -#define HMB_FC_ON (1 << 0) /* To Host Mailbox Flow Control State */ -#define HMB_FC_CHANGE (1 << 1) /* To Host Mailbox Flow Control State Changed */ -#define HMB_FRAME_IND (1 << 2) /* To Host Mailbox Frame Indication */ -#define HMB_HOST_INT (1 << 3) /* To Host Mailbox Miscellaneous Interrupt */ -#define HMB_MASK 0x0000000f /* To Host Mailbox Mask */ - -/* tohostmailboxdata */ -#define HMB_DATA_NAKHANDLED 1 /* we're ready to retransmit NAK'd frame to host */ -#define HMB_DATA_DEVREADY 2 /* we're ready to to talk to host after enable */ -#define HMB_DATA_FC 4 /* per prio flowcontrol update flag to host */ -#define HMB_DATA_FWREADY 8 /* firmware is ready for protocol activity */ - -#define HMB_DATA_FCDATA_MASK 0xff000000 /* per prio flowcontrol data */ -#define HMB_DATA_FCDATA_SHIFT 24 /* per prio flowcontrol data */ - -#define HMB_DATA_VERSION_MASK 0x00ff0000 /* device protocol version (with devready) */ -#define HMB_DATA_VERSION_SHIFT 16 /* device protocol version (with devready) */ - -/* - * Software-defined protocol header - */ - -/* Current protocol version */ -#define SDPCM_PROT_VERSION 4 - -/* SW frame header */ -#define SDPCM_SEQUENCE_MASK 0x000000ff /* Sequence Number Mask */ -#define SDPCM_PACKET_SEQUENCE(p) (((u8 *)p)[0] & 0xff) /* p starts w/SW Header */ - -#define SDPCM_CHANNEL_MASK 0x00000f00 /* Channel Number Mask */ -#define SDPCM_CHANNEL_SHIFT 8 /* Channel Number Shift */ -#define SDPCM_PACKET_CHANNEL(p) (((u8 *)p)[1] & 0x0f) /* p starts w/SW Header */ - -#define SDPCM_FLAGS_MASK 0x0000f000 /* Mask of flag bits */ -#define SDPCM_FLAGS_SHIFT 12 /* Flag bits shift */ -#define SDPCM_PACKET_FLAGS(p) ((((u8 *)p)[1] & 0xf0) >> 4) /* p starts w/SW Header */ - -/* Next Read Len: lookahead length of next frame, in 16-byte units (rounded up) */ -#define SDPCM_NEXTLEN_MASK 0x00ff0000 /* Next Read Len Mask */ -#define SDPCM_NEXTLEN_SHIFT 16 /* Next Read Len Shift */ -#define SDPCM_NEXTLEN_VALUE(p) ((((u8 *)p)[2] & 0xff) << 4) /* p starts w/SW Header */ -#define SDPCM_NEXTLEN_OFFSET 2 - -/* Data Offset from SOF (HW Tag, SW Tag, Pad) */ -#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */ -#define SDPCM_DOFFSET_VALUE(p) (((u8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff) -#define SDPCM_DOFFSET_MASK 0xff000000 -#define SDPCM_DOFFSET_SHIFT 24 - -#define SDPCM_FCMASK_OFFSET 4 /* Flow control */ -#define SDPCM_FCMASK_VALUE(p) (((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff) -#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */ -#define SDPCM_WINDOW_VALUE(p) (((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff) -#define SDPCM_VERSION_OFFSET 6 /* Version # */ -#define SDPCM_VERSION_VALUE(p) (((u8 *)p)[SDPCM_VERSION_OFFSET] & 0xff) -#define SDPCM_UNUSED_OFFSET 7 /* Spare */ -#define SDPCM_UNUSED_VALUE(p) (((u8 *)p)[SDPCM_UNUSED_OFFSET] & 0xff) - -#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */ - -/* logical channel numbers */ -#define SDPCM_CONTROL_CHANNEL 0 /* Control Request/Response Channel Id */ -#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */ -#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */ -#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets (superframes) */ -#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */ -#define SDPCM_MAX_CHANNEL 15 - -#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for eight-bit frame seq number */ - -#define SDPCM_FLAG_RESVD0 0x01 -#define SDPCM_FLAG_RESVD1 0x02 -#define SDPCM_FLAG_GSPI_TXENAB 0x04 -#define SDPCM_FLAG_GLOMDESC 0x08 /* Superframe descriptor mask */ - -/* For GLOM_CHANNEL frames, use a flag to indicate descriptor frame */ -#define SDPCM_GLOMDESC_FLAG (SDPCM_FLAG_GLOMDESC << SDPCM_FLAGS_SHIFT) - -#define SDPCM_GLOMDESC(p) (((u8 *)p)[1] & 0x80) - -/* For TEST_CHANNEL packets, define another 4-byte header */ -#define SDPCM_TEST_HDRLEN 4 /* Generally: Cmd(1), Ext(1), Len(2); - * Semantics of Ext byte depend on command. - * Len is current or requested frame length, not - * including test header; sent little-endian. - */ -#define SDPCM_TEST_DISCARD 0x01 /* Receiver discards. Ext is a pattern id. */ -#define SDPCM_TEST_ECHOREQ 0x02 /* Echo request. Ext is a pattern id. */ -#define SDPCM_TEST_ECHORSP 0x03 /* Echo response. Ext is a pattern id. */ -#define SDPCM_TEST_BURST 0x04 /* Receiver to send a burst. Ext is a frame count */ -#define SDPCM_TEST_SEND 0x05 /* Receiver sets send mode. Ext is boolean on/off */ - -/* Handy macro for filling in datagen packets with a pattern */ -#define SDPCM_TEST_FILL(byteno, id) ((u8)(id + byteno)) - -/* - * Software counters (first part matches hardware counters) - */ - -typedef volatile struct { - u32 cmd52rd; /* Cmd52RdCount, SDIO: cmd52 reads */ - u32 cmd52wr; /* Cmd52WrCount, SDIO: cmd52 writes */ - u32 cmd53rd; /* Cmd53RdCount, SDIO: cmd53 reads */ - u32 cmd53wr; /* Cmd53WrCount, SDIO: cmd53 writes */ - u32 abort; /* AbortCount, SDIO: aborts */ - u32 datacrcerror; /* DataCrcErrorCount, SDIO: frames w/CRC error */ - u32 rdoutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Rd Frm out of sync */ - u32 wroutofsync; /* RdOutOfSyncCount, SDIO/PCMCIA: Wr Frm out of sync */ - u32 writebusy; /* WriteBusyCount, SDIO: device asserted "busy" */ - u32 readwait; /* ReadWaitCount, SDIO: no data ready for a read cmd */ - u32 readterm; /* ReadTermCount, SDIO: read frame termination cmds */ - u32 writeterm; /* WriteTermCount, SDIO: write frames termination cmds */ - u32 rxdescuflo; /* receive descriptor underflows */ - u32 rxfifooflo; /* receive fifo overflows */ - u32 txfifouflo; /* transmit fifo underflows */ - u32 runt; /* runt (too short) frames recv'd from bus */ - u32 badlen; /* frame's rxh len does not match its hw tag len */ - u32 badcksum; /* frame's hw tag chksum doesn't agree with len value */ - u32 seqbreak; /* break in sequence # space from one rx frame to the next */ - u32 rxfcrc; /* frame rx header indicates crc error */ - u32 rxfwoos; /* frame rx header indicates write out of sync */ - u32 rxfwft; /* frame rx header indicates write frame termination */ - u32 rxfabort; /* frame rx header indicates frame aborted */ - u32 woosint; /* write out of sync interrupt */ - u32 roosint; /* read out of sync interrupt */ - u32 rftermint; /* read frame terminate interrupt */ - u32 wftermint; /* write frame terminate interrupt */ -} sdpcmd_cnt_t; - -/* - * Shared structure between dongle and the host. - * The structure contains pointers to trap or assert information. - */ -#define SDPCM_SHARED_VERSION 0x0002 -#define SDPCM_SHARED_VERSION_MASK 0x00FF -#define SDPCM_SHARED_ASSERT_BUILT 0x0100 -#define SDPCM_SHARED_ASSERT 0x0200 -#define SDPCM_SHARED_TRAP 0x0400 - -typedef struct { - u32 flags; - u32 trap_addr; - u32 assert_exp_addr; - u32 assert_file_addr; - u32 assert_line; - u32 console_addr; /* Address of hndrte_cons_t */ - u32 msgtrace_addr; - u8 tag[32]; -} sdpcm_shared_t; - -extern sdpcm_shared_t sdpcm_shared; - -#endif /* _bcmsdpcm_h_ */ diff --git a/drivers/staging/brcm80211/include/bcmsrom_fmt.h b/drivers/staging/brcm80211/include/bcmsrom_fmt.h deleted file mode 100644 index 4666afd883a5..000000000000 --- a/drivers/staging/brcm80211/include/bcmsrom_fmt.h +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _bcmsrom_fmt_h_ -#define _bcmsrom_fmt_h_ - -/* Maximum srom: 6 Kilobits == 768 bytes */ -#define SROM_MAX 768 -#define SROM_MAXW 384 -#define VARS_MAX 4096 - -/* PCI fields */ -#define PCI_F0DEVID 48 - -#define SROM_WORDS 64 - -#define SROM3_SWRGN_OFF 28 /* s/w region offset in words */ - -#define SROM_SSID 2 - -#define SROM_WL1LHMAXP 29 - -#define SROM_WL1LPAB0 30 -#define SROM_WL1LPAB1 31 -#define SROM_WL1LPAB2 32 - -#define SROM_WL1HPAB0 33 -#define SROM_WL1HPAB1 34 -#define SROM_WL1HPAB2 35 - -#define SROM_MACHI_IL0 36 -#define SROM_MACMID_IL0 37 -#define SROM_MACLO_IL0 38 -#define SROM_MACHI_ET0 39 -#define SROM_MACMID_ET0 40 -#define SROM_MACLO_ET0 41 -#define SROM_MACHI_ET1 42 -#define SROM_MACMID_ET1 43 -#define SROM_MACLO_ET1 44 -#define SROM3_MACHI 37 -#define SROM3_MACMID 38 -#define SROM3_MACLO 39 - -#define SROM_BXARSSI2G 40 -#define SROM_BXARSSI5G 41 - -#define SROM_TRI52G 42 -#define SROM_TRI5GHL 43 - -#define SROM_RXPO52G 45 - -#define SROM2_ENETPHY 45 - -#define SROM_AABREV 46 -/* Fields in AABREV */ -#define SROM_BR_MASK 0x00ff -#define SROM_CC_MASK 0x0f00 -#define SROM_CC_SHIFT 8 -#define SROM_AA0_MASK 0x3000 -#define SROM_AA0_SHIFT 12 -#define SROM_AA1_MASK 0xc000 -#define SROM_AA1_SHIFT 14 - -#define SROM_WL0PAB0 47 -#define SROM_WL0PAB1 48 -#define SROM_WL0PAB2 49 - -#define SROM_LEDBH10 50 -#define SROM_LEDBH32 51 - -#define SROM_WL10MAXP 52 - -#define SROM_WL1PAB0 53 -#define SROM_WL1PAB1 54 -#define SROM_WL1PAB2 55 - -#define SROM_ITT 56 - -#define SROM_BFL 57 -#define SROM_BFL2 28 -#define SROM3_BFL2 61 - -#define SROM_AG10 58 - -#define SROM_CCODE 59 - -#define SROM_OPO 60 - -#define SROM3_LEDDC 62 - -#define SROM_CRCREV 63 - -/* SROM Rev 4: Reallocate the software part of the srom to accommodate - * MIMO features. It assumes up to two PCIE functions and 440 bytes - * of usable srom i.e. the usable storage in chips with OTP that - * implements hardware redundancy. - */ - -#define SROM4_WORDS 220 - -#define SROM4_SIGN 32 -#define SROM4_SIGNATURE 0x5372 - -#define SROM4_BREV 33 - -#define SROM4_BFL0 34 -#define SROM4_BFL1 35 -#define SROM4_BFL2 36 -#define SROM4_BFL3 37 -#define SROM5_BFL0 37 -#define SROM5_BFL1 38 -#define SROM5_BFL2 39 -#define SROM5_BFL3 40 - -#define SROM4_MACHI 38 -#define SROM4_MACMID 39 -#define SROM4_MACLO 40 -#define SROM5_MACHI 41 -#define SROM5_MACMID 42 -#define SROM5_MACLO 43 - -#define SROM4_CCODE 41 -#define SROM4_REGREV 42 -#define SROM5_CCODE 34 -#define SROM5_REGREV 35 - -#define SROM4_LEDBH10 43 -#define SROM4_LEDBH32 44 -#define SROM5_LEDBH10 59 -#define SROM5_LEDBH32 60 - -#define SROM4_LEDDC 45 -#define SROM5_LEDDC 45 - -#define SROM4_AA 46 -#define SROM4_AA2G_MASK 0x00ff -#define SROM4_AA2G_SHIFT 0 -#define SROM4_AA5G_MASK 0xff00 -#define SROM4_AA5G_SHIFT 8 - -#define SROM4_AG10 47 -#define SROM4_AG32 48 - -#define SROM4_TXPID2G 49 -#define SROM4_TXPID5G 51 -#define SROM4_TXPID5GL 53 -#define SROM4_TXPID5GH 55 - -#define SROM4_TXRXC 61 -#define SROM4_TXCHAIN_MASK 0x000f -#define SROM4_TXCHAIN_SHIFT 0 -#define SROM4_RXCHAIN_MASK 0x00f0 -#define SROM4_RXCHAIN_SHIFT 4 -#define SROM4_SWITCH_MASK 0xff00 -#define SROM4_SWITCH_SHIFT 8 - -/* Per-path fields */ -#define MAX_PATH_SROM 4 -#define SROM4_PATH0 64 -#define SROM4_PATH1 87 -#define SROM4_PATH2 110 -#define SROM4_PATH3 133 - -#define SROM4_2G_ITT_MAXP 0 -#define SROM4_2G_PA 1 -#define SROM4_5G_ITT_MAXP 5 -#define SROM4_5GLH_MAXP 6 -#define SROM4_5G_PA 7 -#define SROM4_5GL_PA 11 -#define SROM4_5GH_PA 15 - -/* Fields in the ITT_MAXP and 5GLH_MAXP words */ -#define B2G_MAXP_MASK 0xff -#define B2G_ITT_SHIFT 8 -#define B5G_MAXP_MASK 0xff -#define B5G_ITT_SHIFT 8 -#define B5GH_MAXP_MASK 0xff -#define B5GL_MAXP_SHIFT 8 - -/* All the miriad power offsets */ -#define SROM4_2G_CCKPO 156 -#define SROM4_2G_OFDMPO 157 -#define SROM4_5G_OFDMPO 159 -#define SROM4_5GL_OFDMPO 161 -#define SROM4_5GH_OFDMPO 163 -#define SROM4_2G_MCSPO 165 -#define SROM4_5G_MCSPO 173 -#define SROM4_5GL_MCSPO 181 -#define SROM4_5GH_MCSPO 189 -#define SROM4_CDDPO 197 -#define SROM4_STBCPO 198 -#define SROM4_BW40PO 199 -#define SROM4_BWDUPPO 200 - -#define SROM4_CRCREV 219 - -/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6. - * This is acombined srom for both MIMO and SISO boards, usable in - * the .130 4Kilobit OTP with hardware redundancy. - */ - -#define SROM8_SIGN 64 - -#define SROM8_BREV 65 - -#define SROM8_BFL0 66 -#define SROM8_BFL1 67 -#define SROM8_BFL2 68 -#define SROM8_BFL3 69 - -#define SROM8_MACHI 70 -#define SROM8_MACMID 71 -#define SROM8_MACLO 72 - -#define SROM8_CCODE 73 -#define SROM8_REGREV 74 - -#define SROM8_LEDBH10 75 -#define SROM8_LEDBH32 76 - -#define SROM8_LEDDC 77 - -#define SROM8_AA 78 - -#define SROM8_AG10 79 -#define SROM8_AG32 80 - -#define SROM8_TXRXC 81 - -#define SROM8_BXARSSI2G 82 -#define SROM8_BXARSSI5G 83 -#define SROM8_TRI52G 84 -#define SROM8_TRI5GHL 85 -#define SROM8_RXPO52G 86 - -#define SROM8_FEM2G 87 -#define SROM8_FEM5G 88 -#define SROM8_FEM_ANTSWLUT_MASK 0xf800 -#define SROM8_FEM_ANTSWLUT_SHIFT 11 -#define SROM8_FEM_TR_ISO_MASK 0x0700 -#define SROM8_FEM_TR_ISO_SHIFT 8 -#define SROM8_FEM_PDET_RANGE_MASK 0x00f8 -#define SROM8_FEM_PDET_RANGE_SHIFT 3 -#define SROM8_FEM_EXTPA_GAIN_MASK 0x0006 -#define SROM8_FEM_EXTPA_GAIN_SHIFT 1 -#define SROM8_FEM_TSSIPOS_MASK 0x0001 -#define SROM8_FEM_TSSIPOS_SHIFT 0 - -#define SROM8_THERMAL 89 - -/* Temp sense related entries */ -#define SROM8_MPWR_RAWTS 90 -#define SROM8_TS_SLP_OPT_CORRX 91 -/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */ -#define SROM8_FOC_HWIQ_IQSWP 92 - -/* Temperature delta for PHY calibration */ -#define SROM8_PHYCAL_TEMPDELTA 93 - -/* Per-path offsets & fields */ -#define SROM8_PATH0 96 -#define SROM8_PATH1 112 -#define SROM8_PATH2 128 -#define SROM8_PATH3 144 - -#define SROM8_2G_ITT_MAXP 0 -#define SROM8_2G_PA 1 -#define SROM8_5G_ITT_MAXP 4 -#define SROM8_5GLH_MAXP 5 -#define SROM8_5G_PA 6 -#define SROM8_5GL_PA 9 -#define SROM8_5GH_PA 12 - -/* All the miriad power offsets */ -#define SROM8_2G_CCKPO 160 - -#define SROM8_2G_OFDMPO 161 -#define SROM8_5G_OFDMPO 163 -#define SROM8_5GL_OFDMPO 165 -#define SROM8_5GH_OFDMPO 167 - -#define SROM8_2G_MCSPO 169 -#define SROM8_5G_MCSPO 177 -#define SROM8_5GL_MCSPO 185 -#define SROM8_5GH_MCSPO 193 - -#define SROM8_CDDPO 201 -#define SROM8_STBCPO 202 -#define SROM8_BW40PO 203 -#define SROM8_BWDUPPO 204 - -/* SISO PA parameters are in the path0 spaces */ -#define SROM8_SISO 96 - -/* Legacy names for SISO PA paramters */ -#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP) -#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA) -#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1) -#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2) -#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP) -#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP) -#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA) -#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1) -#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2) -#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA) -#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1) -#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2) -#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA) -#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1) -#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2) - -#define SROM8_CRCREV 219 - -/* SROM REV 9 */ -#define SROM9_2GPO_CCKBW20 160 -#define SROM9_2GPO_CCKBW20UL 161 -#define SROM9_2GPO_LOFDMBW20 162 -#define SROM9_2GPO_LOFDMBW20UL 164 - -#define SROM9_5GLPO_LOFDMBW20 166 -#define SROM9_5GLPO_LOFDMBW20UL 168 -#define SROM9_5GMPO_LOFDMBW20 170 -#define SROM9_5GMPO_LOFDMBW20UL 172 -#define SROM9_5GHPO_LOFDMBW20 174 -#define SROM9_5GHPO_LOFDMBW20UL 176 - -#define SROM9_2GPO_MCSBW20 178 -#define SROM9_2GPO_MCSBW20UL 180 -#define SROM9_2GPO_MCSBW40 182 - -#define SROM9_5GLPO_MCSBW20 184 -#define SROM9_5GLPO_MCSBW20UL 186 -#define SROM9_5GLPO_MCSBW40 188 -#define SROM9_5GMPO_MCSBW20 190 -#define SROM9_5GMPO_MCSBW20UL 192 -#define SROM9_5GMPO_MCSBW40 194 -#define SROM9_5GHPO_MCSBW20 196 -#define SROM9_5GHPO_MCSBW20UL 198 -#define SROM9_5GHPO_MCSBW40 200 - -#define SROM9_PO_MCS32 202 -#define SROM9_PO_LOFDM40DUP 203 - -#define SROM9_REV_CRC 219 - -typedef struct { - u8 tssipos; /* TSSI positive slope, 1: positive, 0: negative */ - u8 extpagain; /* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */ - u8 pdetrange; /* support 32 combinations of different Pdet dynamic ranges */ - u8 triso; /* TR switch isolation */ - u8 antswctrllut; /* antswctrl lookup table configuration: 32 possible choices */ -} srom_fem_t; - -#endif /* _bcmsrom_fmt_h_ */ diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h deleted file mode 100644 index 17683f2f785f..000000000000 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _bcmutils_h_ -#define _bcmutils_h_ - -/* Buffer structure for collecting string-formatted data -* using bcm_bprintf() API. -* Use bcm_binit() to initialize before use -*/ - - struct bcmstrbuf { - char *buf; /* pointer to current position in origbuf */ - unsigned int size; /* current (residual) size in bytes */ - char *origbuf; /* unmodified pointer to orignal buffer */ - unsigned int origsize; /* unmodified orignal buffer size in bytes */ - }; - -/* ** driver-only section ** */ - -#define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */ - -/* - * Spin at most 'us' microseconds while 'exp' is true. - * Caller should explicitly test 'exp' when this completes - * and take appropriate error action if 'exp' is still true. - */ -#define SPINWAIT(exp, us) { \ - uint countdown = (us) + 9; \ - while ((exp) && (countdown >= 10)) {\ - udelay(10); \ - countdown -= 10; \ - } \ -} - -/* osl multi-precedence packet queue */ -#ifndef PKTQ_LEN_DEFAULT -#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ -#endif -#ifndef PKTQ_MAX_PREC -#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ -#endif - - struct pktq_prec { - struct sk_buff *head; /* first packet to dequeue */ - struct sk_buff *tail; /* last packet to dequeue */ - u16 len; /* number of queued packets */ - u16 max; /* maximum number of queued packets */ - }; - -/* multi-priority pkt queue */ - struct pktq { - u16 num_prec; /* number of precedences in use */ - u16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ - u16 max; /* total max packets */ - u16 len; /* total number of packets */ - /* q array must be last since # of elements can be either PKTQ_MAX_PREC or 1 */ - struct pktq_prec q[PKTQ_MAX_PREC]; - }; - -#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) - -/* fn(pkt, arg). return true if pkt belongs to if */ -typedef bool(*ifpkt_cb_t) (struct sk_buff *, void *); - -/* operations on a specific precedence in packet queue */ - -#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) -#define pktq_plen(pq, prec) ((pq)->q[prec].len) -#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) -#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) -#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) - -#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) -#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) - -extern struct sk_buff *bcm_pktq_penq(struct pktq *pq, int prec, - struct sk_buff *p); -extern struct sk_buff *bcm_pktq_penq_head(struct pktq *pq, int prec, - struct sk_buff *p); -extern struct sk_buff *bcm_pktq_pdeq(struct pktq *pq, int prec); -extern struct sk_buff *bcm_pktq_pdeq_tail(struct pktq *pq, int prec); - -/* packet primitives */ -extern struct sk_buff *bcm_pkt_buf_get_skb(uint len); -extern void bcm_pkt_buf_free_skb(struct sk_buff *skb); - -/* Empty the queue at particular precedence level */ -extern void bcm_pktq_pflush(struct pktq *pq, int prec, - bool dir, ifpkt_cb_t fn, void *arg); - -/* operations on a set of precedences in packet queue */ - -extern int bcm_pktq_mlen(struct pktq *pq, uint prec_bmp); -extern struct sk_buff *bcm_pktq_mdeq(struct pktq *pq, uint prec_bmp, - int *prec_out); - -/* operations on packet queue as a whole */ - -#define pktq_len(pq) ((int)(pq)->len) -#define pktq_max(pq) ((int)(pq)->max) -#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) -#define pktq_full(pq) ((pq)->len >= (pq)->max) -#define pktq_empty(pq) ((pq)->len == 0) - -/* operations for single precedence queues */ -#define pktenq(pq, p) bcm_pktq_penq(((struct pktq *)pq), 0, (p)) -#define pktenq_head(pq, p) bcm_pktq_penq_head(((struct pktq *)pq), 0, (p)) -#define pktdeq(pq) bcm_pktq_pdeq(((struct pktq *)pq), 0) -#define pktdeq_tail(pq) bcm_pktq_pdeq_tail(((struct pktq *)pq), 0) -#define pktqinit(pq, len) bcm_pktq_init(((struct pktq *)pq), 1, len) - -extern void bcm_pktq_init(struct pktq *pq, int num_prec, int max_len); -/* prec_out may be NULL if caller is not interested in return value */ -extern struct sk_buff *bcm_pktq_peek_tail(struct pktq *pq, int *prec_out); -extern void bcm_pktq_flush(struct pktq *pq, bool dir, - ifpkt_cb_t fn, void *arg); - -/* externs */ -/* packet */ -extern uint bcm_pktfrombuf(struct sk_buff *p, - uint offset, int len, unsigned char *buf); -extern uint bcm_pkttotlen(struct sk_buff *p); - -/* ethernet address */ -extern int bcm_ether_atoe(char *p, u8 *ea); - -/* ip address */ - struct ipv4_addr; - extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf); - -#ifdef BCMDBG -extern void bcm_prpkt(const char *msg, struct sk_buff *p0); -#else -#define bcm_prpkt(a, b) -#endif /* BCMDBG */ - -#define bcm_perf_enable() -#define bcmlog(fmt, a1, a2) -#define bcmdumplog(buf, size) (*buf = '\0') -#define bcmdumplogent(buf, idx) -1 - -#define bcmtslog(tstamp, fmt, a1, a2) -#define bcmprinttslogs() -#define bcmprinttstamp(us) - -/* Support for sharing code across in-driver iovar implementations. - * The intent is that a driver use this structure to map iovar names - * to its (private) iovar identifiers, and the lookup function to - * find the entry. Macros are provided to map ids and get/set actions - * into a single number space for a switch statement. - */ - -/* iovar structure */ - typedef struct bcm_iovar { - const char *name; /* name for lookup and display */ - u16 varid; /* id for switch */ - u16 flags; /* driver-specific flag bits */ - u16 type; /* base type of argument */ - u16 minlen; /* min length for buffer vars */ - } bcm_iovar_t; - -/* varid definitions are per-driver, may use these get/set bits */ - -/* IOVar action bits for id mapping */ -#define IOV_GET 0 /* Get an iovar */ -#define IOV_SET 1 /* Set an iovar */ - -/* Varid to actionid mapping */ -#define IOV_GVAL(id) ((id)*2) -#define IOV_SVAL(id) (((id)*2)+IOV_SET) -#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET) -#define IOV_ID(actionid) (actionid >> 1) - -/* flags are per-driver based on driver attributes */ - - extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, - const char *name); - extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, - int len, bool set); - -/* Base type definitions */ -#define IOVT_VOID 0 /* no value (implictly set only) */ -#define IOVT_BOOL 1 /* any value ok (zero/nonzero) */ -#define IOVT_INT8 2 /* integer values are range-checked */ -#define IOVT_UINT8 3 /* unsigned int 8 bits */ -#define IOVT_INT16 4 /* int 16 bits */ -#define IOVT_UINT16 5 /* unsigned int 16 bits */ -#define IOVT_INT32 6 /* int 32 bits */ -#define IOVT_UINT32 7 /* unsigned int 32 bits */ -#define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */ -#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER) - -/* Initializer for IOV type strings */ -#define BCM_IOV_TYPE_INIT { \ - "void", \ - "bool", \ - "s8", \ - "u8", \ - "s16", \ - "u16", \ - "s32", \ - "u32", \ - "buffer", \ - "" } - -#define BCM_IOVT_IS_INT(type) (\ - (type == IOVT_BOOL) || \ - (type == IOVT_INT8) || \ - (type == IOVT_UINT8) || \ - (type == IOVT_INT16) || \ - (type == IOVT_UINT16) || \ - (type == IOVT_INT32) || \ - (type == IOVT_UINT32)) - -/* ** driver/apps-shared section ** */ - -#define BCME_STRLEN 64 /* Max string length for BCM errors */ - -#ifndef ABS -#define ABS(a) (((a) < 0) ? -(a) : (a)) -#endif /* ABS */ - -#define CEIL(x, y) (((x) + ((y)-1)) / (y)) -#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0) - -/* map physical to virtual I/O */ -#if !defined(CONFIG_MMC_MSM7X00A) -#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), \ - (unsigned long)(size)) -#else -#define REG_MAP(pa, size) (void *)(0) -#endif - -/* register access macros */ -#if defined(BCMSDIO) -#ifdef BRCM_FULLMAC -#include -#endif -#define OSL_WRITE_REG(r, v) \ - (bcmsdh_reg_write(NULL, (unsigned long)(r), sizeof(*(r)), (v))) -#define OSL_READ_REG(r) \ - (bcmsdh_reg_read(NULL, (unsigned long)(r), sizeof(*(r)))) -#endif - -#if defined(BCMSDIO) -#define SELECT_BUS_WRITE(mmap_op, bus_op) bus_op -#define SELECT_BUS_READ(mmap_op, bus_op) bus_op -#else -#define SELECT_BUS_WRITE(mmap_op, bus_op) mmap_op -#define SELECT_BUS_READ(mmap_op, bus_op) mmap_op -#endif - -/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ -#define PKTBUFSZ 2048 - -#define OSL_SYSUPTIME() ((u32)jiffies * (1000 / HZ)) -#ifdef BRCM_FULLMAC -#include /* for vsn/printf's */ -#include /* for mem*, str* */ -#endif -/* bcopy's: Linux kernel doesn't provide these (anymore) */ -#define bcopy(src, dst, len) memcpy((dst), (src), (len)) - -/* register access macros */ -#ifndef __BIG_ENDIAN -#ifndef __mips__ -#define R_REG(r) (\ - SELECT_BUS_READ(sizeof(*(r)) == sizeof(u8) ? \ - readb((volatile u8*)(r)) : \ - sizeof(*(r)) == sizeof(u16) ? readw((volatile u16*)(r)) : \ - readl((volatile u32*)(r)), OSL_READ_REG(r)) \ -) -#else /* __mips__ */ -#define R_REG(r) (\ - SELECT_BUS_READ( \ - ({ \ - __typeof(*(r)) __osl_v; \ - __asm__ __volatile__("sync"); \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - __osl_v = readb((volatile u8*)(r)); \ - break; \ - case sizeof(u16): \ - __osl_v = readw((volatile u16*)(r)); \ - break; \ - case sizeof(u32): \ - __osl_v = \ - readl((volatile u32*)(r)); \ - break; \ - } \ - __asm__ __volatile__("sync"); \ - __osl_v; \ - }), \ - ({ \ - __typeof(*(r)) __osl_v; \ - __asm__ __volatile__("sync"); \ - __osl_v = OSL_READ_REG(r); \ - __asm__ __volatile__("sync"); \ - __osl_v; \ - })) \ -) -#endif /* __mips__ */ - -#define W_REG(r, v) do { \ - SELECT_BUS_WRITE( \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - writeb((u8)(v), (volatile u8*)(r)); break; \ - case sizeof(u16): \ - writew((u16)(v), (volatile u16*)(r)); break; \ - case sizeof(u32): \ - writel((u32)(v), (volatile u32*)(r)); break; \ - }, \ - (OSL_WRITE_REG(r, v))); \ - } while (0) -#else /* __BIG_ENDIAN */ -#define R_REG(r) (\ - SELECT_BUS_READ( \ - ({ \ - __typeof(*(r)) __osl_v; \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - __osl_v = \ - readb((volatile u8*)((r)^3)); \ - break; \ - case sizeof(u16): \ - __osl_v = \ - readw((volatile u16*)((r)^2)); \ - break; \ - case sizeof(u32): \ - __osl_v = readl((volatile u32*)(r)); \ - break; \ - } \ - __osl_v; \ - }), \ - OSL_READ_REG(r)) \ -) -#define W_REG(r, v) do { \ - SELECT_BUS_WRITE( \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - writeb((u8)(v), \ - (volatile u8*)((r)^3)); break; \ - case sizeof(u16): \ - writew((u16)(v), \ - (volatile u16*)((r)^2)); break; \ - case sizeof(u32): \ - writel((u32)(v), \ - (volatile u32*)(r)); break; \ - }, \ - (OSL_WRITE_REG(r, v))); \ - } while (0) -#endif /* __BIG_ENDIAN */ - -#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) -#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) - -#define SET_REG(r, mask, val) \ - W_REG((r), ((R_REG(r) & ~(mask)) | (val))) - -#ifndef setbit -#ifndef NBBY /* the BSD family defines NBBY */ -#define NBBY 8 /* 8 bits per byte */ -#endif /* #ifndef NBBY */ -#define setbit(a, i) (((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) -#define clrbit(a, i) (((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) -#define isset(a, i) (((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) -#define isclr(a, i) ((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) -#endif /* setbit */ - -#define NBITS(type) (sizeof(type) * 8) -#define NBITVAL(nbits) (1 << (nbits)) -#define MAXBITVAL(nbits) ((1 << (nbits)) - 1) -#define NBITMASK(nbits) MAXBITVAL(nbits) -#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) - -/* basic mux operation - can be optimized on several architectures */ -#define MUX(pred, true, false) ((pred) ? (true) : (false)) - -/* modulo inc/dec - assumes x E [0, bound - 1] */ -#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1) -#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1) - -/* modulo inc/dec, bound = 2^k */ -#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1)) -#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1)) - -/* modulo add/sub - assumes x, y E [0, bound - 1] */ -#define MODADD(x, y, bound) \ - MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y)) -#define MODSUB(x, y, bound) \ - MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y)) - -/* module add/sub, bound = 2^k */ -#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1)) -#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) - -/* crc defines */ -#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ -#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ -#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ -#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ - -/* bcm_format_flags() bit description structure */ - typedef struct bcm_bit_desc { - u32 bit; - const char *name; - } bcm_bit_desc_t; - -/* tag_ID/length/value_buffer tuple */ - typedef struct bcm_tlv { - u8 id; - u8 len; - u8 data[1]; - } bcm_tlv_t; - -/* Check that bcm_tlv_t fits into the given buflen */ -#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) - -#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */ - -/* crypto utility function */ -/* 128-bit xor: *dst = *src1 xor *src2. dst1, src1 and src2 may have any alignment */ - static inline void - xor_128bit_block(const u8 *src1, const u8 *src2, u8 *dst) { - if ( -#ifdef __i386__ - 1 || -#endif - (((unsigned long) src1 | (unsigned long) src2 | (unsigned long) dst) & - 3) == 0) { - /* ARM CM3 rel time: 1229 (727 if alignment check could be omitted) */ - /* x86 supports unaligned. This version runs 6x-9x faster on x86. */ - ((u32 *) dst)[0] = - ((const u32 *)src1)[0] ^ ((const u32 *) - src2)[0]; - ((u32 *) dst)[1] = - ((const u32 *)src1)[1] ^ ((const u32 *) - src2)[1]; - ((u32 *) dst)[2] = - ((const u32 *)src1)[2] ^ ((const u32 *) - src2)[2]; - ((u32 *) dst)[3] = - ((const u32 *)src1)[3] ^ ((const u32 *) - src2)[3]; - } else { - /* ARM CM3 rel time: 4668 (4191 if alignment check could be omitted) */ - int k; - for (k = 0; k < 16; k++) - dst[k] = src1[k] ^ src2[k]; - } - } - -/* externs */ -/* crc */ -extern u8 bcm_crc8(u8 *p, uint nbytes, u8 crc); -/* format/print */ -#if defined(BCMDBG) - extern int bcm_format_flags(const bcm_bit_desc_t *bd, u32 flags, - char *buf, int len); - extern int bcm_format_hex(char *str, const void *bytes, int len); -#endif - extern char *bcm_chipname(uint chipid, char *buf, uint len); - - extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, - uint key); - -/* multi-bool data type: set of bools, mbool is true if any is set */ - typedef u32 mbool; -#define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */ -#define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */ -#define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* true if one bool is set */ -#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) - -/* power conversion */ - extern u16 bcm_qdbm_to_mw(u8 qdbm); - extern u8 bcm_mw_to_qdbm(u16 mw); - - extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size); - extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); - - extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, - uint len); - extern uint bcm_bitcount(u8 *bitmap, uint bytelength); - -#endif /* _bcmutils_h_ */ diff --git a/drivers/staging/brcm80211/include/brcm_hw_ids.h b/drivers/staging/brcm80211/include/brcm_hw_ids.h new file mode 100644 index 000000000000..5fb17d53c9b2 --- /dev/null +++ b/drivers/staging/brcm80211/include/brcm_hw_ids.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BRCM_HW_IDS_H_ +#define _BRCM_HW_IDS_H_ + +#define BCM4325_D11DUAL_ID 0x431b +#define BCM4325_D11G_ID 0x431c +#define BCM4325_D11A_ID 0x431d + +#define BCM4329_D11N2G_ID 0x432f /* 4329 802.11n 2.4G device */ +#define BCM4329_D11N5G_ID 0x4330 /* 4329 802.11n 5G device */ +#define BCM4329_D11NDUAL_ID 0x432e + +#define BCM4319_D11N_ID 0x4337 /* 4319 802.11n dualband device */ +#define BCM4319_D11N2G_ID 0x4338 /* 4319 802.11n 2.4G device */ +#define BCM4319_D11N5G_ID 0x4339 /* 4319 802.11n 5G device */ + +#define BCM43224_D11N_ID 0x4353 /* 43224 802.11n dualband device */ +#define BCM43224_D11N_ID_VEN1 0x0576 /* Vendor specific 43224 802.11n db */ + +#define BCM43225_D11N2G_ID 0x4357 /* 43225 802.11n 2.4GHz device */ + +#define BCM43236_D11N_ID 0x4346 /* 43236 802.11n dualband device */ +#define BCM43236_D11N2G_ID 0x4347 /* 43236 802.11n 2.4GHz device */ + +#define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */ + +/* Chip IDs */ +#define BCM4313_CHIP_ID 0x4313 /* 4313 chip id */ +#define BCM4319_CHIP_ID 0x4319 /* 4319 chip id */ + +#define BCM43224_CHIP_ID 43224 /* 43224 chipcommon chipid */ +#define BCM43225_CHIP_ID 43225 /* 43225 chipcommon chipid */ +#define BCM43421_CHIP_ID 43421 /* 43421 chipcommon chipid */ +#define BCM43235_CHIP_ID 43235 /* 43235 chipcommon chipid */ +#define BCM43236_CHIP_ID 43236 /* 43236 chipcommon chipid */ +#define BCM43238_CHIP_ID 43238 /* 43238 chipcommon chipid */ +#define BCM4329_CHIP_ID 0x4329 /* 4329 chipcommon chipid */ +#define BCM4325_CHIP_ID 0x4325 /* 4325 chipcommon chipid */ +#define BCM4331_CHIP_ID 0x4331 /* 4331 chipcommon chipid */ +#define BCM4336_CHIP_ID 0x4336 /* 4336 chipcommon chipid */ +#define BCM4330_CHIP_ID 0x4330 /* 4330 chipcommon chipid */ +#define BCM6362_CHIP_ID 0x6362 /* 6362 chipcommon chipid */ + +#endif /* _BRCM_HW_IDS_H_ */ diff --git a/drivers/staging/brcm80211/include/brcmu_utils.h b/drivers/staging/brcm80211/include/brcmu_utils.h new file mode 100644 index 000000000000..2d54cc5f4b11 --- /dev/null +++ b/drivers/staging/brcm80211/include/brcmu_utils.h @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BRCMU_UTILS_H_ +#define _BRCMU_UTILS_H_ + +#include + +/* Buffer structure for collecting string-formatted data +* using brcmu_bprintf() API. +* Use brcmu_binit() to initialize before use +*/ + +struct brcmu_strbuf { + char *buf; /* pointer to current position in origbuf */ + unsigned int size; /* current (residual) size in bytes */ + char *origbuf; /* unmodified pointer to orignal buffer */ + unsigned int origsize; /* unmodified orignal buffer size in bytes */ +}; + +/* + * Spin at most 'us' microseconds while 'exp' is true. + * Caller should explicitly test 'exp' when this completes + * and take appropriate error action if 'exp' is still true. + */ +#define SPINWAIT(exp, us) { \ + uint countdown = (us) + 9; \ + while ((exp) && (countdown >= 10)) {\ + udelay(10); \ + countdown -= 10; \ + } \ +} + +/* osl multi-precedence packet queue */ +#ifndef PKTQ_LEN_DEFAULT +#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ +#endif +#ifndef PKTQ_MAX_PREC +#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ +#endif + +struct pktq_prec { + struct sk_buff *head; /* first packet to dequeue */ + struct sk_buff *tail; /* last packet to dequeue */ + u16 len; /* number of queued packets */ + u16 max; /* maximum number of queued packets */ +}; + +/* multi-priority pkt queue */ +struct pktq { + u16 num_prec; /* number of precedences in use */ + u16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ + u16 max; /* total max packets */ + u16 len; /* total number of packets */ + /* + * q array must be last since # of elements can be either + * PKTQ_MAX_PREC or 1 + */ + struct pktq_prec q[PKTQ_MAX_PREC]; +}; + +/* fn(pkt, arg). return true if pkt belongs to if */ +typedef bool(*ifpkt_cb_t) (struct sk_buff *, void *); + +/* operations on a specific precedence in packet queue */ + +#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) +#define pktq_plen(pq, prec) ((pq)->q[prec].len) +#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) +#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) +#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) + +#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) +#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) + +extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, + struct sk_buff *p); +extern struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, + struct sk_buff *p); +extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec); +extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec); + +/* packet primitives */ +extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len); +extern void brcmu_pkt_buf_free_skb(struct sk_buff *skb); + +/* Empty the queue at particular precedence level */ +extern void brcmu_pktq_pflush(struct pktq *pq, int prec, + bool dir, ifpkt_cb_t fn, void *arg); + +/* operations on a set of precedences in packet queue */ + +extern int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp); +extern struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, + int *prec_out); + +/* operations on packet queue as a whole */ + +#define pktq_len(pq) ((int)(pq)->len) +#define pktq_max(pq) ((int)(pq)->max) +#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) +#define pktq_full(pq) ((pq)->len >= (pq)->max) +#define pktq_empty(pq) ((pq)->len == 0) + +/* operations for single precedence queues */ +#define pktenq(pq, p) brcmu_pktq_penq(((struct pktq *)pq), 0, (p)) +#define pktenq_head(pq, p)\ + brcmu_pktq_penq_head(((struct pktq *)pq), 0, (p)) +#define pktdeq(pq) brcmu_pktq_pdeq(((struct pktq *)pq), 0) +#define pktdeq_tail(pq) brcmu_pktq_pdeq_tail(((struct pktq *)pq), 0) +#define pktqinit(pq, len) brcmu_pktq_init(((struct pktq *)pq), 1, len) + +extern void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len); +/* prec_out may be NULL if caller is not interested in return value */ +extern struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out); +extern void brcmu_pktq_flush(struct pktq *pq, bool dir, + ifpkt_cb_t fn, void *arg); + +/* externs */ +/* packet */ +extern uint brcmu_pktfrombuf(struct sk_buff *p, + uint offset, int len, unsigned char *buf); +extern uint brcmu_pkttotlen(struct sk_buff *p); + +/* ethernet address */ +extern int brcmu_ether_atoe(char *p, u8 *ea); + +/* ip address */ +struct ipv4_addr; + +#ifdef BCMDBG +extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); +#else +#define brcmu_prpkt(a, b) +#endif /* BCMDBG */ + +/* Support for sharing code across in-driver iovar implementations. + * The intent is that a driver use this structure to map iovar names + * to its (private) iovar identifiers, and the lookup function to + * find the entry. Macros are provided to map ids and get/set actions + * into a single number space for a switch statement. + */ + +/* iovar structure */ +struct brcmu_iovar { + const char *name; /* name for lookup and display */ + u16 varid; /* id for switch */ + u16 flags; /* driver-specific flag bits */ + u16 type; /* base type of argument */ + u16 minlen; /* min length for buffer vars */ +}; + +/* varid definitions are per-driver, may use these get/set bits */ + +/* IOVar action bits for id mapping */ +#define IOV_GET 0 /* Get an iovar */ +#define IOV_SET 1 /* Set an iovar */ + +/* Varid to actionid mapping */ +#define IOV_GVAL(id) ((id)*2) +#define IOV_SVAL(id) (((id)*2)+IOV_SET) +#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET) +#define IOV_ID(actionid) (actionid >> 1) + +extern const struct +brcmu_iovar *brcmu_iovar_lookup(const struct brcmu_iovar *table, + const char *name); +extern int brcmu_iovar_lencheck(const struct brcmu_iovar *table, void *arg, + int len, bool set); + +/* Base type definitions */ +#define IOVT_VOID 0 /* no value (implictly set only) */ +#define IOVT_BOOL 1 /* any value ok (zero/nonzero) */ +#define IOVT_INT8 2 /* integer values are range-checked */ +#define IOVT_UINT8 3 /* unsigned int 8 bits */ +#define IOVT_INT16 4 /* int 16 bits */ +#define IOVT_UINT16 5 /* unsigned int 16 bits */ +#define IOVT_INT32 6 /* int 32 bits */ +#define IOVT_UINT32 7 /* unsigned int 32 bits */ +#define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */ +#define BCM_IOVT_VALID(type) (((unsigned int)(type)) <= IOVT_BUFFER) + +/* ** driver/apps-shared section ** */ + +#define BCME_STRLEN 64 /* Max string length for BCM errors */ + +#ifndef ABS +#define ABS(a) (((a) < 0) ? -(a) : (a)) +#endif /* ABS */ + +#define CEIL(x, y) (((x) + ((y)-1)) / (y)) +#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0) + +/* map physical to virtual I/O */ +#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), \ + (unsigned long)(size)) + +/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ +#define PKTBUFSZ 2048 + +#define OSL_SYSUPTIME() ((u32)jiffies * (1000 / HZ)) + +#ifndef setbit +#ifndef NBBY /* the BSD family defines NBBY */ +#define NBBY 8 /* 8 bits per byte */ +#endif /* #ifndef NBBY */ +#define setbit(a, i) (((u8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) +#define clrbit(a, i) (((u8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) +#define isset(a, i) (((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) +#define isclr(a, i) ((((const u8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) +#endif /* setbit */ + +#define NBITS(type) (sizeof(type) * 8) +#define NBITVAL(nbits) (1 << (nbits)) +#define MAXBITVAL(nbits) ((1 << (nbits)) - 1) +#define NBITMASK(nbits) MAXBITVAL(nbits) +#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) + +/* basic mux operation - can be optimized on several architectures */ +#define MUX(pred, true, false) ((pred) ? (true) : (false)) + +/* modulo inc/dec - assumes x E [0, bound - 1] */ +#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1) +#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1) + +/* modulo inc/dec, bound = 2^k */ +#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1)) +#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1)) + +/* modulo add/sub - assumes x, y E [0, bound - 1] */ +#define MODADD(x, y, bound) \ + MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y)) +#define MODSUB(x, y, bound) \ + MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y)) + +/* module add/sub, bound = 2^k */ +#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1)) +#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) + +/* crc defines */ +#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ +#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ +#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ +#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ + +/* brcmu_format_flags() bit description structure */ +struct brcmu_bit_desc { + u32 bit; + const char *name; +}; + +/* tag_ID/length/value_buffer tuple */ +struct brcmu_tlv { + u8 id; + u8 len; + u8 data[1]; +}; + +#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */ + +/* externs */ +/* crc */ +extern u8 brcmu_crc8(u8 *p, uint nbytes, u8 crc); + +/* format/print */ +#if defined(BCMDBG) +extern int brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags, + char *buf, int len); +extern int brcmu_format_hex(char *str, const void *bytes, int len); +#endif + +extern char *brcmu_chipname(uint chipid, char *buf, uint len); + +extern struct brcmu_tlv *brcmu_parse_tlvs(void *buf, int buflen, + uint key); + +/* power conversion */ +extern u16 brcmu_qdbm_to_mw(u8 qdbm); +extern u8 brcmu_mw_to_qdbm(u16 mw); + +extern void brcmu_binit(struct brcmu_strbuf *b, char *buf, uint size); +extern int brcmu_bprintf(struct brcmu_strbuf *b, const char *fmt, ...); + +extern uint brcmu_mkiovar(char *name, char *data, uint datalen, + char *buf, uint len); +extern uint brcmu_bitcount(u8 *bitmap, uint bytelength); + +#endif /* _BRCMU_UTILS_H_ */ diff --git a/drivers/staging/brcm80211/include/bcmwifi.h b/drivers/staging/brcm80211/include/brcmu_wifi.h similarity index 65% rename from drivers/staging/brcm80211/include/bcmwifi.h rename to drivers/staging/brcm80211/include/brcmu_wifi.h index a573ebff7680..fde592bd9177 100644 --- a/drivers/staging/brcm80211/include/bcmwifi.h +++ b/drivers/staging/brcm80211/include/brcmu_wifi.h @@ -14,8 +14,11 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef _bcmwifi_h_ -#define _bcmwifi_h_ +#ifndef _BRCMU_WIFI_H_ +#define _BRCMU_WIFI_H_ + +#include /* for ETH_ALEN */ +#include /* for WLAN_PMKID_LEN */ /* A chanspec holds the channel number, band, bandwidth and control sideband */ typedef u16 chanspec_t; @@ -28,7 +31,7 @@ typedef u16 chanspec_t; #define CH_10MHZ_APART 2 #define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ #define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ -#define WLC_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL /* legacy define */ +#define BRCM_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL /* legacy define */ #define MAXCHANNEL 224 /* max # supported channels. The max channel no is 216, * this is that + 1 rounded up to a multiple of NBBY (8). * DO NOT MAKE it > 255: channels are u8's all over @@ -64,7 +67,8 @@ typedef u16 chanspec_t; #define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0) #define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ ((channel) + CH_10MHZ_APART) : 0) -#define CHSPEC_WLCBANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) +#define CHSPEC_BANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : \ + BAND_2G_INDEX) #define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \ WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) @@ -107,26 +111,30 @@ typedef u16 chanspec_t; #define CHSPEC_CTL_CHAN(chspec) ((CHSPEC_SB_LOWER(chspec)) ? \ (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \ (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK)))) -#define CHSPEC2WLC_BAND(chspec) (CHSPEC_IS5G(chspec) ? WLC_BAND_5G : WLC_BAND_2G) +#define CHSPEC2BAND(chspec) (CHSPEC_IS5G(chspec) ? BRCM_BAND_5G : BRCM_BAND_2G) #define CHANSPEC_STR_LEN 8 /* defined rate in 500kbps */ -#define WLC_MAXRATE 108 /* in 500kbps units */ -#define WLC_RATE_1M 2 /* in 500kbps units */ -#define WLC_RATE_2M 4 /* in 500kbps units */ -#define WLC_RATE_5M5 11 /* in 500kbps units */ -#define WLC_RATE_11M 22 /* in 500kbps units */ -#define WLC_RATE_6M 12 /* in 500kbps units */ -#define WLC_RATE_9M 18 /* in 500kbps units */ -#define WLC_RATE_12M 24 /* in 500kbps units */ -#define WLC_RATE_18M 36 /* in 500kbps units */ -#define WLC_RATE_24M 48 /* in 500kbps units */ -#define WLC_RATE_36M 72 /* in 500kbps units */ -#define WLC_RATE_48M 96 /* in 500kbps units */ -#define WLC_RATE_54M 108 /* in 500kbps units */ +#define BRCM_MAXRATE 108 /* in 500kbps units */ +#define BRCM_RATE_1M 2 /* in 500kbps units */ +#define BRCM_RATE_2M 4 /* in 500kbps units */ +#define BRCM_RATE_5M5 11 /* in 500kbps units */ +#define BRCM_RATE_11M 22 /* in 500kbps units */ +#define BRCM_RATE_6M 12 /* in 500kbps units */ +#define BRCM_RATE_9M 18 /* in 500kbps units */ +#define BRCM_RATE_12M 24 /* in 500kbps units */ +#define BRCM_RATE_18M 36 /* in 500kbps units */ +#define BRCM_RATE_24M 48 /* in 500kbps units */ +#define BRCM_RATE_36M 72 /* in 500kbps units */ +#define BRCM_RATE_48M 96 /* in 500kbps units */ +#define BRCM_RATE_54M 108 /* in 500kbps units */ -#define WLC_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */ +#define BRCM_2G_25MHZ_OFFSET 5 /* 2.4GHz band channel offset */ + +#define MCSSET_LEN 16 + +#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) /* * Verify the chanspec is using a legal set of parameters, i.e. that the @@ -134,14 +142,14 @@ typedef u16 chanspec_t; * combination could be legal given any set of circumstances. * RETURNS: true is the chanspec is malformed, false if it looks good. */ -extern bool bcm_chspec_malformed(chanspec_t chanspec); +extern bool brcmu_chspec_malformed(chanspec_t chanspec); /* * This function returns the channel number that control traffic is being sent on, for legacy * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ * sideband depending on the chanspec selected */ -extern u8 bcm_chspec_ctlchan(chanspec_t chspec); +extern u8 brcmu_chspec_ctlchan(chanspec_t chspec); /* * Return the channel number for a given frequency and base frequency. @@ -162,6 +170,74 @@ extern u8 bcm_chspec_ctlchan(chanspec_t chspec); * * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2 */ -extern int bcm_mhz2channel(uint freq, uint start_factor); +extern int brcmu_mhz2channel(uint freq, uint start_factor); -#endif /* _bcmwifi_h_ */ +/* Enumerate crypto algorithms */ +#define CRYPTO_ALGO_OFF 0 +#define CRYPTO_ALGO_WEP1 1 +#define CRYPTO_ALGO_TKIP 2 +#define CRYPTO_ALGO_WEP128 3 +#define CRYPTO_ALGO_AES_CCM 4 +#define CRYPTO_ALGO_AES_RESERVED1 5 +#define CRYPTO_ALGO_AES_RESERVED2 6 +#define CRYPTO_ALGO_NALG 7 + +/* wireless security bitvec */ +#define WEP_ENABLED 0x0001 +#define TKIP_ENABLED 0x0002 +#define AES_ENABLED 0x0004 +#define WSEC_SWFLAG 0x0008 +#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ + +/* WPA authentication mode bitvec */ +#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ +#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */ +#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */ +#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ +#define WPA_AUTH_RESERVED1 0x0008 +#define WPA_AUTH_RESERVED2 0x0010 + /* #define WPA_AUTH_8021X 0x0020 *//* 802.1x, reserved */ +#define WPA2_AUTH_RESERVED1 0x0020 +#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ +#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ +#define WPA2_AUTH_RESERVED3 0x0200 +#define WPA2_AUTH_RESERVED4 0x0400 +#define WPA2_AUTH_RESERVED5 0x0800 + +/* pmkid */ +#define MAXPMKID 16 + +#define DOT11_DEFAULT_RTS_LEN 2347 +#define DOT11_DEFAULT_FRAG_LEN 2346 + +#define DOT11_ICV_AES_LEN 8 +#define DOT11_QOS_LEN 2 +#define DOT11_IV_MAX_LEN 8 +#define DOT11_A4_HDR_LEN 30 + +#define HT_CAP_RX_STBC_NO 0x0 +#define HT_CAP_RX_STBC_ONE_STREAM 0x1 + +typedef struct _pmkid { + u8 BSSID[ETH_ALEN]; + u8 PMKID[WLAN_PMKID_LEN]; +} pmkid_t; + +typedef struct _pmkid_list { + u32 npmkid; + pmkid_t pmkid[1]; +} pmkid_list_t; + +typedef struct _pmkid_cand { + u8 BSSID[ETH_ALEN]; + u8 preauth; +} pmkid_cand_t; + +typedef struct _pmkid_cand_list { + u32 npmkid_cand; + pmkid_cand_t pmkid_cand[1]; +} pmkid_cand_list_t; + +typedef u8 ac_bitmap_t; + +#endif /* _BRCMU_WIFI_H_ */ diff --git a/drivers/staging/brcm80211/include/chipcommon.h b/drivers/staging/brcm80211/include/chipcommon.h new file mode 100644 index 000000000000..296582aced69 --- /dev/null +++ b/drivers/staging/brcm80211/include/chipcommon.h @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SBCHIPC_H +#define _SBCHIPC_H + +#include "defs.h" /* for PAD macro */ + +typedef volatile struct { + u32 chipid; /* 0x0 */ + u32 capabilities; + u32 corecontrol; /* corerev >= 1 */ + u32 bist; + + /* OTP */ + u32 otpstatus; /* 0x10, corerev >= 10 */ + u32 otpcontrol; + u32 otpprog; + u32 otplayout; /* corerev >= 23 */ + + /* Interrupt control */ + u32 intstatus; /* 0x20 */ + u32 intmask; + + /* Chip specific regs */ + u32 chipcontrol; /* 0x28, rev >= 11 */ + u32 chipstatus; /* 0x2c, rev >= 11 */ + + /* Jtag Master */ + u32 jtagcmd; /* 0x30, rev >= 10 */ + u32 jtagir; + u32 jtagdr; + u32 jtagctrl; + + /* serial flash interface registers */ + u32 flashcontrol; /* 0x40 */ + u32 flashaddress; + u32 flashdata; + u32 PAD[1]; + + /* Silicon backplane configuration broadcast control */ + u32 broadcastaddress; /* 0x50 */ + u32 broadcastdata; + + /* gpio - cleared only by power-on-reset */ + u32 gpiopullup; /* 0x58, corerev >= 20 */ + u32 gpiopulldown; /* 0x5c, corerev >= 20 */ + u32 gpioin; /* 0x60 */ + u32 gpioout; /* 0x64 */ + u32 gpioouten; /* 0x68 */ + u32 gpiocontrol; /* 0x6C */ + u32 gpiointpolarity; /* 0x70 */ + u32 gpiointmask; /* 0x74 */ + + /* GPIO events corerev >= 11 */ + u32 gpioevent; + u32 gpioeventintmask; + + /* Watchdog timer */ + u32 watchdog; /* 0x80 */ + + /* GPIO events corerev >= 11 */ + u32 gpioeventintpolarity; + + /* GPIO based LED powersave registers corerev >= 16 */ + u32 gpiotimerval; /* 0x88 */ + u32 gpiotimeroutmask; + + /* clock control */ + u32 clockcontrol_n; /* 0x90 */ + u32 clockcontrol_sb; /* aka m0 */ + u32 clockcontrol_pci; /* aka m1 */ + u32 clockcontrol_m2; /* mii/uart/mipsref */ + u32 clockcontrol_m3; /* cpu */ + u32 clkdiv; /* corerev >= 3 */ + u32 gpiodebugsel; /* corerev >= 28 */ + u32 capabilities_ext; /* 0xac */ + + /* pll delay registers (corerev >= 4) */ + u32 pll_on_delay; /* 0xb0 */ + u32 fref_sel_delay; + u32 slow_clk_ctl; /* 5 < corerev < 10 */ + u32 PAD; + + /* Instaclock registers (corerev >= 10) */ + u32 system_clk_ctl; /* 0xc0 */ + u32 clkstatestretch; + u32 PAD[2]; + + /* Indirect backplane access (corerev >= 22) */ + u32 bp_addrlow; /* 0xd0 */ + u32 bp_addrhigh; + u32 bp_data; + u32 PAD; + u32 bp_indaccess; + u32 PAD[3]; + + /* More clock dividers (corerev >= 32) */ + u32 clkdiv2; + u32 PAD[2]; + + /* In AI chips, pointer to erom */ + u32 eromptr; /* 0xfc */ + + /* ExtBus control registers (corerev >= 3) */ + u32 pcmcia_config; /* 0x100 */ + u32 pcmcia_memwait; + u32 pcmcia_attrwait; + u32 pcmcia_iowait; + u32 ide_config; + u32 ide_memwait; + u32 ide_attrwait; + u32 ide_iowait; + u32 prog_config; + u32 prog_waitcount; + u32 flash_config; + u32 flash_waitcount; + u32 SECI_config; /* 0x130 SECI configuration */ + u32 PAD[3]; + + /* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */ + u32 eci_output; /* 0x140 */ + u32 eci_control; + u32 eci_inputlo; + u32 eci_inputmi; + u32 eci_inputhi; + u32 eci_inputintpolaritylo; + u32 eci_inputintpolaritymi; + u32 eci_inputintpolarityhi; + u32 eci_intmasklo; + u32 eci_intmaskmi; + u32 eci_intmaskhi; + u32 eci_eventlo; + u32 eci_eventmi; + u32 eci_eventhi; + u32 eci_eventmasklo; + u32 eci_eventmaskmi; + u32 eci_eventmaskhi; + u32 PAD[3]; + + /* SROM interface (corerev >= 32) */ + u32 sromcontrol; /* 0x190 */ + u32 sromaddress; + u32 sromdata; + u32 PAD[17]; + + /* Clock control and hardware workarounds (corerev >= 20) */ + u32 clk_ctl_st; /* 0x1e0 */ + u32 hw_war; + u32 PAD[70]; + + /* UARTs */ + u8 uart0data; /* 0x300 */ + u8 uart0imr; + u8 uart0fcr; + u8 uart0lcr; + u8 uart0mcr; + u8 uart0lsr; + u8 uart0msr; + u8 uart0scratch; + u8 PAD[248]; /* corerev >= 1 */ + + u8 uart1data; /* 0x400 */ + u8 uart1imr; + u8 uart1fcr; + u8 uart1lcr; + u8 uart1mcr; + u8 uart1lsr; + u8 uart1msr; + u8 uart1scratch; + u32 PAD[126]; + + /* PMU registers (corerev >= 20) */ + u32 pmucontrol; /* 0x600 */ + u32 pmucapabilities; + u32 pmustatus; + u32 res_state; + u32 res_pending; + u32 pmutimer; + u32 min_res_mask; + u32 max_res_mask; + u32 res_table_sel; + u32 res_dep_mask; + u32 res_updn_timer; + u32 res_timer; + u32 clkstretch; + u32 pmuwatchdog; + u32 gpiosel; /* 0x638, rev >= 1 */ + u32 gpioenable; /* 0x63c, rev >= 1 */ + u32 res_req_timer_sel; + u32 res_req_timer; + u32 res_req_mask; + u32 PAD; + u32 chipcontrol_addr; /* 0x650 */ + u32 chipcontrol_data; /* 0x654 */ + u32 regcontrol_addr; + u32 regcontrol_data; + u32 pllcontrol_addr; + u32 pllcontrol_data; + u32 pmustrapopt; /* 0x668, corerev >= 28 */ + u32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */ + u32 PAD[100]; + u16 sromotp[768]; +} chipcregs_t; + +/* chipid */ +#define CID_ID_MASK 0x0000ffff /* Chip Id mask */ +#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */ +#define CID_REV_SHIFT 16 /* Chip Revision shift */ +#define CID_PKG_MASK 0x00f00000 /* Package Option mask */ +#define CID_PKG_SHIFT 20 /* Package Option shift */ +#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */ +#define CID_CC_SHIFT 24 +#define CID_TYPE_MASK 0xf0000000 /* Chip Type */ +#define CID_TYPE_SHIFT 28 + +/* capabilities */ +#define CC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */ +#define CC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */ +#define CC_CAP_UCLKSEL 0x00000018 /* UARTs clock select */ +#define CC_CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */ +#define CC_CAP_UARTGPIO 0x00000020 /* UARTs own GPIOs 15:12 */ +#define CC_CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */ +#define CC_CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */ +#define CC_CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */ +#define CC_CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */ +#define CC_CAP_FLASH_MASK 0x00000700 /* Type of flash */ +#define CC_CAP_PLL_MASK 0x00038000 /* Type of PLL */ +#define CC_CAP_PWR_CTL 0x00040000 /* Power control */ +#define CC_CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */ +#define CC_CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */ +#define CC_CAP_OTPSIZE_BASE 5 /* OTP Size base */ +#define CC_CAP_JTAGP 0x00400000 /* JTAG Master Present */ +#define CC_CAP_ROM 0x00800000 /* Internal boot rom active */ +#define CC_CAP_BKPLN64 0x08000000 /* 64-bit backplane */ +#define CC_CAP_PMU 0x10000000 /* PMU Present, rev >= 20 */ +#define CC_CAP_SROM 0x40000000 /* Srom Present, rev >= 32 */ +#define CC_CAP_NFLASH 0x80000000 /* Nand flash present, rev >= 35 */ + +#define CC_CAP2_SECI 0x00000001 /* SECI Present, rev >= 36 */ +#define CC_CAP2_GSIO 0x00000002 /* GSIO (spi/i2c) present, rev >= 37 */ + +/* pmucapabilities */ +#define PCAP_REV_MASK 0x000000ff +#define PCAP_RC_MASK 0x00001f00 +#define PCAP_RC_SHIFT 8 +#define PCAP_TC_MASK 0x0001e000 +#define PCAP_TC_SHIFT 13 +#define PCAP_PC_MASK 0x001e0000 +#define PCAP_PC_SHIFT 17 +#define PCAP_VC_MASK 0x01e00000 +#define PCAP_VC_SHIFT 21 +#define PCAP_CC_MASK 0x1e000000 +#define PCAP_CC_SHIFT 25 +#define PCAP5_PC_MASK 0x003e0000 /* PMU corerev >= 5 */ +#define PCAP5_PC_SHIFT 17 +#define PCAP5_VC_MASK 0x07c00000 +#define PCAP5_VC_SHIFT 22 +#define PCAP5_CC_MASK 0xf8000000 +#define PCAP5_CC_SHIFT 27 + +/* +* Maximum delay for the PMU state transition in us. +* This is an upper bound intended for spinwaits etc. +*/ +#define PMU_MAX_TRANSITION_DLY 15000 + +#endif /* _SBCHIPC_H */ diff --git a/drivers/staging/brcm80211/include/defs.h b/drivers/staging/brcm80211/include/defs.h new file mode 100644 index 000000000000..8b3e17dec150 --- /dev/null +++ b/drivers/staging/brcm80211/include/defs.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BRCM_DEFS_H_ +#define _BRCM_DEFS_H_ + +#include + +#define SI_BUS 0 +#define PCI_BUS 1 +#define PCMCIA_BUS 2 +#define SDIO_BUS 3 +#define JTAG_BUS 4 +#define USB_BUS 5 +#define SPI_BUS 6 + +#ifndef OFF +#define OFF 0 +#endif + +#ifndef ON +#define ON 1 /* ON = 1 */ +#endif + +#define AUTO (-1) /* Auto = -1 */ + +/* + * Priority definitions according 802.1D + */ +#define PRIO_8021D_NONE 2 +#define PRIO_8021D_BK 1 +#define PRIO_8021D_BE 0 +#define PRIO_8021D_EE 3 +#define PRIO_8021D_CL 4 +#define PRIO_8021D_VI 5 +#define PRIO_8021D_VO 6 +#define PRIO_8021D_NC 7 + +#define MAXPRIO 7 +#define NUMPRIO (MAXPRIO + 1) + +#define WL_NUMRATES 16 /* max # of rates in a rateset */ + +typedef struct wl_rateset { + u32 count; /* # rates in this set */ + u8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ +} wl_rateset_t; + +#define BRCM_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */ + +#define BRCM_SET_CHANNEL 30 +#define BRCM_SET_SRL 32 +#define BRCM_SET_LRL 34 + +#define BRCM_SET_RATESET 72 +#define BRCM_SET_BCNPRD 76 +#define BRCM_GET_CURR_RATESET 114 /* current rateset */ +#define BRCM_GET_PHYLIST 180 + +/* Bit masks for radio disabled status - returned by WL_GET_RADIO */ +#define WL_RADIO_SW_DISABLE (1<<0) +#define WL_RADIO_HW_DISABLE (1<<1) +#define WL_RADIO_MPC_DISABLE (1<<2) +#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any channel */ + +/* Override bit for SET_TXPWR. if set, ignore other level limits */ +#define WL_TXPWR_OVERRIDE (1U<<31) + +/* band types */ +#define BRCM_BAND_AUTO 0 /* auto-select */ +#define BRCM_BAND_5G 1 /* 5 Ghz */ +#define BRCM_BAND_2G 2 /* 2.4 Ghz */ +#define BRCM_BAND_ALL 3 /* all bands */ + +/* Values for PM */ +#define PM_OFF 0 +#define PM_MAX 1 + +/* Message levels */ +#define LOG_ERROR_VAL 0x00000001 +#define LOG_TRACE_VAL 0x00000002 + +#define PM_OFF 0 +#define PM_MAX 1 +#define PM_FAST 2 + +/* + * Sonics Configuration Space Registers. + */ +#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */ + +/* cpp contortions to concatenate w/arg prescan */ +#ifndef PAD +#define _PADLINE(line) pad ## line +#define _XSTR(line) _PADLINE(line) +#define PAD _XSTR(__LINE__) +#endif + +#endif /* _BRCM_DEFS_H_ */ diff --git a/drivers/staging/brcm80211/include/hndsoc.h b/drivers/staging/brcm80211/include/hndsoc.h deleted file mode 100644 index 6435686b329f..000000000000 --- a/drivers/staging/brcm80211/include/hndsoc.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _HNDSOC_H -#define _HNDSOC_H - -/* Include the soci specific files */ -#include -#include - -/* - * SOC Interconnect Address Map. - * All regions may not exist on all chips. - */ -#define SI_SDRAM_BASE 0x00000000 /* Physical SDRAM */ -#define SI_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */ -#define SI_PCI_MEM_SZ (64 * 1024 * 1024) -#define SI_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */ -#define SI_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ -#define SI_SDRAM_R2 0x80000000 /* Region 2 for sdram (512 MB) */ - -#ifdef SI_ENUM_BASE_VARIABLE -#define SI_ENUM_BASE (sii->pub.si_enum_base) -#else -#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */ -#endif /* SI_ENUM_BASE_VARIABLE */ - -#define SI_WRAP_BASE 0x18100000 /* Wrapper space base */ -#define SI_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ -#define SI_MAXCORES 16 /* Max cores (this is arbitrary, for software - * convenience and could be changed if we - * make any larger chips - */ - -#define SI_FASTRAM 0x19000000 /* On-chip RAM on chips that also have DDR */ -#define SI_FASTRAM_SWAPPED 0x19800000 - -#define SI_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ -#define SI_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ -#define SI_ARMCM3_ROM 0x1e000000 /* ARM Cortex-M3 ROM */ -#define SI_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ -#define SI_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */ -#define SI_ARM7S_ROM 0x20000000 /* ARM7TDMI-S ROM */ -#define SI_ARMCM3_SRAM2 0x60000000 /* ARM Cortex-M3 SRAM Region 2 */ -#define SI_ARM7S_SRAM2 0x80000000 /* ARM7TDMI-S SRAM Region 2 */ -#define SI_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */ -#define SI_ARM_FLASH1_SZ 0x00010000 /* ARM Size of Flash Region 1 */ - -#define SI_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -#define SI_PCI_DMA2 0x80000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -#define SI_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */ -#define SI_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 - * (2 ZettaBytes), low 32 bits - */ -#define SI_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 - * (2 ZettaBytes), high 32 bits - */ - -/* core codes */ -#define NODEV_CORE_ID 0x700 /* Invalid coreid */ -#define CC_CORE_ID 0x800 /* chipcommon core */ -#define ILINE20_CORE_ID 0x801 /* iline20 core */ -#define SRAM_CORE_ID 0x802 /* sram core */ -#define SDRAM_CORE_ID 0x803 /* sdram core */ -#define PCI_CORE_ID 0x804 /* pci core */ -#define MIPS_CORE_ID 0x805 /* mips core */ -#define ENET_CORE_ID 0x806 /* enet mac core */ -#define CODEC_CORE_ID 0x807 /* v90 codec core */ -#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ -#define ADSL_CORE_ID 0x809 /* ADSL core */ -#define ILINE100_CORE_ID 0x80a /* iline100 core */ -#define IPSEC_CORE_ID 0x80b /* ipsec core */ -#define UTOPIA_CORE_ID 0x80c /* utopia core */ -#define PCMCIA_CORE_ID 0x80d /* pcmcia core */ -#define SOCRAM_CORE_ID 0x80e /* internal memory core */ -#define MEMC_CORE_ID 0x80f /* memc sdram core */ -#define OFDM_CORE_ID 0x810 /* OFDM phy core */ -#define EXTIF_CORE_ID 0x811 /* external interface core */ -#define D11_CORE_ID 0x812 /* 802.11 MAC core */ -#define APHY_CORE_ID 0x813 /* 802.11a phy core */ -#define BPHY_CORE_ID 0x814 /* 802.11b phy core */ -#define GPHY_CORE_ID 0x815 /* 802.11g phy core */ -#define MIPS33_CORE_ID 0x816 /* mips3302 core */ -#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ -#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ -#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ -#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ -#define SDIOH_CORE_ID 0x81b /* sdio host core */ -#define ROBO_CORE_ID 0x81c /* roboswitch core */ -#define ATA100_CORE_ID 0x81d /* parallel ATA core */ -#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ -#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ -#define PCIE_CORE_ID 0x820 /* pci express core */ -#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ -#define SRAMC_CORE_ID 0x822 /* SRAM controller core */ -#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ -#define ARM11_CORE_ID 0x824 /* ARM 1176 core */ -#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ -#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ -#define PMU_CORE_ID 0x827 /* PMU core */ -#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ -#define SDIOD_CORE_ID 0x829 /* SDIO device core */ -#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ -#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ -#define MIPS74K_CORE_ID 0x82c /* mips 74k core */ -#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ -#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ -#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ -#define SC_CORE_ID 0x831 /* shared common core */ -#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ -#define SPIH_CORE_ID 0x833 /* SPI host core */ -#define I2S_CORE_ID 0x834 /* I2S core */ -#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ -#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ -#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ -#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all - * unused address ranges - */ - -/* There are TWO constants on all HND chips: SI_ENUM_BASE above, - * and chipcommon being the first core: - */ -#define SI_CC_IDX 0 - -/* SOC Interconnect types (aka chip types) */ -#define SOCI_AI 1 - -/* Common core control flags */ -#define SICF_BIST_EN 0x8000 -#define SICF_PME_EN 0x4000 -#define SICF_CORE_BITS 0x3ffc -#define SICF_FGC 0x0002 -#define SICF_CLOCK_EN 0x0001 - -/* Common core status flags */ -#define SISF_BIST_DONE 0x8000 -#define SISF_BIST_ERROR 0x4000 -#define SISF_GATED_CLK 0x2000 -#define SISF_DMA64 0x1000 -#define SISF_CORE_BITS 0x0fff - -/* A register that is common to all cores to - * communicate w/PMU regarding clock control. - */ -#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */ - -/* clk_ctl_st register */ -#define CCS_FORCEALP 0x00000001 /* force ALP request */ -#define CCS_FORCEHT 0x00000002 /* force HT request */ -#define CCS_FORCEILP 0x00000004 /* force ILP request */ -#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */ -#define CCS_HTAREQ 0x00000010 /* HT Avail Request */ -#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */ -#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */ -#define CCS_ERSRC_REQ_SHIFT 8 -#define CCS_ALPAVAIL 0x00010000 /* ALP is available */ -#define CCS_HTAVAIL 0x00020000 /* HT is available */ -#define CCS_BP_ON_APL 0x00040000 /* RO: Backplane is running on ALP clock */ -#define CCS_BP_ON_HT 0x00080000 /* RO: Backplane is running on HT clock */ -#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */ -#define CCS_ERSRC_STS_SHIFT 24 - -#define CCS0_HTAVAIL 0x00010000 /* HT avail in chipc and pcmcia on 4328a0 */ -#define CCS0_ALPAVAIL 0x00020000 /* ALP avail in chipc and pcmcia on 4328a0 */ - -/* Not really related to SOC Interconnect, but a couple of software - * conventions for the use the flash space: - */ - -/* Minimum amount of flash we support */ -#define FLASH_MIN 0x00020000 /* Minimum flash size */ - -/* A boot/binary may have an embedded block that describes its size */ -#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ -#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */ -#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ -#define BISZ_TXTST_IDX 1 /* 1: text start */ -#define BISZ_TXTEND_IDX 2 /* 2: text end */ -#define BISZ_DATAST_IDX 3 /* 3: data start */ -#define BISZ_DATAEND_IDX 4 /* 4: data end */ -#define BISZ_BSSST_IDX 5 /* 5: bss start */ -#define BISZ_BSSEND_IDX 6 /* 6: bss end */ -#define BISZ_SIZE 7 /* descriptor size in 32-bit integers */ - -#endif /* _HNDSOC_H */ diff --git a/drivers/staging/brcm80211/include/nicpci.h b/drivers/staging/brcm80211/include/nicpci.h deleted file mode 100644 index 30321eb0477e..000000000000 --- a/drivers/staging/brcm80211/include/nicpci.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _NICPCI_H -#define _NICPCI_H - -#if defined(BCMSDIO) || (defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)) -#define pcicore_find_pci_capability(a, b, c, d) (0) -#define pcie_readreg(a, b, c, d) (0) -#define pcie_writereg(a, b, c, d, e) (0) - -#define pcie_clkreq(a, b, c) (0) -#define pcie_lcreg(a, b, c) (0) - -#define pcicore_init(a, b, c) (0x0dadbeef) -#define pcicore_deinit(a) do { } while (0) -#define pcicore_attach(a, b, c) do { } while (0) -#define pcicore_hwup(a) do { } while (0) -#define pcicore_up(a, b) do { } while (0) -#define pcicore_sleep(a) do { } while (0) -#define pcicore_down(a, b) do { } while (0) - -#define pcie_war_ovr_aspm_update(a, b) do { } while (0) - -#define pcicore_pcieserdesreg(a, b, c, d, e) (0) -#define pcicore_pciereg(a, b, c, d, e) (0) - -#define pcicore_pmecap_fast(a) (false) -#define pcicore_pmeen(a) do { } while (0) -#define pcicore_pmeclr(a) do { } while (0) -#define pcicore_pmestat(a) (false) -#else -struct sbpcieregs; - -extern u8 pcicore_find_pci_capability(void *dev, u8 req_cap_id, - unsigned char *buf, u32 *buflen); -extern uint pcie_readreg(struct sbpcieregs *pcieregs, - uint addrtype, uint offset); -extern uint pcie_writereg(struct sbpcieregs *pcieregs, - uint addrtype, uint offset, uint val); - -extern u8 pcie_clkreq(void *pch, u32 mask, u32 val); -extern u32 pcie_lcreg(void *pch, u32 mask, u32 val); - -extern void *pcicore_init(si_t *sih, void *pdev, void *regs); -extern void pcicore_deinit(void *pch); -extern void pcicore_attach(void *pch, char *pvars, int state); -extern void pcicore_hwup(void *pch); -extern void pcicore_up(void *pch, int state); -extern void pcicore_sleep(void *pch); -extern void pcicore_down(void *pch, int state); - -extern void pcie_war_ovr_aspm_update(void *pch, u8 aspm); -extern u32 pcicore_pcieserdesreg(void *pch, u32 mdioslave, u32 offset, - u32 mask, u32 val); - -extern u32 pcicore_pciereg(void *pch, u32 offset, u32 mask, - u32 val, uint type); - -extern bool pcicore_pmecap_fast(void *pch); -extern void pcicore_pmeen(void *pch); -extern void pcicore_pmeclr(void *pch); -extern bool pcicore_pmestat(void *pch); -#endif /* defined(BCMSDIO)||(defined(BCMBUSTYPE) && (BCMBUSTYPE==SI_BUS)) */ - -#endif /* _NICPCI_H */ diff --git a/drivers/staging/brcm80211/include/pci_core.h b/drivers/staging/brcm80211/include/pci_core.h deleted file mode 100644 index 9153dcb8160e..000000000000 --- a/drivers/staging/brcm80211/include/pci_core.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _PCI_CORE_H_ -#define _PCI_CORE_H_ - -#ifndef _LANGUAGE_ASSEMBLY - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - -/* Sonics side: PCI core and host control registers */ -struct sbpciregs { - u32 control; /* PCI control */ - u32 PAD[3]; - u32 arbcontrol; /* PCI arbiter control */ - u32 clkrun; /* Clkrun Control (>=rev11) */ - u32 PAD[2]; - u32 intstatus; /* Interrupt status */ - u32 intmask; /* Interrupt mask */ - u32 sbtopcimailbox; /* Sonics to PCI mailbox */ - u32 PAD[9]; - u32 bcastaddr; /* Sonics broadcast address */ - u32 bcastdata; /* Sonics broadcast data */ - u32 PAD[2]; - u32 gpioin; /* ro: gpio input (>=rev2) */ - u32 gpioout; /* rw: gpio output (>=rev2) */ - u32 gpioouten; /* rw: gpio output enable (>= rev2) */ - u32 gpiocontrol; /* rw: gpio control (>= rev2) */ - u32 PAD[36]; - u32 sbtopci0; /* Sonics to PCI translation 0 */ - u32 sbtopci1; /* Sonics to PCI translation 1 */ - u32 sbtopci2; /* Sonics to PCI translation 2 */ - u32 PAD[189]; - u32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */ - u16 sprom[36]; /* SPROM shadow Area */ - u32 PAD[46]; -}; - -#endif /* _LANGUAGE_ASSEMBLY */ - -/* PCI control */ -#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ -#define PCI_RST 0x02 /* Value driven out to pin */ -#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */ -#define PCI_CLK 0x08 /* Gate for clock driven out to pin */ - -/* PCI arbiter control */ -#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */ -#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */ -/* ParkID - for PCI corerev >= 8 */ -#define PCI_PARKID_MASK 0x1c /* Selects which agent is parked on an idle bus */ -#define PCI_PARKID_SHIFT 2 -#define PCI_PARKID_EXT0 0 /* External master 0 */ -#define PCI_PARKID_EXT1 1 /* External master 1 */ -#define PCI_PARKID_EXT2 2 /* External master 2 */ -#define PCI_PARKID_EXT3 3 /* External master 3 (rev >= 11) */ -#define PCI_PARKID_INT 3 /* Internal master (rev < 11) */ -#define PCI11_PARKID_INT 4 /* Internal master (rev >= 11) */ -#define PCI_PARKID_LAST 4 /* Last active master (rev < 11) */ -#define PCI11_PARKID_LAST 5 /* Last active master (rev >= 11) */ - -#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */ - -/* Interrupt status/mask */ -#define PCI_INTA 0x01 /* PCI INTA# is asserted */ -#define PCI_INTB 0x02 /* PCI INTB# is asserted */ -#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */ -#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */ -#define PCI_PME 0x10 /* PCI PME# is asserted */ - -/* (General) PCI/SB mailbox interrupts, two bits per pci function */ -#define MAILBOX_F0_0 0x100 /* function 0, int 0 */ -#define MAILBOX_F0_1 0x200 /* function 0, int 1 */ -#define MAILBOX_F1_0 0x400 /* function 1, int 0 */ -#define MAILBOX_F1_1 0x800 /* function 1, int 1 */ -#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */ -#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */ -#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */ -#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */ - -/* Sonics broadcast address */ -#define BCAST_ADDR_MASK 0xff /* Broadcast register address */ - -/* Sonics to PCI translation types */ -#define SBTOPCI0_MASK 0xfc000000 -#define SBTOPCI1_MASK 0xfc000000 -#define SBTOPCI2_MASK 0xc0000000 -#define SBTOPCI_MEM 0 -#define SBTOPCI_IO 1 -#define SBTOPCI_CFG0 2 -#define SBTOPCI_CFG1 3 -#define SBTOPCI_PREF 0x4 /* prefetch enable */ -#define SBTOPCI_BURST 0x8 /* burst enable */ -#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */ -#define SBTOPCI_RC_READ 0x00 /* memory read */ -#define SBTOPCI_RC_READLINE 0x10 /* memory read line */ -#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ - -/* PCI core index in SROM shadow area */ -#define SRSH_PI_OFFSET 0 /* first word */ -#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ -#define SRSH_PI_SHIFT 12 /* bit 15:12 */ - -#endif /* _PCI_CORE_H_ */ diff --git a/drivers/staging/brcm80211/include/pcicfg.h b/drivers/staging/brcm80211/include/pcicfg.h deleted file mode 100644 index d0c617a63c4f..000000000000 --- a/drivers/staging/brcm80211/include/pcicfg.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _h_pcicfg_ -#define _h_pcicfg_ - -#include - -/* PCI configuration address space size */ -#define PCI_SZPCR 256 - -/* Everything below is BRCM HND proprietary */ - -/* Brcm PCI configuration registers */ -#define PCI_BAR0_WIN 0x80 /* backplane address space accessed by BAR0 */ -#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ -#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ -#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ -#define PCI_BAR0_WIN2 0xac /* backplane address space accessed by second 4KB of BAR0 */ -#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ -#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ -#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ - -#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ -#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ -#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) /* pci core SB registers are at the end of the - * 8KB window, so their address is the "regular" - * address plus 4K - */ -#define PCI_BAR0_WINSZ (16 * 1024) /* bar0 window size Match with corerev 13 */ -/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */ -#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) /* bar0 + 8K accesses pci/pcie core registers */ -#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) /* bar0 + 12K accesses chipc core registers */ - -#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ - -#endif /* _h_pcicfg_ */ diff --git a/drivers/staging/brcm80211/include/pcie_core.h b/drivers/staging/brcm80211/include/pcie_core.h deleted file mode 100644 index cd54ddcf4597..000000000000 --- a/drivers/staging/brcm80211/include/pcie_core.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _PCIE_CORE_H -#define _PCIE_CORE_H - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - -/* PCIE Enumeration space offsets */ -#define PCIE_CORE_CONFIG_OFFSET 0x0 -#define PCIE_FUNC0_CONFIG_OFFSET 0x400 -#define PCIE_FUNC1_CONFIG_OFFSET 0x500 -#define PCIE_FUNC2_CONFIG_OFFSET 0x600 -#define PCIE_FUNC3_CONFIG_OFFSET 0x700 -#define PCIE_SPROM_SHADOW_OFFSET 0x800 -#define PCIE_SBCONFIG_OFFSET 0xE00 - -/* PCIE Bar0 Address Mapping. Each function maps 16KB config space */ -#define PCIE_DEV_BAR0_SIZE 0x4000 -#define PCIE_BAR0_WINMAPCORE_OFFSET 0x0 -#define PCIE_BAR0_EXTSPROM_OFFSET 0x1000 -#define PCIE_BAR0_PCIECORE_OFFSET 0x2000 -#define PCIE_BAR0_CCCOREREG_OFFSET 0x3000 - -/* different register spaces to access thr'u pcie indirect access */ -#define PCIE_CONFIGREGS 1 /* Access to config space */ -#define PCIE_PCIEREGS 2 /* Access to pcie registers */ - -/* SB side: PCIE core and host control registers */ -typedef struct sbpcieregs { - u32 control; /* host mode only */ - u32 PAD[2]; - u32 biststatus; /* bist Status: 0x00C */ - u32 gpiosel; /* PCIE gpio sel: 0x010 */ - u32 gpioouten; /* PCIE gpio outen: 0x14 */ - u32 PAD[2]; - u32 intstatus; /* Interrupt status: 0x20 */ - u32 intmask; /* Interrupt mask: 0x24 */ - u32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */ - u32 PAD[53]; - u32 sbtopcie0; /* sb to pcie translation 0: 0x100 */ - u32 sbtopcie1; /* sb to pcie translation 1: 0x104 */ - u32 sbtopcie2; /* sb to pcie translation 2: 0x108 */ - u32 PAD[5]; - - /* pcie core supports in direct access to config space */ - u32 configaddr; /* pcie config space access: Address field: 0x120 */ - u32 configdata; /* pcie config space access: Data field: 0x124 */ - - /* mdio access to serdes */ - u32 mdiocontrol; /* controls the mdio access: 0x128 */ - u32 mdiodata; /* Data to the mdio access: 0x12c */ - - /* pcie protocol phy/dllp/tlp register indirect access mechanism */ - u32 pcieindaddr; /* indirect access to the internal register: 0x130 */ - u32 pcieinddata; /* Data to/from the internal regsiter: 0x134 */ - - u32 clkreqenctrl; /* >= rev 6, Clkreq rdma control : 0x138 */ - u32 PAD[177]; - u32 pciecfg[4][64]; /* 0x400 - 0x7FF, PCIE Cfg Space */ - u16 sprom[64]; /* SPROM shadow Area */ -} sbpcieregs_t; - -/* PCI control */ -#define PCIE_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ -#define PCIE_RST 0x02 /* Value driven out to pin */ - -#define PCIE_CFGADDR 0x120 /* offsetof(configaddr) */ -#define PCIE_CFGDATA 0x124 /* offsetof(configdata) */ - -/* Interrupt status/mask */ -#define PCIE_INTA 0x01 /* PCIE INTA message is received */ -#define PCIE_INTB 0x02 /* PCIE INTB message is received */ -#define PCIE_INTFATAL 0x04 /* PCIE INTFATAL message is received */ -#define PCIE_INTNFATAL 0x08 /* PCIE INTNONFATAL message is received */ -#define PCIE_INTCORR 0x10 /* PCIE INTCORR message is received */ -#define PCIE_INTPME 0x20 /* PCIE INTPME message is received */ - -/* SB to PCIE translation masks */ -#define SBTOPCIE0_MASK 0xfc000000 -#define SBTOPCIE1_MASK 0xfc000000 -#define SBTOPCIE2_MASK 0xc0000000 - -/* Access type bits (0:1) */ -#define SBTOPCIE_MEM 0 -#define SBTOPCIE_IO 1 -#define SBTOPCIE_CFG0 2 -#define SBTOPCIE_CFG1 3 - -/* Prefetch enable bit 2 */ -#define SBTOPCIE_PF 4 - -/* Write Burst enable for memory write bit 3 */ -#define SBTOPCIE_WR_BURST 8 - -/* config access */ -#define CONFIGADDR_FUNC_MASK 0x7000 -#define CONFIGADDR_FUNC_SHF 12 -#define CONFIGADDR_REG_MASK 0x0FFF -#define CONFIGADDR_REG_SHF 0 - -#define PCIE_CONFIG_INDADDR(f, r) \ - ((((f) & CONFIGADDR_FUNC_MASK) << CONFIGADDR_FUNC_SHF) | \ - (((r) & CONFIGADDR_REG_MASK) << CONFIGADDR_REG_SHF)) - -/* PCIE protocol regs Indirect Address */ -#define PCIEADDR_PROT_MASK 0x300 -#define PCIEADDR_PROT_SHF 8 -#define PCIEADDR_PL_TLP 0 -#define PCIEADDR_PL_DLLP 1 -#define PCIEADDR_PL_PLP 2 - -/* PCIE protocol PHY diagnostic registers */ -#define PCIE_PLP_MODEREG 0x200 /* Mode */ -#define PCIE_PLP_STATUSREG 0x204 /* Status */ -#define PCIE_PLP_LTSSMCTRLREG 0x208 /* LTSSM control */ -#define PCIE_PLP_LTLINKNUMREG 0x20c /* Link Training Link number */ -#define PCIE_PLP_LTLANENUMREG 0x210 /* Link Training Lane number */ -#define PCIE_PLP_LTNFTSREG 0x214 /* Link Training N_FTS */ -#define PCIE_PLP_ATTNREG 0x218 /* Attention */ -#define PCIE_PLP_ATTNMASKREG 0x21C /* Attention Mask */ -#define PCIE_PLP_RXERRCTR 0x220 /* Rx Error */ -#define PCIE_PLP_RXFRMERRCTR 0x224 /* Rx Framing Error */ -#define PCIE_PLP_RXERRTHRESHREG 0x228 /* Rx Error threshold */ -#define PCIE_PLP_TESTCTRLREG 0x22C /* Test Control reg */ -#define PCIE_PLP_SERDESCTRLOVRDREG 0x230 /* SERDES Control Override */ -#define PCIE_PLP_TIMINGOVRDREG 0x234 /* Timing param override */ -#define PCIE_PLP_RXTXSMDIAGREG 0x238 /* RXTX State Machine Diag */ -#define PCIE_PLP_LTSSMDIAGREG 0x23C /* LTSSM State Machine Diag */ - -/* PCIE protocol DLLP diagnostic registers */ -#define PCIE_DLLP_LCREG 0x100 /* Link Control */ -#define PCIE_DLLP_LSREG 0x104 /* Link Status */ -#define PCIE_DLLP_LAREG 0x108 /* Link Attention */ -#define PCIE_DLLP_LAMASKREG 0x10C /* Link Attention Mask */ -#define PCIE_DLLP_NEXTTXSEQNUMREG 0x110 /* Next Tx Seq Num */ -#define PCIE_DLLP_ACKEDTXSEQNUMREG 0x114 /* Acked Tx Seq Num */ -#define PCIE_DLLP_PURGEDTXSEQNUMREG 0x118 /* Purged Tx Seq Num */ -#define PCIE_DLLP_RXSEQNUMREG 0x11C /* Rx Sequence Number */ -#define PCIE_DLLP_LRREG 0x120 /* Link Replay */ -#define PCIE_DLLP_LACKTOREG 0x124 /* Link Ack Timeout */ -#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */ -#define PCIE_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr */ -#define PCIE_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr */ -#define PCIE_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr */ -#define PCIE_DLLP_RTRRWREG 0x138 /* Retry buffer Read/Write */ -#define PCIE_DLLP_ECTHRESHREG 0x13C /* Error Count Threshold */ -#define PCIE_DLLP_TLPERRCTRREG 0x140 /* TLP Error Counter */ -#define PCIE_DLLP_ERRCTRREG 0x144 /* Error Counter */ -#define PCIE_DLLP_NAKRXCTRREG 0x148 /* NAK Received Counter */ -#define PCIE_DLLP_TESTREG 0x14C /* Test */ -#define PCIE_DLLP_PKTBIST 0x150 /* Packet BIST */ -#define PCIE_DLLP_PCIE11 0x154 /* DLLP PCIE 1.1 reg */ - -#define PCIE_DLLP_LSREG_LINKUP (1 << 16) - -/* PCIE protocol TLP diagnostic registers */ -#define PCIE_TLP_CONFIGREG 0x000 /* Configuration */ -#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */ -#define PCIE_TLP_WRDMAUPPER 0x010 /* Write DMA Upper Address */ -#define PCIE_TLP_WRDMALOWER 0x014 /* Write DMA Lower Address */ -#define PCIE_TLP_WRDMAREQ_LBEREG 0x018 /* Write DMA Len/ByteEn Req */ -#define PCIE_TLP_RDDMAUPPER 0x01C /* Read DMA Upper Address */ -#define PCIE_TLP_RDDMALOWER 0x020 /* Read DMA Lower Address */ -#define PCIE_TLP_RDDMALENREG 0x024 /* Read DMA Len Req */ -#define PCIE_TLP_MSIDMAUPPER 0x028 /* MSI DMA Upper Address */ -#define PCIE_TLP_MSIDMALOWER 0x02C /* MSI DMA Lower Address */ -#define PCIE_TLP_MSIDMALENREG 0x030 /* MSI DMA Len Req */ -#define PCIE_TLP_SLVREQLENREG 0x034 /* Slave Request Len */ -#define PCIE_TLP_FCINPUTSREQ 0x038 /* Flow Control Inputs */ -#define PCIE_TLP_TXSMGRSREQ 0x03C /* Tx StateMachine and Gated Req */ -#define PCIE_TLP_ADRACKCNTARBLEN 0x040 /* Address Ack XferCnt and ARB Len */ -#define PCIE_TLP_DMACPLHDR0 0x044 /* DMA Completion Hdr 0 */ -#define PCIE_TLP_DMACPLHDR1 0x048 /* DMA Completion Hdr 1 */ -#define PCIE_TLP_DMACPLHDR2 0x04C /* DMA Completion Hdr 2 */ -#define PCIE_TLP_DMACPLMISC0 0x050 /* DMA Completion Misc0 */ -#define PCIE_TLP_DMACPLMISC1 0x054 /* DMA Completion Misc1 */ -#define PCIE_TLP_DMACPLMISC2 0x058 /* DMA Completion Misc2 */ -#define PCIE_TLP_SPTCTRLLEN 0x05C /* Split Controller Req len */ -#define PCIE_TLP_SPTCTRLMSIC0 0x060 /* Split Controller Misc 0 */ -#define PCIE_TLP_SPTCTRLMSIC1 0x064 /* Split Controller Misc 1 */ -#define PCIE_TLP_BUSDEVFUNC 0x068 /* Bus/Device/Func */ -#define PCIE_TLP_RESETCTR 0x06C /* Reset Counter */ -#define PCIE_TLP_RTRYBUF 0x070 /* Retry Buffer value */ -#define PCIE_TLP_TGTDEBUG1 0x074 /* Target Debug Reg1 */ -#define PCIE_TLP_TGTDEBUG2 0x078 /* Target Debug Reg2 */ -#define PCIE_TLP_TGTDEBUG3 0x07C /* Target Debug Reg3 */ -#define PCIE_TLP_TGTDEBUG4 0x080 /* Target Debug Reg4 */ - -/* MDIO control */ -#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */ -#define MDIOCTL_DIVISOR_VAL 0x2 -#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */ -#define MDIOCTL_ACCESS_DONE 0x100 /* Tranaction complete */ - -/* MDIO Data */ -#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */ -#define MDIODATA_TA 0x00020000 /* Turnaround */ -#define MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift (rev < 10) */ -#define MDIODATA_REGADDR_MASK_OLD 0x003c0000 /* Regaddr Mask (rev < 10) */ -#define MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift (rev < 10) */ -#define MDIODATA_DEVADDR_MASK_OLD 0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */ -#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */ -#define MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */ -#define MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */ -#define MDIODATA_DEVADDR_MASK 0x0f800000 /* Physmedia devaddr Mask */ -#define MDIODATA_WRITE 0x10000000 /* write Transaction */ -#define MDIODATA_READ 0x20000000 /* Read Transaction */ -#define MDIODATA_START 0x40000000 /* start of Transaction */ - -#define MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */ -#define MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */ - -/* MDIO devices (SERDES modules) - * unlike old pcie cores (rev < 10), rev10 pcie serde organizes registers into a few blocks. - * two layers mapping (blockidx, register offset) is required - */ -#define MDIO_DEV_IEEE0 0x000 -#define MDIO_DEV_IEEE1 0x001 -#define MDIO_DEV_BLK0 0x800 -#define MDIO_DEV_BLK1 0x801 -#define MDIO_DEV_BLK2 0x802 -#define MDIO_DEV_BLK3 0x803 -#define MDIO_DEV_BLK4 0x804 -#define MDIO_DEV_TXPLL 0x808 /* TXPLL register block idx */ -#define MDIO_DEV_TXCTRL0 0x820 -#define MDIO_DEV_SERDESID 0x831 -#define MDIO_DEV_RXCTRL0 0x840 - -/* serdes regs (rev < 10) */ -#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */ -#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */ -#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */ - /* SERDES RX registers */ -#define SERDES_RX_CTRL 1 /* Rx cntrl */ -#define SERDES_RX_TIMER1 2 /* Rx Timer1 */ -#define SERDES_RX_CDR 6 /* CDR */ -#define SERDES_RX_CDRBW 7 /* CDR BW */ - - /* SERDES RX control register */ -#define SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */ -#define SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */ - - /* SERDES PLL registers */ -#define SERDES_PLL_CTRL 1 /* PLL control reg */ -#define PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */ - -/* Power management threshold */ -#define PCIE_L0THRESHOLDTIME_MASK 0xFF00 /* bits 0 - 7 */ -#define PCIE_L1THRESHOLDTIME_MASK 0xFF00 /* bits 8 - 15 */ -#define PCIE_L1THRESHOLDTIME_SHIFT 8 /* PCIE_L1THRESHOLDTIME_SHIFT */ -#define PCIE_L1THRESHOLD_WARVAL 0x72 /* WAR value */ -#define PCIE_ASPMTIMER_EXTEND 0x01000000 /* > rev7: enable extend ASPM timer */ - -/* SPROM offsets */ -#define SRSH_ASPM_OFFSET 4 /* word 4 */ -#define SRSH_ASPM_ENB 0x18 /* bit 3, 4 */ -#define SRSH_ASPM_L1_ENB 0x10 /* bit 4 */ -#define SRSH_ASPM_L0s_ENB 0x8 /* bit 3 */ -#define SRSH_PCIE_MISC_CONFIG 5 /* word 5 */ -#define SRSH_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */ -#define SRSH_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */ -#define SRSH_CLKREQ_OFFSET_REV8 52 /* word 52 for srom rev 8 */ -#define SRSH_CLKREQ_ENB 0x0800 /* bit 11 */ -#define SRSH_BD_OFFSET 6 /* word 6 */ -#define SRSH_AUTOINIT_OFFSET 18 /* auto initialization enable */ - -/* Linkcontrol reg offset in PCIE Cap */ -#define PCIE_CAP_LINKCTRL_OFFSET 16 /* linkctrl offset in pcie cap */ -#define PCIE_CAP_LCREG_ASPML0s 0x01 /* ASPM L0s in linkctrl */ -#define PCIE_CAP_LCREG_ASPML1 0x02 /* ASPM L1 in linkctrl */ -#define PCIE_CLKREQ_ENAB 0x100 /* CLKREQ Enab in linkctrl */ - -#define PCIE_ASPM_ENAB 3 /* ASPM L0s & L1 in linkctrl */ -#define PCIE_ASPM_L1_ENAB 2 /* ASPM L0s & L1 in linkctrl */ -#define PCIE_ASPM_L0s_ENAB 1 /* ASPM L0s & L1 in linkctrl */ -#define PCIE_ASPM_DISAB 0 /* ASPM L0s & L1 in linkctrl */ - -/* Status reg PCIE_PLP_STATUSREG */ -#define PCIE_PLP_POLARITYINV_STAT 0x10 -#endif /* _PCIE_CORE_H */ diff --git a/drivers/staging/brcm80211/include/proto/802.11.h b/drivers/staging/brcm80211/include/proto/802.11.h deleted file mode 100644 index 374125d770b9..000000000000 --- a/drivers/staging/brcm80211/include/proto/802.11.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _802_11_H_ -#define _802_11_H_ - -#include - -#define DOT11_A3_HDR_LEN 24 -#define DOT11_A4_HDR_LEN 30 -#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN -#define DOT11_ICV_AES_LEN 8 -#define DOT11_QOS_LEN 2 - -#define DOT11_IV_MAX_LEN 8 - -#define DOT11_DEFAULT_RTS_LEN 2347 - -#define DOT11_MIN_FRAG_LEN 256 -#define DOT11_MAX_FRAG_LEN 2346 -#define DOT11_DEFAULT_FRAG_LEN 2346 - -#define DOT11_MIN_BEACON_PERIOD 1 -#define DOT11_MAX_BEACON_PERIOD 0xFFFF - -#define DOT11_MIN_DTIM_PERIOD 1 -#define DOT11_MAX_DTIM_PERIOD 0xFF - -#define DOT11_OUI_LEN 3 - -#define DOT11_RTS_LEN 16 -#define DOT11_CTS_LEN 10 -#define DOT11_ACK_LEN 10 - -#define DOT11_BA_BITMAP_LEN 128 -#define DOT11_BA_LEN 4 - -#define WME_OUI "\x00\x50\xf2" -#define WME_VER 1 -#define WME_TYPE 2 -#define WME_SUBTYPE_PARAM_IE 1 - -#define AC_BE 0 -#define AC_BK 1 -#define AC_VI 2 -#define AC_VO 3 -#define AC_COUNT 4 - -typedef u8 ac_bitmap_t; - -#define AC_BITMAP_ALL 0xf -#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) - -struct edcf_acparam { - u8 ACI; - u8 ECW; - u16 TXOP; -} __attribute__((packed)); -typedef struct edcf_acparam edcf_acparam_t; - -struct wme_param_ie { - u8 oui[3]; - u8 type; - u8 subtype; - u8 version; - u8 qosinfo; - u8 rsvd; - edcf_acparam_t acparam[AC_COUNT]; -} __attribute__((packed)); -typedef struct wme_param_ie wme_param_ie_t; -#define WME_PARAM_IE_LEN 24 - -#define EDCF_AIFSN_MIN 1 -#define EDCF_AIFSN_MAX 15 -#define EDCF_AIFSN_MASK 0x0f -#define EDCF_ACM_MASK 0x10 -#define EDCF_ACI_MASK 0x60 -#define EDCF_ACI_SHIFT 5 - -#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) -#define EDCF_ECWMIN_MASK 0x0f -#define EDCF_ECWMAX_MASK 0xf0 -#define EDCF_ECWMAX_SHIFT 4 - -#define EDCF_TXOP2USEC(txop) ((txop) << 5) - -#define EDCF_AC_BE_ACI_STA 0x03 -#define EDCF_AC_BE_ECW_STA 0xA4 -#define EDCF_AC_BE_TXOP_STA 0x0000 -#define EDCF_AC_BK_ACI_STA 0x27 -#define EDCF_AC_BK_ECW_STA 0xA4 -#define EDCF_AC_BK_TXOP_STA 0x0000 -#define EDCF_AC_VI_ACI_STA 0x42 -#define EDCF_AC_VI_ECW_STA 0x43 -#define EDCF_AC_VI_TXOP_STA 0x005e -#define EDCF_AC_VO_ACI_STA 0x62 -#define EDCF_AC_VO_ECW_STA 0x32 -#define EDCF_AC_VO_TXOP_STA 0x002f - -#define EDCF_AC_VO_TXOP_AP 0x002f - -#define SEQNUM_SHIFT 4 -#define SEQNUM_MAX 0x1000 -#define FRAGNUM_MASK 0xF - -#define DOT11_MNG_RSN_ID 48 -#define DOT11_MNG_WPA_ID 221 -#define DOT11_MNG_VS_ID 221 - -#define DOT11_BSSTYPE_INFRASTRUCTURE 0 -#define DOT11_BSSTYPE_ANY 2 -#define DOT11_SCANTYPE_ACTIVE 0 - -#define PREN_PREAMBLE 24 -#define PREN_MM_EXT 12 -#define PREN_PREAMBLE_EXT 4 - -#define RIFS_11N_TIME 2 - -#define APHY_SLOT_TIME 9 -#define APHY_SIFS_TIME 16 -#define APHY_PREAMBLE_TIME 16 -#define APHY_SIGNAL_TIME 4 -#define APHY_SYMBOL_TIME 4 -#define APHY_SERVICE_NBITS 16 -#define APHY_TAIL_NBITS 6 -#define APHY_CWMIN 15 - -#define BPHY_SLOT_TIME 20 -#define BPHY_SIFS_TIME 10 -#define BPHY_PLCP_TIME 192 -#define BPHY_PLCP_SHORT_TIME 96 - -#define DOT11_OFDM_SIGNAL_EXTENSION 6 - -#define PHY_CWMAX 1023 - -#define DOT11_MAXNUMFRAGS 16 - -typedef struct d11cnt { - u32 txfrag; - u32 txmulti; - u32 txfail; - u32 txretry; - u32 txretrie; - u32 rxdup; - u32 txrts; - u32 txnocts; - u32 txnoack; - u32 rxfrag; - u32 rxmulti; - u32 rxcrc; - u32 txfrmsnt; - u32 rxundec; -} d11cnt_t; - -#define MCSSET_LEN 16 - -#define HT_CAP_IE_LEN 26 - -#define HT_CAP_RX_STBC_NO 0x0 -#define HT_CAP_RX_STBC_ONE_STREAM 0x1 - -#define AMPDU_MAX_MPDU_DENSITY IEEE80211_HT_MPDU_DENSITY_16 - -#define AMPDU_DELIMITER_LEN 4 - -#define DOT11N_TXBURST 0x0008 - -#define WPA_VERSION 1 -#define WPA_OUI "\x00\x50\xF2" - -#define WFA_OUI "\x00\x50\xF2" -#define WFA_OUI_LEN 3 - -#define WFA_OUI_TYPE_WPA 1 - -#define RSN_AKM_NONE 0 -#define RSN_AKM_UNSPECIFIED 1 -#define RSN_AKM_PSK 2 - -#define DOT11_MAX_DEFAULT_KEYS 4 -#define DOT11_WPA_KEY_RSC_LEN 8 - -#define BRCM_OUI "\x00\x10\x18" - -#endif /* _802_11_H_ */ diff --git a/drivers/staging/brcm80211/include/proto/bcmeth.h b/drivers/staging/brcm80211/include/proto/bcmeth.h deleted file mode 100644 index e98ee654458d..000000000000 --- a/drivers/staging/brcm80211/include/proto/bcmeth.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _BCMETH_H_ -#define _BCMETH_H_ - -#define BCMILCP_SUBTYPE_RATE 1 -#define BCMILCP_SUBTYPE_LINK 2 -#define BCMILCP_SUBTYPE_CSA 3 -#define BCMILCP_SUBTYPE_LARQ 4 -#define BCMILCP_SUBTYPE_VENDOR 5 -#define BCMILCP_SUBTYPE_FLH 17 -#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 -#define BCMILCP_SUBTYPE_CERT 32770 -#define BCMILCP_SUBTYPE_SES 32771 -#define BCMILCP_BCM_SUBTYPE_RESERVED 0 -#define BCMILCP_BCM_SUBTYPE_EVENT 1 -#define BCMILCP_BCM_SUBTYPE_SES 2 -#define BCMILCP_BCM_SUBTYPE_DPT 4 -#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 -#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 - -typedef struct bcmeth_hdr { - u16 subtype; - u16 length; - u8 version; - u8 oui[3]; - u16 usr_subtype; -} __attribute__((packed)) bcmeth_hdr_t; - -#endif /* _BCMETH_H_ */ diff --git a/drivers/staging/brcm80211/include/proto/bcmevent.h b/drivers/staging/brcm80211/include/proto/bcmevent.h deleted file mode 100644 index 1b60789aef05..000000000000 --- a/drivers/staging/brcm80211/include/proto/bcmevent.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _BCMEVENT_H_ -#define _BCMEVENT_H_ - -#include - -#define BCM_EVENT_MSG_VERSION 1 -#define BCM_MSG_IFNAME_MAX 16 - -#define WLC_EVENT_MSG_LINK 0x01 -#define WLC_EVENT_MSG_FLUSHTXQ 0x02 -#define WLC_EVENT_MSG_GROUP 0x04 - -typedef struct { - u16 version; - u16 flags; - u32 event_type; - u32 status; - u32 reason; - u32 auth_type; - u32 datalen; - u8 addr[ETH_ALEN]; - char ifname[BCM_MSG_IFNAME_MAX]; -} __attribute__((packed)) wl_event_msg_t; - -#ifdef BRCM_FULLMAC -typedef struct bcm_event { - struct ethhdr eth; - bcmeth_hdr_t bcm_hdr; - wl_event_msg_t event; -} __attribute__((packed)) bcm_event_t; -#endif -#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - \ - sizeof(struct ether_header)) - -#define WLC_E_SET_SSID 0 -#define WLC_E_JOIN 1 -#define WLC_E_START 2 -#define WLC_E_AUTH 3 -#define WLC_E_AUTH_IND 4 -#define WLC_E_DEAUTH 5 -#define WLC_E_DEAUTH_IND 6 -#define WLC_E_ASSOC 7 -#define WLC_E_ASSOC_IND 8 -#define WLC_E_REASSOC 9 -#define WLC_E_REASSOC_IND 10 -#define WLC_E_DISASSOC 11 -#define WLC_E_DISASSOC_IND 12 -#define WLC_E_QUIET_START 13 -#define WLC_E_QUIET_END 14 -#define WLC_E_BEACON_RX 15 -#define WLC_E_LINK 16 -#define WLC_E_MIC_ERROR 17 -#define WLC_E_NDIS_LINK 18 -#define WLC_E_ROAM 19 -#define WLC_E_TXFAIL 20 -#define WLC_E_PMKID_CACHE 21 -#define WLC_E_RETROGRADE_TSF 22 -#define WLC_E_PRUNE 23 -#define WLC_E_AUTOAUTH 24 -#define WLC_E_EAPOL_MSG 25 -#define WLC_E_SCAN_COMPLETE 26 -#define WLC_E_ADDTS_IND 27 -#define WLC_E_DELTS_IND 28 -#define WLC_E_BCNSENT_IND 29 -#define WLC_E_BCNRX_MSG 30 -#define WLC_E_BCNLOST_MSG 31 -#define WLC_E_ROAM_PREP 32 -#define WLC_E_PFN_NET_FOUND 33 -#define WLC_E_PFN_NET_LOST 34 -#define WLC_E_RESET_COMPLETE 35 -#define WLC_E_JOIN_START 36 -#define WLC_E_ROAM_START 37 -#define WLC_E_ASSOC_START 38 -#define WLC_E_IBSS_ASSOC 39 -#define WLC_E_RADIO 40 -#define WLC_E_PSM_WATCHDOG 41 -#define WLC_E_PROBREQ_MSG 44 -#define WLC_E_SCAN_CONFIRM_IND 45 -#define WLC_E_PSK_SUP 46 -#define WLC_E_COUNTRY_CODE_CHANGED 47 -#define WLC_E_EXCEEDED_MEDIUM_TIME 48 -#define WLC_E_ICV_ERROR 49 -#define WLC_E_UNICAST_DECODE_ERROR 50 -#define WLC_E_MULTICAST_DECODE_ERROR 51 -#define WLC_E_TRACE 52 -#define WLC_E_IF 54 -#define WLC_E_RSSI 56 -#define WLC_E_PFN_SCAN_COMPLETE 57 -#define WLC_E_EXTLOG_MSG 58 -#define WLC_E_ACTION_FRAME 59 -#define WLC_E_ACTION_FRAME_COMPLETE 60 -#define WLC_E_PRE_ASSOC_IND 61 -#define WLC_E_PRE_REASSOC_IND 62 -#define WLC_E_CHANNEL_ADOPTED 63 -#define WLC_E_AP_STARTED 64 -#define WLC_E_DFS_AP_STOP 65 -#define WLC_E_DFS_AP_RESUME 66 -#define WLC_E_RESERVED1 67 -#define WLC_E_RESERVED2 68 -#define WLC_E_ESCAN_RESULT 69 -#define WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 -#define WLC_E_DCS_REQUEST 73 - -#define WLC_E_FIFO_CREDIT_MAP 74 - -#define WLC_E_LAST 75 - -typedef struct { - uint event; - const char *name; -} bcmevent_name_t; - -extern const bcmevent_name_t bcmevent_names[]; -extern const int bcmevent_names_size; - -#define WLC_E_STATUS_SUCCESS 0 -#define WLC_E_STATUS_FAIL 1 -#define WLC_E_STATUS_TIMEOUT 2 -#define WLC_E_STATUS_NO_NETWORKS 3 -#define WLC_E_STATUS_ABORT 4 -#define WLC_E_STATUS_NO_ACK 5 -#define WLC_E_STATUS_UNSOLICITED 6 -#define WLC_E_STATUS_ATTEMPT 7 -#define WLC_E_STATUS_PARTIAL 8 -#define WLC_E_STATUS_NEWSCAN 9 -#define WLC_E_STATUS_NEWASSOC 10 -#define WLC_E_STATUS_11HQUIET 11 -#define WLC_E_STATUS_SUPPRESS 12 -#define WLC_E_STATUS_NOCHANS 13 -#define WLC_E_STATUS_CS_ABORT 15 -#define WLC_E_STATUS_ERROR 16 - -#define WLC_E_REASON_INITIAL_ASSOC 0 -#define WLC_E_REASON_LOW_RSSI 1 -#define WLC_E_REASON_DEAUTH 2 -#define WLC_E_REASON_DISASSOC 3 -#define WLC_E_REASON_BCNS_LOST 4 -#define WLC_E_REASON_MINTXRATE 9 -#define WLC_E_REASON_TXFAIL 10 - -#define WLC_E_REASON_FAST_ROAM_FAILED 5 -#define WLC_E_REASON_DIRECTED_ROAM 6 -#define WLC_E_REASON_TSPEC_REJECTED 7 -#define WLC_E_REASON_BETTER_AP 8 - -#define WLC_E_PRUNE_ENCR_MISMATCH 1 -#define WLC_E_PRUNE_BCAST_BSSID 2 -#define WLC_E_PRUNE_MAC_DENY 3 -#define WLC_E_PRUNE_MAC_NA 4 -#define WLC_E_PRUNE_REG_PASSV 5 -#define WLC_E_PRUNE_SPCT_MGMT 6 -#define WLC_E_PRUNE_RADAR 7 -#define WLC_E_RSN_MISMATCH 8 -#define WLC_E_PRUNE_NO_COMMON_RATES 9 -#define WLC_E_PRUNE_BASIC_RATES 10 -#define WLC_E_PRUNE_CIPHER_NA 12 -#define WLC_E_PRUNE_KNOWN_STA 13 -#define WLC_E_PRUNE_WDS_PEER 15 -#define WLC_E_PRUNE_QBSS_LOAD 16 -#define WLC_E_PRUNE_HOME_AP 17 - -#define WLC_E_SUP_OTHER 0 -#define WLC_E_SUP_DECRYPT_KEY_DATA 1 -#define WLC_E_SUP_BAD_UCAST_WEP128 2 -#define WLC_E_SUP_BAD_UCAST_WEP40 3 -#define WLC_E_SUP_UNSUP_KEY_LEN 4 -#define WLC_E_SUP_PW_KEY_CIPHER 5 -#define WLC_E_SUP_MSG3_TOO_MANY_IE 6 -#define WLC_E_SUP_MSG3_IE_MISMATCH 7 -#define WLC_E_SUP_NO_INSTALL_FLAG 8 -#define WLC_E_SUP_MSG3_NO_GTK 9 -#define WLC_E_SUP_GRP_KEY_CIPHER 10 -#define WLC_E_SUP_GRP_MSG1_NO_GTK 11 -#define WLC_E_SUP_GTK_DECRYPT_FAIL 12 -#define WLC_E_SUP_SEND_FAIL 13 -#define WLC_E_SUP_DEAUTH 14 - -#define WLC_E_IF_ADD 1 -#define WLC_E_IF_DEL 2 -#define WLC_E_IF_CHANGE 3 - -#define WLC_E_IF_ROLE_STA 0 -#define WLC_E_IF_ROLE_AP 1 -#define WLC_E_IF_ROLE_WDS 2 - -#define WLC_E_LINK_BCN_LOSS 1 -#define WLC_E_LINK_DISASSOC 2 -#define WLC_E_LINK_ASSOC_REC 3 -#define WLC_E_LINK_BSSCFG_DIS 4 - -#endif /* _BCMEVENT_H_ */ diff --git a/drivers/staging/brcm80211/include/sbchipc.h b/drivers/staging/brcm80211/include/sbchipc.h deleted file mode 100644 index 8c01c638ab8d..000000000000 --- a/drivers/staging/brcm80211/include/sbchipc.h +++ /dev/null @@ -1,1588 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SBCHIPC_H -#define _SBCHIPC_H - -#ifndef _LANGUAGE_ASSEMBLY - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif /* PAD */ - -typedef volatile struct { - u32 chipid; /* 0x0 */ - u32 capabilities; - u32 corecontrol; /* corerev >= 1 */ - u32 bist; - - /* OTP */ - u32 otpstatus; /* 0x10, corerev >= 10 */ - u32 otpcontrol; - u32 otpprog; - u32 otplayout; /* corerev >= 23 */ - - /* Interrupt control */ - u32 intstatus; /* 0x20 */ - u32 intmask; - - /* Chip specific regs */ - u32 chipcontrol; /* 0x28, rev >= 11 */ - u32 chipstatus; /* 0x2c, rev >= 11 */ - - /* Jtag Master */ - u32 jtagcmd; /* 0x30, rev >= 10 */ - u32 jtagir; - u32 jtagdr; - u32 jtagctrl; - - /* serial flash interface registers */ - u32 flashcontrol; /* 0x40 */ - u32 flashaddress; - u32 flashdata; - u32 PAD[1]; - - /* Silicon backplane configuration broadcast control */ - u32 broadcastaddress; /* 0x50 */ - u32 broadcastdata; - - /* gpio - cleared only by power-on-reset */ - u32 gpiopullup; /* 0x58, corerev >= 20 */ - u32 gpiopulldown; /* 0x5c, corerev >= 20 */ - u32 gpioin; /* 0x60 */ - u32 gpioout; /* 0x64 */ - u32 gpioouten; /* 0x68 */ - u32 gpiocontrol; /* 0x6C */ - u32 gpiointpolarity; /* 0x70 */ - u32 gpiointmask; /* 0x74 */ - - /* GPIO events corerev >= 11 */ - u32 gpioevent; - u32 gpioeventintmask; - - /* Watchdog timer */ - u32 watchdog; /* 0x80 */ - - /* GPIO events corerev >= 11 */ - u32 gpioeventintpolarity; - - /* GPIO based LED powersave registers corerev >= 16 */ - u32 gpiotimerval; /* 0x88 */ - u32 gpiotimeroutmask; - - /* clock control */ - u32 clockcontrol_n; /* 0x90 */ - u32 clockcontrol_sb; /* aka m0 */ - u32 clockcontrol_pci; /* aka m1 */ - u32 clockcontrol_m2; /* mii/uart/mipsref */ - u32 clockcontrol_m3; /* cpu */ - u32 clkdiv; /* corerev >= 3 */ - u32 gpiodebugsel; /* corerev >= 28 */ - u32 capabilities_ext; /* 0xac */ - - /* pll delay registers (corerev >= 4) */ - u32 pll_on_delay; /* 0xb0 */ - u32 fref_sel_delay; - u32 slow_clk_ctl; /* 5 < corerev < 10 */ - u32 PAD; - - /* Instaclock registers (corerev >= 10) */ - u32 system_clk_ctl; /* 0xc0 */ - u32 clkstatestretch; - u32 PAD[2]; - - /* Indirect backplane access (corerev >= 22) */ - u32 bp_addrlow; /* 0xd0 */ - u32 bp_addrhigh; - u32 bp_data; - u32 PAD; - u32 bp_indaccess; - u32 PAD[3]; - - /* More clock dividers (corerev >= 32) */ - u32 clkdiv2; - u32 PAD[2]; - - /* In AI chips, pointer to erom */ - u32 eromptr; /* 0xfc */ - - /* ExtBus control registers (corerev >= 3) */ - u32 pcmcia_config; /* 0x100 */ - u32 pcmcia_memwait; - u32 pcmcia_attrwait; - u32 pcmcia_iowait; - u32 ide_config; - u32 ide_memwait; - u32 ide_attrwait; - u32 ide_iowait; - u32 prog_config; - u32 prog_waitcount; - u32 flash_config; - u32 flash_waitcount; - u32 SECI_config; /* 0x130 SECI configuration */ - u32 PAD[3]; - - /* Enhanced Coexistence Interface (ECI) registers (corerev >= 21) */ - u32 eci_output; /* 0x140 */ - u32 eci_control; - u32 eci_inputlo; - u32 eci_inputmi; - u32 eci_inputhi; - u32 eci_inputintpolaritylo; - u32 eci_inputintpolaritymi; - u32 eci_inputintpolarityhi; - u32 eci_intmasklo; - u32 eci_intmaskmi; - u32 eci_intmaskhi; - u32 eci_eventlo; - u32 eci_eventmi; - u32 eci_eventhi; - u32 eci_eventmasklo; - u32 eci_eventmaskmi; - u32 eci_eventmaskhi; - u32 PAD[3]; - - /* SROM interface (corerev >= 32) */ - u32 sromcontrol; /* 0x190 */ - u32 sromaddress; - u32 sromdata; - u32 PAD[17]; - - /* Clock control and hardware workarounds (corerev >= 20) */ - u32 clk_ctl_st; /* 0x1e0 */ - u32 hw_war; - u32 PAD[70]; - - /* UARTs */ - u8 uart0data; /* 0x300 */ - u8 uart0imr; - u8 uart0fcr; - u8 uart0lcr; - u8 uart0mcr; - u8 uart0lsr; - u8 uart0msr; - u8 uart0scratch; - u8 PAD[248]; /* corerev >= 1 */ - - u8 uart1data; /* 0x400 */ - u8 uart1imr; - u8 uart1fcr; - u8 uart1lcr; - u8 uart1mcr; - u8 uart1lsr; - u8 uart1msr; - u8 uart1scratch; - u32 PAD[126]; - - /* PMU registers (corerev >= 20) */ - u32 pmucontrol; /* 0x600 */ - u32 pmucapabilities; - u32 pmustatus; - u32 res_state; - u32 res_pending; - u32 pmutimer; - u32 min_res_mask; - u32 max_res_mask; - u32 res_table_sel; - u32 res_dep_mask; - u32 res_updn_timer; - u32 res_timer; - u32 clkstretch; - u32 pmuwatchdog; - u32 gpiosel; /* 0x638, rev >= 1 */ - u32 gpioenable; /* 0x63c, rev >= 1 */ - u32 res_req_timer_sel; - u32 res_req_timer; - u32 res_req_mask; - u32 PAD; - u32 chipcontrol_addr; /* 0x650 */ - u32 chipcontrol_data; /* 0x654 */ - u32 regcontrol_addr; - u32 regcontrol_data; - u32 pllcontrol_addr; - u32 pllcontrol_data; - u32 pmustrapopt; /* 0x668, corerev >= 28 */ - u32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */ - u32 PAD[100]; - u16 sromotp[768]; -} chipcregs_t; - -#endif /* _LANGUAGE_ASSEMBLY */ - -#if defined(__BIG_ENDIAN) && defined(BCMHND74K) -/* Selective swapped defines for those registers we need in - * big-endian code. - */ -#define CC_CHIPID 4 -#define CC_CAPABILITIES 0 -#define CC_CHIPST 0x28 -#define CC_EROMPTR 0xf8 - -#else /* !__BIG_ENDIAN || !BCMHND74K */ - -#define CC_CHIPID 0 -#define CC_CAPABILITIES 4 -#define CC_CHIPST 0x2c -#define CC_EROMPTR 0xfc - -#endif /* __BIG_ENDIAN && BCMHND74K */ - -#define CC_OTPST 0x10 -#define CC_JTAGCMD 0x30 -#define CC_JTAGIR 0x34 -#define CC_JTAGDR 0x38 -#define CC_JTAGCTRL 0x3c -#define CC_GPIOPU 0x58 -#define CC_GPIOPD 0x5c -#define CC_GPIOIN 0x60 -#define CC_GPIOOUT 0x64 -#define CC_GPIOOUTEN 0x68 -#define CC_GPIOCTRL 0x6c -#define CC_GPIOPOL 0x70 -#define CC_GPIOINTM 0x74 -#define CC_WATCHDOG 0x80 -#define CC_CLKC_N 0x90 -#define CC_CLKC_M0 0x94 -#define CC_CLKC_M1 0x98 -#define CC_CLKC_M2 0x9c -#define CC_CLKC_M3 0xa0 -#define CC_CLKDIV 0xa4 -#define CC_SYS_CLK_CTL 0xc0 -#define CC_CLK_CTL_ST SI_CLK_CTL_ST -#define PMU_CTL 0x600 -#define PMU_CAP 0x604 -#define PMU_ST 0x608 -#define PMU_RES_STATE 0x60c -#define PMU_TIMER 0x614 -#define PMU_MIN_RES_MASK 0x618 -#define PMU_MAX_RES_MASK 0x61c -#define CC_CHIPCTL_ADDR 0x650 -#define CC_CHIPCTL_DATA 0x654 -#define PMU_REG_CONTROL_ADDR 0x658 -#define PMU_REG_CONTROL_DATA 0x65C -#define PMU_PLL_CONTROL_ADDR 0x660 -#define PMU_PLL_CONTROL_DATA 0x664 -#define CC_SROM_OTP 0x800 /* SROM/OTP address space */ - -/* chipid */ -#define CID_ID_MASK 0x0000ffff /* Chip Id mask */ -#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */ -#define CID_REV_SHIFT 16 /* Chip Revision shift */ -#define CID_PKG_MASK 0x00f00000 /* Package Option mask */ -#define CID_PKG_SHIFT 20 /* Package Option shift */ -#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */ -#define CID_CC_SHIFT 24 -#define CID_TYPE_MASK 0xf0000000 /* Chip Type */ -#define CID_TYPE_SHIFT 28 - -/* capabilities */ -#define CC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */ -#define CC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */ -#define CC_CAP_UCLKSEL 0x00000018 /* UARTs clock select */ -#define CC_CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */ -#define CC_CAP_UARTGPIO 0x00000020 /* UARTs own GPIOs 15:12 */ -#define CC_CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */ -#define CC_CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */ -#define CC_CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */ -#define CC_CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */ -#define CC_CAP_FLASH_MASK 0x00000700 /* Type of flash */ -#define CC_CAP_PLL_MASK 0x00038000 /* Type of PLL */ -#define CC_CAP_PWR_CTL 0x00040000 /* Power control */ -#define CC_CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */ -#define CC_CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */ -#define CC_CAP_OTPSIZE_BASE 5 /* OTP Size base */ -#define CC_CAP_JTAGP 0x00400000 /* JTAG Master Present */ -#define CC_CAP_ROM 0x00800000 /* Internal boot rom active */ -#define CC_CAP_BKPLN64 0x08000000 /* 64-bit backplane */ -#define CC_CAP_PMU 0x10000000 /* PMU Present, rev >= 20 */ -#define CC_CAP_SROM 0x40000000 /* Srom Present, rev >= 32 */ -#define CC_CAP_NFLASH 0x80000000 /* Nand flash present, rev >= 35 */ - -#define CC_CAP2_SECI 0x00000001 /* SECI Present, rev >= 36 */ -#define CC_CAP2_GSIO 0x00000002 /* GSIO (spi/i2c) present, rev >= 37 */ - -/* PLL type */ -#define PLL_NONE 0x00000000 -#define PLL_TYPE1 0x00010000 /* 48MHz base, 3 dividers */ -#define PLL_TYPE2 0x00020000 /* 48MHz, 4 dividers */ -#define PLL_TYPE3 0x00030000 /* 25MHz, 2 dividers */ -#define PLL_TYPE4 0x00008000 /* 48MHz, 4 dividers */ -#define PLL_TYPE5 0x00018000 /* 25MHz, 4 dividers */ -#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */ -#define PLL_TYPE7 0x00038000 /* 25MHz, 4 dividers */ - -/* ILP clock */ -#define ILP_CLOCK 32000 - -/* ALP clock on pre-PMU chips */ -#define ALP_CLOCK 20000000 - -/* HT clock */ -#define HT_CLOCK 80000000 - -/* corecontrol */ -#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */ -#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ -#define CC_UARTCLKEN 0x00000008 /* enable UART Clock (corerev > = 21 */ - -/* chipcontrol */ -#define CHIPCTRL_4321A0_DEFAULT 0x3a4 -#define CHIPCTRL_4321A1_DEFAULT 0x0a4 -#define CHIPCTRL_4321_PLL_DOWN 0x800000 /* serdes PLL down override */ - -/* Fields in the otpstatus register in rev >= 21 */ -#define OTPS_OL_MASK 0x000000ff -#define OTPS_OL_MFG 0x00000001 /* manuf row is locked */ -#define OTPS_OL_OR1 0x00000002 /* otp redundancy row 1 is locked */ -#define OTPS_OL_OR2 0x00000004 /* otp redundancy row 2 is locked */ -#define OTPS_OL_GU 0x00000008 /* general use region is locked */ -#define OTPS_GUP_MASK 0x00000f00 -#define OTPS_GUP_SHIFT 8 -#define OTPS_GUP_HW 0x00000100 /* h/w subregion is programmed */ -#define OTPS_GUP_SW 0x00000200 /* s/w subregion is programmed */ -#define OTPS_GUP_CI 0x00000400 /* chipid/pkgopt subregion is programmed */ -#define OTPS_GUP_FUSE 0x00000800 /* fuse subregion is programmed */ -#define OTPS_READY 0x00001000 -#define OTPS_RV(x) (1 << (16 + (x))) /* redundancy entry valid */ -#define OTPS_RV_MASK 0x0fff0000 - -/* Fields in the otpcontrol register in rev >= 21 */ -#define OTPC_PROGSEL 0x00000001 -#define OTPC_PCOUNT_MASK 0x0000000e -#define OTPC_PCOUNT_SHIFT 1 -#define OTPC_VSEL_MASK 0x000000f0 -#define OTPC_VSEL_SHIFT 4 -#define OTPC_TMM_MASK 0x00000700 -#define OTPC_TMM_SHIFT 8 -#define OTPC_ODM 0x00000800 -#define OTPC_PROGEN 0x80000000 - -/* Fields in otpprog in rev >= 21 and HND OTP */ -#define OTPP_COL_MASK 0x000000ff -#define OTPP_COL_SHIFT 0 -#define OTPP_ROW_MASK 0x0000ff00 -#define OTPP_ROW_SHIFT 8 -#define OTPP_OC_MASK 0x0f000000 -#define OTPP_OC_SHIFT 24 -#define OTPP_READERR 0x10000000 -#define OTPP_VALUE_MASK 0x20000000 -#define OTPP_VALUE_SHIFT 29 -#define OTPP_START_BUSY 0x80000000 -#define OTPP_READ 0x40000000 /* HND OTP */ - -/* otplayout reg corerev >= 36 */ -#define OTP_CISFORMAT_NEW 0x80000000 - -/* Opcodes for OTPP_OC field */ -#define OTPPOC_READ 0 -#define OTPPOC_BIT_PROG 1 -#define OTPPOC_VERIFY 3 -#define OTPPOC_INIT 4 -#define OTPPOC_SET 5 -#define OTPPOC_RESET 6 -#define OTPPOC_OCST 7 -#define OTPPOC_ROW_LOCK 8 -#define OTPPOC_PRESCN_TEST 9 - -/* Jtagm characteristics that appeared at a given corerev */ -#define JTAGM_CREV_OLD 10 /* Old command set, 16bit max IR */ -#define JTAGM_CREV_IRP 22 /* Able to do pause-ir */ -#define JTAGM_CREV_RTI 28 /* Able to do return-to-idle */ - -/* jtagcmd */ -#define JCMD_START 0x80000000 -#define JCMD_BUSY 0x80000000 -#define JCMD_STATE_MASK 0x60000000 -#define JCMD_STATE_TLR 0x00000000 /* Test-logic-reset */ -#define JCMD_STATE_PIR 0x20000000 /* Pause IR */ -#define JCMD_STATE_PDR 0x40000000 /* Pause DR */ -#define JCMD_STATE_RTI 0x60000000 /* Run-test-idle */ -#define JCMD0_ACC_MASK 0x0000f000 -#define JCMD0_ACC_IRDR 0x00000000 -#define JCMD0_ACC_DR 0x00001000 -#define JCMD0_ACC_IR 0x00002000 -#define JCMD0_ACC_RESET 0x00003000 -#define JCMD0_ACC_IRPDR 0x00004000 -#define JCMD0_ACC_PDR 0x00005000 -#define JCMD0_IRW_MASK 0x00000f00 -#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */ -#define JCMD_ACC_IRDR 0x00000000 -#define JCMD_ACC_DR 0x00010000 -#define JCMD_ACC_IR 0x00020000 -#define JCMD_ACC_RESET 0x00030000 -#define JCMD_ACC_IRPDR 0x00040000 -#define JCMD_ACC_PDR 0x00050000 -#define JCMD_ACC_PIR 0x00060000 -#define JCMD_ACC_IRDR_I 0x00070000 /* rev 28: return to run-test-idle */ -#define JCMD_ACC_DR_I 0x00080000 /* rev 28: return to run-test-idle */ -#define JCMD_IRW_MASK 0x00001f00 -#define JCMD_IRW_SHIFT 8 -#define JCMD_DRW_MASK 0x0000003f - -/* jtagctrl */ -#define JCTRL_FORCE_CLK 4 /* Force clock */ -#define JCTRL_EXT_EN 2 /* Enable external targets */ -#define JCTRL_EN 1 /* Enable Jtag master */ - -/* Fields in clkdiv */ -#define CLKD_SFLASH 0x0f000000 -#define CLKD_SFLASH_SHIFT 24 -#define CLKD_OTP 0x000f0000 -#define CLKD_OTP_SHIFT 16 -#define CLKD_JTAG 0x00000f00 -#define CLKD_JTAG_SHIFT 8 -#define CLKD_UART 0x000000ff - -#define CLKD2_SROM 0x00000003 - -/* intstatus/intmask */ -#define CI_GPIO 0x00000001 /* gpio intr */ -#define CI_EI 0x00000002 /* extif intr (corerev >= 3) */ -#define CI_TEMP 0x00000004 /* temp. ctrl intr (corerev >= 15) */ -#define CI_SIRQ 0x00000008 /* serial IRQ intr (corerev >= 15) */ -#define CI_PMU 0x00000020 /* pmu intr (corerev >= 21) */ -#define CI_UART 0x00000040 /* uart intr (corerev >= 21) */ -#define CI_WDRESET 0x80000000 /* watchdog reset occurred */ - -/* slow_clk_ctl */ -#define SCC_SS_MASK 0x00000007 /* slow clock source mask */ -#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */ -#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */ -#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */ -#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ -#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, - * 0: LPO is enabled - */ -#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, - * 0: power logic control - */ -#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors - * PLL clock disable requests from core - */ -#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't - * disable crystal when appropriate - */ -#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ -#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ -#define SCC_CD_SHIFT 16 - -/* system_clk_ctl */ -#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */ -#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */ -#define SYCC_FP 0x00000004 /* ForcePLLOn */ -#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */ -#define SYCC_HR 0x00000010 /* Force HT */ -#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */ -#define SYCC_CD_SHIFT 16 - -/* Indirect backplane access */ -#define BPIA_BYTEEN 0x0000000f -#define BPIA_SZ1 0x00000001 -#define BPIA_SZ2 0x00000003 -#define BPIA_SZ4 0x00000007 -#define BPIA_SZ8 0x0000000f -#define BPIA_WRITE 0x00000100 -#define BPIA_START 0x00000200 -#define BPIA_BUSY 0x00000200 -#define BPIA_ERROR 0x00000400 - -/* pcmcia/prog/flash_config */ -#define CF_EN 0x00000001 /* enable */ -#define CF_EM_MASK 0x0000000e /* mode */ -#define CF_EM_SHIFT 1 -#define CF_EM_FLASH 0 /* flash/asynchronous mode */ -#define CF_EM_SYNC 2 /* synchronous mode */ -#define CF_EM_PCMCIA 4 /* pcmcia mode */ -#define CF_DS 0x00000010 /* destsize: 0=8bit, 1=16bit */ -#define CF_BS 0x00000020 /* byteswap */ -#define CF_CD_MASK 0x000000c0 /* clock divider */ -#define CF_CD_SHIFT 6 -#define CF_CD_DIV2 0x00000000 /* backplane/2 */ -#define CF_CD_DIV3 0x00000040 /* backplane/3 */ -#define CF_CD_DIV4 0x00000080 /* backplane/4 */ -#define CF_CE 0x00000100 /* clock enable */ -#define CF_SB 0x00000200 /* size/bytestrobe (synch only) */ - -/* pcmcia_memwait */ -#define PM_W0_MASK 0x0000003f /* waitcount0 */ -#define PM_W1_MASK 0x00001f00 /* waitcount1 */ -#define PM_W1_SHIFT 8 -#define PM_W2_MASK 0x001f0000 /* waitcount2 */ -#define PM_W2_SHIFT 16 -#define PM_W3_MASK 0x1f000000 /* waitcount3 */ -#define PM_W3_SHIFT 24 - -/* pcmcia_attrwait */ -#define PA_W0_MASK 0x0000003f /* waitcount0 */ -#define PA_W1_MASK 0x00001f00 /* waitcount1 */ -#define PA_W1_SHIFT 8 -#define PA_W2_MASK 0x001f0000 /* waitcount2 */ -#define PA_W2_SHIFT 16 -#define PA_W3_MASK 0x1f000000 /* waitcount3 */ -#define PA_W3_SHIFT 24 - -/* pcmcia_iowait */ -#define PI_W0_MASK 0x0000003f /* waitcount0 */ -#define PI_W1_MASK 0x00001f00 /* waitcount1 */ -#define PI_W1_SHIFT 8 -#define PI_W2_MASK 0x001f0000 /* waitcount2 */ -#define PI_W2_SHIFT 16 -#define PI_W3_MASK 0x1f000000 /* waitcount3 */ -#define PI_W3_SHIFT 24 - -/* prog_waitcount */ -#define PW_W0_MASK 0x0000001f /* waitcount0 */ -#define PW_W1_MASK 0x00001f00 /* waitcount1 */ -#define PW_W1_SHIFT 8 -#define PW_W2_MASK 0x001f0000 /* waitcount2 */ -#define PW_W2_SHIFT 16 -#define PW_W3_MASK 0x1f000000 /* waitcount3 */ -#define PW_W3_SHIFT 24 - -#define PW_W0 0x0000000c -#define PW_W1 0x00000a00 -#define PW_W2 0x00020000 -#define PW_W3 0x01000000 - -/* flash_waitcount */ -#define FW_W0_MASK 0x0000003f /* waitcount0 */ -#define FW_W1_MASK 0x00001f00 /* waitcount1 */ -#define FW_W1_SHIFT 8 -#define FW_W2_MASK 0x001f0000 /* waitcount2 */ -#define FW_W2_SHIFT 16 -#define FW_W3_MASK 0x1f000000 /* waitcount3 */ -#define FW_W3_SHIFT 24 - -/* When Srom support present, fields in sromcontrol */ -#define SRC_START 0x80000000 -#define SRC_BUSY 0x80000000 -#define SRC_OPCODE 0x60000000 -#define SRC_OP_READ 0x00000000 -#define SRC_OP_WRITE 0x20000000 -#define SRC_OP_WRDIS 0x40000000 -#define SRC_OP_WREN 0x60000000 -#define SRC_OTPSEL 0x00000010 -#define SRC_LOCK 0x00000008 -#define SRC_SIZE_MASK 0x00000006 -#define SRC_SIZE_1K 0x00000000 -#define SRC_SIZE_4K 0x00000002 -#define SRC_SIZE_16K 0x00000004 -#define SRC_SIZE_SHIFT 1 -#define SRC_PRESENT 0x00000001 - -/* Fields in pmucontrol */ -#define PCTL_ILP_DIV_MASK 0xffff0000 -#define PCTL_ILP_DIV_SHIFT 16 -#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */ -#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */ -#define PCTL_HT_REQ_EN 0x00000100 -#define PCTL_ALP_REQ_EN 0x00000080 -#define PCTL_XTALFREQ_MASK 0x0000007c -#define PCTL_XTALFREQ_SHIFT 2 -#define PCTL_ILP_DIV_EN 0x00000002 -#define PCTL_LPO_SEL 0x00000001 - -/* Fields in clkstretch */ -#define CSTRETCH_HT 0xffff0000 -#define CSTRETCH_ALP 0x0000ffff - -/* gpiotimerval */ -#define GPIO_ONTIME_SHIFT 16 - -/* clockcontrol_n */ -#define CN_N1_MASK 0x3f /* n1 control */ -#define CN_N2_MASK 0x3f00 /* n2 control */ -#define CN_N2_SHIFT 8 -#define CN_PLLC_MASK 0xf0000 /* pll control */ -#define CN_PLLC_SHIFT 16 - -/* clockcontrol_sb/pci/uart */ -#define CC_M1_MASK 0x3f /* m1 control */ -#define CC_M2_MASK 0x3f00 /* m2 control */ -#define CC_M2_SHIFT 8 -#define CC_M3_MASK 0x3f0000 /* m3 control */ -#define CC_M3_SHIFT 16 -#define CC_MC_MASK 0x1f000000 /* mux control */ -#define CC_MC_SHIFT 24 - -/* N3M Clock control magic field values */ -#define CC_F6_2 0x02 /* A factor of 2 in */ -#define CC_F6_3 0x03 /* 6-bit fields like */ -#define CC_F6_4 0x05 /* N1, M1 or M3 */ -#define CC_F6_5 0x09 -#define CC_F6_6 0x11 -#define CC_F6_7 0x21 - -#define CC_F5_BIAS 5 /* 5-bit fields get this added */ - -#define CC_MC_BYPASS 0x08 -#define CC_MC_M1 0x04 -#define CC_MC_M1M2 0x02 -#define CC_MC_M1M2M3 0x01 -#define CC_MC_M1M3 0x11 - -/* Type 2 Clock control magic field values */ -#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */ -#define CC_T2M2_BIAS 3 /* m2 bias */ - -#define CC_T2MC_M1BYP 1 -#define CC_T2MC_M2BYP 2 -#define CC_T2MC_M3BYP 4 - -/* Type 6 Clock control magic field values */ -#define CC_T6_MMASK 1 /* bits of interest in m */ -#define CC_T6_M0 120000000 /* sb clock for m = 0 */ -#define CC_T6_M1 100000000 /* sb clock for m = 1 */ -#define SB2MIPS_T6(sb) (2 * (sb)) - -/* Common clock base */ -#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */ -#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLLs */ - -/* Clock control values for 200MHz in 5350 */ -#define CLKC_5350_N 0x0311 -#define CLKC_5350_M 0x04020009 - -/* Flash types in the chipcommon capabilities register */ -#define FLASH_NONE 0x000 /* No flash */ -#define SFLASH_ST 0x100 /* ST serial flash */ -#define SFLASH_AT 0x200 /* Atmel serial flash */ -#define PFLASH 0x700 /* Parallel flash */ - -/* Bits in the ExtBus config registers */ -#define CC_CFG_EN 0x0001 /* Enable */ -#define CC_CFG_EM_MASK 0x000e /* Extif Mode */ -#define CC_CFG_EM_ASYNC 0x0000 /* Async/Parallel flash */ -#define CC_CFG_EM_SYNC 0x0002 /* Synchronous */ -#define CC_CFG_EM_PCMCIA 0x0004 /* PCMCIA */ -#define CC_CFG_EM_IDE 0x0006 /* IDE */ -#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */ -#define CC_CFG_CD_MASK 0x00e0 /* Sync: Clock divisor, rev >= 20 */ -#define CC_CFG_CE 0x0100 /* Sync: Clock enable, rev >= 20 */ -#define CC_CFG_SB 0x0200 /* Sync: Size/Bytestrobe, rev >= 20 */ -#define CC_CFG_IS 0x0400 /* Extif Sync Clk Select, rev >= 20 */ - -/* ExtBus address space */ -#define CC_EB_BASE 0x1a000000 /* Chipc ExtBus base address */ -#define CC_EB_PCMCIA_MEM 0x1a000000 /* PCMCIA 0 memory base address */ -#define CC_EB_PCMCIA_IO 0x1a200000 /* PCMCIA 0 I/O base address */ -#define CC_EB_PCMCIA_CFG 0x1a400000 /* PCMCIA 0 config base address */ -#define CC_EB_IDE 0x1a800000 /* IDE memory base */ -#define CC_EB_PCMCIA1_MEM 0x1a800000 /* PCMCIA 1 memory base address */ -#define CC_EB_PCMCIA1_IO 0x1aa00000 /* PCMCIA 1 I/O base address */ -#define CC_EB_PCMCIA1_CFG 0x1ac00000 /* PCMCIA 1 config base address */ -#define CC_EB_PROGIF 0x1b000000 /* ProgIF Async/Sync base address */ - -/* Start/busy bit in flashcontrol */ -#define SFLASH_OPCODE 0x000000ff -#define SFLASH_ACTION 0x00000700 -#define SFLASH_CS_ACTIVE 0x00001000 /* Chip Select Active, rev >= 20 */ -#define SFLASH_START 0x80000000 -#define SFLASH_BUSY SFLASH_START - -/* flashcontrol action codes */ -#define SFLASH_ACT_OPONLY 0x0000 /* Issue opcode only */ -#define SFLASH_ACT_OP1D 0x0100 /* opcode + 1 data byte */ -#define SFLASH_ACT_OP3A 0x0200 /* opcode + 3 addr bytes */ -#define SFLASH_ACT_OP3A1D 0x0300 /* opcode + 3 addr & 1 data bytes */ -#define SFLASH_ACT_OP3A4D 0x0400 /* opcode + 3 addr & 4 data bytes */ -#define SFLASH_ACT_OP3A4X4D 0x0500 /* opcode + 3 addr, 4 don't care & 4 data bytes */ -#define SFLASH_ACT_OP3A1X4D 0x0700 /* opcode + 3 addr, 1 don't care & 4 data bytes */ - -/* flashcontrol action+opcodes for ST flashes */ -#define SFLASH_ST_WREN 0x0006 /* Write Enable */ -#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */ -#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */ -#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */ -#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */ -#define SFLASH_ST_PP 0x0302 /* Page Program */ -#define SFLASH_ST_SE 0x02d8 /* Sector Erase */ -#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */ -#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */ -#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */ -#define SFLASH_ST_CSA 0x1000 /* Keep chip select asserted */ -#define SFLASH_ST_SSE 0x0220 /* Sub-sector Erase */ - -/* Status register bits for ST flashes */ -#define SFLASH_ST_WIP 0x01 /* Write In Progress */ -#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */ -#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */ -#define SFLASH_ST_BP_SHIFT 2 -#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */ - -/* flashcontrol action+opcodes for Atmel flashes */ -#define SFLASH_AT_READ 0x07e8 -#define SFLASH_AT_PAGE_READ 0x07d2 -#define SFLASH_AT_BUF1_READ -#define SFLASH_AT_BUF2_READ -#define SFLASH_AT_STATUS 0x01d7 -#define SFLASH_AT_BUF1_WRITE 0x0384 -#define SFLASH_AT_BUF2_WRITE 0x0387 -#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 -#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 -#define SFLASH_AT_BUF1_PROGRAM 0x0288 -#define SFLASH_AT_BUF2_PROGRAM 0x0289 -#define SFLASH_AT_PAGE_ERASE 0x0281 -#define SFLASH_AT_BLOCK_ERASE 0x0250 -#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 -#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 -#define SFLASH_AT_BUF1_LOAD 0x0253 -#define SFLASH_AT_BUF2_LOAD 0x0255 -#define SFLASH_AT_BUF1_COMPARE 0x0260 -#define SFLASH_AT_BUF2_COMPARE 0x0261 -#define SFLASH_AT_BUF1_REPROGRAM 0x0258 -#define SFLASH_AT_BUF2_REPROGRAM 0x0259 - -/* Status register bits for Atmel flashes */ -#define SFLASH_AT_READY 0x80 -#define SFLASH_AT_MISMATCH 0x40 -#define SFLASH_AT_ID_MASK 0x38 -#define SFLASH_AT_ID_SHIFT 3 - -/* - * These are the UART port assignments, expressed as offsets from the base - * register. These assignments should hold for any serial port based on - * a 8250, 16450, or 16550(A). - */ - -#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ -#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ -#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ -#define UART_IER 1 /* In/Out: Interrupt Enable Register (DLAB=0) */ -#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */ -#define UART_IIR 2 /* In: Interrupt Identity Register */ -#define UART_FCR 2 /* Out: FIFO Control Register */ -#define UART_LCR 3 /* Out: Line Control Register */ -#define UART_MCR 4 /* Out: Modem Control Register */ -#define UART_LSR 5 /* In: Line Status Register */ -#define UART_MSR 6 /* In: Modem Status Register */ -#define UART_SCR 7 /* I/O: Scratch Register */ -#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ -#define UART_LCR_WLEN8 0x03 /* Word length: 8 bits */ -#define UART_MCR_OUT2 0x08 /* MCR GPIO out 2 */ -#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ -#define UART_LSR_RX_FIFO 0x80 /* Receive FIFO error */ -#define UART_LSR_TDHR 0x40 /* Data-hold-register empty */ -#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ -#define UART_LSR_BREAK 0x10 /* Break interrupt */ -#define UART_LSR_FRAMING 0x08 /* Framing error */ -#define UART_LSR_PARITY 0x04 /* Parity error */ -#define UART_LSR_OVERRUN 0x02 /* Overrun error */ -#define UART_LSR_RXRDY 0x01 /* Receiver ready */ -#define UART_FCR_FIFO_ENABLE 1 /* FIFO control register bit controlling FIFO enable/disable */ - -/* Interrupt Identity Register (IIR) bits */ -#define UART_IIR_FIFO_MASK 0xc0 /* IIR FIFO disable/enabled mask */ -#define UART_IIR_INT_MASK 0xf /* IIR interrupt ID source */ -#define UART_IIR_MDM_CHG 0x0 /* Modem status changed */ -#define UART_IIR_NOINT 0x1 /* No interrupt pending */ -#define UART_IIR_THRE 0x2 /* THR empty */ -#define UART_IIR_RCVD_DATA 0x4 /* Received data available */ -#define UART_IIR_RCVR_STATUS 0x6 /* Receiver status */ -#define UART_IIR_CHAR_TIME 0xc /* Character time */ - -/* Interrupt Enable Register (IER) bits */ -#define UART_IER_EDSSI 8 /* enable modem status interrupt */ -#define UART_IER_ELSI 4 /* enable receiver line status interrupt */ -#define UART_IER_ETBEI 2 /* enable transmitter holding register empty interrupt */ -#define UART_IER_ERBFI 1 /* enable data available interrupt */ - -/* pmustatus */ -#define PST_EXTLPOAVAIL 0x0100 -#define PST_WDRESET 0x0080 -#define PST_INTPEND 0x0040 -#define PST_SBCLKST 0x0030 -#define PST_SBCLKST_ILP 0x0010 -#define PST_SBCLKST_ALP 0x0020 -#define PST_SBCLKST_HT 0x0030 -#define PST_ALPAVAIL 0x0008 -#define PST_HTAVAIL 0x0004 -#define PST_RESINIT 0x0003 - -/* pmucapabilities */ -#define PCAP_REV_MASK 0x000000ff -#define PCAP_RC_MASK 0x00001f00 -#define PCAP_RC_SHIFT 8 -#define PCAP_TC_MASK 0x0001e000 -#define PCAP_TC_SHIFT 13 -#define PCAP_PC_MASK 0x001e0000 -#define PCAP_PC_SHIFT 17 -#define PCAP_VC_MASK 0x01e00000 -#define PCAP_VC_SHIFT 21 -#define PCAP_CC_MASK 0x1e000000 -#define PCAP_CC_SHIFT 25 -#define PCAP5_PC_MASK 0x003e0000 /* PMU corerev >= 5 */ -#define PCAP5_PC_SHIFT 17 -#define PCAP5_VC_MASK 0x07c00000 -#define PCAP5_VC_SHIFT 22 -#define PCAP5_CC_MASK 0xf8000000 -#define PCAP5_CC_SHIFT 27 - -/* PMU Resource Request Timer registers */ -/* This is based on PmuRev0 */ -#define PRRT_TIME_MASK 0x03ff -#define PRRT_INTEN 0x0400 -#define PRRT_REQ_ACTIVE 0x0800 -#define PRRT_ALP_REQ 0x1000 -#define PRRT_HT_REQ 0x2000 - -/* PMU resource bit position */ -#define PMURES_BIT(bit) (1 << (bit)) - -/* PMU resource number limit */ -#define PMURES_MAX_RESNUM 30 - -/* PMU chip control0 register */ -#define PMU_CHIPCTL0 0 - -/* PMU chip control1 register */ -#define PMU_CHIPCTL1 1 -#define PMU_CC1_RXC_DLL_BYPASS 0x00010000 - -#define PMU_CC1_IF_TYPE_MASK 0x00000030 -#define PMU_CC1_IF_TYPE_RMII 0x00000000 -#define PMU_CC1_IF_TYPE_MII 0x00000010 -#define PMU_CC1_IF_TYPE_RGMII 0x00000020 - -#define PMU_CC1_SW_TYPE_MASK 0x000000c0 -#define PMU_CC1_SW_TYPE_EPHY 0x00000000 -#define PMU_CC1_SW_TYPE_EPHYMII 0x00000040 -#define PMU_CC1_SW_TYPE_EPHYRMII 0x00000080 -#define PMU_CC1_SW_TYPE_RGMII 0x000000c0 - -/* PMU corerev and chip specific PLL controls. - * PMU_PLL_XX where is PMU corerev and is an arbitrary number - * to differentiate different PLLs controlled by the same PMU rev. - */ -/* pllcontrol registers */ -/* PDIV, div_phy, div_arm, div_adc, dith_sel, ioff, kpd_scale, lsb_sel, mash_sel, lf_c & lf_r */ -#define PMU0_PLL0_PLLCTL0 0 -#define PMU0_PLL0_PC0_PDIV_MASK 1 -#define PMU0_PLL0_PC0_PDIV_FREQ 25000 -#define PMU0_PLL0_PC0_DIV_ARM_MASK 0x00000038 -#define PMU0_PLL0_PC0_DIV_ARM_SHIFT 3 -#define PMU0_PLL0_PC0_DIV_ARM_BASE 8 - -/* PC0_DIV_ARM for PLLOUT_ARM */ -#define PMU0_PLL0_PC0_DIV_ARM_110MHZ 0 -#define PMU0_PLL0_PC0_DIV_ARM_97_7MHZ 1 -#define PMU0_PLL0_PC0_DIV_ARM_88MHZ 2 -#define PMU0_PLL0_PC0_DIV_ARM_80MHZ 3 /* Default */ -#define PMU0_PLL0_PC0_DIV_ARM_73_3MHZ 4 -#define PMU0_PLL0_PC0_DIV_ARM_67_7MHZ 5 -#define PMU0_PLL0_PC0_DIV_ARM_62_9MHZ 6 -#define PMU0_PLL0_PC0_DIV_ARM_58_6MHZ 7 - -/* Wildcard base, stop_mod, en_lf_tp, en_cal & lf_r2 */ -#define PMU0_PLL0_PLLCTL1 1 -#define PMU0_PLL0_PC1_WILD_INT_MASK 0xf0000000 -#define PMU0_PLL0_PC1_WILD_INT_SHIFT 28 -#define PMU0_PLL0_PC1_WILD_FRAC_MASK 0x0fffff00 -#define PMU0_PLL0_PC1_WILD_FRAC_SHIFT 8 -#define PMU0_PLL0_PC1_STOP_MOD 0x00000040 - -/* Wildcard base, vco_calvar, vco_swc, vco_var_selref, vso_ical & vco_sel_avdd */ -#define PMU0_PLL0_PLLCTL2 2 -#define PMU0_PLL0_PC2_WILD_INT_MASK 0xf -#define PMU0_PLL0_PC2_WILD_INT_SHIFT 4 - -/* pllcontrol registers */ -/* ndiv_pwrdn, pwrdn_ch, refcomp_pwrdn, dly_ch, p1div, p2div, _bypass_sdmod */ -#define PMU1_PLL0_PLLCTL0 0 -#define PMU1_PLL0_PC0_P1DIV_MASK 0x00f00000 -#define PMU1_PLL0_PC0_P1DIV_SHIFT 20 -#define PMU1_PLL0_PC0_P2DIV_MASK 0x0f000000 -#define PMU1_PLL0_PC0_P2DIV_SHIFT 24 - -/* mdiv */ -#define PMU1_PLL0_PLLCTL1 1 -#define PMU1_PLL0_PC1_M1DIV_MASK 0x000000ff -#define PMU1_PLL0_PC1_M1DIV_SHIFT 0 -#define PMU1_PLL0_PC1_M2DIV_MASK 0x0000ff00 -#define PMU1_PLL0_PC1_M2DIV_SHIFT 8 -#define PMU1_PLL0_PC1_M3DIV_MASK 0x00ff0000 -#define PMU1_PLL0_PC1_M3DIV_SHIFT 16 -#define PMU1_PLL0_PC1_M4DIV_MASK 0xff000000 -#define PMU1_PLL0_PC1_M4DIV_SHIFT 24 - -#define DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT 8 -#define DOT11MAC_880MHZ_CLK_DIVISOR_MASK (0xFF << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) -#define DOT11MAC_880MHZ_CLK_DIVISOR_VAL (0xE << DOT11MAC_880MHZ_CLK_DIVISOR_SHIFT) - -/* mdiv, ndiv_dither_mfb, ndiv_mode, ndiv_int */ -#define PMU1_PLL0_PLLCTL2 2 -#define PMU1_PLL0_PC2_M5DIV_MASK 0x000000ff -#define PMU1_PLL0_PC2_M5DIV_SHIFT 0 -#define PMU1_PLL0_PC2_M6DIV_MASK 0x0000ff00 -#define PMU1_PLL0_PC2_M6DIV_SHIFT 8 -#define PMU1_PLL0_PC2_NDIV_MODE_MASK 0x000e0000 -#define PMU1_PLL0_PC2_NDIV_MODE_SHIFT 17 -#define PMU1_PLL0_PC2_NDIV_MODE_MASH 1 -#define PMU1_PLL0_PC2_NDIV_MODE_MFB 2 /* recommended for 4319 */ -#define PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000 -#define PMU1_PLL0_PC2_NDIV_INT_SHIFT 20 - -/* ndiv_frac */ -#define PMU1_PLL0_PLLCTL3 3 -#define PMU1_PLL0_PC3_NDIV_FRAC_MASK 0x00ffffff -#define PMU1_PLL0_PC3_NDIV_FRAC_SHIFT 0 - -/* pll_ctrl */ -#define PMU1_PLL0_PLLCTL4 4 - -/* pll_ctrl, vco_rng, clkdrive_ch */ -#define PMU1_PLL0_PLLCTL5 5 -#define PMU1_PLL0_PC5_CLK_DRV_MASK 0xffffff00 -#define PMU1_PLL0_PC5_CLK_DRV_SHIFT 8 - -/* PMU rev 2 control words */ -#define PMU2_PHY_PLL_PLLCTL 4 -#define PMU2_SI_PLL_PLLCTL 10 - -/* PMU rev 2 */ -/* pllcontrol registers */ -/* ndiv_pwrdn, pwrdn_ch, refcomp_pwrdn, dly_ch, p1div, p2div, _bypass_sdmod */ -#define PMU2_PLL_PLLCTL0 0 -#define PMU2_PLL_PC0_P1DIV_MASK 0x00f00000 -#define PMU2_PLL_PC0_P1DIV_SHIFT 20 -#define PMU2_PLL_PC0_P2DIV_MASK 0x0f000000 -#define PMU2_PLL_PC0_P2DIV_SHIFT 24 - -/* mdiv */ -#define PMU2_PLL_PLLCTL1 1 -#define PMU2_PLL_PC1_M1DIV_MASK 0x000000ff -#define PMU2_PLL_PC1_M1DIV_SHIFT 0 -#define PMU2_PLL_PC1_M2DIV_MASK 0x0000ff00 -#define PMU2_PLL_PC1_M2DIV_SHIFT 8 -#define PMU2_PLL_PC1_M3DIV_MASK 0x00ff0000 -#define PMU2_PLL_PC1_M3DIV_SHIFT 16 -#define PMU2_PLL_PC1_M4DIV_MASK 0xff000000 -#define PMU2_PLL_PC1_M4DIV_SHIFT 24 - -/* mdiv, ndiv_dither_mfb, ndiv_mode, ndiv_int */ -#define PMU2_PLL_PLLCTL2 2 -#define PMU2_PLL_PC2_M5DIV_MASK 0x000000ff -#define PMU2_PLL_PC2_M5DIV_SHIFT 0 -#define PMU2_PLL_PC2_M6DIV_MASK 0x0000ff00 -#define PMU2_PLL_PC2_M6DIV_SHIFT 8 -#define PMU2_PLL_PC2_NDIV_MODE_MASK 0x000e0000 -#define PMU2_PLL_PC2_NDIV_MODE_SHIFT 17 -#define PMU2_PLL_PC2_NDIV_INT_MASK 0x1ff00000 -#define PMU2_PLL_PC2_NDIV_INT_SHIFT 20 - -/* ndiv_frac */ -#define PMU2_PLL_PLLCTL3 3 -#define PMU2_PLL_PC3_NDIV_FRAC_MASK 0x00ffffff -#define PMU2_PLL_PC3_NDIV_FRAC_SHIFT 0 - -/* pll_ctrl */ -#define PMU2_PLL_PLLCTL4 4 - -/* pll_ctrl, vco_rng, clkdrive_ch */ -#define PMU2_PLL_PLLCTL5 5 -#define PMU2_PLL_PC5_CLKDRIVE_CH1_MASK 0x00000f00 -#define PMU2_PLL_PC5_CLKDRIVE_CH1_SHIFT 8 -#define PMU2_PLL_PC5_CLKDRIVE_CH2_MASK 0x0000f000 -#define PMU2_PLL_PC5_CLKDRIVE_CH2_SHIFT 12 -#define PMU2_PLL_PC5_CLKDRIVE_CH3_MASK 0x000f0000 -#define PMU2_PLL_PC5_CLKDRIVE_CH3_SHIFT 16 -#define PMU2_PLL_PC5_CLKDRIVE_CH4_MASK 0x00f00000 -#define PMU2_PLL_PC5_CLKDRIVE_CH4_SHIFT 20 -#define PMU2_PLL_PC5_CLKDRIVE_CH5_MASK 0x0f000000 -#define PMU2_PLL_PC5_CLKDRIVE_CH5_SHIFT 24 -#define PMU2_PLL_PC5_CLKDRIVE_CH6_MASK 0xf0000000 -#define PMU2_PLL_PC5_CLKDRIVE_CH6_SHIFT 28 - -/* PMU rev 5 (& 6) */ -#define PMU5_PLL_P1P2_OFF 0 -#define PMU5_PLL_P1_MASK 0x0f000000 -#define PMU5_PLL_P1_SHIFT 24 -#define PMU5_PLL_P2_MASK 0x00f00000 -#define PMU5_PLL_P2_SHIFT 20 -#define PMU5_PLL_M14_OFF 1 -#define PMU5_PLL_MDIV_MASK 0x000000ff -#define PMU5_PLL_MDIV_WIDTH 8 -#define PMU5_PLL_NM5_OFF 2 -#define PMU5_PLL_NDIV_MASK 0xfff00000 -#define PMU5_PLL_NDIV_SHIFT 20 -#define PMU5_PLL_NDIV_MODE_MASK 0x000e0000 -#define PMU5_PLL_NDIV_MODE_SHIFT 17 -#define PMU5_PLL_FMAB_OFF 3 -#define PMU5_PLL_MRAT_MASK 0xf0000000 -#define PMU5_PLL_MRAT_SHIFT 28 -#define PMU5_PLL_ABRAT_MASK 0x08000000 -#define PMU5_PLL_ABRAT_SHIFT 27 -#define PMU5_PLL_FDIV_MASK 0x07ffffff -#define PMU5_PLL_PLLCTL_OFF 4 -#define PMU5_PLL_PCHI_OFF 5 -#define PMU5_PLL_PCHI_MASK 0x0000003f - -/* pmu XtalFreqRatio */ -#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF -#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000 -#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31 - -/* Divider allocation in 4716/47162/5356/5357 */ -#define PMU5_MAINPLL_CPU 1 -#define PMU5_MAINPLL_MEM 2 -#define PMU5_MAINPLL_SI 3 - -#define PMU7_PLL_PLLCTL7 7 -#define PMU7_PLL_PLLCTL8 8 -#define PMU7_PLL_PLLCTL11 11 - -/* PLL usage in 4716/47162 */ -#define PMU4716_MAINPLL_PLL0 12 - -/* PLL usage in 5356/5357 */ -#define PMU5356_MAINPLL_PLL0 0 -#define PMU5357_MAINPLL_PLL0 0 - -/* 4716/47162 resources */ -#define RES4716_PROC_PLL_ON 0x00000040 -#define RES4716_PROC_HT_AVAIL 0x00000080 - -/* 4716/4717/4718 Chip specific ChipControl register bits */ -#define CCTRL471X_I2S_PINS_ENABLE 0x0080 /* I2S pins off by default, shared with pflash */ - -/* 5354 resources */ -#define RES5354_EXT_SWITCHER_PWM 0 /* 0x00001 */ -#define RES5354_BB_SWITCHER_PWM 1 /* 0x00002 */ -#define RES5354_BB_SWITCHER_BURST 2 /* 0x00004 */ -#define RES5354_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */ -#define RES5354_ILP_REQUEST 4 /* 0x00010 */ -#define RES5354_RADIO_SWITCHER_PWM 5 /* 0x00020 */ -#define RES5354_RADIO_SWITCHER_BURST 6 /* 0x00040 */ -#define RES5354_ROM_SWITCH 7 /* 0x00080 */ -#define RES5354_PA_REF_LDO 8 /* 0x00100 */ -#define RES5354_RADIO_LDO 9 /* 0x00200 */ -#define RES5354_AFE_LDO 10 /* 0x00400 */ -#define RES5354_PLL_LDO 11 /* 0x00800 */ -#define RES5354_BG_FILTBYP 12 /* 0x01000 */ -#define RES5354_TX_FILTBYP 13 /* 0x02000 */ -#define RES5354_RX_FILTBYP 14 /* 0x04000 */ -#define RES5354_XTAL_PU 15 /* 0x08000 */ -#define RES5354_XTAL_EN 16 /* 0x10000 */ -#define RES5354_BB_PLL_FILTBYP 17 /* 0x20000 */ -#define RES5354_RF_PLL_FILTBYP 18 /* 0x40000 */ -#define RES5354_BB_PLL_PU 19 /* 0x80000 */ - -/* 5357 Chip specific ChipControl register bits */ -#define CCTRL5357_EXTPA (1<<14) /* extPA in ChipControl 1, bit 14 */ -#define CCTRL5357_ANT_MUX_2o3 (1<<15) /* 2o3 in ChipControl 1, bit 15 */ - -/* 4328 resources */ -#define RES4328_EXT_SWITCHER_PWM 0 /* 0x00001 */ -#define RES4328_BB_SWITCHER_PWM 1 /* 0x00002 */ -#define RES4328_BB_SWITCHER_BURST 2 /* 0x00004 */ -#define RES4328_BB_EXT_SWITCHER_BURST 3 /* 0x00008 */ -#define RES4328_ILP_REQUEST 4 /* 0x00010 */ -#define RES4328_RADIO_SWITCHER_PWM 5 /* 0x00020 */ -#define RES4328_RADIO_SWITCHER_BURST 6 /* 0x00040 */ -#define RES4328_ROM_SWITCH 7 /* 0x00080 */ -#define RES4328_PA_REF_LDO 8 /* 0x00100 */ -#define RES4328_RADIO_LDO 9 /* 0x00200 */ -#define RES4328_AFE_LDO 10 /* 0x00400 */ -#define RES4328_PLL_LDO 11 /* 0x00800 */ -#define RES4328_BG_FILTBYP 12 /* 0x01000 */ -#define RES4328_TX_FILTBYP 13 /* 0x02000 */ -#define RES4328_RX_FILTBYP 14 /* 0x04000 */ -#define RES4328_XTAL_PU 15 /* 0x08000 */ -#define RES4328_XTAL_EN 16 /* 0x10000 */ -#define RES4328_BB_PLL_FILTBYP 17 /* 0x20000 */ -#define RES4328_RF_PLL_FILTBYP 18 /* 0x40000 */ -#define RES4328_BB_PLL_PU 19 /* 0x80000 */ - -/* 4325 A0/A1 resources */ -#define RES4325_BUCK_BOOST_BURST 0 /* 0x00000001 */ -#define RES4325_CBUCK_BURST 1 /* 0x00000002 */ -#define RES4325_CBUCK_PWM 2 /* 0x00000004 */ -#define RES4325_CLDO_CBUCK_BURST 3 /* 0x00000008 */ -#define RES4325_CLDO_CBUCK_PWM 4 /* 0x00000010 */ -#define RES4325_BUCK_BOOST_PWM 5 /* 0x00000020 */ -#define RES4325_ILP_REQUEST 6 /* 0x00000040 */ -#define RES4325_ABUCK_BURST 7 /* 0x00000080 */ -#define RES4325_ABUCK_PWM 8 /* 0x00000100 */ -#define RES4325_LNLDO1_PU 9 /* 0x00000200 */ -#define RES4325_OTP_PU 10 /* 0x00000400 */ -#define RES4325_LNLDO3_PU 11 /* 0x00000800 */ -#define RES4325_LNLDO4_PU 12 /* 0x00001000 */ -#define RES4325_XTAL_PU 13 /* 0x00002000 */ -#define RES4325_ALP_AVAIL 14 /* 0x00004000 */ -#define RES4325_RX_PWRSW_PU 15 /* 0x00008000 */ -#define RES4325_TX_PWRSW_PU 16 /* 0x00010000 */ -#define RES4325_RFPLL_PWRSW_PU 17 /* 0x00020000 */ -#define RES4325_LOGEN_PWRSW_PU 18 /* 0x00040000 */ -#define RES4325_AFE_PWRSW_PU 19 /* 0x00080000 */ -#define RES4325_BBPLL_PWRSW_PU 20 /* 0x00100000 */ -#define RES4325_HT_AVAIL 21 /* 0x00200000 */ - -/* 4325 B0/C0 resources */ -#define RES4325B0_CBUCK_LPOM 1 /* 0x00000002 */ -#define RES4325B0_CBUCK_BURST 2 /* 0x00000004 */ -#define RES4325B0_CBUCK_PWM 3 /* 0x00000008 */ -#define RES4325B0_CLDO_PU 4 /* 0x00000010 */ - -/* 4325 C1 resources */ -#define RES4325C1_LNLDO2_PU 12 /* 0x00001000 */ - -/* 4325 chip-specific ChipStatus register bits */ -#define CST4325_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4325_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ -#define CST4325_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ -#define CST4325_OTP_SEL 2 /* OTP is powered up, no SPROM */ -#define CST4325_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */ -#define CST4325_SDIO_USB_MODE_MASK 0x00000004 -#define CST4325_SDIO_USB_MODE_SHIFT 2 -#define CST4325_RCAL_VALID_MASK 0x00000008 -#define CST4325_RCAL_VALID_SHIFT 3 -#define CST4325_RCAL_VALUE_MASK 0x000001f0 -#define CST4325_RCAL_VALUE_SHIFT 4 -#define CST4325_PMUTOP_2B_MASK 0x00000200 /* 1 for 2b, 0 for to 2a */ -#define CST4325_PMUTOP_2B_SHIFT 9 - -#define RES4329_RESERVED0 0 /* 0x00000001 */ -#define RES4329_CBUCK_LPOM 1 /* 0x00000002 */ -#define RES4329_CBUCK_BURST 2 /* 0x00000004 */ -#define RES4329_CBUCK_PWM 3 /* 0x00000008 */ -#define RES4329_CLDO_PU 4 /* 0x00000010 */ -#define RES4329_PALDO_PU 5 /* 0x00000020 */ -#define RES4329_ILP_REQUEST 6 /* 0x00000040 */ -#define RES4329_RESERVED7 7 /* 0x00000080 */ -#define RES4329_RESERVED8 8 /* 0x00000100 */ -#define RES4329_LNLDO1_PU 9 /* 0x00000200 */ -#define RES4329_OTP_PU 10 /* 0x00000400 */ -#define RES4329_RESERVED11 11 /* 0x00000800 */ -#define RES4329_LNLDO2_PU 12 /* 0x00001000 */ -#define RES4329_XTAL_PU 13 /* 0x00002000 */ -#define RES4329_ALP_AVAIL 14 /* 0x00004000 */ -#define RES4329_RX_PWRSW_PU 15 /* 0x00008000 */ -#define RES4329_TX_PWRSW_PU 16 /* 0x00010000 */ -#define RES4329_RFPLL_PWRSW_PU 17 /* 0x00020000 */ -#define RES4329_LOGEN_PWRSW_PU 18 /* 0x00040000 */ -#define RES4329_AFE_PWRSW_PU 19 /* 0x00080000 */ -#define RES4329_BBPLL_PWRSW_PU 20 /* 0x00100000 */ -#define RES4329_HT_AVAIL 21 /* 0x00200000 */ - -#define CST4329_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4329_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ -#define CST4329_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ -#define CST4329_OTP_SEL 2 /* OTP is powered up, no SPROM */ -#define CST4329_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */ -#define CST4329_SPI_SDIO_MODE_MASK 0x00000004 -#define CST4329_SPI_SDIO_MODE_SHIFT 2 - -/* 4312 chip-specific ChipStatus register bits */ -#define CST4312_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4312_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ -#define CST4312_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ -#define CST4312_OTP_SEL 2 /* OTP is powered up, no SPROM */ -#define CST4312_OTP_BAD 3 /* OTP is broken, SPROM is present */ - -/* 4312 resources (all PMU chips with little memory constraint) */ -#define RES4312_SWITCHER_BURST 0 /* 0x00000001 */ -#define RES4312_SWITCHER_PWM 1 /* 0x00000002 */ -#define RES4312_PA_REF_LDO 2 /* 0x00000004 */ -#define RES4312_CORE_LDO_BURST 3 /* 0x00000008 */ -#define RES4312_CORE_LDO_PWM 4 /* 0x00000010 */ -#define RES4312_RADIO_LDO 5 /* 0x00000020 */ -#define RES4312_ILP_REQUEST 6 /* 0x00000040 */ -#define RES4312_BG_FILTBYP 7 /* 0x00000080 */ -#define RES4312_TX_FILTBYP 8 /* 0x00000100 */ -#define RES4312_RX_FILTBYP 9 /* 0x00000200 */ -#define RES4312_XTAL_PU 10 /* 0x00000400 */ -#define RES4312_ALP_AVAIL 11 /* 0x00000800 */ -#define RES4312_BB_PLL_FILTBYP 12 /* 0x00001000 */ -#define RES4312_RF_PLL_FILTBYP 13 /* 0x00002000 */ -#define RES4312_HT_AVAIL 14 /* 0x00004000 */ - -/* 4322 resources */ -#define RES4322_RF_LDO 0 -#define RES4322_ILP_REQUEST 1 -#define RES4322_XTAL_PU 2 -#define RES4322_ALP_AVAIL 3 -#define RES4322_SI_PLL_ON 4 -#define RES4322_HT_SI_AVAIL 5 -#define RES4322_PHY_PLL_ON 6 -#define RES4322_HT_PHY_AVAIL 7 -#define RES4322_OTP_PU 8 - -/* 4322 chip-specific ChipStatus register bits */ -#define CST4322_XTAL_FREQ_20_40MHZ 0x00000020 -#define CST4322_SPROM_OTP_SEL_MASK 0x000000c0 -#define CST4322_SPROM_OTP_SEL_SHIFT 6 -#define CST4322_NO_SPROM_OTP 0 /* no OTP, no SPROM */ -#define CST4322_SPROM_PRESENT 1 /* SPROM is present */ -#define CST4322_OTP_PRESENT 2 /* OTP is present */ -#define CST4322_PCI_OR_USB 0x00000100 -#define CST4322_BOOT_MASK 0x00000600 -#define CST4322_BOOT_SHIFT 9 -#define CST4322_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ -#define CST4322_BOOT_FROM_ROM 1 /* boot from ROM */ -#define CST4322_BOOT_FROM_FLASH 2 /* boot from FLASH */ -#define CST4322_BOOT_FROM_INVALID 3 -#define CST4322_ILP_DIV_EN 0x00000800 -#define CST4322_FLASH_TYPE_MASK 0x00001000 -#define CST4322_FLASH_TYPE_SHIFT 12 -#define CST4322_FLASH_TYPE_SHIFT_ST 0 /* ST serial FLASH */ -#define CST4322_FLASH_TYPE_SHIFT_ATMEL 1 /* ATMEL flash */ -#define CST4322_ARM_TAP_SEL 0x00002000 -#define CST4322_RES_INIT_MODE_MASK 0x0000c000 -#define CST4322_RES_INIT_MODE_SHIFT 14 -#define CST4322_RES_INIT_MODE_ILPAVAIL 0 /* resinitmode: ILP available */ -#define CST4322_RES_INIT_MODE_ILPREQ 1 /* resinitmode: ILP request */ -#define CST4322_RES_INIT_MODE_ALPAVAIL 2 /* resinitmode: ALP available */ -#define CST4322_RES_INIT_MODE_HTAVAIL 3 /* resinitmode: HT available */ -#define CST4322_PCIPLLCLK_GATING 0x00010000 -#define CST4322_CLK_SWITCH_PCI_TO_ALP 0x00020000 -#define CST4322_PCI_CARDBUS_MODE 0x00040000 - -/* 43224 chip-specific ChipControl register bits */ -#define CCTRL43224_GPIO_TOGGLE 0x8000 -#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 /* 12 mA drive strength */ -#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 /* 12 mA drive strength for later 43224s */ - -/* 43236 resources */ -#define RES43236_REGULATOR 0 -#define RES43236_ILP_REQUEST 1 -#define RES43236_XTAL_PU 2 -#define RES43236_ALP_AVAIL 3 -#define RES43236_SI_PLL_ON 4 -#define RES43236_HT_SI_AVAIL 5 - -/* 43236 chip-specific ChipControl register bits */ -#define CCTRL43236_BT_COEXIST (1<<0) /* 0 disable */ -#define CCTRL43236_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ -#define CCTRL43236_EXT_LNA (1<<2) /* 0 disable */ -#define CCTRL43236_ANT_MUX_2o3 (1<<3) /* 2o3 mux, chipcontrol bit 3 */ -#define CCTRL43236_GSIO (1<<4) /* 0 disable */ - -/* 43236 Chip specific ChipStatus register bits */ -#define CST43236_SFLASH_MASK 0x00000040 -#define CST43236_OTP_MASK 0x00000080 -#define CST43236_HSIC_MASK 0x00000100 /* USB/HSIC */ -#define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */ -#define CST43236_BOOT_MASK 0x00001800 -#define CST43236_BOOT_SHIFT 11 -#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ -#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */ -#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */ -#define CST43236_BOOT_FROM_INVALID 3 - -/* 4331 resources */ -#define RES4331_REGULATOR 0 -#define RES4331_ILP_REQUEST 1 -#define RES4331_XTAL_PU 2 -#define RES4331_ALP_AVAIL 3 -#define RES4331_SI_PLL_ON 4 -#define RES4331_HT_SI_AVAIL 5 - -/* 4331 chip-specific ChipControl register bits */ -#define CCTRL4331_BT_COEXIST (1<<0) /* 0 disable */ -#define CCTRL4331_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ -#define CCTRL4331_EXT_LNA (1<<2) /* 0 disable */ -#define CCTRL4331_SPROM_GPIO13_15 (1<<3) /* sprom/gpio13-15 mux */ -#define CCTRL4331_EXTPA_EN (1<<4) /* 0 ext pa disable, 1 ext pa enabled */ -#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) /* set drive out GPIO_CLK on sprom_cs pin */ -#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) /* use sprom_cs pin as PCIE mdio interface */ -#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) /* aband extpa will be at gpio2/5 and sprom_dout */ -#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) /* override core control on pipe_AuxClkEnable */ -#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) /* override core control on pipe_AuxPowerDown */ -#define CCTRL4331_PCIE_AUXCLKEN (1<<10) /* pcie_auxclkenable */ -#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) /* pcie_pipe_pllpowerdown */ -#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) /* enable bt_shd0 at gpio4 */ -#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* enable bt_shd1 at gpio5 */ - -/* 4331 Chip specific ChipStatus register bits */ -#define CST4331_XTAL_FREQ 0x00000001 /* crystal frequency 20/40Mhz */ -#define CST4331_SPROM_PRESENT 0x00000002 -#define CST4331_OTP_PRESENT 0x00000004 -#define CST4331_LDO_RF 0x00000008 -#define CST4331_LDO_PAR 0x00000010 - -/* 4315 resources */ -#define RES4315_CBUCK_LPOM 1 /* 0x00000002 */ -#define RES4315_CBUCK_BURST 2 /* 0x00000004 */ -#define RES4315_CBUCK_PWM 3 /* 0x00000008 */ -#define RES4315_CLDO_PU 4 /* 0x00000010 */ -#define RES4315_PALDO_PU 5 /* 0x00000020 */ -#define RES4315_ILP_REQUEST 6 /* 0x00000040 */ -#define RES4315_LNLDO1_PU 9 /* 0x00000200 */ -#define RES4315_OTP_PU 10 /* 0x00000400 */ -#define RES4315_LNLDO2_PU 12 /* 0x00001000 */ -#define RES4315_XTAL_PU 13 /* 0x00002000 */ -#define RES4315_ALP_AVAIL 14 /* 0x00004000 */ -#define RES4315_RX_PWRSW_PU 15 /* 0x00008000 */ -#define RES4315_TX_PWRSW_PU 16 /* 0x00010000 */ -#define RES4315_RFPLL_PWRSW_PU 17 /* 0x00020000 */ -#define RES4315_LOGEN_PWRSW_PU 18 /* 0x00040000 */ -#define RES4315_AFE_PWRSW_PU 19 /* 0x00080000 */ -#define RES4315_BBPLL_PWRSW_PU 20 /* 0x00100000 */ -#define RES4315_HT_AVAIL 21 /* 0x00200000 */ - -/* 4315 chip-specific ChipStatus register bits */ -#define CST4315_SPROM_OTP_SEL_MASK 0x00000003 /* gpio [7:6], SDIO CIS selection */ -#define CST4315_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */ -#define CST4315_SPROM_SEL 0x00000001 /* use SPROM, OTP is powered up */ -#define CST4315_OTP_SEL 0x00000002 /* use OTP, OTP is powered up */ -#define CST4315_OTP_PWRDN 0x00000003 /* use SPROM, OTP is powered down */ -#define CST4315_SDIO_MODE 0x00000004 /* gpio [8], sdio/usb mode */ -#define CST4315_RCAL_VALID 0x00000008 -#define CST4315_RCAL_VALUE_MASK 0x000001f0 -#define CST4315_RCAL_VALUE_SHIFT 4 -#define CST4315_PALDO_EXTPNP 0x00000200 /* PALDO is configured with external PNP */ -#define CST4315_CBUCK_MODE_MASK 0x00000c00 -#define CST4315_CBUCK_MODE_BURST 0x00000400 -#define CST4315_CBUCK_MODE_LPBURST 0x00000c00 - -/* 4319 resources */ -#define RES4319_CBUCK_LPOM 1 /* 0x00000002 */ -#define RES4319_CBUCK_BURST 2 /* 0x00000004 */ -#define RES4319_CBUCK_PWM 3 /* 0x00000008 */ -#define RES4319_CLDO_PU 4 /* 0x00000010 */ -#define RES4319_PALDO_PU 5 /* 0x00000020 */ -#define RES4319_ILP_REQUEST 6 /* 0x00000040 */ -#define RES4319_LNLDO1_PU 9 /* 0x00000200 */ -#define RES4319_OTP_PU 10 /* 0x00000400 */ -#define RES4319_LNLDO2_PU 12 /* 0x00001000 */ -#define RES4319_XTAL_PU 13 /* 0x00002000 */ -#define RES4319_ALP_AVAIL 14 /* 0x00004000 */ -#define RES4319_RX_PWRSW_PU 15 /* 0x00008000 */ -#define RES4319_TX_PWRSW_PU 16 /* 0x00010000 */ -#define RES4319_RFPLL_PWRSW_PU 17 /* 0x00020000 */ -#define RES4319_LOGEN_PWRSW_PU 18 /* 0x00040000 */ -#define RES4319_AFE_PWRSW_PU 19 /* 0x00080000 */ -#define RES4319_BBPLL_PWRSW_PU 20 /* 0x00100000 */ -#define RES4319_HT_AVAIL 21 /* 0x00200000 */ - -/* 4319 chip-specific ChipStatus register bits */ -#define CST4319_SPI_CPULESSUSB 0x00000001 -#define CST4319_SPI_CLK_POL 0x00000002 -#define CST4319_SPI_CLK_PH 0x00000008 -#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 /* gpio [7:6], SDIO CIS selection */ -#define CST4319_SPROM_OTP_SEL_SHIFT 6 -#define CST4319_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */ -#define CST4319_SPROM_SEL 0x00000040 /* use SPROM, OTP is powered up */ -#define CST4319_OTP_SEL 0x00000080 /* use OTP, OTP is powered up */ -#define CST4319_OTP_PWRDN 0x000000c0 /* use SPROM, OTP is powered down */ -#define CST4319_SDIO_USB_MODE 0x00000100 /* gpio [8], sdio/usb mode */ -#define CST4319_REMAP_SEL_MASK 0x00000600 -#define CST4319_ILPDIV_EN 0x00000800 -#define CST4319_XTAL_PD_POL 0x00001000 -#define CST4319_LPO_SEL 0x00002000 -#define CST4319_RES_INIT_MODE 0x0000c000 -#define CST4319_PALDO_EXTPNP 0x00010000 /* PALDO is configured with external PNP */ -#define CST4319_CBUCK_MODE_MASK 0x00060000 -#define CST4319_CBUCK_MODE_BURST 0x00020000 -#define CST4319_CBUCK_MODE_LPBURST 0x00060000 -#define CST4319_RCAL_VALID 0x01000000 -#define CST4319_RCAL_VALUE_MASK 0x3e000000 -#define CST4319_RCAL_VALUE_SHIFT 25 - -#define PMU1_PLL0_CHIPCTL0 0 -#define PMU1_PLL0_CHIPCTL1 1 -#define PMU1_PLL0_CHIPCTL2 2 -#define CCTL_4319USB_XTAL_SEL_MASK 0x00180000 -#define CCTL_4319USB_XTAL_SEL_SHIFT 19 -#define CCTL_4319USB_48MHZ_PLL_SEL 1 -#define CCTL_4319USB_24MHZ_PLL_SEL 2 - -/* PMU resources for 4336 */ -#define RES4336_CBUCK_LPOM 0 -#define RES4336_CBUCK_BURST 1 -#define RES4336_CBUCK_LP_PWM 2 -#define RES4336_CBUCK_PWM 3 -#define RES4336_CLDO_PU 4 -#define RES4336_DIS_INT_RESET_PD 5 -#define RES4336_ILP_REQUEST 6 -#define RES4336_LNLDO_PU 7 -#define RES4336_LDO3P3_PU 8 -#define RES4336_OTP_PU 9 -#define RES4336_XTAL_PU 10 -#define RES4336_ALP_AVAIL 11 -#define RES4336_RADIO_PU 12 -#define RES4336_BG_PU 13 -#define RES4336_VREG1p4_PU_PU 14 -#define RES4336_AFE_PWRSW_PU 15 -#define RES4336_RX_PWRSW_PU 16 -#define RES4336_TX_PWRSW_PU 17 -#define RES4336_BB_PWRSW_PU 18 -#define RES4336_SYNTH_PWRSW_PU 19 -#define RES4336_MISC_PWRSW_PU 20 -#define RES4336_LOGEN_PWRSW_PU 21 -#define RES4336_BBPLL_PWRSW_PU 22 -#define RES4336_MACPHY_CLKAVAIL 23 -#define RES4336_HT_AVAIL 24 -#define RES4336_RSVD 25 - -/* 4336 chip-specific ChipStatus register bits */ -#define CST4336_SPI_MODE_MASK 0x00000001 -#define CST4336_SPROM_PRESENT 0x00000002 -#define CST4336_OTP_PRESENT 0x00000004 -#define CST4336_ARMREMAP_0 0x00000008 -#define CST4336_ILPDIV_EN_MASK 0x00000010 -#define CST4336_ILPDIV_EN_SHIFT 4 -#define CST4336_XTAL_PD_POL_MASK 0x00000020 -#define CST4336_XTAL_PD_POL_SHIFT 5 -#define CST4336_LPO_SEL_MASK 0x00000040 -#define CST4336_LPO_SEL_SHIFT 6 -#define CST4336_RES_INIT_MODE_MASK 0x00000180 -#define CST4336_RES_INIT_MODE_SHIFT 7 -#define CST4336_CBUCK_MODE_MASK 0x00000600 -#define CST4336_CBUCK_MODE_SHIFT 9 - -/* 4330 resources */ -#define RES4330_CBUCK_LPOM 0 -#define RES4330_CBUCK_BURST 1 -#define RES4330_CBUCK_LP_PWM 2 -#define RES4330_CBUCK_PWM 3 -#define RES4330_CLDO_PU 4 -#define RES4330_DIS_INT_RESET_PD 5 -#define RES4330_ILP_REQUEST 6 -#define RES4330_LNLDO_PU 7 -#define RES4330_LDO3P3_PU 8 -#define RES4330_OTP_PU 9 -#define RES4330_XTAL_PU 10 -#define RES4330_ALP_AVAIL 11 -#define RES4330_RADIO_PU 12 -#define RES4330_BG_PU 13 -#define RES4330_VREG1p4_PU_PU 14 -#define RES4330_AFE_PWRSW_PU 15 -#define RES4330_RX_PWRSW_PU 16 -#define RES4330_TX_PWRSW_PU 17 -#define RES4330_BB_PWRSW_PU 18 -#define RES4330_SYNTH_PWRSW_PU 19 -#define RES4330_MISC_PWRSW_PU 20 -#define RES4330_LOGEN_PWRSW_PU 21 -#define RES4330_BBPLL_PWRSW_PU 22 -#define RES4330_MACPHY_CLKAVAIL 23 -#define RES4330_HT_AVAIL 24 -#define RES4330_5gRX_PWRSW_PU 25 -#define RES4330_5gTX_PWRSW_PU 26 -#define RES4330_5g_LOGEN_PWRSW_PU 27 - -/* 4330 chip-specific ChipStatus register bits */ -#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) /* SDIO || gSPI */ -#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) /* USB || USBDA */ -#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) /* SDIO */ -#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) /* gSPI */ -#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) /* USB packet-oriented */ -#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) /* USB Direct Access */ -#define CST4330_OTP_PRESENT 0x00000010 -#define CST4330_LPO_AUTODET_EN 0x00000020 -#define CST4330_ARMREMAP_0 0x00000040 -#define CST4330_SPROM_PRESENT 0x00000080 /* takes priority over OTP if both set */ -#define CST4330_ILPDIV_EN 0x00000100 -#define CST4330_LPO_SEL 0x00000200 -#define CST4330_RES_INIT_MODE_SHIFT 10 -#define CST4330_RES_INIT_MODE_MASK 0x00000c00 -#define CST4330_CBUCK_MODE_SHIFT 12 -#define CST4330_CBUCK_MODE_MASK 0x00003000 -#define CST4330_CBUCK_POWER_OK 0x00004000 -#define CST4330_BB_PLL_LOCKED 0x00008000 -#define SOCDEVRAM_4330_BP_ADDR 0x1E000000 -#define SOCDEVRAM_4330_ARM_ADDR 0x00800000 - -/* 4313 resources */ -#define RES4313_BB_PU_RSRC 0 -#define RES4313_ILP_REQ_RSRC 1 -#define RES4313_XTAL_PU_RSRC 2 -#define RES4313_ALP_AVAIL_RSRC 3 -#define RES4313_RADIO_PU_RSRC 4 -#define RES4313_BG_PU_RSRC 5 -#define RES4313_VREG1P4_PU_RSRC 6 -#define RES4313_AFE_PWRSW_RSRC 7 -#define RES4313_RX_PWRSW_RSRC 8 -#define RES4313_TX_PWRSW_RSRC 9 -#define RES4313_BB_PWRSW_RSRC 10 -#define RES4313_SYNTH_PWRSW_RSRC 11 -#define RES4313_MISC_PWRSW_RSRC 12 -#define RES4313_BB_PLL_PWRSW_RSRC 13 -#define RES4313_HT_AVAIL_RSRC 14 -#define RES4313_MACPHY_CLK_AVAIL_RSRC 15 - -/* 4313 chip-specific ChipStatus register bits */ -#define CST4313_SPROM_PRESENT 1 -#define CST4313_OTP_PRESENT 2 -#define CST4313_SPROM_OTP_SEL_MASK 0x00000002 -#define CST4313_SPROM_OTP_SEL_SHIFT 0 - -/* 4313 Chip specific ChipControl register bits */ -#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */ - -/* 43228 resources */ -#define RES43228_NOT_USED 0 -#define RES43228_ILP_REQUEST 1 -#define RES43228_XTAL_PU 2 -#define RES43228_ALP_AVAIL 3 -#define RES43228_PLL_EN 4 -#define RES43228_HT_PHY_AVAIL 5 - -/* 43228 chipstatus reg bits */ -#define CST43228_ILP_DIV_EN 0x1 -#define CST43228_OTP_PRESENT 0x2 -#define CST43228_SERDES_REFCLK_PADSEL 0x4 -#define CST43228_SDIO_MODE 0x8 - -#define CST43228_SDIO_OTP_PRESENT 0x10 -#define CST43228_SDIO_RESET 0x20 - -/* -* Maximum delay for the PMU state transition in us. -* This is an upper bound intended for spinwaits etc. -*/ -#define PMU_MAX_TRANSITION_DLY 15000 - -/* PMU resource up transition time in ILP cycles */ -#define PMURES_UP_TRANSITION 2 - -/* -* Register eci_inputlo bitfield values. -* - BT packet type information bits [7:0] -*/ -/* [3:0] - Task (link) type */ -#define BT_ACL 0x00 -#define BT_SCO 0x01 -#define BT_eSCO 0x02 -#define BT_A2DP 0x03 -#define BT_SNIFF 0x04 -#define BT_PAGE_SCAN 0x05 -#define BT_INQUIRY_SCAN 0x06 -#define BT_PAGE 0x07 -#define BT_INQUIRY 0x08 -#define BT_MSS 0x09 -#define BT_PARK 0x0a -#define BT_RSSISCAN 0x0b -#define BT_MD_ACL 0x0c -#define BT_MD_eSCO 0x0d -#define BT_SCAN_WITH_SCO_LINK 0x0e -#define BT_SCAN_WITHOUT_SCO_LINK 0x0f -/* [7:4] = packet duration code */ -/* [8] - Master / Slave */ -#define BT_MASTER 0 -#define BT_SLAVE 1 -/* [11:9] - multi-level priority */ -#define BT_LOWEST_PRIO 0x0 -#define BT_HIGHEST_PRIO 0x3 - -/* WLAN - number of antenna */ -#define WLAN_NUM_ANT1 TXANT_0 -#define WLAN_NUM_ANT2 TXANT_1 - -#endif /* _SBCHIPC_H */ diff --git a/drivers/staging/brcm80211/include/sbconfig.h b/drivers/staging/brcm80211/include/sbconfig.h deleted file mode 100644 index 5247f01ec364..000000000000 --- a/drivers/staging/brcm80211/include/sbconfig.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SBCONFIG_H -#define _SBCONFIG_H - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif - -/* enumeration in SB is based on the premise that cores are contiguos in the - * enumeration space. - */ -#define SB_BUS_SIZE 0x10000 /* Each bus gets 64Kbytes for cores */ -#define SB_BUS_BASE(b) (SI_ENUM_BASE + (b) * SB_BUS_SIZE) -#define SB_BUS_MAXCORES (SB_BUS_SIZE / SI_CORE_SIZE) /* Max cores per bus */ - -/* - * Sonics Configuration Space Registers. - */ -#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */ -#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */ - -#define SBIPSFLAG 0x08 -#define SBTPSFLAG 0x18 -#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */ -#define SBTMERRLOG 0x50 /* sonics >= 2.3 */ -#define SBADMATCH3 0x60 -#define SBADMATCH2 0x68 -#define SBADMATCH1 0x70 -#define SBIMSTATE 0x90 -#define SBINTVEC 0x94 -#define SBTMSTATELOW 0x98 -#define SBTMSTATEHIGH 0x9c -#define SBBWA0 0xa0 -#define SBIMCONFIGLOW 0xa8 -#define SBIMCONFIGHIGH 0xac -#define SBADMATCH0 0xb0 -#define SBTMCONFIGLOW 0xb8 -#define SBTMCONFIGHIGH 0xbc -#define SBBCONFIG 0xc0 -#define SBBSTATE 0xc8 -#define SBACTCNFG 0xd8 -#define SBFLAGST 0xe8 -#define SBIDLOW 0xf8 -#define SBIDHIGH 0xfc - -/* All the previous registers are above SBCONFIGOFF, but with Sonics 2.3, we have - * a few registers *below* that line. I think it would be very confusing to try - * and change the value of SBCONFIGOFF, so I'm definig them as absolute offsets here, - */ - -#define SBIMERRLOGA 0xea8 -#define SBIMERRLOG 0xeb0 -#define SBTMPORTCONNID0 0xed8 -#define SBTMPORTLOCK0 0xef8 - -#ifndef _LANGUAGE_ASSEMBLY - -typedef volatile struct _sbconfig { - u32 PAD[2]; - u32 sbipsflag; /* initiator port ocp slave flag */ - u32 PAD[3]; - u32 sbtpsflag; /* target port ocp slave flag */ - u32 PAD[11]; - u32 sbtmerrloga; /* (sonics >= 2.3) */ - u32 PAD; - u32 sbtmerrlog; /* (sonics >= 2.3) */ - u32 PAD[3]; - u32 sbadmatch3; /* address match3 */ - u32 PAD; - u32 sbadmatch2; /* address match2 */ - u32 PAD; - u32 sbadmatch1; /* address match1 */ - u32 PAD[7]; - u32 sbimstate; /* initiator agent state */ - u32 sbintvec; /* interrupt mask */ - u32 sbtmstatelow; /* target state */ - u32 sbtmstatehigh; /* target state */ - u32 sbbwa0; /* bandwidth allocation table0 */ - u32 PAD; - u32 sbimconfiglow; /* initiator configuration */ - u32 sbimconfighigh; /* initiator configuration */ - u32 sbadmatch0; /* address match0 */ - u32 PAD; - u32 sbtmconfiglow; /* target configuration */ - u32 sbtmconfighigh; /* target configuration */ - u32 sbbconfig; /* broadcast configuration */ - u32 PAD; - u32 sbbstate; /* broadcast state */ - u32 PAD[3]; - u32 sbactcnfg; /* activate configuration */ - u32 PAD[3]; - u32 sbflagst; /* current sbflags */ - u32 PAD[3]; - u32 sbidlow; /* identification */ - u32 sbidhigh; /* identification */ -} sbconfig_t; - -#endif /* _LANGUAGE_ASSEMBLY */ - -/* sbipsflag */ -#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */ -#define SBIPS_INT1_SHIFT 0 -#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */ -#define SBIPS_INT2_SHIFT 8 -#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */ -#define SBIPS_INT3_SHIFT 16 -#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */ -#define SBIPS_INT4_SHIFT 24 - -/* sbtpsflag */ -#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */ -#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */ - -/* sbtmerrlog */ -#define SBTMEL_CM 0x00000007 /* command */ -#define SBTMEL_CI 0x0000ff00 /* connection id */ -#define SBTMEL_EC 0x0f000000 /* error code */ -#define SBTMEL_ME 0x80000000 /* multiple error */ - -/* sbimstate */ -#define SBIM_PC 0xf /* pipecount */ -#define SBIM_AP_MASK 0x30 /* arbitration policy */ -#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */ -#define SBIM_AP_TS 0x10 /* use timesliaces only */ -#define SBIM_AP_TK 0x20 /* use token only */ -#define SBIM_AP_RSV 0x30 /* reserved */ -#define SBIM_IBE 0x20000 /* inbanderror */ -#define SBIM_TO 0x40000 /* timeout */ -#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ -#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ - -/* sbtmstatelow */ -#define SBTML_RESET 0x0001 /* reset */ -#define SBTML_REJ_MASK 0x0006 /* reject field */ -#define SBTML_REJ 0x0002 /* reject */ -#define SBTML_TMPREJ 0x0004 /* temporary reject, for error recovery */ - -#define SBTML_SICF_SHIFT 16 /* Shift to locate the SI control flags in sbtml */ - -/* sbtmstatehigh */ -#define SBTMH_SERR 0x0001 /* serror */ -#define SBTMH_INT 0x0002 /* interrupt */ -#define SBTMH_BUSY 0x0004 /* busy */ -#define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */ - -#define SBTMH_SISF_SHIFT 16 /* Shift to locate the SI status flags in sbtmh */ - -/* sbbwa0 */ -#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */ -#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */ -#define SBBWA_TAB1_SHIFT 16 - -/* sbimconfiglow */ -#define SBIMCL_STO_MASK 0x7 /* service timeout */ -#define SBIMCL_RTO_MASK 0x70 /* request timeout */ -#define SBIMCL_RTO_SHIFT 4 -#define SBIMCL_CID_MASK 0xff0000 /* connection id */ -#define SBIMCL_CID_SHIFT 16 - -/* sbimconfighigh */ -#define SBIMCH_IEM_MASK 0xc /* inband error mode */ -#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */ -#define SBIMCH_TEM_SHIFT 4 -#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */ -#define SBIMCH_BEM_SHIFT 6 - -/* sbadmatch0 */ -#define SBAM_TYPE_MASK 0x3 /* address type */ -#define SBAM_AD64 0x4 /* reserved */ -#define SBAM_ADINT0_MASK 0xf8 /* type0 size */ -#define SBAM_ADINT0_SHIFT 3 -#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */ -#define SBAM_ADINT1_SHIFT 3 -#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */ -#define SBAM_ADINT2_SHIFT 3 -#define SBAM_ADEN 0x400 /* enable */ -#define SBAM_ADNEG 0x800 /* negative decode */ -#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */ -#define SBAM_BASE0_SHIFT 8 -#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */ -#define SBAM_BASE1_SHIFT 12 -#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */ -#define SBAM_BASE2_SHIFT 16 - -/* sbtmconfiglow */ -#define SBTMCL_CD_MASK 0xff /* clock divide */ -#define SBTMCL_CO_MASK 0xf800 /* clock offset */ -#define SBTMCL_CO_SHIFT 11 -#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */ -#define SBTMCL_IF_SHIFT 18 -#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */ -#define SBTMCL_IM_SHIFT 24 - -/* sbtmconfighigh */ -#define SBTMCH_BM_MASK 0x3 /* busy mode */ -#define SBTMCH_RM_MASK 0x3 /* retry mode */ -#define SBTMCH_RM_SHIFT 2 -#define SBTMCH_SM_MASK 0x30 /* stop mode */ -#define SBTMCH_SM_SHIFT 4 -#define SBTMCH_EM_MASK 0x300 /* sb error mode */ -#define SBTMCH_EM_SHIFT 8 -#define SBTMCH_IM_MASK 0xc00 /* int mode */ -#define SBTMCH_IM_SHIFT 10 - -/* sbbconfig */ -#define SBBC_LAT_MASK 0x3 /* sb latency */ -#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */ -#define SBBC_MAX0_SHIFT 16 -#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */ -#define SBBC_MAX1_SHIFT 20 - -/* sbbstate */ -#define SBBS_SRD 0x1 /* st reg disable */ -#define SBBS_HRD 0x2 /* hold reg disable */ - -/* sbidlow */ -#define SBIDL_CS_MASK 0x3 /* config space */ -#define SBIDL_AR_MASK 0x38 /* # address ranges supported */ -#define SBIDL_AR_SHIFT 3 -#define SBIDL_SYNCH 0x40 /* sync */ -#define SBIDL_INIT 0x80 /* initiator */ -#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */ -#define SBIDL_MINLAT_SHIFT 8 -#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */ -#define SBIDL_MAXLAT_SHIFT 12 -#define SBIDL_FIRST 0x10000 /* this initiator is first */ -#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */ -#define SBIDL_CW_SHIFT 18 -#define SBIDL_TP_MASK 0xf00000 /* target ports */ -#define SBIDL_TP_SHIFT 20 -#define SBIDL_IP_MASK 0xf000000 /* initiator ports */ -#define SBIDL_IP_SHIFT 24 -#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */ -#define SBIDL_RV_SHIFT 28 -#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */ -#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */ - -/* sbidhigh */ -#define SBIDH_RC_MASK 0x000f /* revision code */ -#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ -#define SBIDH_RCE_SHIFT 8 -#define SBCOREREV(sbidh) \ - ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) -#define SBIDH_CC_MASK 0x8ff0 /* core code */ -#define SBIDH_CC_SHIFT 4 -#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ -#define SBIDH_VC_SHIFT 16 - -#define SB_COMMIT 0xfd8 /* update buffered registers value */ - -/* vendor codes */ -#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */ - -#endif /* _SBCONFIG_H */ diff --git a/drivers/staging/brcm80211/include/sbhnddma.h b/drivers/staging/brcm80211/include/sbhnddma.h deleted file mode 100644 index 08cb7f6e0d85..000000000000 --- a/drivers/staging/brcm80211/include/sbhnddma.h +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _sbhnddma_h_ -#define _sbhnddma_h_ - -/* DMA structure: - * support two DMA engines: 32 bits address or 64 bit addressing - * basic DMA register set is per channel(transmit or receive) - * a pair of channels is defined for convenience - */ - -/* 32 bits addressing */ - -/* dma registers per channel(xmt or rcv) */ -typedef volatile struct { - u32 control; /* enable, et al */ - u32 addr; /* descriptor ring base address (4K aligned) */ - u32 ptr; /* last descriptor posted to chip */ - u32 status; /* current active descriptor, et al */ -} dma32regs_t; - -typedef volatile struct { - dma32regs_t xmt; /* dma tx channel */ - dma32regs_t rcv; /* dma rx channel */ -} dma32regp_t; - -typedef volatile struct { /* diag access */ - u32 fifoaddr; /* diag address */ - u32 fifodatalow; /* low 32bits of data */ - u32 fifodatahigh; /* high 32bits of data */ - u32 pad; /* reserved */ -} dma32diag_t; - -/* - * DMA Descriptor - * Descriptors are only read by the hardware, never written back. - */ -typedef volatile struct { - u32 ctrl; /* misc control bits & bufcount */ - u32 addr; /* data buffer address */ -} dma32dd_t; - -/* - * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. - */ -#define D32RINGALIGN_BITS 12 -#define D32MAXRINGSZ (1 << D32RINGALIGN_BITS) -#define D32RINGALIGN (1 << D32RINGALIGN_BITS) - -#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) - -/* transmit channel control */ -#define XC_XE ((u32)1 << 0) /* transmit enable */ -#define XC_SE ((u32)1 << 1) /* transmit suspend request */ -#define XC_LE ((u32)1 << 2) /* loopback enable */ -#define XC_FL ((u32)1 << 4) /* flush request */ -#define XC_PD ((u32)1 << 11) /* parity check disable */ -#define XC_AE ((u32)3 << 16) /* address extension bits */ -#define XC_AE_SHIFT 16 - -/* transmit descriptor table pointer */ -#define XP_LD_MASK 0xfff /* last valid descriptor */ - -/* transmit channel status */ -#define XS_CD_MASK 0x0fff /* current descriptor pointer */ -#define XS_XS_MASK 0xf000 /* transmit state */ -#define XS_XS_SHIFT 12 -#define XS_XS_DISABLED 0x0000 /* disabled */ -#define XS_XS_ACTIVE 0x1000 /* active */ -#define XS_XS_IDLE 0x2000 /* idle wait */ -#define XS_XS_STOPPED 0x3000 /* stopped */ -#define XS_XS_SUSP 0x4000 /* suspend pending */ -#define XS_XE_MASK 0xf0000 /* transmit errors */ -#define XS_XE_SHIFT 16 -#define XS_XE_NOERR 0x00000 /* no error */ -#define XS_XE_DPE 0x10000 /* descriptor protocol error */ -#define XS_XE_DFU 0x20000 /* data fifo underrun */ -#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ -#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ -#define XS_AD_MASK 0xfff00000 /* active descriptor */ -#define XS_AD_SHIFT 20 - -/* receive channel control */ -#define RC_RE ((u32)1 << 0) /* receive enable */ -#define RC_RO_MASK 0xfe /* receive frame offset */ -#define RC_RO_SHIFT 1 -#define RC_FM ((u32)1 << 8) /* direct fifo receive (pio) mode */ -#define RC_SH ((u32)1 << 9) /* separate rx header descriptor enable */ -#define RC_OC ((u32)1 << 10) /* overflow continue */ -#define RC_PD ((u32)1 << 11) /* parity check disable */ -#define RC_AE ((u32)3 << 16) /* address extension bits */ -#define RC_AE_SHIFT 16 - -/* receive descriptor table pointer */ -#define RP_LD_MASK 0xfff /* last valid descriptor */ - -/* receive channel status */ -#define RS_CD_MASK 0x0fff /* current descriptor pointer */ -#define RS_RS_MASK 0xf000 /* receive state */ -#define RS_RS_SHIFT 12 -#define RS_RS_DISABLED 0x0000 /* disabled */ -#define RS_RS_ACTIVE 0x1000 /* active */ -#define RS_RS_IDLE 0x2000 /* idle wait */ -#define RS_RS_STOPPED 0x3000 /* reserved */ -#define RS_RE_MASK 0xf0000 /* receive errors */ -#define RS_RE_SHIFT 16 -#define RS_RE_NOERR 0x00000 /* no error */ -#define RS_RE_DPE 0x10000 /* descriptor protocol error */ -#define RS_RE_DFO 0x20000 /* data fifo overflow */ -#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ -#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ -#define RS_AD_MASK 0xfff00000 /* active descriptor */ -#define RS_AD_SHIFT 20 - -/* fifoaddr */ -#define FA_OFF_MASK 0xffff /* offset */ -#define FA_SEL_MASK 0xf0000 /* select */ -#define FA_SEL_SHIFT 16 -#define FA_SEL_XDD 0x00000 /* transmit dma data */ -#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ -#define FA_SEL_RDD 0x40000 /* receive dma data */ -#define FA_SEL_RDP 0x50000 /* receive dma pointers */ -#define FA_SEL_XFD 0x80000 /* transmit fifo data */ -#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -#define FA_SEL_RFD 0xc0000 /* receive fifo data */ -#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -#define FA_SEL_RSD 0xe0000 /* receive frame status data */ -#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ - -/* descriptor control flags */ -#define CTRL_BC_MASK 0x00001fff /* buffer byte count, real data len must <= 4KB */ -#define CTRL_AE ((u32)3 << 16) /* address extension bits */ -#define CTRL_AE_SHIFT 16 -#define CTRL_PARITY ((u32)3 << 18) /* parity bit */ -#define CTRL_EOT ((u32)1 << 28) /* end of descriptor table */ -#define CTRL_IOC ((u32)1 << 29) /* interrupt on completion */ -#define CTRL_EOF ((u32)1 << 30) /* end of frame */ -#define CTRL_SOF ((u32)1 << 31) /* start of frame */ - -/* control flags in the range [27:20] are core-specific and not defined here */ -#define CTRL_CORE_MASK 0x0ff00000 - -/* 64 bits addressing */ - -/* dma registers per channel(xmt or rcv) */ -typedef volatile struct { - u32 control; /* enable, et al */ - u32 ptr; /* last descriptor posted to chip */ - u32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ - u32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ - u32 status0; /* current descriptor, xmt state */ - u32 status1; /* active descriptor, xmt error */ -} dma64regs_t; - -typedef volatile struct { - dma64regs_t tx; /* dma64 tx channel */ - dma64regs_t rx; /* dma64 rx channel */ -} dma64regp_t; - -typedef volatile struct { /* diag access */ - u32 fifoaddr; /* diag address */ - u32 fifodatalow; /* low 32bits of data */ - u32 fifodatahigh; /* high 32bits of data */ - u32 pad; /* reserved */ -} dma64diag_t; - -/* - * DMA Descriptor - * Descriptors are only read by the hardware, never written back. - */ -typedef volatile struct { - u32 ctrl1; /* misc control bits & bufcount */ - u32 ctrl2; /* buffer count and address extension */ - u32 addrlow; /* memory address of the date buffer, bits 31:0 */ - u32 addrhigh; /* memory address of the date buffer, bits 63:32 */ -} dma64dd_t; - -/* - * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical address. - */ -#define D64RINGALIGN_BITS 13 -#define D64MAXRINGSZ (1 << D64RINGALIGN_BITS) -#define D64RINGALIGN (1 << D64RINGALIGN_BITS) - -#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) - -/* transmit channel control */ -#define D64_XC_XE 0x00000001 /* transmit enable */ -#define D64_XC_SE 0x00000002 /* transmit suspend request */ -#define D64_XC_LE 0x00000004 /* loopback enable */ -#define D64_XC_FL 0x00000010 /* flush request */ -#define D64_XC_PD 0x00000800 /* parity check disable */ -#define D64_XC_AE 0x00030000 /* address extension bits */ -#define D64_XC_AE_SHIFT 16 - -/* transmit descriptor table pointer */ -#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ - -/* transmit channel status */ -#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ -#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ -#define D64_XS0_XS_SHIFT 28 -#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ -#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ -#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ -#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ -#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ - -#define D64_XS1_AD_MASK 0x00001fff /* active descriptor */ -#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ -#define D64_XS1_XE_SHIFT 28 -#define D64_XS1_XE_NOERR 0x00000000 /* no error */ -#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ -#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ -#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ -#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ -#define D64_XS1_XE_COREE 0x50000000 /* core error */ - -/* receive channel control */ -#define D64_RC_RE 0x00000001 /* receive enable */ -#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ -#define D64_RC_RO_SHIFT 1 -#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ -#define D64_RC_SH 0x00000200 /* separate rx header descriptor enable */ -#define D64_RC_OC 0x00000400 /* overflow continue */ -#define D64_RC_PD 0x00000800 /* parity check disable */ -#define D64_RC_AE 0x00030000 /* address extension bits */ -#define D64_RC_AE_SHIFT 16 - -/* flags for dma controller */ -#define DMA_CTRL_PEN (1 << 0) /* partity enable */ -#define DMA_CTRL_ROC (1 << 1) /* rx overflow continue */ -#define DMA_CTRL_RXMULTI (1 << 2) /* allow rx scatter to multiple descriptors */ -#define DMA_CTRL_UNFRAMED (1 << 3) /* Unframed Rx/Tx data */ - -/* receive descriptor table pointer */ -#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ - -/* receive channel status */ -#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ -#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ -#define D64_RS0_RS_SHIFT 28 -#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ -#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ -#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ -#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ -#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ - -#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ -#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ -#define D64_RS1_RE_SHIFT 28 -#define D64_RS1_RE_NOERR 0x00000000 /* no error */ -#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ -#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ -#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ -#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ -#define D64_RS1_RE_COREE 0x50000000 /* core error */ - -/* fifoaddr */ -#define D64_FA_OFF_MASK 0xffff /* offset */ -#define D64_FA_SEL_MASK 0xf0000 /* select */ -#define D64_FA_SEL_SHIFT 16 -#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ -#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ -#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ -#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ -#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ -#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ -#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ -#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ - -/* descriptor control flags 1 */ -#define D64_CTRL_COREFLAGS 0x0ff00000 /* core specific flags */ -#define D64_CTRL1_EOT ((u32)1 << 28) /* end of descriptor table */ -#define D64_CTRL1_IOC ((u32)1 << 29) /* interrupt on completion */ -#define D64_CTRL1_EOF ((u32)1 << 30) /* end of frame */ -#define D64_CTRL1_SOF ((u32)1 << 31) /* start of frame */ - -/* descriptor control flags 2 */ -#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count. real data len must <= 16KB */ -#define D64_CTRL2_AE 0x00030000 /* address extension bits */ -#define D64_CTRL2_AE_SHIFT 16 -#define D64_CTRL2_PARITY 0x00040000 /* parity bit */ - -/* control flags in the range [27:20] are core-specific and not defined here */ -#define D64_CTRL_CORE_MASK 0x0ff00000 - -#define D64_RX_FRM_STS_LEN 0x0000ffff /* frame length mask */ -#define D64_RX_FRM_STS_OVFL 0x00800000 /* RxOverFlow */ -#define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1 */ -#define D64_RX_FRM_STS_DATATYPE 0xf0000000 /* core-dependent data type */ - -/* receive frame status */ -typedef volatile struct { - u16 len; - u16 flags; -} dma_rxh_t; - -#endif /* _sbhnddma_h_ */ diff --git a/drivers/staging/brcm80211/include/sbsdio.h b/drivers/staging/brcm80211/include/sbsdio.h deleted file mode 100644 index c7facd3795a0..000000000000 --- a/drivers/staging/brcm80211/include/sbsdio.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SBSDIO_H -#define _SBSDIO_H - -#define SBSDIO_NUM_FUNCTION 3 /* as of sdiod rev 0, supports 3 functions */ - -/* function 1 miscellaneous registers */ -#define SBSDIO_SPROM_CS 0x10000 /* sprom command and status */ -#define SBSDIO_SPROM_INFO 0x10001 /* sprom info register */ -#define SBSDIO_SPROM_DATA_LOW 0x10002 /* sprom indirect access data byte 0 */ -#define SBSDIO_SPROM_DATA_HIGH 0x10003 /* sprom indirect access data byte 1 */ -#define SBSDIO_SPROM_ADDR_LOW 0x10004 /* sprom indirect access addr byte 0 */ -#define SBSDIO_SPROM_ADDR_HIGH 0x10005 /* sprom indirect access addr byte 0 */ -#define SBSDIO_CHIP_CTRL_DATA 0x10006 /* xtal_pu (gpio) output */ -#define SBSDIO_CHIP_CTRL_EN 0x10007 /* xtal_pu (gpio) enable */ -#define SBSDIO_WATERMARK 0x10008 /* rev < 7, watermark for sdio device */ -#define SBSDIO_DEVICE_CTL 0x10009 /* control busy signal generation */ - -/* registers introduced in rev 8, some content (mask/bits) defs in sbsdpcmdev.h */ -#define SBSDIO_FUNC1_SBADDRLOW 0x1000A /* SB Address Window Low (b15) */ -#define SBSDIO_FUNC1_SBADDRMID 0x1000B /* SB Address Window Mid (b23:b16) */ -#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C /* SB Address Window High (b31:b24) */ -#define SBSDIO_FUNC1_FRAMECTRL 0x1000D /* Frame Control (frame term/abort) */ -#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E /* ChipClockCSR (ALP/HT ctl/status) */ -#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F /* SdioPullUp (on cmd, d0-d2) */ -#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 /* Write Frame Byte Count Low */ -#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A /* Write Frame Byte Count High */ -#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B /* Read Frame Byte Count Low */ -#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C /* Read Frame Byte Count High */ - -#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */ -#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */ - -/* SBSDIO_SPROM_CS */ -#define SBSDIO_SPROM_IDLE 0 -#define SBSDIO_SPROM_WRITE 1 -#define SBSDIO_SPROM_READ 2 -#define SBSDIO_SPROM_WEN 4 -#define SBSDIO_SPROM_WDS 7 -#define SBSDIO_SPROM_DONE 8 - -/* SBSDIO_SPROM_INFO */ -#define SROM_SZ_MASK 0x03 /* SROM size, 1: 4k, 2: 16k */ -#define SROM_BLANK 0x04 /* depreciated in corerev 6 */ -#define SROM_OTP 0x80 /* OTP present */ - -/* SBSDIO_CHIP_CTRL */ -#define SBSDIO_CHIP_CTRL_XTAL 0x01 /* or'd with onchip xtal_pu, - * 1: power on oscillator - * (for 4318 only) - */ -/* SBSDIO_WATERMARK */ -#define SBSDIO_WATERMARK_MASK 0x7f /* number of words - 1 for sd device - * to wait before sending data to host - */ - -/* SBSDIO_DEVICE_CTL */ -#define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when - * receiving CMD53 - */ -#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 /* 1: assertion of sdio interrupt is - * synchronous to the sdio clock - */ -#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04 /* 1: mask all interrupts to host - * except the chipActive (rev 8) - */ -#define SBSDIO_DEVCTL_PADS_ISO 0x08 /* 1: isolate internal sdio signals, put - * external pads in tri-state; requires - * sdio bus power cycle to clear (rev 9) - */ -#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Force SD->SB reset mapping (rev 11) */ -#define SBSDIO_DEVCTL_RST_CORECTL 0x00 /* Determined by CoreControl bit */ -#define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force backplane reset */ -#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* Force no backplane reset */ - -/* SBSDIO_FUNC1_CHIPCLKCSR */ -#define SBSDIO_FORCE_ALP 0x01 /* Force ALP request to backplane */ -#define SBSDIO_FORCE_HT 0x02 /* Force HT request to backplane */ -#define SBSDIO_FORCE_ILP 0x04 /* Force ILP request to backplane */ -#define SBSDIO_ALP_AVAIL_REQ 0x08 /* Make ALP ready (power up xtal) */ -#define SBSDIO_HT_AVAIL_REQ 0x10 /* Make HT ready (power up PLL) */ -#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 /* Squelch clock requests from HW */ -#define SBSDIO_ALP_AVAIL 0x40 /* Status: ALP is ready */ -#define SBSDIO_HT_AVAIL 0x80 /* Status: HT is ready */ -/* In rev8, actual avail bits followed original docs */ -#define SBSDIO_Rev8_HT_AVAIL 0x40 -#define SBSDIO_Rev8_ALP_AVAIL 0x80 - -#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) -#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) -#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) -#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) -#define SBSDIO_CLKAV(regval, alponly) (SBSDIO_ALPAV(regval) && \ - (alponly ? 1 : SBSDIO_HTAV(regval))) - -/* SBSDIO_FUNC1_SDIOPULLUP */ -#define SBSDIO_PULLUP_D0 0x01 /* Enable D0/MISO pullup */ -#define SBSDIO_PULLUP_D1 0x02 /* Enable D1/INT# pullup */ -#define SBSDIO_PULLUP_D2 0x04 /* Enable D2 pullup */ -#define SBSDIO_PULLUP_CMD 0x08 /* Enable CMD/MOSI pullup */ -#define SBSDIO_PULLUP_ALL 0x0f /* All valid bits */ - -/* function 1 OCP space */ -#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */ -#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000 -#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */ - -/* some duplication with sbsdpcmdev.h here */ -/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */ -#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */ -#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */ -#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */ -#define SBSDIO_SBWINDOW_MASK 0xffff8000 /* Address bits from SBADDR regs */ - -/* direct(mapped) cis space */ -#define SBSDIO_CIS_BASE_COMMON 0x1000 /* MAPPED common CIS address */ -#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */ -#define SBSDIO_OTP_CIS_SIZE_LIMIT 0x078 /* maximum bytes OTP CIS */ - -#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF /* cis offset addr is < 17 bits */ - -#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 /* manfid tuple length, include tuple, - * link bytes - */ - -/* indirect cis access (in sprom) */ -#define SBSDIO_SPROM_CIS_OFFSET 0x8 /* 8 control bytes first, CIS starts from - * 8th byte - */ - -#define SBSDIO_BYTEMODE_DATALEN_MAX 64 /* sdio byte mode: maximum length of one - * data command - */ - -#define SBSDIO_CORE_ADDR_MASK 0x1FFFF /* sdio core function one address mask */ - -#endif /* _SBSDIO_H */ diff --git a/drivers/staging/brcm80211/include/sbsdpcmdev.h b/drivers/staging/brcm80211/include/sbsdpcmdev.h deleted file mode 100644 index afd35811d4a5..000000000000 --- a/drivers/staging/brcm80211/include/sbsdpcmdev.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _sbsdpcmdev_h_ -#define _sbsdpcmdev_h_ - -/* cpp contortions to concatenate w/arg prescan */ -#ifndef PAD -#define _PADLINE(line) pad ## line -#define _XSTR(line) _PADLINE(line) -#define PAD _XSTR(__LINE__) -#endif /* PAD */ - -typedef volatile struct { - dma64regs_t xmt; /* dma tx */ - u32 PAD[2]; - dma64regs_t rcv; /* dma rx */ - u32 PAD[2]; -} dma64p_t; - -/* dma64 sdiod corerev >= 1 */ -typedef volatile struct { - dma64p_t dma64regs[2]; - dma64diag_t dmafifo; /* DMA Diagnostic Regs, 0x280-0x28c */ - u32 PAD[92]; -} sdiodma64_t; - -/* dma32 sdiod corerev == 0 */ -typedef volatile struct { - dma32regp_t dma32regs[2]; /* dma tx & rx, 0x200-0x23c */ - dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x240-0x24c */ - u32 PAD[108]; -} sdiodma32_t; - -/* dma32 regs for pcmcia core */ -typedef volatile struct { - dma32regp_t dmaregs; /* DMA Regs, 0x200-0x21c, rev8 */ - dma32diag_t dmafifo; /* DMA Diagnostic Regs, 0x220-0x22c */ - u32 PAD[116]; -} pcmdma32_t; - -/* core registers */ -typedef volatile struct { - u32 corecontrol; /* CoreControl, 0x000, rev8 */ - u32 corestatus; /* CoreStatus, 0x004, rev8 */ - u32 PAD[1]; - u32 biststatus; /* BistStatus, 0x00c, rev8 */ - - /* PCMCIA access */ - u16 pcmciamesportaladdr; /* PcmciaMesPortalAddr, 0x010, rev8 */ - u16 PAD[1]; - u16 pcmciamesportalmask; /* PcmciaMesPortalMask, 0x014, rev8 */ - u16 PAD[1]; - u16 pcmciawrframebc; /* PcmciaWrFrameBC, 0x018, rev8 */ - u16 PAD[1]; - u16 pcmciaunderflowtimer; /* PcmciaUnderflowTimer, 0x01c, rev8 */ - u16 PAD[1]; - - /* interrupt */ - u32 intstatus; /* IntStatus, 0x020, rev8 */ - u32 hostintmask; /* IntHostMask, 0x024, rev8 */ - u32 intmask; /* IntSbMask, 0x028, rev8 */ - u32 sbintstatus; /* SBIntStatus, 0x02c, rev8 */ - u32 sbintmask; /* SBIntMask, 0x030, rev8 */ - u32 funcintmask; /* SDIO Function Interrupt Mask, SDIO rev4 */ - u32 PAD[2]; - u32 tosbmailbox; /* ToSBMailbox, 0x040, rev8 */ - u32 tohostmailbox; /* ToHostMailbox, 0x044, rev8 */ - u32 tosbmailboxdata; /* ToSbMailboxData, 0x048, rev8 */ - u32 tohostmailboxdata; /* ToHostMailboxData, 0x04c, rev8 */ - - /* synchronized access to registers in SDIO clock domain */ - u32 sdioaccess; /* SdioAccess, 0x050, rev8 */ - u32 PAD[3]; - - /* PCMCIA frame control */ - u8 pcmciaframectrl; /* pcmciaFrameCtrl, 0x060, rev8 */ - u8 PAD[3]; - u8 pcmciawatermark; /* pcmciaWaterMark, 0x064, rev8 */ - u8 PAD[155]; - - /* interrupt batching control */ - u32 intrcvlazy; /* IntRcvLazy, 0x100, rev8 */ - u32 PAD[3]; - - /* counters */ - u32 cmd52rd; /* Cmd52RdCount, 0x110, rev8, SDIO: cmd52 reads */ - u32 cmd52wr; /* Cmd52WrCount, 0x114, rev8, SDIO: cmd52 writes */ - u32 cmd53rd; /* Cmd53RdCount, 0x118, rev8, SDIO: cmd53 reads */ - u32 cmd53wr; /* Cmd53WrCount, 0x11c, rev8, SDIO: cmd53 writes */ - u32 abort; /* AbortCount, 0x120, rev8, SDIO: aborts */ - u32 datacrcerror; /* DataCrcErrorCount, 0x124, rev8, SDIO: frames w/bad CRC */ - u32 rdoutofsync; /* RdOutOfSyncCount, 0x128, rev8, SDIO/PCMCIA: Rd Frm OOS */ - u32 wroutofsync; /* RdOutOfSyncCount, 0x12c, rev8, SDIO/PCMCIA: Wr Frm OOS */ - u32 writebusy; /* WriteBusyCount, 0x130, rev8, SDIO: dev asserted "busy" */ - u32 readwait; /* ReadWaitCount, 0x134, rev8, SDIO: read: no data avail */ - u32 readterm; /* ReadTermCount, 0x138, rev8, SDIO: rd frm terminates */ - u32 writeterm; /* WriteTermCount, 0x13c, rev8, SDIO: wr frm terminates */ - u32 PAD[40]; - u32 clockctlstatus; /* ClockCtlStatus, 0x1e0, rev8 */ - u32 PAD[7]; - - /* DMA engines */ - volatile union { - pcmdma32_t pcm32; - sdiodma32_t sdiod32; - sdiodma64_t sdiod64; - } dma; - - /* SDIO/PCMCIA CIS region */ - char cis[512]; /* 512 byte CIS, 0x400-0x5ff, rev6 */ - - /* PCMCIA function control registers */ - char pcmciafcr[256]; /* PCMCIA FCR, 0x600-6ff, rev6 */ - u16 PAD[55]; - - /* PCMCIA backplane access */ - u16 backplanecsr; /* BackplaneCSR, 0x76E, rev6 */ - u16 backplaneaddr0; /* BackplaneAddr0, 0x770, rev6 */ - u16 backplaneaddr1; /* BackplaneAddr1, 0x772, rev6 */ - u16 backplaneaddr2; /* BackplaneAddr2, 0x774, rev6 */ - u16 backplaneaddr3; /* BackplaneAddr3, 0x776, rev6 */ - u16 backplanedata0; /* BackplaneData0, 0x778, rev6 */ - u16 backplanedata1; /* BackplaneData1, 0x77a, rev6 */ - u16 backplanedata2; /* BackplaneData2, 0x77c, rev6 */ - u16 backplanedata3; /* BackplaneData3, 0x77e, rev6 */ - u16 PAD[31]; - - /* sprom "size" & "blank" info */ - u16 spromstatus; /* SPROMStatus, 0x7BE, rev2 */ - u32 PAD[464]; - - /* Sonics SiliconBackplane registers */ - sbconfig_t sbconfig; /* SbConfig Regs, 0xf00-0xfff, rev8 */ -} sdpcmd_regs_t; - -/* corecontrol */ -#define CC_CISRDY (1 << 0) /* CIS Ready */ -#define CC_BPRESEN (1 << 1) /* CCCR RES signal causes backplane reset */ -#define CC_F2RDY (1 << 2) /* set CCCR IOR2 bit */ -#define CC_CLRPADSISO (1 << 3) /* clear SDIO pads isolation bit (rev 11) */ -#define CC_XMTDATAAVAIL_MODE (1 << 4) /* data avail generates an interrupt */ -#define CC_XMTDATAAVAIL_CTRL (1 << 5) /* data avail interrupt ctrl */ - -/* corestatus */ -#define CS_PCMCIAMODE (1 << 0) /* Device Mode; 0=SDIO, 1=PCMCIA */ -#define CS_SMARTDEV (1 << 1) /* 1=smartDev enabled */ -#define CS_F2ENABLED (1 << 2) /* 1=host has enabled the device */ - -#define PCMCIA_MES_PA_MASK 0x7fff /* PCMCIA Message Portal Address Mask */ -#define PCMCIA_MES_PM_MASK 0x7fff /* PCMCIA Message Portal Mask Mask */ -#define PCMCIA_WFBC_MASK 0xffff /* PCMCIA Write Frame Byte Count Mask */ -#define PCMCIA_UT_MASK 0x07ff /* PCMCIA Underflow Timer Mask */ - -/* intstatus */ -#define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */ -#define I_SMB_SW1 (1 << 1) /* To SB Mail S/W interrupt 1 */ -#define I_SMB_SW2 (1 << 2) /* To SB Mail S/W interrupt 2 */ -#define I_SMB_SW3 (1 << 3) /* To SB Mail S/W interrupt 3 */ -#define I_SMB_SW_MASK 0x0000000f /* To SB Mail S/W interrupts mask */ -#define I_SMB_SW_SHIFT 0 /* To SB Mail S/W interrupts shift */ -#define I_HMB_SW0 (1 << 4) /* To Host Mail S/W interrupt 0 */ -#define I_HMB_SW1 (1 << 5) /* To Host Mail S/W interrupt 1 */ -#define I_HMB_SW2 (1 << 6) /* To Host Mail S/W interrupt 2 */ -#define I_HMB_SW3 (1 << 7) /* To Host Mail S/W interrupt 3 */ -#define I_HMB_SW_MASK 0x000000f0 /* To Host Mail S/W interrupts mask */ -#define I_HMB_SW_SHIFT 4 /* To Host Mail S/W interrupts shift */ -#define I_WR_OOSYNC (1 << 8) /* Write Frame Out Of Sync */ -#define I_RD_OOSYNC (1 << 9) /* Read Frame Out Of Sync */ -#define I_PC (1 << 10) /* descriptor error */ -#define I_PD (1 << 11) /* data error */ -#define I_DE (1 << 12) /* Descriptor protocol Error */ -#define I_RU (1 << 13) /* Receive descriptor Underflow */ -#define I_RO (1 << 14) /* Receive fifo Overflow */ -#define I_XU (1 << 15) /* Transmit fifo Underflow */ -#define I_RI (1 << 16) /* Receive Interrupt */ -#define I_BUSPWR (1 << 17) /* SDIO Bus Power Change (rev 9) */ -#define I_XMTDATA_AVAIL (1 << 23) /* bits in fifo */ -#define I_XI (1 << 24) /* Transmit Interrupt */ -#define I_RF_TERM (1 << 25) /* Read Frame Terminate */ -#define I_WF_TERM (1 << 26) /* Write Frame Terminate */ -#define I_PCMCIA_XU (1 << 27) /* PCMCIA Transmit FIFO Underflow */ -#define I_SBINT (1 << 28) /* sbintstatus Interrupt */ -#define I_CHIPACTIVE (1 << 29) /* chip transitioned from doze to active state */ -#define I_SRESET (1 << 30) /* CCCR RES interrupt */ -#define I_IOE2 (1U << 31) /* CCCR IOE2 Bit Changed */ -#define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU) /* DMA Errors */ -#define I_DMA (I_RI | I_XI | I_ERRORS) - -/* sbintstatus */ -#define I_SB_SERR (1 << 8) /* Backplane SError (write) */ -#define I_SB_RESPERR (1 << 9) /* Backplane Response Error (read) */ -#define I_SB_SPROMERR (1 << 10) /* Error accessing the sprom */ - -/* sdioaccess */ -#define SDA_DATA_MASK 0x000000ff /* Read/Write Data Mask */ -#define SDA_ADDR_MASK 0x000fff00 /* Read/Write Address Mask */ -#define SDA_ADDR_SHIFT 8 /* Read/Write Address Shift */ -#define SDA_WRITE 0x01000000 /* Write bit */ -#define SDA_READ 0x00000000 /* Write bit cleared for Read */ -#define SDA_BUSY 0x80000000 /* Busy bit */ - -/* sdioaccess-accessible register address spaces */ -#define SDA_CCCR_SPACE 0x000 /* sdioAccess CCCR register space */ -#define SDA_F1_FBR_SPACE 0x100 /* sdioAccess F1 FBR register space */ -#define SDA_F2_FBR_SPACE 0x200 /* sdioAccess F2 FBR register space */ -#define SDA_F1_REG_SPACE 0x300 /* sdioAccess F1 core-specific register space */ - -/* SDA_F1_REG_SPACE sdioaccess-accessible F1 reg space register offsets */ -#define SDA_CHIPCONTROLDATA 0x006 /* ChipControlData */ -#define SDA_CHIPCONTROLENAB 0x007 /* ChipControlEnable */ -#define SDA_F2WATERMARK 0x008 /* Function 2 Watermark */ -#define SDA_DEVICECONTROL 0x009 /* DeviceControl */ -#define SDA_SBADDRLOW 0x00a /* SbAddrLow */ -#define SDA_SBADDRMID 0x00b /* SbAddrMid */ -#define SDA_SBADDRHIGH 0x00c /* SbAddrHigh */ -#define SDA_FRAMECTRL 0x00d /* FrameCtrl */ -#define SDA_CHIPCLOCKCSR 0x00e /* ChipClockCSR */ -#define SDA_SDIOPULLUP 0x00f /* SdioPullUp */ -#define SDA_SDIOWRFRAMEBCLOW 0x019 /* SdioWrFrameBCLow */ -#define SDA_SDIOWRFRAMEBCHIGH 0x01a /* SdioWrFrameBCHigh */ -#define SDA_SDIORDFRAMEBCLOW 0x01b /* SdioRdFrameBCLow */ -#define SDA_SDIORDFRAMEBCHIGH 0x01c /* SdioRdFrameBCHigh */ - -/* SDA_F2WATERMARK */ -#define SDA_F2WATERMARK_MASK 0x7f /* F2Watermark Mask */ - -/* SDA_SBADDRLOW */ -#define SDA_SBADDRLOW_MASK 0x80 /* SbAddrLow Mask */ - -/* SDA_SBADDRMID */ -#define SDA_SBADDRMID_MASK 0xff /* SbAddrMid Mask */ - -/* SDA_SBADDRHIGH */ -#define SDA_SBADDRHIGH_MASK 0xff /* SbAddrHigh Mask */ - -/* SDA_FRAMECTRL */ -#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */ -#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */ -#define SFC_CRC4WOOS (1 << 2) /* HW reports CRC error for write out of sync */ -#define SFC_ABORTALL (1 << 3) /* Abort cancels all in-progress frames */ - -/* pcmciaframectrl */ -#define PFC_RF_TERM (1 << 0) /* Read Frame Terminate */ -#define PFC_WF_TERM (1 << 1) /* Write Frame Terminate */ - -/* intrcvlazy */ -#define IRL_TO_MASK 0x00ffffff /* timeout */ -#define IRL_FC_MASK 0xff000000 /* frame count */ -#define IRL_FC_SHIFT 24 /* frame count */ - -/* rx header */ -typedef volatile struct { - u16 len; - u16 flags; -} sdpcmd_rxh_t; - -/* rx header flags */ -#define RXF_CRC 0x0001 /* CRC error detected */ -#define RXF_WOOS 0x0002 /* write frame out of sync */ -#define RXF_WF_TERM 0x0004 /* write frame terminated */ -#define RXF_ABORT 0x0008 /* write frame aborted */ -#define RXF_DISCARD (RXF_CRC | RXF_WOOS | RXF_WF_TERM | RXF_ABORT) /* bad frame */ - -/* HW frame tag */ -#define SDPCM_FRAMETAG_LEN 4 /* HW frametag: 2 bytes len, 2 bytes check val */ - -#endif /* _sbsdpcmdev_h_ */ diff --git a/drivers/staging/brcm80211/include/sdio.h b/drivers/staging/brcm80211/include/sdio.h deleted file mode 100644 index 670e379b9aac..000000000000 --- a/drivers/staging/brcm80211/include/sdio.h +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SDIO_H -#define _SDIO_H - -#ifdef BCMSDIO - -/* CCCR structure for function 0 */ -typedef volatile struct { - u8 cccr_sdio_rev; /* RO, cccr and sdio revision */ - u8 sd_rev; /* RO, sd spec revision */ - u8 io_en; /* I/O enable */ - u8 io_rdy; /* I/O ready reg */ - u8 intr_ctl; /* Master and per function interrupt enable control */ - u8 intr_status; /* RO, interrupt pending status */ - u8 io_abort; /* read/write abort or reset all functions */ - u8 bus_inter; /* bus interface control */ - u8 capability; /* RO, card capability */ - - u8 cis_base_low; /* 0x9 RO, common CIS base address, LSB */ - u8 cis_base_mid; - u8 cis_base_high; /* 0xB RO, common CIS base address, MSB */ - - /* suspend/resume registers */ - u8 bus_suspend; /* 0xC */ - u8 func_select; /* 0xD */ - u8 exec_flag; /* 0xE */ - u8 ready_flag; /* 0xF */ - - u8 fn0_blk_size[2]; /* 0x10(LSB), 0x11(MSB) */ - - u8 power_control; /* 0x12 (SDIO version 1.10) */ - - u8 speed_control; /* 0x13 */ -} sdio_regs_t; - -/* SDIO Device CCCR offsets */ -#define SDIOD_CCCR_REV 0x00 -#define SDIOD_CCCR_SDREV 0x01 -#define SDIOD_CCCR_IOEN 0x02 -#define SDIOD_CCCR_IORDY 0x03 -#define SDIOD_CCCR_INTEN 0x04 -#define SDIOD_CCCR_INTPEND 0x05 -#define SDIOD_CCCR_IOABORT 0x06 -#define SDIOD_CCCR_BICTRL 0x07 -#define SDIOD_CCCR_CAPABLITIES 0x08 -#define SDIOD_CCCR_CISPTR_0 0x09 -#define SDIOD_CCCR_CISPTR_1 0x0A -#define SDIOD_CCCR_CISPTR_2 0x0B -#define SDIOD_CCCR_BUSSUSP 0x0C -#define SDIOD_CCCR_FUNCSEL 0x0D -#define SDIOD_CCCR_EXECFLAGS 0x0E -#define SDIOD_CCCR_RDYFLAGS 0x0F -#define SDIOD_CCCR_BLKSIZE_0 0x10 -#define SDIOD_CCCR_BLKSIZE_1 0x11 -#define SDIOD_CCCR_POWER_CONTROL 0x12 -#define SDIOD_CCCR_SPEED_CONTROL 0x13 - -/* Broadcom extensions (corerev >= 1) */ -#define SDIOD_CCCR_BRCM_SEPINT 0xf2 - -/* cccr_sdio_rev */ -#define SDIO_REV_SDIOID_MASK 0xf0 /* SDIO spec revision number */ -#define SDIO_REV_CCCRID_MASK 0x0f /* CCCR format version number */ - -/* sd_rev */ -#define SD_REV_PHY_MASK 0x0f /* SD format version number */ - -/* io_en */ -#define SDIO_FUNC_ENABLE_1 0x02 /* function 1 I/O enable */ -#define SDIO_FUNC_ENABLE_2 0x04 /* function 2 I/O enable */ - -/* io_rdys */ -#define SDIO_FUNC_READY_1 0x02 /* function 1 I/O ready */ -#define SDIO_FUNC_READY_2 0x04 /* function 2 I/O ready */ - -/* intr_ctl */ -#define INTR_CTL_MASTER_EN 0x1 /* interrupt enable master */ -#define INTR_CTL_FUNC1_EN 0x2 /* interrupt enable for function 1 */ -#define INTR_CTL_FUNC2_EN 0x4 /* interrupt enable for function 2 */ - -/* intr_status */ -#define INTR_STATUS_FUNC1 0x2 /* interrupt pending for function 1 */ -#define INTR_STATUS_FUNC2 0x4 /* interrupt pending for function 2 */ - -/* io_abort */ -#define IO_ABORT_RESET_ALL 0x08 /* I/O card reset */ -#define IO_ABORT_FUNC_MASK 0x07 /* abort selction: function x */ - -/* bus_inter */ -#define BUS_CARD_DETECT_DIS 0x80 /* Card Detect disable */ -#define BUS_SPI_CONT_INTR_CAP 0x40 /* support continuous SPI interrupt */ -#define BUS_SPI_CONT_INTR_EN 0x20 /* continuous SPI interrupt enable */ -#define BUS_SD_DATA_WIDTH_MASK 0x03 /* bus width mask */ -#define BUS_SD_DATA_WIDTH_4BIT 0x02 /* bus width 4-bit mode */ -#define BUS_SD_DATA_WIDTH_1BIT 0x00 /* bus width 1-bit mode */ - -/* capability */ -#define SDIO_CAP_4BLS 0x80 /* 4-bit support for low speed card */ -#define SDIO_CAP_LSC 0x40 /* low speed card */ -#define SDIO_CAP_E4MI 0x20 /* enable interrupt between block of data in 4-bit mode */ -#define SDIO_CAP_S4MI 0x10 /* support interrupt between block of data in 4-bit mode */ -#define SDIO_CAP_SBS 0x08 /* support suspend/resume */ -#define SDIO_CAP_SRW 0x04 /* support read wait */ -#define SDIO_CAP_SMB 0x02 /* support multi-block transfer */ -#define SDIO_CAP_SDC 0x01 /* Support Direct commands during multi-byte transfer */ - -/* power_control */ -#define SDIO_POWER_SMPC 0x01 /* supports master power control (RO) */ -#define SDIO_POWER_EMPC 0x02 /* enable master power control (allow > 200mA) (RW) */ - -/* speed_control (control device entry into high-speed clocking mode) */ -#define SDIO_SPEED_SHS 0x01 /* supports high-speed [clocking] mode (RO) */ -#define SDIO_SPEED_EHS 0x02 /* enable high-speed [clocking] mode (RW) */ - -/* brcm sepint */ -#define SDIO_SEPINT_MASK 0x01 /* route sdpcmdev intr onto separate pad (chip-specific) */ -#define SDIO_SEPINT_OE 0x02 /* 1 asserts output enable for above pad */ -#define SDIO_SEPINT_ACT_HI 0x04 /* use active high interrupt level instead of active low */ - -/* FBR structure for function 1-7, FBR addresses and register offsets */ -typedef volatile struct { - u8 devctr; /* device interface, CSA control */ - u8 ext_dev; /* extended standard I/O device type code */ - u8 pwr_sel; /* power selection support */ - u8 PAD[6]; /* reserved */ - - u8 cis_low; /* CIS LSB */ - u8 cis_mid; - u8 cis_high; /* CIS MSB */ - u8 csa_low; /* code storage area, LSB */ - u8 csa_mid; - u8 csa_high; /* code storage area, MSB */ - u8 csa_dat_win; /* data access window to function */ - - u8 fnx_blk_size[2]; /* block size, little endian */ -} sdio_fbr_t; - -/* Maximum number of I/O funcs */ -#define SDIOD_MAX_IOFUNCS 7 - -/* SDIO Device FBR Start Address */ -#define SDIOD_FBR_STARTADDR 0x100 - -/* SDIO Device FBR Size */ -#define SDIOD_FBR_SIZE 0x100 - -/* Macro to calculate FBR register base */ -#define SDIOD_FBR_BASE(n) ((n) * 0x100) - -/* Function register offsets */ -#define SDIOD_FBR_DEVCTR 0x00 /* basic info for function */ -#define SDIOD_FBR_EXT_DEV 0x01 /* extended I/O device code */ -#define SDIOD_FBR_PWR_SEL 0x02 /* power selection bits */ - -/* SDIO Function CIS ptr offset */ -#define SDIOD_FBR_CISPTR_0 0x09 -#define SDIOD_FBR_CISPTR_1 0x0A -#define SDIOD_FBR_CISPTR_2 0x0B - -/* Code Storage Area pointer */ -#define SDIOD_FBR_CSA_ADDR_0 0x0C -#define SDIOD_FBR_CSA_ADDR_1 0x0D -#define SDIOD_FBR_CSA_ADDR_2 0x0E -#define SDIOD_FBR_CSA_DATA 0x0F - -/* SDIO Function I/O Block Size */ -#define SDIOD_FBR_BLKSIZE_0 0x10 -#define SDIOD_FBR_BLKSIZE_1 0x11 - -/* devctr */ -#define SDIOD_FBR_DEVCTR_DIC 0x0f /* device interface code */ -#define SDIOD_FBR_DECVTR_CSA 0x40 /* CSA support flag */ -#define SDIOD_FBR_DEVCTR_CSA_EN 0x80 /* CSA enabled */ -/* interface codes */ -#define SDIOD_DIC_NONE 0 /* SDIO standard interface is not supported */ -#define SDIOD_DIC_UART 1 -#define SDIOD_DIC_BLUETOOTH_A 2 -#define SDIOD_DIC_BLUETOOTH_B 3 -#define SDIOD_DIC_GPS 4 -#define SDIOD_DIC_CAMERA 5 -#define SDIOD_DIC_PHS 6 -#define SDIOD_DIC_WLAN 7 -#define SDIOD_DIC_EXT 0xf /* extended device interface, read ext_dev register */ - -/* pwr_sel */ -#define SDIOD_PWR_SEL_SPS 0x01 /* supports power selection */ -#define SDIOD_PWR_SEL_EPS 0x02 /* enable power selection (low-current mode) */ - -/* misc defines */ -#define SDIO_FUNC_0 0 -#define SDIO_FUNC_1 1 -#define SDIO_FUNC_2 2 -#define SDIO_FUNC_3 3 -#define SDIO_FUNC_4 4 -#define SDIO_FUNC_5 5 -#define SDIO_FUNC_6 6 -#define SDIO_FUNC_7 7 - -#define SD_CARD_TYPE_UNKNOWN 0 /* bad type or unrecognized */ -#define SD_CARD_TYPE_IO 1 /* IO only card */ -#define SD_CARD_TYPE_MEMORY 2 /* memory only card */ -#define SD_CARD_TYPE_COMBO 3 /* IO and memory combo card */ - -#define SDIO_MAX_BLOCK_SIZE 2048 /* maximum block size for block mode operation */ -#define SDIO_MIN_BLOCK_SIZE 1 /* minimum block size for block mode operation */ - -/* Card registers: status bit position */ -#define CARDREG_STATUS_BIT_OUTOFRANGE 31 -#define CARDREG_STATUS_BIT_COMCRCERROR 23 -#define CARDREG_STATUS_BIT_ILLEGALCOMMAND 22 -#define CARDREG_STATUS_BIT_ERROR 19 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE3 12 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE2 11 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE1 10 -#define CARDREG_STATUS_BIT_IOCURRENTSTATE0 9 -#define CARDREG_STATUS_BIT_FUN_NUM_ERROR 4 - -#define SD_CMD_GO_IDLE_STATE 0 /* mandatory for SDIO */ -#define SD_CMD_SEND_OPCOND 1 -#define SD_CMD_MMC_SET_RCA 3 -#define SD_CMD_IO_SEND_OP_COND 5 /* mandatory for SDIO */ -#define SD_CMD_SELECT_DESELECT_CARD 7 -#define SD_CMD_SEND_CSD 9 -#define SD_CMD_SEND_CID 10 -#define SD_CMD_STOP_TRANSMISSION 12 -#define SD_CMD_SEND_STATUS 13 -#define SD_CMD_GO_INACTIVE_STATE 15 -#define SD_CMD_SET_BLOCKLEN 16 -#define SD_CMD_READ_SINGLE_BLOCK 17 -#define SD_CMD_READ_MULTIPLE_BLOCK 18 -#define SD_CMD_WRITE_BLOCK 24 -#define SD_CMD_WRITE_MULTIPLE_BLOCK 25 -#define SD_CMD_PROGRAM_CSD 27 -#define SD_CMD_SET_WRITE_PROT 28 -#define SD_CMD_CLR_WRITE_PROT 29 -#define SD_CMD_SEND_WRITE_PROT 30 -#define SD_CMD_ERASE_WR_BLK_START 32 -#define SD_CMD_ERASE_WR_BLK_END 33 -#define SD_CMD_ERASE 38 -#define SD_CMD_LOCK_UNLOCK 42 -#define SD_CMD_IO_RW_DIRECT 52 /* mandatory for SDIO */ -#define SD_CMD_IO_RW_EXTENDED 53 /* mandatory for SDIO */ -#define SD_CMD_APP_CMD 55 -#define SD_CMD_GEN_CMD 56 -#define SD_CMD_READ_OCR 58 -#define SD_CMD_CRC_ON_OFF 59 /* mandatory for SDIO */ -#define SD_ACMD_SD_STATUS 13 -#define SD_ACMD_SEND_NUM_WR_BLOCKS 22 -#define SD_ACMD_SET_WR_BLOCK_ERASE_CNT 23 -#define SD_ACMD_SD_SEND_OP_COND 41 -#define SD_ACMD_SET_CLR_CARD_DETECT 42 -#define SD_ACMD_SEND_SCR 51 - -/* argument for SD_CMD_IO_RW_DIRECT and SD_CMD_IO_RW_EXTENDED */ -#define SD_IO_OP_READ 0 /* Read_Write: Read */ -#define SD_IO_OP_WRITE 1 /* Read_Write: Write */ -#define SD_IO_RW_NORMAL 0 /* no RAW */ -#define SD_IO_RW_RAW 1 /* RAW */ -#define SD_IO_BYTE_MODE 0 /* Byte Mode */ -#define SD_IO_BLOCK_MODE 1 /* BlockMode */ -#define SD_IO_FIXED_ADDRESS 0 /* fix Address */ -#define SD_IO_INCREMENT_ADDRESS 1 /* IncrementAddress */ - -/* build SD_CMD_IO_RW_DIRECT Argument */ -#define SDIO_IO_RW_DIRECT_ARG(rw, raw, func, addr, data) \ - ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((raw) & 1) << 27) | \ - (((addr) & 0x1FFFF) << 9) | ((data) & 0xFF)) - -/* build SD_CMD_IO_RW_EXTENDED Argument */ -#define SDIO_IO_RW_EXTENDED_ARG(rw, blk, func, addr, inc_addr, count) \ - ((((rw) & 1) << 31) | (((func) & 0x7) << 28) | (((blk) & 1) << 27) | \ - (((inc_addr) & 1) << 26) | (((addr) & 0x1FFFF) << 9) | ((count) & 0x1FF)) - -/* SDIO response parameters */ -#define SD_RSP_NO_NONE 0 -#define SD_RSP_NO_1 1 -#define SD_RSP_NO_2 2 -#define SD_RSP_NO_3 3 -#define SD_RSP_NO_4 4 -#define SD_RSP_NO_5 5 -#define SD_RSP_NO_6 6 - - /* Modified R6 response (to CMD3) */ -#define SD_RSP_MR6_COM_CRC_ERROR 0x8000 -#define SD_RSP_MR6_ILLEGAL_COMMAND 0x4000 -#define SD_RSP_MR6_ERROR 0x2000 - - /* Modified R1 in R4 Response (to CMD5) */ -#define SD_RSP_MR1_SBIT 0x80 -#define SD_RSP_MR1_PARAMETER_ERROR 0x40 -#define SD_RSP_MR1_RFU5 0x20 -#define SD_RSP_MR1_FUNC_NUM_ERROR 0x10 -#define SD_RSP_MR1_COM_CRC_ERROR 0x08 -#define SD_RSP_MR1_ILLEGAL_COMMAND 0x04 -#define SD_RSP_MR1_RFU1 0x02 -#define SD_RSP_MR1_IDLE_STATE 0x01 - - /* R5 response (to CMD52 and CMD53) */ -#define SD_RSP_R5_COM_CRC_ERROR 0x80 -#define SD_RSP_R5_ILLEGAL_COMMAND 0x40 -#define SD_RSP_R5_IO_CURRENTSTATE1 0x20 -#define SD_RSP_R5_IO_CURRENTSTATE0 0x10 -#define SD_RSP_R5_ERROR 0x08 -#define SD_RSP_R5_RFU 0x04 -#define SD_RSP_R5_FUNC_NUM_ERROR 0x02 -#define SD_RSP_R5_OUT_OF_RANGE 0x01 - -#define SD_RSP_R5_ERRBITS 0xCB - -/* ------------------------------------------------ - * SDIO Commands and responses - * - * I/O only commands are: - * CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53 - * ------------------------------------------------ - */ - -/* SDIO Commands */ -#define SDIOH_CMD_0 0 -#define SDIOH_CMD_3 3 -#define SDIOH_CMD_5 5 -#define SDIOH_CMD_7 7 -#define SDIOH_CMD_15 15 -#define SDIOH_CMD_52 52 -#define SDIOH_CMD_53 53 -#define SDIOH_CMD_59 59 - -/* SDIO Command Responses */ -#define SDIOH_RSP_NONE 0 -#define SDIOH_RSP_R1 1 -#define SDIOH_RSP_R2 2 -#define SDIOH_RSP_R3 3 -#define SDIOH_RSP_R4 4 -#define SDIOH_RSP_R5 5 -#define SDIOH_RSP_R6 6 - -/* - * SDIO Response Error flags - */ -#define SDIOH_RSP5_ERROR_FLAGS 0xCB - -/* ------------------------------------------------ - * SDIO Command structures. I/O only commands are: - * - * CMD0, CMD3, CMD5, CMD7, CMD15, CMD52, CMD53 - * ------------------------------------------------ - */ - -#define CMD5_OCR_M BITFIELD_MASK(24) -#define CMD5_OCR_S 0 - -#define CMD7_RCA_M BITFIELD_MASK(16) -#define CMD7_RCA_S 16 - -#define CMD_15_RCA_M BITFIELD_MASK(16) -#define CMD_15_RCA_S 16 - -#define CMD52_DATA_M BITFIELD_MASK(8) /* Bits [7:0] - Write Data/Stuff bits of CMD52 - */ -#define CMD52_DATA_S 0 -#define CMD52_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */ -#define CMD52_REG_ADDR_S 9 -#define CMD52_RAW_M BITFIELD_MASK(1) /* Bit 27 - Read after Write flag */ -#define CMD52_RAW_S 27 -#define CMD52_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */ -#define CMD52_FUNCTION_S 28 -#define CMD52_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */ -#define CMD52_RW_FLAG_S 31 - -#define CMD53_BYTE_BLK_CNT_M BITFIELD_MASK(9) /* Bits [8:0] - Byte/Block Count of CMD53 */ -#define CMD53_BYTE_BLK_CNT_S 0 -#define CMD53_REG_ADDR_M BITFIELD_MASK(17) /* Bits [25:9] - register address */ -#define CMD53_REG_ADDR_S 9 -#define CMD53_OP_CODE_M BITFIELD_MASK(1) /* Bit 26 - R/W Operation Code */ -#define CMD53_OP_CODE_S 26 -#define CMD53_BLK_MODE_M BITFIELD_MASK(1) /* Bit 27 - Block Mode */ -#define CMD53_BLK_MODE_S 27 -#define CMD53_FUNCTION_M BITFIELD_MASK(3) /* Bits [30:28] - Function number */ -#define CMD53_FUNCTION_S 28 -#define CMD53_RW_FLAG_M BITFIELD_MASK(1) /* Bit 31 - R/W flag */ -#define CMD53_RW_FLAG_S 31 - -/* ------------------------------------------------------ - * SDIO Command Response structures for SD1 and SD4 modes - * ----------------------------------------------------- - */ -#define RSP4_IO_OCR_M BITFIELD_MASK(24) /* Bits [23:0] - Card's OCR Bits [23:0] */ -#define RSP4_IO_OCR_S 0 -#define RSP4_STUFF_M BITFIELD_MASK(3) /* Bits [26:24] - Stuff bits */ -#define RSP4_STUFF_S 24 -#define RSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 27 - Memory present */ -#define RSP4_MEM_PRESENT_S 27 -#define RSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [30:28] - Number of I/O funcs */ -#define RSP4_NUM_FUNCS_S 28 -#define RSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 31 - SDIO card ready */ -#define RSP4_CARD_READY_S 31 - -#define RSP6_STATUS_M BITFIELD_MASK(16) /* Bits [15:0] - Card status bits [19,22,23,12:0] - */ -#define RSP6_STATUS_S 0 -#define RSP6_IO_RCA_M BITFIELD_MASK(16) /* Bits [31:16] - RCA bits[31-16] */ -#define RSP6_IO_RCA_S 16 - -#define RSP1_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error */ -#define RSP1_AKE_SEQ_ERROR_S 3 -#define RSP1_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */ -#define RSP1_APP_CMD_S 5 -#define RSP1_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data (buff empty) */ -#define RSP1_READY_FOR_DATA_S 8 -#define RSP1_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - State of card - * when Cmd was received - */ -#define RSP1_CURR_STATE_S 9 -#define RSP1_EARSE_RESET_M BITFIELD_MASK(1) /* Bit 13 - Erase seq cleared */ -#define RSP1_EARSE_RESET_S 13 -#define RSP1_CARD_ECC_DISABLE_M BITFIELD_MASK(1) /* Bit 14 - Card ECC disabled */ -#define RSP1_CARD_ECC_DISABLE_S 14 -#define RSP1_WP_ERASE_SKIP_M BITFIELD_MASK(1) /* Bit 15 - Partial blocks erased due to W/P */ -#define RSP1_WP_ERASE_SKIP_S 15 -#define RSP1_CID_CSD_OVERW_M BITFIELD_MASK(1) /* Bit 16 - Illegal write to CID or R/O bits - * of CSD - */ -#define RSP1_CID_CSD_OVERW_S 16 -#define RSP1_ERROR_M BITFIELD_MASK(1) /* Bit 19 - General/Unknown error */ -#define RSP1_ERROR_S 19 -#define RSP1_CC_ERROR_M BITFIELD_MASK(1) /* Bit 20 - Internal Card Control error */ -#define RSP1_CC_ERROR_S 20 -#define RSP1_CARD_ECC_FAILED_M BITFIELD_MASK(1) /* Bit 21 - Card internal ECC failed - * to correct data - */ -#define RSP1_CARD_ECC_FAILED_S 21 -#define RSP1_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 22 - Cmd not legal for the card state */ -#define RSP1_ILLEGAL_CMD_S 22 -#define RSP1_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 23 - CRC check of previous command failed - */ -#define RSP1_COM_CRC_ERROR_S 23 -#define RSP1_LOCK_UNLOCK_FAIL_M BITFIELD_MASK(1) /* Bit 24 - Card lock-unlock Cmd Seq error */ -#define RSP1_LOCK_UNLOCK_FAIL_S 24 -#define RSP1_CARD_LOCKED_M BITFIELD_MASK(1) /* Bit 25 - Card locked by the host */ -#define RSP1_CARD_LOCKED_S 25 -#define RSP1_WP_VIOLATION_M BITFIELD_MASK(1) /* Bit 26 - Attempt to program - * write-protected blocks - */ -#define RSP1_WP_VIOLATION_S 26 -#define RSP1_ERASE_PARAM_M BITFIELD_MASK(1) /* Bit 27 - Invalid erase blocks */ -#define RSP1_ERASE_PARAM_S 27 -#define RSP1_ERASE_SEQ_ERR_M BITFIELD_MASK(1) /* Bit 28 - Erase Cmd seq error */ -#define RSP1_ERASE_SEQ_ERR_S 28 -#define RSP1_BLK_LEN_ERR_M BITFIELD_MASK(1) /* Bit 29 - Block length error */ -#define RSP1_BLK_LEN_ERR_S 29 -#define RSP1_ADDR_ERR_M BITFIELD_MASK(1) /* Bit 30 - Misaligned address */ -#define RSP1_ADDR_ERR_S 30 -#define RSP1_OUT_OF_RANGE_M BITFIELD_MASK(1) /* Bit 31 - Cmd arg was out of range */ -#define RSP1_OUT_OF_RANGE_S 31 - -#define RSP5_DATA_M BITFIELD_MASK(8) /* Bits [0:7] - data */ -#define RSP5_DATA_S 0 -#define RSP5_FLAGS_M BITFIELD_MASK(8) /* Bit [15:8] - Rsp flags */ -#define RSP5_FLAGS_S 8 -#define RSP5_STUFF_M BITFIELD_MASK(16) /* Bits [31:16] - Stuff bits */ -#define RSP5_STUFF_S 16 - -/* ---------------------------------------------- - * SDIO Command Response structures for SPI mode - * ---------------------------------------------- - */ -#define SPIRSP4_IO_OCR_M BITFIELD_MASK(16) /* Bits [15:0] - Card's OCR Bits [23:8] */ -#define SPIRSP4_IO_OCR_S 0 -#define SPIRSP4_STUFF_M BITFIELD_MASK(3) /* Bits [18:16] - Stuff bits */ -#define SPIRSP4_STUFF_S 16 -#define SPIRSP4_MEM_PRESENT_M BITFIELD_MASK(1) /* Bit 19 - Memory present */ -#define SPIRSP4_MEM_PRESENT_S 19 -#define SPIRSP4_NUM_FUNCS_M BITFIELD_MASK(3) /* Bits [22:20] - Number of I/O funcs */ -#define SPIRSP4_NUM_FUNCS_S 20 -#define SPIRSP4_CARD_READY_M BITFIELD_MASK(1) /* Bit 23 - SDIO card ready */ -#define SPIRSP4_CARD_READY_S 23 -#define SPIRSP4_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - idle state */ -#define SPIRSP4_IDLE_STATE_S 24 -#define SPIRSP4_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */ -#define SPIRSP4_ILLEGAL_CMD_S 26 -#define SPIRSP4_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */ -#define SPIRSP4_COM_CRC_ERROR_S 27 -#define SPIRSP4_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error - */ -#define SPIRSP4_FUNC_NUM_ERROR_S 28 -#define SPIRSP4_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */ -#define SPIRSP4_PARAM_ERROR_S 30 -#define SPIRSP4_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */ -#define SPIRSP4_START_BIT_S 31 - -#define SPIRSP5_DATA_M BITFIELD_MASK(8) /* Bits [23:16] - R/W Data */ -#define SPIRSP5_DATA_S 16 -#define SPIRSP5_IDLE_STATE_M BITFIELD_MASK(1) /* Bit 24 - Idle state */ -#define SPIRSP5_IDLE_STATE_S 24 -#define SPIRSP5_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 26 - Illegal Cmd error */ -#define SPIRSP5_ILLEGAL_CMD_S 26 -#define SPIRSP5_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 27 - COM CRC error */ -#define SPIRSP5_COM_CRC_ERROR_S 27 -#define SPIRSP5_FUNC_NUM_ERROR_M BITFIELD_MASK(1) /* Bit 28 - Function number error - */ -#define SPIRSP5_FUNC_NUM_ERROR_S 28 -#define SPIRSP5_PARAM_ERROR_M BITFIELD_MASK(1) /* Bit 30 - Parameter Error Bit */ -#define SPIRSP5_PARAM_ERROR_S 30 -#define SPIRSP5_START_BIT_M BITFIELD_MASK(1) /* Bit 31 - Start Bit */ -#define SPIRSP5_START_BIT_S 31 - -/* RSP6 card status format; Pg 68 Physical Layer spec v 1.10 */ -#define RSP6STAT_AKE_SEQ_ERROR_M BITFIELD_MASK(1) /* Bit 3 - Authentication seq error - */ -#define RSP6STAT_AKE_SEQ_ERROR_S 3 -#define RSP6STAT_APP_CMD_M BITFIELD_MASK(1) /* Bit 5 - Card expects ACMD */ -#define RSP6STAT_APP_CMD_S 5 -#define RSP6STAT_READY_FOR_DATA_M BITFIELD_MASK(1) /* Bit 8 - Ready for data - * (buff empty) - */ -#define RSP6STAT_READY_FOR_DATA_S 8 -#define RSP6STAT_CURR_STATE_M BITFIELD_MASK(4) /* Bits [12:9] - Card state at - * Cmd reception - */ -#define RSP6STAT_CURR_STATE_S 9 -#define RSP6STAT_ERROR_M BITFIELD_MASK(1) /* Bit 13 - General/Unknown error Bit 19 - */ -#define RSP6STAT_ERROR_S 13 -#define RSP6STAT_ILLEGAL_CMD_M BITFIELD_MASK(1) /* Bit 14 - Illegal cmd for - * card state Bit 22 - */ -#define RSP6STAT_ILLEGAL_CMD_S 14 -#define RSP6STAT_COM_CRC_ERROR_M BITFIELD_MASK(1) /* Bit 15 - CRC previous command - * failed Bit 23 - */ -#define RSP6STAT_COM_CRC_ERROR_S 15 - -#define SDIOH_XFER_TYPE_READ SD_IO_OP_READ -#define SDIOH_XFER_TYPE_WRITE SD_IO_OP_WRITE - -#endif /* def BCMSDIO */ -#endif /* _SDIO_H */ diff --git a/drivers/staging/brcm80211/include/soc.h b/drivers/staging/brcm80211/include/soc.h new file mode 100644 index 000000000000..6e5a705c4937 --- /dev/null +++ b/drivers/staging/brcm80211/include/soc.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BRCM_SOC_H +#define _BRCM_SOC_H + +#ifdef SI_ENUM_BASE_VARIABLE +#define SI_ENUM_BASE (sii->pub.si_enum_base) +#else +#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */ +#endif /* SI_ENUM_BASE_VARIABLE */ + +/* core codes */ +#define NODEV_CORE_ID 0x700 /* Invalid coreid */ +#define CC_CORE_ID 0x800 /* chipcommon core */ +#define ILINE20_CORE_ID 0x801 /* iline20 core */ +#define SRAM_CORE_ID 0x802 /* sram core */ +#define SDRAM_CORE_ID 0x803 /* sdram core */ +#define PCI_CORE_ID 0x804 /* pci core */ +#define MIPS_CORE_ID 0x805 /* mips core */ +#define ENET_CORE_ID 0x806 /* enet mac core */ +#define CODEC_CORE_ID 0x807 /* v90 codec core */ +#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ +#define ADSL_CORE_ID 0x809 /* ADSL core */ +#define ILINE100_CORE_ID 0x80a /* iline100 core */ +#define IPSEC_CORE_ID 0x80b /* ipsec core */ +#define UTOPIA_CORE_ID 0x80c /* utopia core */ +#define PCMCIA_CORE_ID 0x80d /* pcmcia core */ +#define SOCRAM_CORE_ID 0x80e /* internal memory core */ +#define MEMC_CORE_ID 0x80f /* memc sdram core */ +#define OFDM_CORE_ID 0x810 /* OFDM phy core */ +#define EXTIF_CORE_ID 0x811 /* external interface core */ +#define D11_CORE_ID 0x812 /* 802.11 MAC core */ +#define APHY_CORE_ID 0x813 /* 802.11a phy core */ +#define BPHY_CORE_ID 0x814 /* 802.11b phy core */ +#define GPHY_CORE_ID 0x815 /* 802.11g phy core */ +#define MIPS33_CORE_ID 0x816 /* mips3302 core */ +#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ +#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ +#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ +#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ +#define SDIOH_CORE_ID 0x81b /* sdio host core */ +#define ROBO_CORE_ID 0x81c /* roboswitch core */ +#define ATA100_CORE_ID 0x81d /* parallel ATA core */ +#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ +#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ +#define PCIE_CORE_ID 0x820 /* pci express core */ +#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ +#define SRAMC_CORE_ID 0x822 /* SRAM controller core */ +#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ +#define ARM11_CORE_ID 0x824 /* ARM 1176 core */ +#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ +#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ +#define PMU_CORE_ID 0x827 /* PMU core */ +#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ +#define SDIOD_CORE_ID 0x829 /* SDIO device core */ +#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ +#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ +#define MIPS74K_CORE_ID 0x82c /* mips 74k core */ +#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ +#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ +#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ +#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ +#define SC_CORE_ID 0x831 /* shared common core */ +#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ +#define SPIH_CORE_ID 0x833 /* SPI host core */ +#define I2S_CORE_ID 0x834 /* I2S core */ +#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ +#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ +#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ +#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all + * unused address ranges + */ + +/* Common core control flags */ +#define SICF_BIST_EN 0x8000 +#define SICF_PME_EN 0x4000 +#define SICF_CORE_BITS 0x3ffc +#define SICF_FGC 0x0002 +#define SICF_CLOCK_EN 0x0001 + +#endif /* _BRCM_SOC_H */ diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h deleted file mode 100644 index 2876bd9eff85..000000000000 --- a/drivers/staging/brcm80211/include/wlioctl.h +++ /dev/null @@ -1,1365 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlioctl_h_ -#define _wlioctl_h_ - -#include -#ifdef BRCM_FULLMAC -#include -#endif -#include -#include -#include - -#ifndef INTF_NAME_SIZ -#define INTF_NAME_SIZ 16 -#endif - -#ifdef BRCM_FULLMAC - -#define WL_BSS_INFO_VERSION 108 /* current ver of wl_bss_info struct */ - -/* BSS info structure - * Applications MUST CHECK ie_offset field and length field to access IEs and - * next bss_info structure in a vector (in wl_scan_results_t) - */ -typedef struct wl_bss_info { - u32 version; /* version field */ - u32 length; /* byte length of data in this record, - * starting at version and including IEs - */ - u8 BSSID[ETH_ALEN]; - u16 beacon_period; /* units are Kusec */ - u16 capability; /* Capability information */ - u8 SSID_len; - u8 SSID[32]; - struct { - uint count; /* # rates in this set */ - u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ - } rateset; /* supported rates */ - chanspec_t chanspec; /* chanspec for bss */ - u16 atim_window; /* units are Kusec */ - u8 dtim_period; /* DTIM period */ - s16 RSSI; /* receive signal strength (in dBm) */ - s8 phy_noise; /* noise (in dBm) */ - - u8 n_cap; /* BSS is 802.11N Capable */ - u32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */ - u8 ctl_ch; /* 802.11N BSS control channel number */ - u32 reserved32[1]; /* Reserved for expansion of BSS properties */ - u8 flags; /* flags */ - u8 reserved[3]; /* Reserved for expansion of BSS properties */ - u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ - - u16 ie_offset; /* offset at which IEs start, from beginning */ - u32 ie_length; /* byte length of Information Elements */ - s16 SNR; /* average SNR of during frame reception */ - /* Add new fields here */ - /* variable length Information Elements */ -} wl_bss_info_t; -#endif /* BRCM_FULLMAC */ - -typedef struct wlc_ssid { - u32 SSID_len; - unsigned char SSID[32]; -} wlc_ssid_t; - -#ifdef BRCM_FULLMAC -typedef struct chan_scandata { - u8 txpower; - u8 pad; - chanspec_t channel; /* Channel num, bw, ctrl_sb and band */ - u32 channel_mintime; - u32 channel_maxtime; -} chan_scandata_t; - -typedef enum wl_scan_type { - EXTDSCAN_FOREGROUND_SCAN, - EXTDSCAN_BACKGROUND_SCAN, - EXTDSCAN_FORCEDBACKGROUND_SCAN -} wl_scan_type_t; - -#define WLC_EXTDSCAN_MAX_SSID 5 - -#define WL_BSS_FLAGS_FROM_BEACON 0x01 /* bss_info derived from beacon */ -#define WL_BSS_FLAGS_FROM_CACHE 0x02 /* bss_info collected from cache */ -#define WL_BSS_FLAGS_RSSI_ONCHANNEL 0x04 /* rssi info was received on channel (vs offchannel) */ - -typedef struct wl_extdscan_params { - s8 nprobes; /* 0, passive, otherwise active */ - s8 split_scan; /* split scan */ - s8 band; /* band */ - s8 pad; - wlc_ssid_t ssid[WLC_EXTDSCAN_MAX_SSID]; /* ssid list */ - u32 tx_rate; /* in 500ksec units */ - wl_scan_type_t scan_type; /* enum */ - s32 channel_num; - chan_scandata_t channel_list[1]; /* list of chandata structs */ -} wl_extdscan_params_t; - -#define WL_EXTDSCAN_PARAMS_FIXED_SIZE (sizeof(wl_extdscan_params_t) - sizeof(chan_scandata_t)) - -#define WL_BSSTYPE_INFRA 1 -#define WL_BSSTYPE_INDEP 0 -#define WL_BSSTYPE_ANY 2 - -/* Bitmask for scan_type */ -#define WL_SCANFLAGS_PASSIVE 0x01 /* force passive scan */ -#define WL_SCANFLAGS_RESERVED 0x02 /* Reserved */ -#define WL_SCANFLAGS_PROHIBITED 0x04 /* allow scanning prohibited channels */ - -typedef struct wl_scan_params { - wlc_ssid_t ssid; /* default: {0, ""} */ - u8 bssid[ETH_ALEN]; /* default: bcast */ - s8 bss_type; /* default: any, - * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT - */ - u8 scan_type; /* flags, 0 use default */ - s32 nprobes; /* -1 use default, number of probes per channel */ - s32 active_time; /* -1 use default, dwell time per channel for - * active scanning - */ - s32 passive_time; /* -1 use default, dwell time per channel - * for passive scanning - */ - s32 home_time; /* -1 use default, dwell time for the home channel - * between channel scans - */ - s32 channel_num; /* count of channels and ssids that follow - * - * low half is count of channels in channel_list, 0 - * means default (use all available channels) - * - * high half is entries in wlc_ssid_t array that - * follows channel_list, aligned for s32 (4 bytes) - * meaning an odd channel count implies a 2-byte pad - * between end of channel_list and first ssid - * - * if ssid count is zero, single ssid in the fixed - * parameter portion is assumed, otherwise ssid in - * the fixed portion is ignored - */ - u16 channel_list[1]; /* list of chanspecs */ -} wl_scan_params_t; - -/* size of wl_scan_params not including variable length array */ -#define WL_SCAN_PARAMS_FIXED_SIZE 64 - -/* masks for channel and ssid count */ -#define WL_SCAN_PARAMS_COUNT_MASK 0x0000ffff -#define WL_SCAN_PARAMS_NSSID_SHIFT 16 - -#define WL_SCAN_ACTION_START 1 -#define WL_SCAN_ACTION_CONTINUE 2 -#define WL_SCAN_ACTION_ABORT 3 - -#define ISCAN_REQ_VERSION 1 - -/* incremental scan struct */ -typedef struct wl_iscan_params { - u32 version; - u16 action; - u16 scan_duration; - wl_scan_params_t params; -} wl_iscan_params_t; - -/* 3 fields + size of wl_scan_params, not including variable length array */ -#define WL_ISCAN_PARAMS_FIXED_SIZE (offsetof(wl_iscan_params_t, params) + sizeof(wlc_ssid_t)) - -typedef struct wl_scan_results { - u32 buflen; - u32 version; - u32 count; - wl_bss_info_t bss_info[1]; -} wl_scan_results_t; - -/* size of wl_scan_results not including variable length array */ -#define WL_SCAN_RESULTS_FIXED_SIZE (sizeof(wl_scan_results_t) - sizeof(wl_bss_info_t)) - -/* wl_iscan_results status values */ -#define WL_SCAN_RESULTS_SUCCESS 0 -#define WL_SCAN_RESULTS_PARTIAL 1 -#define WL_SCAN_RESULTS_PENDING 2 -#define WL_SCAN_RESULTS_ABORTED 3 -#define WL_SCAN_RESULTS_NO_MEM 4 - -#define ESCAN_REQ_VERSION 1 - -typedef struct wl_escan_params { - u32 version; - u16 action; - u16 sync_id; - wl_scan_params_t params; -} wl_escan_params_t; - -#define WL_ESCAN_PARAMS_FIXED_SIZE (offsetof(wl_escan_params_t, params) + sizeof(wlc_ssid_t)) - -typedef struct wl_escan_result { - u32 buflen; - u32 version; - u16 sync_id; - u16 bss_count; - wl_bss_info_t bss_info[1]; -} wl_escan_result_t; - -#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(wl_escan_result_t) - sizeof(wl_bss_info_t)) - -/* incremental scan results struct */ -typedef struct wl_iscan_results { - u32 status; - wl_scan_results_t results; -} wl_iscan_results_t; - -/* size of wl_iscan_results not including variable length array */ -#define WL_ISCAN_RESULTS_FIXED_SIZE \ - (WL_SCAN_RESULTS_FIXED_SIZE + offsetof(wl_iscan_results_t, results)) - -typedef struct wl_probe_params { - wlc_ssid_t ssid; - u8 bssid[ETH_ALEN]; - u8 mac[ETH_ALEN]; -} wl_probe_params_t; -#endif /* BRCM_FULLMAC */ - -#define WL_NUMRATES 16 /* max # of rates in a rateset */ -typedef struct wl_rateset { - u32 count; /* # rates in this set */ - u8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ -} wl_rateset_t; - -#ifdef BRCM_FULLMAC -typedef struct wl_rateset_args { - u32 count; /* # rates in this set */ - u8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ - u8 mcs[MCSSET_LEN]; /* supported mcs index bit map */ -} wl_rateset_args_t; - -/* u32 list */ -typedef struct wl_u32_list { - /* in - # of elements, out - # of entries */ - u32 count; - /* variable length u32 list */ - u32 element[1]; -} wl_u32_list_t; - -/* used for association with a specific BSSID and chanspec list */ -typedef struct wl_assoc_params { - u8 bssid[ETH_ALEN]; /* 00:00:00:00:00:00: broadcast scan */ - u16 bssid_cnt; - s32 chanspec_num; /* 0: all available channels, - * otherwise count of chanspecs in chanspec_list - */ - chanspec_t chanspec_list[1]; /* list of chanspecs */ -} wl_assoc_params_t; -#define WL_ASSOC_PARAMS_FIXED_SIZE (sizeof(wl_assoc_params_t) - sizeof(chanspec_t)) - -/* used for reassociation/roam to a specific BSSID and channel */ -typedef wl_assoc_params_t wl_reassoc_params_t; -#define WL_REASSOC_PARAMS_FIXED_SIZE WL_ASSOC_PARAMS_FIXED_SIZE - -/* used for join with or without a specific bssid and channel list */ -typedef struct wl_join_params { - wlc_ssid_t ssid; - wl_assoc_params_t params; /* optional field, but it must include the fixed portion - * of the wl_assoc_params_t struct when it does present. - */ -} wl_join_params_t; -#define WL_JOIN_PARAMS_FIXED_SIZE (sizeof(wl_join_params_t) - sizeof(chanspec_t)) - -#endif /* BRCM_FULLMAC */ - -/* defines used by the nrate iovar */ -#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ -#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ -#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ -#define NRATE_STF_SHIFT 8 /* stf mode shift */ -#define NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ -#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */ -#define NRATE_SGI_MASK 0x00800000 /* sgi mode */ -#define NRATE_SGI_SHIFT 23 /* sgi mode */ -#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ -#define NRATE_LDPC_SHIFT 22 /* ldpc shift */ - -#define NRATE_STF_SISO 0 /* stf mode SISO */ -#define NRATE_STF_CDD 1 /* stf mode CDD */ -#define NRATE_STF_STBC 2 /* stf mode STBC */ -#define NRATE_STF_SDM 3 /* stf mode SDM */ - -#define ANTENNA_NUM_1 1 /* total number of antennas to be used */ -#define ANTENNA_NUM_2 2 -#define ANTENNA_NUM_3 3 -#define ANTENNA_NUM_4 4 - -#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ -#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ -#define ANT_SELCFG_MAX 4 /* max number of antenna configurations */ -#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */ -#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */ -#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */ -#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */ - -#define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */ - -typedef struct { - u8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */ - u8 num_antcfg; /* number of available antenna configurations */ -} wlc_antselcfg_t; - -#define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */ - -#ifdef BRCM_FULLMAC -#define MAX_CCA_CHANNELS 38 /* Max number of 20 Mhz wide channels */ -#define MAX_CCA_SECS 60 /* CCA keeps this many seconds history */ - -#define IBSS_MED 15 /* Mediom in-bss congestion percentage */ -#define IBSS_HI 25 /* Hi in-bss congestion percentage */ -#define OBSS_MED 12 -#define OBSS_HI 25 -#define INTERFER_MED 5 -#define INTERFER_HI 10 - -#define CCA_FLAG_2G_ONLY 0x01 /* Return a channel from 2.4 Ghz band */ -#define CCA_FLAG_5G_ONLY 0x02 /* Return a channel from 2.4 Ghz band */ -#define CCA_FLAG_IGNORE_DURATION 0x04 /* Ignore dwell time for each channel */ -#define CCA_FLAGS_PREFER_1_6_11 0x10 -#define CCA_FLAG_IGNORE_INTERFER 0x20 /* do not exlude channel based on interfer level */ - -#define CCA_ERRNO_BAND 1 /* After filtering for band pref, no choices left */ -#define CCA_ERRNO_DURATION 2 /* After filtering for duration, no choices left */ -#define CCA_ERRNO_PREF_CHAN 3 /* After filtering for chan pref, no choices left */ -#define CCA_ERRNO_INTERFER 4 /* After filtering for interference, no choices left */ -#define CCA_ERRNO_TOO_FEW 5 /* Only 1 channel was input */ - -typedef struct { - u32 duration; /* millisecs spent sampling this channel */ - u32 congest_ibss; /* millisecs in our bss (presumably this traffic will */ - /* move if cur bss moves channels) */ - u32 congest_obss; /* traffic not in our bss */ - u32 interference; /* millisecs detecting a non 802.11 interferer. */ - u32 timestamp; /* second timestamp */ -} cca_congest_t; - -typedef struct { - chanspec_t chanspec; /* Which channel? */ - u8 num_secs; /* How many secs worth of data */ - cca_congest_t secs[1]; /* Data */ -} cca_congest_channel_req_t; - -#endif /* BRCM_FULLMAC */ - -#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */ - -#ifdef BRCM_FULLMAC -typedef struct wl_country { - char country_abbrev[WLC_CNTRY_BUF_SZ]; /* nul-terminated country code used in - * the Country IE - */ - s32 rev; /* revision specifier for ccode - * on set, -1 indicates unspecified. - * on get, rev >= 0 - */ - char ccode[WLC_CNTRY_BUF_SZ]; /* nul-terminated built-in country code. - * variable length, but fixed size in - * struct allows simple allocation for - * expected country strings <= 3 chars. - */ -} wl_country_t; - -typedef struct wl_channels_in_country { - u32 buflen; - u32 band; - char country_abbrev[WLC_CNTRY_BUF_SZ]; - u32 count; - u32 channel[1]; -} wl_channels_in_country_t; - -typedef struct wl_country_list { - u32 buflen; - u32 band_set; - u32 band; - u32 count; - char country_abbrev[1]; -} wl_country_list_t; - -#define WL_NUM_RPI_BINS 8 -#define WL_RM_TYPE_BASIC 1 -#define WL_RM_TYPE_CCA 2 -#define WL_RM_TYPE_RPI 3 - -#define WL_RM_FLAG_PARALLEL (1<<0) - -#define WL_RM_FLAG_LATE (1<<1) -#define WL_RM_FLAG_INCAPABLE (1<<2) -#define WL_RM_FLAG_REFUSED (1<<3) - -typedef struct wl_rm_req_elt { - s8 type; - s8 flags; - chanspec_t chanspec; - u32 token; /* token for this measurement */ - u32 tsf_h; /* TSF high 32-bits of Measurement start time */ - u32 tsf_l; /* TSF low 32-bits */ - u32 dur; /* TUs */ -} wl_rm_req_elt_t; - -typedef struct wl_rm_req { - u32 token; /* overall measurement set token */ - u32 count; /* number of measurement requests */ - void *cb; /* completion callback function: may be NULL */ - void *cb_arg; /* arg to completion callback function */ - wl_rm_req_elt_t req[1]; /* variable length block of requests */ -} wl_rm_req_t; -#define WL_RM_REQ_FIXED_LEN offsetof(wl_rm_req_t, req) - -typedef struct wl_rm_rep_elt { - s8 type; - s8 flags; - chanspec_t chanspec; - u32 token; /* token for this measurement */ - u32 tsf_h; /* TSF high 32-bits of Measurement start time */ - u32 tsf_l; /* TSF low 32-bits */ - u32 dur; /* TUs */ - u32 len; /* byte length of data block */ - u8 data[1]; /* variable length data block */ -} wl_rm_rep_elt_t; -#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */ - -#define WL_RPI_REP_BIN_NUM 8 -typedef struct wl_rm_rpi_rep { - u8 rpi[WL_RPI_REP_BIN_NUM]; - s8 rpi_max[WL_RPI_REP_BIN_NUM]; -} wl_rm_rpi_rep_t; - -typedef struct wl_rm_rep { - u32 token; /* overall measurement set token */ - u32 len; /* length of measurement report block */ - wl_rm_rep_elt_t rep[1]; /* variable length block of reports */ -} wl_rm_rep_t; -#define WL_RM_REP_FIXED_LEN 8 -#endif /* BRCM_FULLMAC */ - -/* Enumerate crypto algorithms */ -#define CRYPTO_ALGO_OFF 0 -#define CRYPTO_ALGO_WEP1 1 -#define CRYPTO_ALGO_TKIP 2 -#define CRYPTO_ALGO_WEP128 3 -#define CRYPTO_ALGO_AES_CCM 4 -#define CRYPTO_ALGO_AES_RESERVED1 5 -#define CRYPTO_ALGO_AES_RESERVED2 6 -#define CRYPTO_ALGO_NALG 7 - -#define WSEC_GEN_MIC_ERROR 0x0001 -#define WSEC_GEN_REPLAY 0x0002 -#define WSEC_GEN_ICV_ERROR 0x0004 - -#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ -#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ -#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ -#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ -#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */ - -typedef struct wl_wsec_key { - u32 index; /* key index */ - u32 len; /* key length */ - u8 data[WLAN_MAX_KEY_LEN]; /* key data */ - u32 pad_1[18]; - u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ - u32 flags; /* misc flags */ - u32 pad_2[2]; - int pad_3; - int iv_initialized; /* has IV been initialized already? */ - int pad_4; - /* Rx IV */ - struct { - u32 hi; /* upper 32 bits of IV */ - u16 lo; /* lower 16 bits of IV */ - } rxiv; - u32 pad_5[2]; - u8 ea[ETH_ALEN]; /* per station */ -} wl_wsec_key_t; - -#define WSEC_MIN_PSK_LEN 8 -#define WSEC_MAX_PSK_LEN 64 - -/* Flag for key material needing passhash'ing */ -#define WSEC_PASSPHRASE (1<<0) - -/* receptacle for WLC_SET_WSEC_PMK parameter */ -typedef struct { - unsigned short key_len; /* octets in key material */ - unsigned short flags; /* key handling qualification */ - u8 key[WSEC_MAX_PSK_LEN]; /* PMK material */ -} wsec_pmk_t; - -/* wireless security bitvec */ -#define WEP_ENABLED 0x0001 -#define TKIP_ENABLED 0x0002 -#define AES_ENABLED 0x0004 -#define WSEC_SWFLAG 0x0008 -#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ - -/* WPA authentication mode bitvec */ -#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ -#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */ -#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */ -#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ -#define WPA_AUTH_RESERVED1 0x0008 -#define WPA_AUTH_RESERVED2 0x0010 - /* #define WPA_AUTH_8021X 0x0020 *//* 802.1x, reserved */ -#define WPA2_AUTH_RESERVED1 0x0020 -#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ -#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ -#define WPA2_AUTH_RESERVED3 0x0200 -#define WPA2_AUTH_RESERVED4 0x0400 -#define WPA2_AUTH_RESERVED5 0x0800 - -/* pmkid */ -#define MAXPMKID 16 - -typedef struct _pmkid { - u8 BSSID[ETH_ALEN]; - u8 PMKID[WLAN_PMKID_LEN]; -} pmkid_t; - -typedef struct _pmkid_list { - u32 npmkid; - pmkid_t pmkid[1]; -} pmkid_list_t; - -typedef struct _pmkid_cand { - u8 BSSID[ETH_ALEN]; - u8 preauth; -} pmkid_cand_t; - -typedef struct _pmkid_cand_list { - u32 npmkid_cand; - pmkid_cand_t pmkid_cand[1]; -} pmkid_cand_list_t; - -typedef struct wl_led_info { - u32 index; /* led index */ - u32 behavior; - u8 activehi; -} wl_led_info_t; - -/* R_REG and W_REG struct passed through ioctl */ -typedef struct { - u32 byteoff; /* byte offset of the field in d11regs_t */ - u32 val; /* read/write value of the field */ - u32 size; /* sizeof the field */ - uint band; /* band (optional) */ -} rw_reg_t; - - -#ifdef BRCM_FULLMAC -/* Used to get specific STA parameters */ -typedef struct { - u32 val; - u8 ea[ETH_ALEN]; -} scb_val_t; -#endif /* BRCM_FULLMAC */ - -/* channel encoding */ -typedef struct channel_info { - int hw_channel; - int target_channel; - int scan_channel; -} channel_info_t; - -/* For ioctls that take a list of MAC addresses */ -struct maclist { - uint count; /* number of MAC addresses */ - u8 ea[1][ETH_ALEN]; /* variable length array of MAC addresses */ -}; - -#ifdef BRCM_FULLMAC -/* Linux network driver ioctl encoding */ -typedef struct wl_ioctl { - uint cmd; /* common ioctl definition */ - void *buf; /* pointer to user buffer */ - uint len; /* length of user buffer */ - u8 set; /* get or set request (optional) */ - uint used; /* bytes read or written (optional) */ - uint needed; /* bytes needed (optional) */ -} wl_ioctl_t; -#endif /* BRCM_FULLMAC */ - - -/* - * Structure for passing hardware and software - * revision info up from the driver. - */ -typedef struct wlc_rev_info { - uint vendorid; /* PCI vendor id */ - uint deviceid; /* device id of chip */ - uint radiorev; /* radio revision */ - uint chiprev; /* chip revision */ - uint corerev; /* core revision */ - uint boardid; /* board identifier (usu. PCI sub-device id) */ - uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */ - uint boardrev; /* board revision */ - uint driverrev; /* driver version */ - uint ucoderev; /* microcode version */ - uint bus; /* bus type */ - uint chipnum; /* chip number */ - uint phytype; /* phy type */ - uint phyrev; /* phy revision */ - uint anarev; /* anacore rev */ - uint chippkg; /* chip package info */ -} wlc_rev_info_t; - -#define WL_REV_INFO_LEGACY_LENGTH 48 - -#ifdef BRCM_FULLMAC -#define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ -#define WLC_IOCTL_MEDLEN 1536 /* "med" length ioctl buffer required */ -#define WLC_IOCTL_MAXLEN 8192 -#endif - -/* common ioctl definitions */ -#define WLC_GET_MAGIC 0 -#define WLC_GET_VERSION 1 -#define WLC_UP 2 -#define WLC_DOWN 3 -#define WLC_GET_LOOP 4 -#define WLC_SET_LOOP 5 -#define WLC_DUMP 6 -#define WLC_GET_MSGLEVEL 7 -#define WLC_SET_MSGLEVEL 8 -#define WLC_GET_PROMISC 9 -#define WLC_SET_PROMISC 10 -#define WLC_OVERLAY_IOCTL 11 -#define WLC_GET_RATE 12 - /* #define WLC_SET_RATE 13 *//* no longer supported */ -#define WLC_GET_INSTANCE 14 - /* #define WLC_GET_FRAG 15 *//* no longer supported */ - /* #define WLC_SET_FRAG 16 *//* no longer supported */ - /* #define WLC_GET_RTS 17 *//* no longer supported */ - /* #define WLC_SET_RTS 18 *//* no longer supported */ -#define WLC_GET_INFRA 19 -#define WLC_SET_INFRA 20 -#define WLC_GET_AUTH 21 -#define WLC_SET_AUTH 22 -#define WLC_GET_BSSID 23 -#define WLC_SET_BSSID 24 -#define WLC_GET_SSID 25 -#define WLC_SET_SSID 26 -#define WLC_RESTART 27 - /* #define WLC_DUMP_SCB 28 *//* no longer supported */ -#define WLC_GET_CHANNEL 29 -#define WLC_SET_CHANNEL 30 -#define WLC_GET_SRL 31 -#define WLC_SET_SRL 32 -#define WLC_GET_LRL 33 -#define WLC_SET_LRL 34 -#define WLC_GET_PLCPHDR 35 -#define WLC_SET_PLCPHDR 36 -#define WLC_GET_RADIO 37 -#define WLC_SET_RADIO 38 -#define WLC_GET_PHYTYPE 39 -#define WLC_DUMP_RATE 40 -#define WLC_SET_RATE_PARAMS 41 -#define WLC_GET_FIXRATE 42 -#define WLC_SET_FIXRATE 43 - /* #define WLC_GET_WEP 42 *//* no longer supported */ - /* #define WLC_SET_WEP 43 *//* no longer supported */ -#define WLC_GET_KEY 44 -#define WLC_SET_KEY 45 -#define WLC_GET_REGULATORY 46 -#define WLC_SET_REGULATORY 47 -#define WLC_GET_PASSIVE_SCAN 48 -#define WLC_SET_PASSIVE_SCAN 49 -#define WLC_SCAN 50 -#define WLC_SCAN_RESULTS 51 -#define WLC_DISASSOC 52 -#define WLC_REASSOC 53 -#define WLC_GET_ROAM_TRIGGER 54 -#define WLC_SET_ROAM_TRIGGER 55 -#define WLC_GET_ROAM_DELTA 56 -#define WLC_SET_ROAM_DELTA 57 -#define WLC_GET_ROAM_SCAN_PERIOD 58 -#define WLC_SET_ROAM_SCAN_PERIOD 59 -#define WLC_EVM 60 /* diag */ -#define WLC_GET_TXANT 61 -#define WLC_SET_TXANT 62 -#define WLC_GET_ANTDIV 63 -#define WLC_SET_ANTDIV 64 - /* #define WLC_GET_TXPWR 65 *//* no longer supported */ - /* #define WLC_SET_TXPWR 66 *//* no longer supported */ -#define WLC_GET_CLOSED 67 -#define WLC_SET_CLOSED 68 -#define WLC_GET_MACLIST 69 -#define WLC_SET_MACLIST 70 -#define WLC_GET_RATESET 71 -#define WLC_SET_RATESET 72 - /* #define WLC_GET_LOCALE 73 *//* no longer supported */ -#define WLC_LONGTRAIN 74 -#define WLC_GET_BCNPRD 75 -#define WLC_SET_BCNPRD 76 -#define WLC_GET_DTIMPRD 77 -#define WLC_SET_DTIMPRD 78 -#define WLC_GET_SROM 79 -#define WLC_SET_SROM 80 -#define WLC_GET_WEP_RESTRICT 81 -#define WLC_SET_WEP_RESTRICT 82 -#define WLC_GET_COUNTRY 83 -#define WLC_SET_COUNTRY 84 -#define WLC_GET_PM 85 -#define WLC_SET_PM 86 -#define WLC_GET_WAKE 87 -#define WLC_SET_WAKE 88 - /* #define WLC_GET_D11CNTS 89 *//* -> "counters" iovar */ -#define WLC_GET_FORCELINK 90 /* ndis only */ -#define WLC_SET_FORCELINK 91 /* ndis only */ -#define WLC_FREQ_ACCURACY 92 /* diag */ -#define WLC_CARRIER_SUPPRESS 93 /* diag */ -#define WLC_GET_PHYREG 94 -#define WLC_SET_PHYREG 95 -#define WLC_GET_RADIOREG 96 -#define WLC_SET_RADIOREG 97 -#define WLC_GET_REVINFO 98 -#define WLC_GET_UCANTDIV 99 -#define WLC_SET_UCANTDIV 100 -#define WLC_R_REG 101 -#define WLC_W_REG 102 -/* #define WLC_DIAG_LOOPBACK 103 old tray diag */ - /* #define WLC_RESET_D11CNTS 104 *//* -> "reset_d11cnts" iovar */ -#define WLC_GET_MACMODE 105 -#define WLC_SET_MACMODE 106 -#define WLC_GET_MONITOR 107 -#define WLC_SET_MONITOR 108 -#define WLC_GET_GMODE 109 -#define WLC_SET_GMODE 110 -#define WLC_GET_LEGACY_ERP 111 -#define WLC_SET_LEGACY_ERP 112 -#define WLC_GET_RX_ANT 113 -#define WLC_GET_CURR_RATESET 114 /* current rateset */ -#define WLC_GET_SCANSUPPRESS 115 -#define WLC_SET_SCANSUPPRESS 116 -#define WLC_GET_AP 117 -#define WLC_SET_AP 118 -#define WLC_GET_EAP_RESTRICT 119 -#define WLC_SET_EAP_RESTRICT 120 -#define WLC_SCB_AUTHORIZE 121 -#define WLC_SCB_DEAUTHORIZE 122 -#define WLC_GET_WDSLIST 123 -#define WLC_SET_WDSLIST 124 -#define WLC_GET_ATIM 125 -#define WLC_SET_ATIM 126 -#define WLC_GET_RSSI 127 -#define WLC_GET_PHYANTDIV 128 -#define WLC_SET_PHYANTDIV 129 -#define WLC_AP_RX_ONLY 130 -#define WLC_GET_TX_PATH_PWR 131 -#define WLC_SET_TX_PATH_PWR 132 -#define WLC_GET_WSEC 133 -#define WLC_SET_WSEC 134 -#define WLC_GET_PHY_NOISE 135 -#define WLC_GET_BSS_INFO 136 -#define WLC_GET_PKTCNTS 137 -#define WLC_GET_LAZYWDS 138 -#define WLC_SET_LAZYWDS 139 -#define WLC_GET_BANDLIST 140 -#define WLC_GET_BAND 141 -#define WLC_SET_BAND 142 -#define WLC_SCB_DEAUTHENTICATE 143 -#define WLC_GET_SHORTSLOT 144 -#define WLC_GET_SHORTSLOT_OVERRIDE 145 -#define WLC_SET_SHORTSLOT_OVERRIDE 146 -#define WLC_GET_SHORTSLOT_RESTRICT 147 -#define WLC_SET_SHORTSLOT_RESTRICT 148 -#define WLC_GET_GMODE_PROTECTION 149 -#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 -#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 -#define WLC_UPGRADE 152 - /* #define WLC_GET_MRATE 153 *//* no longer supported */ - /* #define WLC_SET_MRATE 154 *//* no longer supported */ -#define WLC_GET_IGNORE_BCNS 155 -#define WLC_SET_IGNORE_BCNS 156 -#define WLC_GET_SCB_TIMEOUT 157 -#define WLC_SET_SCB_TIMEOUT 158 -#define WLC_GET_ASSOCLIST 159 -#define WLC_GET_CLK 160 -#define WLC_SET_CLK 161 -#define WLC_GET_UP 162 -#define WLC_OUT 163 -#define WLC_GET_WPA_AUTH 164 -#define WLC_SET_WPA_AUTH 165 -#define WLC_GET_UCFLAGS 166 -#define WLC_SET_UCFLAGS 167 -#define WLC_GET_PWRIDX 168 -#define WLC_SET_PWRIDX 169 -#define WLC_GET_TSSI 170 -#define WLC_GET_SUP_RATESET_OVERRIDE 171 -#define WLC_SET_SUP_RATESET_OVERRIDE 172 - /* #define WLC_SET_FAST_TIMER 173 *//* no longer supported */ - /* #define WLC_GET_FAST_TIMER 174 *//* no longer supported */ - /* #define WLC_SET_SLOW_TIMER 175 *//* no longer supported */ - /* #define WLC_GET_SLOW_TIMER 176 *//* no longer supported */ - /* #define WLC_DUMP_PHYREGS 177 *//* no longer supported */ -#define WLC_GET_PROTECTION_CONTROL 178 -#define WLC_SET_PROTECTION_CONTROL 179 -#define WLC_GET_PHYLIST 180 -#define WLC_ENCRYPT_STRENGTH 181 /* ndis only */ -#define WLC_DECRYPT_STATUS 182 /* ndis only */ -#define WLC_GET_KEY_SEQ 183 -#define WLC_GET_SCAN_CHANNEL_TIME 184 -#define WLC_SET_SCAN_CHANNEL_TIME 185 -#define WLC_GET_SCAN_UNASSOC_TIME 186 -#define WLC_SET_SCAN_UNASSOC_TIME 187 -#define WLC_GET_SCAN_HOME_TIME 188 -#define WLC_SET_SCAN_HOME_TIME 189 -#define WLC_GET_SCAN_NPROBES 190 -#define WLC_SET_SCAN_NPROBES 191 -#define WLC_GET_PRB_RESP_TIMEOUT 192 -#define WLC_SET_PRB_RESP_TIMEOUT 193 -#define WLC_GET_ATTEN 194 -#define WLC_SET_ATTEN 195 -#define WLC_GET_SHMEM 196 /* diag */ -#define WLC_SET_SHMEM 197 /* diag */ - /* #define WLC_GET_GMODE_PROTECTION_CTS 198 *//* no longer supported */ - /* #define WLC_SET_GMODE_PROTECTION_CTS 199 *//* no longer supported */ -#define WLC_SET_WSEC_TEST 200 -#define WLC_SCB_DEAUTHENTICATE_FOR_REASON 201 -#define WLC_TKIP_COUNTERMEASURES 202 -#define WLC_GET_PIOMODE 203 -#define WLC_SET_PIOMODE 204 -#define WLC_SET_ASSOC_PREFER 205 -#define WLC_GET_ASSOC_PREFER 206 -#define WLC_SET_ROAM_PREFER 207 -#define WLC_GET_ROAM_PREFER 208 -#define WLC_SET_LED 209 -#define WLC_GET_LED 210 -#define WLC_RESERVED6 211 -#define WLC_RESERVED7 212 -#define WLC_GET_CHANNEL_QA 213 -#define WLC_START_CHANNEL_QA 214 -#define WLC_GET_CHANNEL_SEL 215 -#define WLC_START_CHANNEL_SEL 216 -#define WLC_GET_VALID_CHANNELS 217 -#define WLC_GET_FAKEFRAG 218 -#define WLC_SET_FAKEFRAG 219 -#define WLC_GET_PWROUT_PERCENTAGE 220 -#define WLC_SET_PWROUT_PERCENTAGE 221 -#define WLC_SET_BAD_FRAME_PREEMPT 222 -#define WLC_GET_BAD_FRAME_PREEMPT 223 -#define WLC_SET_LEAP_LIST 224 -#define WLC_GET_LEAP_LIST 225 -#define WLC_GET_CWMIN 226 -#define WLC_SET_CWMIN 227 -#define WLC_GET_CWMAX 228 -#define WLC_SET_CWMAX 229 -#define WLC_GET_WET 230 -#define WLC_SET_WET 231 -#define WLC_GET_PUB 232 - /* #define WLC_SET_GLACIAL_TIMER 233 *//* no longer supported */ - /* #define WLC_GET_GLACIAL_TIMER 234 *//* no longer supported */ -#define WLC_GET_KEY_PRIMARY 235 -#define WLC_SET_KEY_PRIMARY 236 - /* #define WLC_DUMP_RADIOREGS 237 *//* no longer supported */ -#define WLC_RESERVED4 238 -#define WLC_RESERVED5 239 -#define WLC_UNSET_CALLBACK 240 -#define WLC_SET_CALLBACK 241 -#define WLC_GET_RADAR 242 -#define WLC_SET_RADAR 243 -#define WLC_SET_SPECT_MANAGMENT 244 -#define WLC_GET_SPECT_MANAGMENT 245 -#define WLC_WDS_GET_REMOTE_HWADDR 246 /* handled in wl_linux.c/wl_vx.c */ -#define WLC_WDS_GET_WPA_SUP 247 -#define WLC_SET_CS_SCAN_TIMER 248 -#define WLC_GET_CS_SCAN_TIMER 249 -#define WLC_MEASURE_REQUEST 250 -#define WLC_INIT 251 -#define WLC_SEND_QUIET 252 -#define WLC_KEEPALIVE 253 -#define WLC_SEND_PWR_CONSTRAINT 254 -#define WLC_UPGRADE_STATUS 255 -#define WLC_CURRENT_PWR 256 -#define WLC_GET_SCAN_PASSIVE_TIME 257 -#define WLC_SET_SCAN_PASSIVE_TIME 258 -#define WLC_LEGACY_LINK_BEHAVIOR 259 -#define WLC_GET_CHANNELS_IN_COUNTRY 260 -#define WLC_GET_COUNTRY_LIST 261 -#define WLC_GET_VAR 262 /* get value of named variable */ -#define WLC_SET_VAR 263 /* set named variable to value */ -#define WLC_NVRAM_GET 264 /* deprecated */ -#define WLC_NVRAM_SET 265 -#define WLC_NVRAM_DUMP 266 -#define WLC_REBOOT 267 -#define WLC_SET_WSEC_PMK 268 -#define WLC_GET_AUTH_MODE 269 -#define WLC_SET_AUTH_MODE 270 -#define WLC_GET_WAKEENTRY 271 -#define WLC_SET_WAKEENTRY 272 -#define WLC_NDCONFIG_ITEM 273 /* currently handled in wl_oid.c */ -#define WLC_NVOTPW 274 -#define WLC_OTPW 275 -#define WLC_IOV_BLOCK_GET 276 -#define WLC_IOV_MODULES_GET 277 -#define WLC_SOFT_RESET 278 -#define WLC_GET_ALLOW_MODE 279 -#define WLC_SET_ALLOW_MODE 280 -#define WLC_GET_DESIRED_BSSID 281 -#define WLC_SET_DESIRED_BSSID 282 -#define WLC_DISASSOC_MYAP 283 -#define WLC_GET_RESERVED10 284 -#define WLC_GET_RESERVED11 285 -#define WLC_GET_RESERVED12 286 -#define WLC_GET_RESERVED13 287 -#define WLC_GET_RESERVED14 288 -#define WLC_SET_RESERVED15 289 -#define WLC_SET_RESERVED16 290 -#define WLC_GET_RESERVED17 291 -#define WLC_GET_RESERVED18 292 -#define WLC_GET_RESERVED19 293 -#define WLC_SET_RESERVED1A 294 -#define WLC_GET_RESERVED1B 295 -#define WLC_GET_RESERVED1C 296 -#define WLC_GET_RESERVED1D 297 -#define WLC_SET_RESERVED1E 298 -#define WLC_GET_RESERVED1F 299 -#define WLC_GET_RESERVED20 300 -#define WLC_GET_RESERVED21 301 -#define WLC_GET_RESERVED22 302 -#define WLC_GET_RESERVED23 303 -#define WLC_GET_RESERVED24 304 -#define WLC_SET_RESERVED25 305 -#define WLC_GET_RESERVED26 306 -#define WLC_NPHY_SAMPLE_COLLECT 307 /* Nphy sample collect mode */ -#define WLC_UM_PRIV 308 /* for usermode driver private ioctl */ -#define WLC_GET_CMD 309 - /* #define WLC_LAST 310 *//* Never used - can be reused */ -#define WLC_RESERVED8 311 -#define WLC_RESERVED9 312 -#define WLC_RESERVED1 313 -#define WLC_RESERVED2 314 -#define WLC_RESERVED3 315 -#define WLC_LAST 316 - -#ifndef EPICTRL_COOKIE -#define EPICTRL_COOKIE 0xABADCEDE -#endif - -#define WL_DECRYPT_STATUS_SUCCESS 1 -#define WL_DECRYPT_STATUS_FAILURE 2 -#define WL_DECRYPT_STATUS_UNKNOWN 3 - -/* allows user-mode app to poll the status of USB image upgrade */ -#define WLC_UPGRADE_SUCCESS 0 -#define WLC_UPGRADE_PENDING 1 - -/* WLC_GET_AUTH, WLC_SET_AUTH values */ -#define WL_AUTH_OPEN_SYSTEM 0 /* d11 open authentication */ -#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */ -#define WL_AUTH_OPEN_SHARED 2 /* try open, then shared if open failed w/rc 13 */ - -/* Bit masks for radio disabled status - returned by WL_GET_RADIO */ -#define WL_RADIO_SW_DISABLE (1<<0) -#define WL_RADIO_HW_DISABLE (1<<1) -#define WL_RADIO_MPC_DISABLE (1<<2) -#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any channel */ - -#define WL_SPURAVOID_OFF 0 -#define WL_SPURAVOID_ON1 1 -#define WL_SPURAVOID_ON2 2 - -/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */ -#define WL_TXPWR_OVERRIDE (1U<<31) - -#define WL_PHY_PAVARS_LEN 6 /* Phy type, Band range, chain, a1, b0, b1 */ - -typedef struct wl_po { - u16 phy_type; /* Phy type */ - u16 band; - u16 cckpo; - u32 ofdmpo; - u16 mcspo[8]; -} wl_po_t; - -/* a large TX Power as an init value to factor out of min() calculations, - * keep low enough to fit in an s8, units are .25 dBm - */ -#define WLC_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */ - -/* "diag" iovar argument and error code */ -#define WL_DIAG_INTERRUPT 1 /* d11 loopback interrupt test */ -#define WL_DIAG_LOOPBACK 2 /* d11 loopback data test */ -#define WL_DIAG_MEMORY 3 /* d11 memory test */ -#define WL_DIAG_LED 4 /* LED test */ -#define WL_DIAG_REG 5 /* d11/phy register test */ -#define WL_DIAG_SROM 6 /* srom read/crc test */ -#define WL_DIAG_DMA 7 /* DMA test */ - -#define WL_DIAGERR_SUCCESS 0 -#define WL_DIAGERR_FAIL_TO_RUN 1 /* unable to run requested diag */ -#define WL_DIAGERR_NOT_SUPPORTED 2 /* diag requested is not supported */ -#define WL_DIAGERR_INTERRUPT_FAIL 3 /* loopback interrupt test failed */ -#define WL_DIAGERR_LOOPBACK_FAIL 4 /* loopback data test failed */ -#define WL_DIAGERR_SROM_FAIL 5 /* srom read failed */ -#define WL_DIAGERR_SROM_BADCRC 6 /* srom crc failed */ -#define WL_DIAGERR_REG_FAIL 7 /* d11/phy register test failed */ -#define WL_DIAGERR_MEMORY_FAIL 8 /* d11 memory test failed */ -#define WL_DIAGERR_NOMEM 9 /* diag test failed due to no memory */ -#define WL_DIAGERR_DMA_FAIL 10 /* DMA test failed */ - -#define WL_DIAGERR_MEMORY_TIMEOUT 11 /* d11 memory test didn't finish in time */ -#define WL_DIAGERR_MEMORY_BADPATTERN 12 /* d11 memory test result in bad pattern */ - -/* band types */ -#define WLC_BAND_AUTO 0 /* auto-select */ -#define WLC_BAND_5G 1 /* 5 Ghz */ -#define WLC_BAND_2G 2 /* 2.4 Ghz */ -#define WLC_BAND_ALL 3 /* all bands */ - -/* band range returned by band_range iovar */ -#define WL_CHAN_FREQ_RANGE_2G 0 -#define WL_CHAN_FREQ_RANGE_5GL 1 -#define WL_CHAN_FREQ_RANGE_5GM 2 -#define WL_CHAN_FREQ_RANGE_5GH 3 - -/* phy types (returned by WLC_GET_PHYTPE) */ -#define WLC_PHY_TYPE_A 0 -#define WLC_PHY_TYPE_B 1 -#define WLC_PHY_TYPE_G 2 -#define WLC_PHY_TYPE_N 4 -#define WLC_PHY_TYPE_LP 5 -#define WLC_PHY_TYPE_SSN 6 -#define WLC_PHY_TYPE_HT 7 -#define WLC_PHY_TYPE_LCN 8 -#define WLC_PHY_TYPE_NULL 0xf - -/* MAC list modes */ -#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */ -#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */ -#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */ - -/* - * 54g modes (basic bits may still be overridden) - * - * GMODE_LEGACY_B Rateset: 1b, 2b, 5.5, 11 - * Preamble: Long - * Shortslot: Off - * GMODE_AUTO Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 - * Extended Rateset: 6, 9, 12, 48 - * Preamble: Long - * Shortslot: Auto - * GMODE_ONLY Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54 - * Extended Rateset: 6b, 9, 12b, 48 - * Preamble: Short required - * Shortslot: Auto - * GMODE_B_DEFERRED Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 - * Extended Rateset: 6, 9, 12, 48 - * Preamble: Long - * Shortslot: On - * GMODE_PERFORMANCE Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54 - * Preamble: Short required - * Shortslot: On and required - * GMODE_LRS Rateset: 1b, 2b, 5.5b, 11b - * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54 - * Preamble: Long - * Shortslot: Auto - */ -#define GMODE_LEGACY_B 0 -#define GMODE_AUTO 1 -#define GMODE_ONLY 2 -#define GMODE_B_DEFERRED 3 -#define GMODE_PERFORMANCE 4 -#define GMODE_LRS 5 -#define GMODE_MAX 6 - -/* values for PLCPHdr_override */ -#define WLC_PLCP_AUTO -1 -#define WLC_PLCP_SHORT 0 -#define WLC_PLCP_LONG 1 - -/* values for g_protection_override and n_protection_override */ -#define WLC_PROTECTION_AUTO -1 -#define WLC_PROTECTION_OFF 0 -#define WLC_PROTECTION_ON 1 -#define WLC_PROTECTION_MMHDR_ONLY 2 -#define WLC_PROTECTION_CTS_ONLY 3 - -/* values for g_protection_control and n_protection_control */ -#define WLC_PROTECTION_CTL_OFF 0 -#define WLC_PROTECTION_CTL_LOCAL 1 -#define WLC_PROTECTION_CTL_OVERLAP 2 - -/* values for n_protection */ -#define WLC_N_PROTECTION_OFF 0 -#define WLC_N_PROTECTION_OPTIONAL 1 -#define WLC_N_PROTECTION_20IN40 2 -#define WLC_N_PROTECTION_MIXEDMODE 3 - -/* values for n_preamble_type */ -#define WLC_N_PREAMBLE_MIXEDMODE 0 -#define WLC_N_PREAMBLE_GF 1 -#define WLC_N_PREAMBLE_GF_BRCM 2 - -/* values for band specific 40MHz capabilities */ -#define WLC_N_BW_20ALL 0 -#define WLC_N_BW_40ALL 1 -#define WLC_N_BW_20IN2G_40IN5G 2 - -/* values to force tx/rx chain */ -#define WLC_N_TXRX_CHAIN0 0 -#define WLC_N_TXRX_CHAIN1 1 - -/* bitflags for SGI support (sgi_rx iovar) */ -#define WLC_N_SGI_20 0x01 -#define WLC_N_SGI_40 0x02 - -/* Values for PM */ -#define PM_OFF 0 -#define PM_MAX 1 - -/* interference mitigation options */ -#define INTERFERE_OVRRIDE_OFF -1 /* interference override off */ -#define INTERFERE_NONE 0 /* off */ -#define NON_WLAN 1 /* foreign/non 802.11 interference, no auto detect */ -#define WLAN_MANUAL 2 /* ACI: no auto detection */ -#define WLAN_AUTO 3 /* ACI: auto detect */ -#define WLAN_AUTO_W_NOISE 4 /* ACI: auto - detect and non 802.11 interference */ -#define AUTO_ACTIVE (1 << 7) /* Auto is currently active */ - -#define WL_RSSI_ANT_VERSION 1 /* current version of wl_rssi_ant_t */ -#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */ -#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */ -#define WL_ANT_IDX_1 0 /* antenna index 1 */ -#define WL_ANT_IDX_2 1 /* antenna index 2 */ - -#ifndef WL_RSSI_ANT_MAX -#define WL_RSSI_ANT_MAX 4 /* max possible rx antennas */ -#elif WL_RSSI_ANT_MAX != 4 -#error "WL_RSSI_ANT_MAX does not match" -#endif - -/* RSSI per antenna */ -typedef struct { - u32 version; /* version field */ - u32 count; /* number of valid antenna rssi */ - s8 rssi_ant[WL_RSSI_ANT_MAX]; /* rssi per antenna */ -} wl_rssi_ant_t; - -#define NUM_PWRCTRL_RATES 12 - -typedef struct { - u8 txpwr_band_max[NUM_PWRCTRL_RATES]; /* User set target */ - u8 txpwr_limit[NUM_PWRCTRL_RATES]; /* reg and local power limit */ - u8 txpwr_local_max; /* local max according to the AP */ - u8 txpwr_local_constraint; /* local constraint according to the AP */ - u8 txpwr_chan_reg_max; /* Regulatory max for this channel */ - u8 txpwr_target[2][NUM_PWRCTRL_RATES]; /* Latest target for 2.4 and 5 Ghz */ - u8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ - u8 txpwr_opo[NUM_PWRCTRL_RATES]; /* On G phy, OFDM power offset */ - u8 txpwr_bphy_cck_max[NUM_PWRCTRL_RATES]; /* Max CCK power for this band (SROM) */ - u8 txpwr_bphy_ofdm_max; /* Max OFDM power for this band (SROM) */ - u8 txpwr_aphy_max[NUM_PWRCTRL_RATES]; /* Max power for A band (SROM) */ - s8 txpwr_antgain[2]; /* Ant gain for each band - from SROM */ - u8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ -} tx_power_legacy_t; - -#define WL_TX_POWER_RATES_LEGACY 45 -#define WL_TX_POWER_MCS20_FIRST 12 -#define WL_TX_POWER_MCS20_NUM 16 -#define WL_TX_POWER_MCS40_FIRST 28 -#define WL_TX_POWER_MCS40_NUM 17 - - -#define WL_TX_POWER_RATES 101 -#define WL_TX_POWER_CCK_FIRST 0 -#define WL_TX_POWER_CCK_NUM 4 -#define WL_TX_POWER_OFDM_FIRST 4 /* Index for first 20MHz OFDM SISO rate */ -#define WL_TX_POWER_OFDM20_CDD_FIRST 12 /* Index for first 20MHz OFDM CDD rate */ -#define WL_TX_POWER_OFDM40_SISO_FIRST 52 /* Index for first 40MHz OFDM SISO rate */ -#define WL_TX_POWER_OFDM40_CDD_FIRST 60 /* Index for first 40MHz OFDM CDD rate */ -#define WL_TX_POWER_OFDM_NUM 8 -#define WL_TX_POWER_MCS20_SISO_FIRST 20 /* Index for first 20MHz MCS SISO rate */ -#define WL_TX_POWER_MCS20_CDD_FIRST 28 /* Index for first 20MHz MCS CDD rate */ -#define WL_TX_POWER_MCS20_STBC_FIRST 36 /* Index for first 20MHz MCS STBC rate */ -#define WL_TX_POWER_MCS20_SDM_FIRST 44 /* Index for first 20MHz MCS SDM rate */ -#define WL_TX_POWER_MCS40_SISO_FIRST 68 /* Index for first 40MHz MCS SISO rate */ -#define WL_TX_POWER_MCS40_CDD_FIRST 76 /* Index for first 40MHz MCS CDD rate */ -#define WL_TX_POWER_MCS40_STBC_FIRST 84 /* Index for first 40MHz MCS STBC rate */ -#define WL_TX_POWER_MCS40_SDM_FIRST 92 /* Index for first 40MHz MCS SDM rate */ -#define WL_TX_POWER_MCS_1_STREAM_NUM 8 -#define WL_TX_POWER_MCS_2_STREAM_NUM 8 -#define WL_TX_POWER_MCS_32 100 /* Index for 40MHz rate MCS 32 */ -#define WL_TX_POWER_MCS_32_NUM 1 - -/* sslpnphy specifics */ -#define WL_TX_POWER_MCS20_SISO_FIRST_SSN 12 /* Index for first 20MHz MCS SISO rate */ - -/* tx_power_t.flags bits */ -#define WL_TX_POWER_F_ENABLED 1 -#define WL_TX_POWER_F_HW 2 -#define WL_TX_POWER_F_MIMO 4 -#define WL_TX_POWER_F_SISO 8 - -typedef struct { - u32 flags; - chanspec_t chanspec; /* txpwr report for this channel */ - chanspec_t local_chanspec; /* channel on which we are associated */ - u8 local_max; /* local max according to the AP */ - u8 local_constraint; /* local constraint according to the AP */ - s8 antgain[2]; /* Ant gain for each band - from SROM */ - u8 rf_cores; /* count of RF Cores being reported */ - u8 est_Pout[4]; /* Latest tx power out estimate per RF chain */ - u8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain - * without adjustment - */ - u8 est_Pout_cck; /* Latest CCK tx power out estimate */ - u8 tx_power_max[4]; /* Maximum target power among all rates */ - u8 tx_power_max_rate_ind[4]; /* Index of the rate with the max target power */ - u8 user_limit[WL_TX_POWER_RATES]; /* User limit */ - u8 reg_limit[WL_TX_POWER_RATES]; /* Regulatory power limit */ - u8 board_limit[WL_TX_POWER_RATES]; /* Max power board can support (SROM) */ - u8 target[WL_TX_POWER_RATES]; /* Latest target power */ -} tx_power_t; - -typedef struct tx_inst_power { - u8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ - u8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ -} tx_inst_power_t; - -/* Message levels */ -#define WL_ERROR_VAL 0x00000001 -#define WL_TRACE_VAL 0x00000002 - -/* maximum channels returned by the get valid channels iovar */ -#define WL_NUMCHANNELS 64 -#define WL_NUMCHANSPECS 100 - -struct tsinfo_arg { - u8 octets[3]; -}; - -#define NFIFO 6 /* # tx/rx fifopairs */ - -struct wl_msglevel2 { - u32 low; - u32 high; -}; - -/* structure for per-tid ampdu control */ -struct ampdu_tid_control { - u8 tid; /* tid */ - u8 enable; /* enable/disable */ -}; - -/* structure for identifying ea/tid for sending addba/delba */ -struct ampdu_ea_tid { - u8 ea[ETH_ALEN]; /* Station address */ - u8 tid; /* tid */ -}; -/* structure for identifying retry/tid for retry_limit_tid/rr_retry_limit_tid */ -struct ampdu_retry_tid { - u8 tid; /* tid */ - u8 retry; /* retry value */ -}; - - -/* Software feature flag defines used by wlfeatureflag */ -#define WL_SWFL_NOHWRADIO 0x0004 -#define WL_SWFL_FLOWCONTROL 0x0008 /* Enable backpressure to OS stack */ -#define WL_SWFL_WLBSSSORT 0x0010 /* Per-port supports sorting of BSS */ - -#define WL_LIFETIME_MAX 0xFFFF /* Max value in ms */ - - -/* Pattern matching filter. Specifies an offset within received packets to - * start matching, the pattern to match, the size of the pattern, and a bitmask - * that indicates which bits within the pattern should be matched. - */ -typedef struct wl_pkt_filter_pattern { - u32 offset; /* Offset within received packet to start pattern matching. - * Offset '0' is the first byte of the ethernet header. - */ - u32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */ - u8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts - * at offset 0. Pattern immediately follows mask. - */ -} wl_pkt_filter_pattern_t; - -/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */ -typedef struct wl_pkt_filter { - u32 id; /* Unique filter id, specified by app. */ - u32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */ - u32 negate_match; /* Negate the result of filter matches */ - union { /* Filter definitions */ - wl_pkt_filter_pattern_t pattern; /* Pattern matching filter */ - } u; -} wl_pkt_filter_t; - -#define WL_PKT_FILTER_FIXED_LEN offsetof(wl_pkt_filter_t, u) -#define WL_PKT_FILTER_PATTERN_FIXED_LEN offsetof(wl_pkt_filter_pattern_t, mask_and_pattern) - -/* IOVAR "pkt_filter_enable" parameter. */ -typedef struct wl_pkt_filter_enable { - u32 id; /* Unique filter id */ - u32 enable; /* Enable/disable bool */ -} wl_pkt_filter_enable_t; - - -#define WLC_RSSI_INVALID 0 /* invalid RSSI value */ - -/* n-mode support capability */ -/* 2x2 includes both 1x1 & 2x2 devices - * reserved #define 2 for future when we want to separate 1x1 & 2x2 and - * control it independently - */ -#define WL_11N_2x2 1 -#define WL_11N_3x3 3 -#define WL_11N_4x4 4 - -/* define 11n feature disable flags */ -#define WLFEATURE_DISABLE_11N 0x00000001 -#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 -#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 -#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 -#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 -#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 -#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 -#define WLFEATURE_DISABLE_11N_GF 0x00000080 - -#define WL_EVENTING_MASK_LEN 16 - -#define TOE_TX_CSUM_OL 0x00000001 -#define TOE_RX_CSUM_OL 0x00000002 - -#define PM_OFF 0 -#define PM_MAX 1 -#define PM_FAST 2 - -typedef enum sup_auth_status { - WLC_SUP_DISCONNECTED = 0, - WLC_SUP_CONNECTING, - WLC_SUP_IDREQUIRED, - WLC_SUP_AUTHENTICATING, - WLC_SUP_AUTHENTICATED, - WLC_SUP_KEYXCHANGE, - WLC_SUP_KEYED, - WLC_SUP_TIMEOUT, - WLC_SUP_LAST_BASIC_STATE, - WLC_SUP_KEYXCHANGE_WAIT_M1 = WLC_SUP_AUTHENTICATED, - WLC_SUP_KEYXCHANGE_PREP_M2 = WLC_SUP_KEYXCHANGE, - WLC_SUP_KEYXCHANGE_WAIT_M3 = WLC_SUP_LAST_BASIC_STATE, - WLC_SUP_KEYXCHANGE_PREP_M4, - WLC_SUP_KEYXCHANGE_WAIT_G1, - WLC_SUP_KEYXCHANGE_PREP_G2 -} sup_auth_status_t; -#endif /* _wlioctl_h_ */ diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 20008a4376e8..5e65dde5845a 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -841,6 +841,16 @@ config COMEDI_DT3000 To compile this driver as a module, choose M here: the module will be called dt3000. +config COMEDI_DYNA_PCI10XX + tristate "Dynalog PCI DAQ series support" + default N + ---help--- + Enable support for Dynalog PCI DAQ series + PCI-1050 + + To compile this driver as a module, choose M here: the module will be + called dyna_pci10xx. + config COMEDI_UNIOXX5 tristate "Fastwel UNIOxx-5 analog and digital io board support" default N diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 6c900e2756fb..14ea35ac0156 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -514,12 +514,16 @@ return 0x1 + pfi_channel; else return 0xb + pfi_channel; - } static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel) { + } + + static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel) + { if (rtsi_channel < 7) return 0xb + rtsi_channel; else return 0x1b; } + /* mode bits for NI general-purpose counters, set with * INSN_CONFIG_SET_COUNTER_MODE */ #define NI_GPCT_COUNTING_MODE_SHIFT 16 diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index e7e72b8d8cde..e90e3cceb5f8 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -383,8 +383,8 @@ static int do_devinfo_ioctl(struct comedi_device *dev, /* fill devinfo structure */ devinfo.version_code = COMEDI_VERSION_CODE; devinfo.n_subdevs = dev->n_subdevices; - memcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN); - memcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN); + strlcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN); + strlcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN); if (read_subdev) devinfo.read_subdevice = read_subdev - dev->subdevices; @@ -1291,10 +1291,10 @@ static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, s->lock = file; spin_unlock_irqrestore(&s->spin_lock, flags); +#if 0 if (ret < 0) return ret; -#if 0 if (s->lock_f) ret = s->lock_f(dev, s); #endif @@ -2175,9 +2175,8 @@ int comedi_alloc_board_minor(struct device *hardware_device) return -EBUSY; } info->device->minor = i; - csdev = COMEDI_DEVICE_CREATE(comedi_class, NULL, - MKDEV(COMEDI_MAJOR, i), NULL, - hardware_device, "comedi%i", i); + csdev = device_create(comedi_class, hardware_device, + MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i", i); if (!IS_ERR(csdev)) info->device->class_dev = csdev; dev_set_drvdata(csdev, info); @@ -2276,10 +2275,9 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, return -EBUSY; } s->minor = i; - csdev = COMEDI_DEVICE_CREATE(comedi_class, dev->class_dev, - MKDEV(COMEDI_MAJOR, i), NULL, NULL, - "comedi%i_subd%i", dev->minor, - (int)(s - dev->subdevices)); + csdev = device_create(comedi_class, dev->class_dev, + MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i_subd%i", + dev->minor, (int)(s - dev->subdevices)); if (!IS_ERR(csdev)) s->class_dev = csdev; dev_set_drvdata(csdev, info); diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 68aa9176d249..7a0d4bcbc355 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -61,9 +61,6 @@ #define COMEDI_NUM_BOARD_MINORS 0x30 #define COMEDI_FIRST_SUBDEVICE_MINOR COMEDI_NUM_BOARD_MINORS -#define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \ - device_create(cs, ((parent) ? (parent) : (device)), devt, drvdata, fmt) - struct comedi_subdevice { struct comedi_device *device; int type; diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 6d60e91b3a85..db1fd63aaab3 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -502,7 +502,11 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, } if (i == n_pages) { async->prealloc_buf = +#ifdef PAGE_KERNEL_NOCACHE vmap(pages, n_pages, VM_MAP, PAGE_KERNEL_NOCACHE); +#else + vmap(pages, n_pages, VM_MAP, PAGE_KERNEL); +#endif } vfree(pages); diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 354fb7d29841..33bf1f5aad45 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -86,6 +86,7 @@ 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_DYNA_PCI10XX) += dyna_pci10xx.o obj-$(CONFIG_COMEDI_UNIOXX5) += unioxx5.o obj-$(CONFIG_COMEDI_GSC_HPDI) += gsc_hpdi.o obj-$(CONFIG_COMEDI_ICP_MULTI) += icp_multi.o diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 6cf19ed683a8..6fb7594319c6 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -58,8 +58,8 @@ You should also find the complete GPL in the COPYING file accompanying this sour #include #include #include +#include #include "../../comedidev.h" -#include #if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300) #include #endif diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 08b71d9974b6..f17654e44aef 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -67,6 +67,7 @@ Configuration options: #include #include #include +#include #include "amcc_s5933.h" #include "8253.h" diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 1b5682104a08..29455a8e88b4 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -234,7 +234,7 @@ static int pci1723_insn_read_ao(struct comedi_device *dev, int n, chan; chan = CR_CHAN(insn->chanspec); - DPRINTK(" adv_PCI1723 DEBUG: pci1723_insn_read_ao() ----- \n"); + DPRINTK(" adv_PCI1723 DEBUG: pci1723_insn_read_ao() -----\n"); for (n = 0; n < insn->n; n++) data[n] = devpriv->ao_data[chan]; diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 60c2b12d6ffb..a6df30b7fd7c 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -102,6 +102,7 @@ Unipolar and bipolar ranges cannot be mixed in the channel/gain list. #include #include +#include #include "../comedidev.h" #include @@ -198,7 +199,7 @@ static void das1800_flush_dma(struct comedi_device *dev, struct comedi_subdevice *s); static void das1800_flush_dma_channel(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned int channel, uint16_t * buffer); + unsigned int channel, uint16_t *buffer); static void das1800_handle_fifo_half_full(struct comedi_device *dev, struct comedi_subdevice *s); static void das1800_handle_fifo_not_empty(struct comedi_device *dev, @@ -1050,9 +1051,8 @@ static void munge_data(struct comedi_device *dev, uint16_t * array, /* convert to unsigned type if we are in a bipolar mode */ if (!unipolar) { - for (i = 0; i < num_elements; i++) { + for (i = 0; i < num_elements; i++) array[i] = munge_bipolar_sample(dev, array[i]); - } } } @@ -1060,7 +1060,7 @@ static void munge_data(struct comedi_device *dev, uint16_t * array, * Assumes dma lock is held */ static void das1800_flush_dma_channel(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned int channel, uint16_t * buffer) + unsigned int channel, uint16_t *buffer) { unsigned int num_bytes, num_samples; struct comedi_cmd *cmd = &s->async->cmd; @@ -1153,7 +1153,8 @@ static void das1800_handle_fifo_not_empty(struct comedi_device *dev, break; dpnt = inw(dev->iobase + DAS1800_FIFO); /* convert to unsigned type if we are in a bipolar mode */ - if (!unipolar) ; + if (!unipolar) + ; dpnt = munge_bipolar_sample(dev, dpnt); cfc_write_to_buffer(s, dpnt); if (cmd->stop_src == TRIG_COUNT) @@ -1364,9 +1365,8 @@ static int control_a_bits(struct comedi_cmd cmd) int control_a; control_a = FFEN; /* enable fifo */ - if (cmd.stop_src == TRIG_EXT) { + if (cmd.stop_src == TRIG_EXT) control_a |= ATEN; - } switch (cmd.start_src) { case TRIG_EXT: control_a |= TGEN | CGSL; @@ -1443,9 +1443,8 @@ static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) &(cmd.convert_arg), cmd. flags & TRIG_ROUND_MASK); - if (das1800_set_frequency(dev) < 0) { + if (das1800_set_frequency(dev) < 0) return -1; - } } break; case TRIG_TIMER: /* in burst mode */ @@ -1454,9 +1453,8 @@ static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) &(devpriv->divisor2), &(cmd.scan_begin_arg), cmd.flags & TRIG_ROUND_MASK); - if (das1800_set_frequency(dev) < 0) { + if (das1800_set_frequency(dev) < 0) return -1; - } break; default: break; @@ -1553,11 +1551,10 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, /* disable dma on TRIG_WAKE_EOS, or TRIG_RT * (because dma in handler is unsafe at hard real-time priority) */ - if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) { + if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) devpriv->irq_dma_bits &= ~DMA_ENABLED; - } else { + else devpriv->irq_dma_bits |= devpriv->dma_bits; - } /* interrupt on end of conversion for TRIG_WAKE_EOS */ if (cmd.flags & TRIG_WAKE_EOS) { /* interrupt fifo not empty */ @@ -1567,9 +1564,8 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, devpriv->irq_dma_bits |= FIMD; } /* determine how many conversions we need */ - if (cmd.stop_src == TRIG_COUNT) { + if (cmd.stop_src == TRIG_COUNT) devpriv->count = cmd.stop_arg * cmd.chanlist_len; - } das1800_cancel(dev, s); diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 8cea9dca3d7e..95ebc267bb74 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -61,6 +61,7 @@ Configuration options: #include #include #include +#include #include #include "comedi_fc.h" diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c new file mode 100644 index 000000000000..da8a2bf31657 --- /dev/null +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -0,0 +1,462 @@ +/* + * comedi/drivers/dyna_pci10xx.c + * Copyright (C) 2011 Prashant Shah, pshah.mumbai@gmail.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; 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: dyna_pci10xx + Devices: Dynalog India PCI DAQ Cards, http://www.dynalogindia.com/ + Author: Prashant Shah + Developed at Automation Labs, Chemical Dept., IIT Bombay, India. + Prof. Kannan Moudgalya + http://www.iitb.ac.in + Status: Stable + Version: 1.0 + Device Supported : + - Dynalog PCI 1050 + + Notes : + - Dynalog India Pvt. Ltd. does not have a registered PCI Vendor ID and + they are using the PLX Technlogies Vendor ID since that is the PCI Chip used + in the card. + - Dynalog India Pvt. Ltd. has provided the internal register specification for + their cards in their manuals. +*/ + +#include "../comedidev.h" +#include "comedi_pci.h" +#include + +#define PCI_VENDOR_ID_DYNALOG 0x10b5 +#define DRV_NAME "dyna_pci10xx" + +#define READ_TIMEOUT 50 + +static DEFINE_MUTEX(start_stop_sem); + +static DEFINE_PCI_DEVICE_TABLE(dyna_pci10xx_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_DYNALOG, 0x1050) }, + { 0 } +}; + +MODULE_DEVICE_TABLE(pci, dyna_pci10xx_pci_table); + +static int dyna_pci10xx_attach(struct comedi_device *dev, + struct comedi_devconfig *it); +static int dyna_pci10xx_detach(struct comedi_device *dev); + +static const struct comedi_lrange range_pci1050_ai = { 3, { + BIP_RANGE(10), + BIP_RANGE(5), + UNI_RANGE(10) + } +}; + +static const char range_codes_pci1050_ai[] = { 0x00, 0x10, 0x30 }; + +static const struct comedi_lrange range_pci1050_ao = { 1, { + UNI_RANGE(10) + } +}; + +static const char range_codes_pci1050_ao[] = { 0x00 }; + +struct boardtype { + const char *name; + int device_id; + int ai_chans; + int ai_bits; + int ao_chans; + int ao_bits; + int di_chans; + int di_bits; + int do_chans; + int do_bits; + const struct comedi_lrange *range_ai; + const char *range_codes_ai; + const struct comedi_lrange *range_ao; + const char *range_codes_ao; +}; + +static const struct boardtype boardtypes[] = { + { + .name = "dyna_pci1050", + .device_id = 0x1050, + .ai_chans = 16, + .ai_bits = 12, + .ao_chans = 16, + .ao_bits = 12, + .di_chans = 16, + .di_bits = 16, + .do_chans = 16, + .do_bits = 16, + .range_ai = &range_pci1050_ai, + .range_codes_ai = range_codes_pci1050_ai, + .range_ao = &range_pci1050_ao, + .range_codes_ao = range_codes_pci1050_ao, + }, + /* dummy entry corresponding to driver name */ + {.name = DRV_NAME}, +}; + +static struct comedi_driver driver_dyna_pci10xx = { + .driver_name = DRV_NAME, + .module = THIS_MODULE, + .attach = dyna_pci10xx_attach, + .detach = dyna_pci10xx_detach, + .board_name = &boardtypes[0].name, + .offset = sizeof(struct boardtype), + .num_names = ARRAY_SIZE(boardtypes), +}; + +struct dyna_pci10xx_private { + struct pci_dev *pci_dev; /* ptr to PCI device */ + char valid; /* card is usable */ + struct mutex mutex; + + /* device base address registers */ + unsigned long BADR0, BADR1, BADR2, BADR3, BADR4, BADR5; +}; + +#define thisboard ((const struct boardtype *)dev->board_ptr) +#define devpriv ((struct dyna_pci10xx_private *)dev->private) + +/******************************************************************************/ +/************************** READ WRITE FUNCTIONS ******************************/ +/******************************************************************************/ + +/* analog input callback */ +static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int n, counter; + u16 d = 0; + unsigned int chan, range; + + /* get the channel number and range */ + chan = CR_CHAN(insn->chanspec); + range = thisboard->range_codes_ai[CR_RANGE((insn->chanspec))]; + + mutex_lock(&devpriv->mutex); + /* convert n samples */ + for (n = 0; n < insn->n; n++) { + /* trigger conversion */ + smp_mb(); + outw_p(0x0000 + range + chan, devpriv->BADR2 + 2); + udelay(10); + /* read data */ + for (counter = 0; counter < READ_TIMEOUT; counter++) { + d = inw_p(devpriv->BADR2); + + /* check if read is successfull if the EOC bit is set */ + if (d & (1 << 15)) + goto conv_finish; + } + data[n] = 0; + printk(KERN_DEBUG "comedi: dyna_pci10xx: " + "timeout reading analog input\n"); + continue; +conv_finish: + /* mask the first 4 bits - EOC bits */ + d &= 0x0FFF; + data[n] = d; + } + mutex_unlock(&devpriv->mutex); + + /* return the number of samples read/written */ + return n; +} + +/* analog output callback */ +static int dyna_pci10xx_insn_write_ao(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int n; + unsigned int chan, range; + + chan = CR_CHAN(insn->chanspec); + range = thisboard->range_codes_ai[CR_RANGE((insn->chanspec))]; + + mutex_lock(&devpriv->mutex); + for (n = 0; n < insn->n; n++) { + smp_mb(); + /* trigger conversion and write data */ + outw_p(data[n], devpriv->BADR2); + udelay(10); + } + mutex_unlock(&devpriv->mutex); + return n; +} + +/* digital input bit interface */ +static int dyna_pci10xx_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + u16 d = 0; + + if (insn->n != 2) + return -EINVAL; + + mutex_lock(&devpriv->mutex); + smp_mb(); + d = inw_p(devpriv->BADR3); + udelay(10); + + /* on return the data[0] contains output and data[1] contains input */ + data[1] = d; + data[0] = s->state; + mutex_unlock(&devpriv->mutex); + return 2; +} + +/* digital output bit interface */ +static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + if (insn->n != 2) + return -EINVAL; + + /* The insn data is a mask in data[0] and the new data + * in data[1], each channel cooresponding to a bit. + * s->state contains the previous write data + */ + mutex_lock(&devpriv->mutex); + if (data[0]) { + s->state &= ~data[0]; + s->state |= (data[0] & data[1]); + smp_mb(); + outw_p(s->state, devpriv->BADR3); + udelay(10); + } + + /* + * On return, data[1] contains the value of the digital + * input and output lines. We just return the software copy of the + * output values if it was a purely digital output subdevice. + */ + data[1] = s->state; + mutex_unlock(&devpriv->mutex); + return 2; +} + +/******************************************************************************/ +/*********************** INITIALIZATION FUNCTIONS *****************************/ +/******************************************************************************/ + +static int dyna_pci10xx_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct comedi_subdevice *s; + struct pci_dev *pcidev; + unsigned int opt_bus, opt_slot; + int board_index, i; + + mutex_lock(&start_stop_sem); + + if (alloc_private(dev, sizeof(struct dyna_pci10xx_private)) < 0) { + printk(KERN_ERR "comedi: dyna_pci10xx: " + "failed to allocate memory!\n"); + mutex_unlock(&start_stop_sem); + return -ENOMEM; + } + + opt_bus = it->options[0]; + opt_slot = it->options[1]; + dev->board_name = thisboard->name; + dev->irq = 0; + + /* + * Probe the PCI bus and located the matching device + */ + 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)) { + + board_index = -1; + for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { + if ((pcidev->vendor == PCI_VENDOR_ID_DYNALOG) && + (pcidev->device == boardtypes[i].device_id)) { + board_index = i; + break; + } + } + if (board_index < 0) + continue; + + /* Found matching vendor/device. */ + if (opt_bus || opt_slot) { + /* Check bus/slot. */ + if (opt_bus != pcidev->bus->number + || opt_slot != PCI_SLOT(pcidev->devfn)) + continue; /* no match */ + } + + goto found; + } + printk(KERN_ERR "comedi: dyna_pci10xx: no supported device found!\n"); + mutex_unlock(&start_stop_sem); + return -EIO; + +found: + + if (!pcidev) { + if (opt_bus || opt_slot) { + printk(KERN_ERR "comedi: dyna_pci10xx: " + "invalid PCI device at b:s %d:%d\n", + opt_bus, opt_slot); + } else { + printk(KERN_ERR "comedi: dyna_pci10xx: " + "invalid PCI device\n"); + } + mutex_unlock(&start_stop_sem); + return -EIO; + } + + if (comedi_pci_enable(pcidev, DRV_NAME)) { + printk(KERN_ERR "comedi: dyna_pci10xx: " + "failed to enable PCI device and request regions!"); + mutex_unlock(&start_stop_sem); + return -EIO; + } + + mutex_init(&devpriv->mutex); + dev->board_ptr = &boardtypes[board_index]; + devpriv->pci_dev = pcidev; + + printk(KERN_INFO "comedi: dyna_pci10xx: device found!\n"); + + /* initialize device base address registers */ + devpriv->BADR0 = pci_resource_start(pcidev, 0); + devpriv->BADR1 = pci_resource_start(pcidev, 1); + devpriv->BADR2 = pci_resource_start(pcidev, 2); + devpriv->BADR3 = pci_resource_start(pcidev, 3); + devpriv->BADR4 = pci_resource_start(pcidev, 4); + devpriv->BADR5 = pci_resource_start(pcidev, 5); + + if (alloc_subdevices(dev, 4) < 0) { + printk(KERN_ERR "comedi: dyna_pci10xx: " + "failed allocating subdevices\n"); + mutex_unlock(&start_stop_sem); + return -ENOMEM; + } + + /* analog input */ + s = dev->subdevices + 0; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; + s->n_chan = thisboard->ai_chans; + s->maxdata = 0x0FFF; + s->range_table = thisboard->range_ai; + s->len_chanlist = 16; + s->insn_read = dyna_pci10xx_insn_read_ai; + + /* analog output */ + s = dev->subdevices + 1; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = thisboard->ao_chans; + s->maxdata = 0x0FFF; + s->range_table = thisboard->range_ao; + s->len_chanlist = 16; + s->insn_write = dyna_pci10xx_insn_write_ao; + + /* digital input */ + s = dev->subdevices + 2; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND; + s->n_chan = thisboard->di_chans; + s->maxdata = 1; + s->range_table = &range_digital; + s->len_chanlist = thisboard->di_chans; + s->insn_bits = dyna_pci10xx_di_insn_bits; + + /* digital output */ + s = dev->subdevices + 3; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND; + s->n_chan = thisboard->do_chans; + s->maxdata = 1; + s->range_table = &range_digital; + s->len_chanlist = thisboard->do_chans; + s->state = 0; + s->insn_bits = dyna_pci10xx_do_insn_bits; + + devpriv->valid = 1; + mutex_unlock(&start_stop_sem); + + printk(KERN_INFO "comedi: dyna_pci10xx: %s - device setup completed!\n", + boardtypes[board_index].name); + + return 1; +} + +static int dyna_pci10xx_detach(struct comedi_device *dev) +{ + if (devpriv && devpriv->pci_dev) { + comedi_pci_disable(devpriv->pci_dev); + mutex_destroy(&devpriv->mutex); + } + + return 0; +} + +static int __devinit driver_dyna_pci10xx_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, driver_dyna_pci10xx.driver_name); +} + +static void __devexit driver_dyna_pci10xx_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static struct pci_driver driver_dyna_pci10xx_pci_driver = { + .id_table = dyna_pci10xx_pci_table, + .probe = &driver_dyna_pci10xx_pci_probe, + .remove = __devexit_p(&driver_dyna_pci10xx_pci_remove) +}; + +static int __init driver_dyna_pci10xx_init_module(void) +{ + int retval; + + retval = comedi_driver_register(&driver_dyna_pci10xx); + if (retval < 0) + return retval; + + driver_dyna_pci10xx_pci_driver.name = + (char *)driver_dyna_pci10xx.driver_name; + return pci_register_driver(&driver_dyna_pci10xx_pci_driver); +} + +static void __exit driver_dyna_pci10xx_cleanup_module(void) +{ + pci_unregister_driver(&driver_dyna_pci10xx_pci_driver); + comedi_driver_unregister(&driver_dyna_pci10xx); +} + +module_init(driver_dyna_pci10xx_init_module); +module_exit(driver_dyna_pci10xx_cleanup_module); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Prashant Shah "); +MODULE_DESCRIPTION("Comedi based drivers for Dynalog PCI DAQ cards"); diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index c192b71ec04f..32e675e3f0b9 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -69,6 +69,7 @@ TRIG_WAKE_EOS #include "../comedidev.h" #include +#include #include #include "8253.h" diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 2672629e9ff9..e2420123db87 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -51,7 +51,7 @@ IRQ is assigned but not used. #include #include -static struct pcmcia_device *pcmcia_cur_dev = NULL; +static struct pcmcia_device *pcmcia_cur_dev; #define DIO700_SIZE 8 /* size of io region used by board */ @@ -381,11 +381,11 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif break; default: - printk("bug! couldn't determine board type\n"); + printk(KERN_ERR "bug! couldn't determine board type\n"); return -EINVAL; break; } - printk("comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor, + printk(KERN_ERR "comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor, thisboard->name, iobase); #ifdef incomplete if (irq) @@ -396,7 +396,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk("\n"); if (iobase == 0) { - printk("io base address is zero!\n"); + printk(KERN_ERR "io base address is zero!\n"); return -EINVAL; } @@ -421,7 +421,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int dio700_detach(struct comedi_device *dev) { - printk("comedi%d: ni_daq_700: cs-remove\n", dev->minor); + printk(KERN_ERR "comedi%d: ni_daq_700: cs-remove\n", dev->minor); if (dev->subdevices) subdev_700_cleanup(dev, dev->subdevices + 0); diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index ab8f37022a3c..6859af0778cf 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -78,6 +78,7 @@ NI manuals: #include #include +#include #include "../comedidev.h" #include @@ -212,8 +213,10 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it); static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static irqreturn_t labpc_interrupt(int irq, void *d); static int labpc_drain_fifo(struct comedi_device *dev); +#ifdef CONFIG_ISA_DMA_API static void labpc_drain_dma(struct comedi_device *dev); static void handle_isa_dma(struct comedi_device *dev); +#endif static void labpc_drain_dregs(struct comedi_device *dev); static int labpc_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); @@ -237,9 +240,9 @@ static int labpc_eeprom_write_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); -static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd); static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd); #ifdef CONFIG_COMEDI_PCI +static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd); static int labpc_find_device(struct comedi_device *dev, int bus, int slot); #endif static int labpc_dio_mem_callback(int dir, int port, int data, @@ -526,7 +529,10 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, { struct comedi_subdevice *s; int i; - unsigned long dma_flags, isr_flags; + unsigned long isr_flags; +#ifdef CONFIG_ISA_DMA_API + unsigned long dma_flags; +#endif short lsb, msb; printk(KERN_ERR "comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, @@ -586,6 +592,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, } dev->irq = irq; +#ifdef CONFIG_ISA_DMA_API /* grab dma channel */ if (dma_chan > 3) { printk(KERN_ERR " invalid dma channel %u\n", dma_chan); @@ -609,6 +616,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, set_dma_mode(devpriv->dma_chan, DMA_MODE_READ); release_dma_lock(dma_flags); } +#endif dev->board_name = thisboard->name; @@ -723,9 +731,15 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* get base address, irq etc. based on bustype */ switch (thisboard->bustype) { case isa_bustype: +#ifdef CONFIG_ISA_DMA_API iobase = it->options[0]; irq = it->options[1]; dma_chan = it->options[2]; +#else + printk(KERN_ERR " this driver has not been built with ISA DMA " + "support.\n"); + return -EINVAL; +#endif break; case pci_bustype: #ifdef CONFIG_COMEDI_PCI @@ -796,10 +810,12 @@ int labpc_common_detach(struct comedi_device *dev) if (dev->subdevices) subdev_8255_cleanup(dev, dev->subdevices + 2); +#ifdef CONFIG_ISA_DMA_API /* only free stuff if it has been allocated by _attach */ kfree(devpriv->dma_buffer); if (devpriv->dma_chan) free_dma(devpriv->dma_chan); +#endif if (dev->irq) free_irq(dev->irq, dev); if (thisboard->bustype == isa_bustype && dev->iobase) @@ -1134,7 +1150,9 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { int channel, range, aref; +#ifdef CONFIG_ISA_DMA_API unsigned long irq_flags; +#endif int ret; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; @@ -1181,6 +1199,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->write_byte(INIT_A1_BITS, dev->iobase + COUNTER_A_CONTROL_REG); +#ifdef CONFIG_ISA_DMA_API /* figure out what method we will use to transfer data */ if (devpriv->dma_chan && /* need a dma channel allocated */ /* @@ -1192,7 +1211,9 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) thisboard->bustype == isa_bustype) { xfer = isa_dma_transfer; /* pc-plus has no fifo-half full interrupt */ - } else if (thisboard->register_layout == labpc_1200_layout && + } else +#endif + if (thisboard->register_layout == labpc_1200_layout && /* wake-end-of-scan should interrupt on fifo not empty */ (cmd->flags & TRIG_WAKE_EOS) == 0 && /* make sure we are taking more than just a few points */ @@ -1316,6 +1337,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) labpc_clear_adc_fifo(dev); +#ifdef CONFIG_ISA_DMA_API /* set up dma transfer */ if (xfer == isa_dma_transfer) { irq_flags = claim_dma_lock(); @@ -1339,6 +1361,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->command3_bits |= DMA_EN_BIT | DMATC_INTR_EN_BIT; } else devpriv->command3_bits &= ~DMA_EN_BIT & ~DMATC_INTR_EN_BIT; +#endif /* enable error interrupts */ devpriv->command3_bits |= ERR_INTR_EN_BIT; @@ -1425,6 +1448,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d) return IRQ_HANDLED; } +#ifdef CONFIG_ISA_DMA_API if (devpriv->current_transfer == isa_dma_transfer) { /* * if a dma terminal count of external stop trigger @@ -1436,6 +1460,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d) handle_isa_dma(dev); } } else +#endif labpc_drain_fifo(dev); if (devpriv->status1_bits & TIMER_BIT) { @@ -1508,6 +1533,7 @@ static int labpc_drain_fifo(struct comedi_device *dev) return 0; } +#ifdef CONFIG_ISA_DMA_API static void labpc_drain_dma(struct comedi_device *dev) { struct comedi_subdevice *s = dev->read_subdev; @@ -1570,13 +1596,16 @@ static void handle_isa_dma(struct comedi_device *dev) /* clear dma tc interrupt */ devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG); } +#endif /* makes sure all data acquired by board is transferred to comedi (used * when acquisition is terminated by stop_src == TRIG_EXT). */ static void labpc_drain_dregs(struct comedi_device *dev) { +#ifdef CONFIG_ISA_DMA_API if (devpriv->current_transfer == isa_dma_transfer) labpc_drain_dma(dev); +#endif labpc_drain_fifo(dev); } @@ -1768,6 +1797,7 @@ static int labpc_eeprom_write_insn(struct comedi_device *dev, return 1; } +#ifdef CONFIG_ISA_DMA_API /* utility function that suggests a dma transfer size in bytes */ static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd) { @@ -1791,6 +1821,7 @@ static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd) return size; } +#endif /* figures out what counter values to use based on command */ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 09ff4723b225..6fc74645af2c 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -114,6 +114,7 @@ #include #include +#include #include #include "8253.h" diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 8f3fc6ee088b..0b9bee36eb5f 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -38,6 +38,7 @@ Configuration Options: #include #include #include +#include #include #include "8253.h" diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 8933e5089bd3..b45a9bd8b489 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -104,6 +104,7 @@ A word or two about DMA. Driver support DMA operations at two ways: #include #include #include +#include #include #include "8253.h" diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 7f09ed755fe6..138441960506 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -29,8 +29,8 @@ Status: Works. Only tested on DM7520-8. Not SMP safe. Configuration options: [0] - PCI bus of device (optional) - If bus/slot is not specified, the first available PCI - device will be used. + If bus / slot is not specified, the first available PCI + device will be used. [1] - PCI slot of device (optional) */ /* @@ -186,7 +186,7 @@ Configuration options: | PLX_DEMAND_MODE_BIT) #define DMA_TRANSFER_BITS (\ -/* descriptors in PCI memory*/ PLX_DESC_IN_PCI_BIT \ +/* descriptors in PCI memory*/ PLX_DESC_IN_PCI_BIT \ /* interrupt at end of block */ | PLX_INTR_TERM_COUNT \ /* from board to PCI */ | PLX_XFER_LOCAL_TO_PCI) @@ -869,7 +869,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Show board configuration */ - printk("%s:", dev->board_name); + printk(KERN_INFO "%s:", dev->board_name); /* * Allocate the subdevice structures. alloc_subdevice() is a @@ -958,7 +958,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; } dev->irq = devpriv->pci_dev->irq; - printk("( irq=%u )", dev->irq); + printk(KERN_INFO "( irq=%u )", dev->irq); ret = rtd520_probe_fifo_depth(dev); if (ret < 0) @@ -1026,7 +1026,8 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) } RtdDma0Mode(dev, DMA_MODE_BITS); - RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL); /* set DMA trigger source */ + /* set DMA trigger source */ + RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL); } else { printk(KERN_INFO "( no IRQ->no DMA )"); } @@ -1202,11 +1203,13 @@ static unsigned short rtdConvertChanGain(struct comedi_device *dev, CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex); } else if (range < thisboard->rangeUniStart) { /* second batch are +-10 */ r |= 0x100; /* +-10 range */ - r |= ((range - thisboard->range10Start) & 0x7) << 4; /* gain */ + /* gain */ + r |= ((range - thisboard->range10Start) & 0x7) << 4; CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex); } else { /* last batch is +10 */ r |= 0x200; /* +10 range */ - r |= ((range - thisboard->rangeUniStart) & 0x7) << 4; /* gain */ + /* gain */ + r |= ((range - thisboard->rangeUniStart) & 0x7) << 4; CHAN_ARRAY_CLEAR(devpriv->chanBipolar, chanIndex); } @@ -1336,7 +1339,8 @@ static int rtd_ai_rinsn(struct comedi_device *dev, /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */ d = d >> 3; /* low 3 bits are marker lines */ if (CHAN_ARRAY_TEST(devpriv->chanBipolar, 0)) - data[n] = d + 2048; /* convert to comedi unsigned data */ + /* convert to comedi unsigned data */ + data[n] = d + 2048; else data[n] = d; } diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index ebfce33f0b4f..ade2202b6231 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -38,7 +38,7 @@ Status: in development #include #include -#include +#include #include #include #include @@ -192,9 +192,8 @@ static int tty_read(struct file *f, int timeout) elapsed = (1000000 * (now.tv_sec - start.tv_sec) + now.tv_usec - start.tv_usec); - if (elapsed > timeout) { + if (elapsed > timeout) break; - } set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(((timeout - elapsed) * HZ) / 10000); @@ -204,9 +203,8 @@ static int tty_read(struct file *f, int timeout) unsigned char ch; f->f_pos = 0; - if (f->f_op->read(f, &ch, 1, &f->f_pos) == 1) { + if (f->f_op->read(f, &ch, 1, &f->f_pos) == 1) result = ch; - } } } else { /* Device does not support poll, busy wait */ @@ -215,9 +213,8 @@ static int tty_read(struct file *f, int timeout) unsigned char ch; retries++; - if (retries >= timeout) { + if (retries >= timeout) break; - } f->f_pos = 0; if (f->f_op->read(f, &ch, 1, &f->f_pos) == 1) { @@ -329,7 +326,7 @@ static struct serial_data serial_read(struct file *f, int timeout) length++; if (data < 0) { - printk("serial2002 error\n"); + printk(KERN_ERR "serial2002 error\n"); break; } else if (data & 0x80) { result.value = (result.value << 7) | (data & 0x7f); @@ -402,7 +399,7 @@ static int serial_2002_open(struct comedi_device *dev) devpriv->tty = filp_open(port, O_RDWR, 0); if (IS_ERR(devpriv->tty)) { result = (int)PTR_ERR(devpriv->tty); - printk("serial_2002: file open error = %d\n", result); + printk(KERN_ERR "serial_2002: file open error = %d\n", result); } else { struct config_t { @@ -516,9 +513,8 @@ static int serial_2002_open(struct comedi_device *dev) } break; } - if (sign) { + if (sign) min = -min; - } cur_config[channel].min = min; } @@ -557,9 +553,8 @@ static int serial_2002_open(struct comedi_device *dev) } break; } - if (sign) { + if (sign) max = -max; - } cur_config[channel].max = max; } @@ -622,9 +617,8 @@ static int serial_2002_open(struct comedi_device *dev) int j, chan; for (chan = 0, j = 0; j < 32; j++) { - if (c[j].kind == kind) { + if (c[j].kind == kind) chan++; - } } s = &dev->subdevices[i]; s->n_chan = chan; @@ -649,9 +643,8 @@ static int serial_2002_open(struct comedi_device *dev) } for (chan = 0, j = 0; j < 32; j++) { if (c[j].kind == kind) { - if (mapping) { + if (mapping) mapping[chan] = j; - } if (range) { range[j].length = 1; range[j].range.min = @@ -704,9 +697,8 @@ static int serial_2002_open(struct comedi_device *dev) static void serial_2002_close(struct comedi_device *dev) { - if (!IS_ERR(devpriv->tty) && (devpriv->tty != 0)) { + if (!IS_ERR(devpriv->tty) && (devpriv->tty != 0)) filp_close(devpriv->tty, 0); - } } static int serial2002_di_rinsn(struct comedi_device *dev, @@ -723,9 +715,8 @@ static int serial2002_di_rinsn(struct comedi_device *dev, poll_digital(devpriv->tty, chan); while (1) { read = serial_read(devpriv->tty, 1000); - if (read.kind != is_digital || read.index == chan) { + if (read.kind != is_digital || read.index == chan) break; - } } data[n] = read.value; } @@ -765,9 +756,8 @@ static int serial2002_ai_rinsn(struct comedi_device *dev, poll_channel(devpriv->tty, chan); while (1) { read = serial_read(devpriv->tty, 1000); - if (read.kind != is_channel || read.index == chan) { + if (read.kind != is_channel || read.index == chan) break; - } } data[n] = read.value; } @@ -801,9 +791,8 @@ static int serial2002_ao_rinsn(struct comedi_device *dev, int n; int chan = CR_CHAN(insn->chanspec); - for (n = 0; n < insn->n; n++) { + for (n = 0; n < insn->n; n++) data[n] = devpriv->ao_readback[chan]; - } return n; } @@ -822,9 +811,8 @@ static int serial2002_ei_rinsn(struct comedi_device *dev, poll_channel(devpriv->tty, chan); while (1) { read = serial_read(devpriv->tty, 1000); - if (read.kind != is_channel || read.index == chan) { + if (read.kind != is_channel || read.index == chan) break; - } } data[n] = read.value; } @@ -838,9 +826,8 @@ static int serial2002_attach(struct comedi_device *dev, printk("comedi%d: serial2002: ", dev->minor); dev->board_name = thisboard->name; - if (alloc_private(dev, sizeof(struct serial2002_private)) < 0) { + if (alloc_private(dev, sizeof(struct serial2002_private)) < 0) return -ENOMEM; - } dev->open = serial_2002_open; dev->close = serial_2002_close; devpriv->port = it->options[0]; diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index 598884ec3ede..89e62aa134b0 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -75,8 +75,10 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5), /* 'private' structure for each subdevice */ struct unioxx5_subd_priv { int usp_iobase; - unsigned char usp_module_type[12]; /* 12 modules. each can be 70L or 73L */ - unsigned char usp_extra_data[12][4]; /* for saving previous written value for analog modules */ + /* 12 modules. each can be 70L or 73L */ + unsigned char usp_module_type[12]; + /* for saving previous written value for analog modules */ + unsigned char usp_extra_data[12][4]; unsigned char usp_prev_wr_val[3]; /* previous written value */ unsigned char usp_prev_cn_val[3]; /* previous channel value */ }; @@ -169,7 +171,7 @@ static int unioxx5_attach(struct comedi_device *dev, return -1; } - printk("attached\n"); + printk(KERN_INFO "attached\n"); return 0; } @@ -181,7 +183,8 @@ static int unioxx5_subdev_read(struct comedi_device *dev, int channel, type; channel = CR_CHAN(insn->chanspec); - type = usp->usp_module_type[channel / 2]; /* defining module type(analog or digital) */ + /* defining module type(analog or digital) */ + type = usp->usp_module_type[channel / 2]; if (type == MODULE_DIGITAL) { if (!__unioxx5_digital_read(usp, data, channel, dev->minor)) @@ -202,7 +205,8 @@ static int unioxx5_subdev_write(struct comedi_device *dev, int channel, type; channel = CR_CHAN(insn->chanspec); - type = usp->usp_module_type[channel / 2]; /* defining module type(analog or digital) */ + /* defining module type(analog or digital) */ + type = usp->usp_module_type[channel / 2]; if (type == MODULE_DIGITAL) { if (!__unioxx5_digital_write(usp, data, channel, dev->minor)) @@ -261,9 +265,12 @@ static int unioxx5_insn_config(struct comedi_device *dev, * change channel type on input or output) * \* */ outb(1, usp->usp_iobase + 0); - outb(flags, usp->usp_iobase + channel_offset); /* changes type of _one_ channel */ - outb(0, usp->usp_iobase + 0); /* sets channels bank to 0(allows directly input/output) */ - usp->usp_prev_cn_val[channel_offset - 1] = flags; /* saves written value */ + /* changes type of _one_ channel */ + outb(flags, usp->usp_iobase + channel_offset); + /* sets channels bank to 0(allows directly input/output) */ + outb(0, usp->usp_iobase + 0); + /* saves written value */ + usp->usp_prev_cn_val[channel_offset - 1] = flags; return 0; } @@ -304,14 +311,15 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, } usp->usp_iobase = subdev_iobase; - printk("comedi%d: |", minor); + printk(KERN_INFO "comedi%d: |", minor); /* defining modules types */ for (i = 0; i < 12; i++) { to = 10000; __unioxx5_analog_config(usp, i * 2); - outb(i + 1, subdev_iobase + 5); /* sends channel number to card */ + /* sends channel number to card */ + outb(i + 1, subdev_iobase + 5); outb('H', subdev_iobase + 6); /* requests EEPROM world */ while (!(inb(subdev_iobase + 0) & TxBE)) ; /* waits while writting will be allowed */ @@ -346,9 +354,10 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, subdev->range_table = &range_digital; subdev->insn_read = unioxx5_subdev_read; subdev->insn_write = unioxx5_subdev_write; - subdev->insn_config = unioxx5_insn_config; /* for digital modules only!!! */ + /* for digital modules only!!! */ + subdev->insn_config = unioxx5_insn_config; - printk("subdevice configured\n"); + printk(KERN_INFO "subdevice configured\n"); return 0; } @@ -367,7 +376,8 @@ static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, return 0; } - val = usp->usp_prev_wr_val[channel_offset - 1]; /* getting previous written value */ + /* getting previous written value */ + val = usp->usp_prev_wr_val[channel_offset - 1]; if (*data) val |= mask; @@ -375,7 +385,8 @@ static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, val &= ~mask; outb(val, usp->usp_iobase + channel_offset); - usp->usp_prev_wr_val[channel_offset - 1] = val; /* saving new written value */ + /* saving new written value */ + usp->usp_prev_wr_val[channel_offset - 1] = val; return 1; } @@ -399,7 +410,6 @@ static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp, if (channel_offset > 1) channel -= 2 << channel_offset; /* this operation is created for correct readed value to 0 or 1 */ - *data >>= channel; return 1; } @@ -444,7 +454,8 @@ static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, usp->usp_extra_data[module][i] = (unsigned char)((*data & 0xFF00) >> 8); /* while(!((inb(usp->usp_iobase + 0)) & TxBE)); */ - outb(module + 1, usp->usp_iobase + 5); /* sending module number to card(1 .. 12) */ + /* sending module number to card(1 .. 12) */ + outb(module + 1, usp->usp_iobase + 5); outb('W', usp->usp_iobase + 6); /* sends (W)rite command to module */ /* sending for bytes to module(one byte per cycle iteration) */ @@ -475,7 +486,8 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, } __unioxx5_analog_config(usp, channel); - outb(module_no + 1, usp->usp_iobase + 5); /* sends module number to card(1 .. 12) */ + /* sends module number to card(1 .. 12) */ + outb(module_no + 1, usp->usp_iobase + 5); outb('V', usp->usp_iobase + 6); /* sends to module (V)erify command */ control = inb(usp->usp_iobase); /* get control register byte */ diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 1d09bfa2edf5..bf62e0dd6f69 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -1465,6 +1465,7 @@ static int usbdux_ao_inttrig(struct comedi_device *dev, dev_err(&this_usbduxsub->interface->dev, "comedi%d: usbdux_ao_inttrig: invalid trignum\n", dev->minor); + up(&this_usbduxsub->sem); return -EINVAL; } if (!(this_usbduxsub->ao_cmd_running)) { @@ -1935,11 +1936,8 @@ static int usbdux_pwm_cancel(struct comedi_device *dev, dev_dbg(&this_usbduxsub->interface->dev, "comedi %d: sending pwm off command to the usb device.\n", dev->minor); - res = send_dux_commands(this_usbduxsub, SENDPWMOFF); - if (res < 0) - return res; - return res; + return send_dux_commands(this_usbduxsub, SENDPWMOFF); } static void usbduxsub_pwm_irq(struct urb *urb) @@ -2674,6 +2672,7 @@ static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) { dev_err(&udev->interface->dev, "comedi%d: error alloc space for subdev\n", dev->minor); + up(&udev->sem); up(&start_stop_sem); return ret; } diff --git a/drivers/staging/cs5535_gpio/Kconfig b/drivers/staging/cs5535_gpio/Kconfig deleted file mode 100644 index a1b3a8d2b866..000000000000 --- a/drivers/staging/cs5535_gpio/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config CS5535_GPIO - tristate "AMD CS5535/CS5536 GPIO (Geode Companion Device)" - depends on X86_32 - help - Note: this driver is DEPRECATED. Please use the cs5535-gpio module - in the GPIO section instead (CONFIG_GPIO_CS5535). - - Give userspace access to the GPIO pins on the AMD CS5535 and - CS5536 Geode companion devices. - - If compiled as a module, it will be called cs5535_gpio. diff --git a/drivers/staging/cs5535_gpio/Makefile b/drivers/staging/cs5535_gpio/Makefile deleted file mode 100644 index d67c4b85f191..000000000000 --- a/drivers/staging/cs5535_gpio/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o diff --git a/drivers/staging/cs5535_gpio/TODO b/drivers/staging/cs5535_gpio/TODO deleted file mode 100644 index 98d1cd1e2363..000000000000 --- a/drivers/staging/cs5535_gpio/TODO +++ /dev/null @@ -1,6 +0,0 @@ -This is an obsolete driver for some the CS5535 and CS5536 southbridge GPIOs. -It has been replaced by a driver that makes use of the Linux GPIO subsystem. -Please switch to that driver, and let dilinger@queued.net know if there's -anything missing from the new driver. - -This driver is scheduled for removal in 2.6.40. diff --git a/drivers/staging/cs5535_gpio/cs5535_gpio.c b/drivers/staging/cs5535_gpio/cs5535_gpio.c deleted file mode 100644 index b25f9d103b3b..000000000000 --- a/drivers/staging/cs5535_gpio/cs5535_gpio.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * AMD CS5535/CS5536 GPIO driver. - * Allows a user space process to play with the GPIO pins. - * - * Copyright (c) 2005 Ben Gardner - * - * This program is free software; you can redistribute it and/or modify - * it under the smems of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -#define NAME "cs5535_gpio" - -MODULE_AUTHOR("Ben Gardner "); -MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO Pin Driver"); -MODULE_LICENSE("GPL"); - -static int major; -module_param(major, int, 0); -MODULE_PARM_DESC(major, "Major device number"); - -static ulong mask; -module_param(mask, ulong, 0); -MODULE_PARM_DESC(mask, "GPIO channel mask"); - -#define MSR_LBAR_GPIO 0x5140000C - -static u32 gpio_base; - -static struct pci_device_id divil_pci[] = { - { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, - { } /* NULL entry */ -}; -MODULE_DEVICE_TABLE(pci, divil_pci); - -static struct cdev cs5535_gpio_cdev; - -/* reserve 32 entries even though some aren't usable */ -#define CS5535_GPIO_COUNT 32 - -/* IO block size */ -#define CS5535_GPIO_SIZE 256 - -struct gpio_regmap { - u32 rd_offset; - u32 wr_offset; - char on; - char off; -}; -static struct gpio_regmap rm[] = -{ - { 0x30, 0x00, '1', '0' }, /* GPIOx_READ_BACK / GPIOx_OUT_VAL */ - { 0x20, 0x20, 'I', 'i' }, /* GPIOx_IN_EN */ - { 0x04, 0x04, 'O', 'o' }, /* GPIOx_OUT_EN */ - { 0x08, 0x08, 't', 'T' }, /* GPIOx_OUT_OD_EN */ - { 0x18, 0x18, 'P', 'p' }, /* GPIOx_OUT_PU_EN */ - { 0x1c, 0x1c, 'D', 'd' }, /* GPIOx_OUT_PD_EN */ -}; - - -/** - * Gets the register offset for the GPIO bank. - * Low (0-15) starts at 0x00, high (16-31) starts at 0x80 - */ -static inline u32 cs5535_lowhigh_base(int reg) -{ - return (reg & 0x10) << 3; -} - -static ssize_t cs5535_gpio_write(struct file *file, const char __user *data, - size_t len, loff_t *ppos) -{ - u32 m = iminor(file->f_path.dentry->d_inode); - int i, j; - u32 base = gpio_base + cs5535_lowhigh_base(m); - u32 m0, m1; - char c; - - /** - * Creates the mask for atomic bit programming. - * The high 16 bits and the low 16 bits are used to set the mask. - * For example, GPIO 15 maps to 31,15: 0,1 => On; 1,0=> Off - */ - m1 = 1 << (m & 0x0F); - m0 = m1 << 16; - - for (i = 0; i < len; ++i) { - if (get_user(c, data+i)) - return -EFAULT; - - for (j = 0; j < ARRAY_SIZE(rm); j++) { - if (c == rm[j].on) { - outl(m1, base + rm[j].wr_offset); - /* If enabling output, turn off AUX 1 and AUX 2 */ - if (c == 'O') { - outl(m0, base + 0x10); - outl(m0, base + 0x14); - } - break; - } else if (c == rm[j].off) { - outl(m0, base + rm[j].wr_offset); - break; - } - } - } - *ppos = 0; - return len; -} - -static ssize_t cs5535_gpio_read(struct file *file, char __user *buf, - size_t len, loff_t *ppos) -{ - u32 m = iminor(file->f_path.dentry->d_inode); - u32 base = gpio_base + cs5535_lowhigh_base(m); - int rd_bit = 1 << (m & 0x0f); - int i; - char ch; - ssize_t count = 0; - - if (*ppos >= ARRAY_SIZE(rm)) - return 0; - - for (i = *ppos; (i < (*ppos + len)) && (i < ARRAY_SIZE(rm)); i++) { - ch = (inl(base + rm[i].rd_offset) & rd_bit) ? - rm[i].on : rm[i].off; - - if (put_user(ch, buf+count)) - return -EFAULT; - - count++; - } - - /* add a line-feed if there is room */ - if ((i == ARRAY_SIZE(rm)) && (count < len)) { - if (put_user('\n', buf + count)) - return -EFAULT; - count++; - } - - *ppos += count; - return count; -} - -static int cs5535_gpio_open(struct inode *inode, struct file *file) -{ - u32 m = iminor(inode); - - /* the mask says which pins are usable by this driver */ - if ((mask & (1 << m)) == 0) - return -EINVAL; - - return nonseekable_open(inode, file); -} - -static const struct file_operations cs5535_gpio_fops = { - .owner = THIS_MODULE, - .write = cs5535_gpio_write, - .read = cs5535_gpio_read, - .open = cs5535_gpio_open, - .llseek = no_llseek, -}; - -static int __init cs5535_gpio_init(void) -{ - dev_t dev_id; - u32 low, hi; - int retval; - - if (pci_dev_present(divil_pci) == 0) { - printk(KERN_WARNING NAME ": DIVIL not found\n"); - return -ENODEV; - } - - /* Grab the GPIO I/O range */ - rdmsr(MSR_LBAR_GPIO, low, hi); - - /* Check the mask and whether GPIO is enabled (sanity check) */ - if (hi != 0x0000f001) { - printk(KERN_WARNING NAME ": GPIO not enabled\n"); - return -ENODEV; - } - - /* Mask off the IO base address */ - gpio_base = low & 0x0000ff00; - - /** - * Some GPIO pins - * 31-29,23 : reserved (always mask out) - * 28 : Power Button - * 26 : PME# - * 22-16 : LPC - * 14,15 : SMBus - * 9,8 : UART1 - * 7 : PCI INTB - * 3,4 : UART2/DDC - * 2 : IDE_IRQ0 - * 0 : PCI INTA - * - * If a mask was not specified, be conservative and only allow: - * 1,2,5,6,10-13,24,25,27 - */ - if (mask != 0) - mask &= 0x1f7fffff; - else - mask = 0x0b003c66; - - if (!request_region(gpio_base, CS5535_GPIO_SIZE, NAME)) { - printk(KERN_ERR NAME ": can't allocate I/O for GPIO\n"); - return -ENODEV; - } - - if (major) { - dev_id = MKDEV(major, 0); - retval = register_chrdev_region(dev_id, CS5535_GPIO_COUNT, - NAME); - } else { - retval = alloc_chrdev_region(&dev_id, 0, CS5535_GPIO_COUNT, - NAME); - major = MAJOR(dev_id); - } - - if (retval) { - release_region(gpio_base, CS5535_GPIO_SIZE); - return -1; - } - - printk(KERN_DEBUG NAME ": base=%#x mask=%#lx major=%d\n", - gpio_base, mask, major); - - cdev_init(&cs5535_gpio_cdev, &cs5535_gpio_fops); - cdev_add(&cs5535_gpio_cdev, dev_id, CS5535_GPIO_COUNT); - - return 0; -} - -static void __exit cs5535_gpio_cleanup(void) -{ - dev_t dev_id = MKDEV(major, 0); - - cdev_del(&cs5535_gpio_cdev); - unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT); - release_region(gpio_base, CS5535_GPIO_SIZE); -} - -module_init(cs5535_gpio_init); -module_exit(cs5535_gpio_cleanup); diff --git a/drivers/staging/cxd2099/cxd2099.c b/drivers/staging/cxd2099/cxd2099.c index b49186c74eb3..55b1c4a59035 100644 --- a/drivers/staging/cxd2099/cxd2099.c +++ b/drivers/staging/cxd2099/cxd2099.c @@ -22,7 +22,6 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */ -#include #include #include #include diff --git a/drivers/staging/cxt1e1/sbecom_inline_linux.h b/drivers/staging/cxt1e1/sbecom_inline_linux.h index 501a331ded5b..c0563e68997b 100644 --- a/drivers/staging/cxt1e1/sbecom_inline_linux.h +++ b/drivers/staging/cxt1e1/sbecom_inline_linux.h @@ -47,7 +47,6 @@ #include #else #include -#include #if defined(CONFIG_SMP) && ! defined(__SMP__) #define __SMP__ #endif diff --git a/drivers/staging/dt3155v4l/Kconfig b/drivers/staging/dt3155v4l/Kconfig index 5cd5a575b64d..226a1ca90b3c 100644 --- a/drivers/staging/dt3155v4l/Kconfig +++ b/drivers/staging/dt3155v4l/Kconfig @@ -1,7 +1,7 @@ config VIDEO_DT3155 tristate "DT3155 frame grabber, Video4Linux interface" depends on PCI && VIDEO_DEV && VIDEO_V4L2 - select VIDEOBUF_DMA_CONTIG + select VIDEOBUF2_DMA_CONTIG default n ---help--- Enables dt3155 device driver for the DataTranslation DT3155 frame grabber. @@ -18,3 +18,11 @@ 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 streaming capture method" + depends on VIDEO_DT3155 + default y + ---help--- + Select it if you want to use streaming of memory mapped buffers + or leave it unselected if you want to use read method (one copy more). diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c index 15d7efeed292..fe02d22274b4 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/dt3155v4l/dt3155v4l.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "dt3155v4l.h" @@ -38,6 +38,12 @@ #define DT3155_BUF_SIZE (768 * 576) +#ifdef CONFIG_DT3155_STREAMING +#define DT3155_CAPTURE_METHOD V4L2_CAP_STREAMING +#else +#define DT3155_CAPTURE_METHOD V4L2_CAP_READWRITE +#endif + /* global initializers (for all boards) */ #ifdef CONFIG_DT3155_CCIR static const u8 csr2_init = VT_50HZ; @@ -197,14 +203,14 @@ static int wait_i2c_reg(void __iomem *addr) static int dt3155_start_acq(struct dt3155_priv *pd) { - struct videobuf_buffer *vb = pd->curr_buf; + struct vb2_buffer *vb = pd->curr_buf; dma_addr_t dma_addr; - dma_addr = videobuf_to_dma_contig(vb); + dma_addr = vb2_dma_contig_plane_paddr(vb, 0); 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); + iowrite32(dma_addr + img_width, pd->regs + ODD_DMA_START); + iowrite32(img_width, pd->regs + EVEN_DMA_STRIDE); + iowrite32(img_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); @@ -221,95 +227,110 @@ dt3155_start_acq(struct dt3155_priv *pd) return 0; /* success */ } +/* + * driver-specific callbacks (vb2_ops) + */ static int -dt3155_stop_acq(struct dt3155_priv *pd) +dt3155_queue_setup(struct vb2_queue *q, unsigned int *num_buffers, + unsigned int *num_planes, unsigned long sizes[], + void *alloc_ctxs[]) { - int tmp; + struct dt3155_priv *pd = vb2_get_drv_priv(q); + void *ret; - /* 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); + if (*num_buffers == 0) + *num_buffers = 1; + *num_planes = 1; + sizes[0] = img_width * img_height; + if (pd->q->alloc_ctx[0]) + return 0; + ret = vb2_dma_contig_init_ctx(&pd->pdev->dev); + if (IS_ERR(ret)) + return PTR_ERR(ret); + pd->q->alloc_ctx[0] = ret; return 0; } -/* Locking: Caller holds q->vb_lock */ -static int -dt3155_buf_setup(struct videobuf_queue *q, unsigned int *count, - unsigned int *size) +static void +dt3155_wait_prepare(struct vb2_queue *q) { - *size = img_width * img_height; + struct dt3155_priv *pd = vb2_get_drv_priv(q); + + mutex_unlock(pd->vdev->lock); +} + +static void +dt3155_wait_finish(struct vb2_queue *q) +{ + struct dt3155_priv *pd = vb2_get_drv_priv(q); + + mutex_lock(pd->vdev->lock); +} + +static int +dt3155_buf_prepare(struct vb2_buffer *vb) +{ + vb2_set_plane_payload(vb, 0, 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) +dt3155_start_streaming(struct vb2_queue *q) { - 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); /* FIXME: needed? */ - } else - vb->state = VIDEOBUF_PREPARED; - return ret; + return 0; +} + +static int +dt3155_stop_streaming(struct vb2_queue *q) +{ + struct dt3155_priv *pd = vb2_get_drv_priv(q); + struct vb2_buffer *vb; + + spin_lock_irq(&pd->lock); + while (!list_empty(&pd->dmaq)) { + vb = list_first_entry(&pd->dmaq, typeof(*vb), done_entry); + list_del(&vb->done_entry); + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); + } + spin_unlock_irq(&pd->lock); + msleep(45); /* irq hendler will stop the hardware */ + return 0; } -/* Locking: Caller holds q->vb_lock & q->irqlock */ static void -dt3155_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) +dt3155_buf_queue(struct vb2_buffer *vb) { - struct dt3155_priv *pd = q->priv_data; + struct dt3155_priv *pd = vb2_get_drv_priv(vb->vb2_queue); - if (vb->state != VIDEOBUF_NEEDS_INIT) { - vb->state = VIDEOBUF_QUEUED; - list_add_tail(&vb->queue, &pd->dmaq); - wake_up_interruptible_sync(&pd->do_dma); - } else - vb->state = VIDEOBUF_ERROR; + /* pd->q->streaming = 1 when dt3155_buf_queue() is invoked */ + spin_lock_irq(&pd->lock); + if (pd->curr_buf) + list_add_tail(&vb->done_entry, &pd->dmaq); + else { + pd->curr_buf = vb; + dt3155_start_acq(pd); + } + spin_unlock_irq(&pd->lock); } +/* + * end driver-specific callbacks + */ -/* 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(q, vb, 0, 0); /* FIXME: cannot be interrupted */ - videobuf_dma_contig_free(q, vb); - vb->state = VIDEOBUF_NEEDS_INIT; -} - -static struct videobuf_queue_ops vbq_ops = { - .buf_setup = dt3155_buf_setup, +const struct vb2_ops q_ops = { + .queue_setup = dt3155_queue_setup, + .wait_prepare = dt3155_wait_prepare, + .wait_finish = dt3155_wait_finish, .buf_prepare = dt3155_buf_prepare, + .start_streaming = dt3155_start_streaming, + .stop_streaming = dt3155_stop_streaming, .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; + struct vb2_buffer *ivb; dma_addr_t dma_addr; u32 tmp; @@ -341,33 +362,22 @@ dt3155_irq_handler_even(int irq, void *dev_id) } 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 + if (ipd->curr_buf) { + do_gettimeofday(&ipd->curr_buf->v4l2_buf.timestamp); + ipd->curr_buf->v4l2_buf.sequence = (ipd->field_count) >> 1; + vb2_buffer_done(ipd->curr_buf, VB2_BUF_STATE_DONE); + } + + if (!ipd->q->streaming || list_empty(&ipd->dmaq)) 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); + ivb = list_first_entry(&ipd->dmaq, typeof(*ivb), done_entry); + list_del(&ivb->done_entry); + ipd->curr_buf = ivb; + dma_addr = vb2_dma_contig_plane_paddr(ivb, 0); 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); + iowrite32(dma_addr + img_width, ipd->regs + ODD_DMA_START); + iowrite32(img_width, ipd->regs + EVEN_DMA_STRIDE); + iowrite32(img_width, ipd->regs + ODD_DMA_STRIDE); mmiowb(); /* enable interrupts, clear all irq flags */ iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START | @@ -379,68 +389,40 @@ dt3155_irq_handler_even(int irq, void *dev_id) ipd->curr_buf = NULL; /* stop the board */ write_i2c_reg_nowait(ipd->regs, CSR2, ipd->csr2); + iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN | + FLD_DN_ODD | FLD_DN_EVEN, ipd->regs + CSR1); /* 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); + printk(KERN_INFO "dt3155: open(): minor: %i, users: %i\n", + pd->vdev->minor, pd->users); - if (mutex_lock_interruptible(&pd->mux) == -EINTR) - return -ERESTARTSYS; if (!pd->users) { - pd->vidq = kzalloc(sizeof(*pd->vidq), GFP_KERNEL); - if (!pd->vidq) { + pd->q = kzalloc(sizeof(*pd->q), GFP_KERNEL); + if (!pd->q) { printk(KERN_ERR "dt3155: error: alloc queue\n"); ret = -ENOMEM; goto err_alloc_queue; } - 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, NULL); + pd->q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + pd->q->io_modes = VB2_READ | VB2_MMAP; + pd->q->ops = &q_ops; + pd->q->mem_ops = &vb2_dma_contig_memops; + pd->q->drv_priv = pd; + pd->curr_buf = NULL; + pd->field_count = 0; + vb2_queue_init(pd->q); /* cannot fail */ + INIT_LIST_HEAD(&pd->dmaq); + spin_lock_init(&pd->lock); /* disable all irqs, clear all irq flags */ iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR); @@ -451,26 +433,13 @@ dt3155_open(struct file *filp) 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); + return 0; /* success */ err_request_irq: - kfree(pd->vidq); - pd->vidq = NULL; + kfree(pd->q); + pd->q = NULL; err_alloc_queue: -done: - mutex_unlock(&pd->mux); return ret; } @@ -478,61 +447,29 @@ 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); + printk(KERN_INFO "dt3155: release(): minor: %i, users: %i\n", + pd->vdev->minor, pd->users - 1); - 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(pd->vidq, tmp, 0, 1); /* block, interruptible */ - dt3155_stop_acq(pd); - videobuf_stop(pd->vidq); - pd->acq_fp = NULL; - pd->streaming = 0; - } if (!pd->users) { - kthread_stop(pd->thread); + vb2_queue_release(pd->q); free_irq(pd->pdev->irq, pd); - kfree(pd->vidq); - pd->vidq = NULL; + if (pd->q->alloc_ctx[0]) + vb2_dma_contig_cleanup_ctx(pd->q->alloc_ctx[0]); + kfree(pd->q); + pd->q = NULL; } - mutex_unlock(&pd->mux); - return ret; + return 0; } 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; - 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); -done: - mutex_unlock(&pd->mux); - return ret; + return vb2_read(pd->q, user, size, loff, filp->f_flags & O_NONBLOCK); } static unsigned int @@ -540,7 +477,7 @@ 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); + return vb2_poll(pd->q, filp, polltbl); } static int @@ -548,7 +485,7 @@ dt3155_mmap(struct file *filp, struct vm_area_struct *vma) { struct dt3155_priv *pd = video_drvdata(filp); - return videobuf_mmap_mapper(pd->vidq, vma); + return vb2_mmap(pd->q, vma); } static const struct v4l2_file_operations dt3155_fops = { @@ -565,46 +502,16 @@ 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; - 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); - } else - ret = -EBUSY; -unlock: - mutex_unlock(&pd->mux); - return ret; + return vb2_streamon(pd->q, type); } 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(pd->vidq, tmp, 0, 1); /* block, interruptible */ - return ret; + return vb2_streamoff(pd->q, type); } static int @@ -618,8 +525,7 @@ 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 | - V4L2_CAP_STREAMING | - V4L2_CAP_READWRITE; + DT3155_CAPTURE_METHOD; return 0; } @@ -667,93 +573,39 @@ 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) { - 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; + 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; - 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) - ret = videobuf_reqbufs(q, b); - else { /* FIXME: is it necessary? */ - printk(KERN_DEBUG "dt3155: request to free buffers\n"); - /* ret = videobuf_mmap_free(q); */ - ret = dt3155_ioc_streamoff(filp, p, - V4L2_BUF_TYPE_VIDEO_CAPTURE); - } - return ret; + return vb2_reqbufs(pd->q, b); } 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); + return vb2_querybuf(pd->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; - int ret; - ret = videobuf_qbuf(q, b); - if (ret) - return ret; - return videobuf_querybuf(q, b); + return vb2_qbuf(pd->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); + return vb2_dqbuf(pd->q, b, filp->f_flags & O_NONBLOCK); } static int @@ -880,21 +732,21 @@ static const struct v4l2_ioctl_ops dt3155_ioctl_ops = { }; static int __devinit -dt3155_init_board(struct pci_dev *dev) +dt3155_init_board(struct pci_dev *pdev) { - struct dt3155_priv *pd = pci_get_drvdata(dev); + struct dt3155_priv *pd = pci_get_drvdata(pdev); void *buf_cpu; dma_addr_t buf_dma; int i; u8 tmp; - pci_set_master(dev); /* dt3155 needs it */ + pci_set_master(pdev); /* 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); + msleep(20); /* initializing adaper registers */ iowrite32(FIFO_EN | SRST, pd->regs + CSR1); @@ -949,7 +801,7 @@ dt3155_init_board(struct pci_dev *dev) write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3); /* allocate memory, and initialize the DMA machine */ - buf_cpu = dma_alloc_coherent(&dev->dev, DT3155_BUF_SIZE, &buf_dma, + buf_cpu = dma_alloc_coherent(&pdev->dev, DT3155_BUF_SIZE, &buf_dma, GFP_KERNEL); if (!buf_cpu) { printk(KERN_ERR "dt3155: dma_alloc_coherent " @@ -975,7 +827,7 @@ dt3155_init_board(struct pci_dev *dev) iowrite32(FIFO_EN | SRST | FLD_DN_EVEN | FLD_DN_ODD, pd->regs + CSR1); /* deallocate memory */ - dma_free_coherent(&dev->dev, DT3155_BUF_SIZE, buf_cpu, buf_dma); + dma_free_coherent(&pdev->dev, DT3155_BUF_SIZE, buf_cpu, buf_dma); if (tmp & BUSY_EVEN) { printk(KERN_ERR "dt3155: BUSY_EVEN not cleared\n"); return -EIO; @@ -996,7 +848,7 @@ static struct video_device dt3155_vdev = { /* same as in drivers/base/dma-coherent.c */ struct dma_coherent_mem { void *virt_base; - u32 device_base; + dma_addr_t device_base; int size; int flags; unsigned long *bitmap; @@ -1058,18 +910,18 @@ dt3155_free_coherent(struct device *dev) } static int __devinit -dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id) +dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int err; struct dt3155_priv *pd; printk(KERN_INFO "dt3155: probe()\n"); - err = dma_set_mask(&dev->dev, DMA_BIT_MASK(32)); + err = dma_set_mask(&pdev->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)); + err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (err) { printk(KERN_ERR "dt3155: cannot set dma_coherent_mask\n"); return -ENODEV; @@ -1085,31 +937,31 @@ dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id) goto err_video_device_alloc; } *pd->vdev = dt3155_vdev; - pci_set_drvdata(dev, pd); /* for use in dt3155_remove() */ + pci_set_drvdata(pdev, 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; + pd->pdev = pdev; INIT_LIST_HEAD(&pd->dmaq); - init_waitqueue_head(&pd->do_dma); mutex_init(&pd->mux); + pd->vdev->lock = &pd->mux; /* for locking v4l2_file_operations */ + spin_lock_init(&pd->lock); pd->csr2 = csr2_init; pd->config = config_init; - err = pci_enable_device(pd->pdev); + err = pci_enable_device(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)); + err = pci_request_region(pdev, 0, pci_name(pdev)); if (err) goto err_req_region; - pd->regs = pci_iomap(pd->pdev, 0, pci_resource_len(pd->pdev, 0)); + pd->regs = pci_iomap(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); + err = dt3155_init_board(pdev); if (err) { printk(KERN_ERR "dt3155: dt3155_init_board failed\n"); goto err_init_board; @@ -1119,7 +971,7 @@ 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, + err = dt3155_alloc_coherent(&pdev->dev, DT3155_CHUNK_SIZE, DMA_MEMORY_MAP); if (err) printk(KERN_INFO "dt3155: preallocated 8 buffers\n"); @@ -1127,11 +979,11 @@ dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id) return 0; /* success */ err_init_board: - pci_iounmap(pd->pdev, pd->regs); + pci_iounmap(pdev, pd->regs); err_pci_iomap: - pci_release_region(pd->pdev, 0); + pci_release_region(pdev, 0); err_req_region: - pci_disable_device(pd->pdev); + pci_disable_device(pdev); err_enable_dev: video_device_release(pd->vdev); err_video_device_alloc: @@ -1140,16 +992,16 @@ dt3155_probe(struct pci_dev *dev, const struct pci_device_id *id) } static void __devexit -dt3155_remove(struct pci_dev *dev) +dt3155_remove(struct pci_dev *pdev) { - struct dt3155_priv *pd = pci_get_drvdata(dev); + struct dt3155_priv *pd = pci_get_drvdata(pdev); printk(KERN_INFO "dt3155: remove()\n"); - dt3155_free_coherent(&dev->dev); + dt3155_free_coherent(&pdev->dev); video_unregister_device(pd->vdev); - pci_iounmap(dev, pd->regs); - pci_release_region(pd->pdev, 0); - pci_disable_device(pd->pdev); + pci_iounmap(pdev, pd->regs); + pci_release_region(pdev, 0); + pci_disable_device(pdev); /* * video_device_release() is invoked automatically * see: struct video_device dt3155_vdev diff --git a/drivers/staging/dt3155v4l/dt3155v4l.h b/drivers/staging/dt3155v4l/dt3155v4l.h index aa68a6f38aaa..b0792b3d9b76 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.h +++ b/drivers/staging/dt3155v4l/dt3155v4l.h @@ -179,18 +179,13 @@ struct dt3155_stats { * struct dt3155_priv - private data structure * * @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 + * @q pointer to vb2_queue structure * @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 - * @lock spinlock for videobuf queues + * @irq_handler: irq handler for the driver + * @dmaq queue for dma buffers + * @lock spinlock for dma queue * @field_count fields counter * @stats: statistics structure * @users open count @@ -200,17 +195,12 @@ 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; - 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 vb2_queue *q; + struct vb2_buffer *curr_buf; struct mutex mux; + irq_handler_t irq_handler; + struct list_head dmaq; spinlock_t lock; unsigned int field_count; struct dt3155_stats stats; diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/easycap/Kconfig index 6ed208c61855..a425a6f9cdca 100644 --- a/drivers/staging/easycap/Kconfig +++ b/drivers/staging/easycap/Kconfig @@ -1,6 +1,7 @@ config EASYCAP tristate "EasyCAP USB ID 05e1:0408 support" - depends on USB && VIDEO_DEV && (SND || SOUND_OSS_CORE) + depends on USB && VIDEO_DEV && SND + select SND_PCM ---help--- This is an integrated audio/video driver for EasyCAP cards with @@ -15,35 +16,6 @@ config EASYCAP To compile this driver as a module, choose M here: the module will be called easycap -choice - prompt "Sound Interface" - depends on EASYCAP - default EASYCAP_SND - ---help--- - -config EASYCAP_SND - bool "ALSA" - depends on SND - select SND_PCM - - ---help--- - Say 'Y' if you want to use ALSA interface - - This will disable Open Sound System (OSS) binding. - -config EASYCAP_OSS - bool "OSS (DEPRECATED)" - depends on SOUND_OSS_CORE - - ---help--- - Say 'Y' if you prefer Open Sound System (OSS) interface - - This will disable Advanced Linux Sound Architecture (ALSA) binding. - - Once binding to ALSA interface will be stable this option will be - removed. -endchoice - config EASYCAP_DEBUG bool "Enable EasyCAP driver debugging" depends on EASYCAP diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile index b13e9ac473ba..a34e75f59c18 100644 --- a/drivers/staging/easycap/Makefile +++ b/drivers/staging/easycap/Makefile @@ -4,9 +4,7 @@ easycap-objs += easycap_ioctl.o easycap-objs += easycap_settings.o easycap-objs += easycap_testcard.o easycap-objs += easycap_sound.o -easycap-$(CONFIG_EASYCAP_OSS) += easycap_sound_oss.o - -obj-$(CONFIG_EASYCAP) += easycap.o +obj-$(CONFIG_EASYCAP) += easycap.o ccflags-y := -Wall diff --git a/drivers/staging/easycap/README b/drivers/staging/easycap/README index 6b5ac0d34bd9..796b032384bd 100644 --- a/drivers/staging/easycap/README +++ b/drivers/staging/easycap/README @@ -27,28 +27,6 @@ BUILD OPTIONS AND DEPENDENCIES Unless EASYCAP_DEBUG is defined during compilation it will not be possible to select a debug level at the time of module installation. -If the parameter EASYCAP_IS_VIDEODEV_CLIENT is undefined during compilation -the built module is entirely independent of the videodev module, and when -the EasyCAP is physically plugged into a USB port the special files -/dev/easycap0 and /dev/easysnd1 are created as video and sound sources -respectively. - -If the parameter EASYCAP_IS_VIDEODEV_CLIENT is defined during compilation -the built easycap module is configured to register with the videodev module, -in which case the special files created when the EasyCAP is plugged in are -/dev/video0 and /dev/easysnd0. - -During in-tree builds the following should should be defined whenever the -parameter EASYCAP_IS_VIDEODEV_CLIENT is defined: - -EASYCAP_NEEDS_V4L2_DEVICE_H -EASYCAP_NEEDS_V4L2_FOPS -EASYCAP_NEEDS_UNLOCKED_IOCTL - -If the build is performed out-of-tree against older kernels the parameters -to be defined depend on the kernel version in a way which will not be -discussed here. - KNOWN RUNTIME ISSUES -------------------- @@ -82,8 +60,8 @@ Three module parameters are defined: debug the easycap module is configured at diagnostic level n (0 to 9) gain audio gain level n (0 to 31, default is 16) -bars 0 => testcard bars when incoming video signal is lost - 1 => testcard bars when incoming video signal is lost (default) +bars whether to display testcard bars when incoming video signal is lost + 0 => no, 1 => yes (default) SUPPORTED TV STANDARDS AND RESOLUTIONS @@ -128,8 +106,6 @@ hardware, but as yet it has actually been tested on only a few of these. I have been unable to test and calibrate the S-video input myself because I do not possess any equipment with S-video output. -This driver does not understand the V4L1 IOCTL commands. - UDEV RULES ---------- diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 1f94e2389efc..22b24b6c5a5b 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -62,7 +62,6 @@ #include #include -#include #include #include #include @@ -70,7 +69,6 @@ #include #include -#ifndef CONFIG_EASYCAP_OSS #include #include #include @@ -79,16 +77,11 @@ #include #include #include -#endif /* !CONFIG_EASYCAP_OSS */ #include #include #include #include -#ifndef PAGE_SIZE -#error "PAGE_SIZE not defined" -#endif /* PAGE_SIZE */ - /*---------------------------------------------------------------------------*/ /* VENDOR, PRODUCT: Syntek Semiconductor Co., Ltd * @@ -285,8 +278,6 @@ struct inputset { */ /*---------------------------------------------------------------------------*/ struct easycap { -#define TELLTALE "expectedstring" - char telltale[16]; int isdongle; int minor; @@ -420,7 +411,6 @@ struct easycap { * ALSA */ /*---------------------------------------------------------------------------*/ -#ifndef CONFIG_EASYCAP_OSS struct snd_pcm_hardware alsa_hardware; struct snd_card *psnd_card; struct snd_pcm *psnd_pcm; @@ -428,7 +418,6 @@ struct easycap { int dma_fill; int dma_next; int dma_read; -#endif /* !CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ /* * SOUND PROPERTIES @@ -510,12 +499,8 @@ int adjust_volume(struct easycap *, int); * AUDIO FUNCTION PROTOTYPES */ /*---------------------------------------------------------------------------*/ -#ifndef CONFIG_EASYCAP_OSS int easycap_alsa_probe(struct easycap *); void easycap_alsa_complete(struct urb *); -#else /* CONFIG_EASYCAP_OSS */ -void easyoss_complete(struct urb *); -#endif /* !CONFIG_EASYCAP_OSS */ int easycap_sound_setup(struct easycap *); int submit_audio_urbs(struct easycap *); @@ -603,34 +588,6 @@ extern int easycap_debug; #define JOM(n, format, args...) do {} while (0) #endif /* CONFIG_EASYCAP_DEBUG */ -#define MICROSECONDS(X, Y) \ - ((1000000*((long long int)(X.tv_sec - Y.tv_sec))) + \ - (long long int)(X.tv_usec - Y.tv_usec)) - -/*---------------------------------------------------------------------------*/ -/* - * (unsigned char *)P pointer to next byte pair - * (long int *)X pointer to accumulating count - * (long int *)Y pointer to accumulating sum - * (long long int *)Z pointer to accumulating sum of squares - */ -/*---------------------------------------------------------------------------*/ -#define SUMMER(P, X, Y, Z) do { \ - unsigned char *p; \ - unsigned int u0, u1, u2; \ - long int s; \ - p = (unsigned char *)(P); \ - u0 = (unsigned int) (*p); \ - u1 = (unsigned int) (*(p + 1)); \ - u2 = (unsigned int) ((u1 << 8) | u0); \ - if (0x8000 & u2) \ - s = -(long int)(0x7FFF & (~u2)); \ - else \ - s = (long int)(0x7FFF & u2); \ - *((X)) += (long int) 1; \ - *((Y)) += (long int) s; \ - *((Z)) += ((long long int)(s) * (long long int)(s)); \ -} while (0) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -644,8 +601,5 @@ extern struct easycap_format easycap_format[]; extern struct v4l2_queryctrl easycap_control[]; extern struct usb_driver easycap_usb_driver; extern struct easycap_dongle easycapdc60_dongle[]; -#ifdef CONFIG_EASYCAP_OSS -extern struct usb_class_driver easyoss_class; -#endif /* !CONFIG_EASYCAP_OSS */ #endif /* !__EASYCAP_H__ */ diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index b3bd11d5879f..0accab97a7f6 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -25,6 +25,7 @@ */ /*****************************************************************************/ +#include #include "easycap.h" /*--------------------------------------------------------------------------*/ @@ -966,10 +967,6 @@ long easycap_unlocked_ioctl(struct file *file, SAY("ERROR: peasycap is NULL\n"); return -1; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; - } p = peasycap->pusb_device; if (!p) { SAM("ERROR: peasycap->pusb_device is NULL\n"); @@ -1003,12 +1000,6 @@ long easycap_unlocked_ioctl(struct file *file, mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; - } - p = peasycap->pusb_device; if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); @@ -2356,14 +2347,8 @@ long easycap_unlocked_ioctl(struct file *file, /*---------------------------------------------------------------------------*/ JOM(8, "calling wake_up on wq_video and wq_audio\n"); wake_up_interruptible(&(peasycap->wq_video)); -#ifdef CONFIG_EASYCAP_OSS - wake_up_interruptible(&(peasycap->wq_audio)); - -#else if (peasycap->psubstream) snd_pcm_period_elapsed(peasycap->psubstream); -#endif /* CONFIG_EASYCAP_OSS */ -/*---------------------------------------------------------------------------*/ break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 62e07f6a026c..bea281624c41 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -158,10 +158,6 @@ static int easycap_open(struct inode *inode, struct file *file) SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; - } if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; @@ -695,10 +691,6 @@ static int videodev_release(struct video_device *pvideo_device) SAY("ending unsuccessfully\n"); return -EFAULT; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; - } if (0 != kill_video_urbs(peasycap)) { SAM("ERROR: kill_video_urbs() failed\n"); return -EFAULT; @@ -736,10 +728,6 @@ static void easycap_delete(struct kref *pkref) SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); return; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return; - } kd = isdongle(peasycap); /*---------------------------------------------------------------------------*/ /* @@ -888,20 +876,6 @@ static void easycap_delete(struct kref *pkref) } JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n", m * (0x01 << AUDIO_ISOC_ORDER)); -/*---------------------------------------------------------------------------*/ -#ifdef CONFIG_EASYCAP_OSS - JOM(4, "freeing audio buffers.\n"); - gone = 0; - for (k = 0; k < peasycap->audio_buffer_page_many; k++) { - if (peasycap->audio_buffer[k].pgo) { - free_page((unsigned long)peasycap->audio_buffer[k].pgo); - peasycap->audio_buffer[k].pgo = NULL; - peasycap->allocation_audio_page -= 1; - gone++; - } - } - JOM(4, "easyoss_delete(): audio buffers freed: %i pages\n", gone); -#endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ JOM(4, "freeing easycap structure.\n"); allocation_video_urb = peasycap->allocation_video_urb; @@ -913,8 +887,6 @@ static void easycap_delete(struct kref *pkref) allocation_audio_struct = peasycap->allocation_audio_struct; registered_audio = peasycap->registered_audio; - kfree(peasycap); - if (0 <= kd && DONGLE_MANY > kd) { if (mutex_lock_interruptible(&mutex_dongle)) { SAY("ERROR: cannot down mutex_dongle\n"); @@ -929,6 +901,9 @@ static void easycap_delete(struct kref *pkref) } else { SAY("ERROR: cannot purge dongle[].peasycap"); } + + kfree(peasycap); + /*---------------------------------------------------------------------------*/ SAY("%8i=video urbs after all deletions\n", allocation_video_urb); SAY("%8i=video pages after all deletions\n", allocation_video_page); @@ -961,10 +936,6 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; - } if (!peasycap->pusb_device) { SAY("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; @@ -995,11 +966,6 @@ static unsigned int easycap_poll(struct file *file, poll_table *wait) mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -ERESTARTSYS; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ERESTARTSYS; - } if (!peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); @@ -2454,10 +2420,6 @@ static void easycap_vma_open(struct vm_area_struct *pvma) SAY("ERROR: peasycap is NULL\n"); return; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return; - } peasycap->vma_many++; JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); return; @@ -2472,10 +2434,6 @@ static void easycap_vma_close(struct vm_area_struct *pvma) SAY("ERROR: peasycap is NULL\n"); return; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return; - } peasycap->vma_many--; JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); return; @@ -2606,10 +2564,6 @@ static void easycap_complete(struct urb *purb) SAY("ERROR: easycap_complete(): peasycap is NULL\n"); return; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return; - } if (peasycap->video_eof) return; for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) @@ -3000,7 +2954,6 @@ static int easycap_usb_probe(struct usb_interface *intf, struct easycap_format *peasycap_format; int fmtidx; struct inputset *inputset; - struct v4l2_device *pv4l2_device; usbdev = interface_to_usbdev(intf); @@ -3054,7 +3007,6 @@ static int easycap_usb_probe(struct usb_interface *intf, */ /*---------------------------------------------------------------------------*/ peasycap->minor = -1; - strcpy(&peasycap->telltale[0], TELLTALE); kref_init(&peasycap->kref); JOM(8, "intf[%i]: after kref_init(..._video) " "%i=peasycap->kref.refcount.counter\n", @@ -3267,23 +3219,6 @@ static int easycap_usb_probe(struct usb_interface *intf, bInterfaceNumber); return -ENODEV; } -/*---------------------------------------------------------------------------*/ -/* - * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS - * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), - * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. - * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. -*/ -/*---------------------------------------------------------------------------*/ - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - pv4l2_device = usb_get_intfdata(intf); - if (!pv4l2_device) { - SAY("ERROR: pv4l2_device is NULL\n"); - return -ENODEV; - } - peasycap = (struct easycap *) - container_of(pv4l2_device, struct easycap, v4l2_device); - } } /*---------------------------------------------------------------------------*/ if ((USB_CLASS_VIDEO == bInterfaceClass) || @@ -3775,14 +3710,12 @@ static int easycap_usb_probe(struct usb_interface *intf, * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. */ /*--------------------------------------------------------------------------*/ - if (0 != (v4l2_device_register(&(intf->dev), - &(peasycap->v4l2_device)))) { + if (v4l2_device_register(&intf->dev, &peasycap->v4l2_device)) { SAM("v4l2_device_register() failed\n"); return -ENODEV; - } else { - JOM(4, "registered device instance: %s\n", - &(peasycap->v4l2_device.name[0])); } + JOM(4, "registered device instance: %s\n", + peasycap->v4l2_device.name); /*---------------------------------------------------------------------------*/ /* * FIXME @@ -3947,32 +3880,6 @@ static int easycap_usb_probe(struct usb_interface *intf, INIT_LIST_HEAD(&(peasycap->urb_audio_head)); peasycap->purb_audio_head = &(peasycap->urb_audio_head); -#ifdef CONFIG_EASYCAP_OSS - JOM(4, "allocating an audio buffer\n"); - JOM(4, ".... scattered over %i pages\n", - peasycap->audio_buffer_page_many); - - for (k = 0; k < peasycap->audio_buffer_page_many; k++) { - if (peasycap->audio_buffer[k].pgo) { - SAM("ERROR: attempting to reallocate audio buffers\n"); - } else { - pbuf = (void *) __get_free_page(GFP_KERNEL); - if (!pbuf) { - SAM("ERROR: Could not allocate audio " - "buffer page %i\n", k); - return -ENOMEM; - } else - peasycap->allocation_audio_page += 1; - - peasycap->audio_buffer[k].pgo = pbuf; - } - peasycap->audio_buffer[k].pto = peasycap->audio_buffer[k].pgo; - } - - peasycap->audio_fill = 0; - peasycap->audio_read = 0; - JOM(4, "allocation of audio buffer done: %i pages\n", k); -#endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ JOM(4, "allocating %i isoc audio buffers of size %i\n", AUDIO_ISOC_BUFFER_MANY, @@ -4049,11 +3956,7 @@ static int easycap_usb_probe(struct usb_interface *intf, "peasycap->audio_isoc_buffer[.].pgo;\n"); JOM(4, " purb->transfer_buffer_length = %i;\n", peasycap->audio_isoc_buffer_size); -#ifdef CONFIG_EASYCAP_OSS - JOM(4, " purb->complete = easyoss_complete;\n"); -#else /* CONFIG_EASYCAP_OSS */ JOM(4, " purb->complete = easycap_alsa_complete;\n"); -#endif /* CONFIG_EASYCAP_OSS */ JOM(4, " purb->context = peasycap;\n"); JOM(4, " purb->start_frame = 0;\n"); JOM(4, " purb->number_of_packets = %i;\n", @@ -4076,11 +3979,7 @@ static int easycap_usb_probe(struct usb_interface *intf, purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo; purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; -#ifdef CONFIG_EASYCAP_OSS - purb->complete = easyoss_complete; -#else /* CONFIG_EASYCAP_OSS */ purb->complete = easycap_alsa_complete; -#endif /* CONFIG_EASYCAP_OSS */ purb->context = peasycap; purb->start_frame = 0; purb->number_of_packets = peasycap->audio_isoc_framesperdesc; @@ -4103,7 +4002,6 @@ static int easycap_usb_probe(struct usb_interface *intf, * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. */ /*---------------------------------------------------------------------------*/ -#ifndef CONFIG_EASYCAP_OSS JOM(4, "initializing ALSA card\n"); rc = easycap_alsa_probe(peasycap); @@ -4112,15 +4010,6 @@ static int easycap_usb_probe(struct usb_interface *intf, return -ENODEV; } -#else /* CONFIG_EASYCAP_OSS */ - rc = usb_register_dev(intf, &easyoss_class); - if (rc) { - SAY("ERROR: usb_register_dev() failed\n"); - usb_set_intfdata(intf, NULL); - return -ENODEV; - } - SAM("easyoss attached to minor #%d\n", intf->minor); -#endif /* CONFIG_EASYCAP_OSS */ JOM(8, "kref_get() with %i=kref.refcount.counter\n", peasycap->kref.refcount.counter); @@ -4146,7 +4035,7 @@ static int easycap_usb_probe(struct usb_interface *intf, * WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY * UNPLUGGED. HENCE peasycap->pusb_device IS NO LONGER VALID. * - * THIS FUNCTION AFFECTS BOTH OSS AND ALSA. BEWARE. + * THIS FUNCTION AFFECTS ALSA. BEWARE. */ /*---------------------------------------------------------------------------*/ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) @@ -4159,7 +4048,6 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) struct list_head *plist_head; struct data_urb *pdata_urb; int minor, m, kd; - struct v4l2_device *pv4l2_device; JOT(4, "\n"); @@ -4186,29 +4074,6 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) return; } /*---------------------------------------------------------------------------*/ -/* - * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS - * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), - * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. - * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. -*/ -/*---------------------------------------------------------------------------*/ - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - pv4l2_device = usb_get_intfdata(pusb_interface); - if (!pv4l2_device) { - SAY("ERROR: pv4l2_device is NULL\n"); - return; - } - peasycap = (struct easycap *) - container_of(pv4l2_device, struct easycap, v4l2_device); - } -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*---------------------------------------------------------------------------*/ - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return; - } -/*---------------------------------------------------------------------------*/ /* * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE. */ @@ -4321,19 +4186,12 @@ static void easycap_usb_disconnect(struct usb_interface *pusb_interface) JOM(4, "locked dongle[%i].mutex_audio\n", kd); } else SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); -#ifndef CONFIG_EASYCAP_OSS if (0 != snd_card_free(peasycap->psnd_card)) { SAY("ERROR: snd_card_free() failed\n"); } else { peasycap->psnd_card = NULL; (peasycap->registered_audio)--; } -#else /* CONFIG_EASYCAP_OSS */ - usb_deregister_dev(pusb_interface, &easyoss_class); - peasycap->registered_audio--; - JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); - SAM("easyoss detached from minor #%d\n", minor); -#endif /* CONFIG_EASYCAP_OSS */ if (0 <= kd && DONGLE_MANY > kd) { mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); JOM(4, "unlocked dongle[%i].mutex_audio\n", kd); diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c index 898559dad704..70f59b13c34d 100644 --- a/drivers/staging/easycap/easycap_settings.c +++ b/drivers/staging/easycap/easycap_settings.c @@ -567,7 +567,7 @@ int fillin_formats(void) default: return -3; } - bytesperline = width * ((mask3 & 0x00F0) >> 4); + bytesperline = width * ((mask3 & 0x00E0) >> 5); sizeimage = bytesperline * height; for (m = 0; m < INTERLACE_MANY; m++) { diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index a3402b00a8be..213d0400b3ee 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -30,7 +30,6 @@ #include "easycap.h" -#ifndef CONFIG_EASYCAP_OSS /*--------------------------------------------------------------------------*/ /* * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE @@ -92,10 +91,6 @@ easycap_alsa_complete(struct urb *purb) SAY("ERROR: peasycap is NULL\n"); return; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return; - } much = 0; if (peasycap->audio_idle) { JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", @@ -310,10 +305,6 @@ static int easycap_alsa_open(struct snd_pcm_substream *pss) SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; - } if (peasycap->psnd_card != psnd_card) { SAM("ERROR: bad peasycap->psnd_card\n"); return -EFAULT; @@ -350,10 +341,6 @@ static int easycap_alsa_close(struct snd_pcm_substream *pss) SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; - } pss->private_data = NULL; peasycap->psubstream = NULL; JOT(4, "ending successfully\n"); @@ -441,10 +428,6 @@ static int easycap_alsa_prepare(struct snd_pcm_substream *pss) SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; - } JOM(16, "ALSA decides %8i Hz=rate\n", pss->runtime->rate); JOM(16, "ALSA decides %8ld =period_size\n", pss->runtime->period_size); @@ -488,11 +471,6 @@ static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; - } - switch (cmd) { case SNDRV_PCM_TRIGGER_START: { peasycap->audio_idle = 0; @@ -523,10 +501,6 @@ static snd_pcm_uframes_t easycap_alsa_pointer(struct snd_pcm_substream *pss) SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; - } if ((0 != peasycap->audio_eof) || (0 != peasycap->audio_idle)) { JOM(8, "returning -EIO because " "%i=audio_idle %i=audio_eof\n", @@ -584,10 +558,6 @@ int easycap_alsa_probe(struct easycap *peasycap) SAY("ERROR: peasycap is NULL\n"); return -ENODEV; } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; - } if (0 > peasycap->minor) { SAY("ERROR: no minor\n"); return -ENODEV; @@ -644,7 +614,6 @@ int easycap_alsa_probe(struct easycap *peasycap) SAM("registered %s\n", &psnd_card->id[0]); return 0; } -#endif /*! CONFIG_EASYCAP_OSS */ /*****************************************************************************/ /*****************************************************************************/ @@ -762,11 +731,7 @@ submit_audio_urbs(struct easycap *peasycap) purb->transfer_flags = URB_ISO_ASAP; purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo; purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; -#ifdef CONFIG_EASYCAP_OSS - purb->complete = easyoss_complete; -#else /* CONFIG_EASYCAP_OSS */ purb->complete = easycap_alsa_complete; -#endif /* CONFIG_EASYCAP_OSS */ purb->context = peasycap; purb->start_frame = 0; purb->number_of_packets = peasycap->audio_isoc_framesperdesc; diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c deleted file mode 100644 index d92baf222765..000000000000 --- a/drivers/staging/easycap/easycap_sound_oss.c +++ /dev/null @@ -1,954 +0,0 @@ -/****************************************************************************** -* * -* easycap_sound.c * -* * -* Audio driver for EasyCAP USB2.0 Video Capture Device DC60 * -* * -* * -******************************************************************************/ -/* - * - * Copyright (C) 2010 R.M. Thomas - * - * - * This 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. - * - * The software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ -/*****************************************************************************/ - -#include "easycap.h" - -/*****************************************************************************/ -/**************************** **************************/ -/**************************** Open Sound System **************************/ -/**************************** **************************/ -/*****************************************************************************/ -/*--------------------------------------------------------------------------*/ -/* - * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE - */ -/*--------------------------------------------------------------------------*/ -/*****************************************************************************/ -/*---------------------------------------------------------------------------*/ -/* - * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS - * PROVIDED peasycap->audio_idle IS ZERO. REGARDLESS OF THIS BEING TRUE, - * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO. - */ -/*---------------------------------------------------------------------------*/ -void -easyoss_complete(struct urb *purb) -{ - struct easycap *peasycap; - struct data_buffer *paudio_buffer; - u8 *p1, *p2; - s16 tmp; - int i, j, more, much, leap, rc; -#ifdef UPSAMPLE - int k; - s16 oldaudio, newaudio, delta; -#endif /*UPSAMPLE*/ - - JOT(16, "\n"); - - if (!purb) { - SAY("ERROR: purb is NULL\n"); - return; - } - peasycap = purb->context; - if (!peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; - } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return; - } - much = 0; - if (peasycap->audio_idle) { - JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", - peasycap->audio_idle, peasycap->audio_isoc_streaming); - if (peasycap->audio_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (rc) { - if (-ENODEV != rc && -ENOENT != rc) { - SAM("ERROR: while %i=audio_idle, " - "usb_submit_urb() failed with rc: -%s: %d\n", - peasycap->audio_idle, - strerror(rc), rc); - } - } - } - return; - } -/*---------------------------------------------------------------------------*/ - if (purb->status) { - if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { - JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); - return; - } - SAM("ERROR: non-zero urb status: -%s: %d\n", - strerror(purb->status), purb->status); - goto resubmit; - } -/*---------------------------------------------------------------------------*/ -/* - * PROCEED HERE WHEN NO ERROR - */ -/*---------------------------------------------------------------------------*/ -#ifdef UPSAMPLE - oldaudio = peasycap->oldaudio; -#endif /*UPSAMPLE*/ - - for (i = 0; i < purb->number_of_packets; i++) { - if (!purb->iso_frame_desc[i].status) { - - SAM("-%s\n", strerror(purb->iso_frame_desc[i].status)); - - more = purb->iso_frame_desc[i].actual_length; - - if (!more) - peasycap->audio_mt++; - else { - if (peasycap->audio_mt) { - JOM(12, "%4i empty audio urb frames\n", - peasycap->audio_mt); - peasycap->audio_mt = 0; - } - - p1 = (u8 *)(purb->transfer_buffer + purb->iso_frame_desc[i].offset); - - leap = 0; - p1 += leap; - more -= leap; - /* - * COPY more BYTES FROM ISOC BUFFER - * TO AUDIO BUFFER, CONVERTING - * 8-BIT MONO TO 16-BIT SIGNED - * LITTLE-ENDIAN SAMPLES IF NECESSARY - */ - while (more) { - if (0 > more) { - SAM("MISTAKE: more is negative\n"); - return; - } - if (peasycap->audio_buffer_page_many <= peasycap->audio_fill) { - SAM("ERROR: bad peasycap->audio_fill\n"); - return; - } - - paudio_buffer = &peasycap->audio_buffer[peasycap->audio_fill]; - if (PAGE_SIZE < (paudio_buffer->pto - paudio_buffer->pgo)) { - SAM("ERROR: bad paudio_buffer->pto\n"); - return; - } - if (PAGE_SIZE == (paudio_buffer->pto - paudio_buffer->pgo)) { - - paudio_buffer->pto = paudio_buffer->pgo; - (peasycap->audio_fill)++; - if (peasycap->audio_buffer_page_many <= peasycap->audio_fill) - peasycap->audio_fill = 0; - - JOM(8, "bumped peasycap->" - "audio_fill to %i\n", - peasycap->audio_fill); - - paudio_buffer = &peasycap->audio_buffer[peasycap->audio_fill]; - paudio_buffer->pto = paudio_buffer->pgo; - - if (!(peasycap->audio_fill % peasycap->audio_pages_per_fragment)) { - JOM(12, "wakeup call on wq_audio, %i=frag reading %i=fragment fill\n", - (peasycap->audio_read / peasycap->audio_pages_per_fragment), - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); - wake_up_interruptible(&(peasycap->wq_audio)); - } - } - - much = PAGE_SIZE - (int)(paudio_buffer->pto - paudio_buffer->pgo); - - if (!peasycap->microphone) { - if (much > more) - much = more; - - memcpy(paudio_buffer->pto, p1, much); - p1 += much; - more -= much; - } else { -#ifdef UPSAMPLE - if (much % 16) - JOM(8, "MISTAKE? much" - " is not divisible by 16\n"); - if (much > (16 * more)) - much = 16 * more; - p2 = (u8 *)paudio_buffer->pto; - - for (j = 0; j < (much/16); j++) { - newaudio = ((int) *p1) - 128; - newaudio = 128 * newaudio; - - delta = (newaudio - oldaudio) / 4; - tmp = oldaudio + delta; - - for (k = 0; k < 4; k++) { - *p2 = (0x00FF & tmp); - *(p2 + 1) = (0xFF00 & tmp) >> 8; - p2 += 2; - *p2 = (0x00FF & tmp); - *(p2 + 1) = (0xFF00 & tmp) >> 8; - p2 += 2; - - tmp += delta; - } - p1++; - more--; - oldaudio = tmp; - } -#else /*!UPSAMPLE*/ - if (much > (2 * more)) - much = 2 * more; - p2 = (u8 *)paudio_buffer->pto; - - for (j = 0; j < (much / 2); j++) { - tmp = ((int) *p1) - 128; - tmp = 128 * tmp; - *p2 = (0x00FF & tmp); - *(p2 + 1) = (0xFF00 & tmp) >> 8; - p1++; - p2 += 2; - more--; - } -#endif /*UPSAMPLE*/ - } - (paudio_buffer->pto) += much; - } - } - } else { - JOM(12, "discarding audio samples because " - "%i=purb->iso_frame_desc[i].status\n", - purb->iso_frame_desc[i].status); - } - -#ifdef UPSAMPLE - peasycap->oldaudio = oldaudio; -#endif /*UPSAMPLE*/ - - } -/*---------------------------------------------------------------------------*/ -/* - * RESUBMIT THIS URB - */ -/*---------------------------------------------------------------------------*/ -resubmit: - if (peasycap->audio_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (rc) { - if (-ENODEV != rc && -ENOENT != rc) { - SAM("ERROR: while %i=audio_idle, " - "usb_submit_urb() failed " - "with rc: -%s: %d\n", peasycap->audio_idle, - strerror(rc), rc); - } - } - } - return; -} -/*****************************************************************************/ -/*---------------------------------------------------------------------------*/ -/* - * THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO - * STREAM FROM /dev/easyoss1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT - * HAVE AN IOCTL INTERFACE. - */ -/*---------------------------------------------------------------------------*/ -static int easyoss_open(struct inode *inode, struct file *file) -{ - struct usb_interface *pusb_interface; - struct easycap *peasycap; - int subminor; - struct v4l2_device *pv4l2_device; - - JOT(4, "begins\n"); - - subminor = iminor(inode); - - pusb_interface = usb_find_interface(&easycap_usb_driver, subminor); - if (!pusb_interface) { - SAY("ERROR: pusb_interface is NULL\n"); - SAY("ending unsuccessfully\n"); - return -1; - } - peasycap = usb_get_intfdata(pusb_interface); - if (!peasycap) { - SAY("ERROR: peasycap is NULL\n"); - SAY("ending unsuccessfully\n"); - return -1; - } -/*---------------------------------------------------------------------------*/ -/* - * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS - * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), - * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. - * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. -*/ -/*---------------------------------------------------------------------------*/ - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - pv4l2_device = usb_get_intfdata(pusb_interface); - if (!pv4l2_device) { - SAY("ERROR: pv4l2_device is NULL\n"); - return -EFAULT; - } - peasycap = container_of(pv4l2_device, - struct easycap, v4l2_device); - } -/*---------------------------------------------------------------------------*/ - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; - } -/*---------------------------------------------------------------------------*/ - - file->private_data = peasycap; - - if (0 != easycap_sound_setup(peasycap)) { - ; - ; - } - return 0; -} -/*****************************************************************************/ -static int easyoss_release(struct inode *inode, struct file *file) -{ - struct easycap *peasycap; - - JOT(4, "begins\n"); - - peasycap = file->private_data; - if (!peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - return -EFAULT; - } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; - } - if (0 != kill_audio_urbs(peasycap)) { - SAM("ERROR: kill_audio_urbs() failed\n"); - return -EFAULT; - } - JOM(4, "ending successfully\n"); - return 0; -} -/*****************************************************************************/ -static ssize_t easyoss_read(struct file *file, char __user *puserspacebuffer, - size_t kount, loff_t *poff) -{ - struct timeval timeval; - long long int above, below, mean; - struct signed_div_result sdr; - unsigned char *p0; - long int kount1, more, rc, l0, lm; - int fragment, kd; - struct easycap *peasycap; - struct data_buffer *pdata_buffer; - size_t szret; - -/*---------------------------------------------------------------------------*/ -/* - * DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE. - * - ****************************************************************************** - ***** N.B. IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ****** - ***** THIS CONDITION SIGNIFIES END-OF-FILE. ****** - ****************************************************************************** - */ -/*---------------------------------------------------------------------------*/ - - JOT(8, "%5zd=kount %5lld=*poff\n", kount, *poff); - - if (!file) { - SAY("ERROR: file is NULL\n"); - return -ERESTARTSYS; - } - peasycap = file->private_data; - if (!peasycap) { - SAY("ERROR in easyoss_read(): peasycap is NULL\n"); - return -EFAULT; - } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - return -EFAULT; - } - if (!peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; - } - kd = isdongle(peasycap); - if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&(easycapdc60_dongle[kd].mutex_audio))) { - SAY("ERROR: " - "cannot lock dongle[%i].mutex_audio\n", kd); - return -ERESTARTSYS; - } - JOM(4, "locked dongle[%i].mutex_audio\n", kd); - /* - * MEANWHILE, easycap_usb_disconnect() - * MAY HAVE FREED POINTER peasycap, - * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. - * IF NECESSARY, BAIL OUT. - */ - if (kd != isdongle(peasycap)) - return -ERESTARTSYS; - if (!file) { - SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - peasycap = file->private_data; - if (!peasycap) { - SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: %p\n", peasycap); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - if (!peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - } else { - /* - * IF easycap_usb_disconnect() - * HAS ALREADY FREED POINTER peasycap BEFORE THE - * ATTEMPT TO ACQUIRE THE SEMAPHORE, - * isdongle() WILL HAVE FAILED. BAIL OUT. - */ - return -ERESTARTSYS; - } -/*---------------------------------------------------------------------------*/ - JOT(16, "%sBLOCKING kount=%zd, *poff=%lld\n", - (file->f_flags & O_NONBLOCK) ? "NON" : "", kount, *poff); - - if ((0 > peasycap->audio_read) || - (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { - SAM("ERROR: peasycap->audio_read out of range\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; - if (!pdata_buffer) { - SAM("ERROR: pdata_buffer is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(12, "before wait, %i=frag read %i=frag fill\n", - (peasycap->audio_read / peasycap->audio_pages_per_fragment), - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); - fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); - while ((fragment == (peasycap->audio_fill / peasycap->audio_pages_per_fragment)) || - (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) { - if (file->f_flags & O_NONBLOCK) { - JOM(16, "returning -EAGAIN as instructed\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EAGAIN; - } - rc = wait_event_interruptible(peasycap->wq_audio, - (peasycap->audio_idle || peasycap->audio_eof || - ((fragment != - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)) && - (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))))); - if (rc) { - SAM("aborted by signal\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - if (peasycap->audio_eof) { - JOM(8, "returning 0 because %i=audio_eof\n", - peasycap->audio_eof); - kill_audio_urbs(peasycap); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return 0; - } - if (peasycap->audio_idle) { - JOM(16, "returning 0 because %i=audio_idle\n", - peasycap->audio_idle); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return 0; - } - if (!peasycap->audio_isoc_streaming) { - JOM(16, "returning 0 because audio urbs not streaming\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return 0; - } - } - JOM(12, "after wait, %i=frag read %i=frag fill\n", - (peasycap->audio_read / peasycap->audio_pages_per_fragment), - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); - szret = (size_t)0; - fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); - while (fragment == (peasycap->audio_read / peasycap->audio_pages_per_fragment)) { - if (!pdata_buffer->pgo) { - SAM("ERROR: pdata_buffer->pgo is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - if (!pdata_buffer->pto) { - SAM("ERROR: pdata_buffer->pto is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); - if (0 > kount1) { - SAM("MISTAKE: kount1 is negative\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - if (!kount1) { - peasycap->audio_read++; - if (peasycap->audio_buffer_page_many <= peasycap->audio_read) - peasycap->audio_read = 0; - JOM(12, "bumped peasycap->audio_read to %i\n", - peasycap->audio_read); - - if (fragment != (peasycap->audio_read / peasycap->audio_pages_per_fragment)) - break; - - if ((0 > peasycap->audio_read) || - (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { - SAM("ERROR: peasycap->audio_read out of range\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; - if (!pdata_buffer) { - SAM("ERROR: pdata_buffer is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - if (!pdata_buffer->pgo) { - SAM("ERROR: pdata_buffer->pgo is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - if (!pdata_buffer->pto) { - SAM("ERROR: pdata_buffer->pto is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); - } - JOM(12, "ready to send %zd bytes\n", kount1); - JOM(12, "still to send %li bytes\n", (long int) kount); - more = kount1; - if (more > kount) - more = kount; - JOM(12, "agreed to send %li bytes from page %i\n", - more, peasycap->audio_read); - if (!more) - break; - - /* - * ACCUMULATE DYNAMIC-RANGE INFORMATION - */ - p0 = (unsigned char *)pdata_buffer->pgo; - l0 = 0; - lm = more/2; - while (l0 < lm) { - SUMMER(p0, &peasycap->audio_sample, - &peasycap->audio_niveau, - &peasycap->audio_square); - l0++; - p0 += 2; - } - /*-----------------------------------------------------------*/ - rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more); - if (rc) { - SAM("ERROR: copy_to_user() returned %li\n", rc); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - *poff += (loff_t)more; - szret += (size_t)more; - pdata_buffer->pto += more; - puserspacebuffer += more; - kount -= (size_t)more; - } - JOM(12, "after read, %i=frag read %i=frag fill\n", - (peasycap->audio_read / peasycap->audio_pages_per_fragment), - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); - if (kount < 0) { - SAM("MISTAKE: %li=kount %li=szret\n", - (long int)kount, (long int)szret); - } -/*---------------------------------------------------------------------------*/ -/* - * CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL - */ -/*---------------------------------------------------------------------------*/ - if (peasycap->audio_sample) { - below = peasycap->audio_sample; - above = peasycap->audio_square; - sdr = signed_div(above, below); - above = sdr.quotient; - mean = peasycap->audio_niveau; - sdr = signed_div(mean, peasycap->audio_sample); - - JOM(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", - sdr.quotient, above, peasycap->audio_sample); - - sdr = signed_div(above, 32768); - JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient); - } -/*---------------------------------------------------------------------------*/ -/* - * UPDATE THE AUDIO CLOCK - */ -/*---------------------------------------------------------------------------*/ - do_gettimeofday(&timeval); - if (!peasycap->timeval1.tv_sec) { - peasycap->audio_bytes = 0; - peasycap->timeval3 = timeval; - peasycap->timeval1 = peasycap->timeval3; - sdr.quotient = 192000; - } else { - peasycap->audio_bytes += (long long int) szret; - below = ((long long int)(1000000)) * - ((long long int)(timeval.tv_sec - peasycap->timeval3.tv_sec)) + - (long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec); - above = 1000000 * ((long long int) peasycap->audio_bytes); - - if (below) - sdr = signed_div(above, below); - else - sdr.quotient = 192000; - } - JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient); - peasycap->dnbydt = sdr.quotient; - - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd); - JOM(8, "returning %li\n", (long int)szret); - return szret; - -} -/*---------------------------------------------------------------------------*/ -static long easyoss_unlocked_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct easycap *peasycap; - struct usb_device *p; - int kd; - - if (!file) { - SAY("ERROR: file is NULL\n"); - return -ERESTARTSYS; - } - peasycap = file->private_data; - if (!peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - return -EFAULT; - } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; - } - p = peasycap->pusb_device; - if (!p) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; - } - kd = isdongle(peasycap); - if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { - SAY("ERROR: cannot lock " - "easycapdc60_dongle[%i].mutex_audio\n", kd); - return -ERESTARTSYS; - } - JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); - /* - * MEANWHILE, easycap_usb_disconnect() - * MAY HAVE FREED POINTER peasycap, - * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. - * IF NECESSARY, BAIL OUT. - */ - if (kd != isdongle(peasycap)) - return -ERESTARTSYS; - if (!file) { - SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - peasycap = file->private_data; - if (!peasycap) { - SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - p = peasycap->pusb_device; - if (!peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - } else { - /* - * IF easycap_usb_disconnect() - * HAS ALREADY FREED POINTER peasycap BEFORE THE - * ATTEMPT TO ACQUIRE THE SEMAPHORE, - * isdongle() WILL HAVE FAILED. BAIL OUT. - */ - return -ERESTARTSYS; - } -/*---------------------------------------------------------------------------*/ - switch (cmd) { - case SNDCTL_DSP_GETCAPS: { - int caps; - JOM(8, "SNDCTL_DSP_GETCAPS\n"); - -#ifdef UPSAMPLE - if (peasycap->microphone) - caps = 0x04400000; - else - caps = 0x04400000; -#else - if (peasycap->microphone) - caps = 0x02400000; - else - caps = 0x04400000; -#endif /*UPSAMPLE*/ - - if (copy_to_user((void __user *)arg, &caps, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; - } - case SNDCTL_DSP_GETFMTS: { - int incoming; - JOM(8, "SNDCTL_DSP_GETFMTS\n"); - -#ifdef UPSAMPLE - if (peasycap->microphone) - incoming = AFMT_S16_LE; - else - incoming = AFMT_S16_LE; -#else - if (peasycap->microphone) - incoming = AFMT_S16_LE; - else - incoming = AFMT_S16_LE; -#endif /*UPSAMPLE*/ - - if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; - } - case SNDCTL_DSP_SETFMT: { - int incoming, outgoing; - JOM(8, "SNDCTL_DSP_SETFMT\n"); - if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - -#ifdef UPSAMPLE - if (peasycap->microphone) - outgoing = AFMT_S16_LE; - else - outgoing = AFMT_S16_LE; -#else - if (peasycap->microphone) - outgoing = AFMT_S16_LE; - else - outgoing = AFMT_S16_LE; -#endif /*UPSAMPLE*/ - - if (incoming != outgoing) { - JOM(8, "........... %i=outgoing\n", outgoing); - JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE); - JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8); - if (copy_to_user((void __user *)arg, &outgoing, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EINVAL ; - } - break; - } - case SNDCTL_DSP_STEREO: { - int incoming; - JOM(8, "SNDCTL_DSP_STEREO\n"); - if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - -#ifdef UPSAMPLE - if (peasycap->microphone) - incoming = 1; - else - incoming = 1; -#else - if (peasycap->microphone) - incoming = 0; - else - incoming = 1; -#endif /*UPSAMPLE*/ - - if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; - } - case SNDCTL_DSP_SPEED: { - int incoming; - JOM(8, "SNDCTL_DSP_SPEED\n"); - if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - -#ifdef UPSAMPLE - if (peasycap->microphone) - incoming = 32000; - else - incoming = 48000; -#else - if (peasycap->microphone) - incoming = 8000; - else - incoming = 48000; -#endif /*UPSAMPLE*/ - - if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; - } - case SNDCTL_DSP_GETTRIGGER: { - int incoming; - JOM(8, "SNDCTL_DSP_GETTRIGGER\n"); - if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - - incoming = PCM_ENABLE_INPUT; - if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; - } - case SNDCTL_DSP_SETTRIGGER: { - int incoming; - JOM(8, "SNDCTL_DSP_SETTRIGGER\n"); - if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " - "0x%x=PCM_ENABLE_OUTPUT\n", - PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT); - ; - ; - ; - ; - break; - } - case SNDCTL_DSP_GETBLKSIZE: { - int incoming; - JOM(8, "SNDCTL_DSP_GETBLKSIZE\n"); - if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - incoming = peasycap->audio_bytes_per_fragment; - if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; - } - case SNDCTL_DSP_GETISPACE: { - struct audio_buf_info audio_buf_info; - - JOM(8, "SNDCTL_DSP_GETISPACE\n"); - - audio_buf_info.bytes = peasycap->audio_bytes_per_fragment; - audio_buf_info.fragments = 1; - audio_buf_info.fragsize = 0; - audio_buf_info.fragstotal = 0; - - if (copy_to_user((void __user *)arg, &audio_buf_info, sizeof(int))) { - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -EFAULT; - } - break; - } - case 0x00005401: - case 0x00005402: - case 0x00005403: - case 0x00005404: - case 0x00005405: - case 0x00005406: { - JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ENOIOCTLCMD; - } - default: { - JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return -ENOIOCTLCMD; - } - } - mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); - return 0; -} -/*****************************************************************************/ - -static const struct file_operations easyoss_fops = { - .owner = THIS_MODULE, - .open = easyoss_open, - .release = easyoss_release, - .unlocked_ioctl = easyoss_unlocked_ioctl, - .read = easyoss_read, - .llseek = no_llseek, -}; -struct usb_class_driver easyoss_class = { - .name = "usb/easyoss%d", - .fops = &easyoss_fops, - .minor_base = USB_SKEL_MINOR_BASE, -}; -/*****************************************************************************/ diff --git a/drivers/staging/echo/echo.c b/drivers/staging/echo/echo.c index c0adae1bf6d3..afbf5442b42b 100644 --- a/drivers/staging/echo/echo.c +++ b/drivers/staging/echo/echo.c @@ -276,7 +276,6 @@ struct oslec_state *oslec_create(int len, int adaption_mode) kfree(ec); return NULL; } - EXPORT_SYMBOL_GPL(oslec_create); void oslec_free(struct oslec_state *ec) @@ -290,14 +289,12 @@ void oslec_free(struct oslec_state *ec) kfree(ec->snapshot); kfree(ec); } - EXPORT_SYMBOL_GPL(oslec_free); void oslec_adaption_mode(struct oslec_state *ec, int adaption_mode) { ec->adaption_mode = adaption_mode; } - EXPORT_SYMBOL_GPL(oslec_adaption_mode); void oslec_flush(struct oslec_state *ec) @@ -324,14 +321,12 @@ void oslec_flush(struct oslec_state *ec) ec->curr_pos = ec->taps - 1; ec->Pstates = 0; } - EXPORT_SYMBOL_GPL(oslec_flush); void oslec_snapshot(struct oslec_state *ec) { memcpy(ec->snapshot, ec->fir_taps16[0], ec->taps * sizeof(int16_t)); } - EXPORT_SYMBOL_GPL(oslec_snapshot); /* Dual Path Echo Canceller */ @@ -406,7 +401,7 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx) /* efficient "out with the old and in with the new" algorithm so we don't have to recalculate over the whole block of samples. */ - new = (int)tx *(int)tx; + new = (int)tx * (int)tx; old = (int)ec->fir_state.history[ec->fir_state.curr_pos] * (int)ec->fir_state.history[ec->fir_state.curr_pos]; ec->Pstates += @@ -603,7 +598,6 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx) return (int16_t) ec->clean_nlp << 1; } - EXPORT_SYMBOL_GPL(oslec_update); /* This function is separated from the echo canceller is it is usually called @@ -628,7 +622,7 @@ EXPORT_SYMBOL_GPL(oslec_update); giving very clean DC removal. */ -int16_t oslec_hpf_tx(struct oslec_state * ec, int16_t tx) +int16_t oslec_hpf_tx(struct oslec_state *ec, int16_t tx) { int tmp, tmp1; @@ -657,7 +651,6 @@ int16_t oslec_hpf_tx(struct oslec_state * ec, int16_t tx) return tx; } - EXPORT_SYMBOL_GPL(oslec_hpf_tx); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h index 425e9274f28a..410677ee22b7 100644 --- a/drivers/staging/et131x/et1310_address_map.h +++ b/drivers/staging/et131x/et1310_address_map.h @@ -267,19 +267,19 @@ struct txdma_regs { /* Location: */ u32 service_complete; /* 0x1028 */ u32 cache_rd_index; /* 0x102C */ u32 cache_wr_index; /* 0x1030 */ - u32 TxDmaError; /* 0x1034 */ - u32 DescAbortCount; /* 0x1038 */ - u32 PayloadAbortCnt; /* 0x103c */ - u32 WriteBackAbortCnt; /* 0x1040 */ - u32 DescTimeoutCnt; /* 0x1044 */ - u32 PayloadTimeoutCnt; /* 0x1048 */ - u32 WriteBackTimeoutCnt; /* 0x104c */ - u32 DescErrorCount; /* 0x1050 */ - u32 PayloadErrorCnt; /* 0x1054 */ - u32 WriteBackErrorCnt; /* 0x1058 */ - u32 DroppedTLPCount; /* 0x105c */ - u32 NewServiceComplete; /* 0x1060 */ - u32 EthernetPacketCount; /* 0x1064 */ + u32 tx_dma_error; /* 0x1034 */ + u32 desc_abort_cnt; /* 0x1038 */ + u32 payload_abort_cnt; /* 0x103c */ + u32 writeback_abort_cnt; /* 0x1040 */ + u32 desc_timeout_cnt; /* 0x1044 */ + u32 payload_timeout_cnt; /* 0x1048 */ + u32 writeback_timeout_cnt; /* 0x104c */ + u32 desc_error_cnt; /* 0x1050 */ + u32 payload_error_cnt; /* 0x1054 */ + u32 writeback_error_cnt; /* 0x1058 */ + u32 dropped_tlp_cnt; /* 0x105c */ + u32 new_service_complete; /* 0x1060 */ + u32 ethernet_packet_cnt; /* 0x1064 */ }; /* END OF TXDMA REGISTER ADDRESS MAP */ @@ -700,42 +700,27 @@ struct txmac_regs { /* Location: */ /* * structure for Wake On Lan Source Address Lo reg in rxmac address map * located at address 0x4010 + * + * 31-24: sa3 + * 23-16: sa4 + * 15-8: sa5 + * 7-0: sa6 */ -typedef union _RXMAC_WOL_SA_LO_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 sa3:8; /* bits 24-31 */ - u32 sa4:8; /* bits 16-23 */ - u32 sa5:8; /* bits 8-15 */ - u32 sa6:8; /* bits 0-7 */ -#else - u32 sa6:8; /* bits 0-7 */ - u32 sa5:8; /* bits 8-15 */ - u32 sa4:8; /* bits 16-23 */ - u32 sa3:8; /* bits 24-31 */ -#endif - } bits; -} RXMAC_WOL_SA_LO_t, *PRXMAC_WOL_SA_LO_t; + +#define ET_WOL_LO_SA3_SHIFT 24 +#define ET_WOL_LO_SA4_SHIFT 16 +#define ET_WOL_LO_SA5_SHIFT 8 /* * structure for Wake On Lan Source Address Hi reg in rxmac address map * located at address 0x4014 + * + * 31-16: reserved + * 15-8: sa1 + * 7-0: sa2 */ -typedef union _RXMAC_WOL_SA_HI_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 reserved:16; /* bits 16-31 */ - u32 sa1:8; /* bits 8-15 */ - u32 sa2:8; /* bits 0-7 */ -#else - u32 sa2:8; /* bits 0-7 */ - u32 sa1:8; /* bits 8-15 */ - u32 reserved:16; /* bits 16-31 */ -#endif - } bits; -} RXMAC_WOL_SA_HI_t, *PRXMAC_WOL_SA_HI_t; + +#define ET_WOL_HI_SA1_SHIFT 8 /* * structure for Wake On Lan mask reg in rxmac address map @@ -746,65 +731,45 @@ typedef union _RXMAC_WOL_SA_HI_t { /* * structure for Unicast Paket Filter Address 1 reg in rxmac address map * located at address 0x4068 + * + * 31-24: addr1_3 + * 23-16: addr1_4 + * 15-8: addr1_5 + * 7-0: addr1_6 */ -typedef union _RXMAC_UNI_PF_ADDR1_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 addr1_3:8; /* bits 24-31 */ - u32 addr1_4:8; /* bits 16-23 */ - u32 addr1_5:8; /* bits 8-15 */ - u32 addr1_6:8; /* bits 0-7 */ -#else - u32 addr1_6:8; /* bits 0-7 */ - u32 addr1_5:8; /* bits 8-15 */ - u32 addr1_4:8; /* bits 16-23 */ - u32 addr1_3:8; /* bits 24-31 */ -#endif - } bits; -} RXMAC_UNI_PF_ADDR1_t, *PRXMAC_UNI_PF_ADDR1_t; + +#define ET_UNI_PF_ADDR1_3_SHIFT 24 +#define ET_UNI_PF_ADDR1_4_SHIFT 16 +#define ET_UNI_PF_ADDR1_5_SHIFT 8 /* * structure for Unicast Paket Filter Address 2 reg in rxmac address map * located at address 0x406C + * + * 31-24: addr2_3 + * 23-16: addr2_4 + * 15-8: addr2_5 + * 7-0: addr2_6 */ -typedef union _RXMAC_UNI_PF_ADDR2_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 addr2_3:8; /* bits 24-31 */ - u32 addr2_4:8; /* bits 16-23 */ - u32 addr2_5:8; /* bits 8-15 */ - u32 addr2_6:8; /* bits 0-7 */ -#else - u32 addr2_6:8; /* bits 0-7 */ - u32 addr2_5:8; /* bits 8-15 */ - u32 addr2_4:8; /* bits 16-23 */ - u32 addr2_3:8; /* bits 24-31 */ -#endif - } bits; -} RXMAC_UNI_PF_ADDR2_t, *PRXMAC_UNI_PF_ADDR2_t; + +#define ET_UNI_PF_ADDR2_3_SHIFT 24 +#define ET_UNI_PF_ADDR2_4_SHIFT 16 +#define ET_UNI_PF_ADDR2_5_SHIFT 8 /* * structure for Unicast Paket Filter Address 1 & 2 reg in rxmac address map * located at address 0x4070 + * + * 31-24: addr2_1 + * 23-16: addr2_2 + * 15-8: addr1_1 + * 7-0: addr1_2 */ -typedef union _RXMAC_UNI_PF_ADDR3_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 addr2_1:8; /* bits 24-31 */ - u32 addr2_2:8; /* bits 16-23 */ - u32 addr1_1:8; /* bits 8-15 */ - u32 addr1_2:8; /* bits 0-7 */ -#else - u32 addr1_2:8; /* bits 0-7 */ - u32 addr1_1:8; /* bits 8-15 */ - u32 addr2_2:8; /* bits 16-23 */ - u32 addr2_1:8; /* bits 24-31 */ -#endif - } bits; -} RXMAC_UNI_PF_ADDR3_t, *PRXMAC_UNI_PF_ADDR3_t; + +#define ET_UNI_PF_ADDR2_1_SHIFT 24 +#define ET_UNI_PF_ADDR2_2_SHIFT 16 +#define ET_UNI_PF_ADDR1_1_SHIFT 8 + /* * structure for Multicast Hash reg in rxmac address map @@ -888,13 +853,13 @@ typedef union _RXMAC_UNI_PF_ADDR3_t { /* * Rx MAC Module of JAGCore Address Mapping */ -typedef struct _RXMAC_t { /* Location: */ +struct rxmac_regs { /* Location: */ u32 ctrl; /* 0x4000 */ u32 crc0; /* 0x4004 */ u32 crc12; /* 0x4008 */ u32 crc34; /* 0x400C */ - RXMAC_WOL_SA_LO_t sa_lo; /* 0x4010 */ - RXMAC_WOL_SA_HI_t sa_hi; /* 0x4014 */ + u32 sa_lo; /* 0x4010 */ + u32 sa_hi; /* 0x4014 */ u32 mask0_word0; /* 0x4018 */ u32 mask0_word1; /* 0x401C */ u32 mask0_word2; /* 0x4020 */ @@ -915,9 +880,9 @@ typedef struct _RXMAC_t { /* Location: */ u32 mask4_word1; /* 0x405C */ u32 mask4_word2; /* 0x4060 */ u32 mask4_word3; /* 0x4064 */ - RXMAC_UNI_PF_ADDR1_t uni_pf_addr1; /* 0x4068 */ - RXMAC_UNI_PF_ADDR2_t uni_pf_addr2; /* 0x406C */ - RXMAC_UNI_PF_ADDR3_t uni_pf_addr3; /* 0x4070 */ + u32 uni_pf_addr1; /* 0x4068 */ + u32 uni_pf_addr2; /* 0x406C */ + u32 uni_pf_addr3; /* 0x4070 */ u32 multi_hash1; /* 0x4074 */ u32 multi_hash2; /* 0x4078 */ u32 multi_hash3; /* 0x407C */ @@ -930,7 +895,7 @@ typedef struct _RXMAC_t { /* Location: */ u32 mif_ctrl; /* 0x4098 */ u32 err_reg; /* 0x409C */ -} RXMAC_t, *PRXMAC_t; +}; /* END OF RXMAC REGISTER ADDRESS MAP */ @@ -1123,47 +1088,33 @@ typedef struct _RXMAC_t { /* Location: */ /* * structure for Mac Station Address, Part 1 reg in mac address map. * located at address 0x5040 + * + * 31-24: Octet6 + * 23-16: Octet5 + * 15-8: Octet4 + * 7-0: Octet3 */ -typedef union _MAC_STATION_ADDR1_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 Octet6:8; /* bits 24-31 */ - u32 Octet5:8; /* bits 16-23 */ - u32 Octet4:8; /* bits 8-15 */ - u32 Octet3:8; /* bits 0-7 */ -#else - u32 Octet3:8; /* bits 0-7 */ - u32 Octet4:8; /* bits 8-15 */ - u32 Octet5:8; /* bits 16-23 */ - u32 Octet6:8; /* bits 24-31 */ -#endif - } bits; -} MAC_STATION_ADDR1_t, *PMAC_STATION_ADDR1_t; + +#define ET_MAC_STATION_ADDR1_OC6_SHIFT 24 +#define ET_MAC_STATION_ADDR1_OC5_SHIFT 16 +#define ET_MAC_STATION_ADDR1_OC4_SHIFT 8 /* * structure for Mac Station Address, Part 2 reg in mac address map. * located at address 0x5044 + * + * 31-24: Octet2 + * 23-16: Octet1 + * 15-0: reserved */ -typedef union _MAC_STATION_ADDR2_t { - u32 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u32 Octet2:8; /* bits 24-31 */ - u32 Octet1:8; /* bits 16-23 */ - u32 reserved:16; /* bits 0-15 */ -#else - u32 reserved:16; /* bit 0-15 */ - u32 Octet1:8; /* bits 16-23 */ - u32 Octet2:8; /* bits 24-31 */ -#endif - } bits; -} MAC_STATION_ADDR2_t, *PMAC_STATION_ADDR2_t; + +#define ET_MAC_STATION_ADDR2_OC2_SHIFT 24 +#define ET_MAC_STATION_ADDR2_OC1_SHIFT 16 /* * MAC Module of JAGCore Address Mapping */ -typedef struct _MAC_t { /* Location: */ +struct mac_regs { /* Location: */ u32 cfg1; /* 0x5000 */ u32 cfg2; /* 0x5004 */ u32 ipg; /* 0x5008 */ @@ -1180,9 +1131,9 @@ typedef struct _MAC_t { /* Location: */ u32 mii_mgmt_indicator; /* 0x5034 */ u32 if_ctrl; /* 0x5038 */ u32 if_stat; /* 0x503C */ - MAC_STATION_ADDR1_t station_addr_1; /* 0x5040 */ - MAC_STATION_ADDR2_t station_addr_2; /* 0x5044 */ -} MAC_t, *PMAC_t; + u32 station_addr_1; /* 0x5040 */ + u32 station_addr_2; /* 0x5044 */ +}; /* END OF MAC REGISTER ADDRESS MAP */ @@ -1253,148 +1204,148 @@ struct macstat_regs { /* Location: */ u32 pad[32]; /* 0x6000 - 607C */ /* Tx/Rx 0-64 Byte Frame Counter */ - u32 TR64; /* 0x6080 */ + u32 txrx_0_64_byte_frames; /* 0x6080 */ /* Tx/Rx 65-127 Byte Frame Counter */ - u32 TR127; /* 0x6084 */ + u32 txrx_65_127_byte_frames; /* 0x6084 */ /* Tx/Rx 128-255 Byte Frame Counter */ - u32 TR255; /* 0x6088 */ + u32 txrx_128_255_byte_frames; /* 0x6088 */ /* Tx/Rx 256-511 Byte Frame Counter */ - u32 TR511; /* 0x608C */ + u32 txrx_256_511_byte_frames; /* 0x608C */ /* Tx/Rx 512-1023 Byte Frame Counter */ - u32 TR1K; /* 0x6090 */ + u32 txrx_512_1023_byte_frames; /* 0x6090 */ /* Tx/Rx 1024-1518 Byte Frame Counter */ - u32 TRMax; /* 0x6094 */ + u32 txrx_1024_1518_byte_frames; /* 0x6094 */ /* Tx/Rx 1519-1522 Byte Good VLAN Frame Count */ - u32 TRMgv; /* 0x6098 */ + u32 txrx_1519_1522_gvln_frames; /* 0x6098 */ /* Rx Byte Counter */ - u32 RByt; /* 0x609C */ + u32 rx_bytes; /* 0x609C */ /* Rx Packet Counter */ - u32 RPkt; /* 0x60A0 */ + u32 rx_packets; /* 0x60A0 */ /* Rx FCS Error Counter */ - u32 RFcs; /* 0x60A4 */ + u32 rx_fcs_errs; /* 0x60A4 */ /* Rx Multicast Packet Counter */ - u32 RMca; /* 0x60A8 */ + u32 rx_multicast_packets; /* 0x60A8 */ /* Rx Broadcast Packet Counter */ - u32 RBca; /* 0x60AC */ + u32 rx_broadcast_packets; /* 0x60AC */ /* Rx Control Frame Packet Counter */ - u32 RxCf; /* 0x60B0 */ + u32 rx_control_frames; /* 0x60B0 */ /* Rx Pause Frame Packet Counter */ - u32 RxPf; /* 0x60B4 */ + u32 rx_pause_frames; /* 0x60B4 */ /* Rx Unknown OP Code Counter */ - u32 RxUo; /* 0x60B8 */ + u32 rx_unknown_opcodes; /* 0x60B8 */ /* Rx Alignment Error Counter */ - u32 RAln; /* 0x60BC */ + u32 rx_align_errs; /* 0x60BC */ /* Rx Frame Length Error Counter */ - u32 RFlr; /* 0x60C0 */ + u32 rx_frame_len_errs; /* 0x60C0 */ /* Rx Code Error Counter */ - u32 RCde; /* 0x60C4 */ + u32 rx_code_errs; /* 0x60C4 */ /* Rx Carrier Sense Error Counter */ - u32 RCse; /* 0x60C8 */ + u32 rx_carrier_sense_errs; /* 0x60C8 */ /* Rx Undersize Packet Counter */ - u32 RUnd; /* 0x60CC */ + u32 rx_undersize_packets; /* 0x60CC */ /* Rx Oversize Packet Counter */ - u32 ROvr; /* 0x60D0 */ + u32 rx_oversize_packets; /* 0x60D0 */ /* Rx Fragment Counter */ - u32 RFrg; /* 0x60D4 */ + u32 rx_fragment_packets; /* 0x60D4 */ /* Rx Jabber Counter */ - u32 RJbr; /* 0x60D8 */ + u32 rx_jabbers; /* 0x60D8 */ /* Rx Drop */ - u32 RDrp; /* 0x60DC */ + u32 rx_drops; /* 0x60DC */ /* Tx Byte Counter */ - u32 TByt; /* 0x60E0 */ + u32 tx_bytes; /* 0x60E0 */ /* Tx Packet Counter */ - u32 TPkt; /* 0x60E4 */ + u32 tx_packets; /* 0x60E4 */ /* Tx Multicast Packet Counter */ - u32 TMca; /* 0x60E8 */ + u32 tx_multicast_packets; /* 0x60E8 */ /* Tx Broadcast Packet Counter */ - u32 TBca; /* 0x60EC */ + u32 tx_broadcast_packets; /* 0x60EC */ /* Tx Pause Control Frame Counter */ - u32 TxPf; /* 0x60F0 */ + u32 tx_pause_frames; /* 0x60F0 */ /* Tx Deferral Packet Counter */ - u32 TDfr; /* 0x60F4 */ + u32 tx_deferred; /* 0x60F4 */ /* Tx Excessive Deferral Packet Counter */ - u32 TEdf; /* 0x60F8 */ + u32 tx_excessive_deferred; /* 0x60F8 */ /* Tx Single Collision Packet Counter */ - u32 TScl; /* 0x60FC */ + u32 tx_single_collisions; /* 0x60FC */ /* Tx Multiple Collision Packet Counter */ - u32 TMcl; /* 0x6100 */ + u32 tx_multiple_collisions; /* 0x6100 */ /* Tx Late Collision Packet Counter */ - u32 TLcl; /* 0x6104 */ + u32 tx_late_collisions; /* 0x6104 */ /* Tx Excessive Collision Packet Counter */ - u32 TXcl; /* 0x6108 */ + u32 tx_excessive_collisions; /* 0x6108 */ /* Tx Total Collision Packet Counter */ - u32 TNcl; /* 0x610C */ + u32 tx_total_collisions; /* 0x610C */ /* Tx Pause Frame Honored Counter */ - u32 TPfh; /* 0x6110 */ + u32 tx_pause_honored_frames; /* 0x6110 */ /* Tx Drop Frame Counter */ - u32 TDrp; /* 0x6114 */ + u32 tx_drops; /* 0x6114 */ /* Tx Jabber Frame Counter */ - u32 TJbr; /* 0x6118 */ + u32 tx_jabbers; /* 0x6118 */ /* Tx FCS Error Counter */ - u32 TFcs; /* 0x611C */ + u32 tx_fcs_errs; /* 0x611C */ /* Tx Control Frame Counter */ - u32 TxCf; /* 0x6120 */ + u32 tx_control_frames; /* 0x6120 */ /* Tx Oversize Frame Counter */ - u32 TOvr; /* 0x6124 */ + u32 tx_oversize_frames; /* 0x6124 */ /* Tx Undersize Frame Counter */ - u32 TUnd; /* 0x6128 */ + u32 tx_undersize_frames; /* 0x6128 */ /* Tx Fragments Frame Counter */ - u32 TFrg; /* 0x612C */ + u32 tx_fragments; /* 0x612C */ /* Carry Register One Register */ - u32 Carry1; /* 0x6130 */ + u32 carry_reg1; /* 0x6130 */ /* Carry Register Two Register */ - u32 Carry2; /* 0x6134 */ + u32 carry_reg2; /* 0x6134 */ /* Carry Register One Mask Register */ - u32 Carry1M; /* 0x6138 */ + u32 carry_reg1_mask; /* 0x6138 */ /* Carry Register Two Mask Register */ - u32 Carry2M; /* 0x613C */ + u32 carry_reg2_mask; /* 0x613C */ }; /* END OF MAC STAT REGISTER ADDRESS MAP */ @@ -1448,7 +1399,7 @@ struct mmc_regs { /* Location: */ /* * JAGCore Address Mapping */ -typedef struct _ADDRESS_MAP_t { +struct address_map { struct global_regs global; /* unused section of global address map */ u8 unused_global[4096 - sizeof(struct global_regs)]; @@ -1461,12 +1412,12 @@ typedef struct _ADDRESS_MAP_t { struct txmac_regs txmac; /* unused section of txmac address map */ u8 unused_txmac[4096 - sizeof(struct txmac_regs)]; - RXMAC_t rxmac; + struct rxmac_regs rxmac; /* unused section of rxmac address map */ - u8 unused_rxmac[4096 - sizeof(RXMAC_t)]; - MAC_t mac; + u8 unused_rxmac[4096 - sizeof(struct rxmac_regs)]; + struct mac_regs mac; /* unused section of mac address map */ - u8 unused_mac[4096 - sizeof(MAC_t)]; + u8 unused_mac[4096 - sizeof(struct mac_regs)]; struct macstat_regs macstat; /* unused section of mac stat address map */ u8 unused_mac_stat[4096 - sizeof(struct macstat_regs)]; @@ -1478,6 +1429,6 @@ typedef struct _ADDRESS_MAP_t { u8 unused_exp_rom[4096]; /* MGS-size TBD */ u8 unused__[524288]; /* unused section of address map */ -} ADDRESS_MAP_t, *PADDRESS_MAP_t; +}; #endif /* _ET1310_ADDRESS_MAP_H_ */ diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c index 78f72fa5d5e9..656be4b99cf6 100644 --- a/drivers/staging/et131x/et1310_mac.c +++ b/drivers/staging/et131x/et1310_mac.c @@ -104,9 +104,9 @@ */ void ConfigMACRegs1(struct et131x_adapter *etdev) { - struct _MAC_t __iomem *pMac = &etdev->regs->mac; - MAC_STATION_ADDR1_t station1; - MAC_STATION_ADDR2_t station2; + struct mac_regs __iomem *pMac = &etdev->regs->mac; + u32 station1; + u32 station2; u32 ipg; /* First we need to reset everything. Write to MAC configuration @@ -136,14 +136,14 @@ void ConfigMACRegs1(struct et131x_adapter *etdev) * station address is used for generating and checking pause control * packets. */ - station2.bits.Octet1 = etdev->addr[0]; - station2.bits.Octet2 = etdev->addr[1]; - station1.bits.Octet3 = etdev->addr[2]; - station1.bits.Octet4 = etdev->addr[3]; - station1.bits.Octet5 = etdev->addr[4]; - station1.bits.Octet6 = etdev->addr[5]; - writel(station1.value, &pMac->station_addr_1.value); - writel(station2.value, &pMac->station_addr_2.value); + station2 = (etdev->addr[1] << ET_MAC_STATION_ADDR2_OC2_SHIFT) | + (etdev->addr[0] << ET_MAC_STATION_ADDR2_OC1_SHIFT); + station1 = (etdev->addr[5] << ET_MAC_STATION_ADDR1_OC6_SHIFT) | + (etdev->addr[4] << ET_MAC_STATION_ADDR1_OC5_SHIFT) | + (etdev->addr[3] << ET_MAC_STATION_ADDR1_OC4_SHIFT) | + etdev->addr[2]; + writel(station1, &pMac->station_addr_1); + writel(station2, &pMac->station_addr_2); /* Max ethernet packet in bytes that will passed by the mac without * being truncated. Allow the MAC to pass 4 more than our max packet @@ -165,7 +165,7 @@ void ConfigMACRegs1(struct et131x_adapter *etdev) void ConfigMACRegs2(struct et131x_adapter *etdev) { int32_t delay = 0; - struct _MAC_t __iomem *pMac = &etdev->regs->mac; + struct mac_regs __iomem *pMac = &etdev->regs->mac; u32 cfg1; u32 cfg2; u32 ifctrl; @@ -229,7 +229,7 @@ void ConfigMACRegs2(struct et131x_adapter *etdev) writel(ctl, &etdev->regs->txmac.ctl); /* Ready to start the RXDMA/TXDMA engine */ - if (etdev->Flags & fMP_ADAPTER_LOWER_POWER) { + if (etdev->flags & fMP_ADAPTER_LOWER_POWER) { et131x_rx_dma_enable(etdev); et131x_tx_dma_enable(etdev); } @@ -237,9 +237,9 @@ void ConfigMACRegs2(struct et131x_adapter *etdev) void ConfigRxMacRegs(struct et131x_adapter *etdev) { - struct _RXMAC_t __iomem *pRxMac = &etdev->regs->rxmac; - RXMAC_WOL_SA_LO_t sa_lo; - RXMAC_WOL_SA_HI_t sa_hi; + struct rxmac_regs __iomem *pRxMac = &etdev->regs->rxmac; + u32 sa_lo; + u32 sa_hi = 0; u32 pf_ctrl = 0; /* Disable the MAC while it is being configured (also disable WOL) */ @@ -280,15 +280,15 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev) writel(0, &pRxMac->mask4_word3); /* Lets setup the WOL Source Address */ - sa_lo.bits.sa3 = etdev->addr[2]; - sa_lo.bits.sa4 = etdev->addr[3]; - sa_lo.bits.sa5 = etdev->addr[4]; - sa_lo.bits.sa6 = etdev->addr[5]; - writel(sa_lo.value, &pRxMac->sa_lo.value); + sa_lo = (etdev->addr[2] << ET_WOL_LO_SA3_SHIFT) | + (etdev->addr[3] << ET_WOL_LO_SA4_SHIFT) | + (etdev->addr[4] << ET_WOL_LO_SA5_SHIFT) | + etdev->addr[5]; + writel(sa_lo, &pRxMac->sa_lo); - sa_hi.bits.sa1 = etdev->addr[0]; - sa_hi.bits.sa2 = etdev->addr[1]; - writel(sa_hi.value, &pRxMac->sa_hi.value); + sa_hi = (u32) (etdev->addr[0] << ET_WOL_HI_SA1_SHIFT) | + etdev->addr[1]; + writel(sa_hi, &pRxMac->sa_hi); /* Disable all Packet Filtering */ writel(0, &pRxMac->pf_ctrl); @@ -298,9 +298,9 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev) SetupDeviceForUnicast(etdev); pf_ctrl |= 4; /* Unicast filter */ } else { - writel(0, &pRxMac->uni_pf_addr1.value); - writel(0, &pRxMac->uni_pf_addr2.value); - writel(0, &pRxMac->uni_pf_addr3.value); + writel(0, &pRxMac->uni_pf_addr1); + writel(0, &pRxMac->uni_pf_addr2); + writel(0, &pRxMac->uni_pf_addr3); } /* Let's initialize the Multicast hash */ @@ -384,31 +384,64 @@ void ConfigMacStatRegs(struct et131x_adapter *etdev) struct macstat_regs __iomem *macstat = &etdev->regs->macstat; - /* Next we need to initialize all the MAC_STAT registers to zero on + /* Next we need to initialize all the macstat registers to zero on * the device. */ - writel(0, &macstat->RFcs); - writel(0, &macstat->RAln); - writel(0, &macstat->RFlr); - writel(0, &macstat->RDrp); - writel(0, &macstat->RCde); - writel(0, &macstat->ROvr); - writel(0, &macstat->RFrg); + writel(0, &macstat->txrx_0_64_byte_frames); + writel(0, &macstat->txrx_65_127_byte_frames); + writel(0, &macstat->txrx_128_255_byte_frames); + writel(0, &macstat->txrx_256_511_byte_frames); + writel(0, &macstat->txrx_512_1023_byte_frames); + writel(0, &macstat->txrx_1024_1518_byte_frames); + writel(0, &macstat->txrx_1519_1522_gvln_frames); - writel(0, &macstat->TScl); - writel(0, &macstat->TDfr); - writel(0, &macstat->TMcl); - writel(0, &macstat->TLcl); - writel(0, &macstat->TNcl); - writel(0, &macstat->TOvr); - writel(0, &macstat->TUnd); + writel(0, &macstat->rx_bytes); + writel(0, &macstat->rx_packets); + writel(0, &macstat->rx_fcs_errs); + writel(0, &macstat->rx_multicast_packets); + writel(0, &macstat->rx_broadcast_packets); + writel(0, &macstat->rx_control_frames); + writel(0, &macstat->rx_pause_frames); + writel(0, &macstat->rx_unknown_opcodes); + writel(0, &macstat->rx_align_errs); + writel(0, &macstat->rx_frame_len_errs); + writel(0, &macstat->rx_code_errs); + writel(0, &macstat->rx_carrier_sense_errs); + writel(0, &macstat->rx_undersize_packets); + writel(0, &macstat->rx_oversize_packets); + writel(0, &macstat->rx_fragment_packets); + writel(0, &macstat->rx_jabbers); + writel(0, &macstat->rx_drops); + + writel(0, &macstat->tx_bytes); + writel(0, &macstat->tx_packets); + writel(0, &macstat->tx_multicast_packets); + writel(0, &macstat->tx_broadcast_packets); + writel(0, &macstat->tx_pause_frames); + writel(0, &macstat->tx_deferred); + writel(0, &macstat->tx_excessive_deferred); + writel(0, &macstat->tx_single_collisions); + writel(0, &macstat->tx_multiple_collisions); + writel(0, &macstat->tx_late_collisions); + writel(0, &macstat->tx_excessive_collisions); + writel(0, &macstat->tx_total_collisions); + writel(0, &macstat->tx_pause_honored_frames); + writel(0, &macstat->tx_drops); + writel(0, &macstat->tx_jabbers); + writel(0, &macstat->tx_fcs_errs); + writel(0, &macstat->tx_control_frames); + writel(0, &macstat->tx_oversize_frames); + writel(0, &macstat->tx_undersize_frames); + writel(0, &macstat->tx_fragments); + writel(0, &macstat->carry_reg1); + writel(0, &macstat->carry_reg2); /* Unmask any counters that we want to track the overflow of. * Initially this will be all counters. It may become clear later * that we do not need to track all counters. */ - writel(0xFFFFBE32, &macstat->Carry1M); - writel(0xFFFE7E8B, &macstat->Carry2M); + writel(0xFFFFBE32, &macstat->carry_reg1_mask); + writel(0xFFFE7E8B, &macstat->carry_reg2_mask); } void ConfigFlowControl(struct et131x_adapter *etdev) @@ -452,26 +485,26 @@ void ConfigFlowControl(struct et131x_adapter *etdev) */ void UpdateMacStatHostCounters(struct et131x_adapter *etdev) { - struct _ce_stats_t *stats = &etdev->Stats; + struct ce_stats *stats = &etdev->stats; struct macstat_regs __iomem *macstat = &etdev->regs->macstat; - stats->collisions += readl(&macstat->TNcl); - stats->first_collision += readl(&macstat->TScl); - stats->tx_deferred += readl(&macstat->TDfr); - stats->excessive_collisions += readl(&macstat->TMcl); - stats->late_collisions += readl(&macstat->TLcl); - stats->tx_uflo += readl(&macstat->TUnd); - stats->max_pkt_error += readl(&macstat->TOvr); + stats->collisions += readl(&macstat->tx_total_collisions); + stats->first_collision += readl(&macstat->tx_single_collisions); + stats->tx_deferred += readl(&macstat->tx_deferred); + stats->excessive_collisions += readl(&macstat->tx_multiple_collisions); + stats->late_collisions += readl(&macstat->tx_late_collisions); + stats->tx_uflo += readl(&macstat->tx_undersize_frames); + stats->max_pkt_error += readl(&macstat->tx_oversize_frames); - stats->alignment_err += readl(&macstat->RAln); - stats->crc_err += readl(&macstat->RCde); - stats->norcvbuf += readl(&macstat->RDrp); - stats->rx_ov_flow += readl(&macstat->ROvr); - stats->code_violations += readl(&macstat->RFcs); - stats->length_err += readl(&macstat->RFlr); + stats->alignment_err += readl(&macstat->rx_align_errs); + stats->crc_err += readl(&macstat->rx_code_errs); + stats->norcvbuf += readl(&macstat->rx_drops); + stats->rx_ov_flow += readl(&macstat->rx_oversize_packets); + stats->code_violations += readl(&macstat->rx_fcs_errs); + stats->length_err += readl(&macstat->rx_frame_len_errs); - stats->other_errors += readl(&macstat->RFrg); + stats->other_errors += readl(&macstat->rx_fragment_packets); } /** @@ -484,17 +517,17 @@ void UpdateMacStatHostCounters(struct et131x_adapter *etdev) */ void HandleMacStatInterrupt(struct et131x_adapter *etdev) { - u32 Carry1; - u32 Carry2; + u32 carry_reg1; + u32 carry_reg2; /* Read the interrupt bits from the register(s). These are Clear On * Write. */ - Carry1 = readl(&etdev->regs->macstat.Carry1); - Carry2 = readl(&etdev->regs->macstat.Carry2); + carry_reg1 = readl(&etdev->regs->macstat.carry_reg1); + carry_reg2 = readl(&etdev->regs->macstat.carry_reg2); - writel(Carry1, &etdev->regs->macstat.Carry1); - writel(Carry2, &etdev->regs->macstat.Carry2); + writel(carry_reg2, &etdev->regs->macstat.carry_reg1); + writel(carry_reg2, &etdev->regs->macstat.carry_reg2); /* We need to do update the host copy of all the MAC_STAT counters. * For each counter, check it's overflow bit. If the overflow bit is @@ -502,39 +535,39 @@ void HandleMacStatInterrupt(struct et131x_adapter *etdev) * revolution of the counter. This routine is called when the counter * block indicates that one of the counters has wrapped. */ - if (Carry1 & (1 << 14)) - etdev->Stats.code_violations += COUNTER_WRAP_16_BIT; - if (Carry1 & (1 << 8)) - etdev->Stats.alignment_err += COUNTER_WRAP_12_BIT; - if (Carry1 & (1 << 7)) - etdev->Stats.length_err += COUNTER_WRAP_16_BIT; - if (Carry1 & (1 << 2)) - etdev->Stats.other_errors += COUNTER_WRAP_16_BIT; - if (Carry1 & (1 << 6)) - etdev->Stats.crc_err += COUNTER_WRAP_16_BIT; - if (Carry1 & (1 << 3)) - etdev->Stats.rx_ov_flow += COUNTER_WRAP_16_BIT; - if (Carry1 & (1 << 0)) - etdev->Stats.norcvbuf += COUNTER_WRAP_16_BIT; - if (Carry2 & (1 << 16)) - etdev->Stats.max_pkt_error += COUNTER_WRAP_12_BIT; - if (Carry2 & (1 << 15)) - etdev->Stats.tx_uflo += COUNTER_WRAP_12_BIT; - if (Carry2 & (1 << 6)) - etdev->Stats.first_collision += COUNTER_WRAP_12_BIT; - if (Carry2 & (1 << 8)) - etdev->Stats.tx_deferred += COUNTER_WRAP_12_BIT; - if (Carry2 & (1 << 5)) - etdev->Stats.excessive_collisions += COUNTER_WRAP_12_BIT; - if (Carry2 & (1 << 4)) - etdev->Stats.late_collisions += COUNTER_WRAP_12_BIT; - if (Carry2 & (1 << 2)) - etdev->Stats.collisions += COUNTER_WRAP_12_BIT; + if (carry_reg1 & (1 << 14)) + etdev->stats.code_violations += COUNTER_WRAP_16_BIT; + if (carry_reg1 & (1 << 8)) + etdev->stats.alignment_err += COUNTER_WRAP_12_BIT; + if (carry_reg1 & (1 << 7)) + etdev->stats.length_err += COUNTER_WRAP_16_BIT; + if (carry_reg1 & (1 << 2)) + etdev->stats.other_errors += COUNTER_WRAP_16_BIT; + if (carry_reg1 & (1 << 6)) + etdev->stats.crc_err += COUNTER_WRAP_16_BIT; + if (carry_reg1 & (1 << 3)) + etdev->stats.rx_ov_flow += COUNTER_WRAP_16_BIT; + if (carry_reg1 & (1 << 0)) + etdev->stats.norcvbuf += COUNTER_WRAP_16_BIT; + if (carry_reg2 & (1 << 16)) + etdev->stats.max_pkt_error += COUNTER_WRAP_12_BIT; + if (carry_reg2 & (1 << 15)) + etdev->stats.tx_uflo += COUNTER_WRAP_12_BIT; + if (carry_reg2 & (1 << 6)) + etdev->stats.first_collision += COUNTER_WRAP_12_BIT; + if (carry_reg2 & (1 << 8)) + etdev->stats.tx_deferred += COUNTER_WRAP_12_BIT; + if (carry_reg2 & (1 << 5)) + etdev->stats.excessive_collisions += COUNTER_WRAP_12_BIT; + if (carry_reg2 & (1 << 4)) + etdev->stats.late_collisions += COUNTER_WRAP_12_BIT; + if (carry_reg2 & (1 << 2)) + etdev->stats.collisions += COUNTER_WRAP_12_BIT; } void SetupDeviceForMulticast(struct et131x_adapter *etdev) { - struct _RXMAC_t __iomem *rxmac = &etdev->regs->rxmac; + struct rxmac_regs __iomem *rxmac = &etdev->regs->rxmac; uint32_t nIndex; uint32_t result; uint32_t hash1 = 0; @@ -582,10 +615,10 @@ void SetupDeviceForMulticast(struct et131x_adapter *etdev) void SetupDeviceForUnicast(struct et131x_adapter *etdev) { - struct _RXMAC_t __iomem *rxmac = &etdev->regs->rxmac; - RXMAC_UNI_PF_ADDR1_t uni_pf1; - RXMAC_UNI_PF_ADDR2_t uni_pf2; - RXMAC_UNI_PF_ADDR3_t uni_pf3; + struct rxmac_regs __iomem *rxmac = &etdev->regs->rxmac; + u32 uni_pf1; + u32 uni_pf2; + u32 uni_pf3; u32 pm_csr; /* Set up unicast packet filter reg 3 to be the first two octets of @@ -597,25 +630,25 @@ void SetupDeviceForUnicast(struct et131x_adapter *etdev) * Set up unicast packet filter reg 3 to be the octets 2 - 5 of the * MAC address for first address */ - uni_pf3.bits.addr1_1 = etdev->addr[0]; - uni_pf3.bits.addr1_2 = etdev->addr[1]; - uni_pf3.bits.addr2_1 = etdev->addr[0]; - uni_pf3.bits.addr2_2 = etdev->addr[1]; + uni_pf3 = (etdev->addr[0] << ET_UNI_PF_ADDR2_1_SHIFT) | + (etdev->addr[1] << ET_UNI_PF_ADDR2_2_SHIFT) | + (etdev->addr[0] << ET_UNI_PF_ADDR1_1_SHIFT) | + etdev->addr[1]; - uni_pf2.bits.addr2_3 = etdev->addr[2]; - uni_pf2.bits.addr2_4 = etdev->addr[3]; - uni_pf2.bits.addr2_5 = etdev->addr[4]; - uni_pf2.bits.addr2_6 = etdev->addr[5]; + uni_pf2 = (etdev->addr[2] << ET_UNI_PF_ADDR2_3_SHIFT) | + (etdev->addr[3] << ET_UNI_PF_ADDR2_4_SHIFT) | + (etdev->addr[4] << ET_UNI_PF_ADDR2_5_SHIFT) | + etdev->addr[5]; - uni_pf1.bits.addr1_3 = etdev->addr[2]; - uni_pf1.bits.addr1_4 = etdev->addr[3]; - uni_pf1.bits.addr1_5 = etdev->addr[4]; - uni_pf1.bits.addr1_6 = etdev->addr[5]; + uni_pf1 = (etdev->addr[2] << ET_UNI_PF_ADDR1_3_SHIFT) | + (etdev->addr[3] << ET_UNI_PF_ADDR1_4_SHIFT) | + (etdev->addr[4] << ET_UNI_PF_ADDR1_5_SHIFT) | + etdev->addr[5]; pm_csr = readl(&etdev->regs->global.pm_csr); if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) { - writel(uni_pf1.value, &rxmac->uni_pf_addr1.value); - writel(uni_pf2.value, &rxmac->uni_pf_addr2.value); - writel(uni_pf3.value, &rxmac->uni_pf_addr3.value); + writel(uni_pf1, &rxmac->uni_pf_addr1); + writel(uni_pf2, &rxmac->uni_pf_addr2); + writel(uni_pf3, &rxmac->uni_pf_addr3); } } diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c index 2798a2ff6123..0bcb7fb6e2c8 100644 --- a/drivers/staging/et131x/et1310_phy.c +++ b/drivers/staging/et131x/et1310_phy.c @@ -99,7 +99,7 @@ static void et131x_xcvr_init(struct et131x_adapter *etdev); /** * PhyMiRead - Read from the PHY through the MII Interface on the MAC * @etdev: pointer to our private adapter structure - * @xcvrAddr: the address of the transciever + * @xcvrAddr: the address of the transceiver * @xcvrReg: the register to read * @value: pointer to a 16-bit value in which the value will be stored * @@ -108,7 +108,7 @@ static void et131x_xcvr_init(struct et131x_adapter *etdev); int PhyMiRead(struct et131x_adapter *etdev, u8 xcvrAddr, u8 xcvrReg, u16 *value) { - struct _MAC_t __iomem *mac = &etdev->regs->mac; + struct mac_regs __iomem *mac = &etdev->regs->mac; int status = 0; u32 delay; u32 miiAddr; @@ -176,9 +176,9 @@ int PhyMiRead(struct et131x_adapter *etdev, u8 xcvrAddr, */ int MiWrite(struct et131x_adapter *etdev, u8 xcvrReg, u16 value) { - struct _MAC_t __iomem *mac = &etdev->regs->mac; + struct mac_regs __iomem *mac = &etdev->regs->mac; int status = 0; - u8 xcvrAddr = etdev->Stats.xcvr_addr; + u8 xcvrAddr = etdev->stats.xcvr_addr; u32 delay; u32 miiAddr; u32 miiCmd; @@ -259,8 +259,8 @@ int et131x_xcvr_find(struct et131x_adapter *etdev) xcvr_id = (u32) ((idr1 << 16) | idr2); if (idr1 != 0 && idr1 != 0xffff) { - etdev->Stats.xcvr_id = xcvr_id; - etdev->Stats.xcvr_addr = xcvr_addr; + etdev->stats.xcvr_id = xcvr_id; + etdev->stats.xcvr_addr = xcvr_addr; return 0; } } @@ -582,7 +582,7 @@ static void et131x_xcvr_init(struct et131x_adapter *etdev) u16 lcr2; /* Zero out the adapter structure variable representing BMSR */ - etdev->Bmsr.value = 0; + etdev->bmsr = 0; MiRead(etdev, (u8) offsetof(struct mi_regs, isr), &isr); MiRead(etdev, (u8) offsetof(struct mi_regs, imr), &imr); @@ -590,7 +590,7 @@ static void et131x_xcvr_init(struct et131x_adapter *etdev) /* Set the link status interrupt only. Bad behavior when link status * and auto neg are set, we run into a nested interrupt problem */ - imr |= 0x0105; + imr |= 0x0105; MiWrite(etdev, (u8) offsetof(struct mi_regs, imr), imr); @@ -729,7 +729,7 @@ static void et131x_xcvr_init(struct et131x_adapter *etdev) } void et131x_Mii_check(struct et131x_adapter *etdev, - MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints) + u16 bmsr, u16 bmsr_ints) { u8 link_status; u32 autoneg_status; @@ -740,8 +740,8 @@ void et131x_Mii_check(struct et131x_adapter *etdev, u32 polarity; unsigned long flags; - if (bmsr_ints.bits.link_status) { - if (bmsr.bits.link_status) { + if (bmsr_ints & MI_BMSR_LINK_STATUS) { + if (bmsr & MI_BMSR_LINK_STATUS) { etdev->boot_coma = 20; /* Update our state variables and indicate the @@ -750,7 +750,6 @@ void et131x_Mii_check(struct et131x_adapter *etdev, spin_lock_irqsave(&etdev->Lock, flags); etdev->MediaState = NETIF_STATUS_MEDIA_CONNECT; - etdev->Flags &= ~fMP_ADAPTER_LINK_DETECTION; spin_unlock_irqrestore(&etdev->Lock, flags); @@ -780,8 +779,7 @@ void et131x_Mii_check(struct et131x_adapter *etdev, * Timer expires, we can report disconnected (handled * in the LinkDetectionDPC). */ - if (!(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) || - (etdev->MediaState == NETIF_STATUS_MEDIA_DISCONNECT)) { + if ((etdev->MediaState == NETIF_STATUS_MEDIA_DISCONNECT)) { spin_lock_irqsave(&etdev->Lock, flags); etdev->MediaState = NETIF_STATUS_MEDIA_DISCONNECT; @@ -822,9 +820,10 @@ void et131x_Mii_check(struct et131x_adapter *etdev, } } - if (bmsr_ints.bits.auto_neg_complete || - (etdev->AiForceDpx == 3 && bmsr_ints.bits.link_status)) { - if (bmsr.bits.auto_neg_complete || etdev->AiForceDpx == 3) { + if ((bmsr_ints & MI_BMSR_AUTO_NEG_COMPLETE) || + (etdev->AiForceDpx == 3 && (bmsr_ints & MI_BMSR_LINK_STATUS))) { + if ((bmsr & MI_BMSR_AUTO_NEG_COMPLETE) || + etdev->AiForceDpx == 3) { ET1310_PhyLinkStatus(etdev, &link_status, &autoneg_status, &speed, &duplex, &mdi_mdix, diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h index 946c0c547404..6b38a3e0cab2 100644 --- a/drivers/staging/et131x/et1310_phy.h +++ b/drivers/staging/et131x/et1310_phy.h @@ -126,119 +126,66 @@ struct mi_regs { u8 mi_res4[3]; /* Future use by MI working group(Reg 0x1D - 0x1F) */ }; -/* MI Register 0: Basic mode control register */ -typedef union _MI_BMCR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 reset:1; /* bit 15 */ - u16 loopback:1; /* bit 14 */ - u16 speed_sel:1; /* bit 13 */ - u16 enable_autoneg:1; /* bit 12 */ - u16 power_down:1; /* bit 11 */ - u16 isolate:1; /* bit 10 */ - u16 restart_autoneg:1; /* bit 9 */ - u16 duplex_mode:1; /* bit 8 */ - u16 col_test:1; /* bit 7 */ - u16 speed_1000_sel:1; /* bit 6 */ - u16 res1:6; /* bits 0-5 */ -#else - u16 res1:6; /* bits 0-5 */ - u16 speed_1000_sel:1; /* bit 6 */ - u16 col_test:1; /* bit 7 */ - u16 duplex_mode:1; /* bit 8 */ - u16 restart_autoneg:1; /* bit 9 */ - u16 isolate:1; /* bit 10 */ - u16 power_down:1; /* bit 11 */ - u16 enable_autoneg:1; /* bit 12 */ - u16 speed_sel:1; /* bit 13 */ - u16 loopback:1; /* bit 14 */ - u16 reset:1; /* bit 15 */ -#endif - } bits; -} MI_BMCR_t, *PMI_BMCR_t; +/* + * MI Register 0: Basic mode control register + * 15: reset + * 14: loopback + * 13: speed_sel + * 12: enable_autoneg + * 11: power_down + * 10: isolate + * 9: restart_autoneg + * 8: duplex_mode + * 7: col_test + * 6: speed_1000_sel + * 5-0: res1 + */ -/* MI Register 1: Basic mode status register */ -typedef union _MI_BMSR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 link_100T4:1; /* bit 15 */ - u16 link_100fdx:1; /* bit 14 */ - u16 link_100hdx:1; /* bit 13 */ - u16 link_10fdx:1; /* bit 12 */ - u16 link_10hdx:1; /* bit 11 */ - u16 link_100T2fdx:1; /* bit 10 */ - u16 link_100T2hdx:1; /* bit 9 */ - u16 extend_status:1; /* bit 8 */ - u16 res1:1; /* bit 7 */ - u16 preamble_supress:1; /* bit 6 */ - u16 auto_neg_complete:1; /* bit 5 */ - u16 remote_fault:1; /* bit 4 */ - u16 auto_neg_able:1; /* bit 3 */ - u16 link_status:1; /* bit 2 */ - u16 jabber_detect:1; /* bit 1 */ - u16 ext_cap:1; /* bit 0 */ -#else - u16 ext_cap:1; /* bit 0 */ - u16 jabber_detect:1; /* bit 1 */ - u16 link_status:1; /* bit 2 */ - u16 auto_neg_able:1; /* bit 3 */ - u16 remote_fault:1; /* bit 4 */ - u16 auto_neg_complete:1; /* bit 5 */ - u16 preamble_supress:1; /* bit 6 */ - u16 res1:1; /* bit 7 */ - u16 extend_status:1; /* bit 8 */ - u16 link_100T2hdx:1; /* bit 9 */ - u16 link_100T2fdx:1; /* bit 10 */ - u16 link_10hdx:1; /* bit 11 */ - u16 link_10fdx:1; /* bit 12 */ - u16 link_100hdx:1; /* bit 13 */ - u16 link_100fdx:1; /* bit 14 */ - u16 link_100T4:1; /* bit 15 */ -#endif - } bits; -} MI_BMSR_t, *PMI_BMSR_t; +/* + * MI Register 1: Basic mode status register + * 15: link_100T4 + * 14: link_100fdx + * 13: link_100hdx + * 12: link_10fdx + * 11: link_10hdx + * 10: link_100T2fdx + * 9: link_100T2hdx + * 8: extend_status + * 7: res1 + * 6: preamble_supress + * 5: auto_neg_complete + * 4: remote_fault + * 3: auto_neg_able + * 2: link_status + * 1: jabber_detect + * 0: ext_cap + */ -/* MI Register 4: Auto-negotiation advertisement register */ -typedef union _MI_ANAR_t { - u16 value; - struct { -#ifdef _BIT_FIELDS_HTOL - u16 np_indication:1; /* bit 15 */ - u16 res2:1; /* bit 14 */ - u16 remote_fault:1; /* bit 13 */ - u16 res1:1; /* bit 12 */ - u16 cap_asmpause:1; /* bit 11 */ - u16 cap_pause:1; /* bit 10 */ - u16 cap_100T4:1; /* bit 9 */ - u16 cap_100fdx:1; /* bit 8 */ - u16 cap_100hdx:1; /* bit 7 */ - u16 cap_10fdx:1; /* bit 6 */ - u16 cap_10hdx:1; /* bit 5 */ - u16 selector:5; /* bits 0-4 */ -#else - u16 selector:5; /* bits 0-4 */ - u16 cap_10hdx:1; /* bit 5 */ - u16 cap_10fdx:1; /* bit 6 */ - u16 cap_100hdx:1; /* bit 7 */ - u16 cap_100fdx:1; /* bit 8 */ - u16 cap_100T4:1; /* bit 9 */ - u16 cap_pause:1; /* bit 10 */ - u16 cap_asmpause:1; /* bit 11 */ - u16 res1:1; /* bit 12 */ - u16 remote_fault:1; /* bit 13 */ - u16 res2:1; /* bit 14 */ - u16 np_indication:1; /* bit 15 */ -#endif - } bits; -} MI_ANAR_t, *PMI_ANAR_t; +#define MI_BMSR_LINK_STATUS 0x04 +#define MI_BMSR_AUTO_NEG_COMPLETE 0x20 + +/* + * MI Register 4: Auto-negotiation advertisement register + * + * 15: np_indication + * 14: res2 + * 13: remote_fault + * 12: res1 + * 11: cap_asmpause + * 10: cap_pause + * 9: cap_100T4 + * 8: cap_100fdx + * 7: cap_100hdx + * 6: cap_10fdx + * 5: cap_10hdx + * 4-0: selector + */ /* MI Register 5: Auto-negotiation link partner advertisement register * 15: np_indication * 14: acknowledge * 13: remote_fault - * 12: res1:1; + * 12: res1 * 11: cap_asmpause * 10: cap_pause * 9: cap_100T4 @@ -258,7 +205,7 @@ typedef union _MI_ANAR_t { * 0: lp_an_able */ -/* MI Register 7: Auto-negotiation next page transmit reg(0x07) +/* MI Register 7: Auto-negotiation next page transmit reg(0x07) * 15: np * 14: reserved * 13: msg_page @@ -267,7 +214,7 @@ typedef union _MI_ANAR_t { * 10-0 msg */ -/* MI Register 8: Link Partner Next Page Reg(0x08) +/* MI Register 8: Link Partner Next Page Reg(0x08) * 15: np * 14: ack * 13: msg_page @@ -473,7 +420,7 @@ typedef union _MI_ANAR_t { #define TRUEPHY_ADV_DUPLEX_FULL 0x01 #define TRUEPHY_ADV_DUPLEX_HALF 0x02 #define TRUEPHY_ADV_DUPLEX_BOTH \ - (TRUEPHY_ADV_DUPLEX_FULL | TRUEPHY_ADV_DUPLEX_HALF) + (TRUEPHY_ADV_DUPLEX_FULL | TRUEPHY_ADV_DUPLEX_HALF) #define PHY_CONTROL 0x00 /* #define TRU_MI_CONTROL_REGISTER 0 */ #define PHY_STATUS 0x01 /* #define TRU_MI_STATUS_REGISTER 1 */ diff --git a/drivers/staging/et131x/et1310_pm.c b/drivers/staging/et131x/et1310_pm.c index 2bc19448d2e2..29d4d66d345f 100644 --- a/drivers/staging/et131x/et1310_pm.c +++ b/drivers/staging/et131x/et1310_pm.c @@ -121,7 +121,7 @@ void EnablePhyComa(struct et131x_adapter *etdev) /* Stop sending packets. */ spin_lock_irqsave(&etdev->send_hw_lock, flags); - etdev->Flags |= fMP_ADAPTER_LOWER_POWER; + etdev->flags |= fMP_ADAPTER_LOWER_POWER; spin_unlock_irqrestore(&etdev->send_hw_lock, flags); /* Wait for outstanding Receive packets */ @@ -172,7 +172,7 @@ void DisablePhyComa(struct et131x_adapter *etdev) et131x_adapter_setup(etdev); /* Allow Tx to restart */ - etdev->Flags &= ~fMP_ADAPTER_LOWER_POWER; + etdev->flags &= ~fMP_ADAPTER_LOWER_POWER; /* Need to re-enable Rx. */ et131x_rx_dma_enable(etdev); diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c index fc6bd438366d..7e386e07ff97 100644 --- a/drivers/staging/et131x/et1310_rx.c +++ b/drivers/staging/et131x/et1310_rx.c @@ -88,7 +88,23 @@ #include "et1310_rx.h" #include "et131x.h" -void nic_return_rfd(struct et131x_adapter *etdev, struct rfd *rfd); +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; +} /** * et131x_rx_dma_memory_alloc @@ -246,7 +262,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) &rx_ring->Fbr1MemPa[i]); if (!rx_ring->Fbr1MemVa[i]) { - dev_err(&adapter->pdev->dev, + dev_err(&adapter->pdev->dev, "Could not alloc memory\n"); return -ENOMEM; } @@ -378,7 +394,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) SLAB_HWCACHE_ALIGN, NULL); - adapter->Flags |= fMP_ADAPTER_RECV_LOOKASIDE; + adapter->flags |= fMP_ADAPTER_RECV_LOOKASIDE; /* The RFDs are going to be put on lists later on, so initialize the * lists now. @@ -491,7 +507,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) /* Free Packet Status Ring */ if (rx_ring->pPSRingVa) { pktStatRingSize = - sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries; + sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries; pci_free_consistent(adapter->pdev, pktStatRingSize, rx_ring->pPSRingVa, rx_ring->pPSRingPa); @@ -512,9 +528,9 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) /* Free receive packet pool */ /* Destroy the lookaside (RFD) pool */ - if (adapter->Flags & fMP_ADAPTER_RECV_LOOKASIDE) { + if (adapter->flags & fMP_ADAPTER_RECV_LOOKASIDE) { kmem_cache_destroy(rx_ring->RecvLookaside); - adapter->Flags &= ~fMP_ADAPTER_RECV_LOOKASIDE; + adapter->flags &= ~fMP_ADAPTER_RECV_LOOKASIDE; } /* Free the FBR Lookup Table */ @@ -707,6 +723,82 @@ void SetRxDmaTimer(struct et131x_adapter *etdev) } } +/** + * NICReturnRFD - Recycle a RFD and put it back onto the receive list + * @etdev: pointer to our adapter + * @rfd: pointer to the RFD + */ +void nic_return_rfd(struct et131x_adapter *etdev, struct rfd *rfd) +{ + struct rx_ring *rx_local = &etdev->rx_ring; + struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma; + u16 bi = rfd->bufferindex; + u8 ri = rfd->ringindex; + unsigned long flags; + + /* We don't use any of the OOB data besides status. Otherwise, we + * need to clean up OOB data + */ + if ( +#ifdef USE_FBR0 + (ri == 0 && bi < rx_local->Fbr0NumEntries) || +#endif + (ri == 1 && bi < rx_local->Fbr1NumEntries)) { + spin_lock_irqsave(&etdev->FbrLock, flags); + + if (ri == 1) { + struct fbr_desc *next = + (struct fbr_desc *) (rx_local->pFbr1RingVa) + + INDEX10(rx_local->local_Fbr1_full); + + /* Handle the Free Buffer Ring advancement here. Write + * the PA / Buffer Index for the returned buffer into + * the oldest (next to be freed)FBR entry + */ + next->addr_hi = rx_local->fbr[1]->bus_high[bi]; + next->addr_lo = rx_local->fbr[1]->bus_low[bi]; + next->word2 = bi; + + writel(bump_fbr(&rx_local->local_Fbr1_full, + rx_local->Fbr1NumEntries - 1), + &rx_dma->fbr1_full_offset); + } +#ifdef USE_FBR0 + else { + struct fbr_desc *next = (struct fbr_desc *) + rx_local->pFbr0RingVa + + INDEX10(rx_local->local_Fbr0_full); + + /* Handle the Free Buffer Ring advancement here. Write + * the PA / Buffer Index for the returned buffer into + * the oldest (next to be freed) FBR entry + */ + next->addr_hi = rx_local->fbr[0]->bus_high[bi]; + next->addr_lo = rx_local->fbr[0]->bus_low[bi]; + next->word2 = bi; + + writel(bump_fbr(&rx_local->local_Fbr0_full, + rx_local->Fbr0NumEntries - 1), + &rx_dma->fbr0_full_offset); + } +#endif + spin_unlock_irqrestore(&etdev->FbrLock, flags); + } else { + dev_err(&etdev->pdev->dev, + "NICReturnRFD illegal Buffer Index returned\n"); + } + + /* The processing on this RFD is done, so put it back on the tail of + * our list + */ + spin_lock_irqsave(&etdev->rcv_lock, flags); + list_add_tail(&rfd->list_node, &rx_local->RecvList); + rx_local->nReadyRecv++; + spin_unlock_irqrestore(&etdev->rcv_lock, flags); + + WARN_ON(rx_local->nReadyRecv > rx_local->NumRfd); +} + /** * et131x_rx_dma_disable - Stop of Rx_DMA on the ET1310 * @etdev: pointer to our adapter structure @@ -776,7 +868,7 @@ void et131x_rx_dma_enable(struct et131x_adapter *etdev) * the packet to it, puts the RFD in the RecvPendList, and also returns * the pointer to the RFD. */ -struct rfd * nic_rx_pkts(struct et131x_adapter *etdev) +struct rfd *nic_rx_pkts(struct et131x_adapter *etdev) { struct rx_ring *rx_local = &etdev->rx_ring; struct rx_status_block *status; @@ -879,7 +971,7 @@ struct rfd * nic_rx_pkts(struct et131x_adapter *etdev) * also counted here. */ if (len < (NIC_MIN_PACKET_SIZE + 4)) { - etdev->Stats.other_errors++; + etdev->stats.other_errors++; len = 0; } @@ -947,16 +1039,16 @@ struct rfd * nic_rx_pkts(struct et131x_adapter *etdev) } if (len > 0) - etdev->Stats.multircv++; + etdev->stats.multircv++; } else if (word0 & ALCATEL_BROADCAST_PKT) - etdev->Stats.brdcstrcv++; + etdev->stats.brdcstrcv++; else /* Not sure what this counter measures in * promiscuous mode. Perhaps we should check * the MAC address to see if it is directed * to us in promiscuous mode. */ - etdev->Stats.unircv++; + etdev->stats.unircv++; } if (len > 0) { @@ -1034,13 +1126,12 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) * Free buffer ring. */ if (!etdev->PacketFilter || - !(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) || - rfd->len == 0) { + !netif_carrier_ok(etdev->netdev) || + rfd->len == 0) continue; - } /* Increment the number of packets we received */ - etdev->Stats.ipackets++; + etdev->net_stats.rx_packets++; /* Set the status on the packet, either resources or success */ if (etdev->rx_ring.nReadyRecv < RFD_LOW_WATER_MARK) { @@ -1059,96 +1150,3 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) etdev->rx_ring.UnfinishedReceives = false; } -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; -} - -/** - * NICReturnRFD - Recycle a RFD and put it back onto the receive list - * @etdev: pointer to our adapter - * @rfd: pointer to the RFD - */ -void nic_return_rfd(struct et131x_adapter *etdev, struct rfd *rfd) -{ - struct rx_ring *rx_local = &etdev->rx_ring; - struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma; - u16 bi = rfd->bufferindex; - u8 ri = rfd->ringindex; - unsigned long flags; - - /* We don't use any of the OOB data besides status. Otherwise, we - * need to clean up OOB data - */ - if ( -#ifdef USE_FBR0 - (ri == 0 && bi < rx_local->Fbr0NumEntries) || -#endif - (ri == 1 && bi < rx_local->Fbr1NumEntries)) { - spin_lock_irqsave(&etdev->FbrLock, flags); - - if (ri == 1) { - struct fbr_desc *next = - (struct fbr_desc *) (rx_local->pFbr1RingVa) + - INDEX10(rx_local->local_Fbr1_full); - - /* Handle the Free Buffer Ring advancement here. Write - * the PA / Buffer Index for the returned buffer into - * the oldest (next to be freed)FBR entry - */ - next->addr_hi = rx_local->fbr[1]->bus_high[bi]; - next->addr_lo = rx_local->fbr[1]->bus_low[bi]; - next->word2 = bi; - - writel(bump_fbr(&rx_local->local_Fbr1_full, - rx_local->Fbr1NumEntries - 1), - &rx_dma->fbr1_full_offset); - } -#ifdef USE_FBR0 - else { - struct fbr_desc *next = (struct fbr_desc *) - rx_local->pFbr0RingVa + - INDEX10(rx_local->local_Fbr0_full); - - /* Handle the Free Buffer Ring advancement here. Write - * the PA / Buffer Index for the returned buffer into - * the oldest (next to be freed) FBR entry - */ - next->addr_hi = rx_local->fbr[0]->bus_high[bi]; - next->addr_lo = rx_local->fbr[0]->bus_low[bi]; - next->word2 = bi; - - writel(bump_fbr(&rx_local->local_Fbr0_full, - rx_local->Fbr0NumEntries - 1), - &rx_dma->fbr0_full_offset); - } -#endif - spin_unlock_irqrestore(&etdev->FbrLock, flags); - } else { - dev_err(&etdev->pdev->dev, - "NICReturnRFD illegal Buffer Index returned\n"); - } - - /* The processing on this RFD is done, so put it back on the tail of - * our list - */ - spin_lock_irqsave(&etdev->rcv_lock, flags); - list_add_tail(&rfd->list_node, &rx_local->RecvList); - rx_local->nReadyRecv++; - spin_unlock_irqrestore(&etdev->rcv_lock, flags); - - WARN_ON(rx_local->nReadyRecv > rx_local->NumRfd); -} diff --git a/drivers/staging/et131x/et1310_tx.c b/drivers/staging/et131x/et1310_tx.c index 4241d2afecc0..8fb3051fe288 100644 --- a/drivers/staging/et131x/et1310_tx.c +++ b/drivers/staging/et131x/et1310_tx.c @@ -307,7 +307,7 @@ int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev) /* We need to see if the link is up; if it's not, make the * netif layer think we're good and drop the packet */ - if ((etdev->Flags & fMP_ADAPTER_FAIL_SEND_MASK) || + if ((etdev->flags & fMP_ADAPTER_FAIL_SEND_MASK) || !netif_carrier_ok(netdev)) { dev_kfree_skb_any(skb); skb = NULL; @@ -635,11 +635,11 @@ inline void et131x_free_send_packet(struct et131x_adapter *etdev, struct net_device_stats *stats = &etdev->net_stats; if (tcb->flags & fMP_DEST_BROAD) - atomic_inc(&etdev->Stats.brdcstxmt); + atomic_inc(&etdev->stats.brdcstxmt); else if (tcb->flags & fMP_DEST_MULTI) - atomic_inc(&etdev->Stats.multixmt); + atomic_inc(&etdev->stats.multixmt); else - atomic_inc(&etdev->Stats.unixmt); + atomic_inc(&etdev->stats.unixmt); if (tcb->skb) { stats->tx_bytes += tcb->skb->len; @@ -673,7 +673,7 @@ inline void et131x_free_send_packet(struct et131x_adapter *etdev, /* Add the TCB to the Ready Q */ spin_lock_irqsave(&etdev->TCBReadyQLock, flags); - etdev->Stats.opackets++; + etdev->net_stats.tx_packets++; if (etdev->tx_ring.tcb_qtail) etdev->tx_ring.tcb_qtail->next = tcb; @@ -747,7 +747,7 @@ void et131x_handle_send_interrupt(struct et131x_adapter *etdev) struct tcb *tcb; u32 index; - serviced = readl(&etdev->regs->txdma.NewServiceComplete); + serviced = readl(&etdev->regs->txdma.new_service_complete); index = INDEX10(serviced); /* Has the ring wrapped? Process any descriptors that do not have diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h index 8aa3365b83cf..48ebac0e55ce 100644 --- a/drivers/staging/et131x/et131x.h +++ b/drivers/staging/et131x/et131x.h @@ -108,12 +108,12 @@ void et131x_setphy_normal(struct et131x_adapter *adapter); int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr, u8 xcvrReg, u16 *value); #define MiRead(adapter, xcvrReg, value) \ - PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value)) + PhyMiRead((adapter), (adapter)->stats.xcvr_addr, (xcvrReg), (value)) int32_t MiWrite(struct et131x_adapter *adapter, u8 xcvReg, u16 value); void et131x_Mii_check(struct et131x_adapter *pAdapter, - MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints); + u16 bmsr, u16 bmsr_ints); /* This last is not strictly required (the driver could call the TPAL * version instead), but this sets the adapter up correctly, and calls the diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h index c852f867645f..408c50ba4f2b 100644 --- a/drivers/staging/et131x/et131x_adapter.h +++ b/drivers/staging/et131x/et131x_adapter.h @@ -67,7 +67,7 @@ * Do not change these values: if changed, then change also in respective * TXdma and Rxdma engines */ -#define NUM_DESC_PER_RING_TX 512 /* TX Do not change these values */ +#define NUM_DESC_PER_RING_TX 512 /* TX Do not change these values */ #define NUM_TCB 64 /* @@ -98,11 +98,7 @@ struct rfd { #define FLOW_NONE 3 /* Struct to define some device statistics */ -typedef struct _ce_stats_t { - /* Link Input/Output stats */ - uint64_t ipackets; /* # of in packets */ - uint64_t opackets; /* # of out packets */ - +struct ce_stats { /* MIB II variables * * NOTE: atomic_t types are only guaranteed to store 24-bits; if we @@ -118,7 +114,7 @@ typedef struct _ce_stats_t { u32 norcvbuf; /* # Rx packets discarded */ u32 noxmtbuf; /* # Tx packets discarded */ - /* Transciever state informations. */ + /* Transceiver state informations. */ u8 xcvr_addr; u32 xcvr_id; @@ -143,7 +139,7 @@ typedef struct _ce_stats_t { u32 SynchrounousIterations; u32 InterruptStatus; -} CE_STATS_t, *PCE_STATS_t; +}; /* The private adapter structure */ @@ -154,7 +150,7 @@ struct et131x_adapter { struct work_struct task; /* Flags that indicate current state of the adapter */ - u32 Flags; + u32 flags; u32 HwErrCount; /* Configuration */ @@ -186,7 +182,7 @@ struct et131x_adapter { u8 MCList[NIC_MAX_MCAST_LIST][ETH_ALEN]; /* Pointer to the device's PCI register space */ - ADDRESS_MAP_t __iomem *regs; + struct address_map __iomem *regs; /* Registry parameters */ u8 SpeedDuplex; /* speed/duplex */ @@ -226,7 +222,7 @@ struct et131x_adapter { u32 CachedMaskValue; /* Xcvr status at last poll */ - MI_BMSR_t Bmsr; + u16 bmsr; /* Tx Memory Variables */ struct tx_ring tx_ring; @@ -239,10 +235,9 @@ struct et131x_adapter { u8 ReplicaPhyLoopbkPF; /* Replica Enable Pass/Fail */ /* Stats */ - CE_STATS_t Stats; + struct ce_stats stats; struct net_device_stats net_stats; - struct net_device_stats net_stats_prev; }; #endif /* __ET131X_ADAPTER_H__ */ diff --git a/drivers/staging/et131x/et131x_defs.h b/drivers/staging/et131x/et131x_defs.h index d81fc77a501f..3d5193fdb003 100644 --- a/drivers/staging/et131x/et131x_defs.h +++ b/drivers/staging/et131x/et131x_defs.h @@ -95,7 +95,6 @@ #define fMP_ADAPTER_HARDWARE_ERROR 0x04000000 #define fMP_ADAPTER_REMOVE_IN_PROGRESS 0x08000000 #define fMP_ADAPTER_HALT_IN_PROGRESS 0x10000000 -#define fMP_ADAPTER_LINK_DETECTION 0x20000000 #define fMP_ADAPTER_FAIL_SEND_MASK 0x3ff00000 #define fMP_ADAPTER_NOT_READY_MASK 0x3ff00000 diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c index 50237acd6985..8c8d6b87a252 100644 --- a/drivers/staging/et131x/et131x_initpci.c +++ b/drivers/staging/et131x/et131x_initpci.c @@ -113,13 +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 @@ -274,14 +274,14 @@ void et131x_error_timer_handler(unsigned long data) dev_err(&etdev->pdev->dev, "No interrupts, in PHY coma, pm_csr = 0x%x\n", pm_csr); - if (!etdev->Bmsr.bits.link_status && + if (!(etdev->bmsr & MI_BMSR_LINK_STATUS) && etdev->RegistryPhyComa && etdev->boot_coma < 11) { etdev->boot_coma++; } if (etdev->boot_coma == 10) { - if (!etdev->Bmsr.bits.link_status + if (!(etdev->bmsr & MI_BMSR_LINK_STATUS) && etdev->RegistryPhyComa) { if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) { /* NOTE - This was originally a 'sync with @@ -312,7 +312,6 @@ void et131x_link_detection_handler(unsigned long data) spin_lock_irqsave(&etdev->Lock, flags); etdev->MediaState = NETIF_STATUS_MEDIA_DISCONNECT; - etdev->Flags &= ~fMP_ADAPTER_LINK_DETECTION; spin_unlock_irqrestore(&etdev->Lock, flags); @@ -539,7 +538,8 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, struct et131x_adapter *etdev; - /* Setup the fundamental net_device and private adapter structure elements */ + /* Setup the fundamental net_device and private adapter structure + * elements */ SET_NETDEV_DEV(netdev, &pdev->dev); /* Allocate private adapter struct and copy in relevant information */ @@ -807,12 +807,12 @@ static struct pci_device_id et131x_pci_table[] __devinitdata = { MODULE_DEVICE_TABLE(pci, et131x_pci_table); static struct pci_driver et131x_driver = { - .name = DRIVER_NAME, - .id_table = et131x_pci_table, - .probe = et131x_pci_setup, - .remove = __devexit_p(et131x_pci_remove), - .suspend = NULL, /* et131x_pci_suspend */ - .resume = NULL, /* et131x_pci_resume */ + .name = DRIVER_NAME, + .id_table = et131x_pci_table, + .probe = et131x_pci_setup, + .remove = __devexit_p(et131x_pci_remove), + .suspend = NULL, /* et131x_pci_suspend */ + .resume = NULL, /* et131x_pci_resume */ }; diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c index f716e408712b..9c33209c8409 100644 --- a/drivers/staging/et131x/et131x_isr.c +++ b/drivers/staging/et131x/et131x_isr.c @@ -222,7 +222,7 @@ irqreturn_t et131x_isr(int irq, void *dev_id) * DPC. We will clear the software copy of that in that * routine. */ - adapter->Stats.InterruptStatus = status; + adapter->stats.InterruptStatus = status; /* Schedule the ISR handler as a bottom-half task in the * kernel's tq_immediate queue, and mark the queue for @@ -244,8 +244,8 @@ void et131x_isr_handler(struct work_struct *work) { struct et131x_adapter *etdev = container_of(work, struct et131x_adapter, task); - u32 status = etdev->Stats.InterruptStatus; - ADDRESS_MAP_t __iomem *iomem = etdev->regs; + u32 status = etdev->stats.InterruptStatus; + struct address_map __iomem *iomem = etdev->regs; /* * These first two are by far the most common. Once handled, we clear @@ -268,7 +268,7 @@ void et131x_isr_handler(struct work_struct *work) u32 txdma_err; /* Following read also clears the register (COR) */ - txdma_err = readl(&iomem->txdma.TxDmaError); + txdma_err = readl(&iomem->txdma.tx_dma_error); dev_warn(&etdev->pdev->dev, "TXDMA_ERR interrupt, error = %d\n", @@ -365,7 +365,8 @@ void et131x_isr_handler(struct work_struct *work) /* Handle the PHY interrupt */ if (status & ET_INTR_PHY) { u32 pm_csr; - MI_BMSR_t BmsrInts, BmsrData; + u16 bmsr_ints; + u16 bmsr_data; u16 myisr; /* If we are in coma mode when we get this interrupt, @@ -390,14 +391,13 @@ void et131x_isr_handler(struct work_struct *work) if (!etdev->ReplicaPhyLoopbk) { MiRead(etdev, (uint8_t) offsetof(struct mi_regs, bmsr), - &BmsrData.value); + &bmsr_data); - BmsrInts.value = - etdev->Bmsr.value ^ BmsrData.value; - etdev->Bmsr.value = BmsrData.value; + bmsr_ints = etdev->bmsr ^ bmsr_data; + etdev->bmsr = bmsr_data; /* Do all the cable in / cable out stuff */ - et131x_Mii_check(etdev, BmsrData, BmsrInts); + et131x_Mii_check(etdev, bmsr_data, bmsr_ints); } } diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index 95555d25fcb3..5f25bbad36b6 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c @@ -88,82 +88,18 @@ #include "et131x_adapter.h" #include "et131x.h" -struct net_device_stats *et131x_stats(struct net_device *netdev); -int et131x_open(struct net_device *netdev); -int et131x_close(struct net_device *netdev); -int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd); -void et131x_multicast(struct net_device *netdev); -int et131x_tx(struct sk_buff *skb, struct net_device *netdev); -void et131x_tx_timeout(struct net_device *netdev); -int et131x_change_mtu(struct net_device *netdev, int new_mtu); -int et131x_set_mac_addr(struct net_device *netdev, void *new_mac); -void et131x_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); -void et131x_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); - -static const struct net_device_ops et131x_netdev_ops = { - .ndo_open = et131x_open, - .ndo_stop = et131x_close, - .ndo_start_xmit = et131x_tx, - .ndo_set_multicast_list = et131x_multicast, - .ndo_tx_timeout = et131x_tx_timeout, - .ndo_change_mtu = et131x_change_mtu, - .ndo_set_mac_address = et131x_set_mac_addr, - .ndo_validate_addr = eth_validate_addr, - .ndo_get_stats = et131x_stats, - .ndo_do_ioctl = et131x_ioctl, -}; - -/** - * et131x_device_alloc - * - * Returns pointer to the allocated and initialized net_device struct for - * this device. - * - * Create instances of net_device and wl_private for the new adapter and - * register the device's entry points in the net_device structure. - */ -struct net_device *et131x_device_alloc(void) -{ - struct net_device *netdev; - - /* Alloc net_device and adapter structs */ - netdev = alloc_etherdev(sizeof(struct et131x_adapter)); - - if (netdev == NULL) { - printk(KERN_ERR "et131x: Alloc of net_device struct failed\n"); - return NULL; - } - - /* Setup the function registration table (and other data) for a - * net_device - */ - /* netdev->init = &et131x_init; */ - /* netdev->set_config = &et131x_config; */ - netdev->watchdog_timeo = ET131X_TX_TIMEOUT; - netdev->netdev_ops = &et131x_netdev_ops; - - /* netdev->ethtool_ops = &et131x_ethtool_ops; */ - - /* Poll? */ - /* netdev->poll = &et131x_poll; */ - /* netdev->poll_controller = &et131x_poll_controller; */ - return netdev; -} - /** * et131x_stats - Return the current device statistics. * @netdev: device whose stats are being queried * * Returns 0 on success, errno on failure (as defined in errno.h) */ -struct net_device_stats *et131x_stats(struct net_device *netdev) +static struct net_device_stats *et131x_stats(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); struct net_device_stats *stats = &adapter->net_stats; - CE_STATS_t *devstat = &adapter->Stats; + struct ce_stats *devstat = &adapter->stats; - stats->rx_packets = devstat->ipackets; - stats->tx_packets = devstat->opackets; stats->rx_errors = devstat->length_err + devstat->alignment_err + devstat->crc_err + devstat->code_violations + devstat->other_errors; stats->tx_errors = devstat->max_pkt_error; @@ -226,7 +162,7 @@ int et131x_open(struct net_device *netdev) /* Enable device interrupts */ et131x_enable_interrupts(adapter); - adapter->Flags |= fMP_ADAPTER_INTERRUPT_IN_USE; + adapter->flags |= fMP_ADAPTER_INTERRUPT_IN_USE; /* We're ready to move some data, so start the queue */ netif_start_queue(netdev); @@ -254,7 +190,7 @@ int et131x_close(struct net_device *netdev) et131x_disable_interrupts(adapter); /* Deregistering ISR */ - adapter->Flags &= ~fMP_ADAPTER_INTERRUPT_IN_USE; + adapter->flags &= ~fMP_ADAPTER_INTERRUPT_IN_USE; free_irq(netdev->irq, netdev); /* Stop the error timer */ @@ -278,7 +214,7 @@ int et131x_ioctl_mii(struct net_device *netdev, struct ifreq *reqbuf, int cmd) switch (cmd) { case SIOCGMIIPHY: - data->phy_id = etdev->Stats.xcvr_addr; + data->phy_id = etdev->stats.xcvr_addr; break; case SIOCGMIIREG: @@ -510,18 +446,14 @@ void et131x_tx_timeout(struct net_device *netdev) struct tcb *tcb; unsigned long flags; - /* Just skip this part if the adapter is doing link detection */ - if (etdev->Flags & fMP_ADAPTER_LINK_DETECTION) - return; - /* Any nonrecoverable hardware error? * Checks adapter->flags for any failure in phy reading */ - if (etdev->Flags & fMP_ADAPTER_NON_RECOVER_ERROR) + if (etdev->flags & fMP_ADAPTER_NON_RECOVER_ERROR) return; /* Hardware failure? */ - if (etdev->Flags & fMP_ADAPTER_HARDWARE_ERROR) { + if (etdev->flags & fMP_ADAPTER_HARDWARE_ERROR) { dev_err(&etdev->pdev->dev, "hardware error - reset\n"); return; } @@ -539,7 +471,7 @@ void et131x_tx_timeout(struct net_device *netdev) flags); dev_warn(&etdev->pdev->dev, - "Send stuck - reset. tcb->WrIndex %x, Flags 0x%08x\n", + "Send stuck - reset. tcb->WrIndex %x, flags 0x%08x\n", tcb->index, tcb->flags); @@ -608,7 +540,7 @@ int et131x_change_mtu(struct net_device *netdev, int new_mtu) et131x_adapter_setup(adapter); /* Enable interrupts */ - if (adapter->Flags & fMP_ADAPTER_INTERRUPT_IN_USE) + if (adapter->flags & fMP_ADAPTER_INTERRUPT_IN_USE) et131x_enable_interrupts(adapter); /* Restart the Tx and Rx DMA engines */ @@ -690,7 +622,7 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac) et131x_adapter_setup(adapter); /* Enable interrupts */ - if (adapter->Flags & fMP_ADAPTER_INTERRUPT_IN_USE) + if (adapter->flags & fMP_ADAPTER_INTERRUPT_IN_USE) et131x_enable_interrupts(adapter); /* Restart the Tx and Rx DMA engines */ @@ -701,3 +633,54 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac) netif_wake_queue(netdev); return result; } + +static const struct net_device_ops et131x_netdev_ops = { + .ndo_open = et131x_open, + .ndo_stop = et131x_close, + .ndo_start_xmit = et131x_tx, + .ndo_set_multicast_list = et131x_multicast, + .ndo_tx_timeout = et131x_tx_timeout, + .ndo_change_mtu = et131x_change_mtu, + .ndo_set_mac_address = et131x_set_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_get_stats = et131x_stats, + .ndo_do_ioctl = et131x_ioctl, +}; + +/** + * et131x_device_alloc + * + * Returns pointer to the allocated and initialized net_device struct for + * this device. + * + * Create instances of net_device and wl_private for the new adapter and + * register the device's entry points in the net_device structure. + */ +struct net_device *et131x_device_alloc(void) +{ + struct net_device *netdev; + + /* Alloc net_device and adapter structs */ + netdev = alloc_etherdev(sizeof(struct et131x_adapter)); + + if (netdev == NULL) { + printk(KERN_ERR "et131x: Alloc of net_device struct failed\n"); + return NULL; + } + + /* Setup the function registration table (and other data) for a + * net_device + */ + /* netdev->init = &et131x_init; */ + /* netdev->set_config = &et131x_config; */ + netdev->watchdog_timeo = ET131X_TX_TIMEOUT; + netdev->netdev_ops = &et131x_netdev_ops; + + /* netdev->ethtool_ops = &et131x_ethtool_ops; */ + + /* Poll? */ + /* netdev->poll = &et131x_poll; */ + /* netdev->poll_controller = &et131x_poll_controller; */ + return netdev; +} + diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000.conf b/drivers/staging/ft1000/ft1000-pcmcia/ft1000.conf deleted file mode 100644 index e2321a42e312..000000000000 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000.conf +++ /dev/null @@ -1,14 +0,0 @@ -device "ft1000_cs" - class "network" module "ft1000","ft1000_cs" - -card "flarion FT1000" - manfid 0x02cc, 0x0100 - bind "ft1000_cs" - -card "flarion FT1000" - manfid 0x02cc, 0x1000 - bind "ft1000_cs" - -card "flarion FT1000" - manfid 0x02cc, 0x1300 - bind "ft1000_cs" diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h b/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h index 61e1cfc80446..3b0130fe6083 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h @@ -1,409 +1,89 @@ -//--------------------------------------------------------------------------- -// FT1000 driver for Flarion Flash OFDM NIC Device -// -// Copyright (C) 2002 Flarion Technologies, 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. 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. -//--------------------------------------------------------------------------- -// -// File: ft1000.h -// -// Description: Common structures and defines -// -// History: -// 8/29/02 Whc Ported to Linux. -// 7/19/04 Whc Drop packet and cmd msg with pseudo header -// checksum -// 10/27/04 Whc Added dynamic downloading of test image. -// 01/11/04 Whc Added support for Magnemite ASIC -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + FT1000 driver for Flarion Flash OFDM NIC Device + + Copyright (C) 2002 Flarion Technologies, 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. 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. +--------------------------------------------------------------------------- + Description: Common structures and defines +---------------------------------------------------------------------------*/ #ifndef _FT1000H_ #define _FT1000H_ +#include "../ft1000.h" -#define FT1000_DRV_VER 0x01010300 +#define FT1000_DRV_VER 0x01010300 -#define DSPVERSZ 4 -#define HWSERNUMSZ 16 -#define SKUSZ 20 -#define EUISZ 8 -#define MODESZ 2 -#define CALVERSZ 2 -#define CALDATESZ 6 +#define FT1000_DPRAM_BASE 0x0000 /* Dual Port RAM starting offset */ -// Pseudo Header structure -typedef struct _PSEUDO_HDR -{ - unsigned short length; // length of msg body - unsigned char source; // hardware source id - // Host = 0x10 - // Dsp = 0x20 - unsigned char destination; // hardware destination id (refer to source) - unsigned char portdest; // software destination port id - // Host = 0x00 - // Applicaton Broadcast = 0x10 - // Network Stack = 0x20 - // Dsp OAM = 0x80 - // Dsp Airlink = 0x90 - // Dsp Loader = 0xa0 - // Dsp MIP = 0xb0 - unsigned char portsrc; // software source port id (refer to portdest) - unsigned short sh_str_id; // not used - unsigned char control; // not used - unsigned char rsvd1; - unsigned char seq_num; // message sequence number - unsigned char rsvd2; - unsigned short qos_class; // not used - unsigned short checksum; // pseudo header checksum -} __attribute__ ((packed)) PSEUDO_HDR, *PPSEUDO_HDR; +/* Maximum number of occurrence of pseudo header errors before resetting PC Card. */ +#define MAX_PH_ERR 300 -// Definitions to maintain compatibility between other platforms -#define UCHAR u8 -#define USHORT u16 -#define ULONG u32 -#define BOOLEAN u8 -#define PULONG u32 * -#define PUSHORT u16 * -#define PUCHAR u8 * -#define PCHAR u8 * -#define UINT u32 +#define SUCCESS 0x00 +#define FAILURE 0x01 -#define ELECTRABUZZ_ID 0 // ASIC ID for Electrabuzz -#define MAGNEMITE_ID 0x1a01 // ASIC ID for Magnemite - -// MEMORY MAP common to both ELECTRABUZZ and MAGNEMITE -#define FT1000_REG_DPRAM_ADDR 0x000E // DPADR - Dual Port Ram Indirect Address Register -#define FT1000_REG_SUP_CTRL 0x0020 // HCTR - Host Control Register -#define FT1000_REG_SUP_STAT 0x0022 // HSTAT - Host Status Register -#define FT1000_REG_RESET 0x0024 // HCTR - Host Control Register -#define FT1000_REG_SUP_ISR 0x0026 // HISR - Host Interrupt Status Register -#define FT1000_REG_SUP_IMASK 0x0028 // HIMASK - Host Interrupt Mask -#define FT1000_REG_DOORBELL 0x002a // DBELL - Door Bell Register -#define FT1000_REG_ASIC_ID 0x002e // ASICID - ASIC Identification Number - // (Electrabuzz=0 Magnemite=0x1A01) - -// MEMORY MAP FOR ELECTRABUZZ ASIC - -#define FT1000_REG_UFIFO_STAT 0x0000 // UFSR - Uplink FIFO status register -#define FT1000_REG_UFIFO_BEG 0x0002 // UFBR - Uplink FIFO beginning register -#define FT1000_REG_UFIFO_MID 0x0004 // UFMR - Uplink FIFO middle register -#define FT1000_REG_UFIFO_END 0x0006 // UFER - Uplink FIFO end register -#define FT1000_REG_DFIFO_STAT 0x0008 // DFSR - Downlink FIFO status register -#define FT1000_REG_DFIFO 0x000A // DFR - Downlink FIFO Register -#define FT1000_REG_DPRAM_DATA 0x000C // DPRAM - Dual Port Indirect Data Register -#define FT1000_REG_WATERMARK 0x0010 // WMARK - Watermark Register - -// MEMORY MAP FOR MAGNEMITE -#define FT1000_REG_MAG_UFDR 0x0000 // UFDR - Uplink FIFO Data Register (32-bits) -#define FT1000_REG_MAG_UFDRL 0x0000 // UFDRL - Uplink FIFO Data Register low-word (16-bits) -#define FT1000_REG_MAG_UFDRH 0x0002 // UFDRH - Uplink FIFO Data Register high-word (16-bits) -#define FT1000_REG_MAG_UFER 0x0004 // UFER - Uplink FIFO End Register -#define FT1000_REG_MAG_UFSR 0x0006 // UFSR - Uplink FIFO Status Register -#define FT1000_REG_MAG_DFR 0x0008 // DFR - Downlink FIFO Register (32-bits) -#define FT1000_REG_MAG_DFRL 0x0008 // DFRL - Downlink FIFO Register low-word (16-bits) -#define FT1000_REG_MAG_DFRH 0x000a // DFRH - Downlink FIFO Register high-word (16-bits) -#define FT1000_REG_MAG_DFSR 0x000c // DFSR - Downlink FIFO Status Register -#define FT1000_REG_MAG_DPDATA 0x0010 // DPDATA - Dual Port RAM Indirect Data Register (32-bits) -#define FT1000_REG_MAG_DPDATAL 0x0010 // DPDATAL - Dual Port RAM Indirect Data Register low-word (16-bits) -#define FT1000_REG_MAG_DPDATAH 0x0012 // DPDATAH - Dual Port RAM Indirect Data Register high-word (16-bits) -#define FT1000_REG_MAG_WATERMARK 0x002c // WMARK - Watermark Register - -// Reserved Dual Port RAM offsets for Electrabuzz -#define FT1000_DPRAM_TX_BASE 0x0002 // Host to PC Card Messaging Area -#define FT1000_DPRAM_RX_BASE 0x0800 // PC Card to Host Messaging Area -#define FT1000_FIFO_LEN 0x7FC // total length for DSP FIFO tracking -#define FT1000_HI_HO 0x7FE // heartbeat with HI/HO -#define FT1000_DSP_STATUS 0xFFE // dsp status - non-zero is a request to reset dsp -#define FT1000_DSP_LED 0xFFA // dsp led status for PAD device -#define FT1000_DSP_CON_STATE 0xFF8 // DSP Connection Status Info -#define FT1000_DPRAM_FEFE 0x002 // location for dsp ready indicator -#define FT1000_DSP_TIMER0 0x1FF0 // Timer Field from Basestation -#define FT1000_DSP_TIMER1 0x1FF2 // Timer Field from Basestation -#define FT1000_DSP_TIMER2 0x1FF4 // Timer Field from Basestation -#define FT1000_DSP_TIMER3 0x1FF6 // Timer Field from Basestation - -// Reserved Dual Port RAM offsets for Magnemite -#define FT1000_DPRAM_MAG_TX_BASE 0x0000 // Host to PC Card Messaging Area -#define FT1000_DPRAM_MAG_RX_BASE 0x0200 // PC Card to Host Messaging Area -#define FT1000_MAG_FIFO_LEN 0x1FF // total length for DSP FIFO tracking -#define FT1000_MAG_FIFO_LEN_INDX 0x1 // low-word index -#define FT1000_MAG_HI_HO 0x1FF // heartbeat with HI/HO -#define FT1000_MAG_HI_HO_INDX 0x0 // high-word index -#define FT1000_MAG_DSP_LED 0x3FE // dsp led status for PAD device -#define FT1000_MAG_DSP_LED_INDX 0x0 // dsp led status for PAD device - -#define FT1000_MAG_DSP_CON_STATE 0x3FE // DSP Connection Status Info -#define FT1000_MAG_DSP_CON_STATE_INDX 0x1 // DSP Connection Status Info - -#define FT1000_MAG_DPRAM_FEFE 0x000 // location for dsp ready indicator -#define FT1000_MAG_DPRAM_FEFE_INDX 0x0 // location for dsp ready indicator - -#define FT1000_MAG_DSP_TIMER0 0x3FC // Timer Field from Basestation -#define FT1000_MAG_DSP_TIMER0_INDX 0x1 - -#define FT1000_MAG_DSP_TIMER1 0x3FC // Timer Field from Basestation -#define FT1000_MAG_DSP_TIMER1_INDX 0x0 - -#define FT1000_MAG_DSP_TIMER2 0x3FD // Timer Field from Basestation -#define FT1000_MAG_DSP_TIMER2_INDX 0x1 - -#define FT1000_MAG_DSP_TIMER3 0x3FD // Timer Field from Basestation -#define FT1000_MAG_DSP_TIMER3_INDX 0x0 - -#define FT1000_MAG_TOTAL_LEN 0x200 -#define FT1000_MAG_TOTAL_LEN_INDX 0x1 - -#define FT1000_MAG_PH_LEN 0x200 -#define FT1000_MAG_PH_LEN_INDX 0x0 - -#define FT1000_MAG_PORT_ID 0x201 -#define FT1000_MAG_PORT_ID_INDX 0x0 - -#define HOST_INTF_LE 0x0 // Host interface little endian mode -#define HOST_INTF_BE 0x1 // Host interface big endian mode - -// PC Card to Host Doorbell assignments -#define FT1000_DB_DPRAM_RX 0x0001 // this value indicates that DSP has - // data for host in DPRAM -#define FT1000_ASIC_RESET_REQ 0x0004 // DSP requesting host to reset the ASIC -#define FT1000_DSP_ASIC_RESET 0x0008 // DSP indicating host that it will reset the ASIC -#define FT1000_DB_COND_RESET 0x0010 // DSP request for a card reset. - -// Host to PC Card Doorbell assignments -#define FT1000_DB_DPRAM_TX 0x0100 // this value indicates that host has - // data for DSP in DPRAM. -#define FT1000_ASIC_RESET_DSP 0x0400 // Responds to FT1000_ASIC_RESET_REQ -#define FT1000_DB_HB 0x1000 // Indicates that supervisor - // has a heartbeat message for DSP. - -#define FT1000_DPRAM_BASE 0x0000 // Dual Port RAM starting offset - -#define hi 0x6869 // PC Card heartbeat values -#define ho 0x686f // PC Card heartbeat values - -// Magnemite specific defines -#define hi_mag 0x6968 // Byte swap hi to avoid additional system call -#define ho_mag 0x6f68 // Byte swap ho to avoid additional system call - -// -// Bit field definitions for Host Interrupt Status Register -// -// Indicate the cause of an interrupt. -// -#define ISR_EMPTY 0x00 // no bits set -#define ISR_DOORBELL_ACK 0x01 // Doorbell acknowledge from DSP -#define ISR_DOORBELL_PEND 0x02 // Doorbell pending from DSP -#define ISR_RCV 0x04 // Packet available in Downlink FIFO -#define ISR_WATERMARK 0x08 // Watermark requirements satisfied - -// Bit field definition for Host Interrupt Mask -#define ISR_MASK_NONE 0x0000 // no bits set -#define ISR_MASK_DOORBELL_ACK 0x0001 // Doorbell acknowledge mask -#define ISR_MASK_DOORBELL_PEND 0x0002 // Doorbell pending mask -#define ISR_MASK_RCV 0x0004 // Downlink Packet available mask -#define ISR_MASK_WATERMARK 0x0008 // Watermark interrupt mask -#define ISR_MASK_ALL 0xffff // Mask all interrupts - -// Bit field definition for Host Control Register -#define DSP_RESET_BIT 0x0001 // Bit field to control dsp reset state - // (0 = out of reset 1 = reset) -#define ASIC_RESET_BIT 0x0002 // Bit field to control ASIC reset state - // (0 = out of reset 1 = reset) - -// Default interrupt mask (Enable Doorbell pending and Packet available interrupts) -#define ISR_DEFAULT_MASK 0x7ff9 - -// Application specific IDs -#define DSPID 0x20 -#define HOSTID 0x10 -#define DSPAIRID 0x90 -#define DRIVERID 0x00 -#define NETWORKID 0x20 - -// Size of DPRAM Message -#define MAX_CMD_SQSIZE 1780 - -#define ENET_MAX_SIZE 1514 -#define ENET_HEADER_SIZE 14 - -#define SLOWQ_TYPE 0 -#define FASTQ_TYPE 1 - -#define MAX_DSP_SESS_REC 1024 - -#define DSP_QID_OFFSET 4 -#define PSEUDOSZ 16 -#define PSEUDOSZWRD 8 - -// Maximum number of occurrence of pseudo header errors before resetting PC Card. -#define MAX_PH_ERR 300 - -// Driver message types -#define MEDIA_STATE 0x0010 -#define TIME_UPDATE 0x0020 -#define DSP_PROVISION 0x0030 -#define DSP_INIT_MSG 0x0050 -#define DSP_HIBERNATE 0x0060 - -#define DSP_STORE_INFO 0x0070 -#define DSP_GET_INFO 0x0071 -#define GET_DRV_ERR_RPT_MSG 0x0073 -#define RSP_DRV_ERR_RPT_MSG 0x0074 - -// Driver Error Messages for DSP -#define DSP_HB_INFO 0x7ef0 -#define DSP_FIFO_INFO 0x7ef1 -#define DSP_CONDRESET_INFO 0x7ef2 -#define DSP_CMDLEN_INFO 0x7ef3 -#define DSP_CMDPHCKSUM_INFO 0x7ef4 -#define DSP_PKTPHCKSUM_INFO 0x7ef5 -#define DSP_PKTLEN_INFO 0x7ef6 -#define DSP_USER_RESET 0x7ef7 -#define FIFO_FLUSH_MAXLIMIT 0x7ef8 -#define FIFO_FLUSH_BADCNT 0x7ef9 -#define FIFO_ZERO_LEN 0x7efa - -#define HOST_QID_OFFSET 5 -#define QTYPE_OFFSET 13 - -#define SUCCESS 0x00 -#define FAILURE 0x01 -#define TRUE 0x1 -#define FALSE 0x0 - -#define MAX_NUM_APP 6 - -#define MAXIMUM_ASIC_HB_CNT 15 - -typedef struct _DRVMSG { - PSEUDO_HDR pseudo; - u16 type; - u16 length; - u8 data[0]; -} __attribute__ ((packed)) DRVMSG, *PDRVMSG; - -typedef struct _MEDIAMSG { - PSEUDO_HDR pseudo; - u16 type; - u16 length; - u16 state; - u32 ip_addr; - u32 net_mask; - u32 gateway; - u32 dns_1; - u32 dns_2; -} __attribute__ ((packed)) MEDIAMSG, *PMEDIAMSG; - -typedef struct _TIMEMSG { - PSEUDO_HDR pseudo; - u16 type; - u16 length; - u8 timeval[8]; -} __attribute__ ((packed)) TIMEMSG, *PTIMEMSG; - -typedef struct _DSPINITMSG { - PSEUDO_HDR pseudo; - u16 type; - u16 length; - u8 DspVer[DSPVERSZ]; // DSP version number - u8 HwSerNum[HWSERNUMSZ]; // Hardware Serial Number - u8 Sku[SKUSZ]; // SKU - u8 eui64[EUISZ]; // EUI64 - u8 ProductMode[MODESZ]; // Product Mode (Market/Production) - u8 RfCalVer[CALVERSZ]; // Rf Calibration version - u8 RfCalDate[CALDATESZ]; // Rf Calibration date -} __attribute__ ((packed)) DSPINITMSG, *PDSPINITMSG; - -typedef struct _DSPHIBERNATE { - PSEUDO_HDR pseudo; - u16 type; - u16 length; - u32 timeout; - u16 sess_info[0]; -} DSPHIBERNATE, *PDSPHIBERNATE; - -typedef struct _APP_INFO_BLOCK -{ - u32 fileobject; // Application's file object - u16 app_id; // Application id -} APP_INFO_BLOCK, *PAPP_INFO_BLOCK; - -typedef struct _PROV_RECORD { - struct list_head list; - u8 *pprov_data; -} PROV_RECORD, *PPROV_RECORD; - -typedef struct _FT1000_INFO { - struct net_device_stats stats; - u16 DrvErrNum; - u16 AsicID; - int ASICResetNum; - int DspAsicReset; - int PktIntfErr; - int DSPResetNum; - int NumIOCTLBufs; - int IOCTLBufLvl; - int DeviceCreated; - int CardReady; - int DspHibernateFlag; - int DSPReady; - u8 DeviceName[15]; - int DeviceMajor; - int registered; - int mediastate; - u16 packetseqnum; - u8 squeseqnum; // sequence number on slow queue - spinlock_t dpram_lock; - u16 CurrentInterruptEnableMask; - int InterruptsEnabled; - u16 fifo_cnt; - u8 DspVer[DSPVERSZ]; // DSP version number - u8 HwSerNum[HWSERNUMSZ]; // Hardware Serial Number - u8 Sku[SKUSZ]; // SKU - u8 eui64[EUISZ]; // EUI64 - time_t ConTm; // Connection Time - u16 LedStat; - u16 ConStat; - u16 ProgConStat; - u8 ProductMode[MODESZ]; - u8 RfCalVer[CALVERSZ]; - u8 RfCalDate[CALDATESZ]; - u16 DSP_TIME[4]; - struct list_head prov_list; - int appcnt; - APP_INFO_BLOCK app_info[MAX_NUM_APP]; - u16 DSPInfoBlklen; - u16 DrvMsgPend; +struct ft1000_info { + struct net_device_stats stats; + u16 DrvErrNum; + u16 AsicID; + int PktIntfErr; + int CardReady; + int registered; + int mediastate; + u16 packetseqnum; + u8 squeseqnum; /* sequence number on slow queue */ + spinlock_t dpram_lock; + u16 fifo_cnt; + u8 DspVer[DSPVERSZ]; /* DSP version number */ + u8 HwSerNum[HWSERNUMSZ]; /* Hardware Serial Number */ + u8 Sku[SKUSZ]; /* SKU */ + u8 eui64[EUISZ]; /* EUI64 */ + time_t ConTm; /* Connection Time */ + u16 LedStat; + u16 ConStat; + u16 ProgConStat; + u8 ProductMode[MODESZ]; + u8 RfCalVer[CALVERSZ]; + u8 RfCalDate[CALDATESZ]; + u16 DSP_TIME[4]; + struct list_head prov_list; + u16 DSPInfoBlklen; int (*ft1000_reset)(void *); - void *link; - u16 DSPInfoBlk[MAX_DSP_SESS_REC]; - union { - u16 Rec[MAX_DSP_SESS_REC]; - u32 MagRec[MAX_DSP_SESS_REC/2]; - } DSPSess; + void *link; + u16 DSPInfoBlk[MAX_DSP_SESS_REC]; + union { + u16 Rec[MAX_DSP_SESS_REC]; + u32 MagRec[MAX_DSP_SESS_REC/2]; + } DSPSess; struct proc_dir_entry *proc_ft1000; char netdevname[IFNAMSIZ]; -} FT1000_INFO, *PFT1000_INFO; +}; -typedef struct _DPRAM_BLK { - struct list_head list; - u16 *pbuffer; -} __attribute__ ((packed)) DPRAM_BLK, *PDPRAM_BLK; - -extern u16 ft1000_read_dpram (struct net_device *dev, int offset); +extern u16 ft1000_read_dpram(struct net_device *dev, int offset); extern void card_bootload(struct net_device *dev); -extern u16 ft1000_read_dpram_mag_16 (struct net_device *dev, int offset, int Index); -extern u32 ft1000_read_dpram_mag_32 (struct net_device *dev, int offset); -void ft1000_write_dpram_mag_32 (struct net_device *dev, int offset, u32 value); +extern u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index); +extern u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset); +void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value); -#endif // _FT1000H_ +/* Read the value of a given ASIC register. */ +static inline u16 ft1000_read_reg(struct net_device *dev, u16 offset) +{ + return inw(dev->base_addr + offset); +} + +/* Set the value of a given ASIC register. */ +static inline void ft1000_write_reg(struct net_device *dev, u16 offset, u16 value) +{ + outw(value, dev->base_addr + offset); +} + +#endif diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c index 68ea035635f4..6a1c1d4dcca2 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c @@ -29,52 +29,16 @@ #include #include #include -#include -#include -#include -#include -#include -#include - #include -#include - #include -#include #include -#include -#include -#include -#include - /*====================================================================*/ -/* Module parameters */ - -#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") - MODULE_AUTHOR("Wai Chan"); MODULE_DESCRIPTION("FT1000 PCMCIA driver"); MODULE_LICENSE("GPL"); -/* Newer, simpler way of listing specific interrupts */ - -/* The old way: bit map of interrupts to choose from */ -/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */ - -/* - All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If - you do not define PCMCIA_DEBUG at all, all the debug code will be - left out. If you compile with PCMCIA_DEBUG=0, the debug code will - be present but disabled. -*/ -#ifdef FT_DEBUG -#define DEBUG(n, args...) printk(KERN_DEBUG args) -#else -#define DEBUG(n, args...) -#endif - /*====================================================================*/ struct net_device *init_ft1000_card(struct pcmcia_device *link, @@ -82,100 +46,39 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, void stop_ft1000_card(struct net_device *); static int ft1000_config(struct pcmcia_device *link); -static void ft1000_release(struct pcmcia_device *link); - -/* - The attach() and detach() entry points are used to create and destroy - "instances" of the driver, where each instance represents everything - needed to manage one actual PCMCIA card. -*/ - static void ft1000_detach(struct pcmcia_device *link); -static int ft1000_attach(struct pcmcia_device *link); - -typedef struct local_info_t { - struct pcmcia_device *link; - struct net_device *dev; -} local_info_t; - -#define MAX_ASIC_RESET_CNT 10 -#define COR_DEFAULT 0x55 +static int ft1000_attach(struct pcmcia_device *link); /*====================================================================*/ -static void ft1000_reset(struct pcmcia_device * link) +static void ft1000_reset(struct pcmcia_device *link) { pcmcia_reset_card(link->socket); } -/*====================================================================== - - -======================================================================*/ - static int ft1000_attach(struct pcmcia_device *link) { - - local_info_t *local; - - DEBUG(0, "ft1000_cs: ft1000_attach()\n"); - - local = kzalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) { - return -ENOMEM; - } - local->link = link; - - link->priv = local; - local->dev = NULL; - + link->priv = NULL; link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; return ft1000_config(link); - -} /* ft1000_attach */ - -/*====================================================================== - - 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 ft1000_detach(struct pcmcia_device *link) { - struct net_device *dev = ((local_info_t *) link->priv)->dev; + struct net_device *dev = link->priv; - DEBUG(0, "ft1000_cs: ft1000_detach(0x%p)\n", link); - - if (link == NULL) { - DEBUG(0,"ft1000_cs:ft1000_detach: Got a NULL pointer\n"); - return; - } - - if (dev) { + if (dev) stop_ft1000_card(dev); - } pcmcia_disable_device(link); - - /* This points to the parent local_info_t struct */ free_netdev(dev); +} -} /* ft1000_detach */ - -/*====================================================================== - - Check if the io window is configured - -======================================================================*/ int ft1000_confcheck(struct pcmcia_device *link, void *priv_data) { - return pcmcia_request_io(link); -} /* ft1000_confcheck */ +} /*====================================================================== @@ -187,7 +90,7 @@ int ft1000_confcheck(struct pcmcia_device *link, void *priv_data) static int ft1000_config(struct pcmcia_device *link) { - int ret; + int ret; dev_dbg(&link->dev, "ft1000_cs: ft1000_config(0x%p)\n", link); @@ -205,9 +108,8 @@ static int ft1000_config(struct pcmcia_device *link) goto failed; } - ((local_info_t *) link->priv)->dev = init_ft1000_card(link, - &ft1000_reset); - if (((local_info_t *) link->priv)->dev == NULL) { + link->priv = init_ft1000_card(link, &ft1000_reset); + if (!link->priv) { printk(KERN_INFO "ft1000: Could not register as network device\n"); goto failed; } @@ -216,57 +118,13 @@ static int ft1000_config(struct pcmcia_device *link) return 0; failed: - ft1000_release(link); + pcmcia_disable_device(link); return -ENODEV; - -} /* ft1000_config */ - -/*====================================================================== - - After a card is removed, ft1000_release() will unregister the - device, and release the PCMCIA configuration. If the device is - still open, this will be postponed until it is closed. - -======================================================================*/ - -static void ft1000_release(struct pcmcia_device * link) -{ - - DEBUG(0, "ft1000_cs: ft1000_release(0x%p)\n", link); - - /* - If the device is currently in use, we won't release until it - is actually closed, because until then, we can't be sure that - no one will try to access the device or its data structures. - */ - - /* - In a normal driver, additional code may be needed to release - other kernel data structures associated with this device. - */ - kfree((local_info_t *) link->priv); - /* Don't bother checking to see if these succeed or not */ - - pcmcia_disable_device(link); -} /* ft1000_release */ - -/*====================================================================== - - The card status event handler. Mostly, this schedules other - stuff to run after an event is received. - - When a CARD_REMOVAL event is received, we immediately set a - private flag to block future accesses to this device. All the - functions that actually access the device should check this flag - to make sure the card is still present. - -======================================================================*/ +} static int ft1000_suspend(struct pcmcia_device *link) { - struct net_device *dev = ((local_info_t *) link->priv)->dev; - - DEBUG(1, "ft1000_cs: ft1000_event(0x%06x)\n", event); + struct net_device *dev = link->priv; if (link->open) netif_device_detach(dev); @@ -275,13 +133,9 @@ static int ft1000_suspend(struct pcmcia_device *link) static int ft1000_resume(struct pcmcia_device *link) { -/* struct net_device *dev = link->priv; - */ return 0; } - - /*====================================================================*/ static const struct pcmcia_device_id ft1000_ids[] = { @@ -294,26 +148,22 @@ static const struct pcmcia_device_id ft1000_ids[] = { MODULE_DEVICE_TABLE(pcmcia, ft1000_ids); static struct pcmcia_driver ft1000_cs_driver = { - .owner = THIS_MODULE, - .drv = { - .name = "ft1000_cs", - }, - .probe = ft1000_attach, - .remove = ft1000_detach, + .owner = THIS_MODULE, + .name = "ft1000_cs", + .probe = ft1000_attach, + .remove = ft1000_detach, .id_table = ft1000_ids, - .suspend = ft1000_suspend, - .resume = ft1000_resume, + .suspend = ft1000_suspend, + .resume = ft1000_resume, }; static int __init init_ft1000_cs(void) { - DEBUG(0, "ft1000_cs: loading\n"); return pcmcia_register_driver(&ft1000_cs_driver); } static void __exit exit_ft1000_cs(void) { - DEBUG(0, "ft1000_cs: unloading\n"); pcmcia_unregister_driver(&ft1000_cs_driver); } diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dev.h b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dev.h deleted file mode 100644 index 0b63f051f27c..000000000000 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dev.h +++ /dev/null @@ -1,66 +0,0 @@ -//--------------------------------------------------------------------------- -// FT1000 driver for Flarion Flash OFDM NIC Device -// -// Copyright (C) 2002 Flarion Technologies, 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. 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. -//--------------------------------------------------------------------------- -// -// File: ft1000_dev.h -// -// Description: Register definitions and bit masks for the FT1000 NIC -// -// History: -// 2/5/02 Ivan Bohannon Written. -// 8/29/02 Whc Ported to Linux. -// -//--------------------------------------------------------------------------- -#ifndef _FT1000_DEVH_ -#define _FT1000_DEVH_ - -//--------------------------------------------------------------------------- -// -// Function: ft1000_read_reg -// Description: This function will read the value of a given ASIC register. -// Input: -// dev - device structure -// offset - ASIC register offset -// Output: -// data - ASIC register value -// -//--------------------------------------------------------------------------- -static inline u16 ft1000_read_reg (struct net_device *dev, u16 offset) { - u16 data = 0; - - data = inw(dev->base_addr + offset); - - return (data); -} - -//--------------------------------------------------------------------------- -// -// Function: ft1000_write_reg -// Description: This function will set the value for a given ASIC register. -// Input: -// dev - device structure -// offset - ASIC register offset -// value - value to write -// Output: -// None. -// -//--------------------------------------------------------------------------- -static inline void ft1000_write_reg (struct net_device *dev, u16 offset, u16 value) { - outw (value, dev->base_addr + offset); -} - -#endif // _FT1000_DEVH_ - diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c index fb375ea26dd2..c956857e2d58 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c @@ -34,7 +34,6 @@ #include #include -#include "ft1000_dev.h" #include "ft1000.h" #include "boot.h" @@ -87,26 +86,14 @@ #define STATE_DONE_PROV 0x06 #define STATE_DONE_FILE 0x07 -USHORT get_handshake(struct net_device *dev, USHORT expected_value); -void put_handshake(struct net_device *dev, USHORT handshake_value); -USHORT get_request_type(struct net_device *dev); +u16 get_handshake(struct net_device *dev, u16 expected_value); +void put_handshake(struct net_device *dev, u16 handshake_value); +u16 get_request_type(struct net_device *dev); long get_request_value(struct net_device *dev); void put_request_value(struct net_device *dev, long lvalue); -USHORT hdr_checksum(PPSEUDO_HDR pHdr); +u16 hdr_checksum(struct pseudo_hdr *pHdr); -typedef struct _DSP_FILE_HDR { - u32 build_date; - u32 dsp_coff_date; - u32 loader_code_address; - u32 loader_code_size; - u32 loader_code_end; - u32 dsp_code_address; - u32 dsp_code_size; - u32 dsp_code_end; - u32 reserved[8]; -} __attribute__ ((packed)) DSP_FILE_HDR, *PDSP_FILE_HDR; - -typedef struct _DSP_FILE_HDR_5 { +struct dsp_file_hdr { u32 version_id; // Version ID of this image format. u32 package_id; // Package ID of code release. u32 build_date; // Date/time stamp when file was built. @@ -118,18 +105,9 @@ typedef struct _DSP_FILE_HDR_5 { u32 version_data_offset; // Offset were scrambled version data begins. u32 version_data_size; // Size, in words, of scrambled version data. u32 nDspImages; // Number of DSP images in file. -} __attribute__ ((packed)) DSP_FILE_HDR_5, *PDSP_FILE_HDR_5; +} __attribute__ ((packed)); -typedef struct _DSP_IMAGE_INFO { - u32 coff_date; // Date/time when DSP Coff image was built. - u32 begin_offset; // Offset in file where image begins. - u32 end_offset; // Offset in file where image begins. - u32 run_address; // On chip Start address of DSP code. - u32 image_size; // Size of image. - u32 version; // Embedded version # of DSP code. -} __attribute__ ((packed)) DSP_IMAGE_INFO, *PDSP_IMAGE_INFO; - -typedef struct _DSP_IMAGE_INFO_V6 { +struct dsp_image_info { u32 coff_date; // Date/time when DSP Coff image was built. u32 begin_offset; // Offset in file where image begins. u32 end_offset; // Offset in file where image begins. @@ -138,20 +116,20 @@ typedef struct _DSP_IMAGE_INFO_V6 { u32 version; // Embedded version # of DSP code. unsigned short checksum; // Dsp File checksum unsigned short pad1; -} __attribute__ ((packed)) DSP_IMAGE_INFO_V6, *PDSP_IMAGE_INFO_V6; +} __attribute__ ((packed)); void card_bootload(struct net_device *dev) { - FT1000_INFO *info = (PFT1000_INFO) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); unsigned long flags; - PULONG pdata; - UINT size; - UINT i; - ULONG templong; + u32 *pdata; + u32 size; + u32 i; + u32 templong; DEBUG(0, "card_bootload is called\n"); - pdata = (PULONG) bootimage; + pdata = (u32 *) bootimage; size = sizeof(bootimage); // check for odd word @@ -172,11 +150,11 @@ void card_bootload(struct net_device *dev) spin_unlock_irqrestore(&info->dpram_lock, flags); } -USHORT get_handshake(struct net_device *dev, USHORT expected_value) +u16 get_handshake(struct net_device *dev, u16 expected_value) { - FT1000_INFO *info = (PFT1000_INFO) netdev_priv(dev); - USHORT handshake; - ULONG tempx; + struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + u16 handshake; + u32 tempx; int loopcnt; loopcnt = 0; @@ -190,7 +168,7 @@ USHORT get_handshake(struct net_device *dev, USHORT expected_value) tempx = ntohl(ft1000_read_dpram_mag_32 (dev, DWNLD_MAG_HANDSHAKE_LOC)); - handshake = (USHORT) tempx; + handshake = (u16) tempx; } if ((handshake == expected_value) @@ -207,27 +185,27 @@ USHORT get_handshake(struct net_device *dev, USHORT expected_value) } -void put_handshake(struct net_device *dev, USHORT handshake_value) +void put_handshake(struct net_device *dev, u16 handshake_value) { - FT1000_INFO *info = (PFT1000_INFO) netdev_priv(dev); - ULONG tempx; + struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + u32 tempx; if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, DWNLD_HANDSHAKE_LOC); ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, handshake_value); /* Handshake */ } else { - tempx = (ULONG) handshake_value; + tempx = (u32) handshake_value; tempx = ntohl(tempx); ft1000_write_dpram_mag_32(dev, DWNLD_MAG_HANDSHAKE_LOC, tempx); /* Handshake */ } } -USHORT get_request_type(struct net_device *dev) +u16 get_request_type(struct net_device *dev) { - FT1000_INFO *info = (PFT1000_INFO) netdev_priv(dev); - USHORT request_type; - ULONG tempx; + struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + u16 request_type; + u32 tempx; if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, DWNLD_TYPE_LOC); @@ -235,7 +213,7 @@ USHORT get_request_type(struct net_device *dev) } else { tempx = ft1000_read_dpram_mag_32(dev, DWNLD_MAG_TYPE_LOC); tempx = ntohl(tempx); - request_type = (USHORT) tempx; + request_type = (u16) tempx; } return request_type; @@ -244,9 +222,9 @@ USHORT get_request_type(struct net_device *dev) long get_request_value(struct net_device *dev) { - FT1000_INFO *info = (PFT1000_INFO) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); long value; - USHORT w_val; + u16 w_val; if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, @@ -273,19 +251,19 @@ long get_request_value(struct net_device *dev) void put_request_value(struct net_device *dev, long lvalue) { - FT1000_INFO *info = (PFT1000_INFO) netdev_priv(dev); - USHORT size; - ULONG tempx; + struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + u16 size; + u32 tempx; if (info->AsicID == ELECTRABUZZ_ID) { - size = (USHORT) (lvalue >> 16); + size = (u16) (lvalue >> 16); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, DWNLD_SIZE_MSW_LOC); ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size); - size = (USHORT) (lvalue); + size = (u16) (lvalue); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, DWNLD_SIZE_LSW_LOC); @@ -298,10 +276,10 @@ void put_request_value(struct net_device *dev, long lvalue) } -USHORT hdr_checksum(PPSEUDO_HDR pHdr) +u16 hdr_checksum(struct pseudo_hdr *pHdr) { - USHORT *usPtr = (USHORT *) pHdr; - USHORT chksum; + u16 *usPtr = (u16 *) pHdr; + u16 chksum; chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^ usPtr[4]) ^ usPtr[5]) ^ usPtr[6]); @@ -309,32 +287,29 @@ USHORT hdr_checksum(PPSEUDO_HDR pHdr) return chksum; } -int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) +int card_download(struct net_device *dev, const u8 *pFileStart, u32 FileLength) { - FT1000_INFO *info = (PFT1000_INFO) netdev_priv(dev); + struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); int Status = SUCCESS; - USHORT DspWordCnt = 0; - UINT uiState; - USHORT handshake; - PPSEUDO_HDR pHdr; - USHORT usHdrLength; - PDSP_FILE_HDR pFileHdr; + u32 uiState; + u16 handshake; + struct pseudo_hdr *pHdr; + u16 usHdrLength; long word_length; - USHORT request; - USHORT temp; - PPROV_RECORD pprov_record; - PUCHAR pbuffer; - PDSP_FILE_HDR_5 pFileHdr5; - PDSP_IMAGE_INFO pDspImageInfo = NULL; - PDSP_IMAGE_INFO_V6 pDspImageInfoV6 = NULL; + u16 request; + u16 temp; + struct prov_record *pprov_record; + u8 *pbuffer; + struct dsp_file_hdr *pFileHdr5; + struct dsp_image_info *pDspImageInfoV6 = NULL; long requested_version; - BOOLEAN bGoodVersion = 0; - PDRVMSG pMailBoxData; - USHORT *pUsData = NULL; - USHORT *pUsFile = NULL; - UCHAR *pUcFile = NULL; - UCHAR *pBootEnd = NULL; - UCHAR *pCodeEnd = NULL; + bool bGoodVersion = 0; + struct drv_msg *pMailBoxData; + u16 *pUsData = NULL; + u16 *pUsFile = NULL; + u8 *pUcFile = NULL; + u8 *pBootEnd = NULL; + u8 *pCodeEnd = NULL; int imageN; long file_version; long loader_code_address = 0; @@ -345,36 +320,22 @@ int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) unsigned long templong; unsigned long image_chksum = 0; - // - // Get version id of file, at first 4 bytes of file, for newer files. - // file_version = *(long *)pFileStart; + if (file_version != 6) { + printk(KERN_ERR "ft1000: unsupported firmware version %ld\n", file_version); + Status = FAILURE; + } uiState = STATE_START_DWNLD; - pFileHdr = (PDSP_FILE_HDR) pFileStart; - pFileHdr5 = (PDSP_FILE_HDR_5) pFileStart; + pFileHdr5 = (struct dsp_file_hdr *) pFileStart; - switch (file_version) { - case 5: - case 6: - pUsFile = - (USHORT *) ((long)pFileStart + pFileHdr5->loader_offset); - pUcFile = - (UCHAR *) ((long)pFileStart + pFileHdr5->loader_offset); - - pBootEnd = - (UCHAR *) ((long)pFileStart + pFileHdr5->loader_code_end); - - loader_code_address = pFileHdr5->loader_code_address; - loader_code_size = pFileHdr5->loader_code_size; - bGoodVersion = FALSE; - break; - - default: - Status = FAILURE; - break; - } + pUsFile = (u16 *) ((long)pFileStart + pFileHdr5->loader_offset); + pUcFile = (u8 *) ((long)pFileStart + pFileHdr5->loader_offset); + pBootEnd = (u8 *) ((long)pFileStart + pFileHdr5->loader_code_end); + loader_code_address = pFileHdr5->loader_code_address; + loader_code_size = pFileHdr5->loader_code_size; + bGoodVersion = false; while ((Status == SUCCESS) && (uiState != STATE_DONE_FILE)) { @@ -411,8 +372,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) break; case REQUEST_DONE_BL: /* Reposition ptrs to beginning of code section */ - pUsFile = (USHORT *) ((long)pBootEnd); - pUcFile = (UCHAR *) ((long)pBootEnd); + pUsFile = (u16 *) ((long)pBootEnd); + pUcFile = (u8 *) ((long)pBootEnd); uiState = STATE_CODE_DWNLD; break; case REQUEST_CODE_SEGMENT: @@ -432,45 +393,24 @@ int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) // Provide mutual exclusive access while reading ASIC registers. spin_lock_irqsave(&info->dpram_lock, flags); - if (file_version == 5) { - /* - * Position ASIC DPRAM auto-increment pointer. - */ - ft1000_write_reg(dev, - FT1000_REG_DPRAM_ADDR, - DWNLD_PS_HDR_LOC); + /* + * Position ASIC DPRAM auto-increment pointer. + */ + outw(DWNLD_MAG_PS_HDR_LOC, + dev->base_addr + + FT1000_REG_DPRAM_ADDR); + if (word_length & 0x01) + word_length++; + word_length = word_length / 2; - for (; word_length > 0; word_length--) { /* In words */ - //temp = *pUsFile; - //temp = RtlUshortByteSwap(temp); - ft1000_write_reg(dev, - FT1000_REG_DPRAM_DATA, - *pUsFile); - pUsFile++; - pUcFile += 2; - DspWordCnt++; - } - } else { - /* - * Position ASIC DPRAM auto-increment pointer. - */ - outw(DWNLD_MAG_PS_HDR_LOC, + for (; word_length > 0; word_length--) { /* In words */ + templong = *pUsFile++; + templong |= + (*pUsFile++ << 16); + pUcFile += 4; + outl(templong, dev->base_addr + - FT1000_REG_DPRAM_ADDR); - if (word_length & 0x01) { - word_length++; - } - word_length = word_length / 2; - - for (; word_length > 0; word_length--) { /* In words */ - templong = *pUsFile++; - templong |= - (*pUsFile++ << 16); - pUcFile += 4; - outl(templong, - dev->base_addr + - FT1000_REG_MAG_DPDATAL); - } + FT1000_REG_MAG_DPDATAL); } spin_unlock_irqrestore(&info-> dpram_lock, @@ -520,24 +460,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) break; case REQUEST_DONE_CL: /* Reposition ptrs to beginning of provisioning section */ - switch (file_version) { - case 5: - case 6: - pUsFile = - (USHORT *) ((long)pFileStart - + - pFileHdr5-> - commands_offset); - pUcFile = - (UCHAR *) ((long)pFileStart - + - pFileHdr5-> - commands_offset); - break; - default: - Status = FAILURE; - break; - } + pUsFile = (u16 *) ((long)pFileStart + pFileHdr5->commands_offset); + pUcFile = (u8 *) ((long)pFileStart + pFileHdr5->commands_offset); uiState = STATE_DONE_DWNLD; break; case REQUEST_CODE_SEGMENT: @@ -558,45 +482,24 @@ int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) Status = FAILURE; break; } - if (file_version == 5) { - /* - * Position ASIC DPRAM auto-increment pointer. - */ - ft1000_write_reg(dev, - FT1000_REG_DPRAM_ADDR, - DWNLD_PS_HDR_LOC); + /* + * Position ASIC DPRAM auto-increment pointer. + */ + outw(DWNLD_MAG_PS_HDR_LOC, + dev->base_addr + + FT1000_REG_DPRAM_ADDR); + if (word_length & 0x01) + word_length++; + word_length = word_length / 2; - for (; word_length > 0; word_length--) { /* In words */ - //temp = *pUsFile; - //temp = RtlUshortByteSwap(temp); - ft1000_write_reg(dev, - FT1000_REG_DPRAM_DATA, - *pUsFile); - pUsFile++; - pUcFile += 2; - DspWordCnt++; - } - } else { - /* - * Position ASIC DPRAM auto-increment pointer. - */ - outw(DWNLD_MAG_PS_HDR_LOC, + for (; word_length > 0; word_length--) { /* In words */ + templong = *pUsFile++; + templong |= + (*pUsFile++ << 16); + pUcFile += 4; + outl(templong, dev->base_addr + - FT1000_REG_DPRAM_ADDR); - if (word_length & 0x01) { - word_length++; - } - word_length = word_length / 2; - - for (; word_length > 0; word_length--) { /* In words */ - templong = *pUsFile++; - templong |= - (*pUsFile++ << 16); - pUcFile += 4; - outl(templong, - dev->base_addr + - FT1000_REG_MAG_DPDATAL); - } + FT1000_REG_MAG_DPDATAL); } break; @@ -606,9 +509,9 @@ int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) (long)(info->DSPInfoBlklen + 1) / 2; put_request_value(dev, word_length); pMailBoxData = - (PDRVMSG) & info->DSPInfoBlk[0]; + (struct drv_msg *) & info->DSPInfoBlk[0]; pUsData = - (USHORT *) & pMailBoxData->data[0]; + (u16 *) & pMailBoxData->data[0]; // Provide mutual exclusive access while reading ASIC registers. spin_lock_irqsave(&info->dpram_lock, flags); @@ -658,51 +561,32 @@ int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) pFileHdr5->version_data_size; put_request_value(dev, word_length); pUsFile = - (USHORT *) ((long)pFileStart + + (u16 *) ((long)pFileStart + pFileHdr5-> version_data_offset); // Provide mutual exclusive access while reading ASIC registers. spin_lock_irqsave(&info->dpram_lock, flags); - if (file_version == 5) { - /* - * Position ASIC DPRAM auto-increment pointer. - */ - ft1000_write_reg(dev, - FT1000_REG_DPRAM_ADDR, - DWNLD_PS_HDR_LOC); + /* + * Position ASIC DPRAM auto-increment pointer. + */ + outw(DWNLD_MAG_PS_HDR_LOC, + dev->base_addr + + FT1000_REG_DPRAM_ADDR); + if (word_length & 0x01) + word_length++; + word_length = word_length / 2; - for (; word_length > 0; word_length--) { /* In words */ - ft1000_write_reg(dev, - FT1000_REG_DPRAM_DATA, - *pUsFile - /*temp */ - ); - pUsFile++; - } - } else { - /* - * Position ASIC DPRAM auto-increment pointer. - */ - outw(DWNLD_MAG_PS_HDR_LOC, + for (; word_length > 0; word_length--) { /* In words */ + templong = + ntohs(*pUsFile++); + temp = + ntohs(*pUsFile++); + templong |= + (temp << 16); + outl(templong, dev->base_addr + - FT1000_REG_DPRAM_ADDR); - if (word_length & 0x01) { - word_length++; - } - word_length = word_length / 2; - - for (; word_length > 0; word_length--) { /* In words */ - templong = - ntohs(*pUsFile++); - temp = - ntohs(*pUsFile++); - templong |= - (temp << 16); - outl(templong, - dev->base_addr + - FT1000_REG_MAG_DPDATAL); - } + FT1000_REG_MAG_DPDATAL); } spin_unlock_irqrestore(&info-> dpram_lock, @@ -710,120 +594,71 @@ int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) break; case REQUEST_CODE_BY_VERSION: - bGoodVersion = FALSE; + bGoodVersion = false; requested_version = get_request_value(dev); - if (file_version == 5) { - pDspImageInfo = - (PDSP_IMAGE_INFO) ((long) - pFileStart - + - sizeof - (DSP_FILE_HDR_5)); - for (imageN = 0; - imageN < - pFileHdr5->nDspImages; - imageN++) { - if (pDspImageInfo-> - version == - requested_version) { - bGoodVersion = - TRUE; - pUsFile = - (USHORT - *) ((long) - pFileStart - + - pDspImageInfo-> - begin_offset); - pUcFile = - (UCHAR - *) ((long) - pFileStart - + - pDspImageInfo-> - begin_offset); - pCodeEnd = - (UCHAR - *) ((long) - pFileStart - + - pDspImageInfo-> - end_offset); - run_address = - pDspImageInfo-> - run_address; - run_size = - pDspImageInfo-> - image_size; - break; - } - pDspImageInfo++; - } - } else { - pDspImageInfoV6 = - (PDSP_IMAGE_INFO_V6) ((long) - pFileStart - + - sizeof - (DSP_FILE_HDR_5)); - for (imageN = 0; - imageN < - pFileHdr5->nDspImages; - imageN++) { - temp = (USHORT) - (pDspImageInfoV6-> - version); - templong = temp; - temp = (USHORT) - (pDspImageInfoV6-> - version >> 16); - templong |= - (temp << 16); - if (templong == - requested_version) { - bGoodVersion = - TRUE; - pUsFile = - (USHORT - *) ((long) - pFileStart - + - pDspImageInfoV6-> - begin_offset); - pUcFile = - (UCHAR - *) ((long) - pFileStart - + - pDspImageInfoV6-> - begin_offset); - pCodeEnd = - (UCHAR - *) ((long) - pFileStart - + - pDspImageInfoV6-> - end_offset); - run_address = - pDspImageInfoV6-> - run_address; - run_size = - pDspImageInfoV6-> - image_size; - image_chksum = - (ULONG) - pDspImageInfoV6-> - checksum; - DEBUG(0, - "ft1000_dnld: image_chksum = 0x%8x\n", - (unsigned - int) - image_chksum); - break; - } - pDspImageInfoV6++; + pDspImageInfoV6 = + (struct dsp_image_info *) ((long) + pFileStart + + + sizeof + (struct dsp_file_hdr)); + for (imageN = 0; + imageN < + pFileHdr5->nDspImages; + imageN++) { + temp = (u16) + (pDspImageInfoV6-> + version); + templong = temp; + temp = (u16) + (pDspImageInfoV6-> + version >> 16); + templong |= + (temp << 16); + if (templong == + requested_version) { + bGoodVersion = + true; + pUsFile = + (u16 + *) ((long) + pFileStart + + + pDspImageInfoV6-> + begin_offset); + pUcFile = + (u8 + *) ((long) + pFileStart + + + pDspImageInfoV6-> + begin_offset); + pCodeEnd = + (u8 + *) ((long) + pFileStart + + + pDspImageInfoV6-> + end_offset); + run_address = + pDspImageInfoV6-> + run_address; + run_size = + pDspImageInfoV6-> + image_size; + image_chksum = + (u32) + pDspImageInfoV6-> + checksum; + DEBUG(0, + "ft1000_dnld: image_chksum = 0x%8x\n", + (unsigned + int) + image_chksum); + break; } + pDspImageInfoV6++; } if (!bGoodVersion) { /* @@ -852,7 +687,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) break; } - pHdr = (PPSEUDO_HDR) pUsFile; + pHdr = (struct pseudo_hdr *) pUsFile; if (pHdr->portdest == 0x80 /* DspOAM */ && (pHdr->portsrc == 0x00 /* Driver */ @@ -872,7 +707,7 @@ int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) case STATE_SECTION_PROV: - pHdr = (PPSEUDO_HDR) pUcFile; + pHdr = (struct pseudo_hdr *) pUcFile; if (pHdr->checksum == hdr_checksum(pHdr)) { if (pHdr->portdest != 0x80 /* Dsp OAM */ ) { @@ -883,15 +718,15 @@ int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) // Get buffer for provisioning data pbuffer = - kmalloc((usHdrLength + sizeof(PSEUDO_HDR)), + kmalloc((usHdrLength + sizeof(struct pseudo_hdr)), GFP_ATOMIC); if (pbuffer) { memcpy(pbuffer, (void *)pUcFile, - (UINT) (usHdrLength + - sizeof(PSEUDO_HDR))); + (u32) (usHdrLength + + sizeof(struct pseudo_hdr))); // link provisioning data pprov_record = - kmalloc(sizeof(PROV_RECORD), + kmalloc(sizeof(struct prov_record), GFP_ATOMIC); if (pprov_record) { pprov_record->pprov_data = @@ -901,8 +736,8 @@ int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength) &info->prov_list); // Move to next entry if available pUcFile = - (UCHAR *) ((unsigned long) pUcFile + - (unsigned long) ((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(PSEUDO_HDR)); + (u8 *) ((unsigned long) pUcFile + + (unsigned long) ((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); if ((unsigned long) (pUcFile) - (unsigned long) (pFileStart) >= (unsigned long) FileLength) { diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index 830822f86e41..990b2afb3d6b 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -54,10 +54,9 @@ #endif #include -#include "ft1000_dev.h" #include "ft1000.h" -int card_download(struct net_device *dev, const u8 *pFileStart, UINT FileLength); +int card_download(struct net_device *dev, const u8 *pFileStart, u32 FileLength); void ft1000InitProc(struct net_device *dev); void ft1000CleanupProc(struct net_device *dev); @@ -87,40 +86,6 @@ MODULE_SUPPORTED_DEVICE("FT1000"); #define MAX_RCV_LOOP 100 -//--------------------------------------------------------------------------- -// -// Function: ft1000_asic_read -// Description: This function will retrieve the value of a specific ASIC -// register. -// Input: -// dev - network device structure -// offset - ASIC register to read -// Output: -// value - value of ASIC register -// -//--------------------------------------------------------------------------- -inline u16 ft1000_asic_read(struct net_device *dev, u16 offset) -{ - return (ft1000_read_reg(dev, offset)); -} - -//--------------------------------------------------------------------------- -// -// Function: ft1000_asic_write -// Description: This function will set the value of a specific ASIC -// register. -// Input: -// dev - network device structure -// value - value to set ASIC register -// Output: -// none -// -//--------------------------------------------------------------------------- -inline void ft1000_asic_write(struct net_device *dev, u16 offset, u16 value) -{ - ft1000_write_reg(dev, offset, value); -} - //--------------------------------------------------------------------------- // // Function: ft1000_read_fifo_len @@ -136,7 +101,7 @@ inline void ft1000_asic_write(struct net_device *dev, u16 offset, u16 value) //--------------------------------------------------------------------------- static inline u16 ft1000_read_fifo_len(struct net_device *dev) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); if (info->AsicID == ELECTRABUZZ_ID) { return (ft1000_read_reg(dev, FT1000_REG_UFIFO_STAT) - 16); @@ -159,7 +124,7 @@ static inline u16 ft1000_read_fifo_len(struct net_device *dev) //--------------------------------------------------------------------------- u16 ft1000_read_dpram(struct net_device * dev, int offset) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); unsigned long flags; u16 data; @@ -188,7 +153,7 @@ u16 ft1000_read_dpram(struct net_device * dev, int offset) static inline void ft1000_write_dpram(struct net_device *dev, int offset, u16 value) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); unsigned long flags; // Provide mutual exclusive access while reading ASIC registers. @@ -212,7 +177,7 @@ static inline void ft1000_write_dpram(struct net_device *dev, //--------------------------------------------------------------------------- u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); unsigned long flags; u16 data; @@ -246,7 +211,7 @@ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) static inline void ft1000_write_dpram_mag_16(struct net_device *dev, int offset, u16 value, int Index) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); unsigned long flags; // Provide mutual exclusive access while reading ASIC registers. @@ -274,7 +239,7 @@ static inline void ft1000_write_dpram_mag_16(struct net_device *dev, //--------------------------------------------------------------------------- u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); unsigned long flags; u32 data; @@ -302,7 +267,7 @@ u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) //--------------------------------------------------------------------------- void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); unsigned long flags; // Provide mutual exclusive access while reading ASIC registers. @@ -324,17 +289,14 @@ void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value) //--------------------------------------------------------------------------- static void ft1000_enable_interrupts(struct net_device *dev) { - FT1000_INFO *info = netdev_priv(dev); u16 tempword; DEBUG(1, "ft1000_hw:ft1000_enable_interrupts()\n"); - ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, - info->CurrentInterruptEnableMask); + ft1000_write_reg(dev, FT1000_REG_SUP_IMASK, ISR_DEFAULT_MASK); tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK); DEBUG(1, "ft1000_hw:ft1000_enable_interrupts:current interrupt enable mask = 0x%x\n", tempword); - info->InterruptsEnabled = TRUE; } //--------------------------------------------------------------------------- @@ -349,7 +311,6 @@ static void ft1000_enable_interrupts(struct net_device *dev) //--------------------------------------------------------------------------- static void ft1000_disable_interrupts(struct net_device *dev) { - FT1000_INFO *info = netdev_priv(dev); u16 tempword; DEBUG(1, "ft1000_hw: ft1000_disable_interrupts()\n"); @@ -358,7 +319,6 @@ static void ft1000_disable_interrupts(struct net_device *dev) DEBUG(1, "ft1000_hw:ft1000_disable_interrupts:current interrupt enable mask = 0x%x\n", tempword); - info->InterruptsEnabled = FALSE; } //--------------------------------------------------------------------------- @@ -374,13 +334,12 @@ static void ft1000_disable_interrupts(struct net_device *dev) //--------------------------------------------------------------------------- static void ft1000_reset_asic(struct net_device *dev) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); u16 tempword; DEBUG(1, "ft1000_hw:ft1000_reset_asic called\n"); (*info->ft1000_reset) (info->link); - info->ASICResetNum++; // Let's use the register provided by the Magnemite ASIC to reset the // ASIC and DSP. @@ -412,17 +371,17 @@ static void ft1000_reset_asic(struct net_device *dev) // Input: // dev - device structure // Output: -// status - FALSE (card reset fail) -// TRUE (card reset successful) +// status - false (card reset fail) +// true (card reset successful) // //--------------------------------------------------------------------------- static int ft1000_reset_card(struct net_device *dev) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); u16 tempword; int i; unsigned long flags; - PPROV_RECORD ptr; + struct prov_record *ptr; DEBUG(1, "ft1000_hw:ft1000_reset_card called.....\n"); @@ -437,7 +396,7 @@ static int ft1000_reset_card(struct net_device *dev) while (list_empty(&info->prov_list) == 0) { DEBUG(0, "ft1000_hw:ft1000_reset_card:deleting provisioning record\n"); - ptr = list_entry(info->prov_list.next, PROV_RECORD, list); + ptr = list_entry(info->prov_list.next, struct prov_record, list); list_del(&ptr->list); kfree(ptr->pprov_data); kfree(ptr); @@ -457,14 +416,12 @@ static int ft1000_reset_card(struct net_device *dev) if (ft1000_card_present == 1) { spin_lock_irqsave(&info->dpram_lock, flags); if (info->AsicID == ELECTRABUZZ_ID) { - if (info->DspHibernateFlag == 0) { - ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, - FT1000_DPRAM_RX_BASE); - for (i = 0; i < MAX_DSP_SESS_REC; i++) { - info->DSPSess.Rec[i] = - ft1000_read_reg(dev, - FT1000_REG_DPRAM_DATA); - } + ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, + FT1000_DPRAM_RX_BASE); + for (i = 0; i < MAX_DSP_SESS_REC; i++) { + info->DSPSess.Rec[i] = + ft1000_read_reg(dev, + FT1000_REG_DPRAM_DATA); } } else { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, @@ -482,8 +439,6 @@ static int ft1000_reset_card(struct net_device *dev) //reset ASIC ft1000_reset_asic(dev); - info->DSPResetNum++; - DEBUG(1, "ft1000_hw:ft1000_reset_card:downloading dsp image\n"); if (info->AsicID == MAGNEMITE_ID) { @@ -517,7 +472,7 @@ static int ft1000_reset_card(struct net_device *dev) if (i == 50) { DEBUG(0, "ft1000_hw:ft1000_reset_card:No FEFE detected from DSP\n"); - return FALSE; + return false; } } else { @@ -528,7 +483,7 @@ static int ft1000_reset_card(struct net_device *dev) if (card_download(dev, fw_entry->data, fw_entry->size)) { DEBUG(1, "card download unsuccessful\n"); - return FALSE; + return false; } else { DEBUG(1, "card download successful\n"); } @@ -564,7 +519,7 @@ static int ft1000_reset_card(struct net_device *dev) // poll_timer.data = (u_long)dev; // add_timer(&poll_timer); - return TRUE; + return true; } @@ -576,8 +531,8 @@ static int ft1000_reset_card(struct net_device *dev) // Input: // dev - device structure // Output: -// status - FALSE (device is not present) -// TRUE (device is present) +// status - false (device is not present) +// true (device is present) // //--------------------------------------------------------------------------- static int ft1000_chkcard(struct net_device *dev) @@ -590,7 +545,7 @@ static int ft1000_chkcard(struct net_device *dev) if (tempword == 0) { DEBUG(1, "ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); - return FALSE; + return false; } // The system will return the value of 0xffff for the version register // if the device is not present. @@ -598,9 +553,9 @@ static int ft1000_chkcard(struct net_device *dev) if (tempword == 0xffff) { DEBUG(1, "ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); - return FALSE; + return false; } - return TRUE; + return true; } @@ -619,8 +574,8 @@ static void ft1000_hbchk(u_long data) { struct net_device *dev = (struct net_device *)data; - FT1000_INFO *info; - USHORT tempword; + struct ft1000_info *info; + u16 tempword; info = netdev_priv(dev); @@ -835,12 +790,12 @@ static void ft1000_hbchk(u_long data) //--------------------------------------------------------------------------- void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); int i; u16 tempword; unsigned long flags; - size += PSEUDOSZ; + size += sizeof(struct pseudo_hdr); // check for odd byte and increment to 16-bit word align value if ((size & 0x0001)) { size++; @@ -918,9 +873,9 @@ void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qt // = 1 (successful) // //--------------------------------------------------------------------------- -BOOLEAN ft1000_receive_cmd(struct net_device *dev, u16 * pbuffer, int maxsz, u16 *pnxtph) +bool ft1000_receive_cmd(struct net_device *dev, u16 * pbuffer, int maxsz, u16 *pnxtph) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); u16 size; u16 *ppseudohdr; int i; @@ -928,18 +883,18 @@ BOOLEAN ft1000_receive_cmd(struct net_device *dev, u16 * pbuffer, int maxsz, u16 unsigned long flags; if (info->AsicID == ELECTRABUZZ_ID) { - size = ( ft1000_read_dpram(dev, *pnxtph) ) + PSEUDOSZ; + size = ( ft1000_read_dpram(dev, *pnxtph) ) + sizeof(struct pseudo_hdr); } else { size = ntohs(ft1000_read_dpram_mag_16 (dev, FT1000_MAG_PH_LEN, - FT1000_MAG_PH_LEN_INDX)) + PSEUDOSZ; + FT1000_MAG_PH_LEN_INDX)) + sizeof(struct pseudo_hdr); } if (size > maxsz) { DEBUG(1, "FT1000:ft1000_receive_cmd:Invalid command length = %d\n", size); - return FALSE; + return false; } else { ppseudohdr = (u16 *) pbuffer; spin_lock_irqsave(&info->dpram_lock, flags); @@ -994,9 +949,9 @@ BOOLEAN ft1000_receive_cmd(struct net_device *dev, u16 * pbuffer, int maxsz, u16 DEBUG(1, "FT1000:ft1000_receive_cmd:Pseudo header checksum mismatch\n"); // Drop this message - return FALSE; + return false; } - return TRUE; + return true; } } @@ -1013,17 +968,17 @@ BOOLEAN ft1000_receive_cmd(struct net_device *dev, u16 * pbuffer, int maxsz, u16 //--------------------------------------------------------------------------- void ft1000_proc_drvmsg(struct net_device *dev) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); u16 msgtype; u16 tempword; - PMEDIAMSG pmediamsg; - PDSPINITMSG pdspinitmsg; - PDRVMSG pdrvmsg; + struct media_msg *pmediamsg; + struct dsp_init_msg *pdspinitmsg; + struct drv_msg *pdrvmsg; u16 len; u16 i; - PPROV_RECORD ptr; - PPSEUDO_HDR ppseudo_hdr; - PUSHORT pmsg; + struct prov_record *ptr; + struct pseudo_hdr *ppseudo_hdr; + u16 *pmsg; struct timeval tv; union { u8 byte[2]; @@ -1039,7 +994,7 @@ void ft1000_proc_drvmsg(struct net_device *dev) if ( ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword) ) { // Get the message type which is total_len + PSEUDO header + msgtype + message body - pdrvmsg = (PDRVMSG) & cmdbuffer[0]; + pdrvmsg = (struct drv_msg *) & cmdbuffer[0]; msgtype = ntohs(pdrvmsg->type); DEBUG(1, "Command message type = 0x%x\n", msgtype); switch (msgtype) { @@ -1062,12 +1017,12 @@ void ft1000_proc_drvmsg(struct net_device *dev) } ptr = list_entry(info->prov_list.next, - PROV_RECORD, list); + struct prov_record, list); len = *(u16 *) ptr->pprov_data; len = htons(len); - pmsg = (PUSHORT) ptr->pprov_data; - ppseudo_hdr = (PPSEUDO_HDR) pmsg; + pmsg = (u16 *) ptr->pprov_data; + ppseudo_hdr = (struct pseudo_hdr *) pmsg; // Insert slow queue sequence number ppseudo_hdr->seq_num = info->squeseqnum++; ppseudo_hdr->portsrc = 0; @@ -1091,7 +1046,7 @@ void ft1000_proc_drvmsg(struct net_device *dev) info->CardReady = 1; break; case MEDIA_STATE: - pmediamsg = (PMEDIAMSG) & cmdbuffer[0]; + pmediamsg = (struct media_msg *) & cmdbuffer[0]; if (info->ProgConStat != 0xFF) { if (pmediamsg->state) { DEBUG(1, "Media is up\n"); @@ -1123,7 +1078,7 @@ void ft1000_proc_drvmsg(struct net_device *dev) } break; case DSP_INIT_MSG: - pdspinitmsg = (PDSPINITMSG) & cmdbuffer[0]; + pdspinitmsg = (struct dsp_init_msg *) & cmdbuffer[0]; memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ); DEBUG(1, "DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", info->DspVer[0], info->DspVer[1], info->DspVer[2], @@ -1140,7 +1095,7 @@ void ft1000_proc_drvmsg(struct net_device *dev) dev->dev_addr[5] = info->eui64[7]; if (ntohs(pdspinitmsg->length) == - (sizeof(DSPINITMSG) - 20)) { + (sizeof(struct dsp_init_msg) - 20)) { memcpy(info->ProductMode, pdspinitmsg->ProductMode, MODESZ); memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, @@ -1157,7 +1112,7 @@ void ft1000_proc_drvmsg(struct net_device *dev) tempword = ntohs(pdrvmsg->length); info->DSPInfoBlklen = tempword; if (tempword < (MAX_DSP_SESS_REC - 4)) { - pmsg = (PUSHORT) & pdrvmsg->data[0]; + pmsg = (u16 *) & pdrvmsg->data[0]; for (i = 0; i < ((tempword + 1) / 2); i++) { DEBUG(1, "FT1000:drivermsg:dsp info data = 0x%x\n", @@ -1169,7 +1124,6 @@ void ft1000_proc_drvmsg(struct net_device *dev) case DSP_GET_INFO: DEBUG(1, "FT1000:drivermsg:Got DSP_GET_INFO\n"); // copy dsp info block to dsp - info->DrvMsgPend = 1; // allow any outstanding ioctl to finish mdelay(10); tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); @@ -1185,8 +1139,8 @@ void ft1000_proc_drvmsg(struct net_device *dev) if ((tempword & FT1000_DB_DPRAM_TX) == 0) { // Put message into Slow Queue // Form Pseudo header - pmsg = (PUSHORT) info->DSPInfoBlk; - ppseudo_hdr = (PPSEUDO_HDR) pmsg; + pmsg = (u16 *) info->DSPInfoBlk; + ppseudo_hdr = (struct pseudo_hdr *) pmsg; ppseudo_hdr->length = htons(info->DSPInfoBlklen + 4); ppseudo_hdr->source = 0x10; @@ -1210,15 +1164,13 @@ void ft1000_proc_drvmsg(struct net_device *dev) info->DSPInfoBlk[8] = 0x7200; info->DSPInfoBlk[9] = htons(info->DSPInfoBlklen); - ft1000_send_cmd (dev, (PUSHORT)info->DSPInfoBlk, (USHORT)(info->DSPInfoBlklen+4), 0); + ft1000_send_cmd (dev, (u16 *)info->DSPInfoBlk, (u16)(info->DSPInfoBlklen+4), 0); } - info->DrvMsgPend = 0; break; case GET_DRV_ERR_RPT_MSG: DEBUG(1, "FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); // copy driver error message to dsp - info->DrvMsgPend = 1; // allow any outstanding ioctl to finish mdelay(10); tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); @@ -1234,8 +1186,8 @@ void ft1000_proc_drvmsg(struct net_device *dev) if ((tempword & FT1000_DB_DPRAM_TX) == 0) { // Put message into Slow Queue // Form Pseudo header - pmsg = (PUSHORT) & tempbuffer[0]; - ppseudo_hdr = (PPSEUDO_HDR) pmsg; + pmsg = (u16 *) & tempbuffer[0]; + ppseudo_hdr = (struct pseudo_hdr *) pmsg; ppseudo_hdr->length = htons(0x0012); ppseudo_hdr->source = 0x10; ppseudo_hdr->destination = 0x20; @@ -1255,7 +1207,7 @@ void ft1000_proc_drvmsg(struct net_device *dev) for (i=1; i<7; i++) { ppseudo_hdr->checksum ^= *pmsg++; } - pmsg = (PUSHORT) & tempbuffer[16]; + pmsg = (u16 *) & tempbuffer[16]; *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); *pmsg++ = htons(0x000e); *pmsg++ = htons(info->DSP_TIME[0]); @@ -1270,10 +1222,9 @@ void ft1000_proc_drvmsg(struct net_device *dev) *pmsg++ = convert.wrd; *pmsg++ = htons(info->DrvErrNum); - ft1000_send_cmd (dev, (PUSHORT)&tempbuffer[0], (USHORT)(0x0012), 0); + ft1000_send_cmd (dev, (u16 *)&tempbuffer[0], (u16)(0x0012), 0); info->DrvErrNum = 0; } - info->DrvMsgPend = 0; break; default: @@ -1296,7 +1247,7 @@ void ft1000_proc_drvmsg(struct net_device *dev) //--------------------------------------------------------------------------- int ft1000_parse_dpram_msg(struct net_device *dev) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); u16 doorbell; u16 portid; u16 nxtph; @@ -1340,13 +1291,11 @@ int ft1000_parse_dpram_msg(struct net_device *dev) ft1000_write_reg(dev, FT1000_REG_SUP_CTRL, HOST_INTF_BE); } - info->DspAsicReset = 0; } if (doorbell & FT1000_DSP_ASIC_RESET) { DEBUG(0, "FT1000:ft1000_parse_dpram_msg: Got a dsp ASIC reset message\n"); - info->DspAsicReset = 1; ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DSP_ASIC_RESET); udelay(200); @@ -1368,7 +1317,7 @@ int ft1000_parse_dpram_msg(struct net_device *dev) } DEBUG(1, "FT1000:ft1000_parse_dpram_msg:total length = %d\n", total_len); - if ((total_len < MAX_CMD_SQSIZE) && (total_len > PSEUDOSZ)) { + if ((total_len < MAX_CMD_SQSIZE) && (total_len > sizeof(struct pseudo_hdr))) { total_len += nxtph; cnt = 0; // ft1000_read_reg will return a value that needs to be byteswap @@ -1453,7 +1402,7 @@ int ft1000_parse_dpram_msg(struct net_device *dev) //--------------------------------------------------------------------------- static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); u16 i; u32 templong; u16 tempword; @@ -1600,7 +1549,7 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) int ft1000_copy_up_pkt(struct net_device *dev) { u16 tempword; - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); u16 len; struct sk_buff *skb; u16 i; @@ -1715,7 +1664,7 @@ int ft1000_copy_up_pkt(struct net_device *dev) tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); *pbuffer++ = (u8) (tempword >> 8); *pbuffer++ = (u8) tempword; - if (ft1000_chkcard(dev) == FALSE) { + if (ft1000_chkcard(dev) == false) { kfree_skb(skb); return FAILURE; } @@ -1787,11 +1736,11 @@ int ft1000_copy_up_pkt(struct net_device *dev) //--------------------------------------------------------------------------- int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); union { - PSEUDO_HDR blk; - u16 buff[sizeof(PSEUDO_HDR) >> 1]; - u8 buffc[sizeof(PSEUDO_HDR)]; + struct pseudo_hdr blk; + u16 buff[sizeof(struct pseudo_hdr) >> 1]; + u8 buffc[sizeof(struct pseudo_hdr)]; } pseudo; int i; u32 *plong; @@ -1947,7 +1896,7 @@ int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) static struct net_device_stats *ft1000_stats(struct net_device *dev) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); return (&info->stats); } @@ -1971,7 +1920,7 @@ static int ft1000_open(struct net_device *dev) static int ft1000_close(struct net_device *dev) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); DEBUG(0, "ft1000_hw: ft1000_close()\n"); @@ -1993,7 +1942,7 @@ static int ft1000_close(struct net_device *dev) static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) { - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); u8 *pdata; DEBUG(1, "ft1000_hw: ft1000_start_xmit()\n"); @@ -2030,7 +1979,7 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) static irqreturn_t ft1000_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *)dev_id; - FT1000_INFO *info = netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); u16 tempword; u16 inttype; int cnt; @@ -2042,7 +1991,7 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } - if (ft1000_chkcard(dev) == FALSE) { + if (ft1000_chkcard(dev) == false) { ft1000_disable_interrupts(dev); return IRQ_HANDLED; } @@ -2095,8 +2044,8 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) void stop_ft1000_card(struct net_device *dev) { - FT1000_INFO *info = netdev_priv(dev); - PPROV_RECORD ptr; + struct ft1000_info *info = netdev_priv(dev); + struct prov_record *ptr; // int cnt; DEBUG(0, "ft1000_hw: stop_ft1000_card()\n"); @@ -2108,7 +2057,7 @@ void stop_ft1000_card(struct net_device *dev) // Make sure we free any memory reserve for provisioning while (list_empty(&info->prov_list) == 0) { - ptr = list_entry(info->prov_list.next, PROV_RECORD, list); + ptr = list_entry(info->prov_list.next, struct prov_record, list); list_del(&ptr->list); kfree(ptr->pprov_data); kfree(ptr); @@ -2130,7 +2079,7 @@ void stop_ft1000_card(struct net_device *dev) static void ft1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - FT1000_INFO *ft_info; + struct ft1000_info *ft_info; ft_info = netdev_priv(dev); snprintf(info->driver, 32, "ft1000"); @@ -2142,7 +2091,7 @@ static void ft1000_get_drvinfo(struct net_device *dev, static u32 ft1000_get_link(struct net_device *dev) { - FT1000_INFO *info; + struct ft1000_info *info; info = netdev_priv(dev); return info->mediastate; } @@ -2155,7 +2104,7 @@ static const struct ethtool_ops ops = { struct net_device *init_ft1000_card(struct pcmcia_device *link, void *ft1000_reset) { - FT1000_INFO *info; + struct ft1000_info *info; struct net_device *dev; static const struct net_device_ops ft1000ops = // Slavius 21.10.2009 due to kernel changes @@ -2180,7 +2129,7 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, return NULL; } - dev = alloc_etherdev(sizeof(FT1000_INFO)); + dev = alloc_etherdev(sizeof(struct ft1000_info)); if (!dev) { printk(KERN_ERR "ft1000: failed to allocate etherdev\n"); return NULL; @@ -2189,7 +2138,7 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, SET_NETDEV_DEV(dev, &link->dev); info = netdev_priv(dev); - memset(info, 0, sizeof(FT1000_INFO)); + memset(info, 0, sizeof(struct ft1000_info)); DEBUG(1, "address of dev = 0x%8x\n", (u32) dev); DEBUG(1, "address of dev info = 0x%8x\n", (u32) info); @@ -2199,16 +2148,11 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, spin_lock_init(&info->dpram_lock); info->DrvErrNum = 0; - info->ASICResetNum = 0; info->registered = 1; info->link = link; info->ft1000_reset = ft1000_reset; info->mediastate = 0; info->fifo_cnt = 0; - info->DeviceCreated = FALSE; - info->DeviceMajor = 0; - info->CurrentInterruptEnableMask = ISR_DEFAULT_MASK; - info->InterruptsEnabled = FALSE; info->CardReady = 0; info->DSP_TIME[0] = 0; info->DSP_TIME[1] = 0; diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c index bdfb1aec58df..627a98b4ec30 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c @@ -53,7 +53,7 @@ int ft1000ReadProc(char *page, char **start, off_t off, struct net_device *dev; int len; int i; - FT1000_INFO *info; + struct ft1000_info *info; char *status[] = { "Idle (Disconnect)", "Searching", "Active (Connected)", "Waiting for L2", "Sleep", "No Coverage", "", "" @@ -75,16 +75,14 @@ int ft1000ReadProc(char *page, char **start, off_t off, /* Wrap-around */ if (info->AsicID == ELECTRABUZZ_ID) { - if (info->DspHibernateFlag == 0) { - if (info->ProgConStat != 0xFF) { - info->LedStat = - ft1000_read_dpram(dev, FT1000_DSP_LED); - info->ConStat = - ft1000_read_dpram(dev, - FT1000_DSP_CON_STATE); - } else { - info->ConStat = 0xf; - } + if (info->ProgConStat != 0xFF) { + info->LedStat = + ft1000_read_dpram(dev, FT1000_DSP_LED); + info->ConStat = + ft1000_read_dpram(dev, + FT1000_DSP_CON_STATE); + } else { + info->ConStat = 0xf; } } else { if (info->ProgConStat != 0xFF) { @@ -172,7 +170,7 @@ static int ft1000NotifyProc(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = ptr; - FT1000_INFO *info; + struct ft1000_info *info; info = netdev_priv(dev); @@ -193,7 +191,7 @@ static struct notifier_block ft1000_netdev_notifier = { void ft1000InitProc(struct net_device *dev) { - FT1000_INFO *info; + struct ft1000_info *info; info = netdev_priv(dev); @@ -206,7 +204,7 @@ void ft1000InitProc(struct net_device *dev) void ft1000CleanupProc(struct net_device *dev) { - FT1000_INFO *info; + struct ft1000_info *info; info = netdev_priv(dev); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h b/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h index 6a8a1969f9e1..3f4207fd1597 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_ioctl.h @@ -26,38 +26,6 @@ #ifndef _FT1000IOCTLH_ #define _FT1000IOCTLH_ -#define DSPVERSZ 4 -#define HWSERNUMSZ 16 -#define SKUSZ 20 -#define EUISZ 8 -#define CALVERSZ 2 -#define CALDATESZ 6 - -#define MAX_DNLD_BLKSZ 1024 - -// Standard Flarion Pseudo header -struct pseudo_hdr { - unsigned short length; //length of msg body - unsigned char source; //source address (0x10=Host 0x20=DSP) - unsigned char destination; //destination address (refer to source address) - unsigned char portdest; //destination port id - // 0x00=Driver - // 0x10=Application Broadcast - // 0x20=Network Stack - // 0x80=Dsp OAM - // 0x90=Dsp Airlink - // 0xa0=Dsp Loader - // 0xb0=Dsp MIP - unsigned char portsrc; //source port id (refer to portdest) - unsigned short sh_str_id; //stream id (Not applicable on Mobile) - unsigned char control; //stream id (Not applicable on Mobile) - unsigned char rsvd1; //reserved - unsigned char seq_num; //sequence number - unsigned char rsvd2; //reserved - unsigned short qos_class; //Quality of Service class (Not applicable on Mobile) - unsigned short checksum; //Pseudo header checksum -} __attribute__ ((packed)); - typedef struct _IOCTL_GET_VER { unsigned long drv_ver; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 0b30020c7548..51c084756b4a 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -2,81 +2,18 @@ #define _FT1000_USB_H_ /*Jim*/ +#include "../ft1000.h" #include "ft1000_ioctl.h" #define FT1000_DRV_VER 0x01010403 -#define MODESZ 2 #define MAX_NUM_APP 6 #define MAX_MSG_LIMIT 200 #define NUM_OF_FREE_BUFFERS 1500 -// Driver message types -#define MEDIA_STATE 0x0010 -#define DSP_PROVISION 0x0030 -#define DSP_INIT_MSG 0x0050 -#define DSP_STORE_INFO 0x0070 -#define DSP_GET_INFO 0x0071 -#define GET_DRV_ERR_RPT_MSG 0x0073 -#define RSP_DRV_ERR_RPT_MSG 0x0074 - - -// Size of DPRAM Command -#define MAX_CMD_SQSIZE 1780 -#define SLOWQ_TYPE 0 #define PSEUDOSZ 16 -#define DSP_QID_OFFSET 4 - - -// MEMORY MAP FOR ELECTRABUZZ ASIC -#define FT1000_REG_DFIFO_STAT 0x0008 // Downlink FIFO status register -#define FT1000_REG_DPRAM_DATA 0x000C // DPRAM VALUE in DPRAM ADDR - -#define FT1000_DSP_LED 0xFFA // dsp led status for PAD device - -#define FT1000_MAG_DSP_LED 0x3FE // dsp led status for PAD device -#define FT1000_MAG_DSP_LED_INDX 0x1 // dsp led status for PAD device #define SUCCESS 0x00 - -#define DRIVERID 0x00 - -// Driver Error Messages for DSP -#define DSP_CONDRESET_INFO 0x7ef2 -#define DSP_HB_INFO 0x7ef0 - -// Magnemite specific defines -#define hi_mag 0x6968 // Byte swap hi to avoid additional system call -#define ho_mag 0x6f68 // Byte swap ho to avoid additional system call - - - -struct media_msg { - struct pseudo_hdr pseudo; - u16 type; - u16 length; - u16 state; - u32 ip_addr; - u32 net_mask; - u32 gateway; - u32 dns_1; - u32 dns_2; -} __attribute__ ((packed)); - -struct dsp_init_msg { - struct pseudo_hdr pseudo; - u16 type; - u16 length; - u8 DspVer[DSPVERSZ]; // DSP version number - u8 HwSerNum[HWSERNUMSZ]; // Hardware Serial Number - u8 Sku[SKUSZ]; // SKU - u8 eui64[EUISZ]; // EUI64 - u8 ProductMode[MODESZ]; // Product Mode (Market/Production) - u8 RfCalVer[CALVERSZ]; // Rf Calibration version - u8 RfCalDate[CALDATESZ]; // Rf Calibration date -} __attribute__ ((packed)); - - struct app_info_block { u32 nTxMsg; // DPRAM msg sent to DSP with app_id u32 nRxMsg; // DPRAM msg rcv from dsp with app_id @@ -90,11 +27,6 @@ struct app_info_block { struct list_head app_sqlist; // link list of msgs for applicaton on slow queue } __attribute__((packed)); -struct prov_record { - struct list_head list; - u8 *pprov_data; -}; - /*end of Jim*/ #define DEBUG(args...) printk(KERN_INFO args) @@ -108,350 +40,25 @@ struct prov_record { #define LARGE_TIMEOUT 5000 -#define MAX_DSP_SESS_REC 1024 - -#define MAX_NUM_CARDS 32 - -#define DSPVERSZ 4 -#define HWSERNUMSZ 16 -#define SKUSZ 20 -#define EUISZ 8 -#define CALVERSZ 2 -#define CALDATESZ 6 -#define MODESZ 2 - -#define DSPID 0x20 -#define HOSTID 0x10 - -#define DSPOAM 0x80 -#define DSPAIRID 0x90 - -#define DRIVERID 0x00 -#define FMM 0x10 -#define NETWORKID 0x20 -#define AUTOLNCHID 0x30 -#define DSPLPBKID 0x40 - #define DSPBCMSGID 0x10 -#define ENET_MAX_SIZE 1514 -#define ENET_HEADER_SIZE 14 - - -#define CIS_NET_ADDR_OFFSET 0xff0 - -// MAGNEMITE specific - -#define FT1000_REG_MAG_UFDR 0x0000 // Uplink FIFO Data Register. - -#define FT1000_REG_MAG_UFDRL 0x0000 // Uplink FIFO Data Register low-word. - -#define FT1000_REG_MAG_UFDRH 0x0002 // Uplink FIFO Data Register high-word. - -#define FT1000_REG_MAG_UFER 0x0004 // Uplink FIFO End Register - -#define FT1000_REG_MAG_UFSR 0x0006 // Uplink FIFO Status Register - -#define FT1000_REG_MAG_DFR 0x0008 // Downlink FIFO Register - -#define FT1000_REG_MAG_DFRL 0x0008 // Downlink FIFO Register low-word - -#define FT1000_REG_MAG_DFRH 0x000a // Downlink FIFO Register high-word - -#define FT1000_REG_MAG_DFSR 0x000c // Downlink FIFO Status Register - -#define FT1000_REG_MAG_DPDATA 0x0010 // Dual Port RAM Indirect Data Register - -#define FT1000_REG_MAG_DPDATAL 0x0010 // Dual Port RAM Indirect Data Register low-word - -#define FT1000_REG_MAG_DPDATAH 0x0012 // Dual Port RAM Indirect Data Register high-word - -#define FT1000_REG_MAG_WATERMARK 0x002c // Supv. Control Reg. LLC register - -#define FT1000_REG_MAG_VERSION 0x0030 // LLC Version LLC register - - - -// Common - -#define FT1000_REG_DPRAM_ADDR 0x000E // DPRAM ADDRESS when card in IO mode - -#define FT1000_REG_SUP_CTRL 0x0020 // Supv. Control Reg. LLC register - -#define FT1000_REG_SUP_STAT 0x0022 // Supv. Status Reg LLC register - -#define FT1000_REG_RESET 0x0024 // Reset Reg LLC register - -#define FT1000_REG_SUP_ISR 0x0026 // Supv ISR LLC register - -#define FT1000_REG_SUP_IMASK 0x0028 // Supervisor Interrupt Mask LLC register - -#define FT1000_REG_DOORBELL 0x002a // Door Bell Reg LLC register - -#define FT1000_REG_ASIC_ID 0x002e // ASIC Identification Number - - // (Electrabuzz=0 Magnemite=TBD) - - - -// DSP doorbells - -#define FT1000_DB_DPRAM_RX 0x0001 // this value indicates that DSP has - - // data for host in DPRAM SlowQ - -#define FT1000_DB_DNLD_RX 0x0002 // Downloader handshake doorbell - -#define FT1000_ASIC_RESET_REQ 0x0004 - -#define FT1000_DSP_ASIC_RESET 0x0008 - - - -#define FT1000_DB_COND_RESET 0x0010 - - - -// Host doorbells - -#define FT1000_DB_DPRAM_TX 0x0100 // this value indicates that host has - - // data for DSP in DPRAM. - -#define FT1000_DB_DNLD_TX 0x0200 // Downloader handshake doorbell - -#define FT1000_ASIC_RESET_DSP 0x0400 - -#define FT1000_DB_HB 0x1000 // this value indicates that supervisor - - - -// Electrabuzz specific DPRAM mapping // has a heartbeat message for DSP. - -#define FT1000_DPRAM_BASE 0x1000 // 0x0000 to 0x07FF DPRAM 2Kx16 - R/W from PCMCIA or DSP - -#define FT1000_DPRAM_TX_BASE 0x1002 // TX AREA (SlowQ) - -#define FT1000_DPRAM_RX_BASE 0x1800 // RX AREA (SlowQ) - -#define FT1000_DPRAM_SIZE 0x1000 // 4K bytes - - - -#define FT1000_DRV_DEBUG 0x17E0 // Debug area for driver - -#define FT1000_FIFO_LEN 0x17FC // total length for DSP FIFO tracking - -#define FT1000_HI_HO 0x17FE // heartbeat with HI/HO - -#define FT1000_DSP_STATUS 0x1FFE // dsp status - non-zero is a request to reset dsp - - - -#define FT1000_DSP_CON_STATE 0x1FF8 // DSP Connection Status Info - -#define FT1000_DSP_LEDS 0x1FFA // DSP LEDS for rcv pwr strength, Rx data, Tx data - -#define DSP_TIMESTAMP 0x1FFC // dsp timestamp - -#define DSP_TIMESTAMP_DIFF 0x1FFA // difference of dsp timestamp in DPRAM and Pseudo header. - - - -#define FT1000_DPRAM_FEFE 0x1002 // Dsp Downloader handshake location - - - -#define FT1000_DSP_TIMER0 0x1FF0 - -#define FT1000_DSP_TIMER1 0x1FF2 - -#define FT1000_DSP_TIMER2 0x1FF4 - -#define FT1000_DSP_TIMER3 0x1FF6 - - +/* Electrabuzz specific DPRAM mapping */ +/* this is used by ft1000_usb driver - isn't that a bug? */ +#undef FT1000_DPRAM_RX_BASE +#define FT1000_DPRAM_RX_BASE 0x1800 /* RX AREA (SlowQ) */ // MEMORY MAP FOR MAGNEMITE - -#define FT1000_DPRAM_MAG_TX_BASE 0x0000 // TX AREA (SlowQ) - -#define FT1000_DPRAM_MAG_RX_BASE 0x0200 // RX AREA (SlowQ) - - - -#define FT1000_MAG_FIFO_LEN 0x1FF // total length for DSP FIFO tracking - -#define FT1000_MAG_FIFO_LEN_INDX 0x1 // low-word index - -#define FT1000_MAG_HI_HO 0x1FF // heartbeat with HI/HO - -#define FT1000_MAG_HI_HO_INDX 0x0 // high-word index - -#define FT1000_MAG_DSP_LEDS 0x3FE // dsp led status for PAD device - -#define FT1000_MAG_DSP_LEDS_INDX 0x1 // dsp led status for PAD device - - - -#define FT1000_MAG_DSP_CON_STATE 0x3FE // DSP Connection Status Info - -#define FT1000_MAG_DSP_CON_STATE_INDX 0x0 // DSP Connection Status Info - - - -#define FT1000_MAG_DPRAM_FEFE 0x000 // location for dsp ready indicator - -#define FT1000_MAG_DPRAM_FEFE_INDX 0x0 // location for dsp ready indicator - - - -#define FT1000_MAG_DSP_TIMER0 0x3FC - -#define FT1000_MAG_DSP_TIMER0_INDX 0x1 - - - -#define FT1000_MAG_DSP_TIMER1 0x3FC - -#define FT1000_MAG_DSP_TIMER1_INDX 0x0 - - - -#define FT1000_MAG_DSP_TIMER2 0x3FD - -#define FT1000_MAG_DSP_TIMER2_INDX 0x1 - - - -#define FT1000_MAG_DSP_TIMER3 0x3FD - -#define FT1000_MAG_DSP_TIMER3_INDX 0x0 - - - -#define FT1000_MAG_TOTAL_LEN 0x200 - -#define FT1000_MAG_TOTAL_LEN_INDX 0x1 - - - -#define FT1000_MAG_PH_LEN 0x200 - -#define FT1000_MAG_PH_LEN_INDX 0x0 - - - -#define FT1000_MAG_PORT_ID 0x201 - -#define FT1000_MAG_PORT_ID_INDX 0x0 - - - -// - -// Constants for the FT1000_REG_SUP_ISR - -// - -// Indicate the cause of an interrupt. - -// - -// SUPERVISOR ISR BIT MAPS - - - -#define ISR_EMPTY (u8)0x00 // no bits set in ISR - -#define ISR_DOORBELL_ACK (u8)0x01 // the doorbell i sent has been received. - -#define ISR_DOORBELL_PEND (u8)0x02 // doorbell for me - -#define ISR_RCV (u8)0x04 // packet received with no errors - -#define ISR_WATERMARK (u8)0x08 // - - - -// Interrupt mask register defines - -// note these are different from the ISR BIT MAPS. - -#define ISR_MASK_NONE 0x0000 - -#define ISR_MASK_DOORBELL_ACK 0x0001 - -#define ISR_MASK_DOORBELL_PEND 0x0002 - -#define ISR_MASK_RCV 0x0004 - -#define ISR_MASK_WATERMARK 0x0008 // Normally we will only mask the watermark interrupt when we want to enable interrupts. - -#define ISR_MASK_ALL 0xffff - - - -#define HOST_INTF_LE 0x0000 // Host interface little endian - -#define HOST_INTF_BE 0x0001 // Host interface big endian - - - -#define ISR_DEFAULT_MASK 0x7ff9 - - - -#define hi 0x6869 - -#define ho 0x686f - - - -#define FT1000_ASIC_RESET 0x80 // COR value for soft reset to PCMCIA core - -#define FT1000_ASIC_BITS 0x51 // Bits set in COR register under normal operation - -#define FT1000_ASIC_MAG_BITS 0x55 // Bits set in COR register under normal operation - - - -#define FT1000_COR_OFFSET 0x100 - - - -#define ELECTRABUZZ_ID 0 // ASIC ID for ELECTRABUZZ - -#define MAGNEMITE_ID 0x1a01 // ASIC ID for MAGNEMITE - - +/* the indexes are swapped comparing to PCMCIA - is it OK or a bug? */ +#undef FT1000_MAG_DSP_LED_INDX +#define FT1000_MAG_DSP_LED_INDX 0x1 /* dsp led status for PAD device */ +#undef FT1000_MAG_DSP_CON_STATE_INDX +#define FT1000_MAG_DSP_CON_STATE_INDX 0x0 /* DSP Connection Status Info */ // Maximum times trying to get ASIC out of reset - #define MAX_ASIC_RESET_CNT 20 - - -#define DSP_RESET_BIT 0x1 - -#define ASIC_RESET_BIT 0x2 - -#define DSP_UNENCRYPTED 0x4 - -#define DSP_ENCRYPTED 0x8 - -#define EFUSE_MEM_DISABLE 0x0040 - - #define MAX_BUF_SIZE 4096 -struct drv_msg { - struct pseudo_hdr pseudo; - u16 type; - u16 length; - u8 data[0]; -} __attribute__ ((packed)); - struct ft1000_device { struct usb_device *dev; diff --git a/drivers/staging/ft1000/ft1000.h b/drivers/staging/ft1000/ft1000.h new file mode 100644 index 000000000000..03baa5779234 --- /dev/null +++ b/drivers/staging/ft1000/ft1000.h @@ -0,0 +1,252 @@ +/* + * Common structures and definitions for FT1000 Flarion Flash OFDM PCMCIA and USB devices + * + * Originally copyright (c) 2002 Flarion Technologies + * + */ + +#define DSPVERSZ 4 +#define HWSERNUMSZ 16 +#define SKUSZ 20 +#define EUISZ 8 +#define MODESZ 2 +#define CALVERSZ 2 +#define CALDATESZ 6 + +#define ELECTRABUZZ_ID 0 /* ASIC ID for Electrabuzz */ +#define MAGNEMITE_ID 0x1a01 /* ASIC ID for Magnemite */ + +/* MEMORY MAP common to both ELECTRABUZZ and MAGNEMITE */ +#define FT1000_REG_DPRAM_ADDR 0x000E /* DPADR - Dual Port Ram Indirect Address Register */ +#define FT1000_REG_SUP_CTRL 0x0020 /* HCTR - Host Control Register */ +#define FT1000_REG_SUP_STAT 0x0022 /* HSTAT - Host Status Register */ +#define FT1000_REG_RESET 0x0024 /* HCTR - Host Control Register */ +#define FT1000_REG_SUP_ISR 0x0026 /* HISR - Host Interrupt Status Register */ +#define FT1000_REG_SUP_IMASK 0x0028 /* HIMASK - Host Interrupt Mask */ +#define FT1000_REG_DOORBELL 0x002a /* DBELL - Door Bell Register */ +#define FT1000_REG_ASIC_ID 0x002e /* ASICID - ASIC Identification Number */ + +/* MEMORY MAP FOR ELECTRABUZZ ASIC */ +#define FT1000_REG_UFIFO_STAT 0x0000 /* UFSR - Uplink FIFO status register */ +#define FT1000_REG_UFIFO_BEG 0x0002 /* UFBR - Uplink FIFO beginning register */ +#define FT1000_REG_UFIFO_MID 0x0004 /* UFMR - Uplink FIFO middle register */ +#define FT1000_REG_UFIFO_END 0x0006 /* UFER - Uplink FIFO end register */ +#define FT1000_REG_DFIFO_STAT 0x0008 /* DFSR - Downlink FIFO status register */ +#define FT1000_REG_DFIFO 0x000A /* DFR - Downlink FIFO Register */ +#define FT1000_REG_DPRAM_DATA 0x000C /* DPRAM - Dual Port Indirect Data Register */ +#define FT1000_REG_WATERMARK 0x0010 /* WMARK - Watermark Register */ + +/* MEMORY MAP FOR MAGNEMITE */ +#define FT1000_REG_MAG_UFDR 0x0000 /* UFDR - Uplink FIFO Data Register (32-bits) */ +#define FT1000_REG_MAG_UFDRL 0x0000 /* UFDRL - Uplink FIFO Data Register low-word (16-bits) */ +#define FT1000_REG_MAG_UFDRH 0x0002 /* UFDRH - Uplink FIFO Data Register high-word (16-bits) */ +#define FT1000_REG_MAG_UFER 0x0004 /* UFER - Uplink FIFO End Register */ +#define FT1000_REG_MAG_UFSR 0x0006 /* UFSR - Uplink FIFO Status Register */ +#define FT1000_REG_MAG_DFR 0x0008 /* DFR - Downlink FIFO Register (32-bits) */ +#define FT1000_REG_MAG_DFRL 0x0008 /* DFRL - Downlink FIFO Register low-word (16-bits) */ +#define FT1000_REG_MAG_DFRH 0x000a /* DFRH - Downlink FIFO Register high-word (16-bits) */ +#define FT1000_REG_MAG_DFSR 0x000c /* DFSR - Downlink FIFO Status Register */ +#define FT1000_REG_MAG_DPDATA 0x0010 /* DPDATA - Dual Port RAM Indirect Data Register (32-bits) */ +#define FT1000_REG_MAG_DPDATAL 0x0010 /* DPDATAL - Dual Port RAM Indirect Data Register low-word (16-bits) */ +#define FT1000_REG_MAG_DPDATAH 0x0012 /* DPDATAH - Dual Port RAM Indirect Data Register high-word (16-bits) */ +#define FT1000_REG_MAG_WATERMARK 0x002c /* WMARK - Watermark Register */ +#define FT1000_REG_MAG_VERSION 0x0030 /* LLC Version */ + +/* Reserved Dual Port RAM offsets for Electrabuzz */ +#define FT1000_DPRAM_TX_BASE 0x0002 /* Host to PC Card Messaging Area */ +#define FT1000_DPRAM_RX_BASE 0x0800 /* PC Card to Host Messaging Area */ +#define FT1000_FIFO_LEN 0x07FC /* total length for DSP FIFO tracking */ +#define FT1000_HI_HO 0x07FE /* heartbeat with HI/HO */ +#define FT1000_DSP_STATUS 0x0FFE /* dsp status - non-zero is a request to reset dsp */ +#define FT1000_DSP_LED 0x0FFA /* dsp led status for PAD device */ +#define FT1000_DSP_CON_STATE 0x0FF8 /* DSP Connection Status Info */ +#define FT1000_DPRAM_FEFE 0x0002 /* location for dsp ready indicator */ +#define FT1000_DSP_TIMER0 0x1FF0 /* Timer Field from Basestation */ +#define FT1000_DSP_TIMER1 0x1FF2 /* Timer Field from Basestation */ +#define FT1000_DSP_TIMER2 0x1FF4 /* Timer Field from Basestation */ +#define FT1000_DSP_TIMER3 0x1FF6 /* Timer Field from Basestation */ + +/* Reserved Dual Port RAM offsets for Magnemite */ +#define FT1000_DPRAM_MAG_TX_BASE 0x0000 /* Host to PC Card Messaging Area */ +#define FT1000_DPRAM_MAG_RX_BASE 0x0200 /* PC Card to Host Messaging Area */ + +#define FT1000_MAG_FIFO_LEN 0x1FF /* total length for DSP FIFO tracking */ +#define FT1000_MAG_FIFO_LEN_INDX 0x1 /* low-word index */ +#define FT1000_MAG_HI_HO 0x1FF /* heartbeat with HI/HO */ +#define FT1000_MAG_HI_HO_INDX 0x0 /* high-word index */ +#define FT1000_MAG_DSP_LED 0x3FE /* dsp led status for PAD device */ +#define FT1000_MAG_DSP_LED_INDX 0x0 /* dsp led status for PAD device */ +#define FT1000_MAG_DSP_CON_STATE 0x3FE /* DSP Connection Status Info */ +#define FT1000_MAG_DSP_CON_STATE_INDX 0x1 /* DSP Connection Status Info */ +#define FT1000_MAG_DPRAM_FEFE 0x000 /* location for dsp ready indicator */ +#define FT1000_MAG_DPRAM_FEFE_INDX 0x0 /* location for dsp ready indicator */ +#define FT1000_MAG_DSP_TIMER0 0x3FC /* Timer Field from Basestation */ +#define FT1000_MAG_DSP_TIMER0_INDX 0x1 +#define FT1000_MAG_DSP_TIMER1 0x3FC /* Timer Field from Basestation */ +#define FT1000_MAG_DSP_TIMER1_INDX 0x0 +#define FT1000_MAG_DSP_TIMER2 0x3FD /* Timer Field from Basestation */ +#define FT1000_MAG_DSP_TIMER2_INDX 0x1 +#define FT1000_MAG_DSP_TIMER3 0x3FD /* Timer Field from Basestation */ +#define FT1000_MAG_DSP_TIMER3_INDX 0x0 +#define FT1000_MAG_TOTAL_LEN 0x200 +#define FT1000_MAG_TOTAL_LEN_INDX 0x1 +#define FT1000_MAG_PH_LEN 0x200 +#define FT1000_MAG_PH_LEN_INDX 0x0 +#define FT1000_MAG_PORT_ID 0x201 +#define FT1000_MAG_PORT_ID_INDX 0x0 + +#define HOST_INTF_LE 0x0 /* Host interface little endian mode */ +#define HOST_INTF_BE 0x1 /* Host interface big endian mode */ + +/* FT1000 to Host Doorbell assignments */ +#define FT1000_DB_DPRAM_RX 0x0001 /* this value indicates that DSP has data for host in DPRAM */ +#define FT1000_DB_DNLD_RX 0x0002 /* Downloader handshake doorbell */ +#define FT1000_ASIC_RESET_REQ 0x0004 /* DSP requesting host to reset the ASIC */ +#define FT1000_DSP_ASIC_RESET 0x0008 /* DSP indicating host that it will reset the ASIC */ +#define FT1000_DB_COND_RESET 0x0010 /* DSP request for a card reset. */ + +/* Host to FT1000 Doorbell assignments */ +#define FT1000_DB_DPRAM_TX 0x0100 /* this value indicates that host has data for DSP in DPRAM. */ +#define FT1000_DB_DNLD_TX 0x0200 /* Downloader handshake doorbell */ +#define FT1000_ASIC_RESET_DSP 0x0400 /* Responds to FT1000_ASIC_RESET_REQ */ +#define FT1000_DB_HB 0x1000 /* Indicates that supervisor has a heartbeat message for DSP. */ + +#define hi 0x6869 /* PC Card heartbeat values */ +#define ho 0x686f /* PC Card heartbeat values */ + +/* Magnemite specific defines */ +#define hi_mag 0x6968 /* Byte swap hi to avoid additional system call */ +#define ho_mag 0x6f68 /* Byte swap ho to avoid additional system call */ + +/* Bit field definitions for Host Interrupt Status Register */ +/* Indicate the cause of an interrupt. */ +#define ISR_EMPTY 0x00 /* no bits set */ +#define ISR_DOORBELL_ACK 0x01 /* Doorbell acknowledge from DSP */ +#define ISR_DOORBELL_PEND 0x02 /* Doorbell pending from DSP */ +#define ISR_RCV 0x04 /* Packet available in Downlink FIFO */ +#define ISR_WATERMARK 0x08 /* Watermark requirements satisfied */ + +/* Bit field definition for Host Interrupt Mask */ +#define ISR_MASK_NONE 0x0000 /* no bits set */ +#define ISR_MASK_DOORBELL_ACK 0x0001 /* Doorbell acknowledge mask */ +#define ISR_MASK_DOORBELL_PEND 0x0002 /* Doorbell pending mask */ +#define ISR_MASK_RCV 0x0004 /* Downlink Packet available mask */ +#define ISR_MASK_WATERMARK 0x0008 /* Watermark interrupt mask */ +#define ISR_MASK_ALL 0xffff /* Mask all interrupts */ +/* Default interrupt mask (Enable Doorbell pending and Packet available interrupts) */ +#define ISR_DEFAULT_MASK 0x7ff9 + +/* Bit field definition for Host Control Register */ +#define DSP_RESET_BIT 0x0001 /* Bit field to control dsp reset state */ + /* (0 = out of reset 1 = reset) */ +#define ASIC_RESET_BIT 0x0002 /* Bit field to control ASIC reset state */ + /* (0 = out of reset 1 = reset) */ +#define DSP_UNENCRYPTED 0x0004 +#define DSP_ENCRYPTED 0x0008 +#define EFUSE_MEM_DISABLE 0x0040 + +/* Application specific IDs */ +#define DSPID 0x20 +#define HOSTID 0x10 +#define DSPAIRID 0x90 +#define DRIVERID 0x00 +#define NETWORKID 0x20 + +/* Size of DPRAM Message */ +#define MAX_CMD_SQSIZE 1780 + +#define ENET_MAX_SIZE 1514 +#define ENET_HEADER_SIZE 14 + +#define SLOWQ_TYPE 0 +#define FASTQ_TYPE 1 + +#define MAX_DSP_SESS_REC 1024 + +#define DSP_QID_OFFSET 4 + +/* Driver message types */ +#define MEDIA_STATE 0x0010 +#define TIME_UPDATE 0x0020 +#define DSP_PROVISION 0x0030 +#define DSP_INIT_MSG 0x0050 +#define DSP_HIBERNATE 0x0060 +#define DSP_STORE_INFO 0x0070 +#define DSP_GET_INFO 0x0071 +#define GET_DRV_ERR_RPT_MSG 0x0073 +#define RSP_DRV_ERR_RPT_MSG 0x0074 + +/* Driver Error Messages for DSP */ +#define DSP_HB_INFO 0x7ef0 +#define DSP_FIFO_INFO 0x7ef1 +#define DSP_CONDRESET_INFO 0x7ef2 +#define DSP_CMDLEN_INFO 0x7ef3 +#define DSP_CMDPHCKSUM_INFO 0x7ef4 +#define DSP_PKTPHCKSUM_INFO 0x7ef5 +#define DSP_PKTLEN_INFO 0x7ef6 +#define DSP_USER_RESET 0x7ef7 +#define FIFO_FLUSH_MAXLIMIT 0x7ef8 +#define FIFO_FLUSH_BADCNT 0x7ef9 +#define FIFO_ZERO_LEN 0x7efa + +/* Pseudo Header structure */ +struct pseudo_hdr { + unsigned short length; /* length of msg body */ + unsigned char source; /* hardware source id */ + /* Host = 0x10 */ + /* Dsp = 0x20 */ + unsigned char destination; /* hardware destination id (refer to source) */ + unsigned char portdest; /* software destination port id */ + /* Host = 0x00 */ + /* Applicaton Broadcast = 0x10 */ + /* Network Stack = 0x20 */ + /* Dsp OAM = 0x80 */ + /* Dsp Airlink = 0x90 */ + /* Dsp Loader = 0xa0 */ + /* Dsp MIP = 0xb0 */ + unsigned char portsrc; /* software source port id (refer to portdest) */ + unsigned short sh_str_id; /* not used */ + unsigned char control; /* not used */ + unsigned char rsvd1; + unsigned char seq_num; /* message sequence number */ + unsigned char rsvd2; + unsigned short qos_class; /* not used */ + unsigned short checksum; /* pseudo header checksum */ +} __packed; + +struct drv_msg { + struct pseudo_hdr pseudo; + u16 type; + u16 length; + u8 data[0]; +} __packed; + +struct media_msg { + struct pseudo_hdr pseudo; + u16 type; + u16 length; + u16 state; + u32 ip_addr; + u32 net_mask; + u32 gateway; + u32 dns_1; + u32 dns_2; +} __packed; + +struct dsp_init_msg { + struct pseudo_hdr pseudo; + u16 type; + u16 length; + u8 DspVer[DSPVERSZ]; /* DSP version number */ + u8 HwSerNum[HWSERNUMSZ]; /* Hardware Serial Number */ + u8 Sku[SKUSZ]; /* SKU */ + u8 eui64[EUISZ]; /* EUI64 */ + u8 ProductMode[MODESZ]; /* Product Mode (Market/Production) */ + u8 RfCalVer[CALVERSZ]; /* Rf Calibration version */ + u8 RfCalDate[CALDATESZ]; /* Rf Calibration date */ +} __packed; + +struct prov_record { + struct list_head list; + u8 *pprov_data; +}; diff --git a/drivers/staging/generic_serial/Kconfig b/drivers/staging/generic_serial/Kconfig deleted file mode 100644 index 795daea37750..000000000000 --- a/drivers/staging/generic_serial/Kconfig +++ /dev/null @@ -1,45 +0,0 @@ -config A2232 - tristate "Commodore A2232 serial support (EXPERIMENTAL)" - depends on EXPERIMENTAL && ZORRO && BROKEN - ---help--- - This option supports the 2232 7-port serial card shipped with the - Amiga 2000 and other Zorro-bus machines, dating from 1989. At - a max of 19,200 bps, the ports are served by a 6551 ACIA UART chip - each, plus a 8520 CIA, and a master 6502 CPU and buffer as well. The - ports were connected with 8 pin DIN connectors on the card bracket, - for which 8 pin to DB25 adapters were supplied. The card also had - jumpers internally to toggle various pinning configurations. - - This driver can be built as a module; but then "generic_serial" - will also be built as a module. This has to be loaded before - "ser_a2232". If you want to do this, answer M here. - -config SX - tristate "Specialix SX (and SI) card support" - depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA) && BROKEN - help - This is a driver for the SX and SI multiport serial cards. - Please read the file for details. - - This driver can only be built as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called sx. If you want to do that, say M here. - -config RIO - tristate "Specialix RIO system support" - depends on SERIAL_NONSTANDARD && BROKEN - help - This is a driver for the Specialix RIO, a smart serial card which - drives an outboard box that can support up to 128 ports. Product - information is at . - There are both ISA and PCI versions. - -config RIO_OLDPCI - bool "Support really old RIO/PCI cards" - depends on RIO - help - Older RIO PCI cards need some initialization-time configuration to - determine the IRQ and some control addresses. If you have a RIO and - this doesn't seem to work, try setting this to Y. - - diff --git a/drivers/staging/generic_serial/Makefile b/drivers/staging/generic_serial/Makefile deleted file mode 100644 index ffc90c8b013c..000000000000 --- a/drivers/staging/generic_serial/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o -obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o -obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o -obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o -obj-$(CONFIG_SX) += sx.o generic_serial.o -obj-$(CONFIG_RIO) += rio/ generic_serial.o diff --git a/drivers/staging/generic_serial/TODO b/drivers/staging/generic_serial/TODO deleted file mode 100644 index 88756453ac6c..000000000000 --- a/drivers/staging/generic_serial/TODO +++ /dev/null @@ -1,6 +0,0 @@ -These are a few tty/serial drivers that either do not build, -or work if they do build, or if they seem to work, are for obsolete -hardware, or are full of unfixable races and no one uses them anymore. - -If no one steps up to adopt any of these drivers, they will be removed -in the 2.6.41 release. diff --git a/drivers/staging/generic_serial/generic_serial.c b/drivers/staging/generic_serial/generic_serial.c deleted file mode 100644 index f29dda4e9f20..000000000000 --- a/drivers/staging/generic_serial/generic_serial.c +++ /dev/null @@ -1,844 +0,0 @@ -/* - * generic_serial.c - * - * Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl - * - * written for the SX serial driver. - * Contains the code that should be shared over all the serial drivers. - * - * Credit for the idea to do it this way might go to Alan Cox. - * - * - * Version 0.1 -- December, 1998. Initial version. - * Version 0.2 -- March, 1999. Some more routines. Bugfixes. Etc. - * Version 0.5 -- August, 1999. Some more fixes. Reformat for Linus. - * - * BitWizard is actively maintaining this file. We sometimes find - * that someone submitted changes to this file. We really appreciate - * your help, but please submit changes through us. We're doing our - * best to be responsive. -- REW - * */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG - -static int gs_debug; - -#ifdef DEBUG -#define gs_dprintk(f, str...) if (gs_debug & f) printk (str) -#else -#define gs_dprintk(f, str...) /* nothing */ -#endif - -#define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter %s\n", __func__) -#define func_exit() gs_dprintk (GS_DEBUG_FLOW, "gs: exit %s\n", __func__) - -#define RS_EVENT_WRITE_WAKEUP 1 - -module_param(gs_debug, int, 0644); - - -int gs_put_char(struct tty_struct * tty, unsigned char ch) -{ - struct gs_port *port; - - func_enter (); - - port = tty->driver_data; - - if (!port) return 0; - - if (! (port->port.flags & ASYNC_INITIALIZED)) return 0; - - /* Take a lock on the serial tranmit buffer! */ - mutex_lock(& port->port_write_mutex); - - if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { - /* Sorry, buffer is full, drop character. Update statistics???? -- REW */ - mutex_unlock(&port->port_write_mutex); - return 0; - } - - port->xmit_buf[port->xmit_head++] = ch; - port->xmit_head &= SERIAL_XMIT_SIZE - 1; - port->xmit_cnt++; /* Characters in buffer */ - - mutex_unlock(&port->port_write_mutex); - func_exit (); - return 1; -} - - -/* -> Problems to take into account are: -> -1- Interrupts that empty part of the buffer. -> -2- page faults on the access to userspace. -> -3- Other processes that are also trying to do a "write". -*/ - -int gs_write(struct tty_struct * tty, - const unsigned char *buf, int count) -{ - struct gs_port *port; - int c, total = 0; - int t; - - func_enter (); - - port = tty->driver_data; - - if (!port) return 0; - - if (! (port->port.flags & ASYNC_INITIALIZED)) - return 0; - - /* get exclusive "write" access to this port (problem 3) */ - /* This is not a spinlock because we can have a disk access (page - fault) in copy_from_user */ - mutex_lock(& port->port_write_mutex); - - while (1) { - - c = count; - - /* This is safe because we "OWN" the "head". No one else can - change the "head": we own the port_write_mutex. */ - /* Don't overrun the end of the buffer */ - t = SERIAL_XMIT_SIZE - port->xmit_head; - if (t < c) c = t; - - /* This is safe because the xmit_cnt can only decrease. This - would increase "t", so we might copy too little chars. */ - /* Don't copy past the "head" of the buffer */ - t = SERIAL_XMIT_SIZE - 1 - port->xmit_cnt; - if (t < c) c = t; - - /* Can't copy more? break out! */ - if (c <= 0) break; - - memcpy (port->xmit_buf + port->xmit_head, buf, c); - - port -> xmit_cnt += c; - port -> xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE -1); - buf += c; - count -= c; - total += c; - } - mutex_unlock(& port->port_write_mutex); - - gs_dprintk (GS_DEBUG_WRITE, "write: interrupts are %s\n", - (port->port.flags & GS_TX_INTEN)?"enabled": "disabled"); - - if (port->xmit_cnt && - !tty->stopped && - !tty->hw_stopped && - !(port->port.flags & GS_TX_INTEN)) { - port->port.flags |= GS_TX_INTEN; - port->rd->enable_tx_interrupts (port); - } - func_exit (); - return total; -} - - - -int gs_write_room(struct tty_struct * tty) -{ - struct gs_port *port = tty->driver_data; - int ret; - - func_enter (); - ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; - if (ret < 0) - ret = 0; - func_exit (); - return ret; -} - - -int gs_chars_in_buffer(struct tty_struct *tty) -{ - struct gs_port *port = tty->driver_data; - func_enter (); - - func_exit (); - return port->xmit_cnt; -} - - -static int gs_real_chars_in_buffer(struct tty_struct *tty) -{ - struct gs_port *port; - func_enter (); - - port = tty->driver_data; - - if (!port->rd) return 0; - if (!port->rd->chars_in_buffer) return 0; - - func_exit (); - return port->xmit_cnt + port->rd->chars_in_buffer (port); -} - - -static int gs_wait_tx_flushed (void * ptr, unsigned long timeout) -{ - struct gs_port *port = ptr; - unsigned long end_jiffies; - int jiffies_to_transmit, charsleft = 0, rv = 0; - int rcib; - - func_enter(); - - gs_dprintk (GS_DEBUG_FLUSH, "port=%p.\n", port); - if (port) { - gs_dprintk (GS_DEBUG_FLUSH, "xmit_cnt=%x, xmit_buf=%p, tty=%p.\n", - port->xmit_cnt, port->xmit_buf, port->port.tty); - } - - if (!port || port->xmit_cnt < 0 || !port->xmit_buf) { - gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n"); - func_exit(); - return -EINVAL; /* This is an error which we don't know how to handle. */ - } - - rcib = gs_real_chars_in_buffer(port->port.tty); - - if(rcib <= 0) { - gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n"); - func_exit(); - return rv; - } - /* stop trying: now + twice the time it would normally take + seconds */ - if (timeout == 0) timeout = MAX_SCHEDULE_TIMEOUT; - end_jiffies = jiffies; - if (timeout != MAX_SCHEDULE_TIMEOUT) - end_jiffies += port->baud?(2 * rcib * 10 * HZ / port->baud):0; - end_jiffies += timeout; - - gs_dprintk (GS_DEBUG_FLUSH, "now=%lx, end=%lx (%ld).\n", - jiffies, end_jiffies, end_jiffies-jiffies); - - /* the expression is actually jiffies < end_jiffies, but that won't - work around the wraparound. Tricky eh? */ - while ((charsleft = gs_real_chars_in_buffer (port->port.tty)) && - time_after (end_jiffies, jiffies)) { - /* Units check: - chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies! - check! */ - - charsleft += 16; /* Allow 16 chars more to be transmitted ... */ - jiffies_to_transmit = port->baud?(1 + charsleft * 10 * HZ / port->baud):0; - /* ^^^ Round up.... */ - if (jiffies_to_transmit <= 0) jiffies_to_transmit = 1; - - gs_dprintk (GS_DEBUG_FLUSH, "Expect to finish in %d jiffies " - "(%d chars).\n", jiffies_to_transmit, charsleft); - - msleep_interruptible(jiffies_to_msecs(jiffies_to_transmit)); - if (signal_pending (current)) { - gs_dprintk (GS_DEBUG_FLUSH, "Signal pending. Bombing out: "); - rv = -EINTR; - break; - } - } - - gs_dprintk (GS_DEBUG_FLUSH, "charsleft = %d.\n", charsleft); - set_current_state (TASK_RUNNING); - - func_exit(); - return rv; -} - - - -void gs_flush_buffer(struct tty_struct *tty) -{ - struct gs_port *port; - unsigned long flags; - - func_enter (); - - port = tty->driver_data; - - if (!port) return; - - /* XXX Would the write semaphore do? */ - spin_lock_irqsave (&port->driver_lock, flags); - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - spin_unlock_irqrestore (&port->driver_lock, flags); - - tty_wakeup(tty); - func_exit (); -} - - -void gs_flush_chars(struct tty_struct * tty) -{ - struct gs_port *port; - - func_enter (); - - port = tty->driver_data; - - if (!port) return; - - if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || - !port->xmit_buf) { - func_exit (); - return; - } - - /* Beats me -- REW */ - port->port.flags |= GS_TX_INTEN; - port->rd->enable_tx_interrupts (port); - func_exit (); -} - - -void gs_stop(struct tty_struct * tty) -{ - struct gs_port *port; - - func_enter (); - - port = tty->driver_data; - - if (!port) return; - - if (port->xmit_cnt && - port->xmit_buf && - (port->port.flags & GS_TX_INTEN) ) { - port->port.flags &= ~GS_TX_INTEN; - port->rd->disable_tx_interrupts (port); - } - func_exit (); -} - - -void gs_start(struct tty_struct * tty) -{ - struct gs_port *port; - - port = tty->driver_data; - - if (!port) return; - - if (port->xmit_cnt && - port->xmit_buf && - !(port->port.flags & GS_TX_INTEN) ) { - port->port.flags |= GS_TX_INTEN; - port->rd->enable_tx_interrupts (port); - } - func_exit (); -} - - -static void gs_shutdown_port (struct gs_port *port) -{ - unsigned long flags; - - func_enter(); - - if (!port) return; - - if (!(port->port.flags & ASYNC_INITIALIZED)) - return; - - spin_lock_irqsave(&port->driver_lock, flags); - - if (port->xmit_buf) { - free_page((unsigned long) port->xmit_buf); - port->xmit_buf = NULL; - } - - if (port->port.tty) - set_bit(TTY_IO_ERROR, &port->port.tty->flags); - - port->rd->shutdown_port (port); - - port->port.flags &= ~ASYNC_INITIALIZED; - spin_unlock_irqrestore(&port->driver_lock, flags); - - func_exit(); -} - - -void gs_hangup(struct tty_struct *tty) -{ - struct gs_port *port; - unsigned long flags; - - func_enter (); - - port = tty->driver_data; - tty = port->port.tty; - if (!tty) - return; - - gs_shutdown_port (port); - spin_lock_irqsave(&port->port.lock, flags); - port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE); - port->port.tty = NULL; - port->port.count = 0; - spin_unlock_irqrestore(&port->port.lock, flags); - - wake_up_interruptible(&port->port.open_wait); - func_exit (); -} - - -int gs_block_til_ready(void *port_, struct file * filp) -{ - struct gs_port *gp = port_; - struct tty_port *port = &gp->port; - DECLARE_WAITQUEUE(wait, current); - int retval; - int do_clocal = 0; - int CD; - struct tty_struct *tty; - unsigned long flags; - - func_enter (); - - if (!port) return 0; - - tty = port->tty; - - gs_dprintk (GS_DEBUG_BTR, "Entering gs_block_till_ready.\n"); - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { - interruptible_sleep_on(&port->close_wait); - if (port->flags & ASYNC_HUP_NOTIFY) - return -EAGAIN; - else - return -ERESTARTSYS; - } - - gs_dprintk (GS_DEBUG_BTR, "after hung up\n"); - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - port->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - gs_dprintk (GS_DEBUG_BTR, "after nonblock\n"); - - if (C_CLOCAL(tty)) - do_clocal = 1; - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, port->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - - add_wait_queue(&port->open_wait, &wait); - - gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); - spin_lock_irqsave(&port->lock, flags); - if (!tty_hung_up_p(filp)) { - port->count--; - } - port->blocked_open++; - spin_unlock_irqrestore(&port->lock, flags); - while (1) { - CD = tty_port_carrier_raised(port); - gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD); - set_current_state (TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(port->flags & ASYNC_INITIALIZED)) { - if (port->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; - break; - } - if (!(port->flags & ASYNC_CLOSING) && - (do_clocal || CD)) - break; - gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n", - (int)signal_pending (current), *(long*)(¤t->blocked)); - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } - schedule(); - } - gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n", - port->blocked_open); - set_current_state (TASK_RUNNING); - remove_wait_queue(&port->open_wait, &wait); - - spin_lock_irqsave(&port->lock, flags); - if (!tty_hung_up_p(filp)) { - port->count++; - } - port->blocked_open--; - if (retval == 0) - port->flags |= ASYNC_NORMAL_ACTIVE; - spin_unlock_irqrestore(&port->lock, flags); - func_exit (); - return retval; -} - - -void gs_close(struct tty_struct * tty, struct file * filp) -{ - unsigned long flags; - struct gs_port *port; - - func_enter (); - - port = tty->driver_data; - - if (!port) return; - - if (!port->port.tty) { - /* This seems to happen when this is called from vhangup. */ - gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->port.tty is NULL\n"); - port->port.tty = tty; - } - - spin_lock_irqsave(&port->port.lock, flags); - - if (tty_hung_up_p(filp)) { - spin_unlock_irqrestore(&port->port.lock, flags); - if (port->rd->hungup) - port->rd->hungup (port); - func_exit (); - return; - } - - if ((tty->count == 1) && (port->port.count != 1)) { - printk(KERN_ERR "gs: gs_close port %p: bad port count;" - " tty->count is 1, port count is %d\n", port, port->port.count); - port->port.count = 1; - } - if (--port->port.count < 0) { - printk(KERN_ERR "gs: gs_close port %p: bad port count: %d\n", port, port->port.count); - port->port.count = 0; - } - - if (port->port.count) { - gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->port.count); - spin_unlock_irqrestore(&port->port.lock, flags); - func_exit (); - return; - } - port->port.flags |= ASYNC_CLOSING; - - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - /* if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, port->closing_wait); */ - - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - - spin_lock(&port->driver_lock); - port->rd->disable_rx_interrupts (port); - spin_unlock(&port->driver_lock); - spin_unlock_irqrestore(&port->port.lock, flags); - - /* close has no way of returning "EINTR", so discard return value */ - if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) - gs_wait_tx_flushed (port, port->closing_wait); - - port->port.flags &= ~GS_ACTIVE; - - gs_flush_buffer(tty); - - tty_ldisc_flush(tty); - tty->closing = 0; - - spin_lock_irqsave(&port->driver_lock, flags); - port->event = 0; - port->rd->close (port); - port->rd->shutdown_port (port); - spin_unlock_irqrestore(&port->driver_lock, flags); - - spin_lock_irqsave(&port->port.lock, flags); - port->port.tty = NULL; - - if (port->port.blocked_open) { - if (port->close_delay) { - spin_unlock_irqrestore(&port->port.lock, flags); - msleep_interruptible(jiffies_to_msecs(port->close_delay)); - spin_lock_irqsave(&port->port.lock, flags); - } - wake_up_interruptible(&port->port.open_wait); - } - port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED); - spin_unlock_irqrestore(&port->port.lock, flags); - wake_up_interruptible(&port->port.close_wait); - - func_exit (); -} - - -void gs_set_termios (struct tty_struct * tty, - struct ktermios * old_termios) -{ - struct gs_port *port; - int baudrate, tmp, rv; - struct ktermios *tiosp; - - func_enter(); - - port = tty->driver_data; - - if (!port) return; - if (!port->port.tty) { - /* This seems to happen when this is called after gs_close. */ - gs_dprintk (GS_DEBUG_TERMIOS, "gs: Odd: port->port.tty is NULL\n"); - port->port.tty = tty; - } - - - tiosp = tty->termios; - - if (gs_debug & GS_DEBUG_TERMIOS) { - gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp); - } - - if(old_termios && (gs_debug & GS_DEBUG_TERMIOS)) { - if(tiosp->c_iflag != old_termios->c_iflag) printk("c_iflag changed\n"); - if(tiosp->c_oflag != old_termios->c_oflag) printk("c_oflag changed\n"); - if(tiosp->c_cflag != old_termios->c_cflag) printk("c_cflag changed\n"); - if(tiosp->c_lflag != old_termios->c_lflag) printk("c_lflag changed\n"); - if(tiosp->c_line != old_termios->c_line) printk("c_line changed\n"); - if(!memcmp(tiosp->c_cc, old_termios->c_cc, NCC)) printk("c_cc changed\n"); - } - - baudrate = tty_get_baud_rate(tty); - - if ((tiosp->c_cflag & CBAUD) == B38400) { - if ( (port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - baudrate = 57600; - else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - baudrate = 115200; - else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - baudrate = 230400; - else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - baudrate = 460800; - else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) - baudrate = (port->baud_base / port->custom_divisor); - } - - /* I recommend using THIS instead of the mess in termios (and - duplicating the above code). Next we should create a clean - interface towards this variable. If your card supports arbitrary - baud rates, (e.g. CD1400 or 16550 based cards) then everything - will be very easy..... */ - port->baud = baudrate; - - /* Two timer ticks seems enough to wakeup something like SLIP driver */ - /* Baudrate/10 is cps. Divide by HZ to get chars per tick. */ - tmp = (baudrate / 10 / HZ) * 2; - - if (tmp < 0) tmp = 0; - if (tmp >= SERIAL_XMIT_SIZE) tmp = SERIAL_XMIT_SIZE-1; - - port->wakeup_chars = tmp; - - /* We should really wait for the characters to be all sent before - changing the settings. -- CAL */ - rv = gs_wait_tx_flushed (port, MAX_SCHEDULE_TIMEOUT); - if (rv < 0) return /* rv */; - - rv = port->rd->set_real_termios(port); - if (rv < 0) return /* rv */; - - if ((!old_termios || - (old_termios->c_cflag & CRTSCTS)) && - !( tiosp->c_cflag & CRTSCTS)) { - tty->stopped = 0; - gs_start(tty); - } - -#ifdef tytso_patch_94Nov25_1726 - /* This "makes sense", Why is it commented out? */ - - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&port->gs.open_wait); -#endif - - func_exit(); - return /* 0 */; -} - - - -/* Must be called with interrupts enabled */ -int gs_init_port(struct gs_port *port) -{ - unsigned long flags; - - func_enter (); - - if (port->port.flags & ASYNC_INITIALIZED) { - func_exit (); - return 0; - } - if (!port->xmit_buf) { - /* We may sleep in get_zeroed_page() */ - unsigned long tmp; - - tmp = get_zeroed_page(GFP_KERNEL); - spin_lock_irqsave (&port->driver_lock, flags); - if (port->xmit_buf) - free_page (tmp); - else - port->xmit_buf = (unsigned char *) tmp; - spin_unlock_irqrestore(&port->driver_lock, flags); - if (!port->xmit_buf) { - func_exit (); - return -ENOMEM; - } - } - - spin_lock_irqsave (&port->driver_lock, flags); - if (port->port.tty) - clear_bit(TTY_IO_ERROR, &port->port.tty->flags); - mutex_init(&port->port_write_mutex); - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - spin_unlock_irqrestore(&port->driver_lock, flags); - gs_set_termios(port->port.tty, NULL); - spin_lock_irqsave (&port->driver_lock, flags); - port->port.flags |= ASYNC_INITIALIZED; - port->port.flags &= ~GS_TX_INTEN; - - spin_unlock_irqrestore(&port->driver_lock, flags); - func_exit (); - return 0; -} - - -int gs_setserial(struct gs_port *port, struct serial_struct __user *sp) -{ - struct serial_struct sio; - - if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) - return(-EFAULT); - - if (!capable(CAP_SYS_ADMIN)) { - if ((sio.baud_base != port->baud_base) || - (sio.close_delay != port->close_delay) || - ((sio.flags & ~ASYNC_USR_MASK) != - (port->port.flags & ~ASYNC_USR_MASK))) - return(-EPERM); - } - - port->port.flags = (port->port.flags & ~ASYNC_USR_MASK) | - (sio.flags & ASYNC_USR_MASK); - - port->baud_base = sio.baud_base; - port->close_delay = sio.close_delay; - port->closing_wait = sio.closing_wait; - port->custom_divisor = sio.custom_divisor; - - gs_set_termios (port->port.tty, NULL); - - return 0; -} - - -/*****************************************************************************/ - -/* - * Generate the serial struct info. - */ - -int gs_getserial(struct gs_port *port, struct serial_struct __user *sp) -{ - struct serial_struct sio; - - memset(&sio, 0, sizeof(struct serial_struct)); - sio.flags = port->port.flags; - sio.baud_base = port->baud_base; - sio.close_delay = port->close_delay; - sio.closing_wait = port->closing_wait; - sio.custom_divisor = port->custom_divisor; - sio.hub6 = 0; - - /* If you want you can override these. */ - sio.type = PORT_UNKNOWN; - sio.xmit_fifo_size = -1; - sio.line = -1; - sio.port = -1; - sio.irq = -1; - - if (port->rd->getserial) - port->rd->getserial (port, &sio); - - if (copy_to_user(sp, &sio, sizeof(struct serial_struct))) - return -EFAULT; - return 0; - -} - - -void gs_got_break(struct gs_port *port) -{ - func_enter (); - - tty_insert_flip_char(port->port.tty, 0, TTY_BREAK); - tty_schedule_flip(port->port.tty); - if (port->port.flags & ASYNC_SAK) { - do_SAK (port->port.tty); - } - - func_exit (); -} - - -EXPORT_SYMBOL(gs_put_char); -EXPORT_SYMBOL(gs_write); -EXPORT_SYMBOL(gs_write_room); -EXPORT_SYMBOL(gs_chars_in_buffer); -EXPORT_SYMBOL(gs_flush_buffer); -EXPORT_SYMBOL(gs_flush_chars); -EXPORT_SYMBOL(gs_stop); -EXPORT_SYMBOL(gs_start); -EXPORT_SYMBOL(gs_hangup); -EXPORT_SYMBOL(gs_block_til_ready); -EXPORT_SYMBOL(gs_close); -EXPORT_SYMBOL(gs_set_termios); -EXPORT_SYMBOL(gs_init_port); -EXPORT_SYMBOL(gs_setserial); -EXPORT_SYMBOL(gs_getserial); -EXPORT_SYMBOL(gs_got_break); - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/generic_serial/rio/Makefile b/drivers/staging/generic_serial/rio/Makefile deleted file mode 100644 index 1661875883fb..000000000000 --- a/drivers/staging/generic_serial/rio/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for the linux rio-subsystem. -# -# (C) R.E.Wolff@BitWizard.nl -# -# This file is GPL. See other files for the full Blurb. I'm lazy today. -# - -obj-$(CONFIG_RIO) += rio.o - -rio-y := rio_linux.o rioinit.o rioboot.o riocmd.o rioctrl.o riointr.o \ - rioparam.o rioroute.o riotable.o riotty.o diff --git a/drivers/staging/generic_serial/rio/board.h b/drivers/staging/generic_serial/rio/board.h deleted file mode 100644 index bdea633a9076..000000000000 --- a/drivers/staging/generic_serial/rio/board.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : board.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:07 -** Retrieved : 11/6/98 11:34:20 -** -** ident @(#)board.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_board_h__ -#define __rio_board_h__ - -/* -** board.h contains the definitions for the *hardware* of the host cards. -** It describes the memory overlay for the dual port RAM area. -*/ - -#define DP_SRAM1_SIZE 0x7C00 -#define DP_SRAM2_SIZE 0x0200 -#define DP_SRAM3_SIZE 0x7000 -#define DP_SCRATCH_SIZE 0x1000 -#define DP_PARMMAP_ADDR 0x01FE /* offset into SRAM2 */ -#define DP_STARTUP_ADDR 0x01F8 /* offset into SRAM2 */ - -/* -** The shape of the Host Control area, at offset 0x7C00, Write Only -*/ -struct s_Ctrl { - u8 DpCtl; /* 7C00 */ - u8 Dp_Unused2_[127]; - u8 DpIntSet; /* 7C80 */ - u8 Dp_Unused3_[127]; - u8 DpTpuReset; /* 7D00 */ - u8 Dp_Unused4_[127]; - u8 DpIntReset; /* 7D80 */ - u8 Dp_Unused5_[127]; -}; - -/* -** The PROM data area on the host (0x7C00), Read Only -*/ -struct s_Prom { - u16 DpSlxCode[2]; - u16 DpRev; - u16 Dp_Unused6_; - u16 DpUniq[4]; - u16 DpJahre; - u16 DpWoche; - u16 DpHwFeature[5]; - u16 DpOemId; - u16 DpSiggy[16]; -}; - -/* -** Union of the Ctrl and Prom areas -*/ -union u_CtrlProm { /* This is the control/PROM area (0x7C00) */ - struct s_Ctrl DpCtrl; - struct s_Prom DpProm; -}; - -/* -** The top end of memory! -*/ -struct s_ParmMapS { /* Area containing Parm Map Pointer */ - u8 Dp_Unused8_[DP_PARMMAP_ADDR]; - u16 DpParmMapAd; -}; - -struct s_StartUpS { - u8 Dp_Unused9_[DP_STARTUP_ADDR]; - u8 Dp_LongJump[0x4]; - u8 Dp_Unused10_[2]; - u8 Dp_ShortJump[0x2]; -}; - -union u_Sram2ParmMap { /* This is the top of memory (0x7E00-0x7FFF) */ - u8 DpSramMem[DP_SRAM2_SIZE]; - struct s_ParmMapS DpParmMapS; - struct s_StartUpS DpStartUpS; -}; - -/* -** This is the DP RAM overlay. -*/ -struct DpRam { - u8 DpSram1[DP_SRAM1_SIZE]; /* 0000 - 7BFF */ - union u_CtrlProm DpCtrlProm; /* 7C00 - 7DFF */ - union u_Sram2ParmMap DpSram2ParmMap; /* 7E00 - 7FFF */ - u8 DpScratch[DP_SCRATCH_SIZE]; /* 8000 - 8FFF */ - u8 DpSram3[DP_SRAM3_SIZE]; /* 9000 - FFFF */ -}; - -#define DpControl DpCtrlProm.DpCtrl.DpCtl -#define DpSetInt DpCtrlProm.DpCtrl.DpIntSet -#define DpResetTpu DpCtrlProm.DpCtrl.DpTpuReset -#define DpResetInt DpCtrlProm.DpCtrl.DpIntReset - -#define DpSlx DpCtrlProm.DpProm.DpSlxCode -#define DpRevision DpCtrlProm.DpProm.DpRev -#define DpUnique DpCtrlProm.DpProm.DpUniq -#define DpYear DpCtrlProm.DpProm.DpJahre -#define DpWeek DpCtrlProm.DpProm.DpWoche -#define DpSignature DpCtrlProm.DpProm.DpSiggy - -#define DpParmMapR DpSram2ParmMap.DpParmMapS.DpParmMapAd -#define DpSram2 DpSram2ParmMap.DpSramMem - -#endif diff --git a/drivers/staging/generic_serial/rio/cirrus.h b/drivers/staging/generic_serial/rio/cirrus.h deleted file mode 100644 index 5ab51679caa2..000000000000 --- a/drivers/staging/generic_serial/rio/cirrus.h +++ /dev/null @@ -1,210 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* CIRRUS.H ******* - ******* ******* - **************************************************************************** - - Author : Jeremy Rolls - Date : 3 Aug 1990 - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _cirrus_h -#define _cirrus_h 1 - -/* Bit fields for particular registers shared with driver */ - -/* COR1 - driver and RTA */ -#define RIOC_COR1_ODD 0x80 /* Odd parity */ -#define RIOC_COR1_EVEN 0x00 /* Even parity */ -#define RIOC_COR1_NOP 0x00 /* No parity */ -#define RIOC_COR1_FORCE 0x20 /* Force parity */ -#define RIOC_COR1_NORMAL 0x40 /* With parity */ -#define RIOC_COR1_1STOP 0x00 /* 1 stop bit */ -#define RIOC_COR1_15STOP 0x04 /* 1.5 stop bits */ -#define RIOC_COR1_2STOP 0x08 /* 2 stop bits */ -#define RIOC_COR1_5BITS 0x00 /* 5 data bits */ -#define RIOC_COR1_6BITS 0x01 /* 6 data bits */ -#define RIOC_COR1_7BITS 0x02 /* 7 data bits */ -#define RIOC_COR1_8BITS 0x03 /* 8 data bits */ - -#define RIOC_COR1_HOST 0xef /* Safe host bits */ - -/* RTA only */ -#define RIOC_COR1_CINPCK 0x00 /* Check parity of received characters */ -#define RIOC_COR1_CNINPCK 0x10 /* Don't check parity */ - -/* COR2 bits for both RTA and driver use */ -#define RIOC_COR2_IXANY 0x80 /* IXANY - any character is XON */ -#define RIOC_COR2_IXON 0x40 /* IXON - enable tx soft flowcontrol */ -#define RIOC_COR2_RTSFLOW 0x02 /* Enable tx hardware flow control */ - -/* Additional driver bits */ -#define RIOC_COR2_HUPCL 0x20 /* Hang up on close */ -#define RIOC_COR2_CTSFLOW 0x04 /* Enable rx hardware flow control */ -#define RIOC_COR2_IXOFF 0x01 /* Enable rx software flow control */ -#define RIOC_COR2_DTRFLOW 0x08 /* Enable tx hardware flow control */ - -/* RTA use only */ -#define RIOC_COR2_ETC 0x20 /* Embedded transmit options */ -#define RIOC_COR2_LOCAL 0x10 /* Local loopback mode */ -#define RIOC_COR2_REMOTE 0x08 /* Remote loopback mode */ -#define RIOC_COR2_HOST 0xc2 /* Safe host bits */ - -/* COR3 - RTA use only */ -#define RIOC_COR3_SCDRNG 0x80 /* Enable special char detect for range */ -#define RIOC_COR3_SCD34 0x40 /* Special character detect for SCHR's 3 + 4 */ -#define RIOC_COR3_FCT 0x20 /* Flow control transparency */ -#define RIOC_COR3_SCD12 0x10 /* Special character detect for SCHR's 1 + 2 */ -#define RIOC_COR3_FIFO12 0x0c /* 12 chars for receive FIFO threshold */ -#define RIOC_COR3_FIFO10 0x0a /* 10 chars for receive FIFO threshold */ -#define RIOC_COR3_FIFO8 0x08 /* 8 chars for receive FIFO threshold */ -#define RIOC_COR3_FIFO6 0x06 /* 6 chars for receive FIFO threshold */ - -#define RIOC_COR3_THRESHOLD RIOC_COR3_FIFO8 /* MUST BE LESS THAN MCOR_THRESHOLD */ - -#define RIOC_COR3_DEFAULT (RIOC_COR3_FCT | RIOC_COR3_THRESHOLD) - /* Default bits for COR3 */ - -/* COR4 driver and RTA use */ -#define RIOC_COR4_IGNCR 0x80 /* Throw away CR's on input */ -#define RIOC_COR4_ICRNL 0x40 /* Map CR -> NL on input */ -#define RIOC_COR4_INLCR 0x20 /* Map NL -> CR on input */ -#define RIOC_COR4_IGNBRK 0x10 /* Ignore Break */ -#define RIOC_COR4_NBRKINT 0x08 /* No interrupt on break (-BRKINT) */ -#define RIOC_COR4_RAISEMOD 0x01 /* Raise modem output lines on non-zero baud */ - - -/* COR4 driver only */ -#define RIOC_COR4_IGNPAR 0x04 /* IGNPAR (ignore characters with errors) */ -#define RIOC_COR4_PARMRK 0x02 /* PARMRK */ - -#define RIOC_COR4_HOST 0xf8 /* Safe host bits */ - -/* COR4 RTA only */ -#define RIOC_COR4_CIGNPAR 0x02 /* Thrown away bad characters */ -#define RIOC_COR4_CPARMRK 0x04 /* PARMRK characters */ -#define RIOC_COR4_CNPARMRK 0x03 /* Don't PARMRK */ - -/* COR5 driver and RTA use */ -#define RIOC_COR5_ISTRIP 0x80 /* Strip input chars to 7 bits */ -#define RIOC_COR5_LNE 0x40 /* Enable LNEXT processing */ -#define RIOC_COR5_CMOE 0x20 /* Match good and errored characters */ -#define RIOC_COR5_ONLCR 0x02 /* NL -> CR NL on output */ -#define RIOC_COR5_OCRNL 0x01 /* CR -> NL on output */ - -/* -** Spare bits - these are not used in the CIRRUS registers, so we use -** them to set various other features. -*/ -/* -** tstop and tbusy indication -*/ -#define RIOC_COR5_TSTATE_ON 0x08 /* Turn on monitoring of tbusy and tstop */ -#define RIOC_COR5_TSTATE_OFF 0x04 /* Turn off monitoring of tbusy and tstop */ -/* -** TAB3 -*/ -#define RIOC_COR5_TAB3 0x10 /* TAB3 mode */ - -#define RIOC_COR5_HOST 0xc3 /* Safe host bits */ - -/* CCSR */ -#define RIOC_CCSR_TXFLOFF 0x04 /* Tx is xoffed */ - -/* MSVR1 */ -/* NB. DTR / CD swapped from Cirrus spec as the pins are also reversed on the - RTA. This is because otherwise DCD would get lost on the 1 parallel / 3 - serial option. -*/ -#define RIOC_MSVR1_CD 0x80 /* CD (DSR on Cirrus) */ -#define RIOC_MSVR1_RTS 0x40 /* RTS (CTS on Cirrus) */ -#define RIOC_MSVR1_RI 0x20 /* RI */ -#define RIOC_MSVR1_DTR 0x10 /* DTR (CD on Cirrus) */ -#define RIOC_MSVR1_CTS 0x01 /* CTS output pin (RTS on Cirrus) */ -/* Next two used to indicate state of tbusy and tstop to driver */ -#define RIOC_MSVR1_TSTOP 0x08 /* Set if port flow controlled */ -#define RIOC_MSVR1_TEMPTY 0x04 /* Set if port tx buffer empty */ - -#define RIOC_MSVR1_HOST 0xf3 /* The bits the host wants */ - -/* Defines for the subscripts of a CONFIG packet */ -#define RIOC_CONFIG_COR1 1 /* Option register 1 */ -#define RIOC_CONFIG_COR2 2 /* Option register 2 */ -#define RIOC_CONFIG_COR4 3 /* Option register 4 */ -#define RIOC_CONFIG_COR5 4 /* Option register 5 */ -#define RIOC_CONFIG_TXXON 5 /* Tx XON character */ -#define RIOC_CONFIG_TXXOFF 6 /* Tx XOFF character */ -#define RIOC_CONFIG_RXXON 7 /* Rx XON character */ -#define RIOC_CONFIG_RXXOFF 8 /* Rx XOFF character */ -#define RIOC_CONFIG_LNEXT 9 /* LNEXT character */ -#define RIOC_CONFIG_TXBAUD 10 /* Tx baud rate */ -#define RIOC_CONFIG_RXBAUD 11 /* Rx baud rate */ - -#define RIOC_PRE_EMPTIVE 0x80 /* Pre-emptive bit in command field */ - -/* Packet types going from Host to remote - with the exception of OPEN, MOPEN, - CONFIG, SBREAK and MEMDUMP the remaining bytes of the data array will not - be used -*/ -#define RIOC_OPEN 0x00 /* Open a port */ -#define RIOC_CONFIG 0x01 /* Configure a port */ -#define RIOC_MOPEN 0x02 /* Modem open (block for DCD) */ -#define RIOC_CLOSE 0x03 /* Close a port */ -#define RIOC_WFLUSH (0x04 | RIOC_PRE_EMPTIVE) /* Write flush */ -#define RIOC_RFLUSH (0x05 | RIOC_PRE_EMPTIVE) /* Read flush */ -#define RIOC_RESUME (0x06 | RIOC_PRE_EMPTIVE) /* Resume if xoffed */ -#define RIOC_SBREAK 0x07 /* Start break */ -#define RIOC_EBREAK 0x08 /* End break */ -#define RIOC_SUSPEND (0x09 | RIOC_PRE_EMPTIVE) /* Susp op (behave as tho xoffed) */ -#define RIOC_FCLOSE (0x0a | RIOC_PRE_EMPTIVE) /* Force close */ -#define RIOC_XPRINT 0x0b /* Xprint packet */ -#define RIOC_MBIS (0x0c | RIOC_PRE_EMPTIVE) /* Set modem lines */ -#define RIOC_MBIC (0x0d | RIOC_PRE_EMPTIVE) /* Clear modem lines */ -#define RIOC_MSET (0x0e | RIOC_PRE_EMPTIVE) /* Set modem lines */ -#define RIOC_PCLOSE 0x0f /* Pseudo close - Leaves rx/tx enabled */ -#define RIOC_MGET (0x10 | RIOC_PRE_EMPTIVE) /* Force update of modem status */ -#define RIOC_MEMDUMP (0x11 | RIOC_PRE_EMPTIVE) /* Send back mem from addr supplied */ -#define RIOC_READ_REGISTER (0x12 | RIOC_PRE_EMPTIVE) /* Read CD1400 register (debug) */ - -/* "Command" packets going from remote to host COMPLETE and MODEM_STATUS - use data[4] / data[3] to indicate current state and modem status respectively -*/ - -#define RIOC_COMPLETE (0x20 | RIOC_PRE_EMPTIVE) - /* Command complete */ -#define RIOC_BREAK_RECEIVED (0x21 | RIOC_PRE_EMPTIVE) - /* Break received */ -#define RIOC_MODEM_STATUS (0x22 | RIOC_PRE_EMPTIVE) - /* Change in modem status */ - -/* "Command" packet that could go either way - handshake wake-up */ -#define RIOC_HANDSHAKE (0x23 | RIOC_PRE_EMPTIVE) - /* Wake-up to HOST / RTA */ - -#endif diff --git a/drivers/staging/generic_serial/rio/cmdblk.h b/drivers/staging/generic_serial/rio/cmdblk.h deleted file mode 100644 index 9ed4f861675a..000000000000 --- a/drivers/staging/generic_serial/rio/cmdblk.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : cmdblk.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:09 -** Retrieved : 11/6/98 11:34:20 -** -** ident @(#)cmdblk.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_cmdblk_h__ -#define __rio_cmdblk_h__ - -/* -** the structure of a command block, used to queue commands destined for -** a rup. -*/ - -struct CmdBlk { - struct CmdBlk *NextP; /* Pointer to next command block */ - struct PKT Packet; /* A packet, to copy to the rup */ - /* The func to call to check if OK */ - int (*PreFuncP) (unsigned long, struct CmdBlk *); - int PreArg; /* The arg for the func */ - /* The func to call when completed */ - int (*PostFuncP) (unsigned long, struct CmdBlk *); - int PostArg; /* The arg for the func */ -}; - -#define NUM_RIO_CMD_BLKS (3 * (MAX_RUP * 4 + LINKS_PER_UNIT * 4)) -#endif diff --git a/drivers/staging/generic_serial/rio/cmdpkt.h b/drivers/staging/generic_serial/rio/cmdpkt.h deleted file mode 100644 index c1e7a2798070..000000000000 --- a/drivers/staging/generic_serial/rio/cmdpkt.h +++ /dev/null @@ -1,177 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : cmdpkt.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:09 -** Retrieved : 11/6/98 11:34:20 -** -** ident @(#)cmdpkt.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ -#ifndef __rio_cmdpkt_h__ -#define __rio_cmdpkt_h__ - -/* -** overlays for the data area of a packet. Used in both directions -** (to build a packet to send, and to interpret a packet that arrives) -** and is very inconvenient for MIPS, so they appear as two separate -** structures - those used for modifying/reading packets on the card -** and those for modifying/reading packets in real memory, which have an _M -** suffix. -*/ - -#define RTA_BOOT_DATA_SIZE (PKT_MAX_DATA_LEN-2) - -/* -** The boot information packet looks like this: -** This structure overlays a PktCmd->CmdData structure, and so starts -** at Data[2] in the actual pkt! -*/ -struct BootSequence { - u16 NumPackets; - u16 LoadBase; - u16 CodeSize; -}; - -#define BOOT_SEQUENCE_LEN 8 - -struct SamTop { - u8 Unit; - u8 Link; -}; - -struct CmdHdr { - u8 PcCommand; - union { - u8 PcPhbNum; - u8 PcLinkNum; - u8 PcIDNum; - } U0; -}; - - -struct PktCmd { - union { - struct { - struct CmdHdr CmdHdr; - struct BootSequence PcBootSequence; - } S1; - struct { - u16 PcSequence; - u8 PcBootData[RTA_BOOT_DATA_SIZE]; - } S2; - struct { - u16 __crud__; - u8 PcUniqNum[4]; /* this is really a uint. */ - u8 PcModuleTypes; /* what modules are fitted */ - } S3; - struct { - struct CmdHdr CmdHdr; - u8 __undefined__; - u8 PcModemStatus; - u8 PcPortStatus; - u8 PcSubCommand; /* commands like mem or register dump */ - u16 PcSubAddr; /* Address for command */ - u8 PcSubData[64]; /* Date area for command */ - } S4; - struct { - struct CmdHdr CmdHdr; - u8 PcCommandText[1]; - u8 __crud__[20]; - u8 PcIDNum2; /* It had to go somewhere! */ - } S5; - struct { - struct CmdHdr CmdHdr; - struct SamTop Topology[LINKS_PER_UNIT]; - } S6; - } U1; -}; - -struct PktCmd_M { - union { - struct { - struct { - u8 PcCommand; - union { - u8 PcPhbNum; - u8 PcLinkNum; - u8 PcIDNum; - } U0; - } CmdHdr; - struct { - u16 NumPackets; - u16 LoadBase; - u16 CodeSize; - } PcBootSequence; - } S1; - struct { - u16 PcSequence; - u8 PcBootData[RTA_BOOT_DATA_SIZE]; - } S2; - struct { - u16 __crud__; - u8 PcUniqNum[4]; /* this is really a uint. */ - u8 PcModuleTypes; /* what modules are fitted */ - } S3; - struct { - u16 __cmd_hdr__; - u8 __undefined__; - u8 PcModemStatus; - u8 PcPortStatus; - u8 PcSubCommand; - u16 PcSubAddr; - u8 PcSubData[64]; - } S4; - struct { - u16 __cmd_hdr__; - u8 PcCommandText[1]; - u8 __crud__[20]; - u8 PcIDNum2; /* Tacked on end */ - } S5; - struct { - u16 __cmd_hdr__; - struct Top Topology[LINKS_PER_UNIT]; - } S6; - } U1; -}; - -#define Command U1.S1.CmdHdr.PcCommand -#define PhbNum U1.S1.CmdHdr.U0.PcPhbNum -#define IDNum U1.S1.CmdHdr.U0.PcIDNum -#define IDNum2 U1.S5.PcIDNum2 -#define LinkNum U1.S1.CmdHdr.U0.PcLinkNum -#define Sequence U1.S2.PcSequence -#define BootData U1.S2.PcBootData -#define BootSequence U1.S1.PcBootSequence -#define UniqNum U1.S3.PcUniqNum -#define ModemStatus U1.S4.PcModemStatus -#define PortStatus U1.S4.PcPortStatus -#define SubCommand U1.S4.PcSubCommand -#define SubAddr U1.S4.PcSubAddr -#define SubData U1.S4.PcSubData -#define CommandText U1.S5.PcCommandText -#define RouteTopology U1.S6.Topology -#define ModuleTypes U1.S3.PcModuleTypes - -#endif diff --git a/drivers/staging/generic_serial/rio/daemon.h b/drivers/staging/generic_serial/rio/daemon.h deleted file mode 100644 index 4af90323fd00..000000000000 --- a/drivers/staging/generic_serial/rio/daemon.h +++ /dev/null @@ -1,307 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : daemon.h -** SID : 1.3 -** Last Modified : 11/6/98 11:34:09 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)daemon.h 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_daemon_h__ -#define __rio_daemon_h__ - - -/* -** structures used on /dev/rio -*/ - -struct Error { - unsigned int Error; - unsigned int Entry; - unsigned int Other; -}; - -struct DownLoad { - char __user *DataP; - unsigned int Count; - unsigned int ProductCode; -}; - -/* -** A few constants.... -*/ -#ifndef MAX_VERSION_LEN -#define MAX_VERSION_LEN 256 -#endif - -#ifndef MAX_XP_CTRL_LEN -#define MAX_XP_CTRL_LEN 16 /* ALSO IN PORT.H */ -#endif - -struct PortSetup { - unsigned int From; /* Set/Clear XP & IXANY Control from this port.... */ - unsigned int To; /* .... to this port */ - unsigned int XpCps; /* at this speed */ - char XpOn[MAX_XP_CTRL_LEN]; /* this is the start string */ - char XpOff[MAX_XP_CTRL_LEN]; /* this is the stop string */ - u8 IxAny; /* enable/disable IXANY */ - u8 IxOn; /* enable/disable IXON */ - u8 Lock; /* lock port params */ - u8 Store; /* store params across closes */ - u8 Drain; /* close only when drained */ -}; - -struct LpbReq { - unsigned int Host; - unsigned int Link; - struct LPB __user *LpbP; -}; - -struct RupReq { - unsigned int HostNum; - unsigned int RupNum; - struct RUP __user *RupP; -}; - -struct PortReq { - unsigned int SysPort; - struct Port __user *PortP; -}; - -struct StreamInfo { - unsigned int SysPort; - int RQueue; - int WQueue; -}; - -struct HostReq { - unsigned int HostNum; - struct Host __user *HostP; -}; - -struct HostDpRam { - unsigned int HostNum; - struct DpRam __user *DpRamP; -}; - -struct DebugCtrl { - unsigned int SysPort; - unsigned int Debug; - unsigned int Wait; -}; - -struct MapInfo { - unsigned int FirstPort; /* 8 ports, starting from this (tty) number */ - unsigned int RtaUnique; /* reside on this RTA (unique number) */ -}; - -struct MapIn { - unsigned int NumEntries; /* How many port sets are we mapping? */ - struct MapInfo *MapInfoP; /* Pointer to (user space) info */ -}; - -struct SendPack { - unsigned int PortNum; - unsigned char Len; - unsigned char Data[PKT_MAX_DATA_LEN]; -}; - -struct SpecialRupCmd { - struct PKT Packet; - unsigned short Host; - unsigned short RupNum; -}; - -struct IdentifyRta { - unsigned long RtaUnique; - u8 ID; -}; - -struct KillNeighbour { - unsigned long UniqueNum; - u8 Link; -}; - -struct rioVersion { - char version[MAX_VERSION_LEN]; - char relid[MAX_VERSION_LEN]; - int buildLevel; - char buildDate[MAX_VERSION_LEN]; -}; - - -/* -** RIOC commands are for the daemon type operations -** -** 09.12.1998 ARG - ESIL 0776 part fix -** Definition for 'RIOC' also appears in rioioctl.h, so we'd better do a -** #ifndef here first. -** rioioctl.h also now has #define 'RIO_QUICK_CHECK' as this ioctl is now -** allowed to be used by customers. -*/ -#ifndef RIOC -#define RIOC ('R'<<8)|('i'<<16)|('o'<<24) -#endif - -/* -** Boot stuff -*/ -#define RIO_GET_TABLE (RIOC | 100) -#define RIO_PUT_TABLE (RIOC | 101) -#define RIO_ASSIGN_RTA (RIOC | 102) -#define RIO_DELETE_RTA (RIOC | 103) -#define RIO_HOST_FOAD (RIOC | 104) -#define RIO_QUICK_CHECK (RIOC | 105) -#define RIO_SIGNALS_ON (RIOC | 106) -#define RIO_SIGNALS_OFF (RIOC | 107) -#define RIO_CHANGE_NAME (RIOC | 108) -#define RIO_DOWNLOAD (RIOC | 109) -#define RIO_GET_LOG (RIOC | 110) -#define RIO_SETUP_PORTS (RIOC | 111) -#define RIO_ALL_MODEM (RIOC | 112) - -/* -** card state, debug stuff -*/ -#define RIO_NUM_HOSTS (RIOC | 120) -#define RIO_HOST_LPB (RIOC | 121) -#define RIO_HOST_RUP (RIOC | 122) -#define RIO_HOST_PORT (RIOC | 123) -#define RIO_PARMS (RIOC | 124) -#define RIO_HOST_REQ (RIOC | 125) -#define RIO_READ_CONFIG (RIOC | 126) -#define RIO_SET_CONFIG (RIOC | 127) -#define RIO_VERSID (RIOC | 128) -#define RIO_FLAGS (RIOC | 129) -#define RIO_SETDEBUG (RIOC | 130) -#define RIO_GETDEBUG (RIOC | 131) -#define RIO_READ_LEVELS (RIOC | 132) -#define RIO_SET_FAST_BUS (RIOC | 133) -#define RIO_SET_SLOW_BUS (RIOC | 134) -#define RIO_SET_BYTE_MODE (RIOC | 135) -#define RIO_SET_WORD_MODE (RIOC | 136) -#define RIO_STREAM_INFO (RIOC | 137) -#define RIO_START_POLLER (RIOC | 138) -#define RIO_STOP_POLLER (RIOC | 139) -#define RIO_LAST_ERROR (RIOC | 140) -#define RIO_TICK (RIOC | 141) -#define RIO_TOCK (RIOC | 241) /* I did this on purpose, you know. */ -#define RIO_SEND_PACKET (RIOC | 142) -#define RIO_SET_BUSY (RIOC | 143) -#define SPECIAL_RUP_CMD (RIOC | 144) -#define RIO_FOAD_RTA (RIOC | 145) -#define RIO_ZOMBIE_RTA (RIOC | 146) -#define RIO_IDENTIFY_RTA (RIOC | 147) -#define RIO_KILL_NEIGHBOUR (RIOC | 148) -#define RIO_DEBUG_MEM (RIOC | 149) -/* -** 150 - 167 used..... See below -*/ -#define RIO_GET_PORT_SETUP (RIOC | 168) -#define RIO_RESUME (RIOC | 169) -#define RIO_MESG (RIOC | 170) -#define RIO_NO_MESG (RIOC | 171) -#define RIO_WHAT_MESG (RIOC | 172) -#define RIO_HOST_DPRAM (RIOC | 173) -#define RIO_MAP_B50_TO_50 (RIOC | 174) -#define RIO_MAP_B50_TO_57600 (RIOC | 175) -#define RIO_MAP_B110_TO_110 (RIOC | 176) -#define RIO_MAP_B110_TO_115200 (RIOC | 177) -#define RIO_GET_PORT_PARAMS (RIOC | 178) -#define RIO_SET_PORT_PARAMS (RIOC | 179) -#define RIO_GET_PORT_TTY (RIOC | 180) -#define RIO_SET_PORT_TTY (RIOC | 181) -#define RIO_SYSLOG_ONLY (RIOC | 182) -#define RIO_SYSLOG_CONS (RIOC | 183) -#define RIO_CONS_ONLY (RIOC | 184) -#define RIO_BLOCK_OPENS (RIOC | 185) - -/* -** 02.03.1999 ARG - ESIL 0820 fix : -** RIOBootMode is no longer use by the driver, so these ioctls -** are now obsolete : -** -#define RIO_GET_BOOT_MODE (RIOC | 186) -#define RIO_SET_BOOT_MODE (RIOC | 187) -** -*/ - -#define RIO_MEM_DUMP (RIOC | 189) -#define RIO_READ_REGISTER (RIOC | 190) -#define RIO_GET_MODTYPE (RIOC | 191) -#define RIO_SET_TIMER (RIOC | 192) -#define RIO_READ_CHECK (RIOC | 196) -#define RIO_WAITING_FOR_RESTART (RIOC | 197) -#define RIO_BIND_RTA (RIOC | 198) -#define RIO_GET_BINDINGS (RIOC | 199) -#define RIO_PUT_BINDINGS (RIOC | 200) - -#define RIO_MAKE_DEV (RIOC | 201) -#define RIO_MINOR (RIOC | 202) - -#define RIO_IDENTIFY_DRIVER (RIOC | 203) -#define RIO_DISPLAY_HOST_CFG (RIOC | 204) - - -/* -** MAKE_DEV / MINOR stuff -*/ -#define RIO_DEV_DIRECT 0x0000 -#define RIO_DEV_MODEM 0x0200 -#define RIO_DEV_XPRINT 0x0400 -#define RIO_DEV_MASK 0x0600 - -/* -** port management, xprint stuff -*/ -#define rIOCN(N) (RIOC|(N)) -#define rIOCR(N,T) (RIOC|(N)) -#define rIOCW(N,T) (RIOC|(N)) - -#define RIO_GET_XP_ON rIOCR(150,char[16]) /* start xprint string */ -#define RIO_SET_XP_ON rIOCW(151,char[16]) -#define RIO_GET_XP_OFF rIOCR(152,char[16]) /* finish xprint string */ -#define RIO_SET_XP_OFF rIOCW(153,char[16]) -#define RIO_GET_XP_CPS rIOCR(154,int) /* xprint CPS */ -#define RIO_SET_XP_CPS rIOCW(155,int) -#define RIO_GET_IXANY rIOCR(156,int) /* ixany allowed? */ -#define RIO_SET_IXANY rIOCW(157,int) -#define RIO_SET_IXANY_ON rIOCN(158) /* allow ixany */ -#define RIO_SET_IXANY_OFF rIOCN(159) /* disallow ixany */ -#define RIO_GET_MODEM rIOCR(160,int) /* port is modem/direct line? */ -#define RIO_SET_MODEM rIOCW(161,int) -#define RIO_SET_MODEM_ON rIOCN(162) /* port is a modem */ -#define RIO_SET_MODEM_OFF rIOCN(163) /* port is direct */ -#define RIO_GET_IXON rIOCR(164,int) /* ixon allowed? */ -#define RIO_SET_IXON rIOCW(165,int) -#define RIO_SET_IXON_ON rIOCN(166) /* allow ixon */ -#define RIO_SET_IXON_OFF rIOCN(167) /* disallow ixon */ - -#define RIO_GET_SIVIEW ((('s')<<8) | 106) /* backwards compatible with SI */ - -#define RIO_IOCTL_UNKNOWN -2 - -#endif diff --git a/drivers/staging/generic_serial/rio/errors.h b/drivers/staging/generic_serial/rio/errors.h deleted file mode 100644 index bdb05234090a..000000000000 --- a/drivers/staging/generic_serial/rio/errors.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : errors.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:10 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)errors.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_errors_h__ -#define __rio_errors_h__ - -/* -** error codes -*/ - -#define NOTHING_WRONG_AT_ALL 0 -#define BAD_CHARACTER_IN_NAME 1 -#define TABLE_ENTRY_ISNT_PROPERLY_NULL 2 -#define UNKNOWN_HOST_NUMBER 3 -#define ZERO_RTA_ID 4 -#define BAD_RTA_ID 5 -#define DUPLICATED_RTA_ID 6 -#define DUPLICATE_UNIQUE_NUMBER 7 -#define BAD_TTY_NUMBER 8 -#define TTY_NUMBER_IN_USE 9 -#define NAME_USED_TWICE 10 -#define HOST_ID_NOT_ZERO 11 -#define BOOT_IN_PROGRESS 12 -#define COPYIN_FAILED 13 -#define HOST_FILE_TOO_LARGE 14 -#define COPYOUT_FAILED 15 -#define NOT_SUPER_USER 16 -#define RIO_ALREADY_POLLING 17 - -#define ID_NUMBER_OUT_OF_RANGE 18 -#define PORT_NUMBER_OUT_OF_RANGE 19 -#define HOST_NUMBER_OUT_OF_RANGE 20 -#define RUP_NUMBER_OUT_OF_RANGE 21 -#define TTY_NUMBER_OUT_OF_RANGE 22 -#define LINK_NUMBER_OUT_OF_RANGE 23 - -#define HOST_NOT_RUNNING 24 -#define IOCTL_COMMAND_UNKNOWN 25 -#define RIO_SYSTEM_HALTED 26 -#define WAIT_FOR_DRAIN_BROKEN 27 -#define PORT_NOT_MAPPED_INTO_SYSTEM 28 -#define EXCLUSIVE_USE_SET 29 -#define WAIT_FOR_NOT_CLOSING_BROKEN 30 -#define WAIT_FOR_PORT_TO_OPEN_BROKEN 31 -#define WAIT_FOR_CARRIER_BROKEN 32 -#define WAIT_FOR_NOT_IN_USE_BROKEN 33 -#define WAIT_FOR_CAN_ADD_COMMAND_BROKEN 34 -#define WAIT_FOR_ADD_COMMAND_BROKEN 35 -#define WAIT_FOR_NOT_PARAM_BROKEN 36 -#define WAIT_FOR_RETRY_BROKEN 37 -#define HOST_HAS_ALREADY_BEEN_BOOTED 38 -#define UNIT_IS_IN_USE 39 -#define COULDNT_FIND_ENTRY 40 -#define RTA_UNIQUE_NUMBER_ZERO 41 -#define CLOSE_COMMAND_FAILED 42 -#define WAIT_FOR_CLOSE_BROKEN 43 -#define CPS_VALUE_OUT_OF_RANGE 44 -#define ID_ALREADY_IN_USE 45 -#define SIGNALS_ALREADY_SET 46 -#define NOT_RECEIVING_PROCESS 47 -#define RTA_NUMBER_WRONG 48 -#define NO_SUCH_PRODUCT 49 -#define HOST_SYSPORT_BAD 50 -#define ID_NOT_TENTATIVE 51 -#define XPRINT_CPS_OUT_OF_RANGE 52 -#define NOT_ENOUGH_CORE_FOR_PCI_COPY 53 - - -#endif /* __rio_errors_h__ */ diff --git a/drivers/staging/generic_serial/rio/func.h b/drivers/staging/generic_serial/rio/func.h deleted file mode 100644 index 078d44f85e45..000000000000 --- a/drivers/staging/generic_serial/rio/func.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : func.h -** SID : 1.3 -** Last Modified : 11/6/98 11:34:10 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)func.h 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __func_h_def -#define __func_h_def - -#include - -/* rioboot.c */ -int RIOBootCodeRTA(struct rio_info *, struct DownLoad *); -int RIOBootCodeHOST(struct rio_info *, struct DownLoad *); -int RIOBootCodeUNKNOWN(struct rio_info *, struct DownLoad *); -void msec_timeout(struct Host *); -int RIOBootRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *); -int RIOBootOk(struct rio_info *, struct Host *, unsigned long); -int RIORtaBound(struct rio_info *, unsigned int); -void rio_fill_host_slot(int, int, unsigned int, struct Host *); - -/* riocmd.c */ -int RIOFoadRta(struct Host *, struct Map *); -int RIOZombieRta(struct Host *, struct Map *); -int RIOCommandRta(struct rio_info *, unsigned long, int (*func) (struct Host *, struct Map *)); -int RIOIdentifyRta(struct rio_info *, void __user *); -int RIOKillNeighbour(struct rio_info *, void __user *); -int RIOSuspendBootRta(struct Host *, int, int); -int RIOFoadWakeup(struct rio_info *); -struct CmdBlk *RIOGetCmdBlk(void); -void RIOFreeCmdBlk(struct CmdBlk *); -int RIOQueueCmdBlk(struct Host *, unsigned int, struct CmdBlk *); -void RIOPollHostCommands(struct rio_info *, struct Host *); -int RIOWFlushMark(unsigned long, struct CmdBlk *); -int RIORFlushEnable(unsigned long, struct CmdBlk *); -int RIOUnUse(unsigned long, struct CmdBlk *); - -/* rioctrl.c */ -int riocontrol(struct rio_info *, dev_t, int, unsigned long, int); - -int RIOPreemptiveCmd(struct rio_info *, struct Port *, unsigned char); - -/* rioinit.c */ -void rioinit(struct rio_info *, struct RioHostInfo *); -void RIOInitHosts(struct rio_info *, struct RioHostInfo *); -void RIOISAinit(struct rio_info *, int); -int RIODoAT(struct rio_info *, int, int); -caddr_t RIOCheckForATCard(int); -int RIOAssignAT(struct rio_info *, int, void __iomem *, int); -int RIOBoardTest(unsigned long, void __iomem *, unsigned char, int); -void RIOAllocDataStructs(struct rio_info *); -void RIOSetupDataStructs(struct rio_info *); -int RIODefaultName(struct rio_info *, struct Host *, unsigned int); -struct rioVersion *RIOVersid(void); -void RIOHostReset(unsigned int, struct DpRam __iomem *, unsigned int); - -/* riointr.c */ -void RIOTxEnable(char *); -void RIOServiceHost(struct rio_info *, struct Host *); -int riotproc(struct rio_info *, struct ttystatics *, int, int); - -/* rioparam.c */ -int RIOParam(struct Port *, int, int, int); -int RIODelay(struct Port *PortP, int); -int RIODelay_ni(struct Port *PortP, int); -void ms_timeout(struct Port *); -int can_add_transmit(struct PKT __iomem **, struct Port *); -void add_transmit(struct Port *); -void put_free_end(struct Host *, struct PKT __iomem *); -int can_remove_receive(struct PKT __iomem **, struct Port *); -void remove_receive(struct Port *); - -/* rioroute.c */ -int RIORouteRup(struct rio_info *, unsigned int, struct Host *, struct PKT __iomem *); -void RIOFixPhbs(struct rio_info *, struct Host *, unsigned int); -unsigned int GetUnitType(unsigned int); -int RIOSetChange(struct rio_info *); -int RIOFindFreeID(struct rio_info *, struct Host *, unsigned int *, unsigned int *); - - -/* riotty.c */ - -int riotopen(struct tty_struct *tty, struct file *filp); -int riotclose(void *ptr); -int riotioctl(struct rio_info *, struct tty_struct *, int, caddr_t); -void ttyseth(struct Port *, struct ttystatics *, struct old_sgttyb *sg); - -/* riotable.c */ -int RIONewTable(struct rio_info *); -int RIOApel(struct rio_info *); -int RIODeleteRta(struct rio_info *, struct Map *); -int RIOAssignRta(struct rio_info *, struct Map *); -int RIOReMapPorts(struct rio_info *, struct Host *, struct Map *); -int RIOChangeName(struct rio_info *, struct Map *); - -#if 0 -/* riodrvr.c */ -struct rio_info *rio_install(struct RioHostInfo *); -int rio_uninstall(struct rio_info *); -int rio_open(struct rio_info *, int, struct file *); -int rio_close(struct rio_info *, struct file *); -int rio_read(struct rio_info *, struct file *, char *, int); -int rio_write(struct rio_info *, struct file *f, char *, int); -int rio_ioctl(struct rio_info *, struct file *, int, char *); -int rio_select(struct rio_info *, struct file *f, int, struct sel *); -int rio_intr(char *); -int rio_isr_thread(char *); -struct rio_info *rio_info_store(int cmd, struct rio_info *p); -#endif - -extern void rio_copy_to_card(void *from, void __iomem *to, int len); -extern int rio_minor(struct tty_struct *tty); -extern int rio_ismodem(struct tty_struct *tty); - -extern void rio_start_card_running(struct Host *HostP); - -#endif /* __func_h_def */ diff --git a/drivers/staging/generic_serial/rio/host.h b/drivers/staging/generic_serial/rio/host.h deleted file mode 100644 index 78f24540c224..000000000000 --- a/drivers/staging/generic_serial/rio/host.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : host.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:10 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)host.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_host_h__ -#define __rio_host_h__ - -/* -** the host structure - one per host card in the system. -*/ - -#define MAX_EXTRA_UNITS 64 - -/* -** Host data structure. This is used for the software equiv. of -** the host. -*/ -struct Host { - struct pci_dev *pdev; - unsigned char Type; /* RIO_EISA, RIO_MCA, ... */ - unsigned char Ivec; /* POLLED or ivec number */ - unsigned char Mode; /* Control stuff */ - unsigned char Slot; /* Slot */ - void __iomem *Caddr; /* KV address of DPRAM */ - struct DpRam __iomem *CardP; /* KV address of DPRAM, with overlay */ - unsigned long PaddrP; /* Phys. address of DPRAM */ - char Name[MAX_NAME_LEN]; /* The name of the host */ - unsigned int UniqueNum; /* host unique number */ - spinlock_t HostLock; /* Lock structure for MPX */ - unsigned int WorkToBeDone; /* set to true each interrupt */ - unsigned int InIntr; /* Being serviced? */ - unsigned int IntSrvDone; /* host's interrupt has been serviced */ - void (*Copy) (void *, void __iomem *, int); /* copy func */ - struct timer_list timer; - /* - ** I M P O R T A N T ! - ** - ** The rest of this data structure is cleared to zero after - ** a RIO_HOST_FOAD command. - */ - - unsigned long Flags; /* Whats going down */ -#define RC_WAITING 0 -#define RC_STARTUP 1 -#define RC_RUNNING 2 -#define RC_STUFFED 3 -#define RC_READY 7 -#define RUN_STATE 7 -/* -** Boot mode applies to the way in which hosts in this system will -** boot RTAs -*/ -#define RC_BOOT_ALL 0x8 /* Boot all RTAs attached */ -#define RC_BOOT_OWN 0x10 /* Only boot RTAs bound to this system */ -#define RC_BOOT_NONE 0x20 /* Don't boot any RTAs (slave mode) */ - - struct Top Topology[LINKS_PER_UNIT]; /* one per link */ - struct Map Mapping[MAX_RUP]; /* Mappings for host */ - struct PHB __iomem *PhbP; /* Pointer to the PHB array */ - unsigned short __iomem *PhbNumP; /* Ptr to Number of PHB's */ - struct LPB __iomem *LinkStrP; /* Link Structure Array */ - struct RUP __iomem *RupP; /* Sixteen real rups here */ - struct PARM_MAP __iomem *ParmMapP; /* points to the parmmap */ - unsigned int ExtraUnits[MAX_EXTRA_UNITS]; /* unknown things */ - unsigned int NumExtraBooted; /* how many of the above */ - /* - ** Twenty logical rups. - ** The first sixteen are the real Rup entries (above), the last four - ** are the link RUPs. - */ - struct UnixRup UnixRups[MAX_RUP + LINKS_PER_UNIT]; - int timeout_id; /* For calling 100 ms delays */ - int timeout_sem; /* For calling 100 ms delays */ - unsigned long locks; /* long req'd for set_bit --RR */ - char ____end_marker____; -}; -#define Control CardP->DpControl -#define SetInt CardP->DpSetInt -#define ResetTpu CardP->DpResetTpu -#define ResetInt CardP->DpResetInt -#define Signature CardP->DpSignature -#define Sram1 CardP->DpSram1 -#define Sram2 CardP->DpSram2 -#define Sram3 CardP->DpSram3 -#define Scratch CardP->DpScratch -#define __ParmMapR CardP->DpParmMapR -#define SLX CardP->DpSlx -#define Revision CardP->DpRevision -#define Unique CardP->DpUnique -#define Year CardP->DpYear -#define Week CardP->DpWeek - -#define RIO_DUMBPARM 0x0860 /* what not to expect */ - -#endif diff --git a/drivers/staging/generic_serial/rio/link.h b/drivers/staging/generic_serial/rio/link.h deleted file mode 100644 index f3bf11a04d41..000000000000 --- a/drivers/staging/generic_serial/rio/link.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* L I N K - ******* ******* - **************************************************************************** - - Author : Ian Nandhra / Jeremy Rolls - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _link_h -#define _link_h 1 - -/************************************************* - * Define the Link Status stuff - ************************************************/ -/* Boot request stuff */ -#define BOOT_REQUEST ((ushort) 0) /* Request for a boot */ -#define BOOT_ABORT ((ushort) 1) /* Abort a boot */ -#define BOOT_SEQUENCE ((ushort) 2) /* Packet with the number of packets - and load address */ -#define BOOT_COMPLETED ((ushort) 3) /* Boot completed */ - - -struct LPB { - u16 link_number; /* Link Number */ - u16 in_ch; /* Link In Channel */ - u16 out_ch; /* Link Out Channel */ - u8 attached_serial[4]; /* Attached serial number */ - u8 attached_host_serial[4]; - /* Serial number of Host who - booted the other end */ - u16 descheduled; /* Currently Descheduled */ - u16 state; /* Current state */ - u16 send_poll; /* Send a Poll Packet */ - u16 ltt_p; /* Process Descriptor */ - u16 lrt_p; /* Process Descriptor */ - u16 lrt_status; /* Current lrt status */ - u16 ltt_status; /* Current ltt status */ - u16 timeout; /* Timeout value */ - u16 topology; /* Topology bits */ - u16 mon_ltt; - u16 mon_lrt; - u16 WaitNoBoot; /* Secs to hold off booting */ - u16 add_packet_list; /* Add packets to here */ - u16 remove_packet_list; /* Send packets from here */ - - u16 lrt_fail_chan; /* Lrt's failure channel */ - u16 ltt_fail_chan; /* Ltt's failure channel */ - - /* RUP structure for HOST to driver communications */ - struct RUP rup; - struct RUP link_rup; /* RUP for the link (POLL, - topology etc.) */ - u16 attached_link; /* Number of attached link */ - u16 csum_errors; /* csum errors */ - u16 num_disconnects; /* number of disconnects */ - u16 num_sync_rcvd; /* # sync's received */ - u16 num_sync_rqst; /* # sync requests */ - u16 num_tx; /* Num pkts sent */ - u16 num_rx; /* Num pkts received */ - u16 module_attached; /* Module tpyes of attached */ - u16 led_timeout; /* LED timeout */ - u16 first_port; /* First port to service */ - u16 last_port; /* Last port to service */ -}; - -#endif - -/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/linux_compat.h b/drivers/staging/generic_serial/rio/linux_compat.h deleted file mode 100644 index 34c0d2899ef1..000000000000 --- a/drivers/staging/generic_serial/rio/linux_compat.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * (C) 2000 R.E.Wolff@BitWizard.nl - * - * 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 - - -#define DEBUG_ALL - -struct ttystatics { - struct termios tm; -}; - -extern int rio_debug; - -#define RIO_DEBUG_INIT 0x000001 -#define RIO_DEBUG_BOOT 0x000002 -#define RIO_DEBUG_CMD 0x000004 -#define RIO_DEBUG_CTRL 0x000008 -#define RIO_DEBUG_INTR 0x000010 -#define RIO_DEBUG_PARAM 0x000020 -#define RIO_DEBUG_ROUTE 0x000040 -#define RIO_DEBUG_TABLE 0x000080 -#define RIO_DEBUG_TTY 0x000100 -#define RIO_DEBUG_FLOW 0x000200 -#define RIO_DEBUG_MODEMSIGNALS 0x000400 -#define RIO_DEBUG_PROBE 0x000800 -#define RIO_DEBUG_CLEANUP 0x001000 -#define RIO_DEBUG_IFLOW 0x002000 -#define RIO_DEBUG_PFE 0x004000 -#define RIO_DEBUG_REC 0x008000 -#define RIO_DEBUG_SPINLOCK 0x010000 -#define RIO_DEBUG_DELAY 0x020000 -#define RIO_DEBUG_MOD_COUNT 0x040000 - - -/* Copied over from riowinif.h . This is ugly. The winif file declares -also much other stuff which is incompatible with the headers from -the older driver. The older driver includes "brates.h" which shadows -the definitions from Linux, and is incompatible... */ - -/* RxBaud and TxBaud definitions... */ -#define RIO_B0 0x00 /* RTS / DTR signals dropped */ -#define RIO_B50 0x01 /* 50 baud */ -#define RIO_B75 0x02 /* 75 baud */ -#define RIO_B110 0x03 /* 110 baud */ -#define RIO_B134 0x04 /* 134.5 baud */ -#define RIO_B150 0x05 /* 150 baud */ -#define RIO_B200 0x06 /* 200 baud */ -#define RIO_B300 0x07 /* 300 baud */ -#define RIO_B600 0x08 /* 600 baud */ -#define RIO_B1200 0x09 /* 1200 baud */ -#define RIO_B1800 0x0A /* 1800 baud */ -#define RIO_B2400 0x0B /* 2400 baud */ -#define RIO_B4800 0x0C /* 4800 baud */ -#define RIO_B9600 0x0D /* 9600 baud */ -#define RIO_B19200 0x0E /* 19200 baud */ -#define RIO_B38400 0x0F /* 38400 baud */ -#define RIO_B56000 0x10 /* 56000 baud */ -#define RIO_B57600 0x11 /* 57600 baud */ -#define RIO_B64000 0x12 /* 64000 baud */ -#define RIO_B115200 0x13 /* 115200 baud */ -#define RIO_B2000 0x14 /* 2000 baud */ diff --git a/drivers/staging/generic_serial/rio/map.h b/drivers/staging/generic_serial/rio/map.h deleted file mode 100644 index 28a66129293e..000000000000 --- a/drivers/staging/generic_serial/rio/map.h +++ /dev/null @@ -1,98 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : map.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:11 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)map.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_map_h__ -#define __rio_map_h__ - -/* -** mapping structure passed to and from the config.rio program to -** determine the current topology of the world -*/ - -#define MAX_MAP_ENTRY 17 -#define TOTAL_MAP_ENTRIES (MAX_MAP_ENTRY*RIO_SLOTS) -#define MAX_NAME_LEN 32 - -struct Map { - unsigned int HostUniqueNum; /* Supporting hosts unique number */ - unsigned int RtaUniqueNum; /* Unique number */ - /* - ** The next two IDs must be swapped on big-endian architectures - ** when using a v2.04 /etc/rio/config with a v3.00 driver (when - ** upgrading for example). - */ - unsigned short ID; /* ID used in the subnet */ - unsigned short ID2; /* ID of 2nd block of 8 for 16 port */ - unsigned long Flags; /* Booted, ID Given, Disconnected */ - unsigned long SysPort; /* First tty mapped to this port */ - struct Top Topology[LINKS_PER_UNIT]; /* ID connected to each link */ - char Name[MAX_NAME_LEN]; /* Cute name by which RTA is known */ -}; - -/* -** Flag values: -*/ -#define RTA_BOOTED 0x00000001 -#define RTA_NEWBOOT 0x00000010 -#define MSG_DONE 0x00000020 -#define RTA_INTERCONNECT 0x00000040 -#define RTA16_SECOND_SLOT 0x00000080 -#define BEEN_HERE 0x00000100 -#define SLOT_TENTATIVE 0x40000000 -#define SLOT_IN_USE 0x80000000 - -/* -** HostUniqueNum is the unique number from the host card that this RTA -** is to be connected to. -** RtaUniqueNum is the unique number of the RTA concerned. It will be ZERO -** if the slot in the table is unused. If it is the same as the HostUniqueNum -** then this slot represents a host card. -** Flags contains current boot/route state info -** SysPort is a value in the range 0-504, being the number of the first tty -** on this RTA. Each RTA supports 8 ports. The SysPort value must be modulo 8. -** SysPort 0-127 correspond to /dev/ttyr001 to /dev/ttyr128, with minor -** numbers 0-127. SysPort 128-255 correspond to /dev/ttyr129 to /dev/ttyr256, -** again with minor numbers 0-127, and so on for SysPorts 256-383 and 384-511 -** ID will be in the range 0-16 for a `known' RTA. ID will be 0xFFFF for an -** unused slot/unknown ID etc. -** The Topology array contains the ID of the unit connected to each of the -** four links on this unit. The entry will be 0xFFFF if NOTHING is connected -** to the link, or will be 0xFF00 if an UNKNOWN unit is connected to the link. -** The Name field is a null-terminated string, up to 31 characters, containing -** the 'cute' name that the sysadmin/users know the RTA by. It is permissible -** for this string to contain any character in the range \040 to \176 inclusive. -** In particular, ctrl sequences and DEL (0x7F, \177) are not allowed. The -** special character '%' IS allowable, and needs no special action. -** -*/ - -#endif diff --git a/drivers/staging/generic_serial/rio/param.h b/drivers/staging/generic_serial/rio/param.h deleted file mode 100644 index 7e9b6283e8aa..000000000000 --- a/drivers/staging/generic_serial/rio/param.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : param.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:12 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)param.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_param_h__ -#define __rio_param_h__ - -/* -** the param command block, as used in OPEN and PARAM calls. -*/ - -struct phb_param { - u8 Cmd; /* It is very important that these line up */ - u8 Cor1; /* with what is expected at the other end. */ - u8 Cor2; /* to confirm that you've got it right, */ - u8 Cor4; /* check with cirrus/cirrus.h */ - u8 Cor5; - u8 TxXon; /* Transmit X-On character */ - u8 TxXoff; /* Transmit X-Off character */ - u8 RxXon; /* Receive X-On character */ - u8 RxXoff; /* Receive X-Off character */ - u8 LNext; /* Literal-next character */ - u8 TxBaud; /* Transmit baudrate */ - u8 RxBaud; /* Receive baudrate */ -}; - -#endif diff --git a/drivers/staging/generic_serial/rio/parmmap.h b/drivers/staging/generic_serial/rio/parmmap.h deleted file mode 100644 index acc8fa439df5..000000000000 --- a/drivers/staging/generic_serial/rio/parmmap.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* H O S T M E M O R Y M A P - ******* ******* - **************************************************************************** - - Author : Ian Nandhra / Jeremy Rolls - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- -6/4/1991 jonb Made changes to accommodate Mips R3230 bus - ***************************************************************************/ - -#ifndef _parmap_h -#define _parmap_h - -typedef struct PARM_MAP PARM_MAP; - -struct PARM_MAP { - u16 phb_ptr; /* Pointer to the PHB array */ - u16 phb_num_ptr; /* Ptr to Number of PHB's */ - u16 free_list; /* Free List pointer */ - u16 free_list_end; /* Free List End pointer */ - u16 q_free_list_ptr; /* Ptr to Q_BUF variable */ - u16 unit_id_ptr; /* Unit Id */ - u16 link_str_ptr; /* Link Structure Array */ - u16 bootloader_1; /* 1st Stage Boot Loader */ - u16 bootloader_2; /* 2nd Stage Boot Loader */ - u16 port_route_map_ptr; /* Port Route Map */ - u16 route_ptr; /* Unit Route Map */ - u16 map_present; /* Route Map present */ - s16 pkt_num; /* Total number of packets */ - s16 q_num; /* Total number of Q packets */ - u16 buffers_per_port; /* Number of buffers per port */ - u16 heap_size; /* Initial size of heap */ - u16 heap_left; /* Current Heap left */ - u16 error; /* Error code */ - u16 tx_max; /* Max number of tx pkts per phb */ - u16 rx_max; /* Max number of rx pkts per phb */ - u16 rx_limit; /* For high / low watermarks */ - s16 links; /* Links to use */ - s16 timer; /* Interrupts per second */ - u16 rups; /* Pointer to the RUPs */ - u16 max_phb; /* Mostly for debugging */ - u16 living; /* Just increments!! */ - u16 init_done; /* Initialisation over */ - u16 booting_link; - u16 idle_count; /* Idle time counter */ - u16 busy_count; /* Busy counter */ - u16 idle_control; /* Control Idle Process */ - u16 tx_intr; /* TX interrupt pending */ - u16 rx_intr; /* RX interrupt pending */ - u16 rup_intr; /* RUP interrupt pending */ -}; - -#endif - -/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/pci.h b/drivers/staging/generic_serial/rio/pci.h deleted file mode 100644 index 6032f9135956..000000000000 --- a/drivers/staging/generic_serial/rio/pci.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : pci.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:12 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)pci.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_pci_h__ -#define __rio_pci_h__ - -/* -** PCI stuff -*/ - -#define PCITpFastClock 0x80 -#define PCITpSlowClock 0x00 -#define PCITpFastLinks 0x40 -#define PCITpSlowLinks 0x00 -#define PCITpIntEnable 0x04 -#define PCITpIntDisable 0x00 -#define PCITpBusEnable 0x02 -#define PCITpBusDisable 0x00 -#define PCITpBootFromRam 0x01 -#define PCITpBootFromLink 0x00 - -#define RIO_PCI_VENDOR 0x11CB -#define RIO_PCI_DEVICE 0x8000 -#define RIO_PCI_BASE_CLASS 0x02 -#define RIO_PCI_SUB_CLASS 0x80 -#define RIO_PCI_PROG_IFACE 0x00 - -#define RIO_PCI_RID 0x0008 -#define RIO_PCI_BADR0 0x0010 -#define RIO_PCI_INTLN 0x003C -#define RIO_PCI_INTPIN 0x003D - -#define RIO_PCI_MEM_SIZE 65536 - -#define RIO_PCI_TURBO_TP 0x80 -#define RIO_PCI_FAST_LINKS 0x40 -#define RIO_PCI_INT_ENABLE 0x04 -#define RIO_PCI_TP_BUS_ENABLE 0x02 -#define RIO_PCI_BOOT_FROM_RAM 0x01 - -#define RIO_PCI_DEFAULT_MODE 0x05 - -#endif /* __rio_pci_h__ */ diff --git a/drivers/staging/generic_serial/rio/phb.h b/drivers/staging/generic_serial/rio/phb.h deleted file mode 100644 index a4c48ae4e365..000000000000 --- a/drivers/staging/generic_serial/rio/phb.h +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* P H B H E A D E R ******* - ******* ******* - **************************************************************************** - - Author : Ian Nandhra, Jeremy Rolls - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _phb_h -#define _phb_h 1 - -/************************************************* - * Handshake asserted. Deasserted by the LTT(s) - ************************************************/ -#define PHB_HANDSHAKE_SET ((ushort) 0x001) /* Set by LRT */ - -#define PHB_HANDSHAKE_RESET ((ushort) 0x002) /* Set by ISR / driver */ - -#define PHB_HANDSHAKE_FLAGS (PHB_HANDSHAKE_RESET | PHB_HANDSHAKE_SET) - /* Reset by ltt */ - - -/************************************************* - * Maximum number of PHB's - ************************************************/ -#define MAX_PHB ((ushort) 128) /* range 0-127 */ - -/************************************************* - * Defines for the mode fields - ************************************************/ -#define TXPKT_INCOMPLETE 0x0001 /* Previous tx packet not completed */ -#define TXINTR_ENABLED 0x0002 /* Tx interrupt is enabled */ -#define TX_TAB3 0x0004 /* TAB3 mode */ -#define TX_OCRNL 0x0008 /* OCRNL mode */ -#define TX_ONLCR 0x0010 /* ONLCR mode */ -#define TX_SENDSPACES 0x0020 /* Send n spaces command needs - completing */ -#define TX_SENDNULL 0x0040 /* Escaping NULL needs completing */ -#define TX_SENDLF 0x0080 /* LF -> CR LF needs completing */ -#define TX_PARALLELBUG 0x0100 /* CD1400 LF -> CR LF bug on parallel - port */ -#define TX_HANGOVER (TX_SENDSPACES | TX_SENDLF | TX_SENDNULL) -#define TX_DTRFLOW 0x0200 /* DTR tx flow control */ -#define TX_DTRFLOWED 0x0400 /* DTR is low - don't allow more data - into the FIFO */ -#define TX_DATAINFIFO 0x0800 /* There is data in the FIFO */ -#define TX_BUSY 0x1000 /* Data in FIFO, shift or holding regs */ - -#define RX_SPARE 0x0001 /* SPARE */ -#define RXINTR_ENABLED 0x0002 /* Rx interrupt enabled */ -#define RX_ICRNL 0x0008 /* ICRNL mode */ -#define RX_INLCR 0x0010 /* INLCR mode */ -#define RX_IGNCR 0x0020 /* IGNCR mode */ -#define RX_CTSFLOW 0x0040 /* CTSFLOW enabled */ -#define RX_IXOFF 0x0080 /* IXOFF enabled */ -#define RX_CTSFLOWED 0x0100 /* CTSFLOW and CTS dropped */ -#define RX_IXOFFED 0x0200 /* IXOFF and xoff sent */ -#define RX_BUFFERED 0x0400 /* Try and pass on complete packets */ - -#define PORT_ISOPEN 0x0001 /* Port open? */ -#define PORT_HUPCL 0x0002 /* Hangup on close? */ -#define PORT_MOPENPEND 0x0004 /* Modem open pending */ -#define PORT_ISPARALLEL 0x0008 /* Parallel port */ -#define PORT_BREAK 0x0010 /* Port on break */ -#define PORT_STATUSPEND 0x0020 /* Status packet pending */ -#define PORT_BREAKPEND 0x0040 /* Break packet pending */ -#define PORT_MODEMPEND 0x0080 /* Modem status packet pending */ -#define PORT_PARALLELBUG 0x0100 /* CD1400 LF -> CR LF bug on parallel - port */ -#define PORT_FULLMODEM 0x0200 /* Full modem signals */ -#define PORT_RJ45 0x0400 /* RJ45 connector - no RI signal */ -#define PORT_RESTRICTED 0x0600 /* Restricted connector - no RI / DTR */ - -#define PORT_MODEMBITS 0x0600 /* Mask for modem fields */ - -#define PORT_WCLOSE 0x0800 /* Waiting for close */ -#define PORT_HANDSHAKEFIX 0x1000 /* Port has H/W flow control fix */ -#define PORT_WASPCLOSED 0x2000 /* Port closed with PCLOSE */ -#define DUMPMODE 0x4000 /* Dump RTA mem */ -#define READ_REG 0x8000 /* Read CD1400 register */ - - - -/************************************************************************** - * PHB Structure - * A few words. - * - * Normally Packets are added to the end of the list and removed from - * the start. The pointer tx_add points to a SPACE to put a Packet. - * The pointer tx_remove points to the next Packet to remove - *************************************************************************/ - -struct PHB { - u8 source; - u8 handshake; - u8 status; - u16 timeout; /* Maximum of 1.9 seconds */ - u8 link; /* Send down this link */ - u8 destination; - u16 tx_start; - u16 tx_end; - u16 tx_add; - u16 tx_remove; - - u16 rx_start; - u16 rx_end; - u16 rx_add; - u16 rx_remove; - -}; - -#endif - -/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/pkt.h b/drivers/staging/generic_serial/rio/pkt.h deleted file mode 100644 index a9458164f02f..000000000000 --- a/drivers/staging/generic_serial/rio/pkt.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* P A C K E T H E A D E R F I L E - ******* ******* - **************************************************************************** - - Author : Ian Nandhra / Jeremy Rolls - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _pkt_h -#define _pkt_h 1 - -#define PKT_CMD_BIT ((ushort) 0x080) -#define PKT_CMD_DATA ((ushort) 0x080) - -#define PKT_ACK ((ushort) 0x040) - -#define PKT_TGL ((ushort) 0x020) - -#define PKT_LEN_MASK ((ushort) 0x07f) - -#define DATA_WNDW ((ushort) 0x10) -#define PKT_TTL_MASK ((ushort) 0x0f) - -#define PKT_MAX_DATA_LEN 72 - -#define PKT_LENGTH sizeof(struct PKT) -#define SYNC_PKT_LENGTH (PKT_LENGTH + 4) - -#define CONTROL_PKT_LEN_MASK PKT_LEN_MASK -#define CONTROL_PKT_CMD_BIT PKT_CMD_BIT -#define CONTROL_PKT_ACK (PKT_ACK << 8) -#define CONTROL_PKT_TGL (PKT_TGL << 8) -#define CONTROL_PKT_TTL_MASK (PKT_TTL_MASK << 8) -#define CONTROL_DATA_WNDW (DATA_WNDW << 8) - -struct PKT { - u8 dest_unit; /* Destination Unit Id */ - u8 dest_port; /* Destination POrt */ - u8 src_unit; /* Source Unit Id */ - u8 src_port; /* Source POrt */ - u8 len; - u8 control; - u8 data[PKT_MAX_DATA_LEN]; - /* Actual data :-) */ - u16 csum; /* C-SUM */ -}; -#endif - -/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/port.h b/drivers/staging/generic_serial/rio/port.h deleted file mode 100644 index 49cf6d15ee54..000000000000 --- a/drivers/staging/generic_serial/rio/port.h +++ /dev/null @@ -1,179 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : port.h -** SID : 1.3 -** Last Modified : 11/6/98 11:34:12 -** Retrieved : 11/6/98 11:34:21 -** -** ident @(#)port.h 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_port_h__ -#define __rio_port_h__ - -/* -** Port data structure -*/ -struct Port { - struct gs_port gs; - int PortNum; /* RIO port no., 0-511 */ - struct Host *HostP; - void __iomem *Caddr; - unsigned short HostPort; /* Port number on host card */ - unsigned char RupNum; /* Number of RUP for port */ - unsigned char ID2; /* Second ID of RTA for port */ - unsigned long State; /* FLAGS for open & xopen */ -#define RIO_LOPEN 0x00001 /* Local open */ -#define RIO_MOPEN 0x00002 /* Modem open */ -#define RIO_WOPEN 0x00004 /* Waiting for open */ -#define RIO_CLOSING 0x00008 /* The port is being close */ -#define RIO_XPBUSY 0x00010 /* Transparent printer busy */ -#define RIO_BREAKING 0x00020 /* Break in progress */ -#define RIO_DIRECT 0x00040 /* Doing Direct output */ -#define RIO_EXCLUSIVE 0x00080 /* Stream open for exclusive use */ -#define RIO_NDELAY 0x00100 /* Stream is open FNDELAY */ -#define RIO_CARR_ON 0x00200 /* Stream has carrier present */ -#define RIO_XPWANTR 0x00400 /* Stream wanted by Xprint */ -#define RIO_RBLK 0x00800 /* Stream is read-blocked */ -#define RIO_BUSY 0x01000 /* Stream is BUSY for write */ -#define RIO_TIMEOUT 0x02000 /* Stream timeout in progress */ -#define RIO_TXSTOP 0x04000 /* Stream output is stopped */ -#define RIO_WAITFLUSH 0x08000 /* Stream waiting for flush */ -#define RIO_DYNOROD 0x10000 /* Drain failed */ -#define RIO_DELETED 0x20000 /* RTA has been deleted */ -#define RIO_ISSCANCODE 0x40000 /* This line is in scancode mode */ -#define RIO_USING_EUC 0x100000 /* Using extended Unix chars */ -#define RIO_CAN_COOK 0x200000 /* This line can do cooking */ -#define RIO_TRIAD_MODE 0x400000 /* Enable TRIAD special ops. */ -#define RIO_TRIAD_BLOCK 0x800000 /* Next read will block */ -#define RIO_TRIAD_FUNC 0x1000000 /* Seen a function key coming in */ -#define RIO_THROTTLE_RX 0x2000000 /* RX needs to be throttled. */ - - unsigned long Config; /* FLAGS for NOREAD.... */ -#define RIO_NOREAD 0x0001 /* Are not allowed to read port */ -#define RIO_NOWRITE 0x0002 /* Are not allowed to write port */ -#define RIO_NOXPRINT 0x0004 /* Are not allowed to xprint port */ -#define RIO_NOMASK 0x0007 /* All not allowed things */ -#define RIO_IXANY 0x0008 /* Port is allowed ixany */ -#define RIO_MODEM 0x0010 /* Stream is a modem device */ -#define RIO_IXON 0x0020 /* Port is allowed ixon */ -#define RIO_WAITDRAIN 0x0040 /* Wait for port to completely drain */ -#define RIO_MAP_50_TO_50 0x0080 /* Map 50 baud to 50 baud */ -#define RIO_MAP_110_TO_110 0x0100 /* Map 110 baud to 110 baud */ - -/* -** 15.10.1998 ARG - ESIL 0761 prt fix -** As LynxOS does not appear to support Hardware Flow Control ..... -** Define our own flow control flags in 'Config'. -*/ -#define RIO_CTSFLOW 0x0200 /* RIO's own CTSFLOW flag */ -#define RIO_RTSFLOW 0x0400 /* RIO's own RTSFLOW flag */ - - - struct PHB __iomem *PhbP; /* pointer to PHB for port */ - u16 __iomem *TxAdd; /* Add packets here */ - u16 __iomem *TxStart; /* Start of add array */ - u16 __iomem *TxEnd; /* End of add array */ - u16 __iomem *RxRemove; /* Remove packets here */ - u16 __iomem *RxStart; /* Start of remove array */ - u16 __iomem *RxEnd; /* End of remove array */ - unsigned int RtaUniqueNum; /* Unique number of RTA */ - unsigned short PortState; /* status of port */ - unsigned short ModemState; /* status of modem lines */ - unsigned long ModemLines; /* Modem bits sent to RTA */ - unsigned char CookMode; /* who expands CR/LF? */ - unsigned char ParamSem; /* Prevent write during param */ - unsigned char Mapped; /* if port mapped onto host */ - unsigned char SecondBlock; /* if port belongs to 2nd block - of 16 port RTA */ - unsigned char InUse; /* how many pre-emptive cmds */ - unsigned char Lock; /* if params locked */ - unsigned char Store; /* if params stored across closes */ - unsigned char FirstOpen; /* TRUE if first time port opened */ - unsigned char FlushCmdBodge; /* if doing a (non)flush */ - unsigned char MagicFlags; /* require intr processing */ -#define MAGIC_FLUSH 0x01 /* mirror of WflushFlag */ -#define MAGIC_REBOOT 0x02 /* RTA re-booted, re-open ports */ -#define MORE_OUTPUT_EYGOR 0x04 /* riotproc failed to empty clists */ - unsigned char WflushFlag; /* 1 How many WFLUSHs active */ -/* -** Transparent print stuff -*/ - struct Xprint { -#ifndef MAX_XP_CTRL_LEN -#define MAX_XP_CTRL_LEN 16 /* ALSO IN DAEMON.H */ -#endif - unsigned int XpCps; - char XpOn[MAX_XP_CTRL_LEN]; - char XpOff[MAX_XP_CTRL_LEN]; - unsigned short XpLen; /* strlen(XpOn)+strlen(XpOff) */ - unsigned char XpActive; - unsigned char XpLastTickOk; /* TRUE if we can process */ -#define XP_OPEN 00001 -#define XP_RUNABLE 00002 - struct ttystatics *XttyP; - } Xprint; - unsigned char RxDataStart; - unsigned char Cor2Copy; /* copy of COR2 */ - char *Name; /* points to the Rta's name */ - char *TxRingBuffer; - unsigned short TxBufferIn; /* New data arrives here */ - unsigned short TxBufferOut; /* Intr removes data here */ - unsigned short OldTxBufferOut; /* Indicates if draining */ - int TimeoutId; /* Timeout ID */ - unsigned int Debug; - unsigned char WaitUntilBooted; /* True if open should block */ - unsigned int statsGather; /* True if gathering stats */ - unsigned long txchars; /* Chars transmitted */ - unsigned long rxchars; /* Chars received */ - unsigned long opens; /* port open count */ - unsigned long closes; /* port close count */ - unsigned long ioctls; /* ioctl count */ - unsigned char LastRxTgl; /* Last state of rx toggle bit */ - spinlock_t portSem; /* Lock using this sem */ - int MonitorTstate; /* Monitoring ? */ - int timeout_id; /* For calling 100 ms delays */ - int timeout_sem; /* For calling 100 ms delays */ - int firstOpen; /* First time open ? */ - char *p; /* save the global struc here .. */ -}; - -struct ModuleInfo { - char *Name; - unsigned int Flags[4]; /* one per port on a module */ -}; - -/* -** This struct is required because trying to grab an entire Port structure -** runs into problems with differing struct sizes between driver and config. -*/ -struct PortParams { - unsigned int Port; - unsigned long Config; - unsigned long State; - struct ttystatics *TtyP; -}; - -#endif diff --git a/drivers/staging/generic_serial/rio/protsts.h b/drivers/staging/generic_serial/rio/protsts.h deleted file mode 100644 index 8ab79401d3ee..000000000000 --- a/drivers/staging/generic_serial/rio/protsts.h +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* P R O T O C O L S T A T U S S T R U C T U R E ******* - ******* ******* - **************************************************************************** - - Author : Ian Nandhra / Jeremy Rolls - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _protsts_h -#define _protsts_h 1 - -/************************************************* - * ACK bit. Last Packet received OK. Set by - * rxpkt to indicate that the Packet has been - * received OK and that the LTT must set the ACK - * bit in the next outward bound Packet - * and re-set by LTT's after xmit. - * - * Gets shoved into rx_status - ************************************************/ -#define PHB_RX_LAST_PKT_ACKED ((ushort) 0x080) - -/******************************************************* - * The Rx TOGGLE bit. - * Stuffed into rx_status by RXPKT - ******************************************************/ -#define PHB_RX_DATA_WNDW ((ushort) 0x040) - -/******************************************************* - * The Rx TOGGLE bit. Matches the setting in PKT.H - * Stuffed into rx_status - ******************************************************/ -#define PHB_RX_TGL ((ushort) 0x2000) - - -/************************************************* - * This bit is set by the LRT to indicate that - * an ACK (packet) must be returned. - * - * Gets shoved into tx_status - ************************************************/ -#define PHB_TX_SEND_PKT_ACK ((ushort) 0x08) - -/************************************************* - * Set by LTT to indicate that an ACK is required - *************************************************/ -#define PHB_TX_ACK_RQRD ((ushort) 0x01) - - -/******************************************************* - * The Tx TOGGLE bit. - * Stuffed into tx_status by RXPKT from the PKT WndW - * field. Looked by the LTT when the NEXT Packet - * is going to be sent. - ******************************************************/ -#define PHB_TX_DATA_WNDW ((ushort) 0x04) - - -/******************************************************* - * The Tx TOGGLE bit. Matches the setting in PKT.H - * Stuffed into tx_status - ******************************************************/ -#define PHB_TX_TGL ((ushort) 0x02) - -/******************************************************* - * Request intr bit. Set when the queue has gone quiet - * and the PHB has requested an interrupt. - ******************************************************/ -#define PHB_TX_INTR ((ushort) 0x100) - -/******************************************************* - * SET if the PHB cannot send any more data down the - * Link - ******************************************************/ -#define PHB_TX_HANDSHAKE ((ushort) 0x010) - - -#define RUP_SEND_WNDW ((ushort) 0x08) ; - -#endif - -/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/rio.h b/drivers/staging/generic_serial/rio/rio.h deleted file mode 100644 index 1bf36223a4e8..000000000000 --- a/drivers/staging/generic_serial/rio/rio.h +++ /dev/null @@ -1,208 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 1998 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : rio.h -** SID : 1.3 -** Last Modified : 11/6/98 11:34:13 -** Retrieved : 11/6/98 11:34:22 -** -** ident @(#)rio.h 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_rio_h__ -#define __rio_rio_h__ - -/* -** Maximum numbers of things -*/ -#define RIO_SLOTS 4 /* number of configuration slots */ -#define RIO_HOSTS 4 /* number of hosts that can be found */ -#define PORTS_PER_HOST 128 /* number of ports per host */ -#define LINKS_PER_UNIT 4 /* number of links from a host */ -#define RIO_PORTS (PORTS_PER_HOST * RIO_HOSTS) /* max. no. of ports */ -#define RTAS_PER_HOST (MAX_RUP) /* number of RTAs per host */ -#define PORTS_PER_RTA (PORTS_PER_HOST/RTAS_PER_HOST) /* ports on a rta */ -#define PORTS_PER_MODULE 4 /* number of ports on a plug-in module */ - /* number of modules on an RTA */ -#define MODULES_PER_RTA (PORTS_PER_RTA/PORTS_PER_MODULE) -#define MAX_PRODUCT 16 /* numbr of different product codes */ -#define MAX_MODULE_TYPES 16 /* number of different types of module */ - -#define RIO_CONTROL_DEV 128 /* minor number of host/control device */ -#define RIO_INVALID_MAJOR 0 /* test first host card's major no for validity */ - -/* -** number of RTAs that can be bound to a master -*/ -#define MAX_RTA_BINDINGS (MAX_RUP * RIO_HOSTS) - -/* -** Unit types -*/ -#define PC_RTA16 0x90000000 -#define PC_RTA8 0xe0000000 -#define TYPE_HOST 0 -#define TYPE_RTA8 1 -#define TYPE_RTA16 2 - -/* -** Flag values returned by functions -*/ - -#define RIO_FAIL -1 - -/* -** SysPort value for something that hasn't any ports -*/ -#define NO_PORT 0xFFFFFFFF - -/* -** Unit ID Of all hosts -*/ -#define HOST_ID 0 - -/* -** Break bytes into nybles -*/ -#define LONYBLE(X) ((X) & 0xF) -#define HINYBLE(X) (((X)>>4) & 0xF) - -/* -** Flag values passed into some functions -*/ -#define DONT_SLEEP 0 -#define OK_TO_SLEEP 1 - -#define DONT_PRINT 1 -#define DO_PRINT 0 - -#define PRINT_TO_LOG_CONS 0 -#define PRINT_TO_CONS 1 -#define PRINT_TO_LOG 2 - -/* -** Timeout has trouble with times of less than 3 ticks... -*/ -#define MIN_TIMEOUT 3 - -/* -** Generally useful constants -*/ - -#define HUNDRED_MS ((HZ/10)?(HZ/10):1) -#define ONE_MEG 0x100000 -#define SIXTY_FOUR_K 0x10000 - -#define RIO_AT_MEM_SIZE SIXTY_FOUR_K -#define RIO_EISA_MEM_SIZE SIXTY_FOUR_K -#define RIO_MCA_MEM_SIZE SIXTY_FOUR_K - -#define COOK_WELL 0 -#define COOK_MEDIUM 1 -#define COOK_RAW 2 - -/* -** Pointer manipulation stuff -** RIO_PTR takes hostp->Caddr and the offset into the DP RAM area -** and produces a UNIX caddr_t (pointer) to the object -** RIO_OBJ takes hostp->Caddr and a UNIX pointer to an object and -** returns the offset into the DP RAM area. -*/ -#define RIO_PTR(C,O) (((unsigned char __iomem *)(C))+(0xFFFF&(O))) -#define RIO_OFF(C,O) ((unsigned char __iomem *)(O)-(unsigned char __iomem *)(C)) - -/* -** How to convert from various different device number formats: -** DEV is a dev number, as passed to open, close etc - NOT a minor -** number! -**/ - -#define RIO_MODEM_MASK 0x1FF -#define RIO_MODEM_BIT 0x200 -#define RIO_UNMODEM(DEV) (MINOR(DEV) & RIO_MODEM_MASK) -#define RIO_ISMODEM(DEV) (MINOR(DEV) & RIO_MODEM_BIT) -#define RIO_PORT(DEV,FIRST_MAJ) ( (MAJOR(DEV) - FIRST_MAJ) * PORTS_PER_HOST) \ - + MINOR(DEV) -#define CSUM(pkt_ptr) (((u16 *)(pkt_ptr))[0] + ((u16 *)(pkt_ptr))[1] + \ - ((u16 *)(pkt_ptr))[2] + ((u16 *)(pkt_ptr))[3] + \ - ((u16 *)(pkt_ptr))[4] + ((u16 *)(pkt_ptr))[5] + \ - ((u16 *)(pkt_ptr))[6] + ((u16 *)(pkt_ptr))[7] + \ - ((u16 *)(pkt_ptr))[8] + ((u16 *)(pkt_ptr))[9] ) - -#define RIO_LINK_ENABLE 0x80FF /* FF is a hack, mainly for Mips, to */ - /* prevent a really stupid race condition. */ - -#define NOT_INITIALISED 0 -#define INITIALISED 1 - -#define NOT_POLLING 0 -#define POLLING 1 - -#define NOT_CHANGED 0 -#define CHANGED 1 - -#define NOT_INUSE 0 - -#define DISCONNECT 0 -#define CONNECT 1 - -/* ------ Control Codes ------ */ - -#define CONTROL '^' -#define IFOAD ( CONTROL + 1 ) -#define IDENTIFY ( CONTROL + 2 ) -#define ZOMBIE ( CONTROL + 3 ) -#define UFOAD ( CONTROL + 4 ) -#define IWAIT ( CONTROL + 5 ) - -#define IFOAD_MAGIC 0xF0AD /* of course */ -#define ZOMBIE_MAGIC (~0xDEAD) /* not dead -> zombie */ -#define UFOAD_MAGIC 0xD1E /* kill-your-neighbour */ -#define IWAIT_MAGIC 0xB1DE /* Bide your time */ - -/* ------ Error Codes ------ */ - -#define E_NO_ERROR ((ushort) 0) - -/* ------ Free Lists ------ */ - -struct rio_free_list { - u16 next; - u16 prev; -}; - -/* NULL for card side linked lists */ -#define TPNULL ((ushort)(0x8000)) -/* We can add another packet to a transmit queue if the packet pointer pointed - * to by the TxAdd pointer has PKT_IN_USE clear in its address. */ -#define PKT_IN_USE 0x1 - -/* ------ Topology ------ */ - -struct Top { - u8 Unit; - u8 Link; -}; - -#endif /* __rio_h__ */ diff --git a/drivers/staging/generic_serial/rio/rio_linux.c b/drivers/staging/generic_serial/rio/rio_linux.c deleted file mode 100644 index 5e33293d24e3..000000000000 --- a/drivers/staging/generic_serial/rio/rio_linux.c +++ /dev/null @@ -1,1204 +0,0 @@ - -/* rio_linux.c -- Linux driver for the Specialix RIO series cards. - * - * - * (C) 1999 R.E.Wolff@BitWizard.nl - * - * Specialix pays for the development and support of this driver. - * Please DO contact support@specialix.co.uk if you require - * support. But please read the documentation (rio.txt) first. - * - * - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "linux_compat.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" -#include "param.h" -#include "protsts.h" -#include "rioboard.h" - - -#include "rio_linux.h" - -/* I don't think that this driver can handle more than 512 ports on -one machine. Specialix specifies max 4 boards in one machine. I don't -know why. If you want to try anyway you'll have to increase the number -of boards in rio.h. You'll have to allocate more majors if you need -more than 512 ports.... */ - -#ifndef RIO_NORMAL_MAJOR0 -/* This allows overriding on the compiler commandline, or in a "major.h" - include or something like that */ -#define RIO_NORMAL_MAJOR0 154 -#define RIO_NORMAL_MAJOR1 156 -#endif - -#ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 -#define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 -#endif - -#ifndef RIO_WINDOW_LEN -#define RIO_WINDOW_LEN 0x10000 -#endif - - -/* Configurable options: - (Don't be too sure that it'll work if you toggle them) */ - -/* Am I paranoid or not ? ;-) */ -#undef RIO_PARANOIA_CHECK - - -/* 20 -> 2000 per second. The card should rate-limit interrupts at 1000 - Hz, but it is user configurable. I don't recommend going above 1000 - Hz. The interrupt ratelimit might trigger if the interrupt is - shared with a very active other device. - undef this if you want to disable the check.... -*/ -#define IRQ_RATE_LIMIT 200 - - -/* These constants are derived from SCO Source */ -static DEFINE_MUTEX(rio_fw_mutex); -static struct Conf - RIOConf = { - /* locator */ "RIO Config here", - /* startuptime */ HZ * 2, - /* how long to wait for card to run */ - /* slowcook */ 0, - /* TRUE -> always use line disc. */ - /* intrpolltime */ 1, - /* The frequency of OUR polls */ - /* breakinterval */ 25, - /* x10 mS XXX: units seem to be 1ms not 10! -- REW */ - /* timer */ 10, - /* mS */ - /* RtaLoadBase */ 0x7000, - /* HostLoadBase */ 0x7C00, - /* XpHz */ 5, - /* number of Xprint hits per second */ - /* XpCps */ 120, - /* Xprint characters per second */ - /* XpOn */ "\033d#", - /* start Xprint for a wyse 60 */ - /* XpOff */ "\024", - /* end Xprint for a wyse 60 */ - /* MaxXpCps */ 2000, - /* highest Xprint speed */ - /* MinXpCps */ 10, - /* slowest Xprint speed */ - /* SpinCmds */ 1, - /* non-zero for mega fast boots */ - /* First Addr */ 0x0A0000, - /* First address to look at */ - /* Last Addr */ 0xFF0000, - /* Last address looked at */ - /* BufferSize */ 1024, - /* Bytes per port of buffering */ - /* LowWater */ 256, - /* how much data left before wakeup */ - /* LineLength */ 80, - /* how wide is the console? */ - /* CmdTimeout */ HZ, - /* how long a close command may take */ -}; - - - - -/* Function prototypes */ - -static void rio_disable_tx_interrupts(void *ptr); -static void rio_enable_tx_interrupts(void *ptr); -static void rio_disable_rx_interrupts(void *ptr); -static void rio_enable_rx_interrupts(void *ptr); -static int rio_carrier_raised(struct tty_port *port); -static void rio_shutdown_port(void *ptr); -static int rio_set_real_termios(void *ptr); -static void rio_hungup(void *ptr); -static void rio_close(void *ptr); -static int rio_chars_in_buffer(void *ptr); -static long rio_fw_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -static int rio_init_drivers(void); - -static void my_hd(void *addr, int len); - -static struct tty_driver *rio_driver, *rio_driver2; - -/* The name "p" is a bit non-descript. But that's what the rio-lynxos -sources use all over the place. */ -struct rio_info *p; - -int rio_debug; - - -/* You can have the driver poll your card. - - Set rio_poll to 1 to poll every timer tick (10ms on Intel). - This is used when the card cannot use an interrupt for some reason. -*/ -static int rio_poll = 1; - - -/* These are the only open spaces in my computer. Yours may have more - or less.... */ -static int rio_probe_addrs[] = { 0xc0000, 0xd0000, 0xe0000 }; - -#define NR_RIO_ADDRS ARRAY_SIZE(rio_probe_addrs) - - -/* Set the mask to all-ones. This alas, only supports 32 interrupts. - Some architectures may need more. -- Changed to LONG to - support up to 64 bits on 64bit architectures. -- REW 20/06/99 */ -static long rio_irqmask = -1; - -MODULE_AUTHOR("Rogier Wolff , Patrick van de Lageweg "); -MODULE_DESCRIPTION("RIO driver"); -MODULE_LICENSE("GPL"); -module_param(rio_poll, int, 0); -module_param(rio_debug, int, 0644); -module_param(rio_irqmask, long, 0); - -static struct real_driver rio_real_driver = { - rio_disable_tx_interrupts, - rio_enable_tx_interrupts, - rio_disable_rx_interrupts, - rio_enable_rx_interrupts, - rio_shutdown_port, - rio_set_real_termios, - rio_chars_in_buffer, - rio_close, - rio_hungup, - NULL -}; - -/* - * Firmware loader driver specific routines - * - */ - -static const struct file_operations rio_fw_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = rio_fw_ioctl, - .llseek = noop_llseek, -}; - -static struct miscdevice rio_fw_device = { - RIOCTL_MISC_MINOR, "rioctl", &rio_fw_fops -}; - - - - - -#ifdef RIO_PARANOIA_CHECK - -/* This doesn't work. Who's paranoid around here? Not me! */ - -static inline int rio_paranoia_check(struct rio_port const *port, char *name, const char *routine) -{ - - static const char *badmagic = KERN_ERR "rio: Warning: bad rio port magic number for device %s in %s\n"; - static const char *badinfo = KERN_ERR "rio: Warning: null rio port for device %s in %s\n"; - - if (!port) { - printk(badinfo, name, routine); - return 1; - } - if (port->magic != RIO_MAGIC) { - printk(badmagic, name, routine); - return 1; - } - - return 0; -} -#else -#define rio_paranoia_check(a,b,c) 0 -#endif - - -#ifdef DEBUG -static void my_hd(void *ad, int len) -{ - int i, j, ch; - unsigned char *addr = ad; - - for (i = 0; i < len; i += 16) { - rio_dprintk(RIO_DEBUG_PARAM, "%08lx ", (unsigned long) addr + i); - for (j = 0; j < 16; j++) { - rio_dprintk(RIO_DEBUG_PARAM, "%02x %s", addr[j + i], (j == 7) ? " " : ""); - } - for (j = 0; j < 16; j++) { - ch = addr[j + i]; - rio_dprintk(RIO_DEBUG_PARAM, "%c", (ch < 0x20) ? '.' : ((ch > 0x7f) ? '.' : ch)); - } - rio_dprintk(RIO_DEBUG_PARAM, "\n"); - } -} -#else -#define my_hd(ad,len) do{/* nothing*/ } while (0) -#endif - - -/* Delay a number of jiffies, allowing a signal to interrupt */ -int RIODelay(struct Port *PortP, int njiffies) -{ - func_enter(); - - rio_dprintk(RIO_DEBUG_DELAY, "delaying %d jiffies\n", njiffies); - msleep_interruptible(jiffies_to_msecs(njiffies)); - func_exit(); - - if (signal_pending(current)) - return RIO_FAIL; - else - return !RIO_FAIL; -} - - -/* Delay a number of jiffies, disallowing a signal to interrupt */ -int RIODelay_ni(struct Port *PortP, int njiffies) -{ - func_enter(); - - rio_dprintk(RIO_DEBUG_DELAY, "delaying %d jiffies (ni)\n", njiffies); - msleep(jiffies_to_msecs(njiffies)); - func_exit(); - return !RIO_FAIL; -} - -void rio_copy_to_card(void *from, void __iomem *to, int len) -{ - rio_copy_toio(to, from, len); -} - -int rio_minor(struct tty_struct *tty) -{ - return tty->index + ((tty->driver == rio_driver) ? 0 : 256); -} - -static int rio_set_real_termios(void *ptr) -{ - return RIOParam((struct Port *) ptr, RIOC_CONFIG, 1, 1); -} - - -static void rio_reset_interrupt(struct Host *HostP) -{ - func_enter(); - - switch (HostP->Type) { - case RIO_AT: - case RIO_MCA: - case RIO_PCI: - writeb(0xFF, &HostP->ResetInt); - } - - func_exit(); -} - - -static irqreturn_t rio_interrupt(int irq, void *ptr) -{ - struct Host *HostP; - func_enter(); - - HostP = ptr; /* &p->RIOHosts[(long)ptr]; */ - rio_dprintk(RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", irq, HostP->Ivec); - - /* AAargh! The order in which to do these things is essential and - not trivial. - - - hardware twiddling goes before "recursive". Otherwise when we - poll the card, and a recursive interrupt happens, we won't - ack the card, so it might keep on interrupting us. (especially - level sensitive interrupt systems like PCI). - - - Rate limit goes before hardware twiddling. Otherwise we won't - catch a card that has gone bonkers. - - - The "initialized" test goes after the hardware twiddling. Otherwise - the card will stick us in the interrupt routine again. - - - The initialized test goes before recursive. - */ - - rio_dprintk(RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n"); - if (HostP->Ivec == irq) { - /* Tell the card we've noticed the interrupt. */ - rio_reset_interrupt(HostP); - } - - if ((HostP->Flags & RUN_STATE) != RC_RUNNING) - return IRQ_HANDLED; - - if (test_and_set_bit(RIO_BOARD_INTR_LOCK, &HostP->locks)) { - printk(KERN_ERR "Recursive interrupt! (host %p/irq%d)\n", ptr, HostP->Ivec); - return IRQ_HANDLED; - } - - RIOServiceHost(p, HostP); - - rio_dprintk(RIO_DEBUG_IFLOW, "riointr() doing host %p type %d\n", ptr, HostP->Type); - - clear_bit(RIO_BOARD_INTR_LOCK, &HostP->locks); - rio_dprintk(RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", irq, HostP->Ivec); - func_exit(); - return IRQ_HANDLED; -} - - -static void rio_pollfunc(unsigned long data) -{ - func_enter(); - - rio_interrupt(0, &p->RIOHosts[data]); - mod_timer(&p->RIOHosts[data].timer, jiffies + rio_poll); - - func_exit(); -} - - -/* ********************************************************************** * - * Here are the routines that actually * - * interface with the generic_serial driver * - * ********************************************************************** */ - -/* Ehhm. I don't know how to fiddle with interrupts on the Specialix - cards. .... Hmm. Ok I figured it out. You don't. -- REW */ - -static void rio_disable_tx_interrupts(void *ptr) -{ - func_enter(); - - /* port->gs.port.flags &= ~GS_TX_INTEN; */ - - func_exit(); -} - - -static void rio_enable_tx_interrupts(void *ptr) -{ - struct Port *PortP = ptr; - /* int hn; */ - - func_enter(); - - /* hn = PortP->HostP - p->RIOHosts; - - rio_dprintk (RIO_DEBUG_TTY, "Pushing host %d\n", hn); - rio_interrupt (-1,(void *) hn, NULL); */ - - RIOTxEnable((char *) PortP); - - /* - * In general we cannot count on "tx empty" interrupts, although - * the interrupt routine seems to be able to tell the difference. - */ - PortP->gs.port.flags &= ~GS_TX_INTEN; - - func_exit(); -} - - -static void rio_disable_rx_interrupts(void *ptr) -{ - func_enter(); - func_exit(); -} - -static void rio_enable_rx_interrupts(void *ptr) -{ - /* struct rio_port *port = ptr; */ - func_enter(); - func_exit(); -} - - -/* Jeez. Isn't this simple? */ -static int rio_carrier_raised(struct tty_port *port) -{ - struct Port *PortP = container_of(port, struct Port, gs.port); - int rv; - - func_enter(); - rv = (PortP->ModemState & RIOC_MSVR1_CD) != 0; - - rio_dprintk(RIO_DEBUG_INIT, "Getting CD status: %d\n", rv); - - func_exit(); - return rv; -} - - -/* Jeez. Isn't this simple? Actually, we can sync with the actual port - by just pushing stuff into the queue going to the port... */ -static int rio_chars_in_buffer(void *ptr) -{ - func_enter(); - - func_exit(); - return 0; -} - - -/* Nothing special here... */ -static void rio_shutdown_port(void *ptr) -{ - struct Port *PortP; - - func_enter(); - - PortP = (struct Port *) ptr; - PortP->gs.port.tty = NULL; - func_exit(); -} - - -/* I haven't the foggiest why the decrement use count has to happen - here. The whole linux serial drivers stuff needs to be redesigned. - My guess is that this is a hack to minimize the impact of a bug - elsewhere. Thinking about it some more. (try it sometime) Try - running minicom on a serial port that is driven by a modularized - driver. Have the modem hangup. Then remove the driver module. Then - exit minicom. I expect an "oops". -- REW */ -static void rio_hungup(void *ptr) -{ - struct Port *PortP; - - func_enter(); - - PortP = (struct Port *) ptr; - PortP->gs.port.tty = NULL; - - func_exit(); -} - - -/* The standard serial_close would become shorter if you'd wrap it like - this. - rs_close (...){save_flags;cli;real_close();dec_use_count;restore_flags;} - */ -static void rio_close(void *ptr) -{ - struct Port *PortP; - - func_enter(); - - PortP = (struct Port *) ptr; - - riotclose(ptr); - - if (PortP->gs.port.count) { - printk(KERN_ERR "WARNING port count:%d\n", PortP->gs.port.count); - PortP->gs.port.count = 0; - } - - PortP->gs.port.tty = NULL; - func_exit(); -} - - - -static long rio_fw_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int rc = 0; - func_enter(); - - /* The "dev" argument isn't used. */ - mutex_lock(&rio_fw_mutex); - rc = riocontrol(p, 0, cmd, arg, capable(CAP_SYS_ADMIN)); - mutex_unlock(&rio_fw_mutex); - - func_exit(); - return rc; -} - -extern int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg); - -static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; - int rc; - struct Port *PortP; - int ival; - - func_enter(); - - PortP = (struct Port *) tty->driver_data; - - rc = 0; - switch (cmd) { - case TIOCSSOFTCAR: - if ((rc = get_user(ival, (unsigned __user *) argp)) == 0) { - tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (ival ? CLOCAL : 0); - } - break; - case TIOCGSERIAL: - rc = -EFAULT; - if (access_ok(VERIFY_WRITE, argp, sizeof(struct serial_struct))) - rc = gs_getserial(&PortP->gs, argp); - break; - case TCSBRK: - if (PortP->State & RIO_DELETED) { - rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); - rc = -EIO; - } else { - if (RIOShortCommand(p, PortP, RIOC_SBREAK, 2, 250) == - RIO_FAIL) { - rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); - rc = -EIO; - } - } - break; - case TCSBRKP: - if (PortP->State & RIO_DELETED) { - rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n"); - rc = -EIO; - } else { - int l; - l = arg ? arg * 100 : 250; - if (l > 255) - l = 255; - if (RIOShortCommand(p, PortP, RIOC_SBREAK, 2, - arg ? arg * 100 : 250) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n"); - rc = -EIO; - } - } - break; - case TIOCSSERIAL: - rc = -EFAULT; - if (access_ok(VERIFY_READ, argp, sizeof(struct serial_struct))) - rc = gs_setserial(&PortP->gs, argp); - break; - default: - rc = -ENOIOCTLCMD; - break; - } - func_exit(); - return rc; -} - - -/* The throttle/unthrottle scheme for the Specialix card is different - * from other drivers and deserves some explanation. - * The Specialix hardware takes care of XON/XOFF - * and CTS/RTS flow control itself. This means that all we have to - * do when signalled by the upper tty layer to throttle/unthrottle is - * to make a note of it here. When we come to read characters from the - * rx buffers on the card (rio_receive_chars()) we look to see if the - * upper layer can accept more (as noted here in rio_rx_throt[]). - * If it can't we simply don't remove chars from the cards buffer. - * When the tty layer can accept chars, we again note that here and when - * rio_receive_chars() is called it will remove them from the cards buffer. - * The card will notice that a ports buffer has drained below some low - * water mark and will unflow control the line itself, using whatever - * flow control scheme is in use for that port. -- Simon Allen - */ - -static void rio_throttle(struct tty_struct *tty) -{ - struct Port *port = (struct Port *) tty->driver_data; - - func_enter(); - /* If the port is using any type of input flow - * control then throttle the port. - */ - - if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) { - port->State |= RIO_THROTTLE_RX; - } - - func_exit(); -} - - -static void rio_unthrottle(struct tty_struct *tty) -{ - struct Port *port = (struct Port *) tty->driver_data; - - func_enter(); - /* Always unthrottle even if flow control is not enabled on - * this port in case we disabled flow control while the port - * was throttled - */ - - port->State &= ~RIO_THROTTLE_RX; - - func_exit(); - return; -} - - - - - -/* ********************************************************************** * - * Here are the initialization routines. * - * ********************************************************************** */ - - -static struct vpd_prom *get_VPD_PROM(struct Host *hp) -{ - static struct vpd_prom vpdp; - char *p; - int i; - - func_enter(); - rio_dprintk(RIO_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", hp->Caddr + RIO_VPD_ROM); - - p = (char *) &vpdp; - for (i = 0; i < sizeof(struct vpd_prom); i++) - *p++ = readb(hp->Caddr + RIO_VPD_ROM + i * 2); - /* read_rio_byte (hp, RIO_VPD_ROM + i*2); */ - - /* Terminate the identifier string. - *** requires one extra byte in struct vpd_prom *** */ - *p++ = 0; - - if (rio_debug & RIO_DEBUG_PROBE) - my_hd((char *) &vpdp, 0x20); - - func_exit(); - - return &vpdp; -} - -static const struct tty_operations rio_ops = { - .open = riotopen, - .close = gs_close, - .write = gs_write, - .put_char = gs_put_char, - .flush_chars = gs_flush_chars, - .write_room = gs_write_room, - .chars_in_buffer = gs_chars_in_buffer, - .flush_buffer = gs_flush_buffer, - .ioctl = rio_ioctl, - .throttle = rio_throttle, - .unthrottle = rio_unthrottle, - .set_termios = gs_set_termios, - .stop = gs_stop, - .start = gs_start, - .hangup = gs_hangup, -}; - -static int rio_init_drivers(void) -{ - int error = -ENOMEM; - - rio_driver = alloc_tty_driver(256); - if (!rio_driver) - goto out; - rio_driver2 = alloc_tty_driver(256); - if (!rio_driver2) - goto out1; - - func_enter(); - - rio_driver->owner = THIS_MODULE; - rio_driver->driver_name = "specialix_rio"; - rio_driver->name = "ttySR"; - rio_driver->major = RIO_NORMAL_MAJOR0; - rio_driver->type = TTY_DRIVER_TYPE_SERIAL; - rio_driver->subtype = SERIAL_TYPE_NORMAL; - rio_driver->init_termios = tty_std_termios; - rio_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - rio_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(rio_driver, &rio_ops); - - rio_driver2->owner = THIS_MODULE; - rio_driver2->driver_name = "specialix_rio"; - rio_driver2->name = "ttySR"; - rio_driver2->major = RIO_NORMAL_MAJOR1; - rio_driver2->type = TTY_DRIVER_TYPE_SERIAL; - rio_driver2->subtype = SERIAL_TYPE_NORMAL; - rio_driver2->init_termios = tty_std_termios; - rio_driver2->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - rio_driver2->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(rio_driver2, &rio_ops); - - rio_dprintk(RIO_DEBUG_INIT, "set_termios = %p\n", gs_set_termios); - - if ((error = tty_register_driver(rio_driver))) - goto out2; - if ((error = tty_register_driver(rio_driver2))) - goto out3; - func_exit(); - return 0; - out3: - tty_unregister_driver(rio_driver); - out2: - put_tty_driver(rio_driver2); - out1: - put_tty_driver(rio_driver); - out: - printk(KERN_ERR "rio: Couldn't register a rio driver, error = %d\n", error); - return 1; -} - -static const struct tty_port_operations rio_port_ops = { - .carrier_raised = rio_carrier_raised, -}; - -static int rio_init_datastructures(void) -{ - int i; - struct Port *port; - func_enter(); - - /* Many drivers statically allocate the maximum number of ports - There is no reason not to allocate them dynamically. Is there? -- REW */ - /* However, the RIO driver allows users to configure their first - RTA as the ports numbered 504-511. We therefore need to allocate - the whole range. :-( -- REW */ - -#define RI_SZ sizeof(struct rio_info) -#define HOST_SZ sizeof(struct Host) -#define PORT_SZ sizeof(struct Port *) -#define TMIO_SZ sizeof(struct termios *) - rio_dprintk(RIO_DEBUG_INIT, "getting : %Zd %Zd %Zd %Zd %Zd bytes\n", RI_SZ, RIO_HOSTS * HOST_SZ, RIO_PORTS * PORT_SZ, RIO_PORTS * TMIO_SZ, RIO_PORTS * TMIO_SZ); - - if (!(p = kzalloc(RI_SZ, GFP_KERNEL))) - goto free0; - if (!(p->RIOHosts = kzalloc(RIO_HOSTS * HOST_SZ, GFP_KERNEL))) - goto free1; - if (!(p->RIOPortp = kzalloc(RIO_PORTS * PORT_SZ, GFP_KERNEL))) - goto free2; - p->RIOConf = RIOConf; - rio_dprintk(RIO_DEBUG_INIT, "Got : %p %p %p\n", p, p->RIOHosts, p->RIOPortp); - -#if 1 - for (i = 0; i < RIO_PORTS; i++) { - port = p->RIOPortp[i] = kzalloc(sizeof(struct Port), GFP_KERNEL); - if (!port) { - goto free6; - } - rio_dprintk(RIO_DEBUG_INIT, "initing port %d (%d)\n", i, port->Mapped); - tty_port_init(&port->gs.port); - port->gs.port.ops = &rio_port_ops; - port->PortNum = i; - port->gs.magic = RIO_MAGIC; - port->gs.close_delay = HZ / 2; - port->gs.closing_wait = 30 * HZ; - port->gs.rd = &rio_real_driver; - spin_lock_init(&port->portSem); - } -#else - /* We could postpone initializing them to when they are configured. */ -#endif - - - - if (rio_debug & RIO_DEBUG_INIT) { - my_hd(&rio_real_driver, sizeof(rio_real_driver)); - } - - - func_exit(); - return 0; - - free6:for (i--; i >= 0; i--) - kfree(p->RIOPortp[i]); -/*free5: - free4: - free3:*/ kfree(p->RIOPortp); - free2:kfree(p->RIOHosts); - free1: - rio_dprintk(RIO_DEBUG_INIT, "Not enough memory! %p %p %p\n", p, p->RIOHosts, p->RIOPortp); - kfree(p); - free0: - return -ENOMEM; -} - -static void __exit rio_release_drivers(void) -{ - func_enter(); - tty_unregister_driver(rio_driver2); - tty_unregister_driver(rio_driver); - put_tty_driver(rio_driver2); - put_tty_driver(rio_driver); - func_exit(); -} - - -#ifdef CONFIG_PCI - /* This was written for SX, but applies to RIO too... - (including bugs....) - - There is another bit besides Bit 17. Turning that bit off - (on boards shipped with the fix in the eeprom) results in a - hang on the next access to the card. - */ - - /******************************************************** - * Setting bit 17 in the CNTRL register of the PLX 9050 * - * chip forces a retry on writes while a read is pending.* - * This is to prevent the card locking up on Intel Xeon * - * multiprocessor systems with the NX chipset. -- NV * - ********************************************************/ - -/* Newer cards are produced with this bit set from the configuration - EEprom. As the bit is read/write for the CPU, we can fix it here, - if we detect that it isn't set correctly. -- REW */ - -static void fix_rio_pci(struct pci_dev *pdev) -{ - unsigned long hwbase; - unsigned char __iomem *rebase; - unsigned int t; - -#define CNTRL_REG_OFFSET 0x50 -#define CNTRL_REG_GOODVALUE 0x18260000 - - hwbase = pci_resource_start(pdev, 0); - rebase = ioremap(hwbase, 0x80); - t = readl(rebase + CNTRL_REG_OFFSET); - if (t != CNTRL_REG_GOODVALUE) { - printk(KERN_DEBUG "rio: performing cntrl reg fix: %08x -> %08x\n", t, CNTRL_REG_GOODVALUE); - writel(CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); - } - iounmap(rebase); -} -#endif - - -static int __init rio_init(void) -{ - int found = 0; - int i; - struct Host *hp; - int retval; - struct vpd_prom *vpdp; - int okboard; - -#ifdef CONFIG_PCI - struct pci_dev *pdev = NULL; - unsigned short tshort; -#endif - - func_enter(); - rio_dprintk(RIO_DEBUG_INIT, "Initing rio module... (rio_debug=%d)\n", rio_debug); - - if (abs((long) (&rio_debug) - rio_debug) < 0x10000) { - printk(KERN_WARNING "rio: rio_debug is an address, instead of a value. " "Assuming -1. Was %x/%p.\n", rio_debug, &rio_debug); - rio_debug = -1; - } - - if (misc_register(&rio_fw_device) < 0) { - printk(KERN_ERR "RIO: Unable to register firmware loader driver.\n"); - return -EIO; - } - - retval = rio_init_datastructures(); - if (retval < 0) { - misc_deregister(&rio_fw_device); - return retval; - } -#ifdef CONFIG_PCI - /* First look for the JET devices: */ - while ((pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, pdev))) { - u32 tint; - - if (pci_enable_device(pdev)) - continue; - - /* Specialix has a whole bunch of cards with - 0x2000 as the device ID. They say its because - the standard requires it. Stupid standard. */ - /* It seems that reading a word doesn't work reliably on 2.0. - Also, reading a non-aligned dword doesn't work. So we read the - whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID) - ourselves */ - pci_read_config_dword(pdev, 0x2c, &tint); - tshort = (tint >> 16) & 0xffff; - rio_dprintk(RIO_DEBUG_PROBE, "Got a specialix card: %x.\n", tint); - if (tshort != 0x0100) { - rio_dprintk(RIO_DEBUG_PROBE, "But it's not a RIO card (%d)...\n", tshort); - continue; - } - rio_dprintk(RIO_DEBUG_PROBE, "cp1\n"); - - hp = &p->RIOHosts[p->RIONumHosts]; - hp->PaddrP = pci_resource_start(pdev, 2); - hp->Ivec = pdev->irq; - if (((1 << hp->Ivec) & rio_irqmask) == 0) - hp->Ivec = 0; - hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); - hp->CardP = (struct DpRam __iomem *) hp->Caddr; - hp->Type = RIO_PCI; - hp->Copy = rio_copy_to_card; - hp->Mode = RIO_PCI_BOOT_FROM_RAM; - spin_lock_init(&hp->HostLock); - rio_reset_interrupt(hp); - rio_start_card_running(hp); - - rio_dprintk(RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", (void *) p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr); - if (RIOBoardTest(p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr, RIO_PCI, 0) == 0) { - rio_dprintk(RIO_DEBUG_INIT, "Done RIOBoardTest\n"); - writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); - p->RIOHosts[p->RIONumHosts].UniqueNum = - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0]) & 0xFF) << 0) | - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); - rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); - - fix_rio_pci(pdev); - - p->RIOHosts[p->RIONumHosts].pdev = pdev; - pci_dev_get(pdev); - - p->RIOLastPCISearch = 0; - p->RIONumHosts++; - found++; - } else { - iounmap(p->RIOHosts[p->RIONumHosts].Caddr); - p->RIOHosts[p->RIONumHosts].Caddr = NULL; - } - } - - /* Then look for the older PCI card.... : */ - - /* These older PCI cards have problems (only byte-mode access is - supported), which makes them a bit awkward to support. - They also have problems sharing interrupts. Be careful. - (The driver now refuses to share interrupts for these - cards. This should be sufficient). - */ - - /* Then look for the older RIO/PCI devices: */ - while ((pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_RIO, pdev))) { - if (pci_enable_device(pdev)) - continue; - -#ifdef CONFIG_RIO_OLDPCI - hp = &p->RIOHosts[p->RIONumHosts]; - hp->PaddrP = pci_resource_start(pdev, 0); - hp->Ivec = pdev->irq; - if (((1 << hp->Ivec) & rio_irqmask) == 0) - hp->Ivec = 0; - hp->Ivec |= 0x8000; /* Mark as non-sharable */ - hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); - hp->CardP = (struct DpRam __iomem *) hp->Caddr; - hp->Type = RIO_PCI; - hp->Copy = rio_copy_to_card; - hp->Mode = RIO_PCI_BOOT_FROM_RAM; - spin_lock_init(&hp->HostLock); - - rio_dprintk(RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec); - rio_dprintk(RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode); - - rio_reset_interrupt(hp); - rio_start_card_running(hp); - rio_dprintk(RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n", (void *) p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr); - if (RIOBoardTest(p->RIOHosts[p->RIONumHosts].PaddrP, p->RIOHosts[p->RIONumHosts].Caddr, RIO_PCI, 0) == 0) { - writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); - p->RIOHosts[p->RIONumHosts].UniqueNum = - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0]) & 0xFF) << 0) | - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1]) & 0xFF) << 8) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2]) & 0xFF) << 16) | ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3]) & 0xFF) << 24); - rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); - - p->RIOHosts[p->RIONumHosts].pdev = pdev; - pci_dev_get(pdev); - - p->RIOLastPCISearch = 0; - p->RIONumHosts++; - found++; - } else { - iounmap(p->RIOHosts[p->RIONumHosts].Caddr); - p->RIOHosts[p->RIONumHosts].Caddr = NULL; - } -#else - printk(KERN_ERR "Found an older RIO PCI card, but the driver is not " "compiled to support it.\n"); -#endif - } -#endif /* PCI */ - - /* Now probe for ISA cards... */ - for (i = 0; i < NR_RIO_ADDRS; i++) { - hp = &p->RIOHosts[p->RIONumHosts]; - hp->PaddrP = rio_probe_addrs[i]; - /* There was something about the IRQs of these cards. 'Forget what.--REW */ - hp->Ivec = 0; - hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN); - hp->CardP = (struct DpRam __iomem *) hp->Caddr; - hp->Type = RIO_AT; - hp->Copy = rio_copy_to_card; /* AT card PCI???? - PVDL - * -- YES! this is now a normal copy. Only the - * old PCI card uses the special PCI copy. - * Moreover, the ISA card will work with the - * special PCI copy anyway. -- REW */ - hp->Mode = 0; - spin_lock_init(&hp->HostLock); - - vpdp = get_VPD_PROM(hp); - rio_dprintk(RIO_DEBUG_PROBE, "Got VPD ROM\n"); - okboard = 0; - if ((strncmp(vpdp->identifier, RIO_ISA_IDENT, 16) == 0) || (strncmp(vpdp->identifier, RIO_ISA2_IDENT, 16) == 0) || (strncmp(vpdp->identifier, RIO_ISA3_IDENT, 16) == 0)) { - /* Board is present... */ - if (RIOBoardTest(hp->PaddrP, hp->Caddr, RIO_AT, 0) == 0) { - /* ... and feeling fine!!!! */ - rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); - if (RIOAssignAT(p, hp->PaddrP, hp->Caddr, 0)) { - rio_dprintk(RIO_DEBUG_PROBE, "Hmm Tested ok, host%d uniqid = %x.\n", p->RIONumHosts, p->RIOHosts[p->RIONumHosts - 1].UniqueNum); - okboard++; - found++; - } - } - - if (!okboard) { - iounmap(hp->Caddr); - hp->Caddr = NULL; - } - } - } - - - for (i = 0; i < p->RIONumHosts; i++) { - hp = &p->RIOHosts[i]; - if (hp->Ivec) { - int mode = IRQF_SHARED; - if (hp->Ivec & 0x8000) { - mode = 0; - hp->Ivec &= 0x7fff; - } - rio_dprintk(RIO_DEBUG_INIT, "Requesting interrupt hp: %p rio_interrupt: %d Mode: %x\n", hp, hp->Ivec, hp->Mode); - retval = request_irq(hp->Ivec, rio_interrupt, mode, "rio", hp); - rio_dprintk(RIO_DEBUG_INIT, "Return value from request_irq: %d\n", retval); - if (retval) { - printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec); - hp->Ivec = 0; - } - rio_dprintk(RIO_DEBUG_INIT, "Got irq %d.\n", hp->Ivec); - if (hp->Ivec != 0) { - rio_dprintk(RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n"); - hp->Mode |= RIO_PCI_INT_ENABLE; - } else - hp->Mode &= ~RIO_PCI_INT_ENABLE; - rio_dprintk(RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode); - rio_start_card_running(hp); - } - /* Init the timer "always" to make sure that it can safely be - deleted when we unload... */ - - setup_timer(&hp->timer, rio_pollfunc, i); - if (!hp->Ivec) { - rio_dprintk(RIO_DEBUG_INIT, "Starting polling at %dj intervals.\n", rio_poll); - mod_timer(&hp->timer, jiffies + rio_poll); - } - } - - if (found) { - rio_dprintk(RIO_DEBUG_INIT, "rio: total of %d boards detected.\n", found); - rio_init_drivers(); - } else { - /* deregister the misc device we created earlier */ - misc_deregister(&rio_fw_device); - } - - func_exit(); - return found ? 0 : -EIO; -} - - -static void __exit rio_exit(void) -{ - int i; - struct Host *hp; - - func_enter(); - - for (i = 0, hp = p->RIOHosts; i < p->RIONumHosts; i++, hp++) { - RIOHostReset(hp->Type, hp->CardP, hp->Slot); - if (hp->Ivec) { - free_irq(hp->Ivec, hp); - rio_dprintk(RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec); - } - /* It is safe/allowed to del_timer a non-active timer */ - del_timer_sync(&hp->timer); - if (hp->Caddr) - iounmap(hp->Caddr); - if (hp->Type == RIO_PCI) - pci_dev_put(hp->pdev); - } - - if (misc_deregister(&rio_fw_device) < 0) { - printk(KERN_INFO "rio: couldn't deregister control-device\n"); - } - - - rio_dprintk(RIO_DEBUG_CLEANUP, "Cleaning up drivers\n"); - - rio_release_drivers(); - - /* Release dynamically allocated memory */ - kfree(p->RIOPortp); - kfree(p->RIOHosts); - kfree(p); - - func_exit(); -} - -module_init(rio_init); -module_exit(rio_exit); diff --git a/drivers/staging/generic_serial/rio/rio_linux.h b/drivers/staging/generic_serial/rio/rio_linux.h deleted file mode 100644 index 7f26cd7c815e..000000000000 --- a/drivers/staging/generic_serial/rio/rio_linux.h +++ /dev/null @@ -1,197 +0,0 @@ - -/* - * rio_linux.h - * - * Copyright (C) 1998,1999,2000 R.E.Wolff@BitWizard.nl - * - * 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. - * - * RIO serial driver. - * - * Version 1.0 -- July, 1999. - * - */ - -#define RIO_NBOARDS 4 -#define RIO_PORTSPERBOARD 128 -#define RIO_NPORTS (RIO_NBOARDS * RIO_PORTSPERBOARD) - -#define MODEM_SUPPORT - -#ifdef __KERNEL__ - -#define RIO_MAGIC 0x12345678 - - -struct vpd_prom { - unsigned short id; - char hwrev; - char hwass; - int uniqid; - char myear; - char mweek; - char hw_feature[5]; - char oem_id; - char identifier[16]; -}; - - -#define RIO_DEBUG_ALL 0xffffffff - -#define O_OTHER(tty) \ - ((O_OLCUC(tty)) ||\ - (O_ONLCR(tty)) ||\ - (O_OCRNL(tty)) ||\ - (O_ONOCR(tty)) ||\ - (O_ONLRET(tty)) ||\ - (O_OFILL(tty)) ||\ - (O_OFDEL(tty)) ||\ - (O_NLDLY(tty)) ||\ - (O_CRDLY(tty)) ||\ - (O_TABDLY(tty)) ||\ - (O_BSDLY(tty)) ||\ - (O_VTDLY(tty)) ||\ - (O_FFDLY(tty))) - -/* Same for input. */ -#define I_OTHER(tty) \ - ((I_INLCR(tty)) ||\ - (I_IGNCR(tty)) ||\ - (I_ICRNL(tty)) ||\ - (I_IUCLC(tty)) ||\ - (L_ISIG(tty))) - - -#endif /* __KERNEL__ */ - - -#define RIO_BOARD_INTR_LOCK 1 - - -#ifndef RIOCTL_MISC_MINOR -/* Allow others to gather this into "major.h" or something like that */ -#define RIOCTL_MISC_MINOR 169 -#endif - - -/* Allow us to debug "in the field" without requiring clients to - recompile.... */ -#if 1 -#define rio_spin_lock_irqsave(sem, flags) do { \ - rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlockirqsave: %p %s:%d\n", \ - sem, __FILE__, __LINE__);\ - spin_lock_irqsave(sem, flags);\ - } while (0) - -#define rio_spin_unlock_irqrestore(sem, flags) do { \ - rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlockirqrestore: %p %s:%d\n",\ - sem, __FILE__, __LINE__);\ - spin_unlock_irqrestore(sem, flags);\ - } while (0) - -#define rio_spin_lock(sem) do { \ - rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlock: %p %s:%d\n",\ - sem, __FILE__, __LINE__);\ - spin_lock(sem);\ - } while (0) - -#define rio_spin_unlock(sem) do { \ - rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlock: %p %s:%d\n",\ - sem, __FILE__, __LINE__);\ - spin_unlock(sem);\ - } while (0) -#else -#define rio_spin_lock_irqsave(sem, flags) \ - spin_lock_irqsave(sem, flags) - -#define rio_spin_unlock_irqrestore(sem, flags) \ - spin_unlock_irqrestore(sem, flags) - -#define rio_spin_lock(sem) \ - spin_lock(sem) - -#define rio_spin_unlock(sem) \ - spin_unlock(sem) - -#endif - - - -#ifdef CONFIG_RIO_OLDPCI -static inline void __iomem *rio_memcpy_toio(void __iomem *dummy, void __iomem *dest, void *source, int n) -{ - char __iomem *dst = dest; - char *src = source; - - while (n--) { - writeb(*src++, dst++); - (void) readb(dummy); - } - - return dest; -} - -static inline void __iomem *rio_copy_toio(void __iomem *dest, void *source, int n) -{ - char __iomem *dst = dest; - char *src = source; - - while (n--) - writeb(*src++, dst++); - - return dest; -} - - -static inline void *rio_memcpy_fromio(void *dest, void __iomem *source, int n) -{ - char *dst = dest; - char __iomem *src = source; - - while (n--) - *dst++ = readb(src++); - - return dest; -} - -#else -#define rio_memcpy_toio(dummy,dest,source,n) memcpy_toio(dest, source, n) -#define rio_copy_toio memcpy_toio -#define rio_memcpy_fromio memcpy_fromio -#endif - -#define DEBUG 1 - - -/* - This driver can spew a whole lot of debugging output at you. If you - need maximum performance, you should disable the DEBUG define. To - aid in debugging in the field, I'm leaving the compile-time debug - features enabled, and disable them "runtime". That allows me to - instruct people with problems to enable debugging without requiring - them to recompile... -*/ - -#ifdef DEBUG -#define rio_dprintk(f, str...) do { if (rio_debug & f) printk (str);} while (0) -#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s\n", __func__) -#define func_exit() rio_dprintk (RIO_DEBUG_FLOW, "rio: exit %s\n", __func__) -#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter %s (port %d)\n",__func__, port->line) -#else -#define rio_dprintk(f, str...) /* nothing */ -#define func_enter() -#define func_exit() -#define func_enter2() -#endif diff --git a/drivers/staging/generic_serial/rio/rioboard.h b/drivers/staging/generic_serial/rio/rioboard.h deleted file mode 100644 index 252230043c82..000000000000 --- a/drivers/staging/generic_serial/rio/rioboard.h +++ /dev/null @@ -1,275 +0,0 @@ -/************************************************************************/ -/* */ -/* Title : RIO Host Card Hardware Definitions */ -/* */ -/* Author : N.P.Vassallo */ -/* */ -/* Creation : 26th April 1999 */ -/* */ -/* Version : 1.0.0 */ -/* */ -/* Copyright : (c) Specialix International Ltd. 1999 * - * - * 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. - * */ -/* Description : Prototypes, structures and definitions */ -/* describing the RIO board hardware */ -/* */ -/************************************************************************/ - -#ifndef _rioboard_h /* If RIOBOARD.H not already defined */ -#define _rioboard_h 1 - -/***************************************************************************** -*********************** *********************** -*********************** Hardware Control Registers *********************** -*********************** *********************** -*****************************************************************************/ - -/* Hardware Registers... */ - -#define RIO_REG_BASE 0x7C00 /* Base of control registers */ - -#define RIO_CONFIG RIO_REG_BASE + 0x0000 /* WRITE: Configuration Register */ -#define RIO_INTSET RIO_REG_BASE + 0x0080 /* WRITE: Interrupt Set */ -#define RIO_RESET RIO_REG_BASE + 0x0100 /* WRITE: Host Reset */ -#define RIO_INTRESET RIO_REG_BASE + 0x0180 /* WRITE: Interrupt Reset */ - -#define RIO_VPD_ROM RIO_REG_BASE + 0x0000 /* READ: Vital Product Data ROM */ -#define RIO_INTSTAT RIO_REG_BASE + 0x0080 /* READ: Interrupt Status (Jet boards only) */ -#define RIO_RESETSTAT RIO_REG_BASE + 0x0100 /* READ: Reset Status (Jet boards only) */ - -/* RIO_VPD_ROM definitions... */ -#define VPD_SLX_ID1 0x00 /* READ: Specialix Identifier #1 */ -#define VPD_SLX_ID2 0x01 /* READ: Specialix Identifier #2 */ -#define VPD_HW_REV 0x02 /* READ: Hardware Revision */ -#define VPD_HW_ASSEM 0x03 /* READ: Hardware Assembly Level */ -#define VPD_UNIQUEID4 0x04 /* READ: Unique Identifier #4 */ -#define VPD_UNIQUEID3 0x05 /* READ: Unique Identifier #3 */ -#define VPD_UNIQUEID2 0x06 /* READ: Unique Identifier #2 */ -#define VPD_UNIQUEID1 0x07 /* READ: Unique Identifier #1 */ -#define VPD_MANU_YEAR 0x08 /* READ: Year Of Manufacture (0 = 1970) */ -#define VPD_MANU_WEEK 0x09 /* READ: Week Of Manufacture (0 = week 1 Jan) */ -#define VPD_HWFEATURE1 0x0A /* READ: Hardware Feature Byte 1 */ -#define VPD_HWFEATURE2 0x0B /* READ: Hardware Feature Byte 2 */ -#define VPD_HWFEATURE3 0x0C /* READ: Hardware Feature Byte 3 */ -#define VPD_HWFEATURE4 0x0D /* READ: Hardware Feature Byte 4 */ -#define VPD_HWFEATURE5 0x0E /* READ: Hardware Feature Byte 5 */ -#define VPD_OEMID 0x0F /* READ: OEM Identifier */ -#define VPD_IDENT 0x10 /* READ: Identifier string (16 bytes) */ -#define VPD_IDENT_LEN 0x10 - -/* VPD ROM Definitions... */ -#define SLX_ID1 0x4D -#define SLX_ID2 0x98 - -#define PRODUCT_ID(a) ((a>>4)&0xF) /* Use to obtain Product ID from VPD_UNIQUEID1 */ - -#define ID_SX_ISA 0x2 -#define ID_RIO_EISA 0x3 -#define ID_SX_PCI 0x5 -#define ID_SX_EISA 0x7 -#define ID_RIO_RTA16 0x9 -#define ID_RIO_ISA 0xA -#define ID_RIO_MCA 0xB -#define ID_RIO_SBUS 0xC -#define ID_RIO_PCI 0xD -#define ID_RIO_RTA8 0xE - -/* Transputer bootstrap definitions... */ - -#define BOOTLOADADDR (0x8000 - 6) -#define BOOTINDICATE (0x8000 - 2) - -/* Firmware load position... */ - -#define FIRMWARELOADADDR 0x7C00 /* Firmware is loaded _before_ this address */ - -/***************************************************************************** -***************************** ***************************** -***************************** RIO (Rev1) ISA ***************************** -***************************** ***************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_ISA_IDENT "JBJGPGGHINSMJPJR" - -#define RIO_ISA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ -#define RIO_ISA_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_ISA_CFG_IRQMASK 0x30 /* Interrupt mask */ -#define RIO_ISA_CFG_IRQ12 0x10 /* Interrupt Level 12 */ -#define RIO_ISA_CFG_IRQ11 0x20 /* Interrupt Level 11 */ -#define RIO_ISA_CFG_IRQ9 0x30 /* Interrupt Level 9 */ -#define RIO_ISA_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ -#define RIO_ISA_CFG_WAITSTATE0 0x80 /* 0 waitstates, else 1 */ - -/***************************************************************************** -***************************** ***************************** -***************************** RIO (Rev2) ISA ***************************** -***************************** ***************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_ISA2_IDENT "JBJGPGGHINSMJPJR" - -#define RIO_ISA2_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ -#define RIO_ISA2_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_ISA2_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ -#define RIO_ISA2_CFG_16BIT 0x08 /* 16bit mode, else 8bit */ -#define RIO_ISA2_CFG_IRQMASK 0x30 /* Interrupt mask */ -#define RIO_ISA2_CFG_IRQ15 0x00 /* Interrupt Level 15 */ -#define RIO_ISA2_CFG_IRQ12 0x10 /* Interrupt Level 12 */ -#define RIO_ISA2_CFG_IRQ11 0x20 /* Interrupt Level 11 */ -#define RIO_ISA2_CFG_IRQ9 0x30 /* Interrupt Level 9 */ -#define RIO_ISA2_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ -#define RIO_ISA2_CFG_WAITSTATE0 0x80 /* 0 waitstates, else 1 */ - -/***************************************************************************** -***************************** ****************************** -***************************** RIO (Jet) ISA ****************************** -***************************** ****************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_ISA3_IDENT "JET HOST BY KEV#" - -#define RIO_ISA3_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_ISA3_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ -#define RIO_ISA32_CFG_IRQMASK 0xF30 /* Interrupt mask */ -#define RIO_ISA3_CFG_IRQ15 0xF0 /* Interrupt Level 15 */ -#define RIO_ISA3_CFG_IRQ12 0xC0 /* Interrupt Level 12 */ -#define RIO_ISA3_CFG_IRQ11 0xB0 /* Interrupt Level 11 */ -#define RIO_ISA3_CFG_IRQ10 0xA0 /* Interrupt Level 10 */ -#define RIO_ISA3_CFG_IRQ9 0x90 /* Interrupt Level 9 */ - -/***************************************************************************** -********************************* ******************************** -********************************* RIO MCA ******************************** -********************************* ******************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_MCA_IDENT "JBJGPGGHINSMJPJR" - -#define RIO_MCA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ -#define RIO_MCA_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_MCA_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ - -/***************************************************************************** -******************************** ******************************** -******************************** RIO EISA ******************************** -******************************** ******************************** -*****************************************************************************/ - -/* EISA Configuration Space Definitions... */ -#define EISA_PRODUCT_ID1 0xC80 -#define EISA_PRODUCT_ID2 0xC81 -#define EISA_PRODUCT_NUMBER 0xC82 -#define EISA_REVISION_NUMBER 0xC83 -#define EISA_CARD_ENABLE 0xC84 -#define EISA_VPD_UNIQUEID4 0xC88 /* READ: Unique Identifier #4 */ -#define EISA_VPD_UNIQUEID3 0xC8A /* READ: Unique Identifier #3 */ -#define EISA_VPD_UNIQUEID2 0xC90 /* READ: Unique Identifier #2 */ -#define EISA_VPD_UNIQUEID1 0xC92 /* READ: Unique Identifier #1 */ -#define EISA_VPD_MANU_YEAR 0xC98 /* READ: Year Of Manufacture (0 = 1970) */ -#define EISA_VPD_MANU_WEEK 0xC9A /* READ: Week Of Manufacture (0 = week 1 Jan) */ -#define EISA_MEM_ADDR_23_16 0xC00 -#define EISA_MEM_ADDR_31_24 0xC01 -#define EISA_RIO_CONFIG 0xC02 /* WRITE: Configuration Register */ -#define EISA_RIO_INTSET 0xC03 /* WRITE: Interrupt Set */ -#define EISA_RIO_INTRESET 0xC03 /* READ: Interrupt Reset */ - -/* Control Register Definitions... */ -#define RIO_EISA_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ -#define RIO_EISA_CFG_LINK20 0x02 /* 20Mbps link, else 10Mbps */ -#define RIO_EISA_CFG_BUSENABLE 0x04 /* Enable processor bus */ -#define RIO_EISA_CFG_PROCRUN 0x08 /* Processor running, else reset */ -#define RIO_EISA_CFG_IRQMASK 0xF0 /* Interrupt mask */ -#define RIO_EISA_CFG_IRQ15 0xF0 /* Interrupt Level 15 */ -#define RIO_EISA_CFG_IRQ14 0xE0 /* Interrupt Level 14 */ -#define RIO_EISA_CFG_IRQ12 0xC0 /* Interrupt Level 12 */ -#define RIO_EISA_CFG_IRQ11 0xB0 /* Interrupt Level 11 */ -#define RIO_EISA_CFG_IRQ10 0xA0 /* Interrupt Level 10 */ -#define RIO_EISA_CFG_IRQ9 0x90 /* Interrupt Level 9 */ -#define RIO_EISA_CFG_IRQ7 0x70 /* Interrupt Level 7 */ -#define RIO_EISA_CFG_IRQ6 0x60 /* Interrupt Level 6 */ -#define RIO_EISA_CFG_IRQ5 0x50 /* Interrupt Level 5 */ -#define RIO_EISA_CFG_IRQ4 0x40 /* Interrupt Level 4 */ -#define RIO_EISA_CFG_IRQ3 0x30 /* Interrupt Level 3 */ - -/***************************************************************************** -******************************** ******************************** -******************************** RIO SBus ******************************** -******************************** ******************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_SBUS_IDENT "JBPGK#\0\0\0\0\0\0\0\0\0\0" - -#define RIO_SBUS_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ -#define RIO_SBUS_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_SBUS_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ -#define RIO_SBUS_CFG_IRQMASK 0x38 /* Interrupt mask */ -#define RIO_SBUS_CFG_IRQNONE 0x00 /* No Interrupt */ -#define RIO_SBUS_CFG_IRQ7 0x38 /* Interrupt Level 7 */ -#define RIO_SBUS_CFG_IRQ6 0x30 /* Interrupt Level 6 */ -#define RIO_SBUS_CFG_IRQ5 0x28 /* Interrupt Level 5 */ -#define RIO_SBUS_CFG_IRQ4 0x20 /* Interrupt Level 4 */ -#define RIO_SBUS_CFG_IRQ3 0x18 /* Interrupt Level 3 */ -#define RIO_SBUS_CFG_IRQ2 0x10 /* Interrupt Level 2 */ -#define RIO_SBUS_CFG_IRQ1 0x08 /* Interrupt Level 1 */ -#define RIO_SBUS_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ -#define RIO_SBUS_CFG_PROC25 0x80 /* 25Mhz processor clock, else 20Mhz */ - -/***************************************************************************** -********************************* ******************************** -********************************* RIO PCI ******************************** -********************************* ******************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_PCI_IDENT "ECDDPGJGJHJRGSK#" - -#define RIO_PCI_CFG_BOOTRAM 0x01 /* Boot from RAM, else Link */ -#define RIO_PCI_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_PCI_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ -#define RIO_PCI_CFG_LINK20 0x40 /* 20Mbps link, else 10Mbps */ -#define RIO_PCI_CFG_PROC25 0x80 /* 25Mhz processor clock, else 20Mhz */ - -/* PCI Definitions... */ -#define SPX_VENDOR_ID 0x11CB /* Assigned by the PCI SIG */ -#define SPX_DEVICE_ID 0x8000 /* RIO bridge boards */ -#define SPX_PLXDEVICE_ID 0x2000 /* PLX bridge boards */ -#define SPX_SUB_VENDOR_ID SPX_VENDOR_ID /* Same as vendor id */ -#define RIO_SUB_SYS_ID 0x0800 /* RIO PCI board */ - -/***************************************************************************** -***************************** ****************************** -***************************** RIO (Jet) PCI ****************************** -***************************** ****************************** -*****************************************************************************/ - -/* Control Register Definitions... */ -#define RIO_PCI2_IDENT "JET HOST BY KEV#" - -#define RIO_PCI2_CFG_BUSENABLE 0x02 /* Enable processor bus */ -#define RIO_PCI2_CFG_INTENABLE 0x04 /* Interrupt enable, else disable */ - -/* PCI Definitions... */ -#define RIO2_SUB_SYS_ID 0x0100 /* RIO (Jet) PCI board */ - -#endif /*_rioboard_h */ - -/* End of RIOBOARD.H */ diff --git a/drivers/staging/generic_serial/rio/rioboot.c b/drivers/staging/generic_serial/rio/rioboot.c deleted file mode 100644 index ffa01c590216..000000000000 --- a/drivers/staging/generic_serial/rio/rioboot.c +++ /dev/null @@ -1,1113 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : rioboot.c -** SID : 1.3 -** Last Modified : 11/6/98 10:33:36 -** Retrieved : 11/6/98 10:33:48 -** -** ident @(#)rioboot.c 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" - -static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP); - -static const unsigned char RIOAtVec2Ctrl[] = { - /* 0 */ INTERRUPT_DISABLE, - /* 1 */ INTERRUPT_DISABLE, - /* 2 */ INTERRUPT_DISABLE, - /* 3 */ INTERRUPT_DISABLE, - /* 4 */ INTERRUPT_DISABLE, - /* 5 */ INTERRUPT_DISABLE, - /* 6 */ INTERRUPT_DISABLE, - /* 7 */ INTERRUPT_DISABLE, - /* 8 */ INTERRUPT_DISABLE, - /* 9 */ IRQ_9 | INTERRUPT_ENABLE, - /* 10 */ INTERRUPT_DISABLE, - /* 11 */ IRQ_11 | INTERRUPT_ENABLE, - /* 12 */ IRQ_12 | INTERRUPT_ENABLE, - /* 13 */ INTERRUPT_DISABLE, - /* 14 */ INTERRUPT_DISABLE, - /* 15 */ IRQ_15 | INTERRUPT_ENABLE -}; - -/** - * RIOBootCodeRTA - Load RTA boot code - * @p: RIO to load - * @rbp: Download descriptor - * - * Called when the user process initiates booting of the card firmware. - * Lads the firmware - */ - -int RIOBootCodeRTA(struct rio_info *p, struct DownLoad * rbp) -{ - int offset; - - func_enter(); - - rio_dprintk(RIO_DEBUG_BOOT, "Data at user address %p\n", rbp->DataP); - - /* - ** Check that we have set aside enough memory for this - */ - if (rbp->Count > SIXTY_FOUR_K) { - rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n"); - p->RIOError.Error = HOST_FILE_TOO_LARGE; - func_exit(); - return -ENOMEM; - } - - if (p->RIOBooting) { - rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot Code : BUSY BUSY BUSY!\n"); - p->RIOError.Error = BOOT_IN_PROGRESS; - func_exit(); - return -EBUSY; - } - - /* - ** The data we load in must end on a (RTA_BOOT_DATA_SIZE) byte boundary, - ** so calculate how far we have to move the data up the buffer - ** to achieve this. - */ - offset = (RTA_BOOT_DATA_SIZE - (rbp->Count % RTA_BOOT_DATA_SIZE)) % RTA_BOOT_DATA_SIZE; - - /* - ** Be clean, and clear the 'unused' portion of the boot buffer, - ** because it will (eventually) be part of the Rta run time environment - ** and so should be zeroed. - */ - memset(p->RIOBootPackets, 0, offset); - - /* - ** Copy the data from user space into the array - */ - - if (copy_from_user(((u8 *)p->RIOBootPackets) + offset, rbp->DataP, rbp->Count)) { - rio_dprintk(RIO_DEBUG_BOOT, "Bad data copy from user space\n"); - p->RIOError.Error = COPYIN_FAILED; - func_exit(); - return -EFAULT; - } - - /* - ** Make sure that our copy of the size includes that offset we discussed - ** earlier. - */ - p->RIONumBootPkts = (rbp->Count + offset) / RTA_BOOT_DATA_SIZE; - p->RIOBootCount = rbp->Count; - - func_exit(); - return 0; -} - -/** - * rio_start_card_running - host card start - * @HostP: The RIO to kick off - * - * Start a RIO processor unit running. Encapsulates the knowledge - * of the card type. - */ - -void rio_start_card_running(struct Host *HostP) -{ - switch (HostP->Type) { - case RIO_AT: - rio_dprintk(RIO_DEBUG_BOOT, "Start ISA card running\n"); - writeb(BOOT_FROM_RAM | EXTERNAL_BUS_ON | HostP->Mode | RIOAtVec2Ctrl[HostP->Ivec & 0xF], &HostP->Control); - break; - case RIO_PCI: - /* - ** PCI is much the same as MCA. Everything is once again memory - ** mapped, so we are writing to memory registers instead of io - ** ports. - */ - rio_dprintk(RIO_DEBUG_BOOT, "Start PCI card running\n"); - writeb(PCITpBootFromRam | PCITpBusEnable | HostP->Mode, &HostP->Control); - break; - default: - rio_dprintk(RIO_DEBUG_BOOT, "Unknown host type %d\n", HostP->Type); - break; - } - return; -} - -/* -** Load in the host boot code - load it directly onto all halted hosts -** of the correct type. -** -** Put your rubber pants on before messing with this code - even the magic -** numbers have trouble understanding what they are doing here. -*/ - -int RIOBootCodeHOST(struct rio_info *p, struct DownLoad *rbp) -{ - struct Host *HostP; - u8 __iomem *Cad; - PARM_MAP __iomem *ParmMapP; - int RupN; - int PortN; - unsigned int host; - u8 __iomem *StartP; - u8 __iomem *DestP; - int wait_count; - u16 OldParmMap; - u16 offset; /* It is very important that this is a u16 */ - u8 *DownCode = NULL; - unsigned long flags; - - HostP = NULL; /* Assure the compiler we've initialized it */ - - - /* Walk the hosts */ - for (host = 0; host < p->RIONumHosts; host++) { - rio_dprintk(RIO_DEBUG_BOOT, "Attempt to boot host %d\n", host); - HostP = &p->RIOHosts[host]; - - rio_dprintk(RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", HostP->Type, HostP->Mode, HostP->Ivec); - - /* Don't boot hosts already running */ - if ((HostP->Flags & RUN_STATE) != RC_WAITING) { - rio_dprintk(RIO_DEBUG_BOOT, "%s %d already running\n", "Host", host); - continue; - } - - /* - ** Grab a pointer to the card (ioremapped) - */ - Cad = HostP->Caddr; - - /* - ** We are going to (try) and load in rbp->Count bytes. - ** The last byte will reside at p->RIOConf.HostLoadBase-1; - ** Therefore, we need to start copying at address - ** (caddr+p->RIOConf.HostLoadBase-rbp->Count) - */ - StartP = &Cad[p->RIOConf.HostLoadBase - rbp->Count]; - - rio_dprintk(RIO_DEBUG_BOOT, "kernel virtual address for host is %p\n", Cad); - rio_dprintk(RIO_DEBUG_BOOT, "kernel virtual address for download is %p\n", StartP); - rio_dprintk(RIO_DEBUG_BOOT, "host loadbase is 0x%x\n", p->RIOConf.HostLoadBase); - rio_dprintk(RIO_DEBUG_BOOT, "size of download is 0x%x\n", rbp->Count); - - /* Make sure it fits */ - if (p->RIOConf.HostLoadBase < rbp->Count) { - rio_dprintk(RIO_DEBUG_BOOT, "Bin too large\n"); - p->RIOError.Error = HOST_FILE_TOO_LARGE; - func_exit(); - return -EFBIG; - } - /* - ** Ensure that the host really is stopped. - ** Disable it's external bus & twang its reset line. - */ - RIOHostReset(HostP->Type, HostP->CardP, HostP->Slot); - - /* - ** Copy the data directly from user space to the SRAM. - ** This ain't going to be none too clever if the download - ** code is bigger than this segment. - */ - rio_dprintk(RIO_DEBUG_BOOT, "Copy in code\n"); - - /* Buffer to local memory as we want to use I/O space and - some cards only do 8 or 16 bit I/O */ - - DownCode = vmalloc(rbp->Count); - if (!DownCode) { - p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY; - func_exit(); - return -ENOMEM; - } - if (copy_from_user(DownCode, rbp->DataP, rbp->Count)) { - kfree(DownCode); - p->RIOError.Error = COPYIN_FAILED; - func_exit(); - return -EFAULT; - } - HostP->Copy(DownCode, StartP, rbp->Count); - vfree(DownCode); - - rio_dprintk(RIO_DEBUG_BOOT, "Copy completed\n"); - - /* - ** S T O P ! - ** - ** Up to this point the code has been fairly rational, and possibly - ** even straight forward. What follows is a pile of crud that will - ** magically turn into six bytes of transputer assembler. Normally - ** you would expect an array or something, but, being me, I have - ** chosen [been told] to use a technique whereby the startup code - ** will be correct if we change the loadbase for the code. Which - ** brings us onto another issue - the loadbase is the *end* of the - ** code, not the start. - ** - ** If I were you I wouldn't start from here. - */ - - /* - ** We now need to insert a short boot section into - ** the memory at the end of Sram2. This is normally (de)composed - ** of the last eight bytes of the download code. The - ** download has been assembled/compiled to expect to be - ** loaded from 0x7FFF downwards. We have loaded it - ** at some other address. The startup code goes into the small - ** ram window at Sram2, in the last 8 bytes, which are really - ** at addresses 0x7FF8-0x7FFF. - ** - ** If the loadbase is, say, 0x7C00, then we need to branch to - ** address 0x7BFE to run the host.bin startup code. We assemble - ** this jump manually. - ** - ** The two byte sequence 60 08 is loaded into memory at address - ** 0x7FFE,F. This is a local branch to location 0x7FF8 (60 is nfix 0, - ** which adds '0' to the .O register, complements .O, and then shifts - ** it left by 4 bit positions, 08 is a jump .O+8 instruction. This will - ** add 8 to .O (which was 0xFFF0), and will branch RELATIVE to the new - ** location. Now, the branch starts from the value of .PC (or .IP or - ** whatever the bloody register is called on this chip), and the .PC - ** will be pointing to the location AFTER the branch, in this case - ** .PC == 0x8000, so the branch will be to 0x8000+0xFFF8 = 0x7FF8. - ** - ** A long branch is coded at 0x7FF8. This consists of loading a four - ** byte offset into .O using nfix (as above) and pfix operators. The - ** pfix operates in exactly the same way as the nfix operator, but - ** without the complement operation. The offset, of course, must be - ** relative to the address of the byte AFTER the branch instruction, - ** which will be (urm) 0x7FFC, so, our final destination of the branch - ** (loadbase-2), has to be reached from here. Imagine that the loadbase - ** is 0x7C00 (which it is), then we will need to branch to 0x7BFE (which - ** is the first byte of the initial two byte short local branch of the - ** download code). - ** - ** To code a jump from 0x7FFC (which is where the branch will start - ** from) to 0x7BFE, we will need to branch 0xFC02 bytes (0x7FFC+0xFC02)= - ** 0x7BFE. - ** This will be coded as four bytes: - ** 60 2C 20 02 - ** being nfix .O+0 - ** pfix .O+C - ** pfix .O+0 - ** jump .O+2 - ** - ** The nfix operator is used, so that the startup code will be - ** compatible with the whole Tp family. (lies, damn lies, it'll never - ** work in a month of Sundays). - ** - ** The nfix nyble is the 1s complement of the nyble value you - ** want to load - in this case we wanted 'F' so we nfix loaded '0'. - */ - - - /* - ** Dest points to the top 8 bytes of Sram2. The Tp jumps - ** to 0x7FFE at reset time, and starts executing. This is - ** a short branch to 0x7FF8, where a long branch is coded. - */ - - DestP = &Cad[0x7FF8]; /* <<<---- READ THE ABOVE COMMENTS */ - -#define NFIX(N) (0x60 | (N)) /* .O = (~(.O + N))<<4 */ -#define PFIX(N) (0x20 | (N)) /* .O = (.O + N)<<4 */ -#define JUMP(N) (0x00 | (N)) /* .PC = .PC + .O */ - - /* - ** 0x7FFC is the address of the location following the last byte of - ** the four byte jump instruction. - ** READ THE ABOVE COMMENTS - ** - ** offset is (TO-FROM) % MEMSIZE, but with compound buggering about. - ** Memsize is 64K for this range of Tp, so offset is a short (unsigned, - ** cos I don't understand 2's complement). - */ - offset = (p->RIOConf.HostLoadBase - 2) - 0x7FFC; - - writeb(NFIX(((unsigned short) (~offset) >> (unsigned short) 12) & 0xF), DestP); - writeb(PFIX((offset >> 8) & 0xF), DestP + 1); - writeb(PFIX((offset >> 4) & 0xF), DestP + 2); - writeb(JUMP(offset & 0xF), DestP + 3); - - writeb(NFIX(0), DestP + 6); - writeb(JUMP(8), DestP + 7); - - rio_dprintk(RIO_DEBUG_BOOT, "host loadbase is 0x%x\n", p->RIOConf.HostLoadBase); - rio_dprintk(RIO_DEBUG_BOOT, "startup offset is 0x%x\n", offset); - - /* - ** Flag what is going on - */ - HostP->Flags &= ~RUN_STATE; - HostP->Flags |= RC_STARTUP; - - /* - ** Grab a copy of the current ParmMap pointer, so we - ** can tell when it has changed. - */ - OldParmMap = readw(&HostP->__ParmMapR); - - rio_dprintk(RIO_DEBUG_BOOT, "Original parmmap is 0x%x\n", OldParmMap); - - /* - ** And start it running (I hope). - ** As there is nothing dodgy or obscure about the - ** above code, this is guaranteed to work every time. - */ - rio_dprintk(RIO_DEBUG_BOOT, "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n", HostP->Type, HostP->Mode, HostP->Ivec); - - rio_start_card_running(HostP); - - rio_dprintk(RIO_DEBUG_BOOT, "Set control port\n"); - - /* - ** Now, wait for up to five seconds for the Tp to setup the parmmap - ** pointer: - */ - for (wait_count = 0; (wait_count < p->RIOConf.StartupTime) && (readw(&HostP->__ParmMapR) == OldParmMap); wait_count++) { - rio_dprintk(RIO_DEBUG_BOOT, "Checkout %d, 0x%x\n", wait_count, readw(&HostP->__ParmMapR)); - mdelay(100); - - } - - /* - ** If the parmmap pointer is unchanged, then the host code - ** has crashed & burned in a really spectacular way - */ - if (readw(&HostP->__ParmMapR) == OldParmMap) { - rio_dprintk(RIO_DEBUG_BOOT, "parmmap 0x%x\n", readw(&HostP->__ParmMapR)); - rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n"); - HostP->Flags &= ~RUN_STATE; - HostP->Flags |= RC_STUFFED; - RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot ); - continue; - } - - rio_dprintk(RIO_DEBUG_BOOT, "Running 0x%x\n", readw(&HostP->__ParmMapR)); - - /* - ** Well, the board thought it was OK, and setup its parmmap - ** pointer. For the time being, we will pretend that this - ** board is running, and check out what the error flag says. - */ - - /* - ** Grab a 32 bit pointer to the parmmap structure - */ - ParmMapP = (PARM_MAP __iomem *) RIO_PTR(Cad, readw(&HostP->__ParmMapR)); - rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP); - ParmMapP = (PARM_MAP __iomem *)(Cad + readw(&HostP->__ParmMapR)); - rio_dprintk(RIO_DEBUG_BOOT, "ParmMapP : %p\n", ParmMapP); - - /* - ** The links entry should be 0xFFFF; we set it up - ** with a mask to say how many PHBs to use, and - ** which links to use. - */ - if (readw(&ParmMapP->links) != 0xFFFF) { - rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); - rio_dprintk(RIO_DEBUG_BOOT, "Links = 0x%x\n", readw(&ParmMapP->links)); - HostP->Flags &= ~RUN_STATE; - HostP->Flags |= RC_STUFFED; - RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot ); - continue; - } - - writew(RIO_LINK_ENABLE, &ParmMapP->links); - - /* - ** now wait for the card to set all the parmmap->XXX stuff - ** this is a wait of up to two seconds.... - */ - rio_dprintk(RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n", p->RIOConf.StartupTime); - HostP->timeout_id = 0; - for (wait_count = 0; (wait_count < p->RIOConf.StartupTime) && !readw(&ParmMapP->init_done); wait_count++) { - rio_dprintk(RIO_DEBUG_BOOT, "Waiting for init_done\n"); - mdelay(100); - } - rio_dprintk(RIO_DEBUG_BOOT, "OK! init_done!\n"); - - if (readw(&ParmMapP->error) != E_NO_ERROR || !readw(&ParmMapP->init_done)) { - rio_dprintk(RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name); - rio_dprintk(RIO_DEBUG_BOOT, "Timedout waiting for init_done\n"); - HostP->Flags &= ~RUN_STATE; - HostP->Flags |= RC_STUFFED; - RIOHostReset( HostP->Type, HostP->CardP, HostP->Slot ); - continue; - } - - rio_dprintk(RIO_DEBUG_BOOT, "Got init_done\n"); - - /* - ** It runs! It runs! - */ - rio_dprintk(RIO_DEBUG_BOOT, "Host ID %x Running\n", HostP->UniqueNum); - - /* - ** set the time period between interrupts. - */ - writew(p->RIOConf.Timer, &ParmMapP->timer); - - /* - ** Translate all the 16 bit pointers in the __ParmMapR into - ** 32 bit pointers for the driver in ioremap space. - */ - HostP->ParmMapP = ParmMapP; - HostP->PhbP = (struct PHB __iomem *) RIO_PTR(Cad, readw(&ParmMapP->phb_ptr)); - HostP->RupP = (struct RUP __iomem *) RIO_PTR(Cad, readw(&ParmMapP->rups)); - HostP->PhbNumP = (unsigned short __iomem *) RIO_PTR(Cad, readw(&ParmMapP->phb_num_ptr)); - HostP->LinkStrP = (struct LPB __iomem *) RIO_PTR(Cad, readw(&ParmMapP->link_str_ptr)); - - /* - ** point the UnixRups at the real Rups - */ - for (RupN = 0; RupN < MAX_RUP; RupN++) { - HostP->UnixRups[RupN].RupP = &HostP->RupP[RupN]; - HostP->UnixRups[RupN].Id = RupN + 1; - HostP->UnixRups[RupN].BaseSysPort = NO_PORT; - spin_lock_init(&HostP->UnixRups[RupN].RupLock); - } - - for (RupN = 0; RupN < LINKS_PER_UNIT; RupN++) { - HostP->UnixRups[RupN + MAX_RUP].RupP = &HostP->LinkStrP[RupN].rup; - HostP->UnixRups[RupN + MAX_RUP].Id = 0; - HostP->UnixRups[RupN + MAX_RUP].BaseSysPort = NO_PORT; - spin_lock_init(&HostP->UnixRups[RupN + MAX_RUP].RupLock); - } - - /* - ** point the PortP->Phbs at the real Phbs - */ - for (PortN = p->RIOFirstPortsMapped; PortN < p->RIOLastPortsMapped + PORTS_PER_RTA; PortN++) { - if (p->RIOPortp[PortN]->HostP == HostP) { - struct Port *PortP = p->RIOPortp[PortN]; - struct PHB __iomem *PhbP; - /* int oldspl; */ - - if (!PortP->Mapped) - continue; - - PhbP = &HostP->PhbP[PortP->HostPort]; - rio_spin_lock_irqsave(&PortP->portSem, flags); - - PortP->PhbP = PhbP; - - PortP->TxAdd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_add)); - PortP->TxStart = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_start)); - PortP->TxEnd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->tx_end)); - PortP->RxRemove = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_remove)); - PortP->RxStart = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_start)); - PortP->RxEnd = (u16 __iomem *) RIO_PTR(Cad, readw(&PhbP->rx_end)); - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - /* - ** point the UnixRup at the base SysPort - */ - if (!(PortN % PORTS_PER_RTA)) - HostP->UnixRups[PortP->RupNum].BaseSysPort = PortN; - } - } - - rio_dprintk(RIO_DEBUG_BOOT, "Set the card running... \n"); - /* - ** last thing - show the world that everything is in place - */ - HostP->Flags &= ~RUN_STATE; - HostP->Flags |= RC_RUNNING; - } - /* - ** MPX always uses a poller. This is actually patched into the system - ** configuration and called directly from each clock tick. - ** - */ - p->RIOPolling = 1; - - p->RIOSystemUp++; - - rio_dprintk(RIO_DEBUG_BOOT, "Done everything %x\n", HostP->Ivec); - func_exit(); - return 0; -} - - - -/** - * RIOBootRup - Boot an RTA - * @p: rio we are working with - * @Rup: Rup number - * @HostP: host object - * @PacketP: packet to use - * - * If we have successfully processed this boot, then - * return 1. If we havent, then return 0. - */ - -int RIOBootRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem *PacketP) -{ - struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data; - struct PktCmd_M *PktReplyP; - struct CmdBlk *CmdBlkP; - unsigned int sequence; - - /* - ** If we haven't been told what to boot, we can't boot it. - */ - if (p->RIONumBootPkts == 0) { - rio_dprintk(RIO_DEBUG_BOOT, "No RTA code to download yet\n"); - return 0; - } - - /* - ** Special case of boot completed - if we get one of these then we - ** don't need a command block. For all other cases we do, so handle - ** this first and then get a command block, then handle every other - ** case, relinquishing the command block if disaster strikes! - */ - if ((readb(&PacketP->len) & PKT_CMD_BIT) && (readb(&PktCmdP->Command) == BOOT_COMPLETED)) - return RIOBootComplete(p, HostP, Rup, PktCmdP); - - /* - ** Try to allocate a command block. This is in kernel space - */ - if (!(CmdBlkP = RIOGetCmdBlk())) { - rio_dprintk(RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n"); - return 0; - } - - /* - ** Fill in the default info on the command block - */ - CmdBlkP->Packet.dest_unit = Rup < (unsigned short) MAX_RUP ? Rup : 0; - CmdBlkP->Packet.dest_port = BOOT_RUP; - CmdBlkP->Packet.src_unit = 0; - CmdBlkP->Packet.src_port = BOOT_RUP; - - CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; - PktReplyP = (struct PktCmd_M *) CmdBlkP->Packet.data; - - /* - ** process COMMANDS on the boot rup! - */ - if (readb(&PacketP->len) & PKT_CMD_BIT) { - /* - ** We only expect one type of command - a BOOT_REQUEST! - */ - if (readb(&PktCmdP->Command) != BOOT_REQUEST) { - rio_dprintk(RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %Zd\n", readb(&PktCmdP->Command), Rup, HostP - p->RIOHosts); - RIOFreeCmdBlk(CmdBlkP); - return 1; - } - - /* - ** Build a Boot Sequence command block - ** - ** We no longer need to use "Boot Mode", we'll always allow - ** boot requests - the boot will not complete if the device - ** appears in the bindings table. - ** - ** We'll just (always) set the command field in packet reply - ** to allow an attempted boot sequence : - */ - PktReplyP->Command = BOOT_SEQUENCE; - - PktReplyP->BootSequence.NumPackets = p->RIONumBootPkts; - PktReplyP->BootSequence.LoadBase = p->RIOConf.RtaLoadBase; - PktReplyP->BootSequence.CodeSize = p->RIOBootCount; - - CmdBlkP->Packet.len = BOOT_SEQUENCE_LEN | PKT_CMD_BIT; - - memcpy((void *) &CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN], "BOOT", 4); - - rio_dprintk(RIO_DEBUG_BOOT, "Boot RTA on Host %Zd Rup %d - %d (0x%x) packets to 0x%x\n", HostP - p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts, p->RIOConf.RtaLoadBase); - - /* - ** If this host is in slave mode, send the RTA an invalid boot - ** sequence command block to force it to kill the boot. We wait - ** for half a second before sending this packet to prevent the RTA - ** attempting to boot too often. The master host should then grab - ** the RTA and make it its own. - */ - p->RIOBooting++; - RIOQueueCmdBlk(HostP, Rup, CmdBlkP); - return 1; - } - - /* - ** It is a request for boot data. - */ - sequence = readw(&PktCmdP->Sequence); - - rio_dprintk(RIO_DEBUG_BOOT, "Boot block %d on Host %Zd Rup%d\n", sequence, HostP - p->RIOHosts, Rup); - - if (sequence >= p->RIONumBootPkts) { - rio_dprintk(RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence, p->RIONumBootPkts); - } - - PktReplyP->Sequence = sequence; - memcpy(PktReplyP->BootData, p->RIOBootPackets[p->RIONumBootPkts - sequence - 1], RTA_BOOT_DATA_SIZE); - CmdBlkP->Packet.len = PKT_MAX_DATA_LEN; - RIOQueueCmdBlk(HostP, Rup, CmdBlkP); - return 1; -} - -/** - * RIOBootComplete - RTA boot is done - * @p: RIO we are working with - * @HostP: Host structure - * @Rup: RUP being used - * @PktCmdP: Packet command that was used - * - * This function is called when an RTA been booted. - * If booted by a host, HostP->HostUniqueNum is the booting host. - * If booted by an RTA, HostP->Mapping[Rup].RtaUniqueNum is the booting RTA. - * RtaUniq is the booted RTA. - */ - -static int RIOBootComplete(struct rio_info *p, struct Host *HostP, unsigned int Rup, struct PktCmd __iomem *PktCmdP) -{ - struct Map *MapP = NULL; - struct Map *MapP2 = NULL; - int Flag; - int found; - int host, rta; - int EmptySlot = -1; - int entry, entry2; - char *MyType, *MyName; - unsigned int MyLink; - unsigned short RtaType; - u32 RtaUniq = (readb(&PktCmdP->UniqNum[0])) + (readb(&PktCmdP->UniqNum[1]) << 8) + (readb(&PktCmdP->UniqNum[2]) << 16) + (readb(&PktCmdP->UniqNum[3]) << 24); - - p->RIOBooting = 0; - - rio_dprintk(RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting); - - /* - ** Determine type of unit (16/8 port RTA). - */ - - RtaType = GetUnitType(RtaUniq); - if (Rup >= (unsigned short) MAX_RUP) - rio_dprintk(RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n", HostP->Name, 8 * RtaType, readb(&PktCmdP->LinkNum) + 'A'); - else - rio_dprintk(RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n", HostP->Mapping[Rup].Name, 8 * RtaType, readb(&PktCmdP->LinkNum) + 'A'); - - rio_dprintk(RIO_DEBUG_BOOT, "UniqNum is 0x%x\n", RtaUniq); - - if (RtaUniq == 0x00000000 || RtaUniq == 0xffffffff) { - rio_dprintk(RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n"); - return 1; - } - - /* - ** If this RTA has just booted an RTA which doesn't belong to this - ** system, or the system is in slave mode, do not attempt to create - ** a new table entry for it. - */ - - if (!RIOBootOk(p, HostP, RtaUniq)) { - MyLink = readb(&PktCmdP->LinkNum); - if (Rup < (unsigned short) MAX_RUP) { - /* - ** RtaUniq was clone booted (by this RTA). Instruct this RTA - ** to hold off further attempts to boot on this link for 30 - ** seconds. - */ - if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink)) { - rio_dprintk(RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n", 'A' + MyLink); - } - } else - /* - ** RtaUniq was booted by this host. Set the booting link - ** to hold off for 30 seconds to give another unit a - ** chance to boot it. - */ - writew(30, &HostP->LinkStrP[MyLink].WaitNoBoot); - rio_dprintk(RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n", RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum); - return 1; - } - - /* - ** Check for a SLOT_IN_USE entry for this RTA attached to the - ** current host card in the driver table. - ** - ** If it exists, make a note that we have booted it. Other parts of - ** the driver are interested in this information at a later date, - ** in particular when the booting RTA asks for an ID for this unit, - ** we must have set the BOOTED flag, and the NEWBOOT flag is used - ** to force an open on any ports that where previously open on this - ** unit. - */ - for (entry = 0; entry < MAX_RUP; entry++) { - unsigned int sysport; - - if ((HostP->Mapping[entry].Flags & SLOT_IN_USE) && (HostP->Mapping[entry].RtaUniqueNum == RtaUniq)) { - HostP->Mapping[entry].Flags |= RTA_BOOTED | RTA_NEWBOOT; - if ((sysport = HostP->Mapping[entry].SysPort) != NO_PORT) { - if (sysport < p->RIOFirstPortsBooted) - p->RIOFirstPortsBooted = sysport; - if (sysport > p->RIOLastPortsBooted) - p->RIOLastPortsBooted = sysport; - /* - ** For a 16 port RTA, check the second bank of 8 ports - */ - if (RtaType == TYPE_RTA16) { - entry2 = HostP->Mapping[entry].ID2 - 1; - HostP->Mapping[entry2].Flags |= RTA_BOOTED | RTA_NEWBOOT; - sysport = HostP->Mapping[entry2].SysPort; - if (sysport < p->RIOFirstPortsBooted) - p->RIOFirstPortsBooted = sysport; - if (sysport > p->RIOLastPortsBooted) - p->RIOLastPortsBooted = sysport; - } - } - if (RtaType == TYPE_RTA16) - rio_dprintk(RIO_DEBUG_BOOT, "RTA will be given IDs %d+%d\n", entry + 1, entry2 + 1); - else - rio_dprintk(RIO_DEBUG_BOOT, "RTA will be given ID %d\n", entry + 1); - return 1; - } - } - - rio_dprintk(RIO_DEBUG_BOOT, "RTA not configured for this host\n"); - - if (Rup >= (unsigned short) MAX_RUP) { - /* - ** It was a host that did the booting - */ - MyType = "Host"; - MyName = HostP->Name; - } else { - /* - ** It was an RTA that did the booting - */ - MyType = "RTA"; - MyName = HostP->Mapping[Rup].Name; - } - MyLink = readb(&PktCmdP->LinkNum); - - /* - ** There is no SLOT_IN_USE entry for this RTA attached to the current - ** host card in the driver table. - ** - ** Check for a SLOT_TENTATIVE entry for this RTA attached to the - ** current host card in the driver table. - ** - ** If we find one, then we re-use that slot. - */ - for (entry = 0; entry < MAX_RUP; entry++) { - if ((HostP->Mapping[entry].Flags & SLOT_TENTATIVE) && (HostP->Mapping[entry].RtaUniqueNum == RtaUniq)) { - if (RtaType == TYPE_RTA16) { - entry2 = HostP->Mapping[entry].ID2 - 1; - if ((HostP->Mapping[entry2].Flags & SLOT_TENTATIVE) && (HostP->Mapping[entry2].RtaUniqueNum == RtaUniq)) - rio_dprintk(RIO_DEBUG_BOOT, "Found previous tentative slots (%d+%d)\n", entry, entry2); - else - continue; - } else - rio_dprintk(RIO_DEBUG_BOOT, "Found previous tentative slot (%d)\n", entry); - if (!p->RIONoMessage) - printk("RTA connected to %s '%s' (%c) not configured.\n", MyType, MyName, MyLink + 'A'); - return 1; - } - } - - /* - ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA - ** attached to the current host card in the driver table. - ** - ** Check if there is a SLOT_IN_USE or SLOT_TENTATIVE entry on another - ** host for this RTA in the driver table. - ** - ** For a SLOT_IN_USE entry on another host, we need to delete the RTA - ** entry from the other host and add it to this host (using some of - ** the functions from table.c which do this). - ** For a SLOT_TENTATIVE entry on another host, we must cope with the - ** following scenario: - ** - ** + Plug 8 port RTA into host A. (This creates SLOT_TENTATIVE entry - ** in table) - ** + Unplug RTA and plug into host B. (We now have 2 SLOT_TENTATIVE - ** entries) - ** + Configure RTA on host B. (This slot now becomes SLOT_IN_USE) - ** + Unplug RTA and plug back into host A. - ** + Configure RTA on host A. We now have the same RTA configured - ** with different ports on two different hosts. - */ - rio_dprintk(RIO_DEBUG_BOOT, "Have we seen RTA %x before?\n", RtaUniq); - found = 0; - Flag = 0; /* Convince the compiler this variable is initialized */ - for (host = 0; !found && (host < p->RIONumHosts); host++) { - for (rta = 0; rta < MAX_RUP; rta++) { - if ((p->RIOHosts[host].Mapping[rta].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) && (p->RIOHosts[host].Mapping[rta].RtaUniqueNum == RtaUniq)) { - Flag = p->RIOHosts[host].Mapping[rta].Flags; - MapP = &p->RIOHosts[host].Mapping[rta]; - if (RtaType == TYPE_RTA16) { - MapP2 = &p->RIOHosts[host].Mapping[MapP->ID2 - 1]; - rio_dprintk(RIO_DEBUG_BOOT, "This RTA is units %d+%d from host %s\n", rta + 1, MapP->ID2, p->RIOHosts[host].Name); - } else - rio_dprintk(RIO_DEBUG_BOOT, "This RTA is unit %d from host %s\n", rta + 1, p->RIOHosts[host].Name); - found = 1; - break; - } - } - } - - /* - ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA - ** attached to the current host card in the driver table. - ** - ** If we have not found a SLOT_IN_USE or SLOT_TENTATIVE entry on - ** another host for this RTA in the driver table... - ** - ** Check for a SLOT_IN_USE entry for this RTA in the config table. - */ - if (!MapP) { - rio_dprintk(RIO_DEBUG_BOOT, "Look for RTA %x in RIOSavedTable\n", RtaUniq); - for (rta = 0; rta < TOTAL_MAP_ENTRIES; rta++) { - rio_dprintk(RIO_DEBUG_BOOT, "Check table entry %d (%x)", rta, p->RIOSavedTable[rta].RtaUniqueNum); - - if ((p->RIOSavedTable[rta].Flags & SLOT_IN_USE) && (p->RIOSavedTable[rta].RtaUniqueNum == RtaUniq)) { - MapP = &p->RIOSavedTable[rta]; - Flag = p->RIOSavedTable[rta].Flags; - if (RtaType == TYPE_RTA16) { - for (entry2 = rta + 1; entry2 < TOTAL_MAP_ENTRIES; entry2++) { - if (p->RIOSavedTable[entry2].RtaUniqueNum == RtaUniq) - break; - } - MapP2 = &p->RIOSavedTable[entry2]; - rio_dprintk(RIO_DEBUG_BOOT, "This RTA is from table entries %d+%d\n", rta, entry2); - } else - rio_dprintk(RIO_DEBUG_BOOT, "This RTA is from table entry %d\n", rta); - break; - } - } - } - - /* - ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA - ** attached to the current host card in the driver table. - ** - ** We may have found a SLOT_IN_USE entry on another host for this - ** RTA in the config table, or a SLOT_IN_USE or SLOT_TENTATIVE entry - ** on another host for this RTA in the driver table. - ** - ** Check the driver table for room to fit this newly discovered RTA. - ** RIOFindFreeID() first looks for free slots and if it does not - ** find any free slots it will then attempt to oust any - ** tentative entry in the table. - */ - EmptySlot = 1; - if (RtaType == TYPE_RTA16) { - if (RIOFindFreeID(p, HostP, &entry, &entry2) == 0) { - RIODefaultName(p, HostP, entry); - rio_fill_host_slot(entry, entry2, RtaUniq, HostP); - EmptySlot = 0; - } - } else { - if (RIOFindFreeID(p, HostP, &entry, NULL) == 0) { - RIODefaultName(p, HostP, entry); - rio_fill_host_slot(entry, 0, RtaUniq, HostP); - EmptySlot = 0; - } - } - - /* - ** There is no SLOT_IN_USE or SLOT_TENTATIVE entry for this RTA - ** attached to the current host card in the driver table. - ** - ** If we found a SLOT_IN_USE entry on another host for this - ** RTA in the config or driver table, and there are enough free - ** slots in the driver table, then we need to move it over and - ** delete it from the other host. - ** If we found a SLOT_TENTATIVE entry on another host for this - ** RTA in the driver table, just delete the other host entry. - */ - if (EmptySlot == 0) { - if (MapP) { - if (Flag & SLOT_IN_USE) { - rio_dprintk(RIO_DEBUG_BOOT, "This RTA configured on another host - move entry to current host (1)\n"); - HostP->Mapping[entry].SysPort = MapP->SysPort; - memcpy(HostP->Mapping[entry].Name, MapP->Name, MAX_NAME_LEN); - HostP->Mapping[entry].Flags = SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT; - RIOReMapPorts(p, HostP, &HostP->Mapping[entry]); - if (HostP->Mapping[entry].SysPort < p->RIOFirstPortsBooted) - p->RIOFirstPortsBooted = HostP->Mapping[entry].SysPort; - if (HostP->Mapping[entry].SysPort > p->RIOLastPortsBooted) - p->RIOLastPortsBooted = HostP->Mapping[entry].SysPort; - rio_dprintk(RIO_DEBUG_BOOT, "SysPort %d, Name %s\n", (int) MapP->SysPort, MapP->Name); - } else { - rio_dprintk(RIO_DEBUG_BOOT, "This RTA has a tentative entry on another host - delete that entry (1)\n"); - HostP->Mapping[entry].Flags = SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT; - } - if (RtaType == TYPE_RTA16) { - if (Flag & SLOT_IN_USE) { - HostP->Mapping[entry2].Flags = SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; - HostP->Mapping[entry2].SysPort = MapP2->SysPort; - /* - ** Map second block of ttys for 16 port RTA - */ - RIOReMapPorts(p, HostP, &HostP->Mapping[entry2]); - if (HostP->Mapping[entry2].SysPort < p->RIOFirstPortsBooted) - p->RIOFirstPortsBooted = HostP->Mapping[entry2].SysPort; - if (HostP->Mapping[entry2].SysPort > p->RIOLastPortsBooted) - p->RIOLastPortsBooted = HostP->Mapping[entry2].SysPort; - rio_dprintk(RIO_DEBUG_BOOT, "SysPort %d, Name %s\n", (int) HostP->Mapping[entry2].SysPort, HostP->Mapping[entry].Name); - } else - HostP->Mapping[entry2].Flags = SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT; - memset(MapP2, 0, sizeof(struct Map)); - } - memset(MapP, 0, sizeof(struct Map)); - if (!p->RIONoMessage) - printk("An orphaned RTA has been adopted by %s '%s' (%c).\n", MyType, MyName, MyLink + 'A'); - } else if (!p->RIONoMessage) - printk("RTA connected to %s '%s' (%c) not configured.\n", MyType, MyName, MyLink + 'A'); - RIOSetChange(p); - return 1; - } - - /* - ** There is no room in the driver table to make an entry for the - ** booted RTA. Keep a note of its Uniq Num in the overflow table, - ** so we can ignore it's ID requests. - */ - if (!p->RIONoMessage) - printk("The RTA connected to %s '%s' (%c) cannot be configured. You cannot configure more than 128 ports to one host card.\n", MyType, MyName, MyLink + 'A'); - for (entry = 0; entry < HostP->NumExtraBooted; entry++) { - if (HostP->ExtraUnits[entry] == RtaUniq) { - /* - ** already got it! - */ - return 1; - } - } - /* - ** If there is room, add the unit to the list of extras - */ - if (HostP->NumExtraBooted < MAX_EXTRA_UNITS) - HostP->ExtraUnits[HostP->NumExtraBooted++] = RtaUniq; - return 1; -} - - -/* -** If the RTA or its host appears in the RIOBindTab[] structure then -** we mustn't boot the RTA and should return 0. -** This operation is slightly different from the other drivers for RIO -** in that this is designed to work with the new utilities -** not config.rio and is FAR SIMPLER. -** We no longer support the RIOBootMode variable. It is all done from the -** "boot/noboot" field in the rio.cf file. -*/ -int RIOBootOk(struct rio_info *p, struct Host *HostP, unsigned long RtaUniq) -{ - int Entry; - unsigned int HostUniq = HostP->UniqueNum; - - /* - ** Search bindings table for RTA or its parent. - ** If it exists, return 0, else 1. - */ - for (Entry = 0; (Entry < MAX_RTA_BINDINGS) && (p->RIOBindTab[Entry] != 0); Entry++) { - if ((p->RIOBindTab[Entry] == HostUniq) || (p->RIOBindTab[Entry] == RtaUniq)) - return 0; - } - return 1; -} - -/* -** Make an empty slot tentative. If this is a 16 port RTA, make both -** slots tentative, and the second one RTA_SECOND_SLOT as well. -*/ - -void rio_fill_host_slot(int entry, int entry2, unsigned int rta_uniq, struct Host *host) -{ - int link; - - rio_dprintk(RIO_DEBUG_BOOT, "rio_fill_host_slot(%d, %d, 0x%x...)\n", entry, entry2, rta_uniq); - - host->Mapping[entry].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE); - host->Mapping[entry].SysPort = NO_PORT; - host->Mapping[entry].RtaUniqueNum = rta_uniq; - host->Mapping[entry].HostUniqueNum = host->UniqueNum; - host->Mapping[entry].ID = entry + 1; - host->Mapping[entry].ID2 = 0; - if (entry2) { - host->Mapping[entry2].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE | RTA16_SECOND_SLOT); - host->Mapping[entry2].SysPort = NO_PORT; - host->Mapping[entry2].RtaUniqueNum = rta_uniq; - host->Mapping[entry2].HostUniqueNum = host->UniqueNum; - host->Mapping[entry2].Name[0] = '\0'; - host->Mapping[entry2].ID = entry2 + 1; - host->Mapping[entry2].ID2 = entry + 1; - host->Mapping[entry].ID2 = entry2 + 1; - } - /* - ** Must set these up, so that utilities show - ** topology of 16 port RTAs correctly - */ - for (link = 0; link < LINKS_PER_UNIT; link++) { - host->Mapping[entry].Topology[link].Unit = ROUTE_DISCONNECT; - host->Mapping[entry].Topology[link].Link = NO_LINK; - if (entry2) { - host->Mapping[entry2].Topology[link].Unit = ROUTE_DISCONNECT; - host->Mapping[entry2].Topology[link].Link = NO_LINK; - } - } -} diff --git a/drivers/staging/generic_serial/rio/riocmd.c b/drivers/staging/generic_serial/rio/riocmd.c deleted file mode 100644 index 61efd538e850..000000000000 --- a/drivers/staging/generic_serial/rio/riocmd.c +++ /dev/null @@ -1,939 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** ported from the existing SCO driver source -** - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : riocmd.c -** SID : 1.2 -** Last Modified : 11/6/98 10:33:41 -** Retrieved : 11/6/98 10:33:49 -** -** ident @(#)riocmd.c 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" - - -static struct IdentifyRta IdRta; -static struct KillNeighbour KillUnit; - -int RIOFoadRta(struct Host *HostP, struct Map *MapP) -{ - struct CmdBlk *CmdBlkP; - - rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA\n"); - - CmdBlkP = RIOGetCmdBlk(); - - if (!CmdBlkP) { - rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n"); - return -ENXIO; - } - - CmdBlkP->Packet.dest_unit = MapP->ID; - CmdBlkP->Packet.dest_port = BOOT_RUP; - CmdBlkP->Packet.src_unit = 0; - CmdBlkP->Packet.src_port = BOOT_RUP; - CmdBlkP->Packet.len = 0x84; - CmdBlkP->Packet.data[0] = IFOAD; - CmdBlkP->Packet.data[1] = 0; - CmdBlkP->Packet.data[2] = IFOAD_MAGIC & 0xFF; - CmdBlkP->Packet.data[3] = (IFOAD_MAGIC >> 8) & 0xFF; - - if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n"); - return -EIO; - } - return 0; -} - -int RIOZombieRta(struct Host *HostP, struct Map *MapP) -{ - struct CmdBlk *CmdBlkP; - - rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA\n"); - - CmdBlkP = RIOGetCmdBlk(); - - if (!CmdBlkP) { - rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n"); - return -ENXIO; - } - - CmdBlkP->Packet.dest_unit = MapP->ID; - CmdBlkP->Packet.dest_port = BOOT_RUP; - CmdBlkP->Packet.src_unit = 0; - CmdBlkP->Packet.src_port = BOOT_RUP; - CmdBlkP->Packet.len = 0x84; - CmdBlkP->Packet.data[0] = ZOMBIE; - CmdBlkP->Packet.data[1] = 0; - CmdBlkP->Packet.data[2] = ZOMBIE_MAGIC & 0xFF; - CmdBlkP->Packet.data[3] = (ZOMBIE_MAGIC >> 8) & 0xFF; - - if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n"); - return -EIO; - } - return 0; -} - -int RIOCommandRta(struct rio_info *p, unsigned long RtaUnique, int (*func) (struct Host * HostP, struct Map * MapP)) -{ - unsigned int Host; - - rio_dprintk(RIO_DEBUG_CMD, "Command RTA 0x%lx func %p\n", RtaUnique, func); - - if (!RtaUnique) - return (0); - - for (Host = 0; Host < p->RIONumHosts; Host++) { - unsigned int Rta; - struct Host *HostP = &p->RIOHosts[Host]; - - for (Rta = 0; Rta < RTAS_PER_HOST; Rta++) { - struct Map *MapP = &HostP->Mapping[Rta]; - - if (MapP->RtaUniqueNum == RtaUnique) { - uint Link; - - /* - ** now, lets just check we have a route to it... - ** IF the routing stuff is working, then one of the - ** topology entries for this unit will have a legit - ** route *somewhere*. We care not where - if its got - ** any connections, we can get to it. - */ - for (Link = 0; Link < LINKS_PER_UNIT; Link++) { - if (MapP->Topology[Link].Unit <= (u8) MAX_RUP) { - /* - ** Its worth trying the operation... - */ - return (*func) (HostP, MapP); - } - } - } - } - } - return -ENXIO; -} - - -int RIOIdentifyRta(struct rio_info *p, void __user * arg) -{ - unsigned int Host; - - if (copy_from_user(&IdRta, arg, sizeof(IdRta))) { - rio_dprintk(RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - - for (Host = 0; Host < p->RIONumHosts; Host++) { - unsigned int Rta; - struct Host *HostP = &p->RIOHosts[Host]; - - for (Rta = 0; Rta < RTAS_PER_HOST; Rta++) { - struct Map *MapP = &HostP->Mapping[Rta]; - - if (MapP->RtaUniqueNum == IdRta.RtaUnique) { - uint Link; - /* - ** now, lets just check we have a route to it... - ** IF the routing stuff is working, then one of the - ** topology entries for this unit will have a legit - ** route *somewhere*. We care not where - if its got - ** any connections, we can get to it. - */ - for (Link = 0; Link < LINKS_PER_UNIT; Link++) { - if (MapP->Topology[Link].Unit <= (u8) MAX_RUP) { - /* - ** Its worth trying the operation... - */ - struct CmdBlk *CmdBlkP; - - rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA\n"); - - CmdBlkP = RIOGetCmdBlk(); - - if (!CmdBlkP) { - rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n"); - return -ENXIO; - } - - CmdBlkP->Packet.dest_unit = MapP->ID; - CmdBlkP->Packet.dest_port = BOOT_RUP; - CmdBlkP->Packet.src_unit = 0; - CmdBlkP->Packet.src_port = BOOT_RUP; - CmdBlkP->Packet.len = 0x84; - CmdBlkP->Packet.data[0] = IDENTIFY; - CmdBlkP->Packet.data[1] = 0; - CmdBlkP->Packet.data[2] = IdRta.ID; - - if (RIOQueueCmdBlk(HostP, MapP->ID - 1, CmdBlkP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n"); - return -EIO; - } - return 0; - } - } - } - } - } - return -ENOENT; -} - - -int RIOKillNeighbour(struct rio_info *p, void __user * arg) -{ - uint Host; - uint ID; - struct Host *HostP; - struct CmdBlk *CmdBlkP; - - rio_dprintk(RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n"); - - if (copy_from_user(&KillUnit, arg, sizeof(KillUnit))) { - rio_dprintk(RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - - if (KillUnit.Link > 3) - return -ENXIO; - - CmdBlkP = RIOGetCmdBlk(); - - if (!CmdBlkP) { - rio_dprintk(RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n"); - return -ENXIO; - } - - CmdBlkP->Packet.dest_unit = 0; - CmdBlkP->Packet.src_unit = 0; - CmdBlkP->Packet.dest_port = BOOT_RUP; - CmdBlkP->Packet.src_port = BOOT_RUP; - CmdBlkP->Packet.len = 0x84; - CmdBlkP->Packet.data[0] = UFOAD; - CmdBlkP->Packet.data[1] = KillUnit.Link; - CmdBlkP->Packet.data[2] = UFOAD_MAGIC & 0xFF; - CmdBlkP->Packet.data[3] = (UFOAD_MAGIC >> 8) & 0xFF; - - for (Host = 0; Host < p->RIONumHosts; Host++) { - ID = 0; - HostP = &p->RIOHosts[Host]; - - if (HostP->UniqueNum == KillUnit.UniqueNum) { - if (RIOQueueCmdBlk(HostP, RTAS_PER_HOST + KillUnit.Link, CmdBlkP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CMD, "UFOAD: Failed queue command\n"); - return -EIO; - } - return 0; - } - - for (ID = 0; ID < RTAS_PER_HOST; ID++) { - if (HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum) { - CmdBlkP->Packet.dest_unit = ID + 1; - if (RIOQueueCmdBlk(HostP, ID, CmdBlkP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CMD, "UFOAD: Failed queue command\n"); - return -EIO; - } - return 0; - } - } - } - RIOFreeCmdBlk(CmdBlkP); - return -ENXIO; -} - -int RIOSuspendBootRta(struct Host *HostP, int ID, int Link) -{ - struct CmdBlk *CmdBlkP; - - rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link); - - CmdBlkP = RIOGetCmdBlk(); - - if (!CmdBlkP) { - rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n"); - return -ENXIO; - } - - CmdBlkP->Packet.dest_unit = ID; - CmdBlkP->Packet.dest_port = BOOT_RUP; - CmdBlkP->Packet.src_unit = 0; - CmdBlkP->Packet.src_port = BOOT_RUP; - CmdBlkP->Packet.len = 0x84; - CmdBlkP->Packet.data[0] = IWAIT; - CmdBlkP->Packet.data[1] = Link; - CmdBlkP->Packet.data[2] = IWAIT_MAGIC & 0xFF; - CmdBlkP->Packet.data[3] = (IWAIT_MAGIC >> 8) & 0xFF; - - if (RIOQueueCmdBlk(HostP, ID - 1, CmdBlkP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n"); - return -EIO; - } - return 0; -} - -int RIOFoadWakeup(struct rio_info *p) -{ - int port; - struct Port *PortP; - unsigned long flags; - - for (port = 0; port < RIO_PORTS; port++) { - PortP = p->RIOPortp[port]; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->Config = 0; - PortP->State = 0; - PortP->InUse = NOT_INUSE; - PortP->PortState = 0; - PortP->FlushCmdBodge = 0; - PortP->ModemLines = 0; - PortP->ModemState = 0; - PortP->CookMode = 0; - PortP->ParamSem = 0; - PortP->Mapped = 0; - PortP->WflushFlag = 0; - PortP->MagicFlags = 0; - PortP->RxDataStart = 0; - PortP->TxBufferIn = 0; - PortP->TxBufferOut = 0; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - } - return (0); -} - -/* -** Incoming command on the COMMAND_RUP to be processed. -*/ -static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struct PKT __iomem *PacketP) -{ - struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *)PacketP->data; - struct Port *PortP; - struct UnixRup *UnixRupP; - unsigned short SysPort; - unsigned short ReportedModemStatus; - unsigned short rup; - unsigned short subCommand; - unsigned long flags; - - func_enter(); - - /* - ** 16 port RTA note: - ** Command rup packets coming from the RTA will have pkt->data[1] (which - ** translates to PktCmdP->PhbNum) set to the host port number for the - ** particular unit. To access the correct BaseSysPort for a 16 port RTA, - ** we can use PhbNum to get the rup number for the appropriate 8 port - ** block (for the first block, this should be equal to 'Rup'). - */ - rup = readb(&PktCmdP->PhbNum) / (unsigned short) PORTS_PER_RTA; - UnixRupP = &HostP->UnixRups[rup]; - SysPort = UnixRupP->BaseSysPort + (readb(&PktCmdP->PhbNum) % (unsigned short) PORTS_PER_RTA); - rio_dprintk(RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort); - - if (UnixRupP->BaseSysPort == NO_PORT) { - rio_dprintk(RIO_DEBUG_CMD, "OBSCURE ERROR!\n"); - rio_dprintk(RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n"); - rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Host number %Zd, name ``%s''\n", HostP - p->RIOHosts, HostP->Name); - rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Rup number 0x%x\n", rup); - - if (Rup < (unsigned short) MAX_RUP) { - rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n", HostP->Mapping[Rup].Name); - } else - rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", ('A' + Rup - MAX_RUP), HostP->Name); - - rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n", readb(&PacketP->dest_unit), readb(&PacketP->dest_port)); - rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Source 0x%x:0x%x\n", readb(&PacketP->src_unit), readb(&PacketP->src_port)); - rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Length 0x%x (%d)\n", readb(&PacketP->len), readb(&PacketP->len)); - rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Control 0x%x (%d)\n", readb(&PacketP->control), readb(&PacketP->control)); - rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Check 0x%x (%d)\n", readw(&PacketP->csum), readw(&PacketP->csum)); - rio_dprintk(RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, " "Command Code 0x%x\n", readb(&PktCmdP->PhbNum), readb(&PktCmdP->Command)); - return 1; - } - PortP = p->RIOPortp[SysPort]; - rio_spin_lock_irqsave(&PortP->portSem, flags); - switch (readb(&PktCmdP->Command)) { - case RIOC_BREAK_RECEIVED: - rio_dprintk(RIO_DEBUG_CMD, "Received a break!\n"); - /* If the current line disc. is not multi-threading and - the current processor is not the default, reset rup_intr - and return 0 to ensure that the command packet is - not freed. */ - /* Call tmgr HANGUP HERE */ - /* Fix this later when every thing works !!!! RAMRAJ */ - gs_got_break(&PortP->gs); - break; - - case RIOC_COMPLETE: - rio_dprintk(RIO_DEBUG_CMD, "Command complete on phb %d host %Zd\n", readb(&PktCmdP->PhbNum), HostP - p->RIOHosts); - subCommand = 1; - switch (readb(&PktCmdP->SubCommand)) { - case RIOC_MEMDUMP: - rio_dprintk(RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n", readb(&PktCmdP->SubCommand), readw(&PktCmdP->SubAddr)); - break; - case RIOC_READ_REGISTER: - rio_dprintk(RIO_DEBUG_CMD, "Read register (0x%x)\n", readw(&PktCmdP->SubAddr)); - p->CdRegister = (readb(&PktCmdP->ModemStatus) & RIOC_MSVR1_HOST); - break; - default: - subCommand = 0; - break; - } - if (subCommand) - break; - rio_dprintk(RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n", readb(&PktCmdP->PortStatus), PortP->PortState); - if (PortP->PortState != readb(&PktCmdP->PortStatus)) { - rio_dprintk(RIO_DEBUG_CMD, "Mark status & wakeup\n"); - PortP->PortState = readb(&PktCmdP->PortStatus); - /* What should we do here ... - wakeup( &PortP->PortState ); - */ - } else - rio_dprintk(RIO_DEBUG_CMD, "No change\n"); - - /* FALLTHROUGH */ - case RIOC_MODEM_STATUS: - /* - ** Knock out the tbusy and tstop bits, as these are not relevant - ** to the check for modem status change (they're just there because - ** it's a convenient place to put them!). - */ - ReportedModemStatus = readb(&PktCmdP->ModemStatus); - if ((PortP->ModemState & RIOC_MSVR1_HOST) == - (ReportedModemStatus & RIOC_MSVR1_HOST)) { - rio_dprintk(RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState); - /* - ** Update ModemState just in case tbusy or tstop states have - ** changed. - */ - PortP->ModemState = ReportedModemStatus; - } else { - rio_dprintk(RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n", PortP->ModemState, ReportedModemStatus); - PortP->ModemState = ReportedModemStatus; -#ifdef MODEM_SUPPORT - if (PortP->Mapped) { - /***********************************************************\ - ************************************************************* - *** *** - *** M O D E M S T A T E C H A N G E *** - *** *** - ************************************************************* - \***********************************************************/ - /* - ** If the device is a modem, then check the modem - ** carrier. - */ - if (PortP->gs.port.tty == NULL) - break; - if (PortP->gs.port.tty->termios == NULL) - break; - - if (!(PortP->gs.port.tty->termios->c_cflag & CLOCAL) && ((PortP->State & (RIO_MOPEN | RIO_WOPEN)))) { - - rio_dprintk(RIO_DEBUG_CMD, "Is there a Carrier?\n"); - /* - ** Is there a carrier? - */ - if (PortP->ModemState & RIOC_MSVR1_CD) { - /* - ** Has carrier just appeared? - */ - if (!(PortP->State & RIO_CARR_ON)) { - rio_dprintk(RIO_DEBUG_CMD, "Carrier just came up.\n"); - PortP->State |= RIO_CARR_ON; - /* - ** wakeup anyone in WOPEN - */ - if (PortP->State & (PORT_ISOPEN | RIO_WOPEN)) - wake_up_interruptible(&PortP->gs.port.open_wait); - } - } else { - /* - ** Has carrier just dropped? - */ - if (PortP->State & RIO_CARR_ON) { - if (PortP->State & (PORT_ISOPEN | RIO_WOPEN | RIO_MOPEN)) - tty_hangup(PortP->gs.port.tty); - PortP->State &= ~RIO_CARR_ON; - rio_dprintk(RIO_DEBUG_CMD, "Carrirer just went down\n"); - } - } - } - } -#endif - } - break; - - default: - rio_dprintk(RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %Zd\n", readb(&PktCmdP->Command), HostP - p->RIOHosts); - break; - } - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - - func_exit(); - - return 1; -} - -/* -** The command mechanism: -** Each rup has a chain of commands associated with it. -** This chain is maintained by routines in this file. -** Periodically we are called and we run a quick check of all the -** active chains to determine if there is a command to be executed, -** and if the rup is ready to accept it. -** -*/ - -/* -** Allocate an empty command block. -*/ -struct CmdBlk *RIOGetCmdBlk(void) -{ - struct CmdBlk *CmdBlkP; - - CmdBlkP = kzalloc(sizeof(struct CmdBlk), GFP_ATOMIC); - return CmdBlkP; -} - -/* -** Return a block to the head of the free list. -*/ -void RIOFreeCmdBlk(struct CmdBlk *CmdBlkP) -{ - kfree(CmdBlkP); -} - -/* -** attach a command block to the list of commands to be performed for -** a given rup. -*/ -int RIOQueueCmdBlk(struct Host *HostP, uint Rup, struct CmdBlk *CmdBlkP) -{ - struct CmdBlk **Base; - struct UnixRup *UnixRupP; - unsigned long flags; - - if (Rup >= (unsigned short) (MAX_RUP + LINKS_PER_UNIT)) { - rio_dprintk(RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n", Rup); - RIOFreeCmdBlk(CmdBlkP); - return RIO_FAIL; - } - - UnixRupP = &HostP->UnixRups[Rup]; - - rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); - - /* - ** If the RUP is currently inactive, then put the request - ** straight on the RUP.... - */ - if ((UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) && (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) && (CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP) (CmdBlkP->PreArg, CmdBlkP) - : 1)) { - rio_dprintk(RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n", CmdBlkP->Packet.data[0]); - - /* - ** Whammy! blat that pack! - */ - HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT)); - - /* - ** place command packet on the pending position. - */ - UnixRupP->CmdPendingP = CmdBlkP; - - /* - ** set the command register - */ - writew(TX_PACKET_READY, &UnixRupP->RupP->txcontrol); - - rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - - return 0; - } - rio_dprintk(RIO_DEBUG_CMD, "RUP active - en-queing\n"); - - if (UnixRupP->CmdsWaitingP != NULL) - rio_dprintk(RIO_DEBUG_CMD, "Rup active - command waiting\n"); - if (UnixRupP->CmdPendingP != NULL) - rio_dprintk(RIO_DEBUG_CMD, "Rup active - command pending\n"); - if (readw(&UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE) - rio_dprintk(RIO_DEBUG_CMD, "Rup active - command rup not ready\n"); - - Base = &UnixRupP->CmdsWaitingP; - - rio_dprintk(RIO_DEBUG_CMD, "First try to queue cmdblk %p at %p\n", CmdBlkP, Base); - - while (*Base) { - rio_dprintk(RIO_DEBUG_CMD, "Command cmdblk %p here\n", *Base); - Base = &((*Base)->NextP); - rio_dprintk(RIO_DEBUG_CMD, "Now try to queue cmd cmdblk %p at %p\n", CmdBlkP, Base); - } - - rio_dprintk(RIO_DEBUG_CMD, "Will queue cmdblk %p at %p\n", CmdBlkP, Base); - - *Base = CmdBlkP; - - CmdBlkP->NextP = NULL; - - rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - - return 0; -} - -/* -** Here we go - if there is an empty rup, fill it! -** must be called at splrio() or higher. -*/ -void RIOPollHostCommands(struct rio_info *p, struct Host *HostP) -{ - struct CmdBlk *CmdBlkP; - struct UnixRup *UnixRupP; - struct PKT __iomem *PacketP; - unsigned short Rup; - unsigned long flags; - - - Rup = MAX_RUP + LINKS_PER_UNIT; - - do { /* do this loop for each RUP */ - /* - ** locate the rup we are processing & lock it - */ - UnixRupP = &HostP->UnixRups[--Rup]; - - spin_lock_irqsave(&UnixRupP->RupLock, flags); - - /* - ** First check for incoming commands: - */ - if (readw(&UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE) { - int FreeMe; - - PacketP = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->rxpkt)); - - switch (readb(&PacketP->dest_port)) { - case BOOT_RUP: - rio_dprintk(RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n", readb(&PacketP->len) & 0x80 ? "Command" : "Data", readb(&PacketP->data[0])); - rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - FreeMe = RIOBootRup(p, Rup, HostP, PacketP); - rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); - break; - - case COMMAND_RUP: - /* - ** Free the RUP lock as loss of carrier causes a - ** ttyflush which will (eventually) call another - ** routine that uses the RUP lock. - */ - rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - FreeMe = RIOCommandRup(p, Rup, HostP, PacketP); - if (readb(&PacketP->data[5]) == RIOC_MEMDUMP) { - rio_dprintk(RIO_DEBUG_CMD, "Memdump from 0x%x complete\n", readw(&(PacketP->data[6]))); - rio_memcpy_fromio(p->RIOMemDump, &(PacketP->data[8]), 32); - } - rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); - break; - - case ROUTE_RUP: - rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - FreeMe = RIORouteRup(p, Rup, HostP, PacketP); - rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); - break; - - default: - rio_dprintk(RIO_DEBUG_CMD, "Unknown RUP %d\n", readb(&PacketP->dest_port)); - FreeMe = 1; - break; - } - - if (FreeMe) { - rio_dprintk(RIO_DEBUG_CMD, "Free processed incoming command packet\n"); - put_free_end(HostP, PacketP); - - writew(RX_RUP_INACTIVE, &UnixRupP->RupP->rxcontrol); - - if (readw(&UnixRupP->RupP->handshake) == PHB_HANDSHAKE_SET) { - rio_dprintk(RIO_DEBUG_CMD, "Handshake rup %d\n", Rup); - writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &UnixRupP->RupP->handshake); - } - } - } - - /* - ** IF a command was running on the port, - ** and it has completed, then tidy it up. - */ - if ((CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */ - (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) { - /* - ** we are idle. - ** there is a command in pending. - ** Therefore, this command has finished. - ** So, wakeup whoever is waiting for it (and tell them - ** what happened). - */ - if (CmdBlkP->Packet.dest_port == BOOT_RUP) - rio_dprintk(RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n", CmdBlkP->Packet.len & 0x80 ? "Command" : "Data", CmdBlkP->Packet.data[0]); - - rio_dprintk(RIO_DEBUG_CMD, "Command %p completed\n", CmdBlkP); - - /* - ** Clear the Rup lock to prevent mutual exclusion. - */ - if (CmdBlkP->PostFuncP) { - rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - (*CmdBlkP->PostFuncP) (CmdBlkP->PostArg, CmdBlkP); - rio_spin_lock_irqsave(&UnixRupP->RupLock, flags); - } - - /* - ** ....clear the pending flag.... - */ - UnixRupP->CmdPendingP = NULL; - - /* - ** ....and return the command block to the freelist. - */ - RIOFreeCmdBlk(CmdBlkP); - } - - /* - ** If there is a command for this rup, and the rup - ** is idle, then process the command - */ - if ((CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */ - (UnixRupP->CmdPendingP == NULL) && (readw(&UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) { - /* - ** if the pre-function is non-zero, call it. - ** If it returns RIO_FAIL then don't - ** send this command yet! - */ - if (!(CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP) (CmdBlkP->PreArg, CmdBlkP) : 1)) { - rio_dprintk(RIO_DEBUG_CMD, "Not ready to start command %p\n", CmdBlkP); - } else { - rio_dprintk(RIO_DEBUG_CMD, "Start new command %p Cmd byte is 0x%x\n", CmdBlkP, CmdBlkP->Packet.data[0]); - /* - ** Whammy! blat that pack! - */ - HostP->Copy(&CmdBlkP->Packet, RIO_PTR(HostP->Caddr, readw(&UnixRupP->RupP->txpkt)), sizeof(struct PKT)); - - /* - ** remove the command from the rup command queue... - */ - UnixRupP->CmdsWaitingP = CmdBlkP->NextP; - - /* - ** ...and place it on the pending position. - */ - UnixRupP->CmdPendingP = CmdBlkP; - - /* - ** set the command register - */ - writew(TX_PACKET_READY, &UnixRupP->RupP->txcontrol); - - /* - ** the command block will be freed - ** when the command has been processed. - */ - } - } - spin_unlock_irqrestore(&UnixRupP->RupLock, flags); - } while (Rup); -} - -int RIOWFlushMark(unsigned long iPortP, struct CmdBlk *CmdBlkP) -{ - struct Port *PortP = (struct Port *) iPortP; - unsigned long flags; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->WflushFlag++; - PortP->MagicFlags |= MAGIC_FLUSH; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return RIOUnUse(iPortP, CmdBlkP); -} - -int RIORFlushEnable(unsigned long iPortP, struct CmdBlk *CmdBlkP) -{ - struct Port *PortP = (struct Port *) iPortP; - struct PKT __iomem *PacketP; - unsigned long flags; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - - while (can_remove_receive(&PacketP, PortP)) { - remove_receive(PortP); - put_free_end(PortP->HostP, PacketP); - } - - if (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET) { - /* - ** MAGIC! (Basically, handshake the RX buffer, so that - ** the RTAs upstream can be re-enabled.) - */ - rio_dprintk(RIO_DEBUG_CMD, "Util: Set RX handshake bit\n"); - writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake); - } - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return RIOUnUse(iPortP, CmdBlkP); -} - -int RIOUnUse(unsigned long iPortP, struct CmdBlk *CmdBlkP) -{ - struct Port *PortP = (struct Port *) iPortP; - unsigned long flags; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - - rio_dprintk(RIO_DEBUG_CMD, "Decrement in use count for port\n"); - - if (PortP->InUse) { - if (--PortP->InUse != NOT_INUSE) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return 0; - } - } - /* - ** While PortP->InUse is set (i.e. a preemptive command has been sent to - ** the RTA and is awaiting completion), any transmit data is prevented from - ** being transferred from the write queue into the transmit packets - ** (add_transmit) and no furthur transmit interrupt will be sent for that - ** data. The next interrupt will occur up to 500ms later (RIOIntr is called - ** twice a second as a safety measure). This was the case when kermit was - ** used to send data into a RIO port. After each packet was sent, TCFLSH - ** was called to flush the read queue preemptively. PortP->InUse was - ** incremented, thereby blocking the 6 byte acknowledgement packet - ** transmitted back. This acknowledgment hung around for 500ms before - ** being sent, thus reducing input performance substantially!. - ** When PortP->InUse becomes NOT_INUSE, we must ensure that any data - ** hanging around in the transmit buffer is sent immediately. - */ - writew(1, &PortP->HostP->ParmMapP->tx_intr); - /* What to do here .. - wakeup( (caddr_t)&(PortP->InUse) ); - */ - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return 0; -} - -/* -** -** How to use this file: -** -** To send a command down a rup, you need to allocate a command block, fill -** in the packet information, fill in the command number, fill in the pre- -** and post- functions and arguments, and then add the command block to the -** queue of command blocks for the port in question. When the port is idle, -** then the pre-function will be called. If this returns RIO_FAIL then the -** command will be re-queued and tried again at a later date (probably in one -** clock tick). If the pre-function returns NOT RIO_FAIL, then the command -** packet will be queued on the RUP, and the txcontrol field set to the -** command number. When the txcontrol field has changed from being the -** command number, then the post-function will be called, with the argument -** specified earlier, a pointer to the command block, and the value of -** txcontrol. -** -** To allocate a command block, call RIOGetCmdBlk(). This returns a pointer -** to the command block structure allocated, or NULL if there aren't any. -** The block will have been zeroed for you. -** -** The structure has the following fields: -** -** struct CmdBlk -** { -** struct CmdBlk *NextP; ** Pointer to next command block ** -** struct PKT Packet; ** A packet, to copy to the rup ** -** int (*PreFuncP)(); ** The func to call to check if OK ** -** int PreArg; ** The arg for the func ** -** int (*PostFuncP)(); ** The func to call when completed ** -** int PostArg; ** The arg for the func ** -** }; -** -** You need to fill in ALL fields EXCEPT NextP, which is used to link the -** blocks together either on the free list or on the Rup list. -** -** Packet is an actual packet structure to be filled in with the packet -** information associated with the command. You need to fill in everything, -** as the command processor doesn't process the command packet in any way. -** -** The PreFuncP is called before the packet is enqueued on the host rup. -** PreFuncP is called as (*PreFuncP)(PreArg, CmdBlkP);. PreFuncP must -** return !RIO_FAIL to have the packet queued on the rup, and RIO_FAIL -** if the packet is NOT to be queued. -** -** The PostFuncP is called when the command has completed. It is called -** as (*PostFuncP)(PostArg, CmdBlkP, txcontrol);. PostFuncP is not expected -** to return a value. PostFuncP does NOT need to free the command block, -** as this happens automatically after PostFuncP returns. -** -** Once the command block has been filled in, it is attached to the correct -** queue by calling RIOQueueCmdBlk( HostP, Rup, CmdBlkP ) where HostP is -** a pointer to the struct Host, Rup is the NUMBER of the rup (NOT a pointer -** to it!), and CmdBlkP is the pointer to the command block allocated using -** RIOGetCmdBlk(). -** -*/ diff --git a/drivers/staging/generic_serial/rio/rioctrl.c b/drivers/staging/generic_serial/rio/rioctrl.c deleted file mode 100644 index 780506326a73..000000000000 --- a/drivers/staging/generic_serial/rio/rioctrl.c +++ /dev/null @@ -1,1504 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : rioctrl.c -** SID : 1.3 -** Last Modified : 11/6/98 10:33:42 -** Retrieved : 11/6/98 10:33:49 -** -** ident @(#)rioctrl.c 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" - - -static struct LpbReq LpbReq; -static struct RupReq RupReq; -static struct PortReq PortReq; -static struct HostReq HostReq; /* oh really? global? and no locking? */ -static struct HostDpRam HostDpRam; -static struct DebugCtrl DebugCtrl; -static struct Map MapEnt; -static struct PortSetup PortSetup; -static struct DownLoad DownLoad; -static struct SendPack SendPack; -/* static struct StreamInfo StreamInfo; */ -/* static char modemtable[RIO_PORTS]; */ -static struct SpecialRupCmd SpecialRupCmd; -static struct PortParams PortParams; -static struct portStats portStats; - -static struct SubCmdStruct { - ushort Host; - ushort Rup; - ushort Port; - ushort Addr; -} SubCmd; - -struct PortTty { - uint port; - struct ttystatics Tty; -}; - -static struct PortTty PortTty; -typedef struct ttystatics TERMIO; - -/* -** This table is used when the config.rio downloads bin code to the -** driver. We index the table using the product code, 0-F, and call -** the function pointed to by the entry, passing the information -** about the boot. -** The RIOBootCodeUNKNOWN entry is there to politely tell the calling -** process to bog off. -*/ -static int - (*RIOBootTable[MAX_PRODUCT]) (struct rio_info *, struct DownLoad *) = { - /* 0 */ RIOBootCodeHOST, - /* Host Card */ - /* 1 */ RIOBootCodeRTA, - /* RTA */ -}; - -#define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff)) - -static int copy_from_io(void __user *to, void __iomem *from, size_t size) -{ - void *buf = kmalloc(size, GFP_KERNEL); - int res = -ENOMEM; - if (buf) { - rio_memcpy_fromio(buf, from, size); - res = copy_to_user(to, buf, size); - kfree(buf); - } - return res; -} - -int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su) -{ - uint Host; /* leave me unsigned! */ - uint port; /* and me! */ - struct Host *HostP; - ushort loop; - int Entry; - struct Port *PortP; - struct PKT __iomem *PacketP; - int retval = 0; - unsigned long flags; - void __user *argp = (void __user *)arg; - - func_enter(); - - /* Confuse the compiler to think that we've initialized these */ - Host = 0; - PortP = NULL; - - rio_dprintk(RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: %p\n", cmd, argp); - - switch (cmd) { - /* - ** RIO_SET_TIMER - ** - ** Change the value of the host card interrupt timer. - ** If the host card number is -1 then all host cards are changed - ** otherwise just the specified host card will be changed. - */ - case RIO_SET_TIMER: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_TIMER to %ldms\n", arg); - { - int host, value; - host = (arg >> 16) & 0x0000FFFF; - value = arg & 0x0000ffff; - if (host == -1) { - for (host = 0; host < p->RIONumHosts; host++) { - if (p->RIOHosts[host].Flags == RC_RUNNING) { - writew(value, &p->RIOHosts[host].ParmMapP->timer); - } - } - } else if (host >= p->RIONumHosts) { - return -EINVAL; - } else { - if (p->RIOHosts[host].Flags == RC_RUNNING) { - writew(value, &p->RIOHosts[host].ParmMapP->timer); - } - } - } - return 0; - - case RIO_FOAD_RTA: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n"); - return RIOCommandRta(p, arg, RIOFoadRta); - - case RIO_ZOMBIE_RTA: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n"); - return RIOCommandRta(p, arg, RIOZombieRta); - - case RIO_IDENTIFY_RTA: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n"); - return RIOIdentifyRta(p, argp); - - case RIO_KILL_NEIGHBOUR: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n"); - return RIOKillNeighbour(p, argp); - - case SPECIAL_RUP_CMD: - { - struct CmdBlk *CmdBlkP; - - rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n"); - if (copy_from_user(&SpecialRupCmd, argp, sizeof(SpecialRupCmd))) { - rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - CmdBlkP = RIOGetCmdBlk(); - if (!CmdBlkP) { - rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD GetCmdBlk failed\n"); - return -ENXIO; - } - CmdBlkP->Packet = SpecialRupCmd.Packet; - if (SpecialRupCmd.Host >= p->RIONumHosts) - SpecialRupCmd.Host = 0; - rio_dprintk(RIO_DEBUG_CTRL, "Queue special rup command for host %d rup %d\n", SpecialRupCmd.Host, SpecialRupCmd.RupNum); - if (RIOQueueCmdBlk(&p->RIOHosts[SpecialRupCmd.Host], SpecialRupCmd.RupNum, CmdBlkP) == RIO_FAIL) { - printk(KERN_WARNING "rio: FAILED TO QUEUE SPECIAL RUP COMMAND\n"); - } - return 0; - } - - case RIO_DEBUG_MEM: - return -EPERM; - - case RIO_ALL_MODEM: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_ALL_MODEM\n"); - p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; - return -EINVAL; - - case RIO_GET_TABLE: - /* - ** Read the routing table from the device driver to user space - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE\n"); - - if ((retval = RIOApel(p)) != 0) - return retval; - - if (copy_to_user(argp, p->RIOConnectTable, TOTAL_MAP_ENTRIES * sizeof(struct Map))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - - { - int entry; - rio_dprintk(RIO_DEBUG_CTRL, "*****\nMAP ENTRIES\n"); - for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { - if ((p->RIOConnectTable[entry].ID == 0) && (p->RIOConnectTable[entry].HostUniqueNum == 0) && (p->RIOConnectTable[entry].RtaUniqueNum == 0)) - continue; - - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%x\n", entry, (int) p->RIOConnectTable[entry].Flags); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%x\n", entry, (int) p->RIOConnectTable[entry].SysPort); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link); - rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name); - } - rio_dprintk(RIO_DEBUG_CTRL, "*****\nEND MAP ENTRIES\n"); - } - p->RIOQuickCheck = NOT_CHANGED; /* a table has been gotten */ - return 0; - - case RIO_PUT_TABLE: - /* - ** Write the routing table to the device driver from user space - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE\n"); - - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&p->RIOConnectTable[0], argp, TOTAL_MAP_ENTRIES * sizeof(struct Map))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } -/* -*********************************** - { - int entry; - rio_dprint(RIO_DEBUG_CTRL, ("*****\nMAP ENTRIES\n") ); - for ( entry=0; entryRIOConnectTable[entry].HostUniqueNum ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Flags = 0x%x\n", entry, p->RIOConnectTable[entry].Flags ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.SysPort = 0x%x\n", entry, p->RIOConnectTable[entry].SysPort ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Unit ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Link ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Unit ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Link ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Unit ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Link ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[3].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Unit ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[4].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Link ) ); - rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name ) ); - } - rio_dprint(RIO_DEBUG_CTRL, ("*****\nEND MAP ENTRIES\n") ); - } -*********************************** -*/ - return RIONewTable(p); - - case RIO_GET_BINDINGS: - /* - ** Send bindings table, containing unique numbers of RTAs owned - ** by this system to user space - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS\n"); - - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_to_user(argp, p->RIOBindTab, (sizeof(ulong) * MAX_RTA_BINDINGS))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return 0; - - case RIO_PUT_BINDINGS: - /* - ** Receive a bindings table, containing unique numbers of RTAs owned - ** by this system - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n"); - - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&p->RIOBindTab[0], argp, (sizeof(ulong) * MAX_RTA_BINDINGS))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - return 0; - - case RIO_BIND_RTA: - { - int EmptySlot = -1; - /* - ** Bind this RTA to host, so that it will be booted by - ** host in 'boot owned RTAs' mode. - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA\n"); - - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) { - if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L)) - EmptySlot = Entry; - else if (p->RIOBindTab[Entry] == arg) { - /* - ** Already exists - delete - */ - p->RIOBindTab[Entry] = 0L; - rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %ld from p->RIOBindTab\n", arg); - return 0; - } - } - /* - ** Dosen't exist - add - */ - if (EmptySlot != -1) { - p->RIOBindTab[EmptySlot] = arg; - rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %lx to p->RIOBindTab\n", arg); - } else { - rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %lx not added\n", arg); - return -ENOMEM; - } - return 0; - } - - case RIO_RESUME: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME\n"); - port = arg; - if ((port < 0) || (port > 511)) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - PortP = p->RIOPortp[port]; - if (!PortP->Mapped) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port); - p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM; - return -EINVAL; - } - if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port); - return -EINVAL; - } - - rio_spin_lock_irqsave(&PortP->portSem, flags); - if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RIOC_RESUME) == - RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME failed\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return -EBUSY; - } else { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port); - PortP->State |= RIO_BUSY; - } - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_ASSIGN_RTA: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n"); - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) { - rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - return RIOAssignRta(p, &MapEnt); - - case RIO_CHANGE_NAME: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n"); - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) { - rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - return RIOChangeName(p, &MapEnt); - - case RIO_DELETE_RTA: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n"); - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) { - rio_dprintk(RIO_DEBUG_CTRL, "Copy from data space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - return RIODeleteRta(p, &MapEnt); - - case RIO_QUICK_CHECK: - if (copy_to_user(argp, &p->RIORtaDisCons, sizeof(unsigned int))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return 0; - - case RIO_LAST_ERROR: - if (copy_to_user(argp, &p->RIOError, sizeof(struct Error))) - return -EFAULT; - return 0; - - case RIO_GET_LOG: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_LOG\n"); - return -EINVAL; - - case RIO_GET_MODTYPE: - if (copy_from_user(&port, argp, sizeof(unsigned int))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - rio_dprintk(RIO_DEBUG_CTRL, "Get module type for port %d\n", port); - if (port < 0 || port > 511) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - PortP = (p->RIOPortp[port]); - if (!PortP->Mapped) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port); - p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM; - return -EINVAL; - } - /* - ** Return module type of port - */ - port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes; - if (copy_to_user(argp, &port, sizeof(unsigned int))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return (0); - case RIO_BLOCK_OPENS: - rio_dprintk(RIO_DEBUG_CTRL, "Opens block until booted\n"); - for (Entry = 0; Entry < RIO_PORTS; Entry++) { - rio_spin_lock_irqsave(&PortP->portSem, flags); - p->RIOPortp[Entry]->WaitUntilBooted = 1; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - } - return 0; - - case RIO_SETUP_PORTS: - rio_dprintk(RIO_DEBUG_CTRL, "Setup ports\n"); - if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) { - p->RIOError.Error = COPYIN_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "EFAULT"); - return -EFAULT; - } - if (PortSetup.From > PortSetup.To || PortSetup.To >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - rio_dprintk(RIO_DEBUG_CTRL, "ENXIO"); - return -ENXIO; - } - if (PortSetup.XpCps > p->RIOConf.MaxXpCps || PortSetup.XpCps < p->RIOConf.MinXpCps) { - p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE; - rio_dprintk(RIO_DEBUG_CTRL, "EINVAL"); - return -EINVAL; - } - if (!p->RIOPortp) { - printk(KERN_ERR "rio: No p->RIOPortp array!\n"); - rio_dprintk(RIO_DEBUG_CTRL, "No p->RIOPortp array!\n"); - return -EIO; - } - rio_dprintk(RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To); - for (loop = PortSetup.From; loop <= PortSetup.To; loop++) { - rio_dprintk(RIO_DEBUG_CTRL, "in loop (%d)!\n", loop); - } - rio_dprintk(RIO_DEBUG_CTRL, "after loop (%d)!\n", loop); - rio_dprintk(RIO_DEBUG_CTRL, "Retval:%x\n", retval); - return retval; - - case RIO_GET_PORT_SETUP: - rio_dprintk(RIO_DEBUG_CTRL, "Get port setup\n"); - if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (PortSetup.From >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - - port = PortSetup.To = PortSetup.From; - PortSetup.IxAny = (p->RIOPortp[port]->Config & RIO_IXANY) ? 1 : 0; - PortSetup.IxOn = (p->RIOPortp[port]->Config & RIO_IXON) ? 1 : 0; - PortSetup.Drain = (p->RIOPortp[port]->Config & RIO_WAITDRAIN) ? 1 : 0; - PortSetup.Store = p->RIOPortp[port]->Store; - PortSetup.Lock = p->RIOPortp[port]->Lock; - PortSetup.XpCps = p->RIOPortp[port]->Xprint.XpCps; - memcpy(PortSetup.XpOn, p->RIOPortp[port]->Xprint.XpOn, MAX_XP_CTRL_LEN); - memcpy(PortSetup.XpOff, p->RIOPortp[port]->Xprint.XpOff, MAX_XP_CTRL_LEN); - PortSetup.XpOn[MAX_XP_CTRL_LEN - 1] = '\0'; - PortSetup.XpOff[MAX_XP_CTRL_LEN - 1] = '\0'; - - if (copy_to_user(argp, &PortSetup, sizeof(PortSetup))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_GET_PORT_PARAMS: - rio_dprintk(RIO_DEBUG_CTRL, "Get port params\n"); - if (copy_from_user(&PortParams, argp, sizeof(struct PortParams))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (PortParams.Port >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - PortP = (p->RIOPortp[PortParams.Port]); - PortParams.Config = PortP->Config; - PortParams.State = PortP->State; - rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port); - - if (copy_to_user(argp, &PortParams, sizeof(struct PortParams))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_GET_PORT_TTY: - rio_dprintk(RIO_DEBUG_CTRL, "Get port tty\n"); - if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (PortTty.port >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - - rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortTty.port); - PortP = (p->RIOPortp[PortTty.port]); - if (copy_to_user(argp, &PortTty, sizeof(struct PortTty))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_SET_PORT_TTY: - if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - rio_dprintk(RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port); - if (PortTty.port >= (ushort) RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - PortP = (p->RIOPortp[PortTty.port]); - RIOParam(PortP, RIOC_CONFIG, PortP->State & RIO_MODEM, - OK_TO_SLEEP); - return retval; - - case RIO_SET_PORT_PARAMS: - rio_dprintk(RIO_DEBUG_CTRL, "Set port params\n"); - if (copy_from_user(&PortParams, argp, sizeof(PortParams))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (PortParams.Port >= (ushort) RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - PortP = (p->RIOPortp[PortParams.Port]); - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->Config = PortParams.Config; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_GET_PORT_STATS: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n"); - if (copy_from_user(&portStats, argp, sizeof(struct portStats))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (portStats.port < 0 || portStats.port >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - PortP = (p->RIOPortp[portStats.port]); - portStats.gather = PortP->statsGather; - portStats.txchars = PortP->txchars; - portStats.rxchars = PortP->rxchars; - portStats.opens = PortP->opens; - portStats.closes = PortP->closes; - portStats.ioctls = PortP->ioctls; - if (copy_to_user(argp, &portStats, sizeof(struct portStats))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_RESET_PORT_STATS: - port = arg; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n"); - if (port >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - PortP = (p->RIOPortp[port]); - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->txchars = 0; - PortP->rxchars = 0; - PortP->opens = 0; - PortP->closes = 0; - PortP->ioctls = 0; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_GATHER_PORT_STATS: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n"); - if (copy_from_user(&portStats, argp, sizeof(struct portStats))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (portStats.port < 0 || portStats.port >= RIO_PORTS) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - PortP = (p->RIOPortp[portStats.port]); - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->statsGather = portStats.gather; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_READ_CONFIG: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n"); - if (copy_to_user(argp, &p->RIOConf, sizeof(struct Conf))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_SET_CONFIG: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n"); - if (!su) { - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&p->RIOConf, argp, sizeof(struct Conf))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - /* - ** move a few value around - */ - for (Host = 0; Host < p->RIONumHosts; Host++) - if ((p->RIOHosts[Host].Flags & RUN_STATE) == RC_RUNNING) - writew(p->RIOConf.Timer, &p->RIOHosts[Host].ParmMapP->timer); - return retval; - - case RIO_START_POLLER: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_START_POLLER\n"); - return -EINVAL; - - case RIO_STOP_POLLER: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n"); - if (!su) { - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - p->RIOPolling = NOT_POLLING; - return retval; - - case RIO_SETDEBUG: - case RIO_GETDEBUG: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n"); - if (copy_from_user(&DebugCtrl, argp, sizeof(DebugCtrl))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (DebugCtrl.SysPort == NO_PORT) { - if (cmd == RIO_SETDEBUG) { - if (!su) { - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - p->rio_debug = DebugCtrl.Debug; - p->RIODebugWait = DebugCtrl.Wait; - rio_dprintk(RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n", p->rio_debug, p->RIODebugWait); - } else { - rio_dprintk(RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n", p->rio_debug, p->RIODebugWait); - DebugCtrl.Debug = p->rio_debug; - DebugCtrl.Wait = p->RIODebugWait; - if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - } - } else if (DebugCtrl.SysPort >= RIO_PORTS && DebugCtrl.SysPort != NO_PORT) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } else if (cmd == RIO_SETDEBUG) { - if (!su) { - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); - } else { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); - DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug; - if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - } - return retval; - - case RIO_VERSID: - /* - ** Enquire about the release and version. - ** We return MAX_VERSION_LEN bytes, being a - ** textual null terminated string. - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID\n"); - if (copy_to_user(argp, RIOVersid(), sizeof(struct rioVersion))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_NUM_HOSTS: - /* - ** Enquire as to the number of hosts located - ** at init time. - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n"); - if (copy_to_user(argp, &p->RIONumHosts, sizeof(p->RIONumHosts))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - case RIO_HOST_FOAD: - /* - ** Kill host. This may not be in the final version... - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD %ld\n", arg); - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - p->RIOHalted = 1; - p->RIOSystemUp = 0; - - for (Host = 0; Host < p->RIONumHosts; Host++) { - (void) RIOBoardTest(p->RIOHosts[Host].PaddrP, p->RIOHosts[Host].Caddr, p->RIOHosts[Host].Type, p->RIOHosts[Host].Slot); - memset(&p->RIOHosts[Host].Flags, 0, ((char *) &p->RIOHosts[Host].____end_marker____) - ((char *) &p->RIOHosts[Host].Flags)); - p->RIOHosts[Host].Flags = RC_WAITING; - } - RIOFoadWakeup(p); - p->RIONumBootPkts = 0; - p->RIOBooting = 0; - printk("HEEEEELP!\n"); - - for (loop = 0; loop < RIO_PORTS; loop++) { - spin_lock_init(&p->RIOPortp[loop]->portSem); - p->RIOPortp[loop]->InUse = NOT_INUSE; - } - - p->RIOSystemUp = 0; - return retval; - - case RIO_DOWNLOAD: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n"); - if (!su) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n"); - p->RIOError.Error = NOT_SUPER_USER; - return -EPERM; - } - if (copy_from_user(&DownLoad, argp, sizeof(DownLoad))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - rio_dprintk(RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n", DownLoad.ProductCode); - - /* - ** It is important that the product code is an unsigned object! - */ - if (DownLoad.ProductCode >= MAX_PRODUCT) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n", DownLoad.ProductCode); - p->RIOError.Error = NO_SUCH_PRODUCT; - return -ENXIO; - } - /* - ** do something! - */ - retval = (*(RIOBootTable[DownLoad.ProductCode])) (p, &DownLoad); - /* <-- Panic */ - p->RIOHalted = 0; - /* - ** and go back, content with a job well completed. - */ - return retval; - - case RIO_PARMS: - { - unsigned int host; - - if (copy_from_user(&host, argp, sizeof(host))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - /* - ** Fetch the parmmap - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS\n"); - if (copy_from_io(argp, p->RIOHosts[host].ParmMapP, sizeof(PARM_MAP))) { - p->RIOError.Error = COPYOUT_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n"); - return -EFAULT; - } - } - return retval; - - case RIO_HOST_REQ: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ\n"); - if (copy_from_user(&HostReq, argp, sizeof(HostReq))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (HostReq.HostNum >= p->RIONumHosts) { - p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n", HostReq.HostNum); - return -ENXIO; - } - rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum); - - if (copy_to_user(HostReq.HostP, &p->RIOHosts[HostReq.HostNum], sizeof(struct Host))) { - p->RIOError.Error = COPYOUT_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n"); - return -EFAULT; - } - return retval; - - case RIO_HOST_DPRAM: - rio_dprintk(RIO_DEBUG_CTRL, "Request for DPRAM\n"); - if (copy_from_user(&HostDpRam, argp, sizeof(HostDpRam))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (HostDpRam.HostNum >= p->RIONumHosts) { - p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n", HostDpRam.HostNum); - return -ENXIO; - } - rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum); - - if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) { - int off; - /* It's hardware like this that really gets on my tits. */ - static unsigned char copy[sizeof(struct DpRam)]; - for (off = 0; off < sizeof(struct DpRam); off++) - copy[off] = readb(p->RIOHosts[HostDpRam.HostNum].Caddr + off); - if (copy_to_user(HostDpRam.DpRamP, copy, sizeof(struct DpRam))) { - p->RIOError.Error = COPYOUT_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); - return -EFAULT; - } - } else if (copy_from_io(HostDpRam.DpRamP, p->RIOHosts[HostDpRam.HostNum].Caddr, sizeof(struct DpRam))) { - p->RIOError.Error = COPYOUT_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); - return -EFAULT; - } - return retval; - - case RIO_SET_BUSY: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY\n"); - if (arg > 511) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %ld\n", arg); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - p->RIOPortp[arg]->State |= RIO_BUSY; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_HOST_PORT: - /* - ** The daemon want port information - ** (probably for debug reasons) - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT\n"); - if (copy_from_user(&PortReq, argp, sizeof(PortReq))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - - if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n", PortReq.SysPort); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - rio_dprintk(RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort); - if (copy_to_user(PortReq.PortP, p->RIOPortp[PortReq.SysPort], sizeof(struct Port))) { - p->RIOError.Error = COPYOUT_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n"); - return -EFAULT; - } - return retval; - - case RIO_HOST_RUP: - /* - ** The daemon want rup information - ** (probably for debug reasons) - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP\n"); - if (copy_from_user(&RupReq, argp, sizeof(RupReq))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n", RupReq.HostNum); - p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - if (RupReq.RupNum >= MAX_RUP + LINKS_PER_UNIT) { /* eek! */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n", RupReq.RupNum); - p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - HostP = &p->RIOHosts[RupReq.HostNum]; - - if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n", RupReq.HostNum); - p->RIOError.Error = HOST_NOT_RUNNING; - return -EIO; - } - rio_dprintk(RIO_DEBUG_CTRL, "Request for rup %d from host %d\n", RupReq.RupNum, RupReq.HostNum); - - if (copy_from_io(RupReq.RupP, HostP->UnixRups[RupReq.RupNum].RupP, sizeof(struct RUP))) { - p->RIOError.Error = COPYOUT_FAILED; - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n"); - return -EFAULT; - } - return retval; - - case RIO_HOST_LPB: - /* - ** The daemon want lpb information - ** (probably for debug reasons) - */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB\n"); - if (copy_from_user(&LpbReq, argp, sizeof(LpbReq))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n", LpbReq.Host); - p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - if (LpbReq.Link >= LINKS_PER_UNIT) { /* eek! */ - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n", LpbReq.Link); - p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - HostP = &p->RIOHosts[LpbReq.Host]; - - if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n", LpbReq.Host); - p->RIOError.Error = HOST_NOT_RUNNING; - return -EIO; - } - rio_dprintk(RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", LpbReq.Link, LpbReq.Host); - - if (copy_from_io(LpbReq.LpbP, &HostP->LinkStrP[LpbReq.Link], sizeof(struct LPB))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return retval; - - /* - ** Here 3 IOCTL's that allow us to change the way in which - ** rio logs errors. send them just to syslog or send them - ** to both syslog and console or send them to just the console. - ** - ** See RioStrBuf() in util.c for the other half. - */ - case RIO_SYSLOG_ONLY: - p->RIOPrintLogState = PRINT_TO_LOG; /* Just syslog */ - return 0; - - case RIO_SYSLOG_CONS: - p->RIOPrintLogState = PRINT_TO_LOG_CONS; /* syslog and console */ - return 0; - - case RIO_CONS_ONLY: - p->RIOPrintLogState = PRINT_TO_CONS; /* Just console */ - return 0; - - case RIO_SIGNALS_ON: - if (p->RIOSignalProcess) { - p->RIOError.Error = SIGNALS_ALREADY_SET; - return -EBUSY; - } - /* FIXME: PID tracking */ - p->RIOSignalProcess = current->pid; - p->RIOPrintDisabled = DONT_PRINT; - return retval; - - case RIO_SIGNALS_OFF: - if (p->RIOSignalProcess != current->pid) { - p->RIOError.Error = NOT_RECEIVING_PROCESS; - return -EPERM; - } - rio_dprintk(RIO_DEBUG_CTRL, "Clear signal process to zero\n"); - p->RIOSignalProcess = 0; - return retval; - - case RIO_SET_BYTE_MODE: - for (Host = 0; Host < p->RIONumHosts; Host++) - if (p->RIOHosts[Host].Type == RIO_AT) - p->RIOHosts[Host].Mode &= ~WORD_OPERATION; - return retval; - - case RIO_SET_WORD_MODE: - for (Host = 0; Host < p->RIONumHosts; Host++) - if (p->RIOHosts[Host].Type == RIO_AT) - p->RIOHosts[Host].Mode |= WORD_OPERATION; - return retval; - - case RIO_SET_FAST_BUS: - for (Host = 0; Host < p->RIONumHosts; Host++) - if (p->RIOHosts[Host].Type == RIO_AT) - p->RIOHosts[Host].Mode |= FAST_AT_BUS; - return retval; - - case RIO_SET_SLOW_BUS: - for (Host = 0; Host < p->RIONumHosts; Host++) - if (p->RIOHosts[Host].Type == RIO_AT) - p->RIOHosts[Host].Mode &= ~FAST_AT_BUS; - return retval; - - case RIO_MAP_B50_TO_50: - case RIO_MAP_B50_TO_57600: - case RIO_MAP_B110_TO_110: - case RIO_MAP_B110_TO_115200: - rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping\n"); - port = arg; - if (port < 0 || port > 511) { - rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - switch (cmd) { - case RIO_MAP_B50_TO_50: - p->RIOPortp[port]->Config |= RIO_MAP_50_TO_50; - break; - case RIO_MAP_B50_TO_57600: - p->RIOPortp[port]->Config &= ~RIO_MAP_50_TO_50; - break; - case RIO_MAP_B110_TO_110: - p->RIOPortp[port]->Config |= RIO_MAP_110_TO_110; - break; - case RIO_MAP_B110_TO_115200: - p->RIOPortp[port]->Config &= ~RIO_MAP_110_TO_110; - break; - } - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_STREAM_INFO: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n"); - return -EINVAL; - - case RIO_SEND_PACKET: - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n"); - if (copy_from_user(&SendPack, argp, sizeof(SendPack))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n"); - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - if (SendPack.PortNum >= 128) { - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -ENXIO; - } - - PortP = p->RIOPortp[SendPack.PortNum]; - rio_spin_lock_irqsave(&PortP->portSem, flags); - - if (!can_add_transmit(&PacketP, PortP)) { - p->RIOError.Error = UNIT_IS_IN_USE; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return -ENOSPC; - } - - for (loop = 0; loop < (ushort) (SendPack.Len & 127); loop++) - writeb(SendPack.Data[loop], &PacketP->data[loop]); - - writeb(SendPack.Len, &PacketP->len); - - add_transmit(PortP); - /* - ** Count characters transmitted for port statistics reporting - */ - if (PortP->statsGather) - PortP->txchars += (SendPack.Len & 127); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - - case RIO_NO_MESG: - if (su) - p->RIONoMessage = 1; - return su ? 0 : -EPERM; - - case RIO_MESG: - if (su) - p->RIONoMessage = 0; - return su ? 0 : -EPERM; - - case RIO_WHAT_MESG: - if (copy_to_user(argp, &p->RIONoMessage, sizeof(p->RIONoMessage))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return 0; - - case RIO_MEM_DUMP: - if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Addr); - - if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) { - p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - if (SubCmd.Host >= p->RIONumHosts) { - p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort; - - PortP = p->RIOPortp[port]; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - - if (RIOPreemptiveCmd(p, PortP, RIOC_MEMDUMP) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return -EBUSY; - } else - PortP->State |= RIO_BUSY; - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (copy_to_user(argp, p->RIOMemDump, MEMDUMP_SIZE)) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return 0; - - case RIO_TICK: - if (arg >= p->RIONumHosts) - return -EINVAL; - rio_dprintk(RIO_DEBUG_CTRL, "Set interrupt for host %ld\n", arg); - writeb(0xFF, &p->RIOHosts[arg].SetInt); - return 0; - - case RIO_TOCK: - if (arg >= p->RIONumHosts) - return -EINVAL; - rio_dprintk(RIO_DEBUG_CTRL, "Clear interrupt for host %ld\n", arg); - writeb(0xFF, &p->RIOHosts[arg].ResetInt); - return 0; - - case RIO_READ_CHECK: - /* Check reads for pkts with data[0] the same */ - p->RIOReadCheck = !p->RIOReadCheck; - if (copy_to_user(argp, &p->RIOReadCheck, sizeof(unsigned int))) { - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return 0; - - case RIO_READ_REGISTER: - if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) { - p->RIOError.Error = COPYIN_FAILED; - return -EFAULT; - } - rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER host %d rup %d port %d reg %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr); - - if (SubCmd.Port > 511) { - rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", SubCmd.Port); - p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) { - p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - if (SubCmd.Host >= p->RIONumHosts) { - p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort + SubCmd.Port; - PortP = p->RIOPortp[port]; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - - if (RIOPreemptiveCmd(p, PortP, RIOC_READ_REGISTER) == - RIO_FAIL) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return -EBUSY; - } else - PortP->State |= RIO_BUSY; - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (copy_to_user(argp, &p->CdRegister, sizeof(unsigned int))) { - rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n"); - p->RIOError.Error = COPYOUT_FAILED; - return -EFAULT; - } - return 0; - /* - ** rio_make_dev: given port number (0-511) ORed with port type - ** (RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT) return dev_t - ** value to pass to mknod to create the correct device node. - */ - case RIO_MAKE_DEV: - { - unsigned int port = arg & RIO_MODEM_MASK; - unsigned int ret; - - switch (arg & RIO_DEV_MASK) { - case RIO_DEV_DIRECT: - ret = drv_makedev(MAJOR(dev), port); - rio_dprintk(RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n", port, ret); - return ret; - case RIO_DEV_MODEM: - ret = drv_makedev(MAJOR(dev), (port | RIO_MODEM_BIT)); - rio_dprintk(RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n", port, ret); - return ret; - case RIO_DEV_XPRINT: - ret = drv_makedev(MAJOR(dev), port); - rio_dprintk(RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n", port, ret); - return ret; - } - rio_dprintk(RIO_DEBUG_CTRL, "MAKE Device is called\n"); - return -EINVAL; - } - /* - ** rio_minor: given a dev_t from a stat() call, return - ** the port number (0-511) ORed with the port type - ** ( RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT ) - */ - case RIO_MINOR: - { - dev_t dv; - int mino; - unsigned long ret; - - dv = (dev_t) (arg); - mino = RIO_UNMODEM(dv); - - if (RIO_ISMODEM(dv)) { - rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino); - ret = mino | RIO_DEV_MODEM; - } else { - rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino); - ret = mino | RIO_DEV_DIRECT; - } - return ret; - } - } - rio_dprintk(RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n", cmd); - p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; - - func_exit(); - return -EINVAL; -} - -/* -** Pre-emptive commands go on RUPs and are only one byte long. -*/ -int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd) -{ - struct CmdBlk *CmdBlkP; - struct PktCmd_M *PktCmdP; - int Ret; - ushort rup; - int port; - - if (PortP->State & RIO_DELETED) { - rio_dprintk(RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n"); - return RIO_FAIL; - } - - if ((PortP->InUse == (typeof(PortP->InUse))-1) || - !(CmdBlkP = RIOGetCmdBlk())) { - rio_dprintk(RIO_DEBUG_CTRL, "Cannot allocate command block " - "for command %d on port %d\n", Cmd, PortP->PortNum); - return RIO_FAIL; - } - - rio_dprintk(RIO_DEBUG_CTRL, "Command blk %p - InUse now %d\n", - CmdBlkP, PortP->InUse); - - PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0]; - - CmdBlkP->Packet.src_unit = 0; - if (PortP->SecondBlock) - rup = PortP->ID2; - else - rup = PortP->RupNum; - CmdBlkP->Packet.dest_unit = rup; - CmdBlkP->Packet.src_port = COMMAND_RUP; - CmdBlkP->Packet.dest_port = COMMAND_RUP; - CmdBlkP->Packet.len = PKT_CMD_BIT | 2; - CmdBlkP->PostFuncP = RIOUnUse; - CmdBlkP->PostArg = (unsigned long) PortP; - PktCmdP->Command = Cmd; - port = PortP->HostPort % (ushort) PORTS_PER_RTA; - /* - ** Index ports 8-15 for 2nd block of 16 port RTA. - */ - if (PortP->SecondBlock) - port += (ushort) PORTS_PER_RTA; - PktCmdP->PhbNum = port; - - switch (Cmd) { - case RIOC_MEMDUMP: - rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk %p " - "(addr 0x%x)\n", CmdBlkP, (int) SubCmd.Addr); - PktCmdP->SubCommand = RIOC_MEMDUMP; - PktCmdP->SubAddr = SubCmd.Addr; - break; - case RIOC_FCLOSE: - rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk %p\n", - CmdBlkP); - break; - case RIOC_READ_REGISTER: - rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) " - "command blk %p\n", (int) SubCmd.Addr, CmdBlkP); - PktCmdP->SubCommand = RIOC_READ_REGISTER; - PktCmdP->SubAddr = SubCmd.Addr; - break; - case RIOC_RESUME: - rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk %p\n", - CmdBlkP); - break; - case RIOC_RFLUSH: - rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk %p\n", - CmdBlkP); - CmdBlkP->PostFuncP = RIORFlushEnable; - break; - case RIOC_SUSPEND: - rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk %p\n", - CmdBlkP); - break; - - case RIOC_MGET: - rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk %p\n", - CmdBlkP); - break; - - case RIOC_MSET: - case RIOC_MBIC: - case RIOC_MBIS: - CmdBlkP->Packet.data[4] = (char) PortP->ModemLines; - rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command " - "blk %p\n", CmdBlkP); - break; - - case RIOC_WFLUSH: - /* - ** If we have queued up the maximum number of Write flushes - ** allowed then we should not bother sending any more to the - ** RTA. - */ - if (PortP->WflushFlag == (typeof(PortP->WflushFlag))-1) { - rio_dprintk(RIO_DEBUG_CTRL, "Trashed WFLUSH, " - "WflushFlag about to wrap!"); - RIOFreeCmdBlk(CmdBlkP); - return (RIO_FAIL); - } else { - rio_dprintk(RIO_DEBUG_CTRL, "Queue WFLUSH command " - "blk %p\n", CmdBlkP); - CmdBlkP->PostFuncP = RIOWFlushMark; - } - break; - } - - PortP->InUse++; - - Ret = RIOQueueCmdBlk(PortP->HostP, rup, CmdBlkP); - - return Ret; -} diff --git a/drivers/staging/generic_serial/rio/riodrvr.h b/drivers/staging/generic_serial/rio/riodrvr.h deleted file mode 100644 index 0907e711b355..000000000000 --- a/drivers/staging/generic_serial/rio/riodrvr.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : riodrvr.h -** SID : 1.3 -** Last Modified : 11/6/98 09:22:46 -** Retrieved : 11/6/98 09:22:46 -** -** ident @(#)riodrvr.h 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __riodrvr_h -#define __riodrvr_h - -#include /* for HZ */ - -#define MEMDUMP_SIZE 32 -#define MOD_DISABLE (RIO_NOREAD|RIO_NOWRITE|RIO_NOXPRINT) - - -struct rio_info { - int mode; /* Intr or polled, word/byte */ - spinlock_t RIOIntrSem; /* Interrupt thread sem */ - int current_chan; /* current channel */ - int RIOFailed; /* Not initialised ? */ - int RIOInstallAttempts; /* no. of rio-install() calls */ - int RIOLastPCISearch; /* status of last search */ - int RIONumHosts; /* Number of RIO Hosts */ - struct Host *RIOHosts; /* RIO Host values */ - struct Port **RIOPortp; /* RIO port values */ -/* -** 02.03.1999 ARG - ESIL 0820 fix -** We no longer use RIOBootMode -** - int RIOBootMode; * RIO boot mode * -** -*/ - int RIOPrintDisabled; /* RIO printing disabled ? */ - int RIOPrintLogState; /* RIO printing state ? */ - int RIOPolling; /* Polling ? */ -/* -** 09.12.1998 ARG - ESIL 0776 part fix -** The 'RIO_QUICK_CHECK' ioctl was using RIOHalted. -** The fix for this ESIL introduces another member (RIORtaDisCons) here to be -** updated in RIOConCon() - to keep track of RTA connections/disconnections. -** 'RIO_QUICK_CHECK' now returns the value of RIORtaDisCons. -*/ - int RIOHalted; /* halted ? */ - int RIORtaDisCons; /* RTA connections/disconnections */ - unsigned int RIOReadCheck; /* Rio read check */ - unsigned int RIONoMessage; /* To display message or not */ - unsigned int RIONumBootPkts; /* how many packets for an RTA */ - unsigned int RIOBootCount; /* size of RTA code */ - unsigned int RIOBooting; /* count of outstanding boots */ - unsigned int RIOSystemUp; /* Booted ?? */ - unsigned int RIOCounting; /* for counting interrupts */ - unsigned int RIOIntCount; /* # of intr since last check */ - unsigned int RIOTxCount; /* number of xmit intrs */ - unsigned int RIORxCount; /* number of rx intrs */ - unsigned int RIORupCount; /* number of rup intrs */ - int RIXTimer; - int RIOBufferSize; /* Buffersize */ - int RIOBufferMask; /* Buffersize */ - - int RIOFirstMajor; /* First host card's major no */ - - unsigned int RIOLastPortsMapped; /* highest port number known */ - unsigned int RIOFirstPortsMapped; /* lowest port number known */ - - unsigned int RIOLastPortsBooted; /* highest port number running */ - unsigned int RIOFirstPortsBooted; /* lowest port number running */ - - unsigned int RIOLastPortsOpened; /* highest port number running */ - unsigned int RIOFirstPortsOpened; /* lowest port number running */ - - /* Flag to say that the topology information has been changed. */ - unsigned int RIOQuickCheck; - unsigned int CdRegister; /* ??? */ - int RIOSignalProcess; /* Signalling process */ - int rio_debug; /* To debug ... */ - int RIODebugWait; /* For what ??? */ - int tpri; /* Thread prio */ - int tid; /* Thread id */ - unsigned int _RIO_Polled; /* Counter for polling */ - unsigned int _RIO_Interrupted; /* Counter for interrupt */ - int intr_tid; /* iointset return value */ - int TxEnSem; /* TxEnable Semaphore */ - - - struct Error RIOError; /* to Identify what went wrong */ - struct Conf RIOConf; /* Configuration ??? */ - struct ttystatics channel[RIO_PORTS]; /* channel information */ - char RIOBootPackets[1 + (SIXTY_FOUR_K / RTA_BOOT_DATA_SIZE)] - [RTA_BOOT_DATA_SIZE]; - struct Map RIOConnectTable[TOTAL_MAP_ENTRIES]; - struct Map RIOSavedTable[TOTAL_MAP_ENTRIES]; - - /* RTA to host binding table for master/slave operation */ - unsigned long RIOBindTab[MAX_RTA_BINDINGS]; - /* RTA memory dump variable */ - unsigned char RIOMemDump[MEMDUMP_SIZE]; - struct ModuleInfo RIOModuleTypes[MAX_MODULE_TYPES]; - -}; - - -#ifdef linux -#define debug(x) printk x -#else -#define debug(x) kkprintf x -#endif - - - -#define RIO_RESET_INT 0x7d80 - -#endif /* __riodrvr.h */ diff --git a/drivers/staging/generic_serial/rio/rioinfo.h b/drivers/staging/generic_serial/rio/rioinfo.h deleted file mode 100644 index 42ff1e79d96f..000000000000 --- a/drivers/staging/generic_serial/rio/rioinfo.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : rioinfo.h -** SID : 1.2 -** Last Modified : 11/6/98 14:07:49 -** Retrieved : 11/6/98 14:07:50 -** -** ident @(#)rioinfo.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rioinfo_h -#define __rioinfo_h - -/* -** Host card data structure -*/ -struct RioHostInfo { - long location; /* RIO Card Base I/O address */ - long vector; /* RIO Card IRQ vector */ - int bus; /* ISA/EISA/MCA/PCI */ - int mode; /* pointer to host mode - INTERRUPT / POLLED */ - struct old_sgttyb - *Sg; /* pointer to default term characteristics */ -}; - - -/* Mode in rio device info */ -#define INTERRUPTED_MODE 0x01 /* Interrupt is generated */ -#define POLLED_MODE 0x02 /* No interrupt */ -#define AUTO_MODE 0x03 /* Auto mode */ - -#define WORD_ACCESS_MODE 0x10 /* Word Access Mode */ -#define BYTE_ACCESS_MODE 0x20 /* Byte Access Mode */ - - -/* Bus type that RIO supports */ -#define ISA_BUS 0x01 /* The card is ISA */ -#define EISA_BUS 0x02 /* The card is EISA */ -#define MCA_BUS 0x04 /* The card is MCA */ -#define PCI_BUS 0x08 /* The card is PCI */ - -/* -** 11.11.1998 ARG - ESIL ???? part fix -** Moved definition for 'CHAN' here from rioinfo.c (it is now -** called 'DEF_TERM_CHARACTERISTICS'). -*/ - -#define DEF_TERM_CHARACTERISTICS \ -{ \ - B19200, B19200, /* input and output speed */ \ - 'H' - '@', /* erase char */ \ - -1, /* 2nd erase char */ \ - 'U' - '@', /* kill char */ \ - ECHO | CRMOD, /* mode */ \ - 'C' - '@', /* interrupt character */ \ - '\\' - '@', /* quit char */ \ - 'Q' - '@', /* start char */ \ - 'S' - '@', /* stop char */ \ - 'D' - '@', /* EOF */ \ - -1, /* brk */ \ - (LCRTBS | LCRTERA | LCRTKIL | LCTLECH), /* local mode word */ \ - 'Z' - '@', /* process stop */ \ - 'Y' - '@', /* delayed stop */ \ - 'R' - '@', /* reprint line */ \ - 'O' - '@', /* flush output */ \ - 'W' - '@', /* word erase */ \ - 'V' - '@' /* literal next char */ \ -} - -#endif /* __rioinfo_h */ diff --git a/drivers/staging/generic_serial/rio/rioinit.c b/drivers/staging/generic_serial/rio/rioinit.c deleted file mode 100644 index fb62b383f1de..000000000000 --- a/drivers/staging/generic_serial/rio/rioinit.c +++ /dev/null @@ -1,421 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : rioinit.c -** SID : 1.3 -** Last Modified : 11/6/98 10:33:43 -** Retrieved : 11/6/98 10:33:49 -** -** ident @(#)rioinit.c 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - - -#include "linux_compat.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" -#include "rio_linux.h" - -int RIOPCIinit(struct rio_info *p, int Mode); - -static int RIOScrub(int, u8 __iomem *, int); - - -/** -** RIOAssignAT : -** -** Fill out the fields in the p->RIOHosts structure now we know we know -** we have a board present. -** -** bits < 0 indicates 8 bit operation requested, -** bits > 0 indicates 16 bit operation. -*/ - -int RIOAssignAT(struct rio_info *p, int Base, void __iomem *virtAddr, int mode) -{ - int bits; - struct DpRam __iomem *cardp = (struct DpRam __iomem *)virtAddr; - - if ((Base < ONE_MEG) || (mode & BYTE_ACCESS_MODE)) - bits = BYTE_OPERATION; - else - bits = WORD_OPERATION; - - /* - ** Board has passed its scrub test. Fill in all the - ** transient stuff. - */ - p->RIOHosts[p->RIONumHosts].Caddr = virtAddr; - p->RIOHosts[p->RIONumHosts].CardP = virtAddr; - - /* - ** Revision 01 AT host cards don't support WORD operations, - */ - if (readb(&cardp->DpRevision) == 01) - bits = BYTE_OPERATION; - - p->RIOHosts[p->RIONumHosts].Type = RIO_AT; - p->RIOHosts[p->RIONumHosts].Copy = rio_copy_to_card; - /* set this later */ - p->RIOHosts[p->RIONumHosts].Slot = -1; - p->RIOHosts[p->RIONumHosts].Mode = SLOW_LINKS | SLOW_AT_BUS | bits; - writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE , - &p->RIOHosts[p->RIONumHosts].Control); - writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); - writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE, - &p->RIOHosts[p->RIONumHosts].Control); - writeb(0xFF, &p->RIOHosts[p->RIONumHosts].ResetInt); - p->RIOHosts[p->RIONumHosts].UniqueNum = - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[0])&0xFF)<<0)| - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)| - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)| - ((readb(&p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24); - rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum); - - p->RIONumHosts++; - rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Tests Passed at 0x%x\n", Base); - return(1); -} - -static u8 val[] = { -#ifdef VERY_LONG_TEST - 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - 0xa5, 0xff, 0x5a, 0x00, 0xff, 0xc9, 0x36, -#endif - 0xff, 0x00, 0x00 }; - -#define TEST_END sizeof(val) - -/* -** RAM test a board. -** Nothing too complicated, just enough to check it out. -*/ -int RIOBoardTest(unsigned long paddr, void __iomem *caddr, unsigned char type, int slot) -{ - struct DpRam __iomem *DpRam = caddr; - void __iomem *ram[4]; - int size[4]; - int op, bank; - int nbanks; - - rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Reset host type=%d, DpRam=%p, slot=%d\n", - type, DpRam, slot); - - RIOHostReset(type, DpRam, slot); - - /* - ** Scrub the memory. This comes in several banks: - ** DPsram1 - 7000h bytes - ** DPsram2 - 200h bytes - ** DPsram3 - 7000h bytes - ** scratch - 1000h bytes - */ - - rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Setup ram/size arrays\n"); - - size[0] = DP_SRAM1_SIZE; - size[1] = DP_SRAM2_SIZE; - size[2] = DP_SRAM3_SIZE; - size[3] = DP_SCRATCH_SIZE; - - ram[0] = DpRam->DpSram1; - ram[1] = DpRam->DpSram2; - ram[2] = DpRam->DpSram3; - nbanks = (type == RIO_PCI) ? 3 : 4; - if (nbanks == 4) - ram[3] = DpRam->DpScratch; - - - if (nbanks == 3) { - rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Memory: %p(0x%x), %p(0x%x), %p(0x%x)\n", - ram[0], size[0], ram[1], size[1], ram[2], size[2]); - } else { - rio_dprintk (RIO_DEBUG_INIT, "RIO-init: %p(0x%x), %p(0x%x), %p(0x%x), %p(0x%x)\n", - ram[0], size[0], ram[1], size[1], ram[2], size[2], ram[3], size[3]); - } - - /* - ** This scrub operation will test for crosstalk between - ** banks. TEST_END is a magic number, and relates to the offset - ** within the 'val' array used by Scrub. - */ - for (op=0; opMapping[UnitId].Name, "UNKNOWN RTA X-XX", 17); - HostP->Mapping[UnitId].Name[12]='1'+(HostP-p->RIOHosts); - if ((UnitId+1) > 9) { - HostP->Mapping[UnitId].Name[14]='0'+((UnitId+1)/10); - HostP->Mapping[UnitId].Name[15]='0'+((UnitId+1)%10); - } - else { - HostP->Mapping[UnitId].Name[14]='1'+UnitId; - HostP->Mapping[UnitId].Name[15]=0; - } - return 0; -} - -#define RIO_RELEASE "Linux" -#define RELEASE_ID "1.0" - -static struct rioVersion stVersion; - -struct rioVersion *RIOVersid(void) -{ - strlcpy(stVersion.version, "RIO driver for linux V1.0", - sizeof(stVersion.version)); - strlcpy(stVersion.buildDate, "Aug 15 2010", - sizeof(stVersion.buildDate)); - - return &stVersion; -} - -void RIOHostReset(unsigned int Type, struct DpRam __iomem *DpRamP, unsigned int Slot) -{ - /* - ** Reset the Tpu - */ - rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: type 0x%x", Type); - switch ( Type ) { - case RIO_AT: - rio_dprintk (RIO_DEBUG_INIT, " (RIO_AT)\n"); - writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | BYTE_OPERATION | - SLOW_LINKS | SLOW_AT_BUS, &DpRamP->DpControl); - writeb(0xFF, &DpRamP->DpResetTpu); - udelay(3); - rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n"); - writeb(BOOT_FROM_RAM | EXTERNAL_BUS_OFF | INTERRUPT_DISABLE | - BYTE_OPERATION | SLOW_LINKS | SLOW_AT_BUS, &DpRamP->DpControl); - writeb(0xFF, &DpRamP->DpResetTpu); - udelay(3); - break; - case RIO_PCI: - rio_dprintk (RIO_DEBUG_INIT, " (RIO_PCI)\n"); - writeb(RIO_PCI_BOOT_FROM_RAM, &DpRamP->DpControl); - writeb(0xFF, &DpRamP->DpResetInt); - writeb(0xFF, &DpRamP->DpResetTpu); - udelay(100); - break; - default: - rio_dprintk (RIO_DEBUG_INIT, " (UNKNOWN)\n"); - break; - } - return; -} diff --git a/drivers/staging/generic_serial/rio/riointr.c b/drivers/staging/generic_serial/rio/riointr.c deleted file mode 100644 index 2e71aecae206..000000000000 --- a/drivers/staging/generic_serial/rio/riointr.c +++ /dev/null @@ -1,645 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : riointr.c -** SID : 1.2 -** Last Modified : 11/6/98 10:33:44 -** Retrieved : 11/6/98 10:33:49 -** -** ident @(#)riointr.c 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" - - -static void RIOReceive(struct rio_info *, struct Port *); - - -static char *firstchars(char *p, int nch) -{ - static char buf[2][128]; - static int t = 0; - t = !t; - memcpy(buf[t], p, nch); - buf[t][nch] = 0; - return buf[t]; -} - - -#define INCR( P, I ) ((P) = (((P)+(I)) & p->RIOBufferMask)) -/* Enable and start the transmission of packets */ -void RIOTxEnable(char *en) -{ - struct Port *PortP; - struct rio_info *p; - struct tty_struct *tty; - int c; - struct PKT __iomem *PacketP; - unsigned long flags; - - PortP = (struct Port *) en; - p = (struct rio_info *) PortP->p; - tty = PortP->gs.port.tty; - - - rio_dprintk(RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", PortP->PortNum, PortP->gs.xmit_cnt); - - if (!PortP->gs.xmit_cnt) - return; - - - /* This routine is an order of magnitude simpler than the specialix - version. One of the disadvantages is that this version will send - an incomplete packet (usually 64 bytes instead of 72) once for - every 4k worth of data. Let's just say that this won't influence - performance significantly..... */ - - rio_spin_lock_irqsave(&PortP->portSem, flags); - - while (can_add_transmit(&PacketP, PortP)) { - c = PortP->gs.xmit_cnt; - if (c > PKT_MAX_DATA_LEN) - c = PKT_MAX_DATA_LEN; - - /* Don't copy past the end of the source buffer */ - if (c > SERIAL_XMIT_SIZE - PortP->gs.xmit_tail) - c = SERIAL_XMIT_SIZE - PortP->gs.xmit_tail; - - { - int t; - t = (c > 10) ? 10 : c; - - rio_dprintk(RIO_DEBUG_INTR, "rio: tx port %d: copying %d chars: %s - %s\n", PortP->PortNum, c, firstchars(PortP->gs.xmit_buf + PortP->gs.xmit_tail, t), firstchars(PortP->gs.xmit_buf + PortP->gs.xmit_tail + c - t, t)); - } - /* If for one reason or another, we can't copy more data, - we're done! */ - if (c == 0) - break; - - rio_memcpy_toio(PortP->HostP->Caddr, PacketP->data, PortP->gs.xmit_buf + PortP->gs.xmit_tail, c); - /* udelay (1); */ - - writeb(c, &(PacketP->len)); - if (!(PortP->State & RIO_DELETED)) { - add_transmit(PortP); - /* - ** Count chars tx'd for port statistics reporting - */ - if (PortP->statsGather) - PortP->txchars += c; - } - PortP->gs.xmit_tail = (PortP->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE - 1); - PortP->gs.xmit_cnt -= c; - } - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - - if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN)) - tty_wakeup(PortP->gs.port.tty); - -} - - -/* -** RIO Host Service routine. Does all the work traditionally associated with an -** interrupt. -*/ -static int RupIntr; -static int RxIntr; -static int TxIntr; - -void RIOServiceHost(struct rio_info *p, struct Host *HostP) -{ - rio_spin_lock(&HostP->HostLock); - if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { - static int t = 0; - rio_spin_unlock(&HostP->HostLock); - if ((t++ % 200) == 0) - rio_dprintk(RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int) HostP->Flags); - return; - } - rio_spin_unlock(&HostP->HostLock); - - if (readw(&HostP->ParmMapP->rup_intr)) { - writew(0, &HostP->ParmMapP->rup_intr); - p->RIORupCount++; - RupIntr++; - rio_dprintk(RIO_DEBUG_INTR, "rio: RUP interrupt on host %Zd\n", HostP - p->RIOHosts); - RIOPollHostCommands(p, HostP); - } - - if (readw(&HostP->ParmMapP->rx_intr)) { - int port; - - writew(0, &HostP->ParmMapP->rx_intr); - p->RIORxCount++; - RxIntr++; - - rio_dprintk(RIO_DEBUG_INTR, "rio: RX interrupt on host %Zd\n", HostP - p->RIOHosts); - /* - ** Loop through every port. If the port is mapped into - ** the system ( i.e. has /dev/ttyXXXX associated ) then it is - ** worth checking. If the port isn't open, grab any packets - ** hanging on its receive queue and stuff them on the free - ** list; check for commands on the way. - */ - for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) { - struct Port *PortP = p->RIOPortp[port]; - struct tty_struct *ttyP; - struct PKT __iomem *PacketP; - - /* - ** not mapped in - most of the RIOPortp[] information - ** has not been set up! - ** Optimise: ports come in bundles of eight. - */ - if (!PortP->Mapped) { - port += 7; - continue; /* with the next port */ - } - - /* - ** If the host board isn't THIS host board, check the next one. - ** optimise: ports come in bundles of eight. - */ - if (PortP->HostP != HostP) { - port += 7; - continue; - } - - /* - ** Let us see - is the port open? If not, then don't service it. - */ - if (!(PortP->PortState & PORT_ISOPEN)) { - continue; - } - - /* - ** find corresponding tty structure. The process of mapping - ** the ports puts these here. - */ - ttyP = PortP->gs.port.tty; - - /* - ** Lock the port before we begin working on it. - */ - rio_spin_lock(&PortP->portSem); - - /* - ** Process received data if there is any. - */ - if (can_remove_receive(&PacketP, PortP)) - RIOReceive(p, PortP); - - /* - ** If there is no data left to be read from the port, and - ** it's handshake bit is set, then we must clear the handshake, - ** so that that downstream RTA is re-enabled. - */ - if (!can_remove_receive(&PacketP, PortP) && (readw(&PortP->PhbP->handshake) == PHB_HANDSHAKE_SET)) { - /* - ** MAGIC! ( Basically, handshake the RX buffer, so that - ** the RTAs upstream can be re-enabled. ) - */ - rio_dprintk(RIO_DEBUG_INTR, "Set RX handshake bit\n"); - writew(PHB_HANDSHAKE_SET | PHB_HANDSHAKE_RESET, &PortP->PhbP->handshake); - } - rio_spin_unlock(&PortP->portSem); - } - } - - if (readw(&HostP->ParmMapP->tx_intr)) { - int port; - - writew(0, &HostP->ParmMapP->tx_intr); - - p->RIOTxCount++; - TxIntr++; - rio_dprintk(RIO_DEBUG_INTR, "rio: TX interrupt on host %Zd\n", HostP - p->RIOHosts); - - /* - ** Loop through every port. - ** If the port is mapped into the system ( i.e. has /dev/ttyXXXX - ** associated ) then it is worth checking. - */ - for (port = p->RIOFirstPortsBooted; port < p->RIOLastPortsBooted + PORTS_PER_RTA; port++) { - struct Port *PortP = p->RIOPortp[port]; - struct tty_struct *ttyP; - struct PKT __iomem *PacketP; - - /* - ** not mapped in - most of the RIOPortp[] information - ** has not been set up! - */ - if (!PortP->Mapped) { - port += 7; - continue; /* with the next port */ - } - - /* - ** If the host board isn't running, then its data structures - ** are no use to us - continue quietly. - */ - if (PortP->HostP != HostP) { - port += 7; - continue; /* with the next port */ - } - - /* - ** Let us see - is the port open? If not, then don't service it. - */ - if (!(PortP->PortState & PORT_ISOPEN)) { - continue; - } - - rio_dprintk(RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port); - /* - ** Lock the port before we begin working on it. - */ - rio_spin_lock(&PortP->portSem); - - /* - ** If we can't add anything to the transmit queue, then - ** we need do none of this processing. - */ - if (!can_add_transmit(&PacketP, PortP)) { - rio_dprintk(RIO_DEBUG_INTR, "Can't add to port, so skipping.\n"); - rio_spin_unlock(&PortP->portSem); - continue; - } - - /* - ** find corresponding tty structure. The process of mapping - ** the ports puts these here. - */ - ttyP = PortP->gs.port.tty; - /* If ttyP is NULL, the port is getting closed. Forget about it. */ - if (!ttyP) { - rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n"); - rio_spin_unlock(&PortP->portSem); - continue; - } - /* - ** If there is more room available we start up the transmit - ** data process again. This can be direct I/O, if the cookmode - ** is set to COOK_RAW or COOK_MEDIUM, or will be a call to the - ** riotproc( T_OUTPUT ) if we are in COOK_WELL mode, to fetch - ** characters via the line discipline. We must always call - ** the line discipline, - ** so that user input characters can be echoed correctly. - ** - ** ++++ Update +++++ - ** With the advent of double buffering, we now see if - ** TxBufferOut-In is non-zero. If so, then we copy a packet - ** to the output place, and set it going. If this empties - ** the buffer, then we must issue a wakeup( ) on OUT. - ** If it frees space in the buffer then we must issue - ** a wakeup( ) on IN. - ** - ** ++++ Extra! Extra! If PortP->WflushFlag is set, then we - ** have to send a WFLUSH command down the PHB, to mark the - ** end point of a WFLUSH. We also need to clear out any - ** data from the double buffer! ( note that WflushFlag is a - ** *count* of the number of WFLUSH commands outstanding! ) - ** - ** ++++ And there's more! - ** If an RTA is powered off, then on again, and rebooted, - ** whilst it has ports open, then we need to re-open the ports. - ** ( reasonable enough ). We can't do this when we spot the - ** re-boot, in interrupt time, because the queue is probably - ** full. So, when we come in here, we need to test if any - ** ports are in this condition, and re-open the port before - ** we try to send any more data to it. Now, the re-booted - ** RTA will be discarding packets from the PHB until it - ** receives this open packet, but don't worry tooo much - ** about that. The one thing that is interesting is the - ** combination of this effect and the WFLUSH effect! - */ - /* For now don't handle RTA reboots. -- REW. - Reenabled. Otherwise RTA reboots didn't work. Duh. -- REW */ - if (PortP->MagicFlags) { - if (PortP->MagicFlags & MAGIC_REBOOT) { - /* - ** well, the RTA has been rebooted, and there is room - ** on its queue to add the open packet that is required. - ** - ** The messy part of this line is trying to decide if - ** we need to call the Param function as a tty or as - ** a modem. - ** DONT USE CLOCAL AS A TEST FOR THIS! - ** - ** If we can't param the port, then move on to the - ** next port. - */ - PortP->InUse = NOT_INUSE; - - rio_spin_unlock(&PortP->portSem); - if (RIOParam(PortP, RIOC_OPEN, ((PortP->Cor2Copy & (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) == (RIOC_COR2_RTSFLOW | RIOC_COR2_CTSFLOW)) ? 1 : 0, DONT_SLEEP) == RIO_FAIL) - continue; /* with next port */ - rio_spin_lock(&PortP->portSem); - PortP->MagicFlags &= ~MAGIC_REBOOT; - } - - /* - ** As mentioned above, this is a tacky hack to cope - ** with WFLUSH - */ - if (PortP->WflushFlag) { - rio_dprintk(RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n"); - - if (PortP->InUse) - rio_dprintk(RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n"); - } - - while (PortP->WflushFlag && can_add_transmit(&PacketP, PortP) && (PortP->InUse == NOT_INUSE)) { - int p; - struct PktCmd __iomem *PktCmdP; - - rio_dprintk(RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n"); - /* - ** make it look just like a WFLUSH command - */ - PktCmdP = (struct PktCmd __iomem *) &PacketP->data[0]; - - writeb(RIOC_WFLUSH, &PktCmdP->Command); - - p = PortP->HostPort % (u16) PORTS_PER_RTA; - - /* - ** If second block of ports for 16 port RTA, add 8 - ** to index 8-15. - */ - if (PortP->SecondBlock) - p += PORTS_PER_RTA; - - writeb(p, &PktCmdP->PhbNum); - - /* - ** to make debuggery easier - */ - writeb('W', &PacketP->data[2]); - writeb('F', &PacketP->data[3]); - writeb('L', &PacketP->data[4]); - writeb('U', &PacketP->data[5]); - writeb('S', &PacketP->data[6]); - writeb('H', &PacketP->data[7]); - writeb(' ', &PacketP->data[8]); - writeb('0' + PortP->WflushFlag, &PacketP->data[9]); - writeb(' ', &PacketP->data[10]); - writeb(' ', &PacketP->data[11]); - writeb('\0', &PacketP->data[12]); - - /* - ** its two bytes long! - */ - writeb(PKT_CMD_BIT | 2, &PacketP->len); - - /* - ** queue it! - */ - if (!(PortP->State & RIO_DELETED)) { - add_transmit(PortP); - /* - ** Count chars tx'd for port statistics reporting - */ - if (PortP->statsGather) - PortP->txchars += 2; - } - - if (--(PortP->WflushFlag) == 0) { - PortP->MagicFlags &= ~MAGIC_FLUSH; - } - - rio_dprintk(RIO_DEBUG_INTR, "Wflush count now stands at %d\n", PortP->WflushFlag); - } - if (PortP->MagicFlags & MORE_OUTPUT_EYGOR) { - if (PortP->MagicFlags & MAGIC_FLUSH) { - PortP->MagicFlags |= MORE_OUTPUT_EYGOR; - } else { - if (!can_add_transmit(&PacketP, PortP)) { - rio_spin_unlock(&PortP->portSem); - continue; - } - rio_spin_unlock(&PortP->portSem); - RIOTxEnable((char *) PortP); - rio_spin_lock(&PortP->portSem); - PortP->MagicFlags &= ~MORE_OUTPUT_EYGOR; - } - } - } - - - /* - ** If we can't add anything to the transmit queue, then - ** we need do none of the remaining processing. - */ - if (!can_add_transmit(&PacketP, PortP)) { - rio_spin_unlock(&PortP->portSem); - continue; - } - - rio_spin_unlock(&PortP->portSem); - RIOTxEnable((char *) PortP); - } - } -} - -/* -** Routine for handling received data for tty drivers -*/ -static void RIOReceive(struct rio_info *p, struct Port *PortP) -{ - struct tty_struct *TtyP; - unsigned short transCount; - struct PKT __iomem *PacketP; - register unsigned int DataCnt; - unsigned char __iomem *ptr; - unsigned char *buf; - int copied = 0; - - static int intCount, RxIntCnt; - - /* - ** The receive data process is to remove packets from the - ** PHB until there aren't any more or the current cblock - ** is full. When this occurs, there will be some left over - ** data in the packet, that we must do something with. - ** As we haven't unhooked the packet from the read list - ** yet, we can just leave the packet there, having first - ** made a note of how far we got. This means that we need - ** a pointer per port saying where we start taking the - ** data from - this will normally be zero, but when we - ** run out of space it will be set to the offset of the - ** next byte to copy from the packet data area. The packet - ** length field is decremented by the number of bytes that - ** we successfully removed from the packet. When this reaches - ** zero, we reset the offset pointer to be zero, and free - ** the packet from the front of the queue. - */ - - intCount++; - - TtyP = PortP->gs.port.tty; - if (!TtyP) { - rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n"); - return; - } - - if (PortP->State & RIO_THROTTLE_RX) { - rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n"); - return; - } - - if (PortP->State & RIO_DELETED) { - while (can_remove_receive(&PacketP, PortP)) { - remove_receive(PortP); - put_free_end(PortP->HostP, PacketP); - } - } else { - /* - ** loop, just so long as: - ** i ) there's some data ( i.e. can_remove_receive ) - ** ii ) we haven't been blocked - ** iii ) there's somewhere to put the data - ** iv ) we haven't outstayed our welcome - */ - transCount = 1; - while (can_remove_receive(&PacketP, PortP) - && transCount) { - RxIntCnt++; - - /* - ** check that it is not a command! - */ - if (readb(&PacketP->len) & PKT_CMD_BIT) { - rio_dprintk(RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n"); - /* rio_dprint(RIO_DEBUG_INTR, (" sysport = %d\n", p->RIOPortp->PortNum)); */ - rio_dprintk(RIO_DEBUG_INTR, " dest_unit = %d\n", readb(&PacketP->dest_unit)); - rio_dprintk(RIO_DEBUG_INTR, " dest_port = %d\n", readb(&PacketP->dest_port)); - rio_dprintk(RIO_DEBUG_INTR, " src_unit = %d\n", readb(&PacketP->src_unit)); - rio_dprintk(RIO_DEBUG_INTR, " src_port = %d\n", readb(&PacketP->src_port)); - rio_dprintk(RIO_DEBUG_INTR, " len = %d\n", readb(&PacketP->len)); - rio_dprintk(RIO_DEBUG_INTR, " control = %d\n", readb(&PacketP->control)); - rio_dprintk(RIO_DEBUG_INTR, " csum = %d\n", readw(&PacketP->csum)); - rio_dprintk(RIO_DEBUG_INTR, " data bytes: "); - for (DataCnt = 0; DataCnt < PKT_MAX_DATA_LEN; DataCnt++) - rio_dprintk(RIO_DEBUG_INTR, "%d\n", readb(&PacketP->data[DataCnt])); - remove_receive(PortP); - put_free_end(PortP->HostP, PacketP); - continue; /* with next packet */ - } - - /* - ** How many characters can we move 'upstream' ? - ** - ** Determine the minimum of the amount of data - ** available and the amount of space in which to - ** put it. - ** - ** 1. Get the packet length by masking 'len' - ** for only the length bits. - ** 2. Available space is [buffer size] - [space used] - ** - ** Transfer count is the minimum of packet length - ** and available space. - */ - - transCount = tty_buffer_request_room(TtyP, readb(&PacketP->len) & PKT_LEN_MASK); - rio_dprintk(RIO_DEBUG_REC, "port %d: Copy %d bytes\n", PortP->PortNum, transCount); - /* - ** To use the following 'kkprintfs' for debugging - change the '#undef' - ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the - ** driver). - */ - ptr = (unsigned char __iomem *) PacketP->data + PortP->RxDataStart; - - tty_prepare_flip_string(TtyP, &buf, transCount); - rio_memcpy_fromio(buf, ptr, transCount); - PortP->RxDataStart += transCount; - writeb(readb(&PacketP->len)-transCount, &PacketP->len); - copied += transCount; - - - - if (readb(&PacketP->len) == 0) { - /* - ** If we have emptied the packet, then we can - ** free it, and reset the start pointer for - ** the next packet. - */ - remove_receive(PortP); - put_free_end(PortP->HostP, PacketP); - PortP->RxDataStart = 0; - } - } - } - if (copied) { - rio_dprintk(RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied); - tty_flip_buffer_push(TtyP); - } - - return; -} - diff --git a/drivers/staging/generic_serial/rio/rioioctl.h b/drivers/staging/generic_serial/rio/rioioctl.h deleted file mode 100644 index e8af5b30519e..000000000000 --- a/drivers/staging/generic_serial/rio/rioioctl.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : rioioctl.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:13 -** Retrieved : 11/6/98 11:34:22 -** -** ident @(#)rioioctl.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rioioctl_h__ -#define __rioioctl_h__ - -/* -** RIO device driver - user ioctls and associated structures. -*/ - -struct portStats { - int port; - int gather; - unsigned long txchars; - unsigned long rxchars; - unsigned long opens; - unsigned long closes; - unsigned long ioctls; -}; - -#define RIOC ('R'<<8)|('i'<<16)|('o'<<24) - -#define RIO_QUICK_CHECK (RIOC | 105) -#define RIO_GATHER_PORT_STATS (RIOC | 193) -#define RIO_RESET_PORT_STATS (RIOC | 194) -#define RIO_GET_PORT_STATS (RIOC | 195) - -#endif /* __rioioctl_h__ */ diff --git a/drivers/staging/generic_serial/rio/rioparam.c b/drivers/staging/generic_serial/rio/rioparam.c deleted file mode 100644 index 6415f3f32a72..000000000000 --- a/drivers/staging/generic_serial/rio/rioparam.c +++ /dev/null @@ -1,663 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : rioparam.c -** SID : 1.3 -** Last Modified : 11/6/98 10:33:45 -** Retrieved : 11/6/98 10:33:50 -** -** ident @(#)rioparam.c 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" -#include "param.h" - - - -/* -** The Scam, based on email from jeremyr@bugs.specialix.co.uk.... -** -** To send a command on a particular port, you put a packet with the -** command bit set onto the port. The command bit is in the len field, -** and gets ORed in with the actual byte count. -** -** When you send a packet with the command bit set the first -** data byte (data[0]) is interpreted as the command to execute. -** It also governs what data structure overlay should accompany the packet. -** Commands are defined in cirrus/cirrus.h -** -** If you want the command to pre-emt data already on the queue for the -** port, set the pre-emptive bit in conjunction with the command bit. -** It is not defined what will happen if you set the preemptive bit -** on a packet that is NOT a command. -** -** Pre-emptive commands should be queued at the head of the queue using -** add_start(), whereas normal commands and data are enqueued using -** add_end(). -** -** Most commands do not use the remaining bytes in the data array. The -** exceptions are OPEN MOPEN and CONFIG. (NB. As with the SI CONFIG and -** OPEN are currently analogous). With these three commands the following -** 11 data bytes are all used to pass config information such as baud rate etc. -** The fields are also defined in cirrus.h. Some contain straightforward -** information such as the transmit XON character. Two contain the transmit and -** receive baud rates respectively. For most baud rates there is a direct -** mapping between the rates defined in and the byte in the -** packet. There are additional (non UNIX-standard) rates defined in -** /u/dos/rio/cirrus/h/brates.h. -** -** The rest of the data fields contain approximations to the Cirrus registers -** that are used to program number of bits etc. Each registers bit fields is -** defined in cirrus.h. -** -** NB. Only use those bits that are defined as being driver specific -** or common to the RTA and the driver. -** -** All commands going from RTA->Host will be dealt with by the Host code - you -** will never see them. As with the SI there will be three fields to look out -** for in each phb (not yet defined - needs defining a.s.a.p). -** -** modem_status - current state of handshake pins. -** -** port_status - current port status - equivalent to hi_stat for SI, indicates -** if port is IDLE_OPEN, IDLE_CLOSED etc. -** -** break_status - bit X set if break has been received. -** -** Happy hacking. -** -*/ - -/* -** RIOParam is used to open or configure a port. You pass it a PortP, -** which will have a tty struct attached to it. You also pass a command, -** either OPEN or CONFIG. The port's setup is taken from the t_ fields -** of the tty struct inside the PortP, and the port is either opened -** or re-configured. You must also tell RIOParam if the device is a modem -** device or not (i.e. top bit of minor number set or clear - take special -** care when deciding on this!). -** RIOParam neither flushes nor waits for drain, and is NOT preemptive. -** -** RIOParam assumes it will be called at splrio(), and also assumes -** that CookMode is set correctly in the port structure. -** -** NB. for MPX -** tty lock must NOT have been previously acquired. -*/ -int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag) -{ - struct tty_struct *TtyP; - int retval; - struct phb_param __iomem *phb_param_ptr; - struct PKT __iomem *PacketP; - int res; - u8 Cor1 = 0, Cor2 = 0, Cor4 = 0, Cor5 = 0; - u8 TxXon = 0, TxXoff = 0, RxXon = 0, RxXoff = 0; - u8 LNext = 0, TxBaud = 0, RxBaud = 0; - int retries = 0xff; - unsigned long flags; - - func_enter(); - - TtyP = PortP->gs.port.tty; - - rio_dprintk(RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n", PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP); - - if (!TtyP) { - rio_dprintk(RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n"); - - func_exit(); - - return RIO_FAIL; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - - if (cmd == RIOC_OPEN) { - /* - ** If the port is set to store or lock the parameters, and it is - ** paramed with OPEN, we want to restore the saved port termio, but - ** only if StoredTermio has been saved, i.e. NOT 1st open after reboot. - */ - } - - /* - ** wait for space - */ - while (!(res = can_add_transmit(&PacketP, PortP)) || (PortP->InUse != NOT_INUSE)) { - if (retries-- <= 0) { - break; - } - if (PortP->InUse != NOT_INUSE) { - rio_dprintk(RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n"); - } - - if (!res) { - rio_dprintk(RIO_DEBUG_PARAM, "Port has no space on transmit queue\n"); - } - - if (SleepFlag != OK_TO_SLEEP) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - func_exit(); - - return RIO_FAIL; - } - - rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - retval = RIODelay(PortP, HUNDRED_MS); - rio_spin_lock_irqsave(&PortP->portSem, flags); - if (retval == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - func_exit(); - return -EINTR; - } - if (PortP->State & RIO_DELETED) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - func_exit(); - return 0; - } - } - - if (!res) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - func_exit(); - - return RIO_FAIL; - } - - rio_dprintk(RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n", res); - rio_dprintk(RIO_DEBUG_PARAM, "Packet is %p\n", PacketP); - - phb_param_ptr = (struct phb_param __iomem *) PacketP->data; - - - switch (TtyP->termios->c_cflag & CSIZE) { - case CS5: - { - rio_dprintk(RIO_DEBUG_PARAM, "5 bit data\n"); - Cor1 |= RIOC_COR1_5BITS; - break; - } - case CS6: - { - rio_dprintk(RIO_DEBUG_PARAM, "6 bit data\n"); - Cor1 |= RIOC_COR1_6BITS; - break; - } - case CS7: - { - rio_dprintk(RIO_DEBUG_PARAM, "7 bit data\n"); - Cor1 |= RIOC_COR1_7BITS; - break; - } - case CS8: - { - rio_dprintk(RIO_DEBUG_PARAM, "8 bit data\n"); - Cor1 |= RIOC_COR1_8BITS; - break; - } - } - - if (TtyP->termios->c_cflag & CSTOPB) { - rio_dprintk(RIO_DEBUG_PARAM, "2 stop bits\n"); - Cor1 |= RIOC_COR1_2STOP; - } else { - rio_dprintk(RIO_DEBUG_PARAM, "1 stop bit\n"); - Cor1 |= RIOC_COR1_1STOP; - } - - if (TtyP->termios->c_cflag & PARENB) { - rio_dprintk(RIO_DEBUG_PARAM, "Enable parity\n"); - Cor1 |= RIOC_COR1_NORMAL; - } else { - rio_dprintk(RIO_DEBUG_PARAM, "Disable parity\n"); - Cor1 |= RIOC_COR1_NOP; - } - if (TtyP->termios->c_cflag & PARODD) { - rio_dprintk(RIO_DEBUG_PARAM, "Odd parity\n"); - Cor1 |= RIOC_COR1_ODD; - } else { - rio_dprintk(RIO_DEBUG_PARAM, "Even parity\n"); - Cor1 |= RIOC_COR1_EVEN; - } - - /* - ** COR 2 - */ - if (TtyP->termios->c_iflag & IXON) { - rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop output control\n"); - Cor2 |= RIOC_COR2_IXON; - } else { - if (PortP->Config & RIO_IXON) { - rio_dprintk(RIO_DEBUG_PARAM, "Force enable start/stop output control\n"); - Cor2 |= RIOC_COR2_IXON; - } else - rio_dprintk(RIO_DEBUG_PARAM, "IXON has been disabled.\n"); - } - - if (TtyP->termios->c_iflag & IXANY) { - if (PortP->Config & RIO_IXANY) { - rio_dprintk(RIO_DEBUG_PARAM, "Enable any key to restart output\n"); - Cor2 |= RIOC_COR2_IXANY; - } else - rio_dprintk(RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n"); - } - - if (TtyP->termios->c_iflag & IXOFF) { - rio_dprintk(RIO_DEBUG_PARAM, "Enable start/stop input control 2\n"); - Cor2 |= RIOC_COR2_IXOFF; - } - - if (TtyP->termios->c_cflag & HUPCL) { - rio_dprintk(RIO_DEBUG_PARAM, "Hangup on last close\n"); - Cor2 |= RIOC_COR2_HUPCL; - } - - if (C_CRTSCTS(TtyP)) { - rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n"); - Cor2 |= RIOC_COR2_CTSFLOW; - Cor2 |= RIOC_COR2_RTSFLOW; - } else { - rio_dprintk(RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n"); - Cor2 &= ~RIOC_COR2_CTSFLOW; - Cor2 &= ~RIOC_COR2_RTSFLOW; - } - - - if (TtyP->termios->c_cflag & CLOCAL) { - rio_dprintk(RIO_DEBUG_PARAM, "Local line\n"); - } else { - rio_dprintk(RIO_DEBUG_PARAM, "Possible Modem line\n"); - } - - /* - ** COR 4 (there is no COR 3) - */ - if (TtyP->termios->c_iflag & IGNBRK) { - rio_dprintk(RIO_DEBUG_PARAM, "Ignore break condition\n"); - Cor4 |= RIOC_COR4_IGNBRK; - } - if (!(TtyP->termios->c_iflag & BRKINT)) { - rio_dprintk(RIO_DEBUG_PARAM, "Break generates NULL condition\n"); - Cor4 |= RIOC_COR4_NBRKINT; - } else { - rio_dprintk(RIO_DEBUG_PARAM, "Interrupt on break condition\n"); - } - - if (TtyP->termios->c_iflag & INLCR) { - rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage return on input\n"); - Cor4 |= RIOC_COR4_INLCR; - } - - if (TtyP->termios->c_iflag & IGNCR) { - rio_dprintk(RIO_DEBUG_PARAM, "Ignore carriage return on input\n"); - Cor4 |= RIOC_COR4_IGNCR; - } - - if (TtyP->termios->c_iflag & ICRNL) { - rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on input\n"); - Cor4 |= RIOC_COR4_ICRNL; - } - if (TtyP->termios->c_iflag & IGNPAR) { - rio_dprintk(RIO_DEBUG_PARAM, "Ignore characters with parity errors\n"); - Cor4 |= RIOC_COR4_IGNPAR; - } - if (TtyP->termios->c_iflag & PARMRK) { - rio_dprintk(RIO_DEBUG_PARAM, "Mark parity errors\n"); - Cor4 |= RIOC_COR4_PARMRK; - } - - /* - ** Set the RAISEMOD flag to ensure that the modem lines are raised - ** on reception of a config packet. - ** The download code handles the zero baud condition. - */ - Cor4 |= RIOC_COR4_RAISEMOD; - - /* - ** COR 5 - */ - - Cor5 = RIOC_COR5_CMOE; - - /* - ** Set to monitor tbusy/tstop (or not). - */ - - if (PortP->MonitorTstate) - Cor5 |= RIOC_COR5_TSTATE_ON; - else - Cor5 |= RIOC_COR5_TSTATE_OFF; - - /* - ** Could set LNE here if you wanted LNext processing. SVR4 will use it. - */ - if (TtyP->termios->c_iflag & ISTRIP) { - rio_dprintk(RIO_DEBUG_PARAM, "Strip input characters\n"); - if (!(PortP->State & RIO_TRIAD_MODE)) { - Cor5 |= RIOC_COR5_ISTRIP; - } - } - - if (TtyP->termios->c_oflag & ONLCR) { - rio_dprintk(RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n"); - if (PortP->CookMode == COOK_MEDIUM) - Cor5 |= RIOC_COR5_ONLCR; - } - if (TtyP->termios->c_oflag & OCRNL) { - rio_dprintk(RIO_DEBUG_PARAM, "Map carriage return to newline on output\n"); - if (PortP->CookMode == COOK_MEDIUM) - Cor5 |= RIOC_COR5_OCRNL; - } - if ((TtyP->termios->c_oflag & TABDLY) == TAB3) { - rio_dprintk(RIO_DEBUG_PARAM, "Tab delay 3 set\n"); - if (PortP->CookMode == COOK_MEDIUM) - Cor5 |= RIOC_COR5_TAB3; - } - - /* - ** Flow control bytes. - */ - TxXon = TtyP->termios->c_cc[VSTART]; - TxXoff = TtyP->termios->c_cc[VSTOP]; - RxXon = TtyP->termios->c_cc[VSTART]; - RxXoff = TtyP->termios->c_cc[VSTOP]; - /* - ** LNEXT byte - */ - LNext = 0; - - /* - ** Baud rate bytes - */ - rio_dprintk(RIO_DEBUG_PARAM, "Mapping of rx/tx baud %x (%x)\n", TtyP->termios->c_cflag, CBAUD); - - switch (TtyP->termios->c_cflag & CBAUD) { -#define e(b) case B ## b : RxBaud = TxBaud = RIO_B ## b ;break - e(50); - e(75); - e(110); - e(134); - e(150); - e(200); - e(300); - e(600); - e(1200); - e(1800); - e(2400); - e(4800); - e(9600); - e(19200); - e(38400); - e(57600); - e(115200); /* e(230400);e(460800); e(921600); */ - } - - rio_dprintk(RIO_DEBUG_PARAM, "tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud); - - - /* - ** Leftovers - */ - if (TtyP->termios->c_cflag & CREAD) - rio_dprintk(RIO_DEBUG_PARAM, "Enable receiver\n"); -#ifdef RCV1EN - if (TtyP->termios->c_cflag & RCV1EN) - rio_dprintk(RIO_DEBUG_PARAM, "RCV1EN (?)\n"); -#endif -#ifdef XMT1EN - if (TtyP->termios->c_cflag & XMT1EN) - rio_dprintk(RIO_DEBUG_PARAM, "XMT1EN (?)\n"); -#endif - if (TtyP->termios->c_lflag & ISIG) - rio_dprintk(RIO_DEBUG_PARAM, "Input character signal generating enabled\n"); - if (TtyP->termios->c_lflag & ICANON) - rio_dprintk(RIO_DEBUG_PARAM, "Canonical input: erase and kill enabled\n"); - if (TtyP->termios->c_lflag & XCASE) - rio_dprintk(RIO_DEBUG_PARAM, "Canonical upper/lower presentation\n"); - if (TtyP->termios->c_lflag & ECHO) - rio_dprintk(RIO_DEBUG_PARAM, "Enable input echo\n"); - if (TtyP->termios->c_lflag & ECHOE) - rio_dprintk(RIO_DEBUG_PARAM, "Enable echo erase\n"); - if (TtyP->termios->c_lflag & ECHOK) - rio_dprintk(RIO_DEBUG_PARAM, "Enable echo kill\n"); - if (TtyP->termios->c_lflag & ECHONL) - rio_dprintk(RIO_DEBUG_PARAM, "Enable echo newline\n"); - if (TtyP->termios->c_lflag & NOFLSH) - rio_dprintk(RIO_DEBUG_PARAM, "Disable flush after interrupt or quit\n"); -#ifdef TOSTOP - if (TtyP->termios->c_lflag & TOSTOP) - rio_dprintk(RIO_DEBUG_PARAM, "Send SIGTTOU for background output\n"); -#endif -#ifdef XCLUDE - if (TtyP->termios->c_lflag & XCLUDE) - rio_dprintk(RIO_DEBUG_PARAM, "Exclusive use of this line\n"); -#endif - if (TtyP->termios->c_iflag & IUCLC) - rio_dprintk(RIO_DEBUG_PARAM, "Map uppercase to lowercase on input\n"); - if (TtyP->termios->c_oflag & OPOST) - rio_dprintk(RIO_DEBUG_PARAM, "Enable output post-processing\n"); - if (TtyP->termios->c_oflag & OLCUC) - rio_dprintk(RIO_DEBUG_PARAM, "Map lowercase to uppercase on output\n"); - if (TtyP->termios->c_oflag & ONOCR) - rio_dprintk(RIO_DEBUG_PARAM, "No carriage return output at column 0\n"); - if (TtyP->termios->c_oflag & ONLRET) - rio_dprintk(RIO_DEBUG_PARAM, "Newline performs carriage return function\n"); - if (TtyP->termios->c_oflag & OFILL) - rio_dprintk(RIO_DEBUG_PARAM, "Use fill characters for delay\n"); - if (TtyP->termios->c_oflag & OFDEL) - rio_dprintk(RIO_DEBUG_PARAM, "Fill character is DEL\n"); - if (TtyP->termios->c_oflag & NLDLY) - rio_dprintk(RIO_DEBUG_PARAM, "Newline delay set\n"); - if (TtyP->termios->c_oflag & CRDLY) - rio_dprintk(RIO_DEBUG_PARAM, "Carriage return delay set\n"); - if (TtyP->termios->c_oflag & TABDLY) - rio_dprintk(RIO_DEBUG_PARAM, "Tab delay set\n"); - /* - ** These things are kind of useful in a later life! - */ - PortP->Cor2Copy = Cor2; - - if (PortP->State & RIO_DELETED) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - func_exit(); - - return RIO_FAIL; - } - - /* - ** Actually write the info into the packet to be sent - */ - writeb(cmd, &phb_param_ptr->Cmd); - writeb(Cor1, &phb_param_ptr->Cor1); - writeb(Cor2, &phb_param_ptr->Cor2); - writeb(Cor4, &phb_param_ptr->Cor4); - writeb(Cor5, &phb_param_ptr->Cor5); - writeb(TxXon, &phb_param_ptr->TxXon); - writeb(RxXon, &phb_param_ptr->RxXon); - writeb(TxXoff, &phb_param_ptr->TxXoff); - writeb(RxXoff, &phb_param_ptr->RxXoff); - writeb(LNext, &phb_param_ptr->LNext); - writeb(TxBaud, &phb_param_ptr->TxBaud); - writeb(RxBaud, &phb_param_ptr->RxBaud); - - /* - ** Set the length/command field - */ - writeb(12 | PKT_CMD_BIT, &PacketP->len); - - /* - ** The packet is formed - now, whack it off - ** to its final destination: - */ - add_transmit(PortP); - /* - ** Count characters transmitted for port statistics reporting - */ - if (PortP->statsGather) - PortP->txchars += 12; - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - - rio_dprintk(RIO_DEBUG_PARAM, "add_transmit returned.\n"); - /* - ** job done. - */ - func_exit(); - - return 0; -} - - -/* -** We can add another packet to a transmit queue if the packet pointer pointed -** to by the TxAdd pointer has PKT_IN_USE clear in its address. -*/ -int can_add_transmit(struct PKT __iomem **PktP, struct Port *PortP) -{ - struct PKT __iomem *tp; - - *PktP = tp = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->TxAdd)); - - return !((unsigned long) tp & PKT_IN_USE); -} - -/* -** To add a packet to the queue, you set the PKT_IN_USE bit in the address, -** and then move the TxAdd pointer along one position to point to the next -** packet pointer. You must wrap the pointer from the end back to the start. -*/ -void add_transmit(struct Port *PortP) -{ - if (readw(PortP->TxAdd) & PKT_IN_USE) { - rio_dprintk(RIO_DEBUG_PARAM, "add_transmit: Packet has been stolen!"); - } - writew(readw(PortP->TxAdd) | PKT_IN_USE, PortP->TxAdd); - PortP->TxAdd = (PortP->TxAdd == PortP->TxEnd) ? PortP->TxStart : PortP->TxAdd + 1; - writew(RIO_OFF(PortP->Caddr, PortP->TxAdd), &PortP->PhbP->tx_add); -} - -/**************************************** - * Put a packet onto the end of the - * free list - ****************************************/ -void put_free_end(struct Host *HostP, struct PKT __iomem *PktP) -{ - struct rio_free_list __iomem *tmp_pointer; - unsigned short old_end, new_end; - unsigned long flags; - - rio_spin_lock_irqsave(&HostP->HostLock, flags); - - /************************************************* - * Put a packet back onto the back of the free list - * - ************************************************/ - - rio_dprintk(RIO_DEBUG_PFE, "put_free_end(PktP=%p)\n", PktP); - - if ((old_end = readw(&HostP->ParmMapP->free_list_end)) != TPNULL) { - new_end = RIO_OFF(HostP->Caddr, PktP); - tmp_pointer = (struct rio_free_list __iomem *) RIO_PTR(HostP->Caddr, old_end); - writew(new_end, &tmp_pointer->next); - writew(old_end, &((struct rio_free_list __iomem *) PktP)->prev); - writew(TPNULL, &((struct rio_free_list __iomem *) PktP)->next); - writew(new_end, &HostP->ParmMapP->free_list_end); - } else { /* First packet on the free list this should never happen! */ - rio_dprintk(RIO_DEBUG_PFE, "put_free_end(): This should never happen\n"); - writew(RIO_OFF(HostP->Caddr, PktP), &HostP->ParmMapP->free_list_end); - tmp_pointer = (struct rio_free_list __iomem *) PktP; - writew(TPNULL, &tmp_pointer->prev); - writew(TPNULL, &tmp_pointer->next); - } - rio_dprintk(RIO_DEBUG_CMD, "Before unlock: %p\n", &HostP->HostLock); - rio_spin_unlock_irqrestore(&HostP->HostLock, flags); -} - -/* -** can_remove_receive(PktP,P) returns non-zero if PKT_IN_USE is set -** for the next packet on the queue. It will also set PktP to point to the -** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear, -** then can_remove_receive() returns 0. -*/ -int can_remove_receive(struct PKT __iomem **PktP, struct Port *PortP) -{ - if (readw(PortP->RxRemove) & PKT_IN_USE) { - *PktP = (struct PKT __iomem *) RIO_PTR(PortP->Caddr, readw(PortP->RxRemove) & ~PKT_IN_USE); - return 1; - } - return 0; -} - -/* -** To remove a packet from the receive queue you clear its PKT_IN_USE bit, -** and then bump the pointers. Once the pointers get to the end, they must -** be wrapped back to the start. -*/ -void remove_receive(struct Port *PortP) -{ - writew(readw(PortP->RxRemove) & ~PKT_IN_USE, PortP->RxRemove); - PortP->RxRemove = (PortP->RxRemove == PortP->RxEnd) ? PortP->RxStart : PortP->RxRemove + 1; - writew(RIO_OFF(PortP->Caddr, PortP->RxRemove), &PortP->PhbP->rx_remove); -} diff --git a/drivers/staging/generic_serial/rio/rioroute.c b/drivers/staging/generic_serial/rio/rioroute.c deleted file mode 100644 index 8757378e8320..000000000000 --- a/drivers/staging/generic_serial/rio/rioroute.c +++ /dev/null @@ -1,1039 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : rioroute.c -** SID : 1.3 -** Last Modified : 11/6/98 10:33:46 -** Retrieved : 11/6/98 10:33:50 -** -** ident @(#)rioroute.c 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" -#include "param.h" - -static int RIOCheckIsolated(struct rio_info *, struct Host *, unsigned int); -static int RIOIsolate(struct rio_info *, struct Host *, unsigned int); -static int RIOCheck(struct Host *, unsigned int); -static void RIOConCon(struct rio_info *, struct Host *, unsigned int, unsigned int, unsigned int, unsigned int, int); - - -/* -** Incoming on the ROUTE_RUP -** I wrote this while I was tired. Forgive me. -*/ -int RIORouteRup(struct rio_info *p, unsigned int Rup, struct Host *HostP, struct PKT __iomem * PacketP) -{ - struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *) PacketP->data; - struct PktCmd_M *PktReplyP; - struct CmdBlk *CmdBlkP; - struct Port *PortP; - struct Map *MapP; - struct Top *TopP; - int ThisLink, ThisLinkMin, ThisLinkMax; - int port; - int Mod, Mod1, Mod2; - unsigned short RtaType; - unsigned int RtaUniq; - unsigned int ThisUnit, ThisUnit2; /* 2 ids to accommodate 16 port RTA */ - unsigned int OldUnit, NewUnit, OldLink, NewLink; - char *MyType, *MyName; - int Lies; - unsigned long flags; - - /* - ** Is this unit telling us it's current link topology? - */ - if (readb(&PktCmdP->Command) == ROUTE_TOPOLOGY) { - MapP = HostP->Mapping; - - /* - ** The packet can be sent either by the host or by an RTA. - ** If it comes from the host, then we need to fill in the - ** Topology array in the host structure. If it came in - ** from an RTA then we need to fill in the Mapping structure's - ** Topology array for the unit. - */ - if (Rup >= (unsigned short) MAX_RUP) { - ThisUnit = HOST_ID; - TopP = HostP->Topology; - MyType = "Host"; - MyName = HostP->Name; - ThisLinkMin = ThisLinkMax = Rup - MAX_RUP; - } else { - ThisUnit = Rup + 1; - TopP = HostP->Mapping[Rup].Topology; - MyType = "RTA"; - MyName = HostP->Mapping[Rup].Name; - ThisLinkMin = 0; - ThisLinkMax = LINKS_PER_UNIT - 1; - } - - /* - ** Lies will not be tolerated. - ** If any pair of links claim to be connected to the same - ** place, then ignore this packet completely. - */ - Lies = 0; - for (ThisLink = ThisLinkMin + 1; ThisLink <= ThisLinkMax; ThisLink++) { - /* - ** it won't lie about network interconnect, total disconnects - ** and no-IDs. (or at least, it doesn't *matter* if it does) - */ - if (readb(&PktCmdP->RouteTopology[ThisLink].Unit) > (unsigned short) MAX_RUP) - continue; - - for (NewLink = ThisLinkMin; NewLink < ThisLink; NewLink++) { - if ((readb(&PktCmdP->RouteTopology[ThisLink].Unit) == readb(&PktCmdP->RouteTopology[NewLink].Unit)) && (readb(&PktCmdP->RouteTopology[ThisLink].Link) == readb(&PktCmdP->RouteTopology[NewLink].Link))) { - Lies++; - } - } - } - - if (Lies) { - rio_dprintk(RIO_DEBUG_ROUTE, "LIES! DAMN LIES! %d LIES!\n", Lies); - rio_dprintk(RIO_DEBUG_ROUTE, "%d:%c %d:%c %d:%c %d:%c\n", - readb(&PktCmdP->RouteTopology[0].Unit), - 'A' + readb(&PktCmdP->RouteTopology[0].Link), - readb(&PktCmdP->RouteTopology[1].Unit), - 'A' + readb(&PktCmdP->RouteTopology[1].Link), readb(&PktCmdP->RouteTopology[2].Unit), 'A' + readb(&PktCmdP->RouteTopology[2].Link), readb(&PktCmdP->RouteTopology[3].Unit), 'A' + readb(&PktCmdP->RouteTopology[3].Link)); - return 1; - } - - /* - ** now, process each link. - */ - for (ThisLink = ThisLinkMin; ThisLink <= ThisLinkMax; ThisLink++) { - /* - ** this is what it was connected to - */ - OldUnit = TopP[ThisLink].Unit; - OldLink = TopP[ThisLink].Link; - - /* - ** this is what it is now connected to - */ - NewUnit = readb(&PktCmdP->RouteTopology[ThisLink].Unit); - NewLink = readb(&PktCmdP->RouteTopology[ThisLink].Link); - - if (OldUnit != NewUnit || OldLink != NewLink) { - /* - ** something has changed! - */ - - if (NewUnit > MAX_RUP && NewUnit != ROUTE_DISCONNECT && NewUnit != ROUTE_NO_ID && NewUnit != ROUTE_INTERCONNECT) { - rio_dprintk(RIO_DEBUG_ROUTE, "I have a link from %s %s to unit %d:%d - I don't like it.\n", MyType, MyName, NewUnit, NewLink); - } else { - /* - ** put the new values in - */ - TopP[ThisLink].Unit = NewUnit; - TopP[ThisLink].Link = NewLink; - - RIOSetChange(p); - - if (OldUnit <= MAX_RUP) { - /* - ** If something has become bust, then re-enable them messages - */ - if (!p->RIONoMessage) - RIOConCon(p, HostP, ThisUnit, ThisLink, OldUnit, OldLink, DISCONNECT); - } - - if ((NewUnit <= MAX_RUP) && !p->RIONoMessage) - RIOConCon(p, HostP, ThisUnit, ThisLink, NewUnit, NewLink, CONNECT); - - if (NewUnit == ROUTE_NO_ID) - rio_dprintk(RIO_DEBUG_ROUTE, "%s %s (%c) is connected to an unconfigured unit.\n", MyType, MyName, 'A' + ThisLink); - - if (NewUnit == ROUTE_INTERCONNECT) { - if (!p->RIONoMessage) - printk(KERN_DEBUG "rio: %s '%s' (%c) is connected to another network.\n", MyType, MyName, 'A' + ThisLink); - } - - /* - ** perform an update for 'the other end', so that these messages - ** only appears once. Only disconnect the other end if it is pointing - ** at us! - */ - if (OldUnit == HOST_ID) { - if (HostP->Topology[OldLink].Unit == ThisUnit && HostP->Topology[OldLink].Link == ThisLink) { - rio_dprintk(RIO_DEBUG_ROUTE, "SETTING HOST (%c) TO DISCONNECTED!\n", OldLink + 'A'); - HostP->Topology[OldLink].Unit = ROUTE_DISCONNECT; - HostP->Topology[OldLink].Link = NO_LINK; - } else { - rio_dprintk(RIO_DEBUG_ROUTE, "HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n", OldLink + 'A', HostP->Mapping[ThisUnit - 1].Name, ThisLink + 'A'); - } - } else if (OldUnit <= MAX_RUP) { - if (HostP->Mapping[OldUnit - 1].Topology[OldLink].Unit == ThisUnit && HostP->Mapping[OldUnit - 1].Topology[OldLink].Link == ThisLink) { - rio_dprintk(RIO_DEBUG_ROUTE, "SETTING RTA %s (%c) TO DISCONNECTED!\n", HostP->Mapping[OldUnit - 1].Name, OldLink + 'A'); - HostP->Mapping[OldUnit - 1].Topology[OldLink].Unit = ROUTE_DISCONNECT; - HostP->Mapping[OldUnit - 1].Topology[OldLink].Link = NO_LINK; - } else { - rio_dprintk(RIO_DEBUG_ROUTE, "RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n", HostP->Mapping[OldUnit - 1].Name, OldLink + 'A', HostP->Mapping[ThisUnit - 1].Name, ThisLink + 'A'); - } - } - if (NewUnit == HOST_ID) { - rio_dprintk(RIO_DEBUG_ROUTE, "MARKING HOST (%c) CONNECTED TO %s (%c)\n", NewLink + 'A', MyName, ThisLink + 'A'); - HostP->Topology[NewLink].Unit = ThisUnit; - HostP->Topology[NewLink].Link = ThisLink; - } else if (NewUnit <= MAX_RUP) { - rio_dprintk(RIO_DEBUG_ROUTE, "MARKING RTA %s (%c) CONNECTED TO %s (%c)\n", HostP->Mapping[NewUnit - 1].Name, NewLink + 'A', MyName, ThisLink + 'A'); - HostP->Mapping[NewUnit - 1].Topology[NewLink].Unit = ThisUnit; - HostP->Mapping[NewUnit - 1].Topology[NewLink].Link = ThisLink; - } - } - RIOSetChange(p); - RIOCheckIsolated(p, HostP, OldUnit); - } - } - return 1; - } - - /* - ** The only other command we recognise is a route_request command - */ - if (readb(&PktCmdP->Command) != ROUTE_REQUEST) { - rio_dprintk(RIO_DEBUG_ROUTE, "Unknown command %d received on rup %d host %p ROUTE_RUP\n", readb(&PktCmdP->Command), Rup, HostP); - return 1; - } - - RtaUniq = (readb(&PktCmdP->UniqNum[0])) + (readb(&PktCmdP->UniqNum[1]) << 8) + (readb(&PktCmdP->UniqNum[2]) << 16) + (readb(&PktCmdP->UniqNum[3]) << 24); - - /* - ** Determine if 8 or 16 port RTA - */ - RtaType = GetUnitType(RtaUniq); - - rio_dprintk(RIO_DEBUG_ROUTE, "Received a request for an ID for serial number %x\n", RtaUniq); - - Mod = readb(&PktCmdP->ModuleTypes); - Mod1 = LONYBLE(Mod); - if (RtaType == TYPE_RTA16) { - /* - ** Only one ident is set for a 16 port RTA. To make compatible - ** with 8 port, set 2nd ident in Mod2 to the same as Mod1. - */ - Mod2 = Mod1; - rio_dprintk(RIO_DEBUG_ROUTE, "Backplane type is %s (all ports)\n", p->RIOModuleTypes[Mod1].Name); - } else { - Mod2 = HINYBLE(Mod); - rio_dprintk(RIO_DEBUG_ROUTE, "Module types are %s (ports 0-3) and %s (ports 4-7)\n", p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name); - } - - /* - ** try to unhook a command block from the command free list. - */ - if (!(CmdBlkP = RIOGetCmdBlk())) { - rio_dprintk(RIO_DEBUG_ROUTE, "No command blocks to route RTA! come back later.\n"); - return 0; - } - - /* - ** Fill in the default info on the command block - */ - CmdBlkP->Packet.dest_unit = Rup; - CmdBlkP->Packet.dest_port = ROUTE_RUP; - CmdBlkP->Packet.src_unit = HOST_ID; - CmdBlkP->Packet.src_port = ROUTE_RUP; - CmdBlkP->Packet.len = PKT_CMD_BIT | 1; - CmdBlkP->PreFuncP = CmdBlkP->PostFuncP = NULL; - PktReplyP = (struct PktCmd_M *) CmdBlkP->Packet.data; - - if (!RIOBootOk(p, HostP, RtaUniq)) { - rio_dprintk(RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n", RtaUniq); - PktReplyP->Command = ROUTE_FOAD; - memcpy(PktReplyP->CommandText, "RT_FOAD", 7); - RIOQueueCmdBlk(HostP, Rup, CmdBlkP); - return 1; - } - - /* - ** Check to see if the RTA is configured for this host - */ - for (ThisUnit = 0; ThisUnit < MAX_RUP; ThisUnit++) { - rio_dprintk(RIO_DEBUG_ROUTE, "Entry %d Flags=%s %s UniqueNum=0x%x\n", - ThisUnit, HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE ? "Slot-In-Use" : "Not In Use", HostP->Mapping[ThisUnit].Flags & SLOT_TENTATIVE ? "Slot-Tentative" : "Not Tentative", HostP->Mapping[ThisUnit].RtaUniqueNum); - - /* - ** We have an entry for it. - */ - if ((HostP->Mapping[ThisUnit].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) && (HostP->Mapping[ThisUnit].RtaUniqueNum == RtaUniq)) { - if (RtaType == TYPE_RTA16) { - ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1; - rio_dprintk(RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n", RtaUniq, ThisUnit, ThisUnit2); - } else - rio_dprintk(RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n", RtaUniq, ThisUnit); - /* - ** If we have no knowledge of booting it, then the host has - ** been re-booted, and so we must kill the RTA, so that it - ** will be booted again (potentially with new bins) - ** and it will then re-ask for an ID, which we will service. - */ - if ((HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) && !(HostP->Mapping[ThisUnit].Flags & RTA_BOOTED)) { - if (!(HostP->Mapping[ThisUnit].Flags & MSG_DONE)) { - if (!p->RIONoMessage) - printk(KERN_DEBUG "rio: RTA '%s' is being updated.\n", HostP->Mapping[ThisUnit].Name); - HostP->Mapping[ThisUnit].Flags |= MSG_DONE; - } - PktReplyP->Command = ROUTE_FOAD; - memcpy(PktReplyP->CommandText, "RT_FOAD", 7); - RIOQueueCmdBlk(HostP, Rup, CmdBlkP); - return 1; - } - - /* - ** Send the ID (entry) to this RTA. The ID number is implicit as - ** the offset into the table. It is worth noting at this stage - ** that offset zero in the table contains the entries for the - ** RTA with ID 1!!!! - */ - PktReplyP->Command = ROUTE_ALLOCATE; - PktReplyP->IDNum = ThisUnit + 1; - if (RtaType == TYPE_RTA16) { - if (HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE) - /* - ** Adjust the phb and tx pkt dest_units for 2nd block of 8 - ** only if the RTA has ports associated (SLOT_IN_USE) - */ - RIOFixPhbs(p, HostP, ThisUnit2); - PktReplyP->IDNum2 = ThisUnit2 + 1; - rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2); - } else { - PktReplyP->IDNum2 = ROUTE_NO_ID; - rio_dprintk(RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n", HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum); - } - memcpy(PktReplyP->CommandText, "RT_ALLOCAT", 10); - - RIOQueueCmdBlk(HostP, Rup, CmdBlkP); - - /* - ** If this is a freshly booted RTA, then we need to re-open - ** the ports, if any where open, so that data may once more - ** flow around the system! - */ - if ((HostP->Mapping[ThisUnit].Flags & RTA_NEWBOOT) && (HostP->Mapping[ThisUnit].SysPort != NO_PORT)) { - /* - ** look at the ports associated with this beast and - ** see if any where open. If they was, then re-open - ** them, using the info from the tty flags. - */ - for (port = 0; port < PORTS_PER_RTA; port++) { - PortP = p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]; - if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { - rio_dprintk(RIO_DEBUG_ROUTE, "Re-opened this port\n"); - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->MagicFlags |= MAGIC_REBOOT; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - } - } - if (RtaType == TYPE_RTA16) { - for (port = 0; port < PORTS_PER_RTA; port++) { - PortP = p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]; - if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { - rio_dprintk(RIO_DEBUG_ROUTE, "Re-opened this port\n"); - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->MagicFlags |= MAGIC_REBOOT; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - } - } - } - } - - /* - ** keep a copy of the module types! - */ - HostP->UnixRups[ThisUnit].ModTypes = Mod; - if (RtaType == TYPE_RTA16) - HostP->UnixRups[ThisUnit2].ModTypes = Mod; - - /* - ** If either of the modules on this unit is read-only or write-only - ** or none-xprint, then we need to transfer that info over to the - ** relevant ports. - */ - if (HostP->Mapping[ThisUnit].SysPort != NO_PORT) { - for (port = 0; port < PORTS_PER_MODULE; port++) { - p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK; - p->RIOPortp[port + HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; - p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit].SysPort]->Config &= ~RIO_NOMASK; - p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; - } - if (RtaType == TYPE_RTA16) { - for (port = 0; port < PORTS_PER_MODULE; port++) { - p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; - p->RIOPortp[port + HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod1].Flags[port]; - p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit2].SysPort]->Config &= ~RIO_NOMASK; - p->RIOPortp[port + PORTS_PER_MODULE + HostP->Mapping[ThisUnit2].SysPort]->Config |= p->RIOModuleTypes[Mod2].Flags[port]; - } - } - } - - /* - ** Job done, get on with the interrupts! - */ - return 1; - } - } - /* - ** There is no table entry for this RTA at all. - ** - ** Lets check to see if we actually booted this unit - if not, - ** then we reset it and it will go round the loop of being booted - ** we can then worry about trying to fit it into the table. - */ - for (ThisUnit = 0; ThisUnit < HostP->NumExtraBooted; ThisUnit++) - if (HostP->ExtraUnits[ThisUnit] == RtaUniq) - break; - if (ThisUnit == HostP->NumExtraBooted && ThisUnit != MAX_EXTRA_UNITS) { - /* - ** if the unit wasn't in the table, and the table wasn't full, then - ** we reset the unit, because we didn't boot it. - ** However, if the table is full, it could be that we did boot - ** this unit, and so we won't reboot it, because it isn't really - ** all that disastrous to keep the old bins in most cases. This - ** is a rather tacky feature, but we are on the edge of reallity - ** here, because the implication is that someone has connected - ** 16+MAX_EXTRA_UNITS onto one host. - */ - static int UnknownMesgDone = 0; - - if (!UnknownMesgDone) { - if (!p->RIONoMessage) - printk(KERN_DEBUG "rio: One or more unknown RTAs are being updated.\n"); - UnknownMesgDone = 1; - } - - PktReplyP->Command = ROUTE_FOAD; - memcpy(PktReplyP->CommandText, "RT_FOAD", 7); - } else { - /* - ** we did boot it (as an extra), and there may now be a table - ** slot free (because of a delete), so we will try to make - ** a tentative entry for it, so that the configurator can see it - ** and fill in the details for us. - */ - if (RtaType == TYPE_RTA16) { - if (RIOFindFreeID(p, HostP, &ThisUnit, &ThisUnit2) == 0) { - RIODefaultName(p, HostP, ThisUnit); - rio_fill_host_slot(ThisUnit, ThisUnit2, RtaUniq, HostP); - } - } else { - if (RIOFindFreeID(p, HostP, &ThisUnit, NULL) == 0) { - RIODefaultName(p, HostP, ThisUnit); - rio_fill_host_slot(ThisUnit, 0, RtaUniq, HostP); - } - } - PktReplyP->Command = ROUTE_USED; - memcpy(PktReplyP->CommandText, "RT_USED", 7); - } - RIOQueueCmdBlk(HostP, Rup, CmdBlkP); - return 1; -} - - -void RIOFixPhbs(struct rio_info *p, struct Host *HostP, unsigned int unit) -{ - unsigned short link, port; - struct Port *PortP; - unsigned long flags; - int PortN = HostP->Mapping[unit].SysPort; - - rio_dprintk(RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN); - - if (PortN != -1) { - unsigned short dest_unit = HostP->Mapping[unit].ID2; - - /* - ** Get the link number used for the 1st 8 phbs on this unit. - */ - PortP = p->RIOPortp[HostP->Mapping[dest_unit - 1].SysPort]; - - link = readw(&PortP->PhbP->link); - - for (port = 0; port < PORTS_PER_RTA; port++, PortN++) { - unsigned short dest_port = port + 8; - u16 __iomem *TxPktP; - struct PKT __iomem *Pkt; - - PortP = p->RIOPortp[PortN]; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - /* - ** If RTA is not powered on, the tx packets will be - ** unset, so go no further. - */ - if (!PortP->TxStart) { - rio_dprintk(RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - break; - } - - /* - ** For the second slot of a 16 port RTA, the driver needs to - ** sort out the phb to port mappings. The dest_unit for this - ** group of 8 phbs is set to the dest_unit of the accompanying - ** 8 port block. The dest_port of the second unit is set to - ** be in the range 8-15 (i.e. 8 is added). Thus, for a 16 port - ** RTA with IDs 5 and 6, traffic bound for port 6 of unit 6 - ** (being the second map ID) will be sent to dest_unit 5, port - ** 14. When this RTA is deleted, dest_unit for ID 6 will be - ** restored, and the dest_port will be reduced by 8. - ** Transmit packets also have a destination field which needs - ** adjusting in the same manner. - ** Note that the unit/port bytes in 'dest' are swapped. - ** We also need to adjust the phb and rup link numbers for the - ** second block of 8 ttys. - */ - for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) { - /* - ** *TxPktP is the pointer to the transmit packet on the host - ** card. This needs to be translated into a 32 bit pointer - ** so it can be accessed from the driver. - */ - Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(TxPktP)); - - /* - ** If the packet is used, reset it. - */ - Pkt = (struct PKT __iomem *) ((unsigned long) Pkt & ~PKT_IN_USE); - writeb(dest_unit, &Pkt->dest_unit); - writeb(dest_port, &Pkt->dest_port); - } - rio_dprintk(RIO_DEBUG_ROUTE, "phb dest: Old %x:%x New %x:%x\n", readw(&PortP->PhbP->destination) & 0xff, (readw(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port); - writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination); - writew(link, &PortP->PhbP->link); - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - } - /* - ** Now make sure the range of ports to be serviced includes - ** the 2nd 8 on this 16 port RTA. - */ - if (link > 3) - return; - if (((unit * 8) + 7) > readw(&HostP->LinkStrP[link].last_port)) { - rio_dprintk(RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7); - writew((unit * 8) + 7, &HostP->LinkStrP[link].last_port); - } - } -} - -/* -** Check to see if the new disconnection has isolated this unit. -** If it has, then invalidate all its link information, and tell -** the world about it. This is done to ensure that the configurator -** only gets up-to-date information about what is going on. -*/ -static int RIOCheckIsolated(struct rio_info *p, struct Host *HostP, unsigned int UnitId) -{ - unsigned long flags; - rio_spin_lock_irqsave(&HostP->HostLock, flags); - - if (RIOCheck(HostP, UnitId)) { - rio_dprintk(RIO_DEBUG_ROUTE, "Unit %d is NOT isolated\n", UnitId); - rio_spin_unlock_irqrestore(&HostP->HostLock, flags); - return (0); - } - - RIOIsolate(p, HostP, UnitId); - RIOSetChange(p); - rio_spin_unlock_irqrestore(&HostP->HostLock, flags); - return 1; -} - -/* -** Invalidate all the link interconnectivity of this unit, and of -** all the units attached to it. This will mean that the entire -** subnet will re-introduce itself. -*/ -static int RIOIsolate(struct rio_info *p, struct Host *HostP, unsigned int UnitId) -{ - unsigned int link, unit; - - UnitId--; /* this trick relies on the Unit Id being UNSIGNED! */ - - if (UnitId >= MAX_RUP) /* dontcha just lurv unsigned maths! */ - return (0); - - if (HostP->Mapping[UnitId].Flags & BEEN_HERE) - return (0); - - HostP->Mapping[UnitId].Flags |= BEEN_HERE; - - if (p->RIOPrintDisabled == DO_PRINT) - rio_dprintk(RIO_DEBUG_ROUTE, "RIOMesgIsolated %s", HostP->Mapping[UnitId].Name); - - for (link = 0; link < LINKS_PER_UNIT; link++) { - unit = HostP->Mapping[UnitId].Topology[link].Unit; - HostP->Mapping[UnitId].Topology[link].Unit = ROUTE_DISCONNECT; - HostP->Mapping[UnitId].Topology[link].Link = NO_LINK; - RIOIsolate(p, HostP, unit); - } - HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; - return 1; -} - -static int RIOCheck(struct Host *HostP, unsigned int UnitId) -{ - unsigned char link; - -/* rio_dprint(RIO_DEBUG_ROUTE, ("Check to see if unit %d has a route to the host\n",UnitId)); */ - rio_dprintk(RIO_DEBUG_ROUTE, "RIOCheck : UnitID = %d\n", UnitId); - - if (UnitId == HOST_ID) { - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated - it IS the host!\n", UnitId)); */ - return 1; - } - - UnitId--; - - if (UnitId >= MAX_RUP) { - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d - ignored.\n", UnitId)); */ - return 0; - } - - for (link = 0; link < LINKS_PER_UNIT; link++) { - if (HostP->Mapping[UnitId].Topology[link].Unit == HOST_ID) { - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected directly to host via link (%c).\n", - UnitId, 'A'+link)); */ - return 1; - } - } - - if (HostP->Mapping[UnitId].Flags & BEEN_HERE) { - /* rio_dprint(RIO_DEBUG_ROUTE, ("Been to Unit %d before - ignoring\n", UnitId)); */ - return 0; - } - - HostP->Mapping[UnitId].Flags |= BEEN_HERE; - - for (link = 0; link < LINKS_PER_UNIT; link++) { - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d check link (%c)\n", UnitId,'A'+link)); */ - if (RIOCheck(HostP, HostP->Mapping[UnitId].Topology[link].Unit)) { - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is connected to something that knows the host via link (%c)\n", UnitId,link+'A')); */ - HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; - return 1; - } - } - - HostP->Mapping[UnitId].Flags &= ~BEEN_HERE; - - /* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d DOESN'T KNOW THE HOST!\n", UnitId)); */ - - return 0; -} - -/* -** Returns the type of unit (host, 16/8 port RTA) -*/ - -unsigned int GetUnitType(unsigned int Uniq) -{ - switch ((Uniq >> 28) & 0xf) { - case RIO_AT: - case RIO_MCA: - case RIO_EISA: - case RIO_PCI: - rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: Host\n"); - return (TYPE_HOST); - case RIO_RTA_16: - rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: 16 port RTA\n"); - return (TYPE_RTA16); - case RIO_RTA: - rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: 8 port RTA\n"); - return (TYPE_RTA8); - default: - rio_dprintk(RIO_DEBUG_ROUTE, "Unit type: Unrecognised\n"); - return (99); - } -} - -int RIOSetChange(struct rio_info *p) -{ - if (p->RIOQuickCheck != NOT_CHANGED) - return (0); - p->RIOQuickCheck = CHANGED; - if (p->RIOSignalProcess) { - rio_dprintk(RIO_DEBUG_ROUTE, "Send SIG-HUP"); - /* - psignal( RIOSignalProcess, SIGHUP ); - */ - } - return (0); -} - -static void RIOConCon(struct rio_info *p, - struct Host *HostP, - unsigned int FromId, - unsigned int FromLink, - unsigned int ToId, - unsigned int ToLink, - int Change) -{ - char *FromName; - char *FromType; - char *ToName; - char *ToType; - unsigned int tp; - -/* -** 15.10.1998 ARG - ESIL 0759 -** (Part) fix for port being trashed when opened whilst RTA "disconnected" -** -** What's this doing in here anyway ? -** It was causing the port to be 'unmapped' if opened whilst RTA "disconnected" -** -** 09.12.1998 ARG - ESIL 0776 - part fix -** Okay, We've found out what this was all about now ! -** Someone had botched this to use RIOHalted to indicated the number of RTAs -** 'disconnected'. The value in RIOHalted was then being used in the -** 'RIO_QUICK_CHECK' ioctl. A none zero value indicating that a least one RTA -** is 'disconnected'. The change was put in to satisfy a customer's needs. -** Having taken this bit of code out 'RIO_QUICK_CHECK' now no longer works for -** the customer. -** - if (Change == CONNECT) { - if (p->RIOHalted) p->RIOHalted --; - } - else { - p->RIOHalted ++; - } -** -** So - we need to implement it slightly differently - a new member of the -** rio_info struct - RIORtaDisCons (RIO RTA connections) keeps track of RTA -** connections and disconnections. -*/ - if (Change == CONNECT) { - if (p->RIORtaDisCons) - p->RIORtaDisCons--; - } else { - p->RIORtaDisCons++; - } - - if (p->RIOPrintDisabled == DONT_PRINT) - return; - - if (FromId > ToId) { - tp = FromId; - FromId = ToId; - ToId = tp; - tp = FromLink; - FromLink = ToLink; - ToLink = tp; - } - - FromName = FromId ? HostP->Mapping[FromId - 1].Name : HostP->Name; - FromType = FromId ? "RTA" : "HOST"; - ToName = ToId ? HostP->Mapping[ToId - 1].Name : HostP->Name; - ToType = ToId ? "RTA" : "HOST"; - - rio_dprintk(RIO_DEBUG_ROUTE, "Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", FromType, FromName, 'A' + FromLink, ToType, ToName, 'A' + ToLink, (Change == CONNECT) ? "established" : "disconnected"); - printk(KERN_DEBUG "rio: Link between %s '%s' (%c) and %s '%s' (%c) %s.\n", FromType, FromName, 'A' + FromLink, ToType, ToName, 'A' + ToLink, (Change == CONNECT) ? "established" : "disconnected"); -} - -/* -** RIORemoveFromSavedTable : -** -** Delete and RTA entry from the saved table given to us -** by the configuration program. -*/ -static int RIORemoveFromSavedTable(struct rio_info *p, struct Map *pMap) -{ - int entry; - - /* - ** We loop for all entries even after finding an entry and - ** zeroing it because we may have two entries to delete if - ** it's a 16 port RTA. - */ - for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { - if (p->RIOSavedTable[entry].RtaUniqueNum == pMap->RtaUniqueNum) { - memset(&p->RIOSavedTable[entry], 0, sizeof(struct Map)); - } - } - return 0; -} - - -/* -** RIOCheckDisconnected : -** -** Scan the unit links to and return zero if the unit is completely -** disconnected. -*/ -static int RIOFreeDisconnected(struct rio_info *p, struct Host *HostP, int unit) -{ - int link; - - - rio_dprintk(RIO_DEBUG_ROUTE, "RIOFreeDisconnect unit %d\n", unit); - /* - ** If the slot is tentative and does not belong to the - ** second half of a 16 port RTA then scan to see if - ** is disconnected. - */ - for (link = 0; link < LINKS_PER_UNIT; link++) { - if (HostP->Mapping[unit].Topology[link].Unit != ROUTE_DISCONNECT) - break; - } - - /* - ** If not all links are disconnected then we can forget about it. - */ - if (link < LINKS_PER_UNIT) - return 1; - -#ifdef NEED_TO_FIX_THIS - /* Ok so all the links are disconnected. But we may have only just - ** made this slot tentative and not yet received a topology update. - ** Lets check how long ago we made it tentative. - */ - rio_dprintk(RIO_DEBUG_ROUTE, "Just about to check LBOLT on entry %d\n", unit); - if (drv_getparm(LBOLT, (ulong_t *) & current_time)) - rio_dprintk(RIO_DEBUG_ROUTE, "drv_getparm(LBOLT,....) Failed.\n"); - - elapse_time = current_time - TentTime[unit]; - rio_dprintk(RIO_DEBUG_ROUTE, "elapse %d = current %d - tent %d (%d usec)\n", elapse_time, current_time, TentTime[unit], drv_hztousec(elapse_time)); - if (drv_hztousec(elapse_time) < WAIT_TO_FINISH) { - rio_dprintk(RIO_DEBUG_ROUTE, "Skipping slot %d, not timed out yet %d\n", unit, drv_hztousec(elapse_time)); - return 1; - } -#endif - - /* - ** We have found an usable slot. - ** If it is half of a 16 port RTA then delete the other half. - */ - if (HostP->Mapping[unit].ID2 != 0) { - int nOther = (HostP->Mapping[unit].ID2) - 1; - - rio_dprintk(RIO_DEBUG_ROUTE, "RioFreedis second slot %d.\n", nOther); - memset(&HostP->Mapping[nOther], 0, sizeof(struct Map)); - } - RIORemoveFromSavedTable(p, &HostP->Mapping[unit]); - - return 0; -} - - -/* -** RIOFindFreeID : -** -** This function scans the given host table for either one -** or two free unit ID's. -*/ - -int RIOFindFreeID(struct rio_info *p, struct Host *HostP, unsigned int * pID1, unsigned int * pID2) -{ - int unit, tempID; - - /* - ** Initialise the ID's to MAX_RUP. - ** We do this to make the loop for setting the ID's as simple as - ** possible. - */ - *pID1 = MAX_RUP; - if (pID2 != NULL) - *pID2 = MAX_RUP; - - /* - ** Scan all entries of the host mapping table for free slots. - ** We scan for free slots first and then if that is not successful - ** we start all over again looking for tentative slots we can re-use. - */ - for (unit = 0; unit < MAX_RUP; unit++) { - rio_dprintk(RIO_DEBUG_ROUTE, "Scanning unit %d\n", unit); - /* - ** If the flags are zero then the slot is empty. - */ - if (HostP->Mapping[unit].Flags == 0) { - rio_dprintk(RIO_DEBUG_ROUTE, " This slot is empty.\n"); - /* - ** If we haven't allocated the first ID then do it now. - */ - if (*pID1 == MAX_RUP) { - rio_dprintk(RIO_DEBUG_ROUTE, "Make tentative entry for first unit %d\n", unit); - *pID1 = unit; - - /* - ** If the second ID is not needed then we can return - ** now. - */ - if (pID2 == NULL) - return 0; - } else { - /* - ** Allocate the second slot and return. - */ - rio_dprintk(RIO_DEBUG_ROUTE, "Make tentative entry for second unit %d\n", unit); - *pID2 = unit; - return 0; - } - } - } - - /* - ** If we manage to come out of the free slot loop then we - ** need to start all over again looking for tentative slots - ** that we can re-use. - */ - rio_dprintk(RIO_DEBUG_ROUTE, "Starting to scan for tentative slots\n"); - for (unit = 0; unit < MAX_RUP; unit++) { - if (((HostP->Mapping[unit].Flags & SLOT_TENTATIVE) || (HostP->Mapping[unit].Flags == 0)) && !(HostP->Mapping[unit].Flags & RTA16_SECOND_SLOT)) { - rio_dprintk(RIO_DEBUG_ROUTE, " Slot %d looks promising.\n", unit); - - if (unit == *pID1) { - rio_dprintk(RIO_DEBUG_ROUTE, " No it isn't, its the 1st half\n"); - continue; - } - - /* - ** Slot is Tentative or Empty, but not a tentative second - ** slot of a 16 porter. - ** Attempt to free up this slot (and its parnter if - ** it is a 16 port slot. The second slot will become - ** empty after a call to RIOFreeDisconnected so thats why - ** we look for empty slots above as well). - */ - if (HostP->Mapping[unit].Flags != 0) - if (RIOFreeDisconnected(p, HostP, unit) != 0) - continue; - /* - ** If we haven't allocated the first ID then do it now. - */ - if (*pID1 == MAX_RUP) { - rio_dprintk(RIO_DEBUG_ROUTE, "Grab tentative entry for first unit %d\n", unit); - *pID1 = unit; - - /* - ** Clear out this slot now that we intend to use it. - */ - memset(&HostP->Mapping[unit], 0, sizeof(struct Map)); - - /* - ** If the second ID is not needed then we can return - ** now. - */ - if (pID2 == NULL) - return 0; - } else { - /* - ** Allocate the second slot and return. - */ - rio_dprintk(RIO_DEBUG_ROUTE, "Grab tentative/empty entry for second unit %d\n", unit); - *pID2 = unit; - - /* - ** Clear out this slot now that we intend to use it. - */ - memset(&HostP->Mapping[unit], 0, sizeof(struct Map)); - - /* At this point under the right(wrong?) conditions - ** we may have a first unit ID being higher than the - ** second unit ID. This is a bad idea if we are about - ** to fill the slots with a 16 port RTA. - ** Better check and swap them over. - */ - - if (*pID1 > *pID2) { - rio_dprintk(RIO_DEBUG_ROUTE, "Swapping IDS %d %d\n", *pID1, *pID2); - tempID = *pID1; - *pID1 = *pID2; - *pID2 = tempID; - } - return 0; - } - } - } - - /* - ** If we manage to get to the end of the second loop then we - ** can give up and return a failure. - */ - return 1; -} - - -/* -** The link switch scenario. -** -** Rta Wun (A) is connected to Tuw (A). -** The tables are all up to date, and the system is OK. -** -** If Wun (A) is now moved to Wun (B) before Wun (A) can -** become disconnected, then the follow happens: -** -** Tuw (A) spots the change of unit:link at the other end -** of its link and Tuw sends a topology packet reflecting -** the change: Tuw (A) now disconnected from Wun (A), and -** this is closely followed by a packet indicating that -** Tuw (A) is now connected to Wun (B). -** -** Wun (B) will spot that it has now become connected, and -** Wun will send a topology packet, which indicates that -** both Wun (A) and Wun (B) is connected to Tuw (A). -** -** Eventually Wun (A) realises that it is now disconnected -** and Wun will send out a topology packet indicating that -** Wun (A) is now disconnected. -*/ diff --git a/drivers/staging/generic_serial/rio/riospace.h b/drivers/staging/generic_serial/rio/riospace.h deleted file mode 100644 index ffb31d4332b9..000000000000 --- a/drivers/staging/generic_serial/rio/riospace.h +++ /dev/null @@ -1,154 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : riospace.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:13 -** Retrieved : 11/6/98 11:34:22 -** -** ident @(#)riospace.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_riospace_h__ -#define __rio_riospace_h__ - -#define RIO_LOCATOR_LEN 16 -#define MAX_RIO_BOARDS 4 - -/* -** DONT change this file. At all. Unless you can rebuild the entire -** device driver, which you probably can't, then the rest of the -** driver won't see any changes you make here. So don't make any. -** In particular, it won't be able to see changes to RIO_SLOTS -*/ - -struct Conf { - char Locator[24]; - unsigned int StartupTime; - unsigned int SlowCook; - unsigned int IntrPollTime; - unsigned int BreakInterval; - unsigned int Timer; - unsigned int RtaLoadBase; - unsigned int HostLoadBase; - unsigned int XpHz; - unsigned int XpCps; - char *XpOn; - char *XpOff; - unsigned int MaxXpCps; - unsigned int MinXpCps; - unsigned int SpinCmds; - unsigned int FirstAddr; - unsigned int LastAddr; - unsigned int BufferSize; - unsigned int LowWater; - unsigned int LineLength; - unsigned int CmdTime; -}; - -/* -** Board types - these MUST correspond to product codes! -*/ -#define RIO_EMPTY 0x0 -#define RIO_EISA 0x3 -#define RIO_RTA_16 0x9 -#define RIO_AT 0xA -#define RIO_MCA 0xB -#define RIO_PCI 0xD -#define RIO_RTA 0xE - -/* -** Board data structure. This is used for configuration info -*/ -struct Brd { - unsigned char Type; /* RIO_EISA, RIO_MCA, RIO_AT, RIO_EMPTY... */ - unsigned char Ivec; /* POLLED or ivec number */ - unsigned char Mode; /* Control stuff, see below */ -}; - -struct Board { - char Locator[RIO_LOCATOR_LEN]; - int NumSlots; - struct Brd Boards[MAX_RIO_BOARDS]; -}; - -#define BOOT_FROM_LINK 0x00 -#define BOOT_FROM_RAM 0x01 -#define EXTERNAL_BUS_OFF 0x00 -#define EXTERNAL_BUS_ON 0x02 -#define INTERRUPT_DISABLE 0x00 -#define INTERRUPT_ENABLE 0x04 -#define BYTE_OPERATION 0x00 -#define WORD_OPERATION 0x08 -#define POLLED INTERRUPT_DISABLE -#define IRQ_15 (0x00 | INTERRUPT_ENABLE) -#define IRQ_12 (0x10 | INTERRUPT_ENABLE) -#define IRQ_11 (0x20 | INTERRUPT_ENABLE) -#define IRQ_9 (0x30 | INTERRUPT_ENABLE) -#define SLOW_LINKS 0x00 -#define FAST_LINKS 0x40 -#define SLOW_AT_BUS 0x00 -#define FAST_AT_BUS 0x80 -#define SLOW_PCI_TP 0x00 -#define FAST_PCI_TP 0x80 -/* -** Debug levels -*/ -#define DBG_NONE 0x00000000 - -#define DBG_INIT 0x00000001 -#define DBG_OPEN 0x00000002 -#define DBG_CLOSE 0x00000004 -#define DBG_IOCTL 0x00000008 - -#define DBG_READ 0x00000010 -#define DBG_WRITE 0x00000020 -#define DBG_INTR 0x00000040 -#define DBG_PROC 0x00000080 - -#define DBG_PARAM 0x00000100 -#define DBG_CMD 0x00000200 -#define DBG_XPRINT 0x00000400 -#define DBG_POLL 0x00000800 - -#define DBG_DAEMON 0x00001000 -#define DBG_FAIL 0x00002000 -#define DBG_MODEM 0x00004000 -#define DBG_LIST 0x00008000 - -#define DBG_ROUTE 0x00010000 -#define DBG_UTIL 0x00020000 -#define DBG_BOOT 0x00040000 -#define DBG_BUFFER 0x00080000 - -#define DBG_MON 0x00100000 -#define DBG_SPECIAL 0x00200000 -#define DBG_VPIX 0x00400000 -#define DBG_FLUSH 0x00800000 - -#define DBG_QENABLE 0x01000000 - -#define DBG_ALWAYS 0x80000000 - -#endif /* __rio_riospace_h__ */ diff --git a/drivers/staging/generic_serial/rio/riotable.c b/drivers/staging/generic_serial/rio/riotable.c deleted file mode 100644 index 3d15802dc0f3..000000000000 --- a/drivers/staging/generic_serial/rio/riotable.c +++ /dev/null @@ -1,941 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : riotable.c -** SID : 1.2 -** Last Modified : 11/6/98 10:33:47 -** Retrieved : 11/6/98 10:33:50 -** -** ident @(#)riotable.c 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include - - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" -#include "param.h" -#include "protsts.h" - -/* -** A configuration table has been loaded. It is now up to us -** to sort it out and use the information contained therein. -*/ -int RIONewTable(struct rio_info *p) -{ - int Host, Host1, Host2, NameIsUnique, Entry, SubEnt; - struct Map *MapP; - struct Map *HostMapP; - struct Host *HostP; - - char *cptr; - - /* - ** We have been sent a new table to install. We need to break - ** it down into little bits and spread it around a bit to see - ** what we have got. - */ - /* - ** Things to check: - ** (things marked 'xx' aren't checked any more!) - ** (1) That there are no booted Hosts/RTAs out there. - ** (2) That the names are properly formed - ** (3) That blank entries really are. - ** xx (4) That hosts mentioned in the table actually exist. xx - ** (5) That the IDs are unique (per host). - ** (6) That host IDs are zero - ** (7) That port numbers are valid - ** (8) That port numbers aren't duplicated - ** (9) That names aren't duplicated - ** xx (10) That hosts that actually exist are mentioned in the table. xx - */ - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(1)\n"); - if (p->RIOSystemUp) { /* (1) */ - p->RIOError.Error = HOST_HAS_ALREADY_BEEN_BOOTED; - return -EBUSY; - } - - p->RIOError.Error = NOTHING_WRONG_AT_ALL; - p->RIOError.Entry = -1; - p->RIOError.Other = -1; - - for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) { - MapP = &p->RIOConnectTable[Entry]; - if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) { - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(2)\n"); - cptr = MapP->Name; /* (2) */ - cptr[MAX_NAME_LEN - 1] = '\0'; - if (cptr[0] == '\0') { - memcpy(MapP->Name, MapP->RtaUniqueNum ? "RTA NN" : "HOST NN", 8); - MapP->Name[5] = '0' + Entry / 10; - MapP->Name[6] = '0' + Entry % 10; - } - while (*cptr) { - if (*cptr < ' ' || *cptr > '~') { - p->RIOError.Error = BAD_CHARACTER_IN_NAME; - p->RIOError.Entry = Entry; - return -ENXIO; - } - cptr++; - } - } - - /* - ** If the entry saved was a tentative entry then just forget - ** about it. - */ - if (MapP->Flags & SLOT_TENTATIVE) { - MapP->HostUniqueNum = 0; - MapP->RtaUniqueNum = 0; - continue; - } - - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(3)\n"); - if (!MapP->RtaUniqueNum && !MapP->HostUniqueNum) { /* (3) */ - if (MapP->ID || MapP->SysPort || MapP->Flags) { - rio_dprintk(RIO_DEBUG_TABLE, "%s pretending to be empty but isn't\n", MapP->Name); - p->RIOError.Error = TABLE_ENTRY_ISNT_PROPERLY_NULL; - p->RIOError.Entry = Entry; - return -ENXIO; - } - rio_dprintk(RIO_DEBUG_TABLE, "!RIO: Daemon: test (3) passes\n"); - continue; - } - - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(4)\n"); - for (Host = 0; Host < p->RIONumHosts; Host++) { /* (4) */ - if (p->RIOHosts[Host].UniqueNum == MapP->HostUniqueNum) { - HostP = &p->RIOHosts[Host]; - /* - ** having done the lookup, we don't really want to do - ** it again, so hang the host number in a safe place - */ - MapP->Topology[0].Unit = Host; - break; - } - } - - if (Host >= p->RIONumHosts) { - rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has unknown host unique number 0x%x\n", MapP->Name, MapP->HostUniqueNum); - MapP->HostUniqueNum = 0; - /* MapP->RtaUniqueNum = 0; */ - /* MapP->ID = 0; */ - /* MapP->Flags = 0; */ - /* MapP->SysPort = 0; */ - /* MapP->Name[0] = 0; */ - continue; - } - - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(5)\n"); - if (MapP->RtaUniqueNum) { /* (5) */ - if (!MapP->ID) { - rio_dprintk(RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an ID of zero!\n", MapP->Name); - p->RIOError.Error = ZERO_RTA_ID; - p->RIOError.Entry = Entry; - return -ENXIO; - } - if (MapP->ID > MAX_RUP) { - rio_dprintk(RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an invalid ID %d\n", MapP->Name, MapP->ID); - p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; - p->RIOError.Entry = Entry; - return -ENXIO; - } - for (SubEnt = 0; SubEnt < Entry; SubEnt++) { - if (MapP->HostUniqueNum == p->RIOConnectTable[SubEnt].HostUniqueNum && MapP->ID == p->RIOConnectTable[SubEnt].ID) { - rio_dprintk(RIO_DEBUG_TABLE, "Dupl. ID number allocated to RTA %s and RTA %s\n", MapP->Name, p->RIOConnectTable[SubEnt].Name); - p->RIOError.Error = DUPLICATED_RTA_ID; - p->RIOError.Entry = Entry; - p->RIOError.Other = SubEnt; - return -ENXIO; - } - /* - ** If the RtaUniqueNum is the same, it may be looking at both - ** entries for a 16 port RTA, so check the ids - */ - if ((MapP->RtaUniqueNum == p->RIOConnectTable[SubEnt].RtaUniqueNum) - && (MapP->ID2 != p->RIOConnectTable[SubEnt].ID)) { - rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n", MapP->Name); - rio_dprintk(RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n", p->RIOConnectTable[SubEnt].Name); - p->RIOError.Error = DUPLICATE_UNIQUE_NUMBER; - p->RIOError.Entry = Entry; - p->RIOError.Other = SubEnt; - return -ENXIO; - } - } - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(7a)\n"); - /* (7a) */ - if ((MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA)) { - rio_dprintk(RIO_DEBUG_TABLE, "TTY Port number %d-RTA %s is not a multiple of %d!\n", (int) MapP->SysPort, MapP->Name, PORTS_PER_RTA); - p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; - p->RIOError.Entry = Entry; - return -ENXIO; - } - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(7b)\n"); - /* (7b) */ - if ((MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS)) { - rio_dprintk(RIO_DEBUG_TABLE, "TTY Port number %d for RTA %s is too big\n", (int) MapP->SysPort, MapP->Name); - p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; - p->RIOError.Entry = Entry; - return -ENXIO; - } - for (SubEnt = 0; SubEnt < Entry; SubEnt++) { - if (p->RIOConnectTable[SubEnt].Flags & RTA16_SECOND_SLOT) - continue; - if (p->RIOConnectTable[SubEnt].RtaUniqueNum) { - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(8)\n"); - /* (8) */ - if ((MapP->SysPort != NO_PORT) && (MapP->SysPort == p->RIOConnectTable[SubEnt].SysPort)) { - rio_dprintk(RIO_DEBUG_TABLE, "RTA %s:same TTY port # as RTA %s (%d)\n", MapP->Name, p->RIOConnectTable[SubEnt].Name, (int) MapP->SysPort); - p->RIOError.Error = TTY_NUMBER_IN_USE; - p->RIOError.Entry = Entry; - p->RIOError.Other = SubEnt; - return -ENXIO; - } - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(9)\n"); - if (strcmp(MapP->Name, p->RIOConnectTable[SubEnt].Name) == 0 && !(MapP->Flags & RTA16_SECOND_SLOT)) { /* (9) */ - rio_dprintk(RIO_DEBUG_TABLE, "RTA name %s used twice\n", MapP->Name); - p->RIOError.Error = NAME_USED_TWICE; - p->RIOError.Entry = Entry; - p->RIOError.Other = SubEnt; - return -ENXIO; - } - } - } - } else { /* (6) */ - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: entering(6)\n"); - if (MapP->ID) { - rio_dprintk(RIO_DEBUG_TABLE, "RIO:HOST %s has been allocated ID that isn't zero!\n", MapP->Name); - p->RIOError.Error = HOST_ID_NOT_ZERO; - p->RIOError.Entry = Entry; - return -ENXIO; - } - if (MapP->SysPort != NO_PORT) { - rio_dprintk(RIO_DEBUG_TABLE, "RIO: HOST %s has been allocated port numbers!\n", MapP->Name); - p->RIOError.Error = HOST_SYSPORT_BAD; - p->RIOError.Entry = Entry; - return -ENXIO; - } - } - } - - /* - ** wow! if we get here then it's a goody! - */ - - /* - ** Zero the (old) entries for each host... - */ - for (Host = 0; Host < RIO_HOSTS; Host++) { - for (Entry = 0; Entry < MAX_RUP; Entry++) { - memset(&p->RIOHosts[Host].Mapping[Entry], 0, sizeof(struct Map)); - } - memset(&p->RIOHosts[Host].Name[0], 0, sizeof(p->RIOHosts[Host].Name)); - } - - /* - ** Copy in the new table entries - */ - for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) { - rio_dprintk(RIO_DEBUG_TABLE, "RIONewTable: Copy table for Host entry %d\n", Entry); - MapP = &p->RIOConnectTable[Entry]; - - /* - ** Now, if it is an empty slot ignore it! - */ - if (MapP->HostUniqueNum == 0) - continue; - - /* - ** we saved the host number earlier, so grab it back - */ - HostP = &p->RIOHosts[MapP->Topology[0].Unit]; - - /* - ** If it is a host, then we only need to fill in the name field. - */ - if (MapP->ID == 0) { - rio_dprintk(RIO_DEBUG_TABLE, "Host entry found. Name %s\n", MapP->Name); - memcpy(HostP->Name, MapP->Name, MAX_NAME_LEN); - continue; - } - - /* - ** Its an RTA entry, so fill in the host mapping entries for it - ** and the port mapping entries. Notice that entry zero is for - ** ID one. - */ - HostMapP = &HostP->Mapping[MapP->ID - 1]; - - if (MapP->Flags & SLOT_IN_USE) { - rio_dprintk(RIO_DEBUG_TABLE, "Rta entry found. Name %s\n", MapP->Name); - /* - ** structure assign, then sort out the bits we shouldn't have done - */ - *HostMapP = *MapP; - - HostMapP->Flags = SLOT_IN_USE; - if (MapP->Flags & RTA16_SECOND_SLOT) - HostMapP->Flags |= RTA16_SECOND_SLOT; - - RIOReMapPorts(p, HostP, HostMapP); - } else { - rio_dprintk(RIO_DEBUG_TABLE, "TENTATIVE Rta entry found. Name %s\n", MapP->Name); - } - } - - for (Entry = 0; Entry < TOTAL_MAP_ENTRIES; Entry++) { - p->RIOSavedTable[Entry] = p->RIOConnectTable[Entry]; - } - - for (Host = 0; Host < p->RIONumHosts; Host++) { - for (SubEnt = 0; SubEnt < LINKS_PER_UNIT; SubEnt++) { - p->RIOHosts[Host].Topology[SubEnt].Unit = ROUTE_DISCONNECT; - p->RIOHosts[Host].Topology[SubEnt].Link = NO_LINK; - } - for (Entry = 0; Entry < MAX_RUP; Entry++) { - for (SubEnt = 0; SubEnt < LINKS_PER_UNIT; SubEnt++) { - p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Unit = ROUTE_DISCONNECT; - p->RIOHosts[Host].Mapping[Entry].Topology[SubEnt].Link = NO_LINK; - } - } - if (!p->RIOHosts[Host].Name[0]) { - memcpy(p->RIOHosts[Host].Name, "HOST 1", 7); - p->RIOHosts[Host].Name[5] += Host; - } - /* - ** Check that default name assigned is unique. - */ - Host1 = Host; - NameIsUnique = 0; - while (!NameIsUnique) { - NameIsUnique = 1; - for (Host2 = 0; Host2 < p->RIONumHosts; Host2++) { - if (Host2 == Host) - continue; - if (strcmp(p->RIOHosts[Host].Name, p->RIOHosts[Host2].Name) - == 0) { - NameIsUnique = 0; - Host1++; - if (Host1 >= p->RIONumHosts) - Host1 = 0; - p->RIOHosts[Host].Name[5] = '1' + Host1; - } - } - } - /* - ** Rename host if name already used. - */ - if (Host1 != Host) { - rio_dprintk(RIO_DEBUG_TABLE, "Default name %s already used\n", p->RIOHosts[Host].Name); - memcpy(p->RIOHosts[Host].Name, "HOST 1", 7); - p->RIOHosts[Host].Name[5] += Host1; - } - rio_dprintk(RIO_DEBUG_TABLE, "Assigning default name %s\n", p->RIOHosts[Host].Name); - } - return 0; -} - -/* -** User process needs the config table - build it from first -** principles. -** -* FIXME: SMP locking -*/ -int RIOApel(struct rio_info *p) -{ - int Host; - int link; - int Rup; - int Next = 0; - struct Map *MapP; - struct Host *HostP; - unsigned long flags; - - rio_dprintk(RIO_DEBUG_TABLE, "Generating a table to return to config.rio\n"); - - memset(&p->RIOConnectTable[0], 0, sizeof(struct Map) * TOTAL_MAP_ENTRIES); - - for (Host = 0; Host < RIO_HOSTS; Host++) { - rio_dprintk(RIO_DEBUG_TABLE, "Processing host %d\n", Host); - HostP = &p->RIOHosts[Host]; - rio_spin_lock_irqsave(&HostP->HostLock, flags); - - MapP = &p->RIOConnectTable[Next++]; - MapP->HostUniqueNum = HostP->UniqueNum; - if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { - rio_spin_unlock_irqrestore(&HostP->HostLock, flags); - continue; - } - MapP->RtaUniqueNum = 0; - MapP->ID = 0; - MapP->Flags = SLOT_IN_USE; - MapP->SysPort = NO_PORT; - for (link = 0; link < LINKS_PER_UNIT; link++) - MapP->Topology[link] = HostP->Topology[link]; - memcpy(MapP->Name, HostP->Name, MAX_NAME_LEN); - for (Rup = 0; Rup < MAX_RUP; Rup++) { - if (HostP->Mapping[Rup].Flags & (SLOT_IN_USE | SLOT_TENTATIVE)) { - p->RIOConnectTable[Next] = HostP->Mapping[Rup]; - if (HostP->Mapping[Rup].Flags & SLOT_IN_USE) - p->RIOConnectTable[Next].Flags |= SLOT_IN_USE; - if (HostP->Mapping[Rup].Flags & SLOT_TENTATIVE) - p->RIOConnectTable[Next].Flags |= SLOT_TENTATIVE; - if (HostP->Mapping[Rup].Flags & RTA16_SECOND_SLOT) - p->RIOConnectTable[Next].Flags |= RTA16_SECOND_SLOT; - Next++; - } - } - rio_spin_unlock_irqrestore(&HostP->HostLock, flags); - } - return 0; -} - -/* -** config.rio has taken a dislike to one of the gross maps entries. -** if the entry is suitably inactive, then we can gob on it and remove -** it from the table. -*/ -int RIODeleteRta(struct rio_info *p, struct Map *MapP) -{ - int host, entry, port, link; - int SysPort; - struct Host *HostP; - struct Map *HostMapP; - struct Port *PortP; - int work_done = 0; - unsigned long lock_flags, sem_flags; - - rio_dprintk(RIO_DEBUG_TABLE, "Delete entry on host %x, rta %x\n", MapP->HostUniqueNum, MapP->RtaUniqueNum); - - for (host = 0; host < p->RIONumHosts; host++) { - HostP = &p->RIOHosts[host]; - - rio_spin_lock_irqsave(&HostP->HostLock, lock_flags); - - if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { - rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); - continue; - } - - for (entry = 0; entry < MAX_RUP; entry++) { - if (MapP->RtaUniqueNum == HostP->Mapping[entry].RtaUniqueNum) { - HostMapP = &HostP->Mapping[entry]; - rio_dprintk(RIO_DEBUG_TABLE, "Found entry offset %d on host %s\n", entry, HostP->Name); - - /* - ** Check all four links of the unit are disconnected - */ - for (link = 0; link < LINKS_PER_UNIT; link++) { - if (HostMapP->Topology[link].Unit != ROUTE_DISCONNECT) { - rio_dprintk(RIO_DEBUG_TABLE, "Entry is in use and cannot be deleted!\n"); - p->RIOError.Error = UNIT_IS_IN_USE; - rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); - return -EBUSY; - } - } - /* - ** Slot has been allocated, BUT not booted/routed/ - ** connected/selected or anything else-ed - */ - SysPort = HostMapP->SysPort; - - if (SysPort != NO_PORT) { - for (port = SysPort; port < SysPort + PORTS_PER_RTA; port++) { - PortP = p->RIOPortp[port]; - rio_dprintk(RIO_DEBUG_TABLE, "Unmap port\n"); - - rio_spin_lock_irqsave(&PortP->portSem, sem_flags); - - PortP->Mapped = 0; - - if (PortP->State & (RIO_MOPEN | RIO_LOPEN)) { - - rio_dprintk(RIO_DEBUG_TABLE, "Gob on port\n"); - PortP->TxBufferIn = PortP->TxBufferOut = 0; - /* What should I do - wakeup( &PortP->TxBufferIn ); - wakeup( &PortP->TxBufferOut); - */ - PortP->InUse = NOT_INUSE; - /* What should I do - wakeup( &PortP->InUse ); - signal(PortP->TtyP->t_pgrp,SIGKILL); - ttyflush(PortP->TtyP,(FREAD|FWRITE)); - */ - PortP->State |= RIO_CLOSING | RIO_DELETED; - } - - /* - ** For the second slot of a 16 port RTA, the - ** driver needs to reset the changes made to - ** the phb to port mappings in RIORouteRup. - */ - if (PortP->SecondBlock) { - u16 dest_unit = HostMapP->ID; - u16 dest_port = port - SysPort; - u16 __iomem *TxPktP; - struct PKT __iomem *Pkt; - - for (TxPktP = PortP->TxStart; TxPktP <= PortP->TxEnd; TxPktP++) { - /* - ** *TxPktP is the pointer to the - ** transmit packet on the host card. - ** This needs to be translated into - ** a 32 bit pointer so it can be - ** accessed from the driver. - */ - Pkt = (struct PKT __iomem *) RIO_PTR(HostP->Caddr, readw(&*TxPktP)); - rio_dprintk(RIO_DEBUG_TABLE, "Tx packet (%x) destination: Old %x:%x New %x:%x\n", readw(TxPktP), readb(&Pkt->dest_unit), readb(&Pkt->dest_port), dest_unit, dest_port); - writew(dest_unit, &Pkt->dest_unit); - writew(dest_port, &Pkt->dest_port); - } - rio_dprintk(RIO_DEBUG_TABLE, "Port %d phb destination: Old %x:%x New %x:%x\n", port, readb(&PortP->PhbP->destination) & 0xff, (readb(&PortP->PhbP->destination) >> 8) & 0xff, dest_unit, dest_port); - writew(dest_unit + (dest_port << 8), &PortP->PhbP->destination); - } - rio_spin_unlock_irqrestore(&PortP->portSem, sem_flags); - } - } - rio_dprintk(RIO_DEBUG_TABLE, "Entry nulled.\n"); - memset(HostMapP, 0, sizeof(struct Map)); - work_done++; - } - } - rio_spin_unlock_irqrestore(&HostP->HostLock, lock_flags); - } - - /* XXXXX lock me up */ - for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { - if (p->RIOSavedTable[entry].RtaUniqueNum == MapP->RtaUniqueNum) { - memset(&p->RIOSavedTable[entry], 0, sizeof(struct Map)); - work_done++; - } - if (p->RIOConnectTable[entry].RtaUniqueNum == MapP->RtaUniqueNum) { - memset(&p->RIOConnectTable[entry], 0, sizeof(struct Map)); - work_done++; - } - } - if (work_done) - return 0; - - rio_dprintk(RIO_DEBUG_TABLE, "Couldn't find entry to be deleted\n"); - p->RIOError.Error = COULDNT_FIND_ENTRY; - return -ENXIO; -} - -int RIOAssignRta(struct rio_info *p, struct Map *MapP) -{ - int host; - struct Map *HostMapP; - char *sptr; - int link; - - - rio_dprintk(RIO_DEBUG_TABLE, "Assign entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum, MapP->RtaUniqueNum, MapP->ID, (int) MapP->SysPort); - - if ((MapP->ID != (u16) - 1) && ((int) MapP->ID < (int) 1 || (int) MapP->ID > MAX_RUP)) { - rio_dprintk(RIO_DEBUG_TABLE, "Bad ID in map entry!\n"); - p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - if (MapP->RtaUniqueNum == 0) { - rio_dprintk(RIO_DEBUG_TABLE, "Rta Unique number zero!\n"); - p->RIOError.Error = RTA_UNIQUE_NUMBER_ZERO; - return -EINVAL; - } - if ((MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA)) { - rio_dprintk(RIO_DEBUG_TABLE, "Port %d not multiple of %d!\n", (int) MapP->SysPort, PORTS_PER_RTA); - p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - if ((MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS)) { - rio_dprintk(RIO_DEBUG_TABLE, "Port %d not valid!\n", (int) MapP->SysPort); - p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - /* - ** Copy the name across to the map entry. - */ - MapP->Name[MAX_NAME_LEN - 1] = '\0'; - sptr = MapP->Name; - while (*sptr) { - if (*sptr < ' ' || *sptr > '~') { - rio_dprintk(RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n"); - p->RIOError.Error = BAD_CHARACTER_IN_NAME; - return -EINVAL; - } - sptr++; - } - - for (host = 0; host < p->RIONumHosts; host++) { - if (MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum) { - if ((p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING) { - p->RIOError.Error = HOST_NOT_RUNNING; - return -ENXIO; - } - - /* - ** Now we have a host we need to allocate an ID - ** if the entry does not already have one. - */ - if (MapP->ID == (u16) - 1) { - int nNewID; - - rio_dprintk(RIO_DEBUG_TABLE, "Attempting to get a new ID for rta \"%s\"\n", MapP->Name); - /* - ** The idea here is to allow RTA's to be assigned - ** before they actually appear on the network. - ** This allows the addition of RTA's without having - ** to plug them in. - ** What we do is: - ** - Find a free ID and allocate it to the RTA. - ** - If this map entry is the second half of a - ** 16 port entry then find the other half and - ** make sure the 2 cross reference each other. - */ - if (RIOFindFreeID(p, &p->RIOHosts[host], &nNewID, NULL) != 0) { - p->RIOError.Error = COULDNT_FIND_ENTRY; - return -EBUSY; - } - MapP->ID = (u16) nNewID + 1; - rio_dprintk(RIO_DEBUG_TABLE, "Allocated ID %d for this new RTA.\n", MapP->ID); - HostMapP = &p->RIOHosts[host].Mapping[nNewID]; - HostMapP->RtaUniqueNum = MapP->RtaUniqueNum; - HostMapP->HostUniqueNum = MapP->HostUniqueNum; - HostMapP->ID = MapP->ID; - for (link = 0; link < LINKS_PER_UNIT; link++) { - HostMapP->Topology[link].Unit = ROUTE_DISCONNECT; - HostMapP->Topology[link].Link = NO_LINK; - } - if (MapP->Flags & RTA16_SECOND_SLOT) { - int unit; - - for (unit = 0; unit < MAX_RUP; unit++) - if (p->RIOHosts[host].Mapping[unit].RtaUniqueNum == MapP->RtaUniqueNum) - break; - if (unit == MAX_RUP) { - p->RIOError.Error = COULDNT_FIND_ENTRY; - return -EBUSY; - } - HostMapP->Flags |= RTA16_SECOND_SLOT; - HostMapP->ID2 = MapP->ID2 = p->RIOHosts[host].Mapping[unit].ID; - p->RIOHosts[host].Mapping[unit].ID2 = MapP->ID; - rio_dprintk(RIO_DEBUG_TABLE, "Cross referenced id %d to ID %d.\n", MapP->ID, p->RIOHosts[host].Mapping[unit].ID); - } - } - - HostMapP = &p->RIOHosts[host].Mapping[MapP->ID - 1]; - - if (HostMapP->Flags & SLOT_IN_USE) { - rio_dprintk(RIO_DEBUG_TABLE, "Map table slot for ID %d is already in use.\n", MapP->ID); - p->RIOError.Error = ID_ALREADY_IN_USE; - return -EBUSY; - } - - /* - ** Assign the sys ports and the name, and mark the slot as - ** being in use. - */ - HostMapP->SysPort = MapP->SysPort; - if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) - memcpy(HostMapP->Name, MapP->Name, MAX_NAME_LEN); - HostMapP->Flags = SLOT_IN_USE | RTA_BOOTED; -#ifdef NEED_TO_FIX - RIO_SV_BROADCAST(p->RIOHosts[host].svFlags[MapP->ID - 1]); -#endif - if (MapP->Flags & RTA16_SECOND_SLOT) - HostMapP->Flags |= RTA16_SECOND_SLOT; - - RIOReMapPorts(p, &p->RIOHosts[host], HostMapP); - /* - ** Adjust 2nd block of 8 phbs - */ - if (MapP->Flags & RTA16_SECOND_SLOT) - RIOFixPhbs(p, &p->RIOHosts[host], HostMapP->ID - 1); - - if (HostMapP->SysPort != NO_PORT) { - if (HostMapP->SysPort < p->RIOFirstPortsBooted) - p->RIOFirstPortsBooted = HostMapP->SysPort; - if (HostMapP->SysPort > p->RIOLastPortsBooted) - p->RIOLastPortsBooted = HostMapP->SysPort; - } - if (MapP->Flags & RTA16_SECOND_SLOT) - rio_dprintk(RIO_DEBUG_TABLE, "Second map of RTA %s added to configuration\n", p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name); - else - rio_dprintk(RIO_DEBUG_TABLE, "RTA %s added to configuration\n", MapP->Name); - return 0; - } - } - p->RIOError.Error = UNKNOWN_HOST_NUMBER; - rio_dprintk(RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum); - return -ENXIO; -} - - -int RIOReMapPorts(struct rio_info *p, struct Host *HostP, struct Map *HostMapP) -{ - struct Port *PortP; - unsigned int SubEnt; - unsigned int HostPort; - unsigned int SysPort; - u16 RtaType; - unsigned long flags; - - rio_dprintk(RIO_DEBUG_TABLE, "Mapping sysport %d to id %d\n", (int) HostMapP->SysPort, HostMapP->ID); - - /* - ** We need to tell the UnixRups which sysport the rup corresponds to - */ - HostP->UnixRups[HostMapP->ID - 1].BaseSysPort = HostMapP->SysPort; - - if (HostMapP->SysPort == NO_PORT) - return (0); - - RtaType = GetUnitType(HostMapP->RtaUniqueNum); - rio_dprintk(RIO_DEBUG_TABLE, "Mapping sysport %d-%d\n", (int) HostMapP->SysPort, (int) HostMapP->SysPort + PORTS_PER_RTA - 1); - - /* - ** now map each of its eight ports - */ - for (SubEnt = 0; SubEnt < PORTS_PER_RTA; SubEnt++) { - rio_dprintk(RIO_DEBUG_TABLE, "subent = %d, HostMapP->SysPort = %d\n", SubEnt, (int) HostMapP->SysPort); - SysPort = HostMapP->SysPort + SubEnt; /* portnumber within system */ - /* portnumber on host */ - - HostPort = (HostMapP->ID - 1) * PORTS_PER_RTA + SubEnt; - - rio_dprintk(RIO_DEBUG_TABLE, "c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp); - PortP = p->RIOPortp[SysPort]; - rio_dprintk(RIO_DEBUG_TABLE, "Map port\n"); - - /* - ** Point at all the real neat data structures - */ - rio_spin_lock_irqsave(&PortP->portSem, flags); - PortP->HostP = HostP; - PortP->Caddr = HostP->Caddr; - - /* - ** The PhbP cannot be filled in yet - ** unless the host has been booted - */ - if ((HostP->Flags & RUN_STATE) == RC_RUNNING) { - struct PHB __iomem *PhbP = PortP->PhbP = &HostP->PhbP[HostPort]; - PortP->TxAdd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_add)); - PortP->TxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_start)); - PortP->TxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->tx_end)); - PortP->RxRemove = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_remove)); - PortP->RxStart = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_start)); - PortP->RxEnd = (u16 __iomem *) RIO_PTR(HostP->Caddr, readw(&PhbP->rx_end)); - } else - PortP->PhbP = NULL; - - /* - ** port related flags - */ - PortP->HostPort = HostPort; - /* - ** For each part of a 16 port RTA, RupNum is ID - 1. - */ - PortP->RupNum = HostMapP->ID - 1; - if (HostMapP->Flags & RTA16_SECOND_SLOT) { - PortP->ID2 = HostMapP->ID2 - 1; - PortP->SecondBlock = 1; - } else { - PortP->ID2 = 0; - PortP->SecondBlock = 0; - } - PortP->RtaUniqueNum = HostMapP->RtaUniqueNum; - - /* - ** If the port was already mapped then thats all we need to do. - */ - if (PortP->Mapped) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - continue; - } else - HostMapP->Flags &= ~RTA_NEWBOOT; - - PortP->State = 0; - PortP->Config = 0; - /* - ** Check out the module type - if it is special (read only etc.) - ** then we need to set flags in the PortP->Config. - ** Note: For 16 port RTA, all ports are of the same type. - */ - if (RtaType == TYPE_RTA16) { - PortP->Config |= p->RIOModuleTypes[HostP->UnixRups[HostMapP->ID - 1].ModTypes].Flags[SubEnt % PORTS_PER_MODULE]; - } else { - if (SubEnt < PORTS_PER_MODULE) - PortP->Config |= p->RIOModuleTypes[LONYBLE(HostP->UnixRups[HostMapP->ID - 1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE]; - else - PortP->Config |= p->RIOModuleTypes[HINYBLE(HostP->UnixRups[HostMapP->ID - 1].ModTypes)].Flags[SubEnt % PORTS_PER_MODULE]; - } - - /* - ** more port related flags - */ - PortP->PortState = 0; - PortP->ModemLines = 0; - PortP->ModemState = 0; - PortP->CookMode = COOK_WELL; - PortP->ParamSem = 0; - PortP->FlushCmdBodge = 0; - PortP->WflushFlag = 0; - PortP->MagicFlags = 0; - PortP->Lock = 0; - PortP->Store = 0; - PortP->FirstOpen = 1; - - /* - ** Buffers 'n things - */ - PortP->RxDataStart = 0; - PortP->Cor2Copy = 0; - PortP->Name = &HostMapP->Name[0]; - PortP->statsGather = 0; - PortP->txchars = 0; - PortP->rxchars = 0; - PortP->opens = 0; - PortP->closes = 0; - PortP->ioctls = 0; - if (PortP->TxRingBuffer) - memset(PortP->TxRingBuffer, 0, p->RIOBufferSize); - else if (p->RIOBufferSize) { - PortP->TxRingBuffer = kzalloc(p->RIOBufferSize, GFP_KERNEL); - } - PortP->TxBufferOut = 0; - PortP->TxBufferIn = 0; - PortP->Debug = 0; - /* - ** LastRxTgl stores the state of the rx toggle bit for this - ** port, to be compared with the state of the next pkt received. - ** If the same, we have received the same rx pkt from the RTA - ** twice. Initialise to a value not equal to PHB_RX_TGL or 0. - */ - PortP->LastRxTgl = ~(u8) PHB_RX_TGL; - - /* - ** and mark the port as usable - */ - PortP->Mapped = 1; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - } - if (HostMapP->SysPort < p->RIOFirstPortsMapped) - p->RIOFirstPortsMapped = HostMapP->SysPort; - if (HostMapP->SysPort > p->RIOLastPortsMapped) - p->RIOLastPortsMapped = HostMapP->SysPort; - - return 0; -} - -int RIOChangeName(struct rio_info *p, struct Map *MapP) -{ - int host; - struct Map *HostMapP; - char *sptr; - - rio_dprintk(RIO_DEBUG_TABLE, "Change name entry on host %x, rta %x, ID %d, Sysport %d\n", MapP->HostUniqueNum, MapP->RtaUniqueNum, MapP->ID, (int) MapP->SysPort); - - if (MapP->ID > MAX_RUP) { - rio_dprintk(RIO_DEBUG_TABLE, "Bad ID in map entry!\n"); - p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE; - return -EINVAL; - } - - MapP->Name[MAX_NAME_LEN - 1] = '\0'; - sptr = MapP->Name; - - while (*sptr) { - if (*sptr < ' ' || *sptr > '~') { - rio_dprintk(RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n"); - p->RIOError.Error = BAD_CHARACTER_IN_NAME; - return -EINVAL; - } - sptr++; - } - - for (host = 0; host < p->RIONumHosts; host++) { - if (MapP->HostUniqueNum == p->RIOHosts[host].UniqueNum) { - if ((p->RIOHosts[host].Flags & RUN_STATE) != RC_RUNNING) { - p->RIOError.Error = HOST_NOT_RUNNING; - return -ENXIO; - } - if (MapP->ID == 0) { - memcpy(p->RIOHosts[host].Name, MapP->Name, MAX_NAME_LEN); - return 0; - } - - HostMapP = &p->RIOHosts[host].Mapping[MapP->ID - 1]; - - if (HostMapP->RtaUniqueNum != MapP->RtaUniqueNum) { - p->RIOError.Error = RTA_NUMBER_WRONG; - return -ENXIO; - } - memcpy(HostMapP->Name, MapP->Name, MAX_NAME_LEN); - return 0; - } - } - p->RIOError.Error = UNKNOWN_HOST_NUMBER; - rio_dprintk(RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum); - return -ENXIO; -} diff --git a/drivers/staging/generic_serial/rio/riotty.c b/drivers/staging/generic_serial/rio/riotty.c deleted file mode 100644 index e7e9911d7a72..000000000000 --- a/drivers/staging/generic_serial/rio/riotty.c +++ /dev/null @@ -1,654 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : riotty.c -** SID : 1.3 -** Last Modified : 11/6/98 10:33:47 -** Retrieved : 11/6/98 10:33:50 -** -** ident @(#)riotty.c 1.3 -** -** ----------------------------------------------------------------------------- -*/ - -#define __EXPLICIT_DEF_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - - -#include "linux_compat.h" -#include "rio_linux.h" -#include "pkt.h" -#include "daemon.h" -#include "rio.h" -#include "riospace.h" -#include "cmdpkt.h" -#include "map.h" -#include "rup.h" -#include "port.h" -#include "riodrvr.h" -#include "rioinfo.h" -#include "func.h" -#include "errors.h" -#include "pci.h" - -#include "parmmap.h" -#include "unixrup.h" -#include "board.h" -#include "host.h" -#include "phb.h" -#include "link.h" -#include "cmdblk.h" -#include "route.h" -#include "cirrus.h" -#include "rioioctl.h" -#include "param.h" - -static void RIOClearUp(struct Port *PortP); - -/* Below belongs in func.h */ -int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg); - - -extern struct rio_info *p; - - -int riotopen(struct tty_struct *tty, struct file *filp) -{ - unsigned int SysPort; - int repeat_this = 250; - struct Port *PortP; /* pointer to the port structure */ - unsigned long flags; - int retval = 0; - - func_enter(); - - /* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close - is going to oops. - */ - tty->driver_data = NULL; - - SysPort = rio_minor(tty); - - if (p->RIOFailed) { - rio_dprintk(RIO_DEBUG_TTY, "System initialisation failed\n"); - func_exit(); - return -ENXIO; - } - - rio_dprintk(RIO_DEBUG_TTY, "port open SysPort %d (mapped:%d)\n", SysPort, p->RIOPortp[SysPort]->Mapped); - - /* - ** Validate that we have received a legitimate request. - ** Currently, just check that we are opening a port on - ** a host card that actually exists, and that the port - ** has been mapped onto a host. - */ - if (SysPort >= RIO_PORTS) { /* out of range ? */ - rio_dprintk(RIO_DEBUG_TTY, "Illegal port number %d\n", SysPort); - func_exit(); - return -ENXIO; - } - - /* - ** Grab pointer to the port structure - */ - PortP = p->RIOPortp[SysPort]; /* Get control struc */ - rio_dprintk(RIO_DEBUG_TTY, "PortP: %p\n", PortP); - if (!PortP->Mapped) { /* we aren't mapped yet! */ - /* - ** The system doesn't know which RTA this port - ** corresponds to. - */ - rio_dprintk(RIO_DEBUG_TTY, "port not mapped into system\n"); - func_exit(); - return -ENXIO; - } - - tty->driver_data = PortP; - - PortP->gs.port.tty = tty; - PortP->gs.port.count++; - - rio_dprintk(RIO_DEBUG_TTY, "%d bytes in tx buffer\n", PortP->gs.xmit_cnt); - - retval = gs_init_port(&PortP->gs); - if (retval) { - PortP->gs.port.count--; - return -ENXIO; - } - /* - ** If the host hasn't been booted yet, then - ** fail - */ - if ((PortP->HostP->Flags & RUN_STATE) != RC_RUNNING) { - rio_dprintk(RIO_DEBUG_TTY, "Host not running\n"); - func_exit(); - return -ENXIO; - } - - /* - ** If the RTA has not booted yet and the user has chosen to block - ** until the RTA is present then we must spin here waiting for - ** the RTA to boot. - */ - /* I find the above code a bit hairy. I find the below code - easier to read and shorter. Now, if it works too that would - be great... -- REW - */ - rio_dprintk(RIO_DEBUG_TTY, "Checking if RTA has booted... \n"); - while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) { - if (!PortP->WaitUntilBooted) { - rio_dprintk(RIO_DEBUG_TTY, "RTA never booted\n"); - func_exit(); - return -ENXIO; - } - - /* Under Linux you'd normally use a wait instead of this - busy-waiting. I'll stick with the old implementation for - now. --REW - */ - if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n"); - func_exit(); - return -EINTR; - } - if (repeat_this-- <= 0) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n"); - func_exit(); - return -EIO; - } - } - rio_dprintk(RIO_DEBUG_TTY, "RTA has been booted\n"); - rio_spin_lock_irqsave(&PortP->portSem, flags); - if (p->RIOHalted) { - goto bombout; - } - - /* - ** If the port is in the final throws of being closed, - ** we should wait here (politely), waiting - ** for it to finish, so that it doesn't close us! - */ - while ((PortP->State & RIO_CLOSING) && !p->RIOHalted) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n"); - if (repeat_this-- <= 0) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - retval = -EINTR; - goto bombout; - } - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { - rio_spin_lock_irqsave(&PortP->portSem, flags); - retval = -EINTR; - goto bombout; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - } - - if (!PortP->Mapped) { - rio_dprintk(RIO_DEBUG_TTY, "Port unmapped while closing!\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - retval = -ENXIO; - func_exit(); - return retval; - } - - if (p->RIOHalted) { - goto bombout; - } - -/* -** 15.10.1998 ARG - ESIL 0761 part fix -** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure, -** we need to make sure that the flags are clear when the port is opened. -*/ - /* Uh? Suppose I turn these on and then another process opens - the port again? The flags get cleared! Not good. -- REW */ - if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) { - PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW); - } - - if (!(PortP->firstOpen)) { /* First time ? */ - rio_dprintk(RIO_DEBUG_TTY, "First open for this port\n"); - - - PortP->firstOpen++; - PortP->CookMode = 0; /* XXX RIOCookMode(tp); */ - PortP->InUse = NOT_INUSE; - - /* Tentative fix for bug PR27. Didn't work. */ - /* PortP->gs.xmit_cnt = 0; */ - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - - /* Someone explain to me why this delay/config is - here. If I read the docs correctly the "open" - command piggybacks the parameters immediately. - -- REW */ - RIOParam(PortP, RIOC_OPEN, 1, OK_TO_SLEEP); /* Open the port */ - rio_spin_lock_irqsave(&PortP->portSem, flags); - - /* - ** wait for the port to be not closed. - */ - while (!(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n", PortP->PortState); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n"); - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - func_exit(); - return -EINTR; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - } - - if (p->RIOHalted) { - retval = -EIO; - bombout: - /* RIOClearUp( PortP ); */ - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return retval; - } - rio_dprintk(RIO_DEBUG_TTY, "PORT_ISOPEN found\n"); - } - rio_dprintk(RIO_DEBUG_TTY, "Modem - test for carrier\n"); - /* - ** ACTION - ** insert test for carrier here. -- ??? - ** I already see that test here. What's the deal? -- REW - */ - if ((PortP->gs.port.tty->termios->c_cflag & CLOCAL) || - (PortP->ModemState & RIOC_MSVR1_CD)) { - rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort); - /* - tp->tm.c_state |= CARR_ON; - wakeup((caddr_t) &tp->tm.c_canq); - */ - PortP->State |= RIO_CARR_ON; - wake_up_interruptible(&PortP->gs.port.open_wait); - } else { /* no carrier - wait for DCD */ - /* - while (!(PortP->gs.port.tty->termios->c_state & CARR_ON) && - !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted ) - */ - while (!(PortP->State & RIO_CARR_ON) && !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted) { - rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n", SysPort); - /* - PortP->gs.port.tty->termios->c_state |= WOPEN; - */ - PortP->State |= RIO_WOPEN; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { - rio_spin_lock_irqsave(&PortP->portSem, flags); - /* - ** ACTION: verify that this is a good thing - ** to do here. -- ??? - ** I think it's OK. -- REW - */ - rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n", SysPort); - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - /* - tp->tm.c_state &= ~WOPEN; - */ - PortP->State &= ~RIO_WOPEN; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - func_exit(); - return -EINTR; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - } - PortP->State &= ~RIO_WOPEN; - } - if (p->RIOHalted) - goto bombout; - rio_dprintk(RIO_DEBUG_TTY, "Setting RIO_MOPEN\n"); - PortP->State |= RIO_MOPEN; - - if (p->RIOHalted) - goto bombout; - - rio_dprintk(RIO_DEBUG_TTY, "high level open done\n"); - - /* - ** Count opens for port statistics reporting - */ - if (PortP->statsGather) - PortP->opens++; - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - rio_dprintk(RIO_DEBUG_TTY, "Returning from open\n"); - func_exit(); - return 0; -} - -/* -** RIOClose the port. -** The operating system thinks that this is last close for the device. -** As there are two interfaces to the port (Modem and tty), we need to -** check that both are closed before we close the device. -*/ -int riotclose(void *ptr) -{ - struct Port *PortP = ptr; /* pointer to the port structure */ - int deleted = 0; - int try = -1; /* Disable the timeouts by setting them to -1 */ - int repeat_this = -1; /* Congrats to those having 15 years of - uptime! (You get to break the driver.) */ - unsigned long end_time; - struct tty_struct *tty; - unsigned long flags; - int rv = 0; - - rio_dprintk(RIO_DEBUG_TTY, "port close SysPort %d\n", PortP->PortNum); - - /* PortP = p->RIOPortp[SysPort]; */ - rio_dprintk(RIO_DEBUG_TTY, "Port is at address %p\n", PortP); - /* tp = PortP->TtyP; *//* Get tty */ - tty = PortP->gs.port.tty; - rio_dprintk(RIO_DEBUG_TTY, "TTY is at address %p\n", tty); - - if (PortP->gs.closing_wait) - end_time = jiffies + PortP->gs.closing_wait; - else - end_time = jiffies + MAX_SCHEDULE_TIMEOUT; - - rio_spin_lock_irqsave(&PortP->portSem, flags); - - /* - ** Setting this flag will make any process trying to open - ** this port block until we are complete closing it. - */ - PortP->State |= RIO_CLOSING; - - if ((PortP->State & RIO_DELETED)) { - rio_dprintk(RIO_DEBUG_TTY, "Close on deleted RTA\n"); - deleted = 1; - } - - if (p->RIOHalted) { - RIOClearUp(PortP); - rv = -EIO; - goto close_end; - } - - rio_dprintk(RIO_DEBUG_TTY, "Clear bits\n"); - /* - ** clear the open bits for this device - */ - PortP->State &= ~RIO_MOPEN; - PortP->State &= ~RIO_CARR_ON; - PortP->ModemState &= ~RIOC_MSVR1_CD; - /* - ** If the device was open as both a Modem and a tty line - ** then we need to wimp out here, as the port has not really - ** been finally closed (gee, whizz!) The test here uses the - ** bit for the OTHER mode of operation, to see if THAT is - ** still active! - */ - if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) { - /* - ** The port is still open for the other task - - ** return, pretending that we are still active. - */ - rio_dprintk(RIO_DEBUG_TTY, "Channel %d still open !\n", PortP->PortNum); - PortP->State &= ~RIO_CLOSING; - if (PortP->firstOpen) - PortP->firstOpen--; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return -EIO; - } - - rio_dprintk(RIO_DEBUG_TTY, "Closing down - everything must go!\n"); - - PortP->State &= ~RIO_DYNOROD; - - /* - ** This is where we wait for the port - ** to drain down before closing. Bye-bye.... - ** (We never meant to do this) - */ - rio_dprintk(RIO_DEBUG_TTY, "Timeout 1 starts\n"); - - if (!deleted) - while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted && (PortP->TxBufferIn != PortP->TxBufferOut)) { - if (repeat_this-- <= 0) { - rv = -EINTR; - rio_dprintk(RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - goto close_end; - } - rio_dprintk(RIO_DEBUG_TTY, "Calling timeout to flush in closing\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (RIODelay_ni(PortP, HUNDRED_MS * 10) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n"); - rv = -EINTR; - rio_spin_lock_irqsave(&PortP->portSem, flags); - goto close_end; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - } - - PortP->TxBufferIn = PortP->TxBufferOut = 0; - repeat_this = 0xff; - - PortP->InUse = 0; - if ((PortP->State & (RIO_LOPEN | RIO_MOPEN))) { - /* - ** The port has been re-opened for the other task - - ** return, pretending that we are still active. - */ - rio_dprintk(RIO_DEBUG_TTY, "Channel %d re-open!\n", PortP->PortNum); - PortP->State &= ~RIO_CLOSING; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (PortP->firstOpen) - PortP->firstOpen--; - return -EIO; - } - - if (p->RIOHalted) { - RIOClearUp(PortP); - goto close_end; - } - - /* Can't call RIOShortCommand with the port locked. */ - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - - if (RIOShortCommand(p, PortP, RIOC_CLOSE, 1, 0) == RIO_FAIL) { - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - rio_spin_lock_irqsave(&PortP->portSem, flags); - goto close_end; - } - - if (!deleted) - while (try && (PortP->PortState & PORT_ISOPEN)) { - try--; - if (time_after(jiffies, end_time)) { - rio_dprintk(RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n"); - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - break; - } - rio_dprintk(RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", PortP->PortState & PORT_ISOPEN); - - if (p->RIOHalted) { - RIOClearUp(PortP); - rio_spin_lock_irqsave(&PortP->portSem, flags); - goto close_end; - } - if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) { - rio_dprintk(RIO_DEBUG_TTY, "RTA EINTR in delay \n"); - RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); - break; - } - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - rio_dprintk(RIO_DEBUG_TTY, "Close: try was %d on completion\n", try); - - /* RIOPreemptiveCmd(p, PortP, RIOC_FCLOSE); */ - -/* -** 15.10.1998 ARG - ESIL 0761 part fix -** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure,** we need to make sure that the flags are clear when the port is opened. -*/ - PortP->Config &= ~(RIO_CTSFLOW | RIO_RTSFLOW); - - /* - ** Count opens for port statistics reporting - */ - if (PortP->statsGather) - PortP->closes++; - -close_end: - /* XXX: Why would a "DELETED" flag be reset here? I'd have - thought that a "deleted" flag means that the port was - permanently gone, but here we can make it reappear by it - being in close during the "deletion". - */ - PortP->State &= ~(RIO_CLOSING | RIO_DELETED); - if (PortP->firstOpen) - PortP->firstOpen--; - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - rio_dprintk(RIO_DEBUG_TTY, "Return from close\n"); - return rv; -} - - - -static void RIOClearUp(struct Port *PortP) -{ - rio_dprintk(RIO_DEBUG_TTY, "RIOHalted set\n"); - PortP->Config = 0; /* Direct semaphore */ - PortP->PortState = 0; - PortP->firstOpen = 0; - PortP->FlushCmdBodge = 0; - PortP->ModemState = PortP->CookMode = 0; - PortP->Mapped = 0; - PortP->WflushFlag = 0; - PortP->MagicFlags = 0; - PortP->RxDataStart = 0; - PortP->TxBufferIn = 0; - PortP->TxBufferOut = 0; -} - -/* -** Put a command onto a port. -** The PortPointer, command, length and arg are passed. -** The len is the length *inclusive* of the command byte, -** and so for a command that takes no data, len==1. -** The arg is a single byte, and is only used if len==2. -** Other values of len aren't allowed, and will cause -** a panic. -*/ -int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg) -{ - struct PKT __iomem *PacketP; - int retries = 20; /* at 10 per second -> 2 seconds */ - unsigned long flags; - - rio_dprintk(RIO_DEBUG_TTY, "entering shortcommand.\n"); - - if (PortP->State & RIO_DELETED) { - rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n"); - return RIO_FAIL; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - - /* - ** If the port is in use for pre-emptive command, then wait for it to - ** be free again. - */ - while ((PortP->InUse != NOT_INUSE) && !p->RIOHalted) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting for not in use (%d)\n", retries); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (retries-- <= 0) { - return RIO_FAIL; - } - if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) { - return RIO_FAIL; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - } - if (PortP->State & RIO_DELETED) { - rio_dprintk(RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n"); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return RIO_FAIL; - } - - while (!can_add_transmit(&PacketP, PortP) && !p->RIOHalted) { - rio_dprintk(RIO_DEBUG_TTY, "Waiting to add short command to queue (%d)\n", retries); - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - if (retries-- <= 0) { - rio_dprintk(RIO_DEBUG_TTY, "out of tries. Failing\n"); - return RIO_FAIL; - } - if (RIODelay_ni(PortP, HUNDRED_MS) == RIO_FAIL) { - return RIO_FAIL; - } - rio_spin_lock_irqsave(&PortP->portSem, flags); - } - - if (p->RIOHalted) { - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return RIO_FAIL; - } - - /* - ** set the command byte and the argument byte - */ - writeb(command, &PacketP->data[0]); - - if (len == 2) - writeb(arg, &PacketP->data[1]); - - /* - ** set the length of the packet and set the command bit. - */ - writeb(PKT_CMD_BIT | len, &PacketP->len); - - add_transmit(PortP); - /* - ** Count characters transmitted for port statistics reporting - */ - if (PortP->statsGather) - PortP->txchars += len; - - rio_spin_unlock_irqrestore(&PortP->portSem, flags); - return p->RIOHalted ? RIO_FAIL : ~RIO_FAIL; -} - - diff --git a/drivers/staging/generic_serial/rio/route.h b/drivers/staging/generic_serial/rio/route.h deleted file mode 100644 index 46e963771c30..000000000000 --- a/drivers/staging/generic_serial/rio/route.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* R O U T E H E A D E R - ******* ******* - **************************************************************************** - - Author : Ian Nandhra / Jeremy Rolls - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _route_h -#define _route_h - -#define MAX_LINKS 4 -#define MAX_NODES 17 /* Maximum nodes in a subnet */ -#define NODE_BYTES ((MAX_NODES / 8) + 1) /* Number of bytes needed for - 1 bit per node */ -#define ROUTE_DATA_SIZE (NODE_BYTES + 2) /* Number of bytes for complete - info about cost etc. */ -#define ROUTES_PER_PACKET ((PKT_MAX_DATA_LEN -2)/ ROUTE_DATA_SIZE) - /* Number of nodes we can squeeze - into one packet */ -#define MAX_TOPOLOGY_PACKETS (MAX_NODES / ROUTES_PER_PACKET + 1) -/************************************************ - * Define the types of command for the ROUTE RUP. - ************************************************/ -#define ROUTE_REQUEST 0 /* Request an ID */ -#define ROUTE_FOAD 1 /* Kill the RTA */ -#define ROUTE_ALREADY 2 /* ID given already */ -#define ROUTE_USED 3 /* All ID's used */ -#define ROUTE_ALLOCATE 4 /* Here it is */ -#define ROUTE_REQ_TOP 5 /* I bet you didn't expect.... - the Topological Inquisition */ -#define ROUTE_TOPOLOGY 6 /* Topology request answered FD */ -/******************************************************************* - * Define the Route Map Structure - * - * The route map gives a pointer to a Link Structure to use. - * This allows Disconnected Links to be checked quickly - ******************************************************************/ -typedef struct COST_ROUTE COST_ROUTE; -struct COST_ROUTE { - unsigned char cost; /* Cost down this link */ - unsigned char route[NODE_BYTES]; /* Nodes through this route */ -}; - -typedef struct ROUTE_STR ROUTE_STR; -struct ROUTE_STR { - COST_ROUTE cost_route[MAX_LINKS]; - /* cost / route for this link */ - ushort favoured; /* favoured link */ -}; - - -#define NO_LINK (short) 5 /* Link unattached */ -#define ROUTE_NO_ID (short) 100 /* No Id */ -#define ROUTE_DISCONNECT (ushort) 0xff /* Not connected */ -#define ROUTE_INTERCONNECT (ushort) 0x40 /* Sub-net interconnect */ - - -#define SYNC_RUP (ushort) 255 -#define COMMAND_RUP (ushort) 254 -#define ERROR_RUP (ushort) 253 -#define POLL_RUP (ushort) 252 -#define BOOT_RUP (ushort) 251 -#define ROUTE_RUP (ushort) 250 -#define STATUS_RUP (ushort) 249 -#define POWER_RUP (ushort) 248 - -#define HIGHEST_RUP (ushort) 255 /* Set to Top one */ -#define LOWEST_RUP (ushort) 248 /* Set to bottom one */ - -#endif - -/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/rup.h b/drivers/staging/generic_serial/rio/rup.h deleted file mode 100644 index 4ae90cb207a9..000000000000 --- a/drivers/staging/generic_serial/rio/rup.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** - ******* ******* - ******* R U P S T R U C T U R E - ******* ******* - **************************************************************************** - - Author : Ian Nandhra - Date : - - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. - - Version : 0.01 - - - Mods - ---------------------------------------------------------------------------- - Date By Description - ---------------------------------------------------------------------------- - - ***************************************************************************/ - -#ifndef _rup_h -#define _rup_h 1 - -#define MAX_RUP ((short) 16) -#define PKTS_PER_RUP ((short) 2) /* They are always used in pairs */ - -/************************************************* - * Define all the packet request stuff - ************************************************/ -#define TX_RUP_INACTIVE 0 /* Nothing to transmit */ -#define TX_PACKET_READY 1 /* Transmit packet ready */ -#define TX_LOCK_RUP 2 /* Transmit side locked */ - -#define RX_RUP_INACTIVE 0 /* Nothing received */ -#define RX_PACKET_READY 1 /* Packet received */ - -#define RUP_NO_OWNER 0xff /* RUP not owned by any process */ - -struct RUP { - u16 txpkt; /* Outgoing packet */ - u16 rxpkt; /* Incoming packet */ - u16 link; /* Which link to send down? */ - u8 rup_dest_unit[2]; /* Destination unit */ - u16 handshake; /* For handshaking */ - u16 timeout; /* Timeout */ - u16 status; /* Status */ - u16 txcontrol; /* Transmit control */ - u16 rxcontrol; /* Receive control */ -}; - -#endif - -/*********** end of file ***********/ diff --git a/drivers/staging/generic_serial/rio/unixrup.h b/drivers/staging/generic_serial/rio/unixrup.h deleted file mode 100644 index 7abf0cba0f2c..000000000000 --- a/drivers/staging/generic_serial/rio/unixrup.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -** ----------------------------------------------------------------------------- -** -** Perle Specialix driver for Linux -** Ported from existing RIO Driver for SCO sources. - * - * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. - * - * 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. -** -** Module : unixrup.h -** SID : 1.2 -** Last Modified : 11/6/98 11:34:20 -** Retrieved : 11/6/98 11:34:22 -** -** ident @(#)unixrup.h 1.2 -** -** ----------------------------------------------------------------------------- -*/ - -#ifndef __rio_unixrup_h__ -#define __rio_unixrup_h__ - -/* -** UnixRup data structure. This contains pointers to actual RUPs on the -** host card, and all the command/boot control stuff. -*/ -struct UnixRup { - struct CmdBlk *CmdsWaitingP; /* Commands waiting to be done */ - struct CmdBlk *CmdPendingP; /* The command currently being sent */ - struct RUP __iomem *RupP; /* the Rup to send it to */ - unsigned int Id; /* Id number */ - unsigned int BaseSysPort; /* SysPort of first tty on this RTA */ - unsigned int ModTypes; /* Modules on this RTA */ - spinlock_t RupLock; /* Lock structure for MPX */ - /* struct lockb RupLock; *//* Lock structure for MPX */ -}; - -#endif /* __rio_unixrup_h__ */ diff --git a/drivers/staging/generic_serial/ser_a2232.c b/drivers/staging/generic_serial/ser_a2232.c deleted file mode 100644 index 3f47c2ead8e5..000000000000 --- a/drivers/staging/generic_serial/ser_a2232.c +++ /dev/null @@ -1,831 +0,0 @@ -/* drivers/char/ser_a2232.c */ - -/* $Id: ser_a2232.c,v 0.4 2000/01/25 12:00:00 ehaase Exp $ */ - -/* Linux serial driver for the Amiga A2232 board */ - -/* This driver is MAINTAINED. Before applying any changes, please contact - * the author. - */ - -/* Copyright (c) 2000-2001 Enver Haase - * alias The A2232 driver project - * 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. - * - * 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. - * - */ -/***************************** Documentation ************************/ -/* - * This driver is in EXPERIMENTAL state. That means I could not find - * someone with five A2232 boards with 35 ports running at 19200 bps - * at the same time and test the machine's behaviour. - * However, I know that you can performance-tweak this driver (see - * the source code). - * One thing to consider is the time this driver consumes during the - * Amiga's vertical blank interrupt. Everything that is to be done - * _IS DONE_ when entering the vertical blank interrupt handler of - * this driver. - * However, it would be more sane to only do the job for only ONE card - * instead of ALL cards at a time; or, more generally, to handle only - * SOME ports instead of ALL ports at a time. - * However, as long as no-one runs into problems I guess I shouldn't - * change the driver as it runs fine for me :) . - * - * Version history of this file: - * 0.4 Resolved licensing issues. - * 0.3 Inclusion in the Linux/m68k tree, small fixes. - * 0.2 Added documentation, minor typo fixes. - * 0.1 Initial release. - * - * TO DO: - * - Handle incoming BREAK events. I guess "Stevens: Advanced - * Programming in the UNIX(R) Environment" is a good reference - * on what is to be done. - * - When installing as a module, don't simply 'printk' text, but - * send it to the TTY used by the user. - * - * THANKS TO: - * - Jukka Marin (65EC02 code). - * - The other NetBSD developers on whose A2232 driver I had a - * pretty close look. However, I didn't copy any code so it - * is okay to put my code under the GPL and include it into - * Linux. - */ -/***************************** End of Documentation *****************/ - -/***************************** Defines ******************************/ -/* - * Enables experimental 115200 (normal) 230400 (turbo) baud rate. - * The A2232 specification states it can only operate at speeds up to - * 19200 bits per second, and I was not able to send a file via - * "sz"/"rz" and a null-modem cable from one A2232 port to another - * at 115200 bits per second. - * However, this might work for you. - */ -#undef A2232_SPEEDHACK -/* - * Default is not to use RTS/CTS so you could be talked to death. - */ -#define A2232_SUPPRESS_RTSCTS_WARNING -/************************* End of Defines ***************************/ - -/***************************** Includes *****************************/ -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "ser_a2232.h" -#include "ser_a2232fw.h" -/************************* End of Includes **************************/ - -/***************************** Prototypes ***************************/ -/* The interrupt service routine */ -static irqreturn_t a2232_vbl_inter(int irq, void *data); -/* Initialize the port structures */ -static void a2232_init_portstructs(void); -/* Initialize and register TTY drivers. */ -/* returns 0 IFF successful */ -static int a2232_init_drivers(void); - -/* BEGIN GENERIC_SERIAL PROTOTYPES */ -static void a2232_disable_tx_interrupts(void *ptr); -static void a2232_enable_tx_interrupts(void *ptr); -static void a2232_disable_rx_interrupts(void *ptr); -static void a2232_enable_rx_interrupts(void *ptr); -static int a2232_carrier_raised(struct tty_port *port); -static void a2232_shutdown_port(void *ptr); -static int a2232_set_real_termios(void *ptr); -static int a2232_chars_in_buffer(void *ptr); -static void a2232_close(void *ptr); -static void a2232_hungup(void *ptr); -/* static void a2232_getserial (void *ptr, struct serial_struct *sp); */ -/* END GENERIC_SERIAL PROTOTYPES */ - -/* Functions that the TTY driver struct expects */ -static int a2232_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -static void a2232_throttle(struct tty_struct *tty); -static void a2232_unthrottle(struct tty_struct *tty); -static int a2232_open(struct tty_struct * tty, struct file * filp); -/************************* End of Prototypes ************************/ - -/***************************** Global variables *********************/ -/*--------------------------------------------------------------------------- - * Interface from generic_serial.c back here - *--------------------------------------------------------------------------*/ -static struct real_driver a2232_real_driver = { - a2232_disable_tx_interrupts, - a2232_enable_tx_interrupts, - a2232_disable_rx_interrupts, - a2232_enable_rx_interrupts, - a2232_shutdown_port, - a2232_set_real_termios, - a2232_chars_in_buffer, - a2232_close, - a2232_hungup, - NULL /* a2232_getserial */ -}; - -static void *a2232_driver_ID = &a2232_driver_ID; // Some memory address WE own. - -/* Ports structs */ -static struct a2232_port a2232_ports[MAX_A2232_BOARDS*NUMLINES]; - -/* TTY driver structs */ -static struct tty_driver *a2232_driver; - -/* nr of cards completely (all ports) and correctly configured */ -static int nr_a2232; - -/* zorro_dev structs for the A2232's */ -static struct zorro_dev *zd_a2232[MAX_A2232_BOARDS]; -/***************************** End of Global variables **************/ - -/* Helper functions */ - -static inline volatile struct a2232memory *a2232mem(unsigned int board) -{ - return (volatile struct a2232memory *)ZTWO_VADDR(zd_a2232[board]->resource.start); -} - -static inline volatile struct a2232status *a2232stat(unsigned int board, - unsigned int portonboard) -{ - volatile struct a2232memory *mem = a2232mem(board); - return &(mem->Status[portonboard]); -} - -static inline void a2232_receive_char(struct a2232_port *port, int ch, int err) -{ -/* Mostly stolen from other drivers. - Maybe one could implement a more efficient version by not only - transferring one character at a time. -*/ - struct tty_struct *tty = port->gs.port.tty; - -#if 0 - switch(err) { - case TTY_BREAK: - break; - case TTY_PARITY: - break; - case TTY_OVERRUN: - break; - case TTY_FRAME: - break; - } -#endif - - tty_insert_flip_char(tty, ch, err); - tty_flip_buffer_push(tty); -} - -/***************************** Functions ****************************/ -/*** BEGIN OF REAL_DRIVER FUNCTIONS ***/ - -static void a2232_disable_tx_interrupts(void *ptr) -{ - struct a2232_port *port; - volatile struct a2232status *stat; - unsigned long flags; - - port = ptr; - stat = a2232stat(port->which_a2232, port->which_port_on_a2232); - stat->OutDisable = -1; - - /* Does this here really have to be? */ - local_irq_save(flags); - port->gs.port.flags &= ~GS_TX_INTEN; - local_irq_restore(flags); -} - -static void a2232_enable_tx_interrupts(void *ptr) -{ - struct a2232_port *port; - volatile struct a2232status *stat; - unsigned long flags; - - port = ptr; - stat = a2232stat(port->which_a2232, port->which_port_on_a2232); - stat->OutDisable = 0; - - /* Does this here really have to be? */ - local_irq_save(flags); - port->gs.port.flags |= GS_TX_INTEN; - local_irq_restore(flags); -} - -static void a2232_disable_rx_interrupts(void *ptr) -{ - struct a2232_port *port; - port = ptr; - port->disable_rx = -1; -} - -static void a2232_enable_rx_interrupts(void *ptr) -{ - struct a2232_port *port; - port = ptr; - port->disable_rx = 0; -} - -static int a2232_carrier_raised(struct tty_port *port) -{ - struct a2232_port *ap = container_of(port, struct a2232_port, gs.port); - return ap->cd_status; -} - -static void a2232_shutdown_port(void *ptr) -{ - struct a2232_port *port; - volatile struct a2232status *stat; - unsigned long flags; - - port = ptr; - stat = a2232stat(port->which_a2232, port->which_port_on_a2232); - - local_irq_save(flags); - - port->gs.port.flags &= ~GS_ACTIVE; - - if (port->gs.port.tty && port->gs.port.tty->termios->c_cflag & HUPCL) { - /* Set DTR and RTS to Low, flush output. - The NetBSD driver "msc.c" does it this way. */ - stat->Command = ( (stat->Command & ~A2232CMD_CMask) | - A2232CMD_Close ); - stat->OutFlush = -1; - stat->Setup = -1; - } - - local_irq_restore(flags); - - /* After analyzing control flow, I think a2232_shutdown_port - is actually the last call from the system when at application - level someone issues a "echo Hello >>/dev/ttyY0". - Therefore I think the MOD_DEC_USE_COUNT should be here and - not in "a2232_close()". See the comment in "sx.c", too. - If you run into problems, compile this driver into the - kernel instead of compiling it as a module. */ -} - -static int a2232_set_real_termios(void *ptr) -{ - unsigned int cflag, baud, chsize, stopb, parity, softflow; - int rate; - int a2232_param, a2232_cmd; - unsigned long flags; - unsigned int i; - struct a2232_port *port = ptr; - volatile struct a2232status *status; - volatile struct a2232memory *mem; - - if (!port->gs.port.tty || !port->gs.port.tty->termios) return 0; - - status = a2232stat(port->which_a2232, port->which_port_on_a2232); - mem = a2232mem(port->which_a2232); - - a2232_param = a2232_cmd = 0; - - // get baud rate - baud = port->gs.baud; - if (baud == 0) { - /* speed == 0 -> drop DTR, do nothing else */ - local_irq_save(flags); - // Clear DTR (and RTS... mhhh). - status->Command = ( (status->Command & ~A2232CMD_CMask) | - A2232CMD_Close ); - status->OutFlush = -1; - status->Setup = -1; - - local_irq_restore(flags); - return 0; - } - - rate = A2232_BAUD_TABLE_NOAVAIL; - for (i=0; i < A2232_BAUD_TABLE_NUM_RATES * 3; i += 3){ - if (a2232_baud_table[i] == baud){ - if (mem->Common.Crystal == A2232_TURBO) rate = a2232_baud_table[i+2]; - else rate = a2232_baud_table[i+1]; - } - } - if (rate == A2232_BAUD_TABLE_NOAVAIL){ - printk("a2232: Board %d Port %d unsupported baud rate: %d baud. Using another.\n",port->which_a2232,port->which_port_on_a2232,baud); - // This is useful for both (turbo or normal) Crystal versions. - rate = A2232PARAM_B9600; - } - a2232_param |= rate; - - cflag = port->gs.port.tty->termios->c_cflag; - - // get character size - chsize = cflag & CSIZE; - switch (chsize){ - case CS8: a2232_param |= A2232PARAM_8Bit; break; - case CS7: a2232_param |= A2232PARAM_7Bit; break; - case CS6: a2232_param |= A2232PARAM_6Bit; break; - case CS5: a2232_param |= A2232PARAM_5Bit; break; - default: printk("a2232: Board %d Port %d unsupported character size: %d. Using 8 data bits.\n", - port->which_a2232,port->which_port_on_a2232,chsize); - a2232_param |= A2232PARAM_8Bit; break; - } - - // get number of stop bits - stopb = cflag & CSTOPB; - if (stopb){ // two stop bits instead of one - printk("a2232: Board %d Port %d 2 stop bits unsupported. Using 1 stop bit.\n", - port->which_a2232,port->which_port_on_a2232); - } - - // Warn if RTS/CTS not wanted - if (!(cflag & CRTSCTS)){ -#ifndef A2232_SUPPRESS_RTSCTS_WARNING - printk("a2232: Board %d Port %d cannot switch off firmware-implemented RTS/CTS hardware flow control.\n", - port->which_a2232,port->which_port_on_a2232); -#endif - } - - /* I think this is correct. - However, IXOFF means _input_ flow control and I wonder - if one should care about IXON _output_ flow control, - too. If this makes problems, one should turn the A2232 - firmware XON/XOFF "SoftFlow" flow control off and use - the conventional way of inserting START/STOP characters - by hand in throttle()/unthrottle(). - */ - softflow = !!( port->gs.port.tty->termios->c_iflag & IXOFF ); - - // get Parity (Enabled/Disabled? If Enabled, Odd or Even?) - parity = cflag & (PARENB | PARODD); - if (parity & PARENB){ - if (parity & PARODD){ - a2232_cmd |= A2232CMD_OddParity; - } - else{ - a2232_cmd |= A2232CMD_EvenParity; - } - } - else a2232_cmd |= A2232CMD_NoParity; - - - /* Hmm. Maybe an own a2232_port structure - member would be cleaner? */ - if (cflag & CLOCAL) - port->gs.port.flags &= ~ASYNC_CHECK_CD; - else - port->gs.port.flags |= ASYNC_CHECK_CD; - - - /* Now we have all parameters and can go to set them: */ - local_irq_save(flags); - - status->Param = a2232_param | A2232PARAM_RcvBaud; - status->Command = a2232_cmd | A2232CMD_Open | A2232CMD_Enable; - status->SoftFlow = softflow; - status->OutDisable = 0; - status->Setup = -1; - - local_irq_restore(flags); - return 0; -} - -static int a2232_chars_in_buffer(void *ptr) -{ - struct a2232_port *port; - volatile struct a2232status *status; - unsigned char ret; /* we need modulo-256 arithmetics */ - port = ptr; - status = a2232stat(port->which_a2232, port->which_port_on_a2232); -#if A2232_IOBUFLEN != 256 -#error "Re-Implement a2232_chars_in_buffer()!" -#endif - ret = (status->OutHead - status->OutTail); - return ret; -} - -static void a2232_close(void *ptr) -{ - a2232_disable_tx_interrupts(ptr); - a2232_disable_rx_interrupts(ptr); - /* see the comment in a2232_shutdown_port above. */ -} - -static void a2232_hungup(void *ptr) -{ - a2232_close(ptr); -} -/*** END OF REAL_DRIVER FUNCTIONS ***/ - -/*** BEGIN FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/ -static int a2232_ioctl( struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; -} - -static void a2232_throttle(struct tty_struct *tty) -{ -/* Throttle: System cannot take another chars: Drop RTS or - send the STOP char or whatever. - The A2232 firmware does RTS/CTS anyway, and XON/XOFF - if switched on. So the only thing we can do at this - layer here is not taking any characters out of the - A2232 buffer any more. */ - struct a2232_port *port = tty->driver_data; - port->throttle_input = -1; -} - -static void a2232_unthrottle(struct tty_struct *tty) -{ -/* Unthrottle: dual to "throttle()" above. */ - struct a2232_port *port = tty->driver_data; - port->throttle_input = 0; -} - -static int a2232_open(struct tty_struct * tty, struct file * filp) -{ -/* More or less stolen from other drivers. */ - int line; - int retval; - struct a2232_port *port; - - line = tty->index; - port = &a2232_ports[line]; - - tty->driver_data = port; - port->gs.port.tty = tty; - port->gs.port.count++; - retval = gs_init_port(&port->gs); - if (retval) { - port->gs.port.count--; - return retval; - } - port->gs.port.flags |= GS_ACTIVE; - retval = gs_block_til_ready(port, filp); - - if (retval) { - port->gs.port.count--; - return retval; - } - - a2232_enable_rx_interrupts(port); - - return 0; -} -/*** END OF FUNCTIONS EXPECTED BY TTY DRIVER STRUCTS ***/ - -static irqreturn_t a2232_vbl_inter(int irq, void *data) -{ -#if A2232_IOBUFLEN != 256 -#error "Re-Implement a2232_vbl_inter()!" -#endif - -struct a2232_port *port; -volatile struct a2232memory *mem; -volatile struct a2232status *status; -unsigned char newhead; -unsigned char bufpos; /* Must be unsigned char. We need the modulo-256 arithmetics */ -unsigned char ncd, ocd, ccd; /* names consistent with the NetBSD driver */ -volatile u_char *ibuf, *cbuf, *obuf; -int ch, err, n, p; - for (n = 0; n < nr_a2232; n++){ /* for every completely initialized A2232 board */ - mem = a2232mem(n); - for (p = 0; p < NUMLINES; p++){ /* for every port on this board */ - err = 0; - port = &a2232_ports[n*NUMLINES+p]; - if ( port->gs.port.flags & GS_ACTIVE ){ /* if the port is used */ - - status = a2232stat(n,p); - - if (!port->disable_rx && !port->throttle_input){ /* If input is not disabled */ - newhead = status->InHead; /* 65EC02 write pointer */ - bufpos = status->InTail; - - /* check for input for this port */ - if (newhead != bufpos) { - /* buffer for input chars/events */ - ibuf = mem->InBuf[p]; - - /* data types of bytes in ibuf */ - cbuf = mem->InCtl[p]; - - /* do for all chars */ - while (bufpos != newhead) { - /* which type of input data? */ - switch (cbuf[bufpos]) { - /* switch on input event (CD, BREAK, etc.) */ - case A2232INCTL_EVENT: - switch (ibuf[bufpos++]) { - case A2232EVENT_Break: - /* TODO: Handle BREAK signal */ - break; - /* A2232EVENT_CarrierOn and A2232EVENT_CarrierOff are - handled in a separate queue and should not occur here. */ - case A2232EVENT_Sync: - printk("A2232: 65EC02 software sent SYNC event, don't know what to do. Ignoring."); - break; - default: - printk("A2232: 65EC02 software broken, unknown event type %d occurred.\n",ibuf[bufpos-1]); - } /* event type switch */ - break; - case A2232INCTL_CHAR: - /* Receive incoming char */ - a2232_receive_char(port, ibuf[bufpos], err); - bufpos++; - break; - default: - printk("A2232: 65EC02 software broken, unknown data type %d occurred.\n",cbuf[bufpos]); - bufpos++; - } /* switch on input data type */ - } /* while there's something in the buffer */ - - status->InTail = bufpos; /* tell 65EC02 what we've read */ - - } /* if there was something in the buffer */ - } /* If input is not disabled */ - - /* Now check if there's something to output */ - obuf = mem->OutBuf[p]; - bufpos = status->OutHead; - while ( (port->gs.xmit_cnt > 0) && - (!port->gs.port.tty->stopped) && - (!port->gs.port.tty->hw_stopped) ){ /* While there are chars to transmit */ - if (((bufpos+1) & A2232_IOBUFLENMASK) != status->OutTail) { /* If the A2232 buffer is not full */ - ch = port->gs.xmit_buf[port->gs.xmit_tail]; /* get the next char to transmit */ - port->gs.xmit_tail = (port->gs.xmit_tail+1) & (SERIAL_XMIT_SIZE-1); /* modulo-addition for the gs.xmit_buf ring-buffer */ - obuf[bufpos++] = ch; /* put it into the A2232 buffer */ - port->gs.xmit_cnt--; - } - else{ /* If A2232 the buffer is full */ - break; /* simply stop filling it. */ - } - } - status->OutHead = bufpos; - - /* WakeUp if output buffer runs low */ - if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) { - tty_wakeup(port->gs.port.tty); - } - } // if the port is used - } // for every port on the board - - /* Now check the CD message queue */ - newhead = mem->Common.CDHead; - bufpos = mem->Common.CDTail; - if (newhead != bufpos){ /* There are CD events in queue */ - ocd = mem->Common.CDStatus; /* get old status bits */ - while (newhead != bufpos){ /* read all events */ - ncd = mem->CDBuf[bufpos++]; /* get one event */ - ccd = ncd ^ ocd; /* mask of changed lines */ - ocd = ncd; /* save new status bits */ - for(p=0; p < NUMLINES; p++){ /* for all ports */ - if (ccd & 1){ /* this one changed */ - - struct a2232_port *port = &a2232_ports[n*7+p]; - port->cd_status = !(ncd & 1); /* ncd&1 <=> CD is now off */ - - if (!(port->gs.port.flags & ASYNC_CHECK_CD)) - ; /* Don't report DCD changes */ - else if (port->cd_status) { // if DCD on: DCD went UP! - - /* Are we blocking in open?*/ - wake_up_interruptible(&port->gs.port.open_wait); - } - else { // if DCD off: DCD went DOWN! - if (port->gs.port.tty) - tty_hangup (port->gs.port.tty); - } - - } // if CD changed for this port - ccd >>= 1; - ncd >>= 1; /* Shift bits for next line */ - } // for every port - } // while CD events in queue - mem->Common.CDStatus = ocd; /* save new status */ - mem->Common.CDTail = bufpos; /* remove events */ - } // if events in CD queue - - } // for every completely initialized A2232 board - return IRQ_HANDLED; -} - -static const struct tty_port_operations a2232_port_ops = { - .carrier_raised = a2232_carrier_raised, -}; - -static void a2232_init_portstructs(void) -{ - struct a2232_port *port; - int i; - - for (i = 0; i < MAX_A2232_BOARDS*NUMLINES; i++) { - port = a2232_ports + i; - tty_port_init(&port->gs.port); - port->gs.port.ops = &a2232_port_ops; - port->which_a2232 = i/NUMLINES; - port->which_port_on_a2232 = i%NUMLINES; - port->disable_rx = port->throttle_input = port->cd_status = 0; - port->gs.magic = A2232_MAGIC; - port->gs.close_delay = HZ/2; - port->gs.closing_wait = 30 * HZ; - port->gs.rd = &a2232_real_driver; - } -} - -static const struct tty_operations a2232_ops = { - .open = a2232_open, - .close = gs_close, - .write = gs_write, - .put_char = gs_put_char, - .flush_chars = gs_flush_chars, - .write_room = gs_write_room, - .chars_in_buffer = gs_chars_in_buffer, - .flush_buffer = gs_flush_buffer, - .ioctl = a2232_ioctl, - .throttle = a2232_throttle, - .unthrottle = a2232_unthrottle, - .set_termios = gs_set_termios, - .stop = gs_stop, - .start = gs_start, - .hangup = gs_hangup, -}; - -static int a2232_init_drivers(void) -{ - int error; - - a2232_driver = alloc_tty_driver(NUMLINES * nr_a2232); - if (!a2232_driver) - return -ENOMEM; - a2232_driver->owner = THIS_MODULE; - a2232_driver->driver_name = "commodore_a2232"; - a2232_driver->name = "ttyY"; - a2232_driver->major = A2232_NORMAL_MAJOR; - a2232_driver->type = TTY_DRIVER_TYPE_SERIAL; - a2232_driver->subtype = SERIAL_TYPE_NORMAL; - a2232_driver->init_termios = tty_std_termios; - a2232_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - a2232_driver->init_termios.c_ispeed = 9600; - a2232_driver->init_termios.c_ospeed = 9600; - a2232_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(a2232_driver, &a2232_ops); - if ((error = tty_register_driver(a2232_driver))) { - printk(KERN_ERR "A2232: Couldn't register A2232 driver, error = %d\n", - error); - put_tty_driver(a2232_driver); - return 1; - } - return 0; -} - -static int __init a2232board_init(void) -{ - struct zorro_dev *z; - - unsigned int boardaddr; - int bcount; - short start; - u_char *from; - volatile u_char *to; - volatile struct a2232memory *mem; - int error, i; - -#ifdef CONFIG_SMP - return -ENODEV; /* This driver is not SMP aware. Is there an SMP ZorroII-bus-machine? */ -#endif - - if (!MACH_IS_AMIGA){ - return -ENODEV; - } - - printk("Commodore A2232 driver initializing.\n"); /* Say that we're alive. */ - - z = NULL; - nr_a2232 = 0; - while ( (z = zorro_find_device(ZORRO_WILDCARD, z)) ){ - if ( (z->id != ZORRO_PROD_CBM_A2232_PROTOTYPE) && - (z->id != ZORRO_PROD_CBM_A2232) ){ - continue; // The board found was no A2232 - } - if (!zorro_request_device(z,"A2232 driver")) - continue; - - printk("Commodore A2232 found (#%d).\n",nr_a2232); - - zd_a2232[nr_a2232] = z; - - boardaddr = ZTWO_VADDR( z->resource.start ); - printk("Board is located at address 0x%x, size is 0x%x.\n", boardaddr, (unsigned int) ((z->resource.end+1) - (z->resource.start))); - - mem = (volatile struct a2232memory *) boardaddr; - - (void) mem->Enable6502Reset; /* copy the code across to the board */ - to = (u_char *)mem; from = a2232_65EC02code; bcount = sizeof(a2232_65EC02code) - 2; - start = *(short *)from; - from += sizeof(start); - to += start; - while(bcount--) *to++ = *from++; - printk("65EC02 software uploaded to the A2232 memory.\n"); - - mem->Common.Crystal = A2232_UNKNOWN; /* use automatic speed check */ - - /* start 6502 running */ - (void) mem->ResetBoard; - printk("A2232's 65EC02 CPU up and running.\n"); - - /* wait until speed detector has finished */ - for (bcount = 0; bcount < 2000; bcount++) { - udelay(1000); - if (mem->Common.Crystal) - break; - } - printk((mem->Common.Crystal?"A2232 oscillator crystal detected by 65EC02 software: ":"65EC02 software could not determine A2232 oscillator crystal: ")); - switch (mem->Common.Crystal){ - case A2232_UNKNOWN: - printk("Unknown crystal.\n"); - break; - case A2232_NORMAL: - printk ("Normal crystal.\n"); - break; - case A2232_TURBO: - printk ("Turbo crystal.\n"); - break; - default: - printk ("0x%x. Huh?\n",mem->Common.Crystal); - } - - nr_a2232++; - - } - - printk("Total: %d A2232 boards initialized.\n", nr_a2232); /* Some status report if no card was found */ - - a2232_init_portstructs(); - - /* - a2232_init_drivers also registers the drivers. Must be here because all boards - have to be detected first. - */ - if (a2232_init_drivers()) return -ENODEV; // maybe we should use a different -Exxx? - - error = request_irq(IRQ_AMIGA_VERTB, a2232_vbl_inter, 0, - "A2232 serial VBL", a2232_driver_ID); - if (error) { - for (i = 0; i < nr_a2232; i++) - zorro_release_device(zd_a2232[i]); - tty_unregister_driver(a2232_driver); - put_tty_driver(a2232_driver); - } - return error; -} - -static void __exit a2232board_exit(void) -{ - int i; - - for (i = 0; i < nr_a2232; i++) { - zorro_release_device(zd_a2232[i]); - } - - tty_unregister_driver(a2232_driver); - put_tty_driver(a2232_driver); - free_irq(IRQ_AMIGA_VERTB, a2232_driver_ID); -} - -module_init(a2232board_init); -module_exit(a2232board_exit); - -MODULE_AUTHOR("Enver Haase"); -MODULE_DESCRIPTION("Amiga A2232 multi-serial board driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/generic_serial/ser_a2232.h b/drivers/staging/generic_serial/ser_a2232.h deleted file mode 100644 index bc09eb9e118b..000000000000 --- a/drivers/staging/generic_serial/ser_a2232.h +++ /dev/null @@ -1,202 +0,0 @@ -/* drivers/char/ser_a2232.h */ - -/* $Id: ser_a2232.h,v 0.4 2000/01/25 12:00:00 ehaase Exp $ */ - -/* Linux serial driver for the Amiga A2232 board */ - -/* This driver is MAINTAINED. Before applying any changes, please contact - * the author. - */ - -/* Copyright (c) 2000-2001 Enver Haase - * alias The A2232 driver project - * 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. - * - * 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 _SER_A2232_H_ -#define _SER_A2232_H_ - -/* - How many boards are to be supported at maximum; - "up to five A2232 Multiport Serial Cards may be installed in a - single Amiga 2000" states the A2232 User's Guide. If you have - more slots available, you might want to change the value below. -*/ -#define MAX_A2232_BOARDS 5 - -#ifndef A2232_NORMAL_MAJOR -/* This allows overriding on the compiler commandline, or in a "major.h" - include or something like that */ -#define A2232_NORMAL_MAJOR 224 /* /dev/ttyY* */ -#define A2232_CALLOUT_MAJOR 225 /* /dev/cuy* */ -#endif - -/* Some magic is always good - Who knows :) */ -#define A2232_MAGIC 0x000a2232 - -/* A2232 port structure to keep track of the - status of every single line used */ -struct a2232_port{ - struct gs_port gs; - unsigned int which_a2232; - unsigned int which_port_on_a2232; - short disable_rx; - short throttle_input; - short cd_status; -}; - -#define NUMLINES 7 /* number of lines per board */ -#define A2232_IOBUFLEN 256 /* number of bytes per buffer */ -#define A2232_IOBUFLENMASK 0xff /* mask for maximum number of bytes */ - - -#define A2232_UNKNOWN 0 /* crystal not known */ -#define A2232_NORMAL 1 /* normal A2232 (1.8432 MHz oscillator) */ -#define A2232_TURBO 2 /* turbo A2232 (3.6864 MHz oscillator) */ - - -struct a2232common { - char Crystal; /* normal (1) or turbo (2) board? */ - u_char Pad_a; - u_char TimerH; /* timer value after speed check */ - u_char TimerL; - u_char CDHead; /* head pointer for CD message queue */ - u_char CDTail; /* tail pointer for CD message queue */ - u_char CDStatus; - u_char Pad_b; -}; - -struct a2232status { - u_char InHead; /* input queue head */ - u_char InTail; /* input queue tail */ - u_char OutDisable; /* disables output */ - u_char OutHead; /* output queue head */ - u_char OutTail; /* output queue tail */ - u_char OutCtrl; /* soft flow control character to send */ - u_char OutFlush; /* flushes output buffer */ - u_char Setup; /* causes reconfiguration */ - u_char Param; /* parameter byte - see A2232PARAM */ - u_char Command; /* command byte - see A2232CMD */ - u_char SoftFlow; /* enables xon/xoff flow control */ - /* private 65EC02 fields: */ - u_char XonOff; /* stores XON/XOFF enable/disable */ -}; - -#define A2232_MEMPAD1 \ - (0x0200 - NUMLINES * sizeof(struct a2232status) - \ - sizeof(struct a2232common)) -#define A2232_MEMPAD2 (0x2000 - NUMLINES * A2232_IOBUFLEN - A2232_IOBUFLEN) - -struct a2232memory { - struct a2232status Status[NUMLINES]; /* 0x0000-0x006f status areas */ - struct a2232common Common; /* 0x0070-0x0077 common flags */ - u_char Dummy1[A2232_MEMPAD1]; /* 0x00XX-0x01ff */ - u_char OutBuf[NUMLINES][A2232_IOBUFLEN];/* 0x0200-0x08ff output bufs */ - u_char InBuf[NUMLINES][A2232_IOBUFLEN]; /* 0x0900-0x0fff input bufs */ - u_char InCtl[NUMLINES][A2232_IOBUFLEN]; /* 0x1000-0x16ff control data */ - u_char CDBuf[A2232_IOBUFLEN]; /* 0x1700-0x17ff CD event buffer */ - u_char Dummy2[A2232_MEMPAD2]; /* 0x1800-0x2fff */ - u_char Code[0x1000]; /* 0x3000-0x3fff code area */ - u_short InterruptAck; /* 0x4000 intr ack */ - u_char Dummy3[0x3ffe]; /* 0x4002-0x7fff */ - u_short Enable6502Reset; /* 0x8000 Stop board, */ - /* 6502 RESET line held low */ - u_char Dummy4[0x3ffe]; /* 0x8002-0xbfff */ - u_short ResetBoard; /* 0xc000 reset board & run, */ - /* 6502 RESET line held high */ -}; - -#undef A2232_MEMPAD1 -#undef A2232_MEMPAD2 - -#define A2232INCTL_CHAR 0 /* corresponding byte in InBuf is a character */ -#define A2232INCTL_EVENT 1 /* corresponding byte in InBuf is an event */ - -#define A2232EVENT_Break 1 /* break set */ -#define A2232EVENT_CarrierOn 2 /* carrier raised */ -#define A2232EVENT_CarrierOff 3 /* carrier dropped */ -#define A2232EVENT_Sync 4 /* don't know, defined in 2232.ax */ - -#define A2232CMD_Enable 0x1 /* enable/DTR bit */ -#define A2232CMD_Close 0x2 /* close the device */ -#define A2232CMD_Open 0xb /* open the device */ -#define A2232CMD_CMask 0xf /* command mask */ -#define A2232CMD_RTSOff 0x0 /* turn off RTS */ -#define A2232CMD_RTSOn 0x8 /* turn on RTS */ -#define A2232CMD_Break 0xd /* transmit a break */ -#define A2232CMD_RTSMask 0xc /* mask for RTS stuff */ -#define A2232CMD_NoParity 0x00 /* don't use parity */ -#define A2232CMD_OddParity 0x20 /* odd parity */ -#define A2232CMD_EvenParity 0x60 /* even parity */ -#define A2232CMD_ParityMask 0xe0 /* parity mask */ - -#define A2232PARAM_B115200 0x0 /* baud rates */ -#define A2232PARAM_B50 0x1 -#define A2232PARAM_B75 0x2 -#define A2232PARAM_B110 0x3 -#define A2232PARAM_B134 0x4 -#define A2232PARAM_B150 0x5 -#define A2232PARAM_B300 0x6 -#define A2232PARAM_B600 0x7 -#define A2232PARAM_B1200 0x8 -#define A2232PARAM_B1800 0x9 -#define A2232PARAM_B2400 0xa -#define A2232PARAM_B3600 0xb -#define A2232PARAM_B4800 0xc -#define A2232PARAM_B7200 0xd -#define A2232PARAM_B9600 0xe -#define A2232PARAM_B19200 0xf -#define A2232PARAM_BaudMask 0xf /* baud rate mask */ -#define A2232PARAM_RcvBaud 0x10 /* enable receive baud rate */ -#define A2232PARAM_8Bit 0x00 /* numbers of bits */ -#define A2232PARAM_7Bit 0x20 -#define A2232PARAM_6Bit 0x40 -#define A2232PARAM_5Bit 0x60 -#define A2232PARAM_BitMask 0x60 /* numbers of bits mask */ - - -/* Standard speeds tables, -1 means unavailable, -2 means 0 baud: switch off line */ -#define A2232_BAUD_TABLE_NOAVAIL -1 -#define A2232_BAUD_TABLE_NUM_RATES (18) -static int a2232_baud_table[A2232_BAUD_TABLE_NUM_RATES*3] = { - //Baud //Normal //Turbo - 50, A2232PARAM_B50, A2232_BAUD_TABLE_NOAVAIL, - 75, A2232PARAM_B75, A2232_BAUD_TABLE_NOAVAIL, - 110, A2232PARAM_B110, A2232_BAUD_TABLE_NOAVAIL, - 134, A2232PARAM_B134, A2232_BAUD_TABLE_NOAVAIL, - 150, A2232PARAM_B150, A2232PARAM_B75, - 200, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL, - 300, A2232PARAM_B300, A2232PARAM_B150, - 600, A2232PARAM_B600, A2232PARAM_B300, - 1200, A2232PARAM_B1200, A2232PARAM_B600, - 1800, A2232PARAM_B1800, A2232_BAUD_TABLE_NOAVAIL, - 2400, A2232PARAM_B2400, A2232PARAM_B1200, - 4800, A2232PARAM_B4800, A2232PARAM_B2400, - 9600, A2232PARAM_B9600, A2232PARAM_B4800, - 19200, A2232PARAM_B19200, A2232PARAM_B9600, - 38400, A2232_BAUD_TABLE_NOAVAIL, A2232PARAM_B19200, - 57600, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL, -#ifdef A2232_SPEEDHACK - 115200, A2232PARAM_B115200, A2232_BAUD_TABLE_NOAVAIL, - 230400, A2232_BAUD_TABLE_NOAVAIL, A2232PARAM_B115200 -#else - 115200, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL, - 230400, A2232_BAUD_TABLE_NOAVAIL, A2232_BAUD_TABLE_NOAVAIL -#endif -}; -#endif diff --git a/drivers/staging/generic_serial/ser_a2232fw.ax b/drivers/staging/generic_serial/ser_a2232fw.ax deleted file mode 100644 index 736438032768..000000000000 --- a/drivers/staging/generic_serial/ser_a2232fw.ax +++ /dev/null @@ -1,529 +0,0 @@ -;.lib "axm" -; -;begin -;title "A2232 serial board driver" -; -;set modules "2232" -;set executable "2232.bin" -; -;;;;set nolink -; -;set temporary directory "t:" -; -;set assembly options "-m6502 -l60:t:list" -;set link options "bin"; loadadr" -;;;bin2c 2232.bin msc6502.h msc6502code -;end -; -; -; ### Commodore A2232 serial board driver for NetBSD by JM v1.3 ### -; -; - Created 950501 by JM - -; -; -; Serial board driver software. -; -; -% Copyright (c) 1995 Jukka Marin . -% All rights reserved. -% -% Redistribution and use in source and binary forms, with or without -% modification, are permitted provided that the following conditions -% are met: -% 1. Redistributions of source code must retain the above copyright -% notice, and the entire permission notice in its entirety, -% including the disclaimer of warranties. -% 2. 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. -% 3. The name of the author may not be used to endorse or promote -% products derived from this software without specific prior -% written permission. -% -% ALTERNATIVELY, this product may be distributed under the terms of -% the GNU General Public License, in which case the provisions of the -% GPL are required INSTEAD OF the above restrictions. (This clause is -% necessary due to a potential bad interaction between the GPL and -% the restrictions contained in a BSD-style copyright.) -% -% THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED -% WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -% OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -% DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -% INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -% (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -% SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -% STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -% OF THE POSSIBILITY OF SUCH DAMAGE. -; -; -; Bugs: -; -; - Can't send a break yet -; -; -; -; Edited: -; -; - 950501 by JM -> v0.1 - Created this file. -; - 951029 by JM -> v1.3 - Carrier Detect events now queued in a separate -; queue. -; -; - - -CODE equ $3800 ; start address for program code - - -CTL_CHAR equ $00 ; byte in ibuf is a character -CTL_EVENT equ $01 ; byte in ibuf is an event - -EVENT_BREAK equ $01 -EVENT_CDON equ $02 -EVENT_CDOFF equ $03 -EVENT_SYNC equ $04 - -XON equ $11 -XOFF equ $13 - - -VARBASE macro *starting_address ; was VARINIT -_varbase set \1 - endm - -VARDEF macro *name space_needs -\1 equ _varbase -_varbase set _varbase+\2 - endm - - -stz macro * address - db $64,\1 - endm - -stzax macro * address - db $9e,<\1,>\1 - endm - - -biti macro * immediate value - db $89,\1 - endm - -smb0 macro * address - db $87,\1 - endm -smb1 macro * address - db $97,\1 - endm -smb2 macro * address - db $a7,\1 - endm -smb3 macro * address - db $b7,\1 - endm -smb4 macro * address - db $c7,\1 - endm -smb5 macro * address - db $d7,\1 - endm -smb6 macro * address - db $e7,\1 - endm -smb7 macro * address - db $f7,\1 - endm - - - -;-----------------------------------------------------------------------; -; ; -; stuff common for all ports, non-critical (run once / loop) ; -; ; -DO_SLOW macro * port_number ; - .local ; ; - lda CIA+C_PA ; check all CD inputs ; - cmp CommonCDo ; changed from previous accptd? ; - beq =over ; nope, do nothing else here ; - ; ; - cmp CommonCDb ; bouncing? ; - beq =nobounce ; nope -> ; - ; ; - sta CommonCDb ; save current state ; - lda #64 ; reinitialize counter ; - sta CommonCDc ; ; - jmp =over ; skip CD save ; - ; ; -=nobounce dec CommonCDc ; no, decrement bounce counter ; - bpl =over ; not done yet, so skip CD save ; - ; ; -=saveCD ldx CDHead ; get write index ; - sta cdbuf,x ; save status in buffer ; - inx ; ; - cpx CDTail ; buffer full? ; - .if ne ; no: preserve status: ; - stx CDHead ; update index in RAM ; - sta CommonCDo ; save state for the next check ; - .end ; ; -=over .end local ; - endm ; - ; -;-----------------------------------------------------------------------; - - -; port specific stuff (no data transfer) - -DO_PORT macro * port_number - .local ; ; - lda SetUp\1 ; reconfiguration request? ; - .if ne ; yes: ; - lda SoftFlow\1 ; get XON/XOFF flag ; - sta XonOff\1 ; save it ; - lda Param\1 ; get parameter ; - ora #%00010000 ; use baud generator for Rx ; - sta ACIA\1+A_CTRL ; store in control register ; - stz OutDisable\1 ; enable transmit output ; - stz SetUp\1 ; no reconfiguration no more ; - .end ; ; - ; ; - lda InHead\1 ; get write index ; - sbc InTail\1 ; buffer full soon? ; - cmp #200 ; 200 chars or more in buffer? ; - lda Command\1 ; get Command reg value ; - and #%11110011 ; turn RTS OFF by default ; - .if cc ; still room in buffer: ; - ora #%00001000 ; turn RTS ON ; - .end ; ; - sta ACIA\1+A_CMD ; set/clear RTS ; - ; ; - lda OutFlush\1 ; request to flush output buffer; - .if ne ; yessh! ; - lda OutHead\1 ; get head ; - sta OutTail\1 ; save as tail ; - stz OutDisable\1 ; enable transmit output ; - stz OutFlush\1 ; clear request ; - .end - .end local - endm - - -DO_DATA macro * port number - .local - lda ACIA\1+A_SR ; read ACIA status register ; - biti [1<<3] ; something received? ; - .if ne ; yes: ; - biti [1<<1] ; framing error? ; - .if ne ; yes: ; - lda ACIA\1+A_DATA ; read received character ; - bne =SEND ; not break -> ignore it ; - ldx InHead\1 ; get write pointer ; - lda #CTL_EVENT ; get type of byte ; - sta ictl\1,x ; save it in InCtl buffer ; - lda #EVENT_BREAK ; event code ; - sta ibuf\1,x ; save it as well ; - inx ; ; - cpx InTail\1 ; still room in buffer? ; - .if ne ; absolutely: ; - stx InHead\1 ; update index in memory ; - .end ; ; - jmp =SEND ; go check if anything to send ; - .end ; ; - ; normal char received: ; - ldx InHead\1 ; get write index ; - lda ACIA\1+A_DATA ; read received character ; - sta ibuf\1,x ; save char in buffer ; - stzax ictl\1 ; set type to CTL_CHAR ; - inx ; ; - cpx InTail\1 ; buffer full? ; - .if ne ; no: preserve character: ; - stx InHead\1 ; update index in RAM ; - .end ; ; - and #$7f ; mask off parity if any ; - cmp #XOFF ; XOFF from remote host? ; - .if eq ; yes: ; - lda XonOff\1 ; if XON/XOFF handshaking.. ; - sta OutDisable\1 ; ..disable transmitter ; - .end ; ; - .end ; ; - ; ; - ; BUFFER FULL CHECK WAS HERE ; - ; ; -=SEND lda ACIA\1+A_SR ; transmit register empty? ; - and #[1<<4] ; ; - .if ne ; yes: ; - ldx OutCtrl\1 ; sending out XON/XOFF? ; - .if ne ; yes: ; - lda CIA+C_PB ; check CTS signal ; - and #[1<<\1] ; (for this port only) ; - bne =DONE ; not allowed to send -> done ; - stx ACIA\1+A_DATA ; transmit control char ; - stz OutCtrl\1 ; clear flag ; - jmp =DONE ; and we're done ; - .end ; ; - ; ; - ldx OutTail\1 ; anything to transmit? ; - cpx OutHead\1 ; ; - .if ne ; yes: ; - lda OutDisable\1 ; allowed to transmit? ; - .if eq ; yes: ; - lda CIA+C_PB ; check CTS signal ; - and #[1<<\1] ; (for this port only) ; - bne =DONE ; not allowed to send -> done ; - lda obuf\1,x ; get a char from buffer ; - sta ACIA\1+A_DATA ; send it away ; - inc OutTail\1 ; update read index ; - .end ; ; - .end ; ; - .end ; ; -=DONE .end local - endm - - - -PORTVAR macro * port number - VARDEF InHead\1 1 - VARDEF InTail\1 1 - VARDEF OutDisable\1 1 - VARDEF OutHead\1 1 - VARDEF OutTail\1 1 - VARDEF OutCtrl\1 1 - VARDEF OutFlush\1 1 - VARDEF SetUp\1 1 - VARDEF Param\1 1 - VARDEF Command\1 1 - VARDEF SoftFlow\1 1 - ; private: - VARDEF XonOff\1 1 - endm - - - VARBASE 0 ; start variables at address $0000 - PORTVAR 0 ; define variables for port 0 - PORTVAR 1 ; define variables for port 1 - PORTVAR 2 ; define variables for port 2 - PORTVAR 3 ; define variables for port 3 - PORTVAR 4 ; define variables for port 4 - PORTVAR 5 ; define variables for port 5 - PORTVAR 6 ; define variables for port 6 - - - - VARDEF Crystal 1 ; 0 = unknown, 1 = normal, 2 = turbo - VARDEF Pad_a 1 - VARDEF TimerH 1 - VARDEF TimerL 1 - VARDEF CDHead 1 - VARDEF CDTail 1 - VARDEF CDStatus 1 - VARDEF Pad_b 1 - - VARDEF CommonCDo 1 ; for carrier detect optimization - VARDEF CommonCDc 1 ; for carrier detect debouncing - VARDEF CommonCDb 1 ; for carrier detect debouncing - - - VARBASE $0200 - VARDEF obuf0 256 ; output data (characters only) - VARDEF obuf1 256 - VARDEF obuf2 256 - VARDEF obuf3 256 - VARDEF obuf4 256 - VARDEF obuf5 256 - VARDEF obuf6 256 - - VARDEF ibuf0 256 ; input data (characters, events etc - see ictl) - VARDEF ibuf1 256 - VARDEF ibuf2 256 - VARDEF ibuf3 256 - VARDEF ibuf4 256 - VARDEF ibuf5 256 - VARDEF ibuf6 256 - - VARDEF ictl0 256 ; input control information (type of data in ibuf) - VARDEF ictl1 256 - VARDEF ictl2 256 - VARDEF ictl3 256 - VARDEF ictl4 256 - VARDEF ictl5 256 - VARDEF ictl6 256 - - VARDEF cdbuf 256 ; CD event queue - - -ACIA0 equ $4400 -ACIA1 equ $4c00 -ACIA2 equ $5400 -ACIA3 equ $5c00 -ACIA4 equ $6400 -ACIA5 equ $6c00 -ACIA6 equ $7400 - -A_DATA equ $00 -A_SR equ $02 -A_CMD equ $04 -A_CTRL equ $06 -; 00 write transmit data read received data -; 02 reset ACIA read status register -; 04 write command register read command register -; 06 write control register read control register - -CIA equ $7c00 ; 8520 CIA -C_PA equ $00 ; port A data register -C_PB equ $02 ; port B data register -C_DDRA equ $04 ; data direction register for port A -C_DDRB equ $06 ; data direction register for port B -C_TAL equ $08 ; timer A -C_TAH equ $0a -C_TBL equ $0c ; timer B -C_TBH equ $0e -C_TODL equ $10 ; TOD LSB -C_TODM equ $12 ; TOD middle byte -C_TODH equ $14 ; TOD MSB -C_DATA equ $18 ; serial data register -C_INTCTRL equ $1a ; interrupt control register -C_CTRLA equ $1c ; control register A -C_CTRLB equ $1e ; control register B - - - - - - section main,code,CODE-2 - - db >CODE,. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. 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. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* This is the 65EC02 code by Jukka Marin that is executed by - the A2232's 65EC02 processor (base address: 0x3800) - Source file: ser_a2232fw.ax - Version: 1.3 (951029) - Known Bugs: Cannot send a break yet -*/ -static unsigned char a2232_65EC02code[] = { - 0x38, 0x00, 0xA2, 0xFF, 0x9A, 0xD8, 0xA2, 0x00, - 0xA9, 0x00, 0xA0, 0x54, 0x95, 0x00, 0xE8, 0x88, - 0xD0, 0xFA, 0x64, 0x5C, 0x64, 0x5E, 0x64, 0x58, - 0x64, 0x59, 0xA9, 0x00, 0x85, 0x55, 0xA9, 0xAA, - 0xC9, 0x64, 0x90, 0x02, 0xE6, 0x55, 0xA5, 0x54, - 0xF0, 0x03, 0x4C, 0x92, 0x38, 0xA9, 0x98, 0x8D, - 0x06, 0x44, 0xA9, 0x0B, 0x8D, 0x04, 0x44, 0xAD, - 0x02, 0x44, 0xA9, 0x80, 0x8D, 0x1A, 0x7C, 0xA9, - 0xFF, 0x8D, 0x08, 0x7C, 0x8D, 0x0A, 0x7C, 0xA2, - 0x00, 0x8E, 0x00, 0x44, 0xEA, 0xEA, 0xAD, 0x02, - 0x44, 0xEA, 0xEA, 0x8E, 0x00, 0x44, 0xAD, 0x02, - 0x44, 0x29, 0x10, 0xF0, 0xF9, 0xA9, 0x11, 0x8E, - 0x00, 0x44, 0x8D, 0x1C, 0x7C, 0xAD, 0x02, 0x44, - 0x29, 0x10, 0xF0, 0xF9, 0x8E, 0x1C, 0x7C, 0xAD, - 0x08, 0x7C, 0x85, 0x57, 0xAD, 0x0A, 0x7C, 0x85, - 0x56, 0xC9, 0xD0, 0x90, 0x05, 0xA9, 0x02, 0x4C, - 0x82, 0x38, 0xA9, 0x01, 0x85, 0x54, 0xA9, 0x00, - 0x8D, 0x02, 0x44, 0x8D, 0x06, 0x44, 0x8D, 0x04, - 0x44, 0x4C, 0x92, 0x38, 0xAD, 0x00, 0x7C, 0xC5, - 0x5C, 0xF0, 0x1F, 0xC5, 0x5E, 0xF0, 0x09, 0x85, - 0x5E, 0xA9, 0x40, 0x85, 0x5D, 0x4C, 0xB8, 0x38, - 0xC6, 0x5D, 0x10, 0x0E, 0xA6, 0x58, 0x9D, 0x00, - 0x17, 0xE8, 0xE4, 0x59, 0xF0, 0x04, 0x86, 0x58, - 0x85, 0x5C, 0x20, 0x23, 0x3A, 0xA5, 0x07, 0xF0, - 0x0F, 0xA5, 0x0A, 0x85, 0x0B, 0xA5, 0x08, 0x09, - 0x10, 0x8D, 0x06, 0x44, 0x64, 0x02, 0x64, 0x07, - 0xA5, 0x00, 0xE5, 0x01, 0xC9, 0xC8, 0xA5, 0x09, - 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, - 0x44, 0xA5, 0x06, 0xF0, 0x08, 0xA5, 0x03, 0x85, - 0x04, 0x64, 0x02, 0x64, 0x06, 0x20, 0x23, 0x3A, - 0xA5, 0x13, 0xF0, 0x0F, 0xA5, 0x16, 0x85, 0x17, - 0xA5, 0x14, 0x09, 0x10, 0x8D, 0x06, 0x4C, 0x64, - 0x0E, 0x64, 0x13, 0xA5, 0x0C, 0xE5, 0x0D, 0xC9, - 0xC8, 0xA5, 0x15, 0x29, 0xF3, 0xB0, 0x02, 0x09, - 0x08, 0x8D, 0x04, 0x4C, 0xA5, 0x12, 0xF0, 0x08, - 0xA5, 0x0F, 0x85, 0x10, 0x64, 0x0E, 0x64, 0x12, - 0x20, 0x23, 0x3A, 0xA5, 0x1F, 0xF0, 0x0F, 0xA5, - 0x22, 0x85, 0x23, 0xA5, 0x20, 0x09, 0x10, 0x8D, - 0x06, 0x54, 0x64, 0x1A, 0x64, 0x1F, 0xA5, 0x18, - 0xE5, 0x19, 0xC9, 0xC8, 0xA5, 0x21, 0x29, 0xF3, - 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, 0x54, 0xA5, - 0x1E, 0xF0, 0x08, 0xA5, 0x1B, 0x85, 0x1C, 0x64, - 0x1A, 0x64, 0x1E, 0x20, 0x23, 0x3A, 0xA5, 0x2B, - 0xF0, 0x0F, 0xA5, 0x2E, 0x85, 0x2F, 0xA5, 0x2C, - 0x09, 0x10, 0x8D, 0x06, 0x5C, 0x64, 0x26, 0x64, - 0x2B, 0xA5, 0x24, 0xE5, 0x25, 0xC9, 0xC8, 0xA5, - 0x2D, 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, - 0x04, 0x5C, 0xA5, 0x2A, 0xF0, 0x08, 0xA5, 0x27, - 0x85, 0x28, 0x64, 0x26, 0x64, 0x2A, 0x20, 0x23, - 0x3A, 0xA5, 0x37, 0xF0, 0x0F, 0xA5, 0x3A, 0x85, - 0x3B, 0xA5, 0x38, 0x09, 0x10, 0x8D, 0x06, 0x64, - 0x64, 0x32, 0x64, 0x37, 0xA5, 0x30, 0xE5, 0x31, - 0xC9, 0xC8, 0xA5, 0x39, 0x29, 0xF3, 0xB0, 0x02, - 0x09, 0x08, 0x8D, 0x04, 0x64, 0xA5, 0x36, 0xF0, - 0x08, 0xA5, 0x33, 0x85, 0x34, 0x64, 0x32, 0x64, - 0x36, 0x20, 0x23, 0x3A, 0xA5, 0x43, 0xF0, 0x0F, - 0xA5, 0x46, 0x85, 0x47, 0xA5, 0x44, 0x09, 0x10, - 0x8D, 0x06, 0x6C, 0x64, 0x3E, 0x64, 0x43, 0xA5, - 0x3C, 0xE5, 0x3D, 0xC9, 0xC8, 0xA5, 0x45, 0x29, - 0xF3, 0xB0, 0x02, 0x09, 0x08, 0x8D, 0x04, 0x6C, - 0xA5, 0x42, 0xF0, 0x08, 0xA5, 0x3F, 0x85, 0x40, - 0x64, 0x3E, 0x64, 0x42, 0x20, 0x23, 0x3A, 0xA5, - 0x4F, 0xF0, 0x0F, 0xA5, 0x52, 0x85, 0x53, 0xA5, - 0x50, 0x09, 0x10, 0x8D, 0x06, 0x74, 0x64, 0x4A, - 0x64, 0x4F, 0xA5, 0x48, 0xE5, 0x49, 0xC9, 0xC8, - 0xA5, 0x51, 0x29, 0xF3, 0xB0, 0x02, 0x09, 0x08, - 0x8D, 0x04, 0x74, 0xA5, 0x4E, 0xF0, 0x08, 0xA5, - 0x4B, 0x85, 0x4C, 0x64, 0x4A, 0x64, 0x4E, 0x20, - 0x23, 0x3A, 0x4C, 0x92, 0x38, 0xAD, 0x02, 0x44, - 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, - 0xAD, 0x00, 0x44, 0xD0, 0x32, 0xA6, 0x00, 0xA9, - 0x01, 0x9D, 0x00, 0x10, 0xA9, 0x01, 0x9D, 0x00, - 0x09, 0xE8, 0xE4, 0x01, 0xF0, 0x02, 0x86, 0x00, - 0x4C, 0x65, 0x3A, 0xA6, 0x00, 0xAD, 0x00, 0x44, - 0x9D, 0x00, 0x09, 0x9E, 0x00, 0x10, 0xE8, 0xE4, - 0x01, 0xF0, 0x02, 0x86, 0x00, 0x29, 0x7F, 0xC9, - 0x13, 0xD0, 0x04, 0xA5, 0x0B, 0x85, 0x02, 0xAD, - 0x02, 0x44, 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x05, - 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x01, 0xD0, - 0x21, 0x8E, 0x00, 0x44, 0x64, 0x05, 0x4C, 0x98, - 0x3A, 0xA6, 0x04, 0xE4, 0x03, 0xF0, 0x13, 0xA5, - 0x02, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x01, - 0xD0, 0x08, 0xBD, 0x00, 0x02, 0x8D, 0x00, 0x44, - 0xE6, 0x04, 0xAD, 0x02, 0x4C, 0x89, 0x08, 0xF0, - 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, 0x4C, - 0xD0, 0x32, 0xA6, 0x0C, 0xA9, 0x01, 0x9D, 0x00, - 0x11, 0xA9, 0x01, 0x9D, 0x00, 0x0A, 0xE8, 0xE4, - 0x0D, 0xF0, 0x02, 0x86, 0x0C, 0x4C, 0xDA, 0x3A, - 0xA6, 0x0C, 0xAD, 0x00, 0x4C, 0x9D, 0x00, 0x0A, - 0x9E, 0x00, 0x11, 0xE8, 0xE4, 0x0D, 0xF0, 0x02, - 0x86, 0x0C, 0x29, 0x7F, 0xC9, 0x13, 0xD0, 0x04, - 0xA5, 0x17, 0x85, 0x0E, 0xAD, 0x02, 0x4C, 0x29, - 0x10, 0xF0, 0x2C, 0xA6, 0x11, 0xF0, 0x0F, 0xAD, - 0x02, 0x7C, 0x29, 0x02, 0xD0, 0x21, 0x8E, 0x00, - 0x4C, 0x64, 0x11, 0x4C, 0x0D, 0x3B, 0xA6, 0x10, - 0xE4, 0x0F, 0xF0, 0x13, 0xA5, 0x0E, 0xD0, 0x0F, - 0xAD, 0x02, 0x7C, 0x29, 0x02, 0xD0, 0x08, 0xBD, - 0x00, 0x03, 0x8D, 0x00, 0x4C, 0xE6, 0x10, 0xAD, - 0x02, 0x54, 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, - 0xF0, 0x1B, 0xAD, 0x00, 0x54, 0xD0, 0x32, 0xA6, - 0x18, 0xA9, 0x01, 0x9D, 0x00, 0x12, 0xA9, 0x01, - 0x9D, 0x00, 0x0B, 0xE8, 0xE4, 0x19, 0xF0, 0x02, - 0x86, 0x18, 0x4C, 0x4F, 0x3B, 0xA6, 0x18, 0xAD, - 0x00, 0x54, 0x9D, 0x00, 0x0B, 0x9E, 0x00, 0x12, - 0xE8, 0xE4, 0x19, 0xF0, 0x02, 0x86, 0x18, 0x29, - 0x7F, 0xC9, 0x13, 0xD0, 0x04, 0xA5, 0x23, 0x85, - 0x1A, 0xAD, 0x02, 0x54, 0x29, 0x10, 0xF0, 0x2C, - 0xA6, 0x1D, 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, - 0x04, 0xD0, 0x21, 0x8E, 0x00, 0x54, 0x64, 0x1D, - 0x4C, 0x82, 0x3B, 0xA6, 0x1C, 0xE4, 0x1B, 0xF0, - 0x13, 0xA5, 0x1A, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, - 0x29, 0x04, 0xD0, 0x08, 0xBD, 0x00, 0x04, 0x8D, - 0x00, 0x54, 0xE6, 0x1C, 0xAD, 0x02, 0x5C, 0x89, - 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, - 0x00, 0x5C, 0xD0, 0x32, 0xA6, 0x24, 0xA9, 0x01, - 0x9D, 0x00, 0x13, 0xA9, 0x01, 0x9D, 0x00, 0x0C, - 0xE8, 0xE4, 0x25, 0xF0, 0x02, 0x86, 0x24, 0x4C, - 0xC4, 0x3B, 0xA6, 0x24, 0xAD, 0x00, 0x5C, 0x9D, - 0x00, 0x0C, 0x9E, 0x00, 0x13, 0xE8, 0xE4, 0x25, - 0xF0, 0x02, 0x86, 0x24, 0x29, 0x7F, 0xC9, 0x13, - 0xD0, 0x04, 0xA5, 0x2F, 0x85, 0x26, 0xAD, 0x02, - 0x5C, 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x29, 0xF0, - 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x08, 0xD0, 0x21, - 0x8E, 0x00, 0x5C, 0x64, 0x29, 0x4C, 0xF7, 0x3B, - 0xA6, 0x28, 0xE4, 0x27, 0xF0, 0x13, 0xA5, 0x26, - 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x08, 0xD0, - 0x08, 0xBD, 0x00, 0x05, 0x8D, 0x00, 0x5C, 0xE6, - 0x28, 0xAD, 0x02, 0x64, 0x89, 0x08, 0xF0, 0x3B, - 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, 0x64, 0xD0, - 0x32, 0xA6, 0x30, 0xA9, 0x01, 0x9D, 0x00, 0x14, - 0xA9, 0x01, 0x9D, 0x00, 0x0D, 0xE8, 0xE4, 0x31, - 0xF0, 0x02, 0x86, 0x30, 0x4C, 0x39, 0x3C, 0xA6, - 0x30, 0xAD, 0x00, 0x64, 0x9D, 0x00, 0x0D, 0x9E, - 0x00, 0x14, 0xE8, 0xE4, 0x31, 0xF0, 0x02, 0x86, - 0x30, 0x29, 0x7F, 0xC9, 0x13, 0xD0, 0x04, 0xA5, - 0x3B, 0x85, 0x32, 0xAD, 0x02, 0x64, 0x29, 0x10, - 0xF0, 0x2C, 0xA6, 0x35, 0xF0, 0x0F, 0xAD, 0x02, - 0x7C, 0x29, 0x10, 0xD0, 0x21, 0x8E, 0x00, 0x64, - 0x64, 0x35, 0x4C, 0x6C, 0x3C, 0xA6, 0x34, 0xE4, - 0x33, 0xF0, 0x13, 0xA5, 0x32, 0xD0, 0x0F, 0xAD, - 0x02, 0x7C, 0x29, 0x10, 0xD0, 0x08, 0xBD, 0x00, - 0x06, 0x8D, 0x00, 0x64, 0xE6, 0x34, 0xAD, 0x02, - 0x6C, 0x89, 0x08, 0xF0, 0x3B, 0x89, 0x02, 0xF0, - 0x1B, 0xAD, 0x00, 0x6C, 0xD0, 0x32, 0xA6, 0x3C, - 0xA9, 0x01, 0x9D, 0x00, 0x15, 0xA9, 0x01, 0x9D, - 0x00, 0x0E, 0xE8, 0xE4, 0x3D, 0xF0, 0x02, 0x86, - 0x3C, 0x4C, 0xAE, 0x3C, 0xA6, 0x3C, 0xAD, 0x00, - 0x6C, 0x9D, 0x00, 0x0E, 0x9E, 0x00, 0x15, 0xE8, - 0xE4, 0x3D, 0xF0, 0x02, 0x86, 0x3C, 0x29, 0x7F, - 0xC9, 0x13, 0xD0, 0x04, 0xA5, 0x47, 0x85, 0x3E, - 0xAD, 0x02, 0x6C, 0x29, 0x10, 0xF0, 0x2C, 0xA6, - 0x41, 0xF0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x20, - 0xD0, 0x21, 0x8E, 0x00, 0x6C, 0x64, 0x41, 0x4C, - 0xE1, 0x3C, 0xA6, 0x40, 0xE4, 0x3F, 0xF0, 0x13, - 0xA5, 0x3E, 0xD0, 0x0F, 0xAD, 0x02, 0x7C, 0x29, - 0x20, 0xD0, 0x08, 0xBD, 0x00, 0x07, 0x8D, 0x00, - 0x6C, 0xE6, 0x40, 0xAD, 0x02, 0x74, 0x89, 0x08, - 0xF0, 0x3B, 0x89, 0x02, 0xF0, 0x1B, 0xAD, 0x00, - 0x74, 0xD0, 0x32, 0xA6, 0x48, 0xA9, 0x01, 0x9D, - 0x00, 0x16, 0xA9, 0x01, 0x9D, 0x00, 0x0F, 0xE8, - 0xE4, 0x49, 0xF0, 0x02, 0x86, 0x48, 0x4C, 0x23, - 0x3D, 0xA6, 0x48, 0xAD, 0x00, 0x74, 0x9D, 0x00, - 0x0F, 0x9E, 0x00, 0x16, 0xE8, 0xE4, 0x49, 0xF0, - 0x02, 0x86, 0x48, 0x29, 0x7F, 0xC9, 0x13, 0xD0, - 0x04, 0xA5, 0x53, 0x85, 0x4A, 0xAD, 0x02, 0x74, - 0x29, 0x10, 0xF0, 0x2C, 0xA6, 0x4D, 0xF0, 0x0F, - 0xAD, 0x02, 0x7C, 0x29, 0x40, 0xD0, 0x21, 0x8E, - 0x00, 0x74, 0x64, 0x4D, 0x4C, 0x56, 0x3D, 0xA6, - 0x4C, 0xE4, 0x4B, 0xF0, 0x13, 0xA5, 0x4A, 0xD0, - 0x0F, 0xAD, 0x02, 0x7C, 0x29, 0x40, 0xD0, 0x08, - 0xBD, 0x00, 0x08, 0x8D, 0x00, 0x74, 0xE6, 0x4C, - 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xD0, 0xD0, 0x00, 0x38, - 0xCE, 0xC0, -}; diff --git a/drivers/staging/generic_serial/sx.c b/drivers/staging/generic_serial/sx.c deleted file mode 100644 index 4f94aaffbe83..000000000000 --- a/drivers/staging/generic_serial/sx.c +++ /dev/null @@ -1,2894 +0,0 @@ -/* sx.c -- driver for the Specialix SX series cards. - * - * This driver will also support the older SI, and XIO cards. - * - * - * (C) 1998 - 2004 R.E.Wolff@BitWizard.nl - * - * Simon Allen (simonallen@cix.compulink.co.uk) wrote a previous - * version of this driver. Some fragments may have been copied. (none - * yet :-) - * - * Specialix pays for the development and support of this driver. - * Please DO contact support@specialix.co.uk if you require - * support. But please read the documentation (sx.txt) first. - * - * - * - * 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. - * - * Revision history: - * Revision 1.33 2000/03/09 10:00:00 pvdl,wolff - * - Fixed module and port counting - * - Fixed signal handling - * - Fixed an Ooops - * - * Revision 1.32 2000/03/07 09:00:00 wolff,pvdl - * - Fixed some sx_dprintk typos - * - added detection for an invalid board/module configuration - * - * Revision 1.31 2000/03/06 12:00:00 wolff,pvdl - * - Added support for EISA - * - * Revision 1.30 2000/01/21 17:43:06 wolff - * - Added support for SX+ - * - * Revision 1.26 1999/08/05 15:22:14 wolff - * - Port to 2.3.x - * - Reformatted to Linus' liking. - * - * Revision 1.25 1999/07/30 14:24:08 wolff - * Had accidentally left "gs_debug" set to "-1" instead of "off" (=0). - * - * Revision 1.24 1999/07/28 09:41:52 wolff - * - I noticed the remark about use-count straying in sx.txt. I checked - * sx_open, and found a few places where that could happen. I hope it's - * fixed now. - * - * Revision 1.23 1999/07/28 08:56:06 wolff - * - Fixed crash when sx_firmware run twice. - * - Added sx_slowpoll as a module parameter (I guess nobody really wanted - * to change it from the default... ) - * - Fixed a stupid editing problem I introduced in 1.22. - * - Fixed dropping characters on a termios change. - * - * Revision 1.22 1999/07/26 21:01:43 wolff - * Russell Brown noticed that I had overlooked 4 out of six modem control - * signals in sx_getsignals. Ooops. - * - * Revision 1.21 1999/07/23 09:11:33 wolff - * I forgot to free dynamically allocated memory when the driver is unloaded. - * - * Revision 1.20 1999/07/20 06:25:26 wolff - * The "closing wait" wasn't honoured. Thanks to James Griffiths for - * reporting this. - * - * Revision 1.19 1999/07/11 08:59:59 wolff - * Fixed an oops in close, when an open was pending. Changed the memtest - * a bit. Should also test the board in word-mode, however my card fails the - * memtest then. I still have to figure out what is wrong... - * - * Revision 1.18 1999/06/10 09:38:42 wolff - * Changed the format of the firmware revision from %04x to %x.%02x . - * - * Revision 1.17 1999/06/04 09:44:35 wolff - * fixed problem: reference to pci stuff when config_pci was off... - * Thanks to Jorge Novo for noticing this. - * - * Revision 1.16 1999/06/02 08:30:15 wolff - * added/removed the workaround for the DCD bug in the Firmware. - * A bit more debugging code to locate that... - * - * Revision 1.15 1999/06/01 11:35:30 wolff - * when DCD is left low (floating?), on TA's the firmware first tells us - * that DCD is high, but after a short while suddenly comes to the - * conclusion that it is low. All this would be fine, if it weren't that - * Unix requires us to send a "hangup" signal in that case. This usually - * all happens BEFORE the program has had a chance to ioctl the device - * into clocal mode.. - * - * Revision 1.14 1999/05/25 11:18:59 wolff - * Added PCI-fix. - * Added checks for return code of sx_sendcommand. - * Don't issue "reconfig" if port isn't open yet. (bit us on TA modules...) - * - * Revision 1.13 1999/04/29 15:18:01 wolff - * Fixed an "oops" that showed on SuSE 6.0 systems. - * Activate DTR again after stty 0. - * - * Revision 1.12 1999/04/29 07:49:52 wolff - * Improved "stty 0" handling a bit. (used to change baud to 9600 assuming - * the connection would be dropped anyway. That is not always the case, - * and confuses people). - * Told the card to always monitor the modem signals. - * Added support for dynamic gs_debug adjustments. - * Now tells the rest of the system the number of ports. - * - * Revision 1.11 1999/04/24 11:11:30 wolff - * Fixed two stupid typos in the memory test. - * - * Revision 1.10 1999/04/24 10:53:39 wolff - * Added some of Christian's suggestions. - * Fixed an HW_COOK_IN bug (ISIG was not in I_OTHER. We used to trust the - * card to send the signal to the process.....) - * - * Revision 1.9 1999/04/23 07:26:38 wolff - * Included Christian Lademann's 2.0 compile-warning fixes and interrupt - * assignment redesign. - * Cleanup of some other stuff. - * - * Revision 1.8 1999/04/16 13:05:30 wolff - * fixed a DCD change unnoticed bug. - * - * Revision 1.7 1999/04/14 22:19:51 wolff - * Fixed typo that showed up in 2.0.x builds (get_user instead of Get_user!) - * - * Revision 1.6 1999/04/13 18:40:20 wolff - * changed misc-minor to 161, as assigned by HPA. - * - * Revision 1.5 1999/04/13 15:12:25 wolff - * Fixed use-count leak when "hangup" occurred. - * Added workaround for a stupid-PCIBIOS bug. - * - * - * Revision 1.4 1999/04/01 22:47:40 wolff - * Fixed < 1M linux-2.0 problem. - * (vremap isn't compatible with ioremap in that case) - * - * Revision 1.3 1999/03/31 13:45:45 wolff - * Firmware loading is now done through a separate IOCTL. - * - * Revision 1.2 1999/03/28 12:22:29 wolff - * rcs cleanup - * - * Revision 1.1 1999/03/28 12:10:34 wolff - * Readying for release on 2.0.x (sorry David, 1.01 becomes 1.1 for RCS). - * - * Revision 0.12 1999/03/28 09:20:10 wolff - * Fixed problem in 0.11, continuing cleanup. - * - * Revision 0.11 1999/03/28 08:46:44 wolff - * cleanup. Not good. - * - * Revision 0.10 1999/03/28 08:09:43 wolff - * Fixed losing characters on close. - * - * Revision 0.9 1999/03/21 22:52:01 wolff - * Ported back to 2.2.... (minor things) - * - * Revision 0.8 1999/03/21 22:40:33 wolff - * Port to 2.0 - * - * Revision 0.7 1999/03/21 19:06:34 wolff - * Fixed hangup processing. - * - * Revision 0.6 1999/02/05 08:45:14 wolff - * fixed real_raw problems. Inclusion into kernel imminent. - * - * Revision 0.5 1998/12/21 23:51:06 wolff - * Snatched a nasty bug: sx_transmit_chars was getting re-entered, and it - * shouldn't have. THATs why I want to have transmit interrupts even when - * the buffer is empty. - * - * Revision 0.4 1998/12/17 09:34:46 wolff - * PPP works. ioctl works. Basically works! - * - * Revision 0.3 1998/12/15 13:05:18 wolff - * It works! Wow! Gotta start implementing IOCTL and stuff.... - * - * Revision 0.2 1998/12/01 08:33:53 wolff - * moved over to 2.1.130 - * - * Revision 0.1 1998/11/03 21:23:51 wolff - * Initial revision. Detects SX card. - * - * */ - -#define SX_VERSION 1.33 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* The 3.0.0 version of sxboards/sxwindow.h uses BYTE and WORD.... */ -#define BYTE u8 -#define WORD u16 - -/* .... but the 3.0.4 version uses _u8 and _u16. */ -#define _u8 u8 -#define _u16 u16 - -#include "sxboards.h" -#include "sxwindow.h" - -#include -#include "sx.h" - -/* I don't think that this driver can handle more than 256 ports on - one machine. You'll have to increase the number of boards in sx.h - if you want more than 4 boards. */ - -#ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 -#define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 -#endif - -/* Configurable options: - (Don't be too sure that it'll work if you toggle them) */ - -/* Am I paranoid or not ? ;-) */ -#undef SX_PARANOIA_CHECK - -/* 20 -> 2000 per second. The card should rate-limit interrupts at 100 - Hz, but it is user configurable. I don't recommend going above 1000 - Hz. The interrupt ratelimit might trigger if the interrupt is - shared with a very active other device. */ -#define IRQ_RATE_LIMIT 20 - -/* Sharing interrupts is possible now. If the other device wants more - than 2000 interrupts per second, we'd gracefully decline further - interrupts. That's not what we want. On the other hand, if the - other device interrupts 2000 times a second, don't use the SX - interrupt. Use polling. */ -#undef IRQ_RATE_LIMIT - -#if 0 -/* Not implemented */ -/* - * The following defines are mostly for testing purposes. But if you need - * some nice reporting in your syslog, you can define them also. - */ -#define SX_REPORT_FIFO -#define SX_REPORT_OVERRUN -#endif - -/* Function prototypes */ -static void sx_disable_tx_interrupts(void *ptr); -static void sx_enable_tx_interrupts(void *ptr); -static void sx_disable_rx_interrupts(void *ptr); -static void sx_enable_rx_interrupts(void *ptr); -static int sx_carrier_raised(struct tty_port *port); -static void sx_shutdown_port(void *ptr); -static int sx_set_real_termios(void *ptr); -static void sx_close(void *ptr); -static int sx_chars_in_buffer(void *ptr); -static int sx_init_board(struct sx_board *board); -static int sx_init_portstructs(int nboards, int nports); -static long sx_fw_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); -static int sx_init_drivers(void); - -static struct tty_driver *sx_driver; - -static DEFINE_MUTEX(sx_boards_lock); -static struct sx_board boards[SX_NBOARDS]; -static struct sx_port *sx_ports; -static int sx_initialized; -static int sx_nports; -static int sx_debug; - -/* You can have the driver poll your card. - - Set sx_poll to 1 to poll every timer tick (10ms on Intel). - This is used when the card cannot use an interrupt for some reason. - - - set sx_slowpoll to 100 to do an extra poll once a second (on Intel). If - the driver misses an interrupt (report this if it DOES happen to you!) - everything will continue to work.... - */ -static int sx_poll = 1; -static int sx_slowpoll; - -/* The card limits the number of interrupts per second. - At 115k2 "100" should be sufficient. - If you're using higher baudrates, you can increase this... - */ - -static int sx_maxints = 100; - -#ifdef CONFIG_ISA - -/* These are the only open spaces in my computer. Yours may have more - or less.... -- REW - duh: Card at 0xa0000 is possible on HP Netserver?? -- pvdl -*/ -static int sx_probe_addrs[] = { - 0xc0000, 0xd0000, 0xe0000, - 0xc8000, 0xd8000, 0xe8000 -}; -static int si_probe_addrs[] = { - 0xc0000, 0xd0000, 0xe0000, - 0xc8000, 0xd8000, 0xe8000, 0xa0000 -}; -static int si1_probe_addrs[] = { - 0xd0000 -}; - -#define NR_SX_ADDRS ARRAY_SIZE(sx_probe_addrs) -#define NR_SI_ADDRS ARRAY_SIZE(si_probe_addrs) -#define NR_SI1_ADDRS ARRAY_SIZE(si1_probe_addrs) - -module_param_array(sx_probe_addrs, int, NULL, 0); -module_param_array(si_probe_addrs, int, NULL, 0); -#endif - -/* Set the mask to all-ones. This alas, only supports 32 interrupts. - Some architectures may need more. */ -static int sx_irqmask = -1; - -module_param(sx_poll, int, 0); -module_param(sx_slowpoll, int, 0); -module_param(sx_maxints, int, 0); -module_param(sx_debug, int, 0); -module_param(sx_irqmask, int, 0); - -MODULE_LICENSE("GPL"); - -static struct real_driver sx_real_driver = { - sx_disable_tx_interrupts, - sx_enable_tx_interrupts, - sx_disable_rx_interrupts, - sx_enable_rx_interrupts, - sx_shutdown_port, - sx_set_real_termios, - sx_chars_in_buffer, - sx_close, -}; - -/* - This driver can spew a whole lot of debugging output at you. If you - need maximum performance, you should disable the DEBUG define. To - aid in debugging in the field, I'm leaving the compile-time debug - features enabled, and disable them "runtime". That allows me to - instruct people with problems to enable debugging without requiring - them to recompile... -*/ -#define DEBUG - -#ifdef DEBUG -#define sx_dprintk(f, str...) if (sx_debug & f) printk (str) -#else -#define sx_dprintk(f, str...) /* nothing */ -#endif - -#define func_enter() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s\n",__func__) -#define func_exit() sx_dprintk(SX_DEBUG_FLOW, "sx: exit %s\n",__func__) - -#define func_enter2() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \ - __func__, port->line) - -/* - * Firmware loader driver specific routines - * - */ - -static const struct file_operations sx_fw_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = sx_fw_ioctl, - .llseek = noop_llseek, -}; - -static struct miscdevice sx_fw_device = { - SXCTL_MISC_MINOR, "sxctl", &sx_fw_fops -}; - -#ifdef SX_PARANOIA_CHECK - -/* This doesn't work. Who's paranoid around here? Not me! */ - -static inline int sx_paranoia_check(struct sx_port const *port, - char *name, const char *routine) -{ - static const char *badmagic = KERN_ERR "sx: Warning: bad sx port magic " - "number for device %s in %s\n"; - static const char *badinfo = KERN_ERR "sx: Warning: null sx port for " - "device %s in %s\n"; - - if (!port) { - printk(badinfo, name, routine); - return 1; - } - if (port->magic != SX_MAGIC) { - printk(badmagic, name, routine); - return 1; - } - - return 0; -} -#else -#define sx_paranoia_check(a,b,c) 0 -#endif - -/* The timeouts. First try 30 times as fast as possible. Then give - the card some time to breathe between accesses. (Otherwise the - processor on the card might not be able to access its OWN bus... */ - -#define TIMEOUT_1 30 -#define TIMEOUT_2 1000000 - -#ifdef DEBUG -static void my_hd_io(void __iomem *p, int len) -{ - int i, j, ch; - unsigned char __iomem *addr = p; - - for (i = 0; i < len; i += 16) { - printk("%p ", addr + i); - for (j = 0; j < 16; j++) { - printk("%02x %s", readb(addr + j + i), - (j == 7) ? " " : ""); - } - for (j = 0; j < 16; j++) { - ch = readb(addr + j + i); - printk("%c", (ch < 0x20) ? '.' : - ((ch > 0x7f) ? '.' : ch)); - } - printk("\n"); - } -} -static void my_hd(void *p, int len) -{ - int i, j, ch; - unsigned char *addr = p; - - for (i = 0; i < len; i += 16) { - printk("%p ", addr + i); - for (j = 0; j < 16; j++) { - printk("%02x %s", addr[j + i], (j == 7) ? " " : ""); - } - for (j = 0; j < 16; j++) { - ch = addr[j + i]; - printk("%c", (ch < 0x20) ? '.' : - ((ch > 0x7f) ? '.' : ch)); - } - printk("\n"); - } -} -#endif - -/* This needs redoing for Alpha -- REW -- Done. */ - -static inline void write_sx_byte(struct sx_board *board, int offset, u8 byte) -{ - writeb(byte, board->base + offset); -} - -static inline u8 read_sx_byte(struct sx_board *board, int offset) -{ - return readb(board->base + offset); -} - -static inline void write_sx_word(struct sx_board *board, int offset, u16 word) -{ - writew(word, board->base + offset); -} - -static inline u16 read_sx_word(struct sx_board *board, int offset) -{ - return readw(board->base + offset); -} - -static int sx_busy_wait_eq(struct sx_board *board, - int offset, int mask, int correctval) -{ - int i; - - func_enter(); - - for (i = 0; i < TIMEOUT_1; i++) - if ((read_sx_byte(board, offset) & mask) == correctval) { - func_exit(); - return 1; - } - - for (i = 0; i < TIMEOUT_2; i++) { - if ((read_sx_byte(board, offset) & mask) == correctval) { - func_exit(); - return 1; - } - udelay(1); - } - - func_exit(); - return 0; -} - -static int sx_busy_wait_neq(struct sx_board *board, - int offset, int mask, int badval) -{ - int i; - - func_enter(); - - for (i = 0; i < TIMEOUT_1; i++) - if ((read_sx_byte(board, offset) & mask) != badval) { - func_exit(); - return 1; - } - - for (i = 0; i < TIMEOUT_2; i++) { - if ((read_sx_byte(board, offset) & mask) != badval) { - func_exit(); - return 1; - } - udelay(1); - } - - func_exit(); - return 0; -} - -/* 5.6.4 of 6210028 r2.3 */ -static int sx_reset(struct sx_board *board) -{ - func_enter(); - - if (IS_SX_BOARD(board)) { - - write_sx_byte(board, SX_CONFIG, 0); - write_sx_byte(board, SX_RESET, 1); /* Value doesn't matter */ - - if (!sx_busy_wait_eq(board, SX_RESET_STATUS, 1, 0)) { - printk(KERN_INFO "sx: Card doesn't respond to " - "reset...\n"); - return 0; - } - } else if (IS_EISA_BOARD(board)) { - outb(board->irq << 4, board->eisa_base + 0xc02); - } else if (IS_SI1_BOARD(board)) { - write_sx_byte(board, SI1_ISA_RESET, 0); /*value doesn't matter*/ - } else { - /* Gory details of the SI/ISA board */ - write_sx_byte(board, SI2_ISA_RESET, SI2_ISA_RESET_SET); - write_sx_byte(board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_CLEAR); - write_sx_byte(board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_CLEAR); - write_sx_byte(board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_CLEAR); - write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_CLEAR); - write_sx_byte(board, SI2_ISA_IRQSET, SI2_ISA_IRQSET_CLEAR); - } - - func_exit(); - return 1; -} - -/* This doesn't work on machines where "NULL" isn't 0 */ -/* If you have one of those, someone will need to write - the equivalent of this, which will amount to about 3 lines. I don't - want to complicate this right now. -- REW - (See, I do write comments every now and then :-) */ -#define OFFSETOF(strct, elem) ((long)&(((struct strct *)NULL)->elem)) - -#define CHAN_OFFSET(port,elem) (port->ch_base + OFFSETOF (_SXCHANNEL, elem)) -#define MODU_OFFSET(board,addr,elem) (addr + OFFSETOF (_SXMODULE, elem)) -#define BRD_OFFSET(board,elem) (OFFSETOF (_SXCARD, elem)) - -#define sx_write_channel_byte(port, elem, val) \ - write_sx_byte (port->board, CHAN_OFFSET (port, elem), val) - -#define sx_read_channel_byte(port, elem) \ - read_sx_byte (port->board, CHAN_OFFSET (port, elem)) - -#define sx_write_channel_word(port, elem, val) \ - write_sx_word (port->board, CHAN_OFFSET (port, elem), val) - -#define sx_read_channel_word(port, elem) \ - read_sx_word (port->board, CHAN_OFFSET (port, elem)) - -#define sx_write_module_byte(board, addr, elem, val) \ - write_sx_byte (board, MODU_OFFSET (board, addr, elem), val) - -#define sx_read_module_byte(board, addr, elem) \ - read_sx_byte (board, MODU_OFFSET (board, addr, elem)) - -#define sx_write_module_word(board, addr, elem, val) \ - write_sx_word (board, MODU_OFFSET (board, addr, elem), val) - -#define sx_read_module_word(board, addr, elem) \ - read_sx_word (board, MODU_OFFSET (board, addr, elem)) - -#define sx_write_board_byte(board, elem, val) \ - write_sx_byte (board, BRD_OFFSET (board, elem), val) - -#define sx_read_board_byte(board, elem) \ - read_sx_byte (board, BRD_OFFSET (board, elem)) - -#define sx_write_board_word(board, elem, val) \ - write_sx_word (board, BRD_OFFSET (board, elem), val) - -#define sx_read_board_word(board, elem) \ - read_sx_word (board, BRD_OFFSET (board, elem)) - -static int sx_start_board(struct sx_board *board) -{ - if (IS_SX_BOARD(board)) { - write_sx_byte(board, SX_CONFIG, SX_CONF_BUSEN); - } else if (IS_EISA_BOARD(board)) { - write_sx_byte(board, SI2_EISA_OFF, SI2_EISA_VAL); - outb((board->irq << 4) | 4, board->eisa_base + 0xc02); - } else if (IS_SI1_BOARD(board)) { - write_sx_byte(board, SI1_ISA_RESET_CLEAR, 0); - write_sx_byte(board, SI1_ISA_INTCL, 0); - } else { - /* Don't bug me about the clear_set. - I haven't the foggiest idea what it's about -- REW */ - write_sx_byte(board, SI2_ISA_RESET, SI2_ISA_RESET_CLEAR); - write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); - } - return 1; -} - -#define SX_IRQ_REG_VAL(board) \ - ((board->flags & SX_ISA_BOARD) ? (board->irq << 4) : 0) - -/* Note. The SX register is write-only. Therefore, we have to enable the - bus too. This is a no-op, if you don't mess with this driver... */ -static int sx_start_interrupts(struct sx_board *board) -{ - - /* Don't call this with board->irq == 0 */ - - if (IS_SX_BOARD(board)) { - write_sx_byte(board, SX_CONFIG, SX_IRQ_REG_VAL(board) | - SX_CONF_BUSEN | SX_CONF_HOSTIRQ); - } else if (IS_EISA_BOARD(board)) { - inb(board->eisa_base + 0xc03); - } else if (IS_SI1_BOARD(board)) { - write_sx_byte(board, SI1_ISA_INTCL, 0); - write_sx_byte(board, SI1_ISA_INTCL_CLEAR, 0); - } else { - switch (board->irq) { - case 11: - write_sx_byte(board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_SET); - break; - case 12: - write_sx_byte(board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_SET); - break; - case 15: - write_sx_byte(board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_SET); - break; - default: - printk(KERN_INFO "sx: SI/XIO card doesn't support " - "interrupt %d.\n", board->irq); - return 0; - } - write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); - } - - return 1; -} - -static int sx_send_command(struct sx_port *port, - int command, int mask, int newstat) -{ - func_enter2(); - write_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat), command); - func_exit(); - return sx_busy_wait_eq(port->board, CHAN_OFFSET(port, hi_hstat), mask, - newstat); -} - -static char *mod_type_s(int module_type) -{ - switch (module_type) { - case TA4: - return "TA4"; - case TA8: - return "TA8"; - case TA4_ASIC: - return "TA4_ASIC"; - case TA8_ASIC: - return "TA8_ASIC"; - case MTA_CD1400: - return "MTA_CD1400"; - case SXDC: - return "SXDC"; - default: - return "Unknown/invalid"; - } -} - -static char *pan_type_s(int pan_type) -{ - switch (pan_type) { - case MOD_RS232DB25: - return "MOD_RS232DB25"; - case MOD_RS232RJ45: - return "MOD_RS232RJ45"; - case MOD_RS422DB25: - return "MOD_RS422DB25"; - case MOD_PARALLEL: - return "MOD_PARALLEL"; - case MOD_2_RS232DB25: - return "MOD_2_RS232DB25"; - case MOD_2_RS232RJ45: - return "MOD_2_RS232RJ45"; - case MOD_2_RS422DB25: - return "MOD_2_RS422DB25"; - case MOD_RS232DB25MALE: - return "MOD_RS232DB25MALE"; - case MOD_2_PARALLEL: - return "MOD_2_PARALLEL"; - case MOD_BLANK: - return "empty"; - default: - return "invalid"; - } -} - -static int mod_compat_type(int module_type) -{ - return module_type >> 4; -} - -static void sx_reconfigure_port(struct sx_port *port) -{ - if (sx_read_channel_byte(port, hi_hstat) == HS_IDLE_OPEN) { - if (sx_send_command(port, HS_CONFIG, -1, HS_IDLE_OPEN) != 1) { - printk(KERN_WARNING "sx: Sent reconfigure command, but " - "card didn't react.\n"); - } - } else { - sx_dprintk(SX_DEBUG_TERMIOS, "sx: Not sending reconfigure: " - "port isn't open (%02x).\n", - sx_read_channel_byte(port, hi_hstat)); - } -} - -static void sx_setsignals(struct sx_port *port, int dtr, int rts) -{ - int t; - func_enter2(); - - t = sx_read_channel_byte(port, hi_op); - if (dtr >= 0) - t = dtr ? (t | OP_DTR) : (t & ~OP_DTR); - if (rts >= 0) - t = rts ? (t | OP_RTS) : (t & ~OP_RTS); - sx_write_channel_byte(port, hi_op, t); - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts); - - func_exit(); -} - -static int sx_getsignals(struct sx_port *port) -{ - int i_stat, o_stat; - - o_stat = sx_read_channel_byte(port, hi_op); - i_stat = sx_read_channel_byte(port, hi_ip); - - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "getsignals: %d/%d (%d/%d) " - "%02x/%02x\n", - (o_stat & OP_DTR) != 0, (o_stat & OP_RTS) != 0, - port->c_dcd, tty_port_carrier_raised(&port->gs.port), - sx_read_channel_byte(port, hi_ip), - sx_read_channel_byte(port, hi_state)); - - return (((o_stat & OP_DTR) ? TIOCM_DTR : 0) | - ((o_stat & OP_RTS) ? TIOCM_RTS : 0) | - ((i_stat & IP_CTS) ? TIOCM_CTS : 0) | - ((i_stat & IP_DCD) ? TIOCM_CAR : 0) | - ((i_stat & IP_DSR) ? TIOCM_DSR : 0) | - ((i_stat & IP_RI) ? TIOCM_RNG : 0)); -} - -static void sx_set_baud(struct sx_port *port) -{ - int t; - - if (port->board->ta_type == MOD_SXDC) { - switch (port->gs.baud) { - /* Save some typing work... */ -#define e(x) case x: t = BAUD_ ## x; break - e(50); - e(75); - e(110); - e(150); - e(200); - e(300); - e(600); - e(1200); - e(1800); - e(2000); - e(2400); - e(4800); - e(7200); - e(9600); - e(14400); - e(19200); - e(28800); - e(38400); - e(56000); - e(57600); - e(64000); - e(76800); - e(115200); - e(128000); - e(150000); - e(230400); - e(256000); - e(460800); - e(921600); - case 134: - t = BAUD_134_5; - break; - case 0: - t = -1; - break; - default: - /* Can I return "invalid"? */ - t = BAUD_9600; - printk(KERN_INFO "sx: unsupported baud rate: %d.\n", - port->gs.baud); - break; - } -#undef e - if (t > 0) { -/* The baud rate is not set to 0, so we're enabeling DTR... -- REW */ - sx_setsignals(port, 1, -1); - /* XXX This is not TA & MTA compatible */ - sx_write_channel_byte(port, hi_csr, 0xff); - - sx_write_channel_byte(port, hi_txbaud, t); - sx_write_channel_byte(port, hi_rxbaud, t); - } else { - sx_setsignals(port, 0, -1); - } - } else { - switch (port->gs.baud) { -#define e(x) case x: t = CSR_ ## x; break - e(75); - e(150); - e(300); - e(600); - e(1200); - e(2400); - e(4800); - e(1800); - e(9600); - e(19200); - e(57600); - e(38400); -/* TA supports 110, but not 115200, MTA supports 115200, but not 110 */ - case 110: - if (port->board->ta_type == MOD_TA) { - t = CSR_110; - break; - } else { - t = CSR_9600; - printk(KERN_INFO "sx: Unsupported baud rate: " - "%d.\n", port->gs.baud); - break; - } - case 115200: - if (port->board->ta_type == MOD_TA) { - t = CSR_9600; - printk(KERN_INFO "sx: Unsupported baud rate: " - "%d.\n", port->gs.baud); - break; - } else { - t = CSR_110; - break; - } - case 0: - t = -1; - break; - default: - t = CSR_9600; - printk(KERN_INFO "sx: Unsupported baud rate: %d.\n", - port->gs.baud); - break; - } -#undef e - if (t >= 0) { - sx_setsignals(port, 1, -1); - sx_write_channel_byte(port, hi_csr, t * 0x11); - } else { - sx_setsignals(port, 0, -1); - } - } -} - -/* Simon Allen's version of this routine was 225 lines long. 85 is a lot - better. -- REW */ - -static int sx_set_real_termios(void *ptr) -{ - struct sx_port *port = ptr; - - func_enter2(); - - if (!port->gs.port.tty) - return 0; - - /* What is this doing here? -- REW - Ha! figured it out. It is to allow you to get DTR active again - if you've dropped it with stty 0. Moved to set_baud, where it - belongs (next to the drop dtr if baud == 0) -- REW */ - /* sx_setsignals (port, 1, -1); */ - - sx_set_baud(port); - -#define CFLAG port->gs.port.tty->termios->c_cflag - sx_write_channel_byte(port, hi_mr1, - (C_PARENB(port->gs.port.tty) ? MR1_WITH : MR1_NONE) | - (C_PARODD(port->gs.port.tty) ? MR1_ODD : MR1_EVEN) | - (C_CRTSCTS(port->gs.port.tty) ? MR1_RTS_RXFLOW : 0) | - (((CFLAG & CSIZE) == CS8) ? MR1_8_BITS : 0) | - (((CFLAG & CSIZE) == CS7) ? MR1_7_BITS : 0) | - (((CFLAG & CSIZE) == CS6) ? MR1_6_BITS : 0) | - (((CFLAG & CSIZE) == CS5) ? MR1_5_BITS : 0)); - - sx_write_channel_byte(port, hi_mr2, - (C_CRTSCTS(port->gs.port.tty) ? MR2_CTS_TXFLOW : 0) | - (C_CSTOPB(port->gs.port.tty) ? MR2_2_STOP : - MR2_1_STOP)); - - switch (CFLAG & CSIZE) { - case CS8: - sx_write_channel_byte(port, hi_mask, 0xff); - break; - case CS7: - sx_write_channel_byte(port, hi_mask, 0x7f); - break; - case CS6: - sx_write_channel_byte(port, hi_mask, 0x3f); - break; - case CS5: - sx_write_channel_byte(port, hi_mask, 0x1f); - break; - default: - printk(KERN_INFO "sx: Invalid wordsize: %u\n", - (unsigned int)CFLAG & CSIZE); - break; - } - - sx_write_channel_byte(port, hi_prtcl, - (I_IXON(port->gs.port.tty) ? SP_TXEN : 0) | - (I_IXOFF(port->gs.port.tty) ? SP_RXEN : 0) | - (I_IXANY(port->gs.port.tty) ? SP_TANY : 0) | SP_DCEN); - - sx_write_channel_byte(port, hi_break, - (I_IGNBRK(port->gs.port.tty) ? BR_IGN : 0 | - I_BRKINT(port->gs.port.tty) ? BR_INT : 0)); - - sx_write_channel_byte(port, hi_txon, START_CHAR(port->gs.port.tty)); - sx_write_channel_byte(port, hi_rxon, START_CHAR(port->gs.port.tty)); - sx_write_channel_byte(port, hi_txoff, STOP_CHAR(port->gs.port.tty)); - sx_write_channel_byte(port, hi_rxoff, STOP_CHAR(port->gs.port.tty)); - - sx_reconfigure_port(port); - - /* Tell line discipline whether we will do input cooking */ - if (I_OTHER(port->gs.port.tty)) { - clear_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags); - } else { - set_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags); - } - sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ", - (unsigned int)port->gs.port.tty->termios->c_iflag, - I_OTHER(port->gs.port.tty)); - -/* Tell line discipline whether we will do output cooking. - * If OPOST is set and no other output flags are set then we can do output - * processing. Even if only *one* other flag in the O_OTHER group is set - * we do cooking in software. - */ - if (O_OPOST(port->gs.port.tty) && !O_OTHER(port->gs.port.tty)) { - set_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags); - } else { - clear_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags); - } - sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n", - (unsigned int)port->gs.port.tty->termios->c_oflag, - O_OTHER(port->gs.port.tty)); - /* port->c_dcd = sx_get_CD (port); */ - func_exit(); - return 0; -} - -/* ********************************************************************** * - * the interrupt related routines * - * ********************************************************************** */ - -/* Note: - Other drivers use the macro "MIN" to calculate how much to copy. - This has the disadvantage that it will evaluate parts twice. That's - expensive when it's IO (and the compiler cannot optimize those away!). - Moreover, I'm not sure that you're race-free. - - I assign a value, and then only allow the value to decrease. This - is always safe. This makes the code a few lines longer, and you - know I'm dead against that, but I think it is required in this - case. */ - -static void sx_transmit_chars(struct sx_port *port) -{ - int c; - int tx_ip; - int txroom; - - func_enter2(); - sx_dprintk(SX_DEBUG_TRANSMIT, "Port %p: transmit %d chars\n", - port, port->gs.xmit_cnt); - - if (test_and_set_bit(SX_PORT_TRANSMIT_LOCK, &port->locks)) { - return; - } - - while (1) { - c = port->gs.xmit_cnt; - - sx_dprintk(SX_DEBUG_TRANSMIT, "Copying %d ", c); - tx_ip = sx_read_channel_byte(port, hi_txipos); - - /* Took me 5 minutes to deduce this formula. - Luckily it is literally in the manual in section 6.5.4.3.5 */ - txroom = (sx_read_channel_byte(port, hi_txopos) - tx_ip - 1) & - 0xff; - - /* Don't copy more bytes than there is room for in the buffer */ - if (c > txroom) - c = txroom; - sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%d) ", c, txroom); - - /* Don't copy past the end of the hardware transmit buffer */ - if (c > 0x100 - tx_ip) - c = 0x100 - tx_ip; - - sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%d) ", c, 0x100 - tx_ip); - - /* Don't copy pas the end of the source buffer */ - if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail) - c = SERIAL_XMIT_SIZE - port->gs.xmit_tail; - - sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%ld) \n", - c, SERIAL_XMIT_SIZE - port->gs.xmit_tail); - - /* If for one reason or another, we can't copy more data, we're - done! */ - if (c == 0) - break; - - memcpy_toio(port->board->base + CHAN_OFFSET(port, hi_txbuf) + - tx_ip, port->gs.xmit_buf + port->gs.xmit_tail, c); - - /* Update the pointer in the card */ - sx_write_channel_byte(port, hi_txipos, (tx_ip + c) & 0xff); - - /* Update the kernel buffer end */ - port->gs.xmit_tail = (port->gs.xmit_tail + c) & - (SERIAL_XMIT_SIZE - 1); - - /* This one last. (this is essential) - It would allow others to start putting more data into the - buffer! */ - port->gs.xmit_cnt -= c; - } - - if (port->gs.xmit_cnt == 0) { - sx_disable_tx_interrupts(port); - } - - if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) { - tty_wakeup(port->gs.port.tty); - sx_dprintk(SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n", - port->gs.wakeup_chars); - } - - clear_bit(SX_PORT_TRANSMIT_LOCK, &port->locks); - func_exit(); -} - -/* Note the symmetry between receiving chars and transmitting them! - Note: The kernel should have implemented both a receive buffer and - a transmit buffer. */ - -/* Inlined: Called only once. Remove the inline when you add another call */ -static inline void sx_receive_chars(struct sx_port *port) -{ - int c; - int rx_op; - struct tty_struct *tty; - int copied = 0; - unsigned char *rp; - - func_enter2(); - tty = port->gs.port.tty; - while (1) { - rx_op = sx_read_channel_byte(port, hi_rxopos); - c = (sx_read_channel_byte(port, hi_rxipos) - rx_op) & 0xff; - - sx_dprintk(SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); - - /* Don't copy past the end of the hardware receive buffer */ - if (rx_op + c > 0x100) - c = 0x100 - rx_op; - - sx_dprintk(SX_DEBUG_RECEIVE, "c = %d.\n", c); - - /* Don't copy more bytes than there is room for in the buffer */ - - c = tty_prepare_flip_string(tty, &rp, c); - - sx_dprintk(SX_DEBUG_RECEIVE, "c = %d.\n", c); - - /* If for one reason or another, we can't copy more data, we're done! */ - if (c == 0) - break; - - sx_dprintk(SX_DEBUG_RECEIVE, "Copying over %d chars. First is " - "%d at %lx\n", c, read_sx_byte(port->board, - CHAN_OFFSET(port, hi_rxbuf) + rx_op), - CHAN_OFFSET(port, hi_rxbuf)); - memcpy_fromio(rp, port->board->base + - CHAN_OFFSET(port, hi_rxbuf) + rx_op, c); - - /* This one last. ( Not essential.) - It allows the card to start putting more data into the - buffer! - Update the pointer in the card */ - sx_write_channel_byte(port, hi_rxopos, (rx_op + c) & 0xff); - - copied += c; - } - if (copied) { - struct timeval tv; - - do_gettimeofday(&tv); - sx_dprintk(SX_DEBUG_RECEIVE, "pushing flipq port %d (%3d " - "chars): %d.%06d (%d/%d)\n", port->line, - copied, (int)(tv.tv_sec % 60), (int)tv.tv_usec, - tty->raw, tty->real_raw); - - /* Tell the rest of the system the news. Great news. New - characters! */ - tty_flip_buffer_push(tty); - /* tty_schedule_flip (tty); */ - } - - func_exit(); -} - -/* Inlined: it is called only once. Remove the inline if you add another - call */ -static inline void sx_check_modem_signals(struct sx_port *port) -{ - int hi_state; - int c_dcd; - - hi_state = sx_read_channel_byte(port, hi_state); - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Checking modem signals (%d/%d)\n", - port->c_dcd, tty_port_carrier_raised(&port->gs.port)); - - if (hi_state & ST_BREAK) { - hi_state &= ~ST_BREAK; - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a break.\n"); - sx_write_channel_byte(port, hi_state, hi_state); - gs_got_break(&port->gs); - } - if (hi_state & ST_DCD) { - hi_state &= ~ST_DCD; - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a DCD change.\n"); - sx_write_channel_byte(port, hi_state, hi_state); - c_dcd = tty_port_carrier_raised(&port->gs.port); - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD is now %d\n", c_dcd); - if (c_dcd != port->c_dcd) { - port->c_dcd = c_dcd; - if (tty_port_carrier_raised(&port->gs.port)) { - /* DCD went UP */ - if ((sx_read_channel_byte(port, hi_hstat) != - HS_IDLE_CLOSED) && - !(port->gs.port.tty->termios-> - c_cflag & CLOCAL)) { - /* Are we blocking in open? */ - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " - "active, unblocking open\n"); - wake_up_interruptible(&port->gs.port. - open_wait); - } else { - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " - "raised. Ignoring.\n"); - } - } else { - /* DCD went down! */ - if (!(port->gs.port.tty->termios->c_cflag & CLOCAL)){ - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " - "dropped. hanging up....\n"); - tty_hangup(port->gs.port.tty); - } else { - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " - "dropped. ignoring.\n"); - } - } - } else { - sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Hmmm. card told us " - "DCD changed, but it didn't.\n"); - } - } -} - -/* This is what an interrupt routine should look like. - * Small, elegant, clear. - */ - -static irqreturn_t sx_interrupt(int irq, void *ptr) -{ - struct sx_board *board = ptr; - struct sx_port *port; - int i; - - func_enter(); - sx_dprintk(SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d/%d)\n", irq, - board->irq); - - /* AAargh! The order in which to do these things is essential and - not trivial. - - - Rate limit goes before "recursive". Otherwise a series of - recursive calls will hang the machine in the interrupt routine. - - - hardware twiddling goes before "recursive". Otherwise when we - poll the card, and a recursive interrupt happens, we won't - ack the card, so it might keep on interrupting us. (especially - level sensitive interrupt systems like PCI). - - - Rate limit goes before hardware twiddling. Otherwise we won't - catch a card that has gone bonkers. - - - The "initialized" test goes after the hardware twiddling. Otherwise - the card will stick us in the interrupt routine again. - - - The initialized test goes before recursive. - */ - -#ifdef IRQ_RATE_LIMIT - /* Aaargh! I'm ashamed. This costs more lines-of-code than the - actual interrupt routine!. (Well, used to when I wrote that - comment) */ - { - static int lastjif; - static int nintr = 0; - - if (lastjif == jiffies) { - if (++nintr > IRQ_RATE_LIMIT) { - free_irq(board->irq, board); - printk(KERN_ERR "sx: Too many interrupts. " - "Turning off interrupt %d.\n", - board->irq); - } - } else { - lastjif = jiffies; - nintr = 0; - } - } -#endif - - if (board->irq == irq) { - /* Tell the card we've noticed the interrupt. */ - - sx_write_board_word(board, cc_int_pending, 0); - if (IS_SX_BOARD(board)) { - write_sx_byte(board, SX_RESET_IRQ, 1); - } else if (IS_EISA_BOARD(board)) { - inb(board->eisa_base + 0xc03); - write_sx_word(board, 8, 0); - } else { - write_sx_byte(board, SI2_ISA_INTCLEAR, - SI2_ISA_INTCLEAR_CLEAR); - write_sx_byte(board, SI2_ISA_INTCLEAR, - SI2_ISA_INTCLEAR_SET); - } - } - - if (!sx_initialized) - return IRQ_HANDLED; - if (!(board->flags & SX_BOARD_INITIALIZED)) - return IRQ_HANDLED; - - if (test_and_set_bit(SX_BOARD_INTR_LOCK, &board->locks)) { - printk(KERN_ERR "Recursive interrupt! (%d)\n", board->irq); - return IRQ_HANDLED; - } - - for (i = 0; i < board->nports; i++) { - port = &board->ports[i]; - if (port->gs.port.flags & GS_ACTIVE) { - if (sx_read_channel_byte(port, hi_state)) { - sx_dprintk(SX_DEBUG_INTERRUPTS, "Port %d: " - "modem signal change?... \n",i); - sx_check_modem_signals(port); - } - if (port->gs.xmit_cnt) { - sx_transmit_chars(port); - } - if (!(port->gs.port.flags & SX_RX_THROTTLE)) { - sx_receive_chars(port); - } - } - } - - clear_bit(SX_BOARD_INTR_LOCK, &board->locks); - - sx_dprintk(SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d/%d)\n", irq, - board->irq); - func_exit(); - return IRQ_HANDLED; -} - -static void sx_pollfunc(unsigned long data) -{ - struct sx_board *board = (struct sx_board *)data; - - func_enter(); - - sx_interrupt(0, board); - - mod_timer(&board->timer, jiffies + sx_poll); - func_exit(); -} - -/* ********************************************************************** * - * Here are the routines that actually * - * interface with the generic_serial driver * - * ********************************************************************** */ - -/* Ehhm. I don't know how to fiddle with interrupts on the SX card. --REW */ -/* Hmm. Ok I figured it out. You don't. */ - -static void sx_disable_tx_interrupts(void *ptr) -{ - struct sx_port *port = ptr; - func_enter2(); - - port->gs.port.flags &= ~GS_TX_INTEN; - - func_exit(); -} - -static void sx_enable_tx_interrupts(void *ptr) -{ - struct sx_port *port = ptr; - int data_in_buffer; - func_enter2(); - - /* First transmit the characters that we're supposed to */ - sx_transmit_chars(port); - - /* The sx card will never interrupt us if we don't fill the buffer - past 25%. So we keep considering interrupts off if that's the case. */ - data_in_buffer = (sx_read_channel_byte(port, hi_txipos) - - sx_read_channel_byte(port, hi_txopos)) & 0xff; - - /* XXX Must be "HIGH_WATER" for SI card according to doc. */ - if (data_in_buffer < LOW_WATER) - port->gs.port.flags &= ~GS_TX_INTEN; - - func_exit(); -} - -static void sx_disable_rx_interrupts(void *ptr) -{ - /* struct sx_port *port = ptr; */ - func_enter(); - - func_exit(); -} - -static void sx_enable_rx_interrupts(void *ptr) -{ - /* struct sx_port *port = ptr; */ - func_enter(); - - func_exit(); -} - -/* Jeez. Isn't this simple? */ -static int sx_carrier_raised(struct tty_port *port) -{ - struct sx_port *sp = container_of(port, struct sx_port, gs.port); - return ((sx_read_channel_byte(sp, hi_ip) & IP_DCD) != 0); -} - -/* Jeez. Isn't this simple? */ -static int sx_chars_in_buffer(void *ptr) -{ - struct sx_port *port = ptr; - func_enter2(); - - func_exit(); - return ((sx_read_channel_byte(port, hi_txipos) - - sx_read_channel_byte(port, hi_txopos)) & 0xff); -} - -static void sx_shutdown_port(void *ptr) -{ - struct sx_port *port = ptr; - - func_enter(); - - port->gs.port.flags &= ~GS_ACTIVE; - if (port->gs.port.tty && (port->gs.port.tty->termios->c_cflag & HUPCL)) { - sx_setsignals(port, 0, 0); - sx_reconfigure_port(port); - } - - func_exit(); -} - -/* ********************************************************************** * - * Here are the routines that actually * - * interface with the rest of the system * - * ********************************************************************** */ - -static int sx_open(struct tty_struct *tty, struct file *filp) -{ - struct sx_port *port; - int retval, line; - unsigned long flags; - - func_enter(); - - if (!sx_initialized) { - return -EIO; - } - - line = tty->index; - sx_dprintk(SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, " - "np=%d)\n", task_pid_nr(current), line, tty, - current->signal->tty, sx_nports); - - if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports)) - return -ENODEV; - - port = &sx_ports[line]; - port->c_dcd = 0; /* Make sure that the first interrupt doesn't detect a - 1 -> 0 transition. */ - - sx_dprintk(SX_DEBUG_OPEN, "port = %p c_dcd = %d\n", port, port->c_dcd); - - spin_lock_irqsave(&port->gs.driver_lock, flags); - - tty->driver_data = port; - port->gs.port.tty = tty; - port->gs.port.count++; - spin_unlock_irqrestore(&port->gs.driver_lock, flags); - - sx_dprintk(SX_DEBUG_OPEN, "starting port\n"); - - /* - * Start up serial port - */ - retval = gs_init_port(&port->gs); - sx_dprintk(SX_DEBUG_OPEN, "done gs_init\n"); - if (retval) { - port->gs.port.count--; - return retval; - } - - port->gs.port.flags |= GS_ACTIVE; - if (port->gs.port.count <= 1) - sx_setsignals(port, 1, 1); - -#if 0 - if (sx_debug & SX_DEBUG_OPEN) - my_hd(port, sizeof(*port)); -#else - if (sx_debug & SX_DEBUG_OPEN) - my_hd_io(port->board->base + port->ch_base, sizeof(*port)); -#endif - - if (port->gs.port.count <= 1) { - if (sx_send_command(port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) { - printk(KERN_ERR "sx: Card didn't respond to LOPEN " - "command.\n"); - spin_lock_irqsave(&port->gs.driver_lock, flags); - port->gs.port.count--; - spin_unlock_irqrestore(&port->gs.driver_lock, flags); - return -EIO; - } - } - - retval = gs_block_til_ready(port, filp); - sx_dprintk(SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", - retval, port->gs.port.count); - - if (retval) { -/* - * Don't lower gs.port.count here because sx_close() will be called later - */ - - return retval; - } - /* tty->low_latency = 1; */ - - port->c_dcd = sx_carrier_raised(&port->gs.port); - sx_dprintk(SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd); - - func_exit(); - return 0; - -} - -static void sx_close(void *ptr) -{ - struct sx_port *port = ptr; - /* Give the port 5 seconds to close down. */ - int to = 5 * HZ; - - func_enter(); - - sx_setsignals(port, 0, 0); - sx_reconfigure_port(port); - sx_send_command(port, HS_CLOSE, 0, 0); - - while (to-- && (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED)) - if (msleep_interruptible(10)) - break; - if (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED) { - if (sx_send_command(port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) - != 1) { - printk(KERN_ERR "sx: sent the force_close command, but " - "card didn't react\n"); - } else - sx_dprintk(SX_DEBUG_CLOSE, "sent the force_close " - "command.\n"); - } - - sx_dprintk(SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", - 5 * HZ - to - 1, port->gs.port.count); - - if (port->gs.port.count) { - sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", - port->gs.port.count); - /*printk("%s SETTING port count to zero: %p count: %d\n", - __func__, port, port->gs.port.count); - port->gs.port.count = 0;*/ - } - - func_exit(); -} - -/* This is relatively thorough. But then again it is only 20 lines. */ -#define MARCHUP for (i = min; i < max; i++) -#define MARCHDOWN for (i = max - 1; i >= min; i--) -#define W0 write_sx_byte(board, i, 0x55) -#define W1 write_sx_byte(board, i, 0xaa) -#define R0 if (read_sx_byte(board, i) != 0x55) return 1 -#define R1 if (read_sx_byte(board, i) != 0xaa) return 1 - -/* This memtest takes a human-noticeable time. You normally only do it - once a boot, so I guess that it is worth it. */ -static int do_memtest(struct sx_board *board, int min, int max) -{ - int i; - - /* This is a marchb. Theoretically, marchb catches much more than - simpler tests. In practise, the longer test just catches more - intermittent errors. -- REW - (For the theory behind memory testing see: - Testing Semiconductor Memories by A.J. van de Goor.) */ - MARCHUP { - W0; - } - MARCHUP { - R0; - W1; - R1; - W0; - R0; - W1; - } - MARCHUP { - R1; - W0; - W1; - } - MARCHDOWN { - R1; - W0; - W1; - W0; - } - MARCHDOWN { - R0; - W1; - W0; - } - - return 0; -} - -#undef MARCHUP -#undef MARCHDOWN -#undef W0 -#undef W1 -#undef R0 -#undef R1 - -#define MARCHUP for (i = min; i < max; i += 2) -#define MARCHDOWN for (i = max - 1; i >= min; i -= 2) -#define W0 write_sx_word(board, i, 0x55aa) -#define W1 write_sx_word(board, i, 0xaa55) -#define R0 if (read_sx_word(board, i) != 0x55aa) return 1 -#define R1 if (read_sx_word(board, i) != 0xaa55) return 1 - -#if 0 -/* This memtest takes a human-noticeable time. You normally only do it - once a boot, so I guess that it is worth it. */ -static int do_memtest_w(struct sx_board *board, int min, int max) -{ - int i; - - MARCHUP { - W0; - } - MARCHUP { - R0; - W1; - R1; - W0; - R0; - W1; - } - MARCHUP { - R1; - W0; - W1; - } - MARCHDOWN { - R1; - W0; - W1; - W0; - } - MARCHDOWN { - R0; - W1; - W0; - } - - return 0; -} -#endif - -static long sx_fw_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - long rc = 0; - int __user *descr = (int __user *)arg; - int i; - static struct sx_board *board = NULL; - int nbytes, offset; - unsigned long data; - char *tmp; - - func_enter(); - - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - - tty_lock(); - - sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg); - - if (!board) - board = &boards[0]; - if (board->flags & SX_BOARD_PRESENT) { - sx_dprintk(SX_DEBUG_FIRMWARE, "Board present! (%x)\n", - board->flags); - } else { - sx_dprintk(SX_DEBUG_FIRMWARE, "Board not present! (%x) all:", - board->flags); - for (i = 0; i < SX_NBOARDS; i++) - sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags); - sx_dprintk(SX_DEBUG_FIRMWARE, "\n"); - rc = -EIO; - goto out; - } - - switch (cmd) { - case SXIO_SET_BOARD: - sx_dprintk(SX_DEBUG_FIRMWARE, "set board to %ld\n", arg); - rc = -EIO; - if (arg >= SX_NBOARDS) - break; - sx_dprintk(SX_DEBUG_FIRMWARE, "not out of range\n"); - if (!(boards[arg].flags & SX_BOARD_PRESENT)) - break; - sx_dprintk(SX_DEBUG_FIRMWARE, ".. and present!\n"); - board = &boards[arg]; - rc = 0; - /* FIXME: And this does ... nothing?? */ - break; - case SXIO_GET_TYPE: - rc = -ENOENT; /* If we manage to miss one, return error. */ - if (IS_SX_BOARD(board)) - rc = SX_TYPE_SX; - if (IS_CF_BOARD(board)) - rc = SX_TYPE_CF; - if (IS_SI_BOARD(board)) - rc = SX_TYPE_SI; - if (IS_SI1_BOARD(board)) - rc = SX_TYPE_SI; - if (IS_EISA_BOARD(board)) - rc = SX_TYPE_SI; - sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %ld\n", rc); - break; - case SXIO_DO_RAMTEST: - if (sx_initialized) { /* Already initialized: better not ramtest the board. */ - rc = -EPERM; - break; - } - if (IS_SX_BOARD(board)) { - rc = do_memtest(board, 0, 0x7000); - if (!rc) - rc = do_memtest(board, 0, 0x7000); - /*if (!rc) rc = do_memtest_w (board, 0, 0x7000); */ - } else { - rc = do_memtest(board, 0, 0x7ff8); - /* if (!rc) rc = do_memtest_w (board, 0, 0x7ff8); */ - } - sx_dprintk(SX_DEBUG_FIRMWARE, - "returning memtest result= %ld\n", rc); - break; - case SXIO_DOWNLOAD: - if (sx_initialized) {/* Already initialized */ - rc = -EEXIST; - break; - } - if (!sx_reset(board)) { - rc = -EIO; - break; - } - sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); - - tmp = kmalloc(SX_CHUNK_SIZE, GFP_USER); - if (!tmp) { - rc = -ENOMEM; - break; - } - /* FIXME: check returns */ - get_user(nbytes, descr++); - get_user(offset, descr++); - get_user(data, descr++); - while (nbytes && data) { - for (i = 0; i < nbytes; i += SX_CHUNK_SIZE) { - if (copy_from_user(tmp, (char __user *)data + i, - (i + SX_CHUNK_SIZE > nbytes) ? - nbytes - i : SX_CHUNK_SIZE)) { - kfree(tmp); - rc = -EFAULT; - goto out; - } - memcpy_toio(board->base2 + offset + i, tmp, - (i + SX_CHUNK_SIZE > nbytes) ? - nbytes - i : SX_CHUNK_SIZE); - } - - get_user(nbytes, descr++); - get_user(offset, descr++); - get_user(data, descr++); - } - kfree(tmp); - sx_nports += sx_init_board(board); - rc = sx_nports; - break; - case SXIO_INIT: - if (sx_initialized) { /* Already initialized */ - rc = -EEXIST; - break; - } - /* This is not allowed until all boards are initialized... */ - for (i = 0; i < SX_NBOARDS; i++) { - if ((boards[i].flags & SX_BOARD_PRESENT) && - !(boards[i].flags & SX_BOARD_INITIALIZED)) { - rc = -EIO; - break; - } - } - for (i = 0; i < SX_NBOARDS; i++) - if (!(boards[i].flags & SX_BOARD_PRESENT)) - break; - - sx_dprintk(SX_DEBUG_FIRMWARE, "initing portstructs, %d boards, " - "%d channels, first board: %d ports\n", - i, sx_nports, boards[0].nports); - rc = sx_init_portstructs(i, sx_nports); - sx_init_drivers(); - if (rc >= 0) - sx_initialized++; - break; - case SXIO_SETDEBUG: - sx_debug = arg; - break; - case SXIO_GETDEBUG: - rc = sx_debug; - break; - case SXIO_GETGSDEBUG: - case SXIO_SETGSDEBUG: - rc = -EINVAL; - break; - case SXIO_GETNPORTS: - rc = sx_nports; - break; - default: - rc = -ENOTTY; - break; - } -out: - tty_unlock(); - func_exit(); - return rc; -} - -static int sx_break(struct tty_struct *tty, int flag) -{ - struct sx_port *port = tty->driver_data; - int rv; - - func_enter(); - tty_lock(); - - if (flag) - rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK); - else - rv = sx_send_command(port, HS_STOP, -1, HS_IDLE_OPEN); - if (rv != 1) - printk(KERN_ERR "sx: couldn't send break (%x).\n", - read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); - tty_unlock(); - func_exit(); - return 0; -} - -static int sx_tiocmget(struct tty_struct *tty) -{ - struct sx_port *port = tty->driver_data; - return sx_getsignals(port); -} - -static int sx_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct sx_port *port = tty->driver_data; - int rts = -1, dtr = -1; - - if (set & TIOCM_RTS) - rts = 1; - if (set & TIOCM_DTR) - dtr = 1; - if (clear & TIOCM_RTS) - rts = 0; - if (clear & TIOCM_DTR) - dtr = 0; - - sx_setsignals(port, dtr, rts); - sx_reconfigure_port(port); - return 0; -} - -static int sx_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - int rc; - struct sx_port *port = tty->driver_data; - void __user *argp = (void __user *)arg; - - /* func_enter2(); */ - - rc = 0; - tty_lock(); - switch (cmd) { - case TIOCGSERIAL: - rc = gs_getserial(&port->gs, argp); - break; - case TIOCSSERIAL: - rc = gs_setserial(&port->gs, argp); - break; - default: - rc = -ENOIOCTLCMD; - break; - } - tty_unlock(); - - /* func_exit(); */ - return rc; -} - -/* The throttle/unthrottle scheme for the Specialix card is different - * from other drivers and deserves some explanation. - * The Specialix hardware takes care of XON/XOFF - * and CTS/RTS flow control itself. This means that all we have to - * do when signalled by the upper tty layer to throttle/unthrottle is - * to make a note of it here. When we come to read characters from the - * rx buffers on the card (sx_receive_chars()) we look to see if the - * upper layer can accept more (as noted here in sx_rx_throt[]). - * If it can't we simply don't remove chars from the cards buffer. - * When the tty layer can accept chars, we again note that here and when - * sx_receive_chars() is called it will remove them from the cards buffer. - * The card will notice that a ports buffer has drained below some low - * water mark and will unflow control the line itself, using whatever - * flow control scheme is in use for that port. -- Simon Allen - */ - -static void sx_throttle(struct tty_struct *tty) -{ - struct sx_port *port = tty->driver_data; - - func_enter2(); - /* If the port is using any type of input flow - * control then throttle the port. - */ - if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) { - port->gs.port.flags |= SX_RX_THROTTLE; - } - func_exit(); -} - -static void sx_unthrottle(struct tty_struct *tty) -{ - struct sx_port *port = tty->driver_data; - - func_enter2(); - /* Always unthrottle even if flow control is not enabled on - * this port in case we disabled flow control while the port - * was throttled - */ - port->gs.port.flags &= ~SX_RX_THROTTLE; - func_exit(); - return; -} - -/* ********************************************************************** * - * Here are the initialization routines. * - * ********************************************************************** */ - -static int sx_init_board(struct sx_board *board) -{ - int addr; - int chans; - int type; - - func_enter(); - - /* This is preceded by downloading the download code. */ - - board->flags |= SX_BOARD_INITIALIZED; - - if (read_sx_byte(board, 0)) - /* CF boards may need this. */ - write_sx_byte(board, 0, 0); - - /* This resets the processor again, to make sure it didn't do any - foolish things while we were downloading the image */ - if (!sx_reset(board)) - return 0; - - sx_start_board(board); - udelay(10); - if (!sx_busy_wait_neq(board, 0, 0xff, 0)) { - printk(KERN_ERR "sx: Ooops. Board won't initialize.\n"); - return 0; - } - - /* Ok. So now the processor on the card is running. It gathered - some info for us... */ - sx_dprintk(SX_DEBUG_INIT, "The sxcard structure:\n"); - if (sx_debug & SX_DEBUG_INIT) - my_hd_io(board->base, 0x10); - sx_dprintk(SX_DEBUG_INIT, "the first sx_module structure:\n"); - if (sx_debug & SX_DEBUG_INIT) - my_hd_io(board->base + 0x80, 0x30); - - sx_dprintk(SX_DEBUG_INIT, "init_status: %x, %dk memory, firmware " - "V%x.%02x,\n", - read_sx_byte(board, 0), read_sx_byte(board, 1), - read_sx_byte(board, 5), read_sx_byte(board, 4)); - - if (read_sx_byte(board, 0) == 0xff) { - printk(KERN_INFO "sx: No modules found. Sorry.\n"); - board->nports = 0; - return 0; - } - - chans = 0; - - if (IS_SX_BOARD(board)) { - sx_write_board_word(board, cc_int_count, sx_maxints); - } else { - if (sx_maxints) - sx_write_board_word(board, cc_int_count, - SI_PROCESSOR_CLOCK / 8 / sx_maxints); - } - - /* grab the first module type... */ - /* board->ta_type = mod_compat_type (read_sx_byte (board, 0x80 + 0x08)); */ - board->ta_type = mod_compat_type(sx_read_module_byte(board, 0x80, - mc_chip)); - - /* XXX byteorder */ - for (addr = 0x80; addr != 0; addr = read_sx_word(board, addr) & 0x7fff){ - type = sx_read_module_byte(board, addr, mc_chip); - sx_dprintk(SX_DEBUG_INIT, "Module at %x: %d channels\n", - addr, read_sx_byte(board, addr + 2)); - - chans += sx_read_module_byte(board, addr, mc_type); - - sx_dprintk(SX_DEBUG_INIT, "module is an %s, which has %s/%s " - "panels\n", - mod_type_s(type), - pan_type_s(sx_read_module_byte(board, addr, - mc_mods) & 0xf), - pan_type_s(sx_read_module_byte(board, addr, - mc_mods) >> 4)); - - sx_dprintk(SX_DEBUG_INIT, "CD1400 versions: %x/%x, ASIC " - "version: %x\n", - sx_read_module_byte(board, addr, mc_rev1), - sx_read_module_byte(board, addr, mc_rev2), - sx_read_module_byte(board, addr, mc_mtaasic_rev)); - - /* The following combinations are illegal: It should theoretically - work, but timing problems make the bus HANG. */ - - if (mod_compat_type(type) != board->ta_type) { - printk(KERN_ERR "sx: This is an invalid " - "configuration.\nDon't mix TA/MTA/SXDC on the " - "same hostadapter.\n"); - chans = 0; - break; - } - if ((IS_EISA_BOARD(board) || - IS_SI_BOARD(board)) && - (mod_compat_type(type) == 4)) { - printk(KERN_ERR "sx: This is an invalid " - "configuration.\nDon't use SXDCs on an SI/XIO " - "adapter.\n"); - chans = 0; - break; - } -#if 0 /* Problem fixed: firmware 3.05 */ - if (IS_SX_BOARD(board) && (type == TA8)) { - /* There are some issues with the firmware and the DCD/RTS - lines. It might work if you tie them together or something. - It might also work if you get a newer sx_firmware. Therefore - this is just a warning. */ - printk(KERN_WARNING - "sx: The SX host doesn't work too well " - "with the TA8 adapters.\nSpecialix is working on it.\n"); - } -#endif - } - - if (chans) { - if (board->irq > 0) { - /* fixed irq, probably PCI */ - if (sx_irqmask & (1 << board->irq)) { /* may we use this irq? */ - if (request_irq(board->irq, sx_interrupt, - IRQF_SHARED | IRQF_DISABLED, - "sx", board)) { - printk(KERN_ERR "sx: Cannot allocate " - "irq %d.\n", board->irq); - board->irq = 0; - } - } else - board->irq = 0; - } else if (board->irq < 0 && sx_irqmask) { - /* auto-allocate irq */ - int irqnr; - int irqmask = sx_irqmask & (IS_SX_BOARD(board) ? - SX_ISA_IRQ_MASK : SI2_ISA_IRQ_MASK); - for (irqnr = 15; irqnr > 0; irqnr--) - if (irqmask & (1 << irqnr)) - if (!request_irq(irqnr, sx_interrupt, - IRQF_SHARED | IRQF_DISABLED, - "sx", board)) - break; - if (!irqnr) - printk(KERN_ERR "sx: Cannot allocate IRQ.\n"); - board->irq = irqnr; - } else - board->irq = 0; - - if (board->irq) { - /* Found a valid interrupt, start up interrupts! */ - sx_dprintk(SX_DEBUG_INIT, "Using irq %d.\n", - board->irq); - sx_start_interrupts(board); - board->poll = sx_slowpoll; - board->flags |= SX_IRQ_ALLOCATED; - } else { - /* no irq: setup board for polled operation */ - board->poll = sx_poll; - sx_dprintk(SX_DEBUG_INIT, "Using poll-interval %d.\n", - board->poll); - } - - /* The timer should be initialized anyway: That way we can - safely del_timer it when the module is unloaded. */ - setup_timer(&board->timer, sx_pollfunc, (unsigned long)board); - - if (board->poll) - mod_timer(&board->timer, jiffies + board->poll); - } else { - board->irq = 0; - } - - board->nports = chans; - sx_dprintk(SX_DEBUG_INIT, "returning %d ports.", board->nports); - - func_exit(); - return chans; -} - -static void __devinit printheader(void) -{ - static int header_printed; - - if (!header_printed) { - printk(KERN_INFO "Specialix SX driver " - "(C) 1998/1999 R.E.Wolff@BitWizard.nl\n"); - printk(KERN_INFO "sx: version " __stringify(SX_VERSION) "\n"); - header_printed = 1; - } -} - -static int __devinit probe_sx(struct sx_board *board) -{ - struct vpd_prom vpdp; - char *p; - int i; - - func_enter(); - - if (!IS_CF_BOARD(board)) { - sx_dprintk(SX_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", - board->base + SX_VPD_ROM); - - if (sx_debug & SX_DEBUG_PROBE) - my_hd_io(board->base + SX_VPD_ROM, 0x40); - - p = (char *)&vpdp; - for (i = 0; i < sizeof(struct vpd_prom); i++) - *p++ = read_sx_byte(board, SX_VPD_ROM + i * 2); - - if (sx_debug & SX_DEBUG_PROBE) - my_hd(&vpdp, 0x20); - - sx_dprintk(SX_DEBUG_PROBE, "checking identifier...\n"); - - if (strncmp(vpdp.identifier, SX_VPD_IDENT_STRING, 16) != 0) { - sx_dprintk(SX_DEBUG_PROBE, "Got non-SX identifier: " - "'%s'\n", vpdp.identifier); - return 0; - } - } - - printheader(); - - if (!IS_CF_BOARD(board)) { - printk(KERN_DEBUG "sx: Found an SX board at %lx\n", - board->hw_base); - printk(KERN_DEBUG "sx: hw_rev: %d, assembly level: %d, " - "uniq ID:%08x, ", - vpdp.hwrev, vpdp.hwass, vpdp.uniqid); - printk("Manufactured: %d/%d\n", 1970 + vpdp.myear, vpdp.mweek); - - if ((((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) != - SX_PCI_UNIQUEID1) && (((vpdp.uniqid >> 24) & - SX_UNIQUEID_MASK) != SX_ISA_UNIQUEID1)) { - /* This might be a bit harsh. This was the primary - reason the SX/ISA card didn't work at first... */ - printk(KERN_ERR "sx: Hmm. Not an SX/PCI or SX/ISA " - "card. Sorry: giving up.\n"); - return (0); - } - - if (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) == - SX_ISA_UNIQUEID1) { - if (((unsigned long)board->hw_base) & 0x8000) { - printk(KERN_WARNING "sx: Warning: There may be " - "hardware problems with the card at " - "%lx.\n", board->hw_base); - printk(KERN_WARNING "sx: Read sx.txt for more " - "info.\n"); - } - } - } - - board->nports = -1; - - /* This resets the processor, and keeps it off the bus. */ - if (!sx_reset(board)) - return 0; - sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); - - func_exit(); - return 1; -} - -#if defined(CONFIG_ISA) || defined(CONFIG_EISA) - -/* Specialix probes for this card at 32k increments from 640k to 16M. - I consider machines with less than 16M unlikely nowadays, so I'm - not probing above 1Mb. Also, 0xa0000, 0xb0000, are taken by the VGA - card. 0xe0000 and 0xf0000 are taken by the BIOS. That only leaves - 0xc0000, 0xc8000, 0xd0000 and 0xd8000 . */ - -static int __devinit probe_si(struct sx_board *board) -{ - int i; - - func_enter(); - sx_dprintk(SX_DEBUG_PROBE, "Going to verify SI signature hw %lx at " - "%p.\n", board->hw_base, board->base + SI2_ISA_ID_BASE); - - if (sx_debug & SX_DEBUG_PROBE) - my_hd_io(board->base + SI2_ISA_ID_BASE, 0x8); - - if (!IS_EISA_BOARD(board)) { - if (IS_SI1_BOARD(board)) { - for (i = 0; i < 8; i++) { - write_sx_byte(board, SI2_ISA_ID_BASE + 7 - i,i); - } - } - for (i = 0; i < 8; i++) { - if ((read_sx_byte(board, SI2_ISA_ID_BASE + 7 - i) & 7) - != i) { - func_exit(); - return 0; - } - } - } - - /* Now we're pretty much convinced that there is an SI board here, - but to prevent trouble, we'd better double check that we don't - have an SI1 board when we're probing for an SI2 board.... */ - - write_sx_byte(board, SI2_ISA_ID_BASE, 0x10); - if (IS_SI1_BOARD(board)) { - /* This should be an SI1 board, which has this - location writable... */ - if (read_sx_byte(board, SI2_ISA_ID_BASE) != 0x10) { - func_exit(); - return 0; - } - } else { - /* This should be an SI2 board, which has the bottom - 3 bits non-writable... */ - if (read_sx_byte(board, SI2_ISA_ID_BASE) == 0x10) { - func_exit(); - return 0; - } - } - - /* Now we're pretty much convinced that there is an SI board here, - but to prevent trouble, we'd better double check that we don't - have an SI1 board when we're probing for an SI2 board.... */ - - write_sx_byte(board, SI2_ISA_ID_BASE, 0x10); - if (IS_SI1_BOARD(board)) { - /* This should be an SI1 board, which has this - location writable... */ - if (read_sx_byte(board, SI2_ISA_ID_BASE) != 0x10) { - func_exit(); - return 0; - } - } else { - /* This should be an SI2 board, which has the bottom - 3 bits non-writable... */ - if (read_sx_byte(board, SI2_ISA_ID_BASE) == 0x10) { - func_exit(); - return 0; - } - } - - printheader(); - - printk(KERN_DEBUG "sx: Found an SI board at %lx\n", board->hw_base); - /* Compared to the SX boards, it is a complete guess as to what - this card is up to... */ - - board->nports = -1; - - /* This resets the processor, and keeps it off the bus. */ - if (!sx_reset(board)) - return 0; - sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); - - func_exit(); - return 1; -} -#endif - -static const struct tty_operations sx_ops = { - .break_ctl = sx_break, - .open = sx_open, - .close = gs_close, - .write = gs_write, - .put_char = gs_put_char, - .flush_chars = gs_flush_chars, - .write_room = gs_write_room, - .chars_in_buffer = gs_chars_in_buffer, - .flush_buffer = gs_flush_buffer, - .ioctl = sx_ioctl, - .throttle = sx_throttle, - .unthrottle = sx_unthrottle, - .set_termios = gs_set_termios, - .stop = gs_stop, - .start = gs_start, - .hangup = gs_hangup, - .tiocmget = sx_tiocmget, - .tiocmset = sx_tiocmset, -}; - -static const struct tty_port_operations sx_port_ops = { - .carrier_raised = sx_carrier_raised, -}; - -static int sx_init_drivers(void) -{ - int error; - - func_enter(); - - sx_driver = alloc_tty_driver(sx_nports); - if (!sx_driver) - return 1; - sx_driver->owner = THIS_MODULE; - sx_driver->driver_name = "specialix_sx"; - sx_driver->name = "ttyX"; - sx_driver->major = SX_NORMAL_MAJOR; - sx_driver->type = TTY_DRIVER_TYPE_SERIAL; - sx_driver->subtype = SERIAL_TYPE_NORMAL; - sx_driver->init_termios = tty_std_termios; - sx_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - sx_driver->init_termios.c_ispeed = 9600; - sx_driver->init_termios.c_ospeed = 9600; - sx_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(sx_driver, &sx_ops); - - if ((error = tty_register_driver(sx_driver))) { - put_tty_driver(sx_driver); - printk(KERN_ERR "sx: Couldn't register sx driver, error = %d\n", - error); - return 1; - } - func_exit(); - return 0; -} - -static int sx_init_portstructs(int nboards, int nports) -{ - struct sx_board *board; - struct sx_port *port; - int i, j; - int addr, chans; - int portno; - - func_enter(); - - /* Many drivers statically allocate the maximum number of ports - There is no reason not to allocate them dynamically. - Is there? -- REW */ - sx_ports = kcalloc(nports, sizeof(struct sx_port), GFP_KERNEL); - if (!sx_ports) - return -ENOMEM; - - port = sx_ports; - for (i = 0; i < nboards; i++) { - board = &boards[i]; - board->ports = port; - for (j = 0; j < boards[i].nports; j++) { - sx_dprintk(SX_DEBUG_INIT, "initing port %d\n", j); - tty_port_init(&port->gs.port); - port->gs.port.ops = &sx_port_ops; - port->gs.magic = SX_MAGIC; - port->gs.close_delay = HZ / 2; - port->gs.closing_wait = 30 * HZ; - port->board = board; - port->gs.rd = &sx_real_driver; -#ifdef NEW_WRITE_LOCKING - port->gs.port_write_mutex = MUTEX; -#endif - spin_lock_init(&port->gs.driver_lock); - /* - * Initializing wait queue - */ - port++; - } - } - - port = sx_ports; - portno = 0; - for (i = 0; i < nboards; i++) { - board = &boards[i]; - board->port_base = portno; - /* Possibly the configuration was rejected. */ - sx_dprintk(SX_DEBUG_PROBE, "Board has %d channels\n", - board->nports); - if (board->nports <= 0) - continue; - /* XXX byteorder ?? */ - for (addr = 0x80; addr != 0; - addr = read_sx_word(board, addr) & 0x7fff) { - chans = sx_read_module_byte(board, addr, mc_type); - sx_dprintk(SX_DEBUG_PROBE, "Module at %x: %d " - "channels\n", addr, chans); - sx_dprintk(SX_DEBUG_PROBE, "Port at"); - for (j = 0; j < chans; j++) { - /* The "sx-way" is the way it SHOULD be done. - That way in the future, the firmware may for - example pack the structures a bit more - efficient. Neil tells me it isn't going to - happen anytime soon though. */ - if (IS_SX_BOARD(board)) - port->ch_base = sx_read_module_word( - board, addr + j * 2, - mc_chan_pointer); - else - port->ch_base = addr + 0x100 + 0x300 *j; - - sx_dprintk(SX_DEBUG_PROBE, " %x", - port->ch_base); - port->line = portno++; - port++; - } - sx_dprintk(SX_DEBUG_PROBE, "\n"); - } - /* This has to be done earlier. */ - /* board->flags |= SX_BOARD_INITIALIZED; */ - } - - func_exit(); - return 0; -} - -static unsigned int sx_find_free_board(void) -{ - unsigned int i; - - for (i = 0; i < SX_NBOARDS; i++) - if (!(boards[i].flags & SX_BOARD_PRESENT)) - break; - - return i; -} - -static void __exit sx_release_drivers(void) -{ - func_enter(); - tty_unregister_driver(sx_driver); - put_tty_driver(sx_driver); - func_exit(); -} - -static void __devexit sx_remove_card(struct sx_board *board, - struct pci_dev *pdev) -{ - if (board->flags & SX_BOARD_INITIALIZED) { - /* The board should stop messing with us. (actually I mean the - interrupt) */ - sx_reset(board); - if ((board->irq) && (board->flags & SX_IRQ_ALLOCATED)) - free_irq(board->irq, board); - - /* It is safe/allowed to del_timer a non-active timer */ - del_timer(&board->timer); - if (pdev) { -#ifdef CONFIG_PCI - iounmap(board->base2); - pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); -#endif - } else { - iounmap(board->base); - release_region(board->hw_base, board->hw_len); - } - - board->flags &= ~(SX_BOARD_INITIALIZED | SX_BOARD_PRESENT); - } -} - -#ifdef CONFIG_EISA - -static int __devinit sx_eisa_probe(struct device *dev) -{ - struct eisa_device *edev = to_eisa_device(dev); - struct sx_board *board; - unsigned long eisa_slot = edev->base_addr; - unsigned int i; - int retval = -EIO; - - mutex_lock(&sx_boards_lock); - i = sx_find_free_board(); - if (i == SX_NBOARDS) { - mutex_unlock(&sx_boards_lock); - goto err; - } - board = &boards[i]; - board->flags |= SX_BOARD_PRESENT; - mutex_unlock(&sx_boards_lock); - - dev_info(dev, "XIO : Signature found in EISA slot %lu, " - "Product %d Rev %d (REPORT THIS TO LKLM)\n", - eisa_slot >> 12, - inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 2), - inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 3)); - - board->eisa_base = eisa_slot; - board->flags &= ~SX_BOARD_TYPE; - board->flags |= SI_EISA_BOARD; - - board->hw_base = ((inb(eisa_slot + 0xc01) << 8) + - inb(eisa_slot + 0xc00)) << 16; - board->hw_len = SI2_EISA_WINDOW_LEN; - if (!request_region(board->hw_base, board->hw_len, "sx")) { - dev_err(dev, "can't request region\n"); - goto err_flag; - } - board->base2 = - board->base = ioremap_nocache(board->hw_base, SI2_EISA_WINDOW_LEN); - if (!board->base) { - dev_err(dev, "can't remap memory\n"); - goto err_reg; - } - - sx_dprintk(SX_DEBUG_PROBE, "IO hw_base address: %lx\n", board->hw_base); - sx_dprintk(SX_DEBUG_PROBE, "base: %p\n", board->base); - board->irq = inb(eisa_slot + 0xc02) >> 4; - sx_dprintk(SX_DEBUG_PROBE, "IRQ: %d\n", board->irq); - - if (!probe_si(board)) - goto err_unmap; - - dev_set_drvdata(dev, board); - - return 0; -err_unmap: - iounmap(board->base); -err_reg: - release_region(board->hw_base, board->hw_len); -err_flag: - board->flags &= ~SX_BOARD_PRESENT; -err: - return retval; -} - -static int __devexit sx_eisa_remove(struct device *dev) -{ - struct sx_board *board = dev_get_drvdata(dev); - - sx_remove_card(board, NULL); - - return 0; -} - -static struct eisa_device_id sx_eisa_tbl[] = { - { "SLX" }, - { "" } -}; - -MODULE_DEVICE_TABLE(eisa, sx_eisa_tbl); - -static struct eisa_driver sx_eisadriver = { - .id_table = sx_eisa_tbl, - .driver = { - .name = "sx", - .probe = sx_eisa_probe, - .remove = __devexit_p(sx_eisa_remove), - } -}; - -#endif - -#ifdef CONFIG_PCI - /******************************************************** - * Setting bit 17 in the CNTRL register of the PLX 9050 * - * chip forces a retry on writes while a read is pending.* - * This is to prevent the card locking up on Intel Xeon * - * multiprocessor systems with the NX chipset. -- NV * - ********************************************************/ - -/* Newer cards are produced with this bit set from the configuration - EEprom. As the bit is read/write for the CPU, we can fix it here, - if we detect that it isn't set correctly. -- REW */ - -static void __devinit fix_sx_pci(struct pci_dev *pdev, struct sx_board *board) -{ - unsigned int hwbase; - void __iomem *rebase; - unsigned int t; - -#define CNTRL_REG_OFFSET 0x50 -#define CNTRL_REG_GOODVALUE 0x18260000 - - pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase); - hwbase &= PCI_BASE_ADDRESS_MEM_MASK; - rebase = ioremap_nocache(hwbase, 0x80); - t = readl(rebase + CNTRL_REG_OFFSET); - if (t != CNTRL_REG_GOODVALUE) { - printk(KERN_DEBUG "sx: performing cntrl reg fix: %08x -> " - "%08x\n", t, CNTRL_REG_GOODVALUE); - writel(CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); - } - iounmap(rebase); -} -#endif - -static int __devinit sx_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ -#ifdef CONFIG_PCI - struct sx_board *board; - unsigned int i, reg; - int retval = -EIO; - - mutex_lock(&sx_boards_lock); - i = sx_find_free_board(); - if (i == SX_NBOARDS) { - mutex_unlock(&sx_boards_lock); - goto err; - } - board = &boards[i]; - board->flags |= SX_BOARD_PRESENT; - mutex_unlock(&sx_boards_lock); - - retval = pci_enable_device(pdev); - if (retval) - goto err_flag; - - board->flags &= ~SX_BOARD_TYPE; - board->flags |= (pdev->subsystem_vendor == 0x200) ? SX_PCI_BOARD : - SX_CFPCI_BOARD; - - /* CF boards use base address 3.... */ - reg = IS_CF_BOARD(board) ? 3 : 2; - retval = pci_request_region(pdev, reg, "sx"); - if (retval) { - dev_err(&pdev->dev, "can't request region\n"); - goto err_flag; - } - board->hw_base = pci_resource_start(pdev, reg); - board->base2 = - board->base = ioremap_nocache(board->hw_base, WINDOW_LEN(board)); - if (!board->base) { - dev_err(&pdev->dev, "ioremap failed\n"); - goto err_reg; - } - - /* Most of the stuff on the CF board is offset by 0x18000 .... */ - if (IS_CF_BOARD(board)) - board->base += 0x18000; - - board->irq = pdev->irq; - - dev_info(&pdev->dev, "Got a specialix card: %p(%d) %x.\n", board->base, - board->irq, board->flags); - - if (!probe_sx(board)) { - retval = -EIO; - goto err_unmap; - } - - fix_sx_pci(pdev, board); - - pci_set_drvdata(pdev, board); - - return 0; -err_unmap: - iounmap(board->base2); -err_reg: - pci_release_region(pdev, reg); -err_flag: - board->flags &= ~SX_BOARD_PRESENT; -err: - return retval; -#else - return -ENODEV; -#endif -} - -static void __devexit sx_pci_remove(struct pci_dev *pdev) -{ - struct sx_board *board = pci_get_drvdata(pdev); - - sx_remove_card(board, pdev); -} - -/* Specialix has a whole bunch of cards with 0x2000 as the device ID. They say - its because the standard requires it. So check for SUBVENDOR_ID. */ -static struct pci_device_id sx_pci_tbl[] = { - { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, - .subvendor = PCI_ANY_ID, .subdevice = 0x0200 }, - { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, - .subvendor = PCI_ANY_ID, .subdevice = 0x0300 }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, sx_pci_tbl); - -static struct pci_driver sx_pcidriver = { - .name = "sx", - .id_table = sx_pci_tbl, - .probe = sx_pci_probe, - .remove = __devexit_p(sx_pci_remove) -}; - -static int __init sx_init(void) -{ -#ifdef CONFIG_EISA - int retval1; -#endif -#ifdef CONFIG_ISA - struct sx_board *board; - unsigned int i; -#endif - unsigned int found = 0; - int retval; - - func_enter(); - sx_dprintk(SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", - sx_debug); - if (abs((long)(&sx_debug) - sx_debug) < 0x10000) { - printk(KERN_WARNING "sx: sx_debug is an address, instead of a " - "value. Assuming -1.\n(%p)\n", &sx_debug); - sx_debug = -1; - } - - if (misc_register(&sx_fw_device) < 0) { - printk(KERN_ERR "SX: Unable to register firmware loader " - "driver.\n"); - return -EIO; - } -#ifdef CONFIG_ISA - for (i = 0; i < NR_SX_ADDRS; i++) { - board = &boards[found]; - board->hw_base = sx_probe_addrs[i]; - board->hw_len = SX_WINDOW_LEN; - if (!request_region(board->hw_base, board->hw_len, "sx")) - continue; - board->base2 = - board->base = ioremap_nocache(board->hw_base, board->hw_len); - if (!board->base) - goto err_sx_reg; - board->flags &= ~SX_BOARD_TYPE; - board->flags |= SX_ISA_BOARD; - board->irq = sx_irqmask ? -1 : 0; - - if (probe_sx(board)) { - board->flags |= SX_BOARD_PRESENT; - found++; - } else { - iounmap(board->base); -err_sx_reg: - release_region(board->hw_base, board->hw_len); - } - } - - for (i = 0; i < NR_SI_ADDRS; i++) { - board = &boards[found]; - board->hw_base = si_probe_addrs[i]; - board->hw_len = SI2_ISA_WINDOW_LEN; - if (!request_region(board->hw_base, board->hw_len, "sx")) - continue; - board->base2 = - board->base = ioremap_nocache(board->hw_base, board->hw_len); - if (!board->base) - goto err_si_reg; - board->flags &= ~SX_BOARD_TYPE; - board->flags |= SI_ISA_BOARD; - board->irq = sx_irqmask ? -1 : 0; - - if (probe_si(board)) { - board->flags |= SX_BOARD_PRESENT; - found++; - } else { - iounmap(board->base); -err_si_reg: - release_region(board->hw_base, board->hw_len); - } - } - for (i = 0; i < NR_SI1_ADDRS; i++) { - board = &boards[found]; - board->hw_base = si1_probe_addrs[i]; - board->hw_len = SI1_ISA_WINDOW_LEN; - if (!request_region(board->hw_base, board->hw_len, "sx")) - continue; - board->base2 = - board->base = ioremap_nocache(board->hw_base, board->hw_len); - if (!board->base) - goto err_si1_reg; - board->flags &= ~SX_BOARD_TYPE; - board->flags |= SI1_ISA_BOARD; - board->irq = sx_irqmask ? -1 : 0; - - if (probe_si(board)) { - board->flags |= SX_BOARD_PRESENT; - found++; - } else { - iounmap(board->base); -err_si1_reg: - release_region(board->hw_base, board->hw_len); - } - } -#endif -#ifdef CONFIG_EISA - retval1 = eisa_driver_register(&sx_eisadriver); -#endif - retval = pci_register_driver(&sx_pcidriver); - - if (found) { - printk(KERN_INFO "sx: total of %d boards detected.\n", found); - retval = 0; - } else if (retval) { -#ifdef CONFIG_EISA - retval = retval1; - if (retval1) -#endif - misc_deregister(&sx_fw_device); - } - - func_exit(); - return retval; -} - -static void __exit sx_exit(void) -{ - int i; - - func_enter(); -#ifdef CONFIG_EISA - eisa_driver_unregister(&sx_eisadriver); -#endif - pci_unregister_driver(&sx_pcidriver); - - for (i = 0; i < SX_NBOARDS; i++) - sx_remove_card(&boards[i], NULL); - - if (misc_deregister(&sx_fw_device) < 0) { - printk(KERN_INFO "sx: couldn't deregister firmware loader " - "device\n"); - } - sx_dprintk(SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", - sx_initialized); - if (sx_initialized) - sx_release_drivers(); - - kfree(sx_ports); - func_exit(); -} - -module_init(sx_init); -module_exit(sx_exit); diff --git a/drivers/staging/generic_serial/sx.h b/drivers/staging/generic_serial/sx.h deleted file mode 100644 index 87c2defdead7..000000000000 --- a/drivers/staging/generic_serial/sx.h +++ /dev/null @@ -1,201 +0,0 @@ - -/* - * sx.h - * - * Copyright (C) 1998/1999 R.E.Wolff@BitWizard.nl - * - * SX serial driver. - * -- Supports SI, XIO and SX host cards. - * -- Supports TAs, MTAs and SXDCs. - * - * Version 1.3 -- March, 1999. - * - */ - -#define SX_NBOARDS 4 -#define SX_PORTSPERBOARD 32 -#define SX_NPORTS (SX_NBOARDS * SX_PORTSPERBOARD) - -#ifdef __KERNEL__ - -#define SX_MAGIC 0x12345678 - -struct sx_port { - struct gs_port gs; - struct wait_queue *shutdown_wait; - int ch_base; - int c_dcd; - struct sx_board *board; - int line; - unsigned long locks; -}; - -struct sx_board { - int magic; - void __iomem *base; - void __iomem *base2; - unsigned long hw_base; - resource_size_t hw_len; - int eisa_base; - int port_base; /* Number of the first port */ - struct sx_port *ports; - int nports; - int flags; - int irq; - int poll; - int ta_type; - struct timer_list timer; - unsigned long locks; -}; - -struct vpd_prom { - unsigned short id; - char hwrev; - char hwass; - int uniqid; - char myear; - char mweek; - char hw_feature[5]; - char oem_id; - char identifier[16]; -}; - -#ifndef MOD_RS232DB25MALE -#define MOD_RS232DB25MALE 0x0a -#endif - -#define SI_ISA_BOARD 0x00000001 -#define SX_ISA_BOARD 0x00000002 -#define SX_PCI_BOARD 0x00000004 -#define SX_CFPCI_BOARD 0x00000008 -#define SX_CFISA_BOARD 0x00000010 -#define SI_EISA_BOARD 0x00000020 -#define SI1_ISA_BOARD 0x00000040 - -#define SX_BOARD_PRESENT 0x00001000 -#define SX_BOARD_INITIALIZED 0x00002000 -#define SX_IRQ_ALLOCATED 0x00004000 - -#define SX_BOARD_TYPE 0x000000ff - -#define IS_SX_BOARD(board) (board->flags & (SX_PCI_BOARD | SX_CFPCI_BOARD | \ - SX_ISA_BOARD | SX_CFISA_BOARD)) - -#define IS_SI_BOARD(board) (board->flags & SI_ISA_BOARD) -#define IS_SI1_BOARD(board) (board->flags & SI1_ISA_BOARD) - -#define IS_EISA_BOARD(board) (board->flags & SI_EISA_BOARD) - -#define IS_CF_BOARD(board) (board->flags & (SX_CFISA_BOARD | SX_CFPCI_BOARD)) - -/* The SI processor clock is required to calculate the cc_int_count register - value for the SI cards. */ -#define SI_PROCESSOR_CLOCK 25000000 - - -/* port flags */ -/* Make sure these don't clash with gs flags or async flags */ -#define SX_RX_THROTTLE 0x0000001 - - - -#define SX_PORT_TRANSMIT_LOCK 0 -#define SX_BOARD_INTR_LOCK 0 - - - -/* Debug flags. Add these together to get more debug info. */ - -#define SX_DEBUG_OPEN 0x00000001 -#define SX_DEBUG_SETTING 0x00000002 -#define SX_DEBUG_FLOW 0x00000004 -#define SX_DEBUG_MODEMSIGNALS 0x00000008 -#define SX_DEBUG_TERMIOS 0x00000010 -#define SX_DEBUG_TRANSMIT 0x00000020 -#define SX_DEBUG_RECEIVE 0x00000040 -#define SX_DEBUG_INTERRUPTS 0x00000080 -#define SX_DEBUG_PROBE 0x00000100 -#define SX_DEBUG_INIT 0x00000200 -#define SX_DEBUG_CLEANUP 0x00000400 -#define SX_DEBUG_CLOSE 0x00000800 -#define SX_DEBUG_FIRMWARE 0x00001000 -#define SX_DEBUG_MEMTEST 0x00002000 - -#define SX_DEBUG_ALL 0xffffffff - - -#define O_OTHER(tty) \ - ((O_OLCUC(tty)) ||\ - (O_ONLCR(tty)) ||\ - (O_OCRNL(tty)) ||\ - (O_ONOCR(tty)) ||\ - (O_ONLRET(tty)) ||\ - (O_OFILL(tty)) ||\ - (O_OFDEL(tty)) ||\ - (O_NLDLY(tty)) ||\ - (O_CRDLY(tty)) ||\ - (O_TABDLY(tty)) ||\ - (O_BSDLY(tty)) ||\ - (O_VTDLY(tty)) ||\ - (O_FFDLY(tty))) - -/* Same for input. */ -#define I_OTHER(tty) \ - ((I_INLCR(tty)) ||\ - (I_IGNCR(tty)) ||\ - (I_ICRNL(tty)) ||\ - (I_IUCLC(tty)) ||\ - (L_ISIG(tty))) - -#define MOD_TA ( TA>>4) -#define MOD_MTA (MTA_CD1400>>4) -#define MOD_SXDC ( SXDC>>4) - - -/* We copy the download code over to the card in chunks of ... bytes */ -#define SX_CHUNK_SIZE 128 - -#endif /* __KERNEL__ */ - - - -/* Specialix document 6210046-11 page 3 */ -#define SPX(X) (('S'<<24) | ('P' << 16) | (X)) - -/* Specialix-Linux specific IOCTLS. */ -#define SPXL(X) (SPX(('L' << 8) | (X))) - - -#define SXIO_SET_BOARD SPXL(0x01) -#define SXIO_GET_TYPE SPXL(0x02) -#define SXIO_DOWNLOAD SPXL(0x03) -#define SXIO_INIT SPXL(0x04) -#define SXIO_SETDEBUG SPXL(0x05) -#define SXIO_GETDEBUG SPXL(0x06) -#define SXIO_DO_RAMTEST SPXL(0x07) -#define SXIO_SETGSDEBUG SPXL(0x08) -#define SXIO_GETGSDEBUG SPXL(0x09) -#define SXIO_GETNPORTS SPXL(0x0a) - - -#ifndef SXCTL_MISC_MINOR -/* Allow others to gather this into "major.h" or something like that */ -#define SXCTL_MISC_MINOR 167 -#endif - -#ifndef SX_NORMAL_MAJOR -/* This allows overriding on the compiler commandline, or in a "major.h" - include or something like that */ -#define SX_NORMAL_MAJOR 32 -#define SX_CALLOUT_MAJOR 33 -#endif - - -#define SX_TYPE_SX 0x01 -#define SX_TYPE_SI 0x02 -#define SX_TYPE_CF 0x03 - - -#define WINDOW_LEN(board) (IS_CF_BOARD(board)?0x20000:SX_WINDOW_LEN) -/* Need a #define for ^^^^^^^ !!! */ - diff --git a/drivers/staging/generic_serial/sxboards.h b/drivers/staging/generic_serial/sxboards.h deleted file mode 100644 index 427927dc7dbf..000000000000 --- a/drivers/staging/generic_serial/sxboards.h +++ /dev/null @@ -1,206 +0,0 @@ -/************************************************************************/ -/* */ -/* Title : SX/SI/XIO Board Hardware Definitions */ -/* */ -/* Author : N.P.Vassallo */ -/* */ -/* Creation : 16th March 1998 */ -/* */ -/* Version : 3.0.0 */ -/* */ -/* Copyright : (c) Specialix International Ltd. 1998 */ -/* */ -/* Description : Prototypes, structures and definitions */ -/* describing the SX/SI/XIO board hardware */ -/* */ -/************************************************************************/ - -/* History... - -3.0.0 16/03/98 NPV Creation. - -*/ - -#ifndef _sxboards_h /* If SXBOARDS.H not already defined */ -#define _sxboards_h 1 - -/***************************************************************************** -******************************* ****************************** -******************************* Board Types ****************************** -******************************* ****************************** -*****************************************************************************/ - -/* BUS types... */ -#define BUS_ISA 0 -#define BUS_MCA 1 -#define BUS_EISA 2 -#define BUS_PCI 3 - -/* Board phases... */ -#define SI1_Z280 1 -#define SI2_Z280 2 -#define SI3_T225 3 - -/* Board types... */ -#define CARD_TYPE(bus,phase) (bus<<4|phase) -#define CARD_BUS(type) ((type>>4)&0xF) -#define CARD_PHASE(type) (type&0xF) - -#define TYPE_SI1_ISA CARD_TYPE(BUS_ISA,SI1_Z280) -#define TYPE_SI2_ISA CARD_TYPE(BUS_ISA,SI2_Z280) -#define TYPE_SI2_EISA CARD_TYPE(BUS_EISA,SI2_Z280) -#define TYPE_SI2_PCI CARD_TYPE(BUS_PCI,SI2_Z280) - -#define TYPE_SX_ISA CARD_TYPE(BUS_ISA,SI3_T225) -#define TYPE_SX_PCI CARD_TYPE(BUS_PCI,SI3_T225) -/***************************************************************************** -****************************** ****************************** -****************************** Phase 1 Z280 ****************************** -****************************** ****************************** -*****************************************************************************/ - -/* ISA board details... */ -#define SI1_ISA_WINDOW_LEN 0x10000 /* 64 Kbyte shared memory window */ -//#define SI1_ISA_MEMORY_LEN 0x8000 /* Usable memory - unused define*/ -//#define SI1_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ -//#define SI1_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ -//#define SI2_ISA_ADDR_STEP SI2_ISA_WINDOW_LEN/* ISA board address step */ -//#define SI2_ISA_IRQ_MASK 0x9800 /* IRQs 15,12,11 */ - -/* ISA board, register definitions... */ -//#define SI2_ISA_ID_BASE 0x7FF8 /* READ: Board ID string */ -#define SI1_ISA_RESET 0x8000 /* WRITE: Host Reset */ -#define SI1_ISA_RESET_CLEAR 0xc000 /* WRITE: Host Reset clear*/ -#define SI1_ISA_WAIT 0x9000 /* WRITE: Host wait */ -#define SI1_ISA_WAIT_CLEAR 0xd000 /* WRITE: Host wait clear */ -#define SI1_ISA_INTCL 0xa000 /* WRITE: Host Reset */ -#define SI1_ISA_INTCL_CLEAR 0xe000 /* WRITE: Host Reset */ - - -/***************************************************************************** -****************************** ****************************** -****************************** Phase 2 Z280 ****************************** -****************************** ****************************** -*****************************************************************************/ - -/* ISA board details... */ -#define SI2_ISA_WINDOW_LEN 0x8000 /* 32 Kbyte shared memory window */ -#define SI2_ISA_MEMORY_LEN 0x7FF8 /* Usable memory */ -#define SI2_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ -#define SI2_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ -#define SI2_ISA_ADDR_STEP SI2_ISA_WINDOW_LEN/* ISA board address step */ -#define SI2_ISA_IRQ_MASK 0x9800 /* IRQs 15,12,11 */ - -/* ISA board, register definitions... */ -#define SI2_ISA_ID_BASE 0x7FF8 /* READ: Board ID string */ -#define SI2_ISA_RESET SI2_ISA_ID_BASE /* WRITE: Host Reset */ -#define SI2_ISA_IRQ11 (SI2_ISA_ID_BASE+1) /* WRITE: Set IRQ11 */ -#define SI2_ISA_IRQ12 (SI2_ISA_ID_BASE+2) /* WRITE: Set IRQ12 */ -#define SI2_ISA_IRQ15 (SI2_ISA_ID_BASE+3) /* WRITE: Set IRQ15 */ -#define SI2_ISA_IRQSET (SI2_ISA_ID_BASE+4) /* WRITE: Set Host Interrupt */ -#define SI2_ISA_INTCLEAR (SI2_ISA_ID_BASE+5) /* WRITE: Enable Host Interrupt */ - -#define SI2_ISA_IRQ11_SET 0x10 -#define SI2_ISA_IRQ11_CLEAR 0x00 -#define SI2_ISA_IRQ12_SET 0x10 -#define SI2_ISA_IRQ12_CLEAR 0x00 -#define SI2_ISA_IRQ15_SET 0x10 -#define SI2_ISA_IRQ15_CLEAR 0x00 -#define SI2_ISA_INTCLEAR_SET 0x10 -#define SI2_ISA_INTCLEAR_CLEAR 0x00 -#define SI2_ISA_IRQSET_CLEAR 0x10 -#define SI2_ISA_IRQSET_SET 0x00 -#define SI2_ISA_RESET_SET 0x00 -#define SI2_ISA_RESET_CLEAR 0x10 - -/* PCI board details... */ -#define SI2_PCI_WINDOW_LEN 0x100000 /* 1 Mbyte memory window */ - -/* PCI board register definitions... */ -#define SI2_PCI_SET_IRQ 0x40001 /* Set Host Interrupt */ -#define SI2_PCI_RESET 0xC0001 /* Host Reset */ - -/***************************************************************************** -****************************** ****************************** -****************************** Phase 3 T225 ****************************** -****************************** ****************************** -*****************************************************************************/ - -/* General board details... */ -#define SX_WINDOW_LEN 64*1024 /* 64 Kbyte memory window */ - -/* ISA board details... */ -#define SX_ISA_ADDR_LOW 0x0A0000 /* Lowest address = 640 Kbyte */ -#define SX_ISA_ADDR_HIGH 0xFF8000 /* Highest address = 16Mbyte - 32Kbyte */ -#define SX_ISA_ADDR_STEP SX_WINDOW_LEN /* ISA board address step */ -#define SX_ISA_IRQ_MASK 0x9E00 /* IRQs 15,12,11,10,9 */ - -/* Hardware register definitions... */ -#define SX_EVENT_STATUS 0x7800 /* READ: T225 Event Status */ -#define SX_EVENT_STROBE 0x7800 /* WRITE: T225 Event Strobe */ -#define SX_EVENT_ENABLE 0x7880 /* WRITE: T225 Event Enable */ -#define SX_VPD_ROM 0x7C00 /* READ: Vital Product Data ROM */ -#define SX_CONFIG 0x7C00 /* WRITE: Host Configuration Register */ -#define SX_IRQ_STATUS 0x7C80 /* READ: Host Interrupt Status */ -#define SX_SET_IRQ 0x7C80 /* WRITE: Set Host Interrupt */ -#define SX_RESET_STATUS 0x7D00 /* READ: Host Reset Status */ -#define SX_RESET 0x7D00 /* WRITE: Host Reset */ -#define SX_RESET_IRQ 0x7D80 /* WRITE: Reset Host Interrupt */ - -/* SX_VPD_ROM definitions... */ -#define SX_VPD_SLX_ID1 0x00 -#define SX_VPD_SLX_ID2 0x01 -#define SX_VPD_HW_REV 0x02 -#define SX_VPD_HW_ASSEM 0x03 -#define SX_VPD_UNIQUEID4 0x04 -#define SX_VPD_UNIQUEID3 0x05 -#define SX_VPD_UNIQUEID2 0x06 -#define SX_VPD_UNIQUEID1 0x07 -#define SX_VPD_MANU_YEAR 0x08 -#define SX_VPD_MANU_WEEK 0x09 -#define SX_VPD_IDENT 0x10 -#define SX_VPD_IDENT_STRING "JET HOST BY KEV#" - -/* SX unique identifiers... */ -#define SX_UNIQUEID_MASK 0xF0 -#define SX_ISA_UNIQUEID1 0x20 -#define SX_PCI_UNIQUEID1 0x50 - -/* SX_CONFIG definitions... */ -#define SX_CONF_BUSEN 0x02 /* Enable T225 memory and I/O */ -#define SX_CONF_HOSTIRQ 0x04 /* Enable board to host interrupt */ - -/* SX bootstrap... */ -#define SX_BOOTSTRAP "\x28\x20\x21\x02\x60\x0a" -#define SX_BOOTSTRAP_SIZE 6 -#define SX_BOOTSTRAP_ADDR (0x8000-SX_BOOTSTRAP_SIZE) - -/***************************************************************************** -********************************** ********************************** -********************************** EISA ********************************** -********************************** ********************************** -*****************************************************************************/ - -#define SI2_EISA_OFF 0x42 -#define SI2_EISA_VAL 0x01 -#define SI2_EISA_WINDOW_LEN 0x10000 - -/***************************************************************************** -*********************************** ********************************** -*********************************** PCI ********************************** -*********************************** ********************************** -*****************************************************************************/ - -/* General definitions... */ - -#define SPX_VENDOR_ID 0x11CB /* Assigned by the PCI SIG */ -#define SPX_DEVICE_ID 0x4000 /* SI/XIO boards */ -#define SPX_PLXDEVICE_ID 0x2000 /* SX boards */ - -#define SPX_SUB_VENDOR_ID SPX_VENDOR_ID /* Same as vendor id */ -#define SI2_SUB_SYS_ID 0x400 /* Phase 2 (Z280) board */ -#define SX_SUB_SYS_ID 0x200 /* Phase 3 (t225) board */ - -#endif /*_sxboards_h */ - -/* End of SXBOARDS.H */ diff --git a/drivers/staging/generic_serial/sxwindow.h b/drivers/staging/generic_serial/sxwindow.h deleted file mode 100644 index cf01b662aefc..000000000000 --- a/drivers/staging/generic_serial/sxwindow.h +++ /dev/null @@ -1,393 +0,0 @@ -/************************************************************************/ -/* */ -/* Title : SX Shared Memory Window Structure */ -/* */ -/* Author : N.P.Vassallo */ -/* */ -/* Creation : 16th March 1998 */ -/* */ -/* Version : 3.0.0 */ -/* */ -/* Copyright : (c) Specialix International Ltd. 1998 */ -/* */ -/* Description : Prototypes, structures and definitions */ -/* describing the SX/SI/XIO cards shared */ -/* memory window structure: */ -/* SXCARD */ -/* SXMODULE */ -/* SXCHANNEL */ -/* */ -/************************************************************************/ - -/* History... - -3.0.0 16/03/98 NPV Creation. (based on STRUCT.H) - -*/ - -#ifndef _sxwindow_h /* If SXWINDOW.H not already defined */ -#define _sxwindow_h 1 - -/***************************************************************************** -*************************** *************************** -*************************** Common Definitions *************************** -*************************** *************************** -*****************************************************************************/ - -typedef struct _SXCARD *PSXCARD; /* SXCARD structure pointer */ -typedef struct _SXMODULE *PMOD; /* SXMODULE structure pointer */ -typedef struct _SXCHANNEL *PCHAN; /* SXCHANNEL structure pointer */ - -/***************************************************************************** -********************************* ********************************* -********************************* SXCARD ********************************* -********************************* ********************************* -*****************************************************************************/ - -typedef struct _SXCARD -{ - BYTE cc_init_status; /* 0x00 Initialisation status */ - BYTE cc_mem_size; /* 0x01 Size of memory on card */ - WORD cc_int_count; /* 0x02 Interrupt count */ - WORD cc_revision; /* 0x04 Download code revision */ - BYTE cc_isr_count; /* 0x06 Count when ISR is run */ - BYTE cc_main_count; /* 0x07 Count when main loop is run */ - WORD cc_int_pending; /* 0x08 Interrupt pending */ - WORD cc_poll_count; /* 0x0A Count when poll is run */ - BYTE cc_int_set_count; /* 0x0C Count when host interrupt is set */ - BYTE cc_rfu[0x80 - 0x0D]; /* 0x0D Pad structure to 128 bytes (0x80) */ - -} SXCARD; - -/* SXCARD.cc_init_status definitions... */ -#define ADAPTERS_FOUND (BYTE)0x01 -#define NO_ADAPTERS_FOUND (BYTE)0xFF - -/* SXCARD.cc_mem_size definitions... */ -#define SX_MEMORY_SIZE (BYTE)0x40 - -/* SXCARD.cc_int_count definitions... */ -#define INT_COUNT_DEFAULT 100 /* Hz */ - -/***************************************************************************** -******************************** ******************************** -******************************** SXMODULE ******************************** -******************************** ******************************** -*****************************************************************************/ - -#define TOP_POINTER(a) ((a)|0x8000) /* Sets top bit of word */ -#define UNTOP_POINTER(a) ((a)&~0x8000) /* Clears top bit of word */ - -typedef struct _SXMODULE -{ - WORD mc_next; /* 0x00 Next module "pointer" (ORed with 0x8000) */ - BYTE mc_type; /* 0x02 Type of TA in terms of number of channels */ - BYTE mc_mod_no; /* 0x03 Module number on SI bus cable (0 closest to card) */ - BYTE mc_dtr; /* 0x04 Private DTR copy (TA only) */ - BYTE mc_rfu1; /* 0x05 Reserved */ - WORD mc_uart; /* 0x06 UART base address for this module */ - BYTE mc_chip; /* 0x08 Chip type / number of ports */ - BYTE mc_current_uart; /* 0x09 Current uart selected for this module */ -#ifdef DOWNLOAD - PCHAN mc_chan_pointer[8]; /* 0x0A Pointer to each channel structure */ -#else - WORD mc_chan_pointer[8]; /* 0x0A Define as WORD if not compiling into download */ -#endif - WORD mc_rfu2; /* 0x1A Reserved */ - BYTE mc_opens1; /* 0x1C Number of open ports on first four ports on MTA/SXDC */ - BYTE mc_opens2; /* 0x1D Number of open ports on second four ports on MTA/SXDC */ - BYTE mc_mods; /* 0x1E Types of connector module attached to MTA/SXDC */ - BYTE mc_rev1; /* 0x1F Revision of first CD1400 on MTA/SXDC */ - BYTE mc_rev2; /* 0x20 Revision of second CD1400 on MTA/SXDC */ - BYTE mc_mtaasic_rev; /* 0x21 Revision of MTA ASIC 1..4 -> A, B, C, D */ - BYTE mc_rfu3[0x100 - 0x22]; /* 0x22 Pad structure to 256 bytes (0x100) */ - -} SXMODULE; - -/* SXMODULE.mc_type definitions... */ -#define FOUR_PORTS (BYTE)4 -#define EIGHT_PORTS (BYTE)8 - -/* SXMODULE.mc_chip definitions... */ -#define CHIP_MASK 0xF0 -#define TA (BYTE)0 -#define TA4 (TA | FOUR_PORTS) -#define TA8 (TA | EIGHT_PORTS) -#define TA4_ASIC (BYTE)0x0A -#define TA8_ASIC (BYTE)0x0B -#define MTA_CD1400 (BYTE)0x28 -#define SXDC (BYTE)0x48 - -/* SXMODULE.mc_mods definitions... */ -#define MOD_RS232DB25 0x00 /* RS232 DB25 (socket/plug) */ -#define MOD_RS232RJ45 0x01 /* RS232 RJ45 (shielded/opto-isolated) */ -#define MOD_RESERVED_2 0x02 /* Reserved (RS485) */ -#define MOD_RS422DB25 0x03 /* RS422 DB25 Socket */ -#define MOD_RESERVED_4 0x04 /* Reserved */ -#define MOD_PARALLEL 0x05 /* Parallel */ -#define MOD_RESERVED_6 0x06 /* Reserved (RS423) */ -#define MOD_RESERVED_7 0x07 /* Reserved */ -#define MOD_2_RS232DB25 0x08 /* Rev 2.0 RS232 DB25 (socket/plug) */ -#define MOD_2_RS232RJ45 0x09 /* Rev 2.0 RS232 RJ45 */ -#define MOD_RESERVED_A 0x0A /* Rev 2.0 Reserved */ -#define MOD_2_RS422DB25 0x0B /* Rev 2.0 RS422 DB25 */ -#define MOD_RESERVED_C 0x0C /* Rev 2.0 Reserved */ -#define MOD_2_PARALLEL 0x0D /* Rev 2.0 Parallel */ -#define MOD_RESERVED_E 0x0E /* Rev 2.0 Reserved */ -#define MOD_BLANK 0x0F /* Blank Panel */ - -/***************************************************************************** -******************************** ******************************* -******************************** SXCHANNEL ******************************* -******************************** ******************************* -*****************************************************************************/ - -#define TX_BUFF_OFFSET 0x60 /* Transmit buffer offset in channel structure */ -#define BUFF_POINTER(a) (((a)+TX_BUFF_OFFSET)|0x8000) -#define UNBUFF_POINTER(a) (jet_channel*)(((a)&~0x8000)-TX_BUFF_OFFSET) -#define BUFFER_SIZE 256 -#define HIGH_WATER ((BUFFER_SIZE / 4) * 3) -#define LOW_WATER (BUFFER_SIZE / 4) - -typedef struct _SXCHANNEL -{ - WORD next_item; /* 0x00 Offset from window base of next channels hi_txbuf (ORred with 0x8000) */ - WORD addr_uart; /* 0x02 INTERNAL pointer to uart address. Includes FASTPATH bit */ - WORD module; /* 0x04 Offset from window base of parent SXMODULE structure */ - BYTE type; /* 0x06 Chip type / number of ports (copy of mc_chip) */ - BYTE chan_number; /* 0x07 Channel number on the TA/MTA/SXDC */ - WORD xc_status; /* 0x08 Flow control and I/O status */ - BYTE hi_rxipos; /* 0x0A Receive buffer input index */ - BYTE hi_rxopos; /* 0x0B Receive buffer output index */ - BYTE hi_txopos; /* 0x0C Transmit buffer output index */ - BYTE hi_txipos; /* 0x0D Transmit buffer input index */ - BYTE hi_hstat; /* 0x0E Command register */ - BYTE dtr_bit; /* 0x0F INTERNAL DTR control byte (TA only) */ - BYTE txon; /* 0x10 INTERNAL copy of hi_txon */ - BYTE txoff; /* 0x11 INTERNAL copy of hi_txoff */ - BYTE rxon; /* 0x12 INTERNAL copy of hi_rxon */ - BYTE rxoff; /* 0x13 INTERNAL copy of hi_rxoff */ - BYTE hi_mr1; /* 0x14 Mode Register 1 (databits,parity,RTS rx flow)*/ - BYTE hi_mr2; /* 0x15 Mode Register 2 (stopbits,local,CTS tx flow)*/ - BYTE hi_csr; /* 0x16 Clock Select Register (baud rate) */ - BYTE hi_op; /* 0x17 Modem Output Signal */ - BYTE hi_ip; /* 0x18 Modem Input Signal */ - BYTE hi_state; /* 0x19 Channel status */ - BYTE hi_prtcl; /* 0x1A Channel protocol (flow control) */ - BYTE hi_txon; /* 0x1B Transmit XON character */ - BYTE hi_txoff; /* 0x1C Transmit XOFF character */ - BYTE hi_rxon; /* 0x1D Receive XON character */ - BYTE hi_rxoff; /* 0x1E Receive XOFF character */ - BYTE close_prev; /* 0x1F INTERNAL channel previously closed flag */ - BYTE hi_break; /* 0x20 Break and error control */ - BYTE break_state; /* 0x21 INTERNAL copy of hi_break */ - BYTE hi_mask; /* 0x22 Mask for received data */ - BYTE mask; /* 0x23 INTERNAL copy of hi_mask */ - BYTE mod_type; /* 0x24 MTA/SXDC hardware module type */ - BYTE ccr_state; /* 0x25 INTERNAL MTA/SXDC state of CCR register */ - BYTE ip_mask; /* 0x26 Input handshake mask */ - BYTE hi_parallel; /* 0x27 Parallel port flag */ - BYTE par_error; /* 0x28 Error code for parallel loopback test */ - BYTE any_sent; /* 0x29 INTERNAL data sent flag */ - BYTE asic_txfifo_size; /* 0x2A INTERNAL SXDC transmit FIFO size */ - BYTE rfu1[2]; /* 0x2B Reserved */ - BYTE csr; /* 0x2D INTERNAL copy of hi_csr */ -#ifdef DOWNLOAD - PCHAN nextp; /* 0x2E Offset from window base of next channel structure */ -#else - WORD nextp; /* 0x2E Define as WORD if not compiling into download */ -#endif - BYTE prtcl; /* 0x30 INTERNAL copy of hi_prtcl */ - BYTE mr1; /* 0x31 INTERNAL copy of hi_mr1 */ - BYTE mr2; /* 0x32 INTERNAL copy of hi_mr2 */ - BYTE hi_txbaud; /* 0x33 Extended transmit baud rate (SXDC only if((hi_csr&0x0F)==0x0F) */ - BYTE hi_rxbaud; /* 0x34 Extended receive baud rate (SXDC only if((hi_csr&0xF0)==0xF0) */ - BYTE txbreak_state; /* 0x35 INTERNAL MTA/SXDC transmit break state */ - BYTE txbaud; /* 0x36 INTERNAL copy of hi_txbaud */ - BYTE rxbaud; /* 0x37 INTERNAL copy of hi_rxbaud */ - WORD err_framing; /* 0x38 Count of receive framing errors */ - WORD err_parity; /* 0x3A Count of receive parity errors */ - WORD err_overrun; /* 0x3C Count of receive overrun errors */ - WORD err_overflow; /* 0x3E Count of receive buffer overflow errors */ - BYTE rfu2[TX_BUFF_OFFSET - 0x40]; /* 0x40 Reserved until hi_txbuf */ - BYTE hi_txbuf[BUFFER_SIZE]; /* 0x060 Transmit buffer */ - BYTE hi_rxbuf[BUFFER_SIZE]; /* 0x160 Receive buffer */ - BYTE rfu3[0x300 - 0x260]; /* 0x260 Reserved until 768 bytes (0x300) */ - -} SXCHANNEL; - -/* SXCHANNEL.addr_uart definitions... */ -#define FASTPATH 0x1000 /* Set to indicate fast rx/tx processing (TA only) */ - -/* SXCHANNEL.xc_status definitions... */ -#define X_TANY 0x0001 /* XON is any character (TA only) */ -#define X_TION 0x0001 /* Tx interrupts on (MTA only) */ -#define X_TXEN 0x0002 /* Tx XON/XOFF enabled (TA only) */ -#define X_RTSEN 0x0002 /* RTS FLOW enabled (MTA only) */ -#define X_TXRC 0x0004 /* XOFF received (TA only) */ -#define X_RTSLOW 0x0004 /* RTS dropped (MTA only) */ -#define X_RXEN 0x0008 /* Rx XON/XOFF enabled */ -#define X_ANYXO 0x0010 /* XOFF pending/sent or RTS dropped */ -#define X_RXSE 0x0020 /* Rx XOFF sent */ -#define X_NPEND 0x0040 /* Rx XON pending or XOFF pending */ -#define X_FPEND 0x0080 /* Rx XOFF pending */ -#define C_CRSE 0x0100 /* Carriage return sent (TA only) */ -#define C_TEMR 0x0100 /* Tx empty requested (MTA only) */ -#define C_TEMA 0x0200 /* Tx empty acked (MTA only) */ -#define C_ANYP 0x0200 /* Any protocol bar tx XON/XOFF (TA only) */ -#define C_EN 0x0400 /* Cooking enabled (on MTA means port is also || */ -#define C_HIGH 0x0800 /* Buffer previously hit high water */ -#define C_CTSEN 0x1000 /* CTS automatic flow-control enabled */ -#define C_DCDEN 0x2000 /* DCD/DTR checking enabled */ -#define C_BREAK 0x4000 /* Break detected */ -#define C_RTSEN 0x8000 /* RTS automatic flow control enabled (MTA only) */ -#define C_PARITY 0x8000 /* Parity checking enabled (TA only) */ - -/* SXCHANNEL.hi_hstat definitions... */ -#define HS_IDLE_OPEN 0x00 /* Channel open state */ -#define HS_LOPEN 0x02 /* Local open command (no modem monitoring) */ -#define HS_MOPEN 0x04 /* Modem open command (wait for DCD signal) */ -#define HS_IDLE_MPEND 0x06 /* Waiting for DCD signal state */ -#define HS_CONFIG 0x08 /* Configuration command */ -#define HS_CLOSE 0x0A /* Close command */ -#define HS_START 0x0C /* Start transmit break command */ -#define HS_STOP 0x0E /* Stop transmit break command */ -#define HS_IDLE_CLOSED 0x10 /* Closed channel state */ -#define HS_IDLE_BREAK 0x12 /* Transmit break state */ -#define HS_FORCE_CLOSED 0x14 /* Force close command */ -#define HS_RESUME 0x16 /* Clear pending XOFF command */ -#define HS_WFLUSH 0x18 /* Flush transmit buffer command */ -#define HS_RFLUSH 0x1A /* Flush receive buffer command */ -#define HS_SUSPEND 0x1C /* Suspend output command (like XOFF received) */ -#define PARALLEL 0x1E /* Parallel port loopback test command (Diagnostics Only) */ -#define ENABLE_RX_INTS 0x20 /* Enable receive interrupts command (Diagnostics Only) */ -#define ENABLE_TX_INTS 0x22 /* Enable transmit interrupts command (Diagnostics Only) */ -#define ENABLE_MDM_INTS 0x24 /* Enable modem interrupts command (Diagnostics Only) */ -#define DISABLE_INTS 0x26 /* Disable interrupts command (Diagnostics Only) */ - -/* SXCHANNEL.hi_mr1 definitions... */ -#define MR1_BITS 0x03 /* Data bits mask */ -#define MR1_5_BITS 0x00 /* 5 data bits */ -#define MR1_6_BITS 0x01 /* 6 data bits */ -#define MR1_7_BITS 0x02 /* 7 data bits */ -#define MR1_8_BITS 0x03 /* 8 data bits */ -#define MR1_PARITY 0x1C /* Parity mask */ -#define MR1_ODD 0x04 /* Odd parity */ -#define MR1_EVEN 0x00 /* Even parity */ -#define MR1_WITH 0x00 /* Parity enabled */ -#define MR1_FORCE 0x08 /* Force parity */ -#define MR1_NONE 0x10 /* No parity */ -#define MR1_NOPARITY MR1_NONE /* No parity */ -#define MR1_ODDPARITY (MR1_WITH|MR1_ODD) /* Odd parity */ -#define MR1_EVENPARITY (MR1_WITH|MR1_EVEN) /* Even parity */ -#define MR1_MARKPARITY (MR1_FORCE|MR1_ODD) /* Mark parity */ -#define MR1_SPACEPARITY (MR1_FORCE|MR1_EVEN) /* Space parity */ -#define MR1_RTS_RXFLOW 0x80 /* RTS receive flow control */ - -/* SXCHANNEL.hi_mr2 definitions... */ -#define MR2_STOP 0x0F /* Stop bits mask */ -#define MR2_1_STOP 0x07 /* 1 stop bit */ -#define MR2_2_STOP 0x0F /* 2 stop bits */ -#define MR2_CTS_TXFLOW 0x10 /* CTS transmit flow control */ -#define MR2_RTS_TOGGLE 0x20 /* RTS toggle on transmit */ -#define MR2_NORMAL 0x00 /* Normal mode */ -#define MR2_AUTO 0x40 /* Auto-echo mode (TA only) */ -#define MR2_LOCAL 0x80 /* Local echo mode */ -#define MR2_REMOTE 0xC0 /* Remote echo mode (TA only) */ - -/* SXCHANNEL.hi_csr definitions... */ -#define CSR_75 0x0 /* 75 baud */ -#define CSR_110 0x1 /* 110 baud (TA), 115200 (MTA/SXDC) */ -#define CSR_38400 0x2 /* 38400 baud */ -#define CSR_150 0x3 /* 150 baud */ -#define CSR_300 0x4 /* 300 baud */ -#define CSR_600 0x5 /* 600 baud */ -#define CSR_1200 0x6 /* 1200 baud */ -#define CSR_2000 0x7 /* 2000 baud */ -#define CSR_2400 0x8 /* 2400 baud */ -#define CSR_4800 0x9 /* 4800 baud */ -#define CSR_1800 0xA /* 1800 baud */ -#define CSR_9600 0xB /* 9600 baud */ -#define CSR_19200 0xC /* 19200 baud */ -#define CSR_57600 0xD /* 57600 baud */ -#define CSR_EXTBAUD 0xF /* Extended baud rate (hi_txbaud/hi_rxbaud) */ - -/* SXCHANNEL.hi_op definitions... */ -#define OP_RTS 0x01 /* RTS modem output signal */ -#define OP_DTR 0x02 /* DTR modem output signal */ - -/* SXCHANNEL.hi_ip definitions... */ -#define IP_CTS 0x02 /* CTS modem input signal */ -#define IP_DCD 0x04 /* DCD modem input signal */ -#define IP_DSR 0x20 /* DTR modem input signal */ -#define IP_RI 0x40 /* RI modem input signal */ - -/* SXCHANNEL.hi_state definitions... */ -#define ST_BREAK 0x01 /* Break received (clear with config) */ -#define ST_DCD 0x02 /* DCD signal changed state */ - -/* SXCHANNEL.hi_prtcl definitions... */ -#define SP_TANY 0x01 /* Transmit XON/XANY (if SP_TXEN enabled) */ -#define SP_TXEN 0x02 /* Transmit XON/XOFF flow control */ -#define SP_CEN 0x04 /* Cooking enabled */ -#define SP_RXEN 0x08 /* Rx XON/XOFF enabled */ -#define SP_DCEN 0x20 /* DCD / DTR check */ -#define SP_DTR_RXFLOW 0x40 /* DTR receive flow control */ -#define SP_PAEN 0x80 /* Parity checking enabled */ - -/* SXCHANNEL.hi_break definitions... */ -#define BR_IGN 0x01 /* Ignore any received breaks */ -#define BR_INT 0x02 /* Interrupt on received break */ -#define BR_PARMRK 0x04 /* Enable parmrk parity error processing */ -#define BR_PARIGN 0x08 /* Ignore chars with parity errors */ -#define BR_ERRINT 0x80 /* Treat parity/framing/overrun errors as exceptions */ - -/* SXCHANNEL.par_error definitions.. */ -#define DIAG_IRQ_RX 0x01 /* Indicate serial receive interrupt (diags only) */ -#define DIAG_IRQ_TX 0x02 /* Indicate serial transmit interrupt (diags only) */ -#define DIAG_IRQ_MD 0x04 /* Indicate serial modem interrupt (diags only) */ - -/* SXCHANNEL.hi_txbaud/hi_rxbaud definitions... (SXDC only) */ -#define BAUD_75 0x00 /* 75 baud */ -#define BAUD_115200 0x01 /* 115200 baud */ -#define BAUD_38400 0x02 /* 38400 baud */ -#define BAUD_150 0x03 /* 150 baud */ -#define BAUD_300 0x04 /* 300 baud */ -#define BAUD_600 0x05 /* 600 baud */ -#define BAUD_1200 0x06 /* 1200 baud */ -#define BAUD_2000 0x07 /* 2000 baud */ -#define BAUD_2400 0x08 /* 2400 baud */ -#define BAUD_4800 0x09 /* 4800 baud */ -#define BAUD_1800 0x0A /* 1800 baud */ -#define BAUD_9600 0x0B /* 9600 baud */ -#define BAUD_19200 0x0C /* 19200 baud */ -#define BAUD_57600 0x0D /* 57600 baud */ -#define BAUD_230400 0x0E /* 230400 baud */ -#define BAUD_460800 0x0F /* 460800 baud */ -#define BAUD_921600 0x10 /* 921600 baud */ -#define BAUD_50 0x11 /* 50 baud */ -#define BAUD_110 0x12 /* 110 baud */ -#define BAUD_134_5 0x13 /* 134.5 baud */ -#define BAUD_200 0x14 /* 200 baud */ -#define BAUD_7200 0x15 /* 7200 baud */ -#define BAUD_56000 0x16 /* 56000 baud */ -#define BAUD_64000 0x17 /* 64000 baud */ -#define BAUD_76800 0x18 /* 76800 baud */ -#define BAUD_128000 0x19 /* 128000 baud */ -#define BAUD_150000 0x1A /* 150000 baud */ -#define BAUD_14400 0x1B /* 14400 baud */ -#define BAUD_256000 0x1C /* 256000 baud */ -#define BAUD_28800 0x1D /* 28800 baud */ - -/* SXCHANNEL.txbreak_state definiions... */ -#define TXBREAK_OFF 0 /* Not sending break */ -#define TXBREAK_START 1 /* Begin sending break */ -#define TXBREAK_START1 2 /* Begin sending break, part 1 */ -#define TXBREAK_ON 3 /* Sending break */ -#define TXBREAK_STOP 4 /* Stop sending break */ -#define TXBREAK_STOP1 5 /* Stop sending break, part 1 */ - -#endif /* _sxwindow_h */ - -/* End of SXWINDOW.H */ - diff --git a/drivers/staging/generic_serial/vme_scc.c b/drivers/staging/generic_serial/vme_scc.c deleted file mode 100644 index 96838640f575..000000000000 --- a/drivers/staging/generic_serial/vme_scc.c +++ /dev/null @@ -1,1145 +0,0 @@ -/* - * drivers/char/vme_scc.c: MVME147, MVME162, BVME6000 SCC serial ports - * implementation. - * Copyright 1999 Richard Hirst - * - * Based on atari_SCC.c which was - * Copyright 1994-95 Roman Hodek - * Partially based on PC-Linux serial.c by Linus Torvalds and Theodore Ts'o - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_MVME147_SCC -#include -#endif -#ifdef CONFIG_MVME162_SCC -#include -#endif -#ifdef CONFIG_BVME6000_SCC -#include -#endif - -#include -#include "scc.h" - - -#define CHANNEL_A 0 -#define CHANNEL_B 1 - -#define SCC_MINOR_BASE 64 - -/* Shadows for all SCC write registers */ -static unsigned char scc_shadow[2][16]; - -/* Location to access for SCC register access delay */ -static volatile unsigned char *scc_del = NULL; - -/* To keep track of STATUS_REG state for detection of Ext/Status int source */ -static unsigned char scc_last_status_reg[2]; - -/***************************** Prototypes *****************************/ - -/* Function prototypes */ -static void scc_disable_tx_interrupts(void * ptr); -static void scc_enable_tx_interrupts(void * ptr); -static void scc_disable_rx_interrupts(void * ptr); -static void scc_enable_rx_interrupts(void * ptr); -static int scc_carrier_raised(struct tty_port *port); -static void scc_shutdown_port(void * ptr); -static int scc_set_real_termios(void *ptr); -static void scc_hungup(void *ptr); -static void scc_close(void *ptr); -static int scc_chars_in_buffer(void * ptr); -static int scc_open(struct tty_struct * tty, struct file * filp); -static int scc_ioctl(struct tty_struct * tty, - unsigned int cmd, unsigned long arg); -static void scc_throttle(struct tty_struct *tty); -static void scc_unthrottle(struct tty_struct *tty); -static irqreturn_t scc_tx_int(int irq, void *data); -static irqreturn_t scc_rx_int(int irq, void *data); -static irqreturn_t scc_stat_int(int irq, void *data); -static irqreturn_t scc_spcond_int(int irq, void *data); -static void scc_setsignals(struct scc_port *port, int dtr, int rts); -static int scc_break_ctl(struct tty_struct *tty, int break_state); - -static struct tty_driver *scc_driver; - -static struct scc_port scc_ports[2]; - -/*--------------------------------------------------------------------------- - * Interface from generic_serial.c back here - *--------------------------------------------------------------------------*/ - -static struct real_driver scc_real_driver = { - scc_disable_tx_interrupts, - scc_enable_tx_interrupts, - scc_disable_rx_interrupts, - scc_enable_rx_interrupts, - scc_shutdown_port, - scc_set_real_termios, - scc_chars_in_buffer, - scc_close, - scc_hungup, - NULL -}; - - -static const struct tty_operations scc_ops = { - .open = scc_open, - .close = gs_close, - .write = gs_write, - .put_char = gs_put_char, - .flush_chars = gs_flush_chars, - .write_room = gs_write_room, - .chars_in_buffer = gs_chars_in_buffer, - .flush_buffer = gs_flush_buffer, - .ioctl = scc_ioctl, - .throttle = scc_throttle, - .unthrottle = scc_unthrottle, - .set_termios = gs_set_termios, - .stop = gs_stop, - .start = gs_start, - .hangup = gs_hangup, - .break_ctl = scc_break_ctl, -}; - -static const struct tty_port_operations scc_port_ops = { - .carrier_raised = scc_carrier_raised, -}; - -/*---------------------------------------------------------------------------- - * vme_scc_init() and support functions - *---------------------------------------------------------------------------*/ - -static int __init scc_init_drivers(void) -{ - int error; - - scc_driver = alloc_tty_driver(2); - if (!scc_driver) - return -ENOMEM; - scc_driver->owner = THIS_MODULE; - scc_driver->driver_name = "scc"; - scc_driver->name = "ttyS"; - scc_driver->major = TTY_MAJOR; - scc_driver->minor_start = SCC_MINOR_BASE; - scc_driver->type = TTY_DRIVER_TYPE_SERIAL; - scc_driver->subtype = SERIAL_TYPE_NORMAL; - scc_driver->init_termios = tty_std_termios; - scc_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - scc_driver->init_termios.c_ispeed = 9600; - scc_driver->init_termios.c_ospeed = 9600; - scc_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(scc_driver, &scc_ops); - - if ((error = tty_register_driver(scc_driver))) { - printk(KERN_ERR "scc: Couldn't register scc driver, error = %d\n", - error); - put_tty_driver(scc_driver); - return 1; - } - - return 0; -} - - -/* ports[] array is indexed by line no (i.e. [0] for ttyS0, [1] for ttyS1). - */ - -static void __init scc_init_portstructs(void) -{ - struct scc_port *port; - int i; - - for (i = 0; i < 2; i++) { - port = scc_ports + i; - tty_port_init(&port->gs.port); - port->gs.port.ops = &scc_port_ops; - port->gs.magic = SCC_MAGIC; - port->gs.close_delay = HZ/2; - port->gs.closing_wait = 30 * HZ; - port->gs.rd = &scc_real_driver; -#ifdef NEW_WRITE_LOCKING - port->gs.port_write_mutex = MUTEX; -#endif - init_waitqueue_head(&port->gs.port.open_wait); - init_waitqueue_head(&port->gs.port.close_wait); - } -} - - -#ifdef CONFIG_MVME147_SCC -static int __init mvme147_scc_init(void) -{ - struct scc_port *port; - int error; - - printk(KERN_INFO "SCC: MVME147 Serial Driver\n"); - /* Init channel A */ - port = &scc_ports[0]; - port->channel = CHANNEL_A; - port->ctrlp = (volatile unsigned char *)M147_SCC_A_ADDR; - port->datap = port->ctrlp + 1; - port->port_a = &scc_ports[0]; - port->port_b = &scc_ports[1]; - error = request_irq(MVME147_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, - "SCC-A TX", port); - if (error) - goto fail; - error = request_irq(MVME147_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, - "SCC-A status", port); - if (error) - goto fail_free_a_tx; - error = request_irq(MVME147_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, - "SCC-A RX", port); - if (error) - goto fail_free_a_stat; - error = request_irq(MVME147_IRQ_SCCA_SPCOND, scc_spcond_int, - IRQF_DISABLED, "SCC-A special cond", port); - if (error) - goto fail_free_a_rx; - - { - SCC_ACCESS_INIT(port); - - /* disable interrupts for this channel */ - SCCwrite(INT_AND_DMA_REG, 0); - /* Set the interrupt vector */ - SCCwrite(INT_VECTOR_REG, MVME147_IRQ_SCC_BASE); - /* Interrupt parameters: vector includes status, status low */ - SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT); - SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB); - } - - /* Init channel B */ - port = &scc_ports[1]; - port->channel = CHANNEL_B; - port->ctrlp = (volatile unsigned char *)M147_SCC_B_ADDR; - port->datap = port->ctrlp + 1; - port->port_a = &scc_ports[0]; - port->port_b = &scc_ports[1]; - error = request_irq(MVME147_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, - "SCC-B TX", port); - if (error) - goto fail_free_a_spcond; - error = request_irq(MVME147_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, - "SCC-B status", port); - if (error) - goto fail_free_b_tx; - error = request_irq(MVME147_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, - "SCC-B RX", port); - if (error) - goto fail_free_b_stat; - error = request_irq(MVME147_IRQ_SCCB_SPCOND, scc_spcond_int, - IRQF_DISABLED, "SCC-B special cond", port); - if (error) - goto fail_free_b_rx; - - { - SCC_ACCESS_INIT(port); - - /* disable interrupts for this channel */ - SCCwrite(INT_AND_DMA_REG, 0); - } - - /* Ensure interrupts are enabled in the PCC chip */ - m147_pcc->serial_cntrl=PCC_LEVEL_SERIAL|PCC_INT_ENAB; - - /* Initialise the tty driver structures and register */ - scc_init_portstructs(); - scc_init_drivers(); - - return 0; - -fail_free_b_rx: - free_irq(MVME147_IRQ_SCCB_RX, port); -fail_free_b_stat: - free_irq(MVME147_IRQ_SCCB_STAT, port); -fail_free_b_tx: - free_irq(MVME147_IRQ_SCCB_TX, port); -fail_free_a_spcond: - free_irq(MVME147_IRQ_SCCA_SPCOND, port); -fail_free_a_rx: - free_irq(MVME147_IRQ_SCCA_RX, port); -fail_free_a_stat: - free_irq(MVME147_IRQ_SCCA_STAT, port); -fail_free_a_tx: - free_irq(MVME147_IRQ_SCCA_TX, port); -fail: - return error; -} -#endif - - -#ifdef CONFIG_MVME162_SCC -static int __init mvme162_scc_init(void) -{ - struct scc_port *port; - int error; - - if (!(mvme16x_config & MVME16x_CONFIG_GOT_SCCA)) - return (-ENODEV); - - printk(KERN_INFO "SCC: MVME162 Serial Driver\n"); - /* Init channel A */ - port = &scc_ports[0]; - port->channel = CHANNEL_A; - port->ctrlp = (volatile unsigned char *)MVME_SCC_A_ADDR; - port->datap = port->ctrlp + 2; - port->port_a = &scc_ports[0]; - port->port_b = &scc_ports[1]; - error = request_irq(MVME162_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, - "SCC-A TX", port); - if (error) - goto fail; - error = request_irq(MVME162_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, - "SCC-A status", port); - if (error) - goto fail_free_a_tx; - error = request_irq(MVME162_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, - "SCC-A RX", port); - if (error) - goto fail_free_a_stat; - error = request_irq(MVME162_IRQ_SCCA_SPCOND, scc_spcond_int, - IRQF_DISABLED, "SCC-A special cond", port); - if (error) - goto fail_free_a_rx; - - { - SCC_ACCESS_INIT(port); - - /* disable interrupts for this channel */ - SCCwrite(INT_AND_DMA_REG, 0); - /* Set the interrupt vector */ - SCCwrite(INT_VECTOR_REG, MVME162_IRQ_SCC_BASE); - /* Interrupt parameters: vector includes status, status low */ - SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT); - SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB); - } - - /* Init channel B */ - port = &scc_ports[1]; - port->channel = CHANNEL_B; - port->ctrlp = (volatile unsigned char *)MVME_SCC_B_ADDR; - port->datap = port->ctrlp + 2; - port->port_a = &scc_ports[0]; - port->port_b = &scc_ports[1]; - error = request_irq(MVME162_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, - "SCC-B TX", port); - if (error) - goto fail_free_a_spcond; - error = request_irq(MVME162_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, - "SCC-B status", port); - if (error) - goto fail_free_b_tx; - error = request_irq(MVME162_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, - "SCC-B RX", port); - if (error) - goto fail_free_b_stat; - error = request_irq(MVME162_IRQ_SCCB_SPCOND, scc_spcond_int, - IRQF_DISABLED, "SCC-B special cond", port); - if (error) - goto fail_free_b_rx; - - { - SCC_ACCESS_INIT(port); /* Either channel will do */ - - /* disable interrupts for this channel */ - SCCwrite(INT_AND_DMA_REG, 0); - } - - /* Ensure interrupts are enabled in the MC2 chip */ - *(volatile char *)0xfff4201d = 0x14; - - /* Initialise the tty driver structures and register */ - scc_init_portstructs(); - scc_init_drivers(); - - return 0; - -fail_free_b_rx: - free_irq(MVME162_IRQ_SCCB_RX, port); -fail_free_b_stat: - free_irq(MVME162_IRQ_SCCB_STAT, port); -fail_free_b_tx: - free_irq(MVME162_IRQ_SCCB_TX, port); -fail_free_a_spcond: - free_irq(MVME162_IRQ_SCCA_SPCOND, port); -fail_free_a_rx: - free_irq(MVME162_IRQ_SCCA_RX, port); -fail_free_a_stat: - free_irq(MVME162_IRQ_SCCA_STAT, port); -fail_free_a_tx: - free_irq(MVME162_IRQ_SCCA_TX, port); -fail: - return error; -} -#endif - - -#ifdef CONFIG_BVME6000_SCC -static int __init bvme6000_scc_init(void) -{ - struct scc_port *port; - int error; - - printk(KERN_INFO "SCC: BVME6000 Serial Driver\n"); - /* Init channel A */ - port = &scc_ports[0]; - port->channel = CHANNEL_A; - port->ctrlp = (volatile unsigned char *)BVME_SCC_A_ADDR; - port->datap = port->ctrlp + 4; - port->port_a = &scc_ports[0]; - port->port_b = &scc_ports[1]; - error = request_irq(BVME_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED, - "SCC-A TX", port); - if (error) - goto fail; - error = request_irq(BVME_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED, - "SCC-A status", port); - if (error) - goto fail_free_a_tx; - error = request_irq(BVME_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED, - "SCC-A RX", port); - if (error) - goto fail_free_a_stat; - error = request_irq(BVME_IRQ_SCCA_SPCOND, scc_spcond_int, - IRQF_DISABLED, "SCC-A special cond", port); - if (error) - goto fail_free_a_rx; - - { - SCC_ACCESS_INIT(port); - - /* disable interrupts for this channel */ - SCCwrite(INT_AND_DMA_REG, 0); - /* Set the interrupt vector */ - SCCwrite(INT_VECTOR_REG, BVME_IRQ_SCC_BASE); - /* Interrupt parameters: vector includes status, status low */ - SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT); - SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB); - } - - /* Init channel B */ - port = &scc_ports[1]; - port->channel = CHANNEL_B; - port->ctrlp = (volatile unsigned char *)BVME_SCC_B_ADDR; - port->datap = port->ctrlp + 4; - port->port_a = &scc_ports[0]; - port->port_b = &scc_ports[1]; - error = request_irq(BVME_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED, - "SCC-B TX", port); - if (error) - goto fail_free_a_spcond; - error = request_irq(BVME_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED, - "SCC-B status", port); - if (error) - goto fail_free_b_tx; - error = request_irq(BVME_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED, - "SCC-B RX", port); - if (error) - goto fail_free_b_stat; - error = request_irq(BVME_IRQ_SCCB_SPCOND, scc_spcond_int, - IRQF_DISABLED, "SCC-B special cond", port); - if (error) - goto fail_free_b_rx; - - { - SCC_ACCESS_INIT(port); /* Either channel will do */ - - /* disable interrupts for this channel */ - SCCwrite(INT_AND_DMA_REG, 0); - } - - /* Initialise the tty driver structures and register */ - scc_init_portstructs(); - scc_init_drivers(); - - return 0; - -fail: - free_irq(BVME_IRQ_SCCA_STAT, port); -fail_free_a_tx: - free_irq(BVME_IRQ_SCCA_RX, port); -fail_free_a_stat: - free_irq(BVME_IRQ_SCCA_SPCOND, port); -fail_free_a_rx: - free_irq(BVME_IRQ_SCCB_TX, port); -fail_free_a_spcond: - free_irq(BVME_IRQ_SCCB_STAT, port); -fail_free_b_tx: - free_irq(BVME_IRQ_SCCB_RX, port); -fail_free_b_stat: - free_irq(BVME_IRQ_SCCB_SPCOND, port); -fail_free_b_rx: - return error; -} -#endif - - -static int __init vme_scc_init(void) -{ - int res = -ENODEV; - -#ifdef CONFIG_MVME147_SCC - if (MACH_IS_MVME147) - res = mvme147_scc_init(); -#endif -#ifdef CONFIG_MVME162_SCC - if (MACH_IS_MVME16x) - res = mvme162_scc_init(); -#endif -#ifdef CONFIG_BVME6000_SCC - if (MACH_IS_BVME6000) - res = bvme6000_scc_init(); -#endif - return res; -} - -module_init(vme_scc_init); - - -/*--------------------------------------------------------------------------- - * Interrupt handlers - *--------------------------------------------------------------------------*/ - -static irqreturn_t scc_rx_int(int irq, void *data) -{ - unsigned char ch; - struct scc_port *port = data; - struct tty_struct *tty = port->gs.port.tty; - SCC_ACCESS_INIT(port); - - ch = SCCread_NB(RX_DATA_REG); - if (!tty) { - printk(KERN_WARNING "scc_rx_int with NULL tty!\n"); - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - return IRQ_HANDLED; - } - tty_insert_flip_char(tty, ch, 0); - - /* Check if another character is already ready; in that case, the - * spcond_int() function must be used, because this character may have an - * error condition that isn't signalled by the interrupt vector used! - */ - if (SCCread(INT_PENDING_REG) & - (port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) { - scc_spcond_int (irq, data); - return IRQ_HANDLED; - } - - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - - tty_flip_buffer_push(tty); - return IRQ_HANDLED; -} - - -static irqreturn_t scc_spcond_int(int irq, void *data) -{ - struct scc_port *port = data; - struct tty_struct *tty = port->gs.port.tty; - unsigned char stat, ch, err; - int int_pending_mask = port->channel == CHANNEL_A ? - IPR_A_RX : IPR_B_RX; - SCC_ACCESS_INIT(port); - - if (!tty) { - printk(KERN_WARNING "scc_spcond_int with NULL tty!\n"); - SCCwrite(COMMAND_REG, CR_ERROR_RESET); - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - return IRQ_HANDLED; - } - do { - stat = SCCread(SPCOND_STATUS_REG); - ch = SCCread_NB(RX_DATA_REG); - - if (stat & SCSR_RX_OVERRUN) - err = TTY_OVERRUN; - else if (stat & SCSR_PARITY_ERR) - err = TTY_PARITY; - else if (stat & SCSR_CRC_FRAME_ERR) - err = TTY_FRAME; - else - err = 0; - - tty_insert_flip_char(tty, ch, err); - - /* ++TeSche: *All* errors have to be cleared manually, - * else the condition persists for the next chars - */ - if (err) - SCCwrite(COMMAND_REG, CR_ERROR_RESET); - - } while(SCCread(INT_PENDING_REG) & int_pending_mask); - - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - - tty_flip_buffer_push(tty); - return IRQ_HANDLED; -} - - -static irqreturn_t scc_tx_int(int irq, void *data) -{ - struct scc_port *port = data; - SCC_ACCESS_INIT(port); - - if (!port->gs.port.tty) { - printk(KERN_WARNING "scc_tx_int with NULL tty!\n"); - SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); - SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET); - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - return IRQ_HANDLED; - } - while ((SCCread_NB(STATUS_REG) & SR_TX_BUF_EMPTY)) { - if (port->x_char) { - SCCwrite(TX_DATA_REG, port->x_char); - port->x_char = 0; - } - else if ((port->gs.xmit_cnt <= 0) || - port->gs.port.tty->stopped || - port->gs.port.tty->hw_stopped) - break; - else { - SCCwrite(TX_DATA_REG, port->gs.xmit_buf[port->gs.xmit_tail++]); - port->gs.xmit_tail = port->gs.xmit_tail & (SERIAL_XMIT_SIZE-1); - if (--port->gs.xmit_cnt <= 0) - break; - } - } - if ((port->gs.xmit_cnt <= 0) || port->gs.port.tty->stopped || - port->gs.port.tty->hw_stopped) { - /* disable tx interrupts */ - SCCmod (INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); - SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET); /* disable tx_int on next tx underrun? */ - port->gs.port.flags &= ~GS_TX_INTEN; - } - if (port->gs.port.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) - tty_wakeup(port->gs.port.tty); - - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - return IRQ_HANDLED; -} - - -static irqreturn_t scc_stat_int(int irq, void *data) -{ - struct scc_port *port = data; - unsigned channel = port->channel; - unsigned char last_sr, sr, changed; - SCC_ACCESS_INIT(port); - - last_sr = scc_last_status_reg[channel]; - sr = scc_last_status_reg[channel] = SCCread_NB(STATUS_REG); - changed = last_sr ^ sr; - - if (changed & SR_DCD) { - port->c_dcd = !!(sr & SR_DCD); - if (!(port->gs.port.flags & ASYNC_CHECK_CD)) - ; /* Don't report DCD changes */ - else if (port->c_dcd) { - wake_up_interruptible(&port->gs.port.open_wait); - } - else { - if (port->gs.port.tty) - tty_hangup (port->gs.port.tty); - } - } - SCCwrite(COMMAND_REG, CR_EXTSTAT_RESET); - SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET); - return IRQ_HANDLED; -} - - -/*--------------------------------------------------------------------------- - * generic_serial.c callback funtions - *--------------------------------------------------------------------------*/ - -static void scc_disable_tx_interrupts(void *ptr) -{ - struct scc_port *port = ptr; - unsigned long flags; - SCC_ACCESS_INIT(port); - - local_irq_save(flags); - SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0); - port->gs.port.flags &= ~GS_TX_INTEN; - local_irq_restore(flags); -} - - -static void scc_enable_tx_interrupts(void *ptr) -{ - struct scc_port *port = ptr; - unsigned long flags; - SCC_ACCESS_INIT(port); - - local_irq_save(flags); - SCCmod(INT_AND_DMA_REG, 0xff, IDR_TX_INT_ENAB); - /* restart the transmitter */ - scc_tx_int (0, port); - local_irq_restore(flags); -} - - -static void scc_disable_rx_interrupts(void *ptr) -{ - struct scc_port *port = ptr; - unsigned long flags; - SCC_ACCESS_INIT(port); - - local_irq_save(flags); - SCCmod(INT_AND_DMA_REG, - ~(IDR_RX_INT_MASK|IDR_PARERR_AS_SPCOND|IDR_EXTSTAT_INT_ENAB), 0); - local_irq_restore(flags); -} - - -static void scc_enable_rx_interrupts(void *ptr) -{ - struct scc_port *port = ptr; - unsigned long flags; - SCC_ACCESS_INIT(port); - - local_irq_save(flags); - SCCmod(INT_AND_DMA_REG, 0xff, - IDR_EXTSTAT_INT_ENAB|IDR_PARERR_AS_SPCOND|IDR_RX_INT_ALL); - local_irq_restore(flags); -} - - -static int scc_carrier_raised(struct tty_port *port) -{ - struct scc_port *sc = container_of(port, struct scc_port, gs.port); - unsigned channel = sc->channel; - - return !!(scc_last_status_reg[channel] & SR_DCD); -} - - -static void scc_shutdown_port(void *ptr) -{ - struct scc_port *port = ptr; - - port->gs.port.flags &= ~ GS_ACTIVE; - if (port->gs.port.tty && (port->gs.port.tty->termios->c_cflag & HUPCL)) { - scc_setsignals (port, 0, 0); - } -} - - -static int scc_set_real_termios (void *ptr) -{ - /* the SCC has char sizes 5,7,6,8 in that order! */ - static int chsize_map[4] = { 0, 2, 1, 3 }; - unsigned cflag, baud, chsize, channel, brgval = 0; - unsigned long flags; - struct scc_port *port = ptr; - SCC_ACCESS_INIT(port); - - if (!port->gs.port.tty || !port->gs.port.tty->termios) return 0; - - channel = port->channel; - - if (channel == CHANNEL_A) - return 0; /* Settings controlled by boot PROM */ - - cflag = port->gs.port.tty->termios->c_cflag; - baud = port->gs.baud; - chsize = (cflag & CSIZE) >> 4; - - if (baud == 0) { - /* speed == 0 -> drop DTR */ - local_irq_save(flags); - SCCmod(TX_CTRL_REG, ~TCR_DTR, 0); - local_irq_restore(flags); - return 0; - } - else if ((MACH_IS_MVME16x && (baud < 50 || baud > 38400)) || - (MACH_IS_MVME147 && (baud < 50 || baud > 19200)) || - (MACH_IS_BVME6000 &&(baud < 50 || baud > 76800))) { - printk(KERN_NOTICE "SCC: Bad speed requested, %d\n", baud); - return 0; - } - - if (cflag & CLOCAL) - port->gs.port.flags &= ~ASYNC_CHECK_CD; - else - port->gs.port.flags |= ASYNC_CHECK_CD; - -#ifdef CONFIG_MVME147_SCC - if (MACH_IS_MVME147) - brgval = (M147_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2; -#endif -#ifdef CONFIG_MVME162_SCC - if (MACH_IS_MVME16x) - brgval = (MVME_SCC_PCLK + baud/2) / (16 * 2 * baud) - 2; -#endif -#ifdef CONFIG_BVME6000_SCC - if (MACH_IS_BVME6000) - brgval = (BVME_SCC_RTxC + baud/2) / (16 * 2 * baud) - 2; -#endif - /* Now we have all parameters and can go to set them: */ - local_irq_save(flags); - - /* receiver's character size and auto-enables */ - SCCmod(RX_CTRL_REG, ~(RCR_CHSIZE_MASK|RCR_AUTO_ENAB_MODE), - (chsize_map[chsize] << 6) | - ((cflag & CRTSCTS) ? RCR_AUTO_ENAB_MODE : 0)); - /* parity and stop bits (both, Tx and Rx), clock mode never changes */ - SCCmod (AUX1_CTRL_REG, - ~(A1CR_PARITY_MASK | A1CR_MODE_MASK), - ((cflag & PARENB - ? (cflag & PARODD ? A1CR_PARITY_ODD : A1CR_PARITY_EVEN) - : A1CR_PARITY_NONE) - | (cflag & CSTOPB ? A1CR_MODE_ASYNC_2 : A1CR_MODE_ASYNC_1))); - /* sender's character size, set DTR for valid baud rate */ - SCCmod(TX_CTRL_REG, ~TCR_CHSIZE_MASK, chsize_map[chsize] << 5 | TCR_DTR); - /* clock sources never change */ - /* disable BRG before changing the value */ - SCCmod(DPLL_CTRL_REG, ~DCR_BRG_ENAB, 0); - /* BRG value */ - SCCwrite(TIMER_LOW_REG, brgval & 0xff); - SCCwrite(TIMER_HIGH_REG, (brgval >> 8) & 0xff); - /* BRG enable, and clock source never changes */ - SCCmod(DPLL_CTRL_REG, 0xff, DCR_BRG_ENAB); - - local_irq_restore(flags); - - return 0; -} - - -static int scc_chars_in_buffer (void *ptr) -{ - struct scc_port *port = ptr; - SCC_ACCESS_INIT(port); - - return (SCCread (SPCOND_STATUS_REG) & SCSR_ALL_SENT) ? 0 : 1; -} - - -/* Comment taken from sx.c (2.4.0): - I haven't the foggiest why the decrement use count has to happen - here. The whole linux serial drivers stuff needs to be redesigned. - My guess is that this is a hack to minimize the impact of a bug - elsewhere. Thinking about it some more. (try it sometime) Try - running minicom on a serial port that is driven by a modularized - driver. Have the modem hangup. Then remove the driver module. Then - exit minicom. I expect an "oops". -- REW */ - -static void scc_hungup(void *ptr) -{ - scc_disable_tx_interrupts(ptr); - scc_disable_rx_interrupts(ptr); -} - - -static void scc_close(void *ptr) -{ - scc_disable_tx_interrupts(ptr); - scc_disable_rx_interrupts(ptr); -} - - -/*--------------------------------------------------------------------------- - * Internal support functions - *--------------------------------------------------------------------------*/ - -static void scc_setsignals(struct scc_port *port, int dtr, int rts) -{ - unsigned long flags; - unsigned char t; - SCC_ACCESS_INIT(port); - - local_irq_save(flags); - t = SCCread(TX_CTRL_REG); - if (dtr >= 0) t = dtr? (t | TCR_DTR): (t & ~TCR_DTR); - if (rts >= 0) t = rts? (t | TCR_RTS): (t & ~TCR_RTS); - SCCwrite(TX_CTRL_REG, t); - local_irq_restore(flags); -} - - -static void scc_send_xchar(struct tty_struct *tty, char ch) -{ - struct scc_port *port = tty->driver_data; - - port->x_char = ch; - if (ch) - scc_enable_tx_interrupts(port); -} - - -/*--------------------------------------------------------------------------- - * Driver entrypoints referenced from above - *--------------------------------------------------------------------------*/ - -static int scc_open (struct tty_struct * tty, struct file * filp) -{ - int line = tty->index; - int retval; - struct scc_port *port = &scc_ports[line]; - int i, channel = port->channel; - unsigned long flags; - SCC_ACCESS_INIT(port); -#if defined(CONFIG_MVME162_SCC) || defined(CONFIG_MVME147_SCC) - static const struct { - unsigned reg, val; - } mvme_init_tab[] = { - /* Values for MVME162 and MVME147 */ - /* no parity, 1 stop bit, async, 1:16 */ - { AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 }, - /* parity error is special cond, ints disabled, no DMA */ - { INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB }, - /* Rx 8 bits/char, no auto enable, Rx off */ - { RX_CTRL_REG, RCR_CHSIZE_8 }, - /* DTR off, Tx 8 bits/char, RTS off, Tx off */ - { TX_CTRL_REG, TCR_CHSIZE_8 }, - /* special features off */ - { AUX2_CTRL_REG, 0 }, - { CLK_CTRL_REG, CCR_RXCLK_BRG | CCR_TXCLK_BRG }, - { DPLL_CTRL_REG, DCR_BRG_ENAB | DCR_BRG_USE_PCLK }, - /* Start Rx */ - { RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 }, - /* Start Tx */ - { TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 }, - /* Ext/Stat ints: DCD only */ - { INT_CTRL_REG, ICR_ENAB_DCD_INT }, - /* Reset Ext/Stat ints */ - { COMMAND_REG, CR_EXTSTAT_RESET }, - /* ...again */ - { COMMAND_REG, CR_EXTSTAT_RESET }, - }; -#endif -#if defined(CONFIG_BVME6000_SCC) - static const struct { - unsigned reg, val; - } bvme_init_tab[] = { - /* Values for BVME6000 */ - /* no parity, 1 stop bit, async, 1:16 */ - { AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x16 }, - /* parity error is special cond, ints disabled, no DMA */ - { INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB }, - /* Rx 8 bits/char, no auto enable, Rx off */ - { RX_CTRL_REG, RCR_CHSIZE_8 }, - /* DTR off, Tx 8 bits/char, RTS off, Tx off */ - { TX_CTRL_REG, TCR_CHSIZE_8 }, - /* special features off */ - { AUX2_CTRL_REG, 0 }, - { CLK_CTRL_REG, CCR_RTxC_XTAL | CCR_RXCLK_BRG | CCR_TXCLK_BRG }, - { DPLL_CTRL_REG, DCR_BRG_ENAB }, - /* Start Rx */ - { RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 }, - /* Start Tx */ - { TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 }, - /* Ext/Stat ints: DCD only */ - { INT_CTRL_REG, ICR_ENAB_DCD_INT }, - /* Reset Ext/Stat ints */ - { COMMAND_REG, CR_EXTSTAT_RESET }, - /* ...again */ - { COMMAND_REG, CR_EXTSTAT_RESET }, - }; -#endif - if (!(port->gs.port.flags & ASYNC_INITIALIZED)) { - local_irq_save(flags); -#if defined(CONFIG_MVME147_SCC) || defined(CONFIG_MVME162_SCC) - if (MACH_IS_MVME147 || MACH_IS_MVME16x) { - for (i = 0; i < ARRAY_SIZE(mvme_init_tab); ++i) - SCCwrite(mvme_init_tab[i].reg, mvme_init_tab[i].val); - } -#endif -#if defined(CONFIG_BVME6000_SCC) - if (MACH_IS_BVME6000) { - for (i = 0; i < ARRAY_SIZE(bvme_init_tab); ++i) - SCCwrite(bvme_init_tab[i].reg, bvme_init_tab[i].val); - } -#endif - - /* remember status register for detection of DCD and CTS changes */ - scc_last_status_reg[channel] = SCCread(STATUS_REG); - - port->c_dcd = 0; /* Prevent initial 1->0 interrupt */ - scc_setsignals (port, 1,1); - local_irq_restore(flags); - } - - tty->driver_data = port; - port->gs.port.tty = tty; - port->gs.port.count++; - retval = gs_init_port(&port->gs); - if (retval) { - port->gs.port.count--; - return retval; - } - port->gs.port.flags |= GS_ACTIVE; - retval = gs_block_til_ready(port, filp); - - if (retval) { - port->gs.port.count--; - return retval; - } - - port->c_dcd = tty_port_carrier_raised(&port->gs.port); - - scc_enable_rx_interrupts(port); - - return 0; -} - - -static void scc_throttle (struct tty_struct * tty) -{ - struct scc_port *port = tty->driver_data; - unsigned long flags; - SCC_ACCESS_INIT(port); - - if (tty->termios->c_cflag & CRTSCTS) { - local_irq_save(flags); - SCCmod(TX_CTRL_REG, ~TCR_RTS, 0); - local_irq_restore(flags); - } - if (I_IXOFF(tty)) - scc_send_xchar(tty, STOP_CHAR(tty)); -} - - -static void scc_unthrottle (struct tty_struct * tty) -{ - struct scc_port *port = tty->driver_data; - unsigned long flags; - SCC_ACCESS_INIT(port); - - if (tty->termios->c_cflag & CRTSCTS) { - local_irq_save(flags); - SCCmod(TX_CTRL_REG, 0xff, TCR_RTS); - local_irq_restore(flags); - } - if (I_IXOFF(tty)) - scc_send_xchar(tty, START_CHAR(tty)); -} - - -static int scc_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; -} - - -static int scc_break_ctl(struct tty_struct *tty, int break_state) -{ - struct scc_port *port = tty->driver_data; - unsigned long flags; - SCC_ACCESS_INIT(port); - - local_irq_save(flags); - SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK, - break_state ? TCR_SEND_BREAK : 0); - local_irq_restore(flags); - return 0; -} - - -/*--------------------------------------------------------------------------- - * Serial console stuff... - *--------------------------------------------------------------------------*/ - -#define scc_delay() do { __asm__ __volatile__ (" nop; nop"); } while (0) - -static void scc_ch_write (char ch) -{ - volatile char *p = NULL; - -#ifdef CONFIG_MVME147_SCC - if (MACH_IS_MVME147) - p = (volatile char *)M147_SCC_A_ADDR; -#endif -#ifdef CONFIG_MVME162_SCC - if (MACH_IS_MVME16x) - p = (volatile char *)MVME_SCC_A_ADDR; -#endif -#ifdef CONFIG_BVME6000_SCC - if (MACH_IS_BVME6000) - p = (volatile char *)BVME_SCC_A_ADDR; -#endif - - do { - scc_delay(); - } - while (!(*p & 4)); - scc_delay(); - *p = 8; - scc_delay(); - *p = ch; -} - -/* The console must be locked when we get here. */ - -static void scc_console_write (struct console *co, const char *str, unsigned count) -{ - unsigned long flags; - - local_irq_save(flags); - - while (count--) - { - if (*str == '\n') - scc_ch_write ('\r'); - scc_ch_write (*str++); - } - local_irq_restore(flags); -} - -static struct tty_driver *scc_console_device(struct console *c, int *index) -{ - *index = c->index; - return scc_driver; -} - -static struct console sercons = { - .name = "ttyS", - .write = scc_console_write, - .device = scc_console_device, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - - -static int __init vme_scc_console_init(void) -{ - if (vme_brdtype == VME_TYPE_MVME147 || - vme_brdtype == VME_TYPE_MVME162 || - vme_brdtype == VME_TYPE_MVME172 || - vme_brdtype == VME_TYPE_BVME4000 || - vme_brdtype == VME_TYPE_BVME6000) - register_console(&sercons); - return 0; -} -console_initcall(vme_scc_console_init); diff --git a/drivers/staging/gma500/Kconfig b/drivers/staging/gma500/Kconfig index ce8bedaeaac2..bfe2166acda6 100644 --- a/drivers/staging/gma500/Kconfig +++ b/drivers/staging/gma500/Kconfig @@ -1,5 +1,5 @@ config DRM_PSB - tristate "Intel GMA500 KMS Framebuffer" + tristate "Intel GMA5/600 KMS Framebuffer" depends on DRM && PCI && X86 select FB_CFB_COPYAREA select FB_CFB_FILLRECT @@ -7,6 +7,27 @@ config DRM_PSB select DRM_KMS_HELPER select DRM_TTM help - Say yes for an experimental KMS framebuffer driver for the - Intel GMA500 ('Poulsbo') graphics support. + Say yes for an experimental 2D KMS framebuffer driver for the + Intel GMA500 ('Poulsbo') and other Intel IMG based graphics + devices. +config DRM_PSB_MRST + bool "Intel GMA600 support (Experimental)" + depends on DRM_PSB + help + Say yes to include support for GMA600 (Intel Moorestown/Oaktrail) + platforms with LVDS ports. HDMI and MIPI are not currently + supported. + +config DRM_PSB_MFLD + bool "Intel Medfield support (Experimental)" + depends on DRM_PSB + help + Say yes to include support for Intel Medfield platforms with MIPI + interfaces. + +config DRM_PSB_CDV + bool "Intel Cedarview support (Experimental)" + depends on DRM_PSB + help + Say yes to include support for Intel Cedarview platforms diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile index db73ec6d8128..c729868b1b10 100644 --- a/drivers/staging/gma500/Makefile +++ b/drivers/staging/gma500/Makefile @@ -3,24 +3,50 @@ # ccflags-y += -Iinclude/drm -psb_gfx-y += psb_bl.o \ +psb_gfx-y += gem_glue.o \ + accel_2d.o \ + backlight.o \ + framebuffer.o \ + gem.o \ + gtt.o \ + intel_bios.o \ + intel_i2c.o \ + intel_opregion.o \ + mmu.o \ + power.o \ psb_drv.o \ - psb_gem.o \ - psb_fb.o \ - psb_2d.o \ - psb_gtt.o \ - psb_intel_bios.o \ - psb_intel_opregion.o \ psb_intel_display.o \ - psb_intel_i2c.o \ psb_intel_lvds.o \ psb_intel_modes.o \ psb_intel_sdvo.o \ psb_lid.o \ - psb_mmu.o \ - psb_powermgmt.o \ psb_irq.o \ + psb_device.o \ + mid_bios.o + +psb_gfx-$(CONFIG_DRM_PSB_CDV) += cdv_device.o \ + cdv_intel_crt.o \ + cdv_intel_display.o \ + cdv_intel_hdmi.o \ + cdv_intel_lvds.o + +psb_gfx-$(CONFIG_DRM_PSB_MRST) += mrst_device.o \ mrst_crtc.o \ - mrst_lvds.o + mrst_lvds.o \ + mrst_hdmi.o \ + mrst_hdmi_i2c.o + +psb_gfx-$(CONFIG_DRM_PSB_MFLD) += mdfld_device.o \ + mdfld_output.o \ + mdfld_pyr_cmd.o \ + mdfld_tmd_vid.o \ + mdfld_tpo_cmd.o \ + mdfld_tpo_vid.o \ + mdfld_dsi_pkg_sender.o \ + mdfld_dsi_dpi.o \ + mdfld_dsi_output.o \ + mdfld_dsi_dbi.o \ + mdfld_dsi_dbi_dpu.o \ + mdfld_intel_display.o obj-$(CONFIG_DRM_PSB) += psb_gfx.o diff --git a/drivers/staging/gma500/TODO b/drivers/staging/gma500/TODO index f692ce1d2427..fc836158e74c 100644 --- a/drivers/staging/gma500/TODO +++ b/drivers/staging/gma500/TODO @@ -1,26 +1,15 @@ -- Test on more platforms -- Clean up the various chunks of unused code - Sort out the power management side. Not important for Poulsbo but - matters for Moorestown -- Add Moorestown support (single pipe, no BIOS, no stolen memory, - some other differences) -- Sort out the bo and ttm code to support userframe buffers and DRM - interfaces rather than just faking it enough for a framebuffer + matters for Moorestown/Medfield +- Debug Oaktrail/Moorestown support (single pipe, no BIOS on mrst, + some other differences) - Add 2D acceleration via console and DRM +- Add scrolling acceleration using the GTT to do remapping on the main + framebuffer. +- HDMI testing +- Oaktrail HDMI and other features +- Oaktrail MIPI +- Medfield needs a lot of further love As per kernel policy and the in the interest of the safety of various kittens there is no support or plans to add hooks for the closed user space stuff. - - -Why bother ? -- Proper display configuration -- Can be made to work on Moorestown where VESA won't -- Works on systems where the VESA BIOS is bust or the tables are broken - without hacks -- 2D acceleration - -Currently tested on -+ Dell Mini 10 100x600 - - diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/accel_2d.c similarity index 61% rename from drivers/staging/gma500/psb_2d.c rename to drivers/staging/gma500/accel_2d.c index 0bd834c982d3..14400fcfe8a7 100644 --- a/drivers/staging/gma500/psb_2d.c +++ b/drivers/staging/gma500/accel_2d.c @@ -1,5 +1,5 @@ /************************************************************************** - * Copyright (c) 2007, Intel Corporation. + * Copyright (c) 2007-2011, Intel Corporation. * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it @@ -38,16 +38,23 @@ #include "psb_drv.h" #include "psb_reg.h" -#include "psb_drv.h" -#include "psb_fb.h" +#include "framebuffer.h" +/** + * psb_spank - reset the 2D engine + * @dev_priv: our PSB DRM device + * + * Soft reset the graphics engine and then reload the necessary registers. + * We use this at initialisation time but it will become relevant for + * accelerated X later + */ void psb_spank(struct drm_psb_private *dev_priv) { - PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET | + PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET | _PSB_CS_RESET_TA_RESET | _PSB_CS_RESET_USE_RESET | _PSB_CS_RESET_ISP_RESET | _PSB_CS_RESET_TSP_RESET | _PSB_CS_RESET_TWOD_RESET, PSB_CR_SOFT_RESET); - (void) PSB_RSGX32(PSB_CR_SOFT_RESET); + PSB_RSGX32(PSB_CR_SOFT_RESET); msleep(1); @@ -62,16 +69,24 @@ void psb_spank(struct drm_psb_private *dev_priv) PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) & ~_PSB_CB_CTRL_CLEAR_FAULT, PSB_CR_BIF_CTRL); (void) PSB_RSGX32(PSB_CR_BIF_CTRL); - PSB_WSGX32(dev_priv->pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); + PSB_WSGX32(dev_priv->gtt.gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); } +/** + * psb2_2d_wait_available - wait for FIFO room + * @dev_priv: our DRM device + * @size: size (in dwords) of the command we want to issue + * + * Wait until there is room to load the FIFO with our data. If the + * device is not responding then reset it + */ static int psb_2d_wait_available(struct drm_psb_private *dev_priv, unsigned size) { uint32_t avail = PSB_RSGX32(PSB_CR_2D_SOCIF); unsigned long t = jiffies + HZ; - while(avail < size) { + while (avail < size) { avail = PSB_RSGX32(PSB_CR_2D_SOCIF); if (time_after(jiffies, t)) { psb_spank(dev_priv); @@ -81,151 +96,77 @@ static int psb_2d_wait_available(struct drm_psb_private *dev_priv, return 0; } -/* FIXME: Remember if we expose the 2D engine to the DRM we need to serialize - it with console use */ - -int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, - unsigned size) +/** + * psb_2d_submit - submit a 2D command + * @dev_priv: our DRM device + * @cmdbuf: command to issue + * @size: length (in dwords) + * + * Issue one or more 2D commands to the accelerator. This needs to be + * serialized later when we add the GEM interfaces for acceleration + */ +static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, + unsigned size) { int ret = 0; int i; unsigned submit_size; + mutex_lock(&dev_priv->mutex_2d); while (size > 0) { submit_size = (size < 0x60) ? size : 0x60; size -= submit_size; ret = psb_2d_wait_available(dev_priv, submit_size); if (ret) - return ret; + break; submit_size <<= 2; - for (i = 0; i < submit_size; i += 4) { + + for (i = 0; i < submit_size; i += 4) PSB_WSGX32(*cmdbuf++, PSB_SGX_2D_SLAVE_PORT + i); - } + (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4); } - return 0; + mutex_unlock(&dev_priv->mutex_2d); + return ret; } -static int psb_accel_2d_fillrect(struct drm_psb_private *dev_priv, - uint32_t dst_offset, uint32_t dst_stride, - uint32_t dst_format, uint16_t dst_x, - uint16_t dst_y, uint16_t size_x, - uint16_t size_y, uint32_t fill) -{ - uint32_t buffer[10]; - uint32_t *buf; - - buf = buffer; - - *buf++ = PSB_2D_FENCE_BH; - - *buf++ = - PSB_2D_DST_SURF_BH | dst_format | (dst_stride << - PSB_2D_DST_STRIDE_SHIFT); - *buf++ = dst_offset; - - *buf++ = - PSB_2D_BLIT_BH | - PSB_2D_ROT_NONE | - PSB_2D_COPYORDER_TL2BR | - PSB_2D_DSTCK_DISABLE | - PSB_2D_SRCCK_DISABLE | PSB_2D_USE_FILL | PSB_2D_ROP3_PATCOPY; - - *buf++ = fill << PSB_2D_FILLCOLOUR_SHIFT; - *buf++ = - (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y << - PSB_2D_DST_YSTART_SHIFT); - *buf++ = - (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y << - PSB_2D_DST_YSIZE_SHIFT); - *buf++ = PSB_2D_FLUSH_BH; - - return psbfb_2d_submit(dev_priv, buffer, buf - buffer); -} - -static void psbfb_fillrect_accel(struct fb_info *info, - const struct fb_fillrect *r) -{ - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = fbdev->pfb; - struct drm_device *dev = psbfb->base.dev; - struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; - struct drm_psb_private *dev_priv = dev->dev_private; - - uint32_t offset; - uint32_t stride; - uint32_t format; - - if (!fb) - return; - - offset = psbfb->gtt->offset; - stride = fb->pitch; - - switch (fb->depth) { - case 8: - format = PSB_2D_DST_332RGB; - break; - case 15: - format = PSB_2D_DST_555RGB; - break; - case 16: - format = PSB_2D_DST_565RGB; - break; - case 24: - case 32: - /* this is wrong but since we don't do blending its okay */ - format = PSB_2D_DST_8888ARGB; - break; - default: - /* software fallback */ - cfb_fillrect(info, r); - return; - } - - psb_accel_2d_fillrect(dev_priv, - offset, stride, format, - r->dx, r->dy, r->width, r->height, r->color); -} - -void psbfb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ - if (unlikely(info->state != FBINFO_STATE_RUNNING)) - return; - - if (1 || (info->flags & FBINFO_HWACCEL_DISABLED)) - return cfb_fillrect(info, rect); - - /*psb_check_power_state(dev, PSB_DEVICE_SGX); */ - psbfb_fillrect_accel(info, rect); - /* Drop power again here on MRST FIXMEAC */ -} +/** + * psb_accel_2d_copy_direction - compute blit order + * @xdir: X direction of move + * @ydir: Y direction of move + * + * Compute the correct order setings to ensure that an overlapping blit + * correctly copies all the pixels. + */ static u32 psb_accel_2d_copy_direction(int xdir, int ydir) { if (xdir < 0) return (ydir < 0) ? PSB_2D_COPYORDER_BR2TL : - PSB_2D_COPYORDER_TR2BL; + PSB_2D_COPYORDER_TR2BL; else return (ydir < 0) ? PSB_2D_COPYORDER_BL2TR : - PSB_2D_COPYORDER_TL2BR; + PSB_2D_COPYORDER_TL2BR; } -/* - * @src_offset in bytes - * @src_stride in bytes - * @src_format psb 2D format defines - * @dst_offset in bytes - * @dst_stride in bytes - * @dst_format psb 2D format defines - * @src_x offset in pixels - * @src_y offset in pixels - * @dst_x offset in pixels - * @dst_y offset in pixels - * @size_x of the copied area - * @size_y of the copied area +/** + * psb_accel_2d_copy - accelerated 2D copy + * @dev_priv: our DRM device + * @src_offset in bytes + * @src_stride in bytes + * @src_format psb 2D format defines + * @dst_offset in bytes + * @dst_stride in bytes + * @dst_format psb 2D format defines + * @src_x offset in pixels + * @src_y offset in pixels + * @dst_x offset in pixels + * @dst_y offset in pixels + * @size_x of the copied area + * @size_y of the copied area + * + * Format and issue a 2D accelerated copy command. */ static int psb_accel_2d_copy(struct drm_psb_private *dev_priv, uint32_t src_offset, uint32_t src_stride, @@ -287,11 +228,18 @@ static int psb_accel_2d_copy(struct drm_psb_private *dev_priv, return psbfb_2d_submit(dev_priv, buffer, buf - buffer); } +/** + * psbfb_copyarea_accel - copyarea acceleration for /dev/fb + * @info: our framebuffer + * @a: copyarea parameters from the framebuffer core + * + * Perform a 2D copy via the accelerator + */ static void psbfb_copyarea_accel(struct fb_info *info, const struct fb_copyarea *a) { struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = fbdev->pfb; + struct psb_framebuffer *psbfb = &fbdev->pfb; struct drm_device *dev = psbfb->base.dev; struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb; struct drm_psb_private *dev_priv = dev->dev_private; @@ -331,48 +279,56 @@ static void psbfb_copyarea_accel(struct fb_info *info, return; } + if (!gma_power_begin(dev, false)) { + cfb_copyarea(info, a); + return; + } psb_accel_2d_copy(dev_priv, offset, stride, src_format, offset, stride, dst_format, a->sx, a->sy, a->dx, a->dy, a->width, a->height); + gma_power_end(dev); } +/** + * psbfb_copyarea - 2D copy interface + * @info: our framebuffer + * @region: region to copy + * + * Copy an area of the framebuffer console either by the accelerator + * or directly using the cfb helpers according to the request + */ void psbfb_copyarea(struct fb_info *info, const struct fb_copyarea *region) { if (unlikely(info->state != FBINFO_STATE_RUNNING)) return; - if (info->flags & FBINFO_HWACCEL_DISABLED) + /* Avoid the 8 pixel erratum */ + if (region->width == 8 || region->height == 8 || + (info->flags & FBINFO_HWACCEL_DISABLED)) return cfb_copyarea(info, region); - /* psb_check_power_state(dev, PSB_DEVICE_SGX); */ psbfb_copyarea_accel(info, region); - /* Need to power back off here for MRST FIXMEAC */ -} - -void psbfb_imageblit(struct fb_info *info, const struct fb_image *image) -{ - /* For now */ - cfb_imageblit(info, image); } +/** + * psbfb_sync - synchronize 2D + * @info: our framebuffer + * + * Wait for the 2D engine to quiesce so that we can do CPU + * access to the framebuffer again + */ int psbfb_sync(struct fb_info *info) { struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = fbdev->pfb; + struct psb_framebuffer *psbfb = &fbdev->pfb; struct drm_device *dev = psbfb->base.dev; struct drm_psb_private *dev_priv = dev->dev_private; unsigned long _end = jiffies + DRM_HZ; int busy = 0; -#if 0 - /* Just a way to quickly test if cmd issue explodes */ - u32 test[2] = { - PSB_2D_FENCE_BH, - }; - psbfb_2d_submit(dev_priv, test, 1); -#endif + mutex_lock(&dev_priv->mutex_2d); /* * First idle the 2D engine. */ @@ -401,10 +357,56 @@ int psbfb_sync(struct fb_info *info) _PSB_C2B_STATUS_BUSY) != 0); out: + mutex_unlock(&dev_priv->mutex_2d); return (busy) ? -EBUSY : 0; } -/* - info->fix.accel = FB_ACCEL_I830; - info->flags = FBINFO_DEFAULT; -*/ +int psb_accel_ioctl(struct drm_device *dev, void *data, struct drm_file *file) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_psb_2d_op *op = data; + u32 *op_ptr = &op->cmd[0]; + int i; + struct drm_gem_object *obj; + struct gtt_range *gtt; + int err = -EINVAL; + + if (!dev_priv->ops->accel_2d) + return -EOPNOTSUPP; + if (op->size > PSB_2D_OP_BUFLEN) + return -EINVAL; + + /* The GEM object being used. We need to support separate src/dst/etc + in the end but for now keep them all the same */ + obj = drm_gem_object_lookup(dev, file, op->src); + if (obj == NULL) + return -ENOENT; + gtt = container_of(obj, struct gtt_range, gem); + + if (psb_gtt_pin(gtt) < 0) + goto bad_2; + for (i = 0; i < op->size; i++, op_ptr++) { + u32 r = *op_ptr & 0xF0000000; + /* Fill in the GTT offsets for the command buffer */ + if (r == PSB_2D_SRC_SURF_BH || + r == PSB_2D_DST_SURF_BH || + r == PSB_2D_MASK_SURF_BH || + r == PSB_2D_PAT_SURF_BH) { + i++; + op_ptr++; + if (i == op->size) + goto bad; + if (*op_ptr) + goto bad; + *op_ptr = gtt->offset; + continue; + } + } + psbfb_2d_submit(dev_priv, op->cmd, op->size); + err = 0; +bad: + psb_gtt_unpin(gtt); +bad_2: + drm_gem_object_unreference(obj); + return err; +} diff --git a/drivers/staging/gma500/backlight.c b/drivers/staging/gma500/backlight.c new file mode 100644 index 000000000000..20793951fcac --- /dev/null +++ b/drivers/staging/gma500/backlight.c @@ -0,0 +1,49 @@ +/* + * GMA500 Backlight Interface + * + * Copyright (c) 2009-2011, Intel 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., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: Eric Knopp + * + */ + +#include "psb_drv.h" +#include "psb_intel_reg.h" +#include "psb_intel_drv.h" +#include "intel_bios.h" +#include "power.h" + +int gma_backlight_init(struct drm_device *dev) +{ +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + struct drm_psb_private *dev_priv = dev->dev_private; + return dev_priv->ops->backlight_init(dev); +#else + return 0; +#endif +} + +void gma_backlight_exit(struct drm_device *dev) +{ +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + struct drm_psb_private *dev_priv = dev->dev_private; + if (dev_priv->backlight_device) { + dev_priv->backlight_device->props.brightness = 0; + backlight_update_status(dev_priv->backlight_device); + backlight_device_unregister(dev_priv->backlight_device); + } +#endif +} diff --git a/drivers/staging/gma500/cdv_device.c b/drivers/staging/gma500/cdv_device.c new file mode 100644 index 000000000000..87614e0d396a --- /dev/null +++ b/drivers/staging/gma500/cdv_device.c @@ -0,0 +1,351 @@ +/************************************************************************** + * Copyright (c) 2011, Intel Corporation. + * All Rights Reserved. + * + * 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. + * + **************************************************************************/ + +#include +#include +#include +#include "psb_drm.h" +#include "psb_drv.h" +#include "psb_reg.h" +#include "psb_intel_reg.h" +#include "intel_bios.h" +#include "cdv_device.h" + +#define VGA_SR_INDEX 0x3c4 +#define VGA_SR_DATA 0x3c5 + +/* FIXME: should check if we are the active VGA device ?? */ +static void cdv_disable_vga(struct drm_device *dev) +{ + u8 sr1; + u32 vga_reg; + + vga_reg = VGACNTRL; + + outb(1, VGA_SR_INDEX); + sr1 = inb(VGA_SR_DATA); + outb(sr1 | 1<<5, VGA_SR_DATA); + udelay(300); + + REG_WRITE(vga_reg, VGA_DISP_DISABLE); + REG_READ(vga_reg); +} + +static int cdv_output_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + cdv_disable_vga(dev); + + cdv_intel_crt_init(dev, &dev_priv->mode_dev); + cdv_intel_lvds_init(dev, &dev_priv->mode_dev); + + /* These bits indicate HDMI not SDVO on CDV, but we don't yet support + the HDMI interface */ + if (REG_READ(SDVOB) & SDVO_DETECTED) + cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB); + if (REG_READ(SDVOC) & SDVO_DETECTED) + cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOC); + return 0; +} + +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + +/* + * Poulsbo Backlight Interfaces + */ + +#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ +#define BLC_PWM_FREQ_CALC_CONSTANT 32 +#define MHz 1000000 + +#define PSB_BLC_PWM_PRECISION_FACTOR 10 +#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE +#define PSB_BLC_MIN_PWM_REG_FREQ 0x2 + +#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) +#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) + +static int cdv_brightness; +static struct backlight_device *cdv_backlight_device; + +static int cdv_get_brightness(struct backlight_device *bd) +{ + /* return locally cached var instead of HW read (due to DPST etc.) */ + /* FIXME: ideally return actual value in case firmware fiddled with + it */ + return cdv_brightness; +} + + +static int cdv_backlight_setup(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + unsigned long core_clock; + /* u32 bl_max_freq; */ + /* unsigned long value; */ + u16 bl_max_freq; + uint32_t value; + uint32_t blc_pwm_precision_factor; + + /* get bl_max_freq and pol from dev_priv*/ + if (!dev_priv->lvds_bl) { + dev_err(dev->dev, "Has no valid LVDS backlight info\n"); + return -ENOENT; + } + bl_max_freq = dev_priv->lvds_bl->freq; + blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR; + + core_clock = dev_priv->core_freq; + + value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; + value *= blc_pwm_precision_factor; + value /= bl_max_freq; + value /= blc_pwm_precision_factor; + + if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || + value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) + return -ERANGE; + else { + /* FIXME */ + } + return 0; +} + +static int cdv_set_brightness(struct backlight_device *bd) +{ + int level = bd->props.brightness; + + /* Percentage 1-100% being valid */ + if (level < 1) + level = 1; + + /*cdv_intel_lvds_set_brightness(dev, level); FIXME */ + cdv_brightness = level; + return 0; +} + +static const struct backlight_ops cdv_ops = { + .get_brightness = cdv_get_brightness, + .update_status = cdv_set_brightness, +}; + +static int cdv_backlight_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + int ret; + struct backlight_properties props; + + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 100; + props.type = BACKLIGHT_PLATFORM; + + cdv_backlight_device = backlight_device_register("psb-bl", + NULL, (void *)dev, &cdv_ops, &props); + if (IS_ERR(cdv_backlight_device)) + return PTR_ERR(cdv_backlight_device); + + ret = cdv_backlight_setup(dev); + if (ret < 0) { + backlight_device_unregister(cdv_backlight_device); + cdv_backlight_device = NULL; + return ret; + } + cdv_backlight_device->props.brightness = 100; + cdv_backlight_device->props.max_brightness = 100; + backlight_update_status(cdv_backlight_device); + dev_priv->backlight_device = cdv_backlight_device; + return 0; +} + +#endif + +/* + * Provide the Cedarview specific chip logic and low level methods + * for power management + * + * FIXME: we need to implement the apm/ospm base management bits + * for this and the MID devices. + */ + +static inline u32 CDV_MSG_READ32(uint port, uint offset) +{ + int mcr = (0x10<<24) | (port << 16) | (offset << 8); + uint32_t ret_val = 0; + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); + pci_write_config_dword(pci_root, 0xD0, mcr); + pci_read_config_dword(pci_root, 0xD4, &ret_val); + pci_dev_put(pci_root); + return ret_val; +} + +static inline void CDV_MSG_WRITE32(uint port, uint offset, u32 value) +{ + int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0; + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); + pci_write_config_dword(pci_root, 0xD4, value); + pci_write_config_dword(pci_root, 0xD0, mcr); + pci_dev_put(pci_root); +} + +#define PSB_APM_CMD 0x0 +#define PSB_APM_STS 0x04 +#define PSB_PM_SSC 0x20 +#define PSB_PM_SSS 0x30 +#define PSB_PWRGT_GFX_MASK 0x3 +#define CDV_PWRGT_DISPLAY_CNTR 0x000fc00c +#define CDV_PWRGT_DISPLAY_STS 0x000fc00c + +static void cdv_init_pm(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + u32 pwr_cnt; + int i; + + dev_priv->apm_base = CDV_MSG_READ32(PSB_PUNIT_PORT, + PSB_APMBA) & 0xFFFF; + dev_priv->ospm_base = CDV_MSG_READ32(PSB_PUNIT_PORT, + PSB_OSPMBA) & 0xFFFF; + + /* Force power on for now */ + pwr_cnt = inl(dev_priv->apm_base + PSB_APM_CMD); + pwr_cnt &= ~PSB_PWRGT_GFX_MASK; + + outl(pwr_cnt, dev_priv->apm_base + PSB_APM_CMD); + for (i = 0; i < 5; i++) { + u32 pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS); + if ((pwr_sts & PSB_PWRGT_GFX_MASK) == 0) + break; + udelay(10); + } + pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC); + pwr_cnt &= ~CDV_PWRGT_DISPLAY_CNTR; + outl(pwr_cnt, dev_priv->ospm_base + PSB_PM_SSC); + for (i = 0; i < 5; i++) { + u32 pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); + if ((pwr_sts & CDV_PWRGT_DISPLAY_STS) == 0) + break; + udelay(10); + } +} + +/** + * cdv_save_display_registers - save registers lost on suspend + * @dev: our DRM device + * + * Save the state we need in order to be able to restore the interface + * upon resume from suspend + * + * FIXME: review + */ +static int cdv_save_display_registers(struct drm_device *dev) +{ + return 0; +} + +/** + * cdv_restore_display_registers - restore lost register state + * @dev: our DRM device + * + * Restore register state that was lost during suspend and resume. + * + * FIXME: review + */ +static int cdv_restore_display_registers(struct drm_device *dev) +{ + return 0; +} + +static int cdv_power_down(struct drm_device *dev) +{ + return 0; +} + +static int cdv_power_up(struct drm_device *dev) +{ + return 0; +} + +/* FIXME ? - shared with Poulsbo */ +static void cdv_get_core_freq(struct drm_device *dev) +{ + uint32_t clock; + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); + struct drm_psb_private *dev_priv = dev->dev_private; + + pci_write_config_dword(pci_root, 0xD0, 0xD0050300); + pci_read_config_dword(pci_root, 0xD4, &clock); + pci_dev_put(pci_root); + + switch (clock & 0x07) { + case 0: + dev_priv->core_freq = 100; + break; + case 1: + dev_priv->core_freq = 133; + break; + case 2: + dev_priv->core_freq = 150; + break; + case 3: + dev_priv->core_freq = 178; + break; + case 4: + dev_priv->core_freq = 200; + break; + case 5: + case 6: + case 7: + dev_priv->core_freq = 266; + default: + dev_priv->core_freq = 0; + } +} + +static int cdv_chip_setup(struct drm_device *dev) +{ + cdv_get_core_freq(dev); + gma_intel_opregion_init(dev); + psb_intel_init_bios(dev); + return 0; +} + +/* CDV is much like Poulsbo but has MID like SGX offsets and PM */ + +const struct psb_ops cdv_chip_ops = { + .name = "Cedartrail", + .accel_2d = 0, + .pipes = 2, + .sgx_offset = MRST_SGX_OFFSET, + .chip_setup = cdv_chip_setup, + + .crtc_helper = &cdv_intel_helper_funcs, + .crtc_funcs = &cdv_intel_crtc_funcs, + + .output_init = cdv_output_init, + +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + .backlight_init = cdv_backlight_init, +#endif + + .init_pm = cdv_init_pm, + .save_regs = cdv_save_display_registers, + .restore_regs = cdv_restore_display_registers, + .power_down = cdv_power_down, + .power_up = cdv_power_up, +}; diff --git a/drivers/staging/gma500/cdv_device.h b/drivers/staging/gma500/cdv_device.h new file mode 100644 index 000000000000..2a88b7beb551 --- /dev/null +++ b/drivers/staging/gma500/cdv_device.h @@ -0,0 +1,36 @@ +/* + * Copyright © 2011 Intel 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., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +extern const struct drm_crtc_helper_funcs cdv_intel_helper_funcs; +extern const struct drm_crtc_funcs cdv_intel_crtc_funcs; +extern void cdv_intel_crt_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev); +extern void cdv_intel_lvds_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev); +extern void cdv_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev, + int reg); +extern struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev, + struct drm_crtc *crtc); + +extern inline void cdv_intel_wait_for_vblank(struct drm_device *dev) +{ + /* Wait for 20ms, i.e. one cycle at 50hz. */ + /* FIXME: msleep ?? */ + mdelay(20); +} + + diff --git a/drivers/staging/gma500/cdv_intel_crt.c b/drivers/staging/gma500/cdv_intel_crt.c new file mode 100644 index 000000000000..efda63b97b45 --- /dev/null +++ b/drivers/staging/gma500/cdv_intel_crt.c @@ -0,0 +1,326 @@ +/* + * Copyright © 2006-2007 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 + */ + +#include +#include + +#include "intel_bios.h" +#include "psb_drv.h" +#include "psb_intel_drv.h" +#include "psb_intel_reg.h" +#include "power.h" +#include + + +static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode) +{ + struct drm_device *dev = encoder->dev; + u32 temp, reg; + reg = ADPA; + + temp = REG_READ(reg); + temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); + temp &= ~ADPA_DAC_ENABLE; + + switch (mode) { + case DRM_MODE_DPMS_ON: + temp |= ADPA_DAC_ENABLE; + break; + case DRM_MODE_DPMS_STANDBY: + temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE; + break; + case DRM_MODE_DPMS_SUSPEND: + temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE; + break; + case DRM_MODE_DPMS_OFF: + temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE; + break; + } + + REG_WRITE(reg, temp); +} + +static int cdv_intel_crt_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + int max_clock = 0; + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + + /* The lowest clock for CDV is 20000KHz */ + if (mode->clock < 20000) + return MODE_CLOCK_LOW; + + /* The max clock for CDV is 355 instead of 400 */ + max_clock = 355000; + if (mode->clock > max_clock) + return MODE_CLOCK_HIGH; + + if (mode->hdisplay > 1680 || mode->vdisplay > 1050) + return MODE_PANEL; + + return MODE_OK; +} + +static bool cdv_intel_crt_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static void cdv_intel_crt_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + + struct drm_device *dev = encoder->dev; + struct drm_crtc *crtc = encoder->crtc; + struct psb_intel_crtc *psb_intel_crtc = + to_psb_intel_crtc(crtc); + int dpll_md_reg; + u32 adpa, dpll_md; + u32 adpa_reg; + + if (psb_intel_crtc->pipe == 0) + dpll_md_reg = DPLL_A_MD; + else + dpll_md_reg = DPLL_B_MD; + + adpa_reg = ADPA; + + /* + * Disable separate mode multiplier used when cloning SDVO to CRT + * XXX this needs to be adjusted when we really are cloning + */ + { + dpll_md = REG_READ(dpll_md_reg); + REG_WRITE(dpll_md_reg, + dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); + } + + adpa = 0; + if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) + adpa |= ADPA_HSYNC_ACTIVE_HIGH; + if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) + adpa |= ADPA_VSYNC_ACTIVE_HIGH; + + if (psb_intel_crtc->pipe == 0) + adpa |= ADPA_PIPE_A_SELECT; + else + adpa |= ADPA_PIPE_B_SELECT; + + REG_WRITE(adpa_reg, adpa); +} + + +/** + * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence. + * + * \return true if CRT is connected. + * \return false if CRT is disconnected. + */ +static bool cdv_intel_crt_detect_hotplug(struct drm_connector *connector, + bool force) +{ + struct drm_device *dev = connector->dev; + u32 hotplug_en; + int i, tries = 0, ret = false; + u32 adpa_orig; + + /* disable the DAC when doing the hotplug detection */ + + adpa_orig = REG_READ(ADPA); + + REG_WRITE(ADPA, adpa_orig & ~(ADPA_DAC_ENABLE)); + + /* + * On a CDV thep, CRT detect sequence need to be done twice + * to get a reliable result. + */ + tries = 2; + + hotplug_en = REG_READ(PORT_HOTPLUG_EN); + hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK); + hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; + + hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; + hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; + + for (i = 0; i < tries ; i++) { + unsigned long timeout; + /* turn on the FORCE_DETECT */ + REG_WRITE(PORT_HOTPLUG_EN, hotplug_en); + timeout = jiffies + msecs_to_jiffies(1000); + /* wait for FORCE_DETECT to go off */ + do { + if (!(REG_READ(PORT_HOTPLUG_EN) & + CRT_HOTPLUG_FORCE_DETECT)) + break; + msleep(1); + } while (time_after(timeout, jiffies)); + } + + if ((REG_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) != + CRT_HOTPLUG_MONITOR_NONE) + ret = true; + + /* Restore the saved ADPA */ + REG_WRITE(ADPA, adpa_orig); + return ret; +} + +static enum drm_connector_status cdv_intel_crt_detect( + struct drm_connector *connector, bool force) +{ + if (cdv_intel_crt_detect_hotplug(connector, force)) + return connector_status_connected; + else + return connector_status_disconnected; +} + +static void cdv_intel_crt_destroy(struct drm_connector *connector) +{ + struct psb_intel_output *intel_output = to_psb_intel_output(connector); + + psb_intel_i2c_destroy(intel_output->ddc_bus); + drm_sysfs_connector_remove(connector); + drm_connector_cleanup(connector); + kfree(connector); +} + +static int cdv_intel_crt_get_modes(struct drm_connector *connector) +{ + struct psb_intel_output *intel_output = + to_psb_intel_output(connector); + return psb_intel_ddc_get_modes(intel_output); +} + +static int cdv_intel_crt_set_property(struct drm_connector *connector, + struct drm_property *property, + uint64_t value) +{ + return 0; +} + +/* + * Routines for controlling stuff on the analog port + */ + +static const struct drm_encoder_helper_funcs cdv_intel_crt_helper_funcs = { + .dpms = cdv_intel_crt_dpms, + .mode_fixup = cdv_intel_crt_mode_fixup, + .prepare = psb_intel_encoder_prepare, + .commit = psb_intel_encoder_commit, + .mode_set = cdv_intel_crt_mode_set, +}; + +static const struct drm_connector_funcs cdv_intel_crt_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .detect = cdv_intel_crt_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = cdv_intel_crt_destroy, + .set_property = cdv_intel_crt_set_property, +}; + +static const struct drm_connector_helper_funcs + cdv_intel_crt_connector_helper_funcs = { + .mode_valid = cdv_intel_crt_mode_valid, + .get_modes = cdv_intel_crt_get_modes, + .best_encoder = psb_intel_best_encoder, +}; + +static void cdv_intel_crt_enc_destroy(struct drm_encoder *encoder) +{ + drm_encoder_cleanup(encoder); +} + +static const struct drm_encoder_funcs cdv_intel_crt_enc_funcs = { + .destroy = cdv_intel_crt_enc_destroy, +}; + +void cdv_intel_crt_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev) +{ + + struct psb_intel_output *psb_intel_output; + struct drm_connector *connector; + struct drm_encoder *encoder; + + u32 i2c_reg; + + psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL); + if (!psb_intel_output) + return; + + psb_intel_output->mode_dev = mode_dev; + connector = &psb_intel_output->base; + drm_connector_init(dev, connector, + &cdv_intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); + + encoder = &psb_intel_output->enc; + drm_encoder_init(dev, encoder, + &cdv_intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC); + + drm_mode_connector_attach_encoder(&psb_intel_output->base, + &psb_intel_output->enc); + + /* Set up the DDC bus. */ + i2c_reg = GPIOA; + /* Remove the following code for CDV */ + /* + if (dev_priv->crt_ddc_bus != 0) + i2c_reg = dev_priv->crt_ddc_bus; + }*/ + psb_intel_output->ddc_bus = psb_intel_i2c_create(dev, + i2c_reg, "CRTDDC_A"); + if (!psb_intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " + "failed.\n"); + goto failed_ddc; + } + + psb_intel_output->type = INTEL_OUTPUT_ANALOG; + /* + psb_intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT); + psb_intel_output->crtc_mask = (1 << 0) | (1 << 1); + */ + connector->interlace_allowed = 0; + connector->doublescan_allowed = 0; + + drm_encoder_helper_add(encoder, &cdv_intel_crt_helper_funcs); + drm_connector_helper_add(connector, + &cdv_intel_crt_connector_helper_funcs); + + drm_sysfs_connector_add(connector); + + return; +failed_ddc: + drm_encoder_cleanup(&psb_intel_output->enc); + drm_connector_cleanup(&psb_intel_output->base); + kfree(psb_intel_output); + return; +} diff --git a/drivers/staging/gma500/cdv_intel_display.c b/drivers/staging/gma500/cdv_intel_display.c new file mode 100644 index 000000000000..7b97c600eff0 --- /dev/null +++ b/drivers/staging/gma500/cdv_intel_display.c @@ -0,0 +1,1508 @@ +/* + * Copyright © 2006-2011 Intel 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., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + */ + +#include +#include + +#include +#include "framebuffer.h" +#include "psb_drv.h" +#include "psb_intel_drv.h" +#include "psb_intel_reg.h" +#include "psb_intel_display.h" +#include "power.h" +#include "cdv_device.h" + + +struct cdv_intel_range_t { + int min, max; +}; + +struct cdv_intel_p2_t { + int dot_limit; + int p2_slow, p2_fast; +}; + +struct cdv_intel_clock_t { + /* given values */ + int n; + int m1, m2; + int p1, p2; + /* derived values */ + int dot; + int vco; + int m; + int p; +}; + +#define INTEL_P2_NUM 2 + +struct cdv_intel_limit_t { + struct cdv_intel_range_t dot, vco, n, m, m1, m2, p, p1; + struct cdv_intel_p2_t p2; +}; + +#define CDV_LIMIT_SINGLE_LVDS_96 0 +#define CDV_LIMIT_SINGLE_LVDS_100 1 +#define CDV_LIMIT_DAC_HDMI_27 2 +#define CDV_LIMIT_DAC_HDMI_96 3 + +static const struct cdv_intel_limit_t cdv_intel_limits[] = { + { /* CDV_SIGNLE_LVDS_96MHz */ + .dot = {.min = 20000, .max = 115500}, + .vco = {.min = 1800000, .max = 3600000}, + .n = {.min = 2, .max = 6}, + .m = {.min = 60, .max = 160}, + .m1 = {.min = 0, .max = 0}, + .m2 = {.min = 58, .max = 158}, + .p = {.min = 28, .max = 140}, + .p1 = {.min = 2, .max = 10}, + .p2 = {.dot_limit = 200000, + .p2_slow = 14, .p2_fast = 14}, + }, + { /* CDV_SINGLE_LVDS_100MHz */ + .dot = {.min = 20000, .max = 115500}, + .vco = {.min = 1800000, .max = 3600000}, + .n = {.min = 2, .max = 6}, + .m = {.min = 60, .max = 160}, + .m1 = {.min = 0, .max = 0}, + .m2 = {.min = 58, .max = 158}, + .p = {.min = 28, .max = 140}, + .p1 = {.min = 2, .max = 10}, + /* The single-channel range is 25-112Mhz, and dual-channel + * is 80-224Mhz. Prefer single channel as much as possible. + */ + .p2 = {.dot_limit = 200000, .p2_slow = 14, .p2_fast = 14}, + }, + { /* CDV_DAC_HDMI_27MHz */ + .dot = {.min = 20000, .max = 400000}, + .vco = {.min = 1809000, .max = 3564000}, + .n = {.min = 1, .max = 1}, + .m = {.min = 67, .max = 132}, + .m1 = {.min = 0, .max = 0}, + .m2 = {.min = 65, .max = 130}, + .p = {.min = 5, .max = 90}, + .p1 = {.min = 1, .max = 9}, + .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5}, + }, + { /* CDV_DAC_HDMI_96MHz */ + .dot = {.min = 20000, .max = 400000}, + .vco = {.min = 1800000, .max = 3600000}, + .n = {.min = 2, .max = 6}, + .m = {.min = 60, .max = 160}, + .m1 = {.min = 0, .max = 0}, + .m2 = {.min = 58, .max = 158}, + .p = {.min = 5, .max = 100}, + .p1 = {.min = 1, .max = 10}, + .p2 = {.dot_limit = 225000, .p2_slow = 10, .p2_fast = 5}, + }, +}; + +#define _wait_for(COND, MS, W) ({ \ + unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ + int ret__ = 0; \ + while (!(COND)) { \ + if (time_after(jiffies, timeout__)) { \ + ret__ = -ETIMEDOUT; \ + break; \ + } \ + if (W && !in_dbg_master()) \ + msleep(W); \ + } \ + ret__; \ +}) + +#define wait_for(COND, MS) _wait_for(COND, MS, 1) + + +static int cdv_sb_read(struct drm_device *dev, u32 reg, u32 *val) +{ + int ret; + + ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000); + if (ret) { + DRM_ERROR("timeout waiting for SB to idle before read\n"); + return ret; + } + + REG_WRITE(SB_ADDR, reg); + REG_WRITE(SB_PCKT, + SET_FIELD(SB_OPCODE_READ, SB_OPCODE) | + SET_FIELD(SB_DEST_DPLL, SB_DEST) | + SET_FIELD(0xf, SB_BYTE_ENABLE)); + + ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000); + if (ret) { + DRM_ERROR("timeout waiting for SB to idle after read\n"); + return ret; + } + + *val = REG_READ(SB_DATA); + + return 0; +} + +static int cdv_sb_write(struct drm_device *dev, u32 reg, u32 val) +{ + int ret; + static bool dpio_debug = true; + u32 temp; + + if (dpio_debug) { + if (cdv_sb_read(dev, reg, &temp) == 0) + DRM_DEBUG_KMS("0x%08x: 0x%08x (before)\n", reg, temp); + DRM_DEBUG_KMS("0x%08x: 0x%08x\n", reg, val); + } + + ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000); + if (ret) { + DRM_ERROR("timeout waiting for SB to idle before write\n"); + return ret; + } + + REG_WRITE(SB_ADDR, reg); + REG_WRITE(SB_DATA, val); + REG_WRITE(SB_PCKT, + SET_FIELD(SB_OPCODE_WRITE, SB_OPCODE) | + SET_FIELD(SB_DEST_DPLL, SB_DEST) | + SET_FIELD(0xf, SB_BYTE_ENABLE)); + + ret = wait_for((REG_READ(SB_PCKT) & SB_BUSY) == 0, 1000); + if (ret) { + DRM_ERROR("timeout waiting for SB to idle after write\n"); + return ret; + } + + if (dpio_debug) { + if (cdv_sb_read(dev, reg, &temp) == 0) + DRM_DEBUG_KMS("0x%08x: 0x%08x (after)\n", reg, temp); + } + + return 0; +} + +/* Reset the DPIO configuration register. The BIOS does this at every + * mode set. + */ +static void cdv_sb_reset(struct drm_device *dev) +{ + + REG_WRITE(DPIO_CFG, 0); + REG_READ(DPIO_CFG); + REG_WRITE(DPIO_CFG, DPIO_MODE_SELECT_0 | DPIO_CMN_RESET_N); +} + +/* Unlike most Intel display engines, on Cedarview the DPLL registers + * are behind this sideband bus. They must be programmed while the + * DPLL reference clock is on in the DPLL control register, but before + * the DPLL is enabled in the DPLL control register. + */ +static int +cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, + struct cdv_intel_clock_t *clock) +{ + struct psb_intel_crtc *psb_crtc = + to_psb_intel_crtc(crtc); + int pipe = psb_crtc->pipe; + u32 m, n_vco, p; + int ret = 0; + int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; + u32 ref_value; + + cdv_sb_reset(dev); + + if ((REG_READ(dpll_reg) & DPLL_SYNCLOCK_ENABLE) == 0) { + DRM_ERROR("Attempting to set DPLL with refclk disabled\n"); + return -EBUSY; + } + + /* Follow the BIOS and write the REF/SFR Register. Hardcoded value */ + ref_value = 0x68A701; + + cdv_sb_write(dev, SB_REF_SFR(pipe), ref_value); + + /* We don't know what the other fields of these regs are, so + * leave them in place. + */ + ret = cdv_sb_read(dev, SB_M(pipe), &m); + if (ret) + return ret; + m &= ~SB_M_DIVIDER_MASK; + m |= ((clock->m2) << SB_M_DIVIDER_SHIFT); + ret = cdv_sb_write(dev, SB_M(pipe), m); + if (ret) + return ret; + + ret = cdv_sb_read(dev, SB_N_VCO(pipe), &n_vco); + if (ret) + return ret; + + /* Follow the BIOS to program the N_DIVIDER REG */ + n_vco &= 0xFFFF; + n_vco |= 0x107; + n_vco &= ~(SB_N_VCO_SEL_MASK | + SB_N_DIVIDER_MASK | + SB_N_CB_TUNE_MASK); + + n_vco |= ((clock->n) << SB_N_DIVIDER_SHIFT); + + if (clock->vco < 2250000) { + n_vco |= (2 << SB_N_CB_TUNE_SHIFT); + n_vco |= (0 << SB_N_VCO_SEL_SHIFT); + } else if (clock->vco < 2750000) { + n_vco |= (1 << SB_N_CB_TUNE_SHIFT); + n_vco |= (1 << SB_N_VCO_SEL_SHIFT); + } else if (clock->vco < 3300000) { + n_vco |= (0 << SB_N_CB_TUNE_SHIFT); + n_vco |= (2 << SB_N_VCO_SEL_SHIFT); + } else { + n_vco |= (0 << SB_N_CB_TUNE_SHIFT); + n_vco |= (3 << SB_N_VCO_SEL_SHIFT); + } + + ret = cdv_sb_write(dev, SB_N_VCO(pipe), n_vco); + if (ret) + return ret; + + ret = cdv_sb_read(dev, SB_P(pipe), &p); + if (ret) + return ret; + p &= ~(SB_P2_DIVIDER_MASK | SB_P1_DIVIDER_MASK); + p |= SET_FIELD(clock->p1, SB_P1_DIVIDER); + switch (clock->p2) { + case 5: + p |= SET_FIELD(SB_P2_5, SB_P2_DIVIDER); + break; + case 10: + p |= SET_FIELD(SB_P2_10, SB_P2_DIVIDER); + break; + case 14: + p |= SET_FIELD(SB_P2_14, SB_P2_DIVIDER); + break; + case 7: + p |= SET_FIELD(SB_P2_7, SB_P2_DIVIDER); + break; + default: + DRM_ERROR("Bad P2 clock: %d\n", clock->p2); + return -EINVAL; + } + ret = cdv_sb_write(dev, SB_P(pipe), p); + if (ret) + return ret; + + /* always Program the Lane Register for the Pipe A*/ + if (pipe == 0) { + /* Program the Lane0/1 for HDMI B */ + u32 lane_reg, lane_value; + + lane_reg = PSB_LANE0; + cdv_sb_read(dev, lane_reg, &lane_value); + lane_value &= ~(LANE_PLL_MASK); + lane_value |= LANE_PLL_ENABLE; + cdv_sb_write(dev, lane_reg, lane_value); + + lane_reg = PSB_LANE1; + cdv_sb_read(dev, lane_reg, &lane_value); + lane_value &= ~(LANE_PLL_MASK); + lane_value |= LANE_PLL_ENABLE; + cdv_sb_write(dev, lane_reg, lane_value); + + /* Program the Lane2/3 for HDMI C */ + lane_reg = PSB_LANE2; + cdv_sb_read(dev, lane_reg, &lane_value); + lane_value &= ~(LANE_PLL_MASK); + lane_value |= LANE_PLL_ENABLE; + cdv_sb_write(dev, lane_reg, lane_value); + + lane_reg = PSB_LANE3; + cdv_sb_read(dev, lane_reg, &lane_value); + lane_value &= ~(LANE_PLL_MASK); + lane_value |= LANE_PLL_ENABLE; + cdv_sb_write(dev, lane_reg, lane_value); + } + + return 0; +} + +/* + * Returns whether any output on the specified pipe is of the specified type + */ +bool cdv_intel_pipe_has_type(struct drm_crtc *crtc, int type) +{ + struct drm_device *dev = crtc->dev; + struct drm_mode_config *mode_config = &dev->mode_config; + struct drm_connector *l_entry; + + list_for_each_entry(l_entry, &mode_config->connector_list, head) { + if (l_entry->encoder && l_entry->encoder->crtc == crtc) { + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(l_entry); + if (psb_intel_output->type == type) + return true; + } + } + return false; +} + +static const struct cdv_intel_limit_t *cdv_intel_limit(struct drm_crtc *crtc, + int refclk) +{ + const struct cdv_intel_limit_t *limit; + if (cdv_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { + /* + * Now only single-channel LVDS is supported on CDV. If it is + * incorrect, please add the dual-channel LVDS. + */ + if (refclk == 96000) + limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_96]; + else + limit = &cdv_intel_limits[CDV_LIMIT_SINGLE_LVDS_100]; + } else { + if (refclk == 27000) + limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_27]; + else + limit = &cdv_intel_limits[CDV_LIMIT_DAC_HDMI_96]; + } + return limit; +} + +/* m1 is reserved as 0 in CDV, n is a ring counter */ +static void cdv_intel_clock(struct drm_device *dev, + int refclk, struct cdv_intel_clock_t *clock) +{ + clock->m = clock->m2 + 2; + clock->p = clock->p1 * clock->p2; + clock->vco = (refclk * clock->m) / clock->n; + clock->dot = clock->vco / clock->p; +} + + +#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; } +static bool cdv_intel_PLL_is_valid(struct drm_crtc *crtc, + const struct cdv_intel_limit_t *limit, + struct cdv_intel_clock_t *clock) +{ + if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) + INTELPllInvalid("p1 out of range\n"); + if (clock->p < limit->p.min || limit->p.max < clock->p) + INTELPllInvalid("p out of range\n"); + /* unnecessary to check the range of m(m1/M2)/n again */ + if (clock->vco < limit->vco.min || limit->vco.max < clock->vco) + INTELPllInvalid("vco out of range\n"); + /* XXX: We may need to be checking "Dot clock" + * depending on the multiplier, connector, etc., + * rather than just a single range. + */ + if (clock->dot < limit->dot.min || limit->dot.max < clock->dot) + INTELPllInvalid("dot out of range\n"); + + return true; +} + +static bool cdv_intel_find_best_PLL(struct drm_crtc *crtc, int target, + int refclk, + struct cdv_intel_clock_t *best_clock) +{ + struct drm_device *dev = crtc->dev; + struct cdv_intel_clock_t clock; + const struct cdv_intel_limit_t *limit = cdv_intel_limit(crtc, refclk); + int err = target; + + + if (cdv_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + (REG_READ(LVDS) & LVDS_PORT_EN) != 0) { + /* + * For LVDS, if the panel is on, just rely on its current + * settings for dual-channel. We haven't figured out how to + * reliably set up different single/dual channel state, if we + * even can. + */ + if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) == + LVDS_CLKB_POWER_UP) + clock.p2 = limit->p2.p2_fast; + else + clock.p2 = limit->p2.p2_slow; + } else { + if (target < limit->p2.dot_limit) + clock.p2 = limit->p2.p2_slow; + else + clock.p2 = limit->p2.p2_fast; + } + + memset(best_clock, 0, sizeof(*best_clock)); + clock.m1 = 0; + /* m1 is reserved as 0 in CDV, n is a ring counter. + So skip the m1 loop */ + for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) { + for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; + clock.m2++) { + for (clock.p1 = limit->p1.min; + clock.p1 <= limit->p1.max; + clock.p1++) { + int this_err; + + cdv_intel_clock(dev, refclk, &clock); + + if (!cdv_intel_PLL_is_valid(crtc, + limit, &clock)) + continue; + + this_err = abs(clock.dot - target); + if (this_err < err) { + *best_clock = clock; + err = this_err; + } + } + } + } + + return err != target; +} + +int cdv_intel_pipe_set_base(struct drm_crtc *crtc, + int x, int y, struct drm_framebuffer *old_fb) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); + int pipe = psb_intel_crtc->pipe; + unsigned long start, offset; + int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE); + int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); + int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + u32 dspcntr; + int ret = 0; + + if (!gma_power_begin(dev, true)) + return 0; + + /* no fb bound */ + if (!crtc->fb) { + dev_err(dev->dev, "No FB bound\n"); + goto psb_intel_pipe_cleaner; + } + + + /* We are displaying this buffer, make sure it is actually loaded + into the GTT */ + ret = psb_gtt_pin(psbfb->gtt); + if (ret < 0) + goto psb_intel_pipe_set_base_exit; + start = psbfb->gtt->offset; + offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); + + REG_WRITE(dspstride, crtc->fb->pitch); + + dspcntr = REG_READ(dspcntr_reg); + dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; + + switch (crtc->fb->bits_per_pixel) { + case 8: + dspcntr |= DISPPLANE_8BPP; + break; + case 16: + if (crtc->fb->depth == 15) + dspcntr |= DISPPLANE_15_16BPP; + else + dspcntr |= DISPPLANE_16BPP; + break; + case 24: + case 32: + dspcntr |= DISPPLANE_32BPP_NO_ALPHA; + break; + default: + dev_err(dev->dev, "Unknown color depth\n"); + ret = -EINVAL; + goto psb_intel_pipe_set_base_exit; + } + REG_WRITE(dspcntr_reg, dspcntr); + + dev_dbg(dev->dev, + "Writing base %08lX %08lX %d %d\n", start, offset, x, y); + + REG_WRITE(dspbase, offset); + REG_READ(dspbase); + REG_WRITE(dspsurf, start); + REG_READ(dspsurf); + +psb_intel_pipe_cleaner: + /* If there was a previous display we can now unpin it */ + if (old_fb) + psb_gtt_unpin(to_psb_fb(old_fb)->gtt); + +psb_intel_pipe_set_base_exit: + gma_power_end(dev); + return ret; +} + +/** + * Sets the power management mode of the pipe and plane. + * + * This code should probably grow support for turning the cursor off and back + * on appropriately at the same time as we're turning the pipe off/on. + */ +static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + u32 temp; + bool enabled; + + /* XXX: When our outputs are all unaware of DPMS modes other than off + * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. + */ + switch (mode) { + case DRM_MODE_DPMS_ON: + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + /* Enable the DPLL */ + temp = REG_READ(dpll_reg); + if ((temp & DPLL_VCO_ENABLE) == 0) { + REG_WRITE(dpll_reg, temp); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); + } + + /* Jim Bish - switch plan and pipe per scott */ + /* Enable the plane */ + temp = REG_READ(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) == 0) { + REG_WRITE(dspcntr_reg, + temp | DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + } + + udelay(150); + + /* Enable the pipe */ + temp = REG_READ(pipeconf_reg); + if ((temp & PIPEACONF_ENABLE) == 0) + REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); + + psb_intel_crtc_load_lut(crtc); + + /* Give the overlay scaler a chance to enable + * if it's on this pipe */ + /* psb_intel_crtc_dpms_video(crtc, true); TODO */ + break; + case DRM_MODE_DPMS_OFF: + /* Give the overlay scaler a chance to disable + * if it's on this pipe */ + /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ + + /* Disable the VGA plane that we never use */ + REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); + + /* Jim Bish - changed pipe/plane here as well. */ + + /* Wait for vblank for the disable to take effect */ + cdv_intel_wait_for_vblank(dev); + + /* Next, disable display pipes */ + temp = REG_READ(pipeconf_reg); + if ((temp & PIPEACONF_ENABLE) != 0) { + REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); + REG_READ(pipeconf_reg); + } + + /* Wait for vblank for the disable to take effect. */ + cdv_intel_wait_for_vblank(dev); + + udelay(150); + + /* Disable display plane */ + temp = REG_READ(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) != 0) { + REG_WRITE(dspcntr_reg, + temp & ~DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + REG_READ(dspbase_reg); + } + + temp = REG_READ(dpll_reg); + if ((temp & DPLL_VCO_ENABLE) != 0) { + REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + } + + /* Wait for the clocks to turn off. */ + udelay(150); + break; + } + enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF; + /*Set FIFO Watermarks*/ + REG_WRITE(DSPARB, 0x3F3E); +} + +static void cdv_intel_crtc_prepare(struct drm_crtc *crtc) +{ + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); +} + +static void cdv_intel_crtc_commit(struct drm_crtc *crtc) +{ + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); +} + +void cdv_intel_encoder_prepare(struct drm_encoder *encoder) +{ + struct drm_encoder_helper_funcs *encoder_funcs = + encoder->helper_private; + /* lvds has its own version of prepare see cdv_intel_lvds_prepare */ + encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); +} + +void cdv_intel_encoder_commit(struct drm_encoder *encoder) +{ + struct drm_encoder_helper_funcs *encoder_funcs = + encoder->helper_private; + /* lvds has its own version of commit see cdv_intel_lvds_commit */ + encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); +} + +static bool cdv_intel_crtc_mode_fixup(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + + +/** + * Return the pipe currently connected to the panel fitter, + * or -1 if the panel fitter is not present or not in use + */ +static int cdv_intel_panel_fitter_pipe(struct drm_device *dev) +{ + u32 pfit_control; + + pfit_control = REG_READ(PFIT_CONTROL); + + /* See if the panel fitter is in use */ + if ((pfit_control & PFIT_ENABLE) == 0) + return -1; + return (pfit_control >> 29) & 0x3; +} + +static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, + int x, int y, + struct drm_framebuffer *old_fb) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; + int dpll_md_reg = (psb_intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; + int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; + int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; + int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; + int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; + int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; + int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; + int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; + int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; + int refclk; + struct cdv_intel_clock_t clock; + u32 dpll = 0, dspcntr, pipeconf; + bool ok, is_sdvo = false, is_dvo = false; + bool is_crt = false, is_lvds = false, is_tv = false; + bool is_hdmi = false; + struct drm_mode_config *mode_config = &dev->mode_config; + struct drm_connector *connector; + + list_for_each_entry(connector, &mode_config->connector_list, head) { + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + + if (!connector->encoder + || connector->encoder->crtc != crtc) + continue; + + switch (psb_intel_output->type) { + case INTEL_OUTPUT_LVDS: + is_lvds = true; + break; + case INTEL_OUTPUT_SDVO: + is_sdvo = true; + break; + case INTEL_OUTPUT_DVO: + is_dvo = true; + break; + case INTEL_OUTPUT_TVOUT: + is_tv = true; + break; + case INTEL_OUTPUT_ANALOG: + is_crt = true; + break; + case INTEL_OUTPUT_HDMI: + is_hdmi = true; + break; + } + } + + refclk = 96000; + + /* Hack selection about ref clk for CRT */ + /* Select 27MHz as the reference clk for HDMI */ + if (is_crt || is_hdmi) + refclk = 27000; + + drm_mode_debug_printmodeline(adjusted_mode); + + ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, + &clock); + if (!ok) { + dev_err(dev->dev, "Couldn't find PLL settings for mode!\n"); + return 0; + } + + dpll = DPLL_VGA_MODE_DIS; + if (is_tv) { + /* XXX: just matching BIOS for now */ +/* dpll |= PLL_REF_INPUT_TVCLKINBC; */ + dpll |= 3; + } + dpll |= PLL_REF_INPUT_DREFCLK; + + dpll |= DPLL_SYNCLOCK_ENABLE; + dpll |= DPLL_VGA_MODE_DIS; + if (is_lvds) + dpll |= DPLLB_MODE_LVDS; + else + dpll |= DPLLB_MODE_DAC_SERIAL; + /* dpll |= (2 << 11); */ + + /* setup pipeconf */ + pipeconf = REG_READ(pipeconf_reg); + + /* Set up the display plane register */ + dspcntr = DISPPLANE_GAMMA_ENABLE; + + if (pipe == 0) + dspcntr |= DISPPLANE_SEL_PIPE_A; + else + dspcntr |= DISPPLANE_SEL_PIPE_B; + + dspcntr |= DISPLAY_PLANE_ENABLE; + pipeconf |= PIPEACONF_ENABLE; + + REG_WRITE(dpll_reg, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE); + REG_READ(dpll_reg); + + cdv_dpll_set_clock_cdv(dev, crtc, &clock); + + udelay(150); + + + /* The LVDS pin pair needs to be on before the DPLLs are enabled. + * This is an exception to the general rule that mode_set doesn't turn + * things on. + */ + if (is_lvds) { + u32 lvds = REG_READ(LVDS); + + lvds |= + LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | + LVDS_PIPEB_SELECT; + /* Set the B0-B3 data pairs corresponding to + * whether we're going to + * set the DPLLs for dual-channel mode or not. + */ + if (clock.p2 == 7) + lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; + else + lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); + + /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) + * appropriately here, but we need to look more + * thoroughly into how panels behave in the two modes. + */ + + REG_WRITE(LVDS, lvds); + REG_READ(LVDS); + } + + dpll |= DPLL_VCO_ENABLE; + + /* Disable the panel fitter if it was on our pipe */ + if (cdv_intel_panel_fitter_pipe(dev) == pipe) + REG_WRITE(PFIT_CONTROL, 0); + + DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); + drm_mode_debug_printmodeline(mode); + + REG_WRITE(dpll_reg, + (REG_READ(dpll_reg) & ~DPLL_LOCK) | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + /* Wait for the clocks to stabilize. */ + udelay(150); /* 42 usec w/o calibration, 110 with. rounded up. */ + + if (!(REG_READ(dpll_reg) & DPLL_LOCK)) { + dev_err(dev->dev, "Failed to get DPLL lock\n"); + return -EBUSY; + } + + { + int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; + REG_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); + } + + REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | + ((adjusted_mode->crtc_htotal - 1) << 16)); + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | + ((adjusted_mode->crtc_hblank_end - 1) << 16)); + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | + ((adjusted_mode->crtc_hsync_end - 1) << 16)); + REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | + ((adjusted_mode->crtc_vtotal - 1) << 16)); + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | + ((adjusted_mode->crtc_vblank_end - 1) << 16)); + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | + ((adjusted_mode->crtc_vsync_end - 1) << 16)); + /* pipesrc and dspsize control the size that is scaled from, + * which should always be the user's requested size. + */ + REG_WRITE(dspsize_reg, + ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); + REG_WRITE(dsppos_reg, 0); + REG_WRITE(pipesrc_reg, + ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); + REG_WRITE(pipeconf_reg, pipeconf); + REG_READ(pipeconf_reg); + + cdv_intel_wait_for_vblank(dev); + + REG_WRITE(dspcntr_reg, dspcntr); + + /* Flush the plane changes */ + { + struct drm_crtc_helper_funcs *crtc_funcs = + crtc->helper_private; + crtc_funcs->mode_set_base(crtc, x, y, old_fb); + } + + cdv_intel_wait_for_vblank(dev); + + return 0; +} + +/** Loads the palette/gamma unit for the CRTC with the prepared values */ +void cdv_intel_crtc_load_lut(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int palreg = PALETTE_A; + int i; + + /* The clocks have to be on to load the palette. */ + if (!crtc->enabled) + return; + + switch (psb_intel_crtc->pipe) { + case 0: + break; + case 1: + palreg = PALETTE_B; + break; + case 2: + palreg = PALETTE_C; + break; + default: + dev_err(dev->dev, "Illegal Pipe Number.\n"); + return; + } + + if (gma_power_begin(dev, false)) { + for (i = 0; i < 256; i++) { + REG_WRITE(palreg + 4 * i, + ((psb_intel_crtc->lut_r[i] + + psb_intel_crtc->lut_adj[i]) << 16) | + ((psb_intel_crtc->lut_g[i] + + psb_intel_crtc->lut_adj[i]) << 8) | + (psb_intel_crtc->lut_b[i] + + psb_intel_crtc->lut_adj[i])); + } + gma_power_end(dev); + } else { + for (i = 0; i < 256; i++) { + dev_priv->save_palette_a[i] = + ((psb_intel_crtc->lut_r[i] + + psb_intel_crtc->lut_adj[i]) << 16) | + ((psb_intel_crtc->lut_g[i] + + psb_intel_crtc->lut_adj[i]) << 8) | + (psb_intel_crtc->lut_b[i] + + psb_intel_crtc->lut_adj[i]); + } + + } +} + +/** + * Save HW states of giving crtc + */ +static void cdv_intel_crtc_save(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + /* struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; */ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; + int pipeA = (psb_intel_crtc->pipe == 0); + uint32_t paletteReg; + int i; + + if (!crtc_state) { + dev_dbg(dev->dev, "No CRTC state found\n"); + return; + } + + crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR); + crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF); + crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC); + crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0); + crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1); + crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B); + crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B); + crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B); + crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B); + crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B); + crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B); + crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B); + crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE); + + /*NOTE: DSPSIZE DSPPOS only for psb*/ + crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE); + crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS); + + crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE); + + DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", + crtc_state->saveDSPCNTR, + crtc_state->savePIPECONF, + crtc_state->savePIPESRC, + crtc_state->saveFP0, + crtc_state->saveFP1, + crtc_state->saveDPLL, + crtc_state->saveHTOTAL, + crtc_state->saveHBLANK, + crtc_state->saveHSYNC, + crtc_state->saveVTOTAL, + crtc_state->saveVBLANK, + crtc_state->saveVSYNC, + crtc_state->saveDSPSTRIDE, + crtc_state->saveDSPSIZE, + crtc_state->saveDSPPOS, + crtc_state->saveDSPBASE + ); + + paletteReg = pipeA ? PALETTE_A : PALETTE_B; + for (i = 0; i < 256; ++i) + crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2)); +} + +/** + * Restore HW states of giving crtc + */ +static void cdv_intel_crtc_restore(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + /* struct drm_psb_private * dev_priv = + (struct drm_psb_private *)dev->dev_private; */ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; + /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */ + int pipeA = (psb_intel_crtc->pipe == 0); + uint32_t paletteReg; + int i; + + if (!crtc_state) { + dev_dbg(dev->dev, "No crtc state\n"); + return; + } + + DRM_DEBUG( + "current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", + REG_READ(pipeA ? DSPACNTR : DSPBCNTR), + REG_READ(pipeA ? PIPEACONF : PIPEBCONF), + REG_READ(pipeA ? PIPEASRC : PIPEBSRC), + REG_READ(pipeA ? FPA0 : FPB0), + REG_READ(pipeA ? FPA1 : FPB1), + REG_READ(pipeA ? DPLL_A : DPLL_B), + REG_READ(pipeA ? HTOTAL_A : HTOTAL_B), + REG_READ(pipeA ? HBLANK_A : HBLANK_B), + REG_READ(pipeA ? HSYNC_A : HSYNC_B), + REG_READ(pipeA ? VTOTAL_A : VTOTAL_B), + REG_READ(pipeA ? VBLANK_A : VBLANK_B), + REG_READ(pipeA ? VSYNC_A : VSYNC_B), + REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE), + REG_READ(pipeA ? DSPASIZE : DSPBSIZE), + REG_READ(pipeA ? DSPAPOS : DSPBPOS), + REG_READ(pipeA ? DSPABASE : DSPBBASE) + ); + + DRM_DEBUG( + "saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", + crtc_state->saveDSPCNTR, + crtc_state->savePIPECONF, + crtc_state->savePIPESRC, + crtc_state->saveFP0, + crtc_state->saveFP1, + crtc_state->saveDPLL, + crtc_state->saveHTOTAL, + crtc_state->saveHBLANK, + crtc_state->saveHSYNC, + crtc_state->saveVTOTAL, + crtc_state->saveVBLANK, + crtc_state->saveVSYNC, + crtc_state->saveDSPSTRIDE, + crtc_state->saveDSPSIZE, + crtc_state->saveDSPPOS, + crtc_state->saveDSPBASE + ); + + + if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) { + REG_WRITE(pipeA ? DPLL_A : DPLL_B, + crtc_state->saveDPLL & ~DPLL_VCO_ENABLE); + REG_READ(pipeA ? DPLL_A : DPLL_B); + DRM_DEBUG("write dpll: %x\n", + REG_READ(pipeA ? DPLL_A : DPLL_B)); + udelay(150); + } + + REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0); + REG_READ(pipeA ? FPA0 : FPB0); + + REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1); + REG_READ(pipeA ? FPA1 : FPB1); + + REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL); + REG_READ(pipeA ? DPLL_A : DPLL_B); + udelay(150); + + REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL); + REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK); + REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC); + REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL); + REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK); + REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC); + REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE); + + REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE); + REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS); + + REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC); + REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); + REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF); + + cdv_intel_wait_for_vblank(dev); + + REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR); + REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); + + cdv_intel_wait_for_vblank(dev); + + paletteReg = pipeA ? PALETTE_A : PALETTE_B; + for (i = 0; i < 256; ++i) + REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]); +} + +static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc, + struct drm_file *file_priv, + uint32_t handle, + uint32_t width, uint32_t height) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; + uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; + uint32_t temp; + size_t addr = 0; + struct gtt_range *gt; + struct drm_gem_object *obj; + int ret; + + /* if we want to turn of the cursor ignore width and height */ + if (!handle) { + /* turn off the cursor */ + temp = CURSOR_MODE_DISABLE; + + if (gma_power_begin(dev, false)) { + REG_WRITE(control, temp); + REG_WRITE(base, 0); + gma_power_end(dev); + } + + /* unpin the old GEM object */ + if (psb_intel_crtc->cursor_obj) { + gt = container_of(psb_intel_crtc->cursor_obj, + struct gtt_range, gem); + psb_gtt_unpin(gt); + drm_gem_object_unreference(psb_intel_crtc->cursor_obj); + psb_intel_crtc->cursor_obj = NULL; + } + + return 0; + } + + /* Currently we only support 64x64 cursors */ + if (width != 64 || height != 64) { + dev_dbg(dev->dev, "we currently only support 64x64 cursors\n"); + return -EINVAL; + } + + obj = drm_gem_object_lookup(dev, file_priv, handle); + if (!obj) + return -ENOENT; + + if (obj->size < width * height * 4) { + dev_dbg(dev->dev, "buffer is to small\n"); + return -ENOMEM; + } + + gt = container_of(obj, struct gtt_range, gem); + + /* Pin the memory into the GTT */ + ret = psb_gtt_pin(gt); + if (ret) { + dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle); + return ret; + } + + addr = gt->offset; /* Or resource.start ??? */ + + psb_intel_crtc->cursor_addr = addr; + + temp = 0; + /* set the pipe for the cursor */ + temp |= (pipe << 28); + temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + + if (gma_power_begin(dev, false)) { + REG_WRITE(control, temp); + REG_WRITE(base, addr); + gma_power_end(dev); + } + + /* unpin the old GEM object */ + if (psb_intel_crtc->cursor_obj) { + gt = container_of(psb_intel_crtc->cursor_obj, + struct gtt_range, gem); + psb_gtt_unpin(gt); + drm_gem_object_unreference(psb_intel_crtc->cursor_obj); + psb_intel_crtc->cursor_obj = obj; + } + return 0; +} + +static int cdv_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + uint32_t temp = 0; + uint32_t adder; + + + if (x < 0) { + temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT); + x = -x; + } + if (y < 0) { + temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT); + y = -y; + } + + temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT); + temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); + + adder = psb_intel_crtc->cursor_addr; + + if (gma_power_begin(dev, false)) { + REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp); + REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder); + gma_power_end(dev); + } + return 0; +} + +static void cdv_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, + u16 *green, u16 *blue, uint32_t start, uint32_t size) +{ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int i; + int end = (start + size > 256) ? 256 : start + size; + + for (i = start; i < end; i++) { + psb_intel_crtc->lut_r[i] = red[i] >> 8; + psb_intel_crtc->lut_g[i] = green[i] >> 8; + psb_intel_crtc->lut_b[i] = blue[i] >> 8; + } + + cdv_intel_crtc_load_lut(crtc); +} + +static int cdv_crtc_set_config(struct drm_mode_set *set) +{ + int ret = 0; + struct drm_device *dev = set->crtc->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + + if (!dev_priv->rpm_enabled) + return drm_crtc_helper_set_config(set); + + pm_runtime_forbid(&dev->pdev->dev); + + ret = drm_crtc_helper_set_config(set); + + pm_runtime_allow(&dev->pdev->dev); + + return ret; +} + +/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ + +/* FIXME: why are we using this, should it be cdv_ in this tree ? */ + +static void i8xx_clock(int refclk, struct cdv_intel_clock_t *clock) +{ + clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); + clock->p = clock->p1 * clock->p2; + clock->vco = refclk * clock->m / (clock->n + 2); + clock->dot = clock->vco / clock->p; +} + +/* Returns the clock of the currently programmed mode of the given pipe. */ +static int cdv_intel_crtc_clock_get(struct drm_device *dev, + struct drm_crtc *crtc) +{ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + u32 dpll; + u32 fp; + struct cdv_intel_clock_t clock; + bool is_lvds; + struct drm_psb_private *dev_priv = dev->dev_private; + + if (gma_power_begin(dev, false)) { + dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B); + if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) + fp = REG_READ((pipe == 0) ? FPA0 : FPB0); + else + fp = REG_READ((pipe == 0) ? FPA1 : FPB1); + is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN); + gma_power_end(dev); + } else { + dpll = (pipe == 0) ? + dev_priv->saveDPLL_A : dev_priv->saveDPLL_B; + + if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) + fp = (pipe == 0) ? + dev_priv->saveFPA0 : + dev_priv->saveFPB0; + else + fp = (pipe == 0) ? + dev_priv->saveFPA1 : + dev_priv->saveFPB1; + + is_lvds = (pipe == 1) && (dev_priv->saveLVDS & LVDS_PORT_EN); + } + + clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; + clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; + clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; + + if (is_lvds) { + clock.p1 = + ffs((dpll & + DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> + DPLL_FPA01_P1_POST_DIV_SHIFT); + if (clock.p1 == 0) { + clock.p1 = 4; + dev_err(dev->dev, "PLL %d\n", dpll); + } + clock.p2 = 14; + + if ((dpll & PLL_REF_INPUT_MASK) == + PLLB_REF_INPUT_SPREADSPECTRUMIN) { + /* XXX: might not be 66MHz */ + i8xx_clock(66000, &clock); + } else + i8xx_clock(48000, &clock); + } else { + if (dpll & PLL_P1_DIVIDE_BY_TWO) + clock.p1 = 2; + else { + clock.p1 = + ((dpll & + DPLL_FPA01_P1_POST_DIV_MASK_I830) >> + DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; + } + if (dpll & PLL_P2_DIVIDE_BY_4) + clock.p2 = 4; + else + clock.p2 = 2; + + i8xx_clock(48000, &clock); + } + + /* XXX: It would be nice to validate the clocks, but we can't reuse + * i830PllIsValid() because it relies on the xf86_config connector + * configuration being accurate, which it isn't necessarily. + */ + + return clock.dot; +} + +/** Returns the currently programmed mode of the given pipe. */ +struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev, + struct drm_crtc *crtc) +{ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + struct drm_display_mode *mode; + int htot; + int hsync; + int vtot; + int vsync; + struct drm_psb_private *dev_priv = dev->dev_private; + + if (gma_power_begin(dev, false)) { + htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B); + hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B); + vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B); + vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B); + gma_power_end(dev); + } else { + htot = (pipe == 0) ? + dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B; + hsync = (pipe == 0) ? + dev_priv->saveHSYNC_A : dev_priv->saveHSYNC_B; + vtot = (pipe == 0) ? + dev_priv->saveVTOTAL_A : dev_priv->saveVTOTAL_B; + vsync = (pipe == 0) ? + dev_priv->saveVSYNC_A : dev_priv->saveVSYNC_B; + } + + mode = kzalloc(sizeof(*mode), GFP_KERNEL); + if (!mode) + return NULL; + + mode->clock = cdv_intel_crtc_clock_get(dev, crtc); + mode->hdisplay = (htot & 0xffff) + 1; + mode->htotal = ((htot & 0xffff0000) >> 16) + 1; + mode->hsync_start = (hsync & 0xffff) + 1; + mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1; + mode->vdisplay = (vtot & 0xffff) + 1; + mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1; + mode->vsync_start = (vsync & 0xffff) + 1; + mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1; + + drm_mode_set_name(mode); + drm_mode_set_crtcinfo(mode, 0); + + return mode; +} + +static void cdv_intel_crtc_destroy(struct drm_crtc *crtc) +{ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + + kfree(psb_intel_crtc->crtc_state); + drm_crtc_cleanup(crtc); + kfree(psb_intel_crtc); +} + +const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = { + .dpms = cdv_intel_crtc_dpms, + .mode_fixup = cdv_intel_crtc_mode_fixup, + .mode_set = cdv_intel_crtc_mode_set, + .mode_set_base = cdv_intel_pipe_set_base, + .prepare = cdv_intel_crtc_prepare, + .commit = cdv_intel_crtc_commit, +}; + +const struct drm_crtc_funcs cdv_intel_crtc_funcs = { + .save = cdv_intel_crtc_save, + .restore = cdv_intel_crtc_restore, + .cursor_set = cdv_intel_crtc_cursor_set, + .cursor_move = cdv_intel_crtc_cursor_move, + .gamma_set = cdv_intel_crtc_gamma_set, + .set_config = cdv_crtc_set_config, + .destroy = cdv_intel_crtc_destroy, +}; + +/* + * Set the default value of cursor control and base register + * to zero. This is a workaround for h/w defect on oaktrail + */ +void cdv_intel_cursor_init(struct drm_device *dev, int pipe) +{ + uint32_t control; + uint32_t base; + + switch (pipe) { + case 0: + control = CURACNTR; + base = CURABASE; + break; + case 1: + control = CURBCNTR; + base = CURBBASE; + break; + case 2: + control = CURCCNTR; + base = CURCBASE; + break; + default: + return; + } + + REG_WRITE(control, 0); + REG_WRITE(base, 0); +} + diff --git a/drivers/staging/gma500/cdv_intel_hdmi.c b/drivers/staging/gma500/cdv_intel_hdmi.c new file mode 100644 index 000000000000..cbca2b0c7d58 --- /dev/null +++ b/drivers/staging/gma500/cdv_intel_hdmi.c @@ -0,0 +1,376 @@ +/* + * Copyright © 2006-2011 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: + * jim liu + * + * FIXME: + * We should probably make this generic and share it with Medfield + */ + +#include +#include +#include +#include +#include "psb_intel_drv.h" +#include "psb_drv.h" +#include "psb_intel_reg.h" +#include + +/* hdmi control bits */ +#define HDMI_NULL_PACKETS_DURING_VSYNC (1 << 9) +#define HDMI_BORDER_ENABLE (1 << 7) +#define HDMI_AUDIO_ENABLE (1 << 6) +#define HDMI_VSYNC_ACTIVE_HIGH (1 << 4) +#define HDMI_HSYNC_ACTIVE_HIGH (1 << 3) +/* hdmi-b control bits */ +#define HDMIB_PIPE_B_SELECT (1 << 30) + + +struct mid_intel_hdmi_priv { + u32 hdmi_reg; + u32 save_HDMIB; + bool has_hdmi_sink; + bool has_hdmi_audio; + /* Should set this when detect hotplug */ + bool hdmi_device_connected; + struct mdfld_hdmi_i2c *i2c_bus; + struct i2c_adapter *hdmi_i2c_adapter; /* for control functions */ + struct drm_device *dev; +}; + +static void cdv_hdmi_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; + u32 hdmib; + struct drm_crtc *crtc = encoder->crtc; + struct psb_intel_crtc *intel_crtc = to_psb_intel_crtc(crtc); + + hdmib = (2 << 10); + + if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) + hdmib |= HDMI_VSYNC_ACTIVE_HIGH; + if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) + hdmib |= HDMI_HSYNC_ACTIVE_HIGH; + + if (intel_crtc->pipe == 1) + hdmib |= HDMIB_PIPE_B_SELECT; + + if (hdmi_priv->has_hdmi_audio) { + hdmib |= HDMI_AUDIO_ENABLE; + hdmib |= HDMI_NULL_PACKETS_DURING_VSYNC; + } + + REG_WRITE(hdmi_priv->hdmi_reg, hdmib); + REG_READ(hdmi_priv->hdmi_reg); +} + +static bool cdv_hdmi_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static void cdv_hdmi_dpms(struct drm_encoder *encoder, int mode) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; + u32 hdmib; + + hdmib = REG_READ(hdmi_priv->hdmi_reg); + + if (mode != DRM_MODE_DPMS_ON) + REG_WRITE(hdmi_priv->hdmi_reg, hdmib & ~HDMIB_PORT_EN); + else + REG_WRITE(hdmi_priv->hdmi_reg, hdmib | HDMIB_PORT_EN); + REG_READ(hdmi_priv->hdmi_reg); +} + +static void cdv_hdmi_save(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct psb_intel_output *output = to_psb_intel_output(connector); + struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; + + hdmi_priv->save_HDMIB = REG_READ(hdmi_priv->hdmi_reg); +} + +static void cdv_hdmi_restore(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct psb_intel_output *output = to_psb_intel_output(connector); + struct mid_intel_hdmi_priv *hdmi_priv = output->dev_priv; + + REG_WRITE(hdmi_priv->hdmi_reg, hdmi_priv->save_HDMIB); + REG_READ(hdmi_priv->hdmi_reg); +} + +static enum drm_connector_status cdv_hdmi_detect( + struct drm_connector *connector, bool force) +{ + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + struct mid_intel_hdmi_priv *hdmi_priv = psb_intel_output->dev_priv; + struct edid *edid = NULL; + enum drm_connector_status status = connector_status_disconnected; + + edid = drm_get_edid(&psb_intel_output->base, + psb_intel_output->hdmi_i2c_adapter); + + hdmi_priv->has_hdmi_sink = false; + hdmi_priv->has_hdmi_audio = false; + if (edid) { + if (edid->input & DRM_EDID_INPUT_DIGITAL) { + status = connector_status_connected; + hdmi_priv->has_hdmi_sink = + drm_detect_hdmi_monitor(edid); + hdmi_priv->has_hdmi_audio = + drm_detect_monitor_audio(edid); + } + + psb_intel_output->base.display_info.raw_edid = NULL; + kfree(edid); + } + return status; +} + +static int cdv_hdmi_set_property(struct drm_connector *connector, + struct drm_property *property, + uint64_t value) +{ + struct drm_encoder *encoder = connector->encoder; + + if (!strcmp(property->name, "scaling mode") && encoder) { + struct psb_intel_crtc *crtc = to_psb_intel_crtc(encoder->crtc); + bool centre; + uint64_t curValue; + + if (!crtc) + return -1; + + switch (value) { + case DRM_MODE_SCALE_FULLSCREEN: + break; + case DRM_MODE_SCALE_NO_SCALE: + break; + case DRM_MODE_SCALE_ASPECT: + break; + default: + return -1; + } + + if (drm_connector_property_get_value(connector, + property, &curValue)) + return -1; + + if (curValue == value) + return 0; + + if (drm_connector_property_set_value(connector, + property, value)) + return -1; + + centre = (curValue == DRM_MODE_SCALE_NO_SCALE) || + (value == DRM_MODE_SCALE_NO_SCALE); + + if (crtc->saved_mode.hdisplay != 0 && + crtc->saved_mode.vdisplay != 0) { + if (centre) { + if (!drm_crtc_helper_set_mode(encoder->crtc, &crtc->saved_mode, + encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb)) + return -1; + } else { + struct drm_encoder_helper_funcs *helpers + = encoder->helper_private; + helpers->mode_set(encoder, &crtc->saved_mode, + &crtc->saved_adjusted_mode); + } + } + } + return 0; +} + +/* + * Return the list of HDMI DDC modes if available. + */ +static int cdv_hdmi_get_modes(struct drm_connector *connector) +{ + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + struct edid *edid = NULL; + int ret = 0; + + edid = drm_get_edid(&psb_intel_output->base, + psb_intel_output->hdmi_i2c_adapter); + if (edid) { + drm_mode_connector_update_edid_property(&psb_intel_output-> + base, edid); + ret = drm_add_edid_modes(&psb_intel_output->base, edid); + kfree(edid); + } + return ret; +} + +static int cdv_hdmi_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + + if (mode->clock > 165000) + return MODE_CLOCK_HIGH; + if (mode->clock < 20000) + return MODE_CLOCK_HIGH; + + /* just in case */ + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + + /* just in case */ + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + return MODE_NO_INTERLACE; + + /* + * FIXME: for now we limit the size to 1680x1050 on CDV, otherwise it + * will go beyond the stolen memory size allocated to the framebuffer + */ + if (mode->hdisplay > 1680) + return MODE_PANEL; + if (mode->vdisplay > 1050) + return MODE_PANEL; + return MODE_OK; +} + +static void cdv_hdmi_destroy(struct drm_connector *connector) +{ + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + + if (psb_intel_output->ddc_bus) + psb_intel_i2c_destroy(psb_intel_output->ddc_bus); + drm_sysfs_connector_remove(connector); + drm_connector_cleanup(connector); + kfree(connector); +} + +static const struct drm_encoder_helper_funcs cdv_hdmi_helper_funcs = { + .dpms = cdv_hdmi_dpms, + .mode_fixup = cdv_hdmi_mode_fixup, + .prepare = psb_intel_encoder_prepare, + .mode_set = cdv_hdmi_mode_set, + .commit = psb_intel_encoder_commit, +}; + +static const struct drm_connector_helper_funcs + cdv_hdmi_connector_helper_funcs = { + .get_modes = cdv_hdmi_get_modes, + .mode_valid = cdv_hdmi_mode_valid, + .best_encoder = psb_intel_best_encoder, +}; + +static const struct drm_connector_funcs cdv_hdmi_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .save = cdv_hdmi_save, + .restore = cdv_hdmi_restore, + .detect = cdv_hdmi_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .set_property = cdv_hdmi_set_property, + .destroy = cdv_hdmi_destroy, +}; + +void cdv_hdmi_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev, int reg) +{ + struct psb_intel_output *psb_intel_output; + struct drm_connector *connector; + struct drm_encoder *encoder; + struct mid_intel_hdmi_priv *hdmi_priv; + int ddc_bus; + + psb_intel_output = kzalloc(sizeof(struct psb_intel_output) + + sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL); + if (!psb_intel_output) + return; + + hdmi_priv = (struct mid_intel_hdmi_priv *)(psb_intel_output + 1); + psb_intel_output->mode_dev = mode_dev; + connector = &psb_intel_output->base; + encoder = &psb_intel_output->enc; + drm_connector_init(dev, &psb_intel_output->base, + &cdv_hdmi_connector_funcs, + DRM_MODE_CONNECTOR_DVID); + + drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs, + DRM_MODE_ENCODER_TMDS); + + drm_mode_connector_attach_encoder(&psb_intel_output->base, + &psb_intel_output->enc); + psb_intel_output->type = INTEL_OUTPUT_HDMI; + hdmi_priv->hdmi_reg = reg; + hdmi_priv->has_hdmi_sink = false; + psb_intel_output->dev_priv = hdmi_priv; + + drm_encoder_helper_add(encoder, &cdv_hdmi_helper_funcs); + drm_connector_helper_add(connector, + &cdv_hdmi_connector_helper_funcs); + connector->display_info.subpixel_order = SubPixelHorizontalRGB; + connector->interlace_allowed = false; + connector->doublescan_allowed = false; + + drm_connector_attach_property(connector, + dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN); + + switch (reg) { + case SDVOB: + ddc_bus = GPIOE; + break; + case SDVOC: + ddc_bus = GPIOD; + break; + default: + DRM_ERROR("unknown reg 0x%x for HDMI\n", reg); + goto failed_ddc; + break; + } + + psb_intel_output->ddc_bus = psb_intel_i2c_create(dev, + ddc_bus, (reg == SDVOB) ? "HDMIB" : "HDMIC"); + + if (!psb_intel_output->ddc_bus) { + dev_err(dev->dev, "No ddc adapter available!\n"); + goto failed_ddc; + } + psb_intel_output->hdmi_i2c_adapter = + &(psb_intel_output->ddc_bus->adapter); + hdmi_priv->dev = dev; + drm_sysfs_connector_add(connector); + return; + +failed_ddc: + drm_encoder_cleanup(&psb_intel_output->enc); + drm_connector_cleanup(&psb_intel_output->base); + kfree(psb_intel_output); +} diff --git a/drivers/staging/gma500/cdv_intel_lvds.c b/drivers/staging/gma500/cdv_intel_lvds.c new file mode 100644 index 000000000000..988b2d0acf43 --- /dev/null +++ b/drivers/staging/gma500/cdv_intel_lvds.c @@ -0,0 +1,721 @@ +/* + * Copyright © 2006-2011 Intel 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., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Authors: + * Eric Anholt + * Dave Airlie + * Jesse Barnes + */ + +#include +#include +#include + +#include "intel_bios.h" +#include "psb_drv.h" +#include "psb_intel_drv.h" +#include "psb_intel_reg.h" +#include "power.h" +#include +#include "cdv_device.h" + +/** + * LVDS I2C backlight control macros + */ +#define BRIGHTNESS_MAX_LEVEL 100 +#define BRIGHTNESS_MASK 0xFF +#define BLC_I2C_TYPE 0x01 +#define BLC_PWM_TYPT 0x02 + +#define BLC_POLARITY_NORMAL 0 +#define BLC_POLARITY_INVERSE 1 + +#define PSB_BLC_MAX_PWM_REG_FREQ (0xFFFE) +#define PSB_BLC_MIN_PWM_REG_FREQ (0x2) +#define PSB_BLC_PWM_PRECISION_FACTOR (10) +#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) +#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) + +struct cdv_intel_lvds_priv { + /** + * Saved LVDO output states + */ + uint32_t savePP_ON; + uint32_t savePP_OFF; + uint32_t saveLVDS; + uint32_t savePP_CONTROL; + uint32_t savePP_CYCLE; + uint32_t savePFIT_CONTROL; + uint32_t savePFIT_PGM_RATIOS; + uint32_t saveBLC_PWM_CTL; +}; + +/* + * Returns the maximum level of the backlight duty cycle field. + */ +static u32 cdv_intel_lvds_get_max_backlight(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + u32 retval; + + if (gma_power_begin(dev, false)) { + retval = ((REG_READ(BLC_PWM_CTL) & + BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; + + gma_power_end(dev); + } else + retval = ((dev_priv->saveBLC_PWM_CTL & + BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; + + return retval; +} + +/* + * Set LVDS backlight level by I2C command + */ +static int cdv_lvds_i2c_set_brightness(struct drm_device *dev, + unsigned int level) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_intel_i2c_chan *lvds_i2c_bus = dev_priv->lvds_i2c_bus; + u8 out_buf[2]; + unsigned int blc_i2c_brightness; + + struct i2c_msg msgs[] = { + { + .addr = lvds_i2c_bus->slave_addr, + .flags = 0, + .len = 2, + .buf = out_buf, + } + }; + + blc_i2c_brightness = BRIGHTNESS_MASK & ((unsigned int)level * + BRIGHTNESS_MASK / + BRIGHTNESS_MAX_LEVEL); + + if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE) + blc_i2c_brightness = BRIGHTNESS_MASK - blc_i2c_brightness; + + out_buf[0] = dev_priv->lvds_bl->brightnesscmd; + out_buf[1] = (u8)blc_i2c_brightness; + + if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) + return 0; + + DRM_ERROR("I2C transfer error\n"); + return -1; +} + + +static int cdv_lvds_pwm_set_brightness(struct drm_device *dev, int level) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + + u32 max_pwm_blc; + u32 blc_pwm_duty_cycle; + + max_pwm_blc = cdv_intel_lvds_get_max_backlight(dev); + + /*BLC_PWM_CTL Should be initiated while backlight device init*/ + BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0); + + blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL; + + if (dev_priv->lvds_bl->pol == BLC_POLARITY_INVERSE) + blc_pwm_duty_cycle = max_pwm_blc - blc_pwm_duty_cycle; + + blc_pwm_duty_cycle &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; + REG_WRITE(BLC_PWM_CTL, + (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | + (blc_pwm_duty_cycle)); + + return 0; +} + +/* + * Set LVDS backlight level either by I2C or PWM + */ +void cdv_intel_lvds_set_brightness(struct drm_device *dev, int level) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + + if (!dev_priv->lvds_bl) { + DRM_ERROR("NO LVDS Backlight Info\n"); + return; + } + + if (dev_priv->lvds_bl->type == BLC_I2C_TYPE) + cdv_lvds_i2c_set_brightness(dev, level); + else + cdv_lvds_pwm_set_brightness(dev, level); +} + +/** + * Sets the backlight level. + * + * level backlight level, from 0 to cdv_intel_lvds_get_max_backlight(). + */ +static void cdv_intel_lvds_set_backlight(struct drm_device *dev, int level) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + u32 blc_pwm_ctl; + + if (gma_power_begin(dev, false)) { + blc_pwm_ctl = + REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; + REG_WRITE(BLC_PWM_CTL, + (blc_pwm_ctl | + (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); + gma_power_end(dev); + } else { + blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL & + ~BACKLIGHT_DUTY_CYCLE_MASK; + dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl | + (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); + } +} + +/** + * Sets the power state for the panel. + */ +static void cdv_intel_lvds_set_power(struct drm_device *dev, + struct psb_intel_output *output, bool on) +{ + u32 pp_status; + + if (!gma_power_begin(dev, true)) + return; + + if (on) { + REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | + POWER_TARGET_ON); + do { + pp_status = REG_READ(PP_STATUS); + } while ((pp_status & PP_ON) == 0); + + cdv_intel_lvds_set_backlight(dev, + output-> + mode_dev->backlight_duty_cycle); + } else { + cdv_intel_lvds_set_backlight(dev, 0); + + REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & + ~POWER_TARGET_ON); + do { + pp_status = REG_READ(PP_STATUS); + } while (pp_status & PP_ON); + } + gma_power_end(dev); +} + +static void cdv_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + if (mode == DRM_MODE_DPMS_ON) + cdv_intel_lvds_set_power(dev, output, true); + else + cdv_intel_lvds_set_power(dev, output, false); + /* XXX: We never power down the LVDS pairs. */ +} + +static void cdv_intel_lvds_save(struct drm_connector *connector) +{ +} + +static void cdv_intel_lvds_restore(struct drm_connector *connector) +{ +} + +int cdv_intel_lvds_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + struct drm_display_mode *fixed_mode = + psb_intel_output->mode_dev->panel_fixed_mode; + + /* just in case */ + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + + /* just in case */ + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + return MODE_NO_INTERLACE; + + if (fixed_mode) { + if (mode->hdisplay > fixed_mode->hdisplay) + return MODE_PANEL; + if (mode->vdisplay > fixed_mode->vdisplay) + return MODE_PANEL; + } + return MODE_OK; +} + +bool cdv_intel_lvds_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct psb_intel_mode_device *mode_dev = + enc_to_psb_intel_output(encoder)->mode_dev; + struct drm_device *dev = encoder->dev; + struct drm_encoder *tmp_encoder; + struct drm_display_mode *panel_fixed_mode = mode_dev->panel_fixed_mode; + + /* Should never happen!! */ + list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, + head) { + if (tmp_encoder != encoder + && tmp_encoder->crtc == encoder->crtc) { + printk(KERN_ERR "Can't enable LVDS and another " + "encoder on the same pipe\n"); + return false; + } + } + + /* + * If we have timings from the BIOS for the panel, put them in + * to the adjusted mode. The CRTC will be set up for this mode, + * with the panel scaling set up to source from the H/VDisplay + * of the original mode. + */ + if (panel_fixed_mode != NULL) { + adjusted_mode->hdisplay = panel_fixed_mode->hdisplay; + adjusted_mode->hsync_start = panel_fixed_mode->hsync_start; + adjusted_mode->hsync_end = panel_fixed_mode->hsync_end; + adjusted_mode->htotal = panel_fixed_mode->htotal; + adjusted_mode->vdisplay = panel_fixed_mode->vdisplay; + adjusted_mode->vsync_start = panel_fixed_mode->vsync_start; + adjusted_mode->vsync_end = panel_fixed_mode->vsync_end; + adjusted_mode->vtotal = panel_fixed_mode->vtotal; + adjusted_mode->clock = panel_fixed_mode->clock; + drm_mode_set_crtcinfo(adjusted_mode, + CRTC_INTERLACE_HALVE_V); + } + + /* + * XXX: It would be nice to support lower refresh rates on the + * panels to reduce power consumption, and perhaps match the + * user's requested refresh rate. + */ + + return true; +} + +static void cdv_intel_lvds_prepare(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + struct psb_intel_mode_device *mode_dev = output->mode_dev; + + if (!gma_power_begin(dev, true)) + return; + + mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); + mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL & + BACKLIGHT_DUTY_CYCLE_MASK); + + cdv_intel_lvds_set_power(dev, output, false); + + gma_power_end(dev); +} + +static void cdv_intel_lvds_commit(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + struct psb_intel_mode_device *mode_dev = output->mode_dev; + + if (mode_dev->backlight_duty_cycle == 0) + mode_dev->backlight_duty_cycle = + cdv_intel_lvds_get_max_backlight(dev); + + cdv_intel_lvds_set_power(dev, output, true); +} + +static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = encoder->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + u32 pfit_control; + + /* + * The LVDS pin pair will already have been turned on in the + * cdv_intel_crtc_mode_set since it has a large impact on the DPLL + * settings. + */ + + /* + * Enable automatic panel scaling so that non-native modes fill the + * screen. Should be enabled before the pipe is enabled, according to + * register description and PRM. + */ + if (mode->hdisplay != adjusted_mode->hdisplay || + mode->vdisplay != adjusted_mode->vdisplay) + pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | + HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR | + HORIZ_INTERP_BILINEAR); + else + pfit_control = 0; + + if (dev_priv->lvds_dither) + pfit_control |= PANEL_8TO6_DITHER_ENABLE; + + REG_WRITE(PFIT_CONTROL, pfit_control); +} + +/** + * Detect the LVDS connection. + * + * This always returns CONNECTOR_STATUS_CONNECTED. + * This connector should only have + * been set up if the LVDS was actually connected anyway. + */ +static enum drm_connector_status cdv_intel_lvds_detect( + struct drm_connector *connector, bool force) +{ + return connector_status_connected; +} + +/** + * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. + */ +static int cdv_intel_lvds_get_modes(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + struct psb_intel_mode_device *mode_dev = + psb_intel_output->mode_dev; + int ret; + + ret = psb_intel_ddc_get_modes(psb_intel_output); + + if (ret) + return ret; + + /* Didn't get an EDID, so + * Set wide sync ranges so we get all modes + * handed to valid_mode for checking + */ + connector->display_info.min_vfreq = 0; + connector->display_info.max_vfreq = 200; + connector->display_info.min_hfreq = 0; + connector->display_info.max_hfreq = 200; + if (mode_dev->panel_fixed_mode != NULL) { + struct drm_display_mode *mode = + drm_mode_duplicate(dev, mode_dev->panel_fixed_mode); + drm_mode_probed_add(connector, mode); + return 1; + } + + return 0; +} + +/** + * cdv_intel_lvds_destroy - unregister and free LVDS structures + * @connector: connector to free + * + * Unregister the DDC bus for this connector then free the driver private + * structure. + */ +void cdv_intel_lvds_destroy(struct drm_connector *connector) +{ + struct psb_intel_output *psb_intel_output = + to_psb_intel_output(connector); + + if (psb_intel_output->ddc_bus) + psb_intel_i2c_destroy(psb_intel_output->ddc_bus); + drm_sysfs_connector_remove(connector); + drm_connector_cleanup(connector); + kfree(connector); +} + +int cdv_intel_lvds_set_property(struct drm_connector *connector, + struct drm_property *property, + uint64_t value) +{ + struct drm_encoder *encoder = connector->encoder; + + if (!strcmp(property->name, "scaling mode") && encoder) { + struct psb_intel_crtc *crtc = + to_psb_intel_crtc(encoder->crtc); + uint64_t curValue; + + if (!crtc) + return -1; + + switch (value) { + case DRM_MODE_SCALE_FULLSCREEN: + break; + case DRM_MODE_SCALE_NO_SCALE: + break; + case DRM_MODE_SCALE_ASPECT: + break; + default: + return -1; + } + + if (drm_connector_property_get_value(connector, + property, + &curValue)) + return -1; + + if (curValue == value) + return 0; + + if (drm_connector_property_set_value(connector, + property, + value)) + return -1; + + if (crtc->saved_mode.hdisplay != 0 && + crtc->saved_mode.vdisplay != 0) { + if (!drm_crtc_helper_set_mode(encoder->crtc, + &crtc->saved_mode, + encoder->crtc->x, + encoder->crtc->y, + encoder->crtc->fb)) + return -1; + } + } else if (!strcmp(property->name, "backlight") && encoder) { + if (drm_connector_property_set_value(connector, + property, + value)) + return -1; + else { +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + struct drm_psb_private *dev_priv = + encoder->dev->dev_private; + struct backlight_device *bd = + dev_priv->backlight_device; + bd->props.brightness = value; + backlight_update_status(bd); +#endif + } + } else if (!strcmp(property->name, "DPMS") && encoder) { + struct drm_encoder_helper_funcs *helpers = + encoder->helper_private; + helpers->dpms(encoder, value); + } + return 0; +} + +static const struct drm_encoder_helper_funcs + cdv_intel_lvds_helper_funcs = { + .dpms = cdv_intel_lvds_encoder_dpms, + .mode_fixup = cdv_intel_lvds_mode_fixup, + .prepare = cdv_intel_lvds_prepare, + .mode_set = cdv_intel_lvds_mode_set, + .commit = cdv_intel_lvds_commit, +}; + +static const struct drm_connector_helper_funcs + cdv_intel_lvds_connector_helper_funcs = { + .get_modes = cdv_intel_lvds_get_modes, + .mode_valid = cdv_intel_lvds_mode_valid, + .best_encoder = psb_intel_best_encoder, +}; + +static const struct drm_connector_funcs cdv_intel_lvds_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .save = cdv_intel_lvds_save, + .restore = cdv_intel_lvds_restore, + .detect = cdv_intel_lvds_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .set_property = cdv_intel_lvds_set_property, + .destroy = cdv_intel_lvds_destroy, +}; + + +static void cdv_intel_lvds_enc_destroy(struct drm_encoder *encoder) +{ + drm_encoder_cleanup(encoder); +} + +const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = { + .destroy = cdv_intel_lvds_enc_destroy, +}; + +/** + * cdv_intel_lvds_init - setup LVDS connectors on this device + * @dev: drm device + * + * Create the connector, register the LVDS DDC bus, and try to figure out what + * modes we can display on the LVDS panel (if present). + */ +void cdv_intel_lvds_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev) +{ + struct psb_intel_output *psb_intel_output; + struct cdv_intel_lvds_priv *lvds_priv; + struct drm_connector *connector; + struct drm_encoder *encoder; + struct drm_display_mode *scan; + struct drm_crtc *crtc; + struct drm_psb_private *dev_priv = dev->dev_private; + u32 lvds; + int pipe; + + psb_intel_output = kzalloc(sizeof(struct psb_intel_output) + + sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL); + if (!psb_intel_output) + return; + + lvds_priv = (struct cdv_intel_lvds_priv *)(psb_intel_output + 1); + + psb_intel_output->dev_priv = lvds_priv; + + psb_intel_output->mode_dev = mode_dev; + connector = &psb_intel_output->base; + encoder = &psb_intel_output->enc; + + + drm_connector_init(dev, &psb_intel_output->base, + &cdv_intel_lvds_connector_funcs, + DRM_MODE_CONNECTOR_LVDS); + + drm_encoder_init(dev, &psb_intel_output->enc, + &cdv_intel_lvds_enc_funcs, + DRM_MODE_ENCODER_LVDS); + + + drm_mode_connector_attach_encoder(&psb_intel_output->base, + &psb_intel_output->enc); + psb_intel_output->type = INTEL_OUTPUT_LVDS; + + drm_encoder_helper_add(encoder, &cdv_intel_lvds_helper_funcs); + drm_connector_helper_add(connector, + &cdv_intel_lvds_connector_helper_funcs); + connector->display_info.subpixel_order = SubPixelHorizontalRGB; + connector->interlace_allowed = false; + connector->doublescan_allowed = false; + + /*Attach connector properties*/ + drm_connector_attach_property(connector, + dev->mode_config.scaling_mode_property, + DRM_MODE_SCALE_FULLSCREEN); + drm_connector_attach_property(connector, + dev_priv->backlight_property, + BRIGHTNESS_MAX_LEVEL); + + /** + * Set up I2C bus + * FIXME: distroy i2c_bus when exit + */ + psb_intel_output->i2c_bus = psb_intel_i2c_create(dev, + GPIOB, + "LVDSBLC_B"); + if (!psb_intel_output->i2c_bus) { + dev_printk(KERN_ERR, + &dev->pdev->dev, "I2C bus registration failed.\n"); + goto failed_blc_i2c; + } + psb_intel_output->i2c_bus->slave_addr = 0x2C; + dev_priv->lvds_i2c_bus = psb_intel_output->i2c_bus; + + /* + * LVDS discovery: + * 1) check for EDID on DDC + * 2) check for VBT data + * 3) check to see if LVDS is already on + * if none of the above, no panel + * 4) make sure lid is open + * if closed, act like it's not there for now + */ + + /* Set up the DDC bus. */ + psb_intel_output->ddc_bus = psb_intel_i2c_create(dev, + GPIOC, + "LVDSDDC_C"); + if (!psb_intel_output->ddc_bus) { + dev_printk(KERN_ERR, &dev->pdev->dev, + "DDC bus registration " "failed.\n"); + goto failed_ddc; + } + + /* + * Attempt to get the fixed panel mode from DDC. Assume that the + * preferred mode is the right one. + */ + psb_intel_ddc_get_modes(psb_intel_output); + list_for_each_entry(scan, &connector->probed_modes, head) { + if (scan->type & DRM_MODE_TYPE_PREFERRED) { + mode_dev->panel_fixed_mode = + drm_mode_duplicate(dev, scan); + goto out; /* FIXME: check for quirks */ + } + } + + /* Failed to get EDID, what about VBT? do we need this?*/ + if (dev_priv->lfp_lvds_vbt_mode) { + mode_dev->panel_fixed_mode = + drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode); + if (mode_dev->panel_fixed_mode) { + mode_dev->panel_fixed_mode->type |= + DRM_MODE_TYPE_PREFERRED; + goto out; /* FIXME: check for quirks */ + } + } + /* + * If we didn't get EDID, try checking if the panel is already turned + * on. If so, assume that whatever is currently programmed is the + * correct mode. + */ + lvds = REG_READ(LVDS); + pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; + crtc = psb_intel_get_crtc_from_pipe(dev, pipe); + + if (crtc && (lvds & LVDS_PORT_EN)) { + mode_dev->panel_fixed_mode = + cdv_intel_crtc_mode_get(dev, crtc); + if (mode_dev->panel_fixed_mode) { + mode_dev->panel_fixed_mode->type |= + DRM_MODE_TYPE_PREFERRED; + goto out; /* FIXME: check for quirks */ + } + } + + /* If we still don't have a mode after all that, give up. */ + if (!mode_dev->panel_fixed_mode) { + DRM_DEBUG + ("Found no modes on the lvds, ignoring the LVDS\n"); + goto failed_find; + } + +out: + drm_sysfs_connector_add(connector); + return; + +failed_find: + printk(KERN_ERR "Failed find\n"); + if (psb_intel_output->ddc_bus) + psb_intel_i2c_destroy(psb_intel_output->ddc_bus); +failed_ddc: + printk(KERN_ERR "Failed DDC\n"); + if (psb_intel_output->i2c_bus) + psb_intel_i2c_destroy(psb_intel_output->i2c_bus); +failed_blc_i2c: + printk(KERN_ERR "Failed BLC\n"); + drm_encoder_cleanup(encoder); + drm_connector_cleanup(connector); + kfree(connector); +} diff --git a/drivers/staging/gma500/displays/hdmi.h b/drivers/staging/gma500/displays/hdmi.h new file mode 100644 index 000000000000..d58ba9bd010f --- /dev/null +++ b/drivers/staging/gma500/displays/hdmi.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 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: + * Thomas Eaton + * Scott Rowe + */ + +#ifndef HDMI_H +#define HDMI_H + +extern void hdmi_init(struct drm_device *dev); + +#endif diff --git a/drivers/staging/gma500/displays/pyr_cmd.h b/drivers/staging/gma500/displays/pyr_cmd.h new file mode 100644 index 000000000000..84bae5c8c552 --- /dev/null +++ b/drivers/staging/gma500/displays/pyr_cmd.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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, sublicensen + * 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: + * Thomas Eaton + * Scott Rowe + */ + +#ifndef PYR_CMD_H +#define PYR_CMD_H + +extern void pyr_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs); + +#endif + diff --git a/drivers/staging/gma500/displays/pyr_vid.h b/drivers/staging/gma500/displays/pyr_vid.h new file mode 100644 index 000000000000..ce98860fa68a --- /dev/null +++ b/drivers/staging/gma500/displays/pyr_vid.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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, sublicensen + * 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: + * Thomas Eaton + * Scott Rowe +*/ + +#ifndef PYR_VID_H +#define PYR_VID_H + +extern void pyr_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs); +extern struct drm_display_mode *pyr_vid_get_config_mode(struct drm_device* dev); + +#endif diff --git a/drivers/staging/gma500/displays/tmd_cmd.h b/drivers/staging/gma500/displays/tmd_cmd.h new file mode 100644 index 000000000000..641e85eedece --- /dev/null +++ b/drivers/staging/gma500/displays/tmd_cmd.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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, sublicensen + * 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: + * Thomas Eaton + * Scott Rowe + */ + +#ifndef TMD_CMD_H +#define TMD_CMD_H + +extern void tmd_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs); +extern struct drm_display_mode *tmd_cmd_get_config_mode(struct drm_device *dev); + +#endif diff --git a/drivers/staging/gma500/displays/tmd_vid.h b/drivers/staging/gma500/displays/tmd_vid.h new file mode 100644 index 000000000000..7a5fa3b935e3 --- /dev/null +++ b/drivers/staging/gma500/displays/tmd_vid.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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, sublicensen + * 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: + * Thomas Eaton + * Scott Rowe +*/ + +#ifndef TMD_VID_H +#define TMD_VID_H + +extern void tmd_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs); +extern struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev); + +#endif diff --git a/drivers/staging/gma500/displays/tpo_cmd.h b/drivers/staging/gma500/displays/tpo_cmd.h new file mode 100644 index 000000000000..610552730d71 --- /dev/null +++ b/drivers/staging/gma500/displays/tpo_cmd.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 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, sublicensen + * 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: + * Thomas Eaton + * Scott Rowe +*/ + +#ifndef TPO_CMD_H +#define TPO_CMD_H + +extern void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs); +/* extern struct drm_display_mode * */ +/* tpo_cmd_get_config_mode(struct drm_device *dev); */ + +#endif diff --git a/drivers/staging/gma500/displays/tpo_vid.h b/drivers/staging/gma500/displays/tpo_vid.h new file mode 100644 index 000000000000..c24f05722de1 --- /dev/null +++ b/drivers/staging/gma500/displays/tpo_vid.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 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, sublicensen + * 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: + * Thomas Eaton + * Scott Rowe + */ + +#ifndef TPO_VID_H +#define TPO_VID_H + +extern void tpo_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs); + +#endif diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/framebuffer.c similarity index 67% rename from drivers/staging/gma500/psb_fb.c rename to drivers/staging/gma500/framebuffer.c index 084c36bbfe86..ebfde13ec18f 100644 --- a/drivers/staging/gma500/psb_fb.c +++ b/drivers/staging/gma500/framebuffer.c @@ -1,5 +1,5 @@ /************************************************************************** - * Copyright (c) 2007, Intel Corporation. + * Copyright (c) 2007-2011, Intel Corporation. * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it @@ -36,7 +36,9 @@ #include "psb_drv.h" #include "psb_intel_reg.h" #include "psb_intel_drv.h" -#include "psb_fb.h" +#include "framebuffer.h" + +#include "mdfld_output.h" static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb); static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb, @@ -50,14 +52,6 @@ static const struct drm_framebuffer_funcs psb_fb_funcs = { #define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16) -void *psbfb_vdc_reg(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv; - dev_priv = (struct drm_psb_private *) dev->dev_private; - return dev_priv->vdc_reg; -} -/*EXPORT_SYMBOL(psbfb_vdc_reg); */ - static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) @@ -97,109 +91,60 @@ static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green, return 0; } -static int psbfb_kms_off(struct drm_device *dev, int suspend) -{ - struct drm_framebuffer *fb = 0; - struct psb_framebuffer *psbfb = to_psb_fb(fb); - DRM_DEBUG("psbfb_kms_off_ioctl\n"); - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(fb, &dev->mode_config.fb_list, head) { - struct fb_info *info = psbfb->fbdev; - - if (suspend) { - fb_set_suspend(info, 1); - drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); - } - } - mutex_unlock(&dev->mode_config.mutex); - return 0; -} - -int psbfb_kms_off_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - int ret; - - if (drm_psb_no_fb) - return 0; - console_lock(); - ret = psbfb_kms_off(dev, 0); - console_unlock(); - - return ret; -} - -static int psbfb_kms_on(struct drm_device *dev, int resume) -{ - struct drm_framebuffer *fb = 0; - struct psb_framebuffer *psbfb = to_psb_fb(fb); - - DRM_DEBUG("psbfb_kms_on_ioctl\n"); - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(fb, &dev->mode_config.fb_list, head) { - struct fb_info *info = psbfb->fbdev; - - if (resume) { - fb_set_suspend(info, 0); - drm_fb_helper_blank(FB_BLANK_UNBLANK, info); - } - } - mutex_unlock(&dev->mode_config.mutex); - - return 0; -} - -int psbfb_kms_on_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - int ret; - - if (drm_psb_no_fb) - return 0; - console_lock(); - ret = psbfb_kms_on(dev, 0); - console_unlock(); - drm_helper_disable_unused_functions(dev); - return ret; -} void psbfb_suspend(struct drm_device *dev) { + struct drm_framebuffer *fb = 0; + struct psb_framebuffer *psbfb = to_psb_fb(fb); + console_lock(); - psbfb_kms_off(dev, 1); + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(fb, &dev->mode_config.fb_list, head) { + struct fb_info *info = psbfb->fbdev; + fb_set_suspend(info, 1); + drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); + } + mutex_unlock(&dev->mode_config.mutex); console_unlock(); } void psbfb_resume(struct drm_device *dev) { + struct drm_framebuffer *fb = 0; + struct psb_framebuffer *psbfb = to_psb_fb(fb); + console_lock(); - psbfb_kms_on(dev, 1); + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(fb, &dev->mode_config.fb_list, head) { + struct fb_info *info = psbfb->fbdev; + fb_set_suspend(info, 0); + drm_fb_helper_blank(FB_BLANK_UNBLANK, info); + } + mutex_unlock(&dev->mode_config.mutex); console_unlock(); drm_helper_disable_unused_functions(dev); } static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - int page_num = 0; - int i; - unsigned long address = 0; - int ret; - unsigned long pfn; struct psb_framebuffer *psbfb = vma->vm_private_data; struct drm_device *dev = psbfb->base.dev; struct drm_psb_private *dev_priv = dev->dev_private; + int page_num; + int i; + unsigned long address; + int ret; + unsigned long pfn; + /* FIXME: assumes fb at stolen base which may not be true */ unsigned long phys_addr = (unsigned long)dev_priv->stolen_base; page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; - address = (unsigned long)vmf->virtual_address; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); for (i = 0; i < page_num; i++) { - pfn = (phys_addr >> PAGE_SHIFT); /* phys_to_pfn(phys_addr); */ + pfn = (phys_addr >> PAGE_SHIFT); ret = vm_insert_mixed(vma, address, pfn); if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0))) @@ -208,22 +153,18 @@ static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS; return ret; } - address += PAGE_SIZE; phys_addr += PAGE_SIZE; } - return VM_FAULT_NOPAGE; } static void psbfb_vm_open(struct vm_area_struct *vma) { - DRM_DEBUG("vm_open\n"); } static void psbfb_vm_close(struct vm_area_struct *vma) { - DRM_DEBUG("vm_close\n"); } static struct vm_operations_struct psbfb_vm_ops = { @@ -235,10 +176,7 @@ static struct vm_operations_struct psbfb_vm_ops = { static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma) { struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = fbdev->pfb; - char *fb_screen_base = NULL; - struct drm_device *dev = psbfb->base.dev; - struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_framebuffer *psbfb = &fbdev->pfb; if (vma->vm_pgoff != 0) return -EINVAL; @@ -247,51 +185,22 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma) if (!psbfb->addr_space) psbfb->addr_space = vma->vm_file->f_mapping; - - fb_screen_base = (char *)info->screen_base; - - DRM_DEBUG("vm_pgoff 0x%lx, screen base %p vram_addr %p\n", - vma->vm_pgoff, fb_screen_base, - dev_priv->vram_addr); - - /* FIXME: ultimately this needs to become 'if entirely stolen memory' */ - if (1 || fb_screen_base == dev_priv->vram_addr) { - vma->vm_ops = &psbfb_vm_ops; - vma->vm_private_data = (void *)psbfb; - vma->vm_flags |= VM_RESERVED | VM_IO | - VM_MIXEDMAP | VM_DONTEXPAND; - } else { - /* GTT memory backed by kernel/user pages, needs a different - approach ? - GEM ? */ - } - + /* + * If this is a GEM object then info->screen_base is the virtual + * kernel remapping of the object. FIXME: Review if this is + * suitable for our mmap work + */ + vma->vm_ops = &psbfb_vm_ops; + vma->vm_private_data = (void *)psbfb; + vma->vm_flags |= VM_RESERVED | VM_IO | + VM_MIXEDMAP | VM_DONTEXPAND; return 0; } -static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) +static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, + unsigned long arg) { - struct psb_fbdev *fbdev = info->par; - struct psb_framebuffer *psbfb = fbdev->pfb; - struct drm_device *dev = psbfb->base.dev; - struct drm_psb_private *dev_priv = dev->dev_private; - u32 __user *p = (u32 __user *)arg; - u32 l; - u32 buf[32]; - switch (cmd) { - case 0x12345678: - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - if (get_user(l, p)) - return -EFAULT; - if (l > 32) - return -EMSGSIZE; - if (copy_from_user(buf, p + 1, l * sizeof(u32))) - return -EFAULT; - psbfb_2d_submit(dev_priv, buf, l); - return 0; - default: - return -ENOTTY; - } + return -ENOTTY; } static struct fb_ops psbfb_ops = { @@ -300,16 +209,80 @@ static struct fb_ops psbfb_ops = { .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, .fb_setcolreg = psbfb_setcolreg, - .fb_fillrect = psbfb_fillrect, + .fb_fillrect = cfb_fillrect, .fb_copyarea = psbfb_copyarea, - .fb_imageblit = psbfb_imageblit, + .fb_imageblit = cfb_imageblit, .fb_mmap = psbfb_mmap, .fb_sync = psbfb_sync, .fb_ioctl = psbfb_ioctl, }; +static struct fb_ops psbfb_unaccel_ops = { + .owner = THIS_MODULE, + .fb_check_var = drm_fb_helper_check_var, + .fb_set_par = drm_fb_helper_set_par, + .fb_blank = drm_fb_helper_blank, + .fb_setcolreg = psbfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_mmap = psbfb_mmap, + .fb_ioctl = psbfb_ioctl, +}; + +/** + * psb_framebuffer_init - initialize a framebuffer + * @dev: our DRM device + * @fb: framebuffer to set up + * @mode_cmd: mode description + * @gt: backing object + * + * Configure and fill in the boilerplate for our frame buffer. Return + * 0 on success or an error code if we fail. + */ +static int psb_framebuffer_init(struct drm_device *dev, + struct psb_framebuffer *fb, + struct drm_mode_fb_cmd *mode_cmd, + struct gtt_range *gt) +{ + int ret; + + if (mode_cmd->pitch & 63) + return -EINVAL; + switch (mode_cmd->bpp) { + case 8: + case 16: + case 24: + case 32: + break; + default: + return -EINVAL; + } + ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs); + if (ret) { + dev_err(dev->dev, "framebuffer init failed: %d\n", ret); + return ret; + } + drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd); + fb->gtt = gt; + return 0; +} + +/** + * psb_framebuffer_create - create a framebuffer backed by gt + * @dev: our DRM device + * @mode_cmd: the description of the requested mode + * @gt: the backing object + * + * Create a framebuffer object backed by the gt, and fill in the + * boilerplate required + * + * TODO: review object references + */ + static struct drm_framebuffer *psb_framebuffer_create - (struct drm_device *dev, struct drm_mode_fb_cmd *r, + (struct drm_device *dev, + struct drm_mode_fb_cmd *mode_cmd, struct gtt_range *gt) { struct psb_framebuffer *fb; @@ -317,22 +290,14 @@ static struct drm_framebuffer *psb_framebuffer_create fb = kzalloc(sizeof(*fb), GFP_KERNEL); if (!fb) - return NULL; - - ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs); - - if (ret) - goto err; - - drm_helper_mode_fill_fb_struct(&fb->base, r); - - fb->gtt = gt; + return ERR_PTR(-ENOMEM); + ret = psb_framebuffer_init(dev, fb, mode_cmd, gt); + if (ret) { + kfree(fb); + return ERR_PTR(ret); + } return &fb->base; - -err: - kfree(fb); - return NULL; } /** @@ -345,15 +310,22 @@ static struct drm_framebuffer *psb_framebuffer_create * stolen memory or the system has no stolen memory we allocate a range * and back it with a GEM object. * - * In this case the GEM object has no handle. + * In this case the GEM object has no handle. + * + * FIXME: console speed up - allocate twice the space if room and use + * hardware scrolling for acceleration. */ static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size) { struct gtt_range *backing; /* Begin by trying to use stolen memory backing */ backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1); - if (backing) - return backing; + if (backing) { + if (drm_gem_private_object_init(dev, + &backing->gem, aligned_size) == 0) + return backing; + psb_gtt_free_range(dev, backing); + } /* Next try using GEM host memory */ backing = psb_gtt_alloc_range(dev, aligned_size, "fb(gem)", 0); if (backing == NULL) @@ -366,7 +338,7 @@ static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size) } return backing; } - + /** * psbfb_create - create a framebuffer * @fbdev: the framebuffer device @@ -381,74 +353,96 @@ static int psbfb_create(struct psb_fbdev *fbdev, struct drm_psb_private *dev_priv = dev->dev_private; struct fb_info *info; struct drm_framebuffer *fb; - struct psb_framebuffer *psbfb; + struct psb_framebuffer *psbfb = &fbdev->pfb; struct drm_mode_fb_cmd mode_cmd; struct device *device = &dev->pdev->dev; - int size, aligned_size; + int size; int ret; struct gtt_range *backing; mode_cmd.width = sizes->surface_width; mode_cmd.height = sizes->surface_height; + mode_cmd.bpp = sizes->surface_bpp; + + /* No 24bit packed */ + if (mode_cmd.bpp == 24) + mode_cmd.bpp = 32; - mode_cmd.bpp = 32; /* HW requires pitch to be 64 byte aligned */ - mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64); - mode_cmd.depth = 24; + mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64); + mode_cmd.depth = sizes->surface_depth; size = mode_cmd.pitch * mode_cmd.height; - aligned_size = ALIGN(size, PAGE_SIZE); + size = ALIGN(size, PAGE_SIZE); /* Allocate the framebuffer in the GTT with stolen page backing */ - backing = psbfb_alloc(dev, aligned_size); + backing = psbfb_alloc(dev, size); if (backing == NULL) - return -ENOMEM; + return -ENOMEM; mutex_lock(&dev->struct_mutex); - fb = psb_framebuffer_create(dev, &mode_cmd, backing); - if (!fb) { - DRM_ERROR("failed to allocate fb.\n"); + + info = framebuffer_alloc(0, device); + if (!info) { ret = -ENOMEM; goto out_err1; } - psbfb = to_psb_fb(fb); - - info = framebuffer_alloc(sizeof(struct psb_fbdev), device); - if (!info) { - ret = -ENOMEM; - goto out_err0; - } - info->par = fbdev; + ret = psb_framebuffer_init(dev, psbfb, &mode_cmd, backing); + if (ret) + goto out_unref; + + fb = &psbfb->base; psbfb->fbdev = info; fbdev->psb_fb_helper.fb = fb; fbdev->psb_fb_helper.fbdev = info; - fbdev->pfb = psbfb; strcpy(info->fix.id, "psbfb"); info->flags = FBINFO_DEFAULT; - info->fbops = &psbfb_ops; + /* No 2D engine */ + if (!dev_priv->ops->accel_2d) + info->fbops = &psbfb_unaccel_ops; + else + info->fbops = &psbfb_ops; + + ret = fb_alloc_cmap(&info->cmap, 256, 0); + if (ret) { + ret = -ENOMEM; + goto out_unref; + } + info->fix.smem_start = dev->mode_config.fb_base; info->fix.smem_len = size; - /* Accessed via stolen memory directly, This only works for stolem - memory however. Need to address this once we start using gtt - pages we allocate */ - info->screen_base = (char *)dev_priv->vram_addr + backing->offset; + if (backing->stolen) { + /* Accessed stolen memory directly */ + info->screen_base = (char *)dev_priv->vram_addr + + backing->offset; + } else { + /* Pin the pages into the GTT and create a mapping to them */ + psb_gtt_pin(backing); + info->screen_base = vm_map_ram(backing->pages, backing->npage, + -1, PAGE_KERNEL); + if (info->screen_base == NULL) { + psb_gtt_unpin(backing); + ret = -ENOMEM; + goto out_unref; + } + psbfb->vm_map = 1; + } info->screen_size = size; - memset(info->screen_base, 0, size); - if (dev_priv->pg->stolen_size) { + if (dev_priv->gtt.stolen_size) { info->apertures = alloc_apertures(1); if (!info->apertures) { ret = -ENOMEM; - goto out_err0; + goto out_unref; } info->apertures->ranges[0].base = dev->mode_config.fb_base; - info->apertures->ranges[0].size = dev_priv->pg->stolen_size; + info->apertures->ranges[0].size = dev_priv->gtt.stolen_size; } drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); @@ -464,17 +458,19 @@ static int psbfb_create(struct psb_fbdev *fbdev, info->pixmap.flags = FB_PIXMAP_SYSTEM; info->pixmap.scan_align = 1; - DRM_DEBUG("fb depth is %d\n", fb->depth); - DRM_DEBUG(" pitch is %d\n", fb->pitch); - - printk(KERN_INFO"allocated %dx%d fb\n", - psbfb->base.width, psbfb->base.height); + dev_info(dev->dev, "allocated %dx%d fb\n", + psbfb->base.width, psbfb->base.height); mutex_unlock(&dev->struct_mutex); - return 0; -out_err0: - fb->funcs->destroy(fb); +out_unref: + if (backing->stolen) + psb_gtt_free_range(dev, backing); + else { + if (psbfb->vm_map) + vm_unmap_ram(info->screen_base, backing->npage); + drm_gem_object_unreference(&backing->gem); + } out_err1: mutex_unlock(&dev->struct_mutex); psb_gtt_free_range(dev, backing); @@ -493,45 +489,30 @@ static struct drm_framebuffer *psb_user_framebuffer_create (struct drm_device *dev, struct drm_file *filp, struct drm_mode_fb_cmd *cmd) { - struct gtt_range *r; - struct drm_gem_object *obj; - struct psb_framebuffer *psbfb; + struct gtt_range *r; + struct drm_gem_object *obj; - /* Find the GEM object and thus the gtt range object that is - to back this space */ + /* + * Find the GEM object and thus the gtt range object that is + * to back this space + */ obj = drm_gem_object_lookup(dev, filp, cmd->handle); if (obj == NULL) - return ERR_PTR(-ENOENT); + return ERR_PTR(-ENOENT); - /* Allocate a framebuffer */ - psbfb = kzalloc(sizeof(*psbfb), GFP_KERNEL); - if (psbfb == NULL) { - drm_gem_object_unreference_unlocked(obj); - return ERR_PTR(-ENOMEM); - } - - /* Let the core code do all the work */ - r = container_of(obj, struct gtt_range, gem); - if (psb_framebuffer_create(dev, cmd, r) == NULL) { - drm_gem_object_unreference_unlocked(obj); - kfree(psbfb); - return ERR_PTR(-EINVAL); - } - /* Return the drm_framebuffer contained within the psb fbdev which - has been initialized by the framebuffer creation */ - return &psbfb->base; + /* Let the core code do all the work */ + r = container_of(obj, struct gtt_range, gem); + return psb_framebuffer_create(dev, cmd, r); } static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, int regno) { - DRM_DEBUG("%s\n", __func__); } static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, int regno) { - DRM_DEBUG("%s\n", __func__); } static int psbfb_probe(struct drm_fb_helper *helper, @@ -541,8 +522,6 @@ static int psbfb_probe(struct drm_fb_helper *helper, int new_fb = 0; int ret; - DRM_DEBUG("%s\n", __func__); - if (!helper->fb) { ret = psbfb_create(psb_fbdev, sizes); if (ret) @@ -561,24 +540,27 @@ struct drm_fb_helper_funcs psb_fb_helper_funcs = { int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev) { struct fb_info *info; - struct psb_framebuffer *psbfb = fbdev->pfb; + struct psb_framebuffer *psbfb = &fbdev->pfb; if (fbdev->psb_fb_helper.fbdev) { info = fbdev->psb_fb_helper.fbdev; - /* FIXME: this is a bit more inside knowledge than I'd like - but I don't see how to make a fake GEM object of the - stolen space nicely */ - if (psbfb->gtt->stolen) - psb_gtt_free_range(dev, psbfb->gtt); - else - drm_gem_object_unreference(&psbfb->gtt->gem); + + /* If this is our base framebuffer then kill any virtual map + for the framebuffer layer and unpin it */ + if (psbfb->vm_map) { + vm_unmap_ram(info->screen_base, psbfb->gtt->npage); + psb_gtt_unpin(psbfb->gtt); + } unregister_framebuffer(info); - iounmap(info->screen_base); + if (info->cmap.len) + fb_dealloc_cmap(&info->cmap); framebuffer_release(info); } - drm_fb_helper_fini(&fbdev->psb_fb_helper); drm_framebuffer_cleanup(&psbfb->base); + + if (psbfb->gtt) + drm_gem_object_unreference(&psbfb->gtt->gem); return 0; } @@ -586,20 +568,17 @@ int psb_fbdev_init(struct drm_device *dev) { struct psb_fbdev *fbdev; struct drm_psb_private *dev_priv = dev->dev_private; - int num_crtc; fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL); if (!fbdev) { - DRM_ERROR("no memory\n"); + dev_err(dev->dev, "no memory\n"); return -ENOMEM; } dev_priv->fbdev = fbdev; fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs; - num_crtc = 2; - - drm_fb_helper_init(dev, &fbdev->psb_fb_helper, num_crtc, + drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs, INTELFB_CONN_LIMIT); drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper); @@ -626,22 +605,6 @@ static void psbfb_output_poll_changed(struct drm_device *dev) drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper); } -int psbfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) -{ - struct fb_info *info; - struct psb_framebuffer *psbfb = to_psb_fb(fb); - - if (drm_psb_no_fb) - return 0; - - info = psbfb->fbdev; - - if (info) - framebuffer_release(info); - return 0; -} -/*EXPORT_SYMBOL(psbfb_remove); */ - /** * psb_user_framebuffer_create_handle - add hamdle to a framebuffer * @fb: framebuffer @@ -656,11 +619,9 @@ static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb, struct drm_file *file_priv, unsigned int *handle) { - struct psb_framebuffer *psbfb = to_psb_fb(fb); - struct gtt_range *r = psbfb->gtt; - if (r->stolen) - return -EOPNOTSUPP; - return drm_gem_handle_create(file_priv, &r->gem, handle); + struct psb_framebuffer *psbfb = to_psb_fb(fb); + struct gtt_range *r = psbfb->gtt; + return drm_gem_handle_create(file_priv, &r->gem, handle); } /** @@ -672,18 +633,37 @@ static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb, */ static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb) { - struct drm_device *dev = fb->dev; struct psb_framebuffer *psbfb = to_psb_fb(fb); struct gtt_range *r = psbfb->gtt; + struct drm_device *dev = fb->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_fbdev *fbdev = dev_priv->fbdev; + struct drm_crtc *crtc; + int reset = 0; - if (psbfb->fbdev) - psbfb_remove(dev, fb); + /* Should never get stolen memory for a user fb */ + WARN_ON(r->stolen); - /* Let DRM do its clean up */ + /* Check if we are erroneously live */ + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + if (crtc->fb == fb) + reset = 1; + + if (reset) + /* + * Now force a sane response before we permit the DRM CRTC + * layer to do stupid things like blank the display. Instead + * we reset this framebuffer as if the user had forced a reset. + * We must do this before the cleanup so that the DRM layer + * doesn't get a chance to stick its oar in where it isn't + * wanted. + */ + drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper); + + /* Let DRM do its clean up */ drm_framebuffer_cleanup(fb); /* We are no longer using the resource in GEM */ drm_gem_object_unreference_unlocked(&r->gem); - kfree(fb); } @@ -694,17 +674,14 @@ static const struct drm_mode_config_funcs psb_mode_funcs = { static int psb_create_backlight_property(struct drm_device *dev) { - struct drm_psb_private *dev_priv - = (struct drm_psb_private *) dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; struct drm_property *backlight; if (dev_priv->backlight_property) return 0; - backlight = drm_property_create(dev, - DRM_MODE_PROP_RANGE, - "backlight", - 2); + backlight = drm_property_create(dev, DRM_MODE_PROP_RANGE, + "backlight", 2); backlight->values[0] = 0; backlight->values[1] = 100; @@ -715,25 +692,13 @@ static int psb_create_backlight_property(struct drm_device *dev) static void psb_setup_outputs(struct drm_device *dev) { - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; struct drm_connector *connector; - PSB_DEBUG_ENTRY("\n"); - drm_mode_create_scaling_mode_property(dev); - psb_create_backlight_property(dev); - if (IS_MRST(dev)) { - if (dev_priv->iLVDS_enable) - mrst_lvds_init(dev, &dev_priv->mode_dev); - else - DRM_ERROR("DSI is not supported\n"); - } else { - psb_intel_lvds_init(dev, &dev_priv->mode_dev); - psb_intel_sdvo_init(dev, SDVOB); - } + dev_priv->ops->output_init(dev); list_for_each_entry(connector, &dev->mode_config.connector_list, head) { @@ -744,12 +709,15 @@ static void psb_setup_outputs(struct drm_device *dev) /* valid crtcs */ switch (psb_intel_output->type) { + case INTEL_OUTPUT_ANALOG: + crtc_mask = (1 << 0); + clone_mask = (1 << INTEL_OUTPUT_ANALOG); + break; case INTEL_OUTPUT_SDVO: crtc_mask = ((1 << 0) | (1 << 1)); clone_mask = (1 << INTEL_OUTPUT_SDVO); break; case INTEL_OUTPUT_LVDS: - PSB_DEBUG_ENTRY("LVDS.\n"); if (IS_MRST(dev)) crtc_mask = (1 << 0); else @@ -757,26 +725,24 @@ static void psb_setup_outputs(struct drm_device *dev) clone_mask = (1 << INTEL_OUTPUT_LVDS); break; case INTEL_OUTPUT_MIPI: - PSB_DEBUG_ENTRY("MIPI.\n"); crtc_mask = (1 << 0); clone_mask = (1 << INTEL_OUTPUT_MIPI); break; case INTEL_OUTPUT_MIPI2: - PSB_DEBUG_ENTRY("MIPI2.\n"); crtc_mask = (1 << 2); clone_mask = (1 << INTEL_OUTPUT_MIPI2); break; case INTEL_OUTPUT_HDMI: - PSB_DEBUG_ENTRY("HDMI.\n"); - crtc_mask = (1 << 1); + if (IS_MFLD(dev)) + crtc_mask = (1 << 1); + else /* FIXME: review Oaktrail */ + crtc_mask = (1 << 0); /* Cedarview */ clone_mask = (1 << INTEL_OUTPUT_HDMI); break; } - encoder->possible_crtcs = crtc_mask; encoder->possible_clones = psb_intel_connector_clones(dev, clone_mask); - } } @@ -787,8 +753,6 @@ void psb_modeset_init(struct drm_device *dev) struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; int i; - PSB_DEBUG_ENTRY("\n"); - drm_mode_config_init(dev); dev->mode_config.min_width = 0; @@ -809,9 +773,6 @@ void psb_modeset_init(struct drm_device *dev) dev->mode_config.max_height = 2048; psb_setup_outputs(dev); - - /* setup fbs */ - /* drm_initial_config(dev); */ } void psb_modeset_cleanup(struct drm_device *dev) @@ -820,7 +781,6 @@ void psb_modeset_cleanup(struct drm_device *dev) drm_kms_helper_poll_fini(dev); psb_fbdev_fini(dev); - drm_mode_config_cleanup(dev); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/staging/gma500/psb_fb.h b/drivers/staging/gma500/framebuffer.h similarity index 86% rename from drivers/staging/gma500/psb_fb.h rename to drivers/staging/gma500/framebuffer.h index c8ec0d6febb1..d1b2289447f0 100644 --- a/drivers/staging/gma500/psb_fb.h +++ b/drivers/staging/gma500/framebuffer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Intel Corporation + * Copyright (c) 2008-2011, Intel 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, @@ -19,10 +19,9 @@ * */ -#ifndef _PSB_FB_H_ -#define _PSB_FB_H_ +#ifndef _FRAMEBUFFER_H_ +#define _FRAMEBUFFER_H_ -#include #include #include @@ -33,14 +32,14 @@ struct psb_framebuffer { struct address_space *addr_space; struct fb_info *fbdev; struct gtt_range *gtt; + bool vm_map; /* True if we must undo a vm_map_ram */ }; struct psb_fbdev { struct drm_fb_helper psb_fb_helper; - struct psb_framebuffer *pfb; + struct psb_framebuffer pfb; }; - #define to_psb_fb(x) container_of(x, struct psb_framebuffer, base) extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask); diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/gem.c similarity index 69% rename from drivers/staging/gma500/psb_gem.c rename to drivers/staging/gma500/gem.c index 76ff7bacd35b..65fdd6b8ab16 100644 --- a/drivers/staging/gma500/psb_gem.c +++ b/drivers/staging/gma500/gem.c @@ -19,12 +19,8 @@ * Authors: Alan Cox * * TODO: - * - we don't actually put GEM objects into the GART yet - * - we need to work out if the MMU is relevant as well (eg for + * - we need to work out if the MMU is relevant (eg for * accelerated operations on a GEM object) - * - cache coherency - * - * ie this is just an initial framework to get us going. */ #include @@ -40,17 +36,9 @@ int psb_gem_init_object(struct drm_gem_object *obj) void psb_gem_free_object(struct drm_gem_object *obj) { struct gtt_range *gtt = container_of(obj, struct gtt_range, gem); + drm_gem_object_release_wrap(obj); + /* This must occur last as it frees up the memory of the GEM object */ psb_gtt_free_range(obj->dev, gtt); - if (obj->map_list.map) { - /* Do things GEM should do for us */ - struct drm_gem_mm *mm = obj->dev->mm_private; - struct drm_map_list *list = &obj->map_list; - drm_ht_remove_item(&mm->offset_hash, &list->hash); - drm_mm_put_block(list->file_offset_node); - kfree(list->map); - list->map = NULL; - } - drm_gem_object_release(obj); } int psb_gem_get_aperture(struct drm_device *dev, void *data, @@ -59,59 +47,6 @@ int psb_gem_get_aperture(struct drm_device *dev, void *data, return -EINVAL; } -/** - * psb_gem_create_mmap_offset - invent an mmap offset - * @obj: our object - * - * This is basically doing by hand a pile of ugly crap which should - * be done automatically by the GEM library code but isn't - */ -static int psb_gem_create_mmap_offset(struct drm_gem_object *obj) -{ - struct drm_device *dev = obj->dev; - struct drm_gem_mm *mm = dev->mm_private; - struct drm_map_list *list; - struct drm_local_map *map; - int ret; - - list = &obj->map_list; - list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); - if (list->map == NULL) - return -ENOMEM; - map = list->map; - map->type = _DRM_GEM; - map->size = obj->size; - map->handle =obj; - - list->file_offset_node = drm_mm_search_free(&mm->offset_manager, - obj->size / PAGE_SIZE, 0, 0); - if (!list->file_offset_node) { - DRM_ERROR("failed to allocate offset for bo %d\n", obj->name); - ret = -ENOSPC; - goto free_it; - } - list->file_offset_node = drm_mm_get_block(list->file_offset_node, - obj->size / PAGE_SIZE, 0); - if (!list->file_offset_node) { - ret = -ENOMEM; - goto free_it; - } - list->hash.key = list->file_offset_node->start; - ret = drm_ht_insert_item(&mm->offset_hash, &list->hash); - if (ret) { - DRM_ERROR("failed to add to map hash\n"); - goto free_mm; - } - return 0; - -free_mm: - drm_mm_put_block(list->file_offset_node); -free_it: - kfree(list->map); - list->map = NULL; - return ret; -} - /** * psb_gem_dumb_map_gtt - buffer mapping for dumb interface * @file: our drm client file @@ -129,7 +64,7 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, if (!(dev->driver->driver_features & DRIVER_GEM)) return -ENODEV; - + mutex_lock(&dev->struct_mutex); /* GEM does all our handle to object mapping */ @@ -139,10 +74,10 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, goto unlock; } /* What validation is needed here ? */ - + /* Make it mmapable */ if (!obj->map_list.map) { - ret = psb_gem_create_mmap_offset(obj); + ret = gem_create_mmap_offset(obj); if (ret) goto out; } @@ -175,21 +110,26 @@ static int psb_gem_create(struct drm_file *file, size = roundup(size, PAGE_SIZE); - /* Allocate our object - for now a direct gtt range which is not + /* Allocate our object - for now a direct gtt range which is not stolen memory backed */ r = psb_gtt_alloc_range(dev, size, "gem", 0); - if (r == NULL) + if (r == NULL) { + dev_err(dev->dev, "no memory for %lld byte GEM object\n", size); return -ENOSPC; + } /* Initialize the extra goodies GEM needs to do all the hard work */ if (drm_gem_object_init(dev, &r->gem, size) != 0) { psb_gtt_free_range(dev, r); /* GEM doesn't give an error code and we don't have an EGEMSUCKS so make something up for now - FIXME */ + dev_err(dev->dev, "GEM init failed for %lld\n", size); return -ENOMEM; } /* Give the object a handle so we can carry it more easily */ ret = drm_gem_handle_create(file, &r->gem, &handle); if (ret) { + dev_err(dev->dev, "GEM handle failed for %p, %lld\n", + &r->gem, size); drm_gem_object_release(&r->gem); psb_gtt_free_range(dev, r); return ret; @@ -245,19 +185,13 @@ int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, * but we need to do the actual page work. * * This code eventually needs to handle faulting objects in and out - * of the GART and repacking it when we run out of space. We can put + * of the GTT and repacking it when we run out of space. We can put * that off for now and for our simple uses * * The VMA was set up by GEM. In doing so it also ensured that the * vma->vm_private_data points to the GEM object that is backing this * mapping. * - * To avoid aliasing and cache funnies we want to map the object - * through the GART. For the moment this is slightly hackish. It would - * be nicer if GEM provided mmap opened/closed hooks for us giving - * the object so that we could track things nicely. That needs changes - * to the core GEM code so must be tackled post staging - * * FIXME */ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) @@ -268,9 +202,11 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) unsigned long pfn; pgoff_t page_offset; struct drm_device *dev; + struct drm_psb_private *dev_priv; obj = vma->vm_private_data; /* GEM object */ dev = obj->dev; + dev_priv = dev->dev_private; r = container_of(obj, struct gtt_range, gem); /* Get the gtt range */ @@ -283,30 +219,26 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (r->mmapping == 0) { ret = psb_gtt_pin(r); if (ret < 0) { - DRM_ERROR("gma500: pin failed: %d\n", ret); - goto fail; - } + dev_err(dev->dev, "gma500: pin failed: %d\n", ret); + goto fail; + } r->mmapping = 1; } - /* FIXME: Locking. We may also need to repack the GART sometimes */ - - /* Page relative to the VMA start */ + /* Page relative to the VMA start - we must calculate this ourselves + because vmf->pgoff is the fake GEM offset */ page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start) >> PAGE_SHIFT; - /* Bus address of the page is gart + object offset + page offset */ - /* Assumes gtt allocations are page aligned */ - pfn = (r->resource.start >> PAGE_SHIFT) + page_offset; - - pr_debug("Object GTT base at %p\n", (void *)(r->resource.start)); - pr_debug("Inserting %p pfn %lx, pa %lx\n", vmf->virtual_address, - pfn, pfn << PAGE_SHIFT); - + /* CPU view of the page, don't go via the GART for CPU writes */ + if (r->stolen) + pfn = (dev_priv->stolen_base + r->offset) >> PAGE_SHIFT; + else + pfn = page_to_pfn(r->pages[page_offset]); ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); fail: - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&dev->struct_mutex); switch (ret) { case 0: case -ERESTARTSYS: @@ -318,3 +250,46 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) return VM_FAULT_SIGBUS; } } + +static int psb_gem_create_stolen(struct drm_file *file, struct drm_device *dev, + int size, u32 *handle) +{ + struct gtt_range *gtt = psb_gtt_alloc_range(dev, size, "gem", 1); + if (gtt == NULL) + return -ENOMEM; + if (drm_gem_private_object_init(dev, >t->gem, size) != 0) + goto free_gtt; + if (drm_gem_handle_create(file, >t->gem, handle) == 0) + return 0; +free_gtt: + psb_gtt_free_range(dev, gtt); + return -ENOMEM; +} + +/* + * GEM interfaces for our specific client + */ +int psb_gem_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_psb_gem_create *args = data; + int ret; + if (args->flags & PSB_GEM_CREATE_STOLEN) { + ret = psb_gem_create_stolen(file, dev, args->size, + &args->handle); + if (ret == 0) + return 0; + /* Fall throguh */ + args->flags &= ~PSB_GEM_CREATE_STOLEN; + } + return psb_gem_create(file, dev, args->size, &args->handle); +} + +int psb_gem_mmap_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_psb_gem_mmap *args = data; + return dev->driver->dumb_map_offset(file, dev, + args->handle, &args->offset); +} + diff --git a/drivers/staging/gma500/gem_glue.c b/drivers/staging/gma500/gem_glue.c new file mode 100644 index 000000000000..779ac1a12d24 --- /dev/null +++ b/drivers/staging/gma500/gem_glue.c @@ -0,0 +1,110 @@ +/************************************************************************** + * Copyright (c) 2011, Intel Corporation. + * All Rights Reserved. + * + * 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. + * + **************************************************************************/ + +#include +#include + +/** + * Initialize an already allocated GEM object of the specified size with + * no GEM provided backing store. Instead the caller is responsible for + * backing the object and handling it. + */ +int drm_gem_private_object_init(struct drm_device *dev, + struct drm_gem_object *obj, size_t size) +{ + BUG_ON((size & (PAGE_SIZE - 1)) != 0); + + obj->dev = dev; + obj->filp = NULL; + + kref_init(&obj->refcount); + atomic_set(&obj->handle_count, 0); + obj->size = size; + + return 0; +} + +void drm_gem_object_release_wrap(struct drm_gem_object *obj) +{ + /* Remove the list map if one is present */ + if (obj->map_list.map) { + struct drm_gem_mm *mm = obj->dev->mm_private; + struct drm_map_list *list = &obj->map_list; + drm_ht_remove_item(&mm->offset_hash, &list->hash); + drm_mm_put_block(list->file_offset_node); + kfree(list->map); + list->map = NULL; + } + if (obj->filp) + drm_gem_object_release(obj); +} + +/** + * gem_create_mmap_offset - invent an mmap offset + * @obj: our object + * + * Standard implementation of offset generation for mmap as is + * duplicated in several drivers. This belongs in GEM. + */ +int gem_create_mmap_offset(struct drm_gem_object *obj) +{ + struct drm_device *dev = obj->dev; + struct drm_gem_mm *mm = dev->mm_private; + struct drm_map_list *list; + struct drm_local_map *map; + int ret; + + list = &obj->map_list; + list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); + if (list->map == NULL) + return -ENOMEM; + map = list->map; + map->type = _DRM_GEM; + map->size = obj->size; + map->handle = obj; + + list->file_offset_node = drm_mm_search_free(&mm->offset_manager, + obj->size / PAGE_SIZE, 0, 0); + if (!list->file_offset_node) { + dev_err(dev->dev, "failed to allocate offset for bo %d\n", + obj->name); + ret = -ENOSPC; + goto free_it; + } + list->file_offset_node = drm_mm_get_block(list->file_offset_node, + obj->size / PAGE_SIZE, 0); + if (!list->file_offset_node) { + ret = -ENOMEM; + goto free_it; + } + list->hash.key = list->file_offset_node->start; + ret = drm_ht_insert_item(&mm->offset_hash, &list->hash); + if (ret) { + dev_err(dev->dev, "failed to add to map hash\n"); + goto free_mm; + } + return 0; + +free_mm: + drm_mm_put_block(list->file_offset_node); +free_it: + kfree(list->map); + list->map = NULL; + return ret; +} diff --git a/drivers/staging/gma500/gem_glue.h b/drivers/staging/gma500/gem_glue.h new file mode 100644 index 000000000000..a0f2bc4e4ae7 --- /dev/null +++ b/drivers/staging/gma500/gem_glue.h @@ -0,0 +1,4 @@ +extern void drm_gem_object_release_wrap(struct drm_gem_object *obj); +extern int drm_gem_private_object_init(struct drm_device *dev, + struct drm_gem_object *obj, size_t size); +extern int gem_create_mmap_offset(struct drm_gem_object *obj); diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/gtt.c similarity index 69% rename from drivers/staging/gma500/psb_gtt.c rename to drivers/staging/gma500/gtt.c index 74c5a6569d08..461ead251bbd 100644 --- a/drivers/staging/gma500/psb_gtt.c +++ b/drivers/staging/gma500/gtt.c @@ -28,11 +28,11 @@ */ /** - * psb_gtt_mask_pte - generate GART pte entry + * psb_gtt_mask_pte - generate GTT pte entry * @pfn: page number to encode - * @type: type of memory in the GART + * @type: type of memory in the GTT * - * Set the GART entry for the appropriate memory type. + * Set the GTT entry for the appropriate memory type. */ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type) { @@ -49,16 +49,16 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type) } /** - * psb_gtt_entry - find the GART entries for a gtt_range + * psb_gtt_entry - find the GTT entries for a gtt_range * @dev: our DRM device * @r: our GTT range - * - * Given a gtt_range object return the GART offset of the page table + * + * Given a gtt_range object return the GTT offset of the page table * entries for this gtt_range */ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) { - struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; unsigned long offset; offset = r->resource.start - dev_priv->gtt_mem->start; @@ -67,20 +67,18 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) } /** - * psb_gtt_insert - put an object into the GART + * psb_gtt_insert - put an object into the GTT * @dev: our DRM device * @r: our GTT range * * Take our preallocated GTT range and insert the GEM object into - * the GART. + * the GTT. * * FIXME: gtt lock ? */ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) { - struct drm_psb_private *dev_priv = dev->dev_private; u32 *gtt_slot, pte; - int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT; struct page **pages; int i; @@ -94,26 +92,25 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) gtt_slot = psb_gtt_entry(dev, r); pages = r->pages; - /* Make sure we have no alias present */ - wbinvd(); + /* Make sure changes are visible to the GPU */ + set_pages_array_uc(pages, r->npage); - /* Write our page entries into the GART itself */ - for (i = 0; i < numpages; i++) { + /* Write our page entries into the GTT itself */ + for (i = 0; i < r->npage; i++) { pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/); iowrite32(pte, gtt_slot++); } /* Make sure all the entries are set before we return */ ioread32(gtt_slot - 1); - return 0; } /** - * psb_gtt_remove - remove an object from the GART + * psb_gtt_remove - remove an object from the GTT * @dev: our DRM device * @r: our GTT range * - * Remove a preallocated GTT range from the GART. Overwrite all the + * Remove a preallocated GTT range from the GTT. Overwrite all the * page table entries with the dummy page */ @@ -121,17 +118,17 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) { struct drm_psb_private *dev_priv = dev->dev_private; u32 *gtt_slot, pte; - int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT; int i; WARN_ON(r->stolen); gtt_slot = psb_gtt_entry(dev, r); - pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);; + pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0); - for (i = 0; i < numpages; i++) + for (i = 0; i < r->npage; i++) iowrite32(pte, gtt_slot++); ioread32(gtt_slot - 1); + set_pages_array_wb(r->pages, r->npage); } /** @@ -140,8 +137,6 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) * * Pin and build an in kernel list of the pages that back our GEM object. * While we hold this the pages cannot be swapped out - * - * FIXME: Do we need to cache flush when we update the GTT */ static int psb_gtt_attach_pages(struct gtt_range *gt) { @@ -149,7 +144,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt) struct address_space *mapping; int i; struct page *p; - int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT; + int pages = gt->gem.size / PAGE_SIZE; WARN_ON(gt->pages); @@ -160,6 +155,8 @@ static int psb_gtt_attach_pages(struct gtt_range *gt) gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL); if (gt->pages == NULL) return -ENOMEM; + gt->npage = pages; + for (i = 0; i < pages; i++) { /* FIXME: review flags later */ p = read_cache_page_gfp(mapping, i, @@ -183,20 +180,15 @@ static int psb_gtt_attach_pages(struct gtt_range *gt) * @gt: the gtt range * * Undo the effect of psb_gtt_attach_pages. At this point the pages - * must have been removed from the GART as they could now be paged out + * must have been removed from the GTT as they could now be paged out * and move bus address. - * - * FIXME: Do we need to cache flush when we update the GTT */ static void psb_gtt_detach_pages(struct gtt_range *gt) { int i; - int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT; - - for (i = 0; i < pages; i++) { + for (i = 0; i < gt->npage; i++) { /* FIXME: do we need to force dirty */ set_page_dirty(gt->pages[i]); - /* Undo the reference we took when populating the table */ page_cache_release(gt->pages[i]); } kfree(gt->pages); @@ -215,7 +207,7 @@ static void psb_gtt_detach_pages(struct gtt_range *gt) */ int psb_gtt_pin(struct gtt_range *gt) { - int ret; + int ret = 0; struct drm_device *dev = gt->gem.dev; struct drm_psb_private *dev_priv = dev->dev_private; @@ -264,7 +256,7 @@ void psb_gtt_unpin(struct gtt_range *gt) } mutex_unlock(&dev_priv->gtt_mutex); } - + /* * GTT resource allocator - allocate and manage GTT address space */ @@ -291,50 +283,45 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, struct resource *r = dev_priv->gtt_mem; int ret; unsigned long start, end; - + if (backed) { - /* The start of the GTT is the stolen pages */ - start = r->start; - end = r->start + dev_priv->pg->stolen_size - 1; - } else { - /* The rest we will use for GEM backed objects */ - start = r->start + dev_priv->pg->stolen_size; - end = r->end; - } + /* The start of the GTT is the stolen pages */ + start = r->start; + end = r->start + dev_priv->gtt.stolen_size - 1; + } else { + /* The rest we will use for GEM backed objects */ + start = r->start + dev_priv->gtt.stolen_size; + end = r->end; + } gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL); if (gt == NULL) return NULL; - gt->resource.name = name; - gt->stolen = backed; - gt->in_gart = backed; - /* Ensure this is set for non GEM objects */ - gt->gem.dev = dev; - kref_init(>->kref); - + gt->resource.name = name; + gt->stolen = backed; + gt->in_gart = backed; + /* Ensure this is set for non GEM objects */ + gt->gem.dev = dev; ret = allocate_resource(dev_priv->gtt_mem, >->resource, len, start, end, PAGE_SIZE, NULL, NULL); if (ret == 0) { - gt->offset = gt->resource.start - r->start; + gt->offset = gt->resource.start - r->start; return gt; - } + } kfree(gt); return NULL; } /** - * psb_gtt_destroy - final free up of a gtt - * @kref: the kref of the gtt + * psb_gtt_free_range - release GTT address space + * @dev: our DRM device + * @gt: a mapping created with psb_gtt_alloc_range * - * Called from the kernel kref put when the final reference to our - * GTT object is dropped. At that point we can free up the resources. - * - * For now we handle mmap clean up here to work around limits in GEM + * Release a resource that was allocated with psb_gtt_alloc_range. If the + * object has been pinned by mmap users we clean this up here currently. */ -static void psb_gtt_destroy(struct kref *kref) +void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt) { - struct gtt_range *gt = container_of(kref, struct gtt_range, kref); - /* Undo the mmap pin if we are destroying the object */ if (gt->mmapping) { psb_gtt_unpin(gt); @@ -345,48 +332,16 @@ static void psb_gtt_destroy(struct kref *kref) kfree(gt); } -/** - * psb_gtt_kref_put - drop reference to a GTT object - * @gt: the GT being dropped - * - * Drop a reference to a psb gtt - */ -void psb_gtt_kref_put(struct gtt_range *gt) +void psb_gtt_alloc(struct drm_device *dev) { - kref_put(>->kref, psb_gtt_destroy); -} - -/** - * psb_gtt_free_range - release GTT address space - * @dev: our DRM device - * @gt: a mapping created with psb_gtt_alloc_range - * - * Release a resource that was allocated with psb_gtt_alloc_range - */ -void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt) -{ - psb_gtt_kref_put(gt); -} - - -struct psb_gtt *psb_gtt_alloc(struct drm_device *dev) -{ - struct psb_gtt *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); - - if (!tmp) - return NULL; - - init_rwsem(&tmp->sem); - tmp->dev = dev; - - return tmp; + struct drm_psb_private *dev_priv = dev->dev_private; + init_rwsem(&dev_priv->gtt.sem); } void psb_gtt_takedown(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - /* FIXME: iounmap dev_priv->vram_addr etc */ if (dev_priv->gtt_map) { iounmap(dev_priv->gtt_map); dev_priv->gtt_map = NULL; @@ -397,8 +352,8 @@ void psb_gtt_takedown(struct drm_device *dev) PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL); (void) PSB_RVDC32(PSB_PGETBL_CTL); } - kfree(dev_priv->pg); - dev_priv->pg = NULL; + if (dev_priv->vram_addr) + iounmap(dev_priv->gtt_map); } int psb_gtt_init(struct drm_device *dev, int resume) @@ -409,8 +364,6 @@ int psb_gtt_init(struct drm_device *dev, int resume) unsigned i, num_pages; unsigned pfn_base; uint32_t vram_pages; - uint32_t tt_pages; - uint32_t *ttm_gtt_map; uint32_t dvmt_mode = 0; struct psb_gtt *pg; @@ -419,10 +372,10 @@ int psb_gtt_init(struct drm_device *dev, int resume) mutex_init(&dev_priv->gtt_mutex); - dev_priv->pg = pg = psb_gtt_alloc(dev); - if (pg == NULL) - return -ENOMEM; + psb_gtt_alloc(dev); + pg = &dev_priv->gtt; + /* Enable the GTT */ pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl); pci_write_config_word(dev->pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED); @@ -432,31 +385,53 @@ int psb_gtt_init(struct drm_device *dev, int resume) (void) PSB_RVDC32(PSB_PGETBL_CTL); /* The root resource we allocate address space from */ - dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE]; - dev_priv->gtt_initialized = 1; pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; - pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE); - /* fix me: video mmu has hw bug to access 0x0D0000000, - * then make gatt start at 0x0e000,0000 */ + /* + * FIXME: video mmu has hw bug to access 0x0D0000000, + * then make gatt start at 0x0e000,0000 + */ pg->mmu_gatt_start = 0xE0000000; + pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); - gtt_pages = - pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT; + gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) + >> PAGE_SHIFT; + /* CDV workaround */ + if (pg->gtt_start == 0 || gtt_pages == 0) { + dev_err(dev->dev, "GTT PCI BAR not initialized.\n"); + gtt_pages = 64; + pg->gtt_start = dev_priv->pge_ctl; + } + + pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE); pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE) - >> PAGE_SHIFT; + >> PAGE_SHIFT; + dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE]; + + if (pg->gatt_pages == 0 || pg->gatt_start == 0) { + static struct resource fudge; /* Preferably peppermint */ + + /* This can occur on CDV SDV systems. Fudge it in this case. + We really don't care what imaginary space is being allocated + at this point */ + dev_err(dev->dev, "GATT PCI BAR not initialized.\n"); + pg->gatt_start = 0x40000000; + pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT; + fudge.start = 0x40000000; + fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1; + fudge.name = "fudge"; + fudge.flags = IORESOURCE_MEM; + dev_priv->gtt_mem = &fudge; + } pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base); - vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE; + vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base + - PAGE_SIZE; stolen_size = vram_stolen_size; - printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n", - pg->gatt_start, pg->gatt_pages/256); - printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n", - pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start); printk(KERN_INFO "Stolen memory information\n"); printk(KERN_INFO " base in RAM: 0x%x\n", dev_priv->stolen_base); printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n", @@ -467,7 +442,7 @@ int psb_gtt_init(struct drm_device *dev, int resume) if (resume && (gtt_pages != pg->gtt_pages) && (stolen_size != pg->stolen_size)) { - DRM_ERROR("GTT resume error.\n"); + dev_err(dev->dev, "GTT resume error.\n"); ret = -EINVAL; goto out_err; } @@ -475,62 +450,48 @@ int psb_gtt_init(struct drm_device *dev, int resume) pg->gtt_pages = gtt_pages; pg->stolen_size = stolen_size; dev_priv->vram_stolen_size = vram_stolen_size; - dev_priv->gtt_map = - ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT); + + /* + * Map the GTT and the stolen memory area + */ + dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start, + gtt_pages << PAGE_SHIFT); if (!dev_priv->gtt_map) { - DRM_ERROR("Failure to map gtt.\n"); + dev_err(dev->dev, "Failure to map gtt.\n"); ret = -ENOMEM; goto out_err; } dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size); if (!dev_priv->vram_addr) { - DRM_ERROR("Failure to map stolen base.\n"); + dev_err(dev->dev, "Failure to map stolen base.\n"); ret = -ENOMEM; goto out_err; } - DRM_DEBUG("%s: vram kernel virtual address %p\n", dev_priv->vram_addr); - - tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? - (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT; - - ttm_gtt_map = dev_priv->gtt_map + tt_pages / 2; - /* - * insert vram stolen pages. + * Insert vram stolen pages into the GTT */ pfn_base = dev_priv->stolen_base >> PAGE_SHIFT; vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT; printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n", - num_pages, pfn_base, 0); + num_pages, pfn_base << PAGE_SHIFT, 0); for (i = 0; i < num_pages; ++i) { pte = psb_gtt_mask_pte(pfn_base + i, 0); iowrite32(pte, dev_priv->gtt_map + i); } /* - * Init rest of gtt managed by IMG. + * Init rest of GTT to the scratch page to avoid accidents or scribbles */ + pfn_base = page_to_pfn(dev_priv->scratch_page); pte = psb_gtt_mask_pte(pfn_base, 0); - for (; i < tt_pages / 2 - 1; ++i) + for (; i < gtt_pages; ++i) iowrite32(pte, dev_priv->gtt_map + i); - /* - * Init rest of gtt managed by TTM. - */ - - pfn_base = page_to_pfn(dev_priv->scratch_page); - pte = psb_gtt_mask_pte(pfn_base, 0); - PSB_DEBUG_INIT("Initializing the rest of a total " - "of %d gtt pages.\n", pg->gatt_pages); - - for (; i < pg->gatt_pages - tt_pages / 2; ++i) - iowrite32(pte, ttm_gtt_map + i); (void) ioread32(dev_priv->gtt_map + i - 1); - return 0; out_err: diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/gtt.h similarity index 85% rename from drivers/staging/gma500/psb_gtt.h rename to drivers/staging/gma500/gtt.h index 535ae00f2ab9..e0e1cb6f9bd6 100644 --- a/drivers/staging/gma500/psb_gtt.h +++ b/drivers/staging/gma500/gtt.h @@ -22,8 +22,8 @@ #include +/* This wants cleaning up with respect to the psb_dev and un-needed stuff */ struct psb_gtt { - struct drm_device *dev; uint32_t gatt_start; uint32_t mmu_gatt_start; uint32_t gtt_start; @@ -35,20 +35,20 @@ struct psb_gtt { struct rw_semaphore sem; }; -/*Exported functions*/ +/* Exported functions */ extern int psb_gtt_init(struct drm_device *dev, int resume); extern void psb_gtt_takedown(struct drm_device *dev); /* Each gtt_range describes an allocation in the GTT area */ struct gtt_range { - struct resource resource; - u32 offset; - struct kref kref; + struct resource resource; /* Resource for our allocation */ + u32 offset; /* GTT offset of our object */ struct drm_gem_object gem; /* GEM high level stuff */ int in_gart; /* Currently in the GART (ref ct) */ - bool stolen; /* Backed from stolen RAM */ - bool mmapping; /* Is mmappable */ + bool stolen; /* Backed from stolen RAM */ + bool mmapping; /* Is mmappable */ struct page **pages; /* Backing pages if present */ + int npage; /* Number of backing pages */ }; extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, diff --git a/drivers/staging/gma500/psb_intel_bios.c b/drivers/staging/gma500/intel_bios.c similarity index 95% rename from drivers/staging/gma500/psb_intel_bios.c rename to drivers/staging/gma500/intel_bios.c index 417965da5e24..096757f9bc89 100644 --- a/drivers/staging/gma500/psb_intel_bios.c +++ b/drivers/staging/gma500/intel_bios.c @@ -24,7 +24,7 @@ #include "psb_drv.h" #include "psb_intel_drv.h" #include "psb_intel_reg.h" -#include "psb_intel_bios.h" +#include "intel_bios.h" static void *find_section(struct bdb_header *bdb, int section_id) @@ -96,25 +96,20 @@ static void parse_backlight_data(struct drm_psb_private *dev_priv, dev_priv->lvds_bl = NULL; - if (lvds_opts) { - DRM_DEBUG("lvds_options found at %p\n", lvds_opts); + if (lvds_opts) p_type = lvds_opts->panel_type; - } else { - DRM_DEBUG("no lvds_options\n"); + else return; - } bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT); vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type; lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL); if (!lvds_bl) { - DRM_DEBUG("No memory\n"); + dev_err(dev_priv->dev->dev, "out of memory for backlight data\n"); return; } - memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl)); - dev_priv->lvds_bl = lvds_bl; } @@ -144,26 +139,28 @@ static void parse_lfp_panel_data(struct drm_psb_private *dev_priv, if (!lvds_lfp_data) return; - dev_priv->lvds_vbt = 1; entry = &lvds_lfp_data->data[lvds_options->panel_type]; dvo_timing = &entry->dvo_timing; panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); + if (panel_fixed_mode == NULL) { + dev_err(dev_priv->dev->dev, "out of memory for fixed panel mode\n"); + return; + } + dev_priv->lvds_vbt = 1; fill_detail_timing_data(panel_fixed_mode, dvo_timing); if (panel_fixed_mode->htotal > 0 && panel_fixed_mode->vtotal > 0) { dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode; - DRM_DEBUG("Found panel mode in BIOS VBT tables:\n"); drm_mode_debug_printmodeline(panel_fixed_mode); } else { - DRM_DEBUG("Ignoring bogus LVDS VBT mode.\n"); + dev_dbg(dev_priv->dev->dev, "ignoring invalid LVDS VBT\n"); dev_priv->lvds_vbt = 0; kfree(panel_fixed_mode); } - return; } @@ -257,7 +254,7 @@ bool psb_intel_init_bios(struct drm_device *dev) } if (!vbt) { - DRM_ERROR("VBT signature missing\n"); + dev_err(dev->dev, "VBT signature missing\n"); pci_unmap_rom(pdev, bios); return -1; } diff --git a/drivers/staging/gma500/psb_intel_bios.h b/drivers/staging/gma500/intel_bios.h similarity index 100% rename from drivers/staging/gma500/psb_intel_bios.h rename to drivers/staging/gma500/intel_bios.h diff --git a/drivers/staging/gma500/psb_intel_i2c.c b/drivers/staging/gma500/intel_i2c.c similarity index 100% rename from drivers/staging/gma500/psb_intel_i2c.c rename to drivers/staging/gma500/intel_i2c.c diff --git a/drivers/staging/gma500/psb_intel_opregion.c b/drivers/staging/gma500/intel_opregion.c similarity index 79% rename from drivers/staging/gma500/psb_intel_opregion.c rename to drivers/staging/gma500/intel_opregion.c index 65e3e9b8dc16..d2e60376982f 100644 --- a/drivers/staging/gma500/psb_intel_opregion.c +++ b/drivers/staging/gma500/intel_opregion.c @@ -33,24 +33,23 @@ struct opregion_header { u8 driver_ver[16]; u32 mboxes; u8 reserved[164]; -} __attribute__((packed)); +} __packed; struct opregion_apci { /*FIXME: add it later*/ -} __attribute__((packed)); +} __packed; struct opregion_swsci { /*FIXME: add it later*/ -} __attribute__((packed)); +} __packed; struct opregion_acpi { /*FIXME: add it later*/ -} __attribute__((packed)); +} __packed; -int psb_intel_opregion_init(struct drm_device *dev) +int gma_intel_opregion_init(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - /*struct psb_intel_opregion * opregion = &dev_priv->opregion;*/ u32 opregion_phy; void *base; u32 *lid_state; @@ -58,11 +57,8 @@ int psb_intel_opregion_init(struct drm_device *dev) dev_priv->lid_state = NULL; pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy); - if (opregion_phy == 0) { - DRM_DEBUG("Opregion not supported, won't support lid-switch\n"); + if (opregion_phy == 0) return -ENOTSUPP; - } - DRM_DEBUG("OpRegion detected at 0x%8x\n", opregion_phy); base = ioremap(opregion_phy, 8*1024); if (!base) @@ -70,9 +66,15 @@ int psb_intel_opregion_init(struct drm_device *dev) lid_state = base + 0x01ac; - DRM_DEBUG("Lid switch state 0x%08x\n", *lid_state); - dev_priv->lid_state = lid_state; - dev_priv->lid_last_state = *lid_state; + dev_priv->lid_last_state = readl(lid_state); + return 0; +} + +int gma_intel_opregion_exit(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + if (dev_priv->lid_state) + iounmap(dev_priv->lid_state); return 0; } diff --git a/drivers/staging/gma500/mdfld_device.c b/drivers/staging/gma500/mdfld_device.c new file mode 100644 index 000000000000..f47aeb7a2039 --- /dev/null +++ b/drivers/staging/gma500/mdfld_device.c @@ -0,0 +1,714 @@ +/************************************************************************** + * Copyright (c) 2011, Intel Corporation. + * All Rights Reserved. + * + * 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. + * + **************************************************************************/ + +#include +#include +#include +#include "psb_reg.h" +#include "psb_intel_reg.h" +#include "psb_drm.h" +#include "psb_drv.h" +#include "mdfld_output.h" +#include "mdfld_dsi_output.h" +#include "mid_bios.h" + +/* + * Provide the Medfield specific backlight management + */ + +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + +static int mdfld_brightness; +struct backlight_device *mdfld_backlight_device; + +static int mfld_set_brightness(struct backlight_device *bd) +{ + struct drm_device *dev = bl_get_data(mdfld_backlight_device); + struct drm_psb_private *dev_priv = dev->dev_private; + int level = bd->props.brightness; + + /* Percentage 1-100% being valid */ + if (level < 1) + level = 1; + + if (gma_power_begin(dev, 0)) { + /* Calculate and set the brightness value */ + u32 adjusted_level; + + /* Adjust the backlight level with the percent in + * dev_priv->blc_adj2; + */ + adjusted_level = level * dev_priv->blc_adj2; + adjusted_level = adjusted_level / 100; +#if 0 +#ifndef CONFIG_MDFLD_DSI_DPU + if(!(dev_priv->dsr_fb_update & MDFLD_DSR_MIPI_CONTROL) && + (dev_priv->dbi_panel_on || dev_priv->dbi_panel_on2)){ + mdfld_dsi_dbi_exit_dsr(dev,MDFLD_DSR_MIPI_CONTROL, 0, 0); + dev_dbg(dev->dev, "Out of DSR before set brightness to %d.\n",adjusted_level); + } +#endif + mdfld_dsi_brightness_control(dev, 0, adjusted_level); + + if ((dev_priv->dbi_panel_on2) || (dev_priv->dpi_panel_on2)) + mdfld_dsi_brightness_control(dev, 2, adjusted_level); +#endif + gma_power_end(dev); + } + mdfld_brightness = level; + return 0; +} + +int psb_get_brightness(struct backlight_device *bd) +{ + /* return locally cached var instead of HW read (due to DPST etc.) */ + /* FIXME: ideally return actual value in case firmware fiddled with + it */ + return mdfld_brightness; +} + +static const struct backlight_ops mfld_ops = { + .get_brightness = psb_get_brightness, + .update_status = mfld_set_brightness, +}; + +static int mdfld_backlight_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct backlight_properties props; + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 100; + props.type = BACKLIGHT_PLATFORM; + + mdfld_backlight_device = backlight_device_register("mfld-bl", + NULL, (void *)dev, &mfld_ops, &props); + + if (IS_ERR(mdfld_backlight_device)) + return PTR_ERR(mdfld_backlight_device); + + dev_priv->blc_adj1 = 100; + dev_priv->blc_adj2 = 100; + mdfld_backlight_device->props.brightness = 100; + mdfld_backlight_device->props.max_brightness = 100; + backlight_update_status(mdfld_backlight_device); + dev_priv->backlight_device = mdfld_backlight_device; + return 0; +} + +#endif + +/* + * Provide the Medfield specific chip logic and low level methods for + * power management. + */ + +static void mdfld_init_pm(struct drm_device *dev) +{ + /* No work needed here yet */ +} + +/** + * mdfld_save_display_registers - save registers for pipe + * @dev: our device + * @pipe: pipe to save + * + * Save the pipe state of the device before we power it off. Keep everything + * we need to put it back again + */ +static int mdfld_save_display_registers(struct drm_device *dev, int pipe) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + int i; + + /* register */ + u32 dpll_reg = MRST_DPLL_A; + u32 fp_reg = MRST_FPA0; + u32 pipeconf_reg = PIPEACONF; + u32 htot_reg = HTOTAL_A; + u32 hblank_reg = HBLANK_A; + u32 hsync_reg = HSYNC_A; + u32 vtot_reg = VTOTAL_A; + u32 vblank_reg = VBLANK_A; + u32 vsync_reg = VSYNC_A; + u32 pipesrc_reg = PIPEASRC; + u32 dspstride_reg = DSPASTRIDE; + u32 dsplinoff_reg = DSPALINOFF; + u32 dsptileoff_reg = DSPATILEOFF; + u32 dspsize_reg = DSPASIZE; + u32 dsppos_reg = DSPAPOS; + u32 dspsurf_reg = DSPASURF; + u32 mipi_reg = MIPI; + u32 dspcntr_reg = DSPACNTR; + u32 dspstatus_reg = PIPEASTAT; + u32 palette_reg = PALETTE_A; + + /* pointer to values */ + u32 *dpll_val = &dev_priv->saveDPLL_A; + u32 *fp_val = &dev_priv->saveFPA0; + u32 *pipeconf_val = &dev_priv->savePIPEACONF; + u32 *htot_val = &dev_priv->saveHTOTAL_A; + u32 *hblank_val = &dev_priv->saveHBLANK_A; + u32 *hsync_val = &dev_priv->saveHSYNC_A; + u32 *vtot_val = &dev_priv->saveVTOTAL_A; + u32 *vblank_val = &dev_priv->saveVBLANK_A; + u32 *vsync_val = &dev_priv->saveVSYNC_A; + u32 *pipesrc_val = &dev_priv->savePIPEASRC; + u32 *dspstride_val = &dev_priv->saveDSPASTRIDE; + u32 *dsplinoff_val = &dev_priv->saveDSPALINOFF; + u32 *dsptileoff_val = &dev_priv->saveDSPATILEOFF; + u32 *dspsize_val = &dev_priv->saveDSPASIZE; + u32 *dsppos_val = &dev_priv->saveDSPAPOS; + u32 *dspsurf_val = &dev_priv->saveDSPASURF; + u32 *mipi_val = &dev_priv->saveMIPI; + u32 *dspcntr_val = &dev_priv->saveDSPACNTR; + u32 *dspstatus_val = &dev_priv->saveDSPASTATUS; + u32 *palette_val = dev_priv->save_palette_a; + + switch (pipe) { + case 0: + break; + case 1: + /* register */ + dpll_reg = MDFLD_DPLL_B; + fp_reg = MDFLD_DPLL_DIV0; + pipeconf_reg = PIPEBCONF; + htot_reg = HTOTAL_B; + hblank_reg = HBLANK_B; + hsync_reg = HSYNC_B; + vtot_reg = VTOTAL_B; + vblank_reg = VBLANK_B; + vsync_reg = VSYNC_B; + pipesrc_reg = PIPEBSRC; + dspstride_reg = DSPBSTRIDE; + dsplinoff_reg = DSPBLINOFF; + dsptileoff_reg = DSPBTILEOFF; + dspsize_reg = DSPBSIZE; + dsppos_reg = DSPBPOS; + dspsurf_reg = DSPBSURF; + dspcntr_reg = DSPBCNTR; + dspstatus_reg = PIPEBSTAT; + palette_reg = PALETTE_B; + + /* values */ + dpll_val = &dev_priv->saveDPLL_B; + fp_val = &dev_priv->saveFPB0; + pipeconf_val = &dev_priv->savePIPEBCONF; + htot_val = &dev_priv->saveHTOTAL_B; + hblank_val = &dev_priv->saveHBLANK_B; + hsync_val = &dev_priv->saveHSYNC_B; + vtot_val = &dev_priv->saveVTOTAL_B; + vblank_val = &dev_priv->saveVBLANK_B; + vsync_val = &dev_priv->saveVSYNC_B; + pipesrc_val = &dev_priv->savePIPEBSRC; + dspstride_val = &dev_priv->saveDSPBSTRIDE; + dsplinoff_val = &dev_priv->saveDSPBLINOFF; + dsptileoff_val = &dev_priv->saveDSPBTILEOFF; + dspsize_val = &dev_priv->saveDSPBSIZE; + dsppos_val = &dev_priv->saveDSPBPOS; + dspsurf_val = &dev_priv->saveDSPBSURF; + dspcntr_val = &dev_priv->saveDSPBCNTR; + dspstatus_val = &dev_priv->saveDSPBSTATUS; + palette_val = dev_priv->save_palette_b; + break; + case 2: + /* register */ + pipeconf_reg = PIPECCONF; + htot_reg = HTOTAL_C; + hblank_reg = HBLANK_C; + hsync_reg = HSYNC_C; + vtot_reg = VTOTAL_C; + vblank_reg = VBLANK_C; + vsync_reg = VSYNC_C; + pipesrc_reg = PIPECSRC; + dspstride_reg = DSPCSTRIDE; + dsplinoff_reg = DSPCLINOFF; + dsptileoff_reg = DSPCTILEOFF; + dspsize_reg = DSPCSIZE; + dsppos_reg = DSPCPOS; + dspsurf_reg = DSPCSURF; + mipi_reg = MIPI_C; + dspcntr_reg = DSPCCNTR; + dspstatus_reg = PIPECSTAT; + palette_reg = PALETTE_C; + + /* pointer to values */ + pipeconf_val = &dev_priv->savePIPECCONF; + htot_val = &dev_priv->saveHTOTAL_C; + hblank_val = &dev_priv->saveHBLANK_C; + hsync_val = &dev_priv->saveHSYNC_C; + vtot_val = &dev_priv->saveVTOTAL_C; + vblank_val = &dev_priv->saveVBLANK_C; + vsync_val = &dev_priv->saveVSYNC_C; + pipesrc_val = &dev_priv->savePIPECSRC; + dspstride_val = &dev_priv->saveDSPCSTRIDE; + dsplinoff_val = &dev_priv->saveDSPCLINOFF; + dsptileoff_val = &dev_priv->saveDSPCTILEOFF; + dspsize_val = &dev_priv->saveDSPCSIZE; + dsppos_val = &dev_priv->saveDSPCPOS; + dspsurf_val = &dev_priv->saveDSPCSURF; + mipi_val = &dev_priv->saveMIPI_C; + dspcntr_val = &dev_priv->saveDSPCCNTR; + dspstatus_val = &dev_priv->saveDSPCSTATUS; + palette_val = dev_priv->save_palette_c; + break; + default: + DRM_ERROR("%s, invalid pipe number.\n", __func__); + return -EINVAL; + } + + /* Pipe & plane A info */ + *dpll_val = PSB_RVDC32(dpll_reg); + *fp_val = PSB_RVDC32(fp_reg); + *pipeconf_val = PSB_RVDC32(pipeconf_reg); + *htot_val = PSB_RVDC32(htot_reg); + *hblank_val = PSB_RVDC32(hblank_reg); + *hsync_val = PSB_RVDC32(hsync_reg); + *vtot_val = PSB_RVDC32(vtot_reg); + *vblank_val = PSB_RVDC32(vblank_reg); + *vsync_val = PSB_RVDC32(vsync_reg); + *pipesrc_val = PSB_RVDC32(pipesrc_reg); + *dspstride_val = PSB_RVDC32(dspstride_reg); + *dsplinoff_val = PSB_RVDC32(dsplinoff_reg); + *dsptileoff_val = PSB_RVDC32(dsptileoff_reg); + *dspsize_val = PSB_RVDC32(dspsize_reg); + *dsppos_val = PSB_RVDC32(dsppos_reg); + *dspsurf_val = PSB_RVDC32(dspsurf_reg); + *dspcntr_val = PSB_RVDC32(dspcntr_reg); + *dspstatus_val = PSB_RVDC32(dspstatus_reg); + + /*save palette (gamma) */ + for (i = 0; i < 256; i++) + palette_val[i] = PSB_RVDC32(palette_reg + (i<<2)); + + if (pipe == 1) { + dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL); + dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS); + dev_priv->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL); + dev_priv->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL); + return 0; + } + *mipi_val = PSB_RVDC32(mipi_reg); + return 0; +} + +/** + * mdfld_save_cursor_overlay_registers - save cursor overlay info + * @dev: our device + * + * Save the cursor and overlay register state + */ +static int mdfld_save_cursor_overlay_registers(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + + /* Save cursor regs */ + dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR); + dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE); + dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS); + + dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR); + dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE); + dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS); + + dev_priv->saveDSPCCURSOR_CTRL = PSB_RVDC32(CURCCNTR); + dev_priv->saveDSPCCURSOR_BASE = PSB_RVDC32(CURCBASE); + dev_priv->saveDSPCCURSOR_POS = PSB_RVDC32(CURCPOS); + + /* HW overlay */ + dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD); + dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0); + dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1); + dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2); + dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3); + dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4); + dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5); + + dev_priv->saveOV_OVADD_C = PSB_RVDC32(OV_OVADD + OV_C_OFFSET); + dev_priv->saveOV_OGAMC0_C = PSB_RVDC32(OV_OGAMC0 + OV_C_OFFSET); + dev_priv->saveOV_OGAMC1_C = PSB_RVDC32(OV_OGAMC1 + OV_C_OFFSET); + dev_priv->saveOV_OGAMC2_C = PSB_RVDC32(OV_OGAMC2 + OV_C_OFFSET); + dev_priv->saveOV_OGAMC3_C = PSB_RVDC32(OV_OGAMC3 + OV_C_OFFSET); + dev_priv->saveOV_OGAMC4_C = PSB_RVDC32(OV_OGAMC4 + OV_C_OFFSET); + dev_priv->saveOV_OGAMC5_C = PSB_RVDC32(OV_OGAMC5 + OV_C_OFFSET); + + return 0; +} +/* + * mdfld_restore_display_registers - restore the state of a pipe + * @dev: our device + * @pipe: the pipe to restore + * + * Restore the state of a pipe to that which was saved by the register save + * functions. + */ +static int mdfld_restore_display_registers(struct drm_device *dev, int pipe) +{ + /* To get panel out of ULPS mode */ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dsi_config *dsi_config = NULL; + u32 i = 0; + u32 dpll = 0; + u32 timeout = 0; + u32 reg_offset = 0; + + /* register */ + u32 dpll_reg = MRST_DPLL_A; + u32 fp_reg = MRST_FPA0; + u32 pipeconf_reg = PIPEACONF; + u32 htot_reg = HTOTAL_A; + u32 hblank_reg = HBLANK_A; + u32 hsync_reg = HSYNC_A; + u32 vtot_reg = VTOTAL_A; + u32 vblank_reg = VBLANK_A; + u32 vsync_reg = VSYNC_A; + u32 pipesrc_reg = PIPEASRC; + u32 dspstride_reg = DSPASTRIDE; + u32 dsplinoff_reg = DSPALINOFF; + u32 dsptileoff_reg = DSPATILEOFF; + u32 dspsize_reg = DSPASIZE; + u32 dsppos_reg = DSPAPOS; + u32 dspsurf_reg = DSPASURF; + u32 dspstatus_reg = PIPEASTAT; + u32 mipi_reg = MIPI; + u32 dspcntr_reg = DSPACNTR; + u32 palette_reg = PALETTE_A; + + /* values */ + u32 dpll_val = dev_priv->saveDPLL_A & ~DPLL_VCO_ENABLE; + u32 fp_val = dev_priv->saveFPA0; + u32 pipeconf_val = dev_priv->savePIPEACONF; + u32 htot_val = dev_priv->saveHTOTAL_A; + u32 hblank_val = dev_priv->saveHBLANK_A; + u32 hsync_val = dev_priv->saveHSYNC_A; + u32 vtot_val = dev_priv->saveVTOTAL_A; + u32 vblank_val = dev_priv->saveVBLANK_A; + u32 vsync_val = dev_priv->saveVSYNC_A; + u32 pipesrc_val = dev_priv->savePIPEASRC; + u32 dspstride_val = dev_priv->saveDSPASTRIDE; + u32 dsplinoff_val = dev_priv->saveDSPALINOFF; + u32 dsptileoff_val = dev_priv->saveDSPATILEOFF; + u32 dspsize_val = dev_priv->saveDSPASIZE; + u32 dsppos_val = dev_priv->saveDSPAPOS; + u32 dspsurf_val = dev_priv->saveDSPASURF; + u32 dspstatus_val = dev_priv->saveDSPASTATUS; + u32 mipi_val = dev_priv->saveMIPI; + u32 dspcntr_val = dev_priv->saveDSPACNTR; + u32 *palette_val = dev_priv->save_palette_a; + + switch (pipe) { + case 0: + dsi_config = dev_priv->dsi_configs[0]; + break; + case 1: + /* register */ + dpll_reg = MDFLD_DPLL_B; + fp_reg = MDFLD_DPLL_DIV0; + pipeconf_reg = PIPEBCONF; + htot_reg = HTOTAL_B; + hblank_reg = HBLANK_B; + hsync_reg = HSYNC_B; + vtot_reg = VTOTAL_B; + vblank_reg = VBLANK_B; + vsync_reg = VSYNC_B; + pipesrc_reg = PIPEBSRC; + dspstride_reg = DSPBSTRIDE; + dsplinoff_reg = DSPBLINOFF; + dsptileoff_reg = DSPBTILEOFF; + dspsize_reg = DSPBSIZE; + dsppos_reg = DSPBPOS; + dspsurf_reg = DSPBSURF; + dspcntr_reg = DSPBCNTR; + palette_reg = PALETTE_B; + dspstatus_reg = PIPEBSTAT; + + /* values */ + dpll_val = dev_priv->saveDPLL_B & ~DPLL_VCO_ENABLE; + fp_val = dev_priv->saveFPB0; + pipeconf_val = dev_priv->savePIPEBCONF; + htot_val = dev_priv->saveHTOTAL_B; + hblank_val = dev_priv->saveHBLANK_B; + hsync_val = dev_priv->saveHSYNC_B; + vtot_val = dev_priv->saveVTOTAL_B; + vblank_val = dev_priv->saveVBLANK_B; + vsync_val = dev_priv->saveVSYNC_B; + pipesrc_val = dev_priv->savePIPEBSRC; + dspstride_val = dev_priv->saveDSPBSTRIDE; + dsplinoff_val = dev_priv->saveDSPBLINOFF; + dsptileoff_val = dev_priv->saveDSPBTILEOFF; + dspsize_val = dev_priv->saveDSPBSIZE; + dsppos_val = dev_priv->saveDSPBPOS; + dspsurf_val = dev_priv->saveDSPBSURF; + dspcntr_val = dev_priv->saveDSPBCNTR; + dspstatus_val = dev_priv->saveDSPBSTATUS; + palette_val = dev_priv->save_palette_b; + break; + case 2: + reg_offset = MIPIC_REG_OFFSET; + + /* register */ + pipeconf_reg = PIPECCONF; + htot_reg = HTOTAL_C; + hblank_reg = HBLANK_C; + hsync_reg = HSYNC_C; + vtot_reg = VTOTAL_C; + vblank_reg = VBLANK_C; + vsync_reg = VSYNC_C; + pipesrc_reg = PIPECSRC; + dspstride_reg = DSPCSTRIDE; + dsplinoff_reg = DSPCLINOFF; + dsptileoff_reg = DSPCTILEOFF; + dspsize_reg = DSPCSIZE; + dsppos_reg = DSPCPOS; + dspsurf_reg = DSPCSURF; + mipi_reg = MIPI_C; + dspcntr_reg = DSPCCNTR; + palette_reg = PALETTE_C; + dspstatus_reg = PIPECSTAT; + + /* values */ + pipeconf_val = dev_priv->savePIPECCONF; + htot_val = dev_priv->saveHTOTAL_C; + hblank_val = dev_priv->saveHBLANK_C; + hsync_val = dev_priv->saveHSYNC_C; + vtot_val = dev_priv->saveVTOTAL_C; + vblank_val = dev_priv->saveVBLANK_C; + vsync_val = dev_priv->saveVSYNC_C; + pipesrc_val = dev_priv->savePIPECSRC; + dspstride_val = dev_priv->saveDSPCSTRIDE; + dsplinoff_val = dev_priv->saveDSPCLINOFF; + dsptileoff_val = dev_priv->saveDSPCTILEOFF; + dspsize_val = dev_priv->saveDSPCSIZE; + dsppos_val = dev_priv->saveDSPCPOS; + dspsurf_val = dev_priv->saveDSPCSURF; + dspstatus_val = dev_priv->saveDSPCSTATUS; + mipi_val = dev_priv->saveMIPI_C; + dspcntr_val = dev_priv->saveDSPCCNTR; + palette_val = dev_priv->save_palette_c; + + dsi_config = dev_priv->dsi_configs[1]; + break; + default: + DRM_ERROR("%s, invalid pipe number.\n", __func__); + return -EINVAL; + } + + /* Make sure VGA plane is off. it initializes to on after reset!*/ + PSB_WVDC32(0x80000000, VGACNTRL); + if (pipe == 1) { + PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg); + PSB_RVDC32(dpll_reg); + + PSB_WVDC32(fp_val, fp_reg); + } else { + dpll = PSB_RVDC32(dpll_reg); + + if (!(dpll & DPLL_VCO_ENABLE)) { + + /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */ + if (dpll & MDFLD_PWR_GATE_EN) { + dpll &= ~MDFLD_PWR_GATE_EN; + PSB_WVDC32(dpll, dpll_reg); + udelay(500); /* FIXME: 1 ? */ + } + + PSB_WVDC32(fp_val, fp_reg); + PSB_WVDC32(dpll_val, dpll_reg); + /* FIXME_MDFLD PO - change 500 to 1 after PO */ + udelay(500); + + dpll_val |= DPLL_VCO_ENABLE; + PSB_WVDC32(dpll_val, dpll_reg); + PSB_RVDC32(dpll_reg); + + /* wait for DSI PLL to lock */ + while ((timeout < 20000) && !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) { + udelay(150); + timeout++; + } + + if (timeout == 20000) { + DRM_ERROR("%s, can't lock DSIPLL.\n", + __func__); + return -EINVAL; + } + } + } + /* Restore mode */ + PSB_WVDC32(htot_val, htot_reg); + PSB_WVDC32(hblank_val, hblank_reg); + PSB_WVDC32(hsync_val, hsync_reg); + PSB_WVDC32(vtot_val, vtot_reg); + PSB_WVDC32(vblank_val, vblank_reg); + PSB_WVDC32(vsync_val, vsync_reg); + PSB_WVDC32(pipesrc_val, pipesrc_reg); + PSB_WVDC32(dspstatus_val, dspstatus_reg); + + /* Set up the plane */ + PSB_WVDC32(dspstride_val, dspstride_reg); + PSB_WVDC32(dsplinoff_val, dsplinoff_reg); + PSB_WVDC32(dsptileoff_val, dsptileoff_reg); + PSB_WVDC32(dspsize_val, dspsize_reg); + PSB_WVDC32(dsppos_val, dsppos_reg); + PSB_WVDC32(dspsurf_val, dspsurf_reg); + + if (pipe == 1) { + PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL); + PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS); + PSB_WVDC32(dev_priv->saveHDMIPHYMISCCTL, HDMIPHYMISCCTL); + PSB_WVDC32(dev_priv->saveHDMIB_CONTROL, HDMIB_CONTROL); + + } else { + /* Set up pipe related registers */ + PSB_WVDC32(mipi_val, mipi_reg); + /* Setup MIPI adapter + MIPI IP registers */ + mdfld_dsi_controller_init(dsi_config, pipe); + msleep(20); + } + /* Enable the plane */ + PSB_WVDC32(dspcntr_val, dspcntr_reg); + msleep(20); + /* Enable the pipe */ + PSB_WVDC32(pipeconf_val, pipeconf_reg); + + for (i = 0; i < 256; i++) + PSB_WVDC32(palette_val[i], palette_reg + (i<<2)); + if (pipe == 1) + return 0; + if (!mdfld_panel_dpi(dev)) + mdfld_enable_te(dev, pipe); + return 0; +} + +/** + * mdfld_restore_cursor_overlay_registers - restore cursor + * @dev: our device + * + * Restore the cursor and overlay state that was saved earlier + */ +static int mdfld_restore_cursor_overlay_registers(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + + /* Enable Cursor A */ + PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR); + PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS); + PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE); + + PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR); + PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS); + PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE); + + PSB_WVDC32(dev_priv->saveDSPCCURSOR_CTRL, CURCCNTR); + PSB_WVDC32(dev_priv->saveDSPCCURSOR_POS, CURCPOS); + PSB_WVDC32(dev_priv->saveDSPCCURSOR_BASE, CURCBASE); + + /* Restore HW overlay */ + PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD); + PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0); + PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1); + PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2); + PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3); + PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4); + PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5); + + PSB_WVDC32(dev_priv->saveOV_OVADD_C, OV_OVADD + OV_C_OFFSET); + PSB_WVDC32(dev_priv->saveOV_OGAMC0_C, OV_OGAMC0 + OV_C_OFFSET); + PSB_WVDC32(dev_priv->saveOV_OGAMC1_C, OV_OGAMC1 + OV_C_OFFSET); + PSB_WVDC32(dev_priv->saveOV_OGAMC2_C, OV_OGAMC2 + OV_C_OFFSET); + PSB_WVDC32(dev_priv->saveOV_OGAMC3_C, OV_OGAMC3 + OV_C_OFFSET); + PSB_WVDC32(dev_priv->saveOV_OGAMC4_C, OV_OGAMC4 + OV_C_OFFSET); + PSB_WVDC32(dev_priv->saveOV_OGAMC5_C, OV_OGAMC5 + OV_C_OFFSET); + + return 0; +} + +/** + * mdfld_save_display_registers - save registers lost on suspend + * @dev: our DRM device + * + * Save the state we need in order to be able to restore the interface + * upon resume from suspend + */ +static int mdfld_save_registers(struct drm_device *dev) +{ + /* FIXME: We need to shut down panels here if using them + and once the right bits are merged */ + mdfld_save_cursor_overlay_registers(dev); + mdfld_save_display_registers(dev, 0); + mdfld_save_display_registers(dev, 0); + mdfld_save_display_registers(dev, 2); + mdfld_save_display_registers(dev, 1); + mdfld_disable_crtc(dev, 0); + mdfld_disable_crtc(dev, 2); + mdfld_disable_crtc(dev, 1); + return 0; +} + +/** + * mdfld_restore_display_registers - restore lost register state + * @dev: our DRM device + * + * Restore register state that was lost during suspend and resume. + */ +static int mdfld_restore_registers(struct drm_device *dev) +{ + mdfld_restore_display_registers(dev, 1); + mdfld_restore_display_registers(dev, 0); + mdfld_restore_display_registers(dev, 2); + mdfld_restore_cursor_overlay_registers(dev); + return 0; +} + +static int mdfld_power_down(struct drm_device *dev) +{ + /* FIXME */ + return 0; +} + +static int mdfld_power_up(struct drm_device *dev) +{ + /* FIXME */ + return 0; +} + +const struct psb_ops mdfld_chip_ops = { + .name = "Medfield", + .accel_2d = 0, + .pipes = 3, + .crtcs = 2, + .sgx_offset = MRST_SGX_OFFSET, + + .chip_setup = mid_chip_setup, + + .crtc_helper = &mdfld_helper_funcs, + .crtc_funcs = &mdfld_intel_crtc_funcs, + + .output_init = mdfld_output_init, + +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + .backlight_init = mdfld_backlight_init, +#endif + + .init_pm = mdfld_init_pm, + .save_regs = mdfld_save_registers, + .restore_regs = mdfld_restore_registers, + .power_down = mdfld_power_down, + .power_up = mdfld_power_up, +}; + diff --git a/drivers/staging/gma500/mdfld_dsi_dbi.c b/drivers/staging/gma500/mdfld_dsi_dbi.c new file mode 100644 index 000000000000..02e17c9c8637 --- /dev/null +++ b/drivers/staging/gma500/mdfld_dsi_dbi.c @@ -0,0 +1,760 @@ +/* + * Copyright © 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: + * jim liu + * Jackie Li + */ + +#include "mdfld_dsi_dbi.h" +#include "mdfld_dsi_dbi_dpu.h" +#include "mdfld_dsi_pkg_sender.h" + +#include "power.h" +#include + +int enable_gfx_rtpm; + +extern struct drm_device *gpDrmDevice; +extern int gfxrtdelay; +int enter_dsr; +struct mdfld_dsi_dbi_output *gdbi_output; +extern bool gbgfxsuspended; +extern int enable_gfx_rtpm; +extern int gfxrtdelay; + +#define MDFLD_DSR_MAX_IDLE_COUNT 2 + +/* + * set refreshing area + */ +int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output, + u16 x1, u16 y1, u16 x2, u16 y2) +{ + struct mdfld_dsi_pkg_sender *sender = + mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); + u8 param[4]; + u8 cmd; + int err; + + if (!sender) { + WARN_ON(1); + return -EINVAL; + } + + /* Set column */ + cmd = DCS_SET_COLUMN_ADDRESS; + param[0] = x1 >> 8; + param[1] = x1; + param[2] = x2 >> 8; + param[3] = x2; + + err = mdfld_dsi_send_dcs(sender, + cmd, + param, + 4, + CMD_DATA_SRC_SYSTEM_MEM, + MDFLD_DSI_QUEUE_PACKAGE); + if (err) { + dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd); + goto err_out; + } + + /* Set page */ + cmd = DCS_SET_PAGE_ADDRESS; + param[0] = y1 >> 8; + param[1] = y1; + param[2] = y2 >> 8; + param[3] = y2; + + err = mdfld_dsi_send_dcs(sender, + cmd, + param, + 4, + CMD_DATA_SRC_SYSTEM_MEM, + MDFLD_DSI_QUEUE_PACKAGE); + if (err) { + dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd); + goto err_out; + } + + /*update screen*/ + err = mdfld_dsi_send_dcs(sender, + write_mem_start, + NULL, + 0, + CMD_DATA_SRC_PIPE, + MDFLD_DSI_QUEUE_PACKAGE); + if (err) { + dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd); + goto err_out; + } + mdfld_dsi_cmds_kick_out(sender); +err_out: + return err; +} + +/* + * set panel's power state + */ +int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output, + int mode) +{ + struct drm_device *dev = dbi_output->dev; + struct mdfld_dsi_pkg_sender *sender = + mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); + u8 param = 0; + u32 err = 0; + + if (!sender) { + WARN_ON(1); + return -EINVAL; + } + + if (mode == DRM_MODE_DPMS_ON) { + /* Exit sleep mode */ + err = mdfld_dsi_send_dcs(sender, + DCS_EXIT_SLEEP_MODE, + NULL, + 0, + CMD_DATA_SRC_SYSTEM_MEM, + MDFLD_DSI_QUEUE_PACKAGE); + if (err) { + dev_err(dev->dev, "DCS 0x%x sent failed\n", + DCS_EXIT_SLEEP_MODE); + goto power_err; + } + + /* Set display on */ + err = mdfld_dsi_send_dcs(sender, + DCS_SET_DISPLAY_ON, + NULL, + 0, + CMD_DATA_SRC_SYSTEM_MEM, + MDFLD_DSI_QUEUE_PACKAGE); + if (err) { + dev_err(dev->dev, "DCS 0x%x sent failed\n", + DCS_SET_DISPLAY_ON); + goto power_err; + } + + /* set tear effect on */ + err = mdfld_dsi_send_dcs(sender, + DCS_SET_TEAR_ON, + ¶m, + 1, + CMD_DATA_SRC_SYSTEM_MEM, + MDFLD_DSI_QUEUE_PACKAGE); + if (err) { + dev_err(dev->dev, "DCS 0x%x sent failed\n", + set_tear_on); + goto power_err; + } + + /** + * FIXME: remove this later + */ + err = mdfld_dsi_send_dcs(sender, + DCS_WRITE_MEM_START, + NULL, + 0, + CMD_DATA_SRC_PIPE, + MDFLD_DSI_QUEUE_PACKAGE); + if (err) { + dev_err(dev->dev, "DCS 0x%x sent failed\n", + DCS_WRITE_MEM_START); + goto power_err; + } + } else { + /* Set tear effect off */ + err = mdfld_dsi_send_dcs(sender, + DCS_SET_TEAR_OFF, + NULL, + 0, + CMD_DATA_SRC_SYSTEM_MEM, + MDFLD_DSI_QUEUE_PACKAGE); + if (err) { + dev_err(dev->dev, "DCS 0x%x sent failed\n", + DCS_SET_TEAR_OFF); + goto power_err; + } + + /* Turn display off */ + err = mdfld_dsi_send_dcs(sender, + DCS_SET_DISPLAY_OFF, + NULL, + 0, + CMD_DATA_SRC_SYSTEM_MEM, + MDFLD_DSI_QUEUE_PACKAGE); + if (err) { + dev_err(dev->dev, "DCS 0x%x sent failed\n", + DCS_SET_DISPLAY_OFF); + goto power_err; + } + + /* Now enter sleep mode */ + err = mdfld_dsi_send_dcs(sender, + DCS_ENTER_SLEEP_MODE, + NULL, + 0, + CMD_DATA_SRC_SYSTEM_MEM, + MDFLD_DSI_QUEUE_PACKAGE); + if (err) { + dev_err(dev->dev, "DCS 0x%x sent failed\n", + DCS_ENTER_SLEEP_MODE); + goto power_err; + } + } + mdfld_dsi_cmds_kick_out(sender); +power_err: + return err; +} + +/* + * send a generic DCS command with a parameter list + */ +int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output, + u8 dcs, u8 *param, u32 num, u8 data_src) +{ + struct mdfld_dsi_pkg_sender *sender = + mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); + int ret; + + if (!sender) { + WARN_ON(1); + return -EINVAL; + } + + ret = mdfld_dsi_send_dcs(sender, + dcs, + param, + num, + data_src, + MDFLD_DSI_SEND_PACKAGE); + + return ret; +} + +/* + * Enter DSR + */ +void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe) +{ + u32 reg_val; + struct drm_device *dev = dbi_output->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc = dbi_output->base.base.crtc; + struct psb_intel_crtc *psb_crtc = (crtc) ? + to_psb_intel_crtc(crtc) : NULL; + u32 dpll_reg = MRST_DPLL_A; + u32 pipeconf_reg = PIPEACONF; + u32 dspcntr_reg = DSPACNTR; + + if (!dbi_output) + return; + + /* FIXME check if can go */ + dev_priv->is_in_idle = true; + + gdbi_output = dbi_output; + if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) || + (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) + return; + + if (pipe == 2) { + dpll_reg = MRST_DPLL_A; + pipeconf_reg = PIPECCONF; + dspcntr_reg = DSPCCNTR; + } + + if (!gma_power_begin(dev, true)) { + dev_err(dev->dev, "hw begin failed\n"); + return; + } + /* Disable te interrupts */ + mdfld_disable_te(dev, pipe); + + /* Disable plane */ + reg_val = REG_READ(dspcntr_reg); + if (!(reg_val & DISPLAY_PLANE_ENABLE)) { + REG_WRITE(dspcntr_reg, reg_val & ~DISPLAY_PLANE_ENABLE); + REG_READ(dspcntr_reg); + } + + /* Disable pipe */ + reg_val = REG_READ(pipeconf_reg); + if (!(reg_val & DISPLAY_PLANE_ENABLE)) { + reg_val &= ~DISPLAY_PLANE_ENABLE; + reg_val |= (PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF); + REG_WRITE(pipeconf_reg, reg_val); + REG_READ(pipeconf_reg); + mdfldWaitForPipeDisable(dev, pipe); + } + + /* Disable DPLL */ + reg_val = REG_READ(dpll_reg); + if (!(reg_val & DPLL_VCO_ENABLE)) { + reg_val &= ~DPLL_VCO_ENABLE; + REG_WRITE(dpll_reg, reg_val); + REG_READ(dpll_reg); + udelay(500); + } + + gma_power_end(dev); + dbi_output->mode_flags |= MODE_SETTING_IN_DSR; + if (pipe == 2) { + enter_dsr = 1; + /* pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */ + } +} + +static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output, + int pipe) +{ + struct drm_device *dev = dbi_output->dev; + struct drm_crtc *crtc = dbi_output->base.base.crtc; + struct psb_intel_crtc *psb_crtc = (crtc) ? + to_psb_intel_crtc(crtc) : NULL; + u32 reg_val; + u32 dpll_reg = MRST_DPLL_A; + u32 pipeconf_reg = PIPEACONF; + u32 dspcntr_reg = DSPACNTR; + u32 reg_offset = 0; + + /*if mode setting on-going, back off*/ + if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) || + (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) + return; + + if (pipe == 2) { + dpll_reg = MRST_DPLL_A; + pipeconf_reg = PIPECCONF; + dspcntr_reg = DSPCCNTR; + reg_offset = MIPIC_REG_OFFSET; + } + + if (!gma_power_begin(dev, true)) { + dev_err(dev->dev, "hw begin failed\n"); + return; + } + + /* Enable DPLL */ + reg_val = REG_READ(dpll_reg); + if (!(reg_val & DPLL_VCO_ENABLE)) { + if (reg_val & MDFLD_PWR_GATE_EN) { + reg_val &= ~MDFLD_PWR_GATE_EN; + REG_WRITE(dpll_reg, reg_val); + REG_READ(dpll_reg); + udelay(500); + } + + reg_val |= DPLL_VCO_ENABLE; + REG_WRITE(dpll_reg, reg_val); + REG_READ(dpll_reg); + udelay(500); + + /* Add timeout */ + while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) + cpu_relax(); + } + + /* Enable pipe */ + reg_val = REG_READ(pipeconf_reg); + if (!(reg_val & PIPEACONF_ENABLE)) { + reg_val |= PIPEACONF_ENABLE; + REG_WRITE(pipeconf_reg, reg_val); + REG_READ(pipeconf_reg); + udelay(500); + mdfldWaitForPipeEnable(dev, pipe); + } + + /* Enable plane */ + reg_val = REG_READ(dspcntr_reg); + if (!(reg_val & DISPLAY_PLANE_ENABLE)) { + reg_val |= DISPLAY_PLANE_ENABLE; + REG_WRITE(dspcntr_reg, reg_val); + REG_READ(dspcntr_reg); + udelay(500); + } + + /* Enable TE interrupt on this pipe */ + mdfld_enable_te(dev, pipe); + gma_power_end(dev); + + /*clean IN_DSR flag*/ + dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR; +} + +/* + * Exit from DSR + */ +void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info; + struct mdfld_dsi_dbi_output **dbi_output; + int i; + int pipe; + + /* FIXME can go ? */ + dev_priv->is_in_idle = false; + dbi_output = dsr_info->dbi_outputs; + +#ifdef CONFIG_PM_RUNTIME + if (!enable_gfx_rtpm) { +/* pm_runtime_allow(&gpDrmDevice->pdev->dev); */ +/* schedule_delayed_work(&rtpm_work, 30 * 1000);*/ /* FIXME: HZ ? */ + } +#endif + + /* For each output, exit dsr */ + for (i = 0; i < dsr_info->dbi_output_num; i++) { + /* If panel has been turned off, skip */ + if (!dbi_output[i] || !dbi_output[i]->dbi_panel_on) + continue; + pipe = dbi_output[i]->channel_num ? 2 : 0; + enter_dsr = 0; + mdfld_dbi_output_exit_dsr(dbi_output[i], pipe); + } + dev_priv->dsr_fb_update |= update_src; +} + +static bool mdfld_dbi_is_in_dsr(struct drm_device *dev) +{ + if (REG_READ(MRST_DPLL_A) & DPLL_VCO_ENABLE) + return false; + if ((REG_READ(PIPEACONF) & PIPEACONF_ENABLE) || + (REG_READ(PIPECCONF) & PIPEACONF_ENABLE)) + return false; + if ((REG_READ(DSPACNTR) & DISPLAY_PLANE_ENABLE) || + (REG_READ(DSPCCNTR) & DISPLAY_PLANE_ENABLE)) + return false; + + return true; +} + +/* Periodically update dbi panel */ +void mdfld_dbi_update_panel(struct drm_device *dev, int pipe) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info; + struct mdfld_dsi_dbi_output **dbi_outputs; + struct mdfld_dsi_dbi_output *dbi_output; + int i; + int can_enter_dsr = 0; + u32 damage_mask; + + dbi_outputs = dsr_info->dbi_outputs; + dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0]; + + if (!dbi_output) + return; + + if (pipe == 0) + damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_0; + else if (pipe == 2) + damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_2; + else + return; + + /* If FB is damaged and panel is on update on-panel FB */ + if (damage_mask && dbi_output->dbi_panel_on) { + dbi_output->dsr_fb_update_done = false; + + if (dbi_output->p_funcs->update_fb) + dbi_output->p_funcs->update_fb(dbi_output, pipe); + + if (dev_priv->dsr_enable && dbi_output->dsr_fb_update_done) + dev_priv->dsr_fb_update &= ~damage_mask; + + /*clean IN_DSR flag*/ + dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR; + + dbi_output->dsr_idle_count = 0; + } else { + dbi_output->dsr_idle_count++; + } + + switch (dsr_info->dbi_output_num) { + case 1: + if (dbi_output->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT) + can_enter_dsr = 1; + break; + case 2: + if (dbi_outputs[0]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT + && dbi_outputs[1]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT) + can_enter_dsr = 1; + break; + default: + DRM_ERROR("Wrong DBI output number\n"); + } + + /* Try to enter DSR */ + if (can_enter_dsr) { + for (i = 0; i < dsr_info->dbi_output_num; i++) { + if (!mdfld_dbi_is_in_dsr(dev) && dbi_outputs[i] && + !(dbi_outputs[i]->mode_flags & MODE_SETTING_ON_GOING)) { + mdfld_dsi_dbi_enter_dsr(dbi_outputs[i], + dbi_outputs[i]->channel_num ? 2 : 0); +#if 0 + enter_dsr = 1; + pr_err("%s: enter_dsr = 1\n", __func__); +#endif + } + } + /*schedule rpm suspend after gfxrtdelay*/ +#ifdef CONFIG_GFX_RTPM + if (!dev_priv->rpm_enabled + || !enter_dsr + /* || (REG_READ(HDMIB_CONTROL) & HDMIB_PORT_EN) */ + || pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay)) + dev_warn(dev->dev, + "Runtime PM schedule suspend failed, rpm %d\n", + dev_priv->rpm_enabled); +#endif + } +} + +int mdfld_dbi_dsr_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info; + + if (!dsr_info || IS_ERR(dsr_info)) { + dsr_info = kzalloc(sizeof(struct mdfld_dbi_dsr_info), + GFP_KERNEL); + if (!dsr_info) { + dev_err(dev->dev, "No memory\n"); + return -ENOMEM; + } + dev_priv->dbi_dsr_info = dsr_info; + } + return 0; +} + +void mdfld_dbi_dsr_exit(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info; + + if (dsr_info) { + kfree(dsr_info); + dev_priv->dbi_dsr_info = NULL; + } +} + +void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config, + int pipe) +{ + struct drm_device *dev = dsi_config->dev; + u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0; + int lane_count = dsi_config->lane_count; + u32 val = 0; + + dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe); + + /* Un-ready device */ + REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000); + + /* Init dsi adapter before kicking off */ + REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018); + + /* TODO: figure out how to setup these registers */ + REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408); + REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), + 0x000a0014); + REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400); + REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001); + REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000); + + /* Enable all interrupts */ + REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff); + /* Max value: 20 clock cycles of txclkesc */ + REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f); + /* Min 21 txclkesc, max: ffffh */ + REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff); + /* Min: 7d0 max: 4e20 */ + REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0); + + /* Set up func_prg */ + val |= lane_count; + val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET); + val |= DSI_DBI_COLOR_FORMAT_OPTION2; + REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val); + + REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff); + REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff); + + /* De-assert dbi_stall when half of DBI FIFO is empty */ + /* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */ + + REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46); + REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000); + REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004); + REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001); +} + +#if 0 +/*DBI encoder helper funcs*/ +static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = { + .dpms = mdfld_dsi_dbi_dpms, + .mode_fixup = mdfld_dsi_dbi_mode_fixup, + .prepare = mdfld_dsi_dbi_prepare, + .mode_set = mdfld_dsi_dbi_mode_set, + .commit = mdfld_dsi_dbi_commit, +}; + +/*DBI encoder funcs*/ +static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +#endif + +/* + * Init DSI DBI encoder. + * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector + * return pointer of newly allocated DBI encoder, NULL on error + */ +struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev, + struct mdfld_dsi_connector *dsi_connector, + struct panel_funcs *p_funcs) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dsi_dbi_output *dbi_output = NULL; + struct mdfld_dsi_config *dsi_config; + struct drm_connector *connector = NULL; + struct drm_encoder *encoder = NULL; + struct drm_display_mode *fixed_mode = NULL; + struct psb_gtt *pg = dev_priv ? (&dev_priv->gtt) : NULL; + struct mdfld_dbi_dpu_info *dpu_info = dev_priv ? (dev_priv->dbi_dpu_info) : NULL; + struct mdfld_dbi_dsr_info *dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL; + u32 data = 0; + int pipe; + int ret; + + if (!pg || !dsi_connector || !p_funcs) { + WARN_ON(1); + return NULL; + } + + dsi_config = mdfld_dsi_get_config(dsi_connector); + pipe = dsi_connector->pipe; + + /*panel hard-reset*/ + if (p_funcs->reset) { + ret = p_funcs->reset(pipe); + if (ret) { + DRM_ERROR("Panel %d hard-reset failed\n", pipe); + return NULL; + } + } + /* Panel drvIC init */ + if (p_funcs->drv_ic_init) + p_funcs->drv_ic_init(dsi_config, pipe); + + /* Panel power mode detect */ + ret = mdfld_dsi_get_power_mode(dsi_config, + &data, + MDFLD_DSI_HS_TRANSMISSION); + if (ret) { + DRM_ERROR("Panel %d get power mode failed\n", pipe); + dsi_connector->status = connector_status_disconnected; + } else { + DRM_INFO("pipe %d power mode 0x%x\n", pipe, data); + dsi_connector->status = connector_status_connected; + } + + /*TODO: get panel info from DDB*/ + + dbi_output = kzalloc(sizeof(struct mdfld_dsi_dbi_output), GFP_KERNEL); + if (!dbi_output) { + dev_err(dev->dev, "No memory\n"); + return NULL; + } + + if (dsi_connector->pipe == 0) { + dbi_output->channel_num = 0; + dev_priv->dbi_output = dbi_output; + } else if (dsi_connector->pipe == 2) { + dbi_output->channel_num = 1; + dev_priv->dbi_output2 = dbi_output; + } else { + dev_err(dev->dev, "only support 2 DSI outputs\n"); + goto out_err1; + } + + dbi_output->dev = dev; + dbi_output->p_funcs = p_funcs; + fixed_mode = dsi_config->fixed_mode; + dbi_output->panel_fixed_mode = fixed_mode; + + /* Create drm encoder object */ + connector = &dsi_connector->base.base; + encoder = &dbi_output->base.base; + drm_encoder_init(dev, + encoder, + p_funcs->encoder_funcs, + DRM_MODE_ENCODER_MIPI); + drm_encoder_helper_add(encoder, p_funcs->encoder_helper_funcs); + + /* Attach to given connector */ + drm_mode_connector_attach_encoder(connector, encoder); + + /* Set possible CRTCs and clones */ + if (dsi_connector->pipe) { + encoder->possible_crtcs = (1 << 2); + encoder->possible_clones = (1 << 1); + } else { + encoder->possible_crtcs = (1 << 0); + encoder->possible_clones = (1 << 0); + } + + dev_priv->dsr_fb_update = 0; + dev_priv->dsr_enable = false; + dev_priv->exit_idle = mdfld_dsi_dbi_exit_dsr; + + dbi_output->first_boot = true; + dbi_output->mode_flags = MODE_SETTING_IN_ENCODER; + + /* Add this output to dpu_info if in DPU mode */ + if (dpu_info && dsi_connector->status == connector_status_connected) { + if (dsi_connector->pipe == 0) + dpu_info->dbi_outputs[0] = dbi_output; + else + dpu_info->dbi_outputs[1] = dbi_output; + + dpu_info->dbi_output_num++; + } else if (dsi_connector->status == connector_status_connected) { + /* Add this output to dsr_info if not */ + if (dsi_connector->pipe == 0) + dsr_info->dbi_outputs[0] = dbi_output; + else + dsr_info->dbi_outputs[1] = dbi_output; + + dsr_info->dbi_output_num++; + } + return &dbi_output->base; +out_err1: + kfree(dbi_output); + return NULL; +} diff --git a/drivers/staging/gma500/mdfld_dsi_dbi.h b/drivers/staging/gma500/mdfld_dsi_dbi.h new file mode 100644 index 000000000000..dc6242c51d0b --- /dev/null +++ b/drivers/staging/gma500/mdfld_dsi_dbi.h @@ -0,0 +1,176 @@ +/* + * Copyright © 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: + * jim liu + * Jackie Li + */ + +#ifndef __MDFLD_DSI_DBI_H__ +#define __MDFLD_DSI_DBI_H__ + +#include +#include +#include +#include +#include + +#include "psb_drv.h" +#include "psb_intel_drv.h" +#include "psb_intel_reg.h" +#include "power.h" + +#include "mdfld_dsi_output.h" +#include "mdfld_output.h" + +#define DRM_MODE_ENCODER_MIPI 5 + + +/* + * DBI encoder which inherits from mdfld_dsi_encoder + */ +struct mdfld_dsi_dbi_output { + struct mdfld_dsi_encoder base; + struct drm_display_mode *panel_fixed_mode; + u8 last_cmd; + u8 lane_count; + u8 channel_num; + struct drm_device *dev; + + /* Backlight operations */ + + /* DSR timer */ + u32 dsr_idle_count; + bool dsr_fb_update_done; + + /* Mode setting flags */ + u32 mode_flags; + + /* Panel status */ + bool dbi_panel_on; + bool first_boot; + struct panel_funcs *p_funcs; + + /* DPU */ + u32 *dbi_cb_addr; + u32 dbi_cb_phy; + spinlock_t cb_lock; + u32 cb_write; +}; + +#define MDFLD_DSI_DBI_OUTPUT(dsi_encoder) \ + container_of(dsi_encoder, struct mdfld_dsi_dbi_output, base) + +struct mdfld_dbi_dsr_info { + int dbi_output_num; + struct mdfld_dsi_dbi_output *dbi_outputs[2]; + + u32 dsr_idle_count; +}; + +#define DBI_CB_TIMEOUT_COUNT 0xffff + +/* Offsets */ +#define CMD_MEM_ADDR_OFFSET 0 + +#define CMD_DATA_SRC_SYSTEM_MEM 0 +#define CMD_DATA_SRC_PIPE 1 + +static inline int mdfld_dsi_dbi_fifo_ready(struct mdfld_dsi_dbi_output *dbi_output) +{ + struct drm_device *dev = dbi_output->dev; + u32 retry = DBI_CB_TIMEOUT_COUNT; + int reg_offset = (dbi_output->channel_num == 1) ? MIPIC_REG_OFFSET : 0; + int ret = 0; + + /* Query the dbi fifo status*/ + while (retry--) { + if (REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset) & (1 << 27)) + break; + } + + if (!retry) { + DRM_ERROR("Timeout waiting for DBI FIFO empty\n"); + ret = -EAGAIN; + } + return ret; +} + +static inline int mdfld_dsi_dbi_cmd_sent(struct mdfld_dsi_dbi_output *dbi_output) +{ + struct drm_device *dev = dbi_output->dev; + u32 retry = DBI_CB_TIMEOUT_COUNT; + int reg_offset = (dbi_output->channel_num == 1) ? MIPIC_REG_OFFSET : 0; + int ret = 0; + + /* Query the command execution status */ + while (retry--) + if (!(REG_READ(MIPIA_CMD_ADD_REG + reg_offset) & (1 << 0))) + break; + + if (!retry) { + DRM_ERROR("Timeout waiting for DBI command status\n"); + ret = -EAGAIN; + } + + return ret; +} + +static inline int mdfld_dsi_dbi_cb_ready(struct mdfld_dsi_dbi_output *dbi_output) +{ + int ret = 0; + + /* Query the command execution status*/ + ret = mdfld_dsi_dbi_cmd_sent(dbi_output); + if (ret) { + DRM_ERROR("Peripheral is busy\n"); + ret = -EAGAIN; + } + /* Query the dbi fifo status*/ + ret = mdfld_dsi_dbi_fifo_ready(dbi_output); + if (ret) { + DRM_ERROR("DBI FIFO is not empty\n"); + ret = -EAGAIN; + } + return ret; +} + +extern void mdfld_dsi_dbi_output_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev, int pipe); +extern void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src); +extern void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, + int pipe); +extern int mdfld_dbi_dsr_init(struct drm_device *dev); +extern void mdfld_dbi_dsr_exit(struct drm_device *dev); +extern struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev, + struct mdfld_dsi_connector *dsi_connector, + struct panel_funcs *p_funcs); +extern int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output, + u8 dcs, u8 *param, u32 num, u8 data_src); +extern int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output, + u16 x1, u16 y1, u16 x2, u16 y2); +extern int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output, + int mode); +extern void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config, + int pipe); + +#endif /*__MDFLD_DSI_DBI_H__*/ diff --git a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c new file mode 100644 index 000000000000..a4e2ff442b1f --- /dev/null +++ b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.c @@ -0,0 +1,778 @@ +/* + * Copyright © 2010-2011 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: + * Jim Liu + * Jackie Li + */ + +#include "mdfld_dsi_dbi_dpu.h" +#include "mdfld_dsi_dbi.h" + +/* + * NOTE: all mdlfd_x_damage funcs should be called by holding dpu_update_lock + */ + +static int mdfld_cursor_damage(struct mdfld_dbi_dpu_info *dpu_info, + mdfld_plane_t plane, + struct psb_drm_dpu_rect *damaged_rect) +{ + int x, y; + int new_x, new_y; + struct psb_drm_dpu_rect *rect; + struct psb_drm_dpu_rect *pipe_rect; + int cursor_size; + struct mdfld_cursor_info *cursor; + mdfld_plane_t fb_plane; + + if (plane == MDFLD_CURSORA) { + cursor = &dpu_info->cursors[0]; + x = dpu_info->cursors[0].x; + y = dpu_info->cursors[0].y; + cursor_size = dpu_info->cursors[0].size; + pipe_rect = &dpu_info->damage_pipea; + fb_plane = MDFLD_PLANEA; + } else { + cursor = &dpu_info->cursors[1]; + x = dpu_info->cursors[1].x; + y = dpu_info->cursors[1].y; + cursor_size = dpu_info->cursors[1].size; + pipe_rect = &dpu_info->damage_pipec; + fb_plane = MDFLD_PLANEC; + } + new_x = damaged_rect->x; + new_y = damaged_rect->y; + + if (x == new_x && y == new_y) + return 0; + + rect = &dpu_info->damaged_rects[plane]; + /* Move to right */ + if (new_x >= x) { + if (new_y > y) { + rect->x = x; + rect->y = y; + rect->width = (new_x + cursor_size) - x; + rect->height = (new_y + cursor_size) - y; + goto cursor_out; + } else { + rect->x = x; + rect->y = new_y; + rect->width = (new_x + cursor_size) - x; + rect->height = (y - new_y); + goto cursor_out; + } + } else { + if (new_y > y) { + rect->x = new_x; + rect->y = y; + rect->width = (x + cursor_size) - new_x; + rect->height = new_y - y; + goto cursor_out; + } else { + rect->x = new_x; + rect->y = new_y; + rect->width = (x + cursor_size) - new_x; + rect->height = (y + cursor_size) - new_y; + } + } +cursor_out: + if (new_x < 0) + cursor->x = 0; + else if (new_x > 864) + cursor->x = 864; + else + cursor->x = new_x; + + if (new_y < 0) + cursor->y = 0; + else if (new_y > 480) + cursor->y = 480; + else + cursor->y = new_y; + + /* + * FIXME: this is a workaround for cursor plane update, + * remove it later! + */ + rect->x = 0; + rect->y = 0; + rect->width = 864; + rect->height = 480; + + mdfld_check_boundary(dpu_info, rect); + mdfld_dpu_region_extent(pipe_rect, rect); + + /* Update pending status of dpu_info */ + dpu_info->pending |= (1 << plane); + /* Update fb panel as well */ + dpu_info->pending |= (1 << fb_plane); + return 0; +} + +static int mdfld_fb_damage(struct mdfld_dbi_dpu_info *dpu_info, + mdfld_plane_t plane, + struct psb_drm_dpu_rect *damaged_rect) +{ + struct psb_drm_dpu_rect *rect; + + if (plane == MDFLD_PLANEA) + rect = &dpu_info->damage_pipea; + else + rect = &dpu_info->damage_pipec; + + mdfld_check_boundary(dpu_info, damaged_rect); + + /* Add fb damage area to this pipe */ + mdfld_dpu_region_extent(rect, damaged_rect); + + /* Update pending status of dpu_info */ + dpu_info->pending |= (1 << plane); + return 0; +} + +/* Do nothing here, right now */ +static int mdfld_overlay_damage(struct mdfld_dbi_dpu_info *dpu_info, + mdfld_plane_t plane, + struct psb_drm_dpu_rect *damaged_rect) +{ + return 0; +} + +int mdfld_dbi_dpu_report_damage(struct drm_device *dev, + mdfld_plane_t plane, + struct psb_drm_dpu_rect *rect) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info; + int ret = 0; + + /* DPU not in use, no damage reporting needed */ + if (dpu_info == NULL) + return 0; + + spin_lock(&dpu_info->dpu_update_lock); + + switch (plane) { + case MDFLD_PLANEA: + case MDFLD_PLANEC: + mdfld_fb_damage(dpu_info, plane, rect); + break; + case MDFLD_CURSORA: + case MDFLD_CURSORC: + mdfld_cursor_damage(dpu_info, plane, rect); + break; + case MDFLD_OVERLAYA: + case MDFLD_OVERLAYC: + mdfld_overlay_damage(dpu_info, plane, rect); + break; + default: + DRM_ERROR("Invalid plane type %d\n", plane); + ret = -EINVAL; + } + spin_unlock(&dpu_info->dpu_update_lock); + return ret; +} + +int mdfld_dbi_dpu_report_fullscreen_damage(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv; + struct mdfld_dbi_dpu_info *dpu_info; + struct mdfld_dsi_config *dsi_config; + struct psb_drm_dpu_rect rect; + int i; + + if (!dev) { + DRM_ERROR("Invalid parameter\n"); + return -EINVAL; + } + + dev_priv = dev->dev_private; + dpu_info = dev_priv->dbi_dpu_info; + + /* This is fine - we may be in non DPU mode */ + if (!dpu_info) + return -EINVAL; + + for (i = 0; i < dpu_info->dbi_output_num; i++) { + dsi_config = dev_priv->dsi_configs[i]; + if (dsi_config) { + rect.x = rect.y = 0; + rect.width = dsi_config->fixed_mode->hdisplay; + rect.height = dsi_config->fixed_mode->vdisplay; + mdfld_dbi_dpu_report_damage(dev, + i ? (MDFLD_PLANEC) : (MDFLD_PLANEA), + &rect); + } + } + /* Exit DSR state */ + mdfld_dpu_exit_dsr(dev); + return 0; +} + +int mdfld_dsi_dbi_dsr_off(struct drm_device *dev, + struct psb_drm_dpu_rect *rect) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info; + + mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, rect); + + /* If dual display mode */ + if (dpu_info->dbi_output_num == 2) + mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, rect); + + /* Force dsi to exit DSR mode */ + mdfld_dpu_exit_dsr(dev); + return 0; +} + +static void mdfld_dpu_cursor_plane_flush(struct mdfld_dbi_dpu_info *dpu_info, + mdfld_plane_t plane) +{ + struct drm_device *dev = dpu_info->dev; + u32 curpos_reg = CURAPOS; + u32 curbase_reg = CURABASE; + u32 curcntr_reg = CURACNTR; + struct mdfld_cursor_info *cursor = &dpu_info->cursors[0]; + + if (plane == MDFLD_CURSORC) { + curpos_reg = CURCPOS; + curbase_reg = CURCBASE; + curcntr_reg = CURCCNTR; + cursor = &dpu_info->cursors[1]; + } + + REG_WRITE(curcntr_reg, REG_READ(curcntr_reg)); + REG_WRITE(curpos_reg, + (((cursor->x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) | + ((cursor->y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT))); + REG_WRITE(curbase_reg, REG_READ(curbase_reg)); +} + +static void mdfld_dpu_fb_plane_flush(struct mdfld_dbi_dpu_info *dpu_info, + mdfld_plane_t plane) +{ + u32 pipesrc_reg = PIPEASRC; + u32 dspsize_reg = DSPASIZE; + u32 dspoff_reg = DSPALINOFF; + u32 dspsurf_reg = DSPASURF; + u32 dspstride_reg = DSPASTRIDE; + u32 stride; + struct psb_drm_dpu_rect *rect = &dpu_info->damage_pipea; + struct drm_device *dev = dpu_info->dev; + + if (plane == MDFLD_PLANEC) { + pipesrc_reg = PIPECSRC; + dspsize_reg = DSPCSIZE; + dspoff_reg = DSPCLINOFF; + dspsurf_reg = DSPCSURF; + dspstride_reg = DSPCSTRIDE; + rect = &dpu_info->damage_pipec; + } + + stride = REG_READ(dspstride_reg); + /* FIXME: should I do the pipe src update here? */ + REG_WRITE(pipesrc_reg, ((rect->width - 1) << 16) | (rect->height - 1)); + /* Flush plane */ + REG_WRITE(dspsize_reg, ((rect->height - 1) << 16) | (rect->width - 1)); + REG_WRITE(dspoff_reg, ((rect->x * 4) + (rect->y * stride))); + REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg)); + + /* + * TODO: wait for flip finished and restore the pipesrc reg, + * or cursor will be show at a wrong position + */ +} + +static void mdfld_dpu_overlay_plane_flush(struct mdfld_dbi_dpu_info *dpu_info, + mdfld_plane_t plane) +{ +} + +/* + * TODO: we are still in dbi normal mode now, we will try to use partial + * mode later. + */ +static int mdfld_dbi_prepare_cb(struct mdfld_dsi_dbi_output *dbi_output, + struct mdfld_dbi_dpu_info *dpu_info, int pipe) +{ + u8 *cb_addr = (u8 *)dbi_output->dbi_cb_addr; + u32 *index; + struct psb_drm_dpu_rect *rect = pipe ? + (&dpu_info->damage_pipec) : (&dpu_info->damage_pipea); + + /* FIXME: lock command buffer, this may lead to a deadlock, + as we already hold the dpu_update_lock */ + if (!spin_trylock(&dbi_output->cb_lock)) { + DRM_ERROR("lock command buffer failed, try again\n"); + return -EAGAIN; + } + + index = &dbi_output->cb_write; + + if (*index) { + DRM_ERROR("DBI command buffer unclean\n"); + return -EAGAIN; + } + + /* Column address */ + *(cb_addr + ((*index)++)) = set_column_address; + *(cb_addr + ((*index)++)) = rect->x >> 8; + *(cb_addr + ((*index)++)) = rect->x; + *(cb_addr + ((*index)++)) = (rect->x + rect->width - 1) >> 8; + *(cb_addr + ((*index)++)) = (rect->x + rect->width - 1); + + *index = 8; + + /* Page address */ + *(cb_addr + ((*index)++)) = set_page_addr; + *(cb_addr + ((*index)++)) = rect->y >> 8; + *(cb_addr + ((*index)++)) = rect->y; + *(cb_addr + ((*index)++)) = (rect->y + rect->height - 1) >> 8; + *(cb_addr + ((*index)++)) = (rect->y + rect->height - 1); + + *index = 16; + + /*write memory*/ + *(cb_addr + ((*index)++)) = write_mem_start; + + return 0; +} + +static int mdfld_dbi_flush_cb(struct mdfld_dsi_dbi_output *dbi_output, int pipe) +{ + u32 cmd_phy = dbi_output->dbi_cb_phy; + u32 *index = &dbi_output->cb_write; + int reg_offset = pipe ? MIPIC_REG_OFFSET : 0; + struct drm_device *dev = dbi_output->dev; + + if (*index == 0 || !dbi_output) + return 0; + + REG_WRITE((MIPIA_CMD_LEN_REG + reg_offset), 0x010505); + REG_WRITE((MIPIA_CMD_ADD_REG + reg_offset), cmd_phy | 3); + + *index = 0; + + /* FIXME: unlock command buffer */ + spin_unlock(&dbi_output->cb_lock); + return 0; +} + +static int mdfld_dpu_update_pipe(struct mdfld_dsi_dbi_output *dbi_output, + struct mdfld_dbi_dpu_info *dpu_info, int pipe) +{ + struct drm_device *dev = dbi_output->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + mdfld_plane_t cursor_plane = MDFLD_CURSORA; + mdfld_plane_t fb_plane = MDFLD_PLANEA; + mdfld_plane_t overlay_plane = MDFLD_OVERLAYA; + int ret = 0; + u32 plane_mask = MDFLD_PIPEA_PLANE_MASK; + + /* Damaged rects on this pipe */ + if (pipe) { + cursor_plane = MDFLD_CURSORC; + fb_plane = MDFLD_PLANEC; + overlay_plane = MDFLD_OVERLAYC; + plane_mask = MDFLD_PIPEC_PLANE_MASK; + } + + /*update cursor which assigned to @pipe*/ + if (dpu_info->pending & (1 << cursor_plane)) + mdfld_dpu_cursor_plane_flush(dpu_info, cursor_plane); + + /*update fb which assigned to @pipe*/ + if (dpu_info->pending & (1 << fb_plane)) + mdfld_dpu_fb_plane_flush(dpu_info, fb_plane); + + /* TODO: update overlay */ + if (dpu_info->pending & (1 << overlay_plane)) + mdfld_dpu_overlay_plane_flush(dpu_info, overlay_plane); + + /* Flush damage area to panel fb */ + if (dpu_info->pending & plane_mask) { + ret = mdfld_dbi_prepare_cb(dbi_output, dpu_info, pipe); + /* + * TODO: remove b_dsr_enable later, + * added it so that text console could boot smoothly + */ + /* Clean pending flags on this pipe */ + if (!ret && dev_priv->dsr_enable) { + dpu_info->pending &= ~plane_mask; + /* Reset overlay pipe damage rect */ + mdfld_dpu_init_damage(dpu_info, pipe); + } + } + return ret; +} + +static int mdfld_dpu_update_fb(struct drm_device *dev) +{ + struct drm_crtc *crtc; + struct psb_intel_crtc *psb_crtc; + struct mdfld_dsi_dbi_output **dbi_output; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info; + bool pipe_updated[2]; + unsigned long irq_flags; + u32 dpll_reg = MRST_DPLL_A; + u32 dspcntr_reg = DSPACNTR; + u32 pipeconf_reg = PIPEACONF; + u32 dsplinoff_reg = DSPALINOFF; + u32 dspsurf_reg = DSPASURF; + u32 mipi_state_reg = MIPIA_INTR_STAT_REG; + u32 reg_offset = 0; + int pipe; + int i; + int ret; + + dbi_output = dpu_info->dbi_outputs; + pipe_updated[0] = pipe_updated[1] = false; + + if (!gma_power_begin(dev, true)) + return -EAGAIN; + + /* Try to prevent any new damage reports */ + if (!spin_trylock_irqsave(&dpu_info->dpu_update_lock, irq_flags)) + return -EAGAIN; + + for (i = 0; i < dpu_info->dbi_output_num; i++) { + crtc = dbi_output[i]->base.base.crtc; + psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) : NULL; + + pipe = dbi_output[i]->channel_num ? 2 : 0; + + if (pipe == 2) { + dspcntr_reg = DSPCCNTR; + pipeconf_reg = PIPECCONF; + dsplinoff_reg = DSPCLINOFF; + dspsurf_reg = DSPCSURF; + reg_offset = MIPIC_REG_OFFSET; + } + + if (!(REG_READ((MIPIA_GEN_FIFO_STAT_REG + reg_offset)) + & (1 << 27)) || + !(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) || + !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) || + !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) { + dev_err(dev->dev, + "DBI FIFO is busy, DSI %d state %x\n", + pipe, + REG_READ(mipi_state_reg + reg_offset)); + continue; + } + + /* + * If DBI output is in a exclusive state then the pipe + * change won't be updated + */ + if (dbi_output[i]->dbi_panel_on && + !(dbi_output[i]->mode_flags & MODE_SETTING_ON_GOING) && + !(psb_crtc && + psb_crtc->mode_flags & MODE_SETTING_ON_GOING) && + !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) { + ret = mdfld_dpu_update_pipe(dbi_output[i], + dpu_info, dbi_output[i]->channel_num ? 2 : 0); + if (!ret) + pipe_updated[i] = true; + } + } + + for (i = 0; i < dpu_info->dbi_output_num; i++) + if (pipe_updated[i]) + mdfld_dbi_flush_cb(dbi_output[i], + dbi_output[i]->channel_num ? 2 : 0); + + spin_unlock_irqrestore(&dpu_info->dpu_update_lock, irq_flags); + gma_power_end(dev); + return 0; +} + +static int __mdfld_dbi_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output, + int pipe) +{ + struct drm_device *dev = dbi_output->dev; + struct drm_crtc *crtc = dbi_output->base.base.crtc; + struct psb_intel_crtc *psb_crtc = (crtc) ? to_psb_intel_crtc(crtc) + : NULL; + u32 reg_val; + u32 dpll_reg = MRST_DPLL_A; + u32 pipeconf_reg = PIPEACONF; + u32 dspcntr_reg = DSPACNTR; + u32 dspbase_reg = DSPABASE; + u32 dspsurf_reg = DSPASURF; + u32 reg_offset = 0; + + if (!dbi_output) + return 0; + + /* If mode setting on-going, back off */ + if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) || + (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING)) + return -EAGAIN; + + if (pipe == 2) { + dpll_reg = MRST_DPLL_A; + pipeconf_reg = PIPECCONF; + dspcntr_reg = DSPCCNTR; + dspbase_reg = MDFLD_DSPCBASE; + dspsurf_reg = DSPCSURF; + + reg_offset = MIPIC_REG_OFFSET; + } + + if (!gma_power_begin(dev, true)) + return -EAGAIN; + + /* Enable DPLL */ + reg_val = REG_READ(dpll_reg); + if (!(reg_val & DPLL_VCO_ENABLE)) { + + if (reg_val & MDFLD_PWR_GATE_EN) { + reg_val &= ~MDFLD_PWR_GATE_EN; + REG_WRITE(dpll_reg, reg_val); + REG_READ(dpll_reg); + udelay(500); + } + + reg_val |= DPLL_VCO_ENABLE; + REG_WRITE(dpll_reg, reg_val); + REG_READ(dpll_reg); + udelay(500); + + /* FIXME: add timeout */ + while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) + cpu_relax(); + } + + /* Enable pipe */ + reg_val = REG_READ(pipeconf_reg); + if (!(reg_val & PIPEACONF_ENABLE)) { + reg_val |= PIPEACONF_ENABLE; + REG_WRITE(pipeconf_reg, reg_val); + REG_READ(pipeconf_reg); + udelay(500); + mdfldWaitForPipeEnable(dev, pipe); + } + + /* Enable plane */ + reg_val = REG_READ(dspcntr_reg); + if (!(reg_val & DISPLAY_PLANE_ENABLE)) { + reg_val |= DISPLAY_PLANE_ENABLE; + REG_WRITE(dspcntr_reg, reg_val); + REG_READ(dspcntr_reg); + udelay(500); + } + + gma_power_end(dev); + + /* Clean IN_DSR flag */ + dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR; + + return 0; +} + +int mdfld_dpu_exit_dsr(struct drm_device *dev) +{ + struct mdfld_dsi_dbi_output **dbi_output; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info; + int i; + int pipe; + + dbi_output = dpu_info->dbi_outputs; + + for (i = 0; i < dpu_info->dbi_output_num; i++) { + /* If this output is not in DSR mode, don't call exit dsr */ + if (dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR) + __mdfld_dbi_exit_dsr(dbi_output[i], + dbi_output[i]->channel_num ? 2 : 0); + } + + /* Enable TE interrupt */ + for (i = 0; i < dpu_info->dbi_output_num; i++) { + /* If this output is not in DSR mode, don't call exit dsr */ + pipe = dbi_output[i]->channel_num ? 2 : 0; + if (dbi_output[i]->dbi_panel_on && pipe) { + mdfld_disable_te(dev, 0); + mdfld_enable_te(dev, 2); + } else if (dbi_output[i]->dbi_panel_on && !pipe) { + mdfld_disable_te(dev, 2); + mdfld_enable_te(dev, 0); + } + } + return 0; +} + +static int mdfld_dpu_enter_dsr(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info; + struct mdfld_dsi_dbi_output **dbi_output; + int i; + + dbi_output = dpu_info->dbi_outputs; + + for (i = 0; i < dpu_info->dbi_output_num; i++) { + /* If output is off or already in DSR state, don't re-enter */ + if (dbi_output[i]->dbi_panel_on && + !(dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR)) { + mdfld_dsi_dbi_enter_dsr(dbi_output[i], + dbi_output[i]->channel_num ? 2 : 0); + } + } + + return 0; +} + +static void mdfld_dbi_dpu_timer_func(unsigned long data) +{ + struct drm_device *dev = (struct drm_device *)data; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info; + struct timer_list *dpu_timer = &dpu_info->dpu_timer; + unsigned long flags; + + if (dpu_info->pending) { + dpu_info->idle_count = 0; + /* Update panel fb with damaged area */ + mdfld_dpu_update_fb(dev); + } else { + dpu_info->idle_count++; + } + + if (dpu_info->idle_count >= MDFLD_MAX_IDLE_COUNT) { + mdfld_dpu_enter_dsr(dev); + /* Stop timer by return */ + return; + } + + spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags); + if (!timer_pending(dpu_timer)) { + dpu_timer->expires = jiffies + MDFLD_DSR_DELAY; + add_timer(dpu_timer); + } + spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags); +} + +void mdfld_dpu_update_panel(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info; + + if (dpu_info->pending) { + dpu_info->idle_count = 0; + + /*update panel fb with damaged area*/ + mdfld_dpu_update_fb(dev); + } else { + dpu_info->idle_count++; + } + + if (dpu_info->idle_count >= MDFLD_MAX_IDLE_COUNT) { + /*enter dsr*/ + mdfld_dpu_enter_dsr(dev); + } +} + +static int mdfld_dbi_dpu_timer_init(struct drm_device *dev, + struct mdfld_dbi_dpu_info *dpu_info) +{ + struct timer_list *dpu_timer = &dpu_info->dpu_timer; + unsigned long flags; + + spin_lock_init(&dpu_info->dpu_timer_lock); + spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags); + + init_timer(dpu_timer); + + dpu_timer->data = (unsigned long)dev; + dpu_timer->function = mdfld_dbi_dpu_timer_func; + dpu_timer->expires = jiffies + MDFLD_DSR_DELAY; + + spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags); + + return 0; +} + +void mdfld_dbi_dpu_timer_start(struct mdfld_dbi_dpu_info *dpu_info) +{ + struct timer_list *dpu_timer = &dpu_info->dpu_timer; + unsigned long flags; + + spin_lock_irqsave(&dpu_info->dpu_timer_lock, flags); + if (!timer_pending(dpu_timer)) { + dpu_timer->expires = jiffies + MDFLD_DSR_DELAY; + add_timer(dpu_timer); + } + spin_unlock_irqrestore(&dpu_info->dpu_timer_lock, flags); +} + +int mdfld_dbi_dpu_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info; + + if (!dpu_info || IS_ERR(dpu_info)) { + dpu_info = kzalloc(sizeof(struct mdfld_dbi_dpu_info), + GFP_KERNEL); + if (!dpu_info) { + DRM_ERROR("No memory\n"); + return -ENOMEM; + } + dev_priv->dbi_dpu_info = dpu_info; + } + + dpu_info->dev = dev; + + dpu_info->cursors[0].size = MDFLD_CURSOR_SIZE; + dpu_info->cursors[1].size = MDFLD_CURSOR_SIZE; + + /*init dpu_update_lock*/ + spin_lock_init(&dpu_info->dpu_update_lock); + + /*init dpu refresh timer*/ + mdfld_dbi_dpu_timer_init(dev, dpu_info); + + /*init pipe damage area*/ + mdfld_dpu_init_damage(dpu_info, 0); + mdfld_dpu_init_damage(dpu_info, 2); + + return 0; +} + +void mdfld_dbi_dpu_exit(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info; + + if (!dpu_info) + return; + + del_timer_sync(&dpu_info->dpu_timer); + kfree(dpu_info); + dev_priv->dbi_dpu_info = NULL; +} + + diff --git a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h new file mode 100644 index 000000000000..42367ed48c08 --- /dev/null +++ b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h @@ -0,0 +1,154 @@ +/* + * Copyright © 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: + * jim liu + * Jackie Li + */ + +#ifndef __MDFLD_DSI_DBI_DPU_H__ +#define __MDFLD_DSI_DBI_DPU_H__ + +#include "mdfld_dsi_dbi.h" + +typedef enum { + MDFLD_PLANEA, + MDFLD_PLANEC, + MDFLD_CURSORA, + MDFLD_CURSORC, + MDFLD_OVERLAYA, + MDFLD_OVERLAYC, + MDFLD_PLANE_NUM, +} mdfld_plane_t; + +#define MDFLD_PIPEA_PLANE_MASK 0x15 +#define MDFLD_PIPEC_PLANE_MASK 0x2A + +struct mdfld_cursor_info { + int x, y; + int size; +}; + +#define MDFLD_CURSOR_SIZE 64 + +/* + * enter DSR mode if screen has no update for 2 frames. + */ +#define MDFLD_MAX_IDLE_COUNT 2 + +struct mdfld_dbi_dpu_info { + struct drm_device *dev; + /* Lock */ + spinlock_t dpu_update_lock; + + /* Cursor postion */ + struct mdfld_cursor_info cursors[2]; + + /* Damaged area for each plane */ + struct psb_drm_dpu_rect damaged_rects[MDFLD_PLANE_NUM]; + + /* Final damaged area */ + struct psb_drm_dpu_rect damage_pipea; + struct psb_drm_dpu_rect damage_pipec; + + /* Pending */ + u32 pending; + + /* DPU timer */ + struct timer_list dpu_timer; + spinlock_t dpu_timer_lock; + + /* DPU idle count */ + u32 idle_count; + + /* DSI outputs */ + struct mdfld_dsi_dbi_output *dbi_outputs[2]; + int dbi_output_num; +}; + +static inline int mdfld_dpu_region_extent(struct psb_drm_dpu_rect *origin, + struct psb_drm_dpu_rect *rect) +{ + int x1, y1, x2, y2; + + x1 = origin->x + origin->width; + y1 = origin->y + origin->height; + + x2 = rect->x + rect->width; + y2 = rect->y + rect->height; + + origin->x = min(origin->x, rect->x); + origin->y = min(origin->y, rect->y); + origin->width = max(x1, x2) - origin->x; + origin->height = max(y1, y2) - origin->y; + + return 0; +} + +static inline void mdfld_check_boundary(struct mdfld_dbi_dpu_info *dpu_info, + struct psb_drm_dpu_rect *rect) +{ + if (rect->x < 0) + rect->x = 0; + if (rect->y < 0) + rect->y = 0; + + if (rect->x + rect->width > 864) + rect->width = 864 - rect->x; + if (rect->y + rect->height > 480) + rect->height = 480 - rect->height; + + if (!rect->width) + rect->width = 1; + if (!rect->height) + rect->height = 1; +} + +static inline void mdfld_dpu_init_damage(struct mdfld_dbi_dpu_info *dpu_info, + int pipe) +{ + struct psb_drm_dpu_rect *rect; + + if (pipe == 0) + rect = &dpu_info->damage_pipea; + else + rect = &dpu_info->damage_pipec; + + rect->x = 864; + rect->y = 480; + rect->width = -864; + rect->height = -480; +} + +extern int mdfld_dsi_dbi_dsr_off(struct drm_device *dev, + struct psb_drm_dpu_rect *rect); +extern int mdfld_dbi_dpu_report_damage(struct drm_device *dev, + mdfld_plane_t plane, + struct psb_drm_dpu_rect *rect); +extern int mdfld_dbi_dpu_report_fullscreen_damage(struct drm_device *dev); +extern int mdfld_dpu_exit_dsr(struct drm_device *dev); +extern void mdfld_dbi_dpu_timer_start(struct mdfld_dbi_dpu_info *dpu_info); +extern int mdfld_dbi_dpu_init(struct drm_device *dev); +extern void mdfld_dbi_dpu_exit(struct drm_device *dev); +extern void mdfld_dpu_update_panel(struct drm_device *dev); + +#endif /*__MDFLD_DSI_DBI_DPU_H__*/ diff --git a/drivers/staging/gma500/mdfld_dsi_dpi.c b/drivers/staging/gma500/mdfld_dsi_dpi.c new file mode 100644 index 000000000000..6e03a91e947e --- /dev/null +++ b/drivers/staging/gma500/mdfld_dsi_dpi.c @@ -0,0 +1,800 @@ +/* + * Copyright © 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: + * jim liu + * Jackie Li + */ + +#include "mdfld_dsi_dpi.h" +#include "mdfld_output.h" +#include "mdfld_dsi_pkg_sender.h" + + +static void mdfld_wait_for_HS_DATA_FIFO(struct drm_device *dev, u32 pipe) +{ + u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG; + int timeout = 0; + + if (pipe == 2) + gen_fifo_stat_reg += MIPIC_REG_OFFSET; + + udelay(500); + + /* This will time out after approximately 2+ seconds */ + while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_DATA_FULL)) { + udelay(100); + timeout++; + } + + if (timeout == 20000) + dev_warn(dev->dev, "MIPI: HS Data FIFO was never cleared!\n"); +} + +static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe) +{ + u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG; + int timeout = 0; + + if (pipe == 2) + gen_fifo_stat_reg += MIPIC_REG_OFFSET; + + udelay(500); + + /* This will time out after approximately 2+ seconds */ + while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_CTRL_FULL)) { + udelay(100); + timeout++; + } + if (timeout == 20000) + dev_warn(dev->dev, "MIPI: HS CMD FIFO was never cleared!\n"); +} + +static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe) +{ + u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG; + int timeout = 0; + + if (pipe == 2) + gen_fifo_stat_reg += MIPIC_REG_OFFSET; + + udelay(500); + + /* This will time out after approximately 2+ seconds */ + while ((timeout < 20000) && ((REG_READ(gen_fifo_stat_reg) & DPI_FIFO_EMPTY) + != DPI_FIFO_EMPTY)) { + udelay(100); + timeout++; + } + + if (timeout == 20000) + dev_warn(dev->dev, "MIPI: DPI FIFO was never cleared!\n"); +} + +static void mdfld_wait_for_SPL_PKG_SENT(struct drm_device *dev, u32 pipe) +{ + u32 intr_stat_reg = MIPIA_INTR_STAT_REG; + int timeout = 0; + + if (pipe == 2) + intr_stat_reg += MIPIC_REG_OFFSET; + + udelay(500); + + /* This will time out after approximately 2+ seconds */ + while ((timeout < 20000) && (!(REG_READ(intr_stat_reg) & DSI_INTR_STATE_SPL_PKG_SENT))) { + udelay(100); + timeout++; + } + + if (timeout == 20000) + dev_warn(dev->dev, "MIPI: SPL_PKT_SENT_INTERRUPT was not sent successfully!\n"); +} + + +/* ************************************************************************* *\ + * FUNCTION: mdfld_dsi_tpo_ic_init + * + * DESCRIPTION: This function is called only by mrst_dsi_mode_set and + * restore_display_registers. since this function does not + * acquire the mutex, it is important that the calling function + * does! +\* ************************************************************************* */ +void mdfld_dsi_tpo_ic_init(struct mdfld_dsi_config *dsi_config, u32 pipe) +{ + struct drm_device *dev = dsi_config->dev; + u32 dcsChannelNumber = dsi_config->channel_num; + u32 gen_data_reg = MIPIA_HS_GEN_DATA_REG; + u32 gen_ctrl_reg = MIPIA_HS_GEN_CTRL_REG; + u32 gen_ctrl_val = GEN_LONG_WRITE; + + if (pipe == 2) { + gen_data_reg = HS_GEN_DATA_REG + MIPIC_REG_OFFSET; + gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET; + } + + gen_ctrl_val |= dcsChannelNumber << DCS_CHANNEL_NUMBER_POS; + + /* Flip page order */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x00008036); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS)); + + /* 0xF0 */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x005a5af0); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); + + /* Write protection key */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x005a5af1); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); + + /* 0xFC */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x005a5afc); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); + + /* 0xB7 */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x770000b7); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x00000044); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x05 << WORD_COUNTS_POS)); + + /* 0xB6 */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x000a0ab6); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); + + /* 0xF2 */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x081010f2); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x4a070708); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x000000c5); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS)); + + /* 0xF8 */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x024003f8); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x01030a04); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x0e020220); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x00000004); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x0d << WORD_COUNTS_POS)); + + /* 0xE2 */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x398fc3e2); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x0000916f); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x06 << WORD_COUNTS_POS)); + + /* 0xB0 */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x000000b0); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS)); + + /* 0xF4 */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x240242f4); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x78ee2002); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x2a071050); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x507fee10); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x10300710); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x14 << WORD_COUNTS_POS)); + + /* 0xBA */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x19fe07ba); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x101c0a31); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x00000010); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS)); + + /* 0xBB */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x28ff07bb); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x24280a31); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x00000034); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS)); + + /* 0xFB */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x535d05fb); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x1b1a2130); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x221e180e); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x131d2120); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x535d0508); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x1c1a2131); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x231f160d); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x111b2220); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x535c2008); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x1f1d2433); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x2c251a10); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x2c34372d); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x00000023); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS)); + + /* 0xFA */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x525c0bfa); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x1c1c232f); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x2623190e); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x18212625); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x545d0d0e); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x1e1d2333); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x26231a10); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x1a222725); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x545d280f); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x21202635); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x31292013); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x31393d33); + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x00000029); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS)); + + /* Set DM */ + mdfld_wait_for_HS_DATA_FIFO(dev, pipe); + REG_WRITE(gen_data_reg, 0x000100f7); + mdfld_wait_for_HS_CTRL_FIFO(dev, pipe); + REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS)); +} + +static u16 mdfld_dsi_dpi_to_byte_clock_count(int pixel_clock_count, + int num_lane, int bpp) +{ + return (u16)((pixel_clock_count * bpp) / (num_lane * 8)); +} + +/* + * Calculate the dpi time basing on a given drm mode @mode + * return 0 on success. + * FIXME: I was using proposed mode value for calculation, may need to + * use crtc mode values later + */ +int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode, + struct mdfld_dsi_dpi_timing *dpi_timing, + int num_lane, int bpp) +{ + int pclk_hsync, pclk_hfp, pclk_hbp, pclk_hactive; + int pclk_vsync, pclk_vfp, pclk_vbp, pclk_vactive; + + if(!mode || !dpi_timing) { + DRM_ERROR("Invalid parameter\n"); + return -EINVAL; + } + + pclk_hactive = mode->hdisplay; + pclk_hfp = mode->hsync_start - mode->hdisplay; + pclk_hsync = mode->hsync_end - mode->hsync_start; + pclk_hbp = mode->htotal - mode->hsync_end; + + pclk_vactive = mode->vdisplay; + pclk_vfp = mode->vsync_start - mode->vdisplay; + pclk_vsync = mode->vsync_end - mode->vsync_start; + pclk_vbp = mode->vtotal - mode->vsync_end; + + /* + * byte clock counts were calculated by following formula + * bclock_count = pclk_count * bpp / num_lane / 8 + */ + dpi_timing->hsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hsync, num_lane, bpp); + dpi_timing->hbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hbp, num_lane, bpp); + dpi_timing->hfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hfp, num_lane, bpp); + dpi_timing->hactive_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hactive, num_lane, bpp); + dpi_timing->vsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vsync, num_lane, bpp); + dpi_timing->vbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vbp, num_lane, bpp); + dpi_timing->vfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vfp, num_lane, bpp); + + return 0; +} + +void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config, int pipe) +{ + struct drm_device *dev = dsi_config->dev; + u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0; + int lane_count = dsi_config->lane_count; + struct mdfld_dsi_dpi_timing dpi_timing; + struct drm_display_mode *mode = dsi_config->mode; + u32 val = 0; + + /*un-ready device*/ + REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000); + + /*init dsi adapter before kicking off*/ + REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018); + + /*enable all interrupts*/ + REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff); + + + /*set up func_prg*/ + val |= lane_count; + val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET; + + switch(dsi_config->bpp) { + case 16: + val |= DSI_DPI_COLOR_FORMAT_RGB565; + break; + case 18: + val |= DSI_DPI_COLOR_FORMAT_RGB666; + break; + case 24: + val |= DSI_DPI_COLOR_FORMAT_RGB888; + break; + default: + DRM_ERROR("unsupported color format, bpp = %d\n", dsi_config->bpp); + } + REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val); + + REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), + (mode->vtotal * mode->htotal * dsi_config->bpp / (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK); + REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff & DSI_LP_RX_TIMEOUT_MASK); + + /*max value: 20 clock cycles of txclkesc*/ + REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK); + + /*min 21 txclkesc, max: ffffh*/ + REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0xffff & DSI_RESET_TIMER_MASK); + + REG_WRITE((MIPIA_DPI_RESOLUTION_REG + reg_offset), mode->vdisplay << 16 | mode->hdisplay); + + /*set DPI timing registers*/ + mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp); + + REG_WRITE((MIPIA_HSYNC_COUNT_REG + reg_offset), dpi_timing.hsync_count & DSI_DPI_TIMING_MASK); + REG_WRITE((MIPIA_HBP_COUNT_REG + reg_offset), dpi_timing.hbp_count & DSI_DPI_TIMING_MASK); + REG_WRITE((MIPIA_HFP_COUNT_REG + reg_offset), dpi_timing.hfp_count & DSI_DPI_TIMING_MASK); + REG_WRITE((MIPIA_HACTIVE_COUNT_REG + reg_offset), dpi_timing.hactive_count & DSI_DPI_TIMING_MASK); + REG_WRITE((MIPIA_VSYNC_COUNT_REG + reg_offset), dpi_timing.vsync_count & DSI_DPI_TIMING_MASK); + REG_WRITE((MIPIA_VBP_COUNT_REG + reg_offset), dpi_timing.vbp_count & DSI_DPI_TIMING_MASK); + REG_WRITE((MIPIA_VFP_COUNT_REG + reg_offset), dpi_timing.vfp_count & DSI_DPI_TIMING_MASK); + + REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46); + + /*min: 7d0 max: 4e20*/ + REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x000007d0); + + /*set up video mode*/ + val = 0; + val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE; + REG_WRITE((MIPIA_VIDEO_MODE_FORMAT_REG + reg_offset), val); + + REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000); + + REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004); + + /*TODO: figure out how to setup these registers*/ + REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408); + + REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), (0xa << 16) | 0x14); + /*set device ready*/ + REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001); +} + +void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, int pipe) +{ + struct drm_device *dev = output->dev; + u32 reg_offset = 0; + + if(output->panel_on) + return; + + if(pipe) + reg_offset = MIPIC_REG_OFFSET; + + /* clear special packet sent bit */ + if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) { + REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT); + } + + /*send turn on package*/ + REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON); + + /*wait for SPL_PKG_SENT interrupt*/ + mdfld_wait_for_SPL_PKG_SENT(dev, pipe); + + if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) { + REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT); + } + + output->panel_on = 1; + + /* FIXME the following is disabled to WA the X slow start issue for TMD panel */ + /* if(pipe == 2) */ + /* dev_priv->dpi_panel_on2 = true; */ + /* else if (pipe == 0) */ + /* dev_priv->dpi_panel_on = true; */ +} + +static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output, int pipe) +{ + struct drm_device *dev = output->dev; + u32 reg_offset = 0; + + /*if output is on, or mode setting didn't happen, ignore this*/ + if((!output->panel_on) || output->first_boot) { + output->first_boot = 0; + return; + } + + if(pipe) + reg_offset = MIPIC_REG_OFFSET; + + /* Wait for dpi fifo to empty */ + mdfld_wait_for_DPI_CTRL_FIFO(dev, pipe); + + /* Clear the special packet interrupt bit if set */ + if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) { + REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT); + } + + if(REG_READ(MIPIA_DPI_CONTROL_REG + reg_offset) == DSI_DPI_CTRL_HS_SHUTDOWN) { + dev_warn(dev->dev, "try to send the same package again, abort!"); + goto shutdown_out; + } + + REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN); + +shutdown_out: + output->panel_on = 0; + output->first_boot = 0; + + /* FIXME the following is disabled to WA the X slow start issue for TMD panel */ + /* if(pipe == 2) */ + /* dev_priv->dpi_panel_on2 = false; */ + /* else if (pipe == 0) */ + /* dev_priv->dpi_panel_on = false; */ + /* #ifdef CONFIG_PM_RUNTIME*/ + /* if (drm_psb_ospm && !enable_gfx_rtpm) { */ + /* pm_runtime_allow(&gpDrmDevice->pdev->dev); */ + /* schedule_delayed_work(&dev_priv->rtpm_work, 30 * 1000); */ + /* } */ + /*if (enable_gfx_rtpm) */ + /* pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */ + /* #endif */ +} + +void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on) +{ + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); + struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); + int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); + struct drm_device *dev = dsi_config->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + u32 mipi_reg = MIPI; + u32 pipeconf_reg = PIPEACONF; + + if(pipe) { + mipi_reg = MIPI_C; + pipeconf_reg = PIPECCONF; + } + + /* Start up display island if it was shutdown */ + if (!gma_power_begin(dev, true)) + return; + + if(on) { + if (mdfld_get_panel_type(dev, pipe) == TMD_VID){ + mdfld_dsi_dpi_turn_on(dpi_output, pipe); + } else { + /* Enable mipi port */ + REG_WRITE(mipi_reg, (REG_READ(mipi_reg) | (1 << 31))); + REG_READ(mipi_reg); + + mdfld_dsi_dpi_turn_on(dpi_output, pipe); + mdfld_dsi_tpo_ic_init(dsi_config, pipe); + } + + if(pipe == 2) { + dev_priv->dpi_panel_on2 = true; + } + else { + dev_priv->dpi_panel_on = true; + } + + } else { + if (mdfld_get_panel_type(dev, pipe) == TMD_VID) { + mdfld_dsi_dpi_shut_down(dpi_output, pipe); + } else { + mdfld_dsi_dpi_shut_down(dpi_output, pipe); + /* Disable mipi port */ + REG_WRITE(mipi_reg, (REG_READ(mipi_reg) & ~(1<<31))); + REG_READ(mipi_reg); + } + + if(pipe == 2) + dev_priv->dpi_panel_on2 = false; + else + dev_priv->dpi_panel_on = false; + } + gma_power_end(dev); +} + +void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode) +{ + dev_dbg(encoder->dev->dev, "DPMS %s\n", + (mode == DRM_MODE_DPMS_ON ? "on":"off")); + + if (mode == DRM_MODE_DPMS_ON) + mdfld_dsi_dpi_set_power(encoder, true); + else { + mdfld_dsi_dpi_set_power(encoder, false); +#if 0 /* FIXME */ +#ifdef CONFIG_PM_RUNTIME + if (enable_gfx_rtpm) + pm_schedule_suspend(&gpDrmDevice->pdev->dev, gfxrtdelay); +#endif +#endif + } +} + +bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); + struct drm_display_mode *fixed_mode = dsi_config->fixed_mode; + + if(fixed_mode) { + adjusted_mode->hdisplay = fixed_mode->hdisplay; + adjusted_mode->hsync_start = fixed_mode->hsync_start; + adjusted_mode->hsync_end = fixed_mode->hsync_end; + adjusted_mode->htotal = fixed_mode->htotal; + adjusted_mode->vdisplay = fixed_mode->vdisplay; + adjusted_mode->vsync_start = fixed_mode->vsync_start; + adjusted_mode->vsync_end = fixed_mode->vsync_end; + adjusted_mode->vtotal = fixed_mode->vtotal; + adjusted_mode->clock = fixed_mode->clock; + drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); + } + + return true; +} + +void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder) +{ + mdfld_dsi_dpi_set_power(encoder, false); +} + +void mdfld_dsi_dpi_commit(struct drm_encoder *encoder) +{ + mdfld_dsi_dpi_set_power(encoder, true); +} + +void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder); + struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder); + struct drm_device *dev = dsi_config->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder); + + u32 pipeconf_reg = PIPEACONF; + u32 dspcntr_reg = DSPACNTR; + u32 mipi_reg = MIPI; + u32 reg_offset = 0; + + u32 pipeconf = dev_priv->pipeconf; + u32 dspcntr = dev_priv->dspcntr; + u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; + + dev_dbg(dev->dev, "set mode %dx%d on pipe %d\n", + mode->hdisplay, mode->vdisplay, pipe); + + if(pipe) { + pipeconf_reg = PIPECCONF; + dspcntr_reg = DSPCCNTR; + mipi_reg = MIPI_C; + reg_offset = MIPIC_REG_OFFSET; + } else { + mipi |= 2; + } + + if (!gma_power_begin(dev, true)) + return; + + /* Set up mipi port FIXME: do at init time */ + REG_WRITE(mipi_reg, mipi); + REG_READ(mipi_reg); + + /* Set up DSI controller DPI interface */ + mdfld_dsi_dpi_controller_init(dsi_config, pipe); + + if (mdfld_get_panel_type(dev, pipe) != TMD_VID) { + /* Turn on DPI interface */ + mdfld_dsi_dpi_turn_on(dpi_output, pipe); + } + + /* Set up pipe */ + REG_WRITE(pipeconf_reg, pipeconf); + REG_READ(pipeconf_reg); + + /* Set up display plane */ + REG_WRITE(dspcntr_reg, dspcntr); + REG_READ(dspcntr_reg); + + msleep(20); /* FIXME: this should wait for vblank */ + + dev_dbg(dev->dev, "State %x, power %d\n", + REG_READ(MIPIA_INTR_STAT_REG + reg_offset), + dpi_output->panel_on); + + if (mdfld_get_panel_type(dev, pipe) != TMD_VID) { + /* Init driver ic */ + mdfld_dsi_tpo_ic_init(dsi_config, pipe); + /* Init backlight */ + mdfld_dsi_brightness_init(dsi_config, pipe); + } + gma_power_end(dev); +} + + +/* + * Init DSI DPI encoder. + * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector + * return pointer of newly allocated DPI encoder, NULL on error + */ +struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, + struct mdfld_dsi_connector *dsi_connector, + struct panel_funcs *p_funcs) +{ + struct mdfld_dsi_dpi_output *dpi_output = NULL; + struct mdfld_dsi_config *dsi_config; + struct drm_connector *connector = NULL; + struct drm_encoder *encoder = NULL; + struct drm_display_mode *fixed_mode = NULL; + int pipe; + u32 data; + int ret; + + if (!dsi_connector || !p_funcs) { + WARN_ON(1); + return NULL; + } + + dsi_config = mdfld_dsi_get_config(dsi_connector); + pipe = dsi_connector->pipe; + + /* Panel hard-reset */ + if (p_funcs->reset) { + ret = p_funcs->reset(pipe); + if (ret) { + DRM_ERROR("Panel %d hard-reset failed\n", pipe); + return NULL; + } + } + + /* Panel drvIC init */ + if (p_funcs->drv_ic_init) + p_funcs->drv_ic_init(dsi_config, pipe); + + /* Panel power mode detect */ + ret = mdfld_dsi_get_power_mode(dsi_config, + &data, + MDFLD_DSI_LP_TRANSMISSION); + if (ret) { + DRM_ERROR("Panel %d get power mode failed\n", pipe); + dsi_connector->status = connector_status_disconnected; + } else { + DRM_INFO("pipe %d power mode 0x%x\n", pipe, data); + dsi_connector->status = connector_status_connected; + } + + dpi_output = kzalloc(sizeof(struct mdfld_dsi_dpi_output), GFP_KERNEL); + if(!dpi_output) { + dev_err(dev->dev, "No memory for dsi_dpi_output\n"); + return NULL; + } + + if(dsi_connector->pipe) + dpi_output->panel_on = 0; + else + dpi_output->panel_on = 0; + + dpi_output->dev = dev; + dpi_output->p_funcs = p_funcs; + dpi_output->first_boot = 1; + + /* Get fixed mode */ + dsi_config = mdfld_dsi_get_config(dsi_connector); + fixed_mode = dsi_config->fixed_mode; + + /* Create drm encoder object */ + connector = &dsi_connector->base.base; + encoder = &dpi_output->base.base; + drm_encoder_init(dev, + encoder, + p_funcs->encoder_funcs, + DRM_MODE_ENCODER_MIPI); + drm_encoder_helper_add(encoder, + p_funcs->encoder_helper_funcs); + + /* Attach to given connector */ + drm_mode_connector_attach_encoder(connector, encoder); + + /* Set possible crtcs and clones */ + if(dsi_connector->pipe) { + encoder->possible_crtcs = (1 << 2); + encoder->possible_clones = (1 << 1); + } else { + encoder->possible_crtcs = (1 << 0); + encoder->possible_clones = (1 << 0); + } + return &dpi_output->base; +} + diff --git a/drivers/staging/gma500/mdfld_dsi_dpi.h b/drivers/staging/gma500/mdfld_dsi_dpi.h new file mode 100644 index 000000000000..ed92d45ee74a --- /dev/null +++ b/drivers/staging/gma500/mdfld_dsi_dpi.h @@ -0,0 +1,78 @@ +/* + * Copyright © 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: + * jim liu + * Jackie Li + */ + +#ifndef __MDFLD_DSI_DPI_H__ +#define __MDFLD_DSI_DPI_H__ + +#include "mdfld_dsi_output.h" +#include "mdfld_output.h" + +struct mdfld_dsi_dpi_timing { + u16 hsync_count; + u16 hbp_count; + u16 hfp_count; + u16 hactive_count; + u16 vsync_count; + u16 vbp_count; + u16 vfp_count; +}; + +struct mdfld_dsi_dpi_output { + struct mdfld_dsi_encoder base; + struct drm_device *dev; + + int panel_on; + int first_boot; + + struct panel_funcs *p_funcs; +}; + +#define MDFLD_DSI_DPI_OUTPUT(dsi_encoder) \ + container_of(dsi_encoder, struct mdfld_dsi_dpi_output, base) + +extern int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode, + struct mdfld_dsi_dpi_timing *dpi_timing, + int num_lane, int bpp); +extern struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, + struct mdfld_dsi_connector *dsi_connector, + struct panel_funcs *p_funcs); + +/* Medfield DPI helper functions */ +extern void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode); +extern bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); +extern void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder); +extern void mdfld_dsi_dpi_commit(struct drm_encoder *encoder); +extern void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); +extern void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, + int pipe); +extern void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *si_config, + int pipe); +#endif /*__MDFLD_DSI_DPI_H__*/ diff --git a/drivers/staging/gma500/mdfld_dsi_output.c b/drivers/staging/gma500/mdfld_dsi_output.c new file mode 100644 index 000000000000..7536095c30a0 --- /dev/null +++ b/drivers/staging/gma500/mdfld_dsi_output.c @@ -0,0 +1,1011 @@ +/* + * Copyright © 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: + * jim liu + * Jackie Li + */ + +#include "mdfld_dsi_output.h" +#include "mdfld_dsi_dbi.h" +#include "mdfld_dsi_dpi.h" +#include "mdfld_output.h" +#include +#include "mdfld_dsi_pkg_sender.h" +#include + +#define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100 + +static int CABC_control = 1; +static int LABC_control = 1; + +module_param (CABC_control, int, 0644); +module_param (LABC_control, int, 0644); + +/** + * make these MCS command global + * we don't need 'movl' everytime we send them. + * FIXME: these datas were provided by OEM, we should get them from GCT. + **/ +static u32 mdfld_dbi_mcs_hysteresis[] = { + 0x42000f57, 0x8c006400, 0xff00bf00, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x38000aff, 0x82005000, 0xff00ab00, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0x000000ff, +}; + +static u32 mdfld_dbi_mcs_display_profile[] = { + 0x50281450, 0x0000c882, 0x00000000, 0x00000000, + 0x00000000, +}; + +static u32 mdfld_dbi_mcs_kbbc_profile[] = { + 0x00ffcc60, 0x00000000, 0x00000000, 0x00000000, +}; + +static u32 mdfld_dbi_mcs_gamma_profile[] = { + 0x81111158, 0x88888888, 0x88888888, +}; + +/* + * write hysteresis values. + */ +static void mdfld_dsi_write_hysteresis (struct mdfld_dsi_config *dsi_config, + int pipe) +{ + struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config); + + if(!sender) { + WARN_ON(1); + return; + } + mdfld_dsi_send_mcs_long_hs(sender, + mdfld_dbi_mcs_hysteresis, + 17, + MDFLD_DSI_SEND_PACKAGE); +} + +/* + * write display profile values. + */ +static void mdfld_dsi_write_display_profile(struct mdfld_dsi_config *dsi_config, int pipe) +{ + struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config); + + if(!sender) { + WARN_ON(1); + return; + } + mdfld_dsi_send_mcs_long_hs(sender, + mdfld_dbi_mcs_display_profile, + 5, + MDFLD_DSI_SEND_PACKAGE); +} + +/* + * write KBBC profile values. + */ +static void mdfld_dsi_write_kbbc_profile (struct mdfld_dsi_config * dsi_config, int pipe) +{ + struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config); + + if(!sender) { + WARN_ON(1); + return; + } + mdfld_dsi_send_mcs_long_hs(sender, + mdfld_dbi_mcs_kbbc_profile, + 4, + MDFLD_DSI_SEND_PACKAGE); +} + +/* + * write gamma setting. + */ +static void mdfld_dsi_write_gamma_setting (struct mdfld_dsi_config *dsi_config, int pipe) +{ + struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config); + + if(!sender) { + WARN_ON(1); + return; + } + mdfld_dsi_send_mcs_long_hs(sender, + mdfld_dbi_mcs_gamma_profile, + 3, + MDFLD_DSI_SEND_PACKAGE); +} + +/* + * Check and see if the generic control or data buffer is empty and ready. + */ +void mdfld_dsi_gen_fifo_ready (struct drm_device *dev, u32 gen_fifo_stat_reg, u32 fifo_stat) +{ + u32 GEN_BF_time_out_count = 0; + + /* Check MIPI Adatper command registers */ + for (GEN_BF_time_out_count = 0; GEN_BF_time_out_count < GEN_FB_TIME_OUT; GEN_BF_time_out_count++) + { + if ((REG_READ(gen_fifo_stat_reg) & fifo_stat) == fifo_stat) + break; + udelay (100); + } + + if (GEN_BF_time_out_count == GEN_FB_TIME_OUT) + dev_err(dev->dev, + "mdfld_dsi_gen_fifo_ready, Timeout. gen_fifo_stat_reg = 0x%x. \n", + gen_fifo_stat_reg); +} + +/* + * Manage the DSI MIPI keyboard and display brightness. + * FIXME: this is exported to OSPM code. should work out an specific + * display interface to OSPM. + */ +void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, int pipe) +{ + struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config); + struct drm_device *dev = sender->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + u32 gen_ctrl_val; + + if(!sender) { + WARN_ON(1); + return; + } + /* Set default display backlight value to 85% (0xd8)*/ + mdfld_dsi_send_mcs_short_hs(sender, + write_display_brightness, + 0xd8, + 1, + MDFLD_DSI_SEND_PACKAGE); + + /* Set minimum brightness setting of CABC function to 20% (0x33)*/ + mdfld_dsi_send_mcs_short_hs(sender, + write_cabc_min_bright, + 0x33, + 1, + MDFLD_DSI_SEND_PACKAGE); + + mdfld_dsi_write_hysteresis(dsi_config, pipe); + mdfld_dsi_write_display_profile (dsi_config, pipe); + mdfld_dsi_write_kbbc_profile (dsi_config, pipe); + mdfld_dsi_write_gamma_setting (dsi_config, pipe); + + /* Enable backlight or/and LABC */ + gen_ctrl_val = BRIGHT_CNTL_BLOCK_ON | DISPLAY_DIMMING_ON| BACKLIGHT_ON; + if (LABC_control == 1 || CABC_control == 1) + gen_ctrl_val |= DISPLAY_DIMMING_ON| DISPLAY_BRIGHTNESS_AUTO | GAMMA_AUTO; + + if (LABC_control == 1) + gen_ctrl_val |= AMBIENT_LIGHT_SENSE_ON; + + dev_priv->mipi_ctrl_display = gen_ctrl_val; + + mdfld_dsi_send_mcs_short_hs(sender, + write_ctrl_display, + (u8)gen_ctrl_val, + 1, + MDFLD_DSI_SEND_PACKAGE); + + if (CABC_control == 0) + return; + mdfld_dsi_send_mcs_short_hs(sender, + write_ctrl_cabc, + UI_IMAGE, + 1, + MDFLD_DSI_SEND_PACKAGE); +} + +/* + * Manage the mipi display brightness. + * TODO: refine this interface later + */ +void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, int level) +{ + struct mdfld_dsi_pkg_sender *sender; + struct drm_psb_private *dev_priv; + struct mdfld_dsi_config *dsi_config; + u32 gen_ctrl_val; + int p_type; + + if (!dev || (pipe != 0 && pipe != 2)) { + dev_err(dev->dev, "Invalid parameter\n"); + return; + } + + p_type = mdfld_get_panel_type(dev, 0); + + dev_priv = dev->dev_private; + + if(pipe) + dsi_config = dev_priv->dsi_configs[1]; + else + dsi_config = dev_priv->dsi_configs[0]; + + sender = mdfld_dsi_get_pkg_sender(dsi_config); + + if(!sender) { + WARN_ON(1); + return; + } + + gen_ctrl_val = ((level * 0xff) / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL) & 0xff; + + dev_dbg(dev->dev, + "pipe = %d, gen_ctrl_val = %d. \n", pipe, gen_ctrl_val); + + if(p_type == TMD_VID || p_type == TMD_CMD){ + /* Set display backlight value */ + mdfld_dsi_send_mcs_short_hs(sender, + tmd_write_display_brightness, + (u8)gen_ctrl_val, + 1, + MDFLD_DSI_SEND_PACKAGE); + } else { + /* Set display backlight value */ + mdfld_dsi_send_mcs_short_hs(sender, + write_display_brightness, + (u8)gen_ctrl_val, + 1, + MDFLD_DSI_SEND_PACKAGE); + + + /* Enable backlight control */ + if (level == 0) + gen_ctrl_val = 0; + else + gen_ctrl_val = dev_priv->mipi_ctrl_display; + + mdfld_dsi_send_mcs_short_hs(sender, + write_ctrl_display, + (u8)gen_ctrl_val, + 1, + MDFLD_DSI_SEND_PACKAGE); + } +} + +/* + * shut down DSI controller + */ +void mdfld_dsi_controller_shutdown(struct mdfld_dsi_config * dsi_config, int pipe) +{ + struct drm_device * dev; + u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0; + int retry = 100; + + if (!dsi_config) { + WARN_ON(1); + return; + } + + dev = dsi_config->dev; + + if (!gma_power_begin(dev, true)) { + dev_err(dev->dev, "hw begin failed\n"); + return; + } + + if(!(REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & DSI_DEVICE_READY)) + goto shutdown_out; + + /* Send shut down package, clean packet send bit first */ + if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) { + REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), + (REG_READ(MIPIA_INTR_STAT_REG + reg_offset) | DSI_INTR_STATE_SPL_PKG_SENT)); + } + + /*send shut down package in HS*/ + REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN); + + + /* + * make sure shut down is sent. + * FIXME: add max retry counter + */ + while(!(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT)) { + retry--; + + if(!retry) { + dev_err(dev->dev, "timeout\n"); + break; + } + } + + /*sleep 1 ms to ensure shutdown finished*/ + msleep(100); + + /*un-ready device*/ + REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), + (REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & ~DSI_DEVICE_READY)); + +shutdown_out: + gma_power_end(dev); +} + +void mdfld_dsi_controller_startup(struct mdfld_dsi_config * dsi_config, int pipe) +{ + struct drm_device * dev; + u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0; + int retry = 100; + + + if (!dsi_config) { + WARN_ON(1); + return; + } + + dev = dsi_config->dev; + dev_dbg(dev->dev, "starting up DSI controller on pipe %d...\n", pipe); + + if (!gma_power_begin(dev, true)) { + dev_err(dev->dev, "hw begin failed\n"); + return; + } + + if((REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & DSI_DEVICE_READY)) + goto startup_out; + + /*if config DPI, turn on DPI interface*/ + if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) { + if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) { + REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT); + } + + REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON); + + /* + * make sure shut down is sent. + * FIXME: add max retry counter + */ + while(!(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT)) { + retry--; + if(!retry) { + dev_err(dev->dev, "timeout\n"); + break; + } + } + + msleep(100); + } + + /*set device ready*/ + REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), + (REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) | DSI_DEVICE_READY)); + +startup_out: + gma_power_end(dev); +} + + +static int mdfld_dsi_get_panel_status(struct mdfld_dsi_config *dsi_config, + u8 dcs, + u32 *data, + u8 transmission) +{ + struct mdfld_dsi_pkg_sender *sender + = mdfld_dsi_get_pkg_sender(dsi_config); + + if (!sender || !data) { + DRM_ERROR("Invalid parameter\n"); + return -EINVAL; + } + + if (transmission == MDFLD_DSI_HS_TRANSMISSION) + return mdfld_dsi_read_mcs_hs(sender, dcs, data, 1); + else if (transmission == MDFLD_DSI_LP_TRANSMISSION) + return mdfld_dsi_read_mcs_lp(sender, dcs, data, 1); + else + return -EINVAL; +} + +int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config, + u32 *mode, + u8 transmission) +{ + if (!dsi_config || !mode) { + DRM_ERROR("Invalid parameter\n"); + return -EINVAL; + } + + return mdfld_dsi_get_panel_status(dsi_config, 0x0a, mode, transmission); +} + +int mdfld_dsi_get_diagnostic_result(struct mdfld_dsi_config *dsi_config, + u32 *result, + u8 transmission) +{ + if (!dsi_config || !result) { + DRM_ERROR("Invalid parameter\n"); + return -EINVAL; + } + + return mdfld_dsi_get_panel_status(dsi_config, 0x0f, result, + transmission); +} + +/* + * NOTE: this function was used by OSPM. + * TODO: will be removed later, should work out display interfaces for OSPM + */ +void mdfld_dsi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe) +{ + if(!dsi_config || ((pipe != 0) && (pipe != 2))) { + WARN_ON(1); + return; + } + + if(dsi_config->type) + mdfld_dsi_dpi_controller_init(dsi_config, pipe); + else + mdfld_dsi_controller_dbi_init(dsi_config, pipe); +} + +static void mdfld_dsi_connector_save(struct drm_connector * connector) +{ +} + +static void mdfld_dsi_connector_restore(struct drm_connector * connector) +{ +} + +static enum drm_connector_status mdfld_dsi_connector_detect(struct drm_connector * connector, bool force) +{ + struct psb_intel_output *psb_output + = to_psb_intel_output(connector); + struct mdfld_dsi_connector *dsi_connector + = MDFLD_DSI_CONNECTOR(psb_output); + return dsi_connector->status; +} + +static int mdfld_dsi_connector_set_property(struct drm_connector *connector, + struct drm_property *property, + uint64_t value) +{ + struct drm_encoder *encoder = connector->encoder; + + if (!strcmp(property->name, "scaling mode") && encoder) { + struct psb_intel_crtc * psb_crtc = to_psb_intel_crtc(encoder->crtc); + bool bTransitionFromToCentered; + uint64_t curValue; + + if (!psb_crtc) + goto set_prop_error; + + switch (value) { + case DRM_MODE_SCALE_FULLSCREEN: + break; + case DRM_MODE_SCALE_NO_SCALE: + break; + case DRM_MODE_SCALE_ASPECT: + break; + default: + goto set_prop_error; + } + + if (drm_connector_property_get_value(connector, property, &curValue)) + goto set_prop_error; + + if (curValue == value) + goto set_prop_done; + + if (drm_connector_property_set_value(connector, property, value)) + goto set_prop_error; + + bTransitionFromToCentered = (curValue == DRM_MODE_SCALE_NO_SCALE) || + (value == DRM_MODE_SCALE_NO_SCALE); + + if (psb_crtc->saved_mode.hdisplay != 0 && + psb_crtc->saved_mode.vdisplay != 0) { + if (bTransitionFromToCentered) { + if (!drm_crtc_helper_set_mode(encoder->crtc, &psb_crtc->saved_mode, + encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb)) + goto set_prop_error; + } else { + struct drm_encoder_helper_funcs *pEncHFuncs = encoder->helper_private; + pEncHFuncs->mode_set(encoder, &psb_crtc->saved_mode, + &psb_crtc->saved_adjusted_mode); + } + } +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + } else if (!strcmp(property->name, "backlight") && encoder) { + struct drm_psb_private *dev_priv = encoder->dev->dev_private; + struct backlight_device *psb_bd = dev_priv->backlight_device; + dev_dbg(encoder->dev->dev, "backlight level = %d\n", (int)value); + if (drm_connector_property_set_value(connector, property, value)) + goto set_prop_error; + else { + dev_dbg(encoder->dev->dev, + "set brightness to %d", (int)value); + if (psb_bd) { + psb_bd->props.brightness = value; + backlight_update_status(psb_bd); + } + } +#endif + } +set_prop_done: + return 0; +set_prop_error: + return -1; +} + +static void mdfld_dsi_connector_destroy(struct drm_connector *connector) +{ + struct psb_intel_output * psb_output = to_psb_intel_output(connector); + struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output); + struct mdfld_dsi_pkg_sender * sender; + + if(!dsi_connector) + return; + + drm_sysfs_connector_remove(connector); + drm_connector_cleanup(connector); + + sender = dsi_connector->pkg_sender; + + mdfld_dsi_pkg_sender_destroy(sender); + + kfree(dsi_connector); +} + +static int mdfld_dsi_connector_get_modes(struct drm_connector * connector) +{ + struct psb_intel_output * psb_output = to_psb_intel_output(connector); + struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output); + struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector); + struct drm_display_mode * fixed_mode = dsi_config->fixed_mode; + struct drm_display_mode * dup_mode = NULL; + struct drm_device * dev = connector->dev; + + connector->display_info.min_vfreq = 0; + connector->display_info.max_vfreq = 200; + connector->display_info.min_hfreq = 0; + connector->display_info.max_hfreq = 200; + + if(fixed_mode) { + dev_dbg(dev->dev, "fixed_mode %dx%d\n", + fixed_mode->hdisplay, fixed_mode->vdisplay); + + dup_mode = drm_mode_duplicate(dev, fixed_mode); + drm_mode_probed_add(connector, dup_mode); + return 1; + } + dev_err(dev->dev, "Didn't get any modes!\n"); + return 0; +} + +static int mdfld_dsi_connector_mode_valid(struct drm_connector * connector, struct drm_display_mode * mode) +{ + struct psb_intel_output * psb_output = to_psb_intel_output(connector); + struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output); + struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector); + struct drm_display_mode * fixed_mode = dsi_config->fixed_mode; + + dev_dbg(connector->dev->dev, "mode %p, fixed mode %p\n", + mode, fixed_mode); + + if(mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + + if(mode->flags & DRM_MODE_FLAG_INTERLACE) + return MODE_NO_INTERLACE; + + /** + * FIXME: current DC has no fitting unit, reject any mode setting request + * will figure out a way to do up-scaling(pannel fitting) later. + **/ + if(fixed_mode) { + if(mode->hdisplay != fixed_mode->hdisplay) + return MODE_PANEL; + + if(mode->vdisplay != fixed_mode->vdisplay) + return MODE_PANEL; + } + dev_dbg(connector->dev->dev, "mode ok\n"); + + return MODE_OK; +} + +static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode) +{ +#ifdef CONFIG_PM_RUNTIME + struct drm_device * dev = connector->dev; + struct drm_psb_private * dev_priv = dev->dev_private; + bool panel_on, panel_on2; +#endif + /* First, execute DPMS */ + drm_helper_connector_dpms(connector, mode); + +#ifdef CONFIG_PM_RUNTIME + if(mdfld_panel_dpi(dev)) { + /* DPI panel */ + panel_on = dev_priv->dpi_panel_on; + panel_on2 = dev_priv->dpi_panel_on2; + } else { + /* DBI panel */ + panel_on = dev_priv->dbi_panel_on; + panel_on2 = dev_priv->dbi_panel_on2; + } + + /* Then check all display panels + monitors status */ + /* Make sure that the Display (B) sub-system status isn't i3 when + * R/W the DC register, otherwise "Fabric error" issue would occur + * during S0i3 state. */ + if(!panel_on && !panel_on2 && !(REG_READ(HDMIB_CONTROL) + & HDMIB_PORT_EN)) { + /* Request rpm idle */ + if(dev_priv->rpm_enabled) + pm_request_idle(&dev->pdev->dev); + } + /* + * if rpm wasn't enabled yet, try to allow it + * FIXME: won't enable rpm for DPI since DPI + * CRTC setting is a little messy now. + * Enable it later! + */ +#if 0 + if(!dev_priv->rpm_enabled && !mdfld_panel_dpi(dev)) + ospm_runtime_pm_allow(dev); +#endif +#endif +} + +static struct drm_encoder *mdfld_dsi_connector_best_encoder( + struct drm_connector *connector) +{ + struct psb_intel_output * psb_output = to_psb_intel_output(connector); + struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output); + struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector); + struct mdfld_dsi_encoder * encoder = NULL; + + if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) + encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DBI]; + else if (dsi_config->type == MDFLD_DSI_ENCODER_DPI) + encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DPI]; + + dev_dbg(connector->dev->dev, "get encoder %p\n", encoder); + + if(!encoder) { + dev_err(connector->dev->dev, + "Invalid encoder for type %d\n", dsi_config->type); + return NULL; + } + dsi_config->encoder = encoder; + return &encoder->base; +} + +/* DSI connector funcs */ +static const struct drm_connector_funcs mdfld_dsi_connector_funcs = { + .dpms = /*drm_helper_connector_dpms*/mdfld_dsi_connector_dpms, + .save = mdfld_dsi_connector_save, + .restore = mdfld_dsi_connector_restore, + .detect = mdfld_dsi_connector_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .set_property = mdfld_dsi_connector_set_property, + .destroy = mdfld_dsi_connector_destroy, +}; + +/* DSI connector helper funcs */ +static const struct drm_connector_helper_funcs mdfld_dsi_connector_helper_funcs = { + .get_modes = mdfld_dsi_connector_get_modes, + .mode_valid = mdfld_dsi_connector_mode_valid, + .best_encoder = mdfld_dsi_connector_best_encoder, +}; + +static int mdfld_dsi_get_default_config(struct drm_device * dev, + struct mdfld_dsi_config * config, int pipe) +{ + if(!dev || !config) { + WARN_ON(1); + return -EINVAL; + } + + config->bpp = 24; + config->type = mdfld_panel_dpi(dev); + config->lane_count = 2; + config->channel_num = 0; + /*NOTE: video mode is ignored when type is MDFLD_DSI_ENCODER_DBI*/ + if (mdfld_get_panel_type(dev, pipe) == TMD_VID) { + config->video_mode = MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE; + } else { + config->video_mode = MDFLD_DSI_VIDEO_BURST_MODE; + } + + return 0; +} + +/* + * Returns the panel fixed mode from configuration. + */ +struct drm_display_mode * +mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config * dsi_config, int pipe) +{ + struct drm_device *dev = dsi_config->dev; + struct drm_display_mode *mode; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_timing_info *ti = &dev_priv->gct_data.DTD; + bool use_gct = false; + + mode = kzalloc(sizeof(*mode), GFP_KERNEL); + if (!mode) { + dev_err(dev->dev, "Out of memory for mode\n"); + return NULL; + } + if (use_gct) { + dev_dbg(dev->dev, "gct find MIPI panel.\n"); + + mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; + mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; + mode->hsync_start = mode->hdisplay + \ + ((ti->hsync_offset_hi << 8) | \ + ti->hsync_offset_lo); + mode->hsync_end = mode->hsync_start + \ + ((ti->hsync_pulse_width_hi << 8) | \ + ti->hsync_pulse_width_lo); + mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \ + ti->hblank_lo); + mode->vsync_start = \ + mode->vdisplay + ((ti->vsync_offset_hi << 8) | \ + ti->vsync_offset_lo); + mode->vsync_end = \ + mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \ + ti->vsync_pulse_width_lo); + mode->vtotal = mode->vdisplay + \ + ((ti->vblank_hi << 8) | ti->vblank_lo); + mode->clock = ti->pixel_clock * 10; + } else { + if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) { + if (mdfld_get_panel_type(dev, pipe) == TMD_VID) { + mode->hdisplay = 480; + mode->vdisplay = 854; + mode->hsync_start = 487; + mode->hsync_end = 490; + mode->htotal = 499; + mode->vsync_start = 861; + mode->vsync_end = 865; + mode->vtotal = 873; + mode->clock = 33264; + } else { + mode->hdisplay = 864; + mode->vdisplay = 480; + mode->hsync_start = 873; + mode->hsync_end = 876; + mode->htotal = 887; + mode->vsync_start = 487; + mode->vsync_end = 490; + mode->vtotal = 499; + mode->clock = 33264; + } + } else if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) { + mode->hdisplay = 864; + mode->vdisplay = 480; + mode->hsync_start = 872; + mode->hsync_end = 876; + mode->htotal = 884; + mode->vsync_start = 482; + mode->vsync_end = 494; + mode->vtotal = 486; + mode->clock = 25777; + + } + } + + drm_mode_set_name(mode); + drm_mode_set_crtcinfo(mode, 0); + + mode->type |= DRM_MODE_TYPE_PREFERRED; + + return mode; +} + +int mdfld_dsi_panel_reset(int pipe) +{ + unsigned gpio; + int ret = 0; + + switch (pipe) { + case 0: + gpio = 128; + break; + case 2: + gpio = 34; + break; + default: + DRM_ERROR("Invalid output\n"); + return -EINVAL; + } + + ret = gpio_request(gpio, "gfx"); + if (ret) { + DRM_ERROR("gpio_rqueset failed\n"); + return ret; + } + + ret = gpio_direction_output(gpio, 1); + if (ret) { + DRM_ERROR("gpio_direction_output failed\n"); + goto gpio_error; + } + + gpio_get_value(128); + +gpio_error: + if (gpio_is_valid(gpio)) + gpio_free(gpio); + + return ret; +} + +/* + * MIPI output init + * @dev drm device + * @pipe pipe number. 0 or 2 + * @config + * + * Do the initialization of a MIPI output, including create DRM mode objects + * initialization of DSI output on @pipe + */ +void mdfld_dsi_output_init(struct drm_device *dev, + int pipe, + struct mdfld_dsi_config *config, + struct panel_funcs* p_cmd_funcs, + struct panel_funcs* p_vid_funcs) +{ + struct mdfld_dsi_config * dsi_config; + struct mdfld_dsi_connector * dsi_connector; + struct psb_intel_output * psb_output; + struct drm_connector * connector; + struct mdfld_dsi_encoder * encoder; + struct drm_psb_private * dev_priv = dev->dev_private; + struct panel_info dsi_panel_info; + u32 width_mm, height_mm; + + dev_dbg(dev->dev, "init DSI output on pipe %d\n", pipe); + + if(!dev || ((pipe != 0) && (pipe != 2))) { + WARN_ON(1); + return; + } + + /*create a new connetor*/ + dsi_connector = kzalloc(sizeof(struct mdfld_dsi_connector), GFP_KERNEL); + if(!dsi_connector) { + DRM_ERROR("No memory"); + return; + } + + dsi_connector->pipe = pipe; + + /*set DSI config*/ + if(config) { + dsi_config = config; + } else { + dsi_config = kzalloc(sizeof(struct mdfld_dsi_config), GFP_KERNEL); + if(!dsi_config) { + dev_err(dev->dev, + "cannot allocate memory for DSI config\n"); + goto dsi_init_err0; + } + + mdfld_dsi_get_default_config(dev, dsi_config, pipe); + } + + dsi_connector->private = dsi_config; + + dsi_config->changed = 1; + dsi_config->dev = dev; + + /* Init fixed mode basing on DSI config type */ + if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) { + dsi_config->fixed_mode = p_cmd_funcs->get_config_mode(dev); + if(p_cmd_funcs->get_panel_info(dev, pipe, &dsi_panel_info)) + goto dsi_init_err0; + } else if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) { + dsi_config->fixed_mode = p_vid_funcs->get_config_mode(dev); + if(p_vid_funcs->get_panel_info(dev, pipe, &dsi_panel_info)) + goto dsi_init_err0; + } + + width_mm = dsi_panel_info.width_mm; + height_mm = dsi_panel_info.height_mm; + + dsi_config->mode = dsi_config->fixed_mode; + dsi_config->connector = dsi_connector; + + if(!dsi_config->fixed_mode) { + dev_err(dev->dev, "No pannel fixed mode was found\n"); + goto dsi_init_err0; + } + + if(pipe && dev_priv->dsi_configs[0]) { + dsi_config->dvr_ic_inited = 0; + dev_priv->dsi_configs[1] = dsi_config; + } else if(pipe == 0) { + dsi_config->dvr_ic_inited = 1; + dev_priv->dsi_configs[0] = dsi_config; + } else { + dev_err(dev->dev, "Trying to init MIPI1 before MIPI0\n"); + goto dsi_init_err0; + } + + /*init drm connector object*/ + psb_output = &dsi_connector->base; + + psb_output->type = (pipe == 0) ? INTEL_OUTPUT_MIPI : INTEL_OUTPUT_MIPI2; + + connector = &psb_output->base; + drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs, DRM_MODE_CONNECTOR_MIPI); + drm_connector_helper_add(connector, &mdfld_dsi_connector_helper_funcs); + + connector->display_info.subpixel_order = SubPixelHorizontalRGB; + connector->display_info.width_mm = width_mm; + connector->display_info.height_mm = height_mm; + connector->interlace_allowed = false; + connector->doublescan_allowed = false; + + /* Attach properties */ + drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN); + drm_connector_attach_property(connector, dev_priv->backlight_property, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL); + + /* Init DSI package sender on this output */ + if (mdfld_dsi_pkg_sender_init(dsi_connector, pipe)) { + DRM_ERROR("Package Sender initialization failed on pipe %d\n", pipe); + goto dsi_init_err0; + } + + /* Init DBI & DPI encoders */ + if (p_cmd_funcs) { + encoder = mdfld_dsi_dbi_init(dev, dsi_connector, p_cmd_funcs); + if(!encoder) { + dev_err(dev->dev, "Create DBI encoder failed\n"); + goto dsi_init_err1; + } + encoder->private = dsi_config; + dsi_config->encoders[MDFLD_DSI_ENCODER_DBI] = encoder; + } + + if(p_vid_funcs) { + encoder = mdfld_dsi_dpi_init(dev, dsi_connector, p_vid_funcs); + if(!encoder) { + dev_err(dev->dev, "Create DPI encoder failed\n"); + goto dsi_init_err1; + } + encoder->private = dsi_config; + dsi_config->encoders[MDFLD_DSI_ENCODER_DPI] = encoder; + } + + drm_sysfs_connector_add(connector); + return; + + /*TODO: add code to destroy outputs on error*/ +dsi_init_err1: + /*destroy sender*/ + mdfld_dsi_pkg_sender_destroy(dsi_connector->pkg_sender); + + drm_connector_cleanup(connector); + kfree(dsi_config->fixed_mode); + kfree(dsi_config); +dsi_init_err0: + kfree(dsi_connector); +} diff --git a/drivers/staging/gma500/mdfld_dsi_output.h b/drivers/staging/gma500/mdfld_dsi_output.h new file mode 100644 index 000000000000..4699267efd60 --- /dev/null +++ b/drivers/staging/gma500/mdfld_dsi_output.h @@ -0,0 +1,138 @@ +/* + * Copyright © 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: + * jim liu + * Jackie Li + */ + +#ifndef __MDFLD_DSI_OUTPUT_H__ +#define __MDFLD_DSI_OUTPUT_H__ + +#include +#include +#include +#include +#include + +#include "psb_drv.h" +#include "psb_intel_drv.h" +#include "psb_intel_reg.h" +#include "power.h" +#include "mdfld_output.h" + +#include + + +static inline struct mdfld_dsi_config * + mdfld_dsi_get_config(struct mdfld_dsi_connector *connector) +{ + if (!connector) + return NULL; + return (struct mdfld_dsi_config *)connector->private; +} + +static inline void *mdfld_dsi_get_pkg_sender(struct mdfld_dsi_config *config) +{ + struct mdfld_dsi_connector *dsi_connector; + + if (!config) + return NULL; + + dsi_connector = config->connector; + + if (!dsi_connector) + return NULL; + + return dsi_connector->pkg_sender; +} + +static inline struct mdfld_dsi_config * + mdfld_dsi_encoder_get_config(struct mdfld_dsi_encoder *encoder) +{ + if (!encoder) + return NULL; + return (struct mdfld_dsi_config *)encoder->private; +} + +static inline struct mdfld_dsi_connector * + mdfld_dsi_encoder_get_connector(struct mdfld_dsi_encoder *encoder) +{ + struct mdfld_dsi_config *config; + + if (!encoder) + return NULL; + + config = mdfld_dsi_encoder_get_config(encoder); + if (!config) + return NULL; + + return config->connector; +} + +static inline void *mdfld_dsi_encoder_get_pkg_sender( + struct mdfld_dsi_encoder *encoder) +{ + struct mdfld_dsi_config *dsi_config; + + dsi_config = mdfld_dsi_encoder_get_config(encoder); + if (!dsi_config) + return NULL; + + return mdfld_dsi_get_pkg_sender(dsi_config); +} + +static inline int mdfld_dsi_encoder_get_pipe(struct mdfld_dsi_encoder *encoder) +{ + struct mdfld_dsi_connector *connector; + + if (!encoder) + return -1; + + connector = mdfld_dsi_encoder_get_connector(encoder); + if (!connector) + return -1; + + return connector->pipe; +} + +extern void mdfld_dsi_gen_fifo_ready(struct drm_device *dev, + u32 gen_fifo_stat_reg, u32 fifo_stat); +extern void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config, + int pipe); +extern void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, + int level); +extern void mdfld_dsi_output_init(struct drm_device *dev, int pipe, + struct mdfld_dsi_config *config, + struct panel_funcs *p_cmd_funcs, + struct panel_funcs *p_vid_funcs); +extern void mdfld_dsi_controller_init(struct mdfld_dsi_config *dsi_config, + int pipe); +extern int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config, + u32 *mode, + u8 transmission); +extern int mdfld_dsi_get_diagnostic_result(struct mdfld_dsi_config *dsi_config, + u32 *result, + u8 transmission); +extern int mdfld_dsi_panel_reset(int pipe); + +#endif /*__MDFLD_DSI_OUTPUT_H__*/ diff --git a/drivers/staging/gma500/mdfld_dsi_pkg_sender.c b/drivers/staging/gma500/mdfld_dsi_pkg_sender.c new file mode 100644 index 000000000000..9b96a5c9abcd --- /dev/null +++ b/drivers/staging/gma500/mdfld_dsi_pkg_sender.c @@ -0,0 +1,1484 @@ +/* + * Copyright © 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: + * Jackie Li + */ + +#include + +#include "mdfld_dsi_output.h" +#include "mdfld_dsi_pkg_sender.h" +#include "mdfld_dsi_dbi.h" +#include "mdfld_dsi_dpi.h" + +#define MDFLD_DSI_DBI_FIFO_TIMEOUT 100 +#define MDFLD_DSI_MAX_RETURN_PACKET_SIZE 512 +#define MDFLD_DSI_READ_MAX_COUNT 5000 + +static const char * const dsi_errors[] = { + "RX SOT Error", + "RX SOT Sync Error", + "RX EOT Sync Error", + "RX Escape Mode Entry Error", + "RX LP TX Sync Error", + "RX HS Receive Timeout Error", + "RX False Control Error", + "RX ECC Single Bit Error", + "RX ECC Multibit Error", + "RX Checksum Error", + "RX DSI Data Type Not Recognised", + "RX DSI VC ID Invalid", + "TX False Control Error", + "TX ECC Single Bit Error", + "TX ECC Multibit Error", + "TX Checksum Error", + "TX DSI Data Type Not Recognised", + "TX DSI VC ID invalid", + "High Contention", + "Low contention", + "DPI FIFO Under run", + "HS TX Timeout", + "LP RX Timeout", + "Turn Around ACK Timeout", + "ACK With No Error", + "RX Invalid TX Length", + "RX Prot Violation", + "HS Generic Write FIFO Full", + "LP Generic Write FIFO Full", + "Generic Read Data Avail", + "Special Packet Sent", + "Tearing Effect", +}; + +static int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender *sender, + u32 mask) +{ + struct drm_device *dev = sender->dev; + u32 gen_fifo_stat_reg = sender->mipi_gen_fifo_stat_reg; + int retry = 0xffff; + + while (retry--) { + if ((mask & REG_READ(gen_fifo_stat_reg)) == mask) + return 0; + udelay(100); + } + dev_err(dev->dev, "fifo is NOT empty 0x%08x\n", + REG_READ(gen_fifo_stat_reg)); + return -EIO; +} + +static int wait_for_all_fifos_empty(struct mdfld_dsi_pkg_sender *sender) +{ + return wait_for_gen_fifo_empty(sender, (1 << 2) | (1 << 10) | (1 << 18) + | (1 << 26) | (1 << 27) | (1 << 28)); +} + +static int wait_for_lp_fifos_empty(struct mdfld_dsi_pkg_sender *sender) +{ + return wait_for_gen_fifo_empty(sender, (1 << 10) | (1 << 26)); +} + +static int wait_for_hs_fifos_empty(struct mdfld_dsi_pkg_sender *sender) +{ + return wait_for_gen_fifo_empty(sender, (1 << 2) | (1 << 18)); +} + +static int wait_for_dbi_fifo_empty(struct mdfld_dsi_pkg_sender *sender) +{ + return wait_for_gen_fifo_empty(sender, (1 << 27)); +} + +static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask) +{ + u32 intr_stat_reg = sender->mipi_intr_stat_reg; + struct drm_device *dev = sender->dev; + + switch (mask) { + case (1 << 0): + case (1 << 1): + case (1 << 2): + case (1 << 3): + case (1 << 4): + case (1 << 5): + case (1 << 6): + case (1 << 7): + case (1 << 8): + case (1 << 9): + case (1 << 10): + case (1 << 11): + case (1 << 12): + case (1 << 13): + break; + case (1 << 14): + /*wait for all fifo empty*/ + /*wait_for_all_fifos_empty(sender)*/; + break; + case (1 << 15): + break; + case (1 << 16): + break; + case (1 << 17): + break; + case (1 << 18): + case (1 << 19): + /*wait for contention recovery time*/ + /*mdelay(10);*/ + /*wait for all fifo empty*/ + if (0) + wait_for_all_fifos_empty(sender); + break; + case (1 << 20): + break; + case (1 << 21): + /*wait for all fifo empty*/ + /*wait_for_all_fifos_empty(sender);*/ + break; + case (1 << 22): + break; + case (1 << 23): + case (1 << 24): + case (1 << 25): + case (1 << 26): + case (1 << 27): + /* HS Gen fifo full */ + REG_WRITE(intr_stat_reg, mask); + wait_for_hs_fifos_empty(sender); + break; + case (1 << 28): + /* LP Gen fifo full\n */ + REG_WRITE(intr_stat_reg, mask); + wait_for_lp_fifos_empty(sender); + break; + case (1 << 29): + case (1 << 30): + case (1 << 31): + break; + } + + if (mask & REG_READ(intr_stat_reg)) + dev_warn(dev->dev, "Cannot clean interrupt 0x%08x\n", mask); + + return 0; +} + +static int dsi_error_handler(struct mdfld_dsi_pkg_sender *sender) +{ + struct drm_device *dev = sender->dev; + u32 intr_stat_reg = sender->mipi_intr_stat_reg; + u32 mask; + u32 intr_stat; + int i; + int err = 0; + + intr_stat = REG_READ(intr_stat_reg); + + for (i = 0; i < 32; i++) { + mask = (0x00000001UL) << i; + if (intr_stat & mask) { + dev_dbg(dev->dev, "[DSI]: %s\n", dsi_errors[i]); + err = handle_dsi_error(sender, mask); + if (err) + dev_err(dev->dev, "Cannot handle error\n"); + } + } + return err; +} + +static inline int dbi_cmd_sent(struct mdfld_dsi_pkg_sender *sender) +{ + struct drm_device *dev = sender->dev; + u32 retry = 0xffff; + u32 dbi_cmd_addr_reg = sender->mipi_cmd_addr_reg; + + /* Query the command execution status */ + while (retry--) { + if (!(REG_READ(dbi_cmd_addr_reg) & (1 << 0))) + break; + } + + if (!retry) { + dev_err(dev->dev, "Timeout waiting for DBI Command status\n"); + return -EAGAIN; + } + return 0; +} + +/* + * NOTE: this interface is abandoned expect for write_mem_start DCS + * other DCS are sent via generic pkg interfaces + */ +static int send_dcs_pkg(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg) +{ + struct drm_device *dev = sender->dev; + struct mdfld_dsi_dcs_pkg *dcs_pkg = &pkg->pkg.dcs_pkg; + u32 dbi_cmd_len_reg = sender->mipi_cmd_len_reg; + u32 dbi_cmd_addr_reg = sender->mipi_cmd_addr_reg; + u32 cb_phy = sender->dbi_cb_phy; + u32 index = 0; + u8 *cb = (u8 *)sender->dbi_cb_addr; + int i; + int ret; + + if (!sender->dbi_pkg_support) { + dev_err(dev->dev, "Trying to send DCS on a non DBI output, abort!\n"); + return -ENOTSUPP; + } + + /*wait for DBI fifo empty*/ + wait_for_dbi_fifo_empty(sender); + + *(cb + (index++)) = dcs_pkg->cmd; + if (dcs_pkg->param_num) { + for (i = 0; i < dcs_pkg->param_num; i++) + *(cb + (index++)) = *(dcs_pkg->param + i); + } + + REG_WRITE(dbi_cmd_len_reg, (1 + dcs_pkg->param_num)); + REG_WRITE(dbi_cmd_addr_reg, + (cb_phy << CMD_MEM_ADDR_OFFSET) + | (1 << 0) + | ((dcs_pkg->data_src == CMD_DATA_SRC_PIPE) ? (1 << 1) : 0)); + + ret = dbi_cmd_sent(sender); + if (ret) { + dev_err(dev->dev, "command 0x%x not complete\n", dcs_pkg->cmd); + return -EAGAIN; + } + return 0; +} + +static int __send_short_pkg(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg) +{ + struct drm_device *dev = sender->dev; + u32 hs_gen_ctrl_reg = sender->mipi_hs_gen_ctrl_reg; + u32 lp_gen_ctrl_reg = sender->mipi_lp_gen_ctrl_reg; + u32 gen_ctrl_val = 0; + struct mdfld_dsi_gen_short_pkg *short_pkg = &pkg->pkg.short_pkg; + + gen_ctrl_val |= short_pkg->cmd << MCS_COMMANDS_POS; + gen_ctrl_val |= 0 << DCS_CHANNEL_NUMBER_POS; + gen_ctrl_val |= pkg->pkg_type; + gen_ctrl_val |= short_pkg->param << MCS_PARAMETER_POS; + + if (pkg->transmission_type == MDFLD_DSI_HS_TRANSMISSION) { + /* wait for hs fifo empty */ + /* wait_for_hs_fifos_empty(sender); */ + /* Send pkg */ + REG_WRITE(hs_gen_ctrl_reg, gen_ctrl_val); + } else if (pkg->transmission_type == MDFLD_DSI_LP_TRANSMISSION) { + /* wait_for_lp_fifos_empty(sender); */ + /* Send pkg*/ + REG_WRITE(lp_gen_ctrl_reg, gen_ctrl_val); + } else { + dev_err(dev->dev, "Unknown transmission type %d\n", + pkg->transmission_type); + return -EINVAL; + } + + return 0; +} + +static int __send_long_pkg(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg) +{ + struct drm_device *dev = sender->dev; + u32 hs_gen_ctrl_reg = sender->mipi_hs_gen_ctrl_reg; + u32 hs_gen_data_reg = sender->mipi_hs_gen_data_reg; + u32 lp_gen_ctrl_reg = sender->mipi_lp_gen_ctrl_reg; + u32 lp_gen_data_reg = sender->mipi_lp_gen_data_reg; + u32 gen_ctrl_val = 0; + u32 *dp; + int i; + struct mdfld_dsi_gen_long_pkg *long_pkg = &pkg->pkg.long_pkg; + + dp = long_pkg->data; + + /* + * Set up word count for long pkg + * FIXME: double check word count field. + * currently, using the byte counts of the payload as the word count. + * ------------------------------------------------------------ + * | DI | WC | ECC| PAYLOAD |CHECKSUM| + * ------------------------------------------------------------ + */ + gen_ctrl_val |= (long_pkg->len << 2) << WORD_COUNTS_POS; + gen_ctrl_val |= 0 << DCS_CHANNEL_NUMBER_POS; + gen_ctrl_val |= pkg->pkg_type; + + if (pkg->transmission_type == MDFLD_DSI_HS_TRANSMISSION) { + /* Wait for hs ctrl and data fifos to be empty */ + /* wait_for_hs_fifos_empty(sender); */ + for (i = 0; i < long_pkg->len; i++) + REG_WRITE(hs_gen_data_reg, *(dp + i)); + REG_WRITE(hs_gen_ctrl_reg, gen_ctrl_val); + } else if (pkg->transmission_type == MDFLD_DSI_LP_TRANSMISSION) { + /* wait_for_lp_fifos_empty(sender); */ + for (i = 0; i < long_pkg->len; i++) + REG_WRITE(lp_gen_data_reg, *(dp + i)); + REG_WRITE(lp_gen_ctrl_reg, gen_ctrl_val); + } else { + dev_err(dev->dev, "Unknown transmission type %d\n", + pkg->transmission_type); + return -EINVAL; + } + + return 0; + +} + +static int send_mcs_short_pkg(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg) +{ + return __send_short_pkg(sender, pkg); +} + +static int send_mcs_long_pkg(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg) +{ + return __send_long_pkg(sender, pkg); +} + +static int send_gen_short_pkg(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg) +{ + return __send_short_pkg(sender, pkg); +} + +static int send_gen_long_pkg(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg) +{ + return __send_long_pkg(sender, pkg); +} + +static int send_pkg_prepare(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg) +{ + u8 cmd; + u8 *data; + + switch (pkg->pkg_type) { + case MDFLD_DSI_PKG_DCS: + cmd = pkg->pkg.dcs_pkg.cmd; + break; + case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0: + case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1: + cmd = pkg->pkg.short_pkg.cmd; + break; + case MDFLD_DSI_PKG_MCS_LONG_WRITE: + data = (u8 *)pkg->pkg.long_pkg.data; + cmd = *data; + break; + default: + return 0; + } + + /* This prevents other package sending while doing msleep */ + sender->status = MDFLD_DSI_PKG_SENDER_BUSY; + + /* Check panel mode v.s. sending command */ + if ((sender->panel_mode & MDFLD_DSI_PANEL_MODE_SLEEP) && + cmd != exit_sleep_mode) { + dev_err(sender->dev->dev, + "sending 0x%x when panel sleep in\n", cmd); + sender->status = MDFLD_DSI_PKG_SENDER_FREE; + return -EINVAL; + } + + /* Wait for 120 milliseconds in case exit_sleep_mode just be sent */ + if (cmd == DCS_ENTER_SLEEP_MODE) { + /*TODO: replace it with msleep later*/ + mdelay(120); + } + return 0; +} + +static int send_pkg_done(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg) +{ + u8 cmd; + u8 *data; + + switch (pkg->pkg_type) { + case MDFLD_DSI_PKG_DCS: + cmd = pkg->pkg.dcs_pkg.cmd; + break; + case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0: + case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1: + cmd = pkg->pkg.short_pkg.cmd; + break; + case MDFLD_DSI_PKG_MCS_LONG_WRITE: + data = (u8 *)pkg->pkg.long_pkg.data; + cmd = *data; + break; + default: + return 0; + } + + /* Update panel status */ + if (cmd == DCS_ENTER_SLEEP_MODE) { + sender->panel_mode |= MDFLD_DSI_PANEL_MODE_SLEEP; + /*TODO: replace it with msleep later*/ + mdelay(120); + } else if (cmd == DCS_EXIT_SLEEP_MODE) { + sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP; + /*TODO: replace it with msleep later*/ + mdelay(120); + } else if (unlikely(cmd == DCS_SOFT_RESET)) { + /*TODO: replace it with msleep later*/ + mdelay(5); + } + sender->status = MDFLD_DSI_PKG_SENDER_FREE; + return 0; + +} + +static int do_send_pkg(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg) +{ + int ret; + + if (sender->status == MDFLD_DSI_PKG_SENDER_BUSY) { + dev_err(sender->dev->dev, "sender is busy\n"); + return -EAGAIN; + } + + ret = send_pkg_prepare(sender, pkg); + if (ret) { + dev_err(sender->dev->dev, "send_pkg_prepare error\n"); + return ret; + } + + switch (pkg->pkg_type) { + case MDFLD_DSI_PKG_DCS: + ret = send_dcs_pkg(sender, pkg); + break; + case MDFLD_DSI_PKG_GEN_SHORT_WRITE_0: + case MDFLD_DSI_PKG_GEN_SHORT_WRITE_1: + case MDFLD_DSI_PKG_GEN_SHORT_WRITE_2: + case MDFLD_DSI_PKG_GEN_READ_0: + case MDFLD_DSI_PKG_GEN_READ_1: + case MDFLD_DSI_PKG_GEN_READ_2: + ret = send_gen_short_pkg(sender, pkg); + break; + case MDFLD_DSI_PKG_GEN_LONG_WRITE: + ret = send_gen_long_pkg(sender, pkg); + break; + case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0: + case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1: + case MDFLD_DSI_PKG_MCS_READ: + ret = send_mcs_short_pkg(sender, pkg); + break; + case MDFLD_DSI_PKG_MCS_LONG_WRITE: + ret = send_mcs_long_pkg(sender, pkg); + break; + default: + dev_err(sender->dev->dev, "Invalid pkg type 0x%x\n", + pkg->pkg_type); + ret = -EINVAL; + } + send_pkg_done(sender, pkg); + return ret; +} + +static int send_pkg(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg) +{ + int err ; + + /* Handle DSI error */ + err = dsi_error_handler(sender); + if (err) { + dev_err(sender->dev->dev, "Error handling failed\n"); + err = -EAGAIN; + goto send_pkg_err; + } + + /* Send pkg */ + err = do_send_pkg(sender, pkg); + if (err) { + dev_err(sender->dev->dev, "sent pkg failed\n"); + err = -EAGAIN; + goto send_pkg_err; + } + + /* FIXME: should I query complete and fifo empty here? */ +send_pkg_err: + return err; +} + +static struct mdfld_dsi_pkg *pkg_sender_get_pkg_locked( + struct mdfld_dsi_pkg_sender *sender) +{ + struct mdfld_dsi_pkg *pkg; + + if (list_empty(&sender->free_list)) { + dev_err(sender->dev->dev, "No free pkg left\n"); + return NULL; + } + pkg = list_first_entry(&sender->free_list, struct mdfld_dsi_pkg, entry); + /* Detach from free list */ + list_del_init(&pkg->entry); + return pkg; +} + +static void pkg_sender_put_pkg_locked(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg) +{ + memset(pkg, 0, sizeof(struct mdfld_dsi_pkg)); + INIT_LIST_HEAD(&pkg->entry); + list_add_tail(&pkg->entry, &sender->free_list); +} + +static int mdfld_dbi_cb_init(struct mdfld_dsi_pkg_sender *sender, + struct psb_gtt *pg, int pipe) +{ + unsigned long phys; + void *virt_addr = NULL; + + switch (pipe) { + case 0: + /* FIXME: Doesn't this collide with stolen space ? */ + phys = pg->gtt_phys_start - 0x1000; + break; + case 2: + phys = pg->gtt_phys_start - 0x800; + break; + default: + dev_err(sender->dev->dev, "Unsupported channel %d\n", pipe); + return -EINVAL; + } + + virt_addr = ioremap_nocache(phys, 0x800); + if (!virt_addr) { + dev_err(sender->dev->dev, "Map DBI command buffer error\n"); + return -ENOMEM; + } + sender->dbi_cb_phy = phys; + sender->dbi_cb_addr = virt_addr; + return 0; +} + +static void mdfld_dbi_cb_destroy(struct mdfld_dsi_pkg_sender *sender) +{ + if (sender && sender->dbi_cb_addr) + iounmap(sender->dbi_cb_addr); +} + +static void pkg_sender_queue_pkg(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg, + int delay) +{ + unsigned long flags; + + spin_lock_irqsave(&sender->lock, flags); + + if (!delay) { + send_pkg(sender, pkg); + pkg_sender_put_pkg_locked(sender, pkg); + } else { + /* Queue it */ + list_add_tail(&pkg->entry, &sender->pkg_list); + } + spin_unlock_irqrestore(&sender->lock, flags); +} + +static void process_pkg_list(struct mdfld_dsi_pkg_sender *sender) +{ + struct mdfld_dsi_pkg *pkg; + unsigned long flags; + + spin_lock_irqsave(&sender->lock, flags); + + while (!list_empty(&sender->pkg_list)) { + pkg = list_first_entry(&sender->pkg_list, + struct mdfld_dsi_pkg, entry); + send_pkg(sender, pkg); + list_del_init(&pkg->entry); + pkg_sender_put_pkg_locked(sender, pkg); + } + + spin_unlock_irqrestore(&sender->lock, flags); +} + +static int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender, + u32 *data, u32 len, u8 transmission, int delay) +{ + struct mdfld_dsi_pkg *pkg; + unsigned long flags; + + spin_lock_irqsave(&sender->lock, flags); + pkg = pkg_sender_get_pkg_locked(sender); + spin_unlock_irqrestore(&sender->lock, flags); + + if (!pkg) { + dev_err(sender->dev->dev, "No memory\n"); + return -ENOMEM; + } + pkg->pkg_type = MDFLD_DSI_PKG_MCS_LONG_WRITE; + pkg->transmission_type = transmission; + pkg->pkg.long_pkg.data = data; + pkg->pkg.long_pkg.len = len; + INIT_LIST_HEAD(&pkg->entry); + + pkg_sender_queue_pkg(sender, pkg, delay); + return 0; +} + +static int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender, + u8 cmd, u8 param, u8 param_num, + u8 transmission, + int delay) +{ + struct mdfld_dsi_pkg *pkg; + unsigned long flags; + + spin_lock_irqsave(&sender->lock, flags); + pkg = pkg_sender_get_pkg_locked(sender); + spin_unlock_irqrestore(&sender->lock, flags); + + if (!pkg) { + dev_err(sender->dev->dev, "No memory\n"); + return -ENOMEM; + } + + if (param_num) { + pkg->pkg_type = MDFLD_DSI_PKG_MCS_SHORT_WRITE_1; + pkg->pkg.short_pkg.param = param; + } else { + pkg->pkg_type = MDFLD_DSI_PKG_MCS_SHORT_WRITE_0; + pkg->pkg.short_pkg.param = 0; + } + pkg->transmission_type = transmission; + pkg->pkg.short_pkg.cmd = cmd; + INIT_LIST_HEAD(&pkg->entry); + + pkg_sender_queue_pkg(sender, pkg, delay); + return 0; +} + +static int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender, + u8 param0, u8 param1, u8 param_num, + u8 transmission, + int delay) +{ + struct mdfld_dsi_pkg *pkg; + unsigned long flags; + + spin_lock_irqsave(&sender->lock, flags); + pkg = pkg_sender_get_pkg_locked(sender); + spin_unlock_irqrestore(&sender->lock, flags); + + if (!pkg) { + dev_err(sender->dev->dev, "No pkg memory\n"); + return -ENOMEM; + } + + switch (param_num) { + case 0: + pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_0; + pkg->pkg.short_pkg.cmd = 0; + pkg->pkg.short_pkg.param = 0; + break; + case 1: + pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_1; + pkg->pkg.short_pkg.cmd = param0; + pkg->pkg.short_pkg.param = 0; + break; + case 2: + pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_2; + pkg->pkg.short_pkg.cmd = param0; + pkg->pkg.short_pkg.param = param1; + break; + } + + pkg->transmission_type = transmission; + INIT_LIST_HEAD(&pkg->entry); + + pkg_sender_queue_pkg(sender, pkg, delay); + return 0; +} + +static int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender, + u32 *data, u32 len, u8 transmission, int delay) +{ + struct mdfld_dsi_pkg *pkg; + unsigned long flags; + + spin_lock_irqsave(&sender->lock, flags); + pkg = pkg_sender_get_pkg_locked(sender); + spin_unlock_irqrestore(&sender->lock, flags); + + if (!pkg) { + dev_err(sender->dev->dev, "No pkg memory\n"); + return -ENOMEM; + } + + pkg->pkg_type = MDFLD_DSI_PKG_GEN_LONG_WRITE; + pkg->transmission_type = transmission; + pkg->pkg.long_pkg.data = data; + pkg->pkg.long_pkg.len = len; + + INIT_LIST_HEAD(&pkg->entry); + + pkg_sender_queue_pkg(sender, pkg, delay); + + return 0; +} + +static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender, + struct mdfld_dsi_pkg *pkg, + u32 *data, + u16 len) +{ + unsigned long flags; + struct drm_device *dev = sender->dev; + int i; + u32 gen_data_reg; + int retry = MDFLD_DSI_READ_MAX_COUNT; + u8 transmission = pkg->transmission_type; + + /* + * do reading. + * 0) send out generic read request + * 1) polling read data avail interrupt + * 2) read data + */ + spin_lock_irqsave(&sender->lock, flags); + + REG_WRITE(sender->mipi_intr_stat_reg, 1 << 29); + + if ((REG_READ(sender->mipi_intr_stat_reg) & (1 << 29))) + DRM_ERROR("Can NOT clean read data valid interrupt\n"); + + /*send out read request*/ + send_pkg(sender, pkg); + + pkg_sender_put_pkg_locked(sender, pkg); + + /*polling read data avail interrupt*/ + while (retry && !(REG_READ(sender->mipi_intr_stat_reg) & (1 << 29))) { + udelay(100); + retry--; + } + + if (!retry) { + spin_unlock_irqrestore(&sender->lock, flags); + return -ETIMEDOUT; + } + + REG_WRITE(sender->mipi_intr_stat_reg, (1 << 29)); + + /*read data*/ + if (transmission == MDFLD_DSI_HS_TRANSMISSION) + gen_data_reg = sender->mipi_hs_gen_data_reg; + else if (transmission == MDFLD_DSI_LP_TRANSMISSION) + gen_data_reg = sender->mipi_lp_gen_data_reg; + else { + DRM_ERROR("Unknown transmission"); + spin_unlock_irqrestore(&sender->lock, flags); + return -EINVAL; + } + + for (i=0; ilock, flags); + + return 0; +} + +static int mdfld_dsi_read_gen(struct mdfld_dsi_pkg_sender *sender, + u8 param0, + u8 param1, + u8 param_num, + u32 *data, + u16 len, + u8 transmission) +{ + struct mdfld_dsi_pkg *pkg; + unsigned long flags; + + spin_lock_irqsave(&sender->lock, flags); + + pkg = pkg_sender_get_pkg_locked(sender); + + spin_unlock_irqrestore(&sender->lock,flags); + + if (!pkg) { + dev_err(sender->dev->dev, "No pkg memory\n"); + return -ENOMEM; + } + + switch (param_num) { + case 0: + pkg->pkg_type = MDFLD_DSI_PKG_GEN_READ_0; + pkg->pkg.short_pkg.cmd = 0; + pkg->pkg.short_pkg.param = 0; + break; + case 1: + pkg->pkg_type = MDFLD_DSI_PKG_GEN_READ_1; + pkg->pkg.short_pkg.cmd = param0; + pkg->pkg.short_pkg.param = 0; + break; + case 2: + pkg->pkg_type = MDFLD_DSI_PKG_GEN_READ_2; + pkg->pkg.short_pkg.cmd = param0; + pkg->pkg.short_pkg.param = param1; + break; + } + + pkg->transmission_type = transmission; + + INIT_LIST_HEAD(&pkg->entry); + + return __read_panel_data(sender, pkg, data, len); +} + +static int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender, + u8 cmd, + u32 *data, + u16 len, + u8 transmission) +{ + struct mdfld_dsi_pkg *pkg; + unsigned long flags; + + spin_lock_irqsave(&sender->lock, flags); + + pkg = pkg_sender_get_pkg_locked(sender); + + spin_unlock_irqrestore(&sender->lock, flags); + + if (!pkg) { + dev_err(sender->dev->dev, "No pkg memory\n"); + return -ENOMEM; + } + + pkg->pkg_type = MDFLD_DSI_PKG_MCS_READ; + pkg->pkg.short_pkg.cmd = cmd; + pkg->pkg.short_pkg.param = 0; + + pkg->transmission_type = transmission; + + INIT_LIST_HEAD(&pkg->entry); + + return __read_panel_data(sender, pkg, data, len); +} + +void dsi_controller_dbi_init(struct mdfld_dsi_config * dsi_config, int pipe) +{ + struct drm_device * dev = dsi_config->dev; + u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0; + int lane_count = dsi_config->lane_count; + u32 val = 0; + + /*un-ready device*/ + REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000); + + /*init dsi adapter before kicking off*/ + REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018); + + /*TODO: figure out how to setup these registers*/ + REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408); + REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), 0x000a0014); + REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400); + REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001); + REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000); + + /*enable all interrupts*/ + REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff); + /*max value: 20 clock cycles of txclkesc*/ + REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f); + /*min 21 txclkesc, max: ffffh*/ + REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff); + /*min: 7d0 max: 4e20*/ + REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0); + + /*set up max return packet size*/ + REG_WRITE((MIPIA_MAX_RETURN_PACK_SIZE_REG + reg_offset), + MDFLD_DSI_MAX_RETURN_PACKET_SIZE); + + /*set up func_prg*/ + val |= lane_count; + val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET); + val |= DSI_DBI_COLOR_FORMAT_OPTION2; + REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val); + + REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff); + REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff); + + REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46); + REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000); + REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004); + REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001); +} + +void dsi_controller_dpi_init(struct mdfld_dsi_config * dsi_config, int pipe) +{ + struct drm_device * dev = dsi_config->dev; + u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0; + int lane_count = dsi_config->lane_count; + struct mdfld_dsi_dpi_timing dpi_timing; + struct drm_display_mode * mode = dsi_config->mode; + u32 val = 0; + + /*un-ready device*/ + REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000); + + /*init dsi adapter before kicking off*/ + REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018); + + /*enable all interrupts*/ + REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff); + + /*set up func_prg*/ + val |= lane_count; + val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET; + + switch(dsi_config->bpp) { + case 16: + val |= DSI_DPI_COLOR_FORMAT_RGB565; + break; + case 18: + val |= DSI_DPI_COLOR_FORMAT_RGB666; + break; + case 24: + val |= DSI_DPI_COLOR_FORMAT_RGB888; + break; + default: + DRM_ERROR("unsupported color format, bpp = %d\n", dsi_config->bpp); + } + + REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val); + + REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), + (mode->vtotal * mode->htotal * dsi_config->bpp / (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK); + REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff & DSI_LP_RX_TIMEOUT_MASK); + + /*max value: 20 clock cycles of txclkesc*/ + REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK); + + /*min 21 txclkesc, max: ffffh*/ + REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0xffff & DSI_RESET_TIMER_MASK); + + REG_WRITE((MIPIA_DPI_RESOLUTION_REG + reg_offset), mode->vdisplay << 16 | mode->hdisplay); + + /*set DPI timing registers*/ + mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp); + + REG_WRITE((MIPIA_HSYNC_COUNT_REG + reg_offset), dpi_timing.hsync_count & DSI_DPI_TIMING_MASK); + REG_WRITE((MIPIA_HBP_COUNT_REG + reg_offset), dpi_timing.hbp_count & DSI_DPI_TIMING_MASK); + REG_WRITE((MIPIA_HFP_COUNT_REG + reg_offset), dpi_timing.hfp_count & DSI_DPI_TIMING_MASK); + REG_WRITE((MIPIA_HACTIVE_COUNT_REG + reg_offset), dpi_timing.hactive_count & DSI_DPI_TIMING_MASK); + REG_WRITE((MIPIA_VSYNC_COUNT_REG + reg_offset), dpi_timing.vsync_count & DSI_DPI_TIMING_MASK); + REG_WRITE((MIPIA_VBP_COUNT_REG + reg_offset), dpi_timing.vbp_count & DSI_DPI_TIMING_MASK); + REG_WRITE((MIPIA_VFP_COUNT_REG + reg_offset), dpi_timing.vfp_count & DSI_DPI_TIMING_MASK); + + REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46); + + /*min: 7d0 max: 4e20*/ + REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x000007d0); + + /*set up video mode*/ + val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE; + REG_WRITE((MIPIA_VIDEO_MODE_FORMAT_REG + reg_offset), val); + + REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000); + + REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004); + + /*TODO: figure out how to setup these registers*/ + REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408); + + REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), (0xa << 16) | 0x14); + + /*set device ready*/ + REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001); +} + +static void dsi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe) +{ + if (!dsi_config || ((pipe != 0) && (pipe != 2))) { + DRM_ERROR("Invalid parameters\n"); + return; + } + + if (dsi_config->type == MDFLD_DSI_ENCODER_DPI) + dsi_controller_dpi_init(dsi_config, pipe); + else if (dsi_config->type == MDFLD_DSI_ENCODER_DBI) + dsi_controller_dbi_init(dsi_config, pipe); + else + DRM_ERROR("Bad DSI encoder type\n"); +} + +void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender) +{ + process_pkg_list(sender); +} + +int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender *sender, + u8 dcs, u8 *param, u32 param_num, u8 data_src, + int delay) +{ + struct mdfld_dsi_pkg *pkg; + u32 cb_phy = sender->dbi_cb_phy; + struct drm_device *dev = sender->dev; + u32 index = 0; + u8 *cb = (u8 *)sender->dbi_cb_addr; + unsigned long flags; + int retry; + u8 *dst = NULL; + u32 len; + + if (!sender) { + WARN_ON(1); + return -EINVAL; + } + + if (!sender->dbi_pkg_support) { + dev_err(dev->dev, "No DBI pkg sending on this sender\n"); + return -ENOTSUPP; + } + + if (param_num > MDFLD_MAX_DCS_PARAM) { + dev_err(dev->dev, "Sender only supports up to %d DCS params\n", + MDFLD_MAX_DCS_PARAM); + return -EINVAL; + } + + /* + * If dcs is write_mem_start, send it directly using DSI adapter + * interface + */ + if (dcs == DCS_WRITE_MEM_START) { + if (!spin_trylock(&sender->lock)) + return -EAGAIN; + + /* + * query whether DBI FIFO is empty, + * if not wait it becoming empty + */ + retry = MDFLD_DSI_DBI_FIFO_TIMEOUT; + while (retry && + !(REG_READ(sender->mipi_gen_fifo_stat_reg) & (1 << 27))) { + udelay(500); + retry--; + } + + /* If DBI FIFO timeout, drop this frame */ + if (!retry) { + spin_unlock(&sender->lock); + return 0; + } + + *(cb + (index++)) = write_mem_start; + + REG_WRITE(sender->mipi_cmd_len_reg, 1); + REG_WRITE(sender->mipi_cmd_addr_reg, + cb_phy | (1 << 0) | (1 << 1)); + + retry = MDFLD_DSI_DBI_FIFO_TIMEOUT; + while (retry && + (REG_READ(sender->mipi_cmd_addr_reg) & (1 << 0))) { + udelay(1); + retry--; + } + + spin_unlock(&sender->lock); + return 0; + } + + /* Get a free pkg */ + spin_lock_irqsave(&sender->lock, flags); + pkg = pkg_sender_get_pkg_locked(sender); + spin_unlock_irqrestore(&sender->lock, flags); + + if (!pkg) { + dev_err(dev->dev, "No packages memory\n"); + return -ENOMEM; + } + + dst = pkg->pkg.dcs_pkg.param; + memcpy(dst, param, param_num); + + pkg->pkg_type = MDFLD_DSI_PKG_DCS; + pkg->transmission_type = MDFLD_DSI_DCS; + pkg->pkg.dcs_pkg.cmd = dcs; + pkg->pkg.dcs_pkg.param_num = param_num; + pkg->pkg.dcs_pkg.data_src = data_src; + + INIT_LIST_HEAD(&pkg->entry); + + if (param_num == 0) + return mdfld_dsi_send_mcs_short_hs(sender, dcs, 0, 0, delay); + else if (param_num == 1) + return mdfld_dsi_send_mcs_short_hs(sender, dcs, + param[0], 1, delay); + else if (param_num > 1) { + len = (param_num + 1) / 4; + if ((param_num + 1) % 4) + len++; + return mdfld_dsi_send_mcs_long_hs(sender, + (u32 *)&pkg->pkg.dcs_pkg, len, delay); + } + return 0; +} + +int mdfld_dsi_send_mcs_short_hs(struct mdfld_dsi_pkg_sender *sender, + u8 cmd, u8 param, u8 param_num, int delay) +{ + if (!sender) { + WARN_ON(1); + return -EINVAL; + } + return mdfld_dsi_send_mcs_short(sender, cmd, param, param_num, + MDFLD_DSI_HS_TRANSMISSION, delay); +} + +int mdfld_dsi_send_mcs_short_lp(struct mdfld_dsi_pkg_sender *sender, + u8 cmd, u8 param, u8 param_num, int delay) +{ + if (!sender) { + WARN_ON(1); + return -EINVAL; + } + return mdfld_dsi_send_mcs_short(sender, cmd, param, param_num, + MDFLD_DSI_LP_TRANSMISSION, delay); +} + +int mdfld_dsi_send_mcs_long_hs(struct mdfld_dsi_pkg_sender *sender, + u32 *data, + u32 len, + int delay) +{ + if (!sender || !data || !len) { + DRM_ERROR("Invalid parameters\n"); + return -EINVAL; + } + return mdfld_dsi_send_mcs_long(sender, data, len, + MDFLD_DSI_HS_TRANSMISSION, delay); +} + +int mdfld_dsi_send_mcs_long_lp(struct mdfld_dsi_pkg_sender *sender, + u32 *data, + u32 len, + int delay) +{ + if (!sender || !data || !len) { + WARN_ON(1); + return -EINVAL; + } + return mdfld_dsi_send_mcs_long(sender, data, len, + MDFLD_DSI_LP_TRANSMISSION, delay); +} + +int mdfld_dsi_send_gen_short_hs(struct mdfld_dsi_pkg_sender *sender, + u8 param0, u8 param1, u8 param_num, int delay) +{ + if (!sender) { + WARN_ON(1); + return -EINVAL; + } + return mdfld_dsi_send_gen_short(sender, param0, param1, param_num, + MDFLD_DSI_HS_TRANSMISSION, delay); +} + +int mdfld_dsi_send_gen_short_lp(struct mdfld_dsi_pkg_sender *sender, + u8 param0, u8 param1, u8 param_num, int delay) +{ + if (!sender || param_num < 0 || param_num > 2) { + WARN_ON(1); + return -EINVAL; + } + return mdfld_dsi_send_gen_short(sender, param0, param1, param_num, + MDFLD_DSI_LP_TRANSMISSION, delay); +} + +int mdfld_dsi_send_gen_long_hs(struct mdfld_dsi_pkg_sender *sender, + u32 *data, + u32 len, + int delay) +{ + if (!sender || !data || !len) { + WARN_ON(1); + return -EINVAL; + } + return mdfld_dsi_send_gen_long(sender, data, len, + MDFLD_DSI_HS_TRANSMISSION, delay); +} + +int mdfld_dsi_send_gen_long_lp(struct mdfld_dsi_pkg_sender *sender, + u32 *data, + u32 len, + int delay) +{ + if (!sender || !data || !len) { + WARN_ON(1); + return -EINVAL; + } + return mdfld_dsi_send_gen_long(sender, data, len, + MDFLD_DSI_LP_TRANSMISSION, delay); +} + +int mdfld_dsi_read_gen_hs(struct mdfld_dsi_pkg_sender *sender, + u8 param0, + u8 param1, + u8 param_num, + u32 *data, + u16 len) +{ + if (!sender || !data || param_num < 0 || param_num > 2 + || !data || !len) { + DRM_ERROR("Invalid parameters\n"); + return -EINVAL; + } + + return mdfld_dsi_read_gen(sender, param0, param1, param_num, + data, len, MDFLD_DSI_HS_TRANSMISSION); + +} + +int mdfld_dsi_read_gen_lp(struct mdfld_dsi_pkg_sender *sender, + u8 param0, + u8 param1, + u8 param_num, + u32 *data, + u16 len) +{ + if (!sender || !data || param_num < 0 || param_num > 2 + || !data || !len) { + DRM_ERROR("Invalid parameters\n"); + return -EINVAL; + } + + return mdfld_dsi_read_gen(sender, param0, param1, param_num, + data, len, MDFLD_DSI_LP_TRANSMISSION); +} + +int mdfld_dsi_read_mcs_hs(struct mdfld_dsi_pkg_sender *sender, + u8 cmd, + u32 *data, + u16 len) +{ + if (!sender || !data || !len) { + DRM_ERROR("Invalid parameters\n"); + return -EINVAL; + } + + return mdfld_dsi_read_mcs(sender, cmd, data, len, + MDFLD_DSI_HS_TRANSMISSION); +} + +int mdfld_dsi_read_mcs_lp(struct mdfld_dsi_pkg_sender *sender, + u8 cmd, + u32 *data, + u16 len) +{ + if (!sender || !data || !len) { + WARN_ON(1); + return -EINVAL; + } + + return mdfld_dsi_read_mcs(sender, cmd, data, len, + MDFLD_DSI_LP_TRANSMISSION); +} + +int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector, + int pipe) +{ + int ret; + struct mdfld_dsi_pkg_sender *pkg_sender; + struct mdfld_dsi_config *dsi_config = + mdfld_dsi_get_config(dsi_connector); + struct drm_device *dev = dsi_config->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_gtt *pg = &dev_priv->gtt; + int i; + struct mdfld_dsi_pkg *pkg, *tmp; + u32 mipi_val = 0; + + if (!dsi_connector) { + WARN_ON(1); + return -EINVAL; + } + + pkg_sender = dsi_connector->pkg_sender; + + if (!pkg_sender || IS_ERR(pkg_sender)) { + pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender), + GFP_KERNEL); + if (!pkg_sender) { + dev_err(dev->dev, "Create DSI pkg sender failed\n"); + return -ENOMEM; + } + + dsi_connector->pkg_sender = (void *)pkg_sender; + } + + pkg_sender->dev = dev; + pkg_sender->dsi_connector = dsi_connector; + pkg_sender->pipe = pipe; + pkg_sender->pkg_num = 0; + pkg_sender->panel_mode = 0; + pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE; + + /* Init dbi command buffer*/ + + if (dsi_config->type == MDFLD_DSI_ENCODER_DBI) { + pkg_sender->dbi_pkg_support = 1; + ret = mdfld_dbi_cb_init(pkg_sender, pg, pipe); + if (ret) { + dev_err(dev->dev, "DBI command buffer map failed\n"); + goto mapping_err; + } + } + + /* Init regs */ + if (pipe == 0) { + pkg_sender->dpll_reg = MRST_DPLL_A; + pkg_sender->dspcntr_reg = DSPACNTR; + pkg_sender->pipeconf_reg = PIPEACONF; + pkg_sender->dsplinoff_reg = DSPALINOFF; + pkg_sender->dspsurf_reg = DSPASURF; + pkg_sender->pipestat_reg = PIPEASTAT; + + pkg_sender->mipi_intr_stat_reg = MIPIA_INTR_STAT_REG; + pkg_sender->mipi_lp_gen_data_reg = MIPIA_LP_GEN_DATA_REG; + pkg_sender->mipi_hs_gen_data_reg = MIPIA_HS_GEN_DATA_REG; + pkg_sender->mipi_lp_gen_ctrl_reg = MIPIA_LP_GEN_CTRL_REG; + pkg_sender->mipi_hs_gen_ctrl_reg = MIPIA_HS_GEN_CTRL_REG; + pkg_sender->mipi_gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG; + pkg_sender->mipi_data_addr_reg = MIPIA_DATA_ADD_REG; + pkg_sender->mipi_data_len_reg = MIPIA_DATA_LEN_REG; + pkg_sender->mipi_cmd_addr_reg = MIPIA_CMD_ADD_REG; + pkg_sender->mipi_cmd_len_reg = MIPIA_CMD_LEN_REG; + } else if (pipe == 2) { + pkg_sender->dpll_reg = MRST_DPLL_A; + pkg_sender->dspcntr_reg = DSPCCNTR; + pkg_sender->pipeconf_reg = PIPECCONF; + pkg_sender->dsplinoff_reg = DSPCLINOFF; + pkg_sender->dspsurf_reg = DSPCSURF; + pkg_sender->pipestat_reg = PIPECSTAT; + + pkg_sender->mipi_intr_stat_reg = + MIPIA_INTR_STAT_REG + MIPIC_REG_OFFSET; + pkg_sender->mipi_lp_gen_data_reg = + MIPIA_LP_GEN_DATA_REG + MIPIC_REG_OFFSET; + pkg_sender->mipi_hs_gen_data_reg = + MIPIA_HS_GEN_DATA_REG + MIPIC_REG_OFFSET; + pkg_sender->mipi_lp_gen_ctrl_reg = + MIPIA_LP_GEN_CTRL_REG + MIPIC_REG_OFFSET; + pkg_sender->mipi_hs_gen_ctrl_reg = + MIPIA_HS_GEN_CTRL_REG + MIPIC_REG_OFFSET; + pkg_sender->mipi_gen_fifo_stat_reg = + MIPIA_GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET; + pkg_sender->mipi_data_addr_reg = + MIPIA_DATA_ADD_REG + MIPIC_REG_OFFSET; + pkg_sender->mipi_data_len_reg = + MIPIA_DATA_LEN_REG + MIPIC_REG_OFFSET; + pkg_sender->mipi_cmd_addr_reg = + MIPIA_CMD_ADD_REG + MIPIC_REG_OFFSET; + pkg_sender->mipi_cmd_len_reg = + MIPIA_CMD_LEN_REG + MIPIC_REG_OFFSET; + } + + /* Init pkg list */ + INIT_LIST_HEAD(&pkg_sender->pkg_list); + INIT_LIST_HEAD(&pkg_sender->free_list); + + spin_lock_init(&pkg_sender->lock); + + /* Allocate free pkg pool */ + for (i = 0; i < MDFLD_MAX_PKG_NUM; i++) { + pkg = kzalloc(sizeof(struct mdfld_dsi_pkg), GFP_KERNEL); + if (!pkg) { + dev_err(dev->dev, "Out of memory allocating pkg pool"); + ret = -ENOMEM; + goto pkg_alloc_err; + } + INIT_LIST_HEAD(&pkg->entry); + list_add_tail(&pkg->entry, &pkg_sender->free_list); + } + + /* + * For video mode, don't enable DPI timing output here, + * will init the DPI timing output during mode setting. + */ + if (dsi_config->type == MDFLD_DSI_ENCODER_DPI) + mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX; + else if (dsi_config->type == MDFLD_DSI_ENCODER_DBI) + mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX + | TE_TRIGGER_GPIO_PIN; + else + DRM_ERROR("Bad DSI encoder type\n"); + + if (pipe == 0) { + mipi_val |= 0x2; + REG_WRITE(MIPI, mipi_val); + REG_READ(MIPI); + } else if (pipe == 2) { + REG_WRITE(MIPI_C, mipi_val); + REG_READ(MIPI_C); + } + + /*do dsi controller init*/ + dsi_controller_init(dsi_config, pipe); + + return 0; + +pkg_alloc_err: + list_for_each_entry_safe(pkg, tmp, &pkg_sender->free_list, entry) { + list_del(&pkg->entry); + kfree(pkg); + } + + /* Free mapped command buffer */ + mdfld_dbi_cb_destroy(pkg_sender); +mapping_err: + kfree(pkg_sender); + dsi_connector->pkg_sender = NULL; + return ret; +} + +void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender) +{ + struct mdfld_dsi_pkg *pkg, *tmp; + + if (!sender || IS_ERR(sender)) + return; + + /* Free pkg pool */ + list_for_each_entry_safe(pkg, tmp, &sender->free_list, entry) { + list_del(&pkg->entry); + kfree(pkg); + } + /* Free pkg list */ + list_for_each_entry_safe(pkg, tmp, &sender->pkg_list, entry) { + list_del(&pkg->entry); + kfree(pkg); + } + mdfld_dbi_cb_destroy(sender); /* free mapped command buffer */ + kfree(sender); +} diff --git a/drivers/staging/gma500/mdfld_dsi_pkg_sender.h b/drivers/staging/gma500/mdfld_dsi_pkg_sender.h new file mode 100644 index 000000000000..f24abc700684 --- /dev/null +++ b/drivers/staging/gma500/mdfld_dsi_pkg_sender.h @@ -0,0 +1,184 @@ +/* + * Copyright © 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: + * Jackie Li + */ +#ifndef __MDFLD_DSI_PKG_SENDER_H__ +#define __MDFLD_DSI_PKG_SENDER_H__ + +#include + +#define MDFLD_MAX_DCS_PARAM 8 +#define MDFLD_MAX_PKG_NUM 2048 + +enum { + MDFLD_DSI_PKG_DCS, + MDFLD_DSI_PKG_GEN_SHORT_WRITE_0 = 0x03, + MDFLD_DSI_PKG_GEN_SHORT_WRITE_1 = 0x13, + MDFLD_DSI_PKG_GEN_SHORT_WRITE_2 = 0x23, + MDFLD_DSI_PKG_GEN_READ_0 = 0x04, + MDFLD_DSI_PKG_GEN_READ_1 = 0x14, + MDFLD_DSI_PKG_GEN_READ_2 = 0x24, + MDFLD_DSI_PKG_GEN_LONG_WRITE = 0x29, + MDFLD_DSI_PKG_MCS_SHORT_WRITE_0 = 0x05, + MDFLD_DSI_PKG_MCS_SHORT_WRITE_1 = 0x15, + MDFLD_DSI_PKG_MCS_READ = 0x06, + MDFLD_DSI_PKG_MCS_LONG_WRITE = 0x39, +}; + +enum { + MDFLD_DSI_LP_TRANSMISSION, + MDFLD_DSI_HS_TRANSMISSION, + MDFLD_DSI_DCS, +}; + +enum { + MDFLD_DSI_PANEL_MODE_SLEEP = 0x1, +}; + +enum { + MDFLD_DSI_PKG_SENDER_FREE = 0x0, + MDFLD_DSI_PKG_SENDER_BUSY = 0x1, +}; + +enum { + MDFLD_DSI_SEND_PACKAGE, + MDFLD_DSI_QUEUE_PACKAGE, +}; + +struct mdfld_dsi_gen_short_pkg { + u8 cmd; + u8 param; +}; + +struct mdfld_dsi_gen_long_pkg { + u32 *data; + u32 len; +}; + +struct mdfld_dsi_dcs_pkg { + u8 cmd; + u8 param[MDFLD_MAX_DCS_PARAM]; + u32 param_num; + u8 data_src; +}; + +struct mdfld_dsi_pkg { + u8 pkg_type; + u8 transmission_type; + + union { + struct mdfld_dsi_gen_short_pkg short_pkg; + struct mdfld_dsi_gen_long_pkg long_pkg; + struct mdfld_dsi_dcs_pkg dcs_pkg; + } pkg; + + struct list_head entry; +}; + +struct mdfld_dsi_pkg_sender { + struct drm_device *dev; + struct mdfld_dsi_connector *dsi_connector; + u32 status; + + u32 panel_mode; + + int pipe; + + spinlock_t lock; + struct list_head pkg_list; + struct list_head free_list; + + u32 pkg_num; + + int dbi_pkg_support; + + u32 dbi_cb_phy; + void *dbi_cb_addr; + + /* Registers */ + u32 dpll_reg; + u32 dspcntr_reg; + u32 pipeconf_reg; + u32 pipestat_reg; + u32 dsplinoff_reg; + u32 dspsurf_reg; + + u32 mipi_intr_stat_reg; + u32 mipi_lp_gen_data_reg; + u32 mipi_hs_gen_data_reg; + u32 mipi_lp_gen_ctrl_reg; + u32 mipi_hs_gen_ctrl_reg; + u32 mipi_gen_fifo_stat_reg; + u32 mipi_data_addr_reg; + u32 mipi_data_len_reg; + u32 mipi_cmd_addr_reg; + u32 mipi_cmd_len_reg; +}; + +/* DCS definitions */ +#define DCS_SOFT_RESET 0x01 +#define DCS_ENTER_SLEEP_MODE 0x10 +#define DCS_EXIT_SLEEP_MODE 0x11 +#define DCS_SET_DISPLAY_OFF 0x28 +#define DCS_SET_DISPLAY_ON 0x29 +#define DCS_SET_COLUMN_ADDRESS 0x2a +#define DCS_SET_PAGE_ADDRESS 0x2b +#define DCS_WRITE_MEM_START 0x2c +#define DCS_SET_TEAR_OFF 0x34 +#define DCS_SET_TEAR_ON 0x35 + +extern int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector, + int pipe); +extern void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender); +extern int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender *sender, u8 dcs, + u8 *param, u32 param_num, u8 data_src, int delay); +extern int mdfld_dsi_send_mcs_short_hs(struct mdfld_dsi_pkg_sender *sender, + u8 cmd, u8 param, u8 param_num, int delay); +extern int mdfld_dsi_send_mcs_short_lp(struct mdfld_dsi_pkg_sender *sender, + u8 cmd, u8 param, u8 param_num, int delay); +extern int mdfld_dsi_send_mcs_long_hs(struct mdfld_dsi_pkg_sender *sender, + u32 *data, u32 len, int delay); +extern int mdfld_dsi_send_mcs_long_lp(struct mdfld_dsi_pkg_sender *sender, + u32 *data, u32 len, int delay); +extern int mdfld_dsi_send_gen_short_hs(struct mdfld_dsi_pkg_sender *sender, + u8 param0, u8 param1, u8 param_num, int delay); +extern int mdfld_dsi_send_gen_short_lp(struct mdfld_dsi_pkg_sender *sender, + u8 param0, u8 param1, u8 param_num, int delay); +extern int mdfld_dsi_send_gen_long_hs(struct mdfld_dsi_pkg_sender *sender, + u32 *data, u32 len, int delay); +extern int mdfld_dsi_send_gen_long_lp(struct mdfld_dsi_pkg_sender *sender, + u32 *data, u32 len, int delay); + +extern int mdfld_dsi_read_gen_hs(struct mdfld_dsi_pkg_sender *sender, + u8 param0, u8 param1, u8 param_num, u32 *data, u16 len); +extern int mdfld_dsi_read_gen_lp(struct mdfld_dsi_pkg_sender *sender, + u8 param0, u8 param1, u8 param_num, u32 *data, u16 len); +extern int mdfld_dsi_read_mcs_hs(struct mdfld_dsi_pkg_sender *sender, + u8 cmd, u32 *data, u16 len); +extern int mdfld_dsi_read_mcs_lp(struct mdfld_dsi_pkg_sender *sender, + u8 cmd, u32 *data, u16 len); + +extern void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender); + +#endif /* __MDFLD_DSI_PKG_SENDER_H__ */ diff --git a/drivers/staging/gma500/mdfld_intel_display.c b/drivers/staging/gma500/mdfld_intel_display.c new file mode 100644 index 000000000000..aa2ff559383d --- /dev/null +++ b/drivers/staging/gma500/mdfld_intel_display.c @@ -0,0 +1,1402 @@ +/* + * Copyright © 2006-2011 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 + */ + +#include "framebuffer.h" +#include "psb_intel_display.h" +#include "mdfld_dsi_dbi.h" +#include "mdfld_dsi_dpi.h" +#include "mdfld_dsi_dbi_dpu.h" + +#include + +#ifdef MIN +#undef MIN +#endif + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + +/* Hardcoded currently */ +static int ksel = KSEL_CRYSTAL_19; + +extern void mdfld_save_display(struct drm_device *dev); +extern bool gbgfxsuspended; + +struct psb_intel_range_t { + int min, max; +}; + +struct mdfld_limit_t { + struct psb_intel_range_t dot, m, p1; +}; + +struct mdfld_intel_clock_t { + /* given values */ + int n; + int m1, m2; + int p1, p2; + /* derived values */ + int dot; + int vco; + int m; + int p; +}; + + + +#define COUNT_MAX 0x10000000 + +void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe) +{ + int count, temp; + u32 pipeconf_reg = PIPEACONF; + + switch (pipe) { + case 0: + break; + case 1: + pipeconf_reg = PIPEBCONF; + break; + case 2: + pipeconf_reg = PIPECCONF; + break; + default: + DRM_ERROR("Illegal Pipe Number. \n"); + return; + } + + /* FIXME JLIU7_PO */ + psb_intel_wait_for_vblank(dev); + return; + + /* Wait for for the pipe disable to take effect. */ + for (count = 0; count < COUNT_MAX; count++) { + temp = REG_READ(pipeconf_reg); + if ((temp & PIPEACONF_PIPE_STATE) == 0) + break; + } +} + +void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe) +{ + int count, temp; + u32 pipeconf_reg = PIPEACONF; + + switch (pipe) { + case 0: + break; + case 1: + pipeconf_reg = PIPEBCONF; + break; + case 2: + pipeconf_reg = PIPECCONF; + break; + default: + dev_err(dev->dev, "Illegal Pipe Number.\n"); + return; + } + + /* FIXME JLIU7_PO */ + psb_intel_wait_for_vblank(dev); + return; + + /* Wait for for the pipe enable to take effect. */ + for (count = 0; count < COUNT_MAX; count++) { + temp = REG_READ(pipeconf_reg); + if ((temp & PIPEACONF_PIPE_STATE) == 1) + break; + } +} + + +static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc, + struct drm_file *file_priv, + uint32_t handle, + uint32_t width, uint32_t height) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + uint32_t control = CURACNTR; + uint32_t base = CURABASE; + uint32_t temp; + size_t addr = 0; + struct gtt_range *gt; + struct drm_gem_object *obj; + int ret; + + switch (pipe) { + case 0: + break; + case 1: + control = CURBCNTR; + base = CURBBASE; + break; + case 2: + control = CURCCNTR; + base = CURCBASE; + break; + default: + dev_err(dev->dev, "Illegal Pipe Number. \n"); + return -EINVAL; + } + +#if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */ + if (pipe != 0) + return 0; +#endif + /* if we want to turn of the cursor ignore width and height */ + if (!handle) { + dev_dbg(dev->dev, "cursor off\n"); + /* turn off the cursor */ + temp = 0; + temp |= CURSOR_MODE_DISABLE; + + if (gma_power_begin(dev, true)) { + REG_WRITE(control, temp); + REG_WRITE(base, 0); + gma_power_end(dev); + } + /* Unpin the old GEM object */ + if (psb_intel_crtc->cursor_obj) { + gt = container_of(psb_intel_crtc->cursor_obj, + struct gtt_range, gem); + psb_gtt_unpin(gt); + drm_gem_object_unreference(psb_intel_crtc->cursor_obj); + psb_intel_crtc->cursor_obj = NULL; + } + return 0; + } + + /* Currently we only support 64x64 cursors */ + if (width != 64 || height != 64) { + DRM_ERROR("we currently only support 64x64 cursors\n"); + return -EINVAL; + } + + obj = drm_gem_object_lookup(dev, file_priv, handle); + if (!obj) + return -ENOENT; + + if (obj->size < width * height * 4) { + dev_dbg(dev->dev, "buffer is to small\n"); + return -ENOMEM; + } + + gt = container_of(obj, struct gtt_range, gem); + + /* Pin the memory into the GTT */ + ret = psb_gtt_pin(gt); + if (ret) { + dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle); + return ret; + } + + + addr = gt->offset; /* Or resource.start ??? */ + + psb_intel_crtc->cursor_addr = addr; + + temp = 0; + /* set the pipe for the cursor */ + temp |= (pipe << 28); + temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + + if (gma_power_begin(dev, true)) { + REG_WRITE(control, temp); + REG_WRITE(base, addr); + gma_power_end(dev); + } + /* unpin the old GEM object */ + if (psb_intel_crtc->cursor_obj) { + gt = container_of(psb_intel_crtc->cursor_obj, + struct gtt_range, gem); + psb_gtt_unpin(gt); + drm_gem_object_unreference(psb_intel_crtc->cursor_obj); + psb_intel_crtc->cursor_obj = obj; + } + return 0; +} + +static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) +{ + struct drm_device *dev = crtc->dev; + struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private; + struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info; + struct psb_drm_dpu_rect rect; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + uint32_t pos = CURAPOS; + uint32_t base = CURABASE; + uint32_t temp = 0; + uint32_t addr; + + switch (pipe) { + case 0: + if (dpu_info) { + rect.x = x; + rect.y = y; + + mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORA, &rect); + mdfld_dpu_exit_dsr(dev); + } else if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_0)) + mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_CURSOR_0); + break; + case 1: + pos = CURBPOS; + base = CURBBASE; + break; + case 2: + if (dpu_info) { + mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORC, &rect); + mdfld_dpu_exit_dsr(dev); + } else if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_2)) + mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_CURSOR_2); + pos = CURCPOS; + base = CURCBASE; + break; + default: + DRM_ERROR("Illegal Pipe Number. \n"); + return -EINVAL; + } + +#if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */ + if (pipe != 0) + return 0; +#endif + if (x < 0) { + temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT); + x = -x; + } + if (y < 0) { + temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT); + y = -y; + } + + temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT); + temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); + + addr = psb_intel_crtc->cursor_addr; + + if (gma_power_begin(dev, true)) { + REG_WRITE(pos, temp); + REG_WRITE(base, addr); + gma_power_end(dev); + } + + return 0; +} + +const struct drm_crtc_funcs mdfld_intel_crtc_funcs = { + .cursor_set = mdfld_intel_crtc_cursor_set, + .cursor_move = mdfld_intel_crtc_cursor_move, + .gamma_set = psb_intel_crtc_gamma_set, + .set_config = drm_crtc_helper_set_config, + .destroy = psb_intel_crtc_destroy, +}; + +static struct drm_device globle_dev; + +void mdfld__intel_plane_set_alpha(int enable) +{ + struct drm_device *dev = &globle_dev; + int dspcntr_reg = DSPACNTR; + u32 dspcntr; + + dspcntr = REG_READ(dspcntr_reg); + + if (enable) { + dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA; + dspcntr |= DISPPLANE_32BPP; + } else { + dspcntr &= ~DISPPLANE_32BPP; + dspcntr |= DISPPLANE_32BPP_NO_ALPHA; + } + + REG_WRITE(dspcntr_reg, dspcntr); +} + +int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) +{ + struct drm_device *dev = crtc->dev; + /* struct drm_i915_master_private *master_priv; */ + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); + int pipe = psb_intel_crtc->pipe; + unsigned long start, offset; + int dsplinoff = DSPALINOFF; + int dspsurf = DSPASURF; + int dspstride = DSPASTRIDE; + int dspcntr_reg = DSPACNTR; + u32 dspcntr; + int ret = 0; + + memcpy(&globle_dev, dev, sizeof(struct drm_device)); + + if (!gma_power_begin(dev, true)) + return 0; + + /* no fb bound */ + if (!crtc->fb) { + dev_err(dev->dev, "No FB bound\n"); + goto psb_intel_pipe_cleaner; + } + + switch (pipe) { + case 0: + dsplinoff = DSPALINOFF; + break; + case 1: + dsplinoff = DSPBLINOFF; + dspsurf = DSPBSURF; + dspstride = DSPBSTRIDE; + dspcntr_reg = DSPBCNTR; + break; + case 2: + dsplinoff = DSPCLINOFF; + dspsurf = DSPCSURF; + dspstride = DSPCSTRIDE; + dspcntr_reg = DSPCCNTR; + break; + default: + dev_err(dev->dev, "Illegal Pipe Number.\n"); + return -EINVAL; + } + + ret = psb_gtt_pin(psbfb->gtt); + if (ret < 0) + goto psb_intel_pipe_set_base_exit; + + start = psbfb->gtt->offset; + offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8); + + REG_WRITE(dspstride, crtc->fb->pitch); + dspcntr = REG_READ(dspcntr_reg); + dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; + + switch (crtc->fb->bits_per_pixel) { + case 8: + dspcntr |= DISPPLANE_8BPP; + break; + case 16: + if (crtc->fb->depth == 15) + dspcntr |= DISPPLANE_15_16BPP; + else + dspcntr |= DISPPLANE_16BPP; + break; + case 24: + case 32: + dspcntr |= DISPPLANE_32BPP_NO_ALPHA; + break; + default: + dev_err(dev->dev, "Unknown color depth\n"); + ret = -EINVAL; + goto psb_intel_pipe_set_base_exit; + } + REG_WRITE(dspcntr_reg, dspcntr); + + dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n", + start, offset, x, y); + + REG_WRITE(dsplinoff, offset); + REG_READ(dsplinoff); + REG_WRITE(dspsurf, start); + REG_READ(dspsurf); + +psb_intel_pipe_cleaner: + /* If there was a previous display we can now unpin it */ + if (old_fb) + psb_gtt_unpin(to_psb_fb(old_fb)->gtt); + +psb_intel_pipe_set_base_exit: + gma_power_end(dev); + return ret; +} + +/** + * Disable the pipe, plane and pll. + * + */ +void mdfld_disable_crtc (struct drm_device *dev, int pipe) +{ + int dpll_reg = MRST_DPLL_A; + int dspcntr_reg = DSPACNTR; + int dspbase_reg = MRST_DSPABASE; + int pipeconf_reg = PIPEACONF; + u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG; + u32 temp; + + switch (pipe) { + case 0: + break; + case 1: + dpll_reg = MDFLD_DPLL_B; + dspcntr_reg = DSPBCNTR; + dspbase_reg = DSPBSURF; + pipeconf_reg = PIPEBCONF; + break; + case 2: + dpll_reg = MRST_DPLL_A; + dspcntr_reg = DSPCCNTR; + dspbase_reg = MDFLD_DSPCBASE; + pipeconf_reg = PIPECCONF; + gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET; + break; + default: + dev_err(dev->dev, "Illegal Pipe Number. \n"); + return; + } + + if (pipe != 1) + mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY); + + /* Disable display plane */ + temp = REG_READ(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) != 0) { + REG_WRITE(dspcntr_reg, + temp & ~DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + REG_READ(dspbase_reg); + } + + /* FIXME_JLIU7 MDFLD_PO revisit */ + /* Wait for vblank for the disable to take effect */ +// MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev); + + /* Next, disable display pipes */ + temp = REG_READ(pipeconf_reg); + if ((temp & PIPEACONF_ENABLE) != 0) { + temp &= ~PIPEACONF_ENABLE; + temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF; + REG_WRITE(pipeconf_reg, temp); + REG_READ(pipeconf_reg); + + /* Wait for for the pipe disable to take effect. */ + mdfldWaitForPipeDisable(dev, pipe); + } + + temp = REG_READ(dpll_reg); + if (temp & DPLL_VCO_ENABLE) { + if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE)) + || (pipe == 1)){ + temp &= ~(DPLL_VCO_ENABLE); + REG_WRITE(dpll_reg, temp); + REG_READ(dpll_reg); + /* Wait for the clocks to turn off. */ + /* FIXME_MDFLD PO may need more delay */ + udelay(500); + + if (!(temp & MDFLD_PWR_GATE_EN)) { + /* gating power of DPLL */ + REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN); + /* FIXME_MDFLD PO - change 500 to 1 after PO */ + udelay(5000); + } + } + } + +} + +/** + * Sets the power management mode of the pipe and plane. + * + * This code should probably grow support for turning the cursor off and back + * on appropriately at the same time as we're turning the pipe off/on. + */ +static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) +{ + struct drm_device *dev = crtc->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + int pipe = psb_intel_crtc->pipe; + int dpll_reg = MRST_DPLL_A; + int dspcntr_reg = DSPACNTR; + int dspbase_reg = MRST_DSPABASE; + int pipeconf_reg = PIPEACONF; + u32 pipestat_reg = PIPEASTAT; + u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG; + u32 pipeconf = dev_priv->pipeconf; + u32 dspcntr = dev_priv->dspcntr; + u32 mipi_enable_reg = MIPIA_DEVICE_READY_REG; + u32 temp; + bool enabled; + int timeout = 0; + + if (!gma_power_begin(dev, true)) + return; + + /* Ignore if system is already in DSR and in suspended state. */ + if(/*gbgfxsuspended */0 && dev_priv->dispstatus == false && mode == 3){ + if(dev_priv->rpm_enabled && pipe == 1){ + // dev_priv->is_mipi_on = false; + pm_request_idle(&dev->pdev->dev); + } + return; + }else if(mode == 0) { + //do not need to set gbdispstatus=true in crtc. + //this will be set in encoder such as mdfld_dsi_dbi_dpms + //gbdispstatus = true; + } + + +/* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */ +/* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */ + + switch (pipe) { + case 0: + break; + case 1: + dpll_reg = DPLL_B; + dspcntr_reg = DSPBCNTR; + dspbase_reg = MRST_DSPBBASE; + pipeconf_reg = PIPEBCONF; + pipeconf = dev_priv->pipeconf1; + dspcntr = dev_priv->dspcntr1; + dpll_reg = MDFLD_DPLL_B; + break; + case 2: + dpll_reg = MRST_DPLL_A; + dspcntr_reg = DSPCCNTR; + dspbase_reg = MDFLD_DSPCBASE; + pipeconf_reg = PIPECCONF; + pipestat_reg = PIPECSTAT; + pipeconf = dev_priv->pipeconf2; + dspcntr = dev_priv->dspcntr2; + gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET; + mipi_enable_reg = MIPIA_DEVICE_READY_REG + MIPIC_REG_OFFSET; + break; + default: + dev_err(dev->dev, "Illegal Pipe Number.\n"); + return; + } + + /* XXX: When our outputs are all unaware of DPMS modes other than off + * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. + */ + switch (mode) { + case DRM_MODE_DPMS_ON: + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + /* Enable the DPLL */ + temp = REG_READ(dpll_reg); + + if ((temp & DPLL_VCO_ENABLE) == 0) { + /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */ + if (temp & MDFLD_PWR_GATE_EN) { + temp &= ~MDFLD_PWR_GATE_EN; + REG_WRITE(dpll_reg, temp); + /* FIXME_MDFLD PO - change 500 to 1 after PO */ + udelay(500); + } + + REG_WRITE(dpll_reg, temp); + REG_READ(dpll_reg); + /* FIXME_MDFLD PO - change 500 to 1 after PO */ + udelay(500); + + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); + + /** + * wait for DSI PLL to lock + * NOTE: only need to poll status of pipe 0 and pipe 1, + * since both MIPI pipes share the same PLL. + */ + while ((pipe != 2) && (timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) { + udelay(150); + timeout ++; + } + } + + /* Enable the plane */ + temp = REG_READ(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) == 0) { + REG_WRITE(dspcntr_reg, + temp | DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + } + + /* Enable the pipe */ + temp = REG_READ(pipeconf_reg); + if ((temp & PIPEACONF_ENABLE) == 0) { + REG_WRITE(pipeconf_reg, pipeconf); + + /* Wait for for the pipe enable to take effect. */ + mdfldWaitForPipeEnable(dev, pipe); + } + + /*workaround for sighting 3741701 Random X blank display*/ + /*perform w/a in video mode only on pipe A or C*/ + if ((pipe == 0 || pipe == 2) && + (mdfld_panel_dpi(dev) == true)) { + REG_WRITE(pipestat_reg, REG_READ(pipestat_reg)); + msleep(100); + if(PIPE_VBLANK_STATUS & REG_READ(pipestat_reg)) { + printk(KERN_ALERT "OK"); + } else { + printk(KERN_ALERT "STUCK!!!!"); + /*shutdown controller*/ + temp = REG_READ(dspcntr_reg); + REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + /*mdfld_dsi_dpi_shut_down(dev, pipe);*/ + REG_WRITE(0xb048, 1); + msleep(100); + temp = REG_READ(pipeconf_reg); + temp &= ~PIPEACONF_ENABLE; + REG_WRITE(pipeconf_reg, temp); + msleep(100); /*wait for pipe disable*/ + /*printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008)); + printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));*/ + REG_WRITE(mipi_enable_reg, 0); + msleep(100); + printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008)); + printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074)); + REG_WRITE(0xb004, REG_READ(0xb004)); + /* try to bring the controller back up again*/ + REG_WRITE(mipi_enable_reg, 1); + temp = REG_READ(dspcntr_reg); + REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + /*mdfld_dsi_dpi_turn_on(dev, pipe);*/ + REG_WRITE(0xb048, 2); + msleep(100); + temp = REG_READ(pipeconf_reg); + temp |= PIPEACONF_ENABLE; + REG_WRITE(pipeconf_reg, temp); + } + } + + psb_intel_crtc_load_lut(crtc); + + /* Give the overlay scaler a chance to enable + if it's on this pipe */ + /* psb_intel_crtc_dpms_video(crtc, true); TODO */ + + break; + case DRM_MODE_DPMS_OFF: + /* Give the overlay scaler a chance to disable + * if it's on this pipe */ + /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ + if (pipe != 1) + mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY); + + /* Disable the VGA plane that we never use */ + REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); + + /* Disable display plane */ + temp = REG_READ(dspcntr_reg); + if ((temp & DISPLAY_PLANE_ENABLE) != 0) { + REG_WRITE(dspcntr_reg, + temp & ~DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + REG_READ(dspbase_reg); + } + + /* FIXME_JLIU7 MDFLD_PO revisit */ + /* Wait for vblank for the disable to take effect */ +// MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev); + + /* Next, disable display pipes */ + temp = REG_READ(pipeconf_reg); + if ((temp & PIPEACONF_ENABLE) != 0) { + temp &= ~PIPEACONF_ENABLE; + temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF; + REG_WRITE(pipeconf_reg, temp); +// REG_WRITE(pipeconf_reg, 0); + REG_READ(pipeconf_reg); + + /* Wait for for the pipe disable to take effect. */ + mdfldWaitForPipeDisable(dev, pipe); + } + + temp = REG_READ(dpll_reg); + if (temp & DPLL_VCO_ENABLE) { + if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE)) + || (pipe == 1)){ + temp &= ~(DPLL_VCO_ENABLE); + REG_WRITE(dpll_reg, temp); + REG_READ(dpll_reg); + /* Wait for the clocks to turn off. */ + /* FIXME_MDFLD PO may need more delay */ + udelay(500); +#if 0 /* MDFLD_PO_JLIU7 */ + if (!(temp & MDFLD_PWR_GATE_EN)) { + /* gating power of DPLL */ + REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN); + /* FIXME_MDFLD PO - change 500 to 1 after PO */ + udelay(5000); + } +#endif /* MDFLD_PO_JLIU7 */ + } + } + break; + } + + enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF; + +#if 0 /* JB: Add vblank support later */ + if (enabled) + dev_priv->vblank_pipe |= (1 << pipe); + else + dev_priv->vblank_pipe &= ~(1 << pipe); +#endif + + gma_power_end(dev); +} + + +#define MDFLD_LIMT_DPLL_19 0 +#define MDFLD_LIMT_DPLL_25 1 +#define MDFLD_LIMT_DPLL_83 2 +#define MDFLD_LIMT_DPLL_100 3 +#define MDFLD_LIMT_DSIPLL_19 4 +#define MDFLD_LIMT_DSIPLL_25 5 +#define MDFLD_LIMT_DSIPLL_83 6 +#define MDFLD_LIMT_DSIPLL_100 7 + +#define MDFLD_DOT_MIN 19750 /* FIXME_MDFLD JLIU7 need to find out min & max for MDFLD */ +#define MDFLD_DOT_MAX 120000 +#define MDFLD_DPLL_M_MIN_19 113 +#define MDFLD_DPLL_M_MAX_19 155 +#define MDFLD_DPLL_P1_MIN_19 2 +#define MDFLD_DPLL_P1_MAX_19 10 +#define MDFLD_DPLL_M_MIN_25 101 +#define MDFLD_DPLL_M_MAX_25 130 +#define MDFLD_DPLL_P1_MIN_25 2 +#define MDFLD_DPLL_P1_MAX_25 10 +#define MDFLD_DPLL_M_MIN_83 64 +#define MDFLD_DPLL_M_MAX_83 64 +#define MDFLD_DPLL_P1_MIN_83 2 +#define MDFLD_DPLL_P1_MAX_83 2 +#define MDFLD_DPLL_M_MIN_100 64 +#define MDFLD_DPLL_M_MAX_100 64 +#define MDFLD_DPLL_P1_MIN_100 2 +#define MDFLD_DPLL_P1_MAX_100 2 +#define MDFLD_DSIPLL_M_MIN_19 131 +#define MDFLD_DSIPLL_M_MAX_19 175 +#define MDFLD_DSIPLL_P1_MIN_19 3 +#define MDFLD_DSIPLL_P1_MAX_19 8 +#define MDFLD_DSIPLL_M_MIN_25 97 +#define MDFLD_DSIPLL_M_MAX_25 140 +#define MDFLD_DSIPLL_P1_MIN_25 3 +#define MDFLD_DSIPLL_P1_MAX_25 9 +#define MDFLD_DSIPLL_M_MIN_83 33 +#define MDFLD_DSIPLL_M_MAX_83 92 +#define MDFLD_DSIPLL_P1_MIN_83 2 +#define MDFLD_DSIPLL_P1_MAX_83 3 +#define MDFLD_DSIPLL_M_MIN_100 97 +#define MDFLD_DSIPLL_M_MAX_100 140 +#define MDFLD_DSIPLL_P1_MIN_100 3 +#define MDFLD_DSIPLL_P1_MAX_100 9 + +static const struct mdfld_limit_t mdfld_limits[] = { + { /* MDFLD_LIMT_DPLL_19 */ + .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, + .m = {.min = MDFLD_DPLL_M_MIN_19, .max = MDFLD_DPLL_M_MAX_19}, + .p1 = {.min = MDFLD_DPLL_P1_MIN_19, .max = MDFLD_DPLL_P1_MAX_19}, + }, + { /* MDFLD_LIMT_DPLL_25 */ + .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, + .m = {.min = MDFLD_DPLL_M_MIN_25, .max = MDFLD_DPLL_M_MAX_25}, + .p1 = {.min = MDFLD_DPLL_P1_MIN_25, .max = MDFLD_DPLL_P1_MAX_25}, + }, + { /* MDFLD_LIMT_DPLL_83 */ + .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, + .m = {.min = MDFLD_DPLL_M_MIN_83, .max = MDFLD_DPLL_M_MAX_83}, + .p1 = {.min = MDFLD_DPLL_P1_MIN_83, .max = MDFLD_DPLL_P1_MAX_83}, + }, + { /* MDFLD_LIMT_DPLL_100 */ + .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, + .m = {.min = MDFLD_DPLL_M_MIN_100, .max = MDFLD_DPLL_M_MAX_100}, + .p1 = {.min = MDFLD_DPLL_P1_MIN_100, .max = MDFLD_DPLL_P1_MAX_100}, + }, + { /* MDFLD_LIMT_DSIPLL_19 */ + .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, + .m = {.min = MDFLD_DSIPLL_M_MIN_19, .max = MDFLD_DSIPLL_M_MAX_19}, + .p1 = {.min = MDFLD_DSIPLL_P1_MIN_19, .max = MDFLD_DSIPLL_P1_MAX_19}, + }, + { /* MDFLD_LIMT_DSIPLL_25 */ + .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, + .m = {.min = MDFLD_DSIPLL_M_MIN_25, .max = MDFLD_DSIPLL_M_MAX_25}, + .p1 = {.min = MDFLD_DSIPLL_P1_MIN_25, .max = MDFLD_DSIPLL_P1_MAX_25}, + }, + { /* MDFLD_LIMT_DSIPLL_83 */ + .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, + .m = {.min = MDFLD_DSIPLL_M_MIN_83, .max = MDFLD_DSIPLL_M_MAX_83}, + .p1 = {.min = MDFLD_DSIPLL_P1_MIN_83, .max = MDFLD_DSIPLL_P1_MAX_83}, + }, + { /* MDFLD_LIMT_DSIPLL_100 */ + .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX}, + .m = {.min = MDFLD_DSIPLL_M_MIN_100, .max = MDFLD_DSIPLL_M_MAX_100}, + .p1 = {.min = MDFLD_DSIPLL_P1_MIN_100, .max = MDFLD_DSIPLL_P1_MAX_100}, + }, +}; + +#define MDFLD_M_MIN 21 +#define MDFLD_M_MAX 180 +static const u32 mdfld_m_converts[] = { +/* M configuration table from 9-bit LFSR table */ + 224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */ + 173, 342, 171, 85, 298, 149, 74, 37, 18, 265, /* 31 - 40 */ + 388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */ + 83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */ + 341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */ + 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */ + 106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */ + 71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */ + 253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */ + 478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */ + 477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */ + 210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */ + 145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */ + 380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */ + 103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */ + 396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */ +}; + +static const struct mdfld_limit_t *mdfld_limit(struct drm_crtc *crtc) +{ + const struct mdfld_limit_t *limit = NULL; + struct drm_device *dev = crtc->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + + if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI) + || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI2)) { + if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) + limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_19]; + else if (ksel == KSEL_BYPASS_25) + limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_25]; + else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166)) + limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_83]; + else if ((ksel == KSEL_BYPASS_83_100) && + (dev_priv->core_freq == 100 || dev_priv->core_freq == 200)) + limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_100]; + } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { + if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) + limit = &mdfld_limits[MDFLD_LIMT_DPLL_19]; + else if (ksel == KSEL_BYPASS_25) + limit = &mdfld_limits[MDFLD_LIMT_DPLL_25]; + else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166)) + limit = &mdfld_limits[MDFLD_LIMT_DPLL_83]; + else if ((ksel == KSEL_BYPASS_83_100) && + (dev_priv->core_freq == 100 || dev_priv->core_freq == 200)) + limit = &mdfld_limits[MDFLD_LIMT_DPLL_100]; + } else { + limit = NULL; + dev_err(dev->dev, "mdfld_limit Wrong display type.\n"); + } + + return limit; +} + +/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ +static void mdfld_clock(int refclk, struct mdfld_intel_clock_t *clock) +{ + clock->dot = (refclk * clock->m) / clock->p1; +} + +/** + * Returns a set of divisors for the desired target clock with the given refclk, + * or FALSE. Divisor values are the actual divisors for + */ +static bool +mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk, + struct mdfld_intel_clock_t *best_clock) +{ + struct mdfld_intel_clock_t clock; + const struct mdfld_limit_t *limit = mdfld_limit(crtc); + int err = target; + + memset(best_clock, 0, sizeof(*best_clock)); + + for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) { + for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max; + clock.p1++) { + int this_err; + + mdfld_clock(refclk, &clock); + + this_err = abs(clock.dot - target); + if (this_err < err) { + *best_clock = clock; + err = this_err; + } + } + } + return err != target; +} + +/** + * Return the pipe currently connected to the panel fitter, + * or -1 if the panel fitter is not present or not in use + */ +static int mdfld_panel_fitter_pipe(struct drm_device *dev) +{ + u32 pfit_control; + + pfit_control = REG_READ(PFIT_CONTROL); + + /* See if the panel fitter is in use */ + if ((pfit_control & PFIT_ENABLE) == 0) + return -1; + return (pfit_control >> 29) & 3; +} + +static int mdfld_crtc_mode_set(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, + int x, int y, + struct drm_framebuffer *old_fb) +{ + struct drm_device *dev = crtc->dev; + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct drm_psb_private *dev_priv = dev->dev_private; + int pipe = psb_intel_crtc->pipe; + int fp_reg = MRST_FPA0; + int dpll_reg = MRST_DPLL_A; + int dspcntr_reg = DSPACNTR; + int pipeconf_reg = PIPEACONF; + int htot_reg = HTOTAL_A; + int hblank_reg = HBLANK_A; + int hsync_reg = HSYNC_A; + int vtot_reg = VTOTAL_A; + int vblank_reg = VBLANK_A; + int vsync_reg = VSYNC_A; + int dspsize_reg = DSPASIZE; + int dsppos_reg = DSPAPOS; + int pipesrc_reg = PIPEASRC; + u32 *pipeconf = &dev_priv->pipeconf; + u32 *dspcntr = &dev_priv->dspcntr; + int refclk = 0; + int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0, clk_tmp = 0; + struct mdfld_intel_clock_t clock; + bool ok; + u32 dpll = 0, fp = 0; + bool is_crt = false, is_lvds = false, is_tv = false; + bool is_mipi = false, is_mipi2 = false, is_hdmi = false; + struct drm_mode_config *mode_config = &dev->mode_config; + struct psb_intel_output *psb_intel_output = NULL; + uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; + struct drm_encoder *encoder; + struct drm_connector *connector; + int timeout = 0; + + dev_dbg(dev->dev, "pipe = 0x%x \n", pipe); + + switch (pipe) { + case 0: + break; + case 1: + fp_reg = FPB0; + dpll_reg = DPLL_B; + dspcntr_reg = DSPBCNTR; + pipeconf_reg = PIPEBCONF; + htot_reg = HTOTAL_B; + hblank_reg = HBLANK_B; + hsync_reg = HSYNC_B; + vtot_reg = VTOTAL_B; + vblank_reg = VBLANK_B; + vsync_reg = VSYNC_B; + dspsize_reg = DSPBSIZE; + dsppos_reg = DSPBPOS; + pipesrc_reg = PIPEBSRC; + pipeconf = &dev_priv->pipeconf1; + dspcntr = &dev_priv->dspcntr1; + fp_reg = MDFLD_DPLL_DIV0; + dpll_reg = MDFLD_DPLL_B; + break; + case 2: + dpll_reg = MRST_DPLL_A; + dspcntr_reg = DSPCCNTR; + pipeconf_reg = PIPECCONF; + htot_reg = HTOTAL_C; + hblank_reg = HBLANK_C; + hsync_reg = HSYNC_C; + vtot_reg = VTOTAL_C; + vblank_reg = VBLANK_C; + vsync_reg = VSYNC_C; + dspsize_reg = DSPCSIZE; + dsppos_reg = DSPCPOS; + pipesrc_reg = PIPECSRC; + pipeconf = &dev_priv->pipeconf2; + dspcntr = &dev_priv->dspcntr2; + break; + default: + DRM_ERROR("Illegal Pipe Number. \n"); + return 0; + } + + dev_dbg(dev->dev, "adjusted_hdisplay = %d\n", + adjusted_mode->hdisplay); + dev_dbg(dev->dev, "adjusted_vdisplay = %d\n", + adjusted_mode->vdisplay); + dev_dbg(dev->dev, "adjusted_hsync_start = %d\n", + adjusted_mode->hsync_start); + dev_dbg(dev->dev, "adjusted_hsync_end = %d\n", + adjusted_mode->hsync_end); + dev_dbg(dev->dev, "adjusted_htotal = %d\n", + adjusted_mode->htotal); + dev_dbg(dev->dev, "adjusted_vsync_start = %d\n", + adjusted_mode->vsync_start); + dev_dbg(dev->dev, "adjusted_vsync_end = %d\n", + adjusted_mode->vsync_end); + dev_dbg(dev->dev, "adjusted_vtotal = %d\n", + adjusted_mode->vtotal); + dev_dbg(dev->dev, "adjusted_clock = %d\n", + adjusted_mode->clock); + dev_dbg(dev->dev, "hdisplay = %d\n", + mode->hdisplay); + dev_dbg(dev->dev, "vdisplay = %d\n", + mode->vdisplay); + + if (!gma_power_begin(dev, true)) + return 0; + + memcpy(&psb_intel_crtc->saved_mode, mode, sizeof(struct drm_display_mode)); + memcpy(&psb_intel_crtc->saved_adjusted_mode, adjusted_mode, sizeof(struct drm_display_mode)); + + list_for_each_entry(connector, &mode_config->connector_list, head) { + + encoder = connector->encoder; + + if(!encoder) + continue; + + if (encoder->crtc != crtc) + continue; + + psb_intel_output = to_psb_intel_output(connector); + + dev_dbg(dev->dev, "output->type = 0x%x \n", psb_intel_output->type); + + switch (psb_intel_output->type) { + case INTEL_OUTPUT_LVDS: + is_lvds = true; + break; + case INTEL_OUTPUT_TVOUT: + is_tv = true; + break; + case INTEL_OUTPUT_ANALOG: + is_crt = true; + break; + case INTEL_OUTPUT_MIPI: + is_mipi = true; + break; + case INTEL_OUTPUT_MIPI2: + is_mipi2 = true; + break; + case INTEL_OUTPUT_HDMI: + is_hdmi = true; + break; + } + } + + /* Disable the VGA plane that we never use */ + REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); + + /* Disable the panel fitter if it was on our pipe */ + if (mdfld_panel_fitter_pipe(dev) == pipe) + REG_WRITE(PFIT_CONTROL, 0); + + /* pipesrc and dspsize control the size that is scaled from, + * which should always be the user's requested size. + */ + if (pipe == 1) { + /* FIXME: To make HDMI display with 864x480 (TPO), 480x864 (PYR) or 480x854 (TMD), set the sprite + * width/height and souce image size registers with the adjusted mode for pipe B. */ + + /* The defined sprite rectangle must always be completely contained within the displayable + * area of the screen image (frame buffer). */ + REG_WRITE(dspsize_reg, ((MIN(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16) + | (MIN(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1)); + /* Set the CRTC with encoder mode. */ + REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) + | (mode->crtc_vdisplay - 1)); + } else { + REG_WRITE(dspsize_reg, ((mode->crtc_vdisplay - 1) << 16) | (mode->crtc_hdisplay - 1)); + REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); + } + + REG_WRITE(dsppos_reg, 0); + + if (psb_intel_output) + drm_connector_property_get_value(&psb_intel_output->base, + dev->mode_config.scaling_mode_property, &scalingType); + + if (scalingType == DRM_MODE_SCALE_NO_SCALE) { + /*Moorestown doesn't have register support for centering so we need to + mess with the h/vblank and h/vsync start and ends to get centering*/ + int offsetX = 0, offsetY = 0; + + offsetX = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; + offsetY = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; + + REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) | + ((adjusted_mode->crtc_htotal - 1) << 16)); + REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) | + ((adjusted_mode->crtc_vtotal - 1) << 16)); + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - offsetX - 1) | + ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16)); + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - offsetX - 1) | + ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16)); + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - offsetY - 1) | + ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16)); + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - offsetY - 1) | + ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16)); + } else { + REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | + ((adjusted_mode->crtc_htotal - 1) << 16)); + REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | + ((adjusted_mode->crtc_vtotal - 1) << 16)); + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | + ((adjusted_mode->crtc_hblank_end - 1) << 16)); + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | + ((adjusted_mode->crtc_hsync_end - 1) << 16)); + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | + ((adjusted_mode->crtc_vblank_end - 1) << 16)); + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | + ((adjusted_mode->crtc_vsync_end - 1) << 16)); + } + + /* Flush the plane changes */ + { + struct drm_crtc_helper_funcs *crtc_funcs = + crtc->helper_private; + crtc_funcs->mode_set_base(crtc, x, y, old_fb); + } + + /* setup pipeconf */ + *pipeconf = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */ + + /* Set up the display plane register */ + *dspcntr = REG_READ(dspcntr_reg); + *dspcntr |= pipe << DISPPLANE_SEL_PIPE_POS; + *dspcntr |= DISPLAY_PLANE_ENABLE; +/* MDFLD_PO_JLIU7 dspcntr |= DISPPLANE_BOTTOM; */ +/* MDFLD_PO_JLIU7 dspcntr |= DISPPLANE_GAMMA_ENABLE; */ + + if (is_mipi2) + { + goto mrst_crtc_mode_set_exit; + } +/* FIXME JLIU7 Add MDFLD HDMI supports */ +/* FIXME_MDFLD JLIU7 DSIPLL clock *= 8? */ +/* FIXME_MDFLD JLIU7 need to revist for dual MIPI supports */ + clk = adjusted_mode->clock; + + if (is_hdmi) { + if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) + { + refclk = 19200; + + if (is_mipi || is_mipi2) + { + clk_n = 1, clk_p2 = 8; + } else if (is_hdmi) { + clk_n = 1, clk_p2 = 10; + } + } else if (ksel == KSEL_BYPASS_25) { + refclk = 25000; + + if (is_mipi || is_mipi2) + { + clk_n = 1, clk_p2 = 8; + } else if (is_hdmi) { + clk_n = 1, clk_p2 = 10; + } + } else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166)) { + refclk = 83000; + + if (is_mipi || is_mipi2) + { + clk_n = 4, clk_p2 = 8; + } else if (is_hdmi) { + clk_n = 4, clk_p2 = 10; + } + } else if ((ksel == KSEL_BYPASS_83_100) && + (dev_priv->core_freq == 100 || dev_priv->core_freq == 200)) { + refclk = 100000; + if (is_mipi || is_mipi2) + { + clk_n = 4, clk_p2 = 8; + } else if (is_hdmi) { + clk_n = 4, clk_p2 = 10; + } + } + + if (is_mipi) + clk_byte = dev_priv->bpp / 8; + else if (is_mipi2) + clk_byte = dev_priv->bpp2 / 8; + + clk_tmp = clk * clk_n * clk_p2 * clk_byte; + + dev_dbg(dev->dev, "clk = %d, clk_n = %d, clk_p2 = %d. \n", clk, clk_n, clk_p2); + dev_dbg(dev->dev, "adjusted_mode->clock = %d, clk_tmp = %d. \n", adjusted_mode->clock, clk_tmp); + + ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock); + + if (!ok) { + dev_err(dev->dev, + "mdfldFindBestPLL fail in mdfld_crtc_mode_set. \n"); + } else { + m_conv = mdfld_m_converts[(clock.m - MDFLD_M_MIN)]; + + dev_dbg(dev->dev, "dot clock = %d," + "m = %d, p1 = %d, m_conv = %d. \n", clock.dot, clock.m, + clock.p1, m_conv); + } + + dpll = REG_READ(dpll_reg); + + if (dpll & DPLL_VCO_ENABLE) { + dpll &= ~DPLL_VCO_ENABLE; + REG_WRITE(dpll_reg, dpll); + REG_READ(dpll_reg); + + /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */ + /* FIXME_MDFLD PO - change 500 to 1 after PO */ + udelay(500); + + /* reset M1, N1 & P1 */ + REG_WRITE(fp_reg, 0); + dpll &= ~MDFLD_P1_MASK; + REG_WRITE(dpll_reg, dpll); + /* FIXME_MDFLD PO - change 500 to 1 after PO */ + udelay(500); + } + + /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */ + if (dpll & MDFLD_PWR_GATE_EN) { + dpll &= ~MDFLD_PWR_GATE_EN; + REG_WRITE(dpll_reg, dpll); + /* FIXME_MDFLD PO - change 500 to 1 after PO */ + udelay(500); + } + + dpll = 0; + +#if 0 /* FIXME revisit later */ + if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19) || (ksel == KSEL_BYPASS_25)) { + dpll &= ~MDFLD_INPUT_REF_SEL; + } else if (ksel == KSEL_BYPASS_83_100) { + dpll |= MDFLD_INPUT_REF_SEL; + } +#endif /* FIXME revisit later */ + + if (is_hdmi) + dpll |= MDFLD_VCO_SEL; + + fp = (clk_n / 2) << 16; + fp |= m_conv; + + /* compute bitmask from p1 value */ + dpll |= (1 << (clock.p1 - 2)) << 17; + +#if 0 /* 1080p30 & 720p */ + dpll = 0x00050000; + fp = 0x000001be; +#endif +#if 0 /* 480p */ + dpll = 0x02010000; + fp = 0x000000d2; +#endif + } else { +#if 0 /*DBI_TPO_480x864*/ + dpll = 0x00020000; + fp = 0x00000156; +#endif /* DBI_TPO_480x864 */ /* get from spec. */ + + dpll = 0x00800000; + fp = 0x000000c1; +} + + REG_WRITE(fp_reg, fp); + REG_WRITE(dpll_reg, dpll); + /* FIXME_MDFLD PO - change 500 to 1 after PO */ + udelay(500); + + dpll |= DPLL_VCO_ENABLE; + REG_WRITE(dpll_reg, dpll); + REG_READ(dpll_reg); + + /* wait for DSI PLL to lock */ + while ((timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) { + udelay(150); + timeout ++; + } + + if (is_mipi) + goto mrst_crtc_mode_set_exit; + + dev_dbg(dev->dev, "is_mipi = 0x%x \n", is_mipi); + + REG_WRITE(pipeconf_reg, *pipeconf); + REG_READ(pipeconf_reg); + + /* Wait for for the pipe enable to take effect. */ +//FIXME_JLIU7 HDMI mrstWaitForPipeEnable(dev); + + REG_WRITE(dspcntr_reg, *dspcntr); + psb_intel_wait_for_vblank(dev); + +mrst_crtc_mode_set_exit: + + gma_power_end(dev); + + return 0; +} + +static void mdfld_crtc_prepare(struct drm_crtc *crtc) +{ + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); +} + +static void mdfld_crtc_commit(struct drm_crtc *crtc) +{ + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); +} + +static bool mdfld_crtc_mode_fixup(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +const struct drm_crtc_helper_funcs mdfld_helper_funcs = { + .dpms = mdfld_crtc_dpms, + .mode_fixup = mdfld_crtc_mode_fixup, + .mode_set = mdfld_crtc_mode_set, + .mode_set_base = mdfld__intel_pipe_set_base, + .prepare = mdfld_crtc_prepare, + .commit = mdfld_crtc_commit, +}; diff --git a/drivers/staging/gma500/mdfld_msic.h b/drivers/staging/gma500/mdfld_msic.h new file mode 100644 index 000000000000..a7ad65472491 --- /dev/null +++ b/drivers/staging/gma500/mdfld_msic.h @@ -0,0 +1,31 @@ +/* + * Copyright © 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: + * Jim Liu + */ + +#define MSIC_PCI_DEVICE_ID 0x831 + +int msic_regsiter_driver(void); +int msic_unregister_driver(void); +extern void hpd_notify_um(void); diff --git a/drivers/staging/gma500/mdfld_output.c b/drivers/staging/gma500/mdfld_output.c new file mode 100644 index 000000000000..ee55f87ba1fd --- /dev/null +++ b/drivers/staging/gma500/mdfld_output.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 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, sublicensen + * 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: + * Thomas Eaton + * Scott Rowe +*/ + +#include +#include "mdfld_dsi_dbi.h" +#include "mdfld_dsi_dpi.h" +#include "mdfld_dsi_output.h" +#include "mdfld_output.h" +#include "mdfld_dsi_dbi_dpu.h" + +#include "displays/tpo_cmd.h" +#include "displays/tpo_vid.h" +#include "displays/tmd_cmd.h" +#include "displays/tmd_vid.h" +#include "displays/pyr_cmd.h" +#include "displays/pyr_vid.h" +/* #include "displays/hdmi.h" */ + +static int mdfld_dual_mipi; +static int mdfld_hdmi; +static int mdfld_dpu; + +module_param(mdfld_dual_mipi, int, 0600); +MODULE_PARM_DESC(mdfld_dual_mipi, "Enable dual MIPI configuration"); +module_param(mdfld_hdmi, int, 0600); +MODULE_PARM_DESC(mdfld_hdmi, "Enable Medfield HDMI"); +module_param(mdfld_dpu, int, 0600); +MODULE_PARM_DESC(mdfld_dpu, "Enable Medfield DPU"); + +/* For now a single type per device is all we cope with */ +int mdfld_get_panel_type(struct drm_device *dev, int pipe) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + return dev_priv->panel_id; +} + +int mdfld_panel_dpi(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + + switch (dev_priv->panel_id) { + case TMD_VID: + case TPO_VID: + case PYR_VID: + return true; + case TMD_CMD: + case TPO_CMD: + case PYR_CMD: + default: + return false; + } +} + +static int init_panel(struct drm_device *dev, int mipi_pipe, int p_type) +{ + struct panel_funcs *p_cmd_funcs; + struct panel_funcs *p_vid_funcs; + + /* Oh boy ... FIXME */ + p_cmd_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL); + if (p_cmd_funcs == NULL) + return -ENODEV; + p_vid_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL); + if (p_vid_funcs == NULL) { + kfree(p_cmd_funcs); + return -ENODEV; + } + + switch (p_type) { + case TPO_CMD: + tpo_cmd_init(dev, p_cmd_funcs); + mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL); + break; + case TPO_VID: + tpo_vid_init(dev, p_vid_funcs); + mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs); + break; + case TMD_CMD: + /*tmd_cmd_init(dev, p_cmd_funcs); */ + mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL); + break; + case TMD_VID: + tmd_vid_init(dev, p_vid_funcs); + mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs); + break; + case PYR_CMD: + pyr_cmd_init(dev, p_cmd_funcs); + mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL); + break; + case PYR_VID: + mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs); + break; + case TPO: /* TPO panel supports both cmd & vid interfaces */ + tpo_cmd_init(dev, p_cmd_funcs); + tpo_vid_init(dev, p_vid_funcs); + mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, + p_vid_funcs); + break; + case TMD: + break; + case PYR: + break; +#if 0 + case HDMI: + dev_dbg(dev->dev, "Initializing HDMI"); + mdfld_hdmi_init(dev, &dev_priv->mode_dev); + break; +#endif + default: + dev_err(dev->dev, "Unsupported interface %d", p_type); + return -ENODEV; + } + return 0; +} + +int mdfld_output_init(struct drm_device *dev) +{ + int type; + + /* MIPI panel 1 */ + type = mdfld_get_panel_type(dev, 0); + dev_info(dev->dev, "panel 1: type is %d\n", type); + init_panel(dev, 0, type); + + if (mdfld_dual_mipi) { + /* MIPI panel 2 */ + type = mdfld_get_panel_type(dev, 2); + dev_info(dev->dev, "panel 2: type is %d\n", type); + init_panel(dev, 2, type); + } + if (mdfld_hdmi) + /* HDMI panel */ + init_panel(dev, 0, HDMI); + return 0; +} + +void mdfld_output_setup(struct drm_device *dev) +{ + /* FIXME: this is not the right place for this stuff ! */ + if (IS_MFLD(dev)) { + if (mdfld_dpu) + mdfld_dbi_dpu_init(dev); + else + mdfld_dbi_dsr_init(dev); + } +} \ No newline at end of file diff --git a/drivers/staging/gma500/mdfld_output.h b/drivers/staging/gma500/mdfld_output.h new file mode 100644 index 000000000000..daf33e7df9d5 --- /dev/null +++ b/drivers/staging/gma500/mdfld_output.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 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, sublicensen + * 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: + * Thomas Eaton + * Scott Rowe +*/ + +#ifndef MDFLD_OUTPUT_H +#define MDFLD_OUTPUT_H + +int mdfld_output_init(struct drm_device *dev); +int mdfld_panel_dpi(struct drm_device *dev); +int mdfld_get_panel_type(struct drm_device *dev, int pipe); +void mdfld_disable_crtc (struct drm_device *dev, int pipe); + +extern const struct drm_crtc_helper_funcs mdfld_helper_funcs; +extern const struct drm_crtc_funcs mdfld_intel_crtc_funcs; + +extern void mdfld_output_setup(struct drm_device *dev); + +#endif diff --git a/drivers/staging/gma500/mdfld_pyr_cmd.c b/drivers/staging/gma500/mdfld_pyr_cmd.c new file mode 100644 index 000000000000..523f2d8fe4f1 --- /dev/null +++ b/drivers/staging/gma500/mdfld_pyr_cmd.c @@ -0,0 +1,558 @@ +/* + * Copyright (c) 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, sublicensen + * 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: + * Thomas Eaton + * Scott Rowe +*/ + +#include "mdfld_dsi_dbi.h" +#include "mdfld_dsi_dpi.h" +#include "mdfld_dsi_output.h" +#include "mdfld_output.h" +#include "mdfld_dsi_dbi_dpu.h" +#include "mdfld_dsi_pkg_sender.h" + +#include "displays/pyr_cmd.h" + +static struct drm_display_mode *pyr_cmd_get_config_mode(struct drm_device *dev) +{ + struct drm_display_mode *mode; + + mode = kzalloc(sizeof(*mode), GFP_KERNEL); + if (!mode) { + dev_err(dev->dev, "Out of memory\n"); + return NULL; + } + + dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay); + dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay); + dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start); + dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end); + dev_dbg(dev->dev, "htotal is %d\n", mode->htotal); + dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start); + dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end); + dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal); + dev_dbg(dev->dev, "clock is %d\n", mode->clock); + + mode->hdisplay = 480; + mode->vdisplay = 864; + mode->hsync_start = 487; + mode->hsync_end = 490; + mode->htotal = 499; + mode->vsync_start = 874; + mode->vsync_end = 878; + mode->vtotal = 886; + mode->clock = 25777; + + drm_mode_set_name(mode); + drm_mode_set_crtcinfo(mode, 0); + + mode->type |= DRM_MODE_TYPE_PREFERRED; + + return mode; +} + +static bool pyr_dsi_dbi_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = encoder->dev; + struct drm_display_mode *fixed_mode = pyr_cmd_get_config_mode(dev); + + if (fixed_mode) { + adjusted_mode->hdisplay = fixed_mode->hdisplay; + adjusted_mode->hsync_start = fixed_mode->hsync_start; + adjusted_mode->hsync_end = fixed_mode->hsync_end; + adjusted_mode->htotal = fixed_mode->htotal; + adjusted_mode->vdisplay = fixed_mode->vdisplay; + adjusted_mode->vsync_start = fixed_mode->vsync_start; + adjusted_mode->vsync_end = fixed_mode->vsync_end; + adjusted_mode->vtotal = fixed_mode->vtotal; + adjusted_mode->clock = fixed_mode->clock; + drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); + kfree(fixed_mode); + } + return true; +} + +static void pyr_dsi_dbi_set_power(struct drm_encoder *encoder, bool on) +{ + int ret = 0; + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output *dbi_output = + MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + struct drm_device *dev = encoder->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + u32 reg_offset = 0; + int pipe = (dbi_output->channel_num == 0) ? 0 : 2; + + dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n", pipe, + on ? "On" : "Off", + dbi_output->dbi_panel_on ? "True" : "False"); + + if (pipe == 2) { + if (on) + dev_priv->dual_mipi = true; + else + dev_priv->dual_mipi = false; + + reg_offset = MIPIC_REG_OFFSET; + } else { + if (!on) + dev_priv->dual_mipi = false; + } + + if (!gma_power_begin(dev, true)) { + dev_err(dev->dev, "hw begin failed\n"); + return; + } + + + if (on) { + if (dbi_output->dbi_panel_on) + goto out_err; + + ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON); + if (ret) { + dev_err(dev->dev, "power on error\n"); + goto out_err; + } + + dbi_output->dbi_panel_on = true; + + if (pipe == 2) { + dev_priv->dbi_panel_on2 = true; + } else { + dev_priv->dbi_panel_on = true; + mdfld_enable_te(dev, 0); + } + } else { + if (!dbi_output->dbi_panel_on && !dbi_output->first_boot) + goto out_err; + + dbi_output->dbi_panel_on = false; + dbi_output->first_boot = false; + + if (pipe == 2) { + dev_priv->dbi_panel_on2 = false; + mdfld_disable_te(dev, 2); + } else { + dev_priv->dbi_panel_on = false; + mdfld_disable_te(dev, 0); + + if (dev_priv->dbi_panel_on2) + mdfld_enable_te(dev, 2); + } + + ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF); + if (ret) { + dev_err(dev->dev, "power on error\n"); + goto out_err; + } + } + +out_err: + gma_power_end(dev); + + if (ret) + dev_err(dev->dev, "failed\n"); +} + +static void pyr_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config, + int pipe) +{ + struct drm_device *dev = dsi_config->dev; + u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0; + int lane_count = dsi_config->lane_count; + u32 val = 0; + + dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe); + + /* Un-ready device */ + REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000); + + /* Init dsi adapter before kicking off */ + REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018); + + /* TODO: figure out how to setup these registers */ + REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c600F); + REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), + 0x000a0014); + REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400); + REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000); + + /* Enable all interrupts */ + REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff); + /* Max value: 20 clock cycles of txclkesc */ + REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f); + /* Min 21 txclkesc, max: ffffh */ + REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff); + /* Min: 7d0 max: 4e20 */ + REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0); + + /* Set up func_prg */ + val |= lane_count; + val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET); + val |= DSI_DBI_COLOR_FORMAT_OPTION2; + REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val); + + REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff); + REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff); + + /* De-assert dbi_stall when half of DBI FIFO is empty */ + /* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */ + + REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46); + REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000002); + REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004); + REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001); +} + +static void pyr_dsi_dbi_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + int ret = 0; + struct drm_device *dev = encoder->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output *dsi_output = + MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + struct mdfld_dsi_config *dsi_config = + mdfld_dsi_encoder_get_config(dsi_encoder); + struct mdfld_dsi_connector *dsi_connector = dsi_config->connector; + int pipe = dsi_connector->pipe; + u8 param = 0; + + /* Regs */ + u32 mipi_reg = MIPI; + u32 dspcntr_reg = DSPACNTR; + u32 pipeconf_reg = PIPEACONF; + u32 reg_offset = 0; + + /* Values */ + u32 dspcntr_val = dev_priv->dspcntr; + u32 pipeconf_val = dev_priv->pipeconf; + u32 h_active_area = mode->hdisplay; + u32 v_active_area = mode->vdisplay; + u32 mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX | + TE_TRIGGER_GPIO_PIN); + + dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val); + + dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI"); + dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay); + + if (pipe == 2) { + mipi_reg = MIPI_C; + dspcntr_reg = DSPCCNTR; + pipeconf_reg = PIPECCONF; + + reg_offset = MIPIC_REG_OFFSET; + + dspcntr_val = dev_priv->dspcntr2; + pipeconf_val = dev_priv->pipeconf2; + } else { + mipi_val |= 0x2; /* Two lanes for port A and C respectively */ + } + + if (!gma_power_begin(dev, true)) { + dev_err(dev->dev, "hw begin failed\n"); + return; + } + + /* Set up pipe related registers */ + REG_WRITE(mipi_reg, mipi_val); + REG_READ(mipi_reg); + + pyr_dsi_controller_dbi_init(dsi_config, pipe); + + msleep(20); + + REG_WRITE(dspcntr_reg, dspcntr_val); + REG_READ(dspcntr_reg); + + /* 20ms delay before sending exit_sleep_mode */ + msleep(20); + + /* Send exit_sleep_mode DCS */ + ret = mdfld_dsi_dbi_send_dcs(dsi_output, exit_sleep_mode, NULL, + 0, CMD_DATA_SRC_SYSTEM_MEM); + if (ret) { + dev_err(dev->dev, "sent exit_sleep_mode faild\n"); + goto out_err; + } + + /*send set_tear_on DCS*/ + ret = mdfld_dsi_dbi_send_dcs(dsi_output, set_tear_on, + ¶m, 1, CMD_DATA_SRC_SYSTEM_MEM); + if (ret) { + dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__); + goto out_err; + } + + /* Do some init stuff */ + mdfld_dsi_brightness_init(dsi_config, pipe); + mdfld_dsi_gen_fifo_ready(dev, (MIPIA_GEN_FIFO_STAT_REG + reg_offset), + HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY); + + REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR); + REG_READ(pipeconf_reg); + + /* TODO: this looks ugly, try to move it to CRTC mode setting */ + if (pipe == 2) + dev_priv->pipeconf2 |= PIPEACONF_DSR; + else + dev_priv->pipeconf |= PIPEACONF_DSR; + + dev_dbg(dev->dev, "pipeconf %x\n", REG_READ(pipeconf_reg)); + + ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0, + h_active_area - 1, v_active_area - 1); + if (ret) { + dev_err(dev->dev, "update area failed\n"); + goto out_err; + } + +out_err: + gma_power_end(dev); + + if (ret) + dev_err(dev->dev, "mode set failed\n"); + else + dev_dbg(dev->dev, "mode set done successfully\n"); +} + +static void pyr_dsi_dbi_prepare(struct drm_encoder *encoder) +{ + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output *dbi_output = + MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + + dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER; + dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE; + + pyr_dsi_dbi_set_power(encoder, false); +} + +static void pyr_dsi_dbi_commit(struct drm_encoder *encoder) +{ + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output *dbi_output = + MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + struct drm_device *dev = dbi_output->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_drm_dpu_rect rect; + + pyr_dsi_dbi_set_power(encoder, true); + + dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER; + + rect.x = rect.y = 0; + rect.width = 864; + rect.height = 480; + + if (dbi_output->channel_num == 1) { + dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2; + /* If DPU enabled report a fullscreen damage */ + mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect); + } else { + dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0; + mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect); + } + dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE; +} + +static void pyr_dsi_dbi_dpms(struct drm_encoder *encoder, int mode) +{ + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output *dbi_output = + MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + struct drm_device *dev = dbi_output->dev; + + dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off")); + + if (mode == DRM_MODE_DPMS_ON) + pyr_dsi_dbi_set_power(encoder, true); + else + pyr_dsi_dbi_set_power(encoder, false); +} + +/* + * Update the DBI MIPI Panel Frame Buffer. + */ +static void pyr_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output, + int pipe) +{ + struct mdfld_dsi_pkg_sender *sender = + mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); + struct drm_device *dev = dbi_output->dev; + struct drm_crtc *crtc = dbi_output->base.base.crtc; + struct psb_intel_crtc *psb_crtc = (crtc) ? + to_psb_intel_crtc(crtc) : NULL; + + u32 dpll_reg = MRST_DPLL_A; + u32 dspcntr_reg = DSPACNTR; + u32 pipeconf_reg = PIPEACONF; + u32 dsplinoff_reg = DSPALINOFF; + u32 dspsurf_reg = DSPASURF; + u32 hs_gen_ctrl_reg = HS_GEN_CTRL_REG; + u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG; + u32 reg_offset = 0; + + u32 intr_status; + u32 fifo_stat_reg_val; + u32 dpll_reg_val; + u32 dspcntr_reg_val; + u32 pipeconf_reg_val; + + /* If mode setting on-going, back off */ + if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) || + (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) || + !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE)) + return; + + /* + * Look for errors here. In particular we're checking for whatever + * error status might have appeared during the last frame transmit + * (memory write). + * + * Normally, the bits we're testing here would be set infrequently, + * if at all. However, one panel (at least) returns at least one + * error bit on most frames. So we've disabled the kernel message + * for now. + * + * Still clear whatever error bits are set, except don't clear the + * ones that would make the Penwell DSI controller reset if we + * cleared them. + */ + intr_status = REG_READ(INTR_STAT_REG); + if ((intr_status & 0x26FFFFFF) != 0) { + /* dev_err(dev->dev, "DSI status: 0x%08X\n", intr_status); */ + intr_status &= 0x26F3FFFF; + REG_WRITE(INTR_STAT_REG, intr_status); + } + + if (pipe == 2) { + dspcntr_reg = DSPCCNTR; + pipeconf_reg = PIPECCONF; + dsplinoff_reg = DSPCLINOFF; + dspsurf_reg = DSPCSURF; + + hs_gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET; + gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET, + + reg_offset = MIPIC_REG_OFFSET; + } + + if (!gma_power_begin(dev, true)) { + dev_err(dev->dev, "hw begin failed\n"); + return; + } + + fifo_stat_reg_val = REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset); + dpll_reg_val = REG_READ(dpll_reg); + dspcntr_reg_val = REG_READ(dspcntr_reg); + pipeconf_reg_val = REG_READ(pipeconf_reg); + + if (!(fifo_stat_reg_val & (1 << 27)) || + (dpll_reg_val & DPLL_VCO_ENABLE) || + !(dspcntr_reg_val & DISPLAY_PLANE_ENABLE) || + !(pipeconf_reg_val & DISPLAY_PLANE_ENABLE)) { + goto update_fb_out0; + } + + /* Refresh plane changes */ + REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg)); + REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg)); + REG_READ(dspsurf_reg); + + mdfld_dsi_send_dcs(sender, + write_mem_start, + NULL, + 0, + CMD_DATA_SRC_PIPE, + MDFLD_DSI_SEND_PACKAGE); + + /* + * The idea here is to transmit a Generic Read command after the + * Write Memory Start/Continue commands finish. This asks for + * the panel to return an "ACK No Errors," or (if it has errors + * to report) an Error Report. This allows us to monitor the + * panel's perception of the health of the DSI. + */ + mdfld_dsi_gen_fifo_ready(dev, gen_fifo_stat_reg, + HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY); + REG_WRITE(hs_gen_ctrl_reg, (1 << WORD_COUNTS_POS) | GEN_READ_0); + + dbi_output->dsr_fb_update_done = true; +update_fb_out0: + gma_power_end(dev); +} + +/* + * TODO: will be removed later, should work out display interfaces for power + */ +void pyr_dsi_adapter_init(struct mdfld_dsi_config *dsi_config, int pipe) +{ + if (!dsi_config || (pipe != 0 && pipe != 2)) { + WARN_ON(1); + return; + } + pyr_dsi_controller_dbi_init(dsi_config, pipe); +} + +static int pyr_cmd_get_panel_info(struct drm_device *dev, int pipe, + struct panel_info *pi) +{ + if (!dev || !pi) + return -EINVAL; + + pi->width_mm = PYR_PANEL_WIDTH; + pi->height_mm = PYR_PANEL_HEIGHT; + + return 0; +} + +/* PYR DBI encoder helper funcs */ +static const struct drm_encoder_helper_funcs pyr_dsi_dbi_helper_funcs = { + .dpms = pyr_dsi_dbi_dpms, + .mode_fixup = pyr_dsi_dbi_mode_fixup, + .prepare = pyr_dsi_dbi_prepare, + .mode_set = pyr_dsi_dbi_mode_set, + .commit = pyr_dsi_dbi_commit, +}; + +/* PYR DBI encoder funcs */ +static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +void pyr_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs) +{ + p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs; + p_funcs->encoder_helper_funcs = &pyr_dsi_dbi_helper_funcs; + p_funcs->get_config_mode = &pyr_cmd_get_config_mode; + p_funcs->update_fb = pyr_dsi_dbi_update_fb; + p_funcs->get_panel_info = pyr_cmd_get_panel_info; +} diff --git a/drivers/staging/gma500/mdfld_tmd_vid.c b/drivers/staging/gma500/mdfld_tmd_vid.c new file mode 100644 index 000000000000..affdc09c6769 --- /dev/null +++ b/drivers/staging/gma500/mdfld_tmd_vid.c @@ -0,0 +1,206 @@ +/* + * Copyright © 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: + * Jim Liu + * Jackie Li + * Gideon Eaton + */ + +#include "mdfld_dsi_dbi.h" +#include "mdfld_dsi_dpi.h" +#include "mdfld_dsi_output.h" +#include "mdfld_output.h" + +#include "mdfld_dsi_pkg_sender.h" + +#include "displays/tmd_vid.h" + +/* FIXME: static ? */ +struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev) +{ + struct drm_display_mode *mode; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_timing_info *ti = &dev_priv->gct_data.DTD; + bool use_gct = false; /*Disable GCT for now*/ + + mode = kzalloc(sizeof(*mode), GFP_KERNEL); + if (!mode) { + dev_err(dev->dev, "Out of memory\n"); + return NULL; + } + + if (use_gct) { + dev_dbg(dev->dev, "gct find MIPI panel.\n"); + + mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; + mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; + mode->hsync_start = mode->hdisplay + + ((ti->hsync_offset_hi << 8) | + ti->hsync_offset_lo); + mode->hsync_end = mode->hsync_start + + ((ti->hsync_pulse_width_hi << 8) | + ti->hsync_pulse_width_lo); + mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | + ti->hblank_lo); + mode->vsync_start = \ + mode->vdisplay + ((ti->vsync_offset_hi << 8) | + ti->vsync_offset_lo); + mode->vsync_end = \ + mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \ + ti->vsync_pulse_width_lo); + mode->vtotal = mode->vdisplay + + ((ti->vblank_hi << 8) | ti->vblank_lo); + mode->clock = ti->pixel_clock * 10; + + dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay); + dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay); + dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start); + dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end); + dev_dbg(dev->dev, "htotal is %d\n", mode->htotal); + dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start); + dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end); + dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal); + dev_dbg(dev->dev, "clock is %d\n", mode->clock); + } else { + mode->hdisplay = 480; + mode->vdisplay = 854; + mode->hsync_start = 487; + mode->hsync_end = 490; + mode->htotal = 499; + mode->vsync_start = 861; + mode->vsync_end = 865; + mode->vtotal = 873; + mode->clock = 33264; + } + drm_mode_set_name(mode); + drm_mode_set_crtcinfo(mode, 0); + + mode->type |= DRM_MODE_TYPE_PREFERRED; + + return mode; +} + +static int tmd_vid_get_panel_info(struct drm_device *dev, + int pipe, + struct panel_info *pi) +{ + if (!dev || !pi) + return -EINVAL; + + pi->width_mm = TMD_PANEL_WIDTH; + pi->height_mm = TMD_PANEL_HEIGHT; + + return 0; +} + +/* + * mdfld_init_TMD_MIPI - initialise a TMD interface + * @dsi_config: configuration + * @pipe: pipe to configure + * + * This function is called only by mrst_dsi_mode_set and + * restore_display_registers. since this function does not + * acquire the mutex, it is important that the calling function + * does! + */ + + +static void mdfld_dsi_tmd_drv_ic_init(struct mdfld_dsi_config *dsi_config, + int pipe) +{ + static u32 tmd_cmd_mcap_off[] = {0x000000b2}; + static u32 tmd_cmd_enable_lane_switch[] = {0x000101ef}; + static u32 tmd_cmd_set_lane_num[] = {0x006360ef}; + static u32 tmd_cmd_pushing_clock0[] = {0x00cc2fef}; + static u32 tmd_cmd_pushing_clock1[] = {0x00dd6eef}; + static u32 tmd_cmd_set_mode[] = {0x000000b3}; + static u32 tmd_cmd_set_sync_pulse_mode[] = {0x000961ef}; + static u32 tmd_cmd_set_column[] = {0x0100002a, 0x000000df}; + static u32 tmd_cmd_set_page[] = {0x0300002b, 0x00000055}; + static u32 tmd_cmd_set_video_mode[] = {0x00000153}; + /*no auto_bl,need add in furture*/ + static u32 tmd_cmd_enable_backlight[] = {0x00005ab4}; + static u32 tmd_cmd_set_backlight_dimming[] = {0x00000ebd}; + + struct mdfld_dsi_pkg_sender *sender + = mdfld_dsi_get_pkg_sender(dsi_config); + + DRM_INFO("Enter mdfld init TMD MIPI display.\n"); + + if (!sender) { + DRM_ERROR("Cannot get sender\n"); + return; + } + + if (dsi_config->dvr_ic_inited) + return; + + msleep(3); + + mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_mcap_off, 1, 0); + mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_enable_lane_switch, 1, 0); + mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_lane_num, 1, 0); + mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_pushing_clock0, 1, 0); + mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_pushing_clock1, 1, 0); + mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_mode, 1, 0); + mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_sync_pulse_mode, 1, 0); + mdfld_dsi_send_mcs_long_lp(sender, tmd_cmd_set_column, 2, 0); + mdfld_dsi_send_mcs_long_lp(sender, tmd_cmd_set_page, 2, 0); + mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_video_mode, 1, 0); + mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_enable_backlight, 1, 0); + mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_backlight_dimming, 1, 0); + + dsi_config->dvr_ic_inited = 1; +} + +/* TMD DPI encoder helper funcs */ +static const struct drm_encoder_helper_funcs + mdfld_tpo_dpi_encoder_helper_funcs = { + .dpms = mdfld_dsi_dpi_dpms, + .mode_fixup = mdfld_dsi_dpi_mode_fixup, + .prepare = mdfld_dsi_dpi_prepare, + .mode_set = mdfld_dsi_dpi_mode_set, + .commit = mdfld_dsi_dpi_commit, +}; + +/* TMD DPI encoder funcs */ +static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +void tmd_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs) +{ + if (!dev || !p_funcs) { + dev_err(dev->dev, "Invalid parameters\n"); + return; + } + + p_funcs->encoder_funcs = &mdfld_tpo_dpi_encoder_funcs; + p_funcs->encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs; + p_funcs->get_config_mode = &tmd_vid_get_config_mode; + p_funcs->update_fb = NULL; + p_funcs->get_panel_info = tmd_vid_get_panel_info; + p_funcs->reset = mdfld_dsi_panel_reset; + p_funcs->drv_ic_init = mdfld_dsi_tmd_drv_ic_init; +} diff --git a/drivers/staging/gma500/mdfld_tpo_cmd.c b/drivers/staging/gma500/mdfld_tpo_cmd.c new file mode 100644 index 000000000000..c7f7c9c19bc1 --- /dev/null +++ b/drivers/staging/gma500/mdfld_tpo_cmd.c @@ -0,0 +1,509 @@ +/* + * Copyright (c) 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, sublicensen + * 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: + * Thomas Eaton + * Scott Rowe + */ + +#include "mdfld_dsi_dbi.h" +#include "mdfld_dsi_dpi.h" +#include "mdfld_dsi_output.h" +#include "mdfld_output.h" +#include "mdfld_dsi_dbi_dpu.h" +#include "mdfld_dsi_pkg_sender.h" + +#include "displays/tpo_cmd.h" + +static struct drm_display_mode *tpo_cmd_get_config_mode(struct drm_device *dev) +{ + struct drm_display_mode *mode; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_timing_info *ti = &dev_priv->gct_data.DTD; + bool use_gct = false; + + mode = kzalloc(sizeof(*mode), GFP_KERNEL); + if (!mode) + return NULL; + + if (use_gct) { + dev_dbg(dev->dev, "gct find MIPI panel.\n"); + + mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; + mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; + mode->hsync_start = mode->hdisplay + \ + ((ti->hsync_offset_hi << 8) | \ + ti->hsync_offset_lo); + mode->hsync_end = mode->hsync_start + \ + ((ti->hsync_pulse_width_hi << 8) | \ + ti->hsync_pulse_width_lo); + mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \ + ti->hblank_lo); + mode->vsync_start = \ + mode->vdisplay + ((ti->vsync_offset_hi << 8) | \ + ti->vsync_offset_lo); + mode->vsync_end = \ + mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \ + ti->vsync_pulse_width_lo); + mode->vtotal = mode->vdisplay + \ + ((ti->vblank_hi << 8) | ti->vblank_lo); + mode->clock = ti->pixel_clock * 10; + + dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay); + dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay); + dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start); + dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end); + dev_dbg(dev->dev, "htotal is %d\n", mode->htotal); + dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start); + dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end); + dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal); + dev_dbg(dev->dev, "clock is %d\n", mode->clock); + } else { + mode->hdisplay = 864; + mode->vdisplay = 480; + mode->hsync_start = 872; + mode->hsync_end = 876; + mode->htotal = 884; + mode->vsync_start = 482; + mode->vsync_end = 494; + mode->vtotal = 486; + mode->clock = 25777; + } + + drm_mode_set_name(mode); + drm_mode_set_crtcinfo(mode, 0); + + mode->type |= DRM_MODE_TYPE_PREFERRED; + + return mode; +} + +static bool mdfld_dsi_dbi_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = encoder->dev; + struct drm_display_mode *fixed_mode = tpo_cmd_get_config_mode(dev); + + if (fixed_mode) { + adjusted_mode->hdisplay = fixed_mode->hdisplay; + adjusted_mode->hsync_start = fixed_mode->hsync_start; + adjusted_mode->hsync_end = fixed_mode->hsync_end; + adjusted_mode->htotal = fixed_mode->htotal; + adjusted_mode->vdisplay = fixed_mode->vdisplay; + adjusted_mode->vsync_start = fixed_mode->vsync_start; + adjusted_mode->vsync_end = fixed_mode->vsync_end; + adjusted_mode->vtotal = fixed_mode->vtotal; + adjusted_mode->clock = fixed_mode->clock; + drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); + kfree(fixed_mode); + } + return true; +} + +static void mdfld_dsi_dbi_set_power(struct drm_encoder *encoder, bool on) +{ + int ret = 0; + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output *dbi_output = + MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + struct mdfld_dsi_config *dsi_config = + mdfld_dsi_encoder_get_config(dsi_encoder); + struct mdfld_dsi_pkg_sender *sender = + mdfld_dsi_encoder_get_pkg_sender(dsi_encoder); + struct drm_device *dev = encoder->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + u32 reg_offset = 0; + int pipe = (dbi_output->channel_num == 0) ? 0 : 2; + u32 data = 0; + + dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n", + pipe, on ? "On" : "Off", + dbi_output->dbi_panel_on ? "True" : "False"); + + if (pipe == 2) { + if (on) + dev_priv->dual_mipi = true; + else + dev_priv->dual_mipi = false; + reg_offset = MIPIC_REG_OFFSET; + } else { + if (!on) + dev_priv->dual_mipi = false; + } + + if (!gma_power_begin(dev, true)) { + dev_err(dev->dev, "hw begin failed\n"); + return; + } + + if (on) { + if (dbi_output->dbi_panel_on) + goto out_err; + + ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON); + if (ret) { + dev_err(dev->dev, "power on error\n"); + goto out_err; + } + + dbi_output->dbi_panel_on = true; + + if (pipe == 2) + dev_priv->dbi_panel_on2 = true; + else + dev_priv->dbi_panel_on = true; + mdfld_enable_te(dev, pipe); + } else { + if (!dbi_output->dbi_panel_on && !dbi_output->first_boot) + goto out_err; + + dbi_output->dbi_panel_on = false; + dbi_output->first_boot = false; + + if (pipe == 2) + dev_priv->dbi_panel_on2 = false; + else + dev_priv->dbi_panel_on = false; + + mdfld_disable_te(dev, pipe); + + ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF); + if (ret) { + dev_err(dev->dev, "power on error\n"); + goto out_err; + } + } + + /* + * FIXME: this is a WA for TPO panel crash on DPMS on & off around + * 83 times. the root cause of this issue is that Booster in + * drvIC crashed. Add this WA so that we can resume the driver IC + * once we found that booster has a fault + */ + mdfld_dsi_get_power_mode(dsi_config, + &data, + MDFLD_DSI_HS_TRANSMISSION); + + if (on && data && !(data & (1 << 7))) { + /* Soft reset */ + mdfld_dsi_send_dcs(sender, + DCS_SOFT_RESET, + NULL, + 0, + CMD_DATA_SRC_PIPE, + MDFLD_DSI_SEND_PACKAGE); + + /* Init drvIC */ + if (dbi_output->p_funcs->drv_ic_init) + dbi_output->p_funcs->drv_ic_init(dsi_config, + pipe); + } + +out_err: + gma_power_end(dev); + if (ret) + dev_err(dev->dev, "failed\n"); +} + + +static void mdfld_dsi_dbi_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + int ret = 0; + struct drm_device *dev = encoder->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output *dsi_output = + MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + struct mdfld_dsi_config *dsi_config = + mdfld_dsi_encoder_get_config(dsi_encoder); + struct mdfld_dsi_connector *dsi_connector = dsi_config->connector; + int pipe = dsi_connector->pipe; + u8 param = 0; + + /* Regs */ + u32 mipi_reg = MIPI; + u32 dspcntr_reg = DSPACNTR; + u32 pipeconf_reg = PIPEACONF; + u32 reg_offset = 0; + + /* Values */ + u32 dspcntr_val = dev_priv->dspcntr; + u32 pipeconf_val = dev_priv->pipeconf; + u32 h_active_area = mode->hdisplay; + u32 v_active_area = mode->vdisplay; + u32 mipi_val; + + mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX | + TE_TRIGGER_GPIO_PIN); + + dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val); + + dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI"); + dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay); + + if (pipe == 2) { + mipi_reg = MIPI_C; + dspcntr_reg = DSPCCNTR; + pipeconf_reg = PIPECCONF; + + reg_offset = MIPIC_REG_OFFSET; + + dspcntr_val = dev_priv->dspcntr2; + pipeconf_val = dev_priv->pipeconf2; + } else { + mipi_val |= 0x2; /*two lanes for port A and C respectively*/ + } + + if (!gma_power_begin(dev, true)) { + dev_err(dev->dev, "hw begin failed\n"); + return; + } + + REG_WRITE(dspcntr_reg, dspcntr_val); + REG_READ(dspcntr_reg); + + /* 20ms delay before sending exit_sleep_mode */ + msleep(20); + + /* Send exit_sleep_mode DCS */ + ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_EXIT_SLEEP_MODE, + NULL, 0, CMD_DATA_SRC_SYSTEM_MEM); + if (ret) { + dev_err(dev->dev, "sent exit_sleep_mode faild\n"); + goto out_err; + } + + /* Send set_tear_on DCS */ + ret = mdfld_dsi_dbi_send_dcs(dsi_output, DCS_SET_TEAR_ON, + ¶m, 1, CMD_DATA_SRC_SYSTEM_MEM); + if (ret) { + dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__); + goto out_err; + } + + /* Do some init stuff */ + REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR); + REG_READ(pipeconf_reg); + + /* TODO: this looks ugly, try to move it to CRTC mode setting*/ + if (pipe == 2) + dev_priv->pipeconf2 |= PIPEACONF_DSR; + else + dev_priv->pipeconf |= PIPEACONF_DSR; + + dev_dbg(dev->dev, "pipeconf %x\n", REG_READ(pipeconf_reg)); + + ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0, + h_active_area - 1, v_active_area - 1); + if (ret) { + dev_err(dev->dev, "update area failed\n"); + goto out_err; + } + +out_err: + gma_power_end(dev); + + if (ret) + dev_err(dev->dev, "mode set failed\n"); +} + +static void mdfld_dsi_dbi_prepare(struct drm_encoder *encoder) +{ + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output *dbi_output + = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + + dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER; + dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE; + + mdfld_dsi_dbi_set_power(encoder, false); +} + +static void mdfld_dsi_dbi_commit(struct drm_encoder *encoder) +{ + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output *dbi_output = + MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + struct drm_device *dev = dbi_output->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_drm_dpu_rect rect; + + mdfld_dsi_dbi_set_power(encoder, true); + dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER; + + rect.x = rect.y = 0; + rect.width = 864; + rect.height = 480; + + if (dbi_output->channel_num == 1) { + dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2; + /*if dpu enabled report a fullscreen damage*/ + mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect); + } else { + dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0; + mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect); + } + dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE; +} + +static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode) +{ + struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder); + struct mdfld_dsi_dbi_output *dbi_output + = MDFLD_DSI_DBI_OUTPUT(dsi_encoder); + struct drm_device *dev = dbi_output->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + static bool bdispoff; + + dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off")); + + if (mode == DRM_MODE_DPMS_ON) { + /* + * FIXME: in case I am wrong! + * we don't need to exit dsr here to wake up plane/pipe/pll + * if everything goes right, hw_begin will resume them all + * during set_power. + */ + if (bdispoff /* FIXME && gbgfxsuspended */) { + mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D); + bdispoff = false; + dev_priv->dispstatus = true; + } + + mdfld_dsi_dbi_set_power(encoder, true); + /* FIXME if (gbgfxsuspended) + gbgfxsuspended = false; */ + } else { + /* + * I am not sure whether this is the perfect place to + * turn rpm on since we still have a lot of CRTC turnning + * on work to do. + */ + bdispoff = true; + dev_priv->dispstatus = false; + mdfld_dsi_dbi_set_power(encoder, false); + } +} + + +/* + * Update the DBI MIPI Panel Frame Buffer. + */ +static void mdfld_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output, + int pipe) +{ + struct mdfld_dsi_pkg_sender *sender = + mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base); + struct drm_device *dev = dbi_output->dev; + struct drm_crtc *crtc = dbi_output->base.base.crtc; + struct psb_intel_crtc *psb_crtc = (crtc) ? + to_psb_intel_crtc(crtc) : NULL; + u32 dpll_reg = MRST_DPLL_A; + u32 dspcntr_reg = DSPACNTR; + u32 pipeconf_reg = PIPEACONF; + u32 dsplinoff_reg = DSPALINOFF; + u32 dspsurf_reg = DSPASURF; + u32 reg_offset = 0; + + /* If mode setting on-going, back off */ + if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) || + (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) || + !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE)) + return; + + if (pipe == 2) { + dspcntr_reg = DSPCCNTR; + pipeconf_reg = PIPECCONF; + dsplinoff_reg = DSPCLINOFF; + dspsurf_reg = DSPCSURF; + reg_offset = MIPIC_REG_OFFSET; + } + + if (!gma_power_begin(dev, true)) { + dev_err(dev->dev, "hw begin failed\n"); + return; + } + + /* Check DBI FIFO status */ + if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) || + !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) || + !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE)) + goto update_fb_out0; + + /* Refresh plane changes */ + REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg)); + REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg)); + REG_READ(dspsurf_reg); + + mdfld_dsi_send_dcs(sender, + DCS_WRITE_MEM_START, + NULL, + 0, + CMD_DATA_SRC_PIPE, + MDFLD_DSI_SEND_PACKAGE); + + dbi_output->dsr_fb_update_done = true; +update_fb_out0: + gma_power_end(dev); +} + +static int tpo_cmd_get_panel_info(struct drm_device *dev, + int pipe, + struct panel_info *pi) +{ + if (!dev || !pi) + return -EINVAL; + + pi->width_mm = TPO_PANEL_WIDTH; + pi->height_mm = TPO_PANEL_HEIGHT; + + return 0; +} + + +/* TPO DBI encoder helper funcs */ +static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = { + .dpms = mdfld_dsi_dbi_dpms, + .mode_fixup = mdfld_dsi_dbi_mode_fixup, + .prepare = mdfld_dsi_dbi_prepare, + .mode_set = mdfld_dsi_dbi_mode_set, + .commit = mdfld_dsi_dbi_commit, +}; + +/* TPO DBI encoder funcs */ +static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs) +{ + p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs; + p_funcs->encoder_helper_funcs = &mdfld_dsi_dbi_helper_funcs; + p_funcs->get_config_mode = &tpo_cmd_get_config_mode; + p_funcs->update_fb = mdfld_dsi_dbi_update_fb; + p_funcs->get_panel_info = tpo_cmd_get_panel_info; + p_funcs->reset = mdfld_dsi_panel_reset; + p_funcs->drv_ic_init = mdfld_dsi_brightness_init; +} diff --git a/drivers/staging/gma500/mdfld_tpo_vid.c b/drivers/staging/gma500/mdfld_tpo_vid.c new file mode 100644 index 000000000000..954901751760 --- /dev/null +++ b/drivers/staging/gma500/mdfld_tpo_vid.c @@ -0,0 +1,140 @@ +/* + * Copyright © 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: + * jim liu + * Jackie Li + */ + +#include "mdfld_dsi_dbi.h" +#include "mdfld_dsi_dpi.h" +#include "mdfld_dsi_output.h" +#include "mdfld_output.h" + +#include "mdfld_dsi_pkg_sender.h" + +#include "displays/tpo_vid.h" + +static struct drm_display_mode *tpo_vid_get_config_mode(struct drm_device *dev) +{ + struct drm_display_mode *mode; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_timing_info *ti = &dev_priv->gct_data.DTD; + bool use_gct = false; + + mode = kzalloc(sizeof(*mode), GFP_KERNEL); + if (!mode) { + dev_err(dev->dev, "out of memory\n"); + return NULL; + } + + if (use_gct) { + mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; + mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; + mode->hsync_start = mode->hdisplay + \ + ((ti->hsync_offset_hi << 8) | \ + ti->hsync_offset_lo); + mode->hsync_end = mode->hsync_start + \ + ((ti->hsync_pulse_width_hi << 8) | \ + ti->hsync_pulse_width_lo); + mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \ + ti->hblank_lo); + mode->vsync_start = \ + mode->vdisplay + ((ti->vsync_offset_hi << 8) | \ + ti->vsync_offset_lo); + mode->vsync_end = \ + mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \ + ti->vsync_pulse_width_lo); + mode->vtotal = mode->vdisplay + \ + ((ti->vblank_hi << 8) | ti->vblank_lo); + mode->clock = ti->pixel_clock * 10; + + dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay); + dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay); + dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start); + dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end); + dev_dbg(dev->dev, "htotal is %d\n", mode->htotal); + dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start); + dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end); + dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal); + dev_dbg(dev->dev, "clock is %d\n", mode->clock); + } else { + mode->hdisplay = 864; + mode->vdisplay = 480; + mode->hsync_start = 873; + mode->hsync_end = 876; + mode->htotal = 887; + mode->vsync_start = 487; + mode->vsync_end = 490; + mode->vtotal = 499; + mode->clock = 33264; + } + + drm_mode_set_name(mode); + drm_mode_set_crtcinfo(mode, 0); + + mode->type |= DRM_MODE_TYPE_PREFERRED; + + return mode; +} + +static int tpo_vid_get_panel_info(struct drm_device *dev, + int pipe, + struct panel_info *pi) +{ + if (!dev || !pi) + return -EINVAL; + + pi->width_mm = TPO_PANEL_WIDTH; + pi->height_mm = TPO_PANEL_HEIGHT; + + return 0; +} + +/*TPO DPI encoder helper funcs*/ +static const struct drm_encoder_helper_funcs + mdfld_tpo_dpi_encoder_helper_funcs = { + .dpms = mdfld_dsi_dpi_dpms, + .mode_fixup = mdfld_dsi_dpi_mode_fixup, + .prepare = mdfld_dsi_dpi_prepare, + .mode_set = mdfld_dsi_dpi_mode_set, + .commit = mdfld_dsi_dpi_commit, +}; + +/*TPO DPI encoder funcs*/ +static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +void tpo_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs) +{ + if (!dev || !p_funcs) { + dev_err(dev->dev, "tpo_vid_init: Invalid parameters\n"); + return; + } + + p_funcs->encoder_funcs = &mdfld_tpo_dpi_encoder_funcs; + p_funcs->encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs; + p_funcs->get_config_mode = &tpo_vid_get_config_mode; + p_funcs->update_fb = NULL; + p_funcs->get_panel_info = tpo_vid_get_panel_info; +} diff --git a/drivers/staging/gma500/medfield.h b/drivers/staging/gma500/medfield.h new file mode 100644 index 000000000000..38165e8367e5 --- /dev/null +++ b/drivers/staging/gma500/medfield.h @@ -0,0 +1,270 @@ +/* + * Copyright © 2011 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. + */ + +#define DRM_MODE_ENCODER_MIPI 5 + +/* Medfield DSI controller registers */ + +#define MIPIA_DEVICE_READY_REG 0xb000 +#define MIPIA_INTR_STAT_REG 0xb004 +#define MIPIA_INTR_EN_REG 0xb008 +#define MIPIA_DSI_FUNC_PRG_REG 0xb00c +#define MIPIA_HS_TX_TIMEOUT_REG 0xb010 +#define MIPIA_LP_RX_TIMEOUT_REG 0xb014 +#define MIPIA_TURN_AROUND_TIMEOUT_REG 0xb018 +#define MIPIA_DEVICE_RESET_TIMER_REG 0xb01c +#define MIPIA_DPI_RESOLUTION_REG 0xb020 +#define MIPIA_DBI_FIFO_THROTTLE_REG 0xb024 +#define MIPIA_HSYNC_COUNT_REG 0xb028 +#define MIPIA_HBP_COUNT_REG 0xb02c +#define MIPIA_HFP_COUNT_REG 0xb030 +#define MIPIA_HACTIVE_COUNT_REG 0xb034 +#define MIPIA_VSYNC_COUNT_REG 0xb038 +#define MIPIA_VBP_COUNT_REG 0xb03c +#define MIPIA_VFP_COUNT_REG 0xb040 +#define MIPIA_HIGH_LOW_SWITCH_COUNT_REG 0xb044 +#define MIPIA_DPI_CONTROL_REG 0xb048 +#define MIPIA_DPI_DATA_REG 0xb04c +#define MIPIA_INIT_COUNT_REG 0xb050 +#define MIPIA_MAX_RETURN_PACK_SIZE_REG 0xb054 +#define MIPIA_VIDEO_MODE_FORMAT_REG 0xb058 +#define MIPIA_EOT_DISABLE_REG 0xb05c +#define MIPIA_LP_BYTECLK_REG 0xb060 +#define MIPIA_LP_GEN_DATA_REG 0xb064 +#define MIPIA_HS_GEN_DATA_REG 0xb068 +#define MIPIA_LP_GEN_CTRL_REG 0xb06c +#define MIPIA_HS_GEN_CTRL_REG 0xb070 +#define MIPIA_GEN_FIFO_STAT_REG 0xb074 +#define MIPIA_HS_LS_DBI_ENABLE_REG 0xb078 +#define MIPIA_DPHY_PARAM_REG 0xb080 +#define MIPIA_DBI_BW_CTRL_REG 0xb084 +#define MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG 0xb088 + +#define DSI_DEVICE_READY (0x1) +#define DSI_POWER_STATE_ULPS_ENTER (0x2 << 1) +#define DSI_POWER_STATE_ULPS_EXIT (0x1 << 1) +#define DSI_POWER_STATE_ULPS_OFFSET (0x1) + + +#define DSI_ONE_DATA_LANE (0x1) +#define DSI_TWO_DATA_LANE (0x2) +#define DSI_THREE_DATA_LANE (0X3) +#define DSI_FOUR_DATA_LANE (0x4) +#define DSI_DPI_VIRT_CHANNEL_OFFSET (0x3) +#define DSI_DBI_VIRT_CHANNEL_OFFSET (0x5) +#define DSI_DPI_COLOR_FORMAT_RGB565 (0x01 << 7) +#define DSI_DPI_COLOR_FORMAT_RGB666 (0x02 << 7) +#define DSI_DPI_COLOR_FORMAT_RGB666_UNPACK (0x03 << 7) +#define DSI_DPI_COLOR_FORMAT_RGB888 (0x04 << 7) +#define DSI_DBI_COLOR_FORMAT_OPTION2 (0x05 << 13) + +#define DSI_INTR_STATE_RXSOTERROR 1 + +#define DSI_INTR_STATE_SPL_PKG_SENT (1 << 30) +#define DSI_INTR_STATE_TE (1 << 31) + +#define DSI_HS_TX_TIMEOUT_MASK (0xffffff) + +#define DSI_LP_RX_TIMEOUT_MASK (0xffffff) + +#define DSI_TURN_AROUND_TIMEOUT_MASK (0x3f) + +#define DSI_RESET_TIMER_MASK (0xffff) + +#define DSI_DBI_FIFO_WM_HALF (0x0) +#define DSI_DBI_FIFO_WM_QUARTER (0x1) +#define DSI_DBI_FIFO_WM_LOW (0x2) + +#define DSI_DPI_TIMING_MASK (0xffff) + +#define DSI_INIT_TIMER_MASK (0xffff) + +#define DSI_DBI_RETURN_PACK_SIZE_MASK (0x3ff) + +#define DSI_LP_BYTECLK_MASK (0x0ffff) + +#define DSI_HS_CTRL_GEN_SHORT_W0 (0x03) +#define DSI_HS_CTRL_GEN_SHORT_W1 (0x13) +#define DSI_HS_CTRL_GEN_SHORT_W2 (0x23) +#define DSI_HS_CTRL_GEN_R0 (0x04) +#define DSI_HS_CTRL_GEN_R1 (0x14) +#define DSI_HS_CTRL_GEN_R2 (0x24) +#define DSI_HS_CTRL_GEN_LONG_W (0x29) +#define DSI_HS_CTRL_MCS_SHORT_W0 (0x05) +#define DSI_HS_CTRL_MCS_SHORT_W1 (0x15) +#define DSI_HS_CTRL_MCS_R0 (0x06) +#define DSI_HS_CTRL_MCS_LONG_W (0x39) +#define DSI_HS_CTRL_VC_OFFSET (0x06) +#define DSI_HS_CTRL_WC_OFFSET (0x08) + +#define DSI_FIFO_GEN_HS_DATA_FULL (1 << 0) +#define DSI_FIFO_GEN_HS_DATA_HALF_EMPTY (1 << 1) +#define DSI_FIFO_GEN_HS_DATA_EMPTY (1 << 2) +#define DSI_FIFO_GEN_LP_DATA_FULL (1 << 8) +#define DSI_FIFO_GEN_LP_DATA_HALF_EMPTY (1 << 9) +#define DSI_FIFO_GEN_LP_DATA_EMPTY (1 << 10) +#define DSI_FIFO_GEN_HS_CTRL_FULL (1 << 16) +#define DSI_FIFO_GEN_HS_CTRL_HALF_EMPTY (1 << 17) +#define DSI_FIFO_GEN_HS_CTRL_EMPTY (1 << 18) +#define DSI_FIFO_GEN_LP_CTRL_FULL (1 << 24) +#define DSI_FIFO_GEN_LP_CTRL_HALF_EMPTY (1 << 25) +#define DSI_FIFO_GEN_LP_CTRL_EMPTY (1 << 26) +#define DSI_FIFO_DBI_EMPTY (1 << 27) +#define DSI_FIFO_DPI_EMPTY (1 << 28) + +#define DSI_DBI_HS_LP_SWITCH_MASK (0x1) + +#define DSI_HS_LP_SWITCH_COUNTER_OFFSET (0x0) +#define DSI_LP_HS_SWITCH_COUNTER_OFFSET (0x16) + +#define DSI_DPI_CTRL_HS_SHUTDOWN (0x00000001) +#define DSI_DPI_CTRL_HS_TURN_ON (0x00000002) + +/* Medfield DSI adapter registers */ +#define MIPIA_CONTROL_REG 0xb104 +#define MIPIA_DATA_ADD_REG 0xb108 +#define MIPIA_DATA_LEN_REG 0xb10c +#define MIPIA_CMD_ADD_REG 0xb110 +#define MIPIA_CMD_LEN_REG 0xb114 + +/*dsi power modes*/ +#define DSI_POWER_MODE_DISPLAY_ON (1 << 2) +#define DSI_POWER_MODE_NORMAL_ON (1 << 3) +#define DSI_POWER_MODE_SLEEP_OUT (1 << 4) +#define DSI_POWER_MODE_PARTIAL_ON (1 << 5) +#define DSI_POWER_MODE_IDLE_ON (1 << 6) + +enum { + MDFLD_DSI_ENCODER_DBI = 0, + MDFLD_DSI_ENCODER_DPI, +}; + +enum { + MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE = 1, + MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_EVENTS = 2, + MDFLD_DSI_VIDEO_BURST_MODE = 3, +}; + +#define DSI_DPI_COMPLETE_LAST_LINE (1 << 2) +#define DSI_DPI_DISABLE_BTA (1 << 3) +/* Panel types */ +enum { + TPO_CMD, + TPO_VID, + TMD_CMD, + TMD_VID, + PYR_CMD, + PYR_VID, + TPO, + TMD, + PYR, + HDMI, + GCT_DETECT +}; + +/* Junk that belongs elsewhere */ +#define TPO_PANEL_WIDTH 84 +#define TPO_PANEL_HEIGHT 46 +#define TMD_PANEL_WIDTH 39 +#define TMD_PANEL_HEIGHT 71 +#define PYR_PANEL_WIDTH 53 +#define PYR_PANEL_HEIGHT 95 + +/* Panel interface */ +struct panel_info { + u32 width_mm; + u32 height_mm; +}; + +struct mdfld_dsi_dbi_output; + +struct mdfld_dsi_connector_state { + u32 mipi_ctrl_reg; +}; + +struct mdfld_dsi_encoder_state { + +}; + +struct mdfld_dsi_connector { + /* + * This is ugly, but I have to use connector in it! :-( + * FIXME: use drm_connector instead. + */ + struct psb_intel_output base; + + int pipe; + void *private; + void *pkg_sender; + + /* Connection status */ + enum drm_connector_status status; +}; + +struct mdfld_dsi_encoder { + struct drm_encoder base; + void *private; +}; + +/* + * DSI config, consists of one DSI connector, two DSI encoders. + * DRM will pick up on DSI encoder basing on differents configs. + */ +struct mdfld_dsi_config { + struct drm_device *dev; + struct drm_display_mode *fixed_mode; + struct drm_display_mode *mode; + + struct mdfld_dsi_connector *connector; + struct mdfld_dsi_encoder *encoders[DRM_CONNECTOR_MAX_ENCODER]; + struct mdfld_dsi_encoder *encoder; + + int changed; + + int bpp; + int type; + int lane_count; + /*Virtual channel number for this encoder*/ + int channel_num; + /*video mode configure*/ + int video_mode; + + int dvr_ic_inited; +}; + +#define MDFLD_DSI_CONNECTOR(psb_output) \ + (container_of(psb_output, struct mdfld_dsi_connector, base)) + +#define MDFLD_DSI_ENCODER(encoder) \ + (container_of(encoder, struct mdfld_dsi_encoder, base)) + +struct panel_funcs { + const struct drm_encoder_funcs *encoder_funcs; + const struct drm_encoder_helper_funcs *encoder_helper_funcs; + struct drm_display_mode *(*get_config_mode) (struct drm_device *); + void (*update_fb) (struct mdfld_dsi_dbi_output *, int); + int (*get_panel_info) (struct drm_device *, int, struct panel_info *); + int (*reset)(int pipe); + void (*drv_ic_init)(struct mdfld_dsi_config *dsi_config, int pipe); +}; + diff --git a/drivers/staging/gma500/mid_bios.c b/drivers/staging/gma500/mid_bios.c new file mode 100644 index 000000000000..8cfe301f8fb2 --- /dev/null +++ b/drivers/staging/gma500/mid_bios.c @@ -0,0 +1,269 @@ +/************************************************************************** + * Copyright (c) 2011, Intel Corporation. + * All Rights Reserved. + * + * 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. + * + **************************************************************************/ + +/* TODO + * - Split functions by vbt type + * - Make them all take drm_device + * - Check ioremap failures + */ + +#include +#include +#include "psb_drm.h" +#include "psb_drv.h" +#include "mid_bios.h" +#include "mdfld_output.h" + +static int panel_id = GCT_DETECT; +module_param_named(panel_id, panel_id, int, 0600); +MODULE_PARM_DESC(panel_id, "Panel Identifier"); + + +static void mid_get_fuse_settings(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); + uint32_t fuse_value = 0; + uint32_t fuse_value_tmp = 0; + +#define FB_REG06 0xD0810600 +#define FB_MIPI_DISABLE (1 << 11) +#define FB_REG09 0xD0810900 +#define FB_REG09 0xD0810900 +#define FB_SKU_MASK 0x7000 +#define FB_SKU_SHIFT 12 +#define FB_SKU_100 0 +#define FB_SKU_100L 1 +#define FB_SKU_83 2 + pci_write_config_dword(pci_root, 0xD0, FB_REG06); + pci_read_config_dword(pci_root, 0xD4, &fuse_value); + + /* FB_MIPI_DISABLE doesn't mean LVDS on with Medfield */ + if (IS_MRST(dev)) + dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE; + + DRM_INFO("internal display is %s\n", + dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display"); + + /* Prevent runtime suspend at start*/ + if (dev_priv->iLVDS_enable) { + dev_priv->is_lvds_on = true; + dev_priv->is_mipi_on = false; + } else { + dev_priv->is_mipi_on = true; + dev_priv->is_lvds_on = false; + } + + dev_priv->video_device_fuse = fuse_value; + + pci_write_config_dword(pci_root, 0xD0, FB_REG09); + pci_read_config_dword(pci_root, 0xD4, &fuse_value); + + dev_dbg(dev->dev, "SKU values is 0x%x.\n", fuse_value); + fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT; + + dev_priv->fuse_reg_value = fuse_value; + + switch (fuse_value_tmp) { + case FB_SKU_100: + dev_priv->core_freq = 200; + break; + case FB_SKU_100L: + dev_priv->core_freq = 100; + break; + case FB_SKU_83: + dev_priv->core_freq = 166; + break; + default: + dev_warn(dev->dev, "Invalid SKU values, SKU value = 0x%08x\n", + fuse_value_tmp); + dev_priv->core_freq = 0; + } + dev_dbg(dev->dev, "LNC core clk is %dMHz.\n", dev_priv->core_freq); + pci_dev_put(pci_root); +} + +/* + * Get the revison ID, B0:D2:F0;0x08 + */ +static void mid_get_pci_revID(struct drm_psb_private *dev_priv) +{ + uint32_t platform_rev_id = 0; + struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); + + pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id); + dev_priv->platform_rev_id = (uint8_t) platform_rev_id; + pci_dev_put(pci_gfx_root); + dev_dbg(dev_priv->dev->dev, "platform_rev_id is %x\n", + dev_priv->platform_rev_id); +} + +static void mid_get_vbt_data(struct drm_psb_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct mrst_vbt *vbt = &dev_priv->vbt_data; + u32 addr; + u16 new_size; + u8 *vbt_virtual; + u8 bpi; + u8 number_desc = 0; + struct mrst_timing_info *dp_ti = &dev_priv->gct_data.DTD; + struct gct_r10_timing_info ti; + void *pGCT; + struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); + + /* Get the address of the platform config vbt, B0:D2:F0;0xFC */ + pci_read_config_dword(pci_gfx_root, 0xFC, &addr); + pci_dev_put(pci_gfx_root); + + dev_dbg(dev->dev, "drm platform config address is %x\n", addr); + + /* check for platform config address == 0. */ + /* this means fw doesn't support vbt */ + + if (addr == 0) { + vbt->size = 0; + return; + } + + /* get the virtual address of the vbt */ + vbt_virtual = ioremap(addr, sizeof(*vbt)); + + memcpy(vbt, vbt_virtual, sizeof(*vbt)); + iounmap(vbt_virtual); /* Free virtual address space */ + + dev_dbg(dev->dev, "GCT revision is %x\n", vbt->revision); + + switch (vbt->revision) { + case 0: + vbt->mrst_gct = ioremap(addr + sizeof(*vbt) - 4, + vbt->size - sizeof(*vbt) + 4); + pGCT = vbt->mrst_gct; + bpi = ((struct mrst_gct_v1 *)pGCT)->PD.BootPanelIndex; + dev_priv->gct_data.bpi = bpi; + dev_priv->gct_data.pt = + ((struct mrst_gct_v1 *)pGCT)->PD.PanelType; + memcpy(&dev_priv->gct_data.DTD, + &((struct mrst_gct_v1 *)pGCT)->panel[bpi].DTD, + sizeof(struct mrst_timing_info)); + dev_priv->gct_data.Panel_Port_Control = + ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control; + dev_priv->gct_data.Panel_MIPI_Display_Descriptor = + ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; + break; + case 1: + vbt->mrst_gct = ioremap(addr + sizeof(*vbt) - 4, + vbt->size - sizeof(*vbt) + 4); + pGCT = vbt->mrst_gct; + bpi = ((struct mrst_gct_v2 *)pGCT)->PD.BootPanelIndex; + dev_priv->gct_data.bpi = bpi; + dev_priv->gct_data.pt = + ((struct mrst_gct_v2 *)pGCT)->PD.PanelType; + memcpy(&dev_priv->gct_data.DTD, + &((struct mrst_gct_v2 *)pGCT)->panel[bpi].DTD, + sizeof(struct mrst_timing_info)); + dev_priv->gct_data.Panel_Port_Control = + ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control; + dev_priv->gct_data.Panel_MIPI_Display_Descriptor = + ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; + break; + case 0x10: + /*header definition changed from rev 01 (v2) to rev 10h. */ + /*so, some values have changed location*/ + new_size = vbt->checksum; /*checksum contains lo size byte*/ + /*LSB of mrst_gct contains hi size byte*/ + new_size |= ((0xff & (unsigned int)vbt->mrst_gct)) << 8; + + vbt->checksum = vbt->size; /*size contains the checksum*/ + if (new_size > 0xff) + vbt->size = 0xff; /*restrict size to 255*/ + else + vbt->size = new_size; + + /* number of descriptors defined in the GCT */ + number_desc = ((0xff00 & (unsigned int)vbt->mrst_gct)) >> 8; + bpi = ((0xff0000 & (unsigned int)vbt->mrst_gct)) >> 16; + vbt->mrst_gct = ioremap(addr + GCT_R10_HEADER_SIZE, + GCT_R10_DISPLAY_DESC_SIZE * number_desc); + pGCT = vbt->mrst_gct; + pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE); + dev_priv->gct_data.bpi = bpi; /*save boot panel id*/ + + /*copy the GCT display timings into a temp structure*/ + memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info)); + + /*now copy the temp struct into the dev_priv->gct_data*/ + dp_ti->pixel_clock = ti.pixel_clock; + dp_ti->hactive_hi = ti.hactive_hi; + dp_ti->hactive_lo = ti.hactive_lo; + dp_ti->hblank_hi = ti.hblank_hi; + dp_ti->hblank_lo = ti.hblank_lo; + dp_ti->hsync_offset_hi = ti.hsync_offset_hi; + dp_ti->hsync_offset_lo = ti.hsync_offset_lo; + dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi; + dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo; + dp_ti->vactive_hi = ti.vactive_hi; + dp_ti->vactive_lo = ti.vactive_lo; + dp_ti->vblank_hi = ti.vblank_hi; + dp_ti->vblank_lo = ti.vblank_lo; + dp_ti->vsync_offset_hi = ti.vsync_offset_hi; + dp_ti->vsync_offset_lo = ti.vsync_offset_lo; + dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi; + dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo; + + /* Move the MIPI_Display_Descriptor data from GCT to dev priv */ + dev_priv->gct_data.Panel_MIPI_Display_Descriptor = + *((u8 *)pGCT + 0x0d); + dev_priv->gct_data.Panel_MIPI_Display_Descriptor |= + (*((u8 *)pGCT + 0x0e)) << 8; + break; + default: + dev_err(dev->dev, "Unknown revision of GCT!\n"); + vbt->size = 0; + } + if (IS_MFLD(dev_priv->dev)) { + if (panel_id == GCT_DETECT) { + if (dev_priv->gct_data.bpi == 2) { + dev_info(dev->dev, "[GFX] PYR Panel Detected\n"); + dev_priv->panel_id = PYR_CMD; + panel_id = PYR_CMD; + } else if (dev_priv->gct_data.bpi == 0) { + dev_info(dev->dev, "[GFX] TMD Panel Detected.\n"); + dev_priv->panel_id = TMD_VID; + panel_id = TMD_VID; + } else { + dev_info(dev->dev, "[GFX] Default Panel (TPO)\n"); + dev_priv->panel_id = TPO_CMD; + panel_id = TPO_CMD; + } + } else { + dev_info(dev->dev, "[GFX] Panel Parameter Passed in through cmd line\n"); + dev_priv->panel_id = panel_id; + } + } +} + +int mid_chip_setup(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + mid_get_fuse_settings(dev); + mid_get_vbt_data(dev_priv); + mid_get_pci_revID(dev_priv); + return 0; +} diff --git a/drivers/staging/gma500/mid_bios.h b/drivers/staging/gma500/mid_bios.h new file mode 100644 index 000000000000..00e7d564b7eb --- /dev/null +++ b/drivers/staging/gma500/mid_bios.h @@ -0,0 +1,21 @@ +/************************************************************************** + * Copyright (c) 2011, Intel Corporation. + * All Rights Reserved. + * + * 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. + * + **************************************************************************/ + +extern int mid_chip_setup(struct drm_device *dev); + diff --git a/drivers/staging/gma500/psb_mmu.c b/drivers/staging/gma500/mmu.c similarity index 100% rename from drivers/staging/gma500/psb_mmu.c rename to drivers/staging/gma500/mmu.c diff --git a/drivers/staging/gma500/mrst.h b/drivers/staging/gma500/mrst.h index 5e4aaeb3711b..b563dbc73104 100644 --- a/drivers/staging/gma500/mrst.h +++ b/drivers/staging/gma500/mrst.h @@ -25,7 +25,7 @@ struct mrst_vbt { u8 size; u8 checksum; void *mrst_gct; -} __attribute__ ((packed)); +} __packed; struct mrst_timing_info { u16 pixel_clock; @@ -58,7 +58,7 @@ struct mrst_timing_info { u8 stereo:1; u8 unknown6:1; u8 interlaced:1; -} __attribute__((packed)); +} __packed; struct gct_r10_timing_info { u16 pixel_clock; @@ -82,7 +82,7 @@ struct gct_r10_timing_info { u16 vsync_pulse_width_hi:2; u16 vsync_positive:1; u16 rsvd_2:3; -} __attribute__((packed)); +} __packed; struct mrst_panel_descriptor_v1 { u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ @@ -111,7 +111,7 @@ struct mrst_panel_descriptor_v1 { /* Bit 6, Reserved, 2 bits, 00b */ /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ /* Bit 14, Reserved, 2 bits, 00b */ -} __attribute__ ((packed)); +} __packed; struct mrst_panel_descriptor_v2 { u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */ @@ -141,10 +141,10 @@ struct mrst_panel_descriptor_v2 { /* Bit 6, Reserved, 2 bits, 00b */ /* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */ /* Bit 14, Reserved, 2 bits, 00b */ -} __attribute__ ((packed)); +} __packed; union mrst_panel_rx { - struct{ + struct { u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/ /* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */ u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */ @@ -159,10 +159,10 @@ union mrst_panel_rx { u16 Rsvd:5;/*5 bits,00000b */ } panelrx; u16 panel_receiver; -} __attribute__ ((packed)); +} __packed; struct mrst_gct_v1 { - union{ /*8 bits,Defined as follows: */ + union { /*8 bits,Defined as follows: */ struct { u8 PanelType:4; /*4 bits, Bit field for panels*/ /* 0 - 3: 0 = LVDS, 1 = MIPI*/ @@ -176,10 +176,10 @@ struct mrst_gct_v1 { }; struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/ union mrst_panel_rx panelrx[4]; /* panel receivers*/ -} __attribute__ ((packed)); +} __packed; struct mrst_gct_v2 { - union{ /*8 bits,Defined as follows: */ + union { /*8 bits,Defined as follows: */ struct { u8 PanelType:4; /*4 bits, Bit field for panels*/ /* 0 - 3: 0 = LVDS, 1 = MIPI*/ @@ -193,7 +193,7 @@ struct mrst_gct_v2 { }; struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/ union mrst_panel_rx panelrx[4]; /* panel receivers*/ -} __attribute__ ((packed)); +} __packed; struct mrst_gct_data { u8 bpi; /* boot panel index, number of panel used during boot */ @@ -205,13 +205,48 @@ struct mrst_gct_data { u32 PP_Cycle_Delay; u16 Panel_Backlight_Inverter_Descriptor; u16 Panel_MIPI_Display_Descriptor; -} __attribute__ ((packed)); +} __packed; -#define MODE_SETTING_IN_CRTC 0x1 -#define MODE_SETTING_IN_ENCODER 0x2 -#define MODE_SETTING_ON_GOING 0x3 -#define MODE_SETTING_IN_DSR 0x4 -#define MODE_SETTING_ENCODER_DONE 0x8 -#define GCT_R10_HEADER_SIZE 16 +#define MODE_SETTING_IN_CRTC 0x1 +#define MODE_SETTING_IN_ENCODER 0x2 +#define MODE_SETTING_ON_GOING 0x3 +#define MODE_SETTING_IN_DSR 0x4 +#define MODE_SETTING_ENCODER_DONE 0x8 + +#define GCT_R10_HEADER_SIZE 16 #define GCT_R10_DISPLAY_DESC_SIZE 28 +/* + * Moorestown HDMI interfaces + */ + +struct mrst_hdmi_dev { + struct pci_dev *dev; + void __iomem *regs; + unsigned int mmio, mmio_len; + int dpms_mode; + struct hdmi_i2c_dev *i2c_dev; + + /* register state */ + u32 saveDPLL_CTRL; + u32 saveDPLL_DIV_CTRL; + u32 saveDPLL_ADJUST; + u32 saveDPLL_UPDATE; + u32 saveDPLL_CLK_ENABLE; + u32 savePCH_HTOTAL_B; + u32 savePCH_HBLANK_B; + u32 savePCH_HSYNC_B; + u32 savePCH_VTOTAL_B; + u32 savePCH_VBLANK_B; + u32 savePCH_VSYNC_B; + u32 savePCH_PIPEBCONF; + u32 savePCH_PIPEBSRC; +}; + +extern void mrst_hdmi_setup(struct drm_device *dev); +extern void mrst_hdmi_teardown(struct drm_device *dev); +extern int mrst_hdmi_i2c_init(struct pci_dev *dev); +extern void mrst_hdmi_i2c_exit(struct pci_dev *dev); +extern void mrst_hdmi_save(struct drm_device *dev); +extern void mrst_hdmi_restore(struct drm_device *dev); +extern void mrst_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev); diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c index e4a0c033b5b2..72464dd0f23d 100644 --- a/drivers/staging/gma500/mrst_crtc.c +++ b/drivers/staging/gma500/mrst_crtc.c @@ -19,12 +19,12 @@ #include #include -#include "psb_fb.h" +#include "framebuffer.h" #include "psb_drv.h" #include "psb_intel_drv.h" #include "psb_intel_reg.h" #include "psb_intel_display.h" -#include "psb_powermgmt.h" +#include "power.h" struct psb_intel_range_t { int min, max; @@ -86,7 +86,7 @@ static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc) { const struct mrst_limit_t *limit = NULL; struct drm_device *dev = crtc->dev; - DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) { @@ -103,7 +103,7 @@ static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc) } } else { limit = NULL; - PSB_DEBUG_ENTRY("mrst_limit Wrong display type.\n"); + dev_err(dev->dev, "mrst_limit Wrong display type.\n"); } return limit; @@ -117,7 +117,7 @@ static void mrst_clock(int refclk, struct mrst_clock_t *clock) void mrstPrintPll(char *prefix, struct mrst_clock_t *clock) { - PSB_DEBUG_ENTRY("%s: dotclock = %d, m = %d, p1 = %d.\n", + pr_debug("%s: dotclock = %d, m = %d, p1 = %d.\n", prefix, clock->dot, clock->m, clock->p1); } @@ -149,8 +149,7 @@ mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk, } } } - DRM_DEBUG("mrstFindBestPLL err = %d.\n", err); - + dev_dbg(crtc->dev->dev, "mrstFindBestPLL err = %d.\n", err); return err != target; } @@ -172,8 +171,6 @@ static void mrst_crtc_dpms(struct drm_crtc *crtc, int mode) u32 temp; bool enabled; - PSB_DEBUG_ENTRY("mode = %d, pipe = %d\n", mode, pipe); - if (!gma_power_begin(dev, true)) return; @@ -296,7 +293,7 @@ static int mrst_crtc_mode_set(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; int pipe = psb_intel_crtc->pipe; int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0; int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B; @@ -320,8 +317,6 @@ static int mrst_crtc_mode_set(struct drm_crtc *crtc, uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; struct drm_encoder *encoder; - PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe); - if (!gma_power_begin(dev, true)) return 0; @@ -446,10 +441,9 @@ static int mrst_crtc_mode_set(struct drm_crtc *crtc, ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock); if (!ok) { - PSB_DEBUG_ENTRY( - "mrstFindBestPLL fail in mrst_crtc_mode_set.\n"); + dev_dbg(dev->dev, "mrstFindBestPLL fail in mrst_crtc_mode_set.\n"); } else { - PSB_DEBUG_ENTRY("mrst_crtc_mode_set pixel clock = %d," + dev_dbg(dev->dev, "mrst_crtc_mode_set pixel clock = %d," "m = %x, p1 = %x.\n", clock.dot, clock.m, clock.p1); } @@ -540,11 +534,9 @@ int mrst_pipe_set_base(struct drm_crtc *crtc, u32 dspcntr; int ret = 0; - PSB_DEBUG_ENTRY("\n"); - /* no fb bound */ if (!crtc->fb) { - DRM_DEBUG("No FB bound\n"); + dev_dbg(dev->dev, "No FB bound\n"); return 0; } @@ -574,13 +566,12 @@ int mrst_pipe_set_base(struct drm_crtc *crtc, dspcntr |= DISPPLANE_32BPP_NO_ALPHA; break; default: - DRM_ERROR("Unknown color depth\n"); + dev_err(dev->dev, "Unknown color depth\n"); ret = -EINVAL; goto pipe_set_base_exit; } REG_WRITE(dspcntr_reg, dspcntr); - DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y); if (0 /* FIXMEAC - check what PSB needs */) { REG_WRITE(dspbase, offset); REG_READ(dspbase); diff --git a/drivers/staging/gma500/mrst_device.c b/drivers/staging/gma500/mrst_device.c new file mode 100644 index 000000000000..6707fafbfa1e --- /dev/null +++ b/drivers/staging/gma500/mrst_device.c @@ -0,0 +1,634 @@ +/************************************************************************** + * Copyright (c) 2011, Intel Corporation. + * All Rights Reserved. + * + * 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. + * + **************************************************************************/ + +#include +#include +#include +#include +#include +#include "psb_drm.h" +#include "psb_drv.h" +#include "psb_reg.h" +#include "psb_intel_reg.h" +#include +#include +#include "mid_bios.h" + +static int devtype; + +module_param_named(type, devtype, int, 0600); +MODULE_PARM_DESC(type, "Moorestown/Oaktrail device type"); + +#define DEVICE_MOORESTOWN 1 +#define DEVICE_OAKTRAIL 2 +#define DEVICE_MOORESTOWN_MM 3 + +static int mrst_device_ident(struct drm_device *dev) +{ + /* User forced */ + if (devtype) + return devtype; + if (dmi_match(DMI_PRODUCT_NAME, "OakTrail") || + dmi_match(DMI_PRODUCT_NAME, "OakTrail platform")) + return DEVICE_OAKTRAIL; +#if defined(CONFIG_X86_MRST) + if (dmi_match(DMI_PRODUCT_NAME, "MM") || + dmi_match(DMI_PRODUCT_NAME, "MM 10")) + return DEVICE_MOORESTOWN_MM; + if (mrst_identify_cpu()) + return DEVICE_MOORESTOWN; +#endif + return DEVICE_OAKTRAIL; +} + + +/* IPC message and command defines used to enable/disable mipi panel voltages */ +#define IPC_MSG_PANEL_ON_OFF 0xE9 +#define IPC_CMD_PANEL_ON 1 +#define IPC_CMD_PANEL_OFF 0 + +static int mrst_output_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + if (dev_priv->iLVDS_enable) + mrst_lvds_init(dev, &dev_priv->mode_dev); + else + dev_err(dev->dev, "DSI is not supported\n"); + if (dev_priv->hdmi_priv) + mrst_hdmi_init(dev, &dev_priv->mode_dev); + return 0; +} + +/* + * Provide the low level interfaces for the Moorestown backlight + */ + +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + +#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF +#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ +#define BLC_PWM_FREQ_CALC_CONSTANT 32 +#define MHz 1000000 +#define BLC_ADJUSTMENT_MAX 100 + +static struct backlight_device *mrst_backlight_device; +static int mrst_brightness; + +static int mrst_set_brightness(struct backlight_device *bd) +{ + struct drm_device *dev = bl_get_data(mrst_backlight_device); + struct drm_psb_private *dev_priv = dev->dev_private; + int level = bd->props.brightness; + u32 blc_pwm_ctl; + u32 max_pwm_blc; + + /* Percentage 1-100% being valid */ + if (level < 1) + level = 1; + + if (gma_power_begin(dev, 0)) { + /* Calculate and set the brightness value */ + max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16; + blc_pwm_ctl = level * max_pwm_blc / 100; + + /* Adjust the backlight level with the percent in + * dev_priv->blc_adj1; + */ + blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1; + blc_pwm_ctl = blc_pwm_ctl / 100; + + /* Adjust the backlight level with the percent in + * dev_priv->blc_adj2; + */ + blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2; + blc_pwm_ctl = blc_pwm_ctl / 100; + + /* force PWM bit on */ + REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2))); + REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl); + gma_power_end(dev); + } + mrst_brightness = level; + return 0; +} + +static int mrst_get_brightness(struct backlight_device *bd) +{ + /* return locally cached var instead of HW read (due to DPST etc.) */ + /* FIXME: ideally return actual value in case firmware fiddled with + it */ + return mrst_brightness; +} + +static int device_backlight_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + unsigned long core_clock; + u16 bl_max_freq; + uint32_t value; + uint32_t blc_pwm_precision_factor; + + dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX; + dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX; + bl_max_freq = 256; + /* this needs to be set elsewhere */ + blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR; + + core_clock = dev_priv->core_freq; + + value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; + value *= blc_pwm_precision_factor; + value /= bl_max_freq; + value /= blc_pwm_precision_factor; + + if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ) + return -ERANGE; + + if (gma_power_begin(dev, false)) { + REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2))); + REG_WRITE(BLC_PWM_CTL, value | (value << 16)); + gma_power_end(dev); + } + return 0; +} + +static const struct backlight_ops mrst_ops = { + .get_brightness = mrst_get_brightness, + .update_status = mrst_set_brightness, +}; + +int mrst_backlight_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + int ret; + struct backlight_properties props; + + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 100; + props.type = BACKLIGHT_PLATFORM; + + mrst_backlight_device = backlight_device_register("mrst-bl", + NULL, (void *)dev, &mrst_ops, &props); + + if (IS_ERR(mrst_backlight_device)) + return PTR_ERR(mrst_backlight_device); + + ret = device_backlight_init(dev); + if (ret < 0) { + backlight_device_unregister(mrst_backlight_device); + return ret; + } + mrst_backlight_device->props.brightness = 100; + mrst_backlight_device->props.max_brightness = 100; + backlight_update_status(mrst_backlight_device); + dev_priv->backlight_device = mrst_backlight_device; + return 0; +} + +#endif + +/* + * Provide the Moorestown specific chip logic and low level methods + * for power management + */ + +static void mrst_init_pm(struct drm_device *dev) +{ +} + +/** + * mrst_save_display_registers - save registers lost on suspend + * @dev: our DRM device + * + * Save the state we need in order to be able to restore the interface + * upon resume from suspend + */ +static int mrst_save_display_registers(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + int i; + u32 pp_stat; + + /* Display arbitration control + watermarks */ + dev_priv->saveDSPARB = PSB_RVDC32(DSPARB); + dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1); + dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2); + dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3); + dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4); + dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5); + dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6); + dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT); + + /* Pipe & plane A info */ + dev_priv->savePIPEACONF = PSB_RVDC32(PIPEACONF); + dev_priv->savePIPEASRC = PSB_RVDC32(PIPEASRC); + dev_priv->saveFPA0 = PSB_RVDC32(MRST_FPA0); + dev_priv->saveFPA1 = PSB_RVDC32(MRST_FPA1); + dev_priv->saveDPLL_A = PSB_RVDC32(MRST_DPLL_A); + dev_priv->saveHTOTAL_A = PSB_RVDC32(HTOTAL_A); + dev_priv->saveHBLANK_A = PSB_RVDC32(HBLANK_A); + dev_priv->saveHSYNC_A = PSB_RVDC32(HSYNC_A); + dev_priv->saveVTOTAL_A = PSB_RVDC32(VTOTAL_A); + dev_priv->saveVBLANK_A = PSB_RVDC32(VBLANK_A); + dev_priv->saveVSYNC_A = PSB_RVDC32(VSYNC_A); + dev_priv->saveBCLRPAT_A = PSB_RVDC32(BCLRPAT_A); + dev_priv->saveDSPACNTR = PSB_RVDC32(DSPACNTR); + dev_priv->saveDSPASTRIDE = PSB_RVDC32(DSPASTRIDE); + dev_priv->saveDSPAADDR = PSB_RVDC32(DSPABASE); + dev_priv->saveDSPASURF = PSB_RVDC32(DSPASURF); + dev_priv->saveDSPALINOFF = PSB_RVDC32(DSPALINOFF); + dev_priv->saveDSPATILEOFF = PSB_RVDC32(DSPATILEOFF); + + /* Save cursor regs */ + dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR); + dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE); + dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS); + + /* Save palette (gamma) */ + for (i = 0; i < 256; i++) + dev_priv->save_palette_a[i] = PSB_RVDC32(PALETTE_A + (i << 2)); + + if (dev_priv->hdmi_priv) + mrst_hdmi_save(dev); + + /* Save performance state */ + dev_priv->savePERF_MODE = PSB_RVDC32(MRST_PERF_MODE); + + /* LVDS state */ + dev_priv->savePP_CONTROL = PSB_RVDC32(PP_CONTROL); + dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS); + dev_priv->savePFIT_AUTO_RATIOS = PSB_RVDC32(PFIT_AUTO_RATIOS); + dev_priv->saveBLC_PWM_CTL = PSB_RVDC32(BLC_PWM_CTL); + dev_priv->saveBLC_PWM_CTL2 = PSB_RVDC32(BLC_PWM_CTL2); + dev_priv->saveLVDS = PSB_RVDC32(LVDS); + dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL); + dev_priv->savePP_ON_DELAYS = PSB_RVDC32(LVDSPP_ON); + dev_priv->savePP_OFF_DELAYS = PSB_RVDC32(LVDSPP_OFF); + dev_priv->savePP_DIVISOR = PSB_RVDC32(PP_CYCLE); + + /* HW overlay */ + dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD); + dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0); + dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1); + dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2); + dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3); + dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4); + dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5); + + /* DPST registers */ + dev_priv->saveHISTOGRAM_INT_CONTROL_REG = + PSB_RVDC32(HISTOGRAM_INT_CONTROL); + dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG = + PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL); + dev_priv->savePWM_CONTROL_LOGIC = PSB_RVDC32(PWM_CONTROL_LOGIC); + + if (dev_priv->iLVDS_enable) { + /* Shut down the panel */ + PSB_WVDC32(0, PP_CONTROL); + + do { + pp_stat = PSB_RVDC32(PP_STATUS); + } while (pp_stat & 0x80000000); + + /* Turn off the plane */ + PSB_WVDC32(0x58000000, DSPACNTR); + /* Trigger the plane disable */ + PSB_WVDC32(0, DSPASURF); + + /* Wait ~4 ticks */ + msleep(4); + + /* Turn off pipe */ + PSB_WVDC32(0x0, PIPEACONF); + /* Wait ~8 ticks */ + msleep(8); + + /* Turn off PLLs */ + PSB_WVDC32(0, MRST_DPLL_A); + } + return 0; +} + +/** + * mrst_restore_display_registers - restore lost register state + * @dev: our DRM device + * + * Restore register state that was lost during suspend and resume. + */ +static int mrst_restore_display_registers(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + u32 pp_stat; + int i; + + /* Display arbitration + watermarks */ + PSB_WVDC32(dev_priv->saveDSPARB, DSPARB); + PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1); + PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2); + PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3); + PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4); + PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5); + PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6); + PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT); + + /* Make sure VGA plane is off. it initializes to on after reset!*/ + PSB_WVDC32(0x80000000, VGACNTRL); + + /* set the plls */ + PSB_WVDC32(dev_priv->saveFPA0, MRST_FPA0); + PSB_WVDC32(dev_priv->saveFPA1, MRST_FPA1); + + /* Actually enable it */ + PSB_WVDC32(dev_priv->saveDPLL_A, MRST_DPLL_A); + DRM_UDELAY(150); + + /* Restore mode */ + PSB_WVDC32(dev_priv->saveHTOTAL_A, HTOTAL_A); + PSB_WVDC32(dev_priv->saveHBLANK_A, HBLANK_A); + PSB_WVDC32(dev_priv->saveHSYNC_A, HSYNC_A); + PSB_WVDC32(dev_priv->saveVTOTAL_A, VTOTAL_A); + PSB_WVDC32(dev_priv->saveVBLANK_A, VBLANK_A); + PSB_WVDC32(dev_priv->saveVSYNC_A, VSYNC_A); + PSB_WVDC32(dev_priv->savePIPEASRC, PIPEASRC); + PSB_WVDC32(dev_priv->saveBCLRPAT_A, BCLRPAT_A); + + /* Restore performance mode*/ + PSB_WVDC32(dev_priv->savePERF_MODE, MRST_PERF_MODE); + + /* Enable the pipe*/ + if (dev_priv->iLVDS_enable) + PSB_WVDC32(dev_priv->savePIPEACONF, PIPEACONF); + + /* Set up the plane*/ + PSB_WVDC32(dev_priv->saveDSPALINOFF, DSPALINOFF); + PSB_WVDC32(dev_priv->saveDSPASTRIDE, DSPASTRIDE); + PSB_WVDC32(dev_priv->saveDSPATILEOFF, DSPATILEOFF); + + /* Enable the plane */ + PSB_WVDC32(dev_priv->saveDSPACNTR, DSPACNTR); + PSB_WVDC32(dev_priv->saveDSPASURF, DSPASURF); + + /* Enable Cursor A */ + PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR); + PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS); + PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE); + + /* Restore palette (gamma) */ + for (i = 0; i < 256; i++) + PSB_WVDC32(dev_priv->save_palette_a[i], PALETTE_A + (i << 2)); + + if (dev_priv->hdmi_priv) + mrst_hdmi_restore(dev); + + if (dev_priv->iLVDS_enable) { + PSB_WVDC32(dev_priv->saveBLC_PWM_CTL2, BLC_PWM_CTL2); + PSB_WVDC32(dev_priv->saveLVDS, LVDS); /*port 61180h*/ + PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL); + PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS); + PSB_WVDC32(dev_priv->savePFIT_AUTO_RATIOS, PFIT_AUTO_RATIOS); + PSB_WVDC32(dev_priv->saveBLC_PWM_CTL, BLC_PWM_CTL); + PSB_WVDC32(dev_priv->savePP_ON_DELAYS, LVDSPP_ON); + PSB_WVDC32(dev_priv->savePP_OFF_DELAYS, LVDSPP_OFF); + PSB_WVDC32(dev_priv->savePP_DIVISOR, PP_CYCLE); + PSB_WVDC32(dev_priv->savePP_CONTROL, PP_CONTROL); + } + + /* Wait for cycle delay */ + do { + pp_stat = PSB_RVDC32(PP_STATUS); + } while (pp_stat & 0x08000000); + + /* Wait for panel power up */ + do { + pp_stat = PSB_RVDC32(PP_STATUS); + } while (pp_stat & 0x10000000); + + /* Restore HW overlay */ + PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD); + PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0); + PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1); + PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2); + PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3); + PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4); + PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5); + + /* DPST registers */ + PSB_WVDC32(dev_priv->saveHISTOGRAM_INT_CONTROL_REG, + HISTOGRAM_INT_CONTROL); + PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG, + HISTOGRAM_LOGIC_CONTROL); + PSB_WVDC32(dev_priv->savePWM_CONTROL_LOGIC, PWM_CONTROL_LOGIC); + + return 0; +} + +/** + * mrst_power_down - power down the display island + * @dev: our DRM device + * + * Power down the display interface of our device + */ +static int mrst_power_down(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + u32 pwr_mask ; + u32 pwr_sts; + + pwr_mask = PSB_PWRGT_DISPLAY_MASK; + outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC); + + while (true) { + pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); + if ((pwr_sts & pwr_mask) == pwr_mask) + break; + else + udelay(10); + } + return 0; +} + +/* + * mrst_power_up + * + * Restore power to the specified island(s) (powergating) + */ +static int mrst_power_up(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK; + u32 pwr_sts, pwr_cnt; + + pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC); + pwr_cnt &= ~pwr_mask; + outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC)); + + while (true) { + pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); + if ((pwr_sts & pwr_mask) == 0) + break; + else + udelay(10); + } + return 0; +} + +#if defined(CONFIG_X86_MRST) +static void mrst_lvds_cache_bl(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + + intel_scu_ipc_ioread8(0x28, &(dev_priv->saveBKLTCNT)); + intel_scu_ipc_ioread8(0x29, &(dev_priv->saveBKLTREQ)); + intel_scu_ipc_ioread8(0x2A, &(dev_priv->saveBKLTBRTL)); +} + +static void mrst_mm_bl_power(struct drm_device *dev, bool on) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + + if (on) { + intel_scu_ipc_iowrite8(0x2A, dev_priv->saveBKLTBRTL); + intel_scu_ipc_iowrite8(0x28, dev_priv->saveBKLTCNT); + intel_scu_ipc_iowrite8(0x29, dev_priv->saveBKLTREQ); + } else { + intel_scu_ipc_iowrite8(0x2A, 0); + intel_scu_ipc_iowrite8(0x28, 0); + intel_scu_ipc_iowrite8(0x29, 0); + } +} + +static const struct psb_ops mrst_mm_chip_ops = { + .name = "Moorestown MM ", + .accel_2d = 1, + .pipes = 1, + .crtcs = 1, + .sgx_offset = MRST_SGX_OFFSET, + + .crtc_helper = &mrst_helper_funcs, + .crtc_funcs = &psb_intel_crtc_funcs, + + .output_init = mrst_output_init, + + .lvds_bl_power = mrst_mm_bl_power, +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + .backlight_init = mrst_backlight_init, +#endif + + .init_pm = mrst_init_pm, + .save_regs = mrst_save_display_registers, + .restore_regs = mrst_restore_display_registers, + .power_down = mrst_power_down, + .power_up = mrst_power_up, + + .i2c_bus = 0, +}; + +#endif + +static void oaktrail_teardown(struct drm_device *dev) +{ + mrst_hdmi_teardown(dev); +} + +static const struct psb_ops oaktrail_chip_ops = { + .name = "Oaktrail", + .accel_2d = 1, + .pipes = 2, + .crtcs = 2, + .sgx_offset = MRST_SGX_OFFSET, + + .chip_setup = mid_chip_setup, + .chip_teardown = oaktrail_teardown, + .crtc_helper = &mrst_helper_funcs, + .crtc_funcs = &psb_intel_crtc_funcs, + + .output_init = mrst_output_init, + +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + .backlight_init = mrst_backlight_init, +#endif + + .init_pm = mrst_init_pm, + .save_regs = mrst_save_display_registers, + .restore_regs = mrst_restore_display_registers, + .power_down = mrst_power_down, + .power_up = mrst_power_up, + + .i2c_bus = 1, +}; + +/** + * mrst_chip_setup - perform the initial chip init + * @dev: Our drm_device + * + * Figure out which incarnation we are and then scan the firmware for + * tables and information. + */ +static int mrst_chip_setup(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + + switch (mrst_device_ident(dev)) { + case DEVICE_OAKTRAIL: + /* Dual CRTC, PC compatible, HDMI, I2C #2 */ + dev_priv->ops = &oaktrail_chip_ops; + mrst_hdmi_setup(dev); + return mid_chip_setup(dev); +#if defined(CONFIG_X86_MRST) + case DEVICE_MOORESTOWN_MM: + /* Single CRTC, No HDMI, I2C #0, BL control */ + mrst_lvds_cache_bl(dev); + dev_priv->ops = &mrst_mm_chip_ops; + return mid_chip_setup(dev); + case DEVICE_MOORESTOWN: + /* Dual CRTC, No HDMI(?), I2C #1 */ + return mid_chip_setup(dev); +#endif + default: + dev_err(dev->dev, "unsupported device type.\n"); + return -ENODEV; + } +} + +const struct psb_ops mrst_chip_ops = { + .name = "Moorestown", + .accel_2d = 1, + .pipes = 2, + .crtcs = 2, + .sgx_offset = MRST_SGX_OFFSET, + + .chip_setup = mrst_chip_setup, + .crtc_helper = &mrst_helper_funcs, + .crtc_funcs = &psb_intel_crtc_funcs, + + .output_init = mrst_output_init, + +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + .backlight_init = mrst_backlight_init, +#endif + + .init_pm = mrst_init_pm, + .save_regs = mrst_save_display_registers, + .restore_regs = mrst_restore_display_registers, + .power_down = mrst_power_down, + .power_up = mrst_power_up, + + .i2c_bus = 2, +}; + diff --git a/drivers/staging/gma500/mrst_hdmi.c b/drivers/staging/gma500/mrst_hdmi.c new file mode 100644 index 000000000000..d6a517971ba8 --- /dev/null +++ b/drivers/staging/gma500/mrst_hdmi.c @@ -0,0 +1,852 @@ +/* + * Copyright © 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: + * Li Peng + */ + +#include +#include +#include "psb_intel_drv.h" +#include "psb_intel_reg.h" +#include "psb_drv.h" + +#define HDMI_READ(reg) readl(hdmi_dev->regs + (reg)) +#define HDMI_WRITE(reg, val) writel(val, hdmi_dev->regs + (reg)) + +#define HDMI_HCR 0x1000 +#define HCR_ENABLE_HDCP (1 << 5) +#define HCR_ENABLE_AUDIO (1 << 2) +#define HCR_ENABLE_PIXEL (1 << 1) +#define HCR_ENABLE_TMDS (1 << 0) + +#define HDMI_HICR 0x1004 +#define HDMI_HSR 0x1008 +#define HDMI_HISR 0x100C +#define HDMI_DETECT_HDP (1 << 0) + +#define HDMI_VIDEO_REG 0x3000 +#define HDMI_UNIT_EN (1 << 7) +#define HDMI_MODE_OUTPUT (1 << 0) +#define HDMI_HBLANK_A 0x3100 + +#define HDMI_AUDIO_CTRL 0x4000 +#define HDMI_ENABLE_AUDIO (1 << 0) + +#define PCH_HTOTAL_B 0x3100 +#define PCH_HBLANK_B 0x3104 +#define PCH_HSYNC_B 0x3108 +#define PCH_VTOTAL_B 0x310C +#define PCH_VBLANK_B 0x3110 +#define PCH_VSYNC_B 0x3114 +#define PCH_PIPEBSRC 0x311C + +#define PCH_PIPEB_DSL 0x3800 +#define PCH_PIPEB_SLC 0x3804 +#define PCH_PIPEBCONF 0x3808 +#define PCH_PIPEBSTAT 0x3824 + +#define CDVO_DFT 0x5000 +#define CDVO_SLEWRATE 0x5004 +#define CDVO_STRENGTH 0x5008 +#define CDVO_RCOMP 0x500C + +#define DPLL_CTRL 0x6000 +#define DPLL_PDIV_SHIFT 16 +#define DPLL_PDIV_MASK (0xf << 16) +#define DPLL_PWRDN (1 << 4) +#define DPLL_RESET (1 << 3) +#define DPLL_FASTEN (1 << 2) +#define DPLL_ENSTAT (1 << 1) +#define DPLL_DITHEN (1 << 0) + +#define DPLL_DIV_CTRL 0x6004 +#define DPLL_CLKF_MASK 0xffffffc0 +#define DPLL_CLKR_MASK (0x3f) + +#define DPLL_CLK_ENABLE 0x6008 +#define DPLL_EN_DISP (1 << 31) +#define DPLL_SEL_HDMI (1 << 8) +#define DPLL_EN_HDMI (1 << 1) +#define DPLL_EN_VGA (1 << 0) + +#define DPLL_ADJUST 0x600C +#define DPLL_STATUS 0x6010 +#define DPLL_UPDATE 0x6014 +#define DPLL_DFT 0x6020 + +struct intel_range { + int min, max; +}; + +struct mrst_hdmi_limit { + struct intel_range vco, np, nr, nf; +}; + +struct mrst_hdmi_clock { + int np; + int nr; + int nf; + int dot; +}; + +#define VCO_MIN 320000 +#define VCO_MAX 1650000 +#define NP_MIN 1 +#define NP_MAX 15 +#define NR_MIN 1 +#define NR_MAX 64 +#define NF_MIN 2 +#define NF_MAX 4095 + +static const struct mrst_hdmi_limit mrst_hdmi_limit = { + .vco = { .min = VCO_MIN, .max = VCO_MAX }, + .np = { .min = NP_MIN, .max = NP_MAX }, + .nr = { .min = NR_MIN, .max = NR_MAX }, + .nf = { .min = NF_MIN, .max = NF_MAX }, +}; + +static void wait_for_vblank(struct drm_device *dev) +{ + /* FIXME: Can we do this as a sleep ? */ + /* Wait for 20ms, i.e. one cycle at 50hz. */ + udelay(20000); +} + +static void scu_busy_loop(void *scu_base) +{ + u32 status = 0; + u32 loop_count = 0; + + status = readl(scu_base + 0x04); + while (status & 1) { + udelay(1); /* scu processing time is in few u secods */ + status = readl(scu_base + 0x04); + loop_count++; + /* break if scu doesn't reset busy bit after huge retry */ + if (loop_count > 1000) { + DRM_DEBUG_KMS("SCU IPC timed out"); + return; + } + } +} + +static void mrst_hdmi_reset(struct drm_device *dev) +{ + void *base; + /* FIXME: at least make these defines */ + unsigned int scu_ipc_mmio = 0xff11c000; + int scu_len = 1024; + + base = ioremap((resource_size_t)scu_ipc_mmio, scu_len); + if (base == NULL) { + DRM_ERROR("failed to map SCU mmio\n"); + return; + } + + /* scu ipc: assert hdmi controller reset */ + writel(0xff11d118, base + 0x0c); + writel(0x7fffffdf, base + 0x80); + writel(0x42005, base + 0x0); + scu_busy_loop(base); + + /* scu ipc: de-assert hdmi controller reset */ + writel(0xff11d118, base + 0x0c); + writel(0x7fffffff, base + 0x80); + writel(0x42005, base + 0x0); + scu_busy_loop(base); + + iounmap(base); +} + +static void mrst_hdmi_audio_enable(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; + + HDMI_WRITE(HDMI_HCR, 0x67); + HDMI_READ(HDMI_HCR); + + HDMI_WRITE(0x51a8, 0x10); + HDMI_READ(0x51a8); + + HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1); + HDMI_READ(HDMI_AUDIO_CTRL); +} + +static void mrst_hdmi_audio_disable(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; + + HDMI_WRITE(0x51a8, 0x0); + HDMI_READ(0x51a8); + + HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0); + HDMI_READ(HDMI_AUDIO_CTRL); + + HDMI_WRITE(HDMI_HCR, 0x47); + HDMI_READ(HDMI_HCR); +} + +void mrst_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode) +{ + struct drm_device *dev = crtc->dev; + u32 temp; + + switch (mode) { + case DRM_MODE_DPMS_OFF: + /* Disable VGACNTRL */ + REG_WRITE(VGACNTRL, 0x80000000); + + /* Disable plane */ + temp = REG_READ(DSPBCNTR); + if ((temp & DISPLAY_PLANE_ENABLE) != 0) { + REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE); + REG_READ(DSPBCNTR); + /* Flush the plane changes */ + REG_WRITE(DSPBSURF, REG_READ(DSPBSURF)); + REG_READ(DSPBSURF); + } + + /* Disable pipe B */ + temp = REG_READ(PIPEBCONF); + if ((temp & PIPEACONF_ENABLE) != 0) { + REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE); + REG_READ(PIPEBCONF); + } + + /* Disable LNW Pipes, etc */ + temp = REG_READ(PCH_PIPEBCONF); + if ((temp & PIPEACONF_ENABLE) != 0) { + REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE); + REG_READ(PCH_PIPEBCONF); + } + /* wait for pipe off */ + udelay(150); + /* Disable dpll */ + temp = REG_READ(DPLL_CTRL); + if ((temp & DPLL_PWRDN) == 0) { + REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET)); + REG_WRITE(DPLL_STATUS, 0x1); + } + /* wait for dpll off */ + udelay(150); + break; + case DRM_MODE_DPMS_ON: + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + /* Enable dpll */ + temp = REG_READ(DPLL_CTRL); + if ((temp & DPLL_PWRDN) != 0) { + REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET)); + temp = REG_READ(DPLL_CLK_ENABLE); + REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI); + REG_READ(DPLL_CLK_ENABLE); + } + /* wait for dpll warm up */ + udelay(150); + + /* Enable pipe B */ + temp = REG_READ(PIPEBCONF); + if ((temp & PIPEACONF_ENABLE) == 0) { + REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE); + REG_READ(PIPEBCONF); + } + + /* Enable LNW Pipe B */ + temp = REG_READ(PCH_PIPEBCONF); + if ((temp & PIPEACONF_ENABLE) == 0) { + REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE); + REG_READ(PCH_PIPEBCONF); + } + wait_for_vblank(dev); + + /* Enable plane */ + temp = REG_READ(DSPBCNTR); + if ((temp & DISPLAY_PLANE_ENABLE) == 0) { + REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE); + /* Flush the plane changes */ + REG_WRITE(DSPBSURF, REG_READ(DSPBSURF)); + REG_READ(DSPBSURF); + } + psb_intel_crtc_load_lut(crtc); + } + /* DSPARB */ + REG_WRITE(DSPARB, 0x00003fbf); + /* FW1 */ + REG_WRITE(0x70034, 0x3f880a0a); + /* FW2 */ + REG_WRITE(0x70038, 0x0b060808); + /* FW4 */ + REG_WRITE(0x70050, 0x08030404); + /* FW5 */ + REG_WRITE(0x70054, 0x04040404); + /* LNC Chicken Bits */ + REG_WRITE(0x70400, 0x4000); +} + + +static void mrst_hdmi_dpms(struct drm_encoder *encoder, int mode) +{ + static int dpms_mode = -1; + + struct drm_device *dev = encoder->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; + u32 temp; + + if (dpms_mode == mode) + return; + + if (mode != DRM_MODE_DPMS_ON) + temp = 0x0; + else + temp = 0x99; + + dpms_mode = mode; + HDMI_WRITE(HDMI_VIDEO_REG, temp); +} + +static unsigned int htotal_calculate(struct drm_display_mode *mode) +{ + u32 htotal, new_crtc_htotal; + + htotal = (mode->crtc_hdisplay - 1) | ((mode->crtc_htotal - 1) << 16); + + /* + * 1024 x 768 new_crtc_htotal = 0x1024; + * 1280 x 1024 new_crtc_htotal = 0x0c34; + */ + new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock; + + return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16); +} + +static void mrst_hdmi_find_dpll(struct drm_crtc *crtc, int target, + int refclk, struct mrst_hdmi_clock *best_clock) +{ + int np_min, np_max, nr_min, nr_max; + int np, nr, nf; + + np_min = DIV_ROUND_UP(mrst_hdmi_limit.vco.min, target * 10); + np_max = mrst_hdmi_limit.vco.max / (target * 10); + if (np_min < mrst_hdmi_limit.np.min) + np_min = mrst_hdmi_limit.np.min; + if (np_max > mrst_hdmi_limit.np.max) + np_max = mrst_hdmi_limit.np.max; + + nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max)); + nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min)); + if (nr_min < mrst_hdmi_limit.nr.min) + nr_min = mrst_hdmi_limit.nr.min; + if (nr_max > mrst_hdmi_limit.nr.max) + nr_max = mrst_hdmi_limit.nr.max; + + np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max)); + nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np)); + nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk); + DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf); + + /* + * 1024 x 768 np = 1; nr = 0x26; nf = 0x0fd8000; + * 1280 x 1024 np = 1; nr = 0x17; nf = 0x1034000; + */ + best_clock->np = np; + best_clock->nr = nr - 1; + best_clock->nf = (nf << 14); +} + +int mrst_crtc_hdmi_mode_set(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, + int x, int y, + struct drm_framebuffer *old_fb) +{ + struct drm_device *dev = crtc->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; + int pipe = 1; + int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; + int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; + int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; + int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; + int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; + int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; + int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; + int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; + int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + int refclk; + struct mrst_hdmi_clock clock; + u32 dspcntr, pipeconf, dpll, temp; + int dspcntr_reg = DSPBCNTR; + + /* Disable the VGA plane that we never use */ + REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); + + /* XXX: Disable the panel fitter if it was on our pipe */ + + /* Disable dpll if necessary */ + dpll = REG_READ(DPLL_CTRL); + if ((dpll & DPLL_PWRDN) == 0) { + REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET)); + REG_WRITE(DPLL_DIV_CTRL, 0x00000000); + REG_WRITE(DPLL_STATUS, 0x1); + } + udelay(150); + + /* reset controller: FIXME - can we sort out the ioremap mess ? */ + iounmap(hdmi_dev->regs); + mrst_hdmi_reset(dev); + + /* program and enable dpll */ + refclk = 25000; + mrst_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock); + + /* Setting DPLL */ + dpll = REG_READ(DPLL_CTRL); + dpll &= ~DPLL_PDIV_MASK; + dpll &= ~(DPLL_PWRDN | DPLL_RESET); + REG_WRITE(DPLL_CTRL, 0x00000008); + REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr)); + REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1)); + REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN)); + REG_WRITE(DPLL_UPDATE, 0x80000000); + REG_WRITE(DPLL_CLK_ENABLE, 0x80050102); + udelay(150); + + hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len); + if (hdmi_dev->regs == NULL) { + DRM_ERROR("failed to do hdmi mmio mapping\n"); + return -ENOMEM; + } + + /* configure HDMI */ + HDMI_WRITE(0x1004, 0x1fd); + HDMI_WRITE(0x2000, 0x1); + HDMI_WRITE(0x2008, 0x0); + HDMI_WRITE(0x3130, 0x8); + HDMI_WRITE(0x101c, 0x1800810); + + temp = htotal_calculate(adjusted_mode); + REG_WRITE(htot_reg, temp); + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16)); + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16)); + REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16)); + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16)); + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); + REG_WRITE(pipesrc_reg, + ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); + + REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); + REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16)); + REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16)); + REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16)); + REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16)); + REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); + REG_WRITE(PCH_PIPEBSRC, + ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); + + temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start; + HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) | temp); + + REG_WRITE(dspsize_reg, + ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); + REG_WRITE(dsppos_reg, 0); + + /* Flush the plane changes */ + { + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + crtc_funcs->mode_set_base(crtc, x, y, old_fb); + } + + /* Set up the display plane register */ + dspcntr = REG_READ(dspcntr_reg); + dspcntr |= DISPPLANE_GAMMA_ENABLE; + dspcntr |= DISPPLANE_SEL_PIPE_B; + dspcntr |= DISPLAY_PLANE_ENABLE; + + /* setup pipeconf */ + pipeconf = REG_READ(pipeconf_reg); + pipeconf |= PIPEACONF_ENABLE; + + REG_WRITE(pipeconf_reg, pipeconf); + REG_READ(pipeconf_reg); + + REG_WRITE(PCH_PIPEBCONF, pipeconf); + REG_READ(PCH_PIPEBCONF); + wait_for_vblank(dev); + + REG_WRITE(dspcntr_reg, dspcntr); + wait_for_vblank(dev); + + return 0; +} + +static int mrst_hdmi_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + if (mode->clock > 165000) + return MODE_CLOCK_HIGH; + if (mode->clock < 20000) + return MODE_CLOCK_LOW; + + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + return MODE_NO_DBLESCAN; + + return MODE_OK; +} + +static bool mrst_hdmi_mode_fixup(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static enum drm_connector_status +mrst_hdmi_detect(struct drm_connector *connector, bool force) +{ + enum drm_connector_status status; + struct drm_device *dev = connector->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; + u32 temp; + + temp = HDMI_READ(HDMI_HSR); + DRM_DEBUG_KMS("HDMI_HSR %x\n", temp); + + if ((temp & HDMI_DETECT_HDP) != 0) + status = connector_status_connected; + else + status = connector_status_disconnected; + + return status; +} + +static const unsigned char raw_edid[] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0, + 0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78, + 0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5, + 0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0, + 0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35, + 0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44, + 0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20, + 0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d +}; + +static int mrst_hdmi_get_modes(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_psb_private *dev_priv = dev->dev_private; + struct i2c_adapter *i2c_adap; + struct edid *edid; + struct drm_display_mode *mode, *t; + int i = 0, ret = 0; + + i2c_adap = i2c_get_adapter(3); + if (i2c_adap == NULL) { + DRM_ERROR("No ddc adapter available!\n"); + edid = (struct edid *)raw_edid; + } else { + edid = (struct edid *)raw_edid; + /* FIXME ? edid = drm_get_edid(connector, i2c_adap); */ + } + + if (edid) { + drm_mode_connector_update_edid_property(connector, edid); + ret = drm_add_edid_modes(connector, edid); + connector->display_info.raw_edid = NULL; + } + + /* + * prune modes that require frame buffer bigger than stolen mem + */ + list_for_each_entry_safe(mode, t, &connector->probed_modes, head) { + if ((mode->hdisplay * mode->vdisplay * 4) >= dev_priv->vram_stolen_size) { + i++; + drm_mode_remove(connector, mode); + } + } + return ret - i; +} + +static void mrst_hdmi_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *dev = encoder->dev; + + mrst_hdmi_audio_enable(dev); + return; +} + +static void mrst_hdmi_destroy(struct drm_connector *connector) +{ + return; +} + +static const struct drm_encoder_helper_funcs mrst_hdmi_helper_funcs = { + .dpms = mrst_hdmi_dpms, + .mode_fixup = mrst_hdmi_mode_fixup, + .prepare = psb_intel_encoder_prepare, + .mode_set = mrst_hdmi_mode_set, + .commit = psb_intel_encoder_commit, +}; + +static const struct drm_connector_helper_funcs + mrst_hdmi_connector_helper_funcs = { + .get_modes = mrst_hdmi_get_modes, + .mode_valid = mrst_hdmi_mode_valid, + .best_encoder = psb_intel_best_encoder, +}; + +static const struct drm_connector_funcs mrst_hdmi_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .detect = mrst_hdmi_detect, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = mrst_hdmi_destroy, +}; + +static void mrst_hdmi_enc_destroy(struct drm_encoder *encoder) +{ + drm_encoder_cleanup(encoder); +} + +static const struct drm_encoder_funcs mrst_hdmi_enc_funcs = { + .destroy = mrst_hdmi_enc_destroy, +}; + +void mrst_hdmi_init(struct drm_device *dev, + struct psb_intel_mode_device *mode_dev) +{ + struct psb_intel_output *psb_intel_output; + struct drm_connector *connector; + struct drm_encoder *encoder; + + psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL); + if (!psb_intel_output) + return; + + psb_intel_output->mode_dev = mode_dev; + connector = &psb_intel_output->base; + encoder = &psb_intel_output->enc; + drm_connector_init(dev, &psb_intel_output->base, + &mrst_hdmi_connector_funcs, + DRM_MODE_CONNECTOR_DVID); + + drm_encoder_init(dev, &psb_intel_output->enc, + &mrst_hdmi_enc_funcs, + DRM_MODE_ENCODER_TMDS); + + drm_mode_connector_attach_encoder(&psb_intel_output->base, + &psb_intel_output->enc); + + psb_intel_output->type = INTEL_OUTPUT_HDMI; + drm_encoder_helper_add(encoder, &mrst_hdmi_helper_funcs); + drm_connector_helper_add(connector, &mrst_hdmi_connector_helper_funcs); + + connector->display_info.subpixel_order = SubPixelHorizontalRGB; + connector->interlace_allowed = false; + connector->doublescan_allowed = false; + drm_sysfs_connector_add(connector); + + return; +} + +static DEFINE_PCI_DEVICE_TABLE(hdmi_ids) = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) }, + {} +}; + +void mrst_hdmi_setup(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct pci_dev *pdev; + struct mrst_hdmi_dev *hdmi_dev; + int ret; + + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL); + if (!pdev) + return; + + hdmi_dev = kzalloc(sizeof(struct mrst_hdmi_dev), GFP_KERNEL); + if (!hdmi_dev) { + dev_err(dev->dev, "failed to allocate memory\n"); + goto out; + } + + + ret = pci_enable_device(pdev); + if (ret) { + dev_err(dev->dev, "failed to enable hdmi controller\n"); + goto free; + } + + hdmi_dev->mmio = pci_resource_start(pdev, 0); + hdmi_dev->mmio_len = pci_resource_len(pdev, 0); + hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len); + if (!hdmi_dev->regs) { + dev_err(dev->dev, "failed to map hdmi mmio\n"); + goto free; + } + + hdmi_dev->dev = pdev; + pci_set_drvdata(pdev, hdmi_dev); + + /* Initialize i2c controller */ + ret = mrst_hdmi_i2c_init(hdmi_dev->dev); + if (ret) + dev_err(dev->dev, "HDMI I2C initialization failed\n"); + + dev_priv->hdmi_priv = hdmi_dev; + mrst_hdmi_audio_disable(dev); + return; + +free: + kfree(hdmi_dev); +out: + return; +} + +void mrst_hdmi_teardown(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; + struct pci_dev *pdev; + + if (hdmi_dev) { + pdev = hdmi_dev->dev; + pci_set_drvdata(pdev, NULL); + mrst_hdmi_i2c_exit(pdev); + iounmap(hdmi_dev->regs); + kfree(hdmi_dev); + pci_dev_put(pdev); + } +} + +/* save HDMI register state */ +void mrst_hdmi_save(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; + int i; + + /* dpll */ + hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL); + hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL); + hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST); + hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE); + hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE); + + /* pipe B */ + dev_priv->savePIPEBCONF = PSB_RVDC32(PIPEBCONF); + dev_priv->savePIPEBSRC = PSB_RVDC32(PIPEBSRC); + dev_priv->saveHTOTAL_B = PSB_RVDC32(HTOTAL_B); + dev_priv->saveHBLANK_B = PSB_RVDC32(HBLANK_B); + dev_priv->saveHSYNC_B = PSB_RVDC32(HSYNC_B); + dev_priv->saveVTOTAL_B = PSB_RVDC32(VTOTAL_B); + dev_priv->saveVBLANK_B = PSB_RVDC32(VBLANK_B); + dev_priv->saveVSYNC_B = PSB_RVDC32(VSYNC_B); + + hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF); + hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC); + hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B); + hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B); + hdmi_dev->savePCH_HSYNC_B = PSB_RVDC32(PCH_HSYNC_B); + hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B); + hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B); + hdmi_dev->savePCH_VSYNC_B = PSB_RVDC32(PCH_VSYNC_B); + + /* plane */ + dev_priv->saveDSPBCNTR = PSB_RVDC32(DSPBCNTR); + dev_priv->saveDSPBSTRIDE = PSB_RVDC32(DSPBSTRIDE); + dev_priv->saveDSPBADDR = PSB_RVDC32(DSPBBASE); + dev_priv->saveDSPBSURF = PSB_RVDC32(DSPBSURF); + dev_priv->saveDSPBLINOFF = PSB_RVDC32(DSPBLINOFF); + dev_priv->saveDSPBTILEOFF = PSB_RVDC32(DSPBTILEOFF); + + /* cursor B */ + dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR); + dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE); + dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS); + + /* save palette */ + for (i = 0; i < 256; i++) + dev_priv->save_palette_b[i] = PSB_RVDC32(PALETTE_B + (i << 2)); +} + +/* restore HDMI register state */ +void mrst_hdmi_restore(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct mrst_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; + int i; + + /* dpll */ + PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL); + PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL); + PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST); + PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE); + PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE); + DRM_UDELAY(150); + + /* pipe */ + PSB_WVDC32(dev_priv->savePIPEBSRC, PIPEBSRC); + PSB_WVDC32(dev_priv->saveHTOTAL_B, HTOTAL_B); + PSB_WVDC32(dev_priv->saveHBLANK_B, HBLANK_B); + PSB_WVDC32(dev_priv->saveHSYNC_B, HSYNC_B); + PSB_WVDC32(dev_priv->saveVTOTAL_B, VTOTAL_B); + PSB_WVDC32(dev_priv->saveVBLANK_B, VBLANK_B); + PSB_WVDC32(dev_priv->saveVSYNC_B, VSYNC_B); + + PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC); + PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B); + PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B); + PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B, PCH_HSYNC_B); + PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B); + PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B); + PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B, PCH_VSYNC_B); + + PSB_WVDC32(dev_priv->savePIPEBCONF, PIPEBCONF); + PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF); + + /* plane */ + PSB_WVDC32(dev_priv->saveDSPBLINOFF, DSPBLINOFF); + PSB_WVDC32(dev_priv->saveDSPBSTRIDE, DSPBSTRIDE); + PSB_WVDC32(dev_priv->saveDSPBTILEOFF, DSPBTILEOFF); + PSB_WVDC32(dev_priv->saveDSPBCNTR, DSPBCNTR); + PSB_WVDC32(dev_priv->saveDSPBSURF, DSPBSURF); + + /* cursor B */ + PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR); + PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS); + PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE); + + /* restore palette */ + for (i = 0; i < 256; i++) + PSB_WVDC32(dev_priv->save_palette_b[i], PALETTE_B + (i << 2)); +} diff --git a/drivers/staging/gma500/mrst_hdmi_i2c.c b/drivers/staging/gma500/mrst_hdmi_i2c.c new file mode 100644 index 000000000000..351b9d897b9f --- /dev/null +++ b/drivers/staging/gma500/mrst_hdmi_i2c.c @@ -0,0 +1,327 @@ +/* + * Copyright © 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: + * Li Peng + */ + +#include +#include +#include +#include +#include +#include "psb_drv.h" + +#define HDMI_READ(reg) readl(hdmi_dev->regs + (reg)) +#define HDMI_WRITE(reg, val) writel(val, hdmi_dev->regs + (reg)) + +#define HDMI_HCR 0x1000 +#define HCR_DETECT_HDP (1 << 6) +#define HCR_ENABLE_HDCP (1 << 5) +#define HCR_ENABLE_AUDIO (1 << 2) +#define HCR_ENABLE_PIXEL (1 << 1) +#define HCR_ENABLE_TMDS (1 << 0) +#define HDMI_HICR 0x1004 +#define HDMI_INTR_I2C_ERROR (1 << 4) +#define HDMI_INTR_I2C_FULL (1 << 3) +#define HDMI_INTR_I2C_DONE (1 << 2) +#define HDMI_INTR_HPD (1 << 0) +#define HDMI_HSR 0x1008 +#define HDMI_HISR 0x100C +#define HDMI_HI2CRDB0 0x1200 +#define HDMI_HI2CHCR 0x1240 +#define HI2C_HDCP_WRITE (0 << 2) +#define HI2C_HDCP_RI_READ (1 << 2) +#define HI2C_HDCP_READ (2 << 2) +#define HI2C_EDID_READ (3 << 2) +#define HI2C_READ_CONTINUE (1 << 1) +#define HI2C_ENABLE_TRANSACTION (1 << 0) + +#define HDMI_ICRH 0x1100 +#define HDMI_HI2CTDR0 0x1244 +#define HDMI_HI2CTDR1 0x1248 + +#define I2C_STAT_INIT 0 +#define I2C_READ_DONE 1 +#define I2C_TRANSACTION_DONE 2 + +struct hdmi_i2c_dev { + struct i2c_adapter *adap; + struct mutex i2c_lock; + struct completion complete; + int status; + struct i2c_msg *msg; + int buf_offset; +}; + +static void hdmi_i2c_irq_enable(struct mrst_hdmi_dev *hdmi_dev) +{ + u32 temp; + + temp = HDMI_READ(HDMI_HICR); + temp |= (HDMI_INTR_I2C_ERROR | HDMI_INTR_I2C_FULL | HDMI_INTR_I2C_DONE); + HDMI_WRITE(HDMI_HICR, temp); + HDMI_READ(HDMI_HICR); +} + +static void hdmi_i2c_irq_disable(struct mrst_hdmi_dev *hdmi_dev) +{ + HDMI_WRITE(HDMI_HICR, 0x0); + HDMI_READ(HDMI_HICR); +} + +static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg) +{ + struct mrst_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap); + struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; + u32 temp; + + i2c_dev->status = I2C_STAT_INIT; + i2c_dev->msg = pmsg; + i2c_dev->buf_offset = 0; + INIT_COMPLETION(i2c_dev->complete); + + /* Enable I2C transaction */ + temp = ((pmsg->len) << 20) | HI2C_EDID_READ | HI2C_ENABLE_TRANSACTION; + HDMI_WRITE(HDMI_HI2CHCR, temp); + HDMI_READ(HDMI_HI2CHCR); + + while (i2c_dev->status != I2C_TRANSACTION_DONE) + wait_for_completion_interruptible_timeout(&i2c_dev->complete, + 10 * HZ); + + return 0; +} + +static int xfer_write(struct i2c_adapter *adap, struct i2c_msg *pmsg) +{ + /* + * XXX: i2c write seems isn't useful for EDID probe, don't do anything + */ + return 0; +} + +static int mrst_hdmi_i2c_access(struct i2c_adapter *adap, + struct i2c_msg *pmsg, + int num) +{ + struct mrst_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap); + struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; + int i, err = 0; + + mutex_lock(&i2c_dev->i2c_lock); + + /* Enable i2c unit */ + HDMI_WRITE(HDMI_ICRH, 0x00008760); + + /* Enable irq */ + hdmi_i2c_irq_enable(hdmi_dev); + for (i = 0; i < num; i++) { + if (pmsg->len && pmsg->buf) { + if (pmsg->flags & I2C_M_RD) + err = xfer_read(adap, pmsg); + else + err = xfer_write(adap, pmsg); + } + pmsg++; /* next message */ + } + + /* Disable irq */ + hdmi_i2c_irq_disable(hdmi_dev); + + mutex_unlock(&i2c_dev->i2c_lock); + + return i; +} + +static u32 mrst_hdmi_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR; +} + +static const struct i2c_algorithm mrst_hdmi_i2c_algorithm = { + .master_xfer = mrst_hdmi_i2c_access, + .functionality = mrst_hdmi_i2c_func, +}; + +static struct i2c_adapter mrst_hdmi_i2c_adapter = { + .name = "mrst_hdmi_i2c", + .nr = 3, + .owner = THIS_MODULE, + .class = I2C_CLASS_DDC, + .algo = &mrst_hdmi_i2c_algorithm, +}; + +static void hdmi_i2c_read(struct mrst_hdmi_dev *hdmi_dev) +{ + struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; + struct i2c_msg *msg = i2c_dev->msg; + u8 *buf = msg->buf; + u32 temp; + int i, offset; + + offset = i2c_dev->buf_offset; + for (i = 0; i < 0x10; i++) { + temp = HDMI_READ(HDMI_HI2CRDB0 + (i * 4)); + memcpy(buf + (offset + i * 4), &temp, 4); + } + i2c_dev->buf_offset += (0x10 * 4); + + /* clearing read buffer full intr */ + temp = HDMI_READ(HDMI_HISR); + HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_FULL); + HDMI_READ(HDMI_HISR); + + /* continue read transaction */ + temp = HDMI_READ(HDMI_HI2CHCR); + HDMI_WRITE(HDMI_HI2CHCR, temp | HI2C_READ_CONTINUE); + HDMI_READ(HDMI_HI2CHCR); + + i2c_dev->status = I2C_READ_DONE; + return; +} + +static void hdmi_i2c_transaction_done(struct mrst_hdmi_dev *hdmi_dev) +{ + struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; + u32 temp; + + /* clear transaction done intr */ + temp = HDMI_READ(HDMI_HISR); + HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_DONE); + HDMI_READ(HDMI_HISR); + + + temp = HDMI_READ(HDMI_HI2CHCR); + HDMI_WRITE(HDMI_HI2CHCR, temp & ~HI2C_ENABLE_TRANSACTION); + HDMI_READ(HDMI_HI2CHCR); + + i2c_dev->status = I2C_TRANSACTION_DONE; + return; +} + +static irqreturn_t mrst_hdmi_i2c_handler(int this_irq, void *dev) +{ + struct mrst_hdmi_dev *hdmi_dev = dev; + struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev; + u32 stat; + + stat = HDMI_READ(HDMI_HISR); + + if (stat & HDMI_INTR_HPD) { + HDMI_WRITE(HDMI_HISR, stat | HDMI_INTR_HPD); + HDMI_READ(HDMI_HISR); + } + + if (stat & HDMI_INTR_I2C_FULL) + hdmi_i2c_read(hdmi_dev); + + if (stat & HDMI_INTR_I2C_DONE) + hdmi_i2c_transaction_done(hdmi_dev); + + complete(&i2c_dev->complete); + + return IRQ_HANDLED; +} + +/* + * choose alternate function 2 of GPIO pin 52, 53, + * which is used by HDMI I2C logic + */ +static void mrst_hdmi_i2c_gpio_fix(void) +{ + void *base; + unsigned int gpio_base = 0xff12c000; + int gpio_len = 0x1000; + u32 temp; + + base = ioremap((resource_size_t)gpio_base, gpio_len); + if (base == NULL) { + DRM_ERROR("gpio ioremap fail\n"); + return; + } + + temp = readl(base + 0x44); + DRM_DEBUG_DRIVER("old gpio val %x\n", temp); + writel((temp | 0x00000a00), (base + 0x44)); + temp = readl(base + 0x44); + DRM_DEBUG_DRIVER("new gpio val %x\n", temp); + + iounmap(base); +} + +int mrst_hdmi_i2c_init(struct pci_dev *dev) +{ + struct mrst_hdmi_dev *hdmi_dev; + struct hdmi_i2c_dev *i2c_dev; + int ret; + + hdmi_dev = pci_get_drvdata(dev); + + i2c_dev = kzalloc(sizeof(struct hdmi_i2c_dev), GFP_KERNEL); + if (i2c_dev == NULL) { + DRM_ERROR("Can't allocate interface\n"); + ret = -ENOMEM; + goto exit; + } + + i2c_dev->adap = &mrst_hdmi_i2c_adapter; + i2c_dev->status = I2C_STAT_INIT; + init_completion(&i2c_dev->complete); + mutex_init(&i2c_dev->i2c_lock); + i2c_set_adapdata(&mrst_hdmi_i2c_adapter, hdmi_dev); + hdmi_dev->i2c_dev = i2c_dev; + + /* Enable HDMI I2C function on gpio */ + mrst_hdmi_i2c_gpio_fix(); + + /* request irq */ + ret = request_irq(dev->irq, mrst_hdmi_i2c_handler, IRQF_SHARED, + mrst_hdmi_i2c_adapter.name, hdmi_dev); + if (ret) { + DRM_ERROR("Failed to request IRQ for I2C controller\n"); + goto err; + } + + /* Adapter registration */ + ret = i2c_add_numbered_adapter(&mrst_hdmi_i2c_adapter); + return ret; + +err: + kfree(i2c_dev); +exit: + return ret; +} + +void mrst_hdmi_i2c_exit(struct pci_dev *dev) +{ + struct mrst_hdmi_dev *hdmi_dev; + struct hdmi_i2c_dev *i2c_dev; + + hdmi_dev = pci_get_drvdata(dev); + if (i2c_del_adapter(&mrst_hdmi_i2c_adapter)) + DRM_DEBUG_DRIVER("Failed to delete hdmi-i2c adapter\n"); + + i2c_dev = hdmi_dev->i2c_dev; + kfree(i2c_dev); + free_irq(dev->irq, hdmi_dev); +} diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c index 4a08b74f5ff9..e7999a2a3796 100644 --- a/drivers/staging/gma500/mrst_lvds.c +++ b/drivers/staging/gma500/mrst_lvds.c @@ -24,11 +24,11 @@ #include #include -#include "psb_intel_bios.h" +#include "intel_bios.h" #include "psb_drv.h" #include "psb_intel_drv.h" #include "psb_intel_reg.h" -#include "psb_powermgmt.h" +#include "power.h" #include /* The max/min PWM frequency in BPCR[31:17] - */ @@ -46,8 +46,7 @@ static void mrst_lvds_set_power(struct drm_device *dev, struct psb_intel_output *output, bool on) { u32 pp_status; - DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private; - PSB_DEBUG_ENTRY("\n"); + struct drm_psb_private *dev_priv = dev->dev_private; if (!gma_power_begin(dev, true)) return; @@ -59,7 +58,11 @@ static void mrst_lvds_set_power(struct drm_device *dev, pp_status = REG_READ(PP_STATUS); } while ((pp_status & (PP_ON | PP_READY)) == PP_READY); dev_priv->is_lvds_on = true; + if (dev_priv->ops->lvds_bl_power) + dev_priv->ops->lvds_bl_power(dev, true); } else { + if (dev_priv->ops->lvds_bl_power) + dev_priv->ops->lvds_bl_power(dev, false); REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON); do { @@ -68,7 +71,6 @@ static void mrst_lvds_set_power(struct drm_device *dev, dev_priv->is_lvds_on = false; pm_request_idle(&dev->pdev->dev); } - gma_power_end(dev); } @@ -77,8 +79,6 @@ static void mrst_lvds_dpms(struct drm_encoder *encoder, int mode) struct drm_device *dev = encoder->dev; struct psb_intel_output *output = enc_to_psb_intel_output(encoder); - PSB_DEBUG_ENTRY("\n"); - if (mode == DRM_MODE_DPMS_ON) mrst_lvds_set_power(dev, output, true); else @@ -94,11 +94,10 @@ static void mrst_lvds_mode_set(struct drm_encoder *encoder, struct psb_intel_mode_device *mode_dev = enc_to_psb_intel_output(encoder)->mode_dev; struct drm_device *dev = encoder->dev; + struct drm_psb_private *dev_priv = dev->dev_private; u32 lvds_port; uint64_t v = DRM_MODE_SCALE_FULLSCREEN; - PSB_DEBUG_ENTRY("\n"); - if (!gma_power_begin(dev, true)) return; @@ -112,7 +111,9 @@ static void mrst_lvds_mode_set(struct drm_encoder *encoder, LVDS_PORT_EN | LVDS_BORDER_EN; - if (mode_dev->panel_wants_dither) + /* If the firmware says dither on Moorestown, or the BIOS does + on Oaktrail then enable dithering */ + if (mode_dev->panel_wants_dither || dev_priv->lvds_dither) lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE; REG_WRITE(LVDS, lvds_port); @@ -146,13 +147,59 @@ static void mrst_lvds_mode_set(struct drm_encoder *encoder, gma_power_end(dev); } +static void mrst_lvds_prepare(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + struct psb_intel_mode_device *mode_dev = output->mode_dev; + + if (!gma_power_begin(dev, true)) + return; + + mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL); + mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL & + BACKLIGHT_DUTY_CYCLE_MASK); + mrst_lvds_set_power(dev, output, false); + gma_power_end(dev); +} + +static u32 mrst_lvds_get_max_backlight(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + u32 ret; + + if (gma_power_begin(dev, false)) { + ret = ((REG_READ(BLC_PWM_CTL) & + BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; + + gma_power_end(dev); + } else + ret = ((dev_priv->saveBLC_PWM_CTL & + BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; + + return ret; +} + +static void mrst_lvds_commit(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct psb_intel_output *output = enc_to_psb_intel_output(encoder); + struct psb_intel_mode_device *mode_dev = output->mode_dev; + + if (mode_dev->backlight_duty_cycle == 0) + mode_dev->backlight_duty_cycle = + mrst_lvds_get_max_backlight(dev); + mrst_lvds_set_power(dev, output, true); +} static const struct drm_encoder_helper_funcs mrst_lvds_helper_funcs = { .dpms = mrst_lvds_dpms, .mode_fixup = psb_intel_lvds_mode_fixup, - .prepare = psb_intel_lvds_prepare, + .prepare = mrst_lvds_prepare, .mode_set = mrst_lvds_mode_set, - .commit = psb_intel_lvds_commit, + .commit = mrst_lvds_commit, }; static struct drm_display_mode lvds_configuration_modes[] = { @@ -252,8 +299,6 @@ void mrst_lvds_init(struct drm_device *dev, struct i2c_adapter *i2c_adap; struct drm_display_mode *scan; /* *modes, *bios_mode; */ - PSB_DEBUG_ENTRY("\n"); - psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL); if (!psb_intel_output) return; @@ -302,16 +347,10 @@ void mrst_lvds_init(struct drm_device *dev, * if closed, act like it's not there for now */ - /* This ifdef can go once the cpu ident stuff is cleaned up in arch */ -#if defined(CONFIG_X86_MRST) - if (mrst_identify_cpu()) - i2c_adap = i2c_get_adapter(2); - else /* Oaktrail uses I2C 1 */ -#endif - i2c_adap = i2c_get_adapter(1); + i2c_adap = i2c_get_adapter(dev_priv->ops->i2c_bus); if (i2c_adap == NULL) - printk(KERN_ALERT "No ddc adapter available!\n"); + dev_err(dev->dev, "No ddc adapter available!\n"); /* * Attempt to get the fixed panel mode from DDC. Assume that the * preferred mode is the right one. @@ -333,7 +372,6 @@ void mrst_lvds_init(struct drm_device *dev, } } } - /* * If we didn't get EDID, try geting panel timing * from configuration data @@ -341,15 +379,13 @@ void mrst_lvds_init(struct drm_device *dev, mode_dev->panel_fixed_mode = mrst_lvds_get_configuration_mode(dev); if (mode_dev->panel_fixed_mode) { - mode_dev->panel_fixed_mode->type |= - DRM_MODE_TYPE_PREFERRED; + mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; goto out; /* FIXME: check for quirks */ } /* If we still don't have a mode after all that, give up. */ if (!mode_dev->panel_fixed_mode) { - DRM_DEBUG - ("Found no modes on the lvds, ignoring the LVDS\n"); + dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n"); goto failed_find; } @@ -358,7 +394,7 @@ void mrst_lvds_init(struct drm_device *dev, return; failed_find: - DRM_DEBUG("No LVDS modes found, disabling.\n"); + dev_dbg(dev->dev, "No LVDS modes found, disabling.\n"); if (psb_intel_output->ddc_bus) psb_intel_i2c_destroy(psb_intel_output->ddc_bus); diff --git a/drivers/staging/gma500/psb_powermgmt.c b/drivers/staging/gma500/power.c similarity index 59% rename from drivers/staging/gma500/psb_powermgmt.c rename to drivers/staging/gma500/power.c index 1495415be6c7..972bea7c1af2 100644 --- a/drivers/staging/gma500/psb_powermgmt.c +++ b/drivers/staging/gma500/power.c @@ -1,7 +1,7 @@ /************************************************************************** - * Copyright (c) 2009, Intel Corporation. + * Copyright (c) 2009-2011, Intel Corporation. * 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 @@ -27,14 +27,16 @@ * Massively reworked * Alan Cox */ -#include "psb_powermgmt.h" + +#include "power.h" #include "psb_drv.h" #include "psb_reg.h" #include "psb_intel_reg.h" #include #include -static struct mutex power_mutex; +static struct mutex power_mutex; /* Serialize power ops */ +static spinlock_t power_ctrl_lock; /* Serialize power claim */ /** * gma_power_init - initialise power manager @@ -46,23 +48,17 @@ void gma_power_init(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; + /* FIXME: Move APM/OSPM base into relevant device code */ dev_priv->apm_base = dev_priv->apm_reg & 0xffff; dev_priv->ospm_base &= 0xffff; dev_priv->display_power = true; /* We start active */ dev_priv->display_count = 0; /* Currently no users */ dev_priv->suspended = false; /* And not suspended */ + spin_lock_init(&power_ctrl_lock); mutex_init(&power_mutex); - if (!IS_MRST(dev)) { - /* FIXME: wants further review */ - u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL); - /* Disable 2D clock gating */ - gating &= ~3; - gating |= 1; - PSB_WSGX32(gating, PSB_CR_CLKGATECTL); - PSB_RSGX32(PSB_CR_CLKGATECTL); - } + dev_priv->ops->init_pm(dev); } /** @@ -73,114 +69,10 @@ void gma_power_init(struct drm_device *dev) */ void gma_power_uninit(struct drm_device *dev) { - mutex_destroy(&power_mutex); pm_runtime_disable(&dev->pdev->dev); pm_runtime_set_suspended(&dev->pdev->dev); } - -/** - * save_display_registers - save registers lost on suspend - * @dev: our DRM device - * - * Save the state we need in order to be able to restore the interface - * upon resume from suspend - */ -static int save_display_registers(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - struct drm_connector *connector; - - /* Display arbitration control + watermarks */ - dev_priv->saveDSPARB = PSB_RVDC32(DSPARB); - dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1); - dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2); - dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3); - dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4); - dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5); - dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6); - dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT); - - /* Save crtc and output state */ - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (drm_helper_crtc_in_use(crtc)) - crtc->funcs->save(crtc); - } - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - connector->funcs->save(connector); - - mutex_unlock(&dev->mode_config.mutex); - return 0; -} - -/** - * restore_display_registers - restore lost register state - * @dev: our DRM device - * - * Restore register state that was lost during suspend and resume. - */ -static int restore_display_registers(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc; - struct drm_connector *connector; - - /* Display arbitration + watermarks */ - PSB_WVDC32(dev_priv->saveDSPARB, DSPARB); - PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1); - PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2); - PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3); - PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4); - PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5); - PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6); - PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT); - - /*make sure VGA plane is off. it initializes to on after reset!*/ - PSB_WVDC32(0x80000000, VGACNTRL); - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - if (drm_helper_crtc_in_use(crtc)) - crtc->funcs->restore(crtc); - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - connector->funcs->restore(connector); - - mutex_unlock(&dev->mode_config.mutex); - return 0; -} - -/** - * power_down - power down the display island - * @dev: our DRM device - * - * Power down the display interface of our device - */ -static void power_down(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pwr_mask ; - u32 pwr_sts; - - if (IS_MRST(dev)) { - pwr_mask = PSB_PWRGT_DISPLAY_MASK; - outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC); - - while (true) { - pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); - if ((pwr_sts & pwr_mask) == pwr_mask) - break; - else - udelay(10); - } - dev_priv->display_power = false; - } -} - - /** * gma_suspend_display - suspend the display logic * @dev: our DRM device @@ -190,73 +82,12 @@ static void power_down(struct drm_device *dev) static void gma_suspend_display(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - int pp_stat; if (dev_priv->suspended) return; - - save_display_registers(dev); - - if (dev_priv->iLVDS_enable) { - /*shutdown the panel*/ - PSB_WVDC32(0, PP_CONTROL); - - do { - pp_stat = PSB_RVDC32(PP_STATUS); - } while (pp_stat & 0x80000000); - - /*turn off the plane*/ - PSB_WVDC32(0x58000000, DSPACNTR); - PSB_WVDC32(0, DSPASURF);/*trigger the plane disable*/ - /*wait ~4 ticks*/ - msleep(4); - - /*turn off pipe*/ - PSB_WVDC32(0x0, PIPEACONF); - /*wait ~8 ticks*/ - msleep(8); - - /*turn off PLLs*/ - PSB_WVDC32(0, MRST_DPLL_A); - } else { - PSB_WVDC32(DPI_SHUT_DOWN, DPI_CONTROL_REG); - PSB_WVDC32(0x0, PIPEACONF); - PSB_WVDC32(0x2faf0000, BLC_PWM_CTL); - while (REG_READ(0x70008) & 0x40000000); - while ((PSB_RVDC32(GEN_FIFO_STAT_REG) & DPI_FIFO_EMPTY) - != DPI_FIFO_EMPTY); - PSB_WVDC32(0, DEVICE_READY_REG); - /* turn off panel power */ - } - power_down(dev); -} - -/* - * power_up - * - * Description: Restore power to the specified island(s) (powergating) - */ -static void power_up(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK; - u32 pwr_sts, pwr_cnt; - - if (IS_MRST(dev)) { - pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC); - pwr_cnt &= ~pwr_mask; - outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC)); - - while (true) { - pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS); - if ((pwr_sts & pwr_mask) == 0) - break; - else - udelay(10); - } - } - dev_priv->suspended = false; - dev_priv->display_power = true; + dev_priv->ops->save_regs(dev); + dev_priv->ops->power_down(dev); + dev_priv->display_power = false; } /** @@ -274,20 +105,14 @@ static void gma_resume_display(struct pci_dev *pdev) return; /* turn on the display power island */ - power_up(dev); + dev_priv->ops->power_up(dev); + dev_priv->suspended = false; + dev_priv->display_power = true; PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED); - - /* Don't reinitialize the GTT as it is unnecessary. The gtt is - * stored in memory so it will automatically be restored. All - * we need to do is restore the PGETBL_CTL which we already do - * above. - */ - /*psb_gtt_init(dev_priv->pg, 1);*/ - - restore_display_registers(dev); + dev_priv->ops->restore_regs(dev); } /** @@ -339,7 +164,7 @@ static bool gma_resume_pci(struct pci_dev *pdev) pci_restore_state(pdev); pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM); pci_write_config_dword(pdev, 0xFC, dev_priv->saveVBT); - /* retoring MSI address and data in PCIx space */ + /* restoring MSI address and data in PCIx space */ pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr); pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data); ret = pci_enable_device(pdev); @@ -360,8 +185,9 @@ static bool gma_resume_pci(struct pci_dev *pdev) * perform the necessary shut down steps and save enough state that * we can undo this when resume is called. */ -int gma_power_suspend(struct pci_dev *pdev, pm_message_t state) +int gma_power_suspend(struct device *_dev) { + struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev); struct drm_device *dev = pci_get_drvdata(pdev); struct drm_psb_private *dev_priv = dev->dev_private; @@ -379,15 +205,15 @@ int gma_power_suspend(struct pci_dev *pdev, pm_message_t state) return 0; } - /** * gma_power_resume - resume power * @pdev: PCI device * * Resume the PCI side of the graphics and then the displays */ -int gma_power_resume(struct pci_dev *pdev) +int gma_power_resume(struct device *_dev) { + struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev); struct drm_device *dev = pci_get_drvdata(pdev); mutex_lock(&power_mutex); @@ -399,8 +225,6 @@ int gma_power_resume(struct pci_dev *pdev) return 0; } - - /** * gma_power_is_on - returne true if power is on * @dev: our DRM device @@ -413,7 +237,6 @@ bool gma_power_is_on(struct drm_device *dev) return dev_priv->display_power; } - /** * gma_power_begin - begin requiring power * @dev: our DRM device @@ -421,22 +244,23 @@ bool gma_power_is_on(struct drm_device *dev) * * Begin an action that requires the display power island is enabled. * We refcount the islands. - * - * FIXME: locking */ bool gma_power_begin(struct drm_device *dev, bool force_on) { struct drm_psb_private *dev_priv = dev->dev_private; int ret; + unsigned long flags; + spin_lock_irqsave(&power_ctrl_lock, flags); /* Power already on ? */ if (dev_priv->display_power) { dev_priv->display_count++; pm_runtime_get(&dev->pdev->dev); + spin_unlock_irqrestore(&power_ctrl_lock, flags); return true; } if (force_on == false) - return false; + goto out_false; /* Ok power up needed */ ret = gma_resume_pci(dev->pdev); @@ -445,12 +269,14 @@ bool gma_power_begin(struct drm_device *dev, bool force_on) psb_irq_postinstall(dev); pm_runtime_get(&dev->pdev->dev); dev_priv->display_count++; + spin_unlock_irqrestore(&power_ctrl_lock, flags); return true; } +out_false: + spin_unlock_irqrestore(&power_ctrl_lock, flags); return false; } - /** * gma_power_end - end use of power * @dev: Our DRM device @@ -461,15 +287,17 @@ bool gma_power_begin(struct drm_device *dev, bool force_on) void gma_power_end(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; + unsigned long flags; + spin_lock_irqsave(&power_ctrl_lock, flags); dev_priv->display_count--; WARN_ON(dev_priv->display_count < 0); + spin_unlock_irqrestore(&power_ctrl_lock, flags); pm_runtime_put(&dev->pdev->dev); } int psb_runtime_suspend(struct device *dev) { - static pm_message_t dummy; - return gma_power_suspend(to_pci_dev(dev), dummy); + return gma_power_suspend(dev); } int psb_runtime_resume(struct device *dev) @@ -486,4 +314,3 @@ int psb_runtime_idle(struct device *dev) else return 1; } - diff --git a/drivers/staging/gma500/psb_powermgmt.h b/drivers/staging/gma500/power.h similarity index 94% rename from drivers/staging/gma500/psb_powermgmt.h rename to drivers/staging/gma500/power.h index e005229af798..1969d2ecb328 100644 --- a/drivers/staging/gma500/psb_powermgmt.h +++ b/drivers/staging/gma500/power.h @@ -1,5 +1,5 @@ /************************************************************************** - * Copyright (c) 2009, Intel Corporation. + * Copyright (c) 2009-2011, Intel Corporation. * All Rights Reserved. * Permission is hereby granted, free of charge, to any person obtaining a @@ -39,8 +39,8 @@ void gma_power_uninit(struct drm_device *dev); /* * The kernel bus power management will call these functions */ -int gma_power_suspend(struct pci_dev *pdev, pm_message_t state); -int gma_power_resume(struct pci_dev *pdev); +int gma_power_suspend(struct device *dev); +int gma_power_resume(struct device *dev); /* * These are the functions the driver should use to wrap all hw access diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c deleted file mode 100644 index 5dffc71c5125..000000000000 --- a/drivers/staging/gma500/psb_bl.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * psb backlight interface - * - * Copyright (c) 2009, Intel 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., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * Authors: Eric Knopp - * - */ - -#include -#include -#include "psb_drv.h" -#include "psb_intel_reg.h" -#include "psb_intel_drv.h" -#include "psb_intel_bios.h" -#include "psb_powermgmt.h" - -#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF -#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ -#define BLC_PWM_FREQ_CALC_CONSTANT 32 -#define MHz 1000000 -#define BRIGHTNESS_MIN_LEVEL 1 -#define BRIGHTNESS_MASK 0xFF -#define BLC_POLARITY_NORMAL 0 -#define BLC_POLARITY_INVERSE 1 -#define BLC_ADJUSTMENT_MAX 100 - -#define PSB_BLC_PWM_PRECISION_FACTOR 10 -#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE -#define PSB_BLC_MIN_PWM_REG_FREQ 0x2 - -#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) -#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) - -static int psb_brightness; -static struct backlight_device *psb_backlight_device; -static u8 blc_brightnesscmd; -static u8 blc_pol; -static u8 blc_type; - -int psb_set_brightness(struct backlight_device *bd) -{ - struct drm_device *dev = bl_get_data(psb_backlight_device); - int level = bd->props.brightness; - - DRM_DEBUG_DRIVER("backlight level set to %d\n", level); - - /* Percentage 1-100% being valid */ - if (level < 1) - level = 1; - - psb_intel_lvds_set_brightness(dev, level); - psb_brightness = level; - return 0; -} - -int mrst_set_brightness(struct backlight_device *bd) -{ - struct drm_device *dev = bl_get_data(psb_backlight_device); - struct drm_psb_private *dev_priv = dev->dev_private; - int level = bd->props.brightness; - u32 blc_pwm_ctl; - u32 max_pwm_blc; - - DRM_DEBUG_DRIVER("backlight level set to %d\n", level); - - /* Percentage 1-100% being valid */ - if (level < 1) - level = 1; - - if (gma_power_begin(dev, 0)) { - /* Calculate and set the brightness value */ - max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16; - blc_pwm_ctl = level * max_pwm_blc / 100; - - /* Adjust the backlight level with the percent in - * dev_priv->blc_adj1; - */ - blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1; - blc_pwm_ctl = blc_pwm_ctl / 100; - - /* Adjust the backlight level with the percent in - * dev_priv->blc_adj2; - */ - blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2; - blc_pwm_ctl = blc_pwm_ctl / 100; - - if (blc_pol == BLC_POLARITY_INVERSE) - blc_pwm_ctl = max_pwm_blc - blc_pwm_ctl; - /* force PWM bit on */ - REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2))); - REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl); - gma_power_end(dev); - } - psb_brightness = level; - return 0; -} - -int psb_get_brightness(struct backlight_device *bd) -{ - DRM_DEBUG_DRIVER("brightness = 0x%x\n", psb_brightness); - - /* return locally cached var instead of HW read (due to DPST etc.) */ - /* FIXME: ideally return actual value in case firmware fiddled with - it */ - return psb_brightness; -} - -static const struct backlight_ops psb_ops = { - .get_brightness = psb_get_brightness, - .update_status = psb_set_brightness, -}; - -static int device_backlight_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - unsigned long core_clock; - /* u32 bl_max_freq; */ - /* unsigned long value; */ - u16 bl_max_freq; - uint32_t value; - uint32_t blc_pwm_precision_factor; - - if (IS_MRST(dev)) { - dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX; - dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX; - bl_max_freq = 256; - /* this needs to be set elsewhere */ - blc_pol = BLC_POLARITY_NORMAL; - blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR; - } else { - /* get bl_max_freq and pol from dev_priv*/ - if (!dev_priv->lvds_bl) { - DRM_ERROR("Has no valid LVDS backlight info\n"); - return 1; - } - bl_max_freq = dev_priv->lvds_bl->freq; - blc_pol = dev_priv->lvds_bl->pol; - blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR; - blc_brightnesscmd = dev_priv->lvds_bl->brightnesscmd; - blc_type = dev_priv->lvds_bl->type; - } - - core_clock = dev_priv->core_freq; - - value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; - value *= blc_pwm_precision_factor; - value /= bl_max_freq; - value /= blc_pwm_precision_factor; - - if (gma_power_begin(dev, false)) { - if (IS_MRST(dev)) { - if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ) - return 2; - else { - REG_WRITE(BLC_PWM_CTL2, - (0x80000000 | REG_READ(BLC_PWM_CTL2))); - REG_WRITE(BLC_PWM_CTL, value | (value << 16)); - } - } else { - if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || - value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) - return 2; - else { - value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; - REG_WRITE(BLC_PWM_CTL, - (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | - (value)); - } - } - gma_power_end(dev); - } - return 0; -} - -int psb_backlight_init(struct drm_device *dev) -{ -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - int ret = 0; - - struct backlight_properties props; - memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = 100; - props.type = BACKLIGHT_PLATFORM; - - psb_backlight_device = backlight_device_register("psb-bl", NULL, - (void *)dev, &psb_ops, &props); - if (IS_ERR(psb_backlight_device)) - return PTR_ERR(psb_backlight_device); - - ret = device_backlight_init(dev); - if (ret < 0) - return ret; - - psb_backlight_device->props.brightness = 100; - psb_backlight_device->props.max_brightness = 100; - backlight_update_status(psb_backlight_device); -#endif - return 0; -} - -void psb_backlight_exit(void) -{ -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - psb_backlight_device->props.brightness = 0; - backlight_update_status(psb_backlight_device); - backlight_device_unregister(psb_backlight_device); -#endif -} - -struct backlight_device *psb_get_backlight_device(void) -{ - return psb_backlight_device; -} diff --git a/drivers/staging/gma500/psb_device.c b/drivers/staging/gma500/psb_device.c new file mode 100644 index 000000000000..46591323595a --- /dev/null +++ b/drivers/staging/gma500/psb_device.c @@ -0,0 +1,353 @@ +/************************************************************************** + * Copyright (c) 2011, Intel Corporation. + * All Rights Reserved. + * + * 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. + * + **************************************************************************/ + +#include +#include +#include +#include "psb_drm.h" +#include "psb_drv.h" +#include "psb_reg.h" +#include "psb_intel_reg.h" +#include "intel_bios.h" + + +static int psb_output_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + psb_intel_lvds_init(dev, &dev_priv->mode_dev); + psb_intel_sdvo_init(dev, SDVOB); + return 0; +} + +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + +/* + * Poulsbo Backlight Interfaces + */ + +#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ +#define BLC_PWM_FREQ_CALC_CONSTANT 32 +#define MHz 1000000 + +#define PSB_BLC_PWM_PRECISION_FACTOR 10 +#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE +#define PSB_BLC_MIN_PWM_REG_FREQ 0x2 + +#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) +#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) + +static int psb_brightness; +static struct backlight_device *psb_backlight_device; + +static int psb_get_brightness(struct backlight_device *bd) +{ + /* return locally cached var instead of HW read (due to DPST etc.) */ + /* FIXME: ideally return actual value in case firmware fiddled with + it */ + return psb_brightness; +} + + +static int psb_backlight_setup(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + unsigned long core_clock; + /* u32 bl_max_freq; */ + /* unsigned long value; */ + u16 bl_max_freq; + uint32_t value; + uint32_t blc_pwm_precision_factor; + + /* get bl_max_freq and pol from dev_priv*/ + if (!dev_priv->lvds_bl) { + dev_err(dev->dev, "Has no valid LVDS backlight info\n"); + return -ENOENT; + } + bl_max_freq = dev_priv->lvds_bl->freq; + blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR; + + core_clock = dev_priv->core_freq; + + value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; + value *= blc_pwm_precision_factor; + value /= bl_max_freq; + value /= blc_pwm_precision_factor; + + if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || + value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) + return -ERANGE; + else { + value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR; + REG_WRITE(BLC_PWM_CTL, + (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (value)); + } + return 0; +} + +static int psb_set_brightness(struct backlight_device *bd) +{ + struct drm_device *dev = bl_get_data(psb_backlight_device); + int level = bd->props.brightness; + + /* Percentage 1-100% being valid */ + if (level < 1) + level = 1; + + psb_intel_lvds_set_brightness(dev, level); + psb_brightness = level; + return 0; +} + +static const struct backlight_ops psb_ops = { + .get_brightness = psb_get_brightness, + .update_status = psb_set_brightness, +}; + +static int psb_backlight_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + int ret; + struct backlight_properties props; + + memset(&props, 0, sizeof(struct backlight_properties)); + props.max_brightness = 100; + props.type = BACKLIGHT_PLATFORM; + + psb_backlight_device = backlight_device_register("psb-bl", + NULL, (void *)dev, &psb_ops, &props); + if (IS_ERR(psb_backlight_device)) + return PTR_ERR(psb_backlight_device); + + ret = psb_backlight_setup(dev); + if (ret < 0) { + backlight_device_unregister(psb_backlight_device); + psb_backlight_device = NULL; + return ret; + } + psb_backlight_device->props.brightness = 100; + psb_backlight_device->props.max_brightness = 100; + backlight_update_status(psb_backlight_device); + dev_priv->backlight_device = psb_backlight_device; + return 0; +} + +#endif + +/* + * Provide the Poulsbo specific chip logic and low level methods + * for power management + */ + +static void psb_init_pm(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + + u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL); + gating &= ~3; /* Disable 2D clock gating */ + gating |= 1; + PSB_WSGX32(gating, PSB_CR_CLKGATECTL); + PSB_RSGX32(PSB_CR_CLKGATECTL); +} + +/** + * psb_save_display_registers - save registers lost on suspend + * @dev: our DRM device + * + * Save the state we need in order to be able to restore the interface + * upon resume from suspend + */ +static int psb_save_display_registers(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + struct drm_connector *connector; + + /* Display arbitration control + watermarks */ + dev_priv->saveDSPARB = PSB_RVDC32(DSPARB); + dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1); + dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2); + dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3); + dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4); + dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5); + dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6); + dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT); + + /* Save crtc and output state */ + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if (drm_helper_crtc_in_use(crtc)) + crtc->funcs->save(crtc); + } + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + connector->funcs->save(connector); + + mutex_unlock(&dev->mode_config.mutex); + return 0; +} + +/** + * psb_restore_display_registers - restore lost register state + * @dev: our DRM device + * + * Restore register state that was lost during suspend and resume. + */ +static int psb_restore_display_registers(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + struct drm_connector *connector; + int pp_stat; + + /* Display arbitration + watermarks */ + PSB_WVDC32(dev_priv->saveDSPARB, DSPARB); + PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1); + PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2); + PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3); + PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4); + PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5); + PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6); + PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT); + + /*make sure VGA plane is off. it initializes to on after reset!*/ + PSB_WVDC32(0x80000000, VGACNTRL); + + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + if (drm_helper_crtc_in_use(crtc)) + crtc->funcs->restore(crtc); + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + connector->funcs->restore(connector); + + mutex_unlock(&dev->mode_config.mutex); + + if (dev_priv->iLVDS_enable) { + /*shutdown the panel*/ + PSB_WVDC32(0, PP_CONTROL); + do { + pp_stat = PSB_RVDC32(PP_STATUS); + } while (pp_stat & 0x80000000); + + /* Turn off the plane */ + PSB_WVDC32(0x58000000, DSPACNTR); + PSB_WVDC32(0, DSPASURF);/*trigger the plane disable*/ + /* Wait ~4 ticks */ + msleep(4); + /* Turn off pipe */ + PSB_WVDC32(0x0, PIPEACONF); + /* Wait ~8 ticks */ + msleep(8); + + /* Turn off PLLs */ + PSB_WVDC32(0, MRST_DPLL_A); + } else { + PSB_WVDC32(DPI_SHUT_DOWN, DPI_CONTROL_REG); + PSB_WVDC32(0x0, PIPEACONF); + PSB_WVDC32(0x2faf0000, BLC_PWM_CTL); + while (REG_READ(0x70008) & 0x40000000) + cpu_relax(); + while ((PSB_RVDC32(GEN_FIFO_STAT_REG) & DPI_FIFO_EMPTY) + != DPI_FIFO_EMPTY) + cpu_relax(); + PSB_WVDC32(0, DEVICE_READY_REG); + } + return 0; +} + +static int psb_power_down(struct drm_device *dev) +{ + return 0; +} + +static int psb_power_up(struct drm_device *dev) +{ + return 0; +} + +static void psb_get_core_freq(struct drm_device *dev) +{ + uint32_t clock; + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); + struct drm_psb_private *dev_priv = dev->dev_private; + + /*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/ + /*pci_write_config_dword(pci_root, 0xD0, 0xE0033000);*/ + + pci_write_config_dword(pci_root, 0xD0, 0xD0050300); + pci_read_config_dword(pci_root, 0xD4, &clock); + pci_dev_put(pci_root); + + switch (clock & 0x07) { + case 0: + dev_priv->core_freq = 100; + break; + case 1: + dev_priv->core_freq = 133; + break; + case 2: + dev_priv->core_freq = 150; + break; + case 3: + dev_priv->core_freq = 178; + break; + case 4: + dev_priv->core_freq = 200; + break; + case 5: + case 6: + case 7: + dev_priv->core_freq = 266; + default: + dev_priv->core_freq = 0; + } +} + +static int psb_chip_setup(struct drm_device *dev) +{ + psb_get_core_freq(dev); + gma_intel_opregion_init(dev); + psb_intel_init_bios(dev); + return 0; +} + +const struct psb_ops psb_chip_ops = { + .name = "Poulsbo", + .accel_2d = 1, + .pipes = 2, + .crtcs = 2, + .sgx_offset = PSB_SGX_OFFSET, + .chip_setup = psb_chip_setup, + + .crtc_helper = &psb_intel_helper_funcs, + .crtc_funcs = &psb_intel_crtc_funcs, + + .output_init = psb_output_init, + +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + .backlight_init = psb_backlight_init, +#endif + + .init_pm = psb_init_pm, + .save_regs = psb_save_display_registers, + .restore_regs = psb_restore_display_registers, + .power_down = psb_power_down, + .power_up = psb_power_up, +}; + diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h index 49ffdd5b90e2..0da846835688 100644 --- a/drivers/staging/gma500/psb_drm.h +++ b/drivers/staging/gma500/psb_drm.h @@ -1,5 +1,5 @@ /************************************************************************** - * Copyright (c) 2007, Intel Corporation. + * Copyright (c) 2007-2011, Intel Corporation. * All Rights Reserved. * Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA. * All Rights Reserved. @@ -22,84 +22,8 @@ #ifndef _PSB_DRM_H_ #define _PSB_DRM_H_ -#if defined(__linux__) && !defined(__KERNEL__) -#include -#include -#include "drm_mode.h" -#endif - -#define DRM_PSB_SAREA_MAJOR 0 -#define DRM_PSB_SAREA_MINOR 2 -#define PSB_FIXED_SHIFT 16 - #define PSB_NUM_PIPE 3 -/* - * Public memory types. - */ - -typedef s32 psb_fixed; -typedef u32 psb_ufixed; - -static inline s32 psb_int_to_fixed(int a) -{ - return a * (1 << PSB_FIXED_SHIFT); -} - -static inline u32 psb_unsigned_to_ufixed(unsigned int a) -{ - return a << PSB_FIXED_SHIFT; -} - -/*Status of the command sent to the gfx device.*/ -typedef enum { - DRM_CMD_SUCCESS, - DRM_CMD_FAILED, - DRM_CMD_HANG -} drm_cmd_status_t; - -struct drm_psb_scanout { - u32 buffer_id; /* DRM buffer object ID */ - u32 rotation; /* Rotation as in RR_rotation definitions */ - u32 stride; /* Buffer stride in bytes */ - u32 depth; /* Buffer depth in bits (NOT) bpp */ - u32 width; /* Buffer width in pixels */ - u32 height; /* Buffer height in lines */ - s32 transform[3][3]; /* Buffer composite transform */ - /* (scaling, rot, reflect) */ -}; - -#define DRM_PSB_SAREA_OWNERS 16 -#define DRM_PSB_SAREA_OWNER_2D 0 -#define DRM_PSB_SAREA_OWNER_3D 1 - -#define DRM_PSB_SAREA_SCANOUTS 3 - -struct drm_psb_sarea { - /* Track changes of this data structure */ - - u32 major; - u32 minor; - - /* Last context to touch part of hw */ - u32 ctx_owners[DRM_PSB_SAREA_OWNERS]; - - /* Definition of front- and rotated buffers */ - u32 num_scanouts; - struct drm_psb_scanout scanouts[DRM_PSB_SAREA_SCANOUTS]; - - int planeA_x; - int planeA_y; - int planeA_w; - int planeA_h; - int planeB_x; - int planeB_y; - int planeB_w; - int planeB_h; - /* Number of active scanouts */ - u32 num_active_scanouts; -}; - #define PSB_GPU_ACCESS_READ (1ULL << 32) #define PSB_GPU_ACCESS_WRITE (1ULL << 33) #define PSB_GPU_ACCESS_MASK (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE) @@ -194,10 +118,10 @@ struct drm_psb_register_rw_arg { u32 OGAMC3; u32 OGAMC4; u32 OGAMC5; - u32 IEP_ENABLED; - u32 IEP_BLE_MINMAX; - u32 IEP_BSSCC_CONTROL; - u32 b_wait_vblank; + u32 IEP_ENABLED; + u32 IEP_BLE_MINMAX; + u32 IEP_BSSCC_CONTROL; + u32 b_wait_vblank; } overlay; u32 sprite_enable_mask; @@ -221,44 +145,27 @@ struct drm_psb_register_rw_arg { /* Controlling the kernel modesetting buffers */ -#define DRM_PSB_KMS_OFF 0x00 -#define DRM_PSB_KMS_ON 0x01 -#define DRM_PSB_VT_LEAVE 0x02 -#define DRM_PSB_VT_ENTER 0x03 -#define DRM_PSB_EXTENSION 0x06 #define DRM_PSB_SIZES 0x07 #define DRM_PSB_FUSE_REG 0x08 -#define DRM_PSB_VBT 0x09 #define DRM_PSB_DC_STATE 0x0A #define DRM_PSB_ADB 0x0B #define DRM_PSB_MODE_OPERATION 0x0C #define DRM_PSB_STOLEN_MEMORY 0x0D #define DRM_PSB_REGISTER_RW 0x0E -#define DRM_PSB_GTT_MAP 0x0F -#define DRM_PSB_GTT_UNMAP 0x10 -#define DRM_PSB_GETPAGEADDRS 0x11 -/** + +/* * NOTE: Add new commands here, but increment * the values below and increment their * corresponding defines where they're * defined elsewhere. */ -#define DRM_PVR_RESERVED1 0x12 -#define DRM_PVR_RESERVED2 0x13 -#define DRM_PVR_RESERVED3 0x14 -#define DRM_PVR_RESERVED4 0x15 -#define DRM_PVR_RESERVED5 0x16 -#define DRM_PSB_HIST_ENABLE 0x17 -#define DRM_PSB_HIST_STATUS 0x18 -#define DRM_PSB_UPDATE_GUARD 0x19 -#define DRM_PSB_INIT_COMM 0x1A +#define DRM_PSB_GEM_CREATE 0x10 +#define DRM_PSB_2D_OP 0x11 +#define DRM_PSB_GEM_MMAP 0x12 #define DRM_PSB_DPST 0x1B #define DRM_PSB_GAMMA 0x1C #define DRM_PSB_DPST_BL 0x1D - -#define DRM_PVR_RESERVED6 0x1E - #define DRM_PSB_GET_PIPE_FROM_CRTC_ID 0x1F #define PSB_MODE_OPERATION_MODE_VALID 0x01 @@ -272,4 +179,41 @@ struct drm_psb_get_pipe_from_crtc_id_arg { u32 pipe; }; +/* FIXME: move this into a medfield header once we are sure it isn't needed for an + ioctl */ +struct psb_drm_dpu_rect { + int x, y; + int width, height; +}; + +struct drm_psb_gem_create { + __u64 size; + __u32 handle; + __u32 flags; +#define PSB_GEM_CREATE_STOLEN 1 /* Stolen memory can be used */ +}; + +#define PSB_2D_OP_BUFLEN 16 + +struct drm_psb_2d_op { + __u32 src; /* Handles, only src supported right now */ + __u32 dst; + __u32 mask; + __u32 pat; + __u32 size; /* In dwords of command */ + __u32 spare; /* And bumps array to u64 align */ + __u32 cmd[PSB_2D_OP_BUFLEN]; +}; + +struct drm_psb_gem_mmap { + __u32 handle; + __u32 pad; + /** + * Fake offset to use for subsequent mmap call + * + * This is a fixed-size type for 32/64 compatibility. + */ + __u64 offset; +}; + #endif diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index aa87b1b6a44a..b2cdce7b97ef 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -1,5 +1,5 @@ /************************************************************************** - * Copyright (c) 2007, Intel Corporation. + * Copyright (c) 2007-2011, Intel Corporation. * All Rights Reserved. * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA. * All Rights Reserved. @@ -23,44 +23,65 @@ #include #include "psb_drm.h" #include "psb_drv.h" -#include "psb_fb.h" +#include "framebuffer.h" #include "psb_reg.h" #include "psb_intel_reg.h" -#include "psb_intel_bios.h" +#include "intel_bios.h" +#include "mid_bios.h" +#include "mdfld_dsi_dbi.h" #include -#include "psb_powermgmt.h" +#include "power.h" #include #include #include #include #include -int drm_psb_debug; static int drm_psb_trap_pagefaults; int drm_psb_no_fb; static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -MODULE_PARM_DESC(debug, "Enable debug output"); MODULE_PARM_DESC(no_fb, "Disable FBdev"); MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults"); -module_param_named(debug, drm_psb_debug, int, 0600); module_param_named(no_fb, drm_psb_no_fb, int, 0600); module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600); -static struct pci_device_id pciidlist[] = { - { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108 }, - { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109 }, - { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, - { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100}, +static DEFINE_PCI_DEVICE_TABLE(pciidlist) = { + { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops }, + { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops }, +#if defined(CONFIG_DRM_PSB_MRST) + { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops}, + { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops}, + { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops}, + { 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops}, + { 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops}, + { 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops}, + { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops}, + { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops}, +#endif +#if defined(CONFIG_DRM_PSB_MFLD) + { 0x8086, 0x0130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, + { 0x8086, 0x0131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, + { 0x8086, 0x0132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, + { 0x8086, 0x0133, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, + { 0x8086, 0x0134, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, + { 0x8086, 0x0135, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, + { 0x8086, 0x0136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, + { 0x8086, 0x0137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops}, +#endif +#if defined(CONFIG_DRM_PSB_CDV) + { 0x8086, 0x0be0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, + { 0x8086, 0x0be1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, + { 0x8086, 0x0be2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, + { 0x8086, 0x0be3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, + { 0x8086, 0x0be4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, + { 0x8086, 0x0be5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, + { 0x8086, 0x0be6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, + { 0x8086, 0x0be7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, +#endif { 0, 0, 0} }; MODULE_DEVICE_TABLE(pci, pciidlist); @@ -69,10 +90,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist); * Standard IOCTLs. */ -#define DRM_IOCTL_PSB_KMS_OFF \ - DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE) -#define DRM_IOCTL_PSB_KMS_ON \ - DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE) #define DRM_IOCTL_PSB_SIZES \ DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \ struct drm_psb_sizes_arg) @@ -104,6 +121,15 @@ MODULE_DEVICE_TABLE(pci, pciidlist); #define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID \ DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \ struct drm_psb_get_pipe_from_crtc_id_arg) +#define DRM_IOCTL_PSB_GEM_CREATE \ + DRM_IOWR(DRM_PSB_GEM_CREATE + DRM_COMMAND_BASE, \ + struct drm_psb_gem_create) +#define DRM_IOCTL_PSB_2D_OP \ + DRM_IOW(DRM_PSB_2D_OP + DRM_COMMAND_BASE, \ + struct drm_psb_2d_op) +#define DRM_IOCTL_PSB_GEM_MMAP \ + DRM_IOWR(DRM_PSB_GEM_MMAP + DRM_COMMAND_BASE, \ + struct drm_psb_gem_mmap) static int psb_sizes_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -128,11 +154,6 @@ static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data, [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func} static struct drm_ioctl_desc psb_ioctls[] = { - PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_OFF, psbfb_kms_off_ioctl, - DRM_ROOT_ONLY), - PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_ON, - psbfb_kms_on_ioctl, - DRM_ROOT_ONLY), PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH), PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH), PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH), @@ -147,7 +168,12 @@ static struct drm_ioctl_desc psb_ioctls[] = { PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH), PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID, psb_intel_get_pipe_from_crtc_id, 0), - + PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_CREATE, psb_gem_create_ioctl, + DRM_UNLOCKED | DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_2D_OP, psb_accel_ioctl, + DRM_UNLOCKED| DRM_AUTH), + PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_MMAP, psb_gem_mmap_ioctl, + DRM_UNLOCKED | DRM_AUTH), }; static void psb_lastclose(struct drm_device *dev) @@ -160,262 +186,17 @@ static void psb_do_takedown(struct drm_device *dev) /* FIXME: do we need to clean up the gtt here ? */ } -void mrst_get_fuse_settings(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - uint32_t fuse_value = 0; - uint32_t fuse_value_tmp = 0; - -#define FB_REG06 0xD0810600 -#define FB_MIPI_DISABLE (1 << 11) -#define FB_REG09 0xD0810900 -#define FB_REG09 0xD0810900 -#define FB_SKU_MASK 0x7000 -#define FB_SKU_SHIFT 12 -#define FB_SKU_100 0 -#define FB_SKU_100L 1 -#define FB_SKU_83 2 - pci_write_config_dword(pci_root, 0xD0, FB_REG06); - pci_read_config_dword(pci_root, 0xD4, &fuse_value); - - dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE; - - DRM_INFO("internal display is %s\n", - dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display"); - - /*prevent Runtime suspend at start*/ - if (dev_priv->iLVDS_enable) { - dev_priv->is_lvds_on = true; - dev_priv->is_mipi_on = false; - } - else { - dev_priv->is_mipi_on = true; - dev_priv->is_lvds_on = false; - } - - dev_priv->video_device_fuse = fuse_value; - - pci_write_config_dword(pci_root, 0xD0, FB_REG09); - pci_read_config_dword(pci_root, 0xD4, &fuse_value); - - DRM_INFO("SKU values is 0x%x. \n", fuse_value); - fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT; - - dev_priv->fuse_reg_value = fuse_value; - - switch (fuse_value_tmp) { - case FB_SKU_100: - dev_priv->core_freq = 200; - break; - case FB_SKU_100L: - dev_priv->core_freq = 100; - break; - case FB_SKU_83: - dev_priv->core_freq = 166; - break; - default: - DRM_ERROR("Invalid SKU values, SKU value = 0x%08x\n", fuse_value_tmp); - dev_priv->core_freq = 0; - } - DRM_INFO("LNC core clk is %dMHz.\n", dev_priv->core_freq); - pci_dev_put(pci_root); -} - -void mid_get_pci_revID (struct drm_psb_private *dev_priv) -{ - uint32_t platform_rev_id = 0; - struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); - - /*get the revison ID, B0:D2:F0;0x08 */ - pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id); - dev_priv->platform_rev_id = (uint8_t) platform_rev_id; - pci_dev_put(pci_gfx_root); - PSB_DEBUG_ENTRY("platform_rev_id is %x\n", dev_priv->platform_rev_id); -} - -void mrst_get_vbt_data(struct drm_psb_private *dev_priv) -{ - struct mrst_vbt *vbt = &dev_priv->vbt_data; - u32 platform_config_address; - u16 new_size; - u8 *vbt_virtual; - u8 bpi; - u8 number_desc = 0; - struct mrst_timing_info *dp_ti = &dev_priv->gct_data.DTD; - struct gct_r10_timing_info ti; - void *pGCT; - struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); - - /*get the address of the platform config vbt, B0:D2:F0;0xFC */ - pci_read_config_dword(pci_gfx_root, 0xFC, &platform_config_address); - pci_dev_put(pci_gfx_root); - DRM_INFO("drm platform config address is %x\n", - platform_config_address); - - /* check for platform config address == 0. */ - /* this means fw doesn't support vbt */ - - if (platform_config_address == 0) { - vbt->size = 0; - return; - } - - /* get the virtual address of the vbt */ - vbt_virtual = ioremap(platform_config_address, sizeof(*vbt)); - - memcpy(vbt, vbt_virtual, sizeof(*vbt)); - iounmap(vbt_virtual); /* Free virtual address space */ - - printk(KERN_ALERT "GCT revision is %x\n", vbt->revision); - - switch (vbt->revision) { - case 0: - vbt->mrst_gct = NULL; - vbt->mrst_gct = \ - ioremap(platform_config_address + sizeof(*vbt) - 4, - vbt->size - sizeof(*vbt) + 4); - pGCT = vbt->mrst_gct; - bpi = ((struct mrst_gct_v1 *)pGCT)->PD.BootPanelIndex; - dev_priv->gct_data.bpi = bpi; - dev_priv->gct_data.pt = - ((struct mrst_gct_v1 *)pGCT)->PD.PanelType; - memcpy(&dev_priv->gct_data.DTD, - &((struct mrst_gct_v1 *)pGCT)->panel[bpi].DTD, - sizeof(struct mrst_timing_info)); - dev_priv->gct_data.Panel_Port_Control = - ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control; - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; - break; - case 1: - vbt->mrst_gct = NULL; - vbt->mrst_gct = \ - ioremap(platform_config_address + sizeof(*vbt) - 4, - vbt->size - sizeof(*vbt) + 4); - pGCT = vbt->mrst_gct; - bpi = ((struct mrst_gct_v2 *)pGCT)->PD.BootPanelIndex; - dev_priv->gct_data.bpi = bpi; - dev_priv->gct_data.pt = - ((struct mrst_gct_v2 *)pGCT)->PD.PanelType; - memcpy(&dev_priv->gct_data.DTD, - &((struct mrst_gct_v2 *)pGCT)->panel[bpi].DTD, - sizeof(struct mrst_timing_info)); - dev_priv->gct_data.Panel_Port_Control = - ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control; - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; - break; - case 0x10: - /*header definition changed from rev 01 (v2) to rev 10h. */ - /*so, some values have changed location*/ - new_size = vbt->checksum; /*checksum contains lo size byte*/ - /*LSB of mrst_gct contains hi size byte*/ - new_size |= ((0xff & (unsigned int)vbt->mrst_gct)) << 8; - - vbt->checksum = vbt->size; /*size contains the checksum*/ - if (new_size > 0xff) - vbt->size = 0xff; /*restrict size to 255*/ - else - vbt->size = new_size; - - /* number of descriptors defined in the GCT */ - number_desc = ((0xff00 & (unsigned int)vbt->mrst_gct)) >> 8; - bpi = ((0xff0000 & (unsigned int)vbt->mrst_gct)) >> 16; - vbt->mrst_gct = NULL; - vbt->mrst_gct = \ - ioremap(platform_config_address + GCT_R10_HEADER_SIZE, - GCT_R10_DISPLAY_DESC_SIZE * number_desc); - pGCT = vbt->mrst_gct; - pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE); - dev_priv->gct_data.bpi = bpi; /*save boot panel id*/ - - /*copy the GCT display timings into a temp structure*/ - memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info)); - - /*now copy the temp struct into the dev_priv->gct_data*/ - dp_ti->pixel_clock = ti.pixel_clock; - dp_ti->hactive_hi = ti.hactive_hi; - dp_ti->hactive_lo = ti.hactive_lo; - dp_ti->hblank_hi = ti.hblank_hi; - dp_ti->hblank_lo = ti.hblank_lo; - dp_ti->hsync_offset_hi = ti.hsync_offset_hi; - dp_ti->hsync_offset_lo = ti.hsync_offset_lo; - dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi; - dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo; - dp_ti->vactive_hi = ti.vactive_hi; - dp_ti->vactive_lo = ti.vactive_lo; - dp_ti->vblank_hi = ti.vblank_hi; - dp_ti->vblank_lo = ti.vblank_lo; - dp_ti->vsync_offset_hi = ti.vsync_offset_hi; - dp_ti->vsync_offset_lo = ti.vsync_offset_lo; - dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi; - dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo; - - /*mov the MIPI_Display_Descriptor data from GCT to dev priv*/ - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - *((u8 *)pGCT + 0x0d); - dev_priv->gct_data.Panel_MIPI_Display_Descriptor |= - (*((u8 *)pGCT + 0x0e)) << 8; - break; - default: - printk(KERN_ERR "Unknown revision of GCT!\n"); - vbt->size = 0; - } -} - -static void psb_get_core_freq(struct drm_device *dev) -{ - uint32_t clock; - struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); - struct drm_psb_private *dev_priv = dev->dev_private; - - /*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/ - /*pci_write_config_dword(pci_root, 0xD0, 0xE0033000);*/ - - pci_write_config_dword(pci_root, 0xD0, 0xD0050300); - pci_read_config_dword(pci_root, 0xD4, &clock); - pci_dev_put(pci_root); - - switch (clock & 0x07) { - case 0: - dev_priv->core_freq = 100; - break; - case 1: - dev_priv->core_freq = 133; - break; - case 2: - dev_priv->core_freq = 150; - break; - case 3: - dev_priv->core_freq = 178; - break; - case 4: - dev_priv->core_freq = 200; - break; - case 5: - case 6: - case 7: - dev_priv->core_freq = 266; - default: - dev_priv->core_freq = 0; - } -} - static int psb_do_init(struct drm_device *dev) { - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; - struct psb_gtt *pg = dev_priv->pg; + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_gtt *pg = &dev_priv->gtt; uint32_t stolen_gtt; - uint32_t tt_start; - uint32_t tt_pages; int ret = -ENOMEM; if (pg->mmu_gatt_start & 0x0FFFFFFF) { - DRM_ERROR("Gatt must be 256M aligned. This is a bug.\n"); + dev_err(dev->dev, "Gatt must be 256M aligned. This is a bug.\n"); ret = -EINVAL; goto out_err; } @@ -448,24 +229,17 @@ static int psb_do_init(struct drm_device *dev) spin_lock_init(&dev_priv->irqmask_lock); - - tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? - pg->gatt_pages : PSB_TT_PRIV0_PLIMIT; - tt_start = dev_priv->gatt_free_offset - pg->mmu_gatt_start; - tt_pages -= tt_start >> PAGE_SHIFT; - /* FIXME: can we kill ta_mem_size ? */ - dev_priv->sizes.ta_mem_size = 0; + mutex_init(&dev_priv->mutex_2d); PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0); PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1); PSB_RSGX32(PSB_CR_BIF_BANK1); - PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK, + PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK, PSB_CR_BIF_CTRL); psb_spank(dev_priv); /* mmu_gatt ?? */ - PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); - + PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE); return 0; out_err: psb_do_takedown(dev); @@ -474,19 +248,21 @@ static int psb_do_init(struct drm_device *dev) static int psb_driver_unload(struct drm_device *dev) { - struct drm_psb_private *dev_priv = - (struct drm_psb_private *) dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; /* Kill vblank etc here */ - psb_backlight_exit(); /*writes minimum value to backlight HW reg */ + gma_backlight_exit(dev); if (drm_psb_no_fb == 0) psb_modeset_cleanup(dev); if (dev_priv) { psb_lid_timer_takedown(dev_priv); + gma_intel_opregion_exit(dev); + if (dev_priv->ops->chip_teardown) + dev_priv->ops->chip_teardown(dev); psb_do_takedown(dev); @@ -495,7 +271,7 @@ static int psb_driver_unload(struct drm_device *dev) dev_priv->pf_pd = NULL; } if (dev_priv->mmu) { - struct psb_gtt *pg = dev_priv->pg; + struct psb_gtt *pg = &dev_priv->gtt; down_read(&pg->sem); psb_mmu_remove_pfn_sequence( @@ -549,17 +325,12 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) if (dev_priv == NULL) return -ENOMEM; - if (IS_MRST(dev)) - dev_priv->num_pipe = 1; - else - dev_priv->num_pipe = 2; - + dev_priv->ops = (struct psb_ops *)chipset; dev_priv->dev = dev; - dev->dev_private = (void *) dev_priv; - dev_priv->chipset = chipset; - PSB_DEBUG_INIT("Mapping MMIO\n"); + dev_priv->num_pipe = dev_priv->ops->pipes; + resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE); dev_priv->vdc_reg = @@ -567,25 +338,14 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) if (!dev_priv->vdc_reg) goto out_err; - if (IS_MRST(dev)) - dev_priv->sgx_reg = ioremap(resource_start + MRST_SGX_OFFSET, + dev_priv->sgx_reg = ioremap(resource_start + dev_priv->ops->sgx_offset, PSB_SGX_SIZE); - else - dev_priv->sgx_reg = ioremap(resource_start + PSB_SGX_OFFSET, - PSB_SGX_SIZE); - if (!dev_priv->sgx_reg) goto out_err; - if (IS_MRST(dev)) { - mrst_get_fuse_settings(dev); - mrst_get_vbt_data(dev_priv); - mid_get_pci_revID(dev_priv); - } else { - psb_get_core_freq(dev); - psb_intel_opregion_init(dev); - psb_intel_init_bios(dev); - } + ret = dev_priv->ops->chip_setup(dev); + if (ret) + goto out_err; /* Init OSPM support */ gma_power_init(dev); @@ -608,7 +368,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) if (!dev_priv->mmu) goto out_err; - pg = dev_priv->pg; + pg = &dev_priv->gtt; tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ? (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT; @@ -659,6 +419,10 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) dev->driver->get_vblank_counter = psb_get_vblank_counter; +#if defined(CONFIG_DRM_PSB_MFLD) + /* FIXME: this is not the right place for this stuff ! */ + mdfld_output_setup(dev); +#endif if (drm_psb_no_fb == 0) { psb_modeset_init(dev); psb_fbdev_init(dev); @@ -672,7 +436,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) switch (psb_intel_output->type) { case INTEL_OUTPUT_LVDS: - ret = psb_backlight_init(dev); + case INTEL_OUTPUT_MIPI: + ret = gma_backlight_init(dev); break; } } @@ -685,7 +450,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) pm_runtime_set_active(&dev->pdev->dev); #endif /*Intel drm driver load is done, continue doing pvr load*/ - DRM_DEBUG("Pvr driver load\n"); return 0; out_err: psb_driver_unload(dev); @@ -720,6 +484,11 @@ static int psb_dc_state_ioctl(struct drm_device *dev, void * data, struct drm_psb_dc_state_arg *arg = (struct drm_psb_dc_state_arg *)data; + + /* Double check MRST case */ + if (IS_MRST(dev) || IS_MFLD(dev)) + return -EOPNOTSUPP; + flags = arg->flags; obj_id = arg->obj_id; @@ -727,7 +496,7 @@ static int psb_dc_state_ioctl(struct drm_device *dev, void * data, obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CRTC); if (!obj) { - DRM_DEBUG("Invalid CRTC object.\n"); + dev_dbg(dev->dev, "Invalid CRTC object.\n"); return -EINVAL; } @@ -747,7 +516,7 @@ static int psb_dc_state_ioctl(struct drm_device *dev, void * data, obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR); if (!obj) { - DRM_DEBUG("Invalid connector id.\n"); + dev_dbg(dev->dev, "Invalid connector id.\n"); return -EINVAL; } @@ -759,23 +528,27 @@ static int psb_dc_state_ioctl(struct drm_device *dev, void * data, return 0; } - - DRM_DEBUG("Bad flags 0x%x\n", flags); return -EINVAL; } +static inline void get_brightness(struct backlight_device *bd) +{ +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + if (bd) { + bd->props.brightness = bd->ops->get_brightness(bd); + backlight_update_status(bd); + } +#endif +} + static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_psb_private *dev_priv = psb_priv(dev); uint32_t *arg = data; - struct backlight_device bd; - dev_priv->blc_adj2 = *arg; -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - bd.props.brightness = psb_get_brightness(&bd); - psb_set_brightness(&bd); -#endif + dev_priv->blc_adj2 = *arg; + get_brightness(dev_priv->backlight_device); return 0; } @@ -784,13 +557,9 @@ static int psb_adb_ioctl(struct drm_device *dev, void *data, { struct drm_psb_private *dev_priv = psb_priv(dev); uint32_t *arg = data; - struct backlight_device bd; - dev_priv->blc_adj1 = *arg; -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - bd.props.brightness = psb_get_brightness(&bd); - psb_set_brightness(&bd); -#endif + dev_priv->blc_adj1 = *arg; + get_brightness(dev_priv->backlight_device); return 0; } @@ -838,7 +607,7 @@ static int psb_gamma_ioctl(struct drm_device *dev, void *data, obj_id = lut_arg->output_id; obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR); if (!obj) { - DRM_DEBUG("Invalid Connector object.\n"); + dev_dbg(dev->dev, "Invalid Connector object.\n"); return -EINVAL; } @@ -879,7 +648,7 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, case PSB_MODE_OPERATION_SET_DC_BASE: obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_FB); if (!obj) { - DRM_ERROR("Invalid FB id %d\n", obj_id); + dev_dbg(dev->dev, "Invalid FB id %d\n", obj_id); return -EINVAL; } @@ -951,7 +720,7 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, return ret; default: - DRM_DEBUG("Unsupported psb mode operation"); + dev_dbg(dev->dev, "Unsupported psb mode operation\n"); return -EOPNOTSUPP; } @@ -970,6 +739,7 @@ static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data, return 0; } +/* FIXME: needs Medfield changes */ static int psb_register_rw_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -1342,9 +1112,6 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, struct drm_device *dev = file_priv->minor->dev; struct drm_psb_private *dev_priv = dev->dev_private; static unsigned int runtime_allowed; - unsigned int nr = DRM_IOCTL_NR(cmd); - - DRM_DEBUG("cmd = %x, nr = %x\n", cmd, nr); if (runtime_allowed == 1 && dev_priv->is_lvds_on) { runtime_allowed++; @@ -1352,7 +1119,6 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, dev_priv->rpm_enabled = 1; } return drm_ioctl(filp, cmd, arg); - /* FIXME: do we need to wrap the other side of this */ } @@ -1371,6 +1137,8 @@ static void psb_remove(struct pci_dev *pdev) } static const struct dev_pm_ops psb_pm_ops = { + .resume = gma_power_resume, + .suspend = gma_power_suspend, .runtime_suspend = psb_runtime_suspend, .runtime_resume = psb_runtime_resume, .runtime_idle = psb_runtime_idle, @@ -1384,7 +1152,7 @@ static struct vm_operations_struct psb_gem_vm_ops = { static struct drm_driver driver = { .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \ - DRIVER_IRQ_VBL | DRIVER_MODESET| DRIVER_GEM , + DRIVER_IRQ_VBL | DRIVER_MODESET | DRIVER_GEM , .load = psb_driver_load, .unload = psb_driver_unload, @@ -1432,20 +1200,16 @@ static struct drm_driver driver = { static struct pci_driver psb_pci_driver = { .name = DRIVER_NAME, .id_table = pciidlist, - .resume = gma_power_resume, - .suspend = gma_power_suspend, .probe = psb_probe, .remove = psb_remove, -#ifdef CONFIG_PM .driver.pm = &psb_pm_ops, -#endif }; static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { /* MLD Added this from Inaky's patch */ if (pci_enable_msi(pdev)) - DRM_ERROR("Enable MSI failed!\n"); + dev_warn(&pdev->dev, "Enable MSI failed!\n"); return drm_get_pci_dev(pdev, ent, &driver); } @@ -1462,6 +1226,6 @@ static void __exit psb_exit(void) late_initcall(psb_init); module_exit(psb_exit); -MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_AUTHOR("Alan Cox and others"); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index e19a45478757..72f487a2a1b7 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -1,5 +1,5 @@ /************************************************************************** - * Copyright (c) 2007-2008, Intel Corporation. + * Copyright (c) 2007-2011, Intel Corporation. * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it @@ -20,52 +20,48 @@ #ifndef _PSB_DRV_H_ #define _PSB_DRV_H_ -#include #include #include #include "drm_global.h" +#include "gem_glue.h" #include "psb_drm.h" #include "psb_reg.h" #include "psb_intel_drv.h" -#include "psb_gtt.h" -#include "psb_powermgmt.h" +#include "gtt.h" +#include "power.h" #include "mrst.h" +#include "medfield.h" -/*Append new drm mode definition here, align with libdrm definition*/ -#define DRM_MODE_SCALE_NO_SCALE 2 +/* Append new drm mode definition here, align with libdrm definition */ +#define DRM_MODE_SCALE_NO_SCALE 2 +#define DRM_MODE_CONNECTOR_MIPI 15 enum { - CHIP_PSB_8108 = 0, - CHIP_PSB_8109 = 1, - CHIP_MRST_4100 = 2, + CHIP_PSB_8108 = 0, /* Poulsbo */ + CHIP_PSB_8109 = 1, /* Poulsbo */ + CHIP_MRST_4100 = 2, /* Moorestown/Oaktrail */ + CHIP_MFLD_0130 = 3, /* Medfield */ }; #define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100) +#define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130) /* - *Hardware bugfixes + * Driver definitions */ -#define DRIVER_NAME "pvrsrvkm" -#define DRIVER_DESC "drm driver for the Intel GMA500" -#define DRIVER_AUTHOR "Intel Corporation" +#define DRIVER_NAME "gma500" +#define DRIVER_DESC "DRM driver for the Intel GMA500" -#define PSB_DRM_DRIVER_DATE "2009-03-10" -#define PSB_DRM_DRIVER_MAJOR 8 -#define PSB_DRM_DRIVER_MINOR 1 +#define PSB_DRM_DRIVER_DATE "2011-06-06" +#define PSB_DRM_DRIVER_MAJOR 1 +#define PSB_DRM_DRIVER_MINOR 0 #define PSB_DRM_DRIVER_PATCHLEVEL 0 /* - *TTM driver private offsets. + * Hardware offsets */ - -#define DRM_PSB_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) - -#define PSB_OBJECT_HASH_ORDER 13 -#define PSB_FILE_OBJECT_HASH_ORDER 12 -#define PSB_BO_HASH_ORDER 12 - #define PSB_VDC_OFFSET 0x00000000 #define PSB_VDC_SIZE 0x000080000 #define MRST_MMIO_SIZE 0x0000C0000 @@ -73,42 +69,52 @@ enum { #define PSB_SGX_SIZE 0x8000 #define PSB_SGX_OFFSET 0x00040000 #define MRST_SGX_OFFSET 0x00080000 +/* + * PCI resource identifiers + */ #define PSB_MMIO_RESOURCE 0 #define PSB_GATT_RESOURCE 2 #define PSB_GTT_RESOURCE 3 +/* + * PCI configuration + */ #define PSB_GMCH_CTRL 0x52 #define PSB_BSM 0x5C #define _PSB_GMCH_ENABLED 0x4 #define PSB_PGETBL_CTL 0x2020 #define _PSB_PGETBL_ENABLED 0x00000001 #define PSB_SGX_2D_SLAVE_PORT 0x4000 + +/* To get rid of */ #define PSB_TT_PRIV0_LIMIT (256*1024*1024) #define PSB_TT_PRIV0_PLIMIT (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT) -#define PSB_NUM_VALIDATE_BUFFERS 2048 /* - *Flags for external memory type field. + * SGX side MMU definitions (these can probably go) */ +/* + * Flags for external memory type field. + */ #define PSB_MMU_CACHED_MEMORY 0x0001 /* Bind to MMU only */ #define PSB_MMU_RO_MEMORY 0x0002 /* MMU RO memory */ #define PSB_MMU_WO_MEMORY 0x0004 /* MMU WO memory */ - /* - *PTE's and PDE's + * PTE's and PDE's */ - #define PSB_PDE_MASK 0x003FFFFF #define PSB_PDE_SHIFT 22 #define PSB_PTE_SHIFT 12 - +/* + * Cache control + */ #define PSB_PTE_VALID 0x0001 /* PTE / PDE valid */ #define PSB_PTE_WO 0x0002 /* Write only */ #define PSB_PTE_RO 0x0004 /* Read only */ #define PSB_PTE_CACHED 0x0008 /* CPU cache coherent */ /* - *VDC registers and bits + * VDC registers and bits */ #define PSB_MSVDX_CLOCKGATING 0x2064 #define PSB_TOPAZ_CLOCKGATING 0x2068 @@ -130,8 +136,12 @@ enum { #define _LNC_IRQ_TOPAZ_FLAG (1<<20) /* This flag includes all the display IRQ bits excepts the vblank irqs. */ -#define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | _MDFLD_PIPEB_EVENT_FLAG | \ - _PSB_PIPEA_EVENT_FLAG | _PSB_VSYNC_PIPEA_FLAG | _MDFLD_MIPIA_FLAG | _MDFLD_MIPIC_FLAG) +#define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \ + _MDFLD_PIPEB_EVENT_FLAG | \ + _PSB_PIPEA_EVENT_FLAG | \ + _PSB_VSYNC_PIPEA_FLAG | \ + _MDFLD_MIPIA_FLAG | \ + _MDFLD_MIPIC_FLAG) #define PSB_INT_IDENTITY_R 0x20A4 #define PSB_INT_MASK_R 0x20A8 #define PSB_INT_ENABLE_R 0x20A0 @@ -197,10 +207,25 @@ enum { #define PSB_WATCHDOG_DELAY (DRM_HZ * 2) #define PSB_LID_DELAY (DRM_HZ / 10) -#define MDFLD_PNW_A0 0x00 #define MDFLD_PNW_B0 0x04 #define MDFLD_PNW_C0 0x08 +#define MDFLD_DSR_2D_3D_0 (1 << 0) +#define MDFLD_DSR_2D_3D_2 (1 << 1) +#define MDFLD_DSR_CURSOR_0 (1 << 2) +#define MDFLD_DSR_CURSOR_2 (1 << 3) +#define MDFLD_DSR_OVERLAY_0 (1 << 4) +#define MDFLD_DSR_OVERLAY_2 (1 << 5) +#define MDFLD_DSR_MIPI_CONTROL (1 << 6) +#define MDFLD_DSR_DAMAGE_MASK_0 ((1 << 0) | (1 << 2) | (1 << 4)) +#define MDFLD_DSR_DAMAGE_MASK_2 ((1 << 1) | (1 << 3) | (1 << 5)) +#define MDFLD_DSR_2D_3D (MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2) + +#define MDFLD_DSR_RR 45 +#define MDFLD_DPU_ENABLE (1 << 31) +#define MDFLD_DSR_FULLSCREEN (1 << 30) +#define MDFLD_DSR_DELAY (DRM_HZ / MDFLD_DSR_RR) + #define PSB_PWR_STATE_ON 1 #define PSB_PWR_STATE_OFF 2 @@ -214,6 +239,12 @@ enum { #define PSB_PCIx_MSI_ADDR_LOC 0x94 #define PSB_PCIx_MSI_DATA_LOC 0x98 +/* Medfield crystal settings */ +#define KSEL_CRYSTAL_19 1 +#define KSEL_BYPASS_19 5 +#define KSEL_BYPASS_25 6 +#define KSEL_BYPASS_83_100 7 + struct opregion_header; struct opregion_acpi; struct opregion_swsci; @@ -227,13 +258,13 @@ struct psb_intel_opregion { int enabled; }; +struct psb_ops; struct drm_psb_private { struct drm_device *dev; + const struct psb_ops *ops; - unsigned long chipset; - - struct psb_gtt *pg; + struct psb_gtt gtt; /* GTT Memory manager */ struct psb_gtt_mm *gtt_mm; @@ -271,14 +302,14 @@ struct drm_psb_private { /* * Power - */ + */ bool suspended; bool display_power; int display_count; /* - *Modesetting + * Modesetting */ struct psb_intel_mode_device mode_dev; @@ -287,12 +318,8 @@ struct drm_psb_private { uint32_t num_pipe; /* - *Memory managers + * OSPM info (Power management base) (can go ?) */ - - /* - *OSPM info - */ uint32_t ospm_base; /* @@ -304,11 +331,11 @@ struct drm_psb_private { u32 fuse_reg_value; u32 video_device_fuse; - /* pci revision id for B0:D2:F0 */ + /* PCI revision ID for B0:D2:F0 */ uint8_t platform_rev_id; /* - *LVDS info + * LVDS info */ int backlight_duty_cycle; /* restore backlight to this value */ bool panel_wants_dither; @@ -316,10 +343,10 @@ struct drm_psb_private { struct drm_display_mode *lfp_lvds_vbt_mode; struct drm_display_mode *sdvo_lvds_vbt_mode; - struct bdb_lvds_backlight *lvds_bl; /*LVDS backlight info from VBT*/ + struct bdb_lvds_backlight *lvds_bl; /* LVDS backlight info from VBT */ struct psb_intel_i2c_chan *lvds_i2c_bus; - /* Feature bits from the VBIOS*/ + /* Feature bits from the VBIOS */ unsigned int int_tv_support:1; unsigned int lvds_dither:1; unsigned int lvds_vbt:1; @@ -328,17 +355,30 @@ struct drm_psb_private { int lvds_ssc_freq; bool is_lvds_on; bool is_mipi_on; + u32 mipi_ctrl_display; unsigned int core_freq; uint32_t iLVDS_enable; - /*runtime PM state*/ + /* Runtime PM state */ int rpm_enabled; - /* Moorestown specific */ + /* MID specific */ struct mrst_vbt vbt_data; struct mrst_gct_data gct_data; + /* MIPI Panel type etc */ + int panel_id; + bool dual_mipi; /* dual display - DPI & DBI */ + bool dpi_panel_on; /* The DPI panel power is on */ + bool dpi_panel_on2; /* The DPI panel power is on */ + bool dbi_panel_on; /* The DBI panel power is on */ + bool dbi_panel_on2; /* The DBI panel power is on */ + u32 dsr_fb_update; /* DSR FB update counter */ + + /* Moorestown HDMI state */ + struct mrst_hdmi_dev *hdmi_priv; + /* Moorestown pipe config register value cache */ uint32_t pipeconf; uint32_t pipeconf1; @@ -349,8 +389,13 @@ struct drm_psb_private { uint32_t dspcntr1; uint32_t dspcntr2; + /* Moorestown MM backlight cache */ + uint8_t saveBKLTCNT; + uint8_t saveBKLTREQ; + uint8_t saveBKLTBRTL; + /* - *Register state + * Register state */ uint32_t saveDSPACNTR; uint32_t saveDSPBCNTR; @@ -373,6 +418,7 @@ struct drm_psb_private { uint32_t saveDSPAPOS; uint32_t saveDSPABASE; uint32_t saveDSPASURF; + uint32_t saveDSPASTATUS; uint32_t saveFPB0; uint32_t saveFPB1; uint32_t saveDPLL_B; @@ -388,6 +434,7 @@ struct drm_psb_private { uint32_t saveDSPBPOS; uint32_t saveDSPBBASE; uint32_t saveDSPBSURF; + uint32_t saveDSPBSTATUS; uint32_t saveVCLK_DIVISOR_VGA0; uint32_t saveVCLK_DIVISOR_VGA1; uint32_t saveVCLK_POST_DIV; @@ -458,6 +505,77 @@ struct drm_psb_private { uint32_t msi_addr; uint32_t msi_data; + /* Medfield specific register save state */ + uint32_t saveHDMIPHYMISCCTL; + uint32_t saveHDMIB_CONTROL; + uint32_t saveDSPCCNTR; + uint32_t savePIPECCONF; + uint32_t savePIPECSRC; + uint32_t saveHTOTAL_C; + uint32_t saveHBLANK_C; + uint32_t saveHSYNC_C; + uint32_t saveVTOTAL_C; + uint32_t saveVBLANK_C; + uint32_t saveVSYNC_C; + uint32_t saveDSPCSTRIDE; + uint32_t saveDSPCSIZE; + uint32_t saveDSPCPOS; + uint32_t saveDSPCSURF; + uint32_t saveDSPCSTATUS; + uint32_t saveDSPCLINOFF; + uint32_t saveDSPCTILEOFF; + uint32_t saveDSPCCURSOR_CTRL; + uint32_t saveDSPCCURSOR_BASE; + uint32_t saveDSPCCURSOR_POS; + uint32_t save_palette_c[256]; + uint32_t saveOV_OVADD_C; + uint32_t saveOV_OGAMC0_C; + uint32_t saveOV_OGAMC1_C; + uint32_t saveOV_OGAMC2_C; + uint32_t saveOV_OGAMC3_C; + uint32_t saveOV_OGAMC4_C; + uint32_t saveOV_OGAMC5_C; + + /* DSI register save */ + uint32_t saveDEVICE_READY_REG; + uint32_t saveINTR_EN_REG; + uint32_t saveDSI_FUNC_PRG_REG; + uint32_t saveHS_TX_TIMEOUT_REG; + uint32_t saveLP_RX_TIMEOUT_REG; + uint32_t saveTURN_AROUND_TIMEOUT_REG; + uint32_t saveDEVICE_RESET_REG; + uint32_t saveDPI_RESOLUTION_REG; + uint32_t saveHORIZ_SYNC_PAD_COUNT_REG; + uint32_t saveHORIZ_BACK_PORCH_COUNT_REG; + uint32_t saveHORIZ_FRONT_PORCH_COUNT_REG; + uint32_t saveHORIZ_ACTIVE_AREA_COUNT_REG; + uint32_t saveVERT_SYNC_PAD_COUNT_REG; + uint32_t saveVERT_BACK_PORCH_COUNT_REG; + uint32_t saveVERT_FRONT_PORCH_COUNT_REG; + uint32_t saveHIGH_LOW_SWITCH_COUNT_REG; + uint32_t saveINIT_COUNT_REG; + uint32_t saveMAX_RET_PAK_REG; + uint32_t saveVIDEO_FMT_REG; + uint32_t saveEOT_DISABLE_REG; + uint32_t saveLP_BYTECLK_REG; + uint32_t saveHS_LS_DBI_ENABLE_REG; + uint32_t saveTXCLKESC_REG; + uint32_t saveDPHY_PARAM_REG; + uint32_t saveMIPI_CONTROL_REG; + uint32_t saveMIPI; + uint32_t saveMIPI_C; + + /* DPST register save */ + uint32_t saveHISTOGRAM_INT_CONTROL_REG; + uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG; + uint32_t savePWM_CONTROL_LOGIC; + + /* + * DSI info. + */ + void * dbi_dsr_info; + void * dbi_dpu_info; + void * dsi_configs[2]; /* * LID-Switch */ @@ -468,7 +586,7 @@ struct drm_psb_private { u32 lid_last_state; /* - *Watchdog + * Watchdog */ uint32_t apm_reg; @@ -478,14 +596,71 @@ struct drm_psb_private { * Used for modifying backlight from * xrandr -- consider removing and using HAL instead */ + struct backlight_device *backlight_device; struct drm_property *backlight_property; uint32_t blc_adj1; uint32_t blc_adj2; - void * fbdev; + void *fbdev; + /* DPST state */ + uint32_t dsr_idle_count; + bool is_in_idle; + bool dsr_enable; + void (*exit_idle)(struct drm_device *dev, u32 update_src); + + /* 2D acceleration */ + struct mutex mutex_2d; + + /* FIXME: Arrays anyone ? */ + struct mdfld_dsi_encoder *encoder0; + struct mdfld_dsi_encoder *encoder2; + struct mdfld_dsi_dbi_output * dbi_output; + struct mdfld_dsi_dbi_output * dbi_output2; + u32 bpp; + u32 bpp2; + + bool dispstatus; }; +/* + * Operations for each board type + */ + +struct psb_ops { + const char *name; + unsigned int accel_2d:1; + int pipes; /* Number of output pipes */ + int crtcs; /* Number of CRTCs */ + int sgx_offset; /* Base offset of SGX device */ + + /* Sub functions */ + struct drm_crtc_helper_funcs const *crtc_helper; + struct drm_crtc_funcs const *crtc_funcs; + + /* Setup hooks */ + int (*chip_setup)(struct drm_device *dev); + void (*chip_teardown)(struct drm_device *dev); + + /* Display management hooks */ + int (*output_init)(struct drm_device *dev); + /* Power management hooks */ + void (*init_pm)(struct drm_device *dev); + int (*save_regs)(struct drm_device *dev); + int (*restore_regs)(struct drm_device *dev); + int (*power_up)(struct drm_device *dev); + int (*power_down)(struct drm_device *dev); + + void (*lvds_bl_power)(struct drm_device *dev, bool on); +#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE + /* Backlight */ + int (*backlight_init)(struct drm_device *dev); +#endif + int i2c_bus; /* I2C bus identifier for Moorestown */ +}; + + + struct psb_mmu_driver; extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int); @@ -497,7 +672,7 @@ static inline struct drm_psb_private *psb_priv(struct drm_device *dev) } /* - *MMU stuff. + * MMU stuff. */ extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers, @@ -525,7 +700,7 @@ extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual, unsigned long *pfn); /* - *Enable / disable MMU for different requestors. + * Enable / disable MMU for different requestors. */ @@ -552,7 +727,7 @@ extern void psb_irq_turn_on_dpst(struct drm_device *dev); extern void psb_irq_turn_off_dpst(struct drm_device *dev); extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands); -extern int psb_vblank_wait2(struct drm_device *dev,unsigned int *sequence); +extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence); extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence); extern int psb_enable_vblank(struct drm_device *dev, int crtc); extern void psb_disable_vblank(struct drm_device *dev, int crtc); @@ -564,41 +739,33 @@ psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc); -/* - * psb_opregion.c - */ -extern int psb_intel_opregion_init(struct drm_device *dev); +extern int mdfld_enable_te(struct drm_device *dev, int pipe); +extern void mdfld_disable_te(struct drm_device *dev, int pipe); /* - *psb_fb.c + * intel_opregion.c + */ +extern int gma_intel_opregion_init(struct drm_device *dev); +extern int gma_intel_opregion_exit(struct drm_device *dev); + +/* + * framebuffer.c */ extern int psbfb_probed(struct drm_device *dev); extern int psbfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); -extern int psbfb_kms_off_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int psbfb_kms_on_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern void *psbfb_vdc_reg(struct drm_device* dev); - /* - * psb_2d.c + * accel_2d.c */ -extern void psbfb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect); extern void psbfb_copyarea(struct fb_info *info, const struct fb_copyarea *region); -extern void psbfb_imageblit(struct fb_info *info, - const struct fb_image *image); extern int psbfb_sync(struct fb_info *info); - extern void psb_spank(struct drm_psb_private *dev_priv); - -extern int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, - unsigned size); +extern int psb_accel_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); /* - *psb_reset.c + * psb_reset.c */ extern void psb_lid_timer_init(struct drm_psb_private *dev_priv); @@ -608,14 +775,11 @@ extern void psb_print_pagefault(struct drm_psb_private *dev_priv); /* modesetting */ extern void psb_modeset_init(struct drm_device *dev); extern void psb_modeset_cleanup(struct drm_device *dev); -extern int psb_fbdev_init(struct drm_device * dev); +extern int psb_fbdev_init(struct drm_device *dev); -/* psb_bl.c */ -int psb_backlight_init(struct drm_device *dev); -void psb_backlight_exit(void); -int psb_set_brightness(struct backlight_device *bd); -int psb_get_brightness(struct backlight_device *bd); -struct backlight_device * psb_get_backlight_device(void); +/* backlight.c */ +int gma_backlight_init(struct drm_device *dev); +void gma_backlight_exit(struct drm_device *dev); /* mrst_crtc.c */ extern const struct drm_crtc_helper_funcs mrst_helper_funcs; @@ -624,26 +788,43 @@ extern const struct drm_crtc_helper_funcs mrst_helper_funcs; extern void mrst_lvds_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev); +/* psb_intel_display.c */ +extern const struct drm_crtc_helper_funcs psb_intel_helper_funcs; +extern const struct drm_crtc_funcs psb_intel_crtc_funcs; + /* psb_intel_lvds.c */ -extern void psb_intel_lvds_prepare(struct drm_encoder *encoder); -extern void psb_intel_lvds_commit(struct drm_encoder *encoder); extern const struct drm_connector_helper_funcs psb_intel_lvds_connector_helper_funcs; extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs; -/* psb_gem.c */ +/* gem.c */ extern int psb_gem_init_object(struct drm_gem_object *obj); extern void psb_gem_free_object(struct drm_gem_object *obj); extern int psb_gem_get_aperture(struct drm_device *dev, void *data, - struct drm_file *file); + struct drm_file *file); extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev, struct drm_mode_create_dumb *args); extern int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, uint32_t handle); extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, - uint32_t handle, uint64_t *offset); + uint32_t handle, uint64_t *offset); extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); +extern int psb_gem_create_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); +extern int psb_gem_mmap_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); +/* psb_device.c */ +extern const struct psb_ops psb_chip_ops; + +/* mrst_device.c */ +extern const struct psb_ops mrst_chip_ops; + +/* mdfld_device.c */ +extern const struct psb_ops mdfld_chip_ops; + +/* cdv_device.c */ +extern const struct psb_ops cdv_chip_ops; /* * Debug print bits setting @@ -661,110 +842,62 @@ extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); #define PSB_D_MSVDX (1 << 9) #define PSB_D_TOPAZ (1 << 10) -#ifndef DRM_DEBUG_CODE -/* To enable debug printout, set drm_psb_debug in psb_drv.c - * to any combination of above print flags. - */ -/* #define DRM_DEBUG_CODE 2 */ -#endif - -extern int drm_psb_debug; extern int drm_psb_no_fb; extern int drm_idle_check_interval; -#define PSB_DEBUG_GENERAL(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_GENERAL, _fmt, ##_arg) -#define PSB_DEBUG_INIT(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_INIT, _fmt, ##_arg) -#define PSB_DEBUG_IRQ(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_IRQ, _fmt, ##_arg) -#define PSB_DEBUG_ENTRY(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_ENTRY, _fmt, ##_arg) -#define PSB_DEBUG_HV(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_HV, _fmt, ##_arg) -#define PSB_DEBUG_DBI_BF(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_DBI_BF, _fmt, ##_arg) -#define PSB_DEBUG_PM(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_PM, _fmt, ##_arg) -#define PSB_DEBUG_RENDER(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_RENDER, _fmt, ##_arg) -#define PSB_DEBUG_REG(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_REG, _fmt, ##_arg) -#define PSB_DEBUG_MSVDX(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_MSVDX, _fmt, ##_arg) -#define PSB_DEBUG_TOPAZ(_fmt, _arg...) \ - PSB_DEBUG(PSB_D_TOPAZ, _fmt, ##_arg) - -#if DRM_DEBUG_CODE -#define PSB_DEBUG(_flag, _fmt, _arg...) \ - do { \ - if (unlikely((_flag) & drm_psb_debug)) \ - printk(KERN_DEBUG \ - "[psb:0x%02x:%s] " _fmt , _flag, \ - __func__ , ##_arg); \ - } while (0) -#else -#define PSB_DEBUG(_fmt, _arg...) do { } while (0) -#endif - /* - *Utilities + * Utilities */ -#define DRM_DRIVER_PRIVATE_T struct drm_psb_private static inline u32 MRST_MSG_READ32(uint port, uint offset) { int mcr = (0xD0<<24) | (port << 16) | (offset << 8); uint32_t ret_val = 0; - struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0); - pci_write_config_dword (pci_root, 0xD0, mcr); - pci_read_config_dword (pci_root, 0xD4, &ret_val); + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); + pci_write_config_dword(pci_root, 0xD0, mcr); + pci_read_config_dword(pci_root, 0xD4, &ret_val); pci_dev_put(pci_root); return ret_val; } static inline void MRST_MSG_WRITE32(uint port, uint offset, u32 value) { int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0; - struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0); - pci_write_config_dword (pci_root, 0xD4, value); - pci_write_config_dword (pci_root, 0xD0, mcr); + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); + pci_write_config_dword(pci_root, 0xD4, value); + pci_write_config_dword(pci_root, 0xD0, mcr); pci_dev_put(pci_root); } static inline u32 MDFLD_MSG_READ32(uint port, uint offset) { int mcr = (0x10<<24) | (port << 16) | (offset << 8); uint32_t ret_val = 0; - struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0); - pci_write_config_dword (pci_root, 0xD0, mcr); - pci_read_config_dword (pci_root, 0xD4, &ret_val); + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); + pci_write_config_dword(pci_root, 0xD0, mcr); + pci_read_config_dword(pci_root, 0xD4, &ret_val); pci_dev_put(pci_root); return ret_val; } static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value) { int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0; - struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0); - pci_write_config_dword (pci_root, 0xD4, value); - pci_write_config_dword (pci_root, 0xD0, mcr); + struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0); + pci_write_config_dword(pci_root, 0xD4, value); + pci_write_config_dword(pci_root, 0xD0, mcr); pci_dev_put(pci_root); } static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg) { struct drm_psb_private *dev_priv = dev->dev_private; - int reg_val = ioread32(dev_priv->vdc_reg + (reg)); - PSB_DEBUG_REG("reg = 0x%x. reg_val = 0x%x. \n", reg, reg_val); - return reg_val; + return ioread32(dev_priv->vdc_reg + reg); } #define REG_READ(reg) REGISTER_READ(dev, (reg)) + static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg, uint32_t val) { struct drm_psb_private *dev_priv = dev->dev_private; - if ((reg < 0x70084 || reg >0x70088) && (reg < 0xa000 || reg >0xa3ff)) - PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val); - iowrite32((val), dev_priv->vdc_reg + (reg)); } @@ -774,9 +907,6 @@ static inline void REGISTER_WRITE16(struct drm_device *dev, uint32_t reg, uint32_t val) { struct drm_psb_private *dev_priv = dev->dev_private; - - PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val); - iowrite16((val), dev_priv->vdc_reg + (reg)); } @@ -786,60 +916,34 @@ static inline void REGISTER_WRITE8(struct drm_device *dev, uint32_t reg, uint32_t val) { struct drm_psb_private *dev_priv = dev->dev_private; - - PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val); - iowrite8((val), dev_priv->vdc_reg + (reg)); } -#define REG_WRITE8(reg, val) REGISTER_WRITE8(dev, (reg), (val)) +#define REG_WRITE8(reg, val) REGISTER_WRITE8(dev, (reg), (val)) -#define PSB_ALIGN_TO(_val, _align) \ - (((_val) + ((_align) - 1)) & ~((_align) - 1)) -#define PSB_WVDC32(_val, _offs) \ - iowrite32(_val, dev_priv->vdc_reg + (_offs)) -#define PSB_RVDC32(_offs) \ - ioread32(dev_priv->vdc_reg + (_offs)) +#define PSB_WVDC32(_val, _offs) iowrite32(_val, dev_priv->vdc_reg + (_offs)) +#define PSB_RVDC32(_offs) ioread32(dev_priv->vdc_reg + (_offs)) /* #define TRAP_SGX_PM_FAULT 1 */ #ifdef TRAP_SGX_PM_FAULT -#define PSB_RSGX32(_offs) \ -({ \ - if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) { \ - printk(KERN_ERR "access sgx when it's off!! (READ) %s, %d\n", \ - __FILE__, __LINE__); \ - mdelay(1000); \ - } \ - ioread32(dev_priv->sgx_reg + (_offs)); \ +#define PSB_RSGX32(_offs) \ +({ \ + if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) { \ + printk(KERN_ERR \ + "access sgx when it's off!! (READ) %s, %d\n", \ + __FILE__, __LINE__); \ + melay(1000); \ + } \ + ioread32(dev_priv->sgx_reg + (_offs)); \ }) #else -#define PSB_RSGX32(_offs) \ - ioread32(dev_priv->sgx_reg + (_offs)) +#define PSB_RSGX32(_offs) ioread32(dev_priv->sgx_reg + (_offs)) #endif -#define PSB_WSGX32(_val, _offs) \ - iowrite32(_val, dev_priv->sgx_reg + (_offs)) +#define PSB_WSGX32(_val, _offs) iowrite32(_val, dev_priv->sgx_reg + (_offs)) #define MSVDX_REG_DUMP 0 -#if MSVDX_REG_DUMP -#define PSB_WMSVDX32(_val, _offs) \ - printk("MSVDX: write %08x to reg 0x%08x\n", (unsigned int)(_val), (unsigned int)(_offs));\ - iowrite32(_val, dev_priv->msvdx_reg + (_offs)) -#define PSB_RMSVDX32(_offs) \ - ioread32(dev_priv->msvdx_reg + (_offs)) - -#else - -#define PSB_WMSVDX32(_val, _offs) \ - iowrite32(_val, dev_priv->msvdx_reg + (_offs)) -#define PSB_RMSVDX32(_offs) \ - ioread32(dev_priv->msvdx_reg + (_offs)) - -#endif - -#define PSB_ALPL(_val, _base) \ - (((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT)) -#define PSB_ALPLM(_val, _base) \ - ((((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT)) & (_base ## _MASK)) +#define PSB_WMSVDX32(_val, _offs) iowrite32(_val, dev_priv->msvdx_reg + (_offs)) +#define PSB_RMSVDX32(_offs) ioread32(dev_priv->msvdx_reg + (_offs)) #endif diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c index 09e378d5ddcb..4afa671f9747 100644 --- a/drivers/staging/gma500/psb_intel_display.c +++ b/drivers/staging/gma500/psb_intel_display.c @@ -1,5 +1,5 @@ /* - * Copyright © 2006-2007 Intel Corporation + * Copyright © 2006-2011 Intel 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, @@ -22,13 +22,14 @@ #include #include -#include "psb_fb.h" +#include "framebuffer.h" #include "psb_drv.h" #include "psb_intel_drv.h" #include "psb_intel_reg.h" #include "psb_intel_display.h" -#include "psb_powermgmt.h" +#include "power.h" +#include "mdfld_output.h" struct psb_intel_clock_t { /* given values */ @@ -350,17 +351,15 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc, u32 dspcntr; int ret = 0; - PSB_DEBUG_ENTRY("\n"); + if (!gma_power_begin(dev, true)) + return 0; /* no fb bound */ if (!crtc->fb) { - DRM_DEBUG("No FB bound\n"); - return 0; + dev_dbg(dev->dev, "No FB bound\n"); + goto psb_intel_pipe_cleaner; } - if (!gma_power_begin(dev, true)) - return 0; - /* We are displaying this buffer, make sure it is actually loaded into the GTT */ ret = psb_gtt_pin(psbfb->gtt); @@ -390,7 +389,7 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc, dspcntr |= DISPPLANE_32BPP_NO_ALPHA; break; default: - DRM_ERROR("Unknown color depth\n"); + dev_err(dev->dev, "Unknown color depth\n"); ret = -EINVAL; psb_gtt_unpin(psbfb->gtt); goto psb_intel_pipe_set_base_exit; @@ -398,7 +397,6 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc, REG_WRITE(dspcntr_reg, dspcntr); - DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y); if (0 /* FIXMEAC - check what PSB needs */) { REG_WRITE(dspbase, offset); REG_READ(dspbase); @@ -409,6 +407,7 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc, REG_READ(dspbase); } +psb_intel_pipe_cleaner: /* If there was a previous display we can now unpin it */ if (old_fb) psb_gtt_unpin(to_psb_fb(old_fb)->gtt); @@ -588,6 +587,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); + struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; int pipe = psb_intel_crtc->pipe; int fp_reg = (pipe == 0) ? FPA0 : FPB0; int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; @@ -610,6 +610,12 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, struct drm_mode_config *mode_config = &dev->mode_config; struct drm_connector *connector; + /* No scan out no play */ + if (crtc->fb == NULL) { + crtc_funcs->mode_set_base(crtc, x, y, old_fb); + return 0; + } + list_for_each_entry(connector, &mode_config->connector_list, head) { struct psb_intel_output *psb_intel_output = to_psb_intel_output(connector); @@ -642,7 +648,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, ok = psb_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock); if (!ok) { - DRM_ERROR("Couldn't find PLL settings for mode!\n"); + dev_err(dev->dev, "Couldn't find PLL settings for mode!\n"); return 0; } @@ -706,7 +712,6 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, if (psb_intel_panel_fitter_pipe(dev) == pipe) REG_WRITE(PFIT_CONTROL, 0); - DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); drm_mode_debug_printmodeline(mode); if (dpll & DPLL_VCO_ENABLE) { @@ -723,17 +728,18 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, if (is_lvds) { u32 lvds = REG_READ(LVDS); - lvds |= - LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | - LVDS_PIPEB_SELECT; + lvds &= ~LVDS_PIPEB_SELECT; + if (pipe == 1) + lvds |= LVDS_PIPEB_SELECT; + + lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; /* Set the B0-B3 data pairs corresponding to * whether we're going to * set the DPLLs for dual-channel mode or not. */ + lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); if (clock.p2 == 7) lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; - else - lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) * appropriately here, but we need to look more @@ -785,11 +791,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, REG_WRITE(dspcntr_reg, dspcntr); /* Flush the plane changes */ - { - struct drm_crtc_helper_funcs *crtc_funcs = - crtc->helper_private; - crtc_funcs->mode_set_base(crtc, x, y, old_fb); - } + crtc_funcs->mode_set_base(crtc, x, y, old_fb); psb_intel_wait_for_vblank(dev); @@ -820,7 +822,7 @@ void psb_intel_crtc_load_lut(struct drm_crtc *crtc) palreg = PALETTE_C; break; default: - DRM_ERROR("Illegal Pipe Number.\n"); + dev_err(dev->dev, "Illegal Pipe Number.\n"); return; } @@ -863,10 +865,8 @@ static void psb_intel_crtc_save(struct drm_crtc *crtc) uint32_t paletteReg; int i; - DRM_DEBUG("\n"); - if (!crtc_state) { - DRM_DEBUG("No CRTC state found\n"); + dev_err(dev->dev, "No CRTC state found\n"); return; } @@ -890,25 +890,6 @@ static void psb_intel_crtc_save(struct drm_crtc *crtc) crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE); - DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", - crtc_state->saveDSPCNTR, - crtc_state->savePIPECONF, - crtc_state->savePIPESRC, - crtc_state->saveFP0, - crtc_state->saveFP1, - crtc_state->saveDPLL, - crtc_state->saveHTOTAL, - crtc_state->saveHBLANK, - crtc_state->saveHSYNC, - crtc_state->saveVTOTAL, - crtc_state->saveVBLANK, - crtc_state->saveVSYNC, - crtc_state->saveDSPSTRIDE, - crtc_state->saveDSPSIZE, - crtc_state->saveDSPPOS, - crtc_state->saveDSPBASE - ); - paletteReg = pipeA ? PALETTE_A : PALETTE_B; for (i = 0; i < 256; ++i) crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2)); @@ -929,60 +910,15 @@ static void psb_intel_crtc_restore(struct drm_crtc *crtc) uint32_t paletteReg; int i; - DRM_DEBUG("\n"); - if (!crtc_state) { - DRM_DEBUG("No crtc state\n"); + dev_err(dev->dev, "No crtc state\n"); return; } - DRM_DEBUG( - "current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", - REG_READ(pipeA ? DSPACNTR : DSPBCNTR), - REG_READ(pipeA ? PIPEACONF : PIPEBCONF), - REG_READ(pipeA ? PIPEASRC : PIPEBSRC), - REG_READ(pipeA ? FPA0 : FPB0), - REG_READ(pipeA ? FPA1 : FPB1), - REG_READ(pipeA ? DPLL_A : DPLL_B), - REG_READ(pipeA ? HTOTAL_A : HTOTAL_B), - REG_READ(pipeA ? HBLANK_A : HBLANK_B), - REG_READ(pipeA ? HSYNC_A : HSYNC_B), - REG_READ(pipeA ? VTOTAL_A : VTOTAL_B), - REG_READ(pipeA ? VBLANK_A : VBLANK_B), - REG_READ(pipeA ? VSYNC_A : VSYNC_B), - REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE), - REG_READ(pipeA ? DSPASIZE : DSPBSIZE), - REG_READ(pipeA ? DSPAPOS : DSPBPOS), - REG_READ(pipeA ? DSPABASE : DSPBBASE) - ); - - DRM_DEBUG( - "saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", - crtc_state->saveDSPCNTR, - crtc_state->savePIPECONF, - crtc_state->savePIPESRC, - crtc_state->saveFP0, - crtc_state->saveFP1, - crtc_state->saveDPLL, - crtc_state->saveHTOTAL, - crtc_state->saveHBLANK, - crtc_state->saveHSYNC, - crtc_state->saveVTOTAL, - crtc_state->saveVBLANK, - crtc_state->saveVSYNC, - crtc_state->saveDSPSTRIDE, - crtc_state->saveDSPSIZE, - crtc_state->saveDSPPOS, - crtc_state->saveDSPBASE - ); - - if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) { REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL & ~DPLL_VCO_ENABLE); REG_READ(pipeA ? DPLL_A : DPLL_B); - DRM_DEBUG("write dpll: %x\n", - REG_READ(pipeA ? DPLL_A : DPLL_B)); udelay(150); } @@ -1039,11 +975,8 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, struct drm_gem_object *obj; int ret; - DRM_DEBUG("\n"); - /* if we want to turn of the cursor ignore width and height */ if (!handle) { - DRM_DEBUG("cursor off\n"); /* turn off the cursor */ temp = CURSOR_MODE_DISABLE; @@ -1067,7 +1000,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, /* Currently we only support 64x64 cursors */ if (width != 64 || height != 64) { - DRM_ERROR("we currently only support 64x64 cursors\n"); + dev_dbg(dev->dev, "we currently only support 64x64 cursors\n"); return -EINVAL; } @@ -1076,7 +1009,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, return -ENOENT; if (obj->size < width * height * 4) { - DRM_ERROR("buffer is to small\n"); + dev_dbg(dev->dev, "buffer is to small\n"); return -ENOMEM; } @@ -1085,7 +1018,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, /* Pin the memory into the GTT */ ret = psb_gtt_pin(gt); if (ret) { - DRM_ERROR("Can not pin down handle 0x%x\n", handle); + dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle); return ret; } @@ -1106,14 +1039,13 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc, } /* unpin the old bo */ - if (psb_intel_crtc->cursor_obj && psb_intel_crtc->cursor_obj != obj) { + if (psb_intel_crtc->cursor_obj) { gt = container_of(psb_intel_crtc->cursor_obj, struct gtt_range, gem); psb_gtt_unpin(gt); drm_gem_object_unreference(psb_intel_crtc->cursor_obj); psb_intel_crtc->cursor_obj = obj; } - return 0; } @@ -1148,7 +1080,7 @@ static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) return 0; } -static void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, +void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, uint32_t type, uint32_t size) { struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); @@ -1309,7 +1241,7 @@ struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev, return mode; } -static void psb_intel_crtc_destroy(struct drm_crtc *crtc) +void psb_intel_crtc_destroy(struct drm_crtc *crtc) { struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct gtt_range *gt; @@ -1327,7 +1259,7 @@ static void psb_intel_crtc_destroy(struct drm_crtc *crtc) kfree(psb_intel_crtc); } -static const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { +const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { .dpms = psb_intel_crtc_dpms, .mode_fixup = psb_intel_crtc_mode_fixup, .mode_set = psb_intel_crtc_mode_set, @@ -1346,6 +1278,19 @@ const struct drm_crtc_funcs psb_intel_crtc_funcs = { .destroy = psb_intel_crtc_destroy, }; +/* + * Set the default value of cursor control and base register + * to zero. This is a workaround for h/w defect on Oaktrail + */ +static void psb_intel_cursor_init(struct drm_device *dev, int pipe) +{ + u32 control[3] = { CURACNTR, CURBCNTR, CURCCNTR }; + u32 base[3] = { CURABASE, CURBBASE, CURCBASE }; + + REG_WRITE(control[pipe], 0); + REG_WRITE(base[pipe], 0); +} + void psb_intel_crtc_init(struct drm_device *dev, int pipe, struct psb_intel_mode_device *mode_dev) { @@ -1354,8 +1299,6 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, int i; uint16_t *r_base, *g_base, *b_base; - PSB_DEBUG_ENTRY("\n"); - /* We allocate a extra array of drm_connector pointers * for fbdev after the crtc */ psb_intel_crtc = @@ -1368,12 +1311,13 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, psb_intel_crtc->crtc_state = kzalloc(sizeof(struct psb_intel_crtc_state), GFP_KERNEL); if (!psb_intel_crtc->crtc_state) { - DRM_INFO("Crtc state error: No memory\n"); + dev_err(dev->dev, "Crtc state error: No memory\n"); kfree(psb_intel_crtc); return; } - drm_crtc_init(dev, &psb_intel_crtc->base, &psb_intel_crtc_funcs); + /* Set the CRTC operations from the chip specific data */ + drm_crtc_init(dev, &psb_intel_crtc->base, dev_priv->ops->crtc_funcs); drm_mode_crtc_set_gamma_size(&psb_intel_crtc->base, 256); psb_intel_crtc->pipe = pipe; @@ -1396,12 +1340,8 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, psb_intel_crtc->mode_dev = mode_dev; psb_intel_crtc->cursor_addr = 0; - if (IS_MRST(dev)) - drm_crtc_helper_add(&psb_intel_crtc->base, - &mrst_helper_funcs); - else - drm_crtc_helper_add(&psb_intel_crtc->base, - &psb_intel_helper_funcs); + drm_crtc_helper_add(&psb_intel_crtc->base, + dev_priv->ops->crtc_helper); /* Setup the array of drm_connector pointer array */ psb_intel_crtc->mode_set.crtc = &psb_intel_crtc->base; @@ -1414,6 +1354,7 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, psb_intel_crtc->mode_set.connectors = (struct drm_connector **) (psb_intel_crtc + 1); psb_intel_crtc->mode_set.num_connectors = 0; + psb_intel_cursor_init(dev, pipe); } int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, @@ -1425,7 +1366,7 @@ int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, struct psb_intel_crtc *crtc; if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); + dev_err(dev->dev, "called with no initialization\n"); return -EINVAL; } @@ -1433,7 +1374,7 @@ int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, DRM_MODE_OBJECT_CRTC); if (!drmmode_obj) { - DRM_ERROR("no such CRTC id\n"); + dev_err(dev->dev, "no such CRTC id\n"); return -EINVAL; } diff --git a/drivers/staging/gma500/psb_intel_display.h b/drivers/staging/gma500/psb_intel_display.h index 3724b971e91c..535b49a5e409 100644 --- a/drivers/staging/gma500/psb_intel_display.h +++ b/drivers/staging/gma500/psb_intel_display.h @@ -21,5 +21,8 @@ #define _INTEL_DISPLAY_H_ bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type); +void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, + u16 *green, u16 *blue, uint32_t type, uint32_t size); +void psb_intel_crtc_destroy(struct drm_crtc *crtc); #endif diff --git a/drivers/staging/gma500/psb_intel_drv.h b/drivers/staging/gma500/psb_intel_drv.h index 6006ddd993f2..36b554b5c335 100644 --- a/drivers/staging/gma500/psb_intel_drv.h +++ b/drivers/staging/gma500/psb_intel_drv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Intel Corporation. + * Copyright (c) 2009-2011, Intel 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, @@ -25,11 +25,6 @@ #include #include -/* - * MOORESTOWN defines - */ -#define DELAY_TIME1 2000 /* 1000 = 1ms */ - /* * Display related stuff */ @@ -61,16 +56,10 @@ #define INTEL_DVO_CHIP_TMDS 2 #define INTEL_DVO_CHIP_TVOUT 4 -enum mipi_panel_type { - NSC_800X480 = 1, - LGE_480X1024 = 2, - TPO_864X480 = 3 -}; - -/** +/* * Hold information useally put on the device driver privates here, * since it needs to be shared across multiple of devices drivers privates. -*/ + */ struct psb_intel_mode_device { /* @@ -79,7 +68,7 @@ struct psb_intel_mode_device { size_t(*bo_offset) (struct drm_device *dev, void *bo); /* - * Cursor + * Cursor (Can go ?) */ int cursor_needs_physical; @@ -116,7 +105,7 @@ struct psb_intel_output { void *dev_priv; struct psb_intel_mode_device *mode_dev; - + struct i2c_adapter *hdmi_i2c_adapter; /* for control functions */ }; struct psb_intel_crtc_state { @@ -235,4 +224,7 @@ extern int psb_intel_lvds_set_property(struct drm_connector *connector, extern void psb_intel_lvds_destroy(struct drm_connector *connector); extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs; +extern void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe); +extern void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe); + #endif /* __INTEL_DRV_H__ */ diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c index b0a225b9f562..c6436da60732 100644 --- a/drivers/staging/gma500/psb_intel_lvds.c +++ b/drivers/staging/gma500/psb_intel_lvds.c @@ -21,21 +21,16 @@ */ #include -/* #include */ -/* #include */ #include -#include "psb_intel_bios.h" +#include "intel_bios.h" #include "psb_drv.h" #include "psb_intel_drv.h" #include "psb_intel_reg.h" -#include "psb_powermgmt.h" +#include "power.h" #include -u32 CoreClock; -u32 PWMControlRegFreq; - -/** +/* * LVDS I2C backlight control macros */ #define BRIGHTNESS_MAX_LEVEL 100 @@ -53,7 +48,7 @@ u32 PWMControlRegFreq; #define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) struct psb_intel_lvds_priv { - /** + /* * Saved LVDO output states */ uint32_t savePP_ON; @@ -66,9 +61,8 @@ struct psb_intel_lvds_priv { uint32_t saveBLC_PWM_CTL; }; -/* MRST defines end */ -/** +/* * Returns the maximum level of the backlight duty cycle field. */ static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev) @@ -126,13 +120,13 @@ static int psb_lvds_i2c_set_brightness(struct drm_device *dev, out_buf[1] = (u8)blc_i2c_brightness; if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) { - DRM_DEBUG("I2C set brightness.(command, value) (%d, %d)\n", + dev_dbg(dev->dev, "I2C set brightness.(command, value) (%d, %d)\n", dev_priv->lvds_bl->brightnesscmd, blc_i2c_brightness); return 0; } - DRM_ERROR("I2C transfer error\n"); + dev_err(dev->dev, "I2C transfer error\n"); return -1; } @@ -163,7 +157,7 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) return 0; } -/** +/* * Set LVDS backlight level either by I2C or PWM */ void psb_intel_lvds_set_brightness(struct drm_device *dev, int level) @@ -172,10 +166,10 @@ void psb_intel_lvds_set_brightness(struct drm_device *dev, int level) struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private; - DRM_DEBUG("backlight level is %d\n", level); + dev_dbg(dev->dev, "backlight level is %d\n", level); if (!dev_priv->lvds_bl) { - DRM_ERROR("NO LVDS Backlight Info\n"); + dev_err(dev->dev, "NO LVDS Backlight Info\n"); return; } @@ -185,10 +179,10 @@ void psb_intel_lvds_set_brightness(struct drm_device *dev, int level) psb_lvds_pwm_set_brightness(dev, level); } -/** +/* * Sets the backlight level. * - * \param level backlight level, from 0 to psb_intel_lvds_get_max_backlight(). + * level: backlight level, from 0 to psb_intel_lvds_get_max_backlight(). */ static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level) { @@ -210,7 +204,7 @@ static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level) } } -/** +/* * Sets the power state for the panel. */ static void psb_intel_lvds_set_power(struct drm_device *dev, @@ -289,7 +283,7 @@ static void psb_intel_lvds_save(struct drm_connector *connector) dev_priv->backlight_duty_cycle = psb_intel_lvds_get_max_backlight(dev); - DRM_DEBUG("(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", + dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", lvds_priv->savePP_ON, lvds_priv->savePP_OFF, lvds_priv->saveLVDS, @@ -310,7 +304,7 @@ static void psb_intel_lvds_restore(struct drm_connector *connector) struct psb_intel_lvds_priv *lvds_priv = (struct psb_intel_lvds_priv *)psb_intel_output->dev_priv; - DRM_DEBUG("(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", + dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", lvds_priv->savePP_ON, lvds_priv->savePP_OFF, lvds_priv->saveLVDS, @@ -351,8 +345,6 @@ int psb_intel_lvds_mode_valid(struct drm_connector *connector, struct drm_display_mode *fixed_mode = psb_intel_output->mode_dev->panel_fixed_mode; - PSB_DEBUG_ENTRY("\n"); - if (psb_intel_output->type == INTEL_OUTPUT_MIPI2) fixed_mode = psb_intel_output->mode_dev->panel_fixed_mode2; @@ -387,12 +379,10 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, struct psb_intel_output *psb_intel_output = enc_to_psb_intel_output(encoder); - PSB_DEBUG_ENTRY("type = 0x%x, pipe = %d.\n", - psb_intel_output->type, psb_intel_crtc->pipe); - if (psb_intel_output->type == INTEL_OUTPUT_MIPI2) panel_fixed_mode = mode_dev->panel_fixed_mode2; + /* FIXME: review for Medfield */ /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */ if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) { printk(KERN_ERR "Can't support LVDS on pipe A\n"); @@ -442,14 +432,12 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, return true; } -void psb_intel_lvds_prepare(struct drm_encoder *encoder) +static void psb_intel_lvds_prepare(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct psb_intel_output *output = enc_to_psb_intel_output(encoder); struct psb_intel_mode_device *mode_dev = output->mode_dev; - PSB_DEBUG_ENTRY("\n"); - if (!gma_power_begin(dev, true)) return; @@ -462,14 +450,12 @@ void psb_intel_lvds_prepare(struct drm_encoder *encoder) gma_power_end(dev); } -void psb_intel_lvds_commit(struct drm_encoder *encoder) +static void psb_intel_lvds_commit(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct psb_intel_output *output = enc_to_psb_intel_output(encoder); struct psb_intel_mode_device *mode_dev = output->mode_dev; - PSB_DEBUG_ENTRY("\n"); - if (mode_dev->backlight_duty_cycle == 0) mode_dev->backlight_duty_cycle = psb_intel_lvds_get_max_backlight(dev); @@ -481,9 +467,8 @@ static void psb_intel_lvds_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct psb_intel_mode_device *mode_dev = - enc_to_psb_intel_output(encoder)->mode_dev; struct drm_device *dev = encoder->dev; + struct drm_psb_private *dev_priv = dev->dev_private; u32 pfit_control; /* @@ -505,13 +490,13 @@ static void psb_intel_lvds_mode_set(struct drm_encoder *encoder, else pfit_control = 0; - if (mode_dev->panel_wants_dither) + if (dev_priv->lvds_dither) pfit_control |= PANEL_8TO6_DITHER_ENABLE; REG_WRITE(PFIT_CONTROL, pfit_control); } -/** +/* * Detect the LVDS connection. * * This always returns CONNECTOR_STATUS_CONNECTED. @@ -524,7 +509,7 @@ static enum drm_connector_status psb_intel_lvds_detect(struct drm_connector return connector_status_connected; } -/** +/* * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. */ static int psb_intel_lvds_get_modes(struct drm_connector *connector) @@ -536,7 +521,8 @@ static int psb_intel_lvds_get_modes(struct drm_connector *connector) psb_intel_output->mode_dev; int ret = 0; - ret = psb_intel_ddc_get_modes(psb_intel_output); + if (!IS_MRST(dev)) + ret = psb_intel_ddc_get_modes(psb_intel_output); if (ret) return ret; @@ -583,18 +569,17 @@ int psb_intel_lvds_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t value) { - struct drm_encoder *pEncoder = connector->encoder; + struct drm_encoder *encoder = connector->encoder; - PSB_DEBUG_ENTRY("\n"); + if (!encoder) + return -1; - if (!strcmp(property->name, "scaling mode") && pEncoder) { - struct psb_intel_crtc *pPsbCrtc = - to_psb_intel_crtc(pEncoder->crtc); - uint64_t curValue; + if (!strcmp(property->name, "scaling mode")) { + struct psb_intel_crtc *crtc = + to_psb_intel_crtc(encoder->crtc); + uint64_t curval; - PSB_DEBUG_ENTRY("scaling mode\n"); - - if (!pPsbCrtc) + if (!crtc) goto set_prop_error; switch (value) { @@ -610,10 +595,10 @@ int psb_intel_lvds_set_property(struct drm_connector *connector, if (drm_connector_property_get_value(connector, property, - &curValue)) + &curval)) goto set_prop_error; - if (curValue == value) + if (curval == value) goto set_prop_done; if (drm_connector_property_set_value(connector, @@ -621,34 +606,34 @@ int psb_intel_lvds_set_property(struct drm_connector *connector, value)) goto set_prop_error; - if (pPsbCrtc->saved_mode.hdisplay != 0 && - pPsbCrtc->saved_mode.vdisplay != 0) { - if (!drm_crtc_helper_set_mode(pEncoder->crtc, - &pPsbCrtc->saved_mode, - pEncoder->crtc->x, - pEncoder->crtc->y, - pEncoder->crtc->fb)) + if (crtc->saved_mode.hdisplay != 0 && + crtc->saved_mode.vdisplay != 0) { + if (!drm_crtc_helper_set_mode(encoder->crtc, + &crtc->saved_mode, + encoder->crtc->x, + encoder->crtc->y, + encoder->crtc->fb)) goto set_prop_error; } - } else if (!strcmp(property->name, "backlight") && pEncoder) { - PSB_DEBUG_ENTRY("backlight\n"); - + } else if (!strcmp(property->name, "backlight")) { if (drm_connector_property_set_value(connector, property, value)) goto set_prop_error; else { #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - struct backlight_device bd; - bd.props.brightness = value; - psb_set_brightness(&bd); + struct drm_psb_private *devp = encoder->dev->dev_private; + struct backlight_device *bd = devp->backlight_device; + if (bd) { + bd->props.brightness = value; + backlight_update_status(bd); + } #endif } - } else if (!strcmp(property->name, "DPMS") && pEncoder) { - struct drm_encoder_helper_funcs *pEncHFuncs - = pEncoder->helper_private; - PSB_DEBUG_ENTRY("DPMS\n"); - pEncHFuncs->dpms(pEncoder, value); + } else if (!strcmp(property->name, "DPMS")) { + struct drm_encoder_helper_funcs *hfuncs + = encoder->helper_private; + hfuncs->dpms(encoder, value); } set_prop_done: @@ -722,7 +707,7 @@ void psb_intel_lvds_init(struct drm_device *dev, lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL); if (!lvds_priv) { kfree(psb_intel_output); - DRM_DEBUG("LVDS private allocation error\n"); + dev_err(dev->dev, "LVDS private allocation error\n"); return; } @@ -758,7 +743,7 @@ void psb_intel_lvds_init(struct drm_device *dev, dev_priv->backlight_property, BRIGHTNESS_MAX_LEVEL); - /** + /* * Set up I2C bus * FIXME: distroy i2c_bus when exit */ @@ -806,7 +791,7 @@ void psb_intel_lvds_init(struct drm_device *dev, } } - /* Failed to get EDID, what about VBT? do we need this?*/ + /* Failed to get EDID, what about VBT? do we need this? */ if (mode_dev->vbt_mode) mode_dev->panel_fixed_mode = drm_mode_duplicate(dev, mode_dev->vbt_mode); @@ -838,8 +823,7 @@ void psb_intel_lvds_init(struct drm_device *dev, /* If we still don't have a mode after all that, give up. */ if (!mode_dev->panel_fixed_mode) { - DRM_DEBUG - ("Found no modes on the lvds, ignoring the LVDS\n"); + dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n"); goto failed_find; } @@ -849,26 +833,6 @@ void psb_intel_lvds_init(struct drm_device *dev, */ out: drm_sysfs_connector_add(connector); - - PSB_DEBUG_ENTRY("hdisplay = %d\n", - mode_dev->panel_fixed_mode->hdisplay); - PSB_DEBUG_ENTRY(" vdisplay = %d\n", - mode_dev->panel_fixed_mode->vdisplay); - PSB_DEBUG_ENTRY(" hsync_start = %d\n", - mode_dev->panel_fixed_mode->hsync_start); - PSB_DEBUG_ENTRY(" hsync_end = %d\n", - mode_dev->panel_fixed_mode->hsync_end); - PSB_DEBUG_ENTRY(" htotal = %d\n", - mode_dev->panel_fixed_mode->htotal); - PSB_DEBUG_ENTRY(" vsync_start = %d\n", - mode_dev->panel_fixed_mode->vsync_start); - PSB_DEBUG_ENTRY(" vsync_end = %d\n", - mode_dev->panel_fixed_mode->vsync_end); - PSB_DEBUG_ENTRY(" vtotal = %d\n", - mode_dev->panel_fixed_mode->vtotal); - PSB_DEBUG_ENTRY(" clock = %d\n", - mode_dev->panel_fixed_mode->clock); - return; failed_find: diff --git a/drivers/staging/gma500/psb_intel_reg.h b/drivers/staging/gma500/psb_intel_reg.h index 1c283140bccc..1ac16aa791c9 100644 --- a/drivers/staging/gma500/psb_intel_reg.h +++ b/drivers/staging/gma500/psb_intel_reg.h @@ -28,8 +28,8 @@ * * The actual value is this field multiplied by two. */ -#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) -#define BLM_LEGACY_MODE (1 << 16) +#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BLM_LEGACY_MODE (1 << 16) /* * This is the number of cycles out of the backlight modulation cycle for which * the backlight is on. @@ -37,55 +37,55 @@ * This field must be no greater than the number of cycles in the complete * backlight modulation cycle. */ -#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) -#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) +#define BACKLIGHT_DUTY_CYCLE_SHIFT (0) +#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) #define I915_GCFGC 0xf0 -#define I915_LOW_FREQUENCY_ENABLE (1 << 7) -#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) -#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) -#define I915_DISPLAY_CLOCK_MASK (7 << 4) +#define I915_LOW_FREQUENCY_ENABLE (1 << 7) +#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4) +#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4) +#define I915_DISPLAY_CLOCK_MASK (7 << 4) #define I855_HPLLCC 0xc0 -#define I855_CLOCK_CONTROL_MASK (3 << 0) -#define I855_CLOCK_133_200 (0 << 0) -#define I855_CLOCK_100_200 (1 << 0) -#define I855_CLOCK_100_133 (2 << 0) -#define I855_CLOCK_166_250 (3 << 0) +#define I855_CLOCK_CONTROL_MASK (3 << 0) +#define I855_CLOCK_133_200 (0 << 0) +#define I855_CLOCK_100_200 (1 << 0) +#define I855_CLOCK_100_133 (2 << 0) +#define I855_CLOCK_166_250 (3 << 0) /* I830 CRTC registers */ -#define HTOTAL_A 0x60000 -#define HBLANK_A 0x60004 -#define HSYNC_A 0x60008 -#define VTOTAL_A 0x6000c -#define VBLANK_A 0x60010 -#define VSYNC_A 0x60014 -#define PIPEASRC 0x6001c -#define BCLRPAT_A 0x60020 -#define VSYNCSHIFT_A 0x60028 +#define HTOTAL_A 0x60000 +#define HBLANK_A 0x60004 +#define HSYNC_A 0x60008 +#define VTOTAL_A 0x6000c +#define VBLANK_A 0x60010 +#define VSYNC_A 0x60014 +#define PIPEASRC 0x6001c +#define BCLRPAT_A 0x60020 +#define VSYNCSHIFT_A 0x60028 -#define HTOTAL_B 0x61000 -#define HBLANK_B 0x61004 -#define HSYNC_B 0x61008 -#define VTOTAL_B 0x6100c -#define VBLANK_B 0x61010 -#define VSYNC_B 0x61014 -#define PIPEBSRC 0x6101c -#define BCLRPAT_B 0x61020 -#define VSYNCSHIFT_B 0x61028 +#define HTOTAL_B 0x61000 +#define HBLANK_B 0x61004 +#define HSYNC_B 0x61008 +#define VTOTAL_B 0x6100c +#define VBLANK_B 0x61010 +#define VSYNC_B 0x61014 +#define PIPEBSRC 0x6101c +#define BCLRPAT_B 0x61020 +#define VSYNCSHIFT_B 0x61028 -#define HTOTAL_C 0x62000 -#define HBLANK_C 0x62004 -#define HSYNC_C 0x62008 -#define VTOTAL_C 0x6200c -#define VBLANK_C 0x62010 -#define VSYNC_C 0x62014 -#define PIPECSRC 0x6201c -#define BCLRPAT_C 0x62020 -#define VSYNCSHIFT_C 0x62028 +#define HTOTAL_C 0x62000 +#define HBLANK_C 0x62004 +#define HSYNC_C 0x62008 +#define VTOTAL_C 0x6200c +#define VBLANK_C 0x62010 +#define VSYNC_C 0x62014 +#define PIPECSRC 0x6201c +#define BCLRPAT_C 0x62020 +#define VSYNCSHIFT_C 0x62028 -#define PP_STATUS 0x61200 -# define PP_ON (1 << 31) +#define PP_STATUS 0x61200 +# define PP_ON (1 << 31) /* * Indicates that all dependencies of the panel are on: * @@ -93,56 +93,57 @@ * - pipe enabled * - LVDS/DVOB/DVOC on */ -# define PP_READY (1 << 30) -# define PP_SEQUENCE_NONE (0 << 28) -# define PP_SEQUENCE_ON (1 << 28) -# define PP_SEQUENCE_OFF (2 << 28) -# define PP_SEQUENCE_MASK 0x30000000 -#define PP_CONTROL 0x61204 -# define POWER_TARGET_ON (1 << 0) +#define PP_READY (1 << 30) +#define PP_SEQUENCE_NONE (0 << 28) +#define PP_SEQUENCE_ON (1 << 28) +#define PP_SEQUENCE_OFF (2 << 28) +#define PP_SEQUENCE_MASK 0x30000000 +#define PP_CONTROL 0x61204 +#define POWER_TARGET_ON (1 << 0) -#define LVDSPP_ON 0x61208 -#define LVDSPP_OFF 0x6120c -#define PP_CYCLE 0x61210 +#define LVDSPP_ON 0x61208 +#define LVDSPP_OFF 0x6120c +#define PP_CYCLE 0x61210 -#define PFIT_CONTROL 0x61230 -# define PFIT_ENABLE (1 << 31) -# define PFIT_PIPE_MASK (3 << 29) -# define PFIT_PIPE_SHIFT 29 -# define PFIT_SCALING_MODE_PILLARBOX (1 << 27) -# define PFIT_SCALING_MODE_LETTERBOX (3 << 26) -# define VERT_INTERP_DISABLE (0 << 10) -# define VERT_INTERP_BILINEAR (1 << 10) -# define VERT_INTERP_MASK (3 << 10) -# define VERT_AUTO_SCALE (1 << 9) -# define HORIZ_INTERP_DISABLE (0 << 6) -# define HORIZ_INTERP_BILINEAR (1 << 6) -# define HORIZ_INTERP_MASK (3 << 6) -# define HORIZ_AUTO_SCALE (1 << 5) -# define PANEL_8TO6_DITHER_ENABLE (1 << 3) +#define PFIT_CONTROL 0x61230 +#define PFIT_ENABLE (1 << 31) +#define PFIT_PIPE_MASK (3 << 29) +#define PFIT_PIPE_SHIFT 29 +#define PFIT_SCALING_MODE_PILLARBOX (1 << 27) +#define PFIT_SCALING_MODE_LETTERBOX (3 << 26) +#define VERT_INTERP_DISABLE (0 << 10) +#define VERT_INTERP_BILINEAR (1 << 10) +#define VERT_INTERP_MASK (3 << 10) +#define VERT_AUTO_SCALE (1 << 9) +#define HORIZ_INTERP_DISABLE (0 << 6) +#define HORIZ_INTERP_BILINEAR (1 << 6) +#define HORIZ_INTERP_MASK (3 << 6) +#define HORIZ_AUTO_SCALE (1 << 5) +#define PANEL_8TO6_DITHER_ENABLE (1 << 3) -#define PFIT_PGM_RATIOS 0x61234 -# define PFIT_VERT_SCALE_MASK 0xfff00000 -# define PFIT_HORIZ_SCALE_MASK 0x0000fff0 +#define PFIT_PGM_RATIOS 0x61234 +#define PFIT_VERT_SCALE_MASK 0xfff00000 +#define PFIT_HORIZ_SCALE_MASK 0x0000fff0 #define PFIT_AUTO_RATIOS 0x61238 +#define DPLL_A 0x06014 +#define DPLL_B 0x06018 +#define DPLL_VCO_ENABLE (1 << 31) +#define DPLL_DVO_HIGH_SPEED (1 << 30) +#define DPLL_SYNCLOCK_ENABLE (1 << 29) +#define DPLL_VGA_MODE_DIS (1 << 28) +#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ +#define DPLLB_MODE_LVDS (2 << 26) /* i915 */ +#define DPLL_MODE_MASK (3 << 26) +#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ +#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ +#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ +#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ +#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ +#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ +#define DPLL_LOCK (1 << 15) /* CDV */ -#define DPLL_A 0x06014 -#define DPLL_B 0x06018 -# define DPLL_VCO_ENABLE (1 << 31) -# define DPLL_DVO_HIGH_SPEED (1 << 30) -# define DPLL_SYNCLOCK_ENABLE (1 << 29) -# define DPLL_VGA_MODE_DIS (1 << 28) -# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */ -# define DPLLB_MODE_LVDS (2 << 26) /* i915 */ -# define DPLL_MODE_MASK (3 << 26) -# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */ -# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */ -# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ -# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ -# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ -# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ /* * The i830 generation, in DAC/serial mode, defines p1 as two plus this * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set. @@ -152,35 +153,35 @@ * The i830 generation, in LVDS mode, defines P1 as the bit number set within * this field (only one bit may be set). */ -# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 -# define DPLL_FPA01_P1_POST_DIV_SHIFT 16 -# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required +#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000 +#define DPLL_FPA01_P1_POST_DIV_SHIFT 16 +#define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required * in DVO non-gang */ -# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ -# define PLL_REF_INPUT_DREFCLK (0 << 13) -# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ -# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO +# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */ +#define PLL_REF_INPUT_DREFCLK (0 << 13) +#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */ +#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO * TVCLKIN */ -# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) -# define PLL_REF_INPUT_MASK (3 << 13) -# define PLL_LOAD_PULSE_PHASE_SHIFT 9 +#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13) +#define PLL_REF_INPUT_MASK (3 << 13) +#define PLL_LOAD_PULSE_PHASE_SHIFT 9 /* * Parallel to Serial Load Pulse phase selection. * Selects the phase for the 10X DPLL clock for the PCIe * digital display port. The range is 4 to 13; 10 or more * is just a flip delay. The default is 6 */ -# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) -# define DISPLAY_RATE_SELECT_FPA1 (1 << 8) +#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT) +#define DISPLAY_RATE_SELECT_FPA1 (1 << 8) /* * SDVO multiplier for 945G/GM. Not used on 965. * * DPLL_MD_UDI_MULTIPLIER_MASK */ -# define SDVO_MULTIPLIER_MASK 0x000000ff -# define SDVO_MULTIPLIER_SHIFT_HIRES 4 -# define SDVO_MULTIPLIER_SHIFT_VGA 0 +#define SDVO_MULTIPLIER_MASK 0x000000ff +#define SDVO_MULTIPLIER_SHIFT_HIRES 4 +#define SDVO_MULTIPLIER_SHIFT_VGA 0 /* * PLL_MD @@ -194,11 +195,11 @@ * * Value is pixels minus 1. Must be set to 1 pixel for SDVO. */ -# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 -# define DPLL_MD_UDI_DIVIDER_SHIFT 24 +#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000 +#define DPLL_MD_UDI_DIVIDER_SHIFT 24 /* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */ -# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 -# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 +#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000 +#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16 /* * SDVO/UDI pixel multiplier. * @@ -216,80 +217,94 @@ * This register field has values of multiplication factor minus 1, with * a maximum multiplier of 5 for SDVO. */ -# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 -# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 +#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00 +#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8 /* * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. * This best be set to the default value (3) or the CRT won't work. No, * I don't entirely understand what this does... */ -# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f -# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 +#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f +#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0 #define DPLL_TEST 0x606c -# define DPLLB_TEST_SDVO_DIV_1 (0 << 22) -# define DPLLB_TEST_SDVO_DIV_2 (1 << 22) -# define DPLLB_TEST_SDVO_DIV_4 (2 << 22) -# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) -# define DPLLB_TEST_N_BYPASS (1 << 19) -# define DPLLB_TEST_M_BYPASS (1 << 18) -# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) -# define DPLLA_TEST_N_BYPASS (1 << 3) -# define DPLLA_TEST_M_BYPASS (1 << 2) -# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) +#define DPLLB_TEST_SDVO_DIV_1 (0 << 22) +#define DPLLB_TEST_SDVO_DIV_2 (1 << 22) +#define DPLLB_TEST_SDVO_DIV_4 (2 << 22) +#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22) +#define DPLLB_TEST_N_BYPASS (1 << 19) +#define DPLLB_TEST_M_BYPASS (1 << 18) +#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16) +#define DPLLA_TEST_N_BYPASS (1 << 3) +#define DPLLA_TEST_M_BYPASS (1 << 2) +#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) #define ADPA 0x61100 -#define ADPA_DAC_ENABLE (1<<31) -#define ADPA_DAC_DISABLE 0 -#define ADPA_PIPE_SELECT_MASK (1<<30) -#define ADPA_PIPE_A_SELECT 0 -#define ADPA_PIPE_B_SELECT (1<<30) -#define ADPA_USE_VGA_HVPOLARITY (1<<15) -#define ADPA_SETS_HVPOLARITY 0 -#define ADPA_VSYNC_CNTL_DISABLE (1<<11) -#define ADPA_VSYNC_CNTL_ENABLE 0 -#define ADPA_HSYNC_CNTL_DISABLE (1<<10) -#define ADPA_HSYNC_CNTL_ENABLE 0 -#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) -#define ADPA_VSYNC_ACTIVE_LOW 0 -#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) -#define ADPA_HSYNC_ACTIVE_LOW 0 - -#define FPA0 0x06040 -#define FPA1 0x06044 -#define FPB0 0x06048 -#define FPB1 0x0604c -# define FP_N_DIV_MASK 0x003f0000 -# define FP_N_DIV_SHIFT 16 -# define FP_M1_DIV_MASK 0x00003f00 -# define FP_M1_DIV_SHIFT 8 -# define FP_M2_DIV_MASK 0x0000003f -# define FP_M2_DIV_SHIFT 0 +#define ADPA_DAC_ENABLE (1 << 31) +#define ADPA_DAC_DISABLE 0 +#define ADPA_PIPE_SELECT_MASK (1 << 30) +#define ADPA_PIPE_A_SELECT 0 +#define ADPA_PIPE_B_SELECT (1 << 30) +#define ADPA_USE_VGA_HVPOLARITY (1 << 15) +#define ADPA_SETS_HVPOLARITY 0 +#define ADPA_VSYNC_CNTL_DISABLE (1 << 11) +#define ADPA_VSYNC_CNTL_ENABLE 0 +#define ADPA_HSYNC_CNTL_DISABLE (1 << 10) +#define ADPA_HSYNC_CNTL_ENABLE 0 +#define ADPA_VSYNC_ACTIVE_HIGH (1 << 4) +#define ADPA_VSYNC_ACTIVE_LOW 0 +#define ADPA_HSYNC_ACTIVE_HIGH (1 << 3) +#define ADPA_HSYNC_ACTIVE_LOW 0 +#define FPA0 0x06040 +#define FPA1 0x06044 +#define FPB0 0x06048 +#define FPB1 0x0604c +#define FP_N_DIV_MASK 0x003f0000 +#define FP_N_DIV_SHIFT 16 +#define FP_M1_DIV_MASK 0x00003f00 +#define FP_M1_DIV_SHIFT 8 +#define FP_M2_DIV_MASK 0x0000003f +#define FP_M2_DIV_SHIFT 0 #define PORT_HOTPLUG_EN 0x61110 -# define SDVOB_HOTPLUG_INT_EN (1 << 26) -# define SDVOC_HOTPLUG_INT_EN (1 << 25) -# define TV_HOTPLUG_INT_EN (1 << 18) -# define CRT_HOTPLUG_INT_EN (1 << 9) -# define CRT_HOTPLUG_FORCE_DETECT (1 << 3) +#define SDVOB_HOTPLUG_INT_EN (1 << 26) +#define SDVOC_HOTPLUG_INT_EN (1 << 25) +#define TV_HOTPLUG_INT_EN (1 << 18) +#define CRT_HOTPLUG_INT_EN (1 << 9) +#define CRT_HOTPLUG_FORCE_DETECT (1 << 3) +/* CDV.. */ +#define CRT_HOTPLUG_ACTIVATION_PERIOD_64 (1 << 8) +#define CRT_HOTPLUG_DAC_ON_TIME_2M (0 << 7) +#define CRT_HOTPLUG_DAC_ON_TIME_4M (1 << 7) +#define CRT_HOTPLUG_VOLTAGE_COMPARE_40 (0 << 5) +#define CRT_HOTPLUG_VOLTAGE_COMPARE_50 (1 << 5) +#define CRT_HOTPLUG_VOLTAGE_COMPARE_60 (2 << 5) +#define CRT_HOTPLUG_VOLTAGE_COMPARE_70 (3 << 5) +#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK (3 << 5) +#define CRT_HOTPLUG_DETECT_DELAY_1G (0 << 4) +#define CRT_HOTPLUG_DETECT_DELAY_2G (1 << 4) +#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2) +#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2) +#define CRT_HOTPLUG_DETECT_MASK 0x000000F8 #define PORT_HOTPLUG_STAT 0x61114 -# define CRT_HOTPLUG_INT_STATUS (1 << 11) -# define TV_HOTPLUG_INT_STATUS (1 << 10) -# define CRT_HOTPLUG_MONITOR_MASK (3 << 8) -# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) -# define CRT_HOTPLUG_MONITOR_MONO (2 << 8) -# define CRT_HOTPLUG_MONITOR_NONE (0 << 8) -# define SDVOC_HOTPLUG_INT_STATUS (1 << 7) -# define SDVOB_HOTPLUG_INT_STATUS (1 << 6) +#define CRT_HOTPLUG_INT_STATUS (1 << 11) +#define TV_HOTPLUG_INT_STATUS (1 << 10) +#define CRT_HOTPLUG_MONITOR_MASK (3 << 8) +#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8) +#define CRT_HOTPLUG_MONITOR_MONO (2 << 8) +#define CRT_HOTPLUG_MONITOR_NONE (0 << 8) +#define SDVOC_HOTPLUG_INT_STATUS (1 << 7) +#define SDVOB_HOTPLUG_INT_STATUS (1 << 6) #define SDVOB 0x61140 #define SDVOC 0x61160 -#define SDVO_ENABLE (1 << 31) -#define SDVO_PIPE_B_SELECT (1 << 30) -#define SDVO_STALL_SELECT (1 << 29) -#define SDVO_INTERRUPT_ENABLE (1 << 26) +#define SDVO_ENABLE (1 << 31) +#define SDVO_PIPE_B_SELECT (1 << 30) +#define SDVO_STALL_SELECT (1 << 29) +#define SDVO_INTERRUPT_ENABLE (1 << 26) + /** * 915G/GM SDVO pixel multiplier. * @@ -297,18 +312,18 @@ * * DPLL_MD_UDI_MULTIPLIER_MASK */ -#define SDVO_PORT_MULTIPLY_MASK (7 << 23) -#define SDVO_PORT_MULTIPLY_SHIFT 23 -#define SDVO_PHASE_SELECT_MASK (15 << 19) -#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) -#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) -#define SDVOC_GANG_MODE (1 << 16) -#define SDVO_BORDER_ENABLE (1 << 7) -#define SDVOB_PCIE_CONCURRENCY (1 << 3) -#define SDVO_DETECTED (1 << 2) +#define SDVO_PORT_MULTIPLY_MASK (7 << 23) +#define SDVO_PORT_MULTIPLY_SHIFT 23 +#define SDVO_PHASE_SELECT_MASK (15 << 19) +#define SDVO_PHASE_SELECT_DEFAULT (6 << 19) +#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18) +#define SDVOC_GANG_MODE (1 << 16) +#define SDVO_BORDER_ENABLE (1 << 7) +#define SDVOB_PCIE_CONCURRENCY (1 << 3) +#define SDVO_DETECTED (1 << 2) /* Bits to be preserved when writing */ #define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14)) -#define SDVOC_PRESERVE_MASK (1 << 17) +#define SDVOC_PRESERVE_MASK (1 << 17) /* * This register controls the LVDS output enable, pipe selection, and data @@ -321,116 +336,116 @@ * Enables the LVDS port. This bit must be set before DPLLs are enabled, as * the DPLL semantics change when the LVDS is assigned to that pipe. */ -# define LVDS_PORT_EN (1 << 31) +#define LVDS_PORT_EN (1 << 31) /* Selects pipe B for LVDS data. Must be set on pre-965. */ -# define LVDS_PIPEB_SELECT (1 << 30) +#define LVDS_PIPEB_SELECT (1 << 30) /* Turns on border drawing to allow centered display. */ -# define LVDS_BORDER_EN (1 << 15) +#define LVDS_BORDER_EN (1 << 15) /* * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per * pixel. */ -# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) -# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) -# define LVDS_A0A2_CLKA_POWER_UP (3 << 8) +#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8) +#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8) +#define LVDS_A0A2_CLKA_POWER_UP (3 << 8) /* * Controls the A3 data pair, which contains the additional LSBs for 24 bit * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be * on. */ -# define LVDS_A3_POWER_MASK (3 << 6) -# define LVDS_A3_POWER_DOWN (0 << 6) -# define LVDS_A3_POWER_UP (3 << 6) +#define LVDS_A3_POWER_MASK (3 << 6) +#define LVDS_A3_POWER_DOWN (0 << 6) +#define LVDS_A3_POWER_UP (3 << 6) /* * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP * is set. */ -# define LVDS_CLKB_POWER_MASK (3 << 4) -# define LVDS_CLKB_POWER_DOWN (0 << 4) -# define LVDS_CLKB_POWER_UP (3 << 4) +#define LVDS_CLKB_POWER_MASK (3 << 4) +#define LVDS_CLKB_POWER_DOWN (0 << 4) +#define LVDS_CLKB_POWER_UP (3 << 4) /* * Controls the B0-B3 data pairs. This must be set to match the DPLL p2 * setting for whether we are in dual-channel mode. The B3 pair will * additionally only be powered up when LVDS_A3_POWER_UP is set. */ -# define LVDS_B0B3_POWER_MASK (3 << 2) -# define LVDS_B0B3_POWER_DOWN (0 << 2) -# define LVDS_B0B3_POWER_UP (3 << 2) +#define LVDS_B0B3_POWER_MASK (3 << 2) +#define LVDS_B0B3_POWER_DOWN (0 << 2) +#define LVDS_B0B3_POWER_UP (3 << 2) -#define PIPEACONF 0x70008 -#define PIPEACONF_ENABLE (1<<31) -#define PIPEACONF_DISABLE 0 -#define PIPEACONF_DOUBLE_WIDE (1<<30) -#define PIPECONF_ACTIVE (1<<30) -#define I965_PIPECONF_ACTIVE (1<<30) -#define PIPECONF_DSIPLL_LOCK (1<<29) -#define PIPEACONF_SINGLE_WIDE 0 -#define PIPEACONF_PIPE_UNLOCKED 0 -#define PIPEACONF_DSR (1<<26) -#define PIPEACONF_PIPE_LOCKED (1<<25) -#define PIPEACONF_PALETTE 0 -#define PIPECONF_FORCE_BORDER (1<<25) -#define PIPEACONF_GAMMA (1<<24) -#define PIPECONF_PROGRESSIVE (0 << 21) +#define PIPEACONF 0x70008 +#define PIPEACONF_ENABLE (1 << 31) +#define PIPEACONF_DISABLE 0 +#define PIPEACONF_DOUBLE_WIDE (1 << 30) +#define PIPECONF_ACTIVE (1 << 30) +#define I965_PIPECONF_ACTIVE (1 << 30) +#define PIPECONF_DSIPLL_LOCK (1 << 29) +#define PIPEACONF_SINGLE_WIDE 0 +#define PIPEACONF_PIPE_UNLOCKED 0 +#define PIPEACONF_DSR (1 << 26) +#define PIPEACONF_PIPE_LOCKED (1 << 25) +#define PIPEACONF_PALETTE 0 +#define PIPECONF_FORCE_BORDER (1 << 25) +#define PIPEACONF_GAMMA (1 << 24) +#define PIPECONF_PROGRESSIVE (0 << 21) #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) -#define PIPECONF_PLANE_OFF (1<<19) -#define PIPECONF_CURSOR_OFF (1<<18) +#define PIPECONF_PLANE_OFF (1 << 19) +#define PIPECONF_CURSOR_OFF (1 << 18) +#define PIPEBCONF 0x71008 +#define PIPEBCONF_ENABLE (1 << 31) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_DOUBLE_WIDE (1 << 30) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_GAMMA (1 << 24) +#define PIPEBCONF_PALETTE 0 -#define PIPEBCONF 0x71008 -#define PIPEBCONF_ENABLE (1<<31) -#define PIPEBCONF_DISABLE 0 -#define PIPEBCONF_DOUBLE_WIDE (1<<30) -#define PIPEBCONF_DISABLE 0 -#define PIPEBCONF_GAMMA (1<<24) -#define PIPEBCONF_PALETTE 0 - -#define PIPECCONF 0x72008 +#define PIPECCONF 0x72008 #define PIPEBGCMAXRED 0x71010 #define PIPEBGCMAXGREEN 0x71014 #define PIPEBGCMAXBLUE 0x71018 -#define PIPEASTAT 0x70024 +#define PIPEASTAT 0x70024 #define PIPEBSTAT 0x71024 #define PIPECSTAT 0x72024 -#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) -#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) -#define PIPE_VBLANK_CLEAR (1 << 1) -#define PIPE_VBLANK_STATUS (1 << 1) -#define PIPE_TE_STATUS (1UL<<6) -#define PIPE_DPST_EVENT_STATUS (1UL<<7) -#define PIPE_VSYNC_CLEAR (1UL<<9) -#define PIPE_VSYNC_STATUS (1UL<<9) -#define PIPE_HDMI_AUDIO_UNDERRUN_STATUS (1UL<<10) -#define PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS (1UL<<11) -#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17) -#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) -#define PIPE_TE_ENABLE (1UL<<22) -#define PIPE_DPST_EVENT_ENABLE (1UL<<23) -#define PIPE_VSYNC_ENABL (1UL<<25) -#define PIPE_HDMI_AUDIO_UNDERRUN (1UL<<26) -#define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL<<27) -#define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | PIPE_HDMI_AUDIO_BUFFER_DONE) +#define PIPE_VBLANK_INTERRUPT_STATUS (1UL << 1) +#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL << 2) +#define PIPE_VBLANK_CLEAR (1 << 1) +#define PIPE_VBLANK_STATUS (1 << 1) +#define PIPE_TE_STATUS (1UL << 6) +#define PIPE_DPST_EVENT_STATUS (1UL << 7) +#define PIPE_VSYNC_CLEAR (1UL << 9) +#define PIPE_VSYNC_STATUS (1UL << 9) +#define PIPE_HDMI_AUDIO_UNDERRUN_STATUS (1UL << 10) +#define PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS (1UL << 11) +#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL << 17) +#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL << 18) +#define PIPE_TE_ENABLE (1UL << 22) +#define PIPE_DPST_EVENT_ENABLE (1UL << 23) +#define PIPE_VSYNC_ENABL (1UL << 25) +#define PIPE_HDMI_AUDIO_UNDERRUN (1UL << 26) +#define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL << 27) +#define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | \ + PIPE_HDMI_AUDIO_BUFFER_DONE) #define PIPE_EVENT_MASK ((1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)|(1 << 22)|(1 << 21)|(1 << 20)|(1 << 16)) #define PIPE_VBLANK_MASK ((1 << 25)|(1 << 24)|(1 << 18)|(1 << 17)) #define HISTOGRAM_INT_CONTROL 0x61268 #define HISTOGRAM_BIN_DATA 0X61264 #define HISTOGRAM_LOGIC_CONTROL 0x61260 #define PWM_CONTROL_LOGIC 0x61250 -#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10) -#define HISTOGRAM_INTERRUPT_ENABLE (1UL<<31) -#define HISTOGRAM_LOGIC_ENABLE (1UL<<31) -#define PWM_LOGIC_ENABLE (1UL<<31) -#define PWM_PHASEIN_ENABLE (1UL<<25) -#define PWM_PHASEIN_INT_ENABLE (1UL<<24) -#define PWM_PHASEIN_VB_COUNT 0x00001f00 -#define PWM_PHASEIN_INC 0x0000001f -#define HISTOGRAM_INT_CTRL_CLEAR (1UL<<30) -#define DPST_YUV_LUMA_MODE 0 +#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL << 10) +#define HISTOGRAM_INTERRUPT_ENABLE (1UL << 31) +#define HISTOGRAM_LOGIC_ENABLE (1UL << 31) +#define PWM_LOGIC_ENABLE (1UL << 31) +#define PWM_PHASEIN_ENABLE (1UL << 25) +#define PWM_PHASEIN_INT_ENABLE (1UL << 24) +#define PWM_PHASEIN_VB_COUNT 0x00001f00 +#define PWM_PHASEIN_INC 0x0000001f +#define HISTOGRAM_INT_CTRL_CLEAR (1UL << 30) +#define DPST_YUV_LUMA_MODE 0 struct dpst_ie_histogram_control { union { @@ -470,12 +485,12 @@ struct dpst_guardband { #define PIPEBFRAMEPIXEL 0x71044 #define PIPECFRAMEHIGH 0x72040 #define PIPECFRAMEPIXEL 0x72044 -#define PIPE_FRAME_HIGH_MASK 0x0000ffff -#define PIPE_FRAME_HIGH_SHIFT 0 -#define PIPE_FRAME_LOW_MASK 0xff000000 -#define PIPE_FRAME_LOW_SHIFT 24 -#define PIPE_PIXEL_MASK 0x00ffffff -#define PIPE_PIXEL_SHIFT 0 +#define PIPE_FRAME_HIGH_MASK 0x0000ffff +#define PIPE_FRAME_HIGH_SHIFT 0 +#define PIPE_FRAME_LOW_MASK 0xff000000 +#define PIPE_FRAME_LOW_SHIFT 24 +#define PIPE_PIXEL_MASK 0x00ffffff +#define PIPE_PIXEL_SHIFT 0 #define DSPARB 0x70030 #define DSPFW1 0x70034 @@ -488,30 +503,30 @@ struct dpst_guardband { #define DSPACNTR 0x70180 #define DSPBCNTR 0x71180 #define DSPCCNTR 0x72180 -#define DISPLAY_PLANE_ENABLE (1<<31) +#define DISPLAY_PLANE_ENABLE (1 << 31) #define DISPLAY_PLANE_DISABLE 0 -#define DISPPLANE_GAMMA_ENABLE (1<<30) +#define DISPPLANE_GAMMA_ENABLE (1 << 30) #define DISPPLANE_GAMMA_DISABLE 0 -#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) -#define DISPPLANE_8BPP (0x2<<26) -#define DISPPLANE_15_16BPP (0x4<<26) -#define DISPPLANE_16BPP (0x5<<26) -#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) -#define DISPPLANE_32BPP (0x7<<26) -#define DISPPLANE_STEREO_ENABLE (1<<25) +#define DISPPLANE_PIXFORMAT_MASK (0xf << 26) +#define DISPPLANE_8BPP (0x2 << 26) +#define DISPPLANE_15_16BPP (0x4 << 26) +#define DISPPLANE_16BPP (0x5 << 26) +#define DISPPLANE_32BPP_NO_ALPHA (0x6 << 26) +#define DISPPLANE_32BPP (0x7 << 26) +#define DISPPLANE_STEREO_ENABLE (1 << 25) #define DISPPLANE_STEREO_DISABLE 0 -#define DISPPLANE_SEL_PIPE_MASK (1<<24) +#define DISPPLANE_SEL_PIPE_MASK (1 << 24) #define DISPPLANE_SEL_PIPE_POS 24 #define DISPPLANE_SEL_PIPE_A 0 -#define DISPPLANE_SEL_PIPE_B (1<<24) -#define DISPPLANE_SRC_KEY_ENABLE (1<<22) +#define DISPPLANE_SEL_PIPE_B (1 << 24) +#define DISPPLANE_SRC_KEY_ENABLE (1 << 22) #define DISPPLANE_SRC_KEY_DISABLE 0 -#define DISPPLANE_LINE_DOUBLE (1<<20) +#define DISPPLANE_LINE_DOUBLE (1 << 20) #define DISPPLANE_NO_LINE_DOUBLE 0 #define DISPPLANE_STEREO_POLARITY_FIRST 0 -#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) +#define DISPPLANE_STEREO_POLARITY_SECOND (1 << 18) /* plane B only */ -#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) +#define DISPPLANE_ALPHA_TRANS_ENABLE (1 << 15) #define DISPPLANE_ALPHA_TRANS_DISABLE 0 #define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 #define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) @@ -548,25 +563,25 @@ struct dpst_guardband { #define DSPCSURF 0x7219C #define DSPCTILEOFF 0x721A4 -#define DSPCKEYMAXVAL 0x721A0 -#define DSPCKEYMINVAL 0x72194 -#define DSPCKEYMSK 0x72198 +#define DSPCKEYMAXVAL 0x721A0 +#define DSPCKEYMINVAL 0x72194 +#define DSPCKEYMSK 0x72198 #define VGACNTRL 0x71400 -# define VGA_DISP_DISABLE (1 << 31) -# define VGA_2X_MODE (1 << 30) -# define VGA_PIPE_B_SELECT (1 << 29) +#define VGA_DISP_DISABLE (1 << 31) +#define VGA_2X_MODE (1 << 30) +#define VGA_PIPE_B_SELECT (1 << 29) /* * Overlay registers */ #define OV_C_OFFSET 0x08000 #define OV_OVADD 0x30000 -#define OV_DOVASTA 0x30008 -# define OV_PIPE_SELECT ((1 << 6)|(1 << 7)) -# define OV_PIPE_SELECT_POS 6 -# define OV_PIPE_A 0 -# define OV_PIPE_C 1 +#define OV_DOVASTA 0x30008 +# define OV_PIPE_SELECT ((1 << 6)|(1 << 7)) +# define OV_PIPE_SELECT_POS 6 +# define OV_PIPE_A 0 +# define OV_PIPE_C 1 #define OV_OGAMC5 0x30010 #define OV_OGAMC4 0x30014 #define OV_OGAMC3 0x30018 @@ -574,7 +589,7 @@ struct dpst_guardband { #define OV_OGAMC1 0x30020 #define OV_OGAMC0 0x30024 #define OVC_OVADD 0x38000 -#define OVC_DOVCSTA 0x38008 +#define OVC_DOVCSTA 0x38008 #define OVC_OGAMC5 0x38010 #define OVC_OGAMC4 0x38014 #define OVC_OGAMC3 0x38018 @@ -627,16 +642,16 @@ struct dpst_guardband { /* Cursor A & B regs */ #define CURACNTR 0x70080 -#define CURSOR_MODE_DISABLE 0x00 -#define CURSOR_MODE_64_32B_AX 0x07 -#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) -#define MCURSOR_GAMMA_ENABLE (1 << 26) +#define CURSOR_MODE_DISABLE 0x00 +#define CURSOR_MODE_64_32B_AX 0x07 +#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) +#define MCURSOR_GAMMA_ENABLE (1 << 26) #define CURABASE 0x70084 #define CURAPOS 0x70088 -#define CURSOR_POS_MASK 0x007FF -#define CURSOR_POS_SIGN 0x8000 -#define CURSOR_X_SHIFT 0 -#define CURSOR_Y_SHIFT 16 +#define CURSOR_POS_MASK 0x007FF +#define CURSOR_POS_SIGN 0x8000 +#define CURSOR_X_SHIFT 0 +#define CURSOR_Y_SHIFT 16 #define CURBCNTR 0x700c0 #define CURBBASE 0x700c4 #define CURBPOS 0x700c8 @@ -647,22 +662,22 @@ struct dpst_guardband { /* * Interrupt Registers */ -#define IER 0x020a0 -#define IIR 0x020a4 -#define IMR 0x020a8 -#define ISR 0x020ac +#define IER 0x020a0 +#define IIR 0x020a4 +#define IMR 0x020a8 +#define ISR 0x020ac /* * MOORESTOWN delta registers */ #define MRST_DPLL_A 0x0f014 #define MDFLD_DPLL_B 0x0f018 -#define MDFLD_INPUT_REF_SEL (1 << 14) -#define MDFLD_VCO_SEL (1 << 16) -#define DPLLA_MODE_LVDS (2 << 26) /* mrst */ -#define MDFLD_PLL_LATCHEN (1 << 28) -#define MDFLD_PWR_GATE_EN (1 << 30) -#define MDFLD_P1_MASK (0x1FF << 17) +#define MDFLD_INPUT_REF_SEL (1 << 14) +#define MDFLD_VCO_SEL (1 << 16) +#define DPLLA_MODE_LVDS (2 << 26) /* mrst */ +#define MDFLD_PLL_LATCHEN (1 << 28) +#define MDFLD_PWR_GATE_EN (1 << 30) +#define MDFLD_P1_MASK (0x1FF << 17) #define MRST_FPA0 0x0f040 #define MRST_FPA1 0x0f044 #define MDFLD_DPLL_DIV0 0x0f048 @@ -672,45 +687,45 @@ struct dpst_guardband { /* * MEDFIELD HDMI registers */ -#define HDMIPHYMISCCTL 0x61134 -# define HDMI_PHY_POWER_DOWN 0x7f -#define HDMIB_CONTROL 0x61140 -# define HDMIB_PORT_EN (1 << 31) -# define HDMIB_PIPE_B_SELECT (1 << 30) -# define HDMIB_NULL_PACKET (1 << 9) -#define HDMIB_HDCP_PORT (1 << 5) +#define HDMIPHYMISCCTL 0x61134 +#define HDMI_PHY_POWER_DOWN 0x7f +#define HDMIB_CONTROL 0x61140 +#define HDMIB_PORT_EN (1 << 31) +#define HDMIB_PIPE_B_SELECT (1 << 30) +#define HDMIB_NULL_PACKET (1 << 9) +#define HDMIB_HDCP_PORT (1 << 5) /* #define LVDS 0x61180 */ -# define MRST_PANEL_8TO6_DITHER_ENABLE (1 << 25) -# define MRST_PANEL_24_DOT_1_FORMAT (1 << 24) -# define LVDS_A3_POWER_UP_0_OUTPUT (1 << 6) +#define MRST_PANEL_8TO6_DITHER_ENABLE (1 << 25) +#define MRST_PANEL_24_DOT_1_FORMAT (1 << 24) +#define LVDS_A3_POWER_UP_0_OUTPUT (1 << 6) #define MIPI 0x61190 #define MIPI_C 0x62190 -# define MIPI_PORT_EN (1 << 31) +#define MIPI_PORT_EN (1 << 31) /* Turns on border drawing to allow centered display. */ -# define SEL_FLOPPED_HSTX (1 << 23) -# define PASS_FROM_SPHY_TO_AFE (1 << 16) -# define MIPI_BORDER_EN (1 << 15) -# define MIPIA_3LANE_MIPIC_1LANE 0x1 -# define MIPIA_2LANE_MIPIC_2LANE 0x2 -# define TE_TRIGGER_DSI_PROTOCOL (1 << 2) -# define TE_TRIGGER_GPIO_PIN (1 << 3) -#define MIPI_TE_COUNT 0x61194 +#define SEL_FLOPPED_HSTX (1 << 23) +#define PASS_FROM_SPHY_TO_AFE (1 << 16) +#define MIPI_BORDER_EN (1 << 15) +#define MIPIA_3LANE_MIPIC_1LANE 0x1 +#define MIPIA_2LANE_MIPIC_2LANE 0x2 +#define TE_TRIGGER_DSI_PROTOCOL (1 << 2) +#define TE_TRIGGER_GPIO_PIN (1 << 3) +#define MIPI_TE_COUNT 0x61194 /* #define PP_CONTROL 0x61204 */ -# define POWER_DOWN_ON_RESET (1 << 1) +#define POWER_DOWN_ON_RESET (1 << 1) /* #define PFIT_CONTROL 0x61230 */ -# define PFIT_PIPE_SELECT (3 << 29) -# define PFIT_PIPE_SELECT_SHIFT (29) +#define PFIT_PIPE_SELECT (3 << 29) +#define PFIT_PIPE_SELECT_SHIFT (29) /* #define BLC_PWM_CTL 0x61254 */ -#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT (16) -#define MRST_BACKLIGHT_MODULATION_FREQ_MASK (0xffff << 16) +#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT (16) +#define MRST_BACKLIGHT_MODULATION_FREQ_MASK (0xffff << 16) /* #define PIPEACONF 0x70008 */ -#define PIPEACONF_PIPE_STATE (1<<30) +#define PIPEACONF_PIPE_STATE (1 << 30) /* #define DSPACNTR 0x70180 */ #define MRST_DSPABASE 0x7019c @@ -724,281 +739,286 @@ struct dpst_guardband { /* * MIPI IP registers */ -#define MIPIC_REG_OFFSET 0x800 -#define DEVICE_READY_REG 0xb000 -#define LP_OUTPUT_HOLD (1 << 16) -#define EXIT_ULPS_DEV_READY 0x3 -#define LP_OUTPUT_HOLD_RELEASE 0x810000 -# define ENTERING_ULPS (2 << 1) -# define EXITING_ULPS (1 << 1) -# define ULPS_MASK (3 << 1) -# define BUS_POSSESSION (1 << 3) -#define INTR_STAT_REG 0xb004 -#define RX_SOT_ERROR (1 << 0) -#define RX_SOT_SYNC_ERROR (1 << 1) -#define RX_ESCAPE_MODE_ENTRY_ERROR (1 << 3) -#define RX_LP_TX_SYNC_ERROR (1 << 4) -#define RX_HS_RECEIVE_TIMEOUT_ERROR (1 << 5) -#define RX_FALSE_CONTROL_ERROR (1 << 6) -#define RX_ECC_SINGLE_BIT_ERROR (1 << 7) -#define RX_ECC_MULTI_BIT_ERROR (1 << 8) -#define RX_CHECKSUM_ERROR (1 << 9) -#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 10) -#define RX_DSI_VC_ID_INVALID (1 << 11) -#define TX_FALSE_CONTROL_ERROR (1 << 12) -#define TX_ECC_SINGLE_BIT_ERROR (1 << 13) -#define TX_ECC_MULTI_BIT_ERROR (1 << 14) -#define TX_CHECKSUM_ERROR (1 << 15) -#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 16) -#define TX_DSI_VC_ID_INVALID (1 << 17) -#define HIGH_CONTENTION (1 << 18) -#define LOW_CONTENTION (1 << 19) -#define DPI_FIFO_UNDER_RUN (1 << 20) -#define HS_TX_TIMEOUT (1 << 21) -#define LP_RX_TIMEOUT (1 << 22) -#define TURN_AROUND_ACK_TIMEOUT (1 << 23) -#define ACK_WITH_NO_ERROR (1 << 24) -#define HS_GENERIC_WR_FIFO_FULL (1 << 27) -#define LP_GENERIC_WR_FIFO_FULL (1 << 28) -#define SPL_PKT_SENT (1 << 30) -#define INTR_EN_REG 0xb008 -#define DSI_FUNC_PRG_REG 0xb00c -#define DPI_CHANNEL_NUMBER_POS 0x03 -#define DBI_CHANNEL_NUMBER_POS 0x05 -#define FMT_DPI_POS 0x07 -#define FMT_DBI_POS 0x0A -#define DBI_DATA_WIDTH_POS 0x0D +#define MIPIC_REG_OFFSET 0x800 + +#define DEVICE_READY_REG 0xb000 +#define LP_OUTPUT_HOLD (1 << 16) +#define EXIT_ULPS_DEV_READY 0x3 +#define LP_OUTPUT_HOLD_RELEASE 0x810000 +# define ENTERING_ULPS (2 << 1) +# define EXITING_ULPS (1 << 1) +# define ULPS_MASK (3 << 1) +# define BUS_POSSESSION (1 << 3) +#define INTR_STAT_REG 0xb004 +#define RX_SOT_ERROR (1 << 0) +#define RX_SOT_SYNC_ERROR (1 << 1) +#define RX_ESCAPE_MODE_ENTRY_ERROR (1 << 3) +#define RX_LP_TX_SYNC_ERROR (1 << 4) +#define RX_HS_RECEIVE_TIMEOUT_ERROR (1 << 5) +#define RX_FALSE_CONTROL_ERROR (1 << 6) +#define RX_ECC_SINGLE_BIT_ERROR (1 << 7) +#define RX_ECC_MULTI_BIT_ERROR (1 << 8) +#define RX_CHECKSUM_ERROR (1 << 9) +#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 10) +#define RX_DSI_VC_ID_INVALID (1 << 11) +#define TX_FALSE_CONTROL_ERROR (1 << 12) +#define TX_ECC_SINGLE_BIT_ERROR (1 << 13) +#define TX_ECC_MULTI_BIT_ERROR (1 << 14) +#define TX_CHECKSUM_ERROR (1 << 15) +#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 16) +#define TX_DSI_VC_ID_INVALID (1 << 17) +#define HIGH_CONTENTION (1 << 18) +#define LOW_CONTENTION (1 << 19) +#define DPI_FIFO_UNDER_RUN (1 << 20) +#define HS_TX_TIMEOUT (1 << 21) +#define LP_RX_TIMEOUT (1 << 22) +#define TURN_AROUND_ACK_TIMEOUT (1 << 23) +#define ACK_WITH_NO_ERROR (1 << 24) +#define HS_GENERIC_WR_FIFO_FULL (1 << 27) +#define LP_GENERIC_WR_FIFO_FULL (1 << 28) +#define SPL_PKT_SENT (1 << 30) +#define INTR_EN_REG 0xb008 +#define DSI_FUNC_PRG_REG 0xb00c +#define DPI_CHANNEL_NUMBER_POS 0x03 +#define DBI_CHANNEL_NUMBER_POS 0x05 +#define FMT_DPI_POS 0x07 +#define FMT_DBI_POS 0x0A +#define DBI_DATA_WIDTH_POS 0x0D + /* DPI PIXEL FORMATS */ -#define RGB_565_FMT 0x01 /* RGB 565 FORMAT */ -#define RGB_666_FMT 0x02 /* RGB 666 FORMAT */ -#define LRGB_666_FMT 0x03 /* RGB LOOSELY PACKED - * 666 FORMAT - */ -#define RGB_888_FMT 0x04 /* RGB 888 FORMAT */ -#define VIRTUAL_CHANNEL_NUMBER_0 0x00 /* Virtual channel 0 */ -#define VIRTUAL_CHANNEL_NUMBER_1 0x01 /* Virtual channel 1 */ -#define VIRTUAL_CHANNEL_NUMBER_2 0x02 /* Virtual channel 2 */ -#define VIRTUAL_CHANNEL_NUMBER_3 0x03 /* Virtual channel 3 */ -#define DBI_NOT_SUPPORTED 0x00 /* command mode - * is not supported - */ -#define DBI_DATA_WIDTH_16BIT 0x01 /* 16 bit data */ +#define RGB_565_FMT 0x01 /* RGB 565 FORMAT */ +#define RGB_666_FMT 0x02 /* RGB 666 FORMAT */ +#define LRGB_666_FMT 0x03 /* RGB LOOSELY PACKED + * 666 FORMAT + */ +#define RGB_888_FMT 0x04 /* RGB 888 FORMAT */ +#define VIRTUAL_CHANNEL_NUMBER_0 0x00 /* Virtual channel 0 */ +#define VIRTUAL_CHANNEL_NUMBER_1 0x01 /* Virtual channel 1 */ +#define VIRTUAL_CHANNEL_NUMBER_2 0x02 /* Virtual channel 2 */ +#define VIRTUAL_CHANNEL_NUMBER_3 0x03 /* Virtual channel 3 */ + +#define DBI_NOT_SUPPORTED 0x00 /* command mode + * is not supported + */ +#define DBI_DATA_WIDTH_16BIT 0x01 /* 16 bit data */ #define DBI_DATA_WIDTH_9BIT 0x02 /* 9 bit data */ #define DBI_DATA_WIDTH_8BIT 0x03 /* 8 bit data */ -#define DBI_DATA_WIDTH_OPT1 0x04 /* option 1 */ -#define DBI_DATA_WIDTH_OPT2 0x05 /* option 2 */ -#define HS_TX_TIMEOUT_REG 0xb010 -#define LP_RX_TIMEOUT_REG 0xb014 -#define TURN_AROUND_TIMEOUT_REG 0xb018 -#define DEVICE_RESET_REG 0xb01C -#define DPI_RESOLUTION_REG 0xb020 -#define RES_V_POS 0x10 -#define DBI_RESOLUTION_REG 0xb024 /* Reserved for MDFLD */ -#define HORIZ_SYNC_PAD_COUNT_REG 0xb028 -#define HORIZ_BACK_PORCH_COUNT_REG 0xb02C -#define HORIZ_FRONT_PORCH_COUNT_REG 0xb030 -#define HORIZ_ACTIVE_AREA_COUNT_REG 0xb034 -#define VERT_SYNC_PAD_COUNT_REG 0xb038 -#define VERT_BACK_PORCH_COUNT_REG 0xb03c -#define VERT_FRONT_PORCH_COUNT_REG 0xb040 -#define HIGH_LOW_SWITCH_COUNT_REG 0xb044 -#define DPI_CONTROL_REG 0xb048 -#define DPI_SHUT_DOWN (1 << 0) -#define DPI_TURN_ON (1 << 1) -#define DPI_COLOR_MODE_ON (1 << 2) -#define DPI_COLOR_MODE_OFF (1 << 3) -#define DPI_BACK_LIGHT_ON (1 << 4) -#define DPI_BACK_LIGHT_OFF (1 << 5) -#define DPI_LP (1 << 6) -#define DPI_DATA_REG 0xb04c -#define DPI_BACK_LIGHT_ON_DATA 0x07 -#define DPI_BACK_LIGHT_OFF_DATA 0x17 -#define INIT_COUNT_REG 0xb050 -#define MAX_RET_PAK_REG 0xb054 -#define VIDEO_FMT_REG 0xb058 -#define COMPLETE_LAST_PCKT (1 << 2) -#define EOT_DISABLE_REG 0xb05c -#define ENABLE_CLOCK_STOPPING (1 << 1) -#define LP_BYTECLK_REG 0xb060 -#define LP_GEN_DATA_REG 0xb064 -#define HS_GEN_DATA_REG 0xb068 -#define LP_GEN_CTRL_REG 0xb06C -#define HS_GEN_CTRL_REG 0xb070 -#define DCS_CHANNEL_NUMBER_POS 0x06 -#define MCS_COMMANDS_POS 0x8 -#define WORD_COUNTS_POS 0x8 -#define MCS_PARAMETER_POS 0x10 -#define GEN_FIFO_STAT_REG 0xb074 -#define HS_DATA_FIFO_FULL (1 << 0) -#define HS_DATA_FIFO_HALF_EMPTY (1 << 1) -#define HS_DATA_FIFO_EMPTY (1 << 2) -#define LP_DATA_FIFO_FULL (1 << 8) -#define LP_DATA_FIFO_HALF_EMPTY (1 << 9) -#define LP_DATA_FIFO_EMPTY (1 << 10) -#define HS_CTRL_FIFO_FULL (1 << 16) -#define HS_CTRL_FIFO_HALF_EMPTY (1 << 17) -#define HS_CTRL_FIFO_EMPTY (1 << 18) -#define LP_CTRL_FIFO_FULL (1 << 24) -#define LP_CTRL_FIFO_HALF_EMPTY (1 << 25) -#define LP_CTRL_FIFO_EMPTY (1 << 26) -#define DBI_FIFO_EMPTY (1 << 27) -#define DPI_FIFO_EMPTY (1 << 28) -#define HS_LS_DBI_ENABLE_REG 0xb078 -#define TXCLKESC_REG 0xb07c -#define DPHY_PARAM_REG 0xb080 -#define DBI_BW_CTRL_REG 0xb084 -#define CLK_LANE_SWT_REG 0xb088 +#define DBI_DATA_WIDTH_OPT1 0x04 /* option 1 */ +#define DBI_DATA_WIDTH_OPT2 0x05 /* option 2 */ + +#define HS_TX_TIMEOUT_REG 0xb010 +#define LP_RX_TIMEOUT_REG 0xb014 +#define TURN_AROUND_TIMEOUT_REG 0xb018 +#define DEVICE_RESET_REG 0xb01C +#define DPI_RESOLUTION_REG 0xb020 +#define RES_V_POS 0x10 +#define DBI_RESOLUTION_REG 0xb024 /* Reserved for MDFLD */ +#define HORIZ_SYNC_PAD_COUNT_REG 0xb028 +#define HORIZ_BACK_PORCH_COUNT_REG 0xb02C +#define HORIZ_FRONT_PORCH_COUNT_REG 0xb030 +#define HORIZ_ACTIVE_AREA_COUNT_REG 0xb034 +#define VERT_SYNC_PAD_COUNT_REG 0xb038 +#define VERT_BACK_PORCH_COUNT_REG 0xb03c +#define VERT_FRONT_PORCH_COUNT_REG 0xb040 +#define HIGH_LOW_SWITCH_COUNT_REG 0xb044 +#define DPI_CONTROL_REG 0xb048 +#define DPI_SHUT_DOWN (1 << 0) +#define DPI_TURN_ON (1 << 1) +#define DPI_COLOR_MODE_ON (1 << 2) +#define DPI_COLOR_MODE_OFF (1 << 3) +#define DPI_BACK_LIGHT_ON (1 << 4) +#define DPI_BACK_LIGHT_OFF (1 << 5) +#define DPI_LP (1 << 6) +#define DPI_DATA_REG 0xb04c +#define DPI_BACK_LIGHT_ON_DATA 0x07 +#define DPI_BACK_LIGHT_OFF_DATA 0x17 +#define INIT_COUNT_REG 0xb050 +#define MAX_RET_PAK_REG 0xb054 +#define VIDEO_FMT_REG 0xb058 +#define COMPLETE_LAST_PCKT (1 << 2) +#define EOT_DISABLE_REG 0xb05c +#define ENABLE_CLOCK_STOPPING (1 << 1) +#define LP_BYTECLK_REG 0xb060 +#define LP_GEN_DATA_REG 0xb064 +#define HS_GEN_DATA_REG 0xb068 +#define LP_GEN_CTRL_REG 0xb06C +#define HS_GEN_CTRL_REG 0xb070 +#define DCS_CHANNEL_NUMBER_POS 0x6 +#define MCS_COMMANDS_POS 0x8 +#define WORD_COUNTS_POS 0x8 +#define MCS_PARAMETER_POS 0x10 +#define GEN_FIFO_STAT_REG 0xb074 +#define HS_DATA_FIFO_FULL (1 << 0) +#define HS_DATA_FIFO_HALF_EMPTY (1 << 1) +#define HS_DATA_FIFO_EMPTY (1 << 2) +#define LP_DATA_FIFO_FULL (1 << 8) +#define LP_DATA_FIFO_HALF_EMPTY (1 << 9) +#define LP_DATA_FIFO_EMPTY (1 << 10) +#define HS_CTRL_FIFO_FULL (1 << 16) +#define HS_CTRL_FIFO_HALF_EMPTY (1 << 17) +#define HS_CTRL_FIFO_EMPTY (1 << 18) +#define LP_CTRL_FIFO_FULL (1 << 24) +#define LP_CTRL_FIFO_HALF_EMPTY (1 << 25) +#define LP_CTRL_FIFO_EMPTY (1 << 26) +#define DBI_FIFO_EMPTY (1 << 27) +#define DPI_FIFO_EMPTY (1 << 28) +#define HS_LS_DBI_ENABLE_REG 0xb078 +#define TXCLKESC_REG 0xb07c +#define DPHY_PARAM_REG 0xb080 +#define DBI_BW_CTRL_REG 0xb084 +#define CLK_LANE_SWT_REG 0xb088 /* * MIPI Adapter registers */ -#define MIPI_CONTROL_REG 0xb104 -#define MIPI_2X_CLOCK_BITS ((1 << 0) | (1 << 1)) -#define MIPI_DATA_ADDRESS_REG 0xb108 -#define MIPI_DATA_LENGTH_REG 0xb10C -#define MIPI_COMMAND_ADDRESS_REG 0xb110 -#define MIPI_COMMAND_LENGTH_REG 0xb114 -#define MIPI_READ_DATA_RETURN_REG0 0xb118 -#define MIPI_READ_DATA_RETURN_REG1 0xb11C -#define MIPI_READ_DATA_RETURN_REG2 0xb120 -#define MIPI_READ_DATA_RETURN_REG3 0xb124 -#define MIPI_READ_DATA_RETURN_REG4 0xb128 -#define MIPI_READ_DATA_RETURN_REG5 0xb12C -#define MIPI_READ_DATA_RETURN_REG6 0xb130 -#define MIPI_READ_DATA_RETURN_REG7 0xb134 -#define MIPI_READ_DATA_VALID_REG 0xb138 +#define MIPI_CONTROL_REG 0xb104 +#define MIPI_2X_CLOCK_BITS ((1 << 0) | (1 << 1)) +#define MIPI_DATA_ADDRESS_REG 0xb108 +#define MIPI_DATA_LENGTH_REG 0xb10C +#define MIPI_COMMAND_ADDRESS_REG 0xb110 +#define MIPI_COMMAND_LENGTH_REG 0xb114 +#define MIPI_READ_DATA_RETURN_REG0 0xb118 +#define MIPI_READ_DATA_RETURN_REG1 0xb11C +#define MIPI_READ_DATA_RETURN_REG2 0xb120 +#define MIPI_READ_DATA_RETURN_REG3 0xb124 +#define MIPI_READ_DATA_RETURN_REG4 0xb128 +#define MIPI_READ_DATA_RETURN_REG5 0xb12C +#define MIPI_READ_DATA_RETURN_REG6 0xb130 +#define MIPI_READ_DATA_RETURN_REG7 0xb134 +#define MIPI_READ_DATA_VALID_REG 0xb138 + /* DBI COMMANDS */ -#define soft_reset 0x01 +#define soft_reset 0x01 /* * The display module performs a software reset. * Registers are written with their SW Reset default values. */ -#define get_power_mode 0x0a +#define get_power_mode 0x0a /* * The display module returns the current power mode */ -#define get_address_mode 0x0b +#define get_address_mode 0x0b /* * The display module returns the current status. */ -#define get_pixel_format 0x0c +#define get_pixel_format 0x0c /* * This command gets the pixel format for the RGB image data * used by the interface. */ -#define get_display_mode 0x0d +#define get_display_mode 0x0d /* * The display module returns the Display Image Mode status. */ -#define get_signal_mode 0x0e +#define get_signal_mode 0x0e /* * The display module returns the Display Signal Mode. */ -#define get_diagnostic_result 0x0f +#define get_diagnostic_result 0x0f /* * The display module returns the self-diagnostic results following * a Sleep Out command. */ -#define enter_sleep_mode 0x10 +#define enter_sleep_mode 0x10 /* * This command causes the display module to enter the Sleep mode. * In this mode, all unnecessary blocks inside the display module are * disabled except interface communication. This is the lowest power * mode the display module supports. */ -#define exit_sleep_mode 0x11 +#define exit_sleep_mode 0x11 /* * This command causes the display module to exit Sleep mode. * All blocks inside the display module are enabled. */ -#define enter_partial_mode 0x12 +#define enter_partial_mode 0x12 /* * This command causes the display module to enter the Partial Display * Mode. The Partial Display Mode window is described by the * set_partial_area command. */ -#define enter_normal_mode 0x13 +#define enter_normal_mode 0x13 /* * This command causes the display module to enter the Normal mode. * Normal Mode is defined as Partial Display mode and Scroll mode are off */ -#define exit_invert_mode 0x20 +#define exit_invert_mode 0x20 /* * This command causes the display module to stop inverting the image * data on the display device. The frame memory contents remain unchanged. * No status bits are changed. */ -#define enter_invert_mode 0x21 +#define enter_invert_mode 0x21 /* * This command causes the display module to invert the image data only on * the display device. The frame memory contents remain unchanged. * No status bits are changed. */ -#define set_gamma_curve 0x26 +#define set_gamma_curve 0x26 /* * This command selects the desired gamma curve for the display device. * Four fixed gamma curves are defined in section DCS spec. */ -#define set_display_off 0x28 +#define set_display_off 0x28 /* ************************************************************************* *\ This command causes the display module to stop displaying the image data on the display device. The frame memory contents remain unchanged. No status bits are changed. \* ************************************************************************* */ -#define set_display_on 0x29 +#define set_display_on 0x29 /* ************************************************************************* *\ This command causes the display module to start displaying the image data on the display device. The frame memory contents remain unchanged. No status bits are changed. \* ************************************************************************* */ -#define set_column_address 0x2a +#define set_column_address 0x2a /* * This command defines the column extent of the frame memory accessed by * the hostprocessor with the read_memory_continue and * write_memory_continue commands. * No status bits are changed. */ -#define set_page_addr 0x2b +#define set_page_addr 0x2b /* * This command defines the page extent of the frame memory accessed by * the host processor with the write_memory_continue and - * read_memory_continue command. + * read_memory_continue command. * No status bits are changed. */ -#define write_mem_start 0x2c +#define write_mem_start 0x2c /* * This command transfers image data from the host processor to the - * display module s frame memory starting at the pixel location specified + * display modules frame memory starting at the pixel location specified * by preceding set_column_address and set_page_address commands. */ -#define set_partial_area 0x30 +#define set_partial_area 0x30 /* * This command defines the Partial Display mode s display area. * There are two parameters associated with this command, the first * defines the Start Row (SR) and the second the End Row (ER). SR and ER * refer to the Frame Memory Line Pointer. */ -#define set_scroll_area 0x33 +#define set_scroll_area 0x33 /* * This command defines the display modules Vertical Scrolling Area. */ -#define set_tear_off 0x34 +#define set_tear_off 0x34 /* * This command turns off the display modules Tearing Effect output * signal on the TE signal line. */ -#define set_tear_on 0x35 +#define set_tear_on 0x35 /* * This command turns on the display modules Tearing Effect output signal * on the TE signal line. */ -#define set_address_mode 0x36 +#define set_address_mode 0x36 /* * This command sets the data order for transfers from the host processor * to display modules frame memory,bits B[7:5] and B3, and from the * display modules frame memory to the display device, bits B[2:0] and B4. */ -#define set_scroll_start 0x37 +#define set_scroll_start 0x37 /* * This command sets the start of the vertical scrolling area in the frame * memory. The vertical scrolling area is fully defined when this command @@ -1007,18 +1027,18 @@ No status bits are changed. * line in the frame memory that is written to the display device as the * first line of the vertical scroll area. */ -#define exit_idle_mode 0x38 +#define exit_idle_mode 0x38 /* * This command causes the display module to exit Idle mode. */ -#define enter_idle_mode 0x39 +#define enter_idle_mode 0x39 /* * This command causes the display module to enter Idle Mode. * In Idle Mode, color expression is reduced. Colors are shown on the * display device using the MSB of each of the R, G and B color * components in the frame memory */ -#define set_pixel_format 0x3a +#define set_pixel_format 0x3a /* * This command sets the pixel format for the RGB image data used by the * interface. @@ -1026,25 +1046,27 @@ No status bits are changed. * Bits D[2:0] DBI Pixel Format Definition * Bits D7 and D3 are not used. */ - #define DCS_PIXEL_FORMAT_3bbp 0x1 - #define DCS_PIXEL_FORMAT_8bbp 0x2 - #define DCS_PIXEL_FORMAT_12bbp 0x3 - #define DCS_PIXEL_FORMAT_16bbp 0x5 - #define DCS_PIXEL_FORMAT_18bbp 0x6 - #define DCS_PIXEL_FORMAT_24bbp 0x7 -#define write_mem_cont 0x3c +#define DCS_PIXEL_FORMAT_3bpp 0x1 +#define DCS_PIXEL_FORMAT_8bpp 0x2 +#define DCS_PIXEL_FORMAT_12bpp 0x3 +#define DCS_PIXEL_FORMAT_16bpp 0x5 +#define DCS_PIXEL_FORMAT_18bpp 0x6 +#define DCS_PIXEL_FORMAT_24bpp 0x7 + +#define write_mem_cont 0x3c + /* * This command transfers image data from the host processor to the * display module's frame memory continuing from the pixel location * following the previous write_memory_continue or write_memory_start * command. */ -#define set_tear_scanline 0x44 +#define set_tear_scanline 0x44 /* * This command turns on the display modules Tearing Effect output signal * on the TE signal line when the display module reaches line N. */ -#define get_scanline 0x45 +#define get_scanline 0x45 /* * The display module returns the current scanline, N, used to update the * display device. The total number of scanlines on a display device is @@ -1094,22 +1116,22 @@ No status bits are changed. #define GAMMA_AUTO (1 << 0) /* DCS Interface Pixel Formats */ -#define DCS_PIXEL_FORMAT_3BPP 0x1 -#define DCS_PIXEL_FORMAT_8BPP 0x2 -#define DCS_PIXEL_FORMAT_12BPP 0x3 -#define DCS_PIXEL_FORMAT_16BPP 0x5 -#define DCS_PIXEL_FORMAT_18BPP 0x6 -#define DCS_PIXEL_FORMAT_24BPP 0x7 +#define DCS_PIXEL_FORMAT_3BPP 0x1 +#define DCS_PIXEL_FORMAT_8BPP 0x2 +#define DCS_PIXEL_FORMAT_12BPP 0x3 +#define DCS_PIXEL_FORMAT_16BPP 0x5 +#define DCS_PIXEL_FORMAT_18BPP 0x6 +#define DCS_PIXEL_FORMAT_24BPP 0x7 /* ONE PARAMETER READ DATA */ -#define addr_mode_data 0xfc -#define diag_res_data 0x00 -#define disp_mode_data 0x23 -#define pxl_fmt_data 0x77 -#define pwr_mode_data 0x74 -#define sig_mode_data 0x00 +#define addr_mode_data 0xfc +#define diag_res_data 0x00 +#define disp_mode_data 0x23 +#define pxl_fmt_data 0x77 +#define pwr_mode_data 0x74 +#define sig_mode_data 0x00 /* TWO PARAMETERS READ DATA */ -#define scanline_data1 0xff -#define scanline_data2 0xff +#define scanline_data1 0xff +#define scanline_data2 0xff #define NON_BURST_MODE_SYNC_PULSE 0x01 /* Non Burst Mode * with Sync Pulse */ @@ -1117,7 +1139,8 @@ No status bits are changed. * with Sync events */ #define BURST_MODE 0x03 /* Burst Mode */ -#define DBI_COMMAND_BUFFER_SIZE 0x240 /* 0x32 */ /* 0x120 */ /* Allocate at least +#define DBI_COMMAND_BUFFER_SIZE 0x240 /* 0x32 */ /* 0x120 */ + /* Allocate at least * 0x100 Byte with 32 * byte alignment */ @@ -1125,13 +1148,88 @@ No status bits are changed. * 0x100 Byte with 32 * byte alignment */ -#define DBI_CB_TIME_OUT 0xFFFF +#define DBI_CB_TIME_OUT 0xFFFF + +#define GEN_FB_TIME_OUT 2000 + +#define SKU_83 0x01 +#define SKU_100 0x02 +#define SKU_100L 0x04 +#define SKU_BYPASS 0x08 + +/* Some handy macros for playing with bitfields. */ +#define PSB_MASK(high, low) (((1<<((high)-(low)+1))-1)<<(low)) +#define SET_FIELD(value, field) (((value) << field ## _SHIFT) & field ## _MASK) +#define GET_FIELD(word, field) (((word) & field ## _MASK) >> field ## _SHIFT) + +#define _PIPE(pipe, a, b) ((a) + (pipe)*((b)-(a))) + +/* PCI config space */ + +#define SB_PCKT 0x02100 /* cedarview */ +# define SB_OPCODE_MASK PSB_MASK(31, 16) +# define SB_OPCODE_SHIFT 16 +# define SB_OPCODE_READ 0 +# define SB_OPCODE_WRITE 1 +# define SB_DEST_MASK PSB_MASK(15, 8) +# define SB_DEST_SHIFT 8 +# define SB_DEST_DPLL 0x88 +# define SB_BYTE_ENABLE_MASK PSB_MASK(7, 4) +# define SB_BYTE_ENABLE_SHIFT 4 +# define SB_BUSY (1 << 0) + + +/* 32-bit value read/written from the DPIO reg. */ +#define SB_DATA 0x02104 /* cedarview */ +/* 32-bit address of the DPIO reg to be read/written. */ +#define SB_ADDR 0x02108 /* cedarview */ +#define DPIO_CFG 0x02110 /* cedarview */ +# define DPIO_MODE_SELECT_1 (1 << 3) +# define DPIO_MODE_SELECT_0 (1 << 2) +# define DPIO_SFR_BYPASS (1 << 1) +/* reset is active low */ +# define DPIO_CMN_RESET_N (1 << 0) + +/* Cedarview sideband registers */ +#define _SB_M_A 0x8008 +#define _SB_M_B 0x8028 +#define SB_M(pipe) _PIPE(pipe, _SB_M_A, _SB_M_B) +# define SB_M_DIVIDER_MASK (0xFF << 24) +# define SB_M_DIVIDER_SHIFT 24 + +#define _SB_N_VCO_A 0x8014 +#define _SB_N_VCO_B 0x8034 +#define SB_N_VCO(pipe) _PIPE(pipe, _SB_N_VCO_A, _SB_N_VCO_B) +#define SB_N_VCO_SEL_MASK PSB_MASK(31, 30) +#define SB_N_VCO_SEL_SHIFT 30 +#define SB_N_DIVIDER_MASK PSB_MASK(29, 26) +#define SB_N_DIVIDER_SHIFT 26 +#define SB_N_CB_TUNE_MASK PSB_MASK(25, 24) +#define SB_N_CB_TUNE_SHIFT 24 + +#define _SB_REF_A 0x8018 +#define _SB_REF_B 0x8038 +#define SB_REF_SFR(pipe) _PIPE(pipe, _SB_REF_A, _SB_REF_B) + +#define _SB_P_A 0x801c +#define _SB_P_B 0x803c +#define SB_P(pipe) _PIPE(pipe, _SB_P_A, _SB_P_B) +#define SB_P2_DIVIDER_MASK PSB_MASK(31, 30) +#define SB_P2_DIVIDER_SHIFT 30 +#define SB_P2_10 0 /* HDMI, DP, DAC */ +#define SB_P2_5 1 /* DAC */ +#define SB_P2_14 2 /* LVDS single */ +#define SB_P2_7 3 /* LVDS double */ +#define SB_P1_DIVIDER_MASK PSB_MASK(15, 12) +#define SB_P1_DIVIDER_SHIFT 12 + +#define PSB_LANE0 0x120 +#define PSB_LANE1 0x220 +#define PSB_LANE2 0x2320 +#define PSB_LANE3 0x2420 + +#define LANE_PLL_MASK (0x7 << 20) +#define LANE_PLL_ENABLE (0x3 << 20) -#define GEN_FB_TIME_OUT 2000 -#define ALIGNMENT_32BYTE_MASK (~((1 << 0)|(1 << 1)|(1 << 2)|(1 << 3)|(1 << 4))) -#define SKU_83 0x01 -#define SKU_100 0x02 -#define SKU_100L 0x04 -#define SKU_BYPASS 0x08 #endif diff --git a/drivers/staging/gma500/psb_intel_sdvo.c b/drivers/staging/gma500/psb_intel_sdvo.c index df1c006ecfaa..a4bad1af4b7c 100644 --- a/drivers/staging/gma500/psb_intel_sdvo.c +++ b/drivers/staging/gma500/psb_intel_sdvo.c @@ -107,14 +107,10 @@ static bool psb_intel_sdvo_read_byte( ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2); if (ret == 2) { - /* DRM_DEBUG("got back from addr %02X = %02x\n", - * out_buf[0], buf[0]); - */ *ch = buf[0]; return true; } - DRM_DEBUG("i2c transfer returned %d\n", ret); return false; } @@ -205,24 +201,25 @@ static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output, int i; if (0) { - DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd); + printk(KERN_DEBUG "%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd); for (i = 0; i < args_len; i++) - printk(KERN_INFO"%02X ", ((u8 *) args)[i]); + printk(KERN_CONT "%02X ", ((u8 *) args)[i]); for (; i < 8; i++) - printk(" "); + printk(KERN_CONT " "); for (i = 0; i < sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); i++) { if (cmd == sdvo_cmd_names[i].cmd) { - printk("(%s)", sdvo_cmd_names[i].name); + printk(KERN_CONT + "(%s)", sdvo_cmd_names[i].name); break; } } if (i == sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0])) - printk("(%02X)", cmd); - printk("\n"); + printk(KERN_CONT "(%02X)", cmd); + printk(KERN_CONT "\n"); } for (i = 0; i < args_len; i++) { @@ -267,17 +264,17 @@ static u8 psb_intel_sdvo_read_response( &status); if (0) { - DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv)); + pr_debug("%s: R: ", SDVO_NAME(sdvo_priv)); for (i = 0; i < response_len; i++) - printk(KERN_INFO"%02X ", ((u8 *) response)[i]); + printk(KERN_CONT "%02X ", ((u8 *) response)[i]); for (; i < 8; i++) printk(" "); if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) - printk(KERN_INFO"(%s)", + printk(KERN_CONT "(%s)", cmd_status_names[status]); else - printk(KERN_INFO"(??? %d)", status); - printk("\n"); + printk(KERN_CONT "(??? %d)", status); + printk(KERN_CONT "\n"); } if (status != SDVO_CMD_STATUS_PENDING) @@ -997,7 +994,6 @@ int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector) u8 response[2]; u8 status; struct psb_intel_output *psb_intel_output; - DRM_DEBUG("\n"); if (!connector) return 0; @@ -1198,7 +1194,7 @@ void psb_intel_sdvo_init(struct drm_device *dev, int output_device) /* Read the regs to test if we can talk to the device */ for (i = 0; i < 0x40; i++) { if (!psb_intel_sdvo_read_byte(psb_intel_output, i, &ch[i])) { - DRM_DEBUG("No SDVO device found on SDVO%c\n", + dev_dbg(dev->dev, "No SDVO device found on SDVO%c\n", output_device == SDVOB ? 'B' : 'C'); goto err_i2c; } @@ -1242,8 +1238,7 @@ void psb_intel_sdvo_init(struct drm_device *dev, int output_device) unsigned char bytes[2]; memcpy(bytes, &sdvo_priv->caps.output_flags, 2); - DRM_DEBUG - ("%s: No active RGB or TMDS outputs (0x%02x%02x)\n", + dev_dbg(dev->dev, "%s: No active RGB or TMDS outputs (0x%02x%02x)\n", SDVO_NAME(sdvo_priv), bytes[0], bytes[1]); goto err_i2c; } @@ -1267,7 +1262,7 @@ void psb_intel_sdvo_init(struct drm_device *dev, int output_device) pixel_clock_max); - DRM_DEBUG("%s device VID/DID: %02X:%02X.%02X, " + dev_dbg(dev->dev, "%s device VID/DID: %02X:%02X.%02X, " "clock range %dMHz - %dMHz, " "input 1: %c, input 2: %c, " "output 1: %c, output 2: %c\n", diff --git a/drivers/staging/gma500/psb_intel_sdvo_regs.h b/drivers/staging/gma500/psb_intel_sdvo_regs.h index c7107a37e33d..96862ea65aba 100644 --- a/drivers/staging/gma500/psb_intel_sdvo_regs.h +++ b/drivers/staging/gma500/psb_intel_sdvo_regs.h @@ -51,7 +51,7 @@ struct psb_intel_sdvo_caps { unsigned int stall_support:1; unsigned int pad:1; u16 output_flags; -} __attribute__ ((packed)); +} __packed; /** This matches the EDID DTD structure, more or less */ struct psb_intel_sdvo_dtd { @@ -82,18 +82,18 @@ struct psb_intel_sdvo_dtd { u8 v_sync_off_high; u8 reserved; } part2; -} __attribute__ ((packed)); +} __packed; struct psb_intel_sdvo_pixel_clock_range { u16 min; /**< pixel clock, in 10kHz units */ u16 max; /**< pixel clock, in 10kHz units */ -} __attribute__ ((packed)); +} __packed; struct psb_intel_sdvo_preferred_input_timing_args { u16 clock; u16 width; u16 height; -} __attribute__ ((packed)); +} __packed; /* I2C registers for SDVO */ #define SDVO_I2C_ARG_0 0x07 @@ -147,7 +147,7 @@ struct psb_intel_sdvo_get_trained_inputs_response { unsigned int input0_trained:1; unsigned int input1_trained:1; unsigned int pad:6; -} __attribute__ ((packed)); +} __packed; /** Returns a struct psb_intel_sdvo_output_flags of active outputs. */ #define SDVO_CMD_GET_ACTIVE_OUTPUTS 0x04 @@ -201,7 +201,7 @@ struct psb_intel_sdvo_get_interrupt_event_source_response { u16 interrupt_status; unsigned int ambient_light_interrupt:1; unsigned int pad:7; -} __attribute__ ((packed)); +} __packed; /** * Selects which input is affected by future input commands. @@ -214,7 +214,7 @@ struct psb_intel_sdvo_get_interrupt_event_source_response { struct psb_intel_sdvo_set_target_input_args { unsigned int target_1:1; unsigned int pad:7; -} __attribute__ ((packed)); +} __packed; /** * Takes a struct psb_intel_sdvo_output_flags of which outputs are targeted by diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c index 9ea37e588874..4a0fa42893f9 100644 --- a/drivers/staging/gma500/psb_irq.c +++ b/drivers/staging/gma500/psb_irq.c @@ -26,8 +26,8 @@ #include "psb_drv.h" #include "psb_reg.h" #include "psb_intel_reg.h" -#include "psb_powermgmt.h" - +#include "power.h" +#include "mdfld_output.h" /* * inline functions @@ -187,7 +187,8 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) } if (i == WAIT_STATUS_CLEAR_LOOP_COUNT) - DRM_ERROR("%s, can't clear the status bits in pipe_stat_reg, its value = 0x%x.\n", + dev_err(dev->dev, + "%s, can't clear the status bits in pipe_stat_reg, its value = 0x%x.\n", __func__, PSB_RVDC32(pipe_stat_reg)); if (pipe_stat_val & PIPE_VBLANK_STATUS) @@ -219,21 +220,11 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R); - if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG) { - PSB_DEBUG_IRQ("Got DISP interrupt\n"); + if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG) dsp_int = 1; - } - if (vdc_stat & _PSB_IRQ_SGX_FLAG) { - PSB_DEBUG_IRQ("Got SGX interrupt\n"); + if (vdc_stat & _PSB_IRQ_SGX_FLAG) sgx_int = 1; - } - if (vdc_stat & _PSB_IRQ_MSVDX_FLAG) - PSB_DEBUG_IRQ("Got MSVDX interrupt\n"); - - if (vdc_stat & _LNC_IRQ_TOPAZ_FLAG) - PSB_DEBUG_IRQ("Got TOPAZ interrupt\n"); - vdc_stat &= dev_priv->vdc_irq_mask; spin_unlock(&dev_priv->irqmask_lock); @@ -293,8 +284,6 @@ int psb_irq_postinstall(struct drm_device *dev) (struct drm_psb_private *) dev->dev_private; unsigned long irqflags; - PSB_DEBUG_ENTRY("\n"); - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); /* This register is safe even if display island is off */ @@ -326,8 +315,6 @@ void psb_irq_uninstall(struct drm_device *dev) (struct drm_psb_private *) dev->dev_private; unsigned long irqflags; - PSB_DEBUG_ENTRY("\n"); - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); @@ -395,8 +382,6 @@ int psb_irq_enable_dpst(struct drm_device *dev) (struct drm_psb_private *) dev->dev_private; unsigned long irqflags; - PSB_DEBUG_ENTRY("\n"); - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); /* enable DPST */ @@ -435,8 +420,6 @@ int psb_irq_disable_dpst(struct drm_device *dev) (struct drm_psb_private *) dev->dev_private; unsigned long irqflags; - PSB_DEBUG_ENTRY("\n"); - spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); mid_disable_pipe_event(dev_priv, 0); @@ -472,8 +455,12 @@ int psb_enable_vblank(struct drm_device *dev, int pipe) uint32_t reg_val = 0; uint32_t pipeconf_reg = mid_pipeconf(pipe); - PSB_DEBUG_ENTRY("\n"); - +#if defined(CONFIG_DRM_PSB_MFLD) + /* Medfield is different - we should perhaps extract out vblank + and blacklight etc ops */ + if (IS_MFLD(dev) && !mdfld_panel_dpi(dev)) + return mdfld_enable_te(dev, pipe); +#endif if (gma_power_begin(dev, false)) { reg_val = REG_READ(pipeconf_reg); gma_power_end(dev); @@ -500,8 +487,10 @@ void psb_disable_vblank(struct drm_device *dev, int pipe) struct drm_psb_private *dev_priv = dev->dev_private; unsigned long irqflags; - PSB_DEBUG_ENTRY("\n"); - +#if defined(CONFIG_DRM_PSB_MFLD) + if (IS_MFLD(dev) && !mdfld_panel_dpi(dev)) + mdfld_disable_te(dev, pipe); +#endif spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); mid_disable_pipe_event(dev_priv, pipe); @@ -510,6 +499,58 @@ void psb_disable_vblank(struct drm_device *dev, int pipe) spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); } +/** + * mdfld_enable_te - enable TE events + * @dev: our DRM device + * @pipe: which pipe to work on + * + * Enable TE events on a Medfield display pipe. Medfield specific. + */ +int mdfld_enable_te(struct drm_device *dev, int pipe) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + unsigned long flags; + uint32_t reg_val = 0; + uint32_t pipeconf_reg = mid_pipeconf(pipe); + + if (gma_power_begin(dev, false)) { + reg_val = REG_READ(pipeconf_reg); + gma_power_end(dev); + } + + if (!(reg_val & PIPEACONF_ENABLE)) + return -EINVAL; + + spin_lock_irqsave(&dev_priv->irqmask_lock, flags); + + mid_enable_pipe_event(dev_priv, pipe); + psb_enable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE); + + spin_unlock_irqrestore(&dev_priv->irqmask_lock, flags); + + return 0; +} + +/** + * mdfld_disable_te - disable TE events + * @dev: our DRM device + * @pipe: which pipe to work on + * + * Disable TE events on a Medfield display pipe. Medfield specific. + */ +void mdfld_disable_te(struct drm_device *dev, int pipe) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + unsigned long flags; + + spin_lock_irqsave(&dev_priv->irqmask_lock, flags); + + mid_disable_pipe_event(dev_priv, pipe); + psb_disable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE); + + spin_unlock_irqrestore(&dev_priv->irqmask_lock, flags); +} + /* Called from drm generic code, passed a 'crtc', which * we use as a pipe index */ @@ -535,7 +576,7 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe) pipeconf_reg = PIPECCONF; break; default: - DRM_ERROR("%s, invalded pipe.\n", __func__); + dev_err(dev->dev, "%s, invalid pipe.\n", __func__); return 0; } @@ -545,7 +586,7 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe) reg_val = REG_READ(pipeconf_reg); if (!(reg_val & PIPEACONF_ENABLE)) { - DRM_ERROR("trying to get vblank count for disabled pipe %d\n", + dev_err(dev->dev, "trying to get vblank count for disabled pipe %d\n", pipe); goto psb_get_vblank_counter_exit; } diff --git a/drivers/staging/gma500/psb_irq.h b/drivers/staging/gma500/psb_irq.h index 3e56f33efa6b..216fda38b57d 100644 --- a/drivers/staging/gma500/psb_irq.h +++ b/drivers/staging/gma500/psb_irq.h @@ -1,5 +1,5 @@ /************************************************************************** - * Copyright (c) 2009, Intel Corporation. + * Copyright (c) 2009-2011, Intel Corporation. * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it @@ -34,10 +34,6 @@ int psb_irq_postinstall(struct drm_device *dev); void psb_irq_uninstall(struct drm_device *dev); irqreturn_t psb_irq_handler(DRM_IRQ_ARGS); -void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands); -int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands); -void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands); - int psb_irq_enable_dpst(struct drm_device *dev); int psb_irq_disable_dpst(struct drm_device *dev); void psb_irq_turn_on_dpst(struct drm_device *dev); @@ -46,4 +42,4 @@ int psb_enable_vblank(struct drm_device *dev, int pipe); void psb_disable_vblank(struct drm_device *dev, int pipe); u32 psb_get_vblank_counter(struct drm_device *dev, int pipe); -#endif //_SYSIRQ_H_ +#endif /* _SYSIRQ_H_ */ diff --git a/drivers/staging/gma500/psb_lid.c b/drivers/staging/gma500/psb_lid.c index 21fd202f2931..af328516561e 100644 --- a/drivers/staging/gma500/psb_lid.c +++ b/drivers/staging/gma500/psb_lid.c @@ -32,10 +32,10 @@ static void psb_lid_timer_func(unsigned long data) u32 *lid_state = dev_priv->lid_state; u32 pp_status; - if (*lid_state == dev_priv->lid_last_state) + if (readl(lid_state) == dev_priv->lid_last_state) goto lid_timer_schedule; - if ((*lid_state) & 0x01) { + if ((readl(lid_state)) & 0x01) { /*lid state is open*/ REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON); do { @@ -54,7 +54,7 @@ static void psb_lid_timer_func(unsigned long data) } /* printk(KERN_INFO"%s: lid: closed\n", __FUNCTION__); */ - dev_priv->lid_last_state = *lid_state; + dev_priv->lid_last_state = readl(lid_state); lid_timer_schedule: spin_lock_irqsave(&dev_priv->lid_lock, irq_flags); diff --git a/drivers/staging/gma500/psb_reg.h b/drivers/staging/gma500/psb_reg.h index 9ad49892070e..b81c7c1e9c2d 100644 --- a/drivers/staging/gma500/psb_reg.h +++ b/drivers/staging/gma500/psb_reg.h @@ -22,161 +22,157 @@ #ifndef _PSB_REG_H_ #define _PSB_REG_H_ -#define PSB_CR_CLKGATECTL 0x0000 -#define _PSB_C_CLKGATECTL_AUTO_MAN_REG (1 << 24) -#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT (20) -#define _PSB_C_CLKGATECTL_USE_CLKG_MASK (0x3 << 20) -#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT (16) -#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK (0x3 << 16) -#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT (12) -#define _PSB_C_CLKGATECTL_TA_CLKG_MASK (0x3 << 12) -#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT (8) -#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK (0x3 << 8) -#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT (4) -#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK (0x3 << 4) -#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT (0) -#define _PSB_C_CLKGATECTL_2D_CLKG_MASK (0x3 << 0) -#define _PSB_C_CLKGATECTL_CLKG_ENABLED (0) -#define _PSB_C_CLKGATECTL_CLKG_DISABLED (1) -#define _PSB_C_CLKGATECTL_CLKG_AUTO (2) +#define PSB_CR_CLKGATECTL 0x0000 +#define _PSB_C_CLKGATECTL_AUTO_MAN_REG (1 << 24) +#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT (20) +#define _PSB_C_CLKGATECTL_USE_CLKG_MASK (0x3 << 20) +#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT (16) +#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK (0x3 << 16) +#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT (12) +#define _PSB_C_CLKGATECTL_TA_CLKG_MASK (0x3 << 12) +#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT (8) +#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK (0x3 << 8) +#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT (4) +#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK (0x3 << 4) +#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT (0) +#define _PSB_C_CLKGATECTL_2D_CLKG_MASK (0x3 << 0) +#define _PSB_C_CLKGATECTL_CLKG_ENABLED (0) +#define _PSB_C_CLKGATECTL_CLKG_DISABLED (1) +#define _PSB_C_CLKGATECTL_CLKG_AUTO (2) -#define PSB_CR_CORE_ID 0x0010 -#define _PSB_CC_ID_ID_SHIFT (16) -#define _PSB_CC_ID_ID_MASK (0xFFFF << 16) -#define _PSB_CC_ID_CONFIG_SHIFT (0) -#define _PSB_CC_ID_CONFIG_MASK (0xFFFF << 0) +#define PSB_CR_CORE_ID 0x0010 +#define _PSB_CC_ID_ID_SHIFT (16) +#define _PSB_CC_ID_ID_MASK (0xFFFF << 16) +#define _PSB_CC_ID_CONFIG_SHIFT (0) +#define _PSB_CC_ID_CONFIG_MASK (0xFFFF << 0) -#define PSB_CR_CORE_REVISION 0x0014 -#define _PSB_CC_REVISION_DESIGNER_SHIFT (24) -#define _PSB_CC_REVISION_DESIGNER_MASK (0xFF << 24) -#define _PSB_CC_REVISION_MAJOR_SHIFT (16) -#define _PSB_CC_REVISION_MAJOR_MASK (0xFF << 16) -#define _PSB_CC_REVISION_MINOR_SHIFT (8) -#define _PSB_CC_REVISION_MINOR_MASK (0xFF << 8) -#define _PSB_CC_REVISION_MAINTENANCE_SHIFT (0) -#define _PSB_CC_REVISION_MAINTENANCE_MASK (0xFF << 0) +#define PSB_CR_CORE_REVISION 0x0014 +#define _PSB_CC_REVISION_DESIGNER_SHIFT (24) +#define _PSB_CC_REVISION_DESIGNER_MASK (0xFF << 24) +#define _PSB_CC_REVISION_MAJOR_SHIFT (16) +#define _PSB_CC_REVISION_MAJOR_MASK (0xFF << 16) +#define _PSB_CC_REVISION_MINOR_SHIFT (8) +#define _PSB_CC_REVISION_MINOR_MASK (0xFF << 8) +#define _PSB_CC_REVISION_MAINTENANCE_SHIFT (0) +#define _PSB_CC_REVISION_MAINTENANCE_MASK (0xFF << 0) -#define PSB_CR_DESIGNER_REV_FIELD1 0x0018 +#define PSB_CR_DESIGNER_REV_FIELD1 0x0018 -#define PSB_CR_SOFT_RESET 0x0080 -#define _PSB_CS_RESET_TSP_RESET (1 << 6) -#define _PSB_CS_RESET_ISP_RESET (1 << 5) -#define _PSB_CS_RESET_USE_RESET (1 << 4) -#define _PSB_CS_RESET_TA_RESET (1 << 3) -#define _PSB_CS_RESET_DPM_RESET (1 << 2) -#define _PSB_CS_RESET_TWOD_RESET (1 << 1) -#define _PSB_CS_RESET_BIF_RESET (1 << 0) +#define PSB_CR_SOFT_RESET 0x0080 +#define _PSB_CS_RESET_TSP_RESET (1 << 6) +#define _PSB_CS_RESET_ISP_RESET (1 << 5) +#define _PSB_CS_RESET_USE_RESET (1 << 4) +#define _PSB_CS_RESET_TA_RESET (1 << 3) +#define _PSB_CS_RESET_DPM_RESET (1 << 2) +#define _PSB_CS_RESET_TWOD_RESET (1 << 1) +#define _PSB_CS_RESET_BIF_RESET (1 << 0) -#define PSB_CR_DESIGNER_REV_FIELD2 0x001C +#define PSB_CR_DESIGNER_REV_FIELD2 0x001C -#define PSB_CR_EVENT_HOST_ENABLE2 0x0110 +#define PSB_CR_EVENT_HOST_ENABLE2 0x0110 -#define PSB_CR_EVENT_STATUS2 0x0118 +#define PSB_CR_EVENT_STATUS2 0x0118 -#define PSB_CR_EVENT_HOST_CLEAR2 0x0114 -#define _PSB_CE2_BIF_REQUESTER_FAULT (1 << 4) +#define PSB_CR_EVENT_HOST_CLEAR2 0x0114 +#define _PSB_CE2_BIF_REQUESTER_FAULT (1 << 4) -#define PSB_CR_EVENT_STATUS 0x012C +#define PSB_CR_EVENT_STATUS 0x012C -#define PSB_CR_EVENT_HOST_ENABLE 0x0130 +#define PSB_CR_EVENT_HOST_ENABLE 0x0130 -#define PSB_CR_EVENT_HOST_CLEAR 0x0134 -#define _PSB_CE_MASTER_INTERRUPT (1 << 31) -#define _PSB_CE_TA_DPM_FAULT (1 << 28) -#define _PSB_CE_TWOD_COMPLETE (1 << 27) -#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS (1 << 25) -#define _PSB_CE_DPM_TA_MEM_FREE (1 << 24) -#define _PSB_CE_PIXELBE_END_RENDER (1 << 18) -#define _PSB_CE_SW_EVENT (1 << 14) -#define _PSB_CE_TA_FINISHED (1 << 13) -#define _PSB_CE_TA_TERMINATE (1 << 12) -#define _PSB_CE_DPM_REACHED_MEM_THRESH (1 << 3) -#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL (1 << 2) -#define _PSB_CE_DPM_OUT_OF_MEMORY_MT (1 << 1) -#define _PSB_CE_DPM_3D_MEM_FREE (1 << 0) +#define PSB_CR_EVENT_HOST_CLEAR 0x0134 +#define _PSB_CE_MASTER_INTERRUPT (1 << 31) +#define _PSB_CE_TA_DPM_FAULT (1 << 28) +#define _PSB_CE_TWOD_COMPLETE (1 << 27) +#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS (1 << 25) +#define _PSB_CE_DPM_TA_MEM_FREE (1 << 24) +#define _PSB_CE_PIXELBE_END_RENDER (1 << 18) +#define _PSB_CE_SW_EVENT (1 << 14) +#define _PSB_CE_TA_FINISHED (1 << 13) +#define _PSB_CE_TA_TERMINATE (1 << 12) +#define _PSB_CE_DPM_REACHED_MEM_THRESH (1 << 3) +#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL (1 << 2) +#define _PSB_CE_DPM_OUT_OF_MEMORY_MT (1 << 1) +#define _PSB_CE_DPM_3D_MEM_FREE (1 << 0) -#define PSB_USE_OFFSET_MASK 0x0007FFFF -#define PSB_USE_OFFSET_SIZE (PSB_USE_OFFSET_MASK + 1) -#define PSB_CR_USE_CODE_BASE0 0x0A0C -#define PSB_CR_USE_CODE_BASE1 0x0A10 -#define PSB_CR_USE_CODE_BASE2 0x0A14 -#define PSB_CR_USE_CODE_BASE3 0x0A18 -#define PSB_CR_USE_CODE_BASE4 0x0A1C -#define PSB_CR_USE_CODE_BASE5 0x0A20 -#define PSB_CR_USE_CODE_BASE6 0x0A24 -#define PSB_CR_USE_CODE_BASE7 0x0A28 -#define PSB_CR_USE_CODE_BASE8 0x0A2C -#define PSB_CR_USE_CODE_BASE9 0x0A30 -#define PSB_CR_USE_CODE_BASE10 0x0A34 -#define PSB_CR_USE_CODE_BASE11 0x0A38 -#define PSB_CR_USE_CODE_BASE12 0x0A3C -#define PSB_CR_USE_CODE_BASE13 0x0A40 -#define PSB_CR_USE_CODE_BASE14 0x0A44 -#define PSB_CR_USE_CODE_BASE15 0x0A48 -#define PSB_CR_USE_CODE_BASE(_i) (0x0A0C + ((_i) << 2)) -#define _PSB_CUC_BASE_DM_SHIFT (25) -#define _PSB_CUC_BASE_DM_MASK (0x3 << 25) -#define _PSB_CUC_BASE_ADDR_SHIFT (0) /* 1024-bit aligned address? */ -#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT (7) -#define _PSB_CUC_BASE_ADDR_MASK (0x1FFFFFF << 0) -#define _PSB_CUC_DM_VERTEX (0) -#define _PSB_CUC_DM_PIXEL (1) -#define _PSB_CUC_DM_RESERVED (2) -#define _PSB_CUC_DM_EDM (3) +#define PSB_USE_OFFSET_MASK 0x0007FFFF +#define PSB_USE_OFFSET_SIZE (PSB_USE_OFFSET_MASK + 1) +#define PSB_CR_USE_CODE_BASE0 0x0A0C +#define PSB_CR_USE_CODE_BASE1 0x0A10 +#define PSB_CR_USE_CODE_BASE2 0x0A14 +#define PSB_CR_USE_CODE_BASE3 0x0A18 +#define PSB_CR_USE_CODE_BASE4 0x0A1C +#define PSB_CR_USE_CODE_BASE5 0x0A20 +#define PSB_CR_USE_CODE_BASE6 0x0A24 +#define PSB_CR_USE_CODE_BASE7 0x0A28 +#define PSB_CR_USE_CODE_BASE8 0x0A2C +#define PSB_CR_USE_CODE_BASE9 0x0A30 +#define PSB_CR_USE_CODE_BASE10 0x0A34 +#define PSB_CR_USE_CODE_BASE11 0x0A38 +#define PSB_CR_USE_CODE_BASE12 0x0A3C +#define PSB_CR_USE_CODE_BASE13 0x0A40 +#define PSB_CR_USE_CODE_BASE14 0x0A44 +#define PSB_CR_USE_CODE_BASE15 0x0A48 +#define PSB_CR_USE_CODE_BASE(_i) (0x0A0C + ((_i) << 2)) +#define _PSB_CUC_BASE_DM_SHIFT (25) +#define _PSB_CUC_BASE_DM_MASK (0x3 << 25) +#define _PSB_CUC_BASE_ADDR_SHIFT (0) /* 1024-bit aligned address? */ +#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT (7) +#define _PSB_CUC_BASE_ADDR_MASK (0x1FFFFFF << 0) +#define _PSB_CUC_DM_VERTEX (0) +#define _PSB_CUC_DM_PIXEL (1) +#define _PSB_CUC_DM_RESERVED (2) +#define _PSB_CUC_DM_EDM (3) -#define PSB_CR_PDS_EXEC_BASE 0x0AB8 -#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT (20) /* 1MB aligned address */ -#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT (20) +#define PSB_CR_PDS_EXEC_BASE 0x0AB8 +#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT (20) /* 1MB aligned address */ +#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT (20) -#define PSB_CR_EVENT_KICKER 0x0AC4 -#define _PSB_CE_KICKER_ADDRESS_SHIFT (4) /* 128-bit aligned address */ +#define PSB_CR_EVENT_KICKER 0x0AC4 +#define _PSB_CE_KICKER_ADDRESS_SHIFT (4) /* 128-bit aligned address */ -#define PSB_CR_EVENT_KICK 0x0AC8 -#define _PSB_CE_KICK_NOW (1 << 0) +#define PSB_CR_EVENT_KICK 0x0AC8 +#define _PSB_CE_KICK_NOW (1 << 0) +#define PSB_CR_BIF_DIR_LIST_BASE1 0x0C38 -#define PSB_CR_BIF_DIR_LIST_BASE1 0x0C38 +#define PSB_CR_BIF_CTRL 0x0C00 +#define _PSB_CB_CTRL_CLEAR_FAULT (1 << 4) +#define _PSB_CB_CTRL_INVALDC (1 << 3) +#define _PSB_CB_CTRL_FLUSH (1 << 2) -#define PSB_CR_BIF_CTRL 0x0C00 -#define _PSB_CB_CTRL_CLEAR_FAULT (1 << 4) -#define _PSB_CB_CTRL_INVALDC (1 << 3) -#define _PSB_CB_CTRL_FLUSH (1 << 2) +#define PSB_CR_BIF_INT_STAT 0x0C04 -#define PSB_CR_BIF_INT_STAT 0x0C04 +#define PSB_CR_BIF_FAULT 0x0C08 +#define _PSB_CBI_STAT_PF_N_RW (1 << 14) +#define _PSB_CBI_STAT_FAULT_SHIFT (0) +#define _PSB_CBI_STAT_FAULT_MASK (0x3FFF << 0) +#define _PSB_CBI_STAT_FAULT_CACHE (1 << 1) +#define _PSB_CBI_STAT_FAULT_TA (1 << 2) +#define _PSB_CBI_STAT_FAULT_VDM (1 << 3) +#define _PSB_CBI_STAT_FAULT_2D (1 << 4) +#define _PSB_CBI_STAT_FAULT_PBE (1 << 5) +#define _PSB_CBI_STAT_FAULT_TSP (1 << 6) +#define _PSB_CBI_STAT_FAULT_ISP (1 << 7) +#define _PSB_CBI_STAT_FAULT_USSEPDS (1 << 8) +#define _PSB_CBI_STAT_FAULT_HOST (1 << 9) -#define PSB_CR_BIF_FAULT 0x0C08 -#define _PSB_CBI_STAT_PF_N_RW (1 << 14) -#define _PSB_CBI_STAT_FAULT_SHIFT (0) -#define _PSB_CBI_STAT_FAULT_MASK (0x3FFF << 0) -#define _PSB_CBI_STAT_FAULT_CACHE (1 << 1) -#define _PSB_CBI_STAT_FAULT_TA (1 << 2) -#define _PSB_CBI_STAT_FAULT_VDM (1 << 3) -#define _PSB_CBI_STAT_FAULT_2D (1 << 4) -#define _PSB_CBI_STAT_FAULT_PBE (1 << 5) -#define _PSB_CBI_STAT_FAULT_TSP (1 << 6) -#define _PSB_CBI_STAT_FAULT_ISP (1 << 7) -#define _PSB_CBI_STAT_FAULT_USSEPDS (1 << 8) -#define _PSB_CBI_STAT_FAULT_HOST (1 << 9) +#define PSB_CR_BIF_BANK0 0x0C78 +#define PSB_CR_BIF_BANK1 0x0C7C +#define PSB_CR_BIF_DIR_LIST_BASE0 0x0C84 +#define PSB_CR_BIF_TWOD_REQ_BASE 0x0C88 +#define PSB_CR_BIF_3D_REQ_BASE 0x0CAC -#define PSB_CR_BIF_BANK0 0x0C78 +#define PSB_CR_2D_SOCIF 0x0E18 +#define _PSB_C2_SOCIF_FREESPACE_SHIFT (0) +#define _PSB_C2_SOCIF_FREESPACE_MASK (0xFF << 0) +#define _PSB_C2_SOCIF_EMPTY (0x80 << 0) -#define PSB_CR_BIF_BANK1 0x0C7C - -#define PSB_CR_BIF_DIR_LIST_BASE0 0x0C84 - -#define PSB_CR_BIF_TWOD_REQ_BASE 0x0C88 -#define PSB_CR_BIF_3D_REQ_BASE 0x0CAC - -#define PSB_CR_2D_SOCIF 0x0E18 -#define _PSB_C2_SOCIF_FREESPACE_SHIFT (0) -#define _PSB_C2_SOCIF_FREESPACE_MASK (0xFF << 0) -#define _PSB_C2_SOCIF_EMPTY (0x80 << 0) - -#define PSB_CR_2D_BLIT_STATUS 0x0E04 -#define _PSB_C2B_STATUS_BUSY (1 << 24) -#define _PSB_C2B_STATUS_COMPLETE_SHIFT (0) -#define _PSB_C2B_STATUS_COMPLETE_MASK (0xFFFFFF << 0) +#define PSB_CR_2D_BLIT_STATUS 0x0E04 +#define _PSB_C2B_STATUS_BUSY (1 << 24) +#define _PSB_C2B_STATUS_COMPLETE_SHIFT (0) +#define _PSB_C2B_STATUS_COMPLETE_MASK (0xFFFFFF << 0) /* * 2D defs. @@ -186,121 +182,121 @@ * 2D Slave Port Data : Block Header's Object Type */ -#define PSB_2D_CLIP_BH (0x00000000) -#define PSB_2D_PAT_BH (0x10000000) -#define PSB_2D_CTRL_BH (0x20000000) -#define PSB_2D_SRC_OFF_BH (0x30000000) -#define PSB_2D_MASK_OFF_BH (0x40000000) -#define PSB_2D_RESERVED1_BH (0x50000000) -#define PSB_2D_RESERVED2_BH (0x60000000) -#define PSB_2D_FENCE_BH (0x70000000) -#define PSB_2D_BLIT_BH (0x80000000) -#define PSB_2D_SRC_SURF_BH (0x90000000) -#define PSB_2D_DST_SURF_BH (0xA0000000) -#define PSB_2D_PAT_SURF_BH (0xB0000000) -#define PSB_2D_SRC_PAL_BH (0xC0000000) -#define PSB_2D_PAT_PAL_BH (0xD0000000) -#define PSB_2D_MASK_SURF_BH (0xE0000000) -#define PSB_2D_FLUSH_BH (0xF0000000) +#define PSB_2D_CLIP_BH (0x00000000) +#define PSB_2D_PAT_BH (0x10000000) +#define PSB_2D_CTRL_BH (0x20000000) +#define PSB_2D_SRC_OFF_BH (0x30000000) +#define PSB_2D_MASK_OFF_BH (0x40000000) +#define PSB_2D_RESERVED1_BH (0x50000000) +#define PSB_2D_RESERVED2_BH (0x60000000) +#define PSB_2D_FENCE_BH (0x70000000) +#define PSB_2D_BLIT_BH (0x80000000) +#define PSB_2D_SRC_SURF_BH (0x90000000) +#define PSB_2D_DST_SURF_BH (0xA0000000) +#define PSB_2D_PAT_SURF_BH (0xB0000000) +#define PSB_2D_SRC_PAL_BH (0xC0000000) +#define PSB_2D_PAT_PAL_BH (0xD0000000) +#define PSB_2D_MASK_SURF_BH (0xE0000000) +#define PSB_2D_FLUSH_BH (0xF0000000) /* * Clip Definition block (PSB_2D_CLIP_BH) */ -#define PSB_2D_CLIPCOUNT_MAX (1) -#define PSB_2D_CLIPCOUNT_MASK (0x00000000) -#define PSB_2D_CLIPCOUNT_CLRMASK (0xFFFFFFFF) -#define PSB_2D_CLIPCOUNT_SHIFT (0) +#define PSB_2D_CLIPCOUNT_MAX (1) +#define PSB_2D_CLIPCOUNT_MASK (0x00000000) +#define PSB_2D_CLIPCOUNT_CLRMASK (0xFFFFFFFF) +#define PSB_2D_CLIPCOUNT_SHIFT (0) /* clip rectangle min & max */ -#define PSB_2D_CLIP_XMAX_MASK (0x00FFF000) -#define PSB_2D_CLIP_XMAX_CLRMASK (0xFF000FFF) -#define PSB_2D_CLIP_XMAX_SHIFT (12) -#define PSB_2D_CLIP_XMIN_MASK (0x00000FFF) -#define PSB_2D_CLIP_XMIN_CLRMASK (0x00FFF000) -#define PSB_2D_CLIP_XMIN_SHIFT (0) +#define PSB_2D_CLIP_XMAX_MASK (0x00FFF000) +#define PSB_2D_CLIP_XMAX_CLRMASK (0xFF000FFF) +#define PSB_2D_CLIP_XMAX_SHIFT (12) +#define PSB_2D_CLIP_XMIN_MASK (0x00000FFF) +#define PSB_2D_CLIP_XMIN_CLRMASK (0x00FFF000) +#define PSB_2D_CLIP_XMIN_SHIFT (0) /* clip rectangle offset */ -#define PSB_2D_CLIP_YMAX_MASK (0x00FFF000) -#define PSB_2D_CLIP_YMAX_CLRMASK (0xFF000FFF) -#define PSB_2D_CLIP_YMAX_SHIFT (12) -#define PSB_2D_CLIP_YMIN_MASK (0x00000FFF) -#define PSB_2D_CLIP_YMIN_CLRMASK (0x00FFF000) -#define PSB_2D_CLIP_YMIN_SHIFT (0) +#define PSB_2D_CLIP_YMAX_MASK (0x00FFF000) +#define PSB_2D_CLIP_YMAX_CLRMASK (0xFF000FFF) +#define PSB_2D_CLIP_YMAX_SHIFT (12) +#define PSB_2D_CLIP_YMIN_MASK (0x00000FFF) +#define PSB_2D_CLIP_YMIN_CLRMASK (0x00FFF000) +#define PSB_2D_CLIP_YMIN_SHIFT (0) /* * Pattern Control (PSB_2D_PAT_BH) */ -#define PSB_2D_PAT_HEIGHT_MASK (0x0000001F) -#define PSB_2D_PAT_HEIGHT_SHIFT (0) -#define PSB_2D_PAT_WIDTH_MASK (0x000003E0) -#define PSB_2D_PAT_WIDTH_SHIFT (5) -#define PSB_2D_PAT_YSTART_MASK (0x00007C00) -#define PSB_2D_PAT_YSTART_SHIFT (10) -#define PSB_2D_PAT_XSTART_MASK (0x000F8000) -#define PSB_2D_PAT_XSTART_SHIFT (15) +#define PSB_2D_PAT_HEIGHT_MASK (0x0000001F) +#define PSB_2D_PAT_HEIGHT_SHIFT (0) +#define PSB_2D_PAT_WIDTH_MASK (0x000003E0) +#define PSB_2D_PAT_WIDTH_SHIFT (5) +#define PSB_2D_PAT_YSTART_MASK (0x00007C00) +#define PSB_2D_PAT_YSTART_SHIFT (10) +#define PSB_2D_PAT_XSTART_MASK (0x000F8000) +#define PSB_2D_PAT_XSTART_SHIFT (15) /* * 2D Control block (PSB_2D_CTRL_BH) */ /* Present Flags */ -#define PSB_2D_SRCCK_CTRL (0x00000001) -#define PSB_2D_DSTCK_CTRL (0x00000002) -#define PSB_2D_ALPHA_CTRL (0x00000004) +#define PSB_2D_SRCCK_CTRL (0x00000001) +#define PSB_2D_DSTCK_CTRL (0x00000002) +#define PSB_2D_ALPHA_CTRL (0x00000004) /* Colour Key Colour (SRC/DST)*/ -#define PSB_2D_CK_COL_MASK (0xFFFFFFFF) -#define PSB_2D_CK_COL_CLRMASK (0x00000000) -#define PSB_2D_CK_COL_SHIFT (0) +#define PSB_2D_CK_COL_MASK (0xFFFFFFFF) +#define PSB_2D_CK_COL_CLRMASK (0x00000000) +#define PSB_2D_CK_COL_SHIFT (0) /* Colour Key Mask (SRC/DST)*/ -#define PSB_2D_CK_MASK_MASK (0xFFFFFFFF) -#define PSB_2D_CK_MASK_CLRMASK (0x00000000) -#define PSB_2D_CK_MASK_SHIFT (0) +#define PSB_2D_CK_MASK_MASK (0xFFFFFFFF) +#define PSB_2D_CK_MASK_CLRMASK (0x00000000) +#define PSB_2D_CK_MASK_SHIFT (0) /* Alpha Control (Alpha/RGB)*/ -#define PSB_2D_GBLALPHA_MASK (0x000FF000) -#define PSB_2D_GBLALPHA_CLRMASK (0xFFF00FFF) -#define PSB_2D_GBLALPHA_SHIFT (12) -#define PSB_2D_SRCALPHA_OP_MASK (0x00700000) -#define PSB_2D_SRCALPHA_OP_CLRMASK (0xFF8FFFFF) -#define PSB_2D_SRCALPHA_OP_SHIFT (20) -#define PSB_2D_SRCALPHA_OP_ONE (0x00000000) -#define PSB_2D_SRCALPHA_OP_SRC (0x00100000) -#define PSB_2D_SRCALPHA_OP_DST (0x00200000) -#define PSB_2D_SRCALPHA_OP_SG (0x00300000) -#define PSB_2D_SRCALPHA_OP_DG (0x00400000) -#define PSB_2D_SRCALPHA_OP_GBL (0x00500000) -#define PSB_2D_SRCALPHA_OP_ZERO (0x00600000) -#define PSB_2D_SRCALPHA_INVERT (0x00800000) -#define PSB_2D_SRCALPHA_INVERT_CLR (0xFF7FFFFF) -#define PSB_2D_DSTALPHA_OP_MASK (0x07000000) -#define PSB_2D_DSTALPHA_OP_CLRMASK (0xF8FFFFFF) -#define PSB_2D_DSTALPHA_OP_SHIFT (24) -#define PSB_2D_DSTALPHA_OP_ONE (0x00000000) -#define PSB_2D_DSTALPHA_OP_SRC (0x01000000) -#define PSB_2D_DSTALPHA_OP_DST (0x02000000) -#define PSB_2D_DSTALPHA_OP_SG (0x03000000) -#define PSB_2D_DSTALPHA_OP_DG (0x04000000) -#define PSB_2D_DSTALPHA_OP_GBL (0x05000000) -#define PSB_2D_DSTALPHA_OP_ZERO (0x06000000) -#define PSB_2D_DSTALPHA_INVERT (0x08000000) -#define PSB_2D_DSTALPHA_INVERT_CLR (0xF7FFFFFF) +#define PSB_2D_GBLALPHA_MASK (0x000FF000) +#define PSB_2D_GBLALPHA_CLRMASK (0xFFF00FFF) +#define PSB_2D_GBLALPHA_SHIFT (12) +#define PSB_2D_SRCALPHA_OP_MASK (0x00700000) +#define PSB_2D_SRCALPHA_OP_CLRMASK (0xFF8FFFFF) +#define PSB_2D_SRCALPHA_OP_SHIFT (20) +#define PSB_2D_SRCALPHA_OP_ONE (0x00000000) +#define PSB_2D_SRCALPHA_OP_SRC (0x00100000) +#define PSB_2D_SRCALPHA_OP_DST (0x00200000) +#define PSB_2D_SRCALPHA_OP_SG (0x00300000) +#define PSB_2D_SRCALPHA_OP_DG (0x00400000) +#define PSB_2D_SRCALPHA_OP_GBL (0x00500000) +#define PSB_2D_SRCALPHA_OP_ZERO (0x00600000) +#define PSB_2D_SRCALPHA_INVERT (0x00800000) +#define PSB_2D_SRCALPHA_INVERT_CLR (0xFF7FFFFF) +#define PSB_2D_DSTALPHA_OP_MASK (0x07000000) +#define PSB_2D_DSTALPHA_OP_CLRMASK (0xF8FFFFFF) +#define PSB_2D_DSTALPHA_OP_SHIFT (24) +#define PSB_2D_DSTALPHA_OP_ONE (0x00000000) +#define PSB_2D_DSTALPHA_OP_SRC (0x01000000) +#define PSB_2D_DSTALPHA_OP_DST (0x02000000) +#define PSB_2D_DSTALPHA_OP_SG (0x03000000) +#define PSB_2D_DSTALPHA_OP_DG (0x04000000) +#define PSB_2D_DSTALPHA_OP_GBL (0x05000000) +#define PSB_2D_DSTALPHA_OP_ZERO (0x06000000) +#define PSB_2D_DSTALPHA_INVERT (0x08000000) +#define PSB_2D_DSTALPHA_INVERT_CLR (0xF7FFFFFF) -#define PSB_2D_PRE_MULTIPLICATION_ENABLE (0x10000000) -#define PSB_2D_PRE_MULTIPLICATION_CLRMASK (0xEFFFFFFF) -#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE (0x20000000) -#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK (0xDFFFFFFF) +#define PSB_2D_PRE_MULTIPLICATION_ENABLE (0x10000000) +#define PSB_2D_PRE_MULTIPLICATION_CLRMASK (0xEFFFFFFF) +#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE (0x20000000) +#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK (0xDFFFFFFF) /* *Source Offset (PSB_2D_SRC_OFF_BH) */ -#define PSB_2D_SRCOFF_XSTART_MASK ((0x00000FFF) << 12) -#define PSB_2D_SRCOFF_XSTART_SHIFT (12) -#define PSB_2D_SRCOFF_YSTART_MASK (0x00000FFF) -#define PSB_2D_SRCOFF_YSTART_SHIFT (0) +#define PSB_2D_SRCOFF_XSTART_MASK ((0x00000FFF) << 12) +#define PSB_2D_SRCOFF_XSTART_SHIFT (12) +#define PSB_2D_SRCOFF_YSTART_MASK (0x00000FFF) +#define PSB_2D_SRCOFF_YSTART_SHIFT (0) /* * Mask Offset (PSB_2D_MASK_OFF_BH) */ -#define PSB_2D_MASKOFF_XSTART_MASK ((0x00000FFF) << 12) -#define PSB_2D_MASKOFF_XSTART_SHIFT (12) -#define PSB_2D_MASKOFF_YSTART_MASK (0x00000FFF) -#define PSB_2D_MASKOFF_YSTART_SHIFT (0) +#define PSB_2D_MASKOFF_XSTART_MASK ((0x00000FFF) << 12) +#define PSB_2D_MASKOFF_XSTART_SHIFT (12) +#define PSB_2D_MASKOFF_YSTART_MASK (0x00000FFF) +#define PSB_2D_MASKOFF_YSTART_SHIFT (0) /* * 2D Fence (see PSB_2D_FENCE_BH): bits 0:27 are ignored @@ -310,118 +306,118 @@ *Blit Rectangle (PSB_2D_BLIT_BH) */ -#define PSB_2D_ROT_MASK (3<<25) -#define PSB_2D_ROT_CLRMASK (~PSB_2D_ROT_MASK) -#define PSB_2D_ROT_NONE (0<<25) -#define PSB_2D_ROT_90DEGS (1<<25) -#define PSB_2D_ROT_180DEGS (2<<25) -#define PSB_2D_ROT_270DEGS (3<<25) +#define PSB_2D_ROT_MASK (3 << 25) +#define PSB_2D_ROT_CLRMASK (~PSB_2D_ROT_MASK) +#define PSB_2D_ROT_NONE (0 << 25) +#define PSB_2D_ROT_90DEGS (1 << 25) +#define PSB_2D_ROT_180DEGS (2 << 25) +#define PSB_2D_ROT_270DEGS (3 << 25) -#define PSB_2D_COPYORDER_MASK (3<<23) -#define PSB_2D_COPYORDER_CLRMASK (~PSB_2D_COPYORDER_MASK) -#define PSB_2D_COPYORDER_TL2BR (0<<23) -#define PSB_2D_COPYORDER_BR2TL (1<<23) -#define PSB_2D_COPYORDER_TR2BL (2<<23) -#define PSB_2D_COPYORDER_BL2TR (3<<23) +#define PSB_2D_COPYORDER_MASK (3 << 23) +#define PSB_2D_COPYORDER_CLRMASK (~PSB_2D_COPYORDER_MASK) +#define PSB_2D_COPYORDER_TL2BR (0 << 23) +#define PSB_2D_COPYORDER_BR2TL (1 << 23) +#define PSB_2D_COPYORDER_TR2BL (2 << 23) +#define PSB_2D_COPYORDER_BL2TR (3 << 23) -#define PSB_2D_DSTCK_CLRMASK (0xFF9FFFFF) -#define PSB_2D_DSTCK_DISABLE (0x00000000) -#define PSB_2D_DSTCK_PASS (0x00200000) -#define PSB_2D_DSTCK_REJECT (0x00400000) +#define PSB_2D_DSTCK_CLRMASK (0xFF9FFFFF) +#define PSB_2D_DSTCK_DISABLE (0x00000000) +#define PSB_2D_DSTCK_PASS (0x00200000) +#define PSB_2D_DSTCK_REJECT (0x00400000) -#define PSB_2D_SRCCK_CLRMASK (0xFFE7FFFF) -#define PSB_2D_SRCCK_DISABLE (0x00000000) -#define PSB_2D_SRCCK_PASS (0x00080000) -#define PSB_2D_SRCCK_REJECT (0x00100000) +#define PSB_2D_SRCCK_CLRMASK (0xFFE7FFFF) +#define PSB_2D_SRCCK_DISABLE (0x00000000) +#define PSB_2D_SRCCK_PASS (0x00080000) +#define PSB_2D_SRCCK_REJECT (0x00100000) -#define PSB_2D_CLIP_ENABLE (0x00040000) +#define PSB_2D_CLIP_ENABLE (0x00040000) -#define PSB_2D_ALPHA_ENABLE (0x00020000) +#define PSB_2D_ALPHA_ENABLE (0x00020000) -#define PSB_2D_PAT_CLRMASK (0xFFFEFFFF) -#define PSB_2D_PAT_MASK (0x00010000) -#define PSB_2D_USE_PAT (0x00010000) -#define PSB_2D_USE_FILL (0x00000000) +#define PSB_2D_PAT_CLRMASK (0xFFFEFFFF) +#define PSB_2D_PAT_MASK (0x00010000) +#define PSB_2D_USE_PAT (0x00010000) +#define PSB_2D_USE_FILL (0x00000000) /* * Tungsten Graphics note on rop codes: If rop A and rop B are * identical, the mask surface will not be read and need not be * set up. */ -#define PSB_2D_ROP3B_MASK (0x0000FF00) -#define PSB_2D_ROP3B_CLRMASK (0xFFFF00FF) -#define PSB_2D_ROP3B_SHIFT (8) +#define PSB_2D_ROP3B_MASK (0x0000FF00) +#define PSB_2D_ROP3B_CLRMASK (0xFFFF00FF) +#define PSB_2D_ROP3B_SHIFT (8) /* rop code A */ -#define PSB_2D_ROP3A_MASK (0x000000FF) -#define PSB_2D_ROP3A_CLRMASK (0xFFFFFF00) -#define PSB_2D_ROP3A_SHIFT (0) +#define PSB_2D_ROP3A_MASK (0x000000FF) +#define PSB_2D_ROP3A_CLRMASK (0xFFFFFF00) +#define PSB_2D_ROP3A_SHIFT (0) -#define PSB_2D_ROP4_MASK (0x0000FFFF) +#define PSB_2D_ROP4_MASK (0x0000FFFF) /* * DWORD0: (Only pass if Pattern control == Use Fill Colour) * Fill Colour RGBA8888 */ -#define PSB_2D_FILLCOLOUR_MASK (0xFFFFFFFF) -#define PSB_2D_FILLCOLOUR_SHIFT (0) +#define PSB_2D_FILLCOLOUR_MASK (0xFFFFFFFF) +#define PSB_2D_FILLCOLOUR_SHIFT (0) /* * DWORD1: (Always Present) * X Start (Dest) * Y Start (Dest) */ -#define PSB_2D_DST_XSTART_MASK (0x00FFF000) -#define PSB_2D_DST_XSTART_CLRMASK (0xFF000FFF) -#define PSB_2D_DST_XSTART_SHIFT (12) -#define PSB_2D_DST_YSTART_MASK (0x00000FFF) -#define PSB_2D_DST_YSTART_CLRMASK (0xFFFFF000) -#define PSB_2D_DST_YSTART_SHIFT (0) +#define PSB_2D_DST_XSTART_MASK (0x00FFF000) +#define PSB_2D_DST_XSTART_CLRMASK (0xFF000FFF) +#define PSB_2D_DST_XSTART_SHIFT (12) +#define PSB_2D_DST_YSTART_MASK (0x00000FFF) +#define PSB_2D_DST_YSTART_CLRMASK (0xFFFFF000) +#define PSB_2D_DST_YSTART_SHIFT (0) /* * DWORD2: (Always Present) * X Size (Dest) * Y Size (Dest) */ -#define PSB_2D_DST_XSIZE_MASK (0x00FFF000) -#define PSB_2D_DST_XSIZE_CLRMASK (0xFF000FFF) -#define PSB_2D_DST_XSIZE_SHIFT (12) -#define PSB_2D_DST_YSIZE_MASK (0x00000FFF) -#define PSB_2D_DST_YSIZE_CLRMASK (0xFFFFF000) -#define PSB_2D_DST_YSIZE_SHIFT (0) +#define PSB_2D_DST_XSIZE_MASK (0x00FFF000) +#define PSB_2D_DST_XSIZE_CLRMASK (0xFF000FFF) +#define PSB_2D_DST_XSIZE_SHIFT (12) +#define PSB_2D_DST_YSIZE_MASK (0x00000FFF) +#define PSB_2D_DST_YSIZE_CLRMASK (0xFFFFF000) +#define PSB_2D_DST_YSIZE_SHIFT (0) /* * Source Surface (PSB_2D_SRC_SURF_BH) */ /* - * WORD 0 + * WORD 0 */ -#define PSB_2D_SRC_FORMAT_MASK (0x00078000) -#define PSB_2D_SRC_1_PAL (0x00000000) -#define PSB_2D_SRC_2_PAL (0x00008000) -#define PSB_2D_SRC_4_PAL (0x00010000) -#define PSB_2D_SRC_8_PAL (0x00018000) -#define PSB_2D_SRC_8_ALPHA (0x00020000) -#define PSB_2D_SRC_4_ALPHA (0x00028000) -#define PSB_2D_SRC_332RGB (0x00030000) -#define PSB_2D_SRC_4444ARGB (0x00038000) -#define PSB_2D_SRC_555RGB (0x00040000) -#define PSB_2D_SRC_1555ARGB (0x00048000) -#define PSB_2D_SRC_565RGB (0x00050000) -#define PSB_2D_SRC_0888ARGB (0x00058000) -#define PSB_2D_SRC_8888ARGB (0x00060000) -#define PSB_2D_SRC_8888UYVY (0x00068000) -#define PSB_2D_SRC_RESERVED (0x00070000) -#define PSB_2D_SRC_1555ARGB_LOOKUP (0x00078000) +#define PSB_2D_SRC_FORMAT_MASK (0x00078000) +#define PSB_2D_SRC_1_PAL (0x00000000) +#define PSB_2D_SRC_2_PAL (0x00008000) +#define PSB_2D_SRC_4_PAL (0x00010000) +#define PSB_2D_SRC_8_PAL (0x00018000) +#define PSB_2D_SRC_8_ALPHA (0x00020000) +#define PSB_2D_SRC_4_ALPHA (0x00028000) +#define PSB_2D_SRC_332RGB (0x00030000) +#define PSB_2D_SRC_4444ARGB (0x00038000) +#define PSB_2D_SRC_555RGB (0x00040000) +#define PSB_2D_SRC_1555ARGB (0x00048000) +#define PSB_2D_SRC_565RGB (0x00050000) +#define PSB_2D_SRC_0888ARGB (0x00058000) +#define PSB_2D_SRC_8888ARGB (0x00060000) +#define PSB_2D_SRC_8888UYVY (0x00068000) +#define PSB_2D_SRC_RESERVED (0x00070000) +#define PSB_2D_SRC_1555ARGB_LOOKUP (0x00078000) -#define PSB_2D_SRC_STRIDE_MASK (0x00007FFF) -#define PSB_2D_SRC_STRIDE_CLRMASK (0xFFFF8000) -#define PSB_2D_SRC_STRIDE_SHIFT (0) +#define PSB_2D_SRC_STRIDE_MASK (0x00007FFF) +#define PSB_2D_SRC_STRIDE_CLRMASK (0xFFFF8000) +#define PSB_2D_SRC_STRIDE_SHIFT (0) /* * WORD 1 - Base Address */ -#define PSB_2D_SRC_ADDR_MASK (0x0FFFFFFC) -#define PSB_2D_SRC_ADDR_CLRMASK (0x00000003) -#define PSB_2D_SRC_ADDR_SHIFT (2) -#define PSB_2D_SRC_ADDR_ALIGNSHIFT (2) +#define PSB_2D_SRC_ADDR_MASK (0x0FFFFFFC) +#define PSB_2D_SRC_ADDR_CLRMASK (0x00000003) +#define PSB_2D_SRC_ADDR_SHIFT (2) +#define PSB_2D_SRC_ADDR_ALIGNSHIFT (2) /* * Pattern Surface (PSB_2D_PAT_SURF_BH) @@ -430,31 +426,31 @@ * WORD 0 */ -#define PSB_2D_PAT_FORMAT_MASK (0x00078000) -#define PSB_2D_PAT_1_PAL (0x00000000) -#define PSB_2D_PAT_2_PAL (0x00008000) -#define PSB_2D_PAT_4_PAL (0x00010000) -#define PSB_2D_PAT_8_PAL (0x00018000) -#define PSB_2D_PAT_8_ALPHA (0x00020000) -#define PSB_2D_PAT_4_ALPHA (0x00028000) -#define PSB_2D_PAT_332RGB (0x00030000) -#define PSB_2D_PAT_4444ARGB (0x00038000) -#define PSB_2D_PAT_555RGB (0x00040000) -#define PSB_2D_PAT_1555ARGB (0x00048000) -#define PSB_2D_PAT_565RGB (0x00050000) -#define PSB_2D_PAT_0888ARGB (0x00058000) -#define PSB_2D_PAT_8888ARGB (0x00060000) +#define PSB_2D_PAT_FORMAT_MASK (0x00078000) +#define PSB_2D_PAT_1_PAL (0x00000000) +#define PSB_2D_PAT_2_PAL (0x00008000) +#define PSB_2D_PAT_4_PAL (0x00010000) +#define PSB_2D_PAT_8_PAL (0x00018000) +#define PSB_2D_PAT_8_ALPHA (0x00020000) +#define PSB_2D_PAT_4_ALPHA (0x00028000) +#define PSB_2D_PAT_332RGB (0x00030000) +#define PSB_2D_PAT_4444ARGB (0x00038000) +#define PSB_2D_PAT_555RGB (0x00040000) +#define PSB_2D_PAT_1555ARGB (0x00048000) +#define PSB_2D_PAT_565RGB (0x00050000) +#define PSB_2D_PAT_0888ARGB (0x00058000) +#define PSB_2D_PAT_8888ARGB (0x00060000) -#define PSB_2D_PAT_STRIDE_MASK (0x00007FFF) -#define PSB_2D_PAT_STRIDE_CLRMASK (0xFFFF8000) -#define PSB_2D_PAT_STRIDE_SHIFT (0) +#define PSB_2D_PAT_STRIDE_MASK (0x00007FFF) +#define PSB_2D_PAT_STRIDE_CLRMASK (0xFFFF8000) +#define PSB_2D_PAT_STRIDE_SHIFT (0) /* * WORD 1 - Base Address */ -#define PSB_2D_PAT_ADDR_MASK (0x0FFFFFFC) -#define PSB_2D_PAT_ADDR_CLRMASK (0x00000003) -#define PSB_2D_PAT_ADDR_SHIFT (2) -#define PSB_2D_PAT_ADDR_ALIGNSHIFT (2) +#define PSB_2D_PAT_ADDR_MASK (0x0FFFFFFC) +#define PSB_2D_PAT_ADDR_CLRMASK (0x00000003) +#define PSB_2D_PAT_ADDR_SHIFT (2) +#define PSB_2D_PAT_ADDR_ALIGNSHIFT (2) /* * Destination Surface (PSB_2D_DST_SURF_BH) @@ -463,26 +459,26 @@ * WORD 0 */ -#define PSB_2D_DST_FORMAT_MASK (0x00078000) -#define PSB_2D_DST_332RGB (0x00030000) -#define PSB_2D_DST_4444ARGB (0x00038000) -#define PSB_2D_DST_555RGB (0x00040000) -#define PSB_2D_DST_1555ARGB (0x00048000) -#define PSB_2D_DST_565RGB (0x00050000) -#define PSB_2D_DST_0888ARGB (0x00058000) -#define PSB_2D_DST_8888ARGB (0x00060000) -#define PSB_2D_DST_8888AYUV (0x00070000) +#define PSB_2D_DST_FORMAT_MASK (0x00078000) +#define PSB_2D_DST_332RGB (0x00030000) +#define PSB_2D_DST_4444ARGB (0x00038000) +#define PSB_2D_DST_555RGB (0x00040000) +#define PSB_2D_DST_1555ARGB (0x00048000) +#define PSB_2D_DST_565RGB (0x00050000) +#define PSB_2D_DST_0888ARGB (0x00058000) +#define PSB_2D_DST_8888ARGB (0x00060000) +#define PSB_2D_DST_8888AYUV (0x00070000) -#define PSB_2D_DST_STRIDE_MASK (0x00007FFF) -#define PSB_2D_DST_STRIDE_CLRMASK (0xFFFF8000) -#define PSB_2D_DST_STRIDE_SHIFT (0) +#define PSB_2D_DST_STRIDE_MASK (0x00007FFF) +#define PSB_2D_DST_STRIDE_CLRMASK (0xFFFF8000) +#define PSB_2D_DST_STRIDE_SHIFT (0) /* * WORD 1 - Base Address */ -#define PSB_2D_DST_ADDR_MASK (0x0FFFFFFC) -#define PSB_2D_DST_ADDR_CLRMASK (0x00000003) -#define PSB_2D_DST_ADDR_SHIFT (2) -#define PSB_2D_DST_ADDR_ALIGNSHIFT (2) +#define PSB_2D_DST_ADDR_MASK (0x0FFFFFFC) +#define PSB_2D_DST_ADDR_CLRMASK (0x00000003) +#define PSB_2D_DST_ADDR_SHIFT (2) +#define PSB_2D_DST_ADDR_ALIGNSHIFT (2) /* * Mask Surface (PSB_2D_MASK_SURF_BH) @@ -490,99 +486,97 @@ /* * WORD 0 */ -#define PSB_2D_MASK_STRIDE_MASK (0x00007FFF) -#define PSB_2D_MASK_STRIDE_CLRMASK (0xFFFF8000) -#define PSB_2D_MASK_STRIDE_SHIFT (0) +#define PSB_2D_MASK_STRIDE_MASK (0x00007FFF) +#define PSB_2D_MASK_STRIDE_CLRMASK (0xFFFF8000) +#define PSB_2D_MASK_STRIDE_SHIFT (0) /* * WORD 1 - Base Address */ -#define PSB_2D_MASK_ADDR_MASK (0x0FFFFFFC) -#define PSB_2D_MASK_ADDR_CLRMASK (0x00000003) -#define PSB_2D_MASK_ADDR_SHIFT (2) -#define PSB_2D_MASK_ADDR_ALIGNSHIFT (2) +#define PSB_2D_MASK_ADDR_MASK (0x0FFFFFFC) +#define PSB_2D_MASK_ADDR_CLRMASK (0x00000003) +#define PSB_2D_MASK_ADDR_SHIFT (2) +#define PSB_2D_MASK_ADDR_ALIGNSHIFT (2) /* * Source Palette (PSB_2D_SRC_PAL_BH) */ -#define PSB_2D_SRCPAL_ADDR_SHIFT (0) -#define PSB_2D_SRCPAL_ADDR_CLRMASK (0xF0000007) -#define PSB_2D_SRCPAL_ADDR_MASK (0x0FFFFFF8) -#define PSB_2D_SRCPAL_BYTEALIGN (1024) +#define PSB_2D_SRCPAL_ADDR_SHIFT (0) +#define PSB_2D_SRCPAL_ADDR_CLRMASK (0xF0000007) +#define PSB_2D_SRCPAL_ADDR_MASK (0x0FFFFFF8) +#define PSB_2D_SRCPAL_BYTEALIGN (1024) /* * Pattern Palette (PSB_2D_PAT_PAL_BH) */ -#define PSB_2D_PATPAL_ADDR_SHIFT (0) -#define PSB_2D_PATPAL_ADDR_CLRMASK (0xF0000007) -#define PSB_2D_PATPAL_ADDR_MASK (0x0FFFFFF8) -#define PSB_2D_PATPAL_BYTEALIGN (1024) +#define PSB_2D_PATPAL_ADDR_SHIFT (0) +#define PSB_2D_PATPAL_ADDR_CLRMASK (0xF0000007) +#define PSB_2D_PATPAL_ADDR_MASK (0x0FFFFFF8) +#define PSB_2D_PATPAL_BYTEALIGN (1024) /* * Rop3 Codes (2 LS bytes) */ -#define PSB_2D_ROP3_SRCCOPY (0xCCCC) -#define PSB_2D_ROP3_PATCOPY (0xF0F0) -#define PSB_2D_ROP3_WHITENESS (0xFFFF) -#define PSB_2D_ROP3_BLACKNESS (0x0000) -#define PSB_2D_ROP3_SRC (0xCC) -#define PSB_2D_ROP3_PAT (0xF0) -#define PSB_2D_ROP3_DST (0xAA) - +#define PSB_2D_ROP3_SRCCOPY (0xCCCC) +#define PSB_2D_ROP3_PATCOPY (0xF0F0) +#define PSB_2D_ROP3_WHITENESS (0xFFFF) +#define PSB_2D_ROP3_BLACKNESS (0x0000) +#define PSB_2D_ROP3_SRC (0xCC) +#define PSB_2D_ROP3_PAT (0xF0) +#define PSB_2D_ROP3_DST (0xAA) /* * Sizes. */ -#define PSB_SCENE_HW_COOKIE_SIZE 16 -#define PSB_TA_MEM_HW_COOKIE_SIZE 16 +#define PSB_SCENE_HW_COOKIE_SIZE 16 +#define PSB_TA_MEM_HW_COOKIE_SIZE 16 /* * Scene stuff. */ -#define PSB_NUM_HW_SCENES 2 +#define PSB_NUM_HW_SCENES 2 /* * Scheduler completion actions. */ -#define PSB_RASTER_BLOCK 0 -#define PSB_RASTER 1 -#define PSB_RETURN 2 -#define PSB_TA 3 +#define PSB_RASTER_BLOCK 0 +#define PSB_RASTER 1 +#define PSB_RETURN 2 +#define PSB_TA 3 +/* Power management */ +#define PSB_PUNIT_PORT 0x04 +#define PSB_OSPMBA 0x78 +#define PSB_APMBA 0x7a +#define PSB_APM_CMD 0x0 +#define PSB_APM_STS 0x04 +#define PSB_PWRGT_VID_ENC_MASK 0x30 +#define PSB_PWRGT_VID_DEC_MASK 0xc +#define PSB_PWRGT_GL3_MASK 0xc0 -/*Power management*/ -#define PSB_PUNIT_PORT 0x04 -#define PSB_OSPMBA 0x78 -#define PSB_APMBA 0x7a -#define PSB_APM_CMD 0x0 -#define PSB_APM_STS 0x04 -#define PSB_PWRGT_VID_ENC_MASK 0x30 -#define PSB_PWRGT_VID_DEC_MASK 0xc -#define PSB_PWRGT_GL3_MASK 0xc0 - -#define PSB_PM_SSC 0x20 -#define PSB_PM_SSS 0x30 -#define PSB_PWRGT_DISPLAY_MASK 0xc /*on a different BA than video/gfx*/ -#define MDFLD_PWRGT_DISPLAY_A_CNTR 0x0000000c -#define MDFLD_PWRGT_DISPLAY_B_CNTR 0x0000c000 -#define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000 -#define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000 -#define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR)// 0x000fc00c -// Display SSS register bits are different in A0 vs. B0 -#define PSB_PWRGT_GFX_MASK 0x3 -#define MDFLD_PWRGT_DISPLAY_A_STS 0x000000c0 -#define MDFLD_PWRGT_DISPLAY_B_STS 0x00000300 -#define MDFLD_PWRGT_DISPLAY_C_STS 0x00000c00 -#define PSB_PWRGT_GFX_MASK_B0 0xc3 +#define PSB_PM_SSC 0x20 +#define PSB_PM_SSS 0x30 +#define PSB_PWRGT_DISPLAY_MASK 0xc /*on a different BA than video/gfx*/ +#define MDFLD_PWRGT_DISPLAY_A_CNTR 0x0000000c +#define MDFLD_PWRGT_DISPLAY_B_CNTR 0x0000c000 +#define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000 +#define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000 +#define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR) /* 0x000fc00c */ +/* Display SSS register bits are different in A0 vs. B0 */ +#define PSB_PWRGT_GFX_MASK 0x3 +#define MDFLD_PWRGT_DISPLAY_A_STS 0x000000c0 +#define MDFLD_PWRGT_DISPLAY_B_STS 0x00000300 +#define MDFLD_PWRGT_DISPLAY_C_STS 0x00000c00 +#define PSB_PWRGT_GFX_MASK_B0 0xc3 #define MDFLD_PWRGT_DISPLAY_A_STS_B0 0x0000000c -#define MDFLD_PWRGT_DISPLAY_B_STS_B0 0x0000c000 -#define MDFLD_PWRGT_DISPLAY_C_STS_B0 0x00030000 -#define MDFLD_PWRGT_DISP_MIPI_STS 0x000c0000 -#define MDFLD_PWRGT_DISPLAY_STS_A0 (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS)// 0x000fc00c -#define MDFLD_PWRGT_DISPLAY_STS_B0 (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS)// 0x000fc00c +#define MDFLD_PWRGT_DISPLAY_B_STS_B0 0x0000c000 +#define MDFLD_PWRGT_DISPLAY_C_STS_B0 0x00030000 +#define MDFLD_PWRGT_DISP_MIPI_STS 0x000c0000 +#define MDFLD_PWRGT_DISPLAY_STS_A0 (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */ +#define MDFLD_PWRGT_DISPLAY_STS_B0 (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */ #endif diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 46daade7a9e2..3612574ca520 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -518,22 +518,18 @@ static int blkvsc_remove(struct hv_device *dev) blkvsc_do_operation(blkdev, DO_FLUSH); - blk_cleanup_queue(blkdev->gd->queue); + if (blkdev->users == 0) { + del_gendisk(blkdev->gd); + put_disk(blkdev->gd); + blk_cleanup_queue(blkdev->gd->queue); - /* - * Call to the vsc driver to let it know that the device is being - * removed - */ - storvsc_dev_remove(dev); + storvsc_dev_remove(blkdev->device_ctx); - del_gendisk(blkdev->gd); - - kmem_cache_destroy(blkdev->request_pool); - - kfree(blkdev); + kmem_cache_destroy(blkdev->request_pool); + kfree(blkdev); + } return 0; - } static void blkvsc_shutdown(struct hv_device *dev) @@ -568,13 +564,23 @@ static int blkvsc_release(struct gendisk *disk, fmode_t mode) struct block_device_context *blkdev = disk->private_data; unsigned long flags; - if (blkdev->users == 1) { - blkvsc_do_operation(blkdev, DO_FLUSH); - } - spin_lock_irqsave(&blkdev->lock, flags); - blkdev->users--; - spin_unlock_irqrestore(&blkdev->lock, flags); + + if ((--blkdev->users == 0) && (blkdev->shutting_down)) { + blk_stop_queue(blkdev->gd->queue); + spin_unlock_irqrestore(&blkdev->lock, flags); + + blkvsc_do_operation(blkdev, DO_FLUSH); + del_gendisk(blkdev->gd); + put_disk(blkdev->gd); + blk_cleanup_queue(blkdev->gd->queue); + + storvsc_dev_remove(blkdev->device_ctx); + + kmem_cache_destroy(blkdev->request_pool); + kfree(blkdev); + } else + spin_unlock_irqrestore(&blkdev->lock, flags); return 0; } @@ -824,7 +830,6 @@ static int blkvsc_drv_init(void) BUILD_BUG_ON(sizeof(sector_t) != 8); memcpy(&drv->dev_type, &dev_type, sizeof(struct hv_guid)); - drv->name = drv_name; drv->driver.name = drv_name; /* The driver belongs to vmbus */ @@ -921,7 +926,6 @@ static int blkvsc_probe(struct hv_device *dev) else blkdev->gd->first_minor = 0; blkdev->gd->fops = &block_ops; - blkdev->gd->events = DISK_EVENT_MEDIA_CHANGE; blkdev->gd->private_data = blkdev; blkdev->gd->driverfs_dev = &(blkdev->device_ctx->device); sprintf(blkdev->gd->disk_name, "hd%c", 'a' + major_info.index); diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index f655e59a9a8f..455f47a891f1 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -39,7 +39,6 @@ static int create_gpadl_header( u32 size, /* page-size multiple */ struct vmbus_channel_msginfo **msginfo, u32 *messagecount); -static void dump_vmbus_channel(struct vmbus_channel *channel); static void vmbus_setevent(struct vmbus_channel *channel); /* @@ -186,12 +185,12 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, openMsg = (struct vmbus_channel_open_channel *)openInfo->msg; openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL; - openMsg->openid = newchannel->offermsg.child_relid; /* FIXME */ + openMsg->openid = newchannel->offermsg.child_relid; openMsg->child_relid = newchannel->offermsg.child_relid; openMsg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle; openMsg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >> PAGE_SHIFT; - openMsg->server_contextarea_gpadlhandle = 0; /* TODO */ + openMsg->server_contextarea_gpadlhandle = 0; if (userdatalen > MAX_USER_DEFINED_BYTES) { err = -EINVAL; @@ -210,9 +209,9 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, sizeof(struct vmbus_channel_open_channel)); if (ret != 0) - goto Cleanup; + goto cleanup; - t = wait_for_completion_timeout(&openInfo->waitevent, HZ); + t = wait_for_completion_timeout(&openInfo->waitevent, 5*HZ); if (t == 0) { err = -ETIMEDOUT; goto errorout; @@ -222,7 +221,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, if (openInfo->response.open_result.status) err = openInfo->response.open_result.status; -Cleanup: +cleanup: spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_del(&openInfo->msglistentry); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); @@ -356,20 +355,35 @@ static int create_gpadl_header(void *kbuffer, u32 size, 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) + + if (!msgbody) { + struct vmbus_channel_msginfo *pos = NULL; + struct vmbus_channel_msginfo *tmp = NULL; + /* + * Free up all the allocated messages. + */ + list_for_each_entry_safe(pos, tmp, + &msgheader->submsglist, + msglistentry) { + + list_del(&pos->msglistentry); + kfree(pos); + } + goto nomem; + } + msgbody->msgsize = msgsize; (*messagecount)++; gpadl_body = (struct vmbus_channel_gpadl_body *)msgbody->msg; /* - * FIXME: * Gpadl is u32 and we are using a pointer which could * be 64-bit + * This is governed by the guest/host protocol and + * so the hypervisor gurantees that this is ok. */ - /* gpadl_body->Gpadl = kbuffer; */ for (i = 0; i < pfncurr; i++) gpadl_body->pfn[i] = pfn + pfnsum + i; @@ -458,12 +472,11 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize - sizeof(*msginfo)); if (ret != 0) - goto Cleanup; + goto cleanup; if (msgcount > 1) { list_for_each(curr, &msginfo->submsglist) { - /* FIXME: should this use list_entry() instead ? */ submsginfo = (struct vmbus_channel_msginfo *)curr; gpadl_body = (struct vmbus_channel_gpadl_body *)submsginfo->msg; @@ -478,18 +491,18 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, submsginfo->msgsize - sizeof(*submsginfo)); if (ret != 0) - goto Cleanup; + goto cleanup; } } - t = wait_for_completion_timeout(&msginfo->waitevent, HZ); + t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ); BUG_ON(t == 0); /* At this point, we received the gpadl created msg */ *gpadl_handle = gpadlmsg->gpadl; -Cleanup: +cleanup: spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_del(&msginfo->msglistentry); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); @@ -532,7 +545,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) sizeof(struct vmbus_channel_gpadl_teardown)); BUG_ON(ret != 0); - t = wait_for_completion_timeout(&info->waitevent, HZ); + t = wait_for_completion_timeout(&info->waitevent, 5*HZ); BUG_ON(t == 0); /* Received a torndown response */ @@ -551,24 +564,15 @@ EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl); void vmbus_close(struct vmbus_channel *channel) { struct vmbus_channel_close_channel *msg; - struct vmbus_channel_msginfo *info; - unsigned long flags; int ret; /* Stop callback and cancel the timer asap */ channel->onchannel_callback = 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; + msg = &channel->close_msg.msg; - msg = (struct vmbus_channel_close_channel *)info->msg; msg->header.msgtype = CHANNELMSG_CLOSECHANNEL; msg->child_relid = channel->offermsg.child_relid; @@ -580,8 +584,6 @@ void vmbus_close(struct vmbus_channel *channel) vmbus_teardown_gpadl(channel, channel->ringbuffer_gpadlhandle); - /* TODO: Send a msg to release the childRelId */ - /* Cleanup the ring buffers for this channel */ hv_ringbuffer_cleanup(&channel->outbound); hv_ringbuffer_cleanup(&channel->inbound); @@ -589,21 +591,7 @@ void vmbus_close(struct vmbus_channel *channel) free_pages((unsigned long)channel->ringbuffer_pages, get_order(channel->ringbuffer_pagecount * PAGE_SIZE)); - 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(&vmbus_connection.channel_lock, flags); - list_del(&channel->listentry); - spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); - - free_channel(channel); - } } EXPORT_SYMBOL_GPL(vmbus_close); @@ -632,7 +620,6 @@ int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer, u64 aligned_data = 0; int ret; - dump_vmbus_channel(channel); /* Setup the descriptor */ desc.type = type; /* VmbusPacketTypeDataInBand; */ @@ -650,7 +637,6 @@ int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer, ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3); - /* TODO: We should determine if this is optional */ if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound)) vmbus_setevent(channel); @@ -679,7 +665,6 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, if (pagecount > MAX_PAGE_BUFFER_COUNT) return -EINVAL; - dump_vmbus_channel(channel); /* * Adjust the size down since vmbus_channel_packet_page_buffer is the @@ -713,7 +698,6 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3); - /* TODO: We should determine if this is optional */ if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound)) vmbus_setevent(channel); @@ -739,7 +723,6 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset, multi_pagebuffer->len); - dump_vmbus_channel(channel); if ((pfncount < 0) || (pfncount > MAX_MULTIPAGE_BUFFER_COUNT)) return -EINVAL; @@ -777,7 +760,6 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3); - /* TODO: We should determine if this is optional */ if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound)) vmbus_setevent(channel); @@ -829,7 +811,7 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, pr_err("Buffer too small - got %d needs %d\n", bufferlen, userlen); - return -1; + return -ETOOSMALL; } *requestid = desc.trans_id; @@ -893,36 +875,3 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, return 0; } EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw); - -/* - * vmbus_onchannel_event - Channel event callback - */ -void vmbus_onchannel_event(struct vmbus_channel *channel) -{ - dump_vmbus_channel(channel); - - channel->onchannel_callback(channel->channel_callback_context); - - mod_timer(&channel->poll_timer, jiffies + usecs_to_jiffies(100)); -} - -/* - * vmbus_ontimer - Timer event callback - */ -void vmbus_ontimer(unsigned long data) -{ - struct vmbus_channel *channel = (struct vmbus_channel *)data; - - if (channel->onchannel_callback) - channel->onchannel_callback(channel->channel_callback_context); -} - -/* - * dump_vmbus_channel- Dump vmbus channel info to the console - */ -static void dump_vmbus_channel(struct vmbus_channel *channel) -{ - DPRINT_DBG(VMBUS, "Channel (%d)", channel->offermsg.child_relid); - hv_dump_ring_info(&channel->outbound, "Outbound "); - hv_dump_ring_info(&channel->inbound, "Inbound "); -} diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 957d61ee4ceb..bf011f3fb851 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -283,10 +283,6 @@ static struct vmbus_channel *alloc_channel(void) spin_lock_init(&channel->inbound_lock); - init_timer(&channel->poll_timer); - channel->poll_timer.data = (unsigned long)channel; - channel->poll_timer.function = vmbus_ontimer; - channel->controlwq = create_workqueue("hv_vmbus_ctl"); if (!channel->controlwq) { kfree(channel); @@ -315,7 +311,6 @@ static void release_channel(struct work_struct *work) */ void free_channel(struct vmbus_channel *channel) { - del_timer_sync(&channel->poll_timer); /* * We have to release the channel's workqueue/thread in the vmbus's @@ -482,7 +477,6 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) newchannel->monitor_grp = (u8)offer->monitorid / 32; newchannel->monitor_bit = (u8)offer->monitorid % 32; - /* TODO: Make sure the offer comes from our parent partition */ INIT_WORK(&newchannel->work, vmbus_process_offer); queue_work(newchannel->controlwq, &newchannel->work); } @@ -773,7 +767,7 @@ int vmbus_request_offers(void) goto cleanup; } - t = wait_for_completion_timeout(&msginfo->waitevent, HZ); + t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ); if (t == 0) { ret = -ETIMEDOUT; goto cleanup; diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index 37bbf770ef11..e6b40392e08d 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -51,13 +51,13 @@ int vmbus_connect(void) /* Make sure we are not connecting or connected */ if (vmbus_connection.conn_state != DISCONNECTED) - return -1; + return -EISCONN; /* Initialize the vmbus connection */ vmbus_connection.conn_state = CONNECTING; vmbus_connection.work_queue = create_workqueue("hv_vmbus_con"); if (!vmbus_connection.work_queue) { - ret = -1; + ret = -ENOMEM; goto cleanup; } @@ -74,7 +74,7 @@ int vmbus_connect(void) vmbus_connection.int_page = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, 0); if (vmbus_connection.int_page == NULL) { - ret = -1; + ret = -ENOMEM; goto cleanup; } @@ -90,7 +90,7 @@ int vmbus_connect(void) vmbus_connection.monitor_pages = (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 1); if (vmbus_connection.monitor_pages == NULL) { - ret = -1; + ret = -ENOMEM; goto cleanup; } @@ -135,7 +135,7 @@ int vmbus_connect(void) } /* Wait for the connection response */ - t = wait_for_completion_timeout(&msginfo->waitevent, HZ); + t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ); if (t == 0) { spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); @@ -157,7 +157,7 @@ int vmbus_connect(void) pr_err("Unable to connect, " "Version %d not supported by Hyper-V\n", VMBUS_REVISION_NUMBER); - ret = -1; + ret = -ECONNREFUSED; goto cleanup; } @@ -185,44 +185,6 @@ int vmbus_connect(void) return ret; } -/* - * vmbus_disconnect - - * Sends a disconnect request on the partition service connection - */ -int vmbus_disconnect(void) -{ - int ret = 0; - struct vmbus_channel_message_header *msg; - - /* Make sure we are connected */ - if (vmbus_connection.conn_state != CONNECTED) - return -1; - - msg = kzalloc(sizeof(struct vmbus_channel_message_header), GFP_KERNEL); - if (!msg) - return -ENOMEM; - - msg->msgtype = CHANNELMSG_UNLOAD; - - ret = vmbus_post_msg(msg, - sizeof(struct vmbus_channel_message_header)); - if (ret != 0) - goto cleanup; - - free_pages((unsigned long)vmbus_connection.int_page, 0); - free_pages((unsigned long)vmbus_connection.monitor_pages, 1); - - /* TODO: iterate thru the msg list and free up */ - destroy_workqueue(vmbus_connection.work_queue); - - vmbus_connection.conn_state = DISCONNECTED; - - pr_info("hv_vmbus disconnected\n"); - -cleanup: - kfree(msg); - return ret; -} /* * relid2channel - Get the channel object given its @@ -262,7 +224,7 @@ static void process_chn_event(u32 relid) channel = relid2channel(relid); if (channel) { - vmbus_onchannel_event(channel); + channel->onchannel_callback(channel->channel_callback_context); } else { pr_err("channel not found for relid - %u\n", relid); } diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index a2cc0911de58..824f81679ae8 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -277,11 +277,11 @@ u16 hv_post_message(union hv_connection_id connection_id, unsigned long addr; if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT) - return -1; + return -EMSGSIZE; addr = (unsigned long)kmalloc(sizeof(struct aligned_input), GFP_ATOMIC); if (!addr) - return -1; + return -ENOMEM; aligned_msg = (struct hv_input_post_message *) (ALIGN(addr, HV_HYPERCALL_PARAM_ALIGN)); diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index b3324d609c8b..d957fc228019 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -935,7 +935,6 @@ static int __init mousevsc_init(void) sizeof(struct hv_guid)); drv->driver.name = driver_name; - drv->name = driver_name; /* The driver belongs to vmbus */ vmbus_child_driver_register(&drv->driver); diff --git a/drivers/staging/hv/hv_timesource.c b/drivers/staging/hv/hv_timesource.c index 0efb04915255..2b0f9aaf9122 100644 --- a/drivers/staging/hv/hv_timesource.c +++ b/drivers/staging/hv/hv_timesource.c @@ -22,7 +22,6 @@ */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include #include #include #include diff --git a/drivers/staging/hv/hyperv.h b/drivers/staging/hv/hyperv.h index 3310e9bdf562..1747a2404f6c 100644 --- a/drivers/staging/hv/hyperv.h +++ b/drivers/staging/hv/hyperv.h @@ -523,46 +523,6 @@ enum vmbus_channel_state { CHANNEL_OPEN_STATE, }; -struct vmbus_channel { - struct list_head listentry; - - struct hv_device *device_obj; - - struct timer_list poll_timer; /* SA-111 workaround */ - struct work_struct work; - - enum vmbus_channel_state state; - /* - * For util channels, stash the - * the service index for easy access. - */ - s8 util_index; - - struct vmbus_channel_offer_channel offermsg; - /* - * These are based on the OfferMsg.MonitorId. - * Save it here for easy access. - */ - u8 monitor_grp; - u8 monitor_bit; - - u32 ringbuffer_gpadlhandle; - - /* Allocated memory for ring buffer */ - void *ringbuffer_pages; - u32 ringbuffer_pagecount; - struct hv_ring_buffer_info outbound; /* send to parent */ - struct hv_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 (*onchannel_callback)(void *context); - void *channel_callback_context; -}; - struct vmbus_channel_debug_info { u32 relid; enum vmbus_channel_state state; @@ -609,6 +569,51 @@ struct vmbus_channel_msginfo { unsigned char msg[0]; }; +struct vmbus_close_msg { + struct vmbus_channel_msginfo info; + struct vmbus_channel_close_channel msg; +}; + +struct vmbus_channel { + struct list_head listentry; + + struct hv_device *device_obj; + + struct work_struct work; + + enum vmbus_channel_state state; + /* + * For util channels, stash the + * the service index for easy access. + */ + s8 util_index; + + struct vmbus_channel_offer_channel offermsg; + /* + * These are based on the OfferMsg.MonitorId. + * Save it here for easy access. + */ + u8 monitor_grp; + u8 monitor_bit; + + u32 ringbuffer_gpadlhandle; + + /* Allocated memory for ring buffer */ + void *ringbuffer_pages; + u32 ringbuffer_pagecount; + struct hv_ring_buffer_info outbound; /* send to parent */ + struct hv_ring_buffer_info inbound; /* receive from parent */ + spinlock_t inbound_lock; + struct workqueue_struct *controlwq; + + struct vmbus_close_msg close_msg; + + /* Channel callback are invoked in this workqueue context */ + /* HANDLE dataWorkQueue; */ + + void (*onchannel_callback)(void *context); + void *channel_callback_context; +}; void free_channel(struct vmbus_channel *channel); @@ -691,7 +696,6 @@ extern int vmbus_recvpacket_raw(struct vmbus_channel *channel, u32 *buffer_actual_len, u64 *requestid); -extern void vmbus_onchannel_event(struct vmbus_channel *channel); extern void vmbus_get_debug_info(struct vmbus_channel *channel, struct vmbus_channel_debug_info *debug); diff --git a/drivers/staging/hv/hyperv_net.h b/drivers/staging/hv/hyperv_net.h index 315097df799a..27f987b48dfe 100644 --- a/drivers/staging/hv/hyperv_net.h +++ b/drivers/staging/hv/hyperv_net.h @@ -99,9 +99,9 @@ int netvsc_recv_callback(struct hv_device *device_obj, int netvsc_initialize(struct hv_driver *drv); int rndis_filter_open(struct hv_device *dev); int rndis_filter_close(struct hv_device *dev); -int rndis_filte_device_add(struct hv_device *dev, +int rndis_filter_device_add(struct hv_device *dev, void *additional_info); -int rndis_filter_device_remove(struct hv_device *dev); +void rndis_filter_device_remove(struct hv_device *dev); int rndis_filter_receive(struct hv_device *dev, struct hv_netvsc_packet *pkt); @@ -355,10 +355,6 @@ struct nvsp_message { /* #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 @@ -383,12 +379,6 @@ struct netvsc_device { struct list_head recv_pkt_list; spinlock_t recv_pkt_list_lock; - /* Send buffer allocated by us but manages by NetVSP */ - void *send_buf; - u32 send_buf_size; - u32 send_buf_gpadl_handle; - u32 send_section_size; - /* Receive buffer allocated by us but manages by NetVSP */ void *recv_buf; u32 recv_buf_size; diff --git a/drivers/staging/hv/hyperv_vmbus.h b/drivers/staging/hv/hyperv_vmbus.h index bf30a425b643..349ad80ce328 100644 --- a/drivers/staging/hv/hyperv_vmbus.h +++ b/drivers/staging/hv/hyperv_vmbus.h @@ -619,8 +619,6 @@ struct vmbus_channel *relid2channel(u32 relid); int vmbus_connect(void); -int vmbus_disconnect(void); - int vmbus_post_msg(void *buffer, size_t buflen); int vmbus_set_event(u32 child_relid); diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 41cbb26eccbf..dc5e5c488e3b 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -270,7 +270,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) goto cleanup; } - t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ); + t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ); BUG_ON(t == 0); @@ -323,162 +323,6 @@ static int netvsc_init_recv_buf(struct hv_device *device) return ret; } -static int netvsc_destroy_send_buf(struct netvsc_device *net_device) -{ - struct nvsp_message *revoke_packet; - int ret = 0; - - /* - * 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 (net_device->send_section_size) { - /* Send the revoke send buffer */ - revoke_packet = &net_device->revoke_packet; - memset(revoke_packet, 0, sizeof(struct nvsp_message)); - - revoke_packet->hdr.msg_type = - NVSP_MSG1_TYPE_REVOKE_SEND_BUF; - revoke_packet->msg.v1_msg. - revoke_send_buf.id = NETVSC_SEND_BUFFER_ID; - - ret = vmbus_sendpacket(net_device->dev->channel, - revoke_packet, - sizeof(struct nvsp_message), - (unsigned long)revoke_packet, - VM_PKT_DATA_INBAND, 0); - /* - * If we failed here, we might as well return and have a leak - * rather than continue and a bugchk - */ - if (ret != 0) { - dev_err(&net_device->dev->device, "unable to send " - "revoke send buffer to netvsp"); - return -1; - } - } - - /* Teardown the gpadl on the vsp end */ - if (net_device->send_buf_gpadl_handle) { - ret = vmbus_teardown_gpadl(net_device->dev->channel, - net_device->send_buf_gpadl_handle); - - /* - * If we failed here, we might as well return and have a leak - * rather than continue and a bugchk - */ - if (ret != 0) { - dev_err(&net_device->dev->device, - "unable to teardown send buffer's gpadl"); - return -1; - } - net_device->send_buf_gpadl_handle = 0; - } - - if (net_device->send_buf) { - /* Free up the receive buffer */ - free_pages((unsigned long)net_device->send_buf, - get_order(net_device->send_buf_size)); - net_device->send_buf = NULL; - } - - return ret; -} - -static int netvsc_init_send_buf(struct hv_device *device) -{ - int ret = 0; - int t; - struct netvsc_device *net_device; - struct nvsp_message *init_packet; - - net_device = get_outbound_net_device(device); - if (!net_device) { - dev_err(&device->device, "unable to get net device..." - "device being destroyed?"); - return -1; - } - if (net_device->send_buf_size <= 0) { - ret = -EINVAL; - goto cleanup; - } - - net_device->send_buf = - (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, - get_order(net_device->send_buf_size)); - if (!net_device->send_buf) { - dev_err(&device->device, "unable to allocate send " - "buffer of size %d", net_device->send_buf_size); - ret = -1; - goto cleanup; - } - - /* - * 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 = vmbus_establish_gpadl(device->channel, net_device->send_buf, - net_device->send_buf_size, - &net_device->send_buf_gpadl_handle); - if (ret != 0) { - dev_err(&device->device, "unable to establish send buffer's gpadl"); - goto cleanup; - } - - /* Notify the NetVsp of the gpadl handle */ - init_packet = &net_device->channel_init_pkt; - - memset(init_packet, 0, sizeof(struct nvsp_message)); - - init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF; - init_packet->msg.v1_msg.send_recv_buf. - gpadl_handle = net_device->send_buf_gpadl_handle; - init_packet->msg.v1_msg.send_recv_buf.id = - NETVSC_SEND_BUFFER_ID; - - /* Send the gpadl notification request */ - ret = vmbus_sendpacket(device->channel, init_packet, - sizeof(struct nvsp_message), - (unsigned long)init_packet, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) { - dev_err(&device->device, - "unable to send receive buffer's gpadl to netvsp"); - goto cleanup; - } - - t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ); - - BUG_ON(t == 0); - - /* Check the response */ - if (init_packet->msg.v1_msg. - send_send_buf_complete.status != NVSP_STAT_SUCCESS) { - dev_err(&device->device, "Unable to complete send buffer " - "initialzation with NetVsp - status %d", - init_packet->msg.v1_msg. - send_send_buf_complete.status); - ret = -1; - goto cleanup; - } - - net_device->send_section_size = init_packet-> - msg.v1_msg.send_send_buf_complete.section_size; - - goto exit; - -cleanup: - netvsc_destroy_send_buf(net_device); - -exit: - put_net_device(device); - return ret; -} - static int netvsc_connect_vsp(struct hv_device *device) { @@ -513,7 +357,7 @@ static int netvsc_connect_vsp(struct hv_device *device) if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ); + t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ); if (t == 0) { ret = -ETIMEDOUT; @@ -556,8 +400,6 @@ static int netvsc_connect_vsp(struct hv_device *device) /* Post the big receive buffer to NetVSP */ ret = netvsc_init_recv_buf(device); - if (ret == 0) - ret = netvsc_init_send_buf(device); cleanup: put_net_device(device); @@ -567,7 +409,6 @@ static int netvsc_connect_vsp(struct hv_device *device) static void netvsc_disconnect_vsp(struct netvsc_device *net_device) { netvsc_destroy_recv_buf(net_device); - netvsc_destroy_send_buf(net_device); } /* @@ -698,10 +539,10 @@ int netvsc_send(struct hv_device *device, (unsigned long)packet); } else { ret = vmbus_sendpacket(device->channel, &sendMessage, - sizeof(struct nvsp_message), - (unsigned long)packet, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + sizeof(struct nvsp_message), + (unsigned long)packet, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); } @@ -1099,8 +940,6 @@ int netvsc_device_add(struct hv_device *device, void *additional_info) net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE; spin_lock_init(&net_device->recv_pkt_list_lock); - net_device->send_buf_size = NETVSC_SEND_BUFFER_SIZE; - INIT_LIST_HEAD(&net_device->recv_pkt_list); for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) { diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 7b9c229f7295..61989f0d9f0d 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -21,6 +21,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include @@ -45,8 +46,8 @@ struct net_device_context { /* point back to our device context */ struct hv_device *device_ctx; - unsigned long avail; - struct work_struct work; + atomic_t avail; + struct delayed_work dwork; }; @@ -118,9 +119,10 @@ static void netvsc_xmit_completion(void *context) dev_kfree_skb_any(skb); - net_device_ctx->avail += num_pages; - if (net_device_ctx->avail >= PACKET_PAGES_HIWATER) - netif_wake_queue(net); + atomic_add(num_pages, &net_device_ctx->avail); + if (atomic_read(&net_device_ctx->avail) >= + PACKET_PAGES_HIWATER) + netif_wake_queue(net); } } @@ -133,7 +135,7 @@ 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) + if (num_pages > atomic_read(&net_device_ctx->avail)) return NETDEV_TX_BUSY; /* Allocate a netvsc packet based on # of frags. */ @@ -156,9 +158,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) /* Setup the rndis header */ packet->page_buf_cnt = num_pages; - /* TODO: Flush all write buffers/ memory fence ??? */ - /* wmb(); */ - /* Initialize it from the skb */ packet->total_data_buflen = skb->len; @@ -188,8 +187,8 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) net->stats.tx_bytes += skb->len; net->stats.tx_packets++; - net_device_ctx->avail -= num_pages; - if (net_device_ctx->avail < PACKET_PAGES_LOWATER) + atomic_sub(num_pages, &net_device_ctx->avail); + if (atomic_read(&net_device_ctx->avail) < PACKET_PAGES_LOWATER) netif_stop_queue(net); } else { /* we are shutting down or bus overloaded, just drop packet */ @@ -220,7 +219,7 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj, netif_wake_queue(net); netif_notify_peers(net); ndev_ctx = netdev_priv(net); - schedule_work(&ndev_ctx->work); + schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20)); } else { netif_carrier_off(net); netif_stop_queue(net); @@ -318,7 +317,7 @@ static const struct net_device_ops device_ops = { * Send GARP packet to network peers after migrations. * After Quick Migration, the network is not immediately operational in the * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add - * another netif_notify_peers() into a scheduled work, otherwise GARP packet + * another netif_notify_peers() into a delayed work, otherwise GARP packet * will not be sent after quick migration, and cause network disconnection. */ static void netvsc_send_garp(struct work_struct *w) @@ -326,8 +325,7 @@ static void netvsc_send_garp(struct work_struct *w) struct net_device_context *ndev_ctx; struct net_device *net; - msleep(20); - ndev_ctx = container_of(w, struct net_device_context, work); + ndev_ctx = container_of(w, struct net_device_context, dwork.work); net = dev_get_drvdata(&ndev_ctx->device_ctx->device); netif_notify_peers(net); } @@ -349,13 +347,13 @@ static int netvsc_probe(struct hv_device *dev) net_device_ctx = netdev_priv(net); net_device_ctx->device_ctx = dev; - net_device_ctx->avail = ring_size; + atomic_set(&net_device_ctx->avail, ring_size); dev_set_drvdata(&dev->device, net); - INIT_WORK(&net_device_ctx->work, netvsc_send_garp); + INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp); /* Notify the netvsc driver of the new device */ device_info.ring_size = ring_size; - ret = rndis_filte_device_add(dev, &device_info); + ret = rndis_filter_device_add(dev, &device_info); if (ret != 0) { free_netdev(net); dev_set_drvdata(&dev->device, NULL); @@ -364,17 +362,7 @@ static int netvsc_probe(struct hv_device *dev) return ret; } - /* - * If carrier is still off ie we did not get a link status callback, - * update it if necessary - */ - /* - * FIXME: We should use a atomic or test/set instead to avoid getting - * out of sync with the device's link status - */ - if (!netif_carrier_ok(net)) - if (!device_info.link_state) - netif_carrier_on(net); + netif_carrier_on(net); memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); @@ -400,16 +388,18 @@ static int netvsc_probe(struct hv_device *dev) static int netvsc_remove(struct hv_device *dev) { struct net_device *net = dev_get_drvdata(&dev->device); - int ret; + struct net_device_context *ndev_ctx; if (net == NULL) { dev_err(&dev->device, "No net device to remove\n"); return 0; } + ndev_ctx = netdev_priv(net); + cancel_delayed_work_sync(&ndev_ctx->dwork); + /* Stop outbound asap */ netif_stop_queue(net); - /* netif_carrier_off(net); */ unregister_netdev(net); @@ -417,14 +407,10 @@ static int netvsc_remove(struct hv_device *dev) * Call to the vsc driver to let it know that the device is being * removed */ - ret = rndis_filter_device_remove(dev); - if (ret != 0) { - /* TODO: */ - netdev_err(net, "unable to remove vsc device (ret %d)\n", ret); - } + rndis_filter_device_remove(dev); free_netdev(net); - return ret; + return 0; } /* The one and only one */ diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c index 3da333018b5a..42f76728429a 100644 --- a/drivers/staging/hv/ring_buffer.c +++ b/drivers/staging/hv/ring_buffer.c @@ -50,6 +50,8 @@ hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi, { u32 read_loc, write_loc; + smp_read_barrier_depends(); + /* Capture the read/write indices before they changed */ read_loc = rbi->ring_buffer->read_index; write_loc = rbi->ring_buffer->write_index; @@ -411,7 +413,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, sizeof(u64)); /* Make sure we flush all writes before updating the writeIndex */ - mb(); + smp_wmb(); /* Now, update the write location */ hv_set_next_write_location(outring_info, next_write_location); @@ -513,7 +515,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, /* 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(); + smp_mb(); /* Update the read index */ hv_set_next_read_location(inring_info, next_read_location); diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index 60ebdb1b6082..dbb520199756 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -139,14 +139,17 @@ static void put_rndis_request(struct rndis_device *dev, kfree(req); } -static void dump_rndis_message(struct rndis_message *rndis_msg) +static void dump_rndis_message(struct hv_device *hv_dev, + struct rndis_message *rndis_msg) { + struct net_device *netdev = dev_get_drvdata(&hv_dev->device); + switch (rndis_msg->ndis_msg_type) { case REMOTE_NDIS_PACKET_MSG: - DPRINT_DBG(NETVSC, "REMOTE_NDIS_PACKET_MSG (len %u, " + netdev_dbg(netdev, "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", + "pkt len %u\n", rndis_msg->msg_len, rndis_msg->msg.pkt.data_offset, rndis_msg->msg.pkt.data_len, @@ -158,10 +161,10 @@ static void dump_rndis_message(struct rndis_message *rndis_msg) break; case REMOTE_NDIS_INITIALIZE_CMPLT: - DPRINT_DBG(NETVSC, "REMOTE_NDIS_INITIALIZE_CMPLT " + netdev_dbg(netdev, "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)", + "pkt aligned %u)\n", rndis_msg->msg_len, rndis_msg->msg.init_complete.req_id, rndis_msg->msg.init_complete.status, @@ -176,9 +179,9 @@ static void dump_rndis_message(struct rndis_message *rndis_msg) break; case REMOTE_NDIS_QUERY_CMPLT: - DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT " + netdev_dbg(netdev, "REMOTE_NDIS_QUERY_CMPLT " "(len %u, id 0x%x, status 0x%x, buf len %u, " - "buf offset %u)", + "buf offset %u)\n", rndis_msg->msg_len, rndis_msg->msg.query_complete.req_id, rndis_msg->msg.query_complete.status, @@ -189,16 +192,16 @@ static void dump_rndis_message(struct rndis_message *rndis_msg) break; case REMOTE_NDIS_SET_CMPLT: - DPRINT_DBG(NETVSC, - "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)", + netdev_dbg(netdev, + "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)\n", rndis_msg->msg_len, rndis_msg->msg.set_complete.req_id, rndis_msg->msg.set_complete.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)", + netdev_dbg(netdev, "REMOTE_NDIS_INDICATE_STATUS_MSG " + "(len %u, status 0x%x, buf len %u, buf offset %u)\n", rndis_msg->msg_len, rndis_msg->msg.indicate_status.status, rndis_msg->msg.indicate_status.status_buflen, @@ -206,7 +209,7 @@ static void dump_rndis_message(struct rndis_message *rndis_msg) break; default: - DPRINT_DBG(NETVSC, "0x%x (len %u)", + netdev_dbg(netdev, "0x%x (len %u)\n", rndis_msg->ndis_msg_type, rndis_msg->msg_len); break; @@ -372,24 +375,6 @@ int rndis_filter_receive(struct hv_device *dev, pkt->page_buf[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 (pkt->total_data_buflen != rndis_hdr->msg_len) { - kunmap_atomic(rndis_hdr - pkt->page_buf[0].offset, - KM_IRQ0); - - dev_err(&dev->device, "invalid rndis message? (expected %u " - "bytes got %u)...dropping this message!\n", - rndis_hdr->msg_len, - pkt->total_data_buflen); - return -1; - } -#endif - if ((rndis_hdr->ndis_msg_type != REMOTE_NDIS_PACKET_MSG) && (rndis_hdr->msg_len > sizeof(struct rndis_message))) { dev_err(&dev->device, "incoming rndis message buffer overflow " @@ -405,7 +390,7 @@ int rndis_filter_receive(struct hv_device *dev, kunmap_atomic(rndis_hdr - pkt->page_buf[0].offset, KM_IRQ0); - dump_rndis_message(&rndis_msg); + dump_rndis_message(dev, &rndis_msg); switch (rndis_msg.ndis_msg_type) { case REMOTE_NDIS_PACKET_MSG: @@ -467,7 +452,7 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, if (ret != 0) goto Cleanup; - t = wait_for_completion_timeout(&request->wait_event, HZ); + t = wait_for_completion_timeout(&request->wait_event, 5*HZ); if (t == 0) { ret = -ETIMEDOUT; goto Cleanup; @@ -543,7 +528,7 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, if (ret != 0) goto Cleanup; - t = wait_for_completion_timeout(&request->wait_event, HZ); + t = wait_for_completion_timeout(&request->wait_event, 5*HZ); if (t == 0) { ret = -1; @@ -600,7 +585,7 @@ static int rndis_filter_init_device(struct rndis_device *dev) } - t = wait_for_completion_timeout(&request->wait_event, HZ); + t = wait_for_completion_timeout(&request->wait_event, 5*HZ); if (t == 0) { ret = -ETIMEDOUT; @@ -681,7 +666,7 @@ static int rndis_filter_close_device(struct rndis_device *dev) return ret; } -int rndis_filte_device_add(struct hv_device *dev, +int rndis_filter_device_add(struct hv_device *dev, void *additional_info) { int ret; @@ -741,7 +726,7 @@ int rndis_filte_device_add(struct hv_device *dev, return ret; } -int rndis_filter_device_remove(struct hv_device *dev) +void rndis_filter_device_remove(struct hv_device *dev) { struct netvsc_device *net_dev = dev->ext; struct rndis_device *rndis_dev = net_dev->extension; @@ -753,8 +738,6 @@ int rndis_filter_device_remove(struct hv_device *dev) net_dev->extension = NULL; netvsc_device_remove(dev); - - return 0; } diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 06cd3276813c..302978611943 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -135,7 +135,7 @@ static int storvsc_channel_init(struct hv_device *device) if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&request->wait_event, HZ); + t = wait_for_completion_timeout(&request->wait_event, 5*HZ); if (t == 0) { ret = -ETIMEDOUT; goto cleanup; @@ -163,7 +163,7 @@ static int storvsc_channel_init(struct hv_device *device) if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&request->wait_event, HZ); + t = wait_for_completion_timeout(&request->wait_event, 5*HZ); if (t == 0) { ret = -ETIMEDOUT; goto cleanup; @@ -192,7 +192,7 @@ static int storvsc_channel_init(struct hv_device *device) if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&request->wait_event, HZ); + t = wait_for_completion_timeout(&request->wait_event, 5*HZ); if (t == 0) { ret = -ETIMEDOUT; goto cleanup; @@ -222,7 +222,7 @@ static int storvsc_channel_init(struct hv_device *device) if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&request->wait_event, HZ); + t = wait_for_completion_timeout(&request->wait_event, 5*HZ); if (t == 0) { ret = -ETIMEDOUT; goto cleanup; diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 942cc5f98db1..7effaf32e25f 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,7 @@ MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); static const char *driver_name = "storvsc"; /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ -static const struct hv_guid gStorVscDeviceType = { +static const struct hv_guid stor_vsci_device_type = { .data = { 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f @@ -92,12 +93,8 @@ static int storvsc_device_configure(struct scsi_device *sdevice) scsi_adjust_queue_depth(sdevice, MSG_SIMPLE_TAG, STORVSC_MAX_IO_REQUESTS); - DPRINT_INFO(STORVSC_DRV, "sdev (%p) - setting max segment size to %ld", - sdevice, PAGE_SIZE); blk_queue_max_segment_size(sdevice->request_queue, PAGE_SIZE); - DPRINT_INFO(STORVSC_DRV, "sdev (%p) - adding merge bio vec routine", - sdevice); blk_queue_merge_bvec(sdevice->request_queue, storvsc_merge_bvec); blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY); @@ -308,31 +305,21 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, } -/* - * storvsc_remove - Callback when our device is removed - */ static int storvsc_remove(struct hv_device *dev) { struct Scsi_Host *host = dev_get_drvdata(&dev->device); struct hv_host_device *host_dev = (struct hv_host_device *)host->hostdata; - /* - * Call to the vsc driver to let it know that the device is being - * removed - */ - storvsc_dev_remove(dev); + scsi_remove_host(host); + scsi_host_put(host); + + storvsc_dev_remove(dev); if (host_dev->request_pool) { kmem_cache_destroy(host_dev->request_pool); host_dev->request_pool = NULL; } - - DPRINT_INFO(STORVSC, "removing host adapter (%p)...", host); - scsi_remove_host(host); - - DPRINT_INFO(STORVSC, "releasing host adapter (%p)...", host); - scsi_host_put(host); return 0; } @@ -357,9 +344,6 @@ static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev, info[1] = sectors_pt; info[2] = (int)cylinders; - DPRINT_INFO(STORVSC_DRV, "CHS (%d, %d, %d)", (int)cylinders, heads, - sectors_pt); - return 0; } @@ -370,7 +354,6 @@ static int storvsc_host_reset(struct hv_device *device) struct vstor_packet *vstor_packet; int ret, t; - DPRINT_INFO(STORVSC, "resetting host adapter..."); stor_device = get_stor_device(device); if (!stor_device) @@ -393,13 +376,12 @@ static int storvsc_host_reset(struct hv_device *device) if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&request->wait_event, HZ); + t = wait_for_completion_timeout(&request->wait_event, 5*HZ); if (t == 0) { ret = -ETIMEDOUT; goto cleanup; } - DPRINT_INFO(STORVSC, "host adapter reset completed"); /* * At this point, all outstanding requests in the adapter @@ -422,17 +404,10 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) (struct hv_host_device *)scmnd->device->host->hostdata; struct hv_device *dev = host_dev->dev; - DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host resetting...", - scmnd->device, dev); - - /* Invokes the vsc to reset the host/bus */ ret = storvsc_host_reset(dev); if (ret != 0) return ret; - DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host reseted", - scmnd->device, dev); - return ret; } @@ -479,7 +454,6 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) scmnd->host_scribble = NULL; scmnd->scsi_done = NULL; - /* !!DO NOT MODIFY the scmnd after this call */ scsi_done_fn(scmnd); kmem_cache_free(host_dev->request_pool, cmd_request); @@ -510,8 +484,6 @@ static int storvsc_queuecommand_lck(struct scsi_cmnd *scmnd, cmd_request = (struct storvsc_cmd_request *)scmnd->host_scribble; - DPRINT_INFO(STORVSC_DRV, "retrying scmnd %p cmd_request %p", - scmnd, cmd_request); goto retry_request; } @@ -752,11 +724,28 @@ static struct hv_driver storvsc_drv = { .remove = storvsc_remove, }; - /* - * storvsc_drv_init - StorVsc driver initialization. + * We use a DMI table to determine if we should autoload this driver This is + * needed by distro tools to determine if the hyperv drivers should be + * installed and/or configured. We don't do anything else with the table, but + * it needs to be present. */ -static int storvsc_drv_init(void) + +static const struct dmi_system_id __initconst +hv_stor_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_stor_dmi_table); + +static int __init storvsc_drv_init(void) { int ret; struct hv_driver *drv = &storvsc_drv; @@ -775,14 +764,13 @@ static int storvsc_drv_init(void) sizeof(struct vstor_packet) + sizeof(u64), sizeof(u64))); - memcpy(&drv->dev_type, &gStorVscDeviceType, + memcpy(&drv->dev_type, &stor_vsci_device_type, sizeof(struct hv_guid)); if (max_outstanding_req_per_channel < STORVSC_MAX_IO_REQUESTS) return -1; - drv->name = driver_name; drv->driver.name = driver_name; @@ -792,27 +780,13 @@ static int storvsc_drv_init(void) return ret; } -static void storvsc_drv_exit(void) +static void __exit storvsc_drv_exit(void) { vmbus_child_driver_unregister(&storvsc_drv.driver); } -static int __init storvsc_init(void) -{ - int ret; - - DPRINT_INFO(STORVSC_DRV, "Storvsc initializing...."); - ret = storvsc_drv_init(); - return ret; -} - -static void __exit storvsc_exit(void) -{ - storvsc_drv_exit(); -} - MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); MODULE_DESCRIPTION("Microsoft Hyper-V virtual storage driver"); -module_init(storvsc_init); -module_exit(storvsc_exit); +module_init(storvsc_drv_init); +module_exit(storvsc_drv_exit); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index ec1d38cd481c..1c949f5fb716 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -39,7 +39,7 @@ #include "hyperv_vmbus.h" -static struct pci_dev *hv_pci_dev; +static struct acpi_device *hv_acpi_dev; static struct tasklet_struct msg_dpc; static struct tasklet_struct event_dpc; @@ -49,7 +49,6 @@ EXPORT_SYMBOL(vmbus_loglevel); /* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */ /* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */ -static int pci_probe_error; static struct completion probe_event; static int irq; @@ -108,12 +107,12 @@ static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, char *buf) { - struct hv_device *device_ctx = device_to_hv_device(dev); + struct hv_device *hv_dev = device_to_hv_device(dev); struct hv_device_info device_info; memset(&device_info, 0, sizeof(struct hv_device_info)); - get_channel_info(device_ctx, &device_info); + get_channel_info(hv_dev, &device_info); if (!strcmp(dev_attr->attr.name, "class_id")) { return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" @@ -301,10 +300,10 @@ static int vmbus_match(struct device *device, struct device_driver *driver) { int match = 0; struct hv_driver *drv = drv_to_hv_drv(driver); - struct hv_device *device_ctx = device_to_hv_device(device); + struct hv_device *hv_dev = device_to_hv_device(device); /* We found our driver ? */ - if (memcmp(&device_ctx->dev_type, &drv->dev_type, + if (memcmp(&hv_dev->dev_type, &drv->dev_type, sizeof(struct hv_guid)) == 0) match = 1; @@ -330,7 +329,7 @@ static int vmbus_probe(struct device *child_device) } else { pr_err("probe not set for driver %s\n", dev_name(child_device)); - ret = -1; + ret = -ENODEV; } return ret; } @@ -353,7 +352,7 @@ static int vmbus_remove(struct device *child_device) } else { pr_err("remove not set for driver %s\n", dev_name(child_device)); - ret = -1; + ret = -ENODEV; } } @@ -388,9 +387,9 @@ static void vmbus_shutdown(struct device *child_device) */ static void vmbus_device_release(struct device *device) { - struct hv_device *device_ctx = device_to_hv_device(device); + struct hv_device *hv_dev = device_to_hv_device(device); - kfree(device_ctx); + kfree(hv_dev); } @@ -456,7 +455,7 @@ static void vmbus_on_msg_dpc(unsigned long data) * will not deliver any more messages since there is * no empty slot */ - mb(); + smp_mb(); if (msg->header.message_flags.msg_pending) { /* @@ -487,7 +486,6 @@ static int vmbus_on_isr(void) if (msg->header.message_type != HVMSG_NONE) ret |= 0x1; - /* TODO: Check if there are events to be process */ page_addr = hv_context.synic_event_page[cpu]; event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; @@ -528,7 +526,7 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) * - get the irq resource * - retrieve the channel offers */ -static int vmbus_bus_init(struct pci_dev *pdev) +static int vmbus_bus_init(int irq) { int ret; unsigned int vector; @@ -537,7 +535,7 @@ static int vmbus_bus_init(struct pci_dev *pdev) ret = hv_init(); if (ret != 0) { pr_err("Unable to initialize the hypervisor - 0x%x\n", ret); - goto cleanup; + return ret; } /* Initialize the bus context */ @@ -546,27 +544,23 @@ static int vmbus_bus_init(struct pci_dev *pdev) /* Now, register the bus with LDM */ ret = bus_register(&hv_bus); - if (ret) { - ret = -1; - goto cleanup; - } + if (ret) + return ret; /* Get the interrupt resource */ - ret = request_irq(pdev->irq, vmbus_isr, - IRQF_SHARED | IRQF_SAMPLE_RANDOM, - driver_name, pdev); + ret = request_irq(irq, vmbus_isr, IRQF_SAMPLE_RANDOM, + driver_name, hv_acpi_dev); if (ret != 0) { pr_err("Unable to request IRQ %d\n", - pdev->irq); + irq); bus_unregister(&hv_bus); - ret = -1; - goto cleanup; + return ret; } - vector = IRQ0_VECTOR + pdev->irq; + vector = IRQ0_VECTOR + irq; /* * Notify the hypervisor of our irq and @@ -575,16 +569,15 @@ static int vmbus_bus_init(struct pci_dev *pdev) on_each_cpu(hv_synic_init, (void *)&vector, 1); ret = vmbus_connect(); if (ret) { - free_irq(pdev->irq, pdev); + free_irq(irq, hv_acpi_dev); bus_unregister(&hv_bus); - goto cleanup; + return ret; } vmbus_request_offers(); -cleanup: - return ret; + return 0; } /** @@ -631,7 +624,6 @@ void vmbus_child_driver_unregister(struct device_driver *drv) driver_unregister(drv); - drv->bus = NULL; } EXPORT_SYMBOL(vmbus_child_driver_unregister); @@ -676,7 +668,7 @@ int vmbus_child_device_register(struct hv_device *child_device_obj) /* The new device belongs to this bus */ child_device_obj->device.bus = &hv_bus; /* device->dev.bus; */ - child_device_obj->device.parent = &hv_pci_dev->dev; + child_device_obj->device.parent = &hv_acpi_dev->dev; child_device_obj->device.release = vmbus_device_release; /* @@ -733,6 +725,8 @@ static int vmbus_acpi_add(struct acpi_device *device) { acpi_status result; + hv_acpi_dev = device; + result = acpi_walk_resources(device->handle, METHOD_NAME__CRS, vmbus_walk_resources, &irq); @@ -747,6 +741,7 @@ static int vmbus_acpi_add(struct acpi_device *device) static const struct acpi_device_id vmbus_acpi_device_ids[] = { {"VMBUS", 0}, + {"VMBus", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids); @@ -759,53 +754,6 @@ static struct acpi_driver vmbus_acpi_driver = { }, }; -static int vmbus_acpi_init(void) -{ - int result; - - - result = acpi_bus_register_driver(&vmbus_acpi_driver); - if (result < 0) - return result; - - return 0; -} - -static void vmbus_acpi_exit(void) -{ - acpi_bus_unregister_driver(&vmbus_acpi_driver); - - return; -} - - -static int __devinit hv_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - hv_pci_dev = pdev; - - pci_probe_error = pci_enable_device(pdev); - if (pci_probe_error) - goto probe_cleanup; - - /* - * If the PCI sub-sytem did not assign us an - * irq, use the bios provided one. - */ - - if (pdev->irq == 0) - pdev->irq = irq; - - pci_probe_error = vmbus_bus_init(pdev); - - if (pci_probe_error) - pci_disable_device(pdev); - -probe_cleanup: - complete(&probe_event); - return pci_probe_error; -} - /* * We use a PCI table to determine if we should autoload this driver This is * needed by distro tools to determine if the hyperv drivers should be @@ -818,13 +766,7 @@ static const struct pci_device_id microsoft_hv_pci_table[] = { }; MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table); -static struct pci_driver hv_bus_driver = { - .name = "hv_bus", - .probe = hv_pci_probe, - .id_table = microsoft_hv_pci_table, -}; - -static int __init hv_pci_init(void) +static int __init hv_acpi_init(void) { int ret; @@ -834,32 +776,22 @@ static int __init hv_pci_init(void) * Get irq resources first. */ - ret = vmbus_acpi_init(); + ret = acpi_bus_register_driver(&vmbus_acpi_driver); + if (ret) return ret; wait_for_completion(&probe_event); if (irq <= 0) { - vmbus_acpi_exit(); + acpi_bus_unregister_driver(&vmbus_acpi_driver); return -ENODEV; } - vmbus_acpi_exit(); - init_completion(&probe_event); - ret = pci_register_driver(&hv_bus_driver); + ret = vmbus_bus_init(irq); if (ret) - return ret; - /* - * All the vmbus initialization occurs within the - * hv_pci_probe() function. Wait for hv_pci_probe() - * to complete. - */ - wait_for_completion(&probe_event); - - if (pci_probe_error) - pci_unregister_driver(&hv_bus_driver); - return pci_probe_error; + acpi_bus_unregister_driver(&vmbus_acpi_driver); + return ret; } @@ -867,4 +799,4 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); module_param(vmbus_loglevel, int, S_IRUGO|S_IWUSR); -module_init(hv_pci_init); +module_init(hv_acpi_init); diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-light b/drivers/staging/iio/Documentation/sysfs-bus-iio-light index 21d277405816..edbf470e4e30 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio-light +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-light @@ -75,3 +75,11 @@ KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: This property gets/sets the sensors ADC analog integration time. + +What: /sys/bus/iio/devices/device[n]/illuminance0_calibscale +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Hardware or software applied calibration scale factor assumed + to account for attenuation due to industrial design (glass + filters or aperture holes). diff --git a/drivers/staging/iio/accel/adis16201.h b/drivers/staging/iio/accel/adis16201.h index 4cc1a5bfab40..dac5540b5a8e 100644 --- a/drivers/staging/iio/accel/adis16201.h +++ b/drivers/staging/iio/accel/adis16201.h @@ -64,19 +64,17 @@ /** * struct adis16201_state - device instance specific data * @us: actual spi_device - * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16201_state { - struct spi_device *us; - struct iio_dev *indio_dev; - struct iio_trigger *trig; - u8 *tx; - u8 *rx; - struct mutex buf_lock; + struct spi_device *us; + struct iio_trigger *trig; + struct mutex buf_lock; + u8 tx[14] ____cacheline_aligned; + u8 rx[14]; }; int adis16201_set_irq(struct iio_dev *indio_dev, bool enable); diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index e4c49f00d132..2fd01aecdf96 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -24,8 +24,6 @@ #include "adis16201.h" -#define DRIVER_NAME "adis16201" - enum adis16201_chan { in_supply, temp, @@ -42,13 +40,12 @@ enum adis16201_chan { * @reg_address: the address of the register to be written * @val: the value to write **/ -static int adis16201_spi_write_reg_8(struct device *dev, +static int adis16201_spi_write_reg_8(struct iio_dev *indio_dev, u8 reg_address, u8 val) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16201_state *st = iio_dev_get_devdata(indio_dev); + struct adis16201_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADIS16201_WRITE_REG(reg_address); @@ -73,7 +70,7 @@ static int adis16201_spi_write_reg_16(struct iio_dev *indio_dev, { int ret; struct spi_message msg; - struct adis16201_state *st = iio_dev_get_devdata(indio_dev); + struct adis16201_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { .tx_buf = st->tx, @@ -114,7 +111,7 @@ static int adis16201_spi_read_reg_16(struct iio_dev *indio_dev, u16 *val) { struct spi_message msg; - struct adis16201_state *st = iio_dev_get_devdata(indio_dev); + struct adis16201_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -151,14 +148,16 @@ static int adis16201_spi_read_reg_16(struct iio_dev *indio_dev, return ret; } -static int adis16201_reset(struct device *dev) +static int adis16201_reset(struct iio_dev *indio_dev) { int ret; - ret = adis16201_spi_write_reg_8(dev, + struct adis16201_state *st = iio_priv(indio_dev); + + ret = adis16201_spi_write_reg_8(indio_dev, ADIS16201_GLOB_CMD, ADIS16201_GLOB_CMD_SW_RESET); if (ret) - dev_err(dev, "problem resetting device"); + dev_err(&st->us->dev, "problem resetting device"); return ret; } @@ -167,15 +166,15 @@ static ssize_t adis16201_write_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { + int ret; + bool res; + if (len < 1) return -EINVAL; - switch (buf[0]) { - case '1': - case 'y': - case 'Y': - return adis16201_reset(dev); - } - return -EINVAL; + ret = strtobool(buf, &res); + if (ret || !res) + return ret; + return adis16201_reset(dev_get_drvdata(dev)); } int adis16201_set_irq(struct iio_dev *indio_dev, bool enable) @@ -245,41 +244,38 @@ static int adis16201_self_test(struct iio_dev *indio_dev) return ret; } -static int adis16201_initial_setup(struct adis16201_state *st) +static int adis16201_initial_setup(struct iio_dev *indio_dev) { int ret; - struct device *dev = &st->indio_dev->dev; + struct device *dev = &indio_dev->dev; /* Disable IRQ */ - ret = adis16201_set_irq(st->indio_dev, false); + ret = adis16201_set_irq(indio_dev, false); if (ret) { dev_err(dev, "disable irq failed"); goto err_ret; } /* Do self test */ - ret = adis16201_self_test(st->indio_dev); + ret = adis16201_self_test(indio_dev); if (ret) { dev_err(dev, "self test failure"); goto err_ret; } /* Read status register to check the result */ - ret = adis16201_check_status(st->indio_dev); + ret = adis16201_check_status(indio_dev); if (ret) { - adis16201_reset(dev); + adis16201_reset(indio_dev); dev_err(dev, "device not playing ball -> reset"); msleep(ADIS16201_STARTUP_DELAY); - ret = adis16201_check_status(st->indio_dev); + ret = adis16201_check_status(indio_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; } @@ -309,13 +305,17 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); addr = adis16201_addresses[chan->address][0]; ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16); - if (ret) + if (ret) { + mutex_unlock(&indio_dev->mlock); return ret; + } if (val16 & ADIS16201_ERROR_ACTIVE) { ret = adis16201_check_status(indio_dev); - if (ret) + if (ret) { + mutex_unlock(&indio_dev->mlock); return ret; + } } val16 = val16 & ((1 << chan->scan_type.realbits) - 1); if (chan->scan_type.sign == 's') @@ -467,53 +467,40 @@ static const struct iio_info adis16201_info = { static int __devinit adis16201_probe(struct spi_device *spi) { int ret, regdone = 0; - struct adis16201_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; + struct adis16201_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; goto error_ret; } + st = iio_priv(indio_dev); /* this is only used for removal purposes */ - spi_set_drvdata(spi, st); + spi_set_drvdata(spi, indio_dev); - /* Allocate the comms buffers */ - st->rx = kzalloc(sizeof(*st->rx)*ADIS16201_MAX_RX, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kzalloc(sizeof(*st->tx)*ADIS16201_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(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } - st->indio_dev->name = spi->dev.driver->name; - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &adis16201_info; + indio_dev->name = spi->dev.driver->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &adis16201_info; - st->indio_dev->channels = adis16201_channels; - st->indio_dev->num_channels = ARRAY_SIZE(adis16201_channels); - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = adis16201_channels; + indio_dev->num_channels = ARRAY_SIZE(adis16201_channels); + indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16201_configure_ring(st->indio_dev); + ret = adis16201_configure_ring(indio_dev); if (ret) goto error_free_dev; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_unreg_ring_funcs; regdone = 1; - ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0, + ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, adis16201_channels, ARRAY_SIZE(adis16201_channels)); if (ret) { @@ -522,50 +509,40 @@ static int __devinit adis16201_probe(struct spi_device *spi) } if (spi->irq) { - ret = adis16201_probe_trigger(st->indio_dev); + ret = adis16201_probe_trigger(indio_dev); if (ret) goto error_uninitialize_ring; } /* Get the device into a sane initial state */ - ret = adis16201_initial_setup(st); + ret = adis16201_initial_setup(indio_dev); if (ret) goto error_remove_trigger; return 0; error_remove_trigger: - adis16201_remove_trigger(st->indio_dev); + adis16201_remove_trigger(indio_dev); error_uninitialize_ring: - iio_ring_buffer_unregister(st->indio_dev->ring); + iio_ring_buffer_unregister(indio_dev->ring); error_unreg_ring_funcs: - adis16201_unconfigure_ring(st->indio_dev); + adis16201_unconfigure_ring(indio_dev); error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(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); + iio_free_device(indio_dev); error_ret: return ret; } static int adis16201_remove(struct spi_device *spi) { - struct adis16201_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = spi_get_drvdata(spi); adis16201_remove_trigger(indio_dev); iio_ring_buffer_unregister(indio_dev->ring); iio_device_unregister(indio_dev); adis16201_unconfigure_ring(indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); return 0; } diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c index c61f981255ca..66e708ddf8b2 100644 --- a/drivers/staging/iio/accel/adis16201_ring.c +++ b/drivers/staging/iio/accel/adis16201_ring.c @@ -23,7 +23,7 @@ static int adis16201_read_ring_data(struct iio_dev *indio_dev, u8 *rx) { struct spi_message msg; - struct adis16201_state *st = iio_dev_get_devdata(indio_dev); + struct adis16201_state *st = iio_priv(indio_dev); struct spi_transfer xfers[ADIS16201_OUTPUTS + 1]; int ret; int i; @@ -63,7 +63,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->private_data; - struct adis16201_state *st = iio_dev_get_devdata(indio_dev); + struct adis16201_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; int i = 0; @@ -77,7 +77,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p) } if (ring->scan_count) - if (adis16201_read_ring_data(st->indio_dev, st->rx) >= 0) + if (adis16201_read_ring_data(indio_dev, st->rx) >= 0) for (; i < ring->scan_count; i++) data[i] = be16_to_cpup( (__be16 *)&(st->rx[i*2])); @@ -88,7 +88,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p) ring->access->store_to(ring, (u8 *)data, pf->timestamp); - iio_trigger_notify_done(st->indio_dev->trig); + iio_trigger_notify_done(indio_dev->trig); kfree(data); return IRQ_HANDLED; diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c index bea917e03b42..3a95c083b452 100644 --- a/drivers/staging/iio/accel/adis16201_trigger.c +++ b/drivers/staging/iio/accel/adis16201_trigger.c @@ -17,17 +17,16 @@ static int adis16201_data_rdy_trigger_set_state(struct iio_trigger *trig, bool state) { - struct adis16201_state *st = trig->private_data; - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = trig->private_data; dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16201_set_irq(st->indio_dev, state); + return adis16201_set_irq(indio_dev, state); } int adis16201_probe_trigger(struct iio_dev *indio_dev) { int ret; - struct adis16201_state *st = indio_dev->dev_data; + struct adis16201_state *st = iio_priv(indio_dev); st->trig = iio_allocate_trigger("adis16201-dev%d", indio_dev->id); if (st->trig == NULL) { @@ -43,7 +42,7 @@ int adis16201_probe_trigger(struct iio_dev *indio_dev) goto error_free_trig; st->trig->dev.parent = &st->us->dev; st->trig->owner = THIS_MODULE; - st->trig->private_data = st; + st->trig->private_data = indio_dev; st->trig->set_trigger_state = &adis16201_data_rdy_trigger_set_state; ret = iio_trigger_register(st->trig); @@ -64,7 +63,7 @@ int adis16201_probe_trigger(struct iio_dev *indio_dev) void adis16201_remove_trigger(struct iio_dev *indio_dev) { - struct adis16201_state *state = indio_dev->dev_data; + struct adis16201_state *state = iio_priv(indio_dev); iio_trigger_unregister(state->trig); free_irq(state->us->irq, state->trig); diff --git a/drivers/staging/iio/accel/adis16203.h b/drivers/staging/iio/accel/adis16203.h index 175e21bb9b40..4071bc0d69ab 100644 --- a/drivers/staging/iio/accel/adis16203.h +++ b/drivers/staging/iio/accel/adis16203.h @@ -59,19 +59,17 @@ /** * struct adis16203_state - device instance specific data * @us: actual spi_device - * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16203_state { - struct spi_device *us; - struct iio_dev *indio_dev; - struct iio_trigger *trig; - u8 *tx; - u8 *rx; - struct mutex buf_lock; + struct spi_device *us; + struct iio_trigger *trig; + struct mutex buf_lock; + u8 tx[ADIS16203_MAX_TX] ____cacheline_aligned; + u8 rx[ADIS16203_MAX_RX]; }; int adis16203_set_irq(struct iio_dev *indio_dev, bool enable); diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 36be4d5dc614..bf1988884e93 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -36,7 +36,7 @@ static int adis16203_spi_write_reg_8(struct iio_dev *indio_dev, u8 val) { int ret; - struct adis16203_state *st = iio_dev_get_devdata(indio_dev); + struct adis16203_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADIS16203_WRITE_REG(reg_address); @@ -61,7 +61,7 @@ static int adis16203_spi_write_reg_16(struct iio_dev *indio_dev, { int ret; struct spi_message msg; - struct adis16203_state *st = iio_dev_get_devdata(indio_dev); + struct adis16203_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { .tx_buf = st->tx, @@ -102,7 +102,7 @@ static int adis16203_spi_read_reg_16(struct iio_dev *indio_dev, u16 *val) { struct spi_message msg; - struct adis16203_state *st = iio_dev_get_devdata(indio_dev); + struct adis16203_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -418,51 +418,38 @@ static const struct iio_info adis16203_info = { static int __devinit adis16203_probe(struct spi_device *spi) { int ret, regdone = 0; - struct adis16203_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; + struct iio_dev *indio_dev; + struct adis16203_state *st; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; goto error_ret; } + st = iio_priv(indio_dev); /* this is only used for removal purposes */ - spi_set_drvdata(spi, st); - - /* Allocate the comms buffers */ - st->rx = kzalloc(sizeof(*st->rx)*ADIS16203_MAX_RX, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kzalloc(sizeof(*st->tx)*ADIS16203_MAX_TX, GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_free_rx; - } + spi_set_drvdata(spi, indio_dev); st->us = spi; mutex_init(&st->buf_lock); - /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } - st->indio_dev->name = spi->dev.driver->name; - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->channels = adis16203_channels; - st->indio_dev->num_channels = ARRAY_SIZE(adis16203_channels); - st->indio_dev->info = &adis16203_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16203_configure_ring(st->indio_dev); + indio_dev->name = spi->dev.driver->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->channels = adis16203_channels; + indio_dev->num_channels = ARRAY_SIZE(adis16203_channels); + indio_dev->info = &adis16203_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16203_configure_ring(indio_dev); if (ret) goto error_free_dev; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_unreg_ring_funcs; regdone = 1; - ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0, + ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, adis16203_channels, ARRAY_SIZE(adis16203_channels)); if (ret) { @@ -471,50 +458,40 @@ static int __devinit adis16203_probe(struct spi_device *spi) } if (spi->irq) { - ret = adis16203_probe_trigger(st->indio_dev); + ret = adis16203_probe_trigger(indio_dev); if (ret) goto error_uninitialize_ring; } /* Get the device into a sane initial state */ - ret = adis16203_initial_setup(st->indio_dev); + ret = adis16203_initial_setup(indio_dev); if (ret) goto error_remove_trigger; return 0; error_remove_trigger: - adis16203_remove_trigger(st->indio_dev); + adis16203_remove_trigger(indio_dev); error_uninitialize_ring: - iio_ring_buffer_unregister(st->indio_dev->ring); + iio_ring_buffer_unregister(indio_dev->ring); error_unreg_ring_funcs: - adis16203_unconfigure_ring(st->indio_dev); + adis16203_unconfigure_ring(indio_dev); error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(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); + iio_free_device(indio_dev); error_ret: return ret; } static int adis16203_remove(struct spi_device *spi) { - struct adis16203_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = spi_get_drvdata(spi); adis16203_remove_trigger(indio_dev); iio_ring_buffer_unregister(indio_dev->ring); iio_device_unregister(indio_dev); adis16203_unconfigure_ring(indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); return 0; } diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c index a9a789d79c09..d2c07c527467 100644 --- a/drivers/staging/iio/accel/adis16203_ring.c +++ b/drivers/staging/iio/accel/adis16203_ring.c @@ -26,7 +26,7 @@ static int adis16203_read_ring_data(struct device *dev, u8 *rx) { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16203_state *st = iio_dev_get_devdata(indio_dev); + struct adis16203_state *st = iio_priv(indio_dev); struct spi_transfer xfers[ADIS16203_OUTPUTS + 1]; int ret; int i; @@ -68,7 +68,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->private_data; - struct adis16203_state *st = iio_dev_get_devdata(indio_dev); + struct adis16203_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; int i = 0; @@ -82,7 +82,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p) } if (ring->scan_count) - if (adis16203_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) + if (adis16203_read_ring_data(&indio_dev->dev, st->rx) >= 0) for (; i < ring->scan_count; i++) data[i] = be16_to_cpup( (__be16 *)&(st->rx[i*2])); @@ -95,7 +95,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p) (u8 *)data, pf->timestamp); - iio_trigger_notify_done(st->indio_dev->trig); + iio_trigger_notify_done(indio_dev->trig); kfree(data); return IRQ_HANDLED; diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c index ca5db1731988..3caf3e8bc9d9 100644 --- a/drivers/staging/iio/accel/adis16203_trigger.c +++ b/drivers/staging/iio/accel/adis16203_trigger.c @@ -18,17 +18,16 @@ static int adis16203_data_rdy_trigger_set_state(struct iio_trigger *trig, bool state) { - struct adis16203_state *st = trig->private_data; - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = trig->private_data; dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16203_set_irq(st->indio_dev, state); + return adis16203_set_irq(indio_dev, state); } int adis16203_probe_trigger(struct iio_dev *indio_dev) { int ret; - struct adis16203_state *st = indio_dev->dev_data; + struct adis16203_state *st = iio_priv(indio_dev); st->trig = iio_allocate_trigger("adis16203-dev%d", indio_dev->id); if (st->trig == NULL) { @@ -46,7 +45,7 @@ int adis16203_probe_trigger(struct iio_dev *indio_dev) st->trig->dev.parent = &st->us->dev; st->trig->owner = THIS_MODULE; - st->trig->private_data = st; + st->trig->private_data = indio_dev; st->trig->set_trigger_state = &adis16203_data_rdy_trigger_set_state; ret = iio_trigger_register(st->trig); @@ -67,9 +66,9 @@ int adis16203_probe_trigger(struct iio_dev *indio_dev) void adis16203_remove_trigger(struct iio_dev *indio_dev) { - struct adis16203_state *state = indio_dev->dev_data; + struct adis16203_state *st = iio_priv(indio_dev); - iio_trigger_unregister(state->trig); - free_irq(state->us->irq, state->trig); - iio_free_trigger(state->trig); + iio_trigger_unregister(st->trig); + free_irq(st->us->irq, st->trig); + iio_free_trigger(st->trig); } diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h index 1690c0d15690..3bb0490465f4 100644 --- a/drivers/staging/iio/accel/adis16204.h +++ b/drivers/staging/iio/accel/adis16204.h @@ -67,19 +67,17 @@ /** * struct adis16204_state - device instance specific data * @us: actual spi_device - * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16204_state { - struct spi_device *us; - struct iio_dev *indio_dev; - struct iio_trigger *trig; - u8 *tx; - u8 *rx; - struct mutex buf_lock; + struct spi_device *us; + struct iio_trigger *trig; + struct mutex buf_lock; + u8 tx[ADIS16204_MAX_TX] ____cacheline_aligned; + u8 rx[ADIS16204_MAX_RX]; }; int adis16204_set_irq(struct iio_dev *indio_dev, bool enable); diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 16806704bf48..cfd09b3b9937 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -39,7 +39,7 @@ static int adis16204_spi_write_reg_8(struct iio_dev *indio_dev, u8 val) { int ret; - struct adis16204_state *st = iio_dev_get_devdata(indio_dev); + struct adis16204_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADIS16204_WRITE_REG(reg_address); @@ -64,7 +64,7 @@ static int adis16204_spi_write_reg_16(struct iio_dev *indio_dev, { int ret; struct spi_message msg; - struct adis16204_state *st = iio_dev_get_devdata(indio_dev); + struct adis16204_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { .tx_buf = st->tx, @@ -106,7 +106,7 @@ static int adis16204_spi_read_reg_16(struct iio_dev *indio_dev, u16 *val) { struct spi_message msg; - struct adis16204_state *st = iio_dev_get_devdata(indio_dev); + struct adis16204_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -483,52 +483,38 @@ static const struct iio_info adis16204_info = { static int __devinit adis16204_probe(struct spi_device *spi) { int ret, regdone = 0; - struct adis16204_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; + struct adis16204_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; goto error_ret; } + st = iio_priv(indio_dev); /* this is only used for removal purposes */ - spi_set_drvdata(spi, st); - - /* Allocate the comms buffers */ - st->rx = kzalloc(sizeof(*st->rx)*ADIS16204_MAX_RX, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kzalloc(sizeof(*st->tx)*ADIS16204_MAX_TX, GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_free_rx; - } + spi_set_drvdata(spi, indio_dev); st->us = spi; mutex_init(&st->buf_lock); - /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } - st->indio_dev->name = spi->dev.driver->name; - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &adis16204_info; - st->indio_dev->channels = adis16204_channels; - st->indio_dev->num_channels = ARRAY_SIZE(adis16204_channels); - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = spi->dev.driver->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &adis16204_info; + indio_dev->channels = adis16204_channels; + indio_dev->num_channels = ARRAY_SIZE(adis16204_channels); + indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16204_configure_ring(st->indio_dev); + ret = adis16204_configure_ring(indio_dev); if (ret) goto error_free_dev; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_unreg_ring_funcs; regdone = 1; - ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0, + ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, adis16204_channels, ARRAY_SIZE(adis16204_channels)); if (ret) { @@ -537,50 +523,40 @@ static int __devinit adis16204_probe(struct spi_device *spi) } if (spi->irq) { - ret = adis16204_probe_trigger(st->indio_dev); + ret = adis16204_probe_trigger(indio_dev); if (ret) goto error_uninitialize_ring; } /* Get the device into a sane initial state */ - ret = adis16204_initial_setup(st->indio_dev); + ret = adis16204_initial_setup(indio_dev); if (ret) goto error_remove_trigger; return 0; error_remove_trigger: - adis16204_remove_trigger(st->indio_dev); + adis16204_remove_trigger(indio_dev); error_uninitialize_ring: - iio_ring_buffer_unregister(st->indio_dev->ring); + iio_ring_buffer_unregister(indio_dev->ring); error_unreg_ring_funcs: - adis16204_unconfigure_ring(st->indio_dev); + adis16204_unconfigure_ring(indio_dev); error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(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); + iio_free_device(indio_dev); error_ret: return ret; } static int adis16204_remove(struct spi_device *spi) { - struct adis16204_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = spi_get_drvdata(spi); adis16204_remove_trigger(indio_dev); - iio_ring_buffer_unregister(st->indio_dev->ring); + iio_ring_buffer_unregister(indio_dev->ring); iio_device_unregister(indio_dev); adis16204_unconfigure_ring(indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); return 0; } diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c index a2d36fb822e5..852df06684d8 100644 --- a/drivers/staging/iio/accel/adis16204_ring.c +++ b/drivers/staging/iio/accel/adis16204_ring.c @@ -26,7 +26,7 @@ static int adis16204_read_ring_data(struct device *dev, u8 *rx) { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16204_state *st = iio_dev_get_devdata(indio_dev); + struct adis16204_state *st = iio_priv(indio_dev); struct spi_transfer xfers[ADIS16204_OUTPUTS + 1]; int ret; int i; @@ -66,7 +66,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->private_data; - struct adis16204_state *st = iio_dev_get_devdata(indio_dev); + struct adis16204_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; int i = 0; s16 *data; @@ -79,7 +79,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p) } if (ring->scan_count) - if (adis16204_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) + if (adis16204_read_ring_data(&indio_dev->dev, st->rx) >= 0) for (; i < ring->scan_count; i++) data[i] = be16_to_cpup( (__be16 *)&(st->rx[i*2])); @@ -90,7 +90,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p) ring->access->store_to(ring, (u8 *)data, pf->timestamp); - iio_trigger_notify_done(st->indio_dev->trig); + iio_trigger_notify_done(indio_dev->trig); kfree(data); return IRQ_HANDLED; diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c index 5e1f9ae9d5c1..01f73b9b8886 100644 --- a/drivers/staging/iio/accel/adis16204_trigger.c +++ b/drivers/staging/iio/accel/adis16204_trigger.c @@ -18,17 +18,16 @@ static int adis16204_data_rdy_trigger_set_state(struct iio_trigger *trig, bool state) { - struct adis16204_state *st = trig->private_data; - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = trig->private_data; dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16204_set_irq(st->indio_dev, state); + return adis16204_set_irq(indio_dev, state); } int adis16204_probe_trigger(struct iio_dev *indio_dev) { int ret; - struct adis16204_state *st = indio_dev->dev_data; + struct adis16204_state *st = iio_priv(indio_dev); st->trig = iio_allocate_trigger("adis16204-dev%d", indio_dev->id); if (st->trig == NULL) { @@ -46,7 +45,7 @@ int adis16204_probe_trigger(struct iio_dev *indio_dev) st->trig->dev.parent = &st->us->dev; st->trig->owner = THIS_MODULE; - st->trig->private_data = st; + st->trig->private_data = indio_dev; st->trig->set_trigger_state = &adis16204_data_rdy_trigger_set_state; ret = iio_trigger_register(st->trig); @@ -67,7 +66,7 @@ int adis16204_probe_trigger(struct iio_dev *indio_dev) void adis16204_remove_trigger(struct iio_dev *indio_dev) { - struct adis16204_state *state = indio_dev->dev_data; + struct adis16204_state *state = iio_priv(indio_dev); iio_trigger_unregister(state->trig); free_irq(state->us->irq, state->trig); diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h index 3153cbee0957..c8b7b00d417a 100644 --- a/drivers/staging/iio/accel/adis16209.h +++ b/drivers/staging/iio/accel/adis16209.h @@ -104,19 +104,17 @@ /** * struct adis16209_state - device instance specific data * @us: actual spi_device - * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16209_state { - struct spi_device *us; - struct iio_dev *indio_dev; - struct iio_trigger *trig; - u8 *tx; - u8 *rx; - struct mutex buf_lock; + struct spi_device *us; + struct iio_trigger *trig; + struct mutex buf_lock; + u8 tx[ADIS16209_MAX_TX] ____cacheline_aligned; + u8 rx[ADIS16209_MAX_RX]; }; int adis16209_set_irq(struct iio_dev *indio_dev, bool enable); diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index c423cc960254..55f3a7bcaf0a 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -37,7 +37,7 @@ static int adis16209_spi_write_reg_8(struct iio_dev *indio_dev, u8 val) { int ret; - struct adis16209_state *st = iio_dev_get_devdata(indio_dev); + struct adis16209_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADIS16209_WRITE_REG(reg_address); @@ -62,7 +62,7 @@ static int adis16209_spi_write_reg_16(struct iio_dev *indio_dev, { int ret; struct spi_message msg; - struct adis16209_state *st = iio_dev_get_devdata(indio_dev); + struct adis16209_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { .tx_buf = st->tx, @@ -105,7 +105,7 @@ static int adis16209_spi_read_reg_16(struct iio_dev *indio_dev, u16 *val) { struct spi_message msg; - struct adis16209_state *st = iio_dev_get_devdata(indio_dev); + struct adis16209_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -466,52 +466,38 @@ static const struct iio_info adis16209_info = { 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; + struct adis16209_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; goto error_ret; } + st = iio_priv(indio_dev); /* 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; - } + spi_set_drvdata(spi, indio_dev); st->us = spi; mutex_init(&st->buf_lock); - /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } - st->indio_dev->name = spi->dev.driver->name; - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &adis16209_info; - st->indio_dev->channels = adis16209_channels; - st->indio_dev->num_channels = ARRAY_SIZE(adis16209_channels); - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = spi->dev.driver->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &adis16209_info; + indio_dev->channels = adis16209_channels; + indio_dev->num_channels = ARRAY_SIZE(adis16209_channels); + indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16209_configure_ring(st->indio_dev); + ret = adis16209_configure_ring(indio_dev); if (ret) goto error_free_dev; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_unreg_ring_funcs; regdone = 1; - ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0, + ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, adis16209_channels, ARRAY_SIZE(adis16209_channels)); if (ret) { @@ -520,42 +506,35 @@ static int __devinit adis16209_probe(struct spi_device *spi) } if (spi->irq) { - ret = adis16209_probe_trigger(st->indio_dev); + ret = adis16209_probe_trigger(indio_dev); if (ret) goto error_uninitialize_ring; } /* Get the device into a sane initial state */ - ret = adis16209_initial_setup(st->indio_dev); + ret = adis16209_initial_setup(indio_dev); if (ret) goto error_remove_trigger; return 0; error_remove_trigger: - adis16209_remove_trigger(st->indio_dev); + adis16209_remove_trigger(indio_dev); error_uninitialize_ring: - iio_ring_buffer_unregister(st->indio_dev->ring); + iio_ring_buffer_unregister(indio_dev->ring); error_unreg_ring_funcs: - adis16209_unconfigure_ring(st->indio_dev); + adis16209_unconfigure_ring(indio_dev); error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(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); + iio_free_device(indio_dev); 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; + struct iio_dev *indio_dev = spi_get_drvdata(spi); flush_scheduled_work(); @@ -563,9 +542,6 @@ static int adis16209_remove(struct spi_device *spi) iio_ring_buffer_unregister(indio_dev->ring); iio_device_unregister(indio_dev); adis16209_unconfigure_ring(indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); return 0; } diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index 390908b3f02f..45017d3f02f5 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -26,7 +26,7 @@ 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 adis16209_state *st = iio_priv(indio_dev); struct spi_transfer xfers[ADIS16209_OUTPUTS + 1]; int ret; int i; @@ -66,7 +66,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->private_data; - struct adis16209_state *st = iio_dev_get_devdata(indio_dev); + struct adis16209_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; int i = 0; @@ -80,7 +80,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p) } if (ring->scan_count && - adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) + adis16209_read_ring_data(&indio_dev->dev, st->rx) >= 0) for (; i < ring->scan_count; i++) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); @@ -90,7 +90,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p) ring->access->store_to(ring, (u8 *)data, pf->timestamp); - iio_trigger_notify_done(st->indio_dev->trig); + iio_trigger_notify_done(indio_dev->trig); kfree(data); return IRQ_HANDLED; diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c index 211ee7045697..6df7b47ec7b4 100644 --- a/drivers/staging/iio/accel/adis16209_trigger.c +++ b/drivers/staging/iio/accel/adis16209_trigger.c @@ -27,17 +27,16 @@ static irqreturn_t adis16209_data_rdy_trig_poll(int irq, void *trig) 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; + struct iio_dev *indio_dev = trig->private_data; dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16209_set_irq(st->indio_dev, state); + return adis16209_set_irq(indio_dev, state); } int adis16209_probe_trigger(struct iio_dev *indio_dev) { int ret; - struct adis16209_state *st = indio_dev->dev_data; + struct adis16209_state *st = iio_priv(indio_dev); st->trig = iio_allocate_trigger("adis16209-dev%d", indio_dev->id); if (st->trig == NULL) { @@ -54,7 +53,7 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev) goto error_free_trig; st->trig->dev.parent = &st->us->dev; st->trig->owner = THIS_MODULE; - st->trig->private_data = st; + st->trig->private_data = indio_dev; st->trig->set_trigger_state = &adis16209_data_rdy_trigger_set_state; ret = iio_trigger_register(st->trig); @@ -75,9 +74,9 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev) void adis16209_remove_trigger(struct iio_dev *indio_dev) { - struct adis16209_state *state = indio_dev->dev_data; + struct adis16209_state *st = iio_priv(indio_dev); - iio_trigger_unregister(state->trig); - free_irq(state->us->irq, state->trig); - iio_free_trigger(state->trig); + iio_trigger_unregister(st->trig); + free_irq(st->us->irq, st->trig); + iio_free_trigger(st->trig); } diff --git a/drivers/staging/iio/accel/adis16220.h b/drivers/staging/iio/accel/adis16220.h index 4d5758c2c047..024313cf5cf0 100644 --- a/drivers/staging/iio/accel/adis16220.h +++ b/drivers/staging/iio/accel/adis16220.h @@ -126,21 +126,15 @@ /** * struct adis16220_state - device instance specific data * @us: actual spi_device - * @work_trigger_to_ring: bh for triggered event handling - * @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: receive 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 mutex buf_lock; + struct spi_device *us; + struct mutex buf_lock; + u8 tx[ADIS16220_MAX_TX] ____cacheline_aligned; + u8 rx[ADIS16220_MAX_RX]; }; #endif /* SPI_ADIS16220_H_ */ diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index 605a75ea3996..bf9ba07c0383 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -39,7 +39,7 @@ static int adis16220_spi_write_reg_8(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16220_state *st = iio_dev_get_devdata(indio_dev); + struct adis16220_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADIS16220_WRITE_REG(reg_address); @@ -65,7 +65,7 @@ static int adis16220_spi_write_reg_16(struct device *dev, 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 adis16220_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { .tx_buf = st->tx, @@ -110,7 +110,7 @@ static int adis16220_spi_read_reg_16(struct device *dev, { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16220_state *st = iio_dev_get_devdata(indio_dev); + struct adis16220_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -316,10 +316,10 @@ static int adis16220_self_test(struct device *dev) return ret; } -static int adis16220_initial_setup(struct adis16220_state *st) +static int adis16220_initial_setup(struct iio_dev *indio_dev) { int ret; - struct device *dev = &st->indio_dev->dev; + struct device *dev = &indio_dev->dev; /* Do self test */ ret = adis16220_self_test(dev); @@ -341,19 +341,17 @@ static int adis16220_initial_setup(struct adis16220_state *st) } } - 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, +static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, char *buf, loff_t off, size_t count, int addr) { + struct adis16220_state *st = iio_priv(indio_dev); struct spi_message msg; struct spi_transfer xfers[] = { { @@ -383,7 +381,7 @@ static ssize_t adis16220_capture_buffer_read(struct adis16220_state *st, count = ADIS16220_CAPTURE_SIZE - off; /* write the begin position of capture buffer */ - ret = adis16220_spi_write_reg_16(&st->indio_dev->dev, + ret = adis16220_spi_write_reg_16(&indio_dev->dev, ADIS16220_CAPT_PNTR, off > 1); if (ret) @@ -422,9 +420,8 @@ static ssize_t adis16220_accel_bin_read(struct file *filp, struct kobject *kobj, { 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, + return adis16220_capture_buffer_read(indio_dev, buf, off, count, ADIS16220_CAPT_BUFA); } @@ -445,9 +442,8 @@ static ssize_t adis16220_adc1_bin_read(struct file *filp, struct kobject *kobj, { 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, + return adis16220_capture_buffer_read(indio_dev, buf, off, count, ADIS16220_CAPT_BUF1); } @@ -468,9 +464,8 @@ static ssize_t adis16220_adc2_bin_read(struct file *filp, struct kobject *kobj, { 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, + return adis16220_capture_buffer_read(indio_dev, buf, off, count, ADIS16220_CAPT_BUF2); } @@ -551,98 +546,76 @@ static const struct iio_info adis16220_info = { 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; + struct adis16220_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + 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 = iio_priv(indio_dev); + /* this is only used for removal purposes */ + spi_set_drvdata(spi, indio_dev); + st->us = spi; mutex_init(&st->buf_lock); - /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } - st->indio_dev->name = spi->dev.driver->name; - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &adis16220_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = spi->dev.driver->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &adis16220_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; regdone = 1; - ret = sysfs_create_bin_file(&st->indio_dev->dev.kobj, &accel_bin); + ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &accel_bin); if (ret) goto error_free_dev; - ret = sysfs_create_bin_file(&st->indio_dev->dev.kobj, &adc1_bin); + ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &adc1_bin); if (ret) goto error_rm_accel_bin; - ret = sysfs_create_bin_file(&st->indio_dev->dev.kobj, &adc2_bin); + ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &adc2_bin); if (ret) goto error_rm_adc1_bin; /* Get the device into a sane initial state */ - ret = adis16220_initial_setup(st); + ret = adis16220_initial_setup(indio_dev); if (ret) goto error_rm_adc2_bin; return 0; error_rm_adc2_bin: - sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &adc2_bin); + sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin); error_rm_adc1_bin: - sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &adc1_bin); + sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin); error_rm_accel_bin: - sysfs_remove_bin_file(&st->indio_dev->dev.kobj, &accel_bin); + sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin); error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(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); + iio_free_device(indio_dev); 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; + struct iio_dev *indio_dev = spi_get_drvdata(spi); flush_scheduled_work(); - 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); + sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin); + sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin); + sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin); iio_device_unregister(indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); return 0; } diff --git a/drivers/staging/iio/accel/adis16240.h b/drivers/staging/iio/accel/adis16240.h index 162b1f468a1a..f1dd047aa5e0 100644 --- a/drivers/staging/iio/accel/adis16240.h +++ b/drivers/staging/iio/accel/adis16240.h @@ -126,24 +126,21 @@ /** * struct adis16240_state - device instance specific data * @us: actual spi_device - * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio * @tx: transmit buffer * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16240_state { - struct spi_device *us; - struct iio_dev *indio_dev; - struct iio_trigger *trig; - u8 *tx; - u8 *rx; - struct mutex buf_lock; + struct spi_device *us; + struct iio_trigger *trig; + struct mutex buf_lock; + u8 tx[ADIS16240_MAX_TX] ____cacheline_aligned; + u8 rx[ADIS16240_MAX_RX]; }; int adis16240_set_irq(struct iio_dev *indio_dev, bool enable); -#ifdef CONFIG_IIO_RING_BUFFER /* At the moment triggers are only used for ring buffer * filling. This may change! */ @@ -155,6 +152,7 @@ int adis16240_set_irq(struct iio_dev *indio_dev, bool enable); #define ADIS16240_SCAN_AUX_ADC 4 #define ADIS16240_SCAN_TEMP 5 +#ifdef CONFIG_IIO_RING_BUFFER void adis16240_remove_trigger(struct iio_dev *indio_dev); int adis16240_probe_trigger(struct iio_dev *indio_dev); diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index ac6038557b0d..4a4eafc58630 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -41,7 +41,7 @@ static int adis16240_spi_write_reg_8(struct iio_dev *indio_dev, u8 val) { int ret; - struct adis16240_state *st = iio_dev_get_devdata(indio_dev); + struct adis16240_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADIS16240_WRITE_REG(reg_address); @@ -66,7 +66,7 @@ static int adis16240_spi_write_reg_16(struct iio_dev *indio_dev, { int ret; struct spi_message msg; - struct adis16240_state *st = iio_dev_get_devdata(indio_dev); + struct adis16240_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { .tx_buf = st->tx, @@ -109,7 +109,7 @@ static int adis16240_spi_read_reg_16(struct iio_dev *indio_dev, u16 *val) { struct spi_message msg; - struct adis16240_state *st = iio_dev_get_devdata(indio_dev); + struct adis16240_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -517,52 +517,39 @@ static const struct iio_info adis16240_info = { 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; + struct adis16240_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; goto error_ret; } + st = iio_priv(indio_dev); /* this is only used for removal purposes */ - spi_set_drvdata(spi, st); + spi_set_drvdata(spi, indio_dev); - /* 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(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } - st->indio_dev->name = spi->dev.driver->name; - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &adis16240_info; - st->indio_dev->channels = adis16240_channels; - st->indio_dev->num_channels = ARRAY_SIZE(adis16240_channels); - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = spi->dev.driver->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &adis16240_info; + indio_dev->channels = adis16240_channels; + indio_dev->num_channels = ARRAY_SIZE(adis16240_channels); + indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16240_configure_ring(st->indio_dev); + ret = adis16240_configure_ring(indio_dev); if (ret) goto error_free_dev; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_unreg_ring_funcs; regdone = 1; - ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0, + ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, adis16240_channels, ARRAY_SIZE(adis16240_channels)); if (ret) { @@ -571,42 +558,36 @@ static int __devinit adis16240_probe(struct spi_device *spi) } if (spi->irq) { - ret = adis16240_probe_trigger(st->indio_dev); + ret = adis16240_probe_trigger(indio_dev); if (ret) goto error_uninitialize_ring; } /* Get the device into a sane initial state */ - ret = adis16240_initial_setup(st->indio_dev); + ret = adis16240_initial_setup(indio_dev); if (ret) goto error_remove_trigger; return 0; error_remove_trigger: - adis16240_remove_trigger(st->indio_dev); + adis16240_remove_trigger(indio_dev); error_uninitialize_ring: - iio_ring_buffer_unregister(st->indio_dev->ring); + iio_ring_buffer_unregister(indio_dev->ring); error_unreg_ring_funcs: - adis16240_unconfigure_ring(st->indio_dev); + adis16240_unconfigure_ring(indio_dev); error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(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); + iio_free_device(indio_dev); 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; + + struct iio_dev *indio_dev = spi_get_drvdata(spi); flush_scheduled_work(); @@ -614,9 +595,6 @@ static int adis16240_remove(struct spi_device *spi) iio_ring_buffer_unregister(indio_dev->ring); iio_device_unregister(indio_dev); adis16240_unconfigure_ring(indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); return 0; } diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c index 0c6d781d94c6..c812a34dacaf 100644 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -26,7 +26,7 @@ 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 adis16240_state *st = iio_priv(indio_dev); struct spi_transfer xfers[ADIS16240_OUTPUTS + 1]; int ret; int i; @@ -63,7 +63,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->private_data; - struct adis16240_state *st = iio_dev_get_devdata(indio_dev); + struct adis16240_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; int i = 0; @@ -77,7 +77,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p) } if (ring->scan_count && - adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) + adis16240_read_ring_data(&indio_dev->dev, st->rx) >= 0) for (; i < ring->scan_count; i++) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); @@ -87,7 +87,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p) ring->access->store_to(ring, (u8 *)data, pf->timestamp); - iio_trigger_notify_done(st->indio_dev->trig); + iio_trigger_notify_done(indio_dev->trig); kfree(data); return IRQ_HANDLED; diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c index ece3ca8fb7eb..17135fc33c99 100644 --- a/drivers/staging/iio/accel/adis16240_trigger.c +++ b/drivers/staging/iio/accel/adis16240_trigger.c @@ -27,17 +27,16 @@ static irqreturn_t adis16240_data_rdy_trig_poll(int irq, void *trig) 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; + struct iio_dev *indio_dev = trig->private_data; dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16240_set_irq(st->indio_dev, state); + return adis16240_set_irq(indio_dev, state); } int adis16240_probe_trigger(struct iio_dev *indio_dev) { int ret; - struct adis16240_state *st = indio_dev->dev_data; + struct adis16240_state *st = iio_priv(indio_dev); st->trig = iio_allocate_trigger("adis16240-dev%d", indio_dev->id); if (st->trig == NULL) { @@ -55,7 +54,7 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev) st->trig->dev.parent = &st->us->dev; st->trig->owner = THIS_MODULE; - st->trig->private_data = st; + st->trig->private_data = indio_dev; st->trig->set_trigger_state = &adis16240_data_rdy_trigger_set_state; ret = iio_trigger_register(st->trig); @@ -76,9 +75,9 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev) void adis16240_remove_trigger(struct iio_dev *indio_dev) { - struct adis16240_state *state = indio_dev->dev_data; + struct adis16240_state *st = iio_priv(indio_dev); - iio_trigger_unregister(state->trig); - free_irq(state->us->irq, state->trig); - iio_free_trigger(state->trig); + iio_trigger_unregister(st->trig); + free_irq(st->us->irq, st->trig); + iio_free_trigger(st->trig); } diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index 973156e75773..c8a358a5df87 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -56,17 +56,15 @@ /** * struct kxsd9_state - device related storage * @buf_lock: protect the rx and tx buffers. - * @indio_dev: associated industrial IO device * @us: spi device * @rx: single rx buffer storage * @tx: single tx buffer storage **/ struct kxsd9_state { struct mutex buf_lock; - struct iio_dev *indio_dev; struct spi_device *us; - u8 *rx; - u8 *tx; + u8 rx[KXSD9_STATE_RX_SIZE] ____cacheline_aligned; + u8 tx[KXSD9_STATE_TX_SIZE]; }; /* This may want to move to mili g to allow for non integer ranges */ @@ -77,7 +75,7 @@ static ssize_t kxsd9_read_scale(struct device *dev, int ret; ssize_t len = 0; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct kxsd9_state *st = indio_dev->dev_data; + struct kxsd9_state *st = iio_priv(indio_dev); struct spi_transfer xfer = { .bits_per_word = 8, .len = 2, @@ -125,7 +123,7 @@ static ssize_t kxsd9_write_scale(struct device *dev, struct spi_message msg; int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct kxsd9_state *st = indio_dev->dev_data; + struct kxsd9_state *st = iio_priv(indio_dev); u8 val; struct spi_transfer xfers[] = { { @@ -190,7 +188,7 @@ static ssize_t kxsd9_read_accel(struct device *dev, u16 val; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct kxsd9_state *st = indio_dev->dev_data; + struct kxsd9_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { .bits_per_word = 8, @@ -253,52 +251,32 @@ static const struct attribute_group kxsd9_attribute_group = { .attrs = kxsd9_attributes, }; -static int __devinit kxsd9_power_up(struct spi_device *spi) +static int __devinit kxsd9_power_up(struct kxsd9_state *st) { - int ret; struct spi_transfer xfers[2] = { { .bits_per_word = 8, .len = 2, .cs_change = 1, + .tx_buf = st->tx, }, { .bits_per_word = 8, .len = 2, .cs_change = 1, + .tx_buf = st->tx + 2, }, }; struct spi_message msg; - u8 *tx2; - u8 *tx = kmalloc(2, GFP_KERNEL); + st->tx[0] = 0x0d; + st->tx[1] = 0x40; + st->tx[2] = 0x0c; + st->tx[3] = 0x9b; - if (tx == NULL) { - ret = -ENOMEM; - goto error_ret; - } - tx2 = kmalloc(2, GFP_KERNEL); - if (tx2 == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } - tx[0] = 0x0d; - tx[1] = 0x40; - - tx2[0] = 0x0c; - tx2[1] = 0x9b; - - xfers[0].tx_buf = tx; - xfers[1].tx_buf = tx2; spi_message_init(&msg); spi_message_add_tail(&xfers[0], &msg); spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(spi, &msg); - - kfree(tx2); -error_free_tx: - kfree(tx); -error_ret: - return ret; + return spi_sync(st->us, &msg); }; static const struct iio_info kxsd9_info = { @@ -308,72 +286,44 @@ static const struct iio_info kxsd9_info = { static int __devinit kxsd9_probe(struct spi_device *spi) { - + struct iio_dev *indio_dev; struct kxsd9_state *st; int ret = 0; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; } - spi_set_drvdata(spi, st); - - st->rx = kmalloc(sizeof(*st->rx)*KXSD9_STATE_RX_SIZE, - GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kmalloc(sizeof(*st->tx)*KXSD9_STATE_TX_SIZE, - GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_free_rx; - } + st = iio_priv(indio_dev); + spi_set_drvdata(spi, indio_dev); st->us = spi; mutex_init(&st->buf_lock); - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &kxsd9_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(st->indio_dev); + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &kxsd9_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; spi->mode = SPI_MODE_0; spi_setup(spi); - kxsd9_power_up(spi); + kxsd9_power_up(st); return 0; error_free_dev: - iio_free_device(st->indio_dev); -error_free_tx: - kfree(st->tx); -error_free_rx: - kfree(st->rx); -error_free_st: - kfree(st); + iio_free_device(indio_dev); error_ret: return ret; } static int __devexit kxsd9_remove(struct spi_device *spi) { - struct kxsd9_state *st = spi_get_drvdata(spi); - - iio_device_unregister(st->indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); + iio_device_unregister(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index ba5bc679204f..a29dfd27d440 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -676,7 +676,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) } st = iio_priv(indio_dev); /* this is only used tor removal purposes */ - spi_set_drvdata(spi, st); + spi_set_drvdata(spi, indio_dev); st->us = spi; mutex_init(&st->buf_lock); diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h index cf0751d917a9..1e396cefdf6e 100644 --- a/drivers/staging/iio/accel/sca3000.h +++ b/drivers/staging/iio/accel/sca3000.h @@ -173,7 +173,6 @@ struct sca3000_state { struct spi_device *us; const struct sca3000_chip_info *info; - struct iio_dev *indio_dev; struct work_struct interrupt_handler_ws; s64 last_timestamp; int mo_det_use_count; diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index f213b8698eb2..603f5bca797c 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -242,7 +242,7 @@ static int sca3000_check_status(struct device *dev) { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); mutex_lock(&st->lock); ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_STATUS, 1); @@ -269,7 +269,7 @@ static ssize_t sca3000_show_rev(struct device *dev, { int len = 0, ret; struct iio_dev *dev_info = dev_get_drvdata(dev); - struct sca3000_state *st = dev_info->dev_data; + struct sca3000_state *st = iio_priv(dev_info); mutex_lock(&st->lock); ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_REVID, 1); @@ -297,7 +297,7 @@ sca3000_show_available_measurement_modes(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct sca3000_state *st = dev_info->dev_data; + struct sca3000_state *st = iio_priv(dev_info); int len = 0; len += sprintf(buf + len, "0 - normal mode"); @@ -329,7 +329,7 @@ sca3000_show_measurement_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct sca3000_state *st = dev_info->dev_data; + struct sca3000_state *st = iio_priv(dev_info); int len = 0, ret; mutex_lock(&st->lock); @@ -380,7 +380,7 @@ sca3000_store_measurement_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct sca3000_state *st = dev_info->dev_data; + struct sca3000_state *st = iio_priv(dev_info); int ret; int mask = 0x03; long val; @@ -453,7 +453,7 @@ static int sca3000_read_raw(struct iio_dev *indio_dev, int *val2, long mask) { - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); int ret; u8 address; @@ -500,7 +500,7 @@ static ssize_t sca3000_read_av_freq(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); int len = 0, ret, val; mutex_lock(&st->lock); @@ -571,7 +571,7 @@ static ssize_t sca3000_read_frequency(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); int ret, len = 0, base_freq = 0, val; mutex_lock(&st->lock); @@ -613,7 +613,7 @@ static ssize_t sca3000_set_frequency(struct device *dev, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); int ret, base_freq = 0; int ctrlval; long val; @@ -673,7 +673,7 @@ static ssize_t sca3000_read_temp(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); int ret; int val; ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_TEMP_MSB, 2); @@ -699,7 +699,7 @@ static int sca3000_read_thresh(struct iio_dev *indio_dev, int *val) { int ret, i; - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e); mutex_lock(&st->lock); ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]); @@ -726,7 +726,7 @@ static int sca3000_write_thresh(struct iio_dev *indio_dev, int e, int val) { - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e); int ret; int i; @@ -798,11 +798,10 @@ static const struct attribute_group sca3000_attribute_group_with_temp = { static irqreturn_t sca3000_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; - struct sca3000_state *st; + struct sca3000_state *st = iio_priv(indio_dev); int ret, val; s64 last_timestamp = iio_get_time_ns(); - st = indio_dev->dev_data; /* Could lead if badly timed to an extra read of status reg, * but ensures no interrupt is missed. */ @@ -813,10 +812,10 @@ static irqreturn_t sca3000_event_handler(int irq, void *private) if (ret) goto done; - sca3000_ring_int_process(val, st->indio_dev->ring); + sca3000_ring_int_process(val, indio_dev->ring); if (val & SCA3000_INT_STATUS_FREE_FALL) - iio_push_event(st->indio_dev, 0, + iio_push_event(indio_dev, 0, IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, 0, IIO_EV_MOD_X_AND_Y_AND_Z, @@ -825,7 +824,7 @@ static irqreturn_t sca3000_event_handler(int irq, void *private) last_timestamp); if (val & SCA3000_INT_STATUS_Y_TRIGGER) - iio_push_event(st->indio_dev, 0, + iio_push_event(indio_dev, 0, IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, 0, IIO_EV_MOD_Y, @@ -834,7 +833,7 @@ static irqreturn_t sca3000_event_handler(int irq, void *private) last_timestamp); if (val & SCA3000_INT_STATUS_X_TRIGGER) - iio_push_event(st->indio_dev, 0, + iio_push_event(indio_dev, 0, IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, 0, IIO_EV_MOD_X, @@ -843,7 +842,7 @@ static irqreturn_t sca3000_event_handler(int irq, void *private) last_timestamp); if (val & SCA3000_INT_STATUS_Z_TRIGGER) - iio_push_event(st->indio_dev, 0, + iio_push_event(indio_dev, 0, IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, 0, IIO_EV_MOD_Z, @@ -861,7 +860,7 @@ static irqreturn_t sca3000_event_handler(int irq, void *private) static int sca3000_read_event_config(struct iio_dev *indio_dev, int e) { - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); int ret; u8 protect_mask = 0x03; int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e); @@ -895,7 +894,7 @@ static ssize_t sca3000_query_free_fall_mode(struct device *dev, { int ret, len; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); int val; mutex_lock(&st->lock); @@ -923,7 +922,7 @@ static ssize_t sca3000_set_free_fall_mode(struct device *dev, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); long val; int ret; u8 protect_mask = SCA3000_FREE_FALL_DETECT; @@ -965,7 +964,7 @@ static int sca3000_write_event_config(struct iio_dev *indio_dev, int e, int state) { - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); int ret, ctrlval; u8 protect_mask = 0x03; int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e); @@ -1126,42 +1125,38 @@ static int __devinit sca3000_probe(struct spi_device *spi) { int ret, regdone = 0; struct sca3000_state *st; + struct iio_dev *indio_dev; - st = kzalloc(sizeof(struct sca3000_state), GFP_KERNEL); - if (st == NULL) { + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; } - spi_set_drvdata(spi, st); + st = iio_priv(indio_dev); + spi_set_drvdata(spi, indio_dev); st->us = spi; mutex_init(&st->lock); st->info = &sca3000_spi_chip_info_tbl[spi_get_device_id(spi) ->driver_data]; - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_clear_st; - } - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; if (st->info->temp_output) - st->indio_dev->info = &sca3000_info_with_temp; + indio_dev->info = &sca3000_info_with_temp; else { - st->indio_dev->info = &sca3000_info; - st->indio_dev->channels = sca3000_channels; - st->indio_dev->num_channels = ARRAY_SIZE(sca3000_channels); + indio_dev->info = &sca3000_info; + indio_dev->channels = sca3000_channels; + indio_dev->num_channels = ARRAY_SIZE(sca3000_channels); } - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->modes = INDIO_DIRECT_MODE; - sca3000_configure_ring(st->indio_dev); - ret = iio_device_register(st->indio_dev); + sca3000_configure_ring(indio_dev); + ret = iio_device_register(indio_dev); if (ret < 0) goto error_free_dev; regdone = 1; - ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0, + ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, sca3000_channels, ARRAY_SIZE(sca3000_channels)); if (ret < 0) @@ -1172,11 +1167,11 @@ static int __devinit sca3000_probe(struct spi_device *spi) &sca3000_event_handler, IRQF_TRIGGER_FALLING, "sca3000", - st->indio_dev); + indio_dev); if (ret) goto error_unregister_ring; } - sca3000_register_ring_funcs(st->indio_dev); + sca3000_register_ring_funcs(indio_dev); ret = sca3000_clean_setup(st); if (ret) goto error_free_irq; @@ -1184,17 +1179,16 @@ static int __devinit sca3000_probe(struct spi_device *spi) error_free_irq: if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) - free_irq(spi->irq, st->indio_dev); + free_irq(spi->irq, indio_dev); error_unregister_ring: - iio_ring_buffer_unregister(st->indio_dev->ring); + iio_ring_buffer_unregister(indio_dev->ring); error_unregister_dev: error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(indio_dev); else - iio_free_device(st->indio_dev); -error_clear_st: - kfree(st); + iio_free_device(indio_dev); + error_ret: return ret; } @@ -1219,8 +1213,8 @@ static int sca3000_stop_all_interrupts(struct sca3000_state *st) static int sca3000_remove(struct spi_device *spi) { - struct sca3000_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct sca3000_state *st = iio_priv(indio_dev); int ret; /* Must ensure no interrupts can be generated after this!*/ ret = sca3000_stop_all_interrupts(st); @@ -1232,8 +1226,6 @@ static int sca3000_remove(struct spi_device *spi) sca3000_unconfigure_ring(indio_dev); iio_device_unregister(indio_dev); - kfree(st); - return 0; } diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index 7c4ff0b1df04..a704c75fffc2 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -89,7 +89,7 @@ static int sca3000_read_first_n_hw_rb(struct iio_ring_buffer *r, { struct iio_hw_ring_buffer *hw_ring = iio_to_hw_ring_buf(r); struct iio_dev *indio_dev = hw_ring->private; - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); u8 *rx; int ret, i, num_available, num_read = 0; int bytes_per_sample = 1; @@ -168,7 +168,7 @@ static ssize_t sca3000_query_ring_int(struct device *dev, int ret, val; struct iio_ring_buffer *ring = dev_get_drvdata(dev); struct iio_dev *indio_dev = ring->indio_dev; - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); mutex_lock(&st->lock); ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1); @@ -190,7 +190,7 @@ static ssize_t sca3000_set_ring_int(struct device *dev, { struct iio_ring_buffer *ring = dev_get_drvdata(dev); struct iio_dev *indio_dev = ring->indio_dev; - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); long val; int ret; @@ -240,7 +240,7 @@ static ssize_t sca3000_show_ring_bpse(struct device *dev, int len = 0, ret; struct iio_ring_buffer *ring = dev_get_drvdata(dev); struct iio_dev *indio_dev = ring->indio_dev; - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); mutex_lock(&st->lock); ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1); @@ -270,7 +270,7 @@ static ssize_t sca3000_store_ring_bpse(struct device *dev, { struct iio_ring_buffer *ring = dev_get_drvdata(dev); struct iio_dev *indio_dev = ring->indio_dev; - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); int ret; mutex_lock(&st->lock); @@ -300,7 +300,7 @@ static ssize_t sca3000_show_buffer_scale(struct device *dev, { struct iio_ring_buffer *ring = dev_get_drvdata(dev); struct iio_dev *indio_dev = ring->indio_dev; - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); return sprintf(buf, "0.%06d\n", 4*st->info->scale); } @@ -397,7 +397,7 @@ void sca3000_unconfigure_ring(struct iio_dev *indio_dev) static inline int __sca3000_hw_ring_state_set(struct iio_dev *indio_dev, bool state) { - struct sca3000_state *st = indio_dev->dev_data; + struct sca3000_state *st = iio_priv(indio_dev); int ret; mutex_lock(&st->lock); diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 8c751c46ddd7..b39f2e1c1fe6 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -130,6 +130,20 @@ config AD7780 To compile this driver as a module, choose M here: the module will be called ad7780. +config AD7793 + tristate "Analog Devices AD7792 AD7793 ADC driver" + depends on SPI + select IIO_RING_BUFFER + select IIO_SW_RING + select IIO_TRIGGER + help + Say yes here to build support for Analog Devices + AD7792 and AD7793 SPI analog to digital convertors (ADC). + 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 AD7793. + config AD7745 tristate "Analog Devices AD7745, AD7746 AD7747 capacitive sensor driver" depends on I2C diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 1d9b3f582eab..f02035139979 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_AD7291) += ad7291.o obj-$(CONFIG_AD7314) += ad7314.o obj-$(CONFIG_AD7745) += ad7745.o obj-$(CONFIG_AD7780) += ad7780.o +obj-$(CONFIG_AD7793) += ad7793.o obj-$(CONFIG_AD7816) += ad7816.o obj-$(CONFIG_ADT75) += adt75.o obj-$(CONFIG_ADT7310) += adt7310.o diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c index ca32b6778a9e..04017ef6688a 100644 --- a/drivers/staging/iio/adc/ad7150.c +++ b/drivers/staging/iio/adc/ad7150.c @@ -59,7 +59,6 @@ struct ad7150_chip_info { struct i2c_client *client; - struct iio_dev *indio_dev; bool inter; u16 ch1_threshold; /* Ch1 Threshold (in fixed threshold mode) */ u8 ch1_sensitivity; /* Ch1 Sensitivity (in adaptive threshold mode) */ @@ -184,7 +183,7 @@ static ssize_t ad7150_show_conversion_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%s\n", chip->conversion_mode); } @@ -195,7 +194,7 @@ static ssize_t ad7150_store_conversion_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); u8 cfg; int i; @@ -234,7 +233,7 @@ static ssize_t ad7150_show_ch1_value(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); u8 data[2]; ad7150_i2c_read(chip, AD7150_CH1_DATA_HIGH, data, 2); @@ -248,7 +247,7 @@ static ssize_t ad7150_show_ch2_value(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); u8 data[2]; ad7150_i2c_read(chip, AD7150_CH2_DATA_HIGH, data, 2); @@ -262,7 +261,7 @@ static ssize_t ad7150_show_threshold_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%s\n", chip->threshold_mode); } @@ -273,7 +272,7 @@ static ssize_t ad7150_store_threshold_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); u8 cfg; ad7150_i2c_read(chip, AD7150_CFG, &cfg, 1); @@ -305,7 +304,7 @@ static ssize_t ad7150_show_ch1_threshold(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->ch1_threshold); } @@ -316,7 +315,7 @@ static ssize_t ad7150_store_ch1_threshold(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -341,7 +340,7 @@ static ssize_t ad7150_show_ch2_threshold(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->ch2_threshold); } @@ -352,7 +351,7 @@ static ssize_t ad7150_store_ch2_threshold(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -377,7 +376,7 @@ static ssize_t ad7150_show_ch1_sensitivity(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->ch1_sensitivity); } @@ -388,7 +387,7 @@ static ssize_t ad7150_store_ch1_sensitivity(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -412,7 +411,7 @@ static ssize_t ad7150_show_ch2_sensitivity(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->ch2_sensitivity); } @@ -423,7 +422,7 @@ static ssize_t ad7150_store_ch2_sensitivity(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -447,7 +446,7 @@ static ssize_t ad7150_show_ch1_timeout(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->ch1_timeout); } @@ -458,7 +457,7 @@ static ssize_t ad7150_store_ch1_timeout(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -482,7 +481,7 @@ static ssize_t ad7150_show_ch2_timeout(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->ch2_timeout); } @@ -493,7 +492,7 @@ static ssize_t ad7150_store_ch2_timeout(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -517,7 +516,7 @@ static ssize_t ad7150_show_ch1_setup(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%02x\n", chip->ch1_setup); } @@ -528,7 +527,7 @@ static ssize_t ad7150_store_ch1_setup(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -553,7 +552,7 @@ static ssize_t ad7150_show_ch2_setup(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%02x\n", chip->ch2_setup); } @@ -564,7 +563,7 @@ static ssize_t ad7150_store_ch2_setup(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -588,7 +587,7 @@ static ssize_t ad7150_show_powerdown_timer(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%02x\n", chip->powerdown_timer); } @@ -599,7 +598,7 @@ static ssize_t ad7150_store_powerdown_timer(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7150_chip_info *chip = dev_info->dev_data; + struct ad7150_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -645,7 +644,7 @@ static const struct attribute_group ad7150_attribute_group = { static irqreturn_t ad7150_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; - struct ad7150_chip_info *chip = iio_dev_get_devdata(indio_dev); + struct ad7150_chip_info *chip = iio_priv(indio_dev); u8 int_status; s64 timestamp = iio_get_time_ns(); @@ -714,33 +713,29 @@ static int __devinit ad7150_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0, regdone = 0; - struct ad7150_chip_info *chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) { + struct ad7150_chip_info *chip; + struct iio_dev *indio_dev; + + indio_dev = iio_allocate_device(sizeof(*chip)); + if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; } - + chip = iio_priv(indio_dev); /* this is only used for device removal purposes */ - i2c_set_clientdata(client, chip); + i2c_set_clientdata(client, indio_dev); chip->client = client; - chip->indio_dev = iio_allocate_device(0); - if (chip->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_chip; - } - /* Establish that the iio_dev is a child of the i2c device */ - chip->indio_dev->name = id->name; - chip->indio_dev->dev.parent = &client->dev; + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; - chip->indio_dev->info = &ad7150_info; - chip->indio_dev->dev_data = (void *)(chip); + indio_dev->info = &ad7150_info; - chip->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(chip->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; regdone = 1; @@ -752,7 +747,7 @@ static int __devinit ad7150_probe(struct i2c_client *client, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "ad7150", - chip->indio_dev); + indio_dev); if (ret) goto error_free_dev; } @@ -763,24 +758,20 @@ static int __devinit ad7150_probe(struct i2c_client *client, error_free_dev: if (regdone) - iio_device_unregister(chip->indio_dev); + iio_device_unregister(indio_dev); else - iio_free_device(chip->indio_dev); -error_free_chip: - kfree(chip); + iio_free_device(indio_dev); error_ret: return ret; } static int __devexit ad7150_remove(struct i2c_client *client) { - struct ad7150_chip_info *chip = i2c_get_clientdata(client); - struct iio_dev *indio_dev = chip->indio_dev; + struct iio_dev *indio_dev = i2c_get_clientdata(client); if (client->irq) free_irq(client->irq, indio_dev); iio_device_unregister(indio_dev); - kfree(chip); return 0; } diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c index 7a38bcbbe1af..21f5f380fb5e 100644 --- a/drivers/staging/iio/adc/ad7152.c +++ b/drivers/staging/iio/adc/ad7152.c @@ -51,7 +51,6 @@ struct ad7152_chip_info { struct i2c_client *client; - struct iio_dev *indio_dev; u16 ch1_offset; /* Channel 1 offset calibration coefficient */ u16 ch1_gain; /* Channel 1 gain coefficient */ u8 ch1_setup; @@ -166,7 +165,7 @@ static ssize_t ad7152_show_ch1_value(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); u8 data[2]; ad7152_i2c_read(chip, AD7152_CH1_DATA_HIGH, data, 2); @@ -180,7 +179,7 @@ static ssize_t ad7152_show_ch2_value(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); u8 data[2]; ad7152_i2c_read(chip, AD7152_CH2_DATA_HIGH, data, 2); @@ -194,7 +193,7 @@ static ssize_t ad7152_show_conversion_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%s\n", chip->conversion_mode); } @@ -205,7 +204,7 @@ static ssize_t ad7152_store_conversion_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); u8 cfg; int i; @@ -234,7 +233,7 @@ static ssize_t ad7152_show_ch1_offset(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->ch1_offset); } @@ -245,7 +244,7 @@ static ssize_t ad7152_store_ch1_offset(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -270,7 +269,7 @@ static ssize_t ad7152_show_ch2_offset(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->ch2_offset); } @@ -281,7 +280,7 @@ static ssize_t ad7152_store_ch2_offset(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -306,7 +305,7 @@ static ssize_t ad7152_show_ch1_gain(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->ch1_gain); } @@ -317,7 +316,7 @@ static ssize_t ad7152_store_ch1_gain(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -342,7 +341,7 @@ static ssize_t ad7152_show_ch2_gain(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->ch2_gain); } @@ -353,7 +352,7 @@ static ssize_t ad7152_store_ch2_gain(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -378,7 +377,7 @@ static ssize_t ad7152_show_ch1_setup(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%02x\n", chip->ch1_setup); } @@ -389,7 +388,7 @@ static ssize_t ad7152_store_ch1_setup(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -413,7 +412,7 @@ static ssize_t ad7152_show_ch2_setup(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%02x\n", chip->ch2_setup); } @@ -424,7 +423,7 @@ static ssize_t ad7152_store_ch2_setup(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -448,7 +447,7 @@ static ssize_t ad7152_show_filter_rate_setup(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%02x\n", chip->filter_rate_setup); } @@ -459,7 +458,7 @@ static ssize_t ad7152_store_filter_rate_setup(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7152_chip_info *chip = dev_info->dev_data; + struct ad7152_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -509,31 +508,27 @@ static int __devinit ad7152_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; - struct ad7152_chip_info *chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) { + struct ad7152_chip_info *chip; + struct iio_dev *indio_dev; + + indio_dev = iio_allocate_device(sizeof(*chip)); + if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; } - + chip = iio_priv(indio_dev); /* this is only used for device removal purposes */ - i2c_set_clientdata(client, chip); + i2c_set_clientdata(client, indio_dev); chip->client = client; - chip->indio_dev = iio_allocate_device(0); - if (chip->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_chip; - } - /* Echipabilish that the iio_dev is a child of the i2c device */ - chip->indio_dev->name = id->name; - chip->indio_dev->dev.parent = &client->dev; - chip->indio_dev->info = &ad7152_info; - chip->indio_dev->dev_data = (void *)(chip); - chip->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; + indio_dev->info = &ad7152_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(chip->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; @@ -542,20 +537,16 @@ static int __devinit ad7152_probe(struct i2c_client *client, return 0; error_free_dev: - iio_free_device(chip->indio_dev); -error_free_chip: - kfree(chip); + iio_free_device(indio_dev); error_ret: return ret; } static int __devexit ad7152_remove(struct i2c_client *client) { - struct ad7152_chip_info *chip = i2c_get_clientdata(client); - struct iio_dev *indio_dev = chip->indio_dev; + struct iio_dev *indio_dev = i2c_get_clientdata(client); iio_device_unregister(indio_dev); - kfree(chip); return 0; } diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c index 1be3453479b7..96cbb17bc2cd 100644 --- a/drivers/staging/iio/adc/ad7291.c +++ b/drivers/staging/iio/adc/ad7291.c @@ -61,7 +61,6 @@ struct ad7291_chip_info { struct i2c_client *client; - struct iio_dev *indio_dev; u16 command; u8 channels; /* Active voltage channels */ }; @@ -157,7 +156,7 @@ static ssize_t ad7291_show_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); if (chip->command & AD7291_AUTOCYCLE) return sprintf(buf, "autocycle\n"); @@ -171,7 +170,7 @@ static ssize_t ad7291_store_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); u16 command; int ret; @@ -208,7 +207,7 @@ static ssize_t ad7291_store_reset(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); u16 command; int ret; @@ -231,7 +230,7 @@ static ssize_t ad7291_show_ext_ref(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->command & AD7291_EXT_REF)); } @@ -242,7 +241,7 @@ static ssize_t ad7291_store_ext_ref(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); u16 command; int ret; @@ -269,7 +268,7 @@ static ssize_t ad7291_show_noise_delay(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->command & AD7291_NOISE_DELAY)); } @@ -280,7 +279,7 @@ static ssize_t ad7291_store_noise_delay(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); u16 command; int ret; @@ -307,7 +306,7 @@ static ssize_t ad7291_show_t_sense(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); u16 data; char sign = ' '; int ret; @@ -334,7 +333,7 @@ static ssize_t ad7291_show_t_average(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); u16 data; char sign = ' '; int ret; @@ -361,7 +360,7 @@ static ssize_t ad7291_show_voltage(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); u16 data[AD7291_VOLTAGE_LIMIT_COUNT]; int i, size, ret; @@ -390,7 +389,7 @@ static ssize_t ad7291_show_channel_mask(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%x\n", (chip->command & AD7291_VOLTAGE_MASK) >> AD7291_VOLTAGE_OFFSET); @@ -402,7 +401,7 @@ static ssize_t ad7291_store_channel_mask(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); u16 command; unsigned long data; int i, ret; @@ -457,7 +456,7 @@ static const struct attribute_group ad7291_attribute_group = { static irqreturn_t ad7291_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; - struct ad7291_chip_info *chip = iio_dev_get_devdata(private); + struct ad7291_chip_info *chip = iio_priv(private); u16 t_status, v_status; u16 command; int i; @@ -532,7 +531,7 @@ static inline ssize_t ad7291_show_t_bound(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); u16 data; char sign = ' '; @@ -560,7 +559,7 @@ static inline ssize_t ad7291_set_t_bound(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); long tmp1, tmp2; u16 data; @@ -608,7 +607,7 @@ static inline ssize_t ad7291_show_v_bound(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); u16 data; int ret; @@ -633,7 +632,7 @@ static inline ssize_t ad7291_set_v_bound(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7291_chip_info *chip = dev_info->dev_data; + struct ad7291_chip_info *chip = iio_priv(dev_info); unsigned long value; u16 data; int ret; @@ -792,32 +791,27 @@ static int __devinit ad7291_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ad7291_chip_info *chip; + struct iio_dev *indio_dev; int ret = 0; - chip = kzalloc(sizeof(struct ad7291_chip_info), GFP_KERNEL); - - if (chip == NULL) - return -ENOMEM; - + indio_dev = iio_allocate_device(sizeof(*chip)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + chip = iio_priv(indio_dev); /* this is only used for device removal purposes */ - i2c_set_clientdata(client, chip); + i2c_set_clientdata(client, indio_dev); chip->client = client; chip->command = AD7291_NOISE_DELAY | AD7291_T_SENSE_MASK; - chip->indio_dev = iio_allocate_device(0); - if (chip->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_chip; - } + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; + indio_dev->info = &ad7291_info; + indio_dev->modes = INDIO_DIRECT_MODE; - chip->indio_dev->name = id->name; - chip->indio_dev->dev.parent = &client->dev; - chip->indio_dev->info = &ad7291_info; - chip->indio_dev->dev_data = (void *)chip; - chip->indio_dev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(chip->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; @@ -827,7 +821,7 @@ static int __devinit ad7291_probe(struct i2c_client *client, &ad7291_event_handler, IRQF_TRIGGER_LOW | IRQF_ONESHOT, id->name, - chip->indio_dev); + indio_dev); if (ret) goto error_unreg_dev; @@ -847,27 +841,23 @@ static int __devinit ad7291_probe(struct i2c_client *client, return 0; error_unreg_irq: - free_irq(client->irq, chip->indio_dev); + free_irq(client->irq, indio_dev); error_unreg_dev: - iio_device_unregister(chip->indio_dev); + iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(chip->indio_dev); -error_free_chip: - kfree(chip); - + iio_free_device(indio_dev); +error_ret: return ret; } static int __devexit ad7291_remove(struct i2c_client *client) { - struct ad7291_chip_info *chip = i2c_get_clientdata(client); - struct iio_dev *indio_dev = chip->indio_dev; + struct iio_dev *indio_dev = i2c_get_clientdata(client); if (client->irq) - free_irq(client->irq, chip->indio_dev); + free_irq(client->irq, indio_dev); iio_device_unregister(indio_dev); - iio_free_device(chip->indio_dev); - kfree(chip); + iio_free_device(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7314.c b/drivers/staging/iio/adc/ad7314.c index 98bb16fcff26..9070d9cac725 100644 --- a/drivers/staging/iio/adc/ad7314.c +++ b/drivers/staging/iio/adc/ad7314.c @@ -43,7 +43,6 @@ struct ad7314_chip_info { struct spi_device *spi_dev; - struct iio_dev *indio_dev; s64 last_timestamp; u8 mode; }; @@ -87,7 +86,7 @@ static ssize_t ad7314_show_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7314_chip_info *chip = dev_info->dev_data; + struct ad7314_chip_info *chip = iio_priv(dev_info); if (chip->mode) return sprintf(buf, "power-save\n"); @@ -101,7 +100,7 @@ static ssize_t ad7314_store_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7314_chip_info *chip = dev_info->dev_data; + struct ad7314_chip_info *chip = iio_priv(dev_info); u16 mode = 0; int ret; @@ -136,7 +135,7 @@ static ssize_t ad7314_show_temperature(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7314_chip_info *chip = dev_info->dev_data; + struct ad7314_chip_info *chip = iio_priv(dev_info); u16 data; char sign = ' '; int ret; @@ -202,54 +201,45 @@ static const struct iio_info ad7314_info = { static int __devinit ad7314_probe(struct spi_device *spi_dev) { struct ad7314_chip_info *chip; + struct iio_dev *indio_dev; int ret = 0; - chip = kzalloc(sizeof(struct ad7314_chip_info), GFP_KERNEL); - - if (chip == NULL) - return -ENOMEM; - + indio_dev = iio_allocate_device(sizeof(*chip)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + chip = iio_priv(indio_dev); /* this is only used for device removal purposes */ dev_set_drvdata(&spi_dev->dev, chip); chip->spi_dev = spi_dev; - chip->indio_dev = iio_allocate_device(0); - if (chip->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_chip; - } + indio_dev->name = spi_get_device_id(spi_dev)->name; + indio_dev->dev.parent = &spi_dev->dev; + indio_dev->info = &ad7314_info; - chip->indio_dev->name = spi_get_device_id(spi_dev)->name; - chip->indio_dev->dev.parent = &spi_dev->dev; - chip->indio_dev->info = &ad7314_info; - chip->indio_dev->dev_data = (void *)chip; - - ret = iio_device_register(chip->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; dev_info(&spi_dev->dev, "%s temperature sensor registered.\n", - chip->indio_dev->name); + indio_dev->name); return 0; error_free_dev: - iio_free_device(chip->indio_dev); -error_free_chip: - kfree(chip); - + iio_free_device(indio_dev); +error_ret: return ret; } static int __devexit ad7314_remove(struct spi_device *spi_dev) { - struct ad7314_chip_info *chip = dev_get_drvdata(&spi_dev->dev); - struct iio_dev *indio_dev = chip->indio_dev; + struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev); dev_set_drvdata(&spi_dev->dev, NULL); iio_device_unregister(indio_dev); - iio_free_device(chip->indio_dev); - kfree(chip); + iio_free_device(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7476.h b/drivers/staging/iio/adc/ad7476.h index 01a70211f4ff..0d44976e846f 100644 --- a/drivers/staging/iio/adc/ad7476.h +++ b/drivers/staging/iio/adc/ad7476.h @@ -24,7 +24,6 @@ struct ad7476_chip_info { }; struct ad7476_state { - struct iio_dev *indio_dev; struct spi_device *spi; const struct ad7476_chip_info *chip_info; struct regulator *reg; @@ -51,11 +50,11 @@ enum ad7476_supported_device_ids { }; #ifdef CONFIG_IIO_RING_BUFFER -int ad7476_scan_from_ring(struct ad7476_state *st); +int ad7476_scan_from_ring(struct iio_dev *indio_dev); int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev); void ad7476_ring_cleanup(struct iio_dev *indio_dev); #else /* CONFIG_IIO_RING_BUFFER */ -static inline int ad7476_scan_from_ring(struct ad7476_state *st) +static inline int ad7476_scan_from_ring(struct iio_dev *indio_dev) { return 0; } diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index 50cedb422839..c21089894d28 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -39,14 +39,14 @@ static int ad7476_read_raw(struct iio_dev *dev_info, long m) { int ret; - struct ad7476_state *st = dev_info->dev_data; + struct ad7476_state *st = iio_priv(dev_info); unsigned int scale_uv; switch (m) { case 0: mutex_lock(&dev_info->mlock); if (iio_ring_enabled(dev_info)) - ret = ad7476_scan_from_ring(st); + ret = ad7476_scan_from_ring(dev_info); else ret = ad7476_scan_direct(st); mutex_unlock(&dev_info->mlock); @@ -127,23 +127,26 @@ static int __devinit ad7476_probe(struct spi_device *spi) { struct ad7476_platform_data *pdata = spi->dev.platform_data; struct ad7476_state *st; + struct iio_dev *indio_dev; int ret, voltage_uv = 0; + bool reg_done = false; + struct regulator *reg; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; } - - st->reg = regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(st->reg)) { - ret = regulator_enable(st->reg); + st = iio_priv(indio_dev); + reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(reg)) { + ret = regulator_enable(reg); if (ret) goto error_put_reg; - voltage_uv = regulator_get_voltage(st->reg); + voltage_uv = regulator_get_voltage(reg); } - + st->reg = reg; st->chip_info = &ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data]; @@ -156,24 +159,17 @@ static int __devinit ad7476_probe(struct spi_device *spi) else dev_warn(&spi->dev, "reference voltage unspecified\n"); - spi_set_drvdata(spi, st); + spi_set_drvdata(spi, indio_dev); st->spi = spi; - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_disable_reg; - } - /* Establish that the iio_dev is a child of the spi device */ - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->name = spi_get_device_id(spi)->name; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; - st->indio_dev->channels = st->chip_info->channel; - st->indio_dev->num_channels = 2; - st->indio_dev->info = &ad7476_info; + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->chip_info->channel; + indio_dev->num_channels = 2; + indio_dev->info = &ad7476_info; /* Setup default message */ st->xfer.rx_buf = &st->data; @@ -182,15 +178,15 @@ static int __devinit ad7476_probe(struct spi_device *spi) spi_message_init(&st->msg); spi_message_add_tail(&st->xfer, &st->msg); - ret = ad7476_register_ring_funcs_and_init(st->indio_dev); + ret = ad7476_register_ring_funcs_and_init(indio_dev); if (ret) - goto error_free_device; + goto error_disable_reg; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) - goto error_free_device; + goto error_disable_reg; - ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0, + ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, st->chip_info->channel, ARRAY_SIZE(st->chip_info->channel)); if (ret) @@ -198,33 +194,35 @@ static int __devinit ad7476_probe(struct spi_device *spi) return 0; error_cleanup_ring: - ad7476_ring_cleanup(st->indio_dev); - iio_device_unregister(st->indio_dev); -error_free_device: - iio_free_device(st->indio_dev); + ad7476_ring_cleanup(indio_dev); + iio_device_unregister(indio_dev); error_disable_reg: - if (!IS_ERR(st->reg)) + if (!IS_ERR(reg)) regulator_disable(st->reg); error_put_reg: - if (!IS_ERR(st->reg)) - regulator_put(st->reg); - kfree(st); + if (!IS_ERR(reg)) + regulator_put(reg); + if (!reg_done) + iio_free_device(indio_dev); error_ret: return ret; } static int ad7476_remove(struct spi_device *spi) { - struct ad7476_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7476_state *st = iio_priv(indio_dev); + /* copy needed as st will have been freed */ + struct regulator *reg = st->reg; + iio_ring_buffer_unregister(indio_dev->ring); ad7476_ring_cleanup(indio_dev); iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg)) { - regulator_disable(st->reg); - regulator_put(st->reg); + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); } - kfree(st); + return 0; } diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index b1b2ee2c56b0..a92fc5a1a604 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -22,9 +22,9 @@ #include "ad7476.h" -int ad7476_scan_from_ring(struct ad7476_state *st) +int ad7476_scan_from_ring(struct iio_dev *indio_dev) { - struct iio_ring_buffer *ring = st->indio_dev->ring; + struct iio_ring_buffer *ring = indio_dev->ring; int ret; u8 *ring_data; @@ -55,7 +55,7 @@ int ad7476_scan_from_ring(struct ad7476_state *st) **/ static int ad7476_ring_preenable(struct iio_dev *indio_dev) { - struct ad7476_state *st = indio_dev->dev_data; + struct ad7476_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; st->d_size = ring->scan_count * @@ -79,7 +79,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->private_data; - struct ad7476_state *st = iio_dev_get_devdata(indio_dev); + struct ad7476_state *st = iio_priv(indio_dev); s64 time_ns; __u8 *rxbuf; int b_sent; @@ -115,7 +115,7 @@ static const struct iio_ring_setup_ops ad7476_ring_setup_ops = { int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev) { - struct ad7476_state *st = indio_dev->dev_data; + struct ad7476_state *st = iio_priv(indio_dev); int ret = 0; indio_dev->ring = iio_sw_rb_allocate(indio_dev); diff --git a/drivers/staging/iio/adc/ad7745.c b/drivers/staging/iio/adc/ad7745.c index 1944223ef163..4c13f26aa9ae 100644 --- a/drivers/staging/iio/adc/ad7745.c +++ b/drivers/staging/iio/adc/ad7745.c @@ -54,7 +54,6 @@ struct ad774x_chip_info { struct i2c_client *client; - struct iio_dev *indio_dev; bool inter; u16 cap_offs; /* Capacitive offset */ u16 cap_gain; /* Capacitive gain calibration */ @@ -169,7 +168,7 @@ static ssize_t ad774x_show_conversion_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%s\n", chip->conversion_mode); } @@ -180,7 +179,7 @@ static ssize_t ad774x_store_conversion_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); u8 cfg; int i; @@ -210,7 +209,7 @@ static ssize_t ad774x_show_dac_value(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); u8 data; @@ -225,7 +224,7 @@ static ssize_t ad774x_store_dac_value(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); unsigned long data; int ret; @@ -256,7 +255,7 @@ static ssize_t ad774x_show_cap_setup(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%02x\n", chip->cap_setup); } @@ -267,7 +266,7 @@ static ssize_t ad774x_store_cap_setup(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -291,7 +290,7 @@ static ssize_t ad774x_show_vt_setup(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%02x\n", chip->vt_setup); } @@ -302,7 +301,7 @@ static ssize_t ad774x_store_vt_setup(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -326,7 +325,7 @@ static ssize_t ad774x_show_exec_setup(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%02x\n", chip->exec_setup); } @@ -337,7 +336,7 @@ static ssize_t ad774x_store_exec_setup(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -361,7 +360,7 @@ static ssize_t ad774x_show_volt_gain(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->volt_gain); } @@ -372,7 +371,7 @@ static ssize_t ad774x_store_volt_gain(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -397,7 +396,7 @@ static ssize_t ad774x_show_cap_data(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); unsigned long data; char tmp[3]; @@ -414,7 +413,7 @@ static ssize_t ad774x_show_vt_data(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); unsigned long data; char tmp[3]; @@ -431,7 +430,7 @@ static ssize_t ad774x_show_cap_offs(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->cap_offs); } @@ -442,7 +441,7 @@ static ssize_t ad774x_store_cap_offs(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -467,7 +466,7 @@ static ssize_t ad774x_show_cap_gain(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->cap_gain); } @@ -478,7 +477,7 @@ static ssize_t ad774x_store_cap_gain(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad774x_chip_info *chip = dev_info->dev_data; + struct ad774x_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -534,7 +533,7 @@ static const struct attribute_group ad774x_attribute_group = { static irqreturn_t ad774x_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; - struct ad774x_chip_info *chip = iio_dev_get_devdata(indio_dev); + struct ad774x_chip_info *chip = iio_priv(indio_dev); u8 int_status; ad774x_i2c_read(chip, AD774X_STATUS, &int_status, 1); @@ -579,31 +578,27 @@ static int __devinit ad774x_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0, regdone = 0; - struct ad774x_chip_info *chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) { + struct ad774x_chip_info *chip; + struct iio_dev *indio_dev; + + indio_dev = iio_allocate_device(sizeof(*chip)); + if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; } - + chip = iio_priv(indio_dev); /* this is only used for device removal purposes */ - i2c_set_clientdata(client, chip); + i2c_set_clientdata(client, indio_dev); chip->client = client; - chip->indio_dev = iio_allocate_device(0); - if (chip->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_chip; - } - /* Establish that the iio_dev is a child of the i2c device */ - chip->indio_dev->name = id->name; - chip->indio_dev->dev.parent = &client->dev; - chip->indio_dev->info = &ad774x_info; - chip->indio_dev->dev_data = (void *)(chip); - chip->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; + indio_dev->info = &ad774x_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(chip->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; regdone = 1; @@ -614,7 +609,7 @@ static int __devinit ad774x_probe(struct i2c_client *client, &ad774x_event_handler, IRQF_TRIGGER_FALLING, "ad774x", - chip->indio_dev); + indio_dev); if (ret) goto error_free_dev; } @@ -625,24 +620,20 @@ static int __devinit ad774x_probe(struct i2c_client *client, error_free_dev: if (regdone) - free_irq(client->irq, chip->indio_dev); + free_irq(client->irq, indio_dev); else - iio_free_device(chip->indio_dev); -error_free_chip: - kfree(chip); + iio_free_device(indio_dev); error_ret: return ret; } static int __devexit ad774x_remove(struct i2c_client *client) { - struct ad774x_chip_info *chip = i2c_get_clientdata(client); - struct iio_dev *indio_dev = chip->indio_dev; + struct iio_dev *indio_dev = i2c_get_clientdata(client); if (client->irq) free_irq(client->irq, indio_dev); iio_device_unregister(indio_dev); - kfree(chip); return 0; } diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c new file mode 100644 index 000000000000..90f6c039d6c6 --- /dev/null +++ b/drivers/staging/iio/adc/ad7793.c @@ -0,0 +1,987 @@ +/* + * AD7792/AD7793 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_generic.h" +#include "../ring_sw.h" +#include "../trigger.h" +#include "adc.h" + +#include "ad7793.h" + +/* NOTE: + * The AD7792/AD7793 features a dual use data out ready DOUT/RDY output. + * In order to avoid contentions on the SPI bus, it's therefore necessary + * to use spi bus locking. + * + * The DOUT/RDY output must also be wired to an interrupt capable GPIO. + */ + +struct ad7793_chip_info { + struct iio_chan_spec channel[7]; +}; + +struct ad7793_state { + struct spi_device *spi; + struct iio_trigger *trig; + const struct ad7793_chip_info *chip_info; + struct regulator *reg; + struct ad7793_platform_data *pdata; + wait_queue_head_t wq_data_avail; + bool done; + bool irq_dis; + u16 int_vref_mv; + u16 mode; + u16 conf; + u32 scale_avail[8][2]; + u32 available_scan_masks[7]; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + u8 data[4] ____cacheline_aligned; +}; + +enum ad7793_supported_device_ids { + ID_AD7792, + ID_AD7793, +}; + +static int __ad7793_write_reg(struct ad7793_state *st, bool locked, + bool cs_change, unsigned char reg, + unsigned size, unsigned val) +{ + u8 *data = st->data; + struct spi_transfer t = { + .tx_buf = data, + .len = size + 1, + .cs_change = cs_change, + }; + struct spi_message m; + + data[0] = AD7793_COMM_WRITE | AD7793_COMM_ADDR(reg); + + switch (size) { + case 3: + data[1] = val >> 16; + data[2] = val >> 8; + data[3] = val; + break; + case 2: + data[1] = val >> 8; + data[2] = val; + break; + case 1: + data[1] = val; + break; + default: + return -EINVAL; + } + + spi_message_init(&m); + spi_message_add_tail(&t, &m); + + if (locked) + return spi_sync_locked(st->spi, &m); + else + return spi_sync(st->spi, &m); +} + +static int ad7793_write_reg(struct ad7793_state *st, + unsigned reg, unsigned size, unsigned val) +{ + return __ad7793_write_reg(st, false, false, reg, size, val); +} + +static int __ad7793_read_reg(struct ad7793_state *st, bool locked, + bool cs_change, unsigned char reg, + int *val, unsigned size) +{ + u8 *data = st->data; + int ret; + struct spi_transfer t[] = { + { + .tx_buf = data, + .len = 1, + }, { + .rx_buf = data, + .len = size, + .cs_change = cs_change, + }, + }; + struct spi_message m; + + data[0] = AD7793_COMM_READ | AD7793_COMM_ADDR(reg); + + spi_message_init(&m); + spi_message_add_tail(&t[0], &m); + spi_message_add_tail(&t[1], &m); + + if (locked) + ret = spi_sync_locked(st->spi, &m); + else + ret = spi_sync(st->spi, &m); + + if (ret < 0) + return ret; + + switch (size) { + case 3: + *val = data[0] << 16 | data[1] << 8 | data[2]; + break; + case 2: + *val = data[0] << 8 | data[1]; + break; + case 1: + *val = data[0]; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int ad7793_read_reg(struct ad7793_state *st, + unsigned reg, int *val, unsigned size) +{ + return __ad7793_read_reg(st, 0, 0, reg, val, size); +} + +static int ad7793_read(struct ad7793_state *st, unsigned ch, + unsigned len, int *val) +{ + int ret; + st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | AD7793_CONF_CHAN(ch); + st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | + AD7793_MODE_SEL(AD7793_MODE_SINGLE); + + ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); + + spi_bus_lock(st->spi->master); + st->done = false; + + ret = __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE, + sizeof(st->mode), st->mode); + if (ret < 0) + goto out; + + st->irq_dis = false; + enable_irq(st->spi->irq); + wait_event_interruptible(st->wq_data_avail, st->done); + + ret = __ad7793_read_reg(st, 1, 0, AD7793_REG_DATA, val, len); +out: + spi_bus_unlock(st->spi->master); + + return ret; +} + +static int ad7793_calibrate(struct ad7793_state *st, unsigned mode, unsigned ch) +{ + int ret; + + st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | AD7793_CONF_CHAN(ch); + st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | AD7793_MODE_SEL(mode); + + ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); + + spi_bus_lock(st->spi->master); + st->done = false; + + ret = __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE, + sizeof(st->mode), st->mode); + if (ret < 0) + goto out; + + st->irq_dis = false; + enable_irq(st->spi->irq); + wait_event_interruptible(st->wq_data_avail, st->done); + + st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | + AD7793_MODE_SEL(AD7793_MODE_IDLE); + + ret = __ad7793_write_reg(st, 1, 0, AD7793_REG_MODE, + sizeof(st->mode), st->mode); +out: + spi_bus_unlock(st->spi->master); + + return ret; +} + +static const u8 ad7793_calib_arr[6][2] = { + {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN1P_AIN1M}, + {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN1P_AIN1M}, + {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN2P_AIN2M}, + {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN2P_AIN2M}, + {AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN3P_AIN3M}, + {AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN3P_AIN3M} +}; + +static int ad7793_calibrate_all(struct ad7793_state *st) +{ + int i, ret; + + for (i = 0; i < ARRAY_SIZE(ad7793_calib_arr); i++) { + ret = ad7793_calibrate(st, ad7793_calib_arr[i][0], + ad7793_calib_arr[i][1]); + if (ret) + goto out; + } + + return 0; +out: + dev_err(&st->spi->dev, "Calibration failed\n"); + return ret; +} + +static int ad7793_setup(struct ad7793_state *st) +{ + int i, ret = -1; + unsigned long long scale_uv; + u32 id; + + /* reset the serial interface */ + ret = spi_write(st->spi, (u8 *)&ret, sizeof(ret)); + if (ret < 0) + goto out; + msleep(1); /* Wait for at least 500us */ + + /* write/read test for device presence */ + ret = ad7793_read_reg(st, AD7793_REG_ID, &id, 1); + if (ret) + goto out; + + id &= AD7793_ID_MASK; + + if (!((id == AD7792_ID) || (id == AD7793_ID))) { + dev_err(&st->spi->dev, "device ID query failed\n"); + goto out; + } + + st->mode = (st->pdata->mode & ~AD7793_MODE_SEL(-1)) | + AD7793_MODE_SEL(AD7793_MODE_IDLE); + st->conf = st->pdata->conf & ~AD7793_CONF_CHAN(-1); + + ret = ad7793_write_reg(st, AD7793_REG_MODE, sizeof(st->mode), st->mode); + if (ret) + goto out; + + ret = ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); + if (ret) + goto out; + + ret = ad7793_write_reg(st, AD7793_REG_IO, + sizeof(st->pdata->io), st->pdata->io); + if (ret) + goto out; + + ret = ad7793_calibrate_all(st); + if (ret) + goto out; + + /* Populate available ADC input ranges */ + for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) { + scale_uv = ((u64)st->int_vref_mv * 100000000) + >> (st->chip_info->channel[0].scan_type.realbits - + (!!(st->conf & AD7793_CONF_UNIPOLAR) ? 0 : 1)); + scale_uv >>= i; + + st->scale_avail[i][1] = do_div(scale_uv, 100000000) * 10; + st->scale_avail[i][0] = scale_uv; + } + + return 0; +out: + dev_err(&st->spi->dev, "setup failed\n"); + return ret; +} + +static int ad7793_scan_from_ring(struct ad7793_state *st, unsigned ch, int *val) +{ + struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring; + int ret; + s64 dat64[2]; + u32 *dat32 = (u32 *)dat64; + + if (!(ring->scan_mask & (1 << ch))) + return -EBUSY; + + ret = ring->access->read_last(ring, (u8 *) &dat64); + if (ret) + return ret; + + *val = *dat32; + + return 0; +} + +static int ad7793_ring_preenable(struct iio_dev *indio_dev) +{ + struct ad7793_state *st = iio_priv(indio_dev); + struct iio_ring_buffer *ring = indio_dev->ring; + size_t d_size; + unsigned channel; + + if (!ring->scan_count) + return -EINVAL; + + channel = __ffs(ring->scan_mask); + + d_size = ring->scan_count * + indio_dev->channels[0].scan_type.storagebits / 8; + + if (ring->scan_timestamp) { + d_size += sizeof(s64); + + if (d_size % sizeof(s64)) + d_size += sizeof(s64) - (d_size % sizeof(s64)); + } + + if (indio_dev->ring->access->set_bytes_per_datum) + indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring, + d_size); + + st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | + AD7793_MODE_SEL(AD7793_MODE_CONT); + st->conf = (st->conf & ~AD7793_CONF_CHAN(-1)) | + AD7793_CONF_CHAN(indio_dev->channels[channel].address); + + ad7793_write_reg(st, AD7793_REG_CONF, sizeof(st->conf), st->conf); + + spi_bus_lock(st->spi->master); + __ad7793_write_reg(st, 1, 1, AD7793_REG_MODE, + sizeof(st->mode), st->mode); + + st->irq_dis = false; + enable_irq(st->spi->irq); + + return 0; +} + +static int ad7793_ring_postdisable(struct iio_dev *indio_dev) +{ + struct ad7793_state *st = iio_priv(indio_dev); + + st->mode = (st->mode & ~AD7793_MODE_SEL(-1)) | + AD7793_MODE_SEL(AD7793_MODE_IDLE); + + st->done = false; + wait_event_interruptible(st->wq_data_avail, st->done); + + if (!st->irq_dis) + disable_irq_nosync(st->spi->irq); + + __ad7793_write_reg(st, 1, 0, AD7793_REG_MODE, + sizeof(st->mode), st->mode); + + return spi_bus_unlock(st->spi->master); +} + +/** + * ad7793_trigger_handler() bh of trigger launched polling to ring buffer + **/ + +static irqreturn_t ad7793_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->private_data; + struct iio_ring_buffer *ring = indio_dev->ring; + struct ad7793_state *st = iio_priv(indio_dev); + s64 dat64[2]; + s32 *dat32 = (s32 *)dat64; + + if (ring->scan_count) + __ad7793_read_reg(st, 1, 1, AD7793_REG_DATA, + dat32, + indio_dev->channels[0].scan_type.realbits/8); + + /* Guaranteed to be aligned with 8 byte boundary */ + if (ring->scan_timestamp) + dat64[1] = pf->timestamp; + + ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); + + iio_trigger_notify_done(indio_dev->trig); + st->irq_dis = false; + enable_irq(st->spi->irq); + + return IRQ_HANDLED; +} + +static const struct iio_ring_setup_ops ad7793_ring_setup_ops = { + .preenable = &ad7793_ring_preenable, + .postenable = &iio_triggered_ring_postenable, + .predisable = &iio_triggered_ring_predisable, + .postdisable = &ad7793_ring_postdisable, +}; + +static int ad7793_register_ring_funcs_and_init(struct iio_dev *indio_dev) +{ + int ret; + + indio_dev->ring = iio_sw_rb_allocate(indio_dev); + if (!indio_dev->ring) { + ret = -ENOMEM; + goto error_ret; + } + /* Effectively select the ring buffer implementation */ + indio_dev->ring->access = &ring_sw_access_funcs; + indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, + &ad7793_trigger_handler, + IRQF_ONESHOT, + indio_dev, + "ad7793_consumer%d", + indio_dev->id); + if (indio_dev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_deallocate_sw_rb; + } + + /* Ring buffer functions - here trigger setup related */ + indio_dev->ring->setup_ops = &ad7793_ring_setup_ops; + + /* Flag that polled ring buffering is possible */ + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; + +error_deallocate_sw_rb: + iio_sw_rb_free(indio_dev->ring); +error_ret: + return ret; +} + +static void ad7793_ring_cleanup(struct iio_dev *indio_dev) +{ + /* ensure that the trigger has been detached */ + if (indio_dev->trig) { + iio_put_trigger(indio_dev->trig); + iio_trigger_dettach_poll_func(indio_dev->trig, + indio_dev->pollfunc); + } + iio_dealloc_pollfunc(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} + +/** + * ad7793_data_rdy_trig_poll() the event handler for the data rdy trig + **/ +static irqreturn_t ad7793_data_rdy_trig_poll(int irq, void *private) +{ + struct ad7793_state *st = iio_priv(private); + + st->done = true; + wake_up_interruptible(&st->wq_data_avail); + disable_irq_nosync(irq); + st->irq_dis = true; + iio_trigger_poll(st->trig, iio_get_time_ns()); + + return IRQ_HANDLED; +} + +static int ad7793_probe_trigger(struct iio_dev *indio_dev) +{ + struct ad7793_state *st = iio_priv(indio_dev); + int ret; + + st->trig = iio_allocate_trigger("%s-dev%d", + spi_get_device_id(st->spi)->name, + indio_dev->id); + if (st->trig == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + ret = request_irq(st->spi->irq, + ad7793_data_rdy_trig_poll, + IRQF_TRIGGER_LOW, + spi_get_device_id(st->spi)->name, + indio_dev); + if (ret) + goto error_free_trig; + + disable_irq_nosync(st->spi->irq); + st->irq_dis = true; + st->trig->dev.parent = &st->spi->dev; + st->trig->owner = THIS_MODULE; + st->trig->private_data = indio_dev; + + ret = iio_trigger_register(st->trig); + + /* select default trigger */ + indio_dev->trig = st->trig; + if (ret) + goto error_free_irq; + + return 0; + +error_free_irq: + free_irq(st->spi->irq, indio_dev); +error_free_trig: + iio_free_trigger(st->trig); +error_ret: + return ret; +} + +static void ad7793_remove_trigger(struct iio_dev *indio_dev) +{ + struct ad7793_state *st = iio_priv(indio_dev); + + iio_trigger_unregister(st->trig); + free_irq(st->spi->irq, indio_dev); + iio_free_trigger(st->trig); +} + +static const u16 sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39, 33, 19, + 17, 16, 12, 10, 8, 6, 4}; + +static ssize_t ad7793_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad7793_state *st = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", + sample_freq_avail[AD7793_MODE_RATE(st->mode)]); +} + +static ssize_t ad7793_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 ad7793_state *st = iio_priv(indio_dev); + long lval; + int i, ret; + + mutex_lock(&indio_dev->mlock); + if (iio_ring_enabled(indio_dev)) { + mutex_unlock(&indio_dev->mlock); + return -EBUSY; + } + mutex_unlock(&indio_dev->mlock); + + ret = strict_strtol(buf, 10, &lval); + if (ret) + return ret; + + ret = -EINVAL; + + for (i = 0; i < ARRAY_SIZE(sample_freq_avail); i++) + if (lval == sample_freq_avail[i]) { + mutex_lock(&indio_dev->mlock); + st->mode &= ~AD7793_MODE_RATE(-1); + st->mode |= AD7793_MODE_RATE(i); + ad7793_write_reg(st, AD7793_REG_MODE, + sizeof(st->mode), st->mode); + mutex_unlock(&indio_dev->mlock); + ret = 0; + } + + return ret ? ret : len; +} + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + ad7793_read_frequency, + ad7793_write_frequency); + +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( + "470 242 123 62 50 39 33 19 17 16 12 10 8 6 4"); + +static ssize_t ad7793_show_scale_available(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad7793_state *st = iio_priv(indio_dev); + int i, len = 0; + + for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) + len += sprintf(buf + len, "%d.%09u ", st->scale_avail[i][0], + st->scale_avail[i][1]); + + len += sprintf(buf + len, "\n"); + + return len; +} + +static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available, in-in_scale_available, + S_IRUGO, ad7793_show_scale_available, NULL, 0); + +static struct attribute *ad7793_attributes[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_in_m_in_scale_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group ad7793_attribute_group = { + .attrs = ad7793_attributes, +}; + +static int ad7793_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ad7793_state *st = iio_priv(indio_dev); + int ret, smpl = 0; + unsigned long long scale_uv; + bool unipolar = !!(st->conf & AD7793_CONF_UNIPOLAR); + + switch (m) { + case 0: + mutex_lock(&indio_dev->mlock); + if (iio_ring_enabled(indio_dev)) + ret = ad7793_scan_from_ring(st, + chan->scan_index, &smpl); + else + ret = ad7793_read(st, chan->address, + chan->scan_type.realbits / 8, &smpl); + mutex_unlock(&indio_dev->mlock); + + if (ret < 0) + return ret; + + *val = (smpl >> chan->scan_type.shift) & + ((1 << (chan->scan_type.realbits)) - 1); + + if (!unipolar) + *val -= (1 << (chan->scan_type.realbits - 1)); + + return IIO_VAL_INT; + + case (1 << IIO_CHAN_INFO_SCALE_SHARED): + *val = st->scale_avail[(st->conf >> 8) & 0x7][0]; + *val2 = st->scale_avail[(st->conf >> 8) & 0x7][1]; + + return IIO_VAL_INT_PLUS_NANO; + + case (1 << IIO_CHAN_INFO_SCALE_SEPARATE): + switch (chan->type) { + case IIO_IN: + /* 1170mV / 2^23 * 6 */ + scale_uv = (1170ULL * 100000000ULL * 6ULL) + >> (chan->scan_type.realbits - + (unipolar ? 0 : 1)); + break; + case IIO_TEMP: + /* Always uses unity gain and internal ref */ + scale_uv = (2500ULL * 100000000ULL) + >> (chan->scan_type.realbits - + (unipolar ? 0 : 1)); + break; + default: + return -EINVAL; + } + + *val2 = do_div(scale_uv, 100000000) * 10; + *val = scale_uv; + + return IIO_VAL_INT_PLUS_NANO; + } + return -EINVAL; +} + +static int ad7793_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct ad7793_state *st = iio_priv(indio_dev); + int ret, i; + unsigned int tmp; + + mutex_lock(&indio_dev->mlock); + if (iio_ring_enabled(indio_dev)) { + mutex_unlock(&indio_dev->mlock); + return -EBUSY; + } + + switch (mask) { + case (1 << IIO_CHAN_INFO_SCALE_SHARED): + ret = -EINVAL; + for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) + if (val2 == st->scale_avail[i][1]) { + tmp = st->conf; + st->conf &= ~AD7793_CONF_GAIN(-1); + st->conf |= AD7793_CONF_GAIN(i); + + if (tmp != st->conf) { + ad7793_write_reg(st, AD7793_REG_CONF, + sizeof(st->conf), + st->conf); + ad7793_calibrate_all(st); + } + ret = 0; + } + + default: + ret = -EINVAL; + } + + mutex_unlock(&indio_dev->mlock); + return ret; +} + +static int ad7793_validate_trigger(struct iio_dev *indio_dev, + struct iio_trigger *trig) +{ + if (indio_dev->trig != trig) + return -EINVAL; + + return 0; +} + +static int ad7793_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + return IIO_VAL_INT_PLUS_NANO; +} + +static const struct iio_info ad7793_info = { + .read_raw = &ad7793_read_raw, + .write_raw = &ad7793_write_raw, + .write_raw_get_fmt = &ad7793_write_raw_get_fmt, + .attrs = &ad7793_attribute_group, + .validate_trigger = ad7793_validate_trigger, + .driver_module = THIS_MODULE, +}; + +static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { + [ID_AD7793] = { + .channel[0] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD7793_CH_AIN1P_AIN1M, + 0, IIO_ST('s', 24, 32, 0), 0), + .channel[1] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 1, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD7793_CH_AIN2P_AIN2M, + 1, IIO_ST('s', 24, 32, 0), 0), + .channel[2] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 2, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD7793_CH_AIN3P_AIN3M, + 2, IIO_ST('s', 24, 32, 0), 0), + .channel[3] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, "shorted", 0, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD7793_CH_AIN1M_AIN1M, + 3, IIO_ST('s', 24, 32, 0), 0), + .channel[4] = IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + AD7793_CH_TEMP, + 4, IIO_ST('s', 24, 32, 0), 0), + .channel[5] = IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 4, 0, + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + AD7793_CH_AVDD_MONITOR, + 5, IIO_ST('s', 24, 32, 0), 0), + .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), + }, + [ID_AD7792] = { + .channel[0] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD7793_CH_AIN1P_AIN1M, + 0, IIO_ST('s', 16, 32, 0), 0), + .channel[1] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 1, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD7793_CH_AIN2P_AIN2M, + 1, IIO_ST('s', 16, 32, 0), 0), + .channel[2] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 2, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD7793_CH_AIN3P_AIN3M, + 2, IIO_ST('s', 16, 32, 0), 0), + .channel[3] = IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, "shorted", 0, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD7793_CH_AIN1M_AIN1M, + 3, IIO_ST('s', 16, 32, 0), 0), + .channel[4] = IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + AD7793_CH_TEMP, + 4, IIO_ST('s', 16, 32, 0), 0), + .channel[5] = IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 4, 0, + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + AD7793_CH_AVDD_MONITOR, + 5, IIO_ST('s', 16, 32, 0), 0), + .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), + }, +}; + +static int __devinit ad7793_probe(struct spi_device *spi) +{ + struct ad7793_platform_data *pdata = spi->dev.platform_data; + struct ad7793_state *st; + struct iio_dev *indio_dev; + int ret, i, voltage_uv = 0, regdone = 0; + + if (!pdata) { + dev_err(&spi->dev, "no platform data?\n"); + return -ENODEV; + } + + if (!spi->irq) { + dev_err(&spi->dev, "no IRQ?\n"); + return -ENODEV; + } + + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + voltage_uv = regulator_get_voltage(st->reg); + } + + st->chip_info = + &ad7793_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + + st->pdata = pdata; + + if (pdata && pdata->vref_mv) + st->int_vref_mv = pdata->vref_mv; + else if (voltage_uv) + st->int_vref_mv = voltage_uv / 1000; + else + st->int_vref_mv = 2500; /* Build-in ref */ + + spi_set_drvdata(spi, indio_dev); + st->spi = spi; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->chip_info->channel; + indio_dev->available_scan_masks = st->available_scan_masks; + indio_dev->num_channels = 7; + indio_dev->info = &ad7793_info; + + for (i = 0; i < indio_dev->num_channels; i++) + st->available_scan_masks[i] = (1 << i) | (1 << + indio_dev->channels[indio_dev->num_channels - 1]. + scan_index); + + init_waitqueue_head(&st->wq_data_avail); + + ret = ad7793_register_ring_funcs_and_init(indio_dev); + if (ret) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_unreg_ring; + regdone = 1; + + ret = ad7793_probe_trigger(indio_dev); + if (ret) + goto error_unreg_ring; + + ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, + indio_dev->channels, + indio_dev->num_channels); + if (ret) + goto error_remove_trigger; + + ret = ad7793_setup(st); + if (ret) + goto error_uninitialize_ring; + + return 0; + +error_uninitialize_ring: + iio_ring_buffer_unregister(indio_dev->ring); +error_remove_trigger: + ad7793_remove_trigger(indio_dev); +error_unreg_ring: + ad7793_ring_cleanup(indio_dev); +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + + if (regdone) + iio_device_unregister(indio_dev); + else + iio_free_device(indio_dev); + + return ret; +} + +static int ad7793_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7793_state *st = iio_priv(indio_dev); + + iio_ring_buffer_unregister(indio_dev->ring); + ad7793_remove_trigger(indio_dev); + ad7793_ring_cleanup(indio_dev); + + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + + iio_device_unregister(indio_dev); + + return 0; +} + +static const struct spi_device_id ad7793_id[] = { + {"ad7792", ID_AD7792}, + {"ad7793", ID_AD7793}, + {} +}; + +static struct spi_driver ad7793_driver = { + .driver = { + .name = "ad7793", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = ad7793_probe, + .remove = __devexit_p(ad7793_remove), + .id_table = ad7793_id, +}; + +static int __init ad7793_init(void) +{ + return spi_register_driver(&ad7793_driver); +} +module_init(ad7793_init); + +static void __exit ad7793_exit(void) +{ + spi_unregister_driver(&ad7793_driver); +} +module_exit(ad7793_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7792/3 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7793.h b/drivers/staging/iio/adc/ad7793.h new file mode 100644 index 000000000000..64f7d41dc453 --- /dev/null +++ b/drivers/staging/iio/adc/ad7793.h @@ -0,0 +1,107 @@ +/* + * AD7792/AD7793 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ +#ifndef IIO_ADC_AD7793_H_ +#define IIO_ADC_AD7793_H_ + +/* + * TODO: struct ad7793_platform_data needs to go into include/linux/iio + */ + +/* Registers */ +#define AD7793_REG_COMM 0 /* Communications Register (WO, 8-bit) */ +#define AD7793_REG_STAT 0 /* Status Register (RO, 8-bit) */ +#define AD7793_REG_MODE 1 /* Mode Register (RW, 16-bit */ +#define AD7793_REG_CONF 2 /* Configuration Register (RW, 16-bit) */ +#define AD7793_REG_DATA 3 /* Data Register (RO, 16-/24-bit) */ +#define AD7793_REG_ID 4 /* ID Register (RO, 8-bit) */ +#define AD7793_REG_IO 5 /* IO Register (RO, 8-bit) */ +#define AD7793_REG_OFFSET 6 /* Offset Register (RW, 16-bit + * (AD7792)/24-bit (AD7793)) */ +#define AD7793_REG_FULLSALE 7 /* Full-Scale Register + * (RW, 16-bit (AD7792)/24-bit (AD7793)) */ + +/* Communications Register Bit Designations (AD7793_REG_COMM) */ +#define AD7793_COMM_WEN (1 << 7) /* Write Enable */ +#define AD7793_COMM_WRITE (0 << 6) /* Write Operation */ +#define AD7793_COMM_READ (1 << 6) /* Read Operation */ +#define AD7793_COMM_ADDR(x) (((x) & 0x7) << 3) /* Register Address */ +#define AD7793_COMM_CREAD (1 << 2) /* Continuous Read of Data Register */ + +/* Status Register Bit Designations (AD7793_REG_STAT) */ +#define AD7793_STAT_RDY (1 << 7) /* Ready */ +#define AD7793_STAT_ERR (1 << 6) /* Error (Overrange, Underrange) */ +#define AD7793_STAT_CH3 (1 << 2) /* Channel 3 */ +#define AD7793_STAT_CH2 (1 << 1) /* Channel 2 */ +#define AD7793_STAT_CH1 (1 << 0) /* Channel 1 */ + +/* Mode Register Bit Designations (AD7793_REG_MODE) */ +#define AD7793_MODE_SEL(x) (((x) & 0x7) << 13) /* Operation Mode Select */ +#define AD7793_MODE_CLKSRC(x) (((x) & 0x3) << 6) /* ADC Clock Source Select */ +#define AD7793_MODE_RATE(x) ((x) & 0xF) /* Filter Update Rate Select */ + +#define AD7793_MODE_CONT 0 /* Continuous Conversion Mode */ +#define AD7793_MODE_SINGLE 1 /* Single Conversion Mode */ +#define AD7793_MODE_IDLE 2 /* Idle Mode */ +#define AD7793_MODE_PWRDN 3 /* Power-Down Mode */ +#define AD7793_MODE_CAL_INT_ZERO 4 /* Internal Zero-Scale Calibration */ +#define AD7793_MODE_CAL_INT_FULL 5 /* Internal Full-Scale Calibration */ +#define AD7793_MODE_CAL_SYS_ZERO 6 /* System Zero-Scale Calibration */ +#define AD7793_MODE_CAL_SYS_FULL 7 /* System Full-Scale Calibration */ + +#define AD7793_CLK_INT 0 /* Internal 64 kHz Clock not + * available at the CLK pin */ +#define AD7793_CLK_INT_CO 1 /* Internal 64 kHz Clock available + * at the CLK pin */ +#define AD7793_CLK_EXT 2 /* External 64 kHz Clock */ +#define AD7793_CLK_EXT_DIV2 3 /* External Clock divided by 2 */ + +/* Configuration Register Bit Designations (AD7793_REG_CONF) */ +#define AD7793_CONF_VBIAS(x) (((x) & 0x3) << 14) /* Bias Voltage + * Generator Enable */ +#define AD7793_CONF_BO_EN (1 << 13) /* Burnout Current Enable */ +#define AD7793_CONF_UNIPOLAR (1 << 12) /* Unipolar/Bipolar Enable */ +#define AD7793_CONF_BOOST (1 << 11) /* Boost Enable */ +#define AD7793_CONF_GAIN(x) (((x) & 0x7) << 8) /* Gain Select */ +#define AD7793_CONF_REFSEL (1 << 7) /* INT/EXT Reference Select */ +#define AD7793_CONF_BUF (1 << 4) /* Buffered Mode Enable */ +#define AD7793_CONF_CHAN(x) ((x) & 0x7) /* Channel select */ + +#define AD7793_CH_AIN1P_AIN1M 0 /* AIN1(+) - AIN1(-) */ +#define AD7793_CH_AIN2P_AIN2M 1 /* AIN2(+) - AIN2(-) */ +#define AD7793_CH_AIN3P_AIN3M 2 /* AIN3(+) - AIN3(-) */ +#define AD7793_CH_AIN1M_AIN1M 3 /* AIN1(-) - AIN1(-) */ +#define AD7793_CH_TEMP 6 /* Temp Sensor */ +#define AD7793_CH_AVDD_MONITOR 7 /* AVDD Monitor */ + +/* ID Register Bit Designations (AD7793_REG_ID) */ +#define AD7792_ID 0xA +#define AD7793_ID 0xB +#define AD7793_ID_MASK 0xF + +/* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */ +#define AD7793_IO_IEXC1_IOUT1_IEXC2_IOUT2 0 /* IEXC1 connect to IOUT1, + * IEXC2 connect to IOUT2 */ +#define AD7793_IO_IEXC1_IOUT2_IEXC2_IOUT1 1 /* IEXC1 connect to IOUT2, + * IEXC2 connect to IOUT1 */ +#define AD7793_IO_IEXC1_IEXC2_IOUT1 2 /* Both current sources + * IEXC1,2 connect to IOUT1 */ +#define AD7793_IO_IEXC1_IEXC2_IOUT2 3 /* Both current sources + * IEXC1,2 connect to IOUT2 */ + +#define AD7793_IO_IXCEN_10uA (1 << 0) /* Excitation Current 10uA */ +#define AD7793_IO_IXCEN_210uA (2 << 0) /* Excitation Current 210uA */ +#define AD7793_IO_IXCEN_1mA (3 << 0) /* Excitation Current 1mA */ + +struct ad7793_platform_data { + u16 vref_mv; + u16 mode; + u16 conf; + u8 io; +}; + +#endif /* IIO_ADC_AD7793_H_ */ diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 11379e469b07..0c84217bde3d 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -43,7 +43,6 @@ struct ad7816_chip_info { struct spi_device *spi_dev; - struct iio_dev *indio_dev; u16 rdwr_pin; u16 convert_pin; u16 busy_pin; @@ -113,7 +112,7 @@ static ssize_t ad7816_show_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7816_chip_info *chip = dev_info->dev_data; + struct ad7816_chip_info *chip = iio_priv(dev_info); if (chip->mode) return sprintf(buf, "power-save\n"); @@ -127,7 +126,7 @@ static ssize_t ad7816_store_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7816_chip_info *chip = dev_info->dev_data; + struct ad7816_chip_info *chip = iio_priv(dev_info); if (strcmp(buf, "full")) { gpio_set_value(chip->rdwr_pin, 1); @@ -159,7 +158,7 @@ static ssize_t ad7816_show_channel(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7816_chip_info *chip = dev_info->dev_data; + struct ad7816_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", chip->channel_id); } @@ -170,7 +169,7 @@ static ssize_t ad7816_store_channel(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7816_chip_info *chip = dev_info->dev_data; + struct ad7816_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; @@ -208,7 +207,7 @@ static ssize_t ad7816_show_value(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7816_chip_info *chip = dev_info->dev_data; + struct ad7816_chip_info *chip = iio_priv(dev_info); u16 data; s8 value; int ret; @@ -265,7 +264,7 @@ static ssize_t ad7816_show_oti(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7816_chip_info *chip = dev_info->dev_data; + struct ad7816_chip_info *chip = iio_priv(dev_info); int value; if (chip->channel_id > AD7816_CS_MAX) { @@ -286,7 +285,7 @@ static inline ssize_t ad7816_set_oti(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad7816_chip_info *chip = dev_info->dev_data; + struct ad7816_chip_info *chip = iio_priv(dev_info); long value; u8 data; int ret; @@ -345,6 +344,7 @@ static const struct iio_info ad7816_info = { static int __devinit ad7816_probe(struct spi_device *spi_dev) { struct ad7816_chip_info *chip; + struct iio_dev *indio_dev; unsigned short *pins = spi_dev->dev.platform_data; int ret = 0; int i; @@ -354,13 +354,14 @@ static int __devinit ad7816_probe(struct spi_device *spi_dev) return -EINVAL; } - chip = kzalloc(sizeof(struct ad7816_chip_info), GFP_KERNEL); - - if (chip == NULL) - return -ENOMEM; - + indio_dev = iio_allocate_device(sizeof(*chip)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + chip = iio_priv(indio_dev); /* this is only used for device removal purposes */ - dev_set_drvdata(&spi_dev->dev, chip); + dev_set_drvdata(&spi_dev->dev, indio_dev); chip->spi_dev = spi_dev; for (i = 0; i <= AD7816_CS_MAX; i++) @@ -373,7 +374,7 @@ static int __devinit ad7816_probe(struct spi_device *spi_dev) if (ret) { dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n", chip->rdwr_pin); - goto error_free_chip; + goto error_free_device; } gpio_direction_input(chip->rdwr_pin); ret = gpio_request(chip->convert_pin, spi_get_device_id(spi_dev)->name); @@ -391,20 +392,14 @@ static int __devinit ad7816_probe(struct spi_device *spi_dev) } gpio_direction_input(chip->busy_pin); - chip->indio_dev = iio_allocate_device(0); - if (chip->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_gpio; - } - chip->indio_dev->name = spi_get_device_id(spi_dev)->name; - chip->indio_dev->dev.parent = &spi_dev->dev; - chip->indio_dev->info = &ad7816_info; - chip->indio_dev->dev_data = (void *)chip; - chip->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = spi_get_device_id(spi_dev)->name; + indio_dev->dev.parent = &spi_dev->dev; + indio_dev->info = &ad7816_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(chip->indio_dev); + ret = iio_device_register(indio_dev); if (ret) - goto error_free_dev; + goto error_free_gpio; if (spi_dev->irq) { /* Only low trigger is supported in ad7816/7/8 */ @@ -412,47 +407,44 @@ static int __devinit ad7816_probe(struct spi_device *spi_dev) NULL, &ad7816_event_handler, IRQF_TRIGGER_LOW, - chip->indio_dev->name, - chip->indio_dev); + indio_dev->name, + indio_dev); if (ret) goto error_unreg_dev; } dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n", - chip->indio_dev->name); + indio_dev->name); return 0; error_unreg_dev: - iio_device_unregister(chip->indio_dev); -error_free_dev: - iio_free_device(chip->indio_dev); + iio_device_unregister(indio_dev); error_free_gpio: gpio_free(chip->busy_pin); error_free_gpio_convert: gpio_free(chip->convert_pin); error_free_gpio_rdwr: gpio_free(chip->rdwr_pin); -error_free_chip: - kfree(chip); - +error_free_device: + iio_free_device(indio_dev); +error_ret: return ret; } static int __devexit ad7816_remove(struct spi_device *spi_dev) { - struct ad7816_chip_info *chip = dev_get_drvdata(&spi_dev->dev); - struct iio_dev *indio_dev = chip->indio_dev; + struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev); + struct ad7816_chip_info *chip = iio_priv(indio_dev); dev_set_drvdata(&spi_dev->dev, NULL); if (spi_dev->irq) free_irq(spi_dev->irq, indio_dev); - iio_device_unregister(indio_dev); - iio_free_device(chip->indio_dev); gpio_free(chip->busy_pin); gpio_free(chip->convert_pin); gpio_free(chip->rdwr_pin); - kfree(chip); + iio_device_unregister(indio_dev); + iio_free_device(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c index de14b174cef7..3d9121e5c37d 100644 --- a/drivers/staging/iio/adc/ad7887_core.c +++ b/drivers/staging/iio/adc/ad7887_core.c @@ -37,7 +37,7 @@ static int ad7887_read_raw(struct iio_dev *dev_info, long m) { int ret; - struct ad7887_state *st = dev_info->dev_data; + struct ad7887_state *st = iio_priv(dev_info); unsigned int scale_uv; switch (m) { @@ -118,7 +118,6 @@ static int __devinit ad7887_probe(struct spi_device *spi) /* Estabilish that the iio_dev is a child of the spi device */ indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; - indio_dev->dev_data = (void *)(st); indio_dev->info = &ad7887_info; indio_dev->modes = INDIO_DIRECT_MODE; diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index 0e4a5f4fd892..0ac7c0b9d71d 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -64,7 +64,7 @@ int ad7887_scan_from_ring(struct ad7887_state *st, long mask) **/ static int ad7887_ring_preenable(struct iio_dev *indio_dev) { - struct ad7887_state *st = indio_dev->dev_data; + struct ad7887_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; st->d_size = ring->scan_count * @@ -100,7 +100,7 @@ static int ad7887_ring_preenable(struct iio_dev *indio_dev) static int ad7887_ring_postdisable(struct iio_dev *indio_dev) { - struct ad7887_state *st = indio_dev->dev_data; + struct ad7887_state *st = iio_priv(indio_dev); /* dummy read: restore default CH0 settin */ return spi_sync(st->spi, &st->msg[AD7887_CH0]); @@ -116,7 +116,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->private_data; - struct ad7887_state *st = iio_dev_get_devdata(indio_dev); + struct ad7887_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; s64 time_ns; __u8 *buf; diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index 29bfbcf82064..92cfe2e3ea4a 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c @@ -143,7 +143,7 @@ static int ad799x_read_raw(struct iio_dev *dev_info, long m) { int ret; - struct ad799x_state *st = dev_info->dev_data; + struct ad799x_state *st = iio_priv(dev_info); unsigned int scale_uv; switch (m) { @@ -176,7 +176,7 @@ static ssize_t ad799x_read_frequency(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad799x_state *st = iio_dev_get_devdata(dev_info); + struct ad799x_state *st = iio_priv(dev_info); int ret, len = 0; u8 val; @@ -221,7 +221,7 @@ static ssize_t ad799x_write_frequency(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad799x_state *st = iio_dev_get_devdata(dev_info); + struct ad799x_state *st = iio_priv(dev_info); long val; int ret; @@ -281,7 +281,7 @@ static ssize_t ad799x_read_channel_config(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad799x_state *st = iio_dev_get_devdata(dev_info); + struct ad799x_state *st = iio_priv(dev_info); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; @@ -299,7 +299,7 @@ static ssize_t ad799x_write_channel_config(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad799x_state *st = iio_dev_get_devdata(dev_info); + struct ad799x_state *st = iio_priv(dev_info); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); long val; @@ -319,7 +319,7 @@ static ssize_t ad799x_write_channel_config(struct device *dev, static irqreturn_t ad799x_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; - struct ad799x_state *st = iio_dev_get_devdata(private); + struct ad799x_state *st = iio_priv(private); u8 status; int i, ret; @@ -686,7 +686,6 @@ static int __devinit ad799x_probe(struct i2c_client *client, indio_dev->name = id->name; indio_dev->info = st->chip_info->info; indio_dev->name = id->name; - indio_dev->dev_data = (void *)(st); indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = st->chip_info->channel; diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 1ae8857b3d25..0376a826c26c 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -72,7 +72,7 @@ int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask) static int ad799x_ring_preenable(struct iio_dev *indio_dev) { struct iio_ring_buffer *ring = indio_dev->ring; - struct ad799x_state *st = iio_dev_get_devdata(indio_dev); + struct ad799x_state *st = iio_priv(indio_dev); /* * Need to figure out the current mode based upon the requested @@ -109,7 +109,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->private_data; - struct ad799x_state *st = iio_dev_get_devdata(indio_dev); + struct ad799x_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; s64 time_ns; __u8 *rxbuf; diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c index 68eca0b99ac0..1a41b8034405 100644 --- a/drivers/staging/iio/adc/adt7310.c +++ b/drivers/staging/iio/adc/adt7310.c @@ -80,7 +80,6 @@ struct adt7310_chip_info { struct spi_device *spi_dev; - struct iio_dev *indio_dev; u8 config; }; @@ -176,7 +175,7 @@ static ssize_t adt7310_show_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); u8 config; config = chip->config & ADT7310_MODE_MASK; @@ -199,7 +198,7 @@ static ssize_t adt7310_store_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); u16 config; int ret; @@ -243,7 +242,7 @@ static ssize_t adt7310_show_resolution(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); int ret; int bits; @@ -265,7 +264,7 @@ static ssize_t adt7310_store_resolution(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); unsigned long data; u16 config; int ret; @@ -301,7 +300,7 @@ static ssize_t adt7310_show_id(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); u8 id; int ret; @@ -351,7 +350,7 @@ static ssize_t adt7310_show_value(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); u8 status; u16 data; int ret, i = 0; @@ -390,7 +389,7 @@ static const struct attribute_group adt7310_attribute_group = { static irqreturn_t adt7310_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; - struct adt7310_chip_info *chip = iio_dev_get_devdata(indio_dev); + struct adt7310_chip_info *chip = iio_priv(indio_dev); s64 timestamp = iio_get_time_ns(); u8 status; int ret; @@ -425,7 +424,7 @@ static ssize_t adt7310_show_event_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); int ret; ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); @@ -444,7 +443,7 @@ static ssize_t adt7310_set_event_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); u16 config; int ret; @@ -477,7 +476,7 @@ static ssize_t adt7310_show_fault_queue(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); int ret; ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); @@ -493,7 +492,7 @@ static ssize_t adt7310_set_fault_queue(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; u8 config; @@ -523,7 +522,7 @@ static inline ssize_t adt7310_show_t_bound(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); u16 data; int ret; @@ -541,7 +540,7 @@ static inline ssize_t adt7310_set_t_bound(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); long tmp1, tmp2; u16 data; char *pos; @@ -661,7 +660,7 @@ static ssize_t adt7310_show_t_hyst(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); int ret; u8 t_hyst; @@ -678,7 +677,7 @@ static inline ssize_t adt7310_set_t_hyst(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7310_chip_info *chip = dev_info->dev_data; + struct adt7310_chip_info *chip = iio_priv(dev_info); int ret; unsigned long data; u8 t_hyst; @@ -760,33 +759,28 @@ static const struct iio_info adt7310_info = { static int __devinit adt7310_probe(struct spi_device *spi_dev) { struct adt7310_chip_info *chip; + struct iio_dev *indio_dev; int ret = 0; unsigned long *adt7310_platform_data = spi_dev->dev.platform_data; unsigned long irq_flags; - chip = kzalloc(sizeof(struct adt7310_chip_info), GFP_KERNEL); - - if (chip == NULL) - return -ENOMEM; - + indio_dev = iio_allocate_device(sizeof(*chip)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + chip = iio_priv(indio_dev); /* this is only used for device removal purposes */ - dev_set_drvdata(&spi_dev->dev, chip); + dev_set_drvdata(&spi_dev->dev, indio_dev); chip->spi_dev = spi_dev; - chip->indio_dev = iio_allocate_device(0); - if (chip->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_chip; - } + indio_dev->dev.parent = &spi_dev->dev; + indio_dev->name = spi_get_device_id(spi_dev)->name; + indio_dev->info = &adt7310_info; + indio_dev->modes = INDIO_DIRECT_MODE; - chip->indio_dev->dev.parent = &spi_dev->dev; - chip->indio_dev->name = spi_get_device_id(spi_dev)->name; - chip->indio_dev->info = &adt7310_info; - chip->indio_dev->dev_data = (void *)chip; - chip->indio_dev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(chip->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; @@ -800,8 +794,8 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev) NULL, &adt7310_event_handler, irq_flags, - chip->indio_dev->name, - chip->indio_dev); + indio_dev->name, + indio_dev); if (ret) goto error_unreg_dev; } @@ -812,8 +806,8 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev) NULL, &adt7310_event_handler, adt7310_platform_data[1], - chip->indio_dev->name, - chip->indio_dev); + indio_dev->name, + indio_dev); if (ret) goto error_unreg_ct_irq; } @@ -841,38 +835,34 @@ static int __devinit adt7310_probe(struct spi_device *spi_dev) } dev_info(&spi_dev->dev, "%s temperature sensor registered.\n", - chip->indio_dev->name); + indio_dev->name); return 0; error_unreg_int_irq: - free_irq(adt7310_platform_data[0], chip->indio_dev); + free_irq(adt7310_platform_data[0], indio_dev); error_unreg_ct_irq: - free_irq(spi_dev->irq, chip->indio_dev); + free_irq(spi_dev->irq, indio_dev); error_unreg_dev: - iio_device_unregister(chip->indio_dev); + iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(chip->indio_dev); -error_free_chip: - kfree(chip); - + iio_free_device(indio_dev); +error_ret: return ret; } static int __devexit adt7310_remove(struct spi_device *spi_dev) { - struct adt7310_chip_info *chip = dev_get_drvdata(&spi_dev->dev); - struct iio_dev *indio_dev = chip->indio_dev; + struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev); unsigned long *adt7310_platform_data = spi_dev->dev.platform_data; dev_set_drvdata(&spi_dev->dev, NULL); if (adt7310_platform_data[0]) - free_irq(adt7310_platform_data[0], chip->indio_dev); + free_irq(adt7310_platform_data[0], indio_dev); if (spi_dev->irq) - free_irq(spi_dev->irq, chip->indio_dev); + free_irq(spi_dev->irq, indio_dev); iio_device_unregister(indio_dev); - iio_free_device(chip->indio_dev); - kfree(chip); + iio_free_device(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c index c40a84f9c2ff..76aa0639a55a 100644 --- a/drivers/staging/iio/adc/adt7410.c +++ b/drivers/staging/iio/adc/adt7410.c @@ -75,7 +75,6 @@ struct adt7410_chip_info { struct i2c_client *client; - struct iio_dev *indio_dev; u8 config; }; @@ -144,7 +143,7 @@ static ssize_t adt7410_show_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); u8 config; config = chip->config & ADT7410_MODE_MASK; @@ -167,7 +166,7 @@ static ssize_t adt7410_store_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); u16 config; int ret; @@ -211,7 +210,7 @@ static ssize_t adt7410_show_resolution(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); int ret; int bits; @@ -233,7 +232,7 @@ static ssize_t adt7410_store_resolution(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); unsigned long data; u16 config; int ret; @@ -269,7 +268,7 @@ static ssize_t adt7410_show_id(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); u8 id; int ret; @@ -319,7 +318,7 @@ static ssize_t adt7410_show_value(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); u8 status; u16 data; int ret, i = 0; @@ -358,7 +357,7 @@ static const struct attribute_group adt7410_attribute_group = { static irqreturn_t adt7410_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; - struct adt7410_chip_info *chip = iio_dev_get_devdata(indio_dev); + struct adt7410_chip_info *chip = iio_priv(indio_dev); s64 timestamp = iio_get_time_ns(); u8 status; @@ -392,7 +391,7 @@ static ssize_t adt7410_show_event_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); int ret; ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); @@ -411,7 +410,7 @@ static ssize_t adt7410_set_event_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); u16 config; int ret; @@ -444,7 +443,7 @@ static ssize_t adt7410_show_fault_queue(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); int ret; ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); @@ -460,7 +459,7 @@ static ssize_t adt7410_set_fault_queue(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; u8 config; @@ -490,7 +489,7 @@ static inline ssize_t adt7410_show_t_bound(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); u16 data; int ret; @@ -508,7 +507,7 @@ static inline ssize_t adt7410_set_t_bound(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); long tmp1, tmp2; u16 data; char *pos; @@ -628,7 +627,7 @@ static ssize_t adt7410_show_t_hyst(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); int ret; u8 t_hyst; @@ -645,7 +644,7 @@ static inline ssize_t adt7410_set_t_hyst(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7410_chip_info *chip = dev_info->dev_data; + struct adt7410_chip_info *chip = iio_priv(dev_info); int ret; unsigned long data; u8 t_hyst; @@ -728,31 +727,27 @@ static int __devinit adt7410_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct adt7410_chip_info *chip; + struct iio_dev *indio_dev; int ret = 0; unsigned long *adt7410_platform_data = client->dev.platform_data; - chip = kzalloc(sizeof(struct adt7410_chip_info), GFP_KERNEL); - - if (chip == NULL) - return -ENOMEM; - + indio_dev = iio_allocate_device(sizeof(*chip)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + chip = iio_priv(indio_dev); /* this is only used for device removal purposes */ - i2c_set_clientdata(client, chip); + i2c_set_clientdata(client, indio_dev); chip->client = client; - chip->indio_dev = iio_allocate_device(0); - if (chip->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_chip; - } - chip->indio_dev->name = id->name; - chip->indio_dev->dev.parent = &client->dev; - chip->indio_dev->info = &adt7410_info; - chip->indio_dev->dev_data = (void *)chip; - chip->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; + indio_dev->info = &adt7410_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(chip->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; @@ -763,7 +758,7 @@ static int __devinit adt7410_probe(struct i2c_client *client, &adt7410_event_handler, IRQF_TRIGGER_LOW, id->name, - chip->indio_dev); + indio_dev); if (ret) goto error_unreg_dev; } @@ -775,7 +770,7 @@ static int __devinit adt7410_probe(struct i2c_client *client, &adt7410_event_handler, adt7410_platform_data[1], id->name, - chip->indio_dev); + indio_dev); if (ret) goto error_unreg_ct_irq; } @@ -809,32 +804,27 @@ static int __devinit adt7410_probe(struct i2c_client *client, return 0; error_unreg_int_irq: - free_irq(adt7410_platform_data[0], chip->indio_dev); + free_irq(adt7410_platform_data[0], indio_dev); error_unreg_ct_irq: - free_irq(client->irq, chip->indio_dev); + free_irq(client->irq, indio_dev); error_unreg_dev: - iio_device_unregister(chip->indio_dev); + iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(chip->indio_dev); -error_free_chip: - kfree(chip); - + iio_free_device(indio_dev); +error_ret: return ret; } static int __devexit adt7410_remove(struct i2c_client *client) { - struct adt7410_chip_info *chip = i2c_get_clientdata(client); - struct iio_dev *indio_dev = chip->indio_dev; + struct iio_dev *indio_dev = i2c_get_clientdata(client); unsigned long *adt7410_platform_data = client->dev.platform_data; if (adt7410_platform_data[0]) - free_irq(adt7410_platform_data[0], chip->indio_dev); + free_irq(adt7410_platform_data[0], indio_dev); if (client->irq) - free_irq(client->irq, chip->indio_dev); + free_irq(client->irq, indio_dev); iio_device_unregister(indio_dev); - iio_free_device(chip->indio_dev); - kfree(chip); return 0; } diff --git a/drivers/staging/iio/adc/adt75.c b/drivers/staging/iio/adc/adt75.c index 1171fb9c178f..38f141de6a4b 100644 --- a/drivers/staging/iio/adc/adt75.c +++ b/drivers/staging/iio/adc/adt75.c @@ -51,7 +51,6 @@ struct adt75_chip_info { struct i2c_client *client; - struct iio_dev *indio_dev; u8 config; }; @@ -59,8 +58,9 @@ struct adt75_chip_info { * adt75 register access by I2C */ -static int adt75_i2c_read(struct adt75_chip_info *chip, u8 reg, u8 *data) +static int adt75_i2c_read(struct iio_dev *dev_info, u8 reg, u8 *data) { + struct adt75_chip_info *chip = iio_priv(dev_info); struct i2c_client *client = chip->client; int ret = 0, len; @@ -84,8 +84,9 @@ static int adt75_i2c_read(struct adt75_chip_info *chip, u8 reg, u8 *data) return ret; } -static int adt75_i2c_write(struct adt75_chip_info *chip, u8 reg, u8 data) +static int adt75_i2c_write(struct iio_dev *dev_info, u8 reg, u8 data) { + struct adt75_chip_info *chip = iio_priv(dev_info); struct i2c_client *client = chip->client; int ret = 0; @@ -104,8 +105,7 @@ static ssize_t adt75_show_mode(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; + struct adt75_chip_info *chip = iio_priv(dev_get_drvdata(dev)); if (chip->config & ADT75_PD) return sprintf(buf, "power-save\n"); @@ -119,11 +119,11 @@ static ssize_t adt75_store_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; + struct adt75_chip_info *chip = iio_priv(dev_info); int ret; u8 config; - ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); if (ret) return -EIO; @@ -131,7 +131,7 @@ static ssize_t adt75_store_mode(struct device *dev, if (!strcmp(buf, "full")) config |= ADT75_PD; - ret = adt75_i2c_write(chip, ADT75_CONFIG, config); + ret = adt75_i2c_write(dev_info, ADT75_CONFIG, config); if (ret) return -EIO; @@ -158,8 +158,7 @@ static ssize_t adt75_show_oneshot(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; + struct adt75_chip_info *chip = iio_priv(dev_get_drvdata(dev)); return sprintf(buf, "%d\n", !!(chip->config & ADT75_ONESHOT)); } @@ -170,7 +169,7 @@ static ssize_t adt75_store_oneshot(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; + struct adt75_chip_info *chip = iio_priv(dev_info); unsigned long data = 0; int ret; u8 config; @@ -180,7 +179,7 @@ static ssize_t adt75_store_oneshot(struct device *dev, return -EINVAL; - ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); if (ret) return -EIO; @@ -188,7 +187,7 @@ static ssize_t adt75_store_oneshot(struct device *dev, if (data) config |= ADT75_ONESHOT; - ret = adt75_i2c_write(chip, ADT75_CONFIG, config); + ret = adt75_i2c_write(dev_info, ADT75_CONFIG, config); if (ret) return -EIO; @@ -207,7 +206,7 @@ static ssize_t adt75_show_value(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; + struct adt75_chip_info *chip = iio_priv(dev_info); u16 data; char sign = ' '; int ret; @@ -224,7 +223,7 @@ static ssize_t adt75_show_value(struct device *dev, return -EIO; } - ret = adt75_i2c_read(chip, ADT75_TEMPERATURE, (u8 *)&data); + ret = adt75_i2c_read(dev_info, ADT75_TEMPERATURE, (u8 *)&data); if (ret) return -EIO; @@ -277,11 +276,11 @@ static ssize_t adt75_show_oti_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; + struct adt75_chip_info *chip = iio_priv(dev_info); int ret; /* retrive ALART status */ - ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); if (ret) return -EIO; @@ -297,12 +296,12 @@ static ssize_t adt75_set_oti_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; + struct adt75_chip_info *chip = iio_priv(dev_info); int ret; u8 config; /* retrive ALART status */ - ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); if (ret) return -EIO; @@ -310,7 +309,7 @@ static ssize_t adt75_set_oti_mode(struct device *dev, if (strcmp(buf, "comparator") != 0) config |= ADT75_OS_INT; - ret = adt75_i2c_write(chip, ADT75_CONFIG, config); + ret = adt75_i2c_write(dev_info, ADT75_CONFIG, config); if (ret) return -EIO; @@ -331,11 +330,11 @@ static ssize_t adt75_show_smbus_alart(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; + struct adt75_chip_info *chip = iio_priv(dev_info); int ret; /* retrive ALART status */ - ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); if (ret) return -EIO; @@ -348,7 +347,7 @@ static ssize_t adt75_set_smbus_alart(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; + struct adt75_chip_info *chip = iio_priv(dev_info); unsigned long data = 0; int ret; u8 config; @@ -358,7 +357,7 @@ static ssize_t adt75_set_smbus_alart(struct device *dev, return -EINVAL; /* retrive ALART status */ - ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); if (ret) return -EIO; @@ -366,7 +365,7 @@ static ssize_t adt75_set_smbus_alart(struct device *dev, if (data) config |= ADT75_SMBUS_ALART; - ret = adt75_i2c_write(chip, ADT75_CONFIG, config); + ret = adt75_i2c_write(dev_info, ADT75_CONFIG, config); if (ret) return -EIO; @@ -380,11 +379,11 @@ static ssize_t adt75_show_fault_queue(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; + struct adt75_chip_info *chip = iio_priv(dev_info); int ret; /* retrive ALART status */ - ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); if (ret) return -EIO; @@ -398,7 +397,7 @@ static ssize_t adt75_set_fault_queue(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; + struct adt75_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; u8 config; @@ -408,13 +407,13 @@ static ssize_t adt75_set_fault_queue(struct device *dev, return -EINVAL; /* retrive ALART status */ - ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + ret = adt75_i2c_read(dev_info, ADT75_CONFIG, &chip->config); if (ret) return -EIO; config = chip->config & ~ADT75_FAULT_QUEUE_MASK; config |= (data << ADT75_FAULT_QUEUE_OFFSET); - ret = adt75_i2c_write(chip, ADT75_CONFIG, config); + ret = adt75_i2c_write(dev_info, ADT75_CONFIG, config); if (ret) return -EIO; @@ -428,12 +427,11 @@ static inline ssize_t adt75_show_t_bound(struct device *dev, { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; u16 data; char sign = ' '; int ret; - ret = adt75_i2c_read(chip, this_attr->address, (u8 *)&data); + ret = adt75_i2c_read(dev_info, this_attr->address, (u8 *)&data); if (ret) return -EIO; @@ -456,7 +454,6 @@ static inline ssize_t adt75_set_t_bound(struct device *dev, { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt75_chip_info *chip = dev_info->dev_data; long tmp1, tmp2; u16 data; char *pos; @@ -491,7 +488,7 @@ static inline ssize_t adt75_set_t_bound(struct device *dev, data <<= ADT75_VALUE_OFFSET; data = swab16(data); - ret = adt75_i2c_write(chip, this_attr->address, (u8)data); + ret = adt75_i2c_write(dev_info, this_attr->address, (u8)data); if (ret) return -EIO; @@ -549,31 +546,27 @@ static int __devinit adt75_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct adt75_chip_info *chip; + struct iio_dev *indio_dev; int ret = 0; - chip = kzalloc(sizeof(struct adt75_chip_info), GFP_KERNEL); - - if (chip == NULL) - return -ENOMEM; + indio_dev = iio_allocate_device(sizeof(*chip)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + chip = iio_priv(indio_dev); /* this is only used for device removal purposes */ - i2c_set_clientdata(client, chip); + i2c_set_clientdata(client, indio_dev); chip->client = client; - chip->indio_dev = iio_allocate_device(0); - if (chip->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_chip; - } + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; + indio_dev->info = &adt75_info; + indio_dev->modes = INDIO_DIRECT_MODE; - chip->indio_dev->name = id->name; - chip->indio_dev->dev.parent = &client->dev; - chip->indio_dev->info = &adt75_info; - chip->indio_dev->dev_data = (void *)chip; - chip->indio_dev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(chip->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; @@ -582,12 +575,12 @@ static int __devinit adt75_probe(struct i2c_client *client, NULL, &adt75_event_handler, IRQF_TRIGGER_LOW, - chip->indio_dev->name, - chip->indio_dev); + indio_dev->name, + indio_dev); if (ret) goto error_unreg_dev; - ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + ret = adt75_i2c_read(indio_dev, ADT75_CONFIG, &chip->config); if (ret) { ret = -EIO; goto error_unreg_irq; @@ -596,7 +589,7 @@ static int __devinit adt75_probe(struct i2c_client *client, /* set irq polarity low level */ chip->config &= ~ADT75_OS_POLARITY; - ret = adt75_i2c_write(chip, ADT75_CONFIG, chip->config); + ret = adt75_i2c_write(indio_dev, ADT75_CONFIG, chip->config); if (ret) { ret = -EIO; goto error_unreg_irq; @@ -604,31 +597,27 @@ static int __devinit adt75_probe(struct i2c_client *client, } dev_info(&client->dev, "%s temperature sensor registered.\n", - chip->indio_dev->name); + indio_dev->name); return 0; error_unreg_irq: - free_irq(client->irq, chip->indio_dev); + free_irq(client->irq, indio_dev); error_unreg_dev: - iio_device_unregister(chip->indio_dev); + iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(chip->indio_dev); -error_free_chip: - kfree(chip); - + iio_free_device(indio_dev); +error_ret: return ret; } static int __devexit adt75_remove(struct i2c_client *client) { - struct adt75_chip_info *chip = i2c_get_clientdata(client); - struct iio_dev *indio_dev = chip->indio_dev; + struct iio_dev *indio_dev = i2c_get_clientdata(client); if (client->irq) - free_irq(client->irq, chip->indio_dev); + free_irq(client->irq, indio_dev); iio_device_unregister(indio_dev); - iio_free_device(chip->indio_dev); - kfree(chip); + iio_free_device(indio_dev); return 0; } diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 98cebd26310f..72b0917412ee 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -1255,12 +1255,15 @@ static int __devinit max1363_probe(struct i2c_client *client, struct regulator *reg; reg = regulator_get(&client->dev, "vcc"); - if (!IS_ERR(reg)) { - ret = regulator_enable(reg); - if (ret) - goto error_put_reg; + if (IS_ERR(reg)) { + ret = PTR_ERR(reg); + goto error_out; } + ret = regulator_enable(reg); + if (ret) + goto error_put_reg; + indio_dev = iio_allocate_device(sizeof(struct max1363_state)); if (indio_dev == NULL) { ret = -ENOMEM; @@ -1323,6 +1326,7 @@ static int __devinit max1363_probe(struct i2c_client *client, } return 0; + error_uninit_ring: iio_ring_buffer_unregister(indio_dev->ring); error_cleanup_ring: @@ -1335,12 +1339,10 @@ static int __devinit max1363_probe(struct i2c_client *client, else iio_device_unregister(indio_dev); error_disable_reg: - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + regulator_disable(reg); error_put_reg: - if (!IS_ERR(st->reg)) - regulator_put(st->reg); - + regulator_put(reg); +error_out: return ret; } diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index 7097deb0f309..637316f79f78 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -174,7 +174,6 @@ */ struct adt7316_chip_info { - struct iio_dev *indio_dev; struct adt7316_bus bus; u16 ldac_pin; u16 int_mask; /* 0x2f */ @@ -220,7 +219,7 @@ static ssize_t adt7316_show_enabled(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_EN)); } @@ -252,7 +251,7 @@ static ssize_t adt7316_store_enabled(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); int enable; if (!memcmp(buf, "1", 1)) @@ -276,7 +275,7 @@ static ssize_t adt7316_show_select_ex_temp(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX) return -EPERM; @@ -290,7 +289,7 @@ static ssize_t adt7316_store_select_ex_temp(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config1; int ret; @@ -320,7 +319,7 @@ static ssize_t adt7316_show_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); if (chip->config2 & ADT7316_AD_SINGLE_CH_MODE) return sprintf(buf, "single_channel\n"); @@ -334,7 +333,7 @@ static ssize_t adt7316_store_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config2; int ret; @@ -370,7 +369,7 @@ static ssize_t adt7316_show_ad_channel(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE)) return -EPERM; @@ -409,7 +408,7 @@ static ssize_t adt7316_store_ad_channel(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config2; unsigned long data = 0; int ret; @@ -455,7 +454,7 @@ static ssize_t adt7316_show_all_ad_channels(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE)) return -EPERM; @@ -477,7 +476,7 @@ static ssize_t adt7316_show_disable_averaging(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->config2 & ADT7316_DISABLE_AVERAGING)); @@ -489,7 +488,7 @@ static ssize_t adt7316_store_disable_averaging(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config2; int ret; @@ -516,7 +515,7 @@ static ssize_t adt7316_show_enable_smbus_timeout(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->config2 & ADT7316_EN_SMBUS_TIMEOUT)); @@ -528,7 +527,7 @@ static ssize_t adt7316_store_enable_smbus_timeout(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config2; int ret; @@ -557,7 +556,7 @@ static ssize_t adt7316_store_reset(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config2; int ret; @@ -580,7 +579,7 @@ static ssize_t adt7316_show_powerdown(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_PD)); } @@ -591,7 +590,7 @@ static ssize_t adt7316_store_powerdown(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config1; int ret; @@ -618,7 +617,7 @@ static ssize_t adt7316_show_fast_ad_clock(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->config3 & ADT7316_ADCLK_22_5)); } @@ -629,7 +628,7 @@ static ssize_t adt7316_store_fast_ad_clock(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config3; int ret; @@ -656,7 +655,7 @@ static ssize_t adt7316_show_da_high_resolution(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); if (chip->config3 & ADT7316_DA_HIGH_RESOLUTION) { if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516) @@ -674,7 +673,7 @@ static ssize_t adt7316_store_da_high_resolution(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config3; int ret; @@ -708,7 +707,7 @@ static ssize_t adt7316_show_AIN_internal_Vref(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX) return -EPERM; @@ -723,7 +722,7 @@ static ssize_t adt7316_store_AIN_internal_Vref(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config3; int ret; @@ -755,7 +754,7 @@ static ssize_t adt7316_show_enable_prop_DACA(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)); @@ -767,7 +766,7 @@ static ssize_t adt7316_store_enable_prop_DACA(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config3; int ret; @@ -794,7 +793,7 @@ static ssize_t adt7316_show_enable_prop_DACB(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB)); @@ -806,7 +805,7 @@ static ssize_t adt7316_store_enable_prop_DACB(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config3; int ret; @@ -833,7 +832,7 @@ static ssize_t adt7316_show_DAC_2Vref_ch_mask(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%x\n", chip->dac_config & ADT7316_DA_2VREF_CH_MASK); @@ -845,7 +844,7 @@ static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 dac_config; unsigned long data = 0; int ret; @@ -876,7 +875,7 @@ static ssize_t adt7316_show_DAC_update_mode(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA)) return sprintf(buf, "manual\n"); @@ -900,7 +899,7 @@ static ssize_t adt7316_store_DAC_update_mode(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 dac_config; unsigned long data; int ret; @@ -934,7 +933,7 @@ static ssize_t adt7316_show_all_DAC_update_modes(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) return sprintf(buf, "0 - auto at any MSB DAC writing\n" @@ -955,7 +954,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 ldac_config; unsigned long data; int ret; @@ -994,7 +993,7 @@ static ssize_t adt7316_show_DA_AB_Vref_bypass(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) return -EPERM; @@ -1009,7 +1008,7 @@ static ssize_t adt7316_store_DA_AB_Vref_bypass(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 dac_config; int ret; @@ -1039,7 +1038,7 @@ static ssize_t adt7316_show_DA_CD_Vref_bypass(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) return -EPERM; @@ -1054,7 +1053,7 @@ static ssize_t adt7316_store_DA_CD_Vref_bypass(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 dac_config; int ret; @@ -1084,7 +1083,7 @@ static ssize_t adt7316_show_DAC_internal_Vref(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) return sprintf(buf, "0x%x\n", @@ -1101,7 +1100,7 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 ldac_config; unsigned long data; int ret; @@ -1220,7 +1219,7 @@ static ssize_t adt7316_show_VDD(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_VDD, buf); } @@ -1231,7 +1230,7 @@ static ssize_t adt7316_show_in_temp(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_IN, buf); } @@ -1243,7 +1242,7 @@ static ssize_t adt7316_show_ex_temp_AIN1(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_EX, buf); } @@ -1256,7 +1255,7 @@ static ssize_t adt7316_show_AIN2(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN2, buf); } @@ -1267,7 +1266,7 @@ static ssize_t adt7316_show_AIN3(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN3, buf); } @@ -1278,7 +1277,7 @@ static ssize_t adt7316_show_AIN4(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN4, buf); } @@ -1330,7 +1329,7 @@ static ssize_t adt7316_show_in_temp_offset(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf); } @@ -1341,7 +1340,7 @@ static ssize_t adt7316_store_in_temp_offset(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf, len); } @@ -1355,7 +1354,7 @@ static ssize_t adt7316_show_ex_temp_offset(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf); } @@ -1366,7 +1365,7 @@ static ssize_t adt7316_store_ex_temp_offset(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf, len); } @@ -1380,7 +1379,7 @@ static ssize_t adt7316_show_in_analog_temp_offset(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_temp_offset(chip, ADT7316_IN_ANALOG_TEMP_OFFSET, buf); @@ -1392,7 +1391,7 @@ static ssize_t adt7316_store_in_analog_temp_offset(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_temp_offset(chip, ADT7316_IN_ANALOG_TEMP_OFFSET, buf, len); @@ -1407,7 +1406,7 @@ static ssize_t adt7316_show_ex_analog_temp_offset(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_temp_offset(chip, ADT7316_EX_ANALOG_TEMP_OFFSET, buf); @@ -1419,7 +1418,7 @@ static ssize_t adt7316_store_ex_analog_temp_offset(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_temp_offset(chip, ADT7316_EX_ANALOG_TEMP_OFFSET, buf, len); @@ -1504,7 +1503,7 @@ static ssize_t adt7316_show_DAC_A(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_DAC(chip, 0, buf); } @@ -1515,7 +1514,7 @@ static ssize_t adt7316_store_DAC_A(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_DAC(chip, 0, buf, len); } @@ -1528,7 +1527,7 @@ static ssize_t adt7316_show_DAC_B(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_DAC(chip, 1, buf); } @@ -1539,7 +1538,7 @@ static ssize_t adt7316_store_DAC_B(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_DAC(chip, 1, buf, len); } @@ -1552,7 +1551,7 @@ static ssize_t adt7316_show_DAC_C(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_DAC(chip, 2, buf); } @@ -1563,7 +1562,7 @@ static ssize_t adt7316_store_DAC_C(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_DAC(chip, 2, buf, len); } @@ -1576,7 +1575,7 @@ static ssize_t adt7316_show_DAC_D(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_show_DAC(chip, 3, buf); } @@ -1587,7 +1586,7 @@ static ssize_t adt7316_store_DAC_D(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return adt7316_store_DAC(chip, 3, buf, len); } @@ -1600,7 +1599,7 @@ static ssize_t adt7316_show_device_id(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 id; int ret; @@ -1618,7 +1617,7 @@ static ssize_t adt7316_show_manufactorer_id(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 id; int ret; @@ -1637,7 +1636,7 @@ static ssize_t adt7316_show_device_rev(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 rev; int ret; @@ -1655,7 +1654,7 @@ static ssize_t adt7316_show_bus_type(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 stat; int ret; @@ -1765,7 +1764,7 @@ static const struct attribute_group adt7516_attribute_group = { static irqreturn_t adt7316_event_handler(int irq, void *private) { struct iio_dev *indio_dev = private; - struct adt7316_chip_info *chip = iio_dev_get_devdata(indio_dev); + struct adt7316_chip_info *chip = iio_priv(indio_dev); u8 stat1, stat2; int ret; s64 time; @@ -1777,43 +1776,43 @@ static irqreturn_t adt7316_event_handler(int irq, void *private) time = iio_get_time_ns(); if (stat1 & (1 << 0)) - iio_push_event(chip->indio_dev, 0, + iio_push_event(indio_dev, 0, IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), time); if (stat1 & (1 << 1)) - iio_push_event(chip->indio_dev, 0, + iio_push_event(indio_dev, 0, IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), time); if (stat1 & (1 << 2)) - iio_push_event(chip->indio_dev, 0, + iio_push_event(indio_dev, 0, IIO_UNMOD_EVENT_CODE(IIO_TEMP, 1, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), time); if (stat1 & (1 << 3)) - iio_push_event(chip->indio_dev, 0, + iio_push_event(indio_dev, 0, IIO_UNMOD_EVENT_CODE(IIO_TEMP, 1, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), time); if (stat1 & (1 << 5)) - iio_push_event(chip->indio_dev, 0, + iio_push_event(indio_dev, 0, IIO_UNMOD_EVENT_CODE(IIO_IN, 1, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), time); if (stat1 & (1 << 6)) - iio_push_event(chip->indio_dev, 0, + iio_push_event(indio_dev, 0, IIO_UNMOD_EVENT_CODE(IIO_IN, 2, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), time); if (stat1 & (1 << 7)) - iio_push_event(chip->indio_dev, 0, + iio_push_event(indio_dev, 0, IIO_UNMOD_EVENT_CODE(IIO_IN, 3, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), @@ -1822,7 +1821,7 @@ static irqreturn_t adt7316_event_handler(int irq, void *private) ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT2, &stat2); if (!ret) { if (stat2 & ADT7316_INT_MASK2_VDD) - iio_push_event(chip->indio_dev, 0, + iio_push_event(indio_dev, 0, IIO_UNMOD_EVENT_CODE(IIO_IN, 0, IIO_EV_TYPE_THRESH, @@ -1841,7 +1840,7 @@ static ssize_t adt7316_show_int_mask(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "0x%x\n", chip->int_mask); } @@ -1855,7 +1854,7 @@ static ssize_t adt7316_set_int_mask(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); unsigned long data; int ret; u8 mask; @@ -1895,7 +1894,7 @@ static inline ssize_t adt7316_show_ad_bound(struct device *dev, { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 val; int data; int ret; @@ -1926,7 +1925,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev, { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); long data; u8 val; int ret; @@ -1965,7 +1964,7 @@ static ssize_t adt7316_show_int_enabled(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_INT_EN)); } @@ -1976,7 +1975,7 @@ static ssize_t adt7316_set_int_enabled(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); u8 config1; int ret; @@ -2090,7 +2089,7 @@ static struct attribute_group adt7516_event_attribute_group = { int adt7316_disable(struct device *dev) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return _adt7316_store_enabled(chip, 0); } @@ -2099,7 +2098,7 @@ EXPORT_SYMBOL(adt7316_disable); int adt7316_enable(struct device *dev) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct adt7316_chip_info *chip = iio_priv(dev_info); return _adt7316_store_enabled(chip, 1); } @@ -2127,16 +2126,18 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus, const char *name) { struct adt7316_chip_info *chip; + struct iio_dev *indio_dev; unsigned short *adt7316_platform_data = dev->platform_data; int ret = 0; - chip = kzalloc(sizeof(struct adt7316_chip_info), GFP_KERNEL); - - if (chip == NULL) - return -ENOMEM; - + indio_dev = iio_allocate_device(sizeof(*chip)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_ret; + } + chip = iio_priv(indio_dev); /* this is only used for device removal purposes */ - dev_set_drvdata(dev, chip); + dev_set_drvdata(dev, indio_dev); chip->bus = *bus; @@ -2157,22 +2158,15 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus, if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) chip->int_mask |= ADT7516_AIN_INT_MASK; - chip->indio_dev = iio_allocate_device(0); - if (chip->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_chip; - } - - chip->indio_dev->dev.parent = dev; + indio_dev->dev.parent = dev; if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) - chip->indio_dev->info = &adt7516_info; + indio_dev->info = &adt7516_info; else - chip->indio_dev->info = &adt7316_info; - chip->indio_dev->name = name; - chip->indio_dev->dev_data = (void *)chip; - chip->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &adt7316_info; + indio_dev->name = name; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(chip->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; @@ -2184,8 +2178,8 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus, NULL, &adt7316_event_handler, chip->bus.irq_flags | IRQF_ONESHOT, - chip->indio_dev->name, - chip->indio_dev); + indio_dev->name, + indio_dev); if (ret) goto error_unreg_dev; @@ -2206,35 +2200,31 @@ int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus, } dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n", - chip->indio_dev->name); + indio_dev->name); return 0; error_unreg_irq: - free_irq(chip->bus.irq, chip->indio_dev); + free_irq(chip->bus.irq, indio_dev); error_unreg_dev: - iio_device_unregister(chip->indio_dev); + iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(chip->indio_dev); -error_free_chip: - kfree(chip); - + iio_free_device(indio_dev); +error_ret: return ret; } EXPORT_SYMBOL(adt7316_probe); int __devexit adt7316_remove(struct device *dev) { - - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct adt7316_chip_info *chip = dev_info->dev_data; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = iio_priv(indio_dev); dev_set_drvdata(dev, NULL); if (chip->bus.irq) - free_irq(chip->bus.irq, chip->indio_dev); - iio_device_unregister(chip->indio_dev); - iio_free_device(chip->indio_dev); - kfree(chip); + free_irq(chip->bus.irq, indio_dev); + iio_device_unregister(indio_dev); + iio_free_device(indio_dev); return 0; } diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig index d5a5556cf985..7ddae357f20e 100644 --- a/drivers/staging/iio/dac/Kconfig +++ b/drivers/staging/iio/dac/Kconfig @@ -42,6 +42,17 @@ config AD5791 To compile this driver as a module, choose M here: the module will be called ad5791. +config AD5686 + tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver" + depends on SPI + help + Say yes here to build support for Analog Devices AD5686R, AD5685R, + AD5684R, AD5791 Voltage Output Digital to + Analog Converter. + + To compile this driver as a module, choose M here: the + module will be called ad5686. + config MAX517 tristate "Maxim MAX517/518/519 DAC driver" depends on I2C && EXPERIMENTAL diff --git a/drivers/staging/iio/dac/Makefile b/drivers/staging/iio/dac/Makefile index 83196de7a54c..7f4f2ed031ec 100644 --- a/drivers/staging/iio/dac/Makefile +++ b/drivers/staging/iio/dac/Makefile @@ -6,4 +6,5 @@ obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o obj-$(CONFIG_AD5504) += ad5504.o obj-$(CONFIG_AD5446) += ad5446.o obj-$(CONFIG_AD5791) += ad5791.o +obj-$(CONFIG_AD5686) += ad5686.o obj-$(CONFIG_MAX517) += max517.o diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 86cb08ce199b..e8a9d0bf1edb 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -68,7 +68,7 @@ static ssize_t ad5446_write(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad5446_state *st = dev_info->dev_data; + struct ad5446_state *st = iio_priv(dev_info); int ret; long val; @@ -98,7 +98,7 @@ static ssize_t ad5446_show_scale(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad5446_state *st = iio_dev_get_devdata(dev_info); + struct ad5446_state *st = iio_priv(dev_info); /* Corresponds to Vref / 2^(bits) */ unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits; @@ -111,7 +111,7 @@ static ssize_t ad5446_write_powerdown_mode(struct device *dev, const char *buf, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad5446_state *st = dev_info->dev_data; + struct ad5446_state *st = iio_priv(dev_info); if (sysfs_streq(buf, "1kohm_to_gnd")) st->pwr_down_mode = MODE_PWRDWN_1k; @@ -129,7 +129,7 @@ static ssize_t ad5446_read_powerdown_mode(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad5446_state *st = dev_info->dev_data; + struct ad5446_state *st = iio_priv(dev_info); char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"}; @@ -141,7 +141,7 @@ static ssize_t ad5446_read_dac_powerdown(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad5446_state *st = dev_info->dev_data; + struct ad5446_state *st = iio_priv(dev_info); return sprintf(buf, "%d\n", st->pwr_down); } @@ -151,7 +151,7 @@ static ssize_t ad5446_write_dac_powerdown(struct device *dev, const char *buf, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad5446_state *st = dev_info->dev_data; + struct ad5446_state *st = iio_priv(dev_info); unsigned long readin; int ret; @@ -201,7 +201,7 @@ static mode_t ad5446_attr_is_visible(struct kobject *kobj, { struct device *dev = container_of(kobj, struct device, kobj); struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad5446_state *st = iio_dev_get_devdata(dev_info); + struct ad5446_state *st = iio_priv(dev_info); mode_t mode = attr->mode; @@ -342,42 +342,37 @@ static const struct iio_info ad5446_info = { static int __devinit ad5446_probe(struct spi_device *spi) { struct ad5446_state *st; + struct iio_dev *indio_dev; + struct regulator *reg; int ret, voltage_uv = 0; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - st->reg = regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(st->reg)) { - ret = regulator_enable(st->reg); + reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(reg)) { + ret = regulator_enable(reg); if (ret) goto error_put_reg; - voltage_uv = regulator_get_voltage(st->reg); + voltage_uv = regulator_get_voltage(reg); } - st->chip_info = - &ad5446_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - - spi_set_drvdata(spi, st); - - st->spi = spi; - - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { ret = -ENOMEM; goto error_disable_reg; } + st = iio_priv(indio_dev); + st->chip_info = + &ad5446_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + + spi_set_drvdata(spi, indio_dev); + st->reg = reg; + st->spi = spi; /* Estabilish that the iio_dev is a child of the spi device */ - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->name = spi_get_device_id(spi)->name; - st->indio_dev->info = &ad5446_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->info = &ad5446_info; + indio_dev->modes = INDIO_DIRECT_MODE; /* Setup default message */ @@ -404,36 +399,35 @@ static int __devinit ad5446_probe(struct spi_device *spi) "reference voltage unspecified\n"); } - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_device; return 0; error_free_device: - iio_free_device(st->indio_dev); + iio_free_device(indio_dev); error_disable_reg: - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + if (!IS_ERR(reg)) + regulator_disable(reg); error_put_reg: - if (!IS_ERR(st->reg)) - regulator_put(st->reg); - kfree(st); -error_ret: + if (!IS_ERR(reg)) + regulator_put(reg); + return ret; } static int ad5446_remove(struct spi_device *spi) { - struct ad5446_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad5446_state *st = iio_priv(indio_dev); + struct regulator *reg = st->reg; iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg)) { - regulator_disable(st->reg); - regulator_put(st->reg); + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); } - kfree(st); return 0; } diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h index e6ffd2bb7c7d..7118d653ac3e 100644 --- a/drivers/staging/iio/dac/ad5446.h +++ b/drivers/staging/iio/dac/ad5446.h @@ -33,7 +33,6 @@ /** * struct ad5446_state - driver instance specific data - * @indio_dev: the industrial I/O device * @spi: spi_device * @chip_info: chip model specific constants, available modes etc * @reg: supply regulator @@ -45,7 +44,6 @@ */ struct ad5446_state { - struct iio_dev *indio_dev; struct spi_device *spi; const struct ad5446_chip_info *chip_info; struct regulator *reg; diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c index ed029cdff300..1915f459868b 100644 --- a/drivers/staging/iio/dac/ad5504.c +++ b/drivers/staging/iio/dac/ad5504.c @@ -55,7 +55,7 @@ static ssize_t ad5504_write_dac(struct device *dev, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + struct ad5504_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); long readin; int ret; @@ -73,7 +73,7 @@ static ssize_t ad5504_read_dac(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + struct ad5504_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; u16 val; @@ -89,7 +89,7 @@ static ssize_t ad5504_read_powerdown_mode(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + struct ad5504_state *st = iio_priv(indio_dev); const char mode[][14] = {"20kohm_to_gnd", "three_state"}; @@ -101,7 +101,7 @@ static ssize_t ad5504_write_powerdown_mode(struct device *dev, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + struct ad5504_state *st = iio_priv(indio_dev); int ret; if (sysfs_streq(buf, "20kohm_to_gnd")) @@ -119,7 +119,7 @@ static ssize_t ad5504_read_dac_powerdown(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + struct ad5504_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); return sprintf(buf, "%d\n", @@ -133,7 +133,7 @@ static ssize_t ad5504_write_dac_powerdown(struct device *dev, long readin; int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + struct ad5504_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = strict_strtol(buf, 10, &readin); @@ -162,7 +162,7 @@ static ssize_t ad5504_show_scale(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5504_state *st = iio_dev_get_devdata(indio_dev); + struct ad5504_state *st = iio_priv(indio_dev); /* Corresponds to Vref / 2^(bits) */ unsigned int scale_uv = (st->vref_mv * 1000) >> AD5505_BITS; @@ -277,26 +277,27 @@ static const struct iio_info ad5501_info = { static int __devinit ad5504_probe(struct spi_device *spi) { struct ad5504_platform_data *pdata = spi->dev.platform_data; + struct iio_dev *indio_dev; struct ad5504_state *st; + struct regulator *reg; int ret, voltage_uv = 0; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - spi_set_drvdata(spi, st); - - st->reg = regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(st->reg)) { - ret = regulator_enable(st->reg); + reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(reg)) { + ret = regulator_enable(reg); if (ret) goto error_put_reg; - voltage_uv = regulator_get_voltage(st->reg); + voltage_uv = regulator_get_voltage(reg); } + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + spi_set_drvdata(spi, indio_dev); + st = iio_priv(indio_dev); if (voltage_uv) st->vref_mv = voltage_uv / 1000; else if (pdata) @@ -304,22 +305,17 @@ static int __devinit ad5504_probe(struct spi_device *spi) else dev_warn(&spi->dev, "reference voltage unspecified\n"); + st->reg = reg; st->spi = spi; - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_disable_reg; - } - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->name = spi_get_device_id(st->spi)->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(st->spi)->name; if (spi_get_device_id(st->spi)->driver_data == ID_AD5501) - st->indio_dev->info = &ad5501_info; + indio_dev->info = &ad5501_info; else - st->indio_dev->info = &ad5504_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &ad5504_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; @@ -329,7 +325,7 @@ static int __devinit ad5504_probe(struct spi_device *spi) &ad5504_event_handler, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, spi_get_device_id(st->spi)->name, - st->indio_dev); + indio_dev); if (ret) goto error_unreg_iio_device; } @@ -337,37 +333,34 @@ static int __devinit ad5504_probe(struct spi_device *spi) return 0; error_unreg_iio_device: - iio_device_unregister(st->indio_dev); + iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(st->indio_dev); + iio_free_device(indio_dev); error_disable_reg: - if (!IS_ERR(st->reg)) + if (!IS_ERR(reg)) regulator_disable(st->reg); error_put_reg: - if (!IS_ERR(st->reg)) - regulator_put(st->reg); + if (!IS_ERR(reg)) + regulator_put(reg); - kfree(st); -error_ret: return ret; } static int __devexit ad5504_remove(struct spi_device *spi) { - struct ad5504_state *st = spi_get_drvdata(spi); - + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad5504_state *st = iio_priv(indio_dev); + struct regulator *reg = st->reg; if (spi->irq) - free_irq(spi->irq, st->indio_dev); + free_irq(spi->irq, indio_dev); - iio_device_unregister(st->indio_dev); + iio_device_unregister(indio_dev); - if (!IS_ERR(st->reg)) { - regulator_disable(st->reg); - regulator_put(st->reg); + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); } - kfree(st); - return 0; } diff --git a/drivers/staging/iio/dac/ad5504.h b/drivers/staging/iio/dac/ad5504.h index 13ef35399137..85beb1dd29b9 100644 --- a/drivers/staging/iio/dac/ad5504.h +++ b/drivers/staging/iio/dac/ad5504.h @@ -41,7 +41,6 @@ struct ad5504_platform_data { /** * struct ad5446_state - driver instance specific data - * @indio_dev: the industrial I/O device * @us: spi_device * @reg: supply regulator * @vref_mv: actual reference voltage used @@ -50,7 +49,6 @@ struct ad5504_platform_data { */ struct ad5504_state { - struct iio_dev *indio_dev; struct spi_device *spi; struct regulator *reg; unsigned short vref_mv; diff --git a/drivers/staging/iio/dac/ad5624r.h b/drivers/staging/iio/dac/ad5624r.h index c16df4ed52ca..b71c6a03e780 100644 --- a/drivers/staging/iio/dac/ad5624r.h +++ b/drivers/staging/iio/dac/ad5624r.h @@ -53,7 +53,6 @@ struct ad5624r_chip_info { */ struct ad5624r_state { - struct iio_dev *indio_dev; struct spi_device *us; const struct ad5624r_chip_info *chip_info; struct regulator *reg; diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index c679981f0143..a5b3776718e9 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -77,7 +77,7 @@ static ssize_t ad5624r_write_dac(struct device *dev, long readin; int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); + struct ad5624r_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = strict_strtol(buf, 10, &readin); @@ -94,7 +94,7 @@ static ssize_t ad5624r_read_powerdown_mode(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); + struct ad5624r_state *st = iio_priv(indio_dev); char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"}; @@ -106,7 +106,7 @@ static ssize_t ad5624r_write_powerdown_mode(struct device *dev, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); + struct ad5624r_state *st = iio_priv(indio_dev); int ret; if (sysfs_streq(buf, "1kohm_to_gnd")) @@ -126,7 +126,7 @@ static ssize_t ad5624r_read_dac_powerdown(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); + struct ad5624r_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); return sprintf(buf, "%d\n", @@ -140,7 +140,7 @@ static ssize_t ad5624r_write_dac_powerdown(struct device *dev, long readin; int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); + struct ad5624r_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = strict_strtol(buf, 10, &readin); @@ -166,7 +166,7 @@ static ssize_t ad5624r_show_scale(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5624r_state *st = iio_dev_get_devdata(indio_dev); + struct ad5624r_state *st = iio_priv(indio_dev); /* Corresponds to Vref / 2^(bits) */ unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits; @@ -226,24 +226,26 @@ static const struct iio_info ad5624r_info = { static int __devinit ad5624r_probe(struct spi_device *spi) { struct ad5624r_state *st; + struct iio_dev *indio_dev; + struct regulator *reg; int ret, voltage_uv = 0; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { - ret = -ENOMEM; - goto error_ret; - } - spi_set_drvdata(spi, st); - - st->reg = regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(st->reg)) { - ret = regulator_enable(st->reg); + reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(reg)) { + ret = regulator_enable(reg); if (ret) goto error_put_reg; - voltage_uv = regulator_get_voltage(st->reg); + voltage_uv = regulator_get_voltage(reg); } - + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + st = iio_priv(indio_dev); + st->reg = reg; + spi_set_drvdata(spi, indio_dev); st->chip_info = &ad5624r_chip_info_tbl[spi_get_device_id(spi)->driver_data]; @@ -253,18 +255,13 @@ static int __devinit ad5624r_probe(struct spi_device *spi) st->vref_mv = st->chip_info->int_vref_mv; st->us = spi; - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_disable_reg; - } - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->name = spi_get_device_id(spi)->name; - st->indio_dev->info = &ad5624r_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(st->indio_dev); + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->info = &ad5624r_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; @@ -276,32 +273,29 @@ static int __devinit ad5624r_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(st->indio_dev); + iio_free_device(indio_dev); error_disable_reg: - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + if (!IS_ERR(reg)) + regulator_disable(reg); error_put_reg: - if (!IS_ERR(st->reg)) - regulator_put(st->reg); + if (!IS_ERR(reg)) + regulator_put(reg); - kfree(st); -error_ret: return ret; } static int __devexit ad5624r_remove(struct spi_device *spi) { - struct ad5624r_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad5624r_state *st = iio_priv(indio_dev); + struct regulator *reg = st->reg; - iio_device_unregister(st->indio_dev); - - if (!IS_ERR(st->reg)) { - regulator_disable(st->reg); - regulator_put(st->reg); + iio_device_unregister(indio_dev); + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); } - kfree(st); - return 0; } diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c new file mode 100644 index 000000000000..fd67cfa5edb6 --- /dev/null +++ b/drivers/staging/iio/dac/ad5686.c @@ -0,0 +1,497 @@ +/* + * AD5686R, AD5685R, AD5684R Digital to analog converters driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "dac.h" + +#define AD5686_DAC_CHANNELS 4 + +#define AD5686_ADDR(x) ((x) << 16) +#define AD5686_CMD(x) ((x) << 20) + +#define AD5686_ADDR_DAC0 0x1 +#define AD5686_ADDR_DAC1 0x2 +#define AD5686_ADDR_DAC2 0x4 +#define AD5686_ADDR_DAC3 0x8 +#define AD5686_ADDR_ALL_DAC 0xF + +#define AD5686_CMD_NOOP 0x0 +#define AD5686_CMD_WRITE_INPUT_N 0x1 +#define AD5686_CMD_UPDATE_DAC_N 0x2 +#define AD5686_CMD_WRITE_INPUT_N_UPDATE_N 0x3 +#define AD5686_CMD_POWERDOWN_DAC 0x4 +#define AD5686_CMD_LDAC_MASK 0x5 +#define AD5686_CMD_RESET 0x6 +#define AD5686_CMD_INTERNAL_REFER_SETUP 0x7 +#define AD5686_CMD_DAISY_CHAIN_ENABLE 0x8 +#define AD5686_CMD_READBACK_ENABLE 0x9 + +#define AD5686_LDAC_PWRDN_NONE 0x0 +#define AD5686_LDAC_PWRDN_1K 0x1 +#define AD5686_LDAC_PWRDN_100K 0x2 +#define AD5686_LDAC_PWRDN_3STATE 0x3 + +/** + * struct ad5686_chip_info - chip specific information + * @int_vref_mv: AD5620/40/60: the internal reference voltage + * @channel: channel specification +*/ + +struct ad5686_chip_info { + u16 int_vref_mv; + struct iio_chan_spec channel[AD5686_DAC_CHANNELS]; +}; + +/** + * struct ad5446_state - driver instance specific data + * @spi: spi_device + * @chip_info: chip model specific constants, available modes etc + * @reg: supply regulator + * @vref_mv: actual reference voltage used + * @pwr_down_mask: power down mask + * @pwr_down_mode: current power down mode + * @data: spi transfer buffers + */ + +struct ad5686_state { + struct spi_device *spi; + const struct ad5686_chip_info *chip_info; + struct regulator *reg; + unsigned short vref_mv; + unsigned pwr_down_mask; + unsigned pwr_down_mode; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + + union { + u32 d32; + u8 d8[4]; + } data[3] ____cacheline_aligned; +}; + +/** + * ad5686_supported_device_ids: + */ + +enum ad5686_supported_device_ids { + ID_AD5684, + ID_AD5685, + ID_AD5686, +}; + +static const struct ad5686_chip_info ad5686_chip_info_tbl[] = { + [ID_AD5684] = { + .channel[0] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 0, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD5686_ADDR_DAC0, + 0, IIO_ST('u', 12, 16, 4), 0), + .channel[1] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 1, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD5686_ADDR_DAC1, + 1, IIO_ST('u', 12, 16, 4), 0), + .channel[2] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 2, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD5686_ADDR_DAC2, + 2, IIO_ST('u', 12, 16, 4), 0), + .channel[3] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 3, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD5686_ADDR_DAC3, + 3, IIO_ST('u', 12, 16, 4), 0), + .int_vref_mv = 2500, + }, + [ID_AD5685] = { + .channel[0] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 0, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD5686_ADDR_DAC0, + 0, IIO_ST('u', 14, 16, 2), 0), + .channel[1] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 1, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD5686_ADDR_DAC1, + 1, IIO_ST('u', 14, 16, 2), 0), + .channel[2] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 2, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD5686_ADDR_DAC2, + 2, IIO_ST('u', 14, 16, 2), 0), + .channel[3] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 3, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD5686_ADDR_DAC3, + 3, IIO_ST('u', 14, 16, 2), 0), + .int_vref_mv = 2500, + }, + [ID_AD5686] = { + .channel[0] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 0, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD5686_ADDR_DAC0, + 0, IIO_ST('u', 16, 16, 0), 0), + .channel[1] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 1, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD5686_ADDR_DAC1, + 1, IIO_ST('u', 16, 16, 0), 0), + .channel[2] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 2, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD5686_ADDR_DAC2, + 2, IIO_ST('u', 16, 16, 0), 0), + .channel[3] = IIO_CHAN(IIO_OUT, 0, 1, 0, NULL, 3, 0, + (1 << IIO_CHAN_INFO_SCALE_SHARED), + AD5686_ADDR_DAC3, + 3, IIO_ST('u', 16, 16, 0), 0), + .int_vref_mv = 2500, + }, +}; + +static int ad5686_spi_write(struct ad5686_state *st, + u8 cmd, u8 addr, u16 val, u8 shift) +{ + val <<= shift; + + st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | + AD5686_ADDR(addr) | + val); + + return spi_write(st->spi, &st->data[0].d8[1], 3); +} + +static int ad5686_spi_read(struct ad5686_state *st, u8 addr) +{ + struct spi_transfer t[] = { + { + .tx_buf = &st->data[0].d8[1], + .len = 3, + .cs_change = 1, + }, { + .tx_buf = &st->data[1].d8[1], + .rx_buf = &st->data[2].d8[1], + .len = 3, + }, + }; + struct spi_message m; + int ret; + + spi_message_init(&m); + spi_message_add_tail(&t[0], &m); + spi_message_add_tail(&t[1], &m); + + st->data[0].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_READBACK_ENABLE) | + AD5686_ADDR(addr)); + st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP)); + + ret = spi_sync(st->spi, &m); + if (ret < 0) + return ret; + + return be32_to_cpu(st->data[2].d32); +} + +static ssize_t ad5686_read_powerdown_mode(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5686_state *st = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + char mode[][15] = {"", "1kohm_to_gnd", "100kohm_to_gnd", "three_state"}; + + return sprintf(buf, "%s\n", mode[(st->pwr_down_mode >> + (this_attr->address * 2)) & 0x3]); +} + +static ssize_t ad5686_write_powerdown_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5686_state *st = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + unsigned mode; + + if (sysfs_streq(buf, "1kohm_to_gnd")) + mode = AD5686_LDAC_PWRDN_1K; + else if (sysfs_streq(buf, "100kohm_to_gnd")) + mode = AD5686_LDAC_PWRDN_100K; + else if (sysfs_streq(buf, "three_state")) + mode = AD5686_LDAC_PWRDN_3STATE; + else + return -EINVAL; + + st->pwr_down_mode &= ~(0x3 << (this_attr->address * 2)); + st->pwr_down_mode |= (mode << (this_attr->address * 2)); + + return len; +} + +static ssize_t ad5686_read_dac_powerdown(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5686_state *st = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + return sprintf(buf, "%d\n", !!(st->pwr_down_mask & + (0x3 << (this_attr->address * 2)))); +} + +static ssize_t ad5686_write_dac_powerdown(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + bool readin; + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5686_state *st = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = strtobool(buf, &readin); + if (ret) + return ret; + + if (readin == true) + st->pwr_down_mask |= (0x3 << (this_attr->address * 2)); + else + st->pwr_down_mask &= ~(0x3 << (this_attr->address * 2)); + + ret = ad5686_spi_write(st, AD5686_CMD_POWERDOWN_DAC, 0, + st->pwr_down_mask & st->pwr_down_mode, 0); + + return ret ? ret : len; +} + +static IIO_CONST_ATTR(out_powerdown_mode_available, + "1kohm_to_gnd 100kohm_to_gnd three_state"); + +#define IIO_DEV_ATTR_DAC_POWERDOWN_MODE(_num) \ + IIO_DEVICE_ATTR(out##_num##_powerdown_mode, S_IRUGO | S_IWUSR, \ + ad5686_read_powerdown_mode, \ + ad5686_write_powerdown_mode, _num) + +static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(0); +static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(1); +static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(2); +static IIO_DEV_ATTR_DAC_POWERDOWN_MODE(3); + +#define IIO_DEV_ATTR_DAC_POWERDOWN(_num) \ + IIO_DEVICE_ATTR(out##_num##_powerdown, S_IRUGO | S_IWUSR, \ + ad5686_read_dac_powerdown, \ + ad5686_write_dac_powerdown, _num) + +static IIO_DEV_ATTR_DAC_POWERDOWN(0); +static IIO_DEV_ATTR_DAC_POWERDOWN(1); +static IIO_DEV_ATTR_DAC_POWERDOWN(2); +static IIO_DEV_ATTR_DAC_POWERDOWN(3); + +static struct attribute *ad5686_attributes[] = { + &iio_dev_attr_out0_powerdown.dev_attr.attr, + &iio_dev_attr_out1_powerdown.dev_attr.attr, + &iio_dev_attr_out2_powerdown.dev_attr.attr, + &iio_dev_attr_out3_powerdown.dev_attr.attr, + &iio_dev_attr_out0_powerdown_mode.dev_attr.attr, + &iio_dev_attr_out1_powerdown_mode.dev_attr.attr, + &iio_dev_attr_out2_powerdown_mode.dev_attr.attr, + &iio_dev_attr_out3_powerdown_mode.dev_attr.attr, + &iio_const_attr_out_powerdown_mode_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad5686_attribute_group = { + .attrs = ad5686_attributes, +}; + +static int ad5686_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ad5686_state *st = iio_priv(indio_dev); + unsigned long scale_uv; + int ret; + + switch (m) { + case 0: + mutex_lock(&indio_dev->mlock); + ret = ad5686_spi_read(st, chan->address); + mutex_unlock(&indio_dev->mlock); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; + break; + case (1 << IIO_CHAN_INFO_SCALE_SHARED): + scale_uv = (st->vref_mv * 100000) + >> (chan->scan_type.realbits); + *val = scale_uv / 100000; + *val2 = (scale_uv % 100000) * 10; + return IIO_VAL_INT_PLUS_MICRO; + + } + return -EINVAL; +} + +static int ad5686_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct ad5686_state *st = iio_priv(indio_dev); + int ret; + + switch (mask) { + case 0: + if (val > (1 << chan->scan_type.realbits)) + return -EINVAL; + + mutex_lock(&indio_dev->mlock); + ret = ad5686_spi_write(st, + AD5686_CMD_WRITE_INPUT_N_UPDATE_N, + chan->address, + val, + chan->scan_type.shift); + mutex_unlock(&indio_dev->mlock); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static const struct iio_info ad5686_info = { + .read_raw = ad5686_read_raw, + .write_raw = ad5686_write_raw, + .attrs = &ad5686_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad5686_probe(struct spi_device *spi) +{ + struct ad5686_state *st; + struct iio_dev *indio_dev; + int ret, regdone = 0, voltage_uv = 0; + + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + spi_set_drvdata(spi, indio_dev); + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + voltage_uv = regulator_get_voltage(st->reg); + } + + st->chip_info = + &ad5686_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + + if (voltage_uv) + st->vref_mv = voltage_uv / 1000; + else + st->vref_mv = st->chip_info->int_vref_mv; + + st->spi = spi; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->info = &ad5686_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->chip_info->channel; + indio_dev->num_channels = AD5686_DAC_CHANNELS; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_disable_reg; + + regdone = 1; + ret = ad5686_spi_write(st, AD5686_CMD_INTERNAL_REFER_SETUP, 0, + !!voltage_uv, 0); + if (ret) + goto error_disable_reg; + + return 0; + +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + + if (regdone) + iio_device_unregister(indio_dev); + else + iio_free_device(indio_dev); + + return ret; +} + +static int __devexit ad5686_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad5686_state *st = iio_priv(indio_dev); + struct regulator *reg = st->reg; + + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); + } + + iio_device_unregister(indio_dev); + + return 0; +} + +static const struct spi_device_id ad5686_id[] = { + {"ad5684", ID_AD5684}, + {"ad5685", ID_AD5685}, + {"ad5686", ID_AD5686}, + {} +}; + +static struct spi_driver ad5686_driver = { + .driver = { + .name = "ad5686", + .owner = THIS_MODULE, + }, + .probe = ad5686_probe, + .remove = __devexit_p(ad5686_remove), + .id_table = ad5686_id, +}; + +static __init int ad5686_spi_init(void) +{ + return spi_register_driver(&ad5686_driver); +} +module_init(ad5686_spi_init); + +static __exit void ad5686_spi_exit(void) +{ + spi_unregister_driver(&ad5686_driver); +} +module_exit(ad5686_spi_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD5686/85/84 DAC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c index 4eda25cba870..64770d2a1b4c 100644 --- a/drivers/staging/iio/dac/ad5791.c +++ b/drivers/staging/iio/dac/ad5791.c @@ -76,7 +76,7 @@ static ssize_t ad5791_write_dac(struct device *dev, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5791_state *st = iio_dev_get_devdata(indio_dev); + struct ad5791_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); long readin; int ret; @@ -98,7 +98,7 @@ static ssize_t ad5791_read_dac(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5791_state *st = iio_dev_get_devdata(indio_dev); + struct ad5791_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; int val; @@ -118,7 +118,7 @@ static ssize_t ad5791_read_powerdown_mode(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5791_state *st = iio_dev_get_devdata(indio_dev); + struct ad5791_state *st = iio_priv(indio_dev); const char mode[][14] = {"6kohm_to_gnd", "three_state"}; @@ -130,7 +130,7 @@ static ssize_t ad5791_write_powerdown_mode(struct device *dev, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5791_state *st = iio_dev_get_devdata(indio_dev); + struct ad5791_state *st = iio_priv(indio_dev); int ret; if (sysfs_streq(buf, "6kohm_to_gnd")) @@ -148,7 +148,7 @@ static ssize_t ad5791_read_dac_powerdown(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5791_state *st = iio_dev_get_devdata(indio_dev); + struct ad5791_state *st = iio_priv(indio_dev); return sprintf(buf, "%d\n", st->pwr_down); } @@ -160,7 +160,7 @@ static ssize_t ad5791_write_dac_powerdown(struct device *dev, long readin; int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5791_state *st = iio_dev_get_devdata(indio_dev); + struct ad5791_state *st = iio_priv(indio_dev); ret = strict_strtol(buf, 10, &readin); if (ret) @@ -188,7 +188,7 @@ static ssize_t ad5791_show_scale(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5791_state *st = iio_dev_get_devdata(indio_dev); + struct ad5791_state *st = iio_priv(indio_dev); /* Corresponds to Vref / 2^(bits) */ unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits; @@ -201,7 +201,7 @@ static ssize_t ad5791_show_name(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ad5791_state *st = iio_dev_get_devdata(indio_dev); + struct ad5791_state *st = iio_priv(indio_dev); return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name); } @@ -295,36 +295,39 @@ static const struct iio_info ad5791_info = { static int __devinit ad5791_probe(struct spi_device *spi) { struct ad5791_platform_data *pdata = spi->dev.platform_data; + struct iio_dev *indio_dev; + struct regulator *reg_vdd, *reg_vss; struct ad5791_state *st; int ret, pos_voltage_uv = 0, neg_voltage_uv = 0; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - spi_set_drvdata(spi, st); - - st->reg_vdd = regulator_get(&spi->dev, "vdd"); - if (!IS_ERR(st->reg_vdd)) { - ret = regulator_enable(st->reg_vdd); + reg_vdd = regulator_get(&spi->dev, "vdd"); + if (!IS_ERR(reg_vdd)) { + ret = regulator_enable(reg_vdd); if (ret) goto error_put_reg_pos; - pos_voltage_uv = regulator_get_voltage(st->reg_vdd); + pos_voltage_uv = regulator_get_voltage(reg_vdd); } - st->reg_vss = regulator_get(&spi->dev, "vss"); - if (!IS_ERR(st->reg_vss)) { - ret = regulator_enable(st->reg_vss); + reg_vss = regulator_get(&spi->dev, "vss"); + if (!IS_ERR(reg_vss)) { + ret = regulator_enable(reg_vss); if (ret) goto error_put_reg_neg; - neg_voltage_uv = regulator_get_voltage(st->reg_vss); + neg_voltage_uv = regulator_get_voltage(reg_vss); } - if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg_neg; + } + st = iio_priv(indio_dev); + st->pwr_down = true; + st->spi = spi; + + if (!IS_ERR(reg_vss) && !IS_ERR(reg_vdd)) st->vref_mv = (pos_voltage_uv - neg_voltage_uv) / 1000; else if (pdata) st->vref_mv = pdata->vref_pos_mv - pdata->vref_neg_mv; @@ -333,7 +336,7 @@ static int __devinit ad5791_probe(struct spi_device *spi) ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET); if (ret) - goto error_disable_reg_neg; + goto error_free_dev; st->chip_info = &ad5791_chip_info_tbl[spi_get_device_id(spi)->driver_data]; @@ -346,66 +349,61 @@ static int __devinit ad5791_probe(struct spi_device *spi) ret = ad5791_spi_write(spi, AD5791_ADDR_CTRL, st->ctrl | AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI); if (ret) - goto error_disable_reg_neg; + goto error_free_dev; - st->pwr_down = true; + st->reg_vdd = reg_vdd; + st->reg_vss = reg_vss; - st->spi = spi; - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_disable_reg_neg; - } - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->info = &ad5791_info; - st->indio_dev->modes = INDIO_DIRECT_MODE; + spi_set_drvdata(spi, indio_dev); + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &ad5791_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; return 0; error_free_dev: - iio_free_device(st->indio_dev); + iio_free_device(indio_dev); error_disable_reg_neg: - if (!IS_ERR(st->reg_vss)) - regulator_disable(st->reg_vss); + if (!IS_ERR(reg_vss)) + regulator_disable(reg_vss); error_put_reg_neg: - if (!IS_ERR(st->reg_vss)) - regulator_put(st->reg_vss); + if (!IS_ERR(reg_vss)) + regulator_put(reg_vss); - if (!IS_ERR(st->reg_vdd)) - regulator_disable(st->reg_vdd); + if (!IS_ERR(reg_vdd)) + regulator_disable(reg_vdd); error_put_reg_pos: - if (!IS_ERR(st->reg_vdd)) - regulator_put(st->reg_vdd); + if (!IS_ERR(reg_vdd)) + regulator_put(reg_vdd); - kfree(st); error_ret: return ret; } static int __devexit ad5791_remove(struct spi_device *spi) { - struct ad5791_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad5791_state *st = iio_priv(indio_dev); + struct regulator *reg_vdd = st->reg_vdd; + struct regulator *reg_vss = st->reg_vss; - iio_device_unregister(st->indio_dev); + iio_device_unregister(indio_dev); if (!IS_ERR(st->reg_vdd)) { - regulator_disable(st->reg_vdd); - regulator_put(st->reg_vdd); + regulator_disable(reg_vdd); + regulator_put(reg_vdd); } if (!IS_ERR(st->reg_vss)) { - regulator_disable(st->reg_vss); - regulator_put(st->reg_vss); + regulator_disable(reg_vss); + regulator_put(reg_vss); } - kfree(st); - return 0; } diff --git a/drivers/staging/iio/dac/ad5791.h b/drivers/staging/iio/dac/ad5791.h index f09ad9a430c3..c807f26539db 100644 --- a/drivers/staging/iio/dac/ad5791.h +++ b/drivers/staging/iio/dac/ad5791.h @@ -81,7 +81,6 @@ struct ad5791_chip_info { /** * struct ad5791_state - driver instance specific data - * @indio_dev: the industrial I/O device * @us: spi_device * @reg_vdd: positive supply regulator * @reg_vss: negative supply regulator @@ -91,7 +90,6 @@ struct ad5791_chip_info { */ struct ad5791_state { - struct iio_dev *indio_dev; struct spi_device *spi; struct regulator *reg_vdd; struct regulator *reg_vss; diff --git a/drivers/staging/iio/dac/max517.c b/drivers/staging/iio/dac/max517.c index 2fe34d21b6aa..ed5d351b2387 100644 --- a/drivers/staging/iio/dac/max517.c +++ b/drivers/staging/iio/dac/max517.c @@ -59,7 +59,7 @@ static ssize_t max517_set_value(struct device *dev, const char *buf, size_t count, int channel) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct max517_data *data = iio_dev_get_devdata(dev_info); + struct max517_data *data = iio_priv(dev_info); struct i2c_client *client = data->client; u8 outbuf[4]; /* 1x or 2x command + value */ int outbuf_size = 0; @@ -127,7 +127,7 @@ static ssize_t max517_show_scale(struct device *dev, char *buf, int channel) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct max517_data *data = iio_dev_get_devdata(dev_info); + struct max517_data *data = iio_priv(dev_info); /* Corresponds to Vref / 2^(bits) */ unsigned int scale_uv = (data->vref_mv[channel - 1] * 1000) >> 8; @@ -203,35 +203,28 @@ static int max517_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct max517_data *data; + struct iio_dev *indio_dev; struct max517_platform_data *platform_data = client->dev.platform_data; int err; - data = kzalloc(sizeof(struct max517_data), GFP_KERNEL); - if (!data) { + indio_dev = iio_allocate_device(sizeof(*data)); + if (indio_dev == NULL) { err = -ENOMEM; goto exit; } - - i2c_set_clientdata(client, data); - + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); data->client = client; - data->indio_dev = iio_allocate_device(0); - if (data->indio_dev == NULL) { - err = -ENOMEM; - goto exit_free_data; - } - /* establish that the iio_dev is a child of the i2c device */ - data->indio_dev->dev.parent = &client->dev; + indio_dev->dev.parent = &client->dev; /* reduced attribute set for MAX517 */ if (id->driver_data == ID_MAX517) - data->indio_dev->info = &max517_info; + indio_dev->info = &max517_info; else - data->indio_dev->info = &max518_info; - data->indio_dev->dev_data = (void *)(data); - data->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &max518_info; + indio_dev->modes = INDIO_DIRECT_MODE; /* * Reference voltage on MAX518 and default is 5V, else take vref_mv @@ -244,7 +237,7 @@ static int max517_probe(struct i2c_client *client, data->vref_mv[1] = platform_data->vref_mv[1]; } - err = iio_device_register(data->indio_dev); + err = iio_device_register(indio_dev); if (err) goto exit_free_device; @@ -253,19 +246,14 @@ static int max517_probe(struct i2c_client *client, return 0; exit_free_device: - iio_free_device(data->indio_dev); -exit_free_data: - kfree(data); + iio_free_device(indio_dev); exit: return err; } static int max517_remove(struct i2c_client *client) { - struct max517_data *data = i2c_get_clientdata(client); - - iio_free_device(data->indio_dev); - kfree(data); + iio_free_device(i2c_get_clientdata(client)); return 0; } diff --git a/drivers/staging/iio/dds/ad5930.c b/drivers/staging/iio/dds/ad5930.c index 490c3637bc8e..0b2aa4cafdd8 100644 --- a/drivers/staging/iio/dds/ad5930.c +++ b/drivers/staging/iio/dds/ad5930.c @@ -35,7 +35,6 @@ struct ad5903_config { struct ad5930_state { struct mutex lock; - struct iio_dev *idev; struct spi_device *sdev; }; @@ -49,7 +48,7 @@ static ssize_t ad5930_set_parameter(struct device *dev, int ret; struct ad5903_config *config = (struct ad5903_config *)buf; struct iio_dev *idev = dev_get_drvdata(dev); - struct ad5930_state *st = idev->dev_data; + struct ad5930_state *st = iio_priv(idev); config->control = (config->control & ~value_mask); config->incnum = (config->control & ~value_mask) | (1 << addr_shift); @@ -83,42 +82,35 @@ static struct attribute *ad5930_attributes[] = { }; static const struct attribute_group ad5930_attribute_group = { - .name = DRV_NAME, .attrs = ad5930_attributes, }; static const struct iio_info ad5930_info = { .attrs = &ad5930_attribute_group, - .driver_module = THIS_MODULE, }; static int __devinit ad5930_probe(struct spi_device *spi) { struct ad5930_state *st; + struct iio_dev *idev; int ret = 0; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { + idev = iio_allocate_device(sizeof(*st)); + if (idev == NULL) { ret = -ENOMEM; goto error_ret; } - spi_set_drvdata(spi, st); + spi_set_drvdata(spi, idev); + st = iio_priv(idev); mutex_init(&st->lock); st->sdev = spi; + idev->dev.parent = &spi->dev; + idev->info = &ad5930_info; + idev->modes = INDIO_DIRECT_MODE; - st->idev = iio_allocate_device(0); - if (st->idev == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->idev->dev.parent = &spi->dev; - st->idev->dev_data = (void *)(st); - st->idev->info = &ad5930_info; - st->idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(st->idev); + ret = iio_device_register(idev); if (ret) goto error_free_dev; spi->max_speed_hz = 2000000; @@ -129,19 +121,14 @@ static int __devinit ad5930_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(st->idev); -error_free_st: - kfree(st); + iio_free_device(idev); error_ret: return ret; } static int __devexit ad5930_remove(struct spi_device *spi) { - struct ad5930_state *st = spi_get_drvdata(spi); - - iio_device_unregister(st->idev); - kfree(st); + iio_device_unregister(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c index e8fe1426a329..e3e61a469bb8 100644 --- a/drivers/staging/iio/dds/ad9832.c +++ b/drivers/staging/iio/dds/ad9832.c @@ -77,7 +77,7 @@ static ssize_t ad9832_write(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad9832_state *st = dev_info->dev_data; + struct ad9832_state *st = iio_priv(dev_info); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; long val; @@ -203,7 +203,9 @@ static const struct iio_info ad9832_info = { static int __devinit ad9832_probe(struct spi_device *spi) { struct ad9832_platform_data *pdata = spi->dev.platform_data; + struct iio_dev *indio_dev; struct ad9832_state *st; + struct regulator *reg; int ret; if (!pdata) { @@ -211,35 +213,28 @@ static int __devinit ad9832_probe(struct spi_device *spi) return -ENODEV; } - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - st->reg = regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(st->reg)) { - ret = regulator_enable(st->reg); + reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(reg)) { + ret = regulator_enable(reg); if (ret) goto error_put_reg; } - st->mclk = pdata->mclk; - - spi_set_drvdata(spi, st); - st->spi = spi; - - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { ret = -ENOMEM; goto error_disable_reg; } + spi_set_drvdata(spi, indio_dev); + st = iio_priv(indio_dev); + st->reg = reg; + st->mclk = pdata->mclk; + st->spi = spi; - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->name = spi_get_device_id(spi)->name; - st->indio_dev->info = &ad9832_info; - st->indio_dev->dev_data = (void *) st; - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->info = &ad9832_info; + indio_dev->modes = INDIO_DIRECT_MODE; /* Setup default messages */ @@ -310,35 +305,35 @@ static int __devinit ad9832_probe(struct spi_device *spi) if (ret) goto error_free_device; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_device; return 0; error_free_device: - iio_free_device(st->indio_dev); + iio_free_device(indio_dev); error_disable_reg: - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + if (!IS_ERR(reg)) + regulator_disable(reg); error_put_reg: - if (!IS_ERR(st->reg)) - regulator_put(st->reg); - kfree(st); -error_ret: + if (!IS_ERR(reg)) + regulator_put(reg); + return ret; } static int __devexit ad9832_remove(struct spi_device *spi) { - struct ad9832_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad9832_state *st = iio_priv(indio_dev); + struct regulator *reg = st->reg; - iio_device_unregister(st->indio_dev); - if (!IS_ERR(st->reg)) { - regulator_disable(st->reg); - regulator_put(st->reg); + iio_device_unregister(indio_dev); + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); } - kfree(st); return 0; } diff --git a/drivers/staging/iio/dds/ad9832.h b/drivers/staging/iio/dds/ad9832.h index 5d474543dfce..c5b701f8aabb 100644 --- a/drivers/staging/iio/dds/ad9832.h +++ b/drivers/staging/iio/dds/ad9832.h @@ -57,7 +57,6 @@ /** * struct ad9832_state - driver instance specific data - * @indio_dev: the industrial I/O device * @spi: spi_device * @reg: supply regulator * @mclk: external master clock @@ -76,7 +75,6 @@ */ struct ad9832_state { - struct iio_dev *indio_dev; struct spi_device *spi; struct regulator *reg; unsigned long mclk; diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/dds/ad9834.c index 0ebe8d58e92e..e6454d58fe41 100644 --- a/drivers/staging/iio/dds/ad9834.c +++ b/drivers/staging/iio/dds/ad9834.c @@ -66,7 +66,7 @@ static ssize_t ad9834_write(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad9834_state *st = dev_info->dev_data; + struct ad9834_state *st = iio_priv(dev_info); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; long val; @@ -145,7 +145,7 @@ static ssize_t ad9834_store_wavetype(struct device *dev, size_t len) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad9834_state *st = dev_info->dev_data; + struct ad9834_state *st = iio_priv(dev_info); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret = 0; bool is_ad9833_7 = (st->devid == ID_AD9833) || (st->devid == ID_AD9837); @@ -203,7 +203,7 @@ static ssize_t ad9834_show_out0_wavetype_available(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad9834_state *st = iio_dev_get_devdata(dev_info); + struct ad9834_state *st = iio_priv(dev_info); char *str; if ((st->devid == ID_AD9833) || (st->devid == ID_AD9837)) @@ -225,7 +225,7 @@ static ssize_t ad9834_show_out1_wavetype_available(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad9834_state *st = iio_dev_get_devdata(dev_info); + struct ad9834_state *st = iio_priv(dev_info); char *str; if (st->control & AD9834_MODE) @@ -285,7 +285,7 @@ static mode_t ad9834_attr_is_visible(struct kobject *kobj, { struct device *dev = container_of(kobj, struct device, kobj); struct iio_dev *dev_info = dev_get_drvdata(dev); - struct ad9834_state *st = iio_dev_get_devdata(dev_info); + struct ad9834_state *st = iio_priv(dev_info); mode_t mode = attr->mode; @@ -314,6 +314,8 @@ static int __devinit ad9834_probe(struct spi_device *spi) { struct ad9834_platform_data *pdata = spi->dev.platform_data; struct ad9834_state *st; + struct iio_dev *indio_dev; + struct regulator *reg; int ret; if (!pdata) { @@ -321,37 +323,28 @@ static int __devinit ad9834_probe(struct spi_device *spi) return -ENODEV; } - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - st->reg = regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(st->reg)) { - ret = regulator_enable(st->reg); + reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(reg)) { + ret = regulator_enable(reg); if (ret) goto error_put_reg; } - st->mclk = pdata->mclk; - - spi_set_drvdata(spi, st); - - st->spi = spi; - st->devid = spi_get_device_id(spi)->driver_data; - - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { ret = -ENOMEM; goto error_disable_reg; } - - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->name = spi_get_device_id(spi)->name; - st->indio_dev->info = &ad9834_info; - st->indio_dev->dev_data = (void *) st; - st->indio_dev->modes = INDIO_DIRECT_MODE; + spi_set_drvdata(spi, indio_dev); + st = iio_priv(indio_dev); + st->mclk = pdata->mclk; + st->spi = spi; + st->devid = spi_get_device_id(spi)->driver_data; + st->reg = reg; + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->info = &ad9834_info; + indio_dev->modes = INDIO_DIRECT_MODE; /* Setup default messages */ @@ -402,35 +395,35 @@ static int __devinit ad9834_probe(struct spi_device *spi) if (ret) goto error_free_device; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_device; return 0; error_free_device: - iio_free_device(st->indio_dev); + iio_free_device(indio_dev); error_disable_reg: - if (!IS_ERR(st->reg)) - regulator_disable(st->reg); + if (!IS_ERR(reg)) + regulator_disable(reg); error_put_reg: - if (!IS_ERR(st->reg)) - regulator_put(st->reg); - kfree(st); -error_ret: + if (!IS_ERR(reg)) + regulator_put(reg); return ret; } static int __devexit ad9834_remove(struct spi_device *spi) { - struct ad9834_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad9834_state *st = iio_priv(indio_dev); + struct regulator *reg = st->reg; - iio_device_unregister(st->indio_dev); - if (!IS_ERR(st->reg)) { - regulator_disable(st->reg); - regulator_put(st->reg); + iio_device_unregister(indio_dev); + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); } - kfree(st); + return 0; } diff --git a/drivers/staging/iio/dds/ad9834.h b/drivers/staging/iio/dds/ad9834.h index 2abd63587e03..ed5ed8d0007f 100644 --- a/drivers/staging/iio/dds/ad9834.h +++ b/drivers/staging/iio/dds/ad9834.h @@ -38,7 +38,6 @@ /** * struct ad9834_state - driver instance specific data - * @indio_dev: the industrial I/O device * @spi: spi_device * @reg: supply regulator * @mclk: external master clock @@ -52,7 +51,6 @@ */ struct ad9834_state { - struct iio_dev *indio_dev; struct spi_device *spi; struct regulator *reg; unsigned int mclk; diff --git a/drivers/staging/iio/dds/ad9850.c b/drivers/staging/iio/dds/ad9850.c index b580d852a1ee..d7c9d05f6359 100644 --- a/drivers/staging/iio/dds/ad9850.c +++ b/drivers/staging/iio/dds/ad9850.c @@ -30,7 +30,6 @@ struct ad9850_config { struct ad9850_state { struct mutex lock; - struct iio_dev *idev; struct spi_device *sdev; }; @@ -44,7 +43,7 @@ static ssize_t ad9850_set_parameter(struct device *dev, int ret; struct ad9850_config *config = (struct ad9850_config *)buf; struct iio_dev *idev = dev_get_drvdata(dev); - struct ad9850_state *st = idev->dev_data; + struct ad9850_state *st = iio_priv(idev); xfer.len = len; xfer.tx_buf = config; @@ -69,7 +68,6 @@ static struct attribute *ad9850_attributes[] = { }; static const struct attribute_group ad9850_attribute_group = { - .name = DRV_NAME, .attrs = ad9850_attributes, }; @@ -81,30 +79,24 @@ static const struct iio_info ad9850_info = { static int __devinit ad9850_probe(struct spi_device *spi) { struct ad9850_state *st; + struct iio_dev *idev; int ret = 0; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { + idev = iio_allocate_device(sizeof(*st)); + if (idev == NULL) { ret = -ENOMEM; goto error_ret; } - spi_set_drvdata(spi, st); - + spi_set_drvdata(spi, idev); + st = iio_priv(idev); mutex_init(&st->lock); st->sdev = spi; - st->idev = iio_allocate_device(0); - if (st->idev == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->idev->dev.parent = &spi->dev; + idev->dev.parent = &spi->dev; + idev->info = &ad9850_info; + idev->modes = INDIO_DIRECT_MODE; - st->idev->info = &ad9850_info; - st->idev->dev_data = (void *)(st); - st->idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(st->idev); + ret = iio_device_register(idev); if (ret) goto error_free_dev; spi->max_speed_hz = 2000000; @@ -115,19 +107,14 @@ static int __devinit ad9850_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(st->idev); -error_free_st: - kfree(st); + iio_free_device(idev); error_ret: return ret; } static int __devexit ad9850_remove(struct spi_device *spi) { - struct ad9850_state *st = spi_get_drvdata(spi); - - iio_device_unregister(st->idev); - kfree(st); + iio_device_unregister(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/dds/ad9852.c b/drivers/staging/iio/dds/ad9852.c index 08020f96300a..0184585425d8 100644 --- a/drivers/staging/iio/dds/ad9852.c +++ b/drivers/staging/iio/dds/ad9852.c @@ -58,7 +58,6 @@ struct ad9852_config { struct ad9852_state { struct mutex lock; - struct iio_dev *idev; struct spi_device *sdev; }; @@ -72,7 +71,7 @@ static ssize_t ad9852_set_parameter(struct device *dev, int ret; struct ad9852_config *config = (struct ad9852_config *)buf; struct iio_dev *idev = dev_get_drvdata(dev); - struct ad9852_state *st = idev->dev_data; + struct ad9852_state *st = iio_priv(idev); xfer.len = 3; xfer.tx_buf = &config->phajst0[0]; @@ -230,30 +229,24 @@ static const struct iio_info ad9852_info = { static int __devinit ad9852_probe(struct spi_device *spi) { struct ad9852_state *st; + struct iio_dev *idev; int ret = 0; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { + idev = iio_allocate_device(sizeof(*st)); + if (idev == NULL) { ret = -ENOMEM; goto error_ret; } - spi_set_drvdata(spi, st); - + st = iio_priv(idev); + spi_set_drvdata(spi, idev); mutex_init(&st->lock); st->sdev = spi; - st->idev = iio_allocate_device(0); - if (st->idev == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->idev->dev.parent = &spi->dev; + idev->dev.parent = &spi->dev; + idev->info = &ad9852_info; + idev->modes = INDIO_DIRECT_MODE; - st->idev->info = &ad9852_info; - st->idev->dev_data = (void *)(st); - st->idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(st->idev); + ret = iio_device_register(idev); if (ret) goto error_free_dev; spi->max_speed_hz = 2000000; @@ -261,22 +254,19 @@ static int __devinit ad9852_probe(struct spi_device *spi) spi->bits_per_word = 8; spi_setup(spi); ad9852_init(st); + return 0; error_free_dev: - iio_free_device(st->idev); -error_free_st: - kfree(st); + iio_free_device(idev); + error_ret: return ret; } static int __devexit ad9852_remove(struct spi_device *spi) { - struct ad9852_state *st = spi_get_drvdata(spi); - - iio_device_unregister(st->idev); - kfree(st); + iio_device_unregister(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/dds/ad9910.c b/drivers/staging/iio/dds/ad9910.c index 97d75d755824..0fa217f7b901 100644 --- a/drivers/staging/iio/dds/ad9910.c +++ b/drivers/staging/iio/dds/ad9910.c @@ -110,7 +110,6 @@ struct ad9910_config { struct ad9910_state { struct mutex lock; - struct iio_dev *idev; struct spi_device *sdev; }; @@ -124,7 +123,7 @@ static ssize_t ad9910_set_parameter(struct device *dev, int ret; struct ad9910_config *config = (struct ad9910_config *)buf; struct iio_dev *idev = dev_get_drvdata(dev); - struct ad9910_state *st = idev->dev_data; + struct ad9910_state *st = iio_priv(idev); xfer.len = 5; xfer.tx_buf = &config->auxdac[0]; @@ -365,30 +364,24 @@ static const struct iio_info ad9910_info = { static int __devinit ad9910_probe(struct spi_device *spi) { struct ad9910_state *st; + struct iio_dev *idev; int ret = 0; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { + idev = iio_allocate_device(sizeof(*st)); + if (idev == NULL) { ret = -ENOMEM; goto error_ret; } - spi_set_drvdata(spi, st); - + spi_set_drvdata(spi, idev); + st = iio_priv(idev); mutex_init(&st->lock); st->sdev = spi; - st->idev = iio_allocate_device(0); - if (st->idev == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->idev->dev.parent = &spi->dev; + idev->dev.parent = &spi->dev; + idev->info = &ad9910_info; + idev->modes = INDIO_DIRECT_MODE; - st->idev->info = &ad9910_info; - st->idev->dev_data = (void *)(st); - st->idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(st->idev); + ret = iio_device_register(idev); if (ret) goto error_free_dev; spi->max_speed_hz = 2000000; @@ -399,19 +392,14 @@ static int __devinit ad9910_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(st->idev); -error_free_st: - kfree(st); + iio_free_device(idev); error_ret: return ret; } static int __devexit ad9910_remove(struct spi_device *spi) { - struct ad9910_state *st = spi_get_drvdata(spi); - - iio_device_unregister(st->idev); - kfree(st); + iio_device_unregister(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/dds/ad9951.c b/drivers/staging/iio/dds/ad9951.c index d4dfcd41d5f9..d361d1f125de 100644 --- a/drivers/staging/iio/dds/ad9951.c +++ b/drivers/staging/iio/dds/ad9951.c @@ -51,7 +51,6 @@ struct ad9951_config { struct ad9951_state { struct mutex lock; - struct iio_dev *idev; struct spi_device *sdev; }; @@ -65,7 +64,7 @@ static ssize_t ad9951_set_parameter(struct device *dev, int ret; struct ad9951_config *config = (struct ad9951_config *)buf; struct iio_dev *idev = dev_get_drvdata(dev); - struct ad9951_state *st = idev->dev_data; + struct ad9951_state *st = iio_priv(idev); xfer.len = 3; xfer.tx_buf = &config->asf[0]; @@ -174,30 +173,25 @@ static const struct iio_info ad9951_info = { static int __devinit ad9951_probe(struct spi_device *spi) { struct ad9951_state *st; + struct iio_dev *idev; int ret = 0; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { + idev = iio_allocate_device(sizeof(*st)); + if (idev == NULL) { ret = -ENOMEM; goto error_ret; } - spi_set_drvdata(spi, st); - + spi_set_drvdata(spi, idev); + st = iio_priv(idev); mutex_init(&st->lock); st->sdev = spi; - st->idev = iio_allocate_device(0); - if (st->idev == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->idev->dev.parent = &spi->dev; + idev->dev.parent = &spi->dev; - st->idev->info = &ad9951_info; - st->idev->dev_data = (void *)(st); - st->idev->modes = INDIO_DIRECT_MODE; + idev->info = &ad9951_info; + idev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(st->idev); + ret = iio_device_register(idev); if (ret) goto error_free_dev; spi->max_speed_hz = 2000000; @@ -208,19 +202,15 @@ static int __devinit ad9951_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(st->idev); -error_free_st: - kfree(st); + iio_free_device(idev); + error_ret: return ret; } static int __devexit ad9951_remove(struct spi_device *spi) { - struct ad9951_state *st = spi_get_drvdata(spi); - - iio_device_unregister(st->idev); - kfree(st); + iio_device_unregister(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index edf9e3bf3efd..afa52d1961a9 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -29,27 +29,25 @@ * struct adis16060_state - device instance specific data * @us_w: actual spi_device to write config * @us_r: actual spi_device to read back data - * @indio_dev: industrial I/O device structure * @buf: transmit or receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16060_state { struct spi_device *us_w; struct spi_device *us_r; - struct iio_dev *indio_dev; struct mutex buf_lock; u8 buf[3] ____cacheline_aligned; }; -static struct adis16060_state *adis16060_st; +static struct iio_dev *adis16060_iio_dev; static int adis16060_spi_write(struct device *dev, u8 val) { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16060_state *st = iio_dev_get_devdata(indio_dev); + struct adis16060_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->buf[2] = val; /* The last 8 bits clocked in are latched */ @@ -64,7 +62,7 @@ static int adis16060_spi_read(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16060_state *st = iio_dev_get_devdata(indio_dev); + struct adis16060_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -141,43 +139,38 @@ static const struct iio_info adis16060_info = { static int __devinit adis16060_r_probe(struct spi_device *spi) { int ret, regdone = 0; - struct adis16060_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; + struct adis16060_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; goto error_ret; } /* this is only used for removal purposes */ - spi_set_drvdata(spi, st); - + spi_set_drvdata(spi, indio_dev); + st = iio_priv(indio_dev); st->us_r = spi; mutex_init(&st->buf_lock); - /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &adis16060_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &adis16060_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; regdone = 1; - adis16060_st = st; + adis16060_iio_dev = indio_dev; return 0; error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(indio_dev); else - iio_free_device(st->indio_dev); -error_free_st: - kfree(st); + iio_free_device(indio_dev); error_ret: return ret; } @@ -185,11 +178,7 @@ static int __devinit adis16060_r_probe(struct spi_device *spi) /* fixme, confirm ordering in this function */ static int adis16060_r_remove(struct spi_device *spi) { - struct adis16060_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; - - iio_device_unregister(indio_dev); - kfree(st); + iio_device_unregister(spi_get_drvdata(spi)); return 0; } @@ -197,12 +186,14 @@ static int adis16060_r_remove(struct spi_device *spi) static int __devinit adis16060_w_probe(struct spi_device *spi) { int ret; - struct adis16060_state *st = adis16060_st; - if (!st) { + struct iio_dev *indio_dev = adis16060_iio_dev; + struct adis16060_state *st; + if (!indio_dev) { ret = -ENODEV; goto error_ret; } - spi_set_drvdata(spi, st); + st = iio_priv(indio_dev); + spi_set_drvdata(spi, indio_dev); st->us_w = spi; return 0; diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c index d42690bea066..ad2db4d723df 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -34,13 +34,11 @@ /** * struct adis16080_state - device instance specific data * @us: actual spi_device to write data - * @indio_dev: industrial I/O device structure * @buf: transmit or receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16080_state { struct spi_device *us; - struct iio_dev *indio_dev; struct mutex buf_lock; u8 buf[2] ____cacheline_aligned; @@ -51,7 +49,7 @@ static int adis16080_spi_write(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16080_state *st = iio_dev_get_devdata(indio_dev); + struct adis16080_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->buf[0] = val >> 8; @@ -68,7 +66,7 @@ static int adis16080_spi_read(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16080_state *st = iio_dev_get_devdata(indio_dev); + struct adis16080_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -131,31 +129,29 @@ static const struct iio_info adis16080_info = { static int __devinit adis16080_probe(struct spi_device *spi) { int ret, regdone = 0; - struct adis16080_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; + struct adis16080_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; goto error_ret; } + st = iio_priv(indio_dev); /* this is only used for removal purposes */ - spi_set_drvdata(spi, st); + spi_set_drvdata(spi, indio_dev); /* Allocate the comms buffers */ st->us = spi; mutex_init(&st->buf_lock); - /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->indio_dev->name = spi->dev.driver->name; - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &adis16080_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = spi->dev.driver->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &adis16080_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; regdone = 1; @@ -164,11 +160,9 @@ static int __devinit adis16080_probe(struct spi_device *spi) error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(indio_dev); else - iio_free_device(st->indio_dev); -error_free_st: - kfree(st); + iio_free_device(indio_dev); error_ret: return ret; } @@ -176,11 +170,7 @@ static int __devinit adis16080_probe(struct spi_device *spi) /* fixme, confirm ordering in this function */ static int adis16080_remove(struct spi_device *spi) { - struct adis16080_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; - - iio_device_unregister(indio_dev); - kfree(st); + iio_device_unregister(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c index 14d5a34ab441..c80e908d8acf 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -41,14 +41,12 @@ /** * struct adis16130_state - device instance specific data * @us: actual spi_device to write data - * @indio_dev: industrial I/O device structure * @mode: 24 bits (1) or 16 bits (0) * @buf_lock: mutex to protect tx and rx * @buf: unified tx/rx buffer **/ struct adis16130_state { struct spi_device *us; - struct iio_dev *indio_dev; u32 mode; struct mutex buf_lock; u8 buf[4] ____cacheline_aligned; @@ -59,7 +57,7 @@ static int adis16130_spi_write(struct device *dev, u8 reg_addr, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16130_state *st = iio_dev_get_devdata(indio_dev); + struct adis16130_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->buf[0] = reg_addr; @@ -76,7 +74,7 @@ static int adis16130_spi_read(struct device *dev, u8 reg_addr, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16130_state *st = iio_dev_get_devdata(indio_dev); + struct adis16130_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -125,7 +123,7 @@ static ssize_t adis16130_bitsmode_read(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16130_state *st = iio_dev_get_devdata(indio_dev); + struct adis16130_state *st = iio_priv(indio_dev); if (st->mode == 1) return sprintf(buf, "s24\n"); @@ -183,39 +181,35 @@ static const struct iio_info adis16130_info = { static int __devinit adis16130_probe(struct spi_device *spi) { int ret; - struct adis16130_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; + struct adis16130_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; goto error_ret; } + st = iio_priv(indio_dev); /* this is only used for removal purposes */ - spi_set_drvdata(spi, st); + spi_set_drvdata(spi, indio_dev); st->us = spi; mutex_init(&st->buf_lock); - /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - - st->indio_dev->name = spi->dev.driver->name; - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &adis16130_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = spi->dev.driver->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &adis16130_info; + indio_dev->modes = INDIO_DIRECT_MODE; st->mode = 1; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; return 0; error_free_dev: - iio_free_device(st->indio_dev); -error_free_st: - kfree(st); + iio_free_device(indio_dev); + error_ret: return ret; } @@ -223,11 +217,7 @@ static int __devinit adis16130_probe(struct spi_device *spi) /* fixme, confirm ordering in this function */ static int adis16130_remove(struct spi_device *spi) { - struct adis16130_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; - - iio_device_unregister(indio_dev); - kfree(st); + iio_device_unregister(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h index 24bf70e4b29b..969b624be6d3 100644 --- a/drivers/staging/iio/gyro/adis16260.h +++ b/drivers/staging/iio/gyro/adis16260.h @@ -85,21 +85,19 @@ /** * struct adis16260_state - device instance specific data * @us: actual spi_device - * @indio_dev: industrial I/O device structure * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: receive buffer * @buf_lock: mutex to protect tx and rx * @negate: negate the scale parameter + * @tx: transmit buffer + * @rx: receive buffer **/ struct adis16260_state { - struct spi_device *us; - struct iio_dev *indio_dev; - struct iio_trigger *trig; - u8 *tx; - u8 *rx; - struct mutex buf_lock; - unsigned negate:1; + struct spi_device *us; + struct iio_trigger *trig; + struct mutex buf_lock; + unsigned negate:1; + u8 tx[ADIS16260_MAX_TX] ____cacheline_aligned; + u8 rx[ADIS16260_MAX_RX]; }; int adis16260_set_irq(struct iio_dev *indio_dev, bool enable); diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 3dc9a272749d..05797f404bea 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -41,7 +41,7 @@ static int adis16260_spi_write_reg_8(struct iio_dev *indio_dev, u8 val) { int ret; - struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + struct adis16260_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADIS16260_WRITE_REG(reg_address); @@ -66,7 +66,7 @@ static int adis16260_spi_write_reg_16(struct iio_dev *indio_dev, { int ret; struct spi_message msg; - struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + struct adis16260_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { .tx_buf = st->tx, @@ -109,7 +109,7 @@ static int adis16260_spi_read_reg_16(struct iio_dev *indio_dev, u16 *val) { struct spi_message msg; - struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + struct adis16260_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -152,7 +152,7 @@ static ssize_t adis16260_read_frequency_available(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + struct adis16260_state *st = iio_priv(indio_dev); if (spi_get_device_id(st->us)->driver_data) return sprintf(buf, "%s\n", "0.129 ~ 256"); else @@ -164,7 +164,7 @@ static ssize_t adis16260_read_frequency(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + struct adis16260_state *st = iio_priv(indio_dev); int ret, len = 0; u16 t; int sps; @@ -189,7 +189,7 @@ static ssize_t adis16260_write_frequency(struct device *dev, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + struct adis16260_state *st = iio_priv(indio_dev); long val; int ret; u8 t; @@ -435,7 +435,7 @@ static int adis16260_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { - struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + struct adis16260_state *st = iio_priv(indio_dev); int ret; int bits; u8 addr; @@ -576,71 +576,58 @@ static int __devinit adis16260_probe(struct spi_device *spi) { int ret, regdone = 0; struct adis16260_platform_data *pd = spi->dev.platform_data; - struct adis16260_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; + struct adis16260_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; goto error_ret; } + st = iio_priv(indio_dev); if (pd) st->negate = pd->negate; /* 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(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } - st->indio_dev->name = spi_get_device_id(st->us)->name; - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &adis16260_info; - st->indio_dev->num_channels + indio_dev->name = spi_get_device_id(st->us)->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &adis16260_info; + indio_dev->num_channels = ARRAY_SIZE(adis16260_channels_x); if (pd && pd->direction) switch (pd->direction) { case 'x': - st->indio_dev->channels = adis16260_channels_x; + indio_dev->channels = adis16260_channels_x; break; case 'y': - st->indio_dev->channels = adis16260_channels_y; + indio_dev->channels = adis16260_channels_y; break; case 'z': - st->indio_dev->channels = adis16260_channels_z; + indio_dev->channels = adis16260_channels_z; break; default: return -EINVAL; } else - st->indio_dev->channels = adis16260_channels_x; + indio_dev->channels = adis16260_channels_x; + indio_dev->num_channels = ARRAY_SIZE(adis16260_channels_x); + indio_dev->modes = INDIO_DIRECT_MODE; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; - - ret = adis16260_configure_ring(st->indio_dev); + ret = adis16260_configure_ring(indio_dev); if (ret) goto error_free_dev; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_unreg_ring_funcs; regdone = 1; - ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0, - st->indio_dev->channels, + ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, + indio_dev->channels, ARRAY_SIZE(adis16260_channels_x)); if (ret) { printk(KERN_ERR "failed to initialize the ring\n"); @@ -648,34 +635,28 @@ static int __devinit adis16260_probe(struct spi_device *spi) } if (spi->irq) { - ret = adis16260_probe_trigger(st->indio_dev); + ret = adis16260_probe_trigger(indio_dev); if (ret) goto error_uninitialize_ring; } /* Get the device into a sane initial state */ - ret = adis16260_initial_setup(st->indio_dev); + ret = adis16260_initial_setup(indio_dev); if (ret) goto error_remove_trigger; return 0; error_remove_trigger: - adis16260_remove_trigger(st->indio_dev); + adis16260_remove_trigger(indio_dev); error_uninitialize_ring: - iio_ring_buffer_unregister(st->indio_dev->ring); + iio_ring_buffer_unregister(indio_dev->ring); error_unreg_ring_funcs: - adis16260_unconfigure_ring(st->indio_dev); + adis16260_unconfigure_ring(indio_dev); error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(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); + iio_free_device(indio_dev); error_ret: return ret; } @@ -683,8 +664,7 @@ static int __devinit adis16260_probe(struct spi_device *spi) 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; + struct iio_dev *indio_dev = spi_get_drvdata(spi); ret = adis16260_stop_device(indio_dev); if (ret) @@ -693,13 +673,9 @@ static int adis16260_remove(struct spi_device *spi) flush_scheduled_work(); adis16260_remove_trigger(indio_dev); - - iio_ring_buffer_unregister(st->indio_dev->ring); + iio_ring_buffer_unregister(indio_dev->ring); iio_device_unregister(indio_dev); adis16260_unconfigure_ring(indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); err_ret: return ret; diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c index a0925044eaa5..a4df8b32251e 100644 --- a/drivers/staging/iio/gyro/adis16260_ring.c +++ b/drivers/staging/iio/gyro/adis16260_ring.c @@ -17,7 +17,6 @@ #include "../trigger.h" #include "adis16260.h" - /** * 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) @@ -27,7 +26,7 @@ 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 adis16260_state *st = iio_priv(indio_dev); struct spi_transfer xfers[ADIS16260_OUTPUTS + 1]; int ret; int i; @@ -70,7 +69,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->private_data; - struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + struct adis16260_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; int i = 0; s16 *data; @@ -83,7 +82,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p) } if (ring->scan_count && - adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) + adis16260_read_ring_data(&indio_dev->dev, st->rx) >= 0) for (; i < ring->scan_count; i++) data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); @@ -93,7 +92,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p) ring->access->store_to(ring, (u8 *)data, pf->timestamp); - iio_trigger_notify_done(st->indio_dev->trig); + iio_trigger_notify_done(indio_dev->trig); kfree(data); return IRQ_HANDLED; diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c index 4f10fb543356..01094d0e714a 100644 --- a/drivers/staging/iio/gyro/adis16260_trigger.c +++ b/drivers/staging/iio/gyro/adis16260_trigger.c @@ -18,8 +18,7 @@ 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; + struct iio_dev *indio_dev = trig->private_data; dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); return adis16260_set_irq(indio_dev, state); @@ -28,7 +27,7 @@ static int adis16260_data_rdy_trigger_set_state(struct iio_trigger *trig, int adis16260_probe_trigger(struct iio_dev *indio_dev) { int ret; - struct adis16260_state *st = indio_dev->dev_data; + struct adis16260_state *st = iio_priv(indio_dev); st->trig = iio_allocate_trigger("%s-dev%d", spi_get_device_id(st->us)->name, @@ -48,7 +47,7 @@ int adis16260_probe_trigger(struct iio_dev *indio_dev) st->trig->dev.parent = &st->us->dev; st->trig->owner = THIS_MODULE; - st->trig->private_data = st; + st->trig->private_data = indio_dev; st->trig->set_trigger_state = &adis16260_data_rdy_trigger_set_state; ret = iio_trigger_register(st->trig); @@ -69,9 +68,9 @@ int adis16260_probe_trigger(struct iio_dev *indio_dev) void adis16260_remove_trigger(struct iio_dev *indio_dev) { - struct adis16260_state *state = indio_dev->dev_data; + struct adis16260_state *st = iio_priv(indio_dev); - iio_trigger_unregister(state->trig); - free_irq(state->us->irq, state->trig); - iio_free_trigger(state->trig); + iio_trigger_unregister(st->trig); + free_irq(st->us->irq, st->trig); + iio_free_trigger(st->trig); } diff --git a/drivers/staging/iio/gyro/adxrs450.h b/drivers/staging/iio/gyro/adxrs450.h index c92f6945f00f..b6b682876406 100644 --- a/drivers/staging/iio/gyro/adxrs450.h +++ b/drivers/staging/iio/gyro/adxrs450.h @@ -42,17 +42,16 @@ /** * struct adxrs450_state - device instance specific data * @us: actual spi_device - * @indio_dev: industrial I/O device structure + * @buf_lock: mutex to protect tx and rx * @tx: transmit buffer * @rx: recieve buffer - * @buf_lock: mutex to protect tx and rx **/ struct adxrs450_state { - struct spi_device *us; - struct iio_dev *indio_dev; - u8 *tx; - u8 *rx; - struct mutex buf_lock; + struct spi_device *us; + struct mutex buf_lock; + u8 tx[ADXRS450_MAX_RX] ____cacheline_aligned; + u8 rx[ADXRS450_MAX_TX]; + }; #endif /* SPI_ADXRS450_H_ */ diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c index 3714e4aadc23..7502a264770b 100644 --- a/drivers/staging/iio/gyro/adxrs450_core.c +++ b/drivers/staging/iio/gyro/adxrs450_core.c @@ -38,7 +38,7 @@ static int adxrs450_spi_read_reg_16(struct device *dev, { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adxrs450_state *st = iio_dev_get_devdata(indio_dev); + struct adxrs450_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -92,7 +92,7 @@ static int adxrs450_spi_write_reg_16(struct device *dev, { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adxrs450_state *st = iio_dev_get_devdata(indio_dev); + struct adxrs450_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers = { .tx_buf = st->tx, @@ -130,7 +130,7 @@ static int adxrs450_spi_sensor_data(struct device *dev, s16 *val) { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adxrs450_state *st = iio_dev_get_devdata(indio_dev); + struct adxrs450_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -267,12 +267,13 @@ static ssize_t adxrs450_read_sensor_data(struct device *dev, } /* Recommended Startup Sequence by spec */ -static int adxrs450_initial_setup(struct adxrs450_state *st) +static int adxrs450_initial_setup(struct iio_dev *indio_dev) { u32 t; u16 data; int ret; - struct device *dev = &st->indio_dev->dev; + struct device *dev = &indio_dev->dev; + struct adxrs450_state *st = iio_priv(indio_dev); msleep(ADXRS450_STARTUP_DELAY*2); ret = adxrs450_spi_initial(st, &t, 1); @@ -357,46 +358,32 @@ static const struct iio_info adxrs450_info = { static int __devinit adxrs450_probe(struct spi_device *spi) { int ret, regdone = 0; - struct adxrs450_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; + struct adxrs450_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + 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)*ADXRS450_MAX_RX, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kzalloc(sizeof(*st->tx)*ADXRS450_MAX_TX, GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_free_rx; - } + st = iio_priv(indio_dev); st->us = spi; mutex_init(&st->buf_lock); - /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } + /* This is only used for removal purposes */ + spi_set_drvdata(spi, indio_dev); - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &adxrs450_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &adxrs450_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; regdone = 1; /* Get the device into a sane initial state */ - ret = adxrs450_initial_setup(st); + ret = adxrs450_initial_setup(indio_dev); if (ret) goto error_initial; return 0; @@ -404,27 +391,17 @@ static int __devinit adxrs450_probe(struct spi_device *spi) error_initial: error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(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); + iio_free_device(indio_dev); + error_ret: return ret; } static int adxrs450_remove(struct spi_device *spi) { - struct adxrs450_state *st = spi_get_drvdata(spi); - - iio_device_unregister(st->indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); + iio_device_unregister(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index 38f1425f4645..7a6ce4d0fb7b 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -30,6 +30,7 @@ enum iio_chan_type { /* real channel types */ IIO_IN, + IIO_OUT, IIO_CURRENT, IIO_POWER, IIO_ACCEL, @@ -202,6 +203,9 @@ static inline s64 iio_get_time_ns(void) * call to iio_device_register. */ #define IIO_VAL_INT 1 #define IIO_VAL_INT_PLUS_MICRO 2 +#define IIO_VAL_INT_PLUS_NANO 3 + +struct iio_trigger; /* forward declaration */ /** * struct iio_info - constant information about device @@ -217,12 +221,17 @@ static inline s64 iio_get_time_ns(void) * contain the elements making up the returned value. * @write_raw: function to write a value to the device. * Parameters are the same as for read_raw. + * @write_raw_get_fmt: callback function to query the expected + * format/precision. If not set by the driver, write_raw + * returns IIO_VAL_INT_PLUS_MICRO. * @read_event_config: find out if the event is enabled. * @write_event_config: set if the event is enabled. * @read_event_value: read a value associated with the event. Meaning * is event dependant. event_code specifies which event. * @write_event_value: write the value associate with the event. * Meaning is event dependent. + * @validate_trigger: function to validate the trigger when the + * current trigger gets changed. **/ struct iio_info { struct module *driver_module; @@ -242,6 +251,10 @@ struct iio_info { int val2, long mask); + int (*write_raw_get_fmt)(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask); + int (*read_event_config)(struct iio_dev *indio_dev, int event_code); @@ -255,6 +268,9 @@ struct iio_info { int (*write_event_value)(struct iio_dev *indio_dev, int event_code, int val); + int (*validate_trigger)(struct iio_dev *indio_dev, + struct iio_trigger *trig); + }; /** diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h index e87715b9acc6..1f8f0c60c2c3 100644 --- a/drivers/staging/iio/imu/adis16400.h +++ b/drivers/staging/iio/imu/adis16400.h @@ -41,6 +41,9 @@ #define ADIS16350_YTEMP_OUT 0x12 /* Y-axis gyroscope temperature measurement */ #define ADIS16350_ZTEMP_OUT 0x14 /* Z-axis gyroscope temperature measurement */ +#define ADIS16300_PITCH_OUT 0x12 /* X axis inclinometer output measurement */ +#define ADIS16300_ROLL_OUT 0x12 /* Y axis inclinometer output 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 */ diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index fe89802e3fe7..a2c3b67dcbdf 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -441,10 +441,12 @@ enum adis16400_chan { magn_z, temp, temp0, temp1, temp2, - in1 + in1, + incli_x, + incli_y, }; -static u8 adis16400_addresses[16][2] = { +static u8 adis16400_addresses[17][2] = { [in_supply] = { ADIS16400_SUPPLY_OUT, 0 }, [gyro_x] = { ADIS16400_XGYRO_OUT, ADIS16400_XGYRO_OFF }, [gyro_y] = { ADIS16400_YGYRO_OUT, ADIS16400_YGYRO_OFF }, @@ -459,7 +461,9 @@ static u8 adis16400_addresses[16][2] = { [temp0] = { ADIS16350_XTEMP_OUT }, [temp1] = { ADIS16350_YTEMP_OUT }, [temp2] = { ADIS16350_ZTEMP_OUT }, - [in1] = { ADIS16400_AUX_ADC , 0 }, + [in1] = { ADIS16400_AUX_ADC, 0 }, + [incli_x] = { ADIS16300_PITCH_OUT, 0 }, + [incli_y] = { ADIS16300_ROLL_OUT, 0 } }; static int adis16400_write_raw(struct iio_dev *indio_dev, @@ -612,82 +616,82 @@ static struct iio_chan_spec adis16400_channels[] = { static struct iio_chan_spec adis16350_channels[] = { IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0, (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - 0, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0), + in_supply, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0), IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X, (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SHARED), - 1, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0), + gyro_x, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0), IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Y, (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SHARED), - 2, ADIS16400_SCAN_GYRO_Y, IIO_ST('s', 14, 16, 0), 0), + gyro_y, ADIS16400_SCAN_GYRO_Y, IIO_ST('s', 14, 16, 0), 0), IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Z, (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SHARED), - 3, ADIS16400_SCAN_GYRO_Z, IIO_ST('s', 14, 16, 0), 0), + gyro_z, ADIS16400_SCAN_GYRO_Z, IIO_ST('s', 14, 16, 0), 0), IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SHARED), - 4, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0), + accel_x, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0), IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SHARED), - 0, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0), + accel_y, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0), IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SHARED), - 0, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0), + accel_z, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0), IIO_CHAN(IIO_TEMP, 0, 1, 0, "x", 0, 0, (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - 0, ADIS16350_SCAN_TEMP_X, IIO_ST('s', 12, 16, 0), 0), + temp0, ADIS16350_SCAN_TEMP_X, IIO_ST('s', 12, 16, 0), 0), IIO_CHAN(IIO_TEMP, 0, 1, 0, "y", 1, 0, (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - 0, ADIS16350_SCAN_TEMP_Y, IIO_ST('s', 12, 16, 0), 0), + temp1, ADIS16350_SCAN_TEMP_Y, IIO_ST('s', 12, 16, 0), 0), IIO_CHAN(IIO_TEMP, 0, 1, 0, "z", 2, 0, (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - 0, ADIS16350_SCAN_TEMP_Z, IIO_ST('s', 12, 16, 0), 0), + temp2, ADIS16350_SCAN_TEMP_Z, IIO_ST('s', 12, 16, 0), 0), IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - 0, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0), + in1, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0), IIO_CHAN_SOFT_TIMESTAMP(11) }; static struct iio_chan_spec adis16300_channels[] = { IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0, (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - 0, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0), + in_supply, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0), IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X, (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SHARED), - 1, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0), + gyro_x, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0), IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SHARED), - 4, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0), + accel_x, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0), IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SHARED), - 0, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0), + accel_y, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0), IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SHARED), - 0, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0), + accel_z, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0), IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - 0, ADIS16400_SCAN_TEMP, IIO_ST('s', 12, 16, 0), 0), + temp, ADIS16400_SCAN_TEMP, IIO_ST('s', 12, 16, 0), 0), IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, (1 << IIO_CHAN_INFO_SCALE_SEPARATE), - 0, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0), + in1, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0), IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X, (1 << IIO_CHAN_INFO_SCALE_SHARED), - 0, ADIS16300_SCAN_INCLI_X, IIO_ST('s', 13, 16, 0), 0), + incli_x, ADIS16300_SCAN_INCLI_X, IIO_ST('s', 13, 16, 0), 0), IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y, (1 << IIO_CHAN_INFO_SCALE_SHARED), - 0, ADIS16300_SCAN_INCLI_Y, IIO_ST('s', 13, 16, 0), 0), + incli_y, ADIS16300_SCAN_INCLI_Y, IIO_ST('s', 13, 16, 0), 0), IIO_CHAN_SOFT_TIMESTAMP(14) }; diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 94d3bfaa061d..19819e7578c6 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -44,20 +44,22 @@ struct bus_type iio_bus_type = { EXPORT_SYMBOL(iio_bus_type); static const char * const iio_chan_type_name_spec_shared[] = { - [IIO_TIMESTAMP] = "timestamp", - [IIO_ACCEL] = "accel", [IIO_IN] = "in", + [IIO_OUT] = "out", [IIO_CURRENT] = "current", [IIO_POWER] = "power", + [IIO_ACCEL] = "accel", [IIO_IN_DIFF] = "in-in", [IIO_GYRO] = "gyro", - [IIO_TEMP] = "temp", [IIO_MAGN] = "magn", + [IIO_LIGHT] = "illuminance", + [IIO_INTENSITY] = "intensity", + [IIO_PROXIMITY] = "proximity", + [IIO_TEMP] = "temp", [IIO_INCLI] = "incli", [IIO_ROT] = "rot", - [IIO_INTENSITY] = "intensity", - [IIO_LIGHT] = "illuminance", [IIO_ANGL] = "angl", + [IIO_TIMESTAMP] = "timestamp", }; static const char * const iio_chan_type_name_spec_complex[] = { @@ -396,6 +398,11 @@ static ssize_t iio_read_channel_info(struct device *dev, return sprintf(buf, "-%d.%06u\n", val, -val2); else return sprintf(buf, "%d.%06u\n", val, val2); + } else if (ret == IIO_VAL_INT_PLUS_NANO) { + if (val2 < 0) + return sprintf(buf, "-%d.%09u\n", val, -val2); + else + return sprintf(buf, "%d.%09u\n", val, val2); } else return 0; } @@ -407,25 +414,40 @@ static ssize_t iio_write_channel_info(struct device *dev, { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret, integer = 0, micro = 0, micro_mult = 100000; + int ret, integer = 0, fract = 0, fract_mult = 100000; bool integer_part = true, negative = false; /* Assumes decimal - precision based on number of digits */ if (!indio_dev->info->write_raw) return -EINVAL; + + if (indio_dev->info->write_raw_get_fmt) + switch (indio_dev->info->write_raw_get_fmt(indio_dev, + this_attr->c, this_attr->address)) { + case IIO_VAL_INT_PLUS_MICRO: + fract_mult = 100000; + break; + case IIO_VAL_INT_PLUS_NANO: + fract_mult = 100000000; + break; + default: + return -EINVAL; + } + if (buf[0] == '-') { negative = true; buf++; } + while (*buf) { if ('0' <= *buf && *buf <= '9') { if (integer_part) integer = integer*10 + *buf - '0'; else { - micro += micro_mult*(*buf - '0'); - if (micro_mult == 1) + fract += fract_mult*(*buf - '0'); + if (fract_mult == 1) break; - micro_mult /= 10; + fract_mult /= 10; } } else if (*buf == '\n') { if (*(buf + 1) == '\0') @@ -443,11 +465,11 @@ static ssize_t iio_write_channel_info(struct device *dev, if (integer) integer = -integer; else - micro = -micro; + fract = -fract; } ret = indio_dev->info->write_raw(indio_dev, this_attr->c, - integer, micro, this_attr->address); + integer, fract, this_attr->address); if (ret) return ret; @@ -655,7 +677,8 @@ static int iio_device_add_channel_sysfs(struct iio_dev *dev_info, else ret = __iio_add_chan_devattr("raw", NULL, chan, &iio_read_channel_info, - NULL, + (chan->type == IIO_OUT ? + &iio_write_channel_info : NULL), 0, 0, &dev_info->dev, diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c index d504aa251ced..90ca2df23eab 100644 --- a/drivers/staging/iio/industrialio-trigger.c +++ b/drivers/staging/iio/industrialio-trigger.c @@ -340,6 +340,9 @@ static ssize_t iio_trigger_write_current(struct device *dev, { struct iio_dev *dev_info = dev_get_drvdata(dev); struct iio_trigger *oldtrig = dev_info->trig; + struct iio_trigger *trig; + int ret; + mutex_lock(&dev_info->mlock); if (dev_info->currentmode == INDIO_RING_TRIGGERED) { mutex_unlock(&dev_info->mlock); @@ -347,7 +350,22 @@ static ssize_t iio_trigger_write_current(struct device *dev, } mutex_unlock(&dev_info->mlock); - dev_info->trig = iio_trigger_find_by_name(buf, len); + trig = iio_trigger_find_by_name(buf, len); + + if (trig && dev_info->info->validate_trigger) { + ret = dev_info->info->validate_trigger(dev_info, trig); + if (ret) + return ret; + } + + if (trig && trig->validate_device) { + ret = trig->validate_device(trig, dev_info); + if (ret) + return ret; + } + + dev_info->trig = trig; + if (oldtrig && dev_info->trig != oldtrig) iio_put_trigger(oldtrig); if (dev_info->trig) diff --git a/drivers/staging/iio/kfifo_buf.c b/drivers/staging/iio/kfifo_buf.c index cc14b96d814c..6002368fdcfa 100644 --- a/drivers/staging/iio/kfifo_buf.c +++ b/drivers/staging/iio/kfifo_buf.c @@ -110,9 +110,7 @@ struct iio_ring_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev) iio_ring_buffer_init(&kf->ring, indio_dev); __iio_init_kfifo(kf); kf->ring.dev.type = &iio_kfifo_type; - device_initialize(&kf->ring.dev); kf->ring.dev.parent = &indio_dev->dev; - kf->ring.dev.bus = &iio_bus_type; dev_set_drvdata(&kf->ring.dev, (void *)&(kf->ring)); return &kf->ring; diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig index 46d62d1b0370..1ad2d56c8ba8 100644 --- a/drivers/staging/iio/light/Kconfig +++ b/drivers/staging/iio/light/Kconfig @@ -1,4 +1,4 @@ -\# +# # Light sensors # comment "Light sensors" diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 4794ffd5e446..426b6af70807 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -54,9 +54,9 @@ #define ISL29018_MAX_REGS ISL29018_REG_ADD_DATA_MSB struct isl29018_chip { - struct iio_dev *indio_dev; struct i2c_client *client; struct mutex lock; + unsigned int lux_scale; unsigned int range; unsigned int adc_bit; int prox_scheme; @@ -68,7 +68,7 @@ static int isl29018_write_data(struct i2c_client *client, u8 reg, { u8 regval; int ret = 0; - struct isl29018_chip *chip = i2c_get_clientdata(client); + struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client)); regval = chip->reg_cache[reg]; regval &= ~mask; @@ -158,7 +158,7 @@ static int isl29018_read_sensor_input(struct i2c_client *client, int mode) static int isl29018_read_lux(struct i2c_client *client, int *lux) { int lux_data; - struct isl29018_chip *chip = i2c_get_clientdata(client); + struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client)); lux_data = isl29018_read_sensor_input(client, COMMMAND1_OPMODE_ALS_ONCE); @@ -166,7 +166,7 @@ static int isl29018_read_lux(struct i2c_client *client, int *lux) if (lux_data < 0) return lux_data; - *lux = (lux_data * chip->range) >> chip->adc_bit; + *lux = (lux_data * chip->range * chip->lux_scale) >> chip->adc_bit; return 0; } @@ -224,52 +224,13 @@ static int isl29018_read_proximity_ir(struct i2c_client *client, int scheme, return 0; } -static ssize_t get_sensor_data(struct device *dev, char *buf, int mode) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct isl29018_chip *chip = indio_dev->dev_data; - struct i2c_client *client = chip->client; - int value = 0; - int status; - - mutex_lock(&chip->lock); - switch (mode) { - case COMMMAND1_OPMODE_PROX_ONCE: - status = isl29018_read_proximity_ir(client, - chip->prox_scheme, &value); - break; - - case COMMMAND1_OPMODE_ALS_ONCE: - status = isl29018_read_lux(client, &value); - break; - - case COMMMAND1_OPMODE_IR_ONCE: - status = isl29018_read_ir(client, &value); - break; - - default: - dev_err(&client->dev, "Mode %d is not supported\n", mode); - mutex_unlock(&chip->lock); - return -EBUSY; - } - if (status < 0) { - dev_err(&client->dev, "Error in Reading data"); - mutex_unlock(&chip->lock); - return status; - } - - mutex_unlock(&chip->lock); - - return sprintf(buf, "%d\n", value); -} - /* Sysfs interface */ /* range */ static ssize_t show_range(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct isl29018_chip *chip = indio_dev->dev_data; + struct isl29018_chip *chip = iio_priv(indio_dev); return sprintf(buf, "%u\n", chip->range); } @@ -278,7 +239,7 @@ static ssize_t store_range(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct isl29018_chip *chip = indio_dev->dev_data; + struct isl29018_chip *chip = iio_priv(indio_dev); struct i2c_client *client = chip->client; int status; unsigned long lval; @@ -311,7 +272,7 @@ static ssize_t show_resolution(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct isl29018_chip *chip = indio_dev->dev_data; + struct isl29018_chip *chip = iio_priv(indio_dev); return sprintf(buf, "%u\n", chip->adc_bit); } @@ -320,7 +281,7 @@ static ssize_t store_resolution(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct isl29018_chip *chip = indio_dev->dev_data; + struct isl29018_chip *chip = iio_priv(indio_dev); struct i2c_client *client = chip->client; int status; unsigned long lval; @@ -351,7 +312,7 @@ static ssize_t show_prox_infrared_supression(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct isl29018_chip *chip = indio_dev->dev_data; + struct isl29018_chip *chip = iio_priv(indio_dev); /* return the "proximity scheme" i.e. if the chip does on chip infrared supression (1 means perform on chip supression) */ @@ -362,7 +323,7 @@ static ssize_t store_prox_infrared_supression(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct isl29018_chip *chip = indio_dev->dev_data; + struct isl29018_chip *chip = iio_priv(indio_dev); unsigned long lval; if (strict_strtoul(buf, 10, &lval)) @@ -381,26 +342,86 @@ static ssize_t store_prox_infrared_supression(struct device *dev, return count; } -/* Read lux */ -static ssize_t show_lux(struct device *dev, - struct device_attribute *devattr, char *buf) +/* Channel IO */ +static int isl29018_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) { - return get_sensor_data(dev, buf, COMMMAND1_OPMODE_ALS_ONCE); + struct isl29018_chip *chip = iio_priv(indio_dev); + int ret = -EINVAL; + + mutex_lock(&chip->lock); + if (mask == (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) && + chan->type == IIO_LIGHT) { + chip->lux_scale = val; + ret = 0; + } + mutex_unlock(&chip->lock); + + return 0; } -/* Read ir */ -static ssize_t show_ir(struct device *dev, - struct device_attribute *devattr, char *buf) +static int isl29018_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) { - return get_sensor_data(dev, buf, COMMMAND1_OPMODE_IR_ONCE); + int ret = -EINVAL; + struct isl29018_chip *chip = iio_priv(indio_dev); + struct i2c_client *client = chip->client; + + mutex_lock(&chip->lock); + switch (mask) { + case 0: + switch (chan->type) { + case IIO_LIGHT: + ret = isl29018_read_lux(client, val); + break; + case IIO_INTENSITY: + ret = isl29018_read_ir(client, val); + break; + case IIO_PROXIMITY: + ret = isl29018_read_proximity_ir(client, + chip->prox_scheme, val); + break; + default: + break; + } + if (!ret) + ret = IIO_VAL_INT; + break; + case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE): + if (chan->type == IIO_LIGHT) { + *val = chip->lux_scale; + ret = IIO_VAL_INT; + } + break; + default: + break; + } + mutex_unlock(&chip->lock); + return ret; } -/* Read nearest ir */ -static ssize_t show_proxim_ir(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - return get_sensor_data(dev, buf, COMMMAND1_OPMODE_PROX_ONCE); -} +static const struct iio_chan_spec isl29018_channels[] = { + { + .type = IIO_LIGHT, + .indexed = 1, + .channel = 0, + .processed_val = 1, + .info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE), + }, { + .type = IIO_INTENSITY, + .modified = 1, + .channel2 = IIO_MOD_LIGHT_IR, + }, { + /* Unindexed in current ABI. But perhaps it should be. */ + .type = IIO_PROXIMITY, + } +}; static IIO_DEVICE_ATTR(range, S_IRUGO | S_IWUSR, show_range, store_range, 0); static IIO_CONST_ATTR(range_available, "1000 4000 16000 64000"); @@ -411,9 +432,6 @@ static IIO_DEVICE_ATTR(proximity_on_chip_ambient_infrared_supression, S_IRUGO | S_IWUSR, show_prox_infrared_supression, store_prox_infrared_supression, 0); -static IIO_DEVICE_ATTR(illuminance0_input, S_IRUGO, show_lux, NULL, 0); -static IIO_DEVICE_ATTR(intensity_infrared_raw, S_IRUGO, show_ir, NULL, 0); -static IIO_DEVICE_ATTR(proximity_raw, S_IRUGO, show_proxim_ir, NULL, 0); #define ISL29018_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr) #define ISL29018_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr) @@ -423,9 +441,6 @@ static struct attribute *isl29018_attributes[] = { ISL29018_DEV_ATTR(adc_resolution), ISL29018_CONST_ATTR(adc_resolution_available), ISL29018_DEV_ATTR(proximity_on_chip_ambient_infrared_supression), - ISL29018_DEV_ATTR(illuminance0_input), - ISL29018_DEV_ATTR(intensity_infrared_raw), - ISL29018_DEV_ATTR(proximity_raw), NULL }; @@ -435,7 +450,7 @@ static const struct attribute_group isl29108_group = { static int isl29018_chip_init(struct i2c_client *client) { - struct isl29018_chip *chip = i2c_get_clientdata(client); + struct isl29018_chip *chip = iio_priv(i2c_get_clientdata(client)); int status; int new_adc_bit; unsigned int new_range; @@ -458,44 +473,45 @@ static int isl29018_chip_init(struct i2c_client *client) static const struct iio_info isl29108_info = { .attrs = &isl29108_group, .driver_module = THIS_MODULE, + .read_raw = &isl29018_read_raw, + .write_raw = &isl29018_write_raw, }; static int __devinit isl29018_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct isl29018_chip *chip; + struct iio_dev *indio_dev; int err; - chip = kzalloc(sizeof(struct isl29018_chip), GFP_KERNEL); - if (!chip) { - dev_err(&client->dev, "Memory allocation fails\n"); + indio_dev = iio_allocate_device(sizeof(*chip)); + if (indio_dev == NULL) { + dev_err(&client->dev, "iio allocation fails\n"); err = -ENOMEM; goto exit; } + chip = iio_priv(indio_dev); - i2c_set_clientdata(client, chip); + i2c_set_clientdata(client, indio_dev); chip->client = client; mutex_init(&chip->lock); + chip->lux_scale = 1; chip->range = 1000; chip->adc_bit = 16; err = isl29018_chip_init(client); if (err) - goto exit_free; + goto exit_iio_free; - chip->indio_dev = iio_allocate_device(0); - if (!chip->indio_dev) { - dev_err(&client->dev, "iio allocation fails\n"); - goto exit_free; - } - chip->indio_dev->info = &isl29108_info; - chip->indio_dev->name = id->name; - chip->indio_dev->dev.parent = &client->dev; - chip->indio_dev->dev_data = (void *)(chip); - chip->indio_dev->modes = INDIO_DIRECT_MODE; - err = iio_device_register(chip->indio_dev); + indio_dev->info = &isl29108_info; + indio_dev->channels = isl29018_channels; + indio_dev->num_channels = ARRAY_SIZE(isl29018_channels); + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + err = iio_device_register(indio_dev); if (err) { dev_err(&client->dev, "iio registration fails\n"); goto exit_iio_free; @@ -503,20 +519,17 @@ static int __devinit isl29018_probe(struct i2c_client *client, return 0; exit_iio_free: - iio_free_device(chip->indio_dev); -exit_free: - kfree(chip); + iio_free_device(indio_dev); exit: return err; } static int __devexit isl29018_remove(struct i2c_client *client) { - struct isl29018_chip *chip = i2c_get_clientdata(client); + struct iio_dev *indio_dev = i2c_get_clientdata(client); dev_dbg(&client->dev, "%s()\n", __func__); - iio_device_unregister(chip->indio_dev); - kfree(chip); + iio_device_unregister(indio_dev); return 0; } diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index 9cffa2ecb0ee..f25243b08472 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -137,37 +137,14 @@ struct tsl2563_chip { u32 data1; }; -static int tsl2563_write(struct i2c_client *client, u8 reg, u8 value) -{ - int ret; - u8 buf[2]; - - buf[0] = TSL2563_CMD | reg; - buf[1] = value; - - ret = i2c_master_send(client, buf, sizeof(buf)); - return (ret == sizeof(buf)) ? 0 : ret; -} - -static int tsl2563_read(struct i2c_client *client, u8 reg, void *buf, int len) -{ - int ret; - u8 cmd = TSL2563_CMD | reg; - - ret = i2c_master_send(client, &cmd, sizeof(cmd)); - if (ret != sizeof(cmd)) - return ret; - - return i2c_master_recv(client, buf, len); -} - static int tsl2563_set_power(struct tsl2563_chip *chip, int on) { struct i2c_client *client = chip->client; u8 cmd; cmd = on ? TSL2563_CMD_POWER_ON : TSL2563_CMD_POWER_OFF; - return tsl2563_write(client, TSL2563_REG_CTRL, cmd); + return i2c_smbus_write_byte_data(client, + TSL2563_CMD | TSL2563_REG_CTRL, cmd); } /* @@ -178,36 +155,40 @@ static int tsl2563_get_power(struct tsl2563_chip *chip) { struct i2c_client *client = chip->client; int ret; - u8 val; - ret = tsl2563_read(client, TSL2563_REG_CTRL, &val, sizeof(val)); - if (ret != sizeof(val)) + ret = i2c_smbus_read_byte_data(client, TSL2563_CMD | TSL2563_REG_CTRL); + if (ret < 0) return ret; - return (val & TSL2563_CTRL_POWER_MASK) == TSL2563_CMD_POWER_ON; + return (ret & TSL2563_CTRL_POWER_MASK) == TSL2563_CMD_POWER_ON; } static int tsl2563_configure(struct tsl2563_chip *chip) { int ret; - ret = tsl2563_write(chip->client, TSL2563_REG_TIMING, + ret = i2c_smbus_write_byte_data(chip->client, + TSL2563_CMD | TSL2563_REG_TIMING, chip->gainlevel->gaintime); if (ret) goto error_ret; - ret = tsl2563_write(chip->client, TSL2563_REG_HIGHLOW, + ret = i2c_smbus_write_byte_data(chip->client, + TSL2563_CMD | TSL2563_REG_HIGHLOW, chip->high_thres & 0xFF); if (ret) goto error_ret; - ret = tsl2563_write(chip->client, TSL2563_REG_HIGHHIGH, + ret = i2c_smbus_write_byte_data(chip->client, + TSL2563_CMD | TSL2563_REG_HIGHHIGH, (chip->high_thres >> 8) & 0xFF); if (ret) goto error_ret; - ret = tsl2563_write(chip->client, TSL2563_REG_LOWLOW, + ret = i2c_smbus_write_byte_data(chip->client, + TSL2563_CMD | TSL2563_REG_LOWLOW, chip->low_thres & 0xFF); if (ret) goto error_ret; - ret = tsl2563_write(chip->client, TSL2563_REG_LOWHIGH, + ret = i2c_smbus_write_byte_data(chip->client, + TSL2563_CMD | TSL2563_REG_LOWHIGH, (chip->low_thres >> 8) & 0xFF); /* Interrupt register is automatically written anyway if it is relevant so is not here */ @@ -242,8 +223,8 @@ static int tsl2563_read_id(struct tsl2563_chip *chip, u8 *id) struct i2c_client *client = chip->client; int ret; - ret = tsl2563_read(client, TSL2563_REG_ID, id, sizeof(*id)); - if (ret != sizeof(*id)) + ret = i2c_smbus_read_byte_data(client, TSL2563_CMD | TSL2563_REG_ID); + if (ret < 0) return ret; return 0; @@ -313,8 +294,9 @@ static int tsl2563_adjust_gainlevel(struct tsl2563_chip *chip, u16 adc) (adc > chip->gainlevel->max) ? chip->gainlevel++ : chip->gainlevel--; - tsl2563_write(client, TSL2563_REG_TIMING, - chip->gainlevel->gaintime); + i2c_smbus_write_byte_data(client, + TSL2563_CMD | TSL2563_REG_TIMING, + chip->gainlevel->gaintime); tsl2563_wait_adc(chip); tsl2563_wait_adc(chip); @@ -327,7 +309,6 @@ static int tsl2563_adjust_gainlevel(struct tsl2563_chip *chip, u16 adc) static int tsl2563_get_adc(struct tsl2563_chip *chip) { struct i2c_client *client = chip->client; - u8 buf0[2], buf1[2]; u16 adc0, adc1; int retry = 1; int ret = 0; @@ -350,19 +331,17 @@ static int tsl2563_get_adc(struct tsl2563_chip *chip) } while (retry) { - ret = tsl2563_read(client, - TSL2563_REG_DATA0LOW, - buf0, sizeof(buf0)); - if (ret != sizeof(buf0)) + ret = i2c_smbus_read_word_data(client, + TSL2563_CMD | TSL2563_REG_DATA0LOW); + if (ret < 0) goto out; + adc0 = ret; - ret = tsl2563_read(client, TSL2563_REG_DATA1LOW, - buf1, sizeof(buf1)); - if (ret != sizeof(buf1)) + ret = i2c_smbus_read_word_data(client, + TSL2563_CMD | TSL2563_REG_DATA1LOW); + if (ret < 0) goto out; - - adc0 = (buf0[1] << 8) + buf0[0]; - adc1 = (buf1[1] << 8) + buf1[0]; + adc1 = ret; retry = tsl2563_adjust_gainlevel(chip, adc0); } @@ -548,15 +527,16 @@ static int tsl2563_read_raw(struct iio_dev *indio_dev, return ret; } +#define INFO_MASK (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) +#define EVENT_MASK (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \ + IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)) +#define IIO_CHAN_2563(type, mod, proc, chan, imask, emask) \ + IIO_CHAN(type, mod, 1, proc, NULL, chan, 0, imask, 0, 0, {}, emask) + static const struct iio_chan_spec tsl2563_channels[] = { - IIO_CHAN(IIO_LIGHT, 0, 1, 1, NULL, 0, 0, 0, 0, 0, {}, 0), - IIO_CHAN(IIO_INTENSITY, 1, 1, 0, "both", 0, - (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE), 0, 0, 0, {}, - IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | - IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)), - IIO_CHAN(IIO_INTENSITY, 1, 1, 0, "ir", 1, - (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE), 0, 0, 0, {}, - 0) + IIO_CHAN_2563(IIO_LIGHT, 0, 1, 0, 0, 0), + IIO_CHAN_2563(IIO_INTENSITY, 1, 0, 0, INFO_MASK, EVENT_MASK), + IIO_CHAN_2563(IIO_INTENSITY, 1, 0, 1, INFO_MASK, 0), }; static int tsl2563_read_thresh(struct iio_dev *indio_dev, @@ -592,11 +572,13 @@ static ssize_t tsl2563_write_thresh(struct iio_dev *indio_dev, else address = TSL2563_REG_LOWLOW; mutex_lock(&chip->lock); - ret = tsl2563_write(chip->client, address, val & 0xFF); + ret = i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | address, + val & 0xFF); if (ret) goto error_ret; - ret = tsl2563_write(chip->client, address + 1, - (val >> 8) & 0xFF); + ret = i2c_smbus_write_byte_data(chip->client, + TSL2563_CMD | (address + 1), + (val >> 8) & 0xFF); if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING) chip->high_thres = val; else @@ -612,7 +594,6 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private) { struct iio_dev *dev_info = private; struct tsl2563_chip *chip = iio_priv(dev_info); - u8 cmd = TSL2563_CMD | TSL2563_CLEARINT; iio_push_event(dev_info, 0, IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_LIGHT, @@ -622,7 +603,7 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private) iio_get_time_ns()); /* clear the interrupt and push the event */ - i2c_master_send(chip->client, &cmd, sizeof(cmd)); + i2c_smbus_write_byte(chip->client, TSL2563_CMD | TSL2563_CLEARINT); return IRQ_HANDLED; } @@ -647,13 +628,17 @@ static int tsl2563_write_interrupt_config(struct iio_dev *indio_dev, if (ret) goto out; } - ret = tsl2563_write(chip->client, TSL2563_REG_INT, chip->intr); + ret = i2c_smbus_write_byte_data(chip->client, + TSL2563_CMD | TSL2563_REG_INT, + chip->intr); chip->int_enabled = true; } if (!state && (chip->intr & 0x30)) { chip->intr |= ~0x30; - ret = tsl2563_write(chip->client, TSL2563_REG_INT, chip->intr); + ret = i2c_smbus_write_byte_data(chip->client, + TSL2563_CMD | TSL2563_REG_INT, + chip->intr); chip->int_enabled = false; /* now the interrupt is not enabled, we can go to sleep */ schedule_delayed_work(&chip->poweroff_work, 5 * HZ); @@ -668,16 +653,15 @@ static int tsl2563_read_interrupt_config(struct iio_dev *indio_dev, int event_code) { struct tsl2563_chip *chip = iio_priv(indio_dev); - u8 rxbuf; int ret; mutex_lock(&chip->lock); - ret = tsl2563_read(chip->client, TSL2563_REG_INT, - &rxbuf, sizeof(rxbuf)); + ret = i2c_smbus_read_byte_data(chip->client, + TSL2563_CMD | TSL2563_REG_INT); mutex_unlock(&chip->lock); if (ret < 0) goto error_ret; - ret = !!(rxbuf & 0x30); + ret = !!(ret & 0x30); error_ret: return ret; @@ -690,6 +674,8 @@ static struct i2c_driver tsl2563_i2c_driver; static const struct iio_info tsl2563_info_no_irq = { .driver_module = THIS_MODULE, + .read_raw = &tsl2563_read_raw, + .write_raw = &tsl2563_write_raw, }; static const struct iio_info tsl2563_info = { @@ -797,7 +783,8 @@ static int tsl2563_remove(struct i2c_client *client) cancel_delayed_work(&chip->poweroff_work); /* Ensure that interrupts are disabled - then flush any bottom halves */ chip->intr |= ~0x30; - tsl2563_write(chip->client, TSL2563_REG_INT, chip->intr); + i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | TSL2563_REG_INT, + chip->intr); flush_scheduled_work(); tsl2563_set_power(chip, 0); if (client->irq) diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 700f96c70273..33919e87e7ce 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -89,7 +89,6 @@ */ struct ak8975_data { struct i2c_client *client; - struct iio_dev *indio_dev; struct attribute_group attrs; struct mutex lock; u8 asa[3]; @@ -221,7 +220,7 @@ static ssize_t show_mode(struct device *dev, struct device_attribute *devattr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ak8975_data *data = indio_dev->dev_data; + struct ak8975_data *data = iio_priv(indio_dev); return sprintf(buf, "%lu\n", data->mode); } @@ -234,7 +233,7 @@ static ssize_t store_mode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ak8975_data *data = indio_dev->dev_data; + struct ak8975_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; unsigned long oval; int ret; @@ -310,7 +309,7 @@ static ssize_t show_scale(struct device *dev, struct device_attribute *devattr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ak8975_data *data = indio_dev->dev_data; + struct ak8975_data *data = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(devattr); return sprintf(buf, "%ld\n", data->raw_to_gauss[this_attr->address]); @@ -376,7 +375,7 @@ static ssize_t show_raw(struct device *dev, struct device_attribute *devattr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ak8975_data *data = indio_dev->dev_data; + struct ak8975_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; struct iio_dev_attr *this_attr = to_iio_dev_attr(devattr); u16 meas_reg; @@ -483,46 +482,41 @@ static int ak8975_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ak8975_data *data; + struct iio_dev *indio_dev; + int eoc_gpio; int err; - /* Allocate our device context. */ - data = kzalloc(sizeof(struct ak8975_data), GFP_KERNEL); - if (!data) { - dev_err(&client->dev, "Memory allocation fails\n"); - err = -ENOMEM; - goto exit; - } - - i2c_set_clientdata(client, data); - data->client = client; - - mutex_init(&data->lock); - /* Grab and set up the supplied GPIO. */ - data->eoc_irq = client->irq; - data->eoc_gpio = irq_to_gpio(client->irq); + eoc_gpio = irq_to_gpio(client->irq); /* We may not have a GPIO based IRQ to scan, that is fine, we will poll if so */ - if (data->eoc_gpio > 0) { - err = gpio_request(data->eoc_gpio, "ak_8975"); + if (eoc_gpio > 0) { + err = gpio_request(eoc_gpio, "ak_8975"); if (err < 0) { dev_err(&client->dev, "failed to request GPIO %d, error %d\n", - data->eoc_gpio, err); - goto exit_free; + eoc_gpio, err); + goto exit; } - err = gpio_direction_input(data->eoc_gpio); + err = gpio_direction_input(eoc_gpio); if (err < 0) { dev_err(&client->dev, "Failed to configure input direction for GPIO %d, error %d\n", - data->eoc_gpio, err); + eoc_gpio, err); goto exit_gpio; } } else - data->eoc_gpio = 0; /* No GPIO available */ + eoc_gpio = 0; /* No GPIO available */ + /* Register with IIO */ + indio_dev = iio_allocate_device(sizeof(*data)); + if (indio_dev == NULL) { + err = -ENOMEM; + goto exit_gpio; + } + data = iio_priv(indio_dev); /* Perform some basic start-of-day setup of the device. */ err = ak8975_setup(client); if (err < 0) { @@ -530,46 +524,41 @@ static int ak8975_probe(struct i2c_client *client, goto exit_gpio; } - /* Register with IIO */ - data->indio_dev = iio_allocate_device(0); - if (data->indio_dev == NULL) { - err = -ENOMEM; - goto exit_gpio; - } + i2c_set_clientdata(client, indio_dev); + data->client = client; + mutex_init(&data->lock); + data->eoc_irq = client->irq; + data->eoc_gpio = eoc_gpio; + indio_dev->dev.parent = &client->dev; + indio_dev->info = &ak8975_info; + indio_dev->modes = INDIO_DIRECT_MODE; - data->indio_dev->dev.parent = &client->dev; - data->indio_dev->info = &ak8975_info; - data->indio_dev->dev_data = (void *)(data); - data->indio_dev->modes = INDIO_DIRECT_MODE; - - err = iio_device_register(data->indio_dev); + err = iio_device_register(indio_dev); if (err < 0) goto exit_free_iio; return 0; exit_free_iio: - iio_free_device(data->indio_dev); + iio_free_device(indio_dev); exit_gpio: - if (data->eoc_gpio) - gpio_free(data->eoc_gpio); -exit_free: - kfree(data); + if (eoc_gpio) + gpio_free(eoc_gpio); exit: return err; } static int ak8975_remove(struct i2c_client *client) { - struct ak8975_data *data = i2c_get_clientdata(client); + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct ak8975_data *data = iio_priv(indio_dev); + int eoc_gpio = data->eoc_gpio; - iio_device_unregister(data->indio_dev); - iio_free_device(data->indio_dev); + iio_device_unregister(indio_dev); + iio_free_device(indio_dev); - if (data->eoc_gpio) - gpio_free(data->eoc_gpio); - - kfree(data); + if (eoc_gpio) + gpio_free(eoc_gpio); return 0; } diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index dd9a3bb6aa01..b44c273a91a8 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -131,7 +131,6 @@ static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS, /* Each client has this additional data */ struct hmc5843_data { - struct iio_dev *indio_dev; struct mutex lock; u8 rate; u8 meas_conf; @@ -159,7 +158,7 @@ static ssize_t hmc5843_read_measurement(struct device *dev, struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); s16 coordinate_val; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct hmc5843_data *data = indio_dev->dev_data; + struct hmc5843_data *data = iio_priv(indio_dev); s32 result; mutex_lock(&data->lock); @@ -202,7 +201,7 @@ static ssize_t hmc5843_show_operating_mode(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct hmc5843_data *data = indio_dev->dev_data; + struct hmc5843_data *data = iio_priv(indio_dev); return sprintf(buf, "%d\n", data->operating_mode); } @@ -213,7 +212,7 @@ static ssize_t hmc5843_set_operating_mode(struct device *dev, { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); - struct hmc5843_data *data = indio_dev->dev_data; + struct hmc5843_data *data = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); unsigned long operating_mode = 0; s32 status; @@ -278,7 +277,7 @@ static ssize_t hmc5843_show_measurement_configuration(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct hmc5843_data *data = indio_dev->dev_data; + struct hmc5843_data *data = iio_priv(indio_dev); return sprintf(buf, "%d\n", data->meas_conf); } @@ -350,7 +349,7 @@ static ssize_t set_sampling_frequency(struct device *dev, struct iio_dev *indio_dev = dev_get_drvdata(dev); struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); - struct hmc5843_data *data = indio_dev->dev_data; + struct hmc5843_data *data = iio_priv(indio_dev); unsigned long rate = 0; if (strncmp(buf, "0.5" , 3) == 0) @@ -422,7 +421,7 @@ static ssize_t show_range(struct device *dev, { u8 range; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct hmc5843_data *data = indio_dev->dev_data; + struct hmc5843_data *data = iio_priv(indio_dev); range = data->range; return sprintf(buf, "%d\n", regval_to_input_field_mg[range]); @@ -436,7 +435,7 @@ static ssize_t set_range(struct device *dev, struct iio_dev *indio_dev = dev_get_drvdata(dev); struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct hmc5843_data *data = indio_dev->dev_data; + struct hmc5843_data *data = iio_priv(indio_dev); unsigned long range = 0; int error; mutex_lock(&data->lock); @@ -473,7 +472,7 @@ static ssize_t show_scale(struct device *dev, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct hmc5843_data *data = indio_dev->dev_data; + struct hmc5843_data *data = iio_priv(indio_dev); return strlen(strcpy(buf, regval_to_scale[data->range])); } static IIO_DEVICE_ATTR(magn_scale, @@ -538,53 +537,46 @@ static int hmc5843_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct hmc5843_data *data; + struct iio_dev *indio_dev; int err = 0; - data = kzalloc(sizeof(struct hmc5843_data), GFP_KERNEL); - if (!data) { + indio_dev = iio_allocate_device(sizeof(*data)); + if (indio_dev == NULL) { err = -ENOMEM; goto exit; } - + data = iio_priv(indio_dev); /* default settings at probe */ data->meas_conf = CONF_NORMAL; data->range = RANGE_1_0; data->operating_mode = MODE_CONVERSION_CONTINUOUS; - i2c_set_clientdata(client, data); + i2c_set_clientdata(client, indio_dev); /* Initialize the HMC5843 chip */ hmc5843_init_client(client); - data->indio_dev = iio_allocate_device(0); - if (!data->indio_dev) { - err = -ENOMEM; - goto exit_free1; - } - data->indio_dev->info = &hmc5843_info; - data->indio_dev->dev.parent = &client->dev; - data->indio_dev->dev_data = (void *)(data); - data->indio_dev->modes = INDIO_DIRECT_MODE; - err = iio_device_register(data->indio_dev); + indio_dev->info = &hmc5843_info; + indio_dev->dev.parent = &client->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + err = iio_device_register(indio_dev); if (err) goto exit_free2; return 0; exit_free2: - iio_free_device(data->indio_dev); -exit_free1: - kfree(data); + iio_free_device(indio_dev); exit: return err; } static int hmc5843_remove(struct i2c_client *client) { - struct hmc5843_data *data = i2c_get_clientdata(client); + struct iio_dev *indio_dev = i2c_get_clientdata(client); /* sleep mode to save power */ hmc5843_configure(client, MODE_SLEEP); - iio_device_unregister(data->indio_dev); - kfree(i2c_get_clientdata(client)); + iio_device_unregister(indio_dev); + return 0; } diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index 6c9c23fc4aed..4d1bd42ff9e0 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -29,7 +29,7 @@ static int ade7753_spi_write_reg_8(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7753_state *st = iio_dev_get_devdata(indio_dev); + struct ade7753_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADE7753_WRITE_REG(reg_address); @@ -47,7 +47,7 @@ static int ade7753_spi_write_reg_16(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7753_state *st = iio_dev_get_devdata(indio_dev); + struct ade7753_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADE7753_WRITE_REG(reg_address); @@ -64,7 +64,7 @@ static int ade7753_spi_read_reg_8(struct device *dev, u8 *val) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7753_state *st = iio_dev_get_devdata(indio_dev); + struct ade7753_state *st = iio_priv(indio_dev); ssize_t ret; ret = spi_w8r8(st->us, ADE7753_READ_REG(reg_address)); @@ -83,7 +83,7 @@ static int ade7753_spi_read_reg_16(struct device *dev, u16 *val) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7753_state *st = iio_dev_get_devdata(indio_dev); + struct ade7753_state *st = iio_priv(indio_dev); ssize_t ret; ret = spi_w8r16(st->us, ADE7753_READ_REG(reg_address)); @@ -105,7 +105,7 @@ static int ade7753_spi_read_reg_24(struct device *dev, { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7753_state *st = iio_dev_get_devdata(indio_dev); + struct ade7753_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -369,10 +369,11 @@ static int ade7753_stop_device(struct device *dev) return ade7753_spi_write_reg_16(dev, ADE7753_MODE, val); } -static int ade7753_initial_setup(struct ade7753_state *st) +static int ade7753_initial_setup(struct iio_dev *indio_dev) { int ret; - struct device *dev = &st->indio_dev->dev; + struct device *dev = &indio_dev->dev; + struct ade7753_state *st = iio_priv(indio_dev); /* use low spi speed for init */ st->us->mode = SPI_MODE_3; @@ -397,9 +398,9 @@ static ssize_t ade7753_read_frequency(struct device *dev, char *buf) { int ret, len = 0; - u8 t; + u16 t; int sps; - ret = ade7753_spi_read_reg_8(dev, ADE7753_MODE, &t); + ret = ade7753_spi_read_reg_16(dev, ADE7753_MODE, &t); if (ret) return ret; @@ -416,7 +417,7 @@ static ssize_t ade7753_write_frequency(struct device *dev, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7753_state *st = iio_dev_get_devdata(indio_dev); + struct ade7753_state *st = iio_priv(indio_dev); unsigned long val; int ret; u16 reg, t; @@ -512,62 +513,44 @@ static const struct iio_info ade7753_info = { static int __devinit ade7753_probe(struct spi_device *spi) { int ret, regdone = 0; - struct ade7753_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; + struct ade7753_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; goto error_ret; } /* this is only used for removal purposes */ - spi_set_drvdata(spi, st); + spi_set_drvdata(spi, indio_dev); - /* Allocate the comms buffers */ - st->rx = kzalloc(sizeof(*st->rx)*ADE7753_MAX_RX, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kzalloc(sizeof(*st->tx)*ADE7753_MAX_TX, GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_free_rx; - } + st = iio_priv(indio_dev); st->us = spi; mutex_init(&st->buf_lock); - /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } - st->indio_dev->name = spi->dev.driver->name; - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &ade7753_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = spi->dev.driver->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &ade7753_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; regdone = 1; /* Get the device into a sane initial state */ - ret = ade7753_initial_setup(st); + ret = ade7753_initial_setup(indio_dev); if (ret) goto error_free_dev; return 0; error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(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); + iio_free_device(indio_dev); + error_ret: return ret; } @@ -576,19 +559,13 @@ static int __devinit ade7753_probe(struct spi_device *spi) static int ade7753_remove(struct spi_device *spi) { int ret; - struct ade7753_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = spi_get_drvdata(spi); ret = ade7753_stop_device(&(indio_dev->dev)); if (ret) goto err_ret; iio_device_unregister(indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); - - return 0; err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7753.h b/drivers/staging/iio/meter/ade7753.h index 3b9c7f6a50e7..3f059d3d9392 100644 --- a/drivers/staging/iio/meter/ade7753.h +++ b/drivers/staging/iio/meter/ade7753.h @@ -60,17 +60,15 @@ /** * struct ade7753_state - device instance specific data * @us: actual spi_device - * @indio_dev: industrial I/O device structure * @tx: transmit buffer * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct ade7753_state { - struct spi_device *us; - struct iio_dev *indio_dev; - u8 *tx; - u8 *rx; - struct mutex buf_lock; + struct spi_device *us; + struct mutex buf_lock; + u8 tx[ADE7753_MAX_TX] ____cacheline_aligned; + u8 rx[ADE7753_MAX_RX]; }; #endif diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 378f2c87086f..f4f85fd5619b 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -29,7 +29,7 @@ static int ade7754_spi_write_reg_8(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7754_state *st = iio_dev_get_devdata(indio_dev); + struct ade7754_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADE7754_WRITE_REG(reg_address); @@ -47,7 +47,7 @@ static int ade7754_spi_write_reg_16(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7754_state *st = iio_dev_get_devdata(indio_dev); + struct ade7754_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADE7754_WRITE_REG(reg_address); @@ -64,7 +64,7 @@ static int ade7754_spi_read_reg_8(struct device *dev, u8 *val) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7754_state *st = iio_dev_get_devdata(indio_dev); + struct ade7754_state *st = iio_priv(indio_dev); int ret; ret = spi_w8r8(st->us, ADE7754_READ_REG(reg_address)); @@ -83,7 +83,7 @@ static int ade7754_spi_read_reg_16(struct device *dev, u16 *val) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7754_state *st = iio_dev_get_devdata(indio_dev); + struct ade7754_state *st = iio_priv(indio_dev); int ret; ret = spi_w8r16(st->us, ADE7754_READ_REG(reg_address)); @@ -105,7 +105,7 @@ static int ade7754_spi_read_reg_24(struct device *dev, { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7754_state *st = iio_dev_get_devdata(indio_dev); + struct ade7754_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -388,10 +388,11 @@ static int ade7754_stop_device(struct device *dev) return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); } -static int ade7754_initial_setup(struct ade7754_state *st) +static int ade7754_initial_setup(struct iio_dev *indio_dev) { int ret; - struct device *dev = &st->indio_dev->dev; + struct ade7754_state *st = iio_priv(indio_dev); + struct device *dev = &indio_dev->dev; /* use low spi speed for init */ st->us->mode = SPI_MODE_3; @@ -436,7 +437,7 @@ static ssize_t ade7754_write_frequency(struct device *dev, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7754_state *st = iio_dev_get_devdata(indio_dev); + struct ade7754_state *st = iio_priv(indio_dev); unsigned long val; int ret; u8 reg, t; @@ -535,62 +536,44 @@ static const struct iio_info ade7754_info = { static int __devinit ade7754_probe(struct spi_device *spi) { int ret, regdone = 0; - struct ade7754_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; + struct ade7754_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; goto error_ret; } /* this is only used for removal purposes */ - spi_set_drvdata(spi, st); + spi_set_drvdata(spi, indio_dev); - /* Allocate the comms buffers */ - st->rx = kzalloc(sizeof(*st->rx)*ADE7754_MAX_RX, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kzalloc(sizeof(*st->tx)*ADE7754_MAX_TX, GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_free_rx; - } + st = iio_priv(indio_dev); st->us = spi; mutex_init(&st->buf_lock); - /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } - st->indio_dev->name = spi->dev.driver->name; - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->info = &ade7754_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = spi->dev.driver->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &ade7754_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; regdone = 1; /* Get the device into a sane initial state */ - ret = ade7754_initial_setup(st); + ret = ade7754_initial_setup(indio_dev); if (ret) goto error_free_dev; return 0; error_free_dev: if (regdone) - iio_device_unregister(st->indio_dev); + iio_device_unregister(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); + iio_free_device(indio_dev); + error_ret: return ret; } @@ -599,22 +582,17 @@ static int __devinit ade7754_probe(struct spi_device *spi) static int ade7754_remove(struct spi_device *spi) { int ret; - struct ade7754_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = spi_get_drvdata(spi); ret = ade7754_stop_device(&(indio_dev->dev)); if (ret) goto err_ret; iio_device_unregister(indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); - - return 0; err_ret: return ret; + } static struct spi_driver ade7754_driver = { diff --git a/drivers/staging/iio/meter/ade7754.h b/drivers/staging/iio/meter/ade7754.h index 0aa0522a33a3..6121125520f6 100644 --- a/drivers/staging/iio/meter/ade7754.h +++ b/drivers/staging/iio/meter/ade7754.h @@ -78,17 +78,15 @@ /** * struct ade7754_state - device instance specific data * @us: actual spi_device - * @indio_dev: industrial I/O device structure + * @buf_lock: mutex to protect tx and rx * @tx: transmit buffer * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx **/ struct ade7754_state { - struct spi_device *us; - struct iio_dev *indio_dev; - u8 *tx; - u8 *rx; - struct mutex buf_lock; + struct spi_device *us; + struct mutex buf_lock; + u8 tx[ADE7754_MAX_TX] ____cacheline_aligned; + u8 rx[ADE7754_MAX_RX]; }; #endif diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index 730f6d9074a6..a51a64cad034 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -29,7 +29,7 @@ static int ade7759_spi_write_reg_8(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7759_state *st = iio_dev_get_devdata(indio_dev); + struct ade7759_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADE7759_WRITE_REG(reg_address); @@ -47,7 +47,7 @@ static int ade7759_spi_write_reg_16(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7759_state *st = iio_dev_get_devdata(indio_dev); + struct ade7759_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = ADE7759_WRITE_REG(reg_address); @@ -64,7 +64,7 @@ static int ade7759_spi_read_reg_8(struct device *dev, u8 *val) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7759_state *st = iio_dev_get_devdata(indio_dev); + struct ade7759_state *st = iio_priv(indio_dev); int ret; ret = spi_w8r8(st->us, ADE7759_READ_REG(reg_address)); @@ -83,7 +83,7 @@ static int ade7759_spi_read_reg_16(struct device *dev, u16 *val) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7759_state *st = iio_dev_get_devdata(indio_dev); + struct ade7759_state *st = iio_priv(indio_dev); int ret; ret = spi_w8r16(st->us, ADE7759_READ_REG(reg_address)); @@ -105,7 +105,7 @@ static int ade7759_spi_read_reg_40(struct device *dev, { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7759_state *st = iio_dev_get_devdata(indio_dev); + struct ade7759_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -328,10 +328,11 @@ static int ade7759_stop_device(struct device *dev) return ade7759_spi_write_reg_16(dev, ADE7759_MODE, val); } -static int ade7759_initial_setup(struct ade7759_state *st) +static int ade7759_initial_setup(struct iio_dev *indio_dev) { int ret; - struct device *dev = &st->indio_dev->dev; + struct ade7759_state *st = iio_priv(indio_dev); + struct device *dev = &indio_dev->dev; /* use low spi speed for init */ st->us->mode = SPI_MODE_3; @@ -376,7 +377,7 @@ static ssize_t ade7759_write_frequency(struct device *dev, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7759_state *st = iio_dev_get_devdata(indio_dev); + struct ade7759_state *st = iio_priv(indio_dev); unsigned long val; int ret; u16 reg, t; @@ -458,62 +459,41 @@ static const struct iio_info ade7759_info = { static int __devinit ade7759_probe(struct spi_device *spi) { int ret; - struct ade7759_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; + struct ade7759_state *st; + struct iio_dev *indio_dev; + + /* setup the industrialio driver allocated elements */ + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { + ret = -ENOMEM; goto error_ret; } /* this is only used for removal purposes */ - spi_set_drvdata(spi, st); + spi_set_drvdata(spi, indio_dev); - /* Allocate the comms buffers */ - st->rx = kzalloc(sizeof(*st->rx)*ADE7759_MAX_RX, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kzalloc(sizeof(*st->tx)*ADE7759_MAX_TX, GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_free_rx; - } + st = iio_priv(indio_dev); st->us = spi; mutex_init(&st->buf_lock); - /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } + indio_dev->name = spi->dev.driver->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &ade7759_info; + indio_dev->modes = INDIO_DIRECT_MODE; - st->indio_dev->name = spi->dev.driver->name; - st->indio_dev->dev.parent = &spi->dev; - - st->indio_dev->info = &ade7759_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; /* Get the device into a sane initial state */ - ret = ade7759_initial_setup(st); + ret = ade7759_initial_setup(indio_dev); if (ret) goto error_unreg_dev; return 0; error_unreg_dev: - iio_device_unregister(st->indio_dev); + iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(st->indio_dev); -error_free_tx: - kfree(st->tx); -error_free_rx: - kfree(st->rx); -error_free_st: - kfree(st); + iio_free_device(indio_dev); error_ret: return ret; } @@ -522,19 +502,13 @@ static int __devinit ade7759_probe(struct spi_device *spi) static int ade7759_remove(struct spi_device *spi) { int ret; - struct ade7759_state *st = spi_get_drvdata(spi); - struct iio_dev *indio_dev = st->indio_dev; + struct iio_dev *indio_dev = spi_get_drvdata(spi); ret = ade7759_stop_device(&(indio_dev->dev)); if (ret) goto err_ret; iio_device_unregister(indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); - - return 0; err_ret: return ret; diff --git a/drivers/staging/iio/meter/ade7759.h b/drivers/staging/iio/meter/ade7759.h index cc76c2c4c039..c81d23d730d2 100644 --- a/drivers/staging/iio/meter/ade7759.h +++ b/drivers/staging/iio/meter/ade7759.h @@ -41,17 +41,15 @@ /** * struct ade7759_state - device instance specific data * @us: actual spi_device - * @indio_dev: industrial I/O device structure + * @buf_lock: mutex to protect tx and rx * @tx: transmit buffer * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx **/ struct ade7759_state { - struct spi_device *us; - struct iio_dev *indio_dev; - u8 *tx; - u8 *rx; - struct mutex buf_lock; + struct spi_device *us; + struct mutex buf_lock; + u8 tx[ADE7759_MAX_TX] ____cacheline_aligned; + u8 rx[ADE7759_MAX_RX]; }; #endif diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c index 4578e7b7f460..dd7234353405 100644 --- a/drivers/staging/iio/meter/ade7854-i2c.c +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -20,7 +20,7 @@ static int ade7854_i2c_write_reg_8(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = (reg_address >> 8) & 0xFF; @@ -39,7 +39,7 @@ static int ade7854_i2c_write_reg_16(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = (reg_address >> 8) & 0xFF; @@ -59,7 +59,7 @@ static int ade7854_i2c_write_reg_24(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = (reg_address >> 8) & 0xFF; @@ -80,7 +80,7 @@ static int ade7854_i2c_write_reg_32(struct device *dev, { int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); st->tx[0] = (reg_address >> 8) & 0xFF; @@ -101,7 +101,7 @@ static int ade7854_i2c_read_reg_8(struct device *dev, u8 *val) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; mutex_lock(&st->buf_lock); @@ -127,7 +127,7 @@ static int ade7854_i2c_read_reg_16(struct device *dev, u16 *val) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; mutex_lock(&st->buf_lock); @@ -153,7 +153,7 @@ static int ade7854_i2c_read_reg_24(struct device *dev, u32 *val) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; mutex_lock(&st->buf_lock); @@ -179,7 +179,7 @@ static int ade7854_i2c_read_reg_32(struct device *dev, u32 *val) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; mutex_lock(&st->buf_lock); @@ -204,13 +204,14 @@ static int __devinit ade7854_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret; - struct ade7854_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; - return ret; - } + struct ade7854_state *st; + struct iio_dev *indio_dev; - i2c_set_clientdata(client, st); + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + st = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); st->read_reg_8 = ade7854_i2c_read_reg_8; st->read_reg_16 = ade7854_i2c_read_reg_16; st->read_reg_24 = ade7854_i2c_read_reg_24; @@ -222,11 +223,9 @@ static int __devinit ade7854_i2c_probe(struct i2c_client *client, st->i2c = client; st->irq = client->irq; - ret = ade7854_probe(st, &client->dev); - if (ret) { - kfree(st); - return ret; - } + ret = ade7854_probe(indio_dev, &client->dev); + if (ret) + iio_free_device(indio_dev); return ret; } diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c index 84da8fbde022..e0d10865590a 100644 --- a/drivers/staging/iio/meter/ade7854-spi.c +++ b/drivers/staging/iio/meter/ade7854-spi.c @@ -21,7 +21,7 @@ static int ade7854_spi_write_reg_8(struct device *dev, int ret; struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); struct spi_transfer xfer = { .tx_buf = st->tx, .bits_per_word = 8, @@ -49,7 +49,7 @@ static int ade7854_spi_write_reg_16(struct device *dev, int ret; struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); struct spi_transfer xfer = { .tx_buf = st->tx, .bits_per_word = 8, @@ -78,7 +78,7 @@ static int ade7854_spi_write_reg_24(struct device *dev, int ret; struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); struct spi_transfer xfer = { .tx_buf = st->tx, .bits_per_word = 8, @@ -108,7 +108,7 @@ static int ade7854_spi_write_reg_32(struct device *dev, int ret; struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); struct spi_transfer xfer = { .tx_buf = st->tx, .bits_per_word = 8, @@ -138,7 +138,7 @@ static int ade7854_spi_read_reg_8(struct device *dev, { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -180,7 +180,7 @@ static int ade7854_spi_read_reg_16(struct device *dev, { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -221,7 +221,7 @@ static int ade7854_spi_read_reg_24(struct device *dev, { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -263,7 +263,7 @@ static int ade7854_spi_read_reg_32(struct device *dev, { struct spi_message msg; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { { @@ -302,13 +302,14 @@ static int ade7854_spi_read_reg_32(struct device *dev, static int __devinit ade7854_spi_probe(struct spi_device *spi) { int ret; - struct ade7854_state *st = kzalloc(sizeof *st, GFP_KERNEL); - if (!st) { - ret = -ENOMEM; - return ret; - } + struct ade7854_state *st; + struct iio_dev *indio_dev; - spi_set_drvdata(spi, st); + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + st = iio_priv(indio_dev); + spi_set_drvdata(spi, indio_dev); st->read_reg_8 = ade7854_spi_read_reg_8; st->read_reg_16 = ade7854_spi_read_reg_16; st->read_reg_24 = ade7854_spi_read_reg_24; @@ -320,11 +321,10 @@ static int __devinit ade7854_spi_probe(struct spi_device *spi) st->irq = spi->irq; st->spi = spi; - ret = ade7854_probe(st, &spi->dev); - if (ret) { - kfree(st); - return ret; - } + + ret = ade7854_probe(indio_dev, &spi->dev); + if (ret) + iio_free_device(indio_dev); return 0; } diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c index 44cd3ec546ae..b82659f43bc6 100644 --- a/drivers/staging/iio/meter/ade7854.c +++ b/drivers/staging/iio/meter/ade7854.c @@ -29,7 +29,7 @@ static ssize_t ade7854_read_8bit(struct device *dev, int ret; u8 val = 0; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = st->read_reg_8(dev, this_attr->address, &val); @@ -46,7 +46,7 @@ static ssize_t ade7854_read_16bit(struct device *dev, int ret; u16 val = 0; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = st->read_reg_16(dev, this_attr->address, &val); @@ -63,7 +63,7 @@ static ssize_t ade7854_read_24bit(struct device *dev, int ret; u32 val; struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); ret = st->read_reg_24(dev, this_attr->address, &val); @@ -81,7 +81,7 @@ static ssize_t ade7854_read_32bit(struct device *dev, u32 val = 0; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); ret = st->read_reg_32(dev, this_attr->address, &val); if (ret) @@ -97,7 +97,7 @@ static ssize_t ade7854_write_8bit(struct device *dev, { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; long val; @@ -118,7 +118,7 @@ static ssize_t ade7854_write_16bit(struct device *dev, { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; long val; @@ -139,7 +139,7 @@ static ssize_t ade7854_write_24bit(struct device *dev, { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; long val; @@ -160,7 +160,7 @@ static ssize_t ade7854_write_32bit(struct device *dev, { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; long val; @@ -177,7 +177,7 @@ static ssize_t ade7854_write_32bit(struct device *dev, static int ade7854_reset(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); u16 val; st->read_reg_16(dev, ADE7854_CONFIG, &val); @@ -426,7 +426,7 @@ static IIO_DEV_ATTR_CVAHR(ade7854_read_32bit, static int ade7854_set_irq(struct device *dev, bool enable) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct ade7854_state *st = iio_priv(indio_dev); int ret; u32 irqen; @@ -449,10 +449,10 @@ static int ade7854_set_irq(struct device *dev, bool enable) return ret; } -static int ade7854_initial_setup(struct ade7854_state *st) +static int ade7854_initial_setup(struct iio_dev *indio_dev) { int ret; - struct device *dev = &st->indio_dev->dev; + struct device *dev = &indio_dev->dev; /* Disable IRQ */ ret = ade7854_set_irq(dev, false); @@ -556,68 +556,40 @@ static const struct iio_info ade7854_info = { .driver_module = THIS_MODULE, }; -int ade7854_probe(struct ade7854_state *st, struct device *dev) +int ade7854_probe(struct iio_dev *indio_dev, struct device *dev) { int ret; - - /* Allocate the comms buffers */ - st->rx = kzalloc(sizeof(*st->rx)*ADE7854_MAX_RX, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->tx = kzalloc(sizeof(*st->tx)*ADE7854_MAX_TX, GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_free_rx; - } - mutex_init(&st->buf_lock); + struct ade7854_state *st = iio_priv(indio_dev); /* setup the industrialio driver allocated elements */ - st->indio_dev = iio_allocate_device(0); - if (st->indio_dev == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } + mutex_init(&st->buf_lock); - st->indio_dev->dev.parent = dev; - st->indio_dev->info = &ade7854_info; - st->indio_dev->dev_data = (void *)(st); - st->indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->dev.parent = dev; + indio_dev->info = &ade7854_info; + indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(st->indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; /* Get the device into a sane initial state */ - ret = ade7854_initial_setup(st); + ret = ade7854_initial_setup(indio_dev); if (ret) goto error_unreg_dev; return 0; error_unreg_dev: - iio_device_unregister(st->indio_dev); + iio_device_unregister(indio_dev); error_free_dev: - iio_free_device(st->indio_dev); -error_free_tx: - kfree(st->tx); -error_free_rx: - kfree(st->rx); -error_free_st: - kfree(st); - + iio_free_device(indio_dev); +error_ret: return ret; } EXPORT_SYMBOL(ade7854_probe); -int ade7854_remove(struct ade7854_state *st) +int ade7854_remove(struct iio_dev *indio_dev) { - struct iio_dev *indio_dev = st->indio_dev; - iio_device_unregister(indio_dev); - kfree(st->tx); - kfree(st->rx); - kfree(st); return 0; } diff --git a/drivers/staging/iio/meter/ade7854.h b/drivers/staging/iio/meter/ade7854.h index 79a21109f4e2..2c96e8695d57 100644 --- a/drivers/staging/iio/meter/ade7854.h +++ b/drivers/staging/iio/meter/ade7854.h @@ -148,29 +148,29 @@ * struct ade7854_state - device instance specific data * @spi: actual spi_device * @indio_dev: industrial I/O device structure + * @buf_lock: mutex to protect tx and rx * @tx: transmit buffer * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx **/ struct ade7854_state { - struct spi_device *spi; - struct i2c_client *i2c; - struct iio_dev *indio_dev; - u8 *tx; - u8 *rx; - int (*read_reg_8) (struct device *, u16, u8 *); - int (*read_reg_16) (struct device *, u16, u16 *); - int (*read_reg_24) (struct device *, u16, u32 *); - int (*read_reg_32) (struct device *, u16, u32 *); - int (*write_reg_8) (struct device *, u16, u8); - int (*write_reg_16) (struct device *, u16, u16); - int (*write_reg_24) (struct device *, u16, u32); - int (*write_reg_32) (struct device *, u16, u32); - int irq; - struct mutex buf_lock; + struct spi_device *spi; + struct i2c_client *i2c; + int (*read_reg_8) (struct device *, u16, u8 *); + int (*read_reg_16) (struct device *, u16, u16 *); + int (*read_reg_24) (struct device *, u16, u32 *); + int (*read_reg_32) (struct device *, u16, u32 *); + int (*write_reg_8) (struct device *, u16, u8); + int (*write_reg_16) (struct device *, u16, u16); + int (*write_reg_24) (struct device *, u16, u32); + int (*write_reg_32) (struct device *, u16, u32); + int irq; + struct mutex buf_lock; + u8 tx[ADE7854_MAX_TX] ____cacheline_aligned; + u8 rx[ADE7854_MAX_RX]; + }; -extern int ade7854_probe(struct ade7854_state *st, struct device *dev); -extern int ade7854_remove(struct ade7854_state *st); +extern int ade7854_probe(struct iio_dev *indio_dev, struct device *dev); +extern int ade7854_remove(struct iio_dev *indio_dev); #endif diff --git a/drivers/staging/iio/resolver/Kconfig b/drivers/staging/iio/resolver/Kconfig index a4a363429355..6ecd79e30038 100644 --- a/drivers/staging/iio/resolver/Kconfig +++ b/drivers/staging/iio/resolver/Kconfig @@ -25,30 +25,3 @@ config AD2S1210 Say yes here to build support for Analog Devices spi resolver to digital converters, ad2s1210, provides direct access via sysfs. -choice - prompt "Resolution Control" - depends on AD2S1210 - default AD2S1210_GPIO_NONE - help - In normal mode, the resolution of the digital output is selected - using the RES0 and RES1 input pins. In configuration mode, the - resolution is selected by setting the RES0 and RES1 bits in the - control regsiter. When switching between normal mode and configuration - mode, there are some schemes to keep them matchs. - -config AD2S1210_GPIO_INPUT - bool "read resolution from gpio pins" - help - GPIO pins are sampling RES0 and RES1 pins, read the resolution - settings from the GPIO pins. - -config AD2S1210_GPIO_OUTPUT - bool "set gpio pins to set resolution" - help - RES0 and RES1 pins are controlled by GPIOs, setting GPIO pins to - set the resolution. - -config AD2S1210_GPIO_NONE - bool "take the responsibility by user" - -endchoice diff --git a/drivers/staging/iio/resolver/ad2s120x.c b/drivers/staging/iio/resolver/ad2s120x.c index f83e1422fd29..bed4c725f2df 100644 --- a/drivers/staging/iio/resolver/ad2s120x.c +++ b/drivers/staging/iio/resolver/ad2s120x.c @@ -32,109 +32,41 @@ struct ad2s120x_state { struct mutex lock; - struct iio_dev *idev; struct spi_device *sdev; - unsigned short sample; - unsigned short rdvel; - u8 rx[2]; - u8 tx[2]; + int sample; + int rdvel; + u8 rx[2] ____cacheline_aligned; }; -static ssize_t ad2s120x_show_pos_vel(struct device *dev, +static ssize_t ad2s120x_show_val(struct device *dev, struct device_attribute *attr, char *buf) { - struct spi_message msg; - struct spi_transfer xfer; int ret = 0; ssize_t len = 0; u16 pos; s16 vel; u8 status; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s120x_state *st = idev->dev_data; + struct ad2s120x_state *st = iio_priv(dev_get_drvdata(dev)); + struct iio_dev_attr *iattr = to_iio_dev_attr(attr); - xfer.len = 1; - xfer.tx_buf = st->tx; - xfer.rx_buf = st->rx; mutex_lock(&st->lock); gpio_set_value(st->sample, 0); /* delay (6 * AD2S120X_TSCLK + 20) nano seconds */ udelay(1); gpio_set_value(st->sample, 1); - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) + gpio_set_value(st->rdvel, iattr->address); + ret = spi_read(st->sdev, st->rx, 2); + if (ret < 0) goto error_ret; status = st->rx[1]; - pos = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); - len = sprintf(buf, "%d %c%c%c%c ", pos, - (status & 0x8) ? 'P' : 'V', - (status & 0x4) ? 'd' : '_', - (status & 0x2) ? 'l' : '_', - (status & 0x1) ? '1' : '0'); - - /* delay 18 ns */ - /* ndelay(18); */ - - gpio_set_value(st->rdvel, 0); - /* ndelay(5);*/ - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - status = st->rx[1]; - vel = (st->rx[0] & 0x80) ? 0xf000 : 0; - vel |= (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); - len += sprintf(buf + len, "%d %c%c%c%c\n", vel, - (status & 0x8) ? 'P' : 'V', - (status & 0x4) ? 'd' : '_', - (status & 0x2) ? 'l' : '_', - (status & 0x1) ? '1' : '0'); -error_ret: - gpio_set_value(st->rdvel, 1); - /* delay (2 * AD2S120X_TSCLK + 20) ns for sample pulse */ - udelay(1); - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static ssize_t ad2s120x_show_pos(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct spi_message msg; - struct spi_transfer xfer; - int ret = 0; - ssize_t len = 0; - u16 pos; - u8 status; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s120x_state *st = idev->dev_data; - - xfer.len = 1; - xfer.tx_buf = st->tx; - xfer.rx_buf = st->rx; - mutex_lock(&st->lock); - - gpio_set_value(st->sample, 0); - /* delay (6 * AD2S120X_TSCLK + 20) nano seconds */ - udelay(1); - gpio_set_value(st->sample, 1); - gpio_set_value(st->rdvel, 1); - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - status = st->rx[1]; - pos = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); - len = sprintf(buf, "%d %c%c%c%c ", pos, + if (iattr->address) + pos = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); + else { + vel = (st->rx[0] & 0x80) ? 0xf000 : 0; + vel |= (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); + } + len = sprintf(buf, "%d %c%c%c%c ", iattr->address ? pos : vel, (status & 0x8) ? 'P' : 'V', (status & 0x4) ? 'd' : '_', (status & 0x2) ? 'l' : '_', @@ -147,62 +79,10 @@ static ssize_t ad2s120x_show_pos(struct device *dev, return ret ? ret : len; } -static ssize_t ad2s120x_show_vel(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct spi_message msg; - struct spi_transfer xfer; - int ret = 0; - ssize_t len = 0; - s16 vel; - u8 status; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s120x_state *st = idev->dev_data; - - xfer.len = 1; - xfer.tx_buf = st->tx; - xfer.rx_buf = st->rx; - mutex_lock(&st->lock); - - gpio_set_value(st->sample, 0); - /* delay (6 * AD2S120X_TSCLK + 20) nano seconds */ - udelay(1); - gpio_set_value(st->sample, 1); - - gpio_set_value(st->rdvel, 0); - /* ndelay(5);*/ - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - status = st->rx[1]; - vel = (st->rx[0] & 0x80) ? 0xf000 : 0; - vel |= (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); - len += sprintf(buf + len, "%d %c%c%c%c\n", vel, - (status & 0x8) ? 'P' : 'V', - (status & 0x4) ? 'd' : '_', - (status & 0x2) ? 'l' : '_', - (status & 0x1) ? '1' : '0'); -error_ret: - gpio_set_value(st->rdvel, 1); - /* delay (2 * AD2S120X_TSCLK + 20) ns for sample pulse */ - udelay(1); - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_CONST_ATTR(description, - "12-Bit R/D Converter with Reference Oscillator"); -static IIO_DEVICE_ATTR(pos_vel, S_IRUGO, ad2s120x_show_pos_vel, NULL, 0); -static IIO_DEVICE_ATTR(pos, S_IRUGO, ad2s120x_show_pos, NULL, 0); -static IIO_DEVICE_ATTR(vel, S_IRUGO, ad2s120x_show_vel, NULL, 0); +static IIO_DEVICE_ATTR(pos, S_IRUGO, ad2s120x_show_val, NULL, 1); +static IIO_DEVICE_ATTR(vel, S_IRUGO, ad2s120x_show_val, NULL, 0); static struct attribute *ad2s120x_attributes[] = { - &iio_const_attr_description.dev_attr.attr, - &iio_dev_attr_pos_vel.dev_attr.attr, &iio_dev_attr_pos.dev_attr.attr, &iio_dev_attr_vel.dev_attr.attr, NULL, @@ -220,42 +100,33 @@ static const struct iio_info ad2s120x_info = { static int __devinit ad2s120x_probe(struct spi_device *spi) { struct ad2s120x_state *st; + struct iio_dev *indio_dev; int pn, ret = 0; unsigned short *pins = spi->dev.platform_data; - for (pn = 0; pn < AD2S120X_PN; pn++) { - if (gpio_request(pins[pn], DRV_NAME)) { + for (pn = 0; pn < AD2S120X_PN; pn++) + if (gpio_request_one(pins[pn], GPIOF_DIR_OUT, DRV_NAME)) { pr_err("%s: request gpio pin %d failed\n", DRV_NAME, pins[pn]); goto error_ret; } - gpio_direction_output(pins[pn], 1); - } - - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; } - spi_set_drvdata(spi, st); - + spi_set_drvdata(spi, indio_dev); + st = iio_priv(indio_dev); mutex_init(&st->lock); st->sdev = spi; st->sample = pins[0]; st->rdvel = pins[1]; - st->idev = iio_allocate_device(0); - if (st->idev == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->idev->dev.parent = &spi->dev; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &ad2s120x_info; + indio_dev->modes = INDIO_DIRECT_MODE; - st->idev->info = &ad2s120x_info; - st->idev->dev_data = (void *)(st); - st->idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(st->idev); + ret = iio_device_register(indio_dev); if (ret) goto error_free_dev; @@ -266,9 +137,7 @@ static int __devinit ad2s120x_probe(struct spi_device *spi) return 0; error_free_dev: - iio_free_device(st->idev); -error_free_st: - kfree(st); + iio_free_device(indio_dev); error_ret: for (--pn; pn >= 0; pn--) gpio_free(pins[pn]); @@ -277,10 +146,7 @@ static int __devinit ad2s120x_probe(struct spi_device *spi) static int __devexit ad2s120x_remove(struct spi_device *spi) { - struct ad2s120x_state *st = spi_get_drvdata(spi); - - iio_device_unregister(st->idev); - kfree(st); + iio_device_unregister(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index 09f4fcfda73a..ecaf7bb790fe 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -19,44 +19,41 @@ #include "../iio.h" #include "../sysfs.h" +#include "ad2s1210.h" #define DRV_NAME "ad2s1210" -#define DEF_CONTROL 0x7E +#define AD2S1210_DEF_CONTROL 0x7E -#define MSB_IS_HIGH 0x80 -#define MSB_IS_LOW 0x7F -#define PHASE_LOCK_RANGE_44 0x20 -#define ENABLE_HYSTERESIS 0x10 -#define SET_ENRES1 0x08 -#define SET_ENRES0 0x04 -#define SET_RES1 0x02 -#define SET_RES0 0x01 +#define AD2S1210_MSB_IS_HIGH 0x80 +#define AD2S1210_MSB_IS_LOW 0x7F +#define AD2S1210_PHASE_LOCK_RANGE_44 0x20 +#define AD2S1210_ENABLE_HYSTERESIS 0x10 +#define AD2S1210_SET_ENRES1 0x08 +#define AD2S1210_SET_ENRES0 0x04 +#define AD2S1210_SET_RES1 0x02 +#define AD2S1210_SET_RES0 0x01 -#define SET_ENRESOLUTION (SET_ENRES1 | SET_ENRES0) -#define SET_RESOLUTION (SET_RES1 | SET_RES0) +#define AD2S1210_SET_ENRESOLUTION (AD2S1210_SET_ENRES1 | \ + AD2S1210_SET_ENRES0) +#define AD2S1210_SET_RESOLUTION (AD2S1210_SET_RES1 | AD2S1210_SET_RES0) -#define REG_POSITION 0x80 -#define REG_VELOCITY 0x82 -#define REG_LOS_THRD 0x88 -#define REG_DOS_OVR_THRD 0x89 -#define REG_DOS_MIS_THRD 0x8A -#define REG_DOS_RST_MAX_THRD 0x8B -#define REG_DOS_RST_MIN_THRD 0x8C -#define REG_LOT_HIGH_THRD 0x8D -#define REG_LOT_LOW_THRD 0x8E -#define REG_EXCIT_FREQ 0x91 -#define REG_CONTROL 0x92 -#define REG_SOFT_RESET 0xF0 -#define REG_FAULT 0xFF +#define AD2S1210_REG_POSITION 0x80 +#define AD2S1210_REG_VELOCITY 0x82 +#define AD2S1210_REG_LOS_THRD 0x88 +#define AD2S1210_REG_DOS_OVR_THRD 0x89 +#define AD2S1210_REG_DOS_MIS_THRD 0x8A +#define AD2S1210_REG_DOS_RST_MAX_THRD 0x8B +#define AD2S1210_REG_DOS_RST_MIN_THRD 0x8C +#define AD2S1210_REG_LOT_HIGH_THRD 0x8D +#define AD2S1210_REG_LOT_LOW_THRD 0x8E +#define AD2S1210_REG_EXCIT_FREQ 0x91 +#define AD2S1210_REG_CONTROL 0x92 +#define AD2S1210_REG_SOFT_RESET 0xF0 +#define AD2S1210_REG_FAULT 0xFF /* pin SAMPLE, A0, A1, RES0, RES1, is controlled by driver */ #define AD2S1210_SAA 3 -#if defined(CONFIG_AD2S1210_GPIO_INPUT) || defined(CONFIG_AD2S1210_GPIO_OUTPUT) -# define AD2S1210_RES 2 -#else -# define AD2S1210_RES 0 -#endif #define AD2S1210_PN (AD2S1210_SAA + AD2S1210_RES) #define AD2S1210_MIN_CLKIN 6144000 @@ -75,190 +72,153 @@ enum ad2s1210_mode { MOD_POS = 0, MOD_VEL, - MOD_RESERVED, MOD_CONFIG, + MOD_RESERVED, }; -enum ad2s1210_res { - RES_10 = 10, - RES_12 = 12, - RES_14 = 14, - RES_16 = 16, -}; - -static unsigned int resolution_value[] = { - RES_10, RES_12, RES_14, RES_16}; +static const unsigned int ad2s1210_resolution_value[] = { 10, 12, 14, 16 }; struct ad2s1210_state { + const struct ad2s1210_platform_data *pdata; struct mutex lock; - struct iio_dev *idev; struct spi_device *sdev; - struct spi_transfer xfer; - unsigned int hysteresis; - unsigned int old_data; - enum ad2s1210_mode mode; - enum ad2s1210_res resolution; unsigned int fclkin; unsigned int fexcit; - unsigned short sample; - unsigned short a0; - unsigned short a1; - unsigned short res0; - unsigned short res1; - u8 rx[3]; - u8 tx[3]; + bool hysteresis; + bool old_data; + u8 resolution; + enum ad2s1210_mode mode; + u8 rx[2] ____cacheline_aligned; + u8 tx[2] ____cacheline_aligned; }; -static inline void start_sample(struct ad2s1210_state *st) +static const int ad2s1210_mode_vals[4][2] = { + [MOD_POS] = { 0, 0 }, + [MOD_VEL] = { 0, 1 }, + [MOD_CONFIG] = { 1, 0 }, +}; +static inline void ad2s1210_set_mode(enum ad2s1210_mode mode, + struct ad2s1210_state *st) { - gpio_set_value(st->sample, 0); -} - -static inline void stop_sample(struct ad2s1210_state *st) -{ - gpio_set_value(st->sample, 1); -} - -static inline void set_mode(enum ad2s1210_mode mode, struct ad2s1210_state *st) -{ - switch (mode) { - case MOD_POS: - gpio_set_value(st->a0, 0); - gpio_set_value(st->a1, 0); - break; - case MOD_VEL: - gpio_set_value(st->a0, 0); - gpio_set_value(st->a1, 1); - break; - case MOD_CONFIG: - gpio_set_value(st->a0, 1); - gpio_set_value(st->a1, 1); - break; - default: - /* set to reserved mode */ - gpio_set_value(st->a0, 1); - gpio_set_value(st->a1, 0); - } + gpio_set_value(st->pdata->a[0], ad2s1210_mode_vals[mode][0]); + gpio_set_value(st->pdata->a[1], ad2s1210_mode_vals[mode][1]); st->mode = mode; } /* write 1 bytes (address or data) to the chip */ -static int config_write(struct ad2s1210_state *st, - unsigned char data) +static int ad2s1210_config_write(struct ad2s1210_state *st, u8 data) { - struct spi_message msg; - int ret = 0; + int ret; - st->xfer.len = 1; - set_mode(MOD_CONFIG, st); - - spi_message_init(&msg); - spi_message_add_tail(&st->xfer, &msg); + ad2s1210_set_mode(MOD_CONFIG, st); st->tx[0] = data; - ret = spi_sync(st->sdev, &msg); - if (ret) + ret = spi_write(st->sdev, st->tx, 1); + if (ret < 0) return ret; - st->old_data = 1; - return ret; + st->old_data = true; + + return 0; } /* read value from one of the registers */ -static int config_read(struct ad2s1210_state *st, - unsigned char address, - unsigned char *data) +static int ad2s1210_config_read(struct ad2s1210_state *st, + unsigned char address) { + struct spi_transfer xfer = { + .len = 2, + .rx_buf = st->rx, + .tx_buf = st->tx, + }; struct spi_message msg; int ret = 0; - st->xfer.len = 2; - set_mode(MOD_CONFIG, st); - + ad2s1210_set_mode(MOD_CONFIG, st); spi_message_init(&msg); - spi_message_add_tail(&st->xfer, &msg); - st->tx[0] = address | MSB_IS_HIGH; - st->tx[1] = REG_FAULT; + spi_message_add_tail(&xfer, &msg); + st->tx[0] = address | AD2S1210_MSB_IS_HIGH; + st->tx[1] = AD2S1210_REG_FAULT; ret = spi_sync(st->sdev, &msg); - if (ret) + if (ret < 0) return ret; - *data = st->rx[1]; - st->old_data = 1; - return ret; + st->old_data = true; + + return st->rx[1]; } -static inline void update_frequency_control_word(struct ad2s1210_state *st) +static inline +int ad2s1210_update_frequency_control_word(struct ad2s1210_state *st) { + int ret; unsigned char fcw; + fcw = (unsigned char)(st->fexcit * (1 << 15) / st->fclkin); - if (fcw >= AD2S1210_MIN_FCW && fcw <= AD2S1210_MAX_FCW) { - config_write(st, REG_EXCIT_FREQ); - config_write(st, fcw); - } else + if (fcw < AD2S1210_MIN_FCW || fcw > AD2S1210_MAX_FCW) { pr_err("ad2s1210: FCW out of range\n"); -} - -#if defined(CONFIG_AD2S1210_GPIO_INPUT) -static inline unsigned char read_resolution_pin(struct ad2s1210_state *st) -{ - unsigned int data; - data = (gpio_get_value(st->res0) << 1) | - gpio_get_value(st->res1); - return resolution_value[data]; -} -#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT) -static inline void set_resolution_pin(struct ad2s1210_state *st) -{ - switch (st->resolution) { - case RES_10: - gpio_set_value(st->res0, 0); - gpio_set_value(st->res1, 0); - break; - case RES_12: - gpio_set_value(st->res0, 0); - gpio_set_value(st->res1, 1); - break; - case RES_14: - gpio_set_value(st->res0, 1); - gpio_set_value(st->res1, 0); - break; - case RES_16: - gpio_set_value(st->res0, 1); - gpio_set_value(st->res1, 1); - break; + return -ERANGE; } -} -#endif -static inline void soft_reset(struct ad2s1210_state *st) + ret = ad2s1210_config_write(st, AD2S1210_REG_EXCIT_FREQ); + if (ret < 0) + return ret; + + return ad2s1210_config_write(st, fcw); +} + +static unsigned char ad2s1210_read_resolution_pin(struct ad2s1210_state *st) { - config_write(st, REG_SOFT_RESET); - config_write(st, 0x0); + return ad2s1210_resolution_value[ + (gpio_get_value(st->pdata->res[0]) << 1) | + gpio_get_value(st->pdata->res[1])]; +} + +static const int ad2s1210_res_pins[4][2] = { + { 0, 0 }, {0, 1}, {1, 0}, {1, 1} +}; + +static inline void ad2s1210_set_resolution_pin(struct ad2s1210_state *st) +{ + gpio_set_value(st->pdata->res[0], + ad2s1210_res_pins[(st->resolution - 10)/2][0]); + gpio_set_value(st->pdata->res[1], + ad2s1210_res_pins[(st->resolution - 10)/2][1]); +} + +static inline int ad2s1210_soft_reset(struct ad2s1210_state *st) +{ + int ret; + + ret = ad2s1210_config_write(st, AD2S1210_REG_SOFT_RESET); + if (ret < 0) + return ret; + + return ad2s1210_config_write(st, 0x0); } /* return the OLD DATA since last spi bus write */ static ssize_t ad2s1210_show_raw(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; - int ret; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + int ret = 0; mutex_lock(&st->lock); if (st->old_data) { ret = sprintf(buf, "0x%x\n", st->rx[0]); - st->old_data = 0; - } else - ret = 0; + st->old_data = false; + } mutex_unlock(&st->lock); + return ret; } static ssize_t ad2s1210_store_raw(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, + size_t len) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); unsigned long udata; unsigned char data; int ret; @@ -266,139 +226,157 @@ static ssize_t ad2s1210_store_raw(struct device *dev, ret = strict_strtoul(buf, 16, &udata); if (ret) return -EINVAL; + data = udata & 0xff; mutex_lock(&st->lock); - config_write(st, data); + ret = ad2s1210_config_write(st, data); mutex_unlock(&st->lock); - return 1; + + return ret < 0 ? ret : len; } static ssize_t ad2s1210_store_softreset(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, + size_t len) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + int ret; + mutex_lock(&st->lock); - soft_reset(st); + ret = ad2s1210_soft_reset(st); mutex_unlock(&st->lock); - return len; + + return ret < 0 ? ret : len; } static ssize_t ad2s1210_show_fclkin(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); return sprintf(buf, "%d\n", st->fclkin); } static ssize_t ad2s1210_store_fclkin(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, + size_t len) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); unsigned long fclkin; int ret; ret = strict_strtoul(buf, 10, &fclkin); - if (!ret && fclkin >= AD2S1210_MIN_CLKIN && - fclkin <= AD2S1210_MAX_CLKIN) { - mutex_lock(&st->lock); - st->fclkin = fclkin; - } else { + if (ret) + return ret; + if (fclkin < AD2S1210_MIN_CLKIN || fclkin > AD2S1210_MAX_CLKIN) { pr_err("ad2s1210: fclkin out of range\n"); return -EINVAL; } - update_frequency_control_word(st); - soft_reset(st); + + mutex_lock(&st->lock); + st->fclkin = fclkin; + + ret = ad2s1210_update_frequency_control_word(st); + if (ret < 0) + goto error_ret; + ret = ad2s1210_soft_reset(st); +error_ret: mutex_unlock(&st->lock); - return len; + + return ret < 0 ? ret : len; } static ssize_t ad2s1210_show_fexcit(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); return sprintf(buf, "%d\n", st->fexcit); } static ssize_t ad2s1210_store_fexcit(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); unsigned long fexcit; int ret; ret = strict_strtoul(buf, 10, &fexcit); - if (!ret && fexcit >= AD2S1210_MIN_EXCIT && - fexcit <= AD2S1210_MAX_EXCIT) { - mutex_lock(&st->lock); - st->fexcit = fexcit; - } else { + if (ret < 0) + return ret; + if (fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT) { pr_err("ad2s1210: excitation frequency out of range\n"); return -EINVAL; } - update_frequency_control_word(st); - soft_reset(st); + mutex_lock(&st->lock); + st->fexcit = fexcit; + ret = ad2s1210_update_frequency_control_word(st); + if (ret < 0) + goto error_ret; + ret = ad2s1210_soft_reset(st); +error_ret: mutex_unlock(&st->lock); - return len; + + return ret < 0 ? ret : len; } static ssize_t ad2s1210_show_control(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; - unsigned char data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + int ret; mutex_lock(&st->lock); - config_read(st, REG_CONTROL, &data); + ret = ad2s1210_config_read(st, AD2S1210_REG_CONTROL); mutex_unlock(&st->lock); - return sprintf(buf, "0x%x\n", data); + return ret < 0 ? ret : sprintf(buf, "0x%x\n", ret); } static ssize_t ad2s1210_store_control(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); unsigned long udata; unsigned char data; int ret; ret = strict_strtoul(buf, 16, &udata); - if (ret) { - ret = -EINVAL; - goto error_ret; - } + if (ret) + return -EINVAL; + mutex_lock(&st->lock); - config_write(st, REG_CONTROL); - data = udata & MSB_IS_LOW; - config_write(st, data); - config_read(st, REG_CONTROL, &data); - if (data & MSB_IS_HIGH) { + ret = ad2s1210_config_write(st, AD2S1210_REG_CONTROL); + if (ret < 0) + goto error_ret; + data = udata & AD2S1210_MSB_IS_LOW; + ret = ad2s1210_config_write(st, data); + if (ret < 0) + goto error_ret; + + ret = ad2s1210_config_read(st, AD2S1210_REG_CONTROL); + if (ret < 0) + goto error_ret; + if (ret & AD2S1210_MSB_IS_HIGH) { ret = -EIO; pr_err("ad2s1210: write control register fail\n"); goto error_ret; } - st->resolution = resolution_value[data & SET_RESOLUTION]; -#if defined(CONFIG_AD2S1210_GPIO_INPUT) - data = read_resolution_pin(st); - if (data != st->resolution) - pr_warning("ad2s1210: resolution settings not match\n"); -#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT) - set_resolution_pin(st); -#endif + st->resolution + = ad2s1210_resolution_value[data & AD2S1210_SET_RESOLUTION]; + if (st->pdata->gpioin) { + data = ad2s1210_read_resolution_pin(st); + if (data != st->resolution) + pr_warning("ad2s1210: resolution settings not match\n"); + } else + ad2s1210_set_resolution_pin(st); + ret = len; - if (data & ENABLE_HYSTERESIS) - st->hysteresis = 1; - else - st->hysteresis = 0; + st->hysteresis = !!(data & AD2S1210_ENABLE_HYSTERESIS); + error_ret: mutex_unlock(&st->lock); return ret; @@ -407,8 +385,7 @@ static ssize_t ad2s1210_store_control(struct device *dev, static ssize_t ad2s1210_show_resolution(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); return sprintf(buf, "%d\n", st->resolution); } @@ -416,103 +393,109 @@ static ssize_t ad2s1210_store_resolution(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); unsigned char data; unsigned long udata; int ret; ret = strict_strtoul(buf, 10, &udata); - if (ret || udata < RES_10 || udata > RES_16) { + if (ret || udata < 10 || udata > 16) { pr_err("ad2s1210: resolution out of range\n"); return -EINVAL; } mutex_lock(&st->lock); - config_read(st, REG_CONTROL, &data); - data &= ~SET_RESOLUTION; - data |= (udata - RES_10) >> 1; - config_write(st, REG_CONTROL); - config_write(st, data & MSB_IS_LOW); - config_read(st, REG_CONTROL, &data); - if (data & MSB_IS_HIGH) { + ret = ad2s1210_config_read(st, AD2S1210_REG_CONTROL); + if (ret < 0) + goto error_ret; + data = ret; + data &= ~AD2S1210_SET_RESOLUTION; + data |= (udata - 10) >> 1; + ret = ad2s1210_config_write(st, AD2S1210_REG_CONTROL); + if (ret < 0) + goto error_ret; + ret = ad2s1210_config_write(st, data & AD2S1210_MSB_IS_LOW); + if (ret < 0) + goto error_ret; + ret = ad2s1210_config_read(st, AD2S1210_REG_CONTROL); + if (ret < 0) + goto error_ret; + data = ret; + if (data & AD2S1210_MSB_IS_HIGH) { ret = -EIO; pr_err("ad2s1210: setting resolution fail\n"); goto error_ret; } - st->resolution = resolution_value[data & SET_RESOLUTION]; -#if defined(CONFIG_AD2S1210_GPIO_INPUT) - data = read_resolution_pin(st); - if (data != st->resolution) - pr_warning("ad2s1210: resolution settings not match\n"); -#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT) - set_resolution_pin(st); -#endif + st->resolution + = ad2s1210_resolution_value[data & AD2S1210_SET_RESOLUTION]; + if (st->pdata->gpioin) { + data = ad2s1210_read_resolution_pin(st); + if (data != st->resolution) + pr_warning("ad2s1210: resolution settings not match\n"); + } else + ad2s1210_set_resolution_pin(st); ret = len; error_ret: mutex_unlock(&st->lock); return ret; } + /* read the fault register since last sample */ static ssize_t ad2s1210_show_fault(struct device *dev, struct device_attribute *attr, char *buf) { - int ret = 0; - ssize_t len = 0; - unsigned char data; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + int ret; mutex_lock(&st->lock); - ret = config_read(st, REG_FAULT, &data); - - if (ret) - goto error_ret; - len = sprintf(buf, "0x%x\n", data); -error_ret: + ret = ad2s1210_config_read(st, AD2S1210_REG_FAULT); mutex_unlock(&st->lock); - return ret ? ret : len; + + return ret ? ret : sprintf(buf, "0x%x\n", ret); } static ssize_t ad2s1210_clear_fault(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t len) + struct device_attribute *attr, + const char *buf, + size_t len) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; - unsigned char data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); + int ret; mutex_lock(&st->lock); - start_sample(st); + gpio_set_value(st->pdata->sample, 0); /* delay (2 * tck + 20) nano seconds */ udelay(1); - stop_sample(st); - config_read(st, REG_FAULT, &data); - start_sample(st); - stop_sample(st); + gpio_set_value(st->pdata->sample, 1); + ret = ad2s1210_config_read(st, AD2S1210_REG_FAULT); + if (ret < 0) + goto error_ret; + gpio_set_value(st->pdata->sample, 0); + gpio_set_value(st->pdata->sample, 1); +error_ret: mutex_unlock(&st->lock); - return 0; + return ret < 0 ? ret : len; } static ssize_t ad2s1210_show_reg(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; - unsigned char data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); struct iio_dev_attr *iattr = to_iio_dev_attr(attr); + int ret; mutex_lock(&st->lock); - config_read(st, iattr->address, &data); + ret = ad2s1210_config_read(st, iattr->address); mutex_unlock(&st->lock); - return sprintf(buf, "%d\n", data); + + return ret < 0 ? ret : sprintf(buf, "%d\n", ret); } static ssize_t ad2s1210_store_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); unsigned long data; int ret; struct iio_dev_attr *iattr = to_iio_dev_attr(attr); @@ -521,183 +504,121 @@ static ssize_t ad2s1210_store_reg(struct device *dev, if (ret) return -EINVAL; mutex_lock(&st->lock); - config_write(st, iattr->address); - config_write(st, data & MSB_IS_LOW); + ret = ad2s1210_config_write(st, iattr->address); + if (ret < 0) + goto error_ret; + ret = ad2s1210_config_write(st, data & AD2S1210_MSB_IS_LOW); +error_ret: mutex_unlock(&st->lock); - return len; + return ret < 0 ? ret : len; } static ssize_t ad2s1210_show_pos(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { - struct spi_message msg; int ret = 0; ssize_t len = 0; u16 pos; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); - st->xfer.len = 2; mutex_lock(&st->lock); - start_sample(st); + gpio_set_value(st->pdata->sample, 0); /* delay (6 * tck + 20) nano seconds */ udelay(1); - set_mode(MOD_POS, st); - - spi_message_init(&msg); - spi_message_add_tail(&st->xfer, &msg); - ret = spi_sync(st->sdev, &msg); + ad2s1210_set_mode(MOD_POS, st); + ret = spi_read(st->sdev, st->rx, 2); if (ret) goto error_ret; - pos = ((((u16)(st->rx[0])) << 8) | (st->rx[1])); + pos = be16_to_cpup((u16 *)st->rx); if (st->hysteresis) pos >>= 16 - st->resolution; len = sprintf(buf, "%d\n", pos); error_ret: - stop_sample(st); + gpio_set_value(st->pdata->sample, 1); /* delay (2 * tck + 20) nano seconds */ udelay(1); mutex_unlock(&st->lock); - return ret ? ret : len; + return ret < 0 ? ret : len; } static ssize_t ad2s1210_show_vel(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { - struct spi_message msg; unsigned short negative; int ret = 0; ssize_t len = 0; s16 vel; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; + struct ad2s1210_state *st = iio_priv(dev_get_drvdata(dev)); - st->xfer.len = 2; mutex_lock(&st->lock); - start_sample(st); + gpio_set_value(st->pdata->sample, 0); /* delay (6 * tck + 20) nano seconds */ udelay(1); - set_mode(MOD_VEL, st); - - spi_message_init(&msg); - spi_message_add_tail(&st->xfer, &msg); - ret = spi_sync(st->sdev, &msg); + ad2s1210_set_mode(MOD_VEL, st); + ret = spi_read(st->sdev, st->rx, 2); if (ret) goto error_ret; negative = st->rx[0] & 0x80; - vel = ((((s16)(st->rx[0])) << 8) | (st->rx[1])); + vel = be16_to_cpup((s16 *)st->rx); vel >>= 16 - st->resolution; - if (negative) { + if (vel & 0x8000) { negative = (0xffff >> st->resolution) << st->resolution; vel |= negative; } len = sprintf(buf, "%d\n", vel); error_ret: - stop_sample(st); + gpio_set_value(st->pdata->sample, 1); /* delay (2 * tck + 20) nano seconds */ udelay(1); mutex_unlock(&st->lock); - return ret ? ret : len; + return ret < 0 ? ret : len; } -static ssize_t ad2s1210_show_pos_vel(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct spi_message msg; - unsigned short negative; - int ret = 0; - ssize_t len = 0; - u16 pos; - s16 vel; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s1210_state *st = idev->dev_data; - - st->xfer.len = 2; - mutex_lock(&st->lock); - start_sample(st); - /* delay (6 * tck + 20) nano seconds */ - udelay(1); - - set_mode(MOD_POS, st); - - spi_message_init(&msg); - spi_message_add_tail(&st->xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - pos = ((((u16)(st->rx[0])) << 8) | (st->rx[1])); - if (st->hysteresis) - pos >>= 16 - st->resolution; - len = sprintf(buf, "%d ", pos); - - st->xfer.len = 2; - set_mode(MOD_VEL, st); - spi_message_init(&msg); - spi_message_add_tail(&st->xfer, &msg); - ret = spi_sync(st->sdev, &msg); - if (ret) - goto error_ret; - negative = st->rx[0] & 0x80; - vel = ((((s16)(st->rx[0])) << 8) | (st->rx[1])); - vel >>= 16 - st->resolution; - if (negative) { - negative = (0xffff >> st->resolution) << st->resolution; - vel |= negative; - } - len += sprintf(buf + len, "%d\n", vel); -error_ret: - stop_sample(st); - /* delay (2 * tck + 20) nano seconds */ - udelay(1); - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_CONST_ATTR(description, - "Variable Resolution, 10-Bit to 16Bit R/D\n\ -Converter with Reference Oscillator"); static IIO_DEVICE_ATTR(raw_io, S_IRUGO | S_IWUSR, - ad2s1210_show_raw, ad2s1210_store_raw, 0); + ad2s1210_show_raw, ad2s1210_store_raw, 0); static IIO_DEVICE_ATTR(reset, S_IWUSR, - NULL, ad2s1210_store_softreset, 0); + NULL, ad2s1210_store_softreset, 0); static IIO_DEVICE_ATTR(fclkin, S_IRUGO | S_IWUSR, - ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0); + ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0); static IIO_DEVICE_ATTR(fexcit, S_IRUGO | S_IWUSR, - ad2s1210_show_fexcit, ad2s1210_store_fexcit, 0); + ad2s1210_show_fexcit, ad2s1210_store_fexcit, 0); static IIO_DEVICE_ATTR(control, S_IRUGO | S_IWUSR, - ad2s1210_show_control, ad2s1210_store_control, 0); + ad2s1210_show_control, ad2s1210_store_control, 0); static IIO_DEVICE_ATTR(bits, S_IRUGO | S_IWUSR, - ad2s1210_show_resolution, ad2s1210_store_resolution, 0); + ad2s1210_show_resolution, ad2s1210_store_resolution, 0); static IIO_DEVICE_ATTR(fault, S_IRUGO | S_IWUSR, - ad2s1210_show_fault, ad2s1210_clear_fault, 0); -static IIO_DEVICE_ATTR(pos, S_IRUGO, - ad2s1210_show_pos, NULL, 0); -static IIO_DEVICE_ATTR(vel, S_IRUGO, - ad2s1210_show_vel, NULL, 0); -static IIO_DEVICE_ATTR(pos_vel, S_IRUGO, - ad2s1210_show_pos_vel, NULL, 0); + ad2s1210_show_fault, ad2s1210_clear_fault, 0); +static IIO_DEVICE_ATTR(pos, S_IRUGO, ad2s1210_show_pos, NULL, 0); +static IIO_DEVICE_ATTR(vel, S_IRUGO, ad2s1210_show_vel, NULL, 0); static IIO_DEVICE_ATTR(los_thrd, S_IRUGO | S_IWUSR, - ad2s1210_show_reg, ad2s1210_store_reg, REG_LOS_THRD); + ad2s1210_show_reg, ad2s1210_store_reg, + AD2S1210_REG_LOS_THRD); static IIO_DEVICE_ATTR(dos_ovr_thrd, S_IRUGO | S_IWUSR, - ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_OVR_THRD); + ad2s1210_show_reg, ad2s1210_store_reg, + AD2S1210_REG_DOS_OVR_THRD); static IIO_DEVICE_ATTR(dos_mis_thrd, S_IRUGO | S_IWUSR, - ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_MIS_THRD); + ad2s1210_show_reg, ad2s1210_store_reg, + AD2S1210_REG_DOS_MIS_THRD); static IIO_DEVICE_ATTR(dos_rst_max_thrd, S_IRUGO | S_IWUSR, - ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_RST_MAX_THRD); + ad2s1210_show_reg, ad2s1210_store_reg, + AD2S1210_REG_DOS_RST_MAX_THRD); static IIO_DEVICE_ATTR(dos_rst_min_thrd, S_IRUGO | S_IWUSR, - ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_RST_MIN_THRD); + ad2s1210_show_reg, ad2s1210_store_reg, + AD2S1210_REG_DOS_RST_MIN_THRD); static IIO_DEVICE_ATTR(lot_high_thrd, S_IRUGO | S_IWUSR, - ad2s1210_show_reg, ad2s1210_store_reg, REG_LOT_HIGH_THRD); + ad2s1210_show_reg, ad2s1210_store_reg, + AD2S1210_REG_LOT_HIGH_THRD); static IIO_DEVICE_ATTR(lot_low_thrd, S_IRUGO | S_IWUSR, - ad2s1210_show_reg, ad2s1210_store_reg, REG_LOT_LOW_THRD); + ad2s1210_show_reg, ad2s1210_store_reg, + AD2S1210_REG_LOT_LOW_THRD); static struct attribute *ad2s1210_attributes[] = { - &iio_const_attr_description.dev_attr.attr, &iio_dev_attr_raw_io.dev_attr.attr, &iio_dev_attr_reset.dev_attr.attr, &iio_dev_attr_fclkin.dev_attr.attr, @@ -707,7 +628,6 @@ static struct attribute *ad2s1210_attributes[] = { &iio_dev_attr_fault.dev_attr.attr, &iio_dev_attr_pos.dev_attr.attr, &iio_dev_attr_vel.dev_attr.attr, - &iio_dev_attr_pos_vel.dev_attr.attr, &iio_dev_attr_los_thrd.dev_attr.attr, &iio_dev_attr_dos_ovr_thrd.dev_attr.attr, &iio_dev_attr_dos_mis_thrd.dev_attr.attr, @@ -729,27 +649,32 @@ static int __devinit ad2s1210_initial(struct ad2s1210_state *st) int ret; mutex_lock(&st->lock); -#if defined(CONFIG_AD2S1210_GPIO_INPUT) - st->resolution = read_resolution_pin(st); -#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT) - set_resolution_pin(st); -#endif + if (st->pdata->gpioin) + st->resolution = ad2s1210_read_resolution_pin(st); + else + ad2s1210_set_resolution_pin(st); - config_write(st, REG_CONTROL); - data = DEF_CONTROL & ~(SET_RESOLUTION); - data |= (st->resolution - RES_10) >> 1; - config_write(st, data); - ret = config_read(st, REG_CONTROL, &data); - if (ret) + ret = ad2s1210_config_write(st, AD2S1210_REG_CONTROL); + if (ret < 0) + goto error_ret; + data = AD2S1210_DEF_CONTROL & ~(AD2S1210_SET_RESOLUTION); + data |= (st->resolution - 10) >> 1; + ret = ad2s1210_config_write(st, data); + if (ret < 0) + goto error_ret; + ret = ad2s1210_config_read(st, AD2S1210_REG_CONTROL); + if (ret < 0) goto error_ret; - if (data & MSB_IS_HIGH) { + if (ret & AD2S1210_MSB_IS_HIGH) { ret = -EIO; goto error_ret; } - update_frequency_control_word(st); - soft_reset(st); + ret = ad2s1210_update_frequency_control_word(st); + if (ret < 0) + goto error_ret; + ret = ad2s1210_soft_reset(st); error_ret: mutex_unlock(&st->lock); return ret; @@ -760,90 +685,107 @@ static const struct iio_info ad2s1210_info = { .driver_module = THIS_MODULE, }; +static int ad2s1210_setup_gpios(struct ad2s1210_state *st) +{ + int ret; + unsigned long flags = st->pdata->gpioin ? GPIOF_DIR_IN : GPIOF_DIR_OUT; + + ret = gpio_request_one(st->pdata->sample, GPIOF_DIR_IN, "sample"); + if (ret < 0) + goto error_ret; + ret = gpio_request_one(st->pdata->a[0], flags, "a0"); + if (ret < 0) + goto error_free_sample; + ret = gpio_request_one(st->pdata->a[1], flags, "a1"); + if (ret < 0) + goto error_free_a0; + ret = gpio_request_one(st->pdata->res[1], flags, "res0"); + if (ret < 0) + goto error_free_a1; + ret = gpio_request_one(st->pdata->res[1], flags, "res1"); + if (ret < 0) + goto error_free_res0; + + return 0; +error_free_res0: + gpio_free(st->pdata->res[0]); +error_free_a1: + gpio_free(st->pdata->a[1]); +error_free_a0: + gpio_free(st->pdata->a[0]); +error_free_sample: + gpio_free(st->pdata->sample); +error_ret: + return ret; +} + +static void ad2s1210_free_gpios(struct ad2s1210_state *st) +{ + gpio_free(st->pdata->res[1]); + gpio_free(st->pdata->res[0]); + gpio_free(st->pdata->a[1]); + gpio_free(st->pdata->a[0]); + gpio_free(st->pdata->sample); +} + static int __devinit ad2s1210_probe(struct spi_device *spi) { + struct iio_dev *indio_dev; struct ad2s1210_state *st; - int pn, ret = 0; - unsigned short *pins = spi->dev.platform_data; + int ret; - for (pn = 0; pn < AD2S1210_PN; pn++) { - if (gpio_request(pins[pn], DRV_NAME)) { - pr_err("%s: request gpio pin %d failed\n", - DRV_NAME, pins[pn]); - goto error_ret; - } - if (pn < AD2S1210_SAA) - gpio_direction_output(pins[pn], 1); - else { -#if defined(CONFIG_AD2S1210_GPIO_INPUT) - gpio_direction_input(pins[pn]); -#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT) - gpio_direction_output(pins[pn], 1); -#endif - } - } + if (spi->dev.platform_data == NULL) + return -EINVAL; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; } - spi_set_drvdata(spi, st); + st = iio_priv(indio_dev); + st->pdata = spi->dev.platform_data; + ret = ad2s1210_setup_gpios(st); + if (ret < 0) + goto error_free_dev; + + spi_set_drvdata(spi, indio_dev); mutex_init(&st->lock); st->sdev = spi; - st->xfer.tx_buf = st->tx; - st->xfer.rx_buf = st->rx; - st->hysteresis = 1; + st->hysteresis = true; st->mode = MOD_CONFIG; - st->resolution = RES_12; - st->fclkin = AD2S1210_DEF_CLKIN; + st->resolution = 12; st->fexcit = AD2S1210_DEF_EXCIT; - st->sample = pins[0]; - st->a0 = pins[1]; - st->a1 = pins[2]; - st->res0 = pins[3]; - st->res1 = pins[4]; - st->idev = iio_allocate_device(0); - if (st->idev == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->idev->dev.parent = &spi->dev; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &ad2s1210_info; + indio_dev->modes = INDIO_DIRECT_MODE; - st->idev->info = &ad2s1210_info; - st->idev->dev_data = (void *)(st); - st->idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(st->idev); + ret = iio_device_register(indio_dev); if (ret) - goto error_free_dev; + goto error_free_gpios; - if (spi->max_speed_hz != AD2S1210_DEF_CLKIN) - st->fclkin = spi->max_speed_hz; + st->fclkin = spi->max_speed_hz; spi->mode = SPI_MODE_3; spi_setup(spi); - ad2s1210_initial(st); + return 0; +error_free_gpios: + ad2s1210_free_gpios(st); error_free_dev: - iio_free_device(st->idev); -error_free_st: - kfree(st); + iio_free_device(indio_dev); error_ret: - for (--pn; pn >= 0; pn--) - gpio_free(pins[pn]); return ret; } static int __devexit ad2s1210_remove(struct spi_device *spi) { - struct ad2s1210_state *st = spi_get_drvdata(spi); - - iio_device_unregister(st->idev); - kfree(st); + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad2s1210_state *st = iio_priv(indio_dev); + iio_device_unregister(indio_dev); + ad2s1210_free_gpios(st); return 0; } diff --git a/drivers/staging/iio/resolver/ad2s1210.h b/drivers/staging/iio/resolver/ad2s1210.h new file mode 100644 index 000000000000..aec0bdca16a4 --- /dev/null +++ b/drivers/staging/iio/resolver/ad2s1210.h @@ -0,0 +1,17 @@ +/* + * ad2s1210.h plaform data for the ADI Resolver to Digital Converters: + * AD2S1210 + * + * Copyright (c) 2010-2010 Analog Devices Inc. + * + * 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. + */ + +struct ad2s1210_platform_data { + unsigned sample; + unsigned a[2]; + unsigned res[2]; + bool gpioin; +}; diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c index 9b72a952f2bc..166e2414ac85 100644 --- a/drivers/staging/iio/resolver/ad2s90.c +++ b/drivers/staging/iio/resolver/ad2s90.c @@ -24,29 +24,19 @@ struct ad2s90_state { struct mutex lock; struct iio_dev *idev; struct spi_device *sdev; - u8 rx[2]; - u8 tx[2]; + u8 rx[2] ____cacheline_aligned; }; static ssize_t ad2s90_show_angular(struct device *dev, struct device_attribute *attr, char *buf) { - struct spi_message msg; - struct spi_transfer xfer; int ret; ssize_t len = 0; u16 val; - struct iio_dev *idev = dev_get_drvdata(dev); - struct ad2s90_state *st = idev->dev_data; + struct ad2s90_state *st = iio_priv(dev_get_drvdata(dev)); - xfer.len = 1; - xfer.tx_buf = st->tx; - xfer.rx_buf = st->rx; mutex_lock(&st->lock); - - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->sdev, &msg); + ret = spi_read(st->sdev, st->rx, 2); if (ret) goto error_ret; val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); @@ -60,12 +50,9 @@ static ssize_t ad2s90_show_angular(struct device *dev, #define IIO_DEV_ATTR_SIMPLE_RESOLVER(_show) \ IIO_DEVICE_ATTR(angular, S_IRUGO, _show, NULL, 0) -static IIO_CONST_ATTR(description, - "Low Cost, Complete 12-Bit Resolver-to-Digital Converter"); static IIO_DEV_ATTR_SIMPLE_RESOLVER(ad2s90_show_angular); static struct attribute *ad2s90_attributes[] = { - &iio_const_attr_description.dev_attr.attr, &iio_dev_attr_angular.dev_attr.attr, NULL, }; @@ -82,29 +69,23 @@ static const struct iio_info ad2s90_info = { static int __devinit ad2s90_probe(struct spi_device *spi) { + struct iio_dev *indio_dev; struct ad2s90_state *st; int ret = 0; - st = kzalloc(sizeof(*st), GFP_KERNEL); - if (st == NULL) { + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) { ret = -ENOMEM; goto error_ret; } - spi_set_drvdata(spi, st); + st = iio_priv(indio_dev); + spi_set_drvdata(spi, indio_dev); mutex_init(&st->lock); st->sdev = spi; - - st->idev = iio_allocate_device(0); - if (st->idev == NULL) { - ret = -ENOMEM; - goto error_free_st; - } - st->idev->dev.parent = &spi->dev; - - st->idev->info = &ad2s90_info; - st->idev->dev_data = (void *)(st); - st->idev->modes = INDIO_DIRECT_MODE; + indio_dev->dev.parent = &spi->dev; + indio_dev->info = &ad2s90_info; + indio_dev->modes = INDIO_DIRECT_MODE; ret = iio_device_register(st->idev); if (ret) @@ -119,18 +100,13 @@ static int __devinit ad2s90_probe(struct spi_device *spi) error_free_dev: iio_free_device(st->idev); -error_free_st: - kfree(st); error_ret: return ret; } static int __devexit ad2s90_remove(struct spi_device *spi) { - struct ad2s90_state *st = spi_get_drvdata(spi); - - iio_device_unregister(st->idev); - kfree(st); + iio_device_unregister(spi_get_drvdata(spi)); return 0; } diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h index f329fe10fa2f..e0b58ed749b8 100644 --- a/drivers/staging/iio/trigger.h +++ b/drivers/staging/iio/trigger.h @@ -29,6 +29,8 @@ struct iio_subirq { * @set_trigger_state: [DRIVER] switch on/off the trigger on demand * @try_reenable: function to reenable the trigger when the * use count is zero (may be NULL) + * @validate_device: function to validate the device when the + * current trigger gets changed. * @subirq_chip: [INTERN] associate 'virtual' irq chip. * @subirq_base: [INTERN] base number for irqs provided by trigger. * @subirqs: [INTERN] information about the 'child' irqs. @@ -48,6 +50,8 @@ struct iio_trigger { int (*set_trigger_state)(struct iio_trigger *trig, bool state); int (*try_reenable)(struct iio_trigger *trig); + int (*validate_device)(struct iio_trigger *trig, + struct iio_dev *indio_dev); struct irq_chip subirq_chip; int subirq_base; @@ -57,6 +61,30 @@ struct iio_trigger { struct mutex pool_lock; }; +/** + * struct iio_poll_func - poll function pair + * + * @private_data: data specific to device (passed into poll func) + * @h: the function that is actually run on trigger + * @thread: threaded interrupt part + * @type: the type of interrupt (basically if oneshot) + * @name: name used to identify the trigger consumer. + * @irq: the corresponding irq as allocated from the + * trigger pool + * @timestamp: some devices need a timestamp grabbed as soon + * as possible after the trigger - hence handler + * passes it via here. + **/ +struct iio_poll_func { + void *private_data; + irqreturn_t (*h)(int irq, void *p); + irqreturn_t (*thread)(int irq, void *p); + int type; + char *name; + int irq; + s64 timestamp; +}; + static inline struct iio_trigger *to_iio_trigger(struct device *d) { return container_of(d, struct iio_trigger, dev); @@ -136,30 +164,6 @@ static inline void iio_trigger_put_irq(struct iio_trigger *trig, int irq) mutex_unlock(&trig->pool_lock); }; -/** - * struct iio_poll_func - poll function pair - * - * @private_data: data specific to device (passed into poll func) - * @h: the function that is actually run on trigger - * @thread: threaded interrupt part - * @type: the type of interrupt (basically if oneshot) - * @name: name used to identify the trigger consumer. - * @irq: the corresponding irq as allocated from the - * trigger pool - * @timestamp: some devices need a timestamp grabbed as soon - * as possible after the trigger - hence handler - * passes it via here. - **/ -struct iio_poll_func { - void *private_data; - irqreturn_t (*h)(int irq, void *p); - irqreturn_t (*thread)(int irq, void *p); - int type; - char *name; - int irq; - s64 timestamp; -}; - struct iio_poll_func *iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p), irqreturn_t (*thread)(int irq, void *p), diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index b188635c3460..f1fb795e6410 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -7,7 +7,7 @@ * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. * - * Currently this is more of a functioning proof of concept that a fully + * Currently this is more of a functioning proof of concept than a full * fledged trigger driver. * * TODO: diff --git a/drivers/staging/intel_sst/intel_sst.c b/drivers/staging/intel_sst/intel_sst.c index c0c144a2cda1..d892861346fc 100644 --- a/drivers/staging/intel_sst/intel_sst.c +++ b/drivers/staging/intel_sst/intel_sst.c @@ -545,7 +545,10 @@ static int intel_sst_runtime_suspend(struct device *dev) /* Move the SST state to Suspended */ mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_SUSPENDED; - sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full); + + /* Only needed by Medfield */ + if (sst_drv_ctx->pci_id != SST_MRST_PCI_ID) + sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full); mutex_unlock(&sst_drv_ctx->sst_lock); return 0; } diff --git a/drivers/staging/intel_sst/intel_sst_app_interface.c b/drivers/staging/intel_sst/intel_sst_app_interface.c index b8c7ddbd7cf3..93b41a284d83 100644 --- a/drivers/staging/intel_sst/intel_sst_app_interface.c +++ b/drivers/staging/intel_sst/intel_sst_app_interface.c @@ -430,8 +430,10 @@ static int snd_sst_fill_kernel_list(struct stream_info *stream, return -ENOMEM; if (copy_from_user((void *) &rar_handle, iovec[index].iov_base, - sizeof(__u32))) + sizeof(__u32))) { + kfree(stream_bufs); return -EFAULT; + } stream_bufs->addr = (char *)rar_handle; stream_bufs->in_use = false; stream_bufs->size = iovec[0].iov_len; diff --git a/drivers/staging/intel_sst/intel_sst_common.h b/drivers/staging/intel_sst/intel_sst_common.h index f8e9da6b3097..870981ba3c97 100644 --- a/drivers/staging/intel_sst/intel_sst_common.h +++ b/drivers/staging/intel_sst/intel_sst_common.h @@ -420,6 +420,8 @@ struct intel_sst_drv { unsigned int max_streams; unsigned int *fw_cntx; unsigned int fw_cntx_size; + + unsigned int fw_downloaded; }; extern struct intel_sst_drv *sst_drv_ctx; diff --git a/drivers/staging/intel_sst/intel_sst_drv_interface.c b/drivers/staging/intel_sst/intel_sst_drv_interface.c index 1021477f238d..69daa1404b68 100644 --- a/drivers/staging/intel_sst/intel_sst_drv_interface.c +++ b/drivers/staging/intel_sst/intel_sst_drv_interface.c @@ -53,6 +53,13 @@ int sst_download_fw(void) if (sst_drv_ctx->sst_state != SST_UN_INIT) return -EPERM; + /* Reload firmware is not needed for MRST */ + if ( (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) && sst_drv_ctx->fw_downloaded) { + pr_debug("FW already downloaded, skip for MRST platform\n"); + sst_drv_ctx->sst_state = SST_FW_RUNNING; + return 0; + } + snprintf(name, sizeof(name), "%s%04x%s", "fw_sst_", sst_drv_ctx->pci_id, ".bin"); @@ -71,6 +78,9 @@ int sst_download_fw(void) retval = sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[0]); if (retval) pr_err("fw download failed %d\n" , retval); + else + sst_drv_ctx->fw_downloaded = 1; + end_restore: release_firmware(fw_sst); sst_drv_ctx->alloc_block[0].sst_id = BLOCK_UNINIT; diff --git a/drivers/staging/intel_sst/intelmid_v2_control.c b/drivers/staging/intel_sst/intelmid_v2_control.c index 000378a35c1f..46ab55eb8097 100644 --- a/drivers/staging/intel_sst/intelmid_v2_control.c +++ b/drivers/staging/intel_sst/intelmid_v2_control.c @@ -1090,7 +1090,7 @@ static void nc_pmic_irq_cb(void *cb_data, u8 intsts) if (intsts & 0x1) { pr_debug("SST DBG:MAD headset detected\n"); /* send headset detect/undetect */ - present = (value == 0x1) ? 1 : 0; + present = (value == 0x1) ? 3 : 0; jack_event_flag = 1; mjack->jack.type = SND_JACK_HEADSET; hp_automute(SND_JACK_HEADSET, present); diff --git a/drivers/staging/keucr/Kconfig b/drivers/staging/keucr/Kconfig index e397fad693a7..ba756bf20665 100644 --- a/drivers/staging/keucr/Kconfig +++ b/drivers/staging/keucr/Kconfig @@ -1,9 +1,9 @@ config USB_ENESTORAGE - tristate "USB ENE SM/MS card reader support" + tristate "USB ENE SM card reader support" depends on USB && SCSI && m ---help--- - Say Y here if you wish to control a ENE SM/MS Card reader. - To use SD card, please build driver/usb/storage/ums-eneub6250.ko + Say Y here if you wish to control a ENE SM Card reader. + To use SD/MS card, please build driver/usb/storage/ums-eneub6250.ko This option depends on 'SCSI' support being enabled, but you probably also need 'SCSI device support: SCSI disk support' diff --git a/drivers/staging/keucr/Makefile b/drivers/staging/keucr/Makefile index ae928f9cd71a..c180bf4fab93 100644 --- a/drivers/staging/keucr/Makefile +++ b/drivers/staging/keucr/Makefile @@ -7,8 +7,6 @@ keucr-y := \ scsiglue.o \ transport.o \ init.o \ - msscsi.o \ - ms.o \ smscsi.o \ smilmain.o \ smilsub.o \ diff --git a/drivers/staging/keucr/init.c b/drivers/staging/keucr/init.c index b5a89375df22..071bdc238786 100644 --- a/drivers/staging/keucr/init.c +++ b/drivers/staging/keucr/init.c @@ -31,9 +31,7 @@ int ENE_InitMedia(struct us_data *us) if (!us->SM_Status.Ready && !us->MS_Status.Ready) { result = ENE_SMInit(us); if (result != USB_STOR_XFER_GOOD) { - result = ENE_MSInit(us); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; + return USB_STOR_TRANSPORT_ERROR; } } @@ -61,60 +59,6 @@ int ENE_Read_BYTE(struct us_data *us, WORD index, void *buf) return result; } -/* - * ENE_MSInit(): - */ -int ENE_MSInit(struct us_data *us) -{ - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result; - BYTE buf[0x200]; - WORD MSP_BlockSize, MSP_UserAreaBlocks; - - printk(KERN_INFO "transport --- ENE_MSInit\n"); - result = ENE_LoadBinCode(us, MS_INIT_PATTERN); - if (result != USB_STOR_XFER_GOOD) { - printk(KERN_ERR "Load MS Init Code Fail !!\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = 0x200; - bcb->Flags = 0x80; - bcb->CDB[0] = 0xF1; - bcb->CDB[1] = 0x01; - - result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0); - if (result != USB_STOR_XFER_GOOD) { - printk(KERN_ERR "Execution MS Init Code Fail !!\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - us->MS_Status = *(PMS_STATUS)&buf[0]; - - if (us->MS_Status.Insert && us->MS_Status.Ready) { - printk(KERN_INFO "Insert = %x\n", us->MS_Status.Insert); - printk(KERN_INFO "Ready = %x\n", us->MS_Status.Ready); - printk(KERN_INFO "IsMSPro = %x\n", us->MS_Status.IsMSPro); - printk(KERN_INFO "IsMSPHG = %x\n", us->MS_Status.IsMSPHG); - printk(KERN_INFO "WtP = %x\n", us->MS_Status.WtP); - if (us->MS_Status.IsMSPro) { - MSP_BlockSize = (buf[6] << 8) | buf[7]; - MSP_UserAreaBlocks = (buf[10] << 8) | buf[11]; - us->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks; - } else { - MS_CardInit(us); - } - printk(KERN_INFO "MS Init Code OK !!\n"); - } else { - printk(KERN_INFO "MS Card Not Ready --- %x\n", buf[0]); - return USB_STOR_TRANSPORT_ERROR; - } - - return USB_STOR_TRANSPORT_GOOD; -} - /* *ENE_SMInit() */ @@ -185,19 +129,6 @@ int ENE_LoadBinCode(struct us_data *us, BYTE flag) if (buf == NULL) return USB_STOR_TRANSPORT_ERROR; switch (flag) { - /* For MS */ - case MS_INIT_PATTERN: - printk(KERN_INFO "MS_INIT_PATTERN\n"); - memcpy(buf, MS_Init, 0x800); - break; - case MSP_RW_PATTERN: - printk(KERN_INFO "MSP_RW_PATTERN\n"); - memcpy(buf, MSP_Rdwr, 0x800); - break; - case MS_RW_PATTERN: - printk(KERN_INFO "MS_RW_PATTERN\n"); - memcpy(buf, MS_Rdwr, 0x800); - break; /* For SS */ case SM_INIT_PATTERN: printk(KERN_INFO "SM_INIT_PATTERN\n"); diff --git a/drivers/staging/keucr/init.h b/drivers/staging/keucr/init.h index f709055ae146..c8b2cd604460 100644 --- a/drivers/staging/keucr/init.h +++ b/drivers/staging/keucr/init.h @@ -4,779 +4,6 @@ extern DWORD MediaChange; extern int Check_D_MediaFmt(struct us_data *); -static BYTE MS_Init[] = { -0x90, 0xF0, 0x15, 0xE0, 0xF5, 0x1C, 0x11, 0x2C, -0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, -0xFF, 0x23, 0x74, 0x80, 0xF0, 0x90, 0xFF, 0x09, -0xE0, 0x30, 0xE5, 0xFC, 0x51, 0x59, 0x75, 0x3F, -0x00, 0x75, 0x3E, 0x00, 0x75, 0x3D, 0x00, 0x75, -0x3C, 0x00, 0xD3, 0x22, 0x90, 0xFF, 0x83, 0xE0, -0xA2, 0xE1, 0x92, 0x25, 0x20, 0x25, 0x06, 0xC2, -0x1F, 0xD2, 0x19, 0xC3, 0x22, 0x7F, 0x02, 0x12, -0x2F, 0xCB, 0x20, 0x19, 0x05, 0x30, 0x1F, 0x02, -0xD3, 0x22, 0x90, 0xEA, 0x44, 0x74, 0x80, 0xF0, -0x7F, 0x10, 0x12, 0x2F, 0xC5, 0x90, 0xFE, 0x47, -0xE0, 0x44, 0x80, 0xF0, 0x78, 0x00, 0xE8, 0xC3, -0x94, 0x04, 0x50, 0x0A, 0x7F, 0x88, 0x7E, 0x13, -0x12, 0xE4, 0xA6, 0x08, 0x80, 0xF0, 0x90, 0xFE, -0x45, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0xFE, 0x47, -0xE0, 0x54, 0xBF, 0xF0, 0x90, 0xFE, 0x45, 0xE0, -0x54, 0xFE, 0xF0, 0x90, 0xFE, 0x45, 0xE0, 0x54, -0x7F, 0xF0, 0x90, 0xFE, 0x46, 0xE0, 0x44, 0x40, -0xF0, 0x90, 0xFE, 0x45, 0xE0, 0x54, 0xC7, 0x44, -0x18, 0xF0, 0x90, 0xFE, 0x47, 0xE0, 0x44, 0x08, -0xF0, 0x90, 0xFE, 0x45, 0xE0, 0x44, 0x40, 0xF0, -0x7F, 0x32, 0x7E, 0x00, 0x12, 0xE4, 0xA6, 0x90, -0xFE, 0x51, 0xE0, 0x54, 0x33, 0xF0, 0x90, 0xFE, -0x44, 0x74, 0x02, 0xF0, 0x30, 0x25, 0x04, 0xE0, -0x20, 0xE1, 0xF9, 0x90, 0xFE, 0x51, 0xE0, 0x54, -0x0F, 0xF0, 0x90, 0xFE, 0x44, 0x74, 0x02, 0xF0, -0x30, 0x25, 0x04, 0xE0, 0x20, 0xE1, 0xF9, 0x90, -0xFE, 0x44, 0x74, 0x04, 0xF0, 0x30, 0x25, 0x04, -0xE0, 0x20, 0xE2, 0xF9, 0x90, 0xFE, 0x4C, 0xE0, -0xF0, 0x90, 0xFE, 0x4D, 0xE0, 0xF0, 0x90, 0xFE, -0x48, 0x74, 0x7F, 0xF0, 0x90, 0xFE, 0x49, 0x74, -0x9F, 0xF0, 0x90, 0xFE, 0x51, 0xE0, 0x54, 0x3C, -0x44, 0x02, 0xF0, 0x90, 0xFE, 0x44, 0x74, 0x02, -0xF0, 0x30, 0x25, 0x04, 0xE0, 0x20, 0xE1, 0xF9, -0x90, 0xFE, 0x46, 0xE0, 0x44, 0x20, 0xF0, 0x79, -0x02, 0x7A, 0x06, 0x7B, 0x00, 0x7C, 0x00, 0x7D, -0x06, 0x7E, 0xEB, 0x7F, 0xC9, 0x12, 0x2F, 0xA7, -0x40, 0x03, 0x02, 0xE2, 0x37, 0xC2, 0x45, 0xC2, -0x1E, 0x90, 0xEB, 0xCB, 0xE0, 0x64, 0x01, 0x70, -0x65, 0x90, 0xEB, 0xCD, 0xE0, 0x70, 0x5F, 0x90, -0xEB, 0xCE, 0xE0, 0x60, 0x08, 0x54, 0x03, 0x60, -0x55, 0xD2, 0x1E, 0x80, 0x09, 0x90, 0xEB, 0xC9, -0xE0, 0x30, 0xE0, 0x02, 0xD2, 0x1E, 0x90, 0xEA, -0x45, 0x74, 0x01, 0xF0, 0x75, 0x0B, 0x00, 0xE5, -0x0B, 0xC3, 0x94, 0x80, 0x50, 0x31, 0x12, 0x2F, -0xB9, 0x40, 0x03, 0x02, 0xE2, 0x37, 0x90, 0xEB, -0xC8, 0xE0, 0x54, 0x80, 0x70, 0x0B, 0x7F, 0x38, -0x7E, 0x13, 0x12, 0xE4, 0xA6, 0x05, 0x0B, 0x80, -0xDE, 0x12, 0x2F, 0xB9, 0x40, 0x03, 0x02, 0xE2, -0x37, 0x90, 0xEB, 0xC8, 0xE0, 0xF9, 0x54, 0x40, -0x60, 0x0A, 0xE9, 0x54, 0x01, 0x70, 0x03, 0x02, -0xE2, 0x37, 0xD2, 0x1E, 0x80, 0x24, 0x90, 0xEB, -0xCB, 0xE0, 0x64, 0x00, 0x60, 0x03, 0x02, 0xE2, -0x37, 0x90, 0xEA, 0x45, 0x74, 0x00, 0xF0, 0x7F, -0x90, 0x12, 0x2F, 0xC5, 0x12, 0xE2, 0xB0, 0x40, -0x03, 0x02, 0xE2, 0x37, 0xD2, 0x1F, 0xC2, 0x19, -0xD3, 0x22, 0x90, 0xEA, 0x44, 0x74, 0x00, 0xF0, -0x75, 0x17, 0x00, 0x79, 0x00, 0x7A, 0x00, 0x7B, -0x10, 0x7C, 0x02, 0x7D, 0x02, 0x12, 0x2F, 0xA7, -0x40, 0x02, 0x80, 0x5B, 0x7F, 0x80, 0x12, 0x2F, -0xC5, 0x90, 0xFE, 0x45, 0xE0, 0x54, 0xFE, 0xF0, -0x90, 0xFE, 0x45, 0xE0, 0x44, 0x04, 0xF0, 0x90, -0xEB, 0xCC, 0xE0, 0x64, 0x07, 0x70, 0x2D, 0x90, -0xEA, 0x44, 0x74, 0x40, 0xF0, 0x75, 0x17, 0x00, -0x79, 0x00, 0x7A, 0x00, 0x7B, 0x10, 0x7C, 0x02, -0x7D, 0x02, 0x12, 0x2F, 0xA7, 0x40, 0x02, 0x80, -0x26, 0x7F, 0x80, 0x12, 0x2F, 0xC5, 0x90, 0xFE, -0x45, 0xE0, 0x54, 0xFA, 0xF0, 0x90, 0xFE, 0x45, -0xE0, 0x44, 0x01, 0xF0, 0x90, 0xEA, 0x45, 0xE0, -0x60, 0x07, 0x12, 0x2F, 0xCE, 0x40, 0x02, 0x80, -0x06, 0xD2, 0x1F, 0xC2, 0x19, 0xD3, 0x22, 0xE4, -0x90, 0xFE, 0x48, 0xF0, 0x90, 0xFE, 0x49, 0xF0, -0x90, 0xFE, 0x4C, 0xE0, 0xF0, 0x90, 0xFE, 0x4D, -0xE0, 0xF0, 0x90, 0xFE, 0x47, 0xE0, 0x54, 0x7F, -0xF0, 0xC2, 0x25, 0xC2, 0x1F, 0xD2, 0x19, 0xC3, -0x22, 0x90, 0xEA, 0x45, 0xE0, 0x64, 0x01, 0x70, -0x03, 0xD3, 0x80, 0x01, 0xC3, 0xE4, 0x92, 0xE3, -0xC0, 0xE0, 0x90, 0xEB, 0xCC, 0xE0, 0x64, 0x07, -0x70, 0x03, 0xD3, 0x80, 0x01, 0xC3, 0xD0, 0xE0, -0x92, 0xE4, 0xA2, 0x25, 0x92, 0xE0, 0xA2, 0x1F, -0x92, 0xE1, 0xA2, 0x19, 0x92, 0xE2, 0xA2, 0x1E, -0x92, 0xE6, 0x90, 0xF4, 0x00, 0xF0, 0x74, 0xFF, -0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0x7B, -0x40, 0x7C, 0xEB, 0x7D, 0x6F, 0xAE, 0x83, 0xAF, -0x82, 0x12, 0x2F, 0xC8, 0x90, 0xFF, 0x2A, 0x74, -0x02, 0xF0, 0xA3, 0x74, 0x00, 0xF0, 0xD3, 0x22, -0xC2, 0x1E, 0x74, 0xFF, 0x90, 0xEA, 0x49, 0xF0, -0x90, 0xFE, 0x44, 0x74, 0x02, 0xF0, 0x30, 0x25, -0x04, 0xE0, 0x20, 0xE1, 0xF9, 0x90, 0xFF, 0x09, -0x30, 0x25, 0x07, 0xE0, 0x30, 0xE5, 0xF9, 0xD3, -0x80, 0x01, 0xC3, 0x40, 0x01, 0x22, 0xC2, 0x1A, -0xC2, 0x22, 0x75, 0x14, 0x00, 0xE5, 0x14, 0x64, -0x0C, 0x70, 0x03, 0x02, 0xE4, 0x4B, 0x75, 0x17, -0x00, 0x75, 0x18, 0x00, 0x85, 0x14, 0x19, 0x75, -0x1B, 0x00, 0x12, 0x2F, 0x8C, 0x40, 0x03, 0x02, -0xE4, 0x46, 0x30, 0x41, 0x03, 0x02, 0xE4, 0x46, -0x90, 0xEB, 0xDD, 0xE0, 0x20, 0xE7, 0x03, 0x02, -0xE4, 0x46, 0x90, 0xEB, 0xDE, 0xE0, 0x20, 0xE2, -0x02, 0x80, 0x03, 0x02, 0xE4, 0x46, 0x90, 0xF4, -0x00, 0xE0, 0xFE, 0x90, 0xF4, 0x01, 0xE0, 0x64, -0x01, 0x4E, 0x60, 0x03, 0x02, 0xE4, 0x46, 0x90, -0xEA, 0x49, 0xE0, 0x64, 0xFF, 0x60, 0x03, 0x02, -0xE4, 0x4B, 0x90, 0xF5, 0xA0, 0xE0, 0x64, 0x01, -0x60, 0x03, 0x02, 0xE4, 0x46, 0x90, 0xF5, 0xD6, -0xE0, 0x64, 0x01, 0x60, 0x03, 0x02, 0xE4, 0x46, -0x90, 0xF5, 0xD8, 0xE0, 0xFF, 0xC3, 0x74, 0x03, -0x9F, 0x50, 0x03, 0x02, 0xE4, 0x46, 0xEF, 0x60, -0x04, 0xD2, 0x1E, 0x80, 0x0B, 0xC2, 0x1E, 0x90, -0xEB, 0xC9, 0xE0, 0x30, 0xE0, 0x02, 0xD2, 0x1E, -0x90, 0xF5, 0xA2, 0xE0, 0xFE, 0x90, 0xF5, 0xA3, -0xE0, 0xFF, 0x25, 0xE0, 0x90, 0xEA, 0x47, 0xF0, -0xE4, 0x74, 0x10, 0x9F, 0x74, 0x00, 0x9E, 0x50, -0x03, 0x02, 0xE4, 0x46, 0x90, 0xF5, 0xA4, 0xE0, -0xFE, 0x90, 0xF5, 0xA5, 0xE0, 0xFF, 0xC3, 0x74, -0x00, 0x9F, 0x74, 0x20, 0x9E, 0x50, 0x03, 0x02, -0xE4, 0x46, 0xEE, 0x4F, 0x70, 0x03, 0x02, 0xE4, -0x46, 0x90, 0xF5, 0xA6, 0xE0, 0xFE, 0x90, 0xF5, -0xA7, 0xE0, 0xFF, 0xEE, 0x4F, 0x70, 0x03, 0x02, -0xE4, 0x46, 0x90, 0xF5, 0x78, 0xE0, 0x64, 0x01, -0x60, 0x03, 0x02, 0xE4, 0x46, 0x90, 0xF5, 0x74, -0xE0, 0xFC, 0x90, 0xF5, 0x75, 0xE0, 0xFD, 0x90, -0xF5, 0x76, 0xE0, 0x90, 0xEA, 0x5B, 0xF0, 0xFE, -0x90, 0xF5, 0x77, 0xE0, 0x90, 0xEA, 0x5C, 0xF0, -0xFF, 0x4E, 0x4D, 0x4C, 0x70, 0x03, 0x02, 0xE4, -0x46, 0x90, 0xF5, 0x70, 0xE0, 0xFC, 0x90, 0xF5, -0x71, 0xE0, 0xFD, 0x90, 0xF5, 0x72, 0xE0, 0xFE, -0x90, 0xF5, 0x73, 0xE0, 0xFF, 0xEC, 0x90, 0xEA, -0x55, 0xF0, 0xED, 0x90, 0xEA, 0x56, 0xF0, 0xEE, -0x90, 0xEA, 0x57, 0xF0, 0xEF, 0x90, 0xEA, 0x58, -0xF0, 0xEC, 0x64, 0xFF, 0x70, 0x12, 0xED, 0x64, -0xFF, 0x70, 0x0D, 0xEE, 0x64, 0xFF, 0x70, 0x08, -0xEF, 0x64, 0xFF, 0x70, 0x03, 0x02, 0xE4, 0x46, -0xC2, 0x3F, 0x90, 0xF5, 0xD3, 0xE0, 0x64, 0x01, -0x70, 0x02, 0xD2, 0x3F, 0x75, 0x17, 0x00, 0x75, -0x18, 0x00, 0x85, 0x14, 0x19, 0x75, 0x1B, 0x01, -0x12, 0x2F, 0x8C, 0x40, 0x03, 0x02, 0xE4, 0x46, -0x90, 0xEA, 0x49, 0xE5, 0x14, 0xF0, 0x05, 0x14, -0x02, 0xE2, 0xDD, 0xD2, 0x22, 0x90, 0xEA, 0x49, -0xE0, 0x64, 0xFF, 0x70, 0x02, 0x80, 0x02, 0x80, -0x12, 0x90, 0xFE, 0x44, 0x74, 0x02, 0xF0, 0x30, -0x25, 0x04, 0xE0, 0x20, 0xE1, 0xF9, 0x12, 0x2F, -0x9E, 0xC3, 0x22, 0x30, 0x3F, 0x36, 0x74, 0x88, -0x90, 0xEA, 0x44, 0xF0, 0x75, 0x17, 0x00, 0x79, -0x00, 0x7A, 0x00, 0x7B, 0x10, 0x7C, 0x02, 0x7D, -0x02, 0x12, 0x2F, 0xA7, 0x7F, 0x80, 0x12, 0x2F, -0xC5, 0x90, 0xFE, 0x45, 0xE0, 0x54, 0xFE, 0xF0, -0x90, 0xFE, 0x45, 0xE0, 0x44, 0x04, 0xF0, 0x90, -0xFE, 0x44, 0x74, 0x02, 0xF0, 0x30, 0x25, 0x04, -0xE0, 0x20, 0xE1, 0xF9, 0xD3, 0x22, 0x75, 0x8A, -0x00, 0x75, 0x8C, 0xCE, 0xC2, 0x8D, 0x90, 0xEA, -0x65, 0xE4, 0xF0, 0xA3, 0xF0, 0xD2, 0x8C, 0x90, -0xEA, 0x65, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xEC, -0xC3, 0x9E, 0x40, 0xF3, 0x70, 0x05, 0xED, 0xC3, -0x9F, 0x40, 0xEC, 0xC2, 0x8C, 0x22, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, -0x4D, 0x53, 0x2D, 0x49, 0x6E, 0x69, 0x74, 0x20, -0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x30 }; - -static BYTE MSP_Rdwr[] = { -0x90, 0xF0, 0x10, 0xE0, 0x90, 0xEA, 0x46, 0xF0, -0xB4, 0x04, 0x03, 0x02, 0xE1, 0x1E, 0x90, 0xFF, -0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23, -0x74, 0x80, 0xF0, 0x90, 0xFF, 0x09, 0xE0, 0x30, -0xE5, 0xFC, 0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, -0x92, 0x25, 0x40, 0x01, 0x22, 0x20, 0x1F, 0x02, -0xC3, 0x22, 0x30, 0x45, 0x02, 0xC3, 0x22, 0xC3, -0xE5, 0x3D, 0x13, 0xF5, 0x08, 0xE5, 0x3E, 0x13, -0xF5, 0x09, 0x78, 0x96, 0x79, 0x20, 0xAA, 0x08, -0xAB, 0x09, 0x12, 0xE2, 0x53, 0x20, 0x1D, 0x10, -0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, 0x92, 0x25, -0x30, 0x25, 0x03, 0x30, 0x24, 0xEF, 0xD2, 0x24, -0x20, 0x23, 0x10, 0x90, 0xFF, 0x83, 0xE0, 0xA2, -0xE1, 0x92, 0x25, 0x30, 0x25, 0x03, 0x30, 0x24, -0xEF, 0xD2, 0x24, 0x30, 0x24, 0x02, 0xC3, 0x22, -0xC2, 0x24, 0xC2, 0x23, 0x90, 0xEA, 0x4B, 0xE0, -0x30, 0xE3, 0x0B, 0xC2, 0x25, 0x90, 0xFF, 0x85, -0xE0, 0x54, 0xFD, 0xF0, 0xC3, 0x22, 0x30, 0xE2, -0x78, 0x90, 0xFF, 0x09, 0x90, 0xFF, 0x83, 0xE0, -0xA2, 0xE1, 0x92, 0x25, 0x30, 0x25, 0x0A, 0x90, -0xFF, 0x09, 0xE0, 0x30, 0xE5, 0xEE, 0xD3, 0x80, -0x01, 0xC3, 0x40, 0x01, 0x22, 0x79, 0x00, 0x90, -0xFE, 0x46, 0xE0, 0x54, 0xF0, 0x49, 0xF0, 0x78, -0x2D, 0x12, 0x2F, 0xAA, 0x7E, 0xF4, 0x7F, 0x00, -0x7D, 0x00, 0x7C, 0x02, 0x12, 0x2F, 0xC2, 0x20, -0x1D, 0x10, 0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, -0x92, 0x25, 0x30, 0x25, 0x03, 0x30, 0x24, 0xEF, -0xD2, 0x24, 0x30, 0x24, 0x13, 0x75, 0x3F, 0x00, -0xC3, 0xE5, 0x09, 0x33, 0xF5, 0x3E, 0xE5, 0x08, -0x33, 0xF5, 0x3D, 0x75, 0x3C, 0x00, 0xC3, 0x22, -0x90, 0xFF, 0x2A, 0x74, 0x02, 0xF0, 0xA3, 0x74, -0x00, 0xF0, 0xE5, 0x09, 0x24, 0xFF, 0xF5, 0x09, -0xE5, 0x08, 0x34, 0xFF, 0xF5, 0x08, 0x02, 0xE0, -0x60, 0x90, 0xEA, 0x4B, 0xE0, 0x20, 0xE0, 0x03, -0x02, 0xE0, 0x60, 0xE4, 0xF5, 0x3F, 0xF5, 0x3E, -0xF5, 0x3D, 0xF5, 0x3C, 0xD3, 0x22, 0x90, 0xFF, -0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23, -0x74, 0x80, 0xF0, 0x90, 0xFF, 0x09, 0xE0, 0x30, -0xE5, 0xFC, 0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, -0x92, 0x25, 0x40, 0x01, 0x22, 0x20, 0x1F, 0x02, -0xC3, 0x22, 0x30, 0x1E, 0x02, 0xC3, 0x22, 0xC3, -0xE5, 0x3D, 0x13, 0xF5, 0x08, 0xE5, 0x3E, 0x13, -0xF5, 0x09, 0x78, 0x96, 0x79, 0x21, 0xAA, 0x08, -0xAB, 0x09, 0x12, 0xE2, 0x53, 0x20, 0x1D, 0x10, -0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, 0x92, 0x25, -0x30, 0x25, 0x03, 0x30, 0x24, 0xEF, 0xD2, 0x24, -0x30, 0x2D, 0x05, 0x75, 0x0A, 0x01, 0x80, 0x03, -0x75, 0x0A, 0x08, 0x20, 0x23, 0x10, 0x90, 0xFF, -0x83, 0xE0, 0xA2, 0xE1, 0x92, 0x25, 0x30, 0x25, -0x03, 0x30, 0x24, 0xEF, 0xD2, 0x24, 0x30, 0x24, -0x02, 0xC3, 0x22, 0xC2, 0x24, 0xC2, 0x23, 0x90, -0xEA, 0x4B, 0xE0, 0x30, 0xE1, 0x0B, 0xC2, 0x25, -0x90, 0xFF, 0x85, 0xE0, 0x54, 0xFD, 0xF0, 0xC3, -0x22, 0x20, 0xE2, 0x03, 0x02, 0xE2, 0x3E, 0x79, -0x0F, 0x90, 0xFE, 0x46, 0xE0, 0x54, 0xF0, 0x49, -0xF0, 0x75, 0x0B, 0x00, 0xE5, 0x0B, 0xC3, 0x95, -0x0A, 0x50, 0x43, 0x90, 0xFF, 0x09, 0x30, 0x25, -0x0B, 0xE0, 0x30, 0xE1, 0xF9, 0x90, 0xFF, 0x09, -0xF0, 0xD3, 0x80, 0x01, 0xC3, 0x50, 0x0F, 0xAF, -0x0B, 0x7C, 0xF0, 0x7D, 0x00, 0xAB, 0x4D, 0xAA, -0x4C, 0x12, 0x2F, 0xBF, 0x40, 0x0F, 0x90, 0xFF, -0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23, -0x74, 0x80, 0xF0, 0xC3, 0x22, 0x90, 0xFF, 0x09, -0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74, -0x80, 0xF0, 0x05, 0x0B, 0x80, 0xB6, 0x20, 0x1D, -0x10, 0x90, 0xFF, 0x83, 0xE0, 0xA2, 0xE1, 0x92, -0x25, 0x30, 0x25, 0x03, 0x30, 0x24, 0xEF, 0xD2, -0x24, 0x30, 0x24, 0x13, 0x75, 0x3F, 0x00, 0xC3, -0xE5, 0x09, 0x33, 0xF5, 0x3E, 0xE5, 0x08, 0x33, -0xF5, 0x3D, 0x75, 0x3C, 0x00, 0xC3, 0x22, 0xE5, -0x09, 0x24, 0xFF, 0xF5, 0x09, 0xE5, 0x08, 0x34, -0xFF, 0xF5, 0x08, 0x02, 0xE1, 0x7B, 0x90, 0xEA, -0x4B, 0xE0, 0x20, 0xE0, 0x03, 0x02, 0xE1, 0x7B, -0xE4, 0xF5, 0x3F, 0xF5, 0x3E, 0xF5, 0x3D, 0xF5, -0x3C, 0xD3, 0x22, 0x90, 0xFE, 0x4C, 0xE0, 0xF0, -0x90, 0xFE, 0x4D, 0xE0, 0xF0, 0xC2, 0x24, 0xC2, -0x23, 0xC2, 0x1D, 0x90, 0xFE, 0x50, 0xE8, 0xF0, -0x90, 0xFE, 0x40, 0xE9, 0xF0, 0x90, 0xFE, 0x40, -0xEA, 0xF0, 0x90, 0xFE, 0x40, 0xEB, 0xF0, 0x90, -0xEB, 0x2A, 0xE0, 0x90, 0xFE, 0x40, 0xF0, 0x90, -0xEB, 0x2B, 0xE0, 0x90, 0xFE, 0x40, 0xF0, 0x90, -0xEB, 0x2C, 0xE0, 0x90, 0xFE, 0x40, 0xF0, 0x90, -0xEB, 0x2D, 0xE0, 0x90, 0xFE, 0x40, 0xF0, 0x90, -0xFE, 0x44, 0x74, 0x01, 0xF0, 0x22, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, 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, 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, -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, 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, 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, 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, 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, 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, -0x4D, 0x53, 0x50, 0x2D, 0x52, 0x57, 0x20, 0x20, -0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x30 }; - -static BYTE MS_Rdwr[] = { -0x90, 0xF0, 0x10, 0xE0, 0x90, 0xEA, 0x46, 0xF0, -0xB4, 0x02, 0x02, 0x80, 0x36, 0x90, 0xF0, 0x11, -0xE0, 0xF5, 0x17, 0x90, 0xF0, 0x12, 0xE0, 0xF5, -0x18, 0x90, 0xF0, 0x13, 0xE0, 0xF5, 0x19, 0x90, -0xF0, 0x14, 0xE0, 0xF5, 0x1B, 0x90, 0xF0, 0x15, -0xE0, 0xF5, 0x1C, 0x90, 0xF0, 0x16, 0xE0, 0xF5, -0x1D, 0x90, 0xF0, 0x17, 0xE0, 0xF5, 0x1E, 0x90, -0xF0, 0x18, 0xE0, 0xF5, 0x1F, 0x90, 0xF0, 0x19, -0xE0, 0xF5, 0x10, 0x90, 0xFF, 0x09, 0xE0, 0x30, -0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0, -0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE5, 0xFC, 0x90, -0xFF, 0x83, 0xE0, 0xA2, 0xE1, 0x92, 0x25, 0x40, -0x01, 0x22, 0x90, 0xEA, 0x46, 0xE0, 0xB4, 0x02, -0x02, 0x80, 0x2B, 0xB4, 0x03, 0x03, 0x02, 0xE0, -0x96, 0xB4, 0x04, 0x05, 0xD2, 0x21, 0x02, 0xE2, -0xBC, 0xB4, 0x08, 0x0E, 0x85, 0x1C, 0x11, 0x85, -0x1D, 0x12, 0x85, 0x10, 0x1B, 0xC2, 0x21, 0x02, -0xE2, 0xBC, 0xB4, 0x06, 0x03, 0x02, 0xE2, 0x2F, -0xB4, 0x05, 0x03, 0x02, 0xE2, 0x7A, 0x20, 0x1F, -0x02, 0xC3, 0x22, 0x90, 0xEA, 0x46, 0xE0, 0xB4, -0x03, 0x03, 0x02, 0xE1, 0x94, 0xC3, 0xE5, 0x3D, -0x13, 0xF5, 0x14, 0xE5, 0x3E, 0x13, 0xF5, 0x15, -0x90, 0xEB, 0x2A, 0xE0, 0xFC, 0x90, 0xEB, 0x2B, -0xE0, 0xFD, 0x90, 0xEB, 0x2C, 0xE0, 0xFE, 0x90, -0xEB, 0x2D, 0xE0, 0xFF, 0x90, 0xEA, 0x47, 0xE0, -0x14, 0xFB, 0x60, 0x12, 0xC3, 0xEC, 0x13, 0xFC, -0xED, 0x13, 0xFD, 0xEE, 0x13, 0xFE, 0xEF, 0x13, -0xFF, 0xC3, 0xEB, 0x13, 0x80, 0xEB, 0x8E, 0x1E, -0x8F, 0x1F, 0x90, 0xEB, 0x2D, 0xE0, 0xFF, 0x90, -0xEA, 0x47, 0xE0, 0x14, 0x5F, 0xF5, 0x1B, 0xD2, -0x1A, 0x90, 0xEA, 0x47, 0xE0, 0xC3, 0x95, 0x1B, -0xF5, 0x16, 0xE5, 0x14, 0x70, 0x0A, 0xE5, 0x16, -0xD3, 0x95, 0x15, 0x40, 0x03, 0x85, 0x15, 0x16, -0xE5, 0x1E, 0xF5, 0x18, 0xE5, 0x1F, 0xF5, 0x19, -0x75, 0x17, 0x00, 0x90, 0xEA, 0x5C, 0xE0, 0xF8, -0x90, 0xEB, 0x6D, 0xE0, 0x65, 0x18, 0x70, 0x08, -0xA3, 0xE0, 0x65, 0x19, 0x70, 0x03, 0x80, 0x07, -0xA3, 0xA3, 0xD8, 0xEF, 0xC3, 0x80, 0x01, 0xD3, -0x40, 0x4F, 0xE5, 0x16, 0x64, 0x01, 0x70, 0x07, -0x12, 0x2F, 0x8C, 0x50, 0x41, 0x80, 0x07, 0xAB, -0x16, 0x12, 0xE5, 0x60, 0x50, 0x38, 0xC3, 0xE5, -0x15, 0x95, 0x16, 0xF5, 0x15, 0xE5, 0x14, 0x94, -0x00, 0xF5, 0x14, 0xE5, 0x14, 0x45, 0x15, 0x60, -0x17, 0x05, 0x0D, 0xE5, 0x0D, 0x70, 0x02, 0x05, -0x0C, 0x05, 0x1F, 0xE5, 0x1F, 0x70, 0x02, 0x05, -0x1E, 0x74, 0x00, 0xF5, 0x1B, 0x02, 0xE0, 0xF1, -0x75, 0x3F, 0x00, 0x75, 0x3E, 0x00, 0x75, 0x3D, -0x00, 0x75, 0x3C, 0x00, 0xD3, 0x22, 0x12, 0x2F, -0x9E, 0x75, 0x3F, 0x00, 0xC3, 0xE5, 0x15, 0x33, -0xF5, 0x3E, 0xE5, 0x14, 0x33, 0xF5, 0x3D, 0x75, -0x3C, 0x00, 0xC3, 0x22, 0xE5, 0x1C, 0x70, 0x03, -0x75, 0x1C, 0x01, 0xC3, 0x94, 0x80, 0x40, 0x03, -0x75, 0x1C, 0x80, 0xAA, 0x1C, 0xAD, 0x1B, 0x90, -0xF4, 0x00, 0xC0, 0x83, 0xC0, 0x82, 0xEA, 0x60, -0x5F, 0xAE, 0x18, 0xAF, 0x19, 0xE4, 0x90, 0xFE, -0x48, 0xF0, 0x90, 0xFE, 0x49, 0xF0, 0x12, 0x2F, -0x8F, 0x90, 0xFE, 0x48, 0x74, 0x7F, 0xF0, 0x90, -0xFE, 0x49, 0x74, 0x9F, 0xF0, 0x90, 0xEB, 0xDD, -0xE0, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0xA3, 0xC0, -0x83, 0xC0, 0x82, 0x90, 0xEB, 0xDE, 0xE0, 0xD0, -0x82, 0xD0, 0x83, 0xF0, 0xA3, 0xC0, 0x83, 0xC0, -0x82, 0x90, 0xEB, 0xDF, 0xE0, 0xD0, 0x82, 0xD0, -0x83, 0xF0, 0xA3, 0xC0, 0x83, 0xC0, 0x82, 0x90, -0xEB, 0xE0, 0xE0, 0xD0, 0x82, 0xD0, 0x83, 0xF0, -0xA3, 0xC0, 0x83, 0xC0, 0x82, 0x1A, 0x05, 0x19, -0xE5, 0x19, 0x70, 0x02, 0x05, 0x18, 0x80, 0x9E, -0xD0, 0x82, 0xD0, 0x83, 0xE5, 0x1C, 0x25, 0xE0, -0xFF, 0x74, 0x00, 0x33, 0xFE, 0xEF, 0x25, 0xE0, -0xFF, 0xEE, 0x33, 0xFE, 0x90, 0xFF, 0x2A, 0xEE, -0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0xE1, 0x70, 0x20, -0x1F, 0x02, 0xC3, 0x22, 0x30, 0x1E, 0x02, 0x80, -0xF9, 0xD2, 0x1A, 0x75, 0x17, 0x00, 0x75, 0x3F, -0x00, 0x75, 0x3E, 0x00, 0x75, 0x3D, 0x00, 0x75, -0x3C, 0x00, 0x90, 0xEA, 0x5C, 0xE0, 0xF8, 0x90, -0xEB, 0x6D, 0xE0, 0x65, 0x18, 0x70, 0x08, 0xA3, -0xE0, 0x65, 0x19, 0x70, 0x03, 0x80, 0x07, 0xA3, -0xA3, 0xD8, 0xEF, 0xC3, 0x80, 0x01, 0xD3, 0x40, -0x0E, 0x75, 0x1C, 0xF8, 0x75, 0x1D, 0xFF, 0x12, -0xE7, 0x77, 0x40, 0x05, 0x12, 0x2F, 0x9E, 0xC3, -0x22, 0x22, 0x20, 0x1F, 0x02, 0xC3, 0x22, 0x30, -0x1E, 0x02, 0x80, 0xF9, 0xD2, 0x1A, 0x75, 0x3F, -0x00, 0x75, 0x3E, 0x00, 0x75, 0x3D, 0x00, 0x75, -0x3C, 0x00, 0x90, 0xEA, 0x5C, 0xE0, 0xF8, 0x90, -0xEB, 0x6D, 0xE0, 0x65, 0x18, 0x70, 0x08, 0xA3, -0xE0, 0x65, 0x19, 0x70, 0x03, 0x80, 0x07, 0xA3, -0xA3, 0xD8, 0xEF, 0xC3, 0x80, 0x01, 0xD3, 0x40, -0x08, 0x12, 0xE6, 0x6F, 0x40, 0x05, 0x12, 0x2F, -0x9E, 0xC3, 0x22, 0x22, 0x20, 0x1F, 0x02, 0xC3, -0x22, 0x30, 0x1E, 0x02, 0x80, 0xF9, 0xC3, 0xE5, -0x3D, 0x13, 0xF5, 0x14, 0xE5, 0x3E, 0x13, 0xF5, -0x15, 0x30, 0x21, 0x39, 0x90, 0xEB, 0x2A, 0xE0, -0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFE, 0xA3, -0xE0, 0xFF, 0x90, 0xEA, 0x47, 0xE0, 0x14, 0xFB, -0x60, 0x12, 0xC3, 0xEC, 0x13, 0xFC, 0xED, 0x13, -0xFD, 0xEE, 0x13, 0xFE, 0xEF, 0x13, 0xFF, 0xC3, -0xEB, 0x13, 0x80, 0xEB, 0x8E, 0x18, 0x8F, 0x19, -0x90, 0xEB, 0x2D, 0xE0, 0xFF, 0x90, 0xEA, 0x47, -0xE0, 0x14, 0x5F, 0xF5, 0x1B, 0xD2, 0x1C, 0xC3, -0x90, 0xEA, 0x47, 0xE0, 0x95, 0x1B, 0xF5, 0x16, -0xE5, 0x14, 0x70, 0x0A, 0xD3, 0xE5, 0x16, 0x95, -0x15, 0x40, 0x03, 0x85, 0x15, 0x16, 0x90, 0xEA, -0x5C, 0xE0, 0xF8, 0x90, 0xEB, 0x6D, 0xE0, 0x65, -0x18, 0x70, 0x08, 0xA3, 0xE0, 0x65, 0x19, 0x70, -0x03, 0x80, 0x07, 0xA3, 0xA3, 0xD8, 0xEF, 0xC3, -0x80, 0x01, 0xD3, 0x50, 0x03, 0x02, 0xE4, 0x34, -0x20, 0x21, 0x2F, 0xC2, 0x42, 0x75, 0x10, 0x00, -0xE5, 0x10, 0x65, 0x1B, 0x70, 0x03, 0x02, 0xE3, -0x7A, 0x12, 0x2F, 0x89, 0x40, 0x03, 0x02, 0xE4, -0x31, 0xE5, 0x10, 0x70, 0x11, 0xC0, 0x1C, 0xC0, -0x1B, 0x75, 0x1B, 0x00, 0x75, 0x1C, 0xEF, 0x12, -0x2F, 0x95, 0xD0, 0x1B, 0xD0, 0x1C, 0x05, 0x10, -0x80, 0xD6, 0x75, 0x17, 0x00, 0x30, 0x21, 0x06, -0xC0, 0x18, 0xC0, 0x19, 0x80, 0x10, 0x75, 0x1C, -0xF8, 0x75, 0x1D, 0xFF, 0xC0, 0x18, 0xC0, 0x19, -0x85, 0x11, 0x18, 0x85, 0x12, 0x19, 0xE5, 0x16, -0xB4, 0x01, 0x0C, 0x12, 0xE5, 0x11, 0x40, 0x13, -0xD0, 0x19, 0xD0, 0x18, 0x02, 0xE4, 0x31, 0x12, -0x2F, 0x92, 0x40, 0x07, 0xD0, 0x19, 0xD0, 0x18, -0x02, 0xE4, 0x31, 0xD0, 0x19, 0xD0, 0x18, 0xE5, -0x10, 0x25, 0x16, 0xF5, 0x10, 0x20, 0x21, 0x3A, -0x90, 0xEA, 0x47, 0xE0, 0x65, 0x10, 0x60, 0x0C, -0x12, 0x2F, 0x89, 0x40, 0x03, 0x02, 0xE4, 0x31, -0x05, 0x10, 0x80, 0xEC, 0x20, 0x42, 0x05, 0x12, -0xE7, 0x77, 0x80, 0x09, 0x75, 0x1B, 0x00, 0x75, -0x1C, 0x7F, 0x12, 0x2F, 0x95, 0x75, 0x17, 0x00, -0x85, 0x11, 0x18, 0x85, 0x12, 0x19, 0x75, 0x1B, -0x00, 0x75, 0x1C, 0xF8, 0x75, 0x1D, 0xFF, 0x12, -0xE6, 0x6F, 0xC3, 0xE5, 0x15, 0x95, 0x16, 0xF5, -0x15, 0xE5, 0x14, 0x94, 0x00, 0xF5, 0x14, 0xE5, -0x15, 0x45, 0x14, 0x60, 0x16, 0x05, 0x19, 0xE5, -0x19, 0x70, 0x02, 0x05, 0x18, 0x05, 0x0D, 0xE5, -0x0D, 0x70, 0x02, 0x05, 0x0C, 0x75, 0x1B, 0x00, -0x02, 0xE3, 0x0F, 0x75, 0x3F, 0x00, 0x75, 0x3E, -0x00, 0x75, 0x3D, 0x00, 0x75, 0x3C, 0x00, 0xD3, -0x22, 0x12, 0x2F, 0x9E, 0x90, 0xFF, 0x09, 0xE0, -0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74, 0x80, -0xF0, 0x75, 0x3F, 0x00, 0xC3, 0xE5, 0x15, 0x33, -0xF5, 0x3E, 0xE5, 0x14, 0x33, 0xF5, 0x3D, 0x75, -0x3C, 0x00, 0xC3, 0x22, 0x75, 0x1A, 0x20, 0x12, -0x2F, 0xA4, 0x40, 0x03, 0x02, 0xE5, 0x0F, 0x79, -0x0F, 0x90, 0xFE, 0x46, 0xE0, 0x54, 0xF0, 0x49, -0xF0, 0x78, 0xD2, 0x12, 0x2F, 0xAA, 0x30, 0x1C, -0x5A, 0x30, 0x2D, 0x05, 0x75, 0x16, 0x01, 0x80, -0x03, 0x75, 0x16, 0x08, 0x75, 0x08, 0x00, 0xE5, -0x08, 0x65, 0x16, 0x70, 0x02, 0x80, 0x55, 0x90, -0xFF, 0x09, 0x30, 0x25, 0x0B, 0xE0, 0x30, 0xE1, -0xF9, 0x90, 0xFF, 0x09, 0xF0, 0xD3, 0x80, 0x01, -0xC3, 0x50, 0x0F, 0xAF, 0x08, 0x7C, 0xF0, 0x7D, -0x00, 0xAB, 0x4D, 0xAA, 0x4C, 0x12, 0x2F, 0xBF, -0x40, 0x10, 0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, -0x06, 0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0, 0x02, -0xE5, 0x0A, 0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, -0x06, 0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0, 0x05, -0x08, 0x80, 0xB4, 0x7C, 0xF0, 0x7D, 0x00, 0x7B, -0x00, 0x7A, 0x02, 0x7F, 0x00, 0x12, 0x2F, 0xBF, -0x40, 0x02, 0x80, 0x2E, 0x20, 0x1D, 0x08, 0x30, -0x25, 0x03, 0x30, 0x24, 0xF7, 0xD2, 0x24, 0x30, -0x24, 0x02, 0xC3, 0x22, 0x79, 0x55, 0x7A, 0x01, -0x12, 0x2F, 0xAD, 0x40, 0x02, 0x80, 0x18, 0x12, -0x2F, 0xB0, 0x30, 0x24, 0x02, 0xC3, 0x22, 0xEF, -0x54, 0xC1, 0x64, 0x80, 0x60, 0x02, 0x80, 0x02, -0xD3, 0x22, 0x79, 0xC3, 0x12, 0x2F, 0x9B, 0xC3, -0x22, 0xC0, 0x16, 0x30, 0x1E, 0x03, 0x02, 0xE5, -0x5C, 0x75, 0x09, 0x00, 0x7C, 0x08, 0x30, 0x2D, -0x02, 0x7C, 0x20, 0x20, 0x25, 0x03, 0x02, 0xE5, -0x5C, 0xC0, 0x04, 0x12, 0xE4, 0x54, 0xD0, 0x04, -0x50, 0x04, 0xD0, 0x16, 0xD3, 0x22, 0xA9, 0x09, -0xE9, 0x54, 0x07, 0x60, 0x0C, 0x90, 0xFE, 0x4C, -0xE0, 0xF0, 0x90, 0xFE, 0x4D, 0xE0, 0xF0, 0x80, -0x09, 0x20, 0x25, 0x03, 0x02, 0xE5, 0x5C, 0x12, -0x2F, 0xB3, 0x05, 0x09, 0xE5, 0x09, 0x6C, 0x60, -0x03, 0x02, 0xE5, 0x23, 0xD0, 0x16, 0xC3, 0x22, -0xC0, 0x03, 0x75, 0x1A, 0x00, 0x12, 0x2F, 0xB6, -0x40, 0x04, 0xD0, 0x03, 0xC3, 0x22, 0xC2, 0x41, -0x79, 0xAA, 0x7A, 0x00, 0x12, 0x2F, 0xAD, 0x50, -0xF1, 0xD0, 0x03, 0x1B, 0x8B, 0x08, 0xC2, 0x40, -0x20, 0x20, 0x08, 0x30, 0x25, 0x03, 0x30, 0x24, -0xF7, 0xD2, 0x24, 0x30, 0x24, 0x02, 0xC3, 0x22, -0x12, 0x2F, 0xB0, 0xC2, 0x20, 0xC2, 0x24, 0xEF, -0x54, 0xE1, 0xFF, 0x30, 0xE0, 0x03, 0x02, 0xE6, -0x6D, 0x20, 0xE6, 0x0F, 0x30, 0xE7, 0x02, 0xD2, -0x40, 0x20, 0xE5, 0x19, 0x64, 0x80, 0x70, 0x03, -0x02, 0xE6, 0x4B, 0x12, 0x2F, 0xB9, 0x40, 0x03, -0x02, 0xE6, 0x68, 0x90, 0xEB, 0xCA, 0xE0, 0x54, -0x15, 0x60, 0x02, 0xD2, 0x41, 0xE5, 0x08, 0x70, -0x0E, 0x20, 0x40, 0x0B, 0x79, 0x33, 0x7A, 0x01, -0x12, 0x2F, 0xAD, 0x40, 0x02, 0xC1, 0x6D, 0x12, -0x2F, 0xBC, 0x40, 0x02, 0xC1, 0x6D, 0x90, 0xEB, -0xDE, 0xE0, 0x54, 0x30, 0x64, 0x30, 0x60, 0x02, -0xC1, 0x6D, 0x79, 0x00, 0x90, 0xFE, 0x46, 0xE0, -0x54, 0xF0, 0x49, 0xF0, 0x79, 0x00, 0x78, 0x2D, -0x12, 0x2F, 0xAA, 0x90, 0xFF, 0x09, 0x30, 0x25, -0x07, 0xE0, 0x30, 0xE5, 0xF9, 0xD3, 0x80, 0x01, -0xC3, 0x40, 0x02, 0x80, 0x5B, 0xC0, 0x01, 0x7E, -0xF4, 0x7F, 0x00, 0x7D, 0x00, 0x7C, 0x02, 0x12, -0x2F, 0xC2, 0xD0, 0x01, 0x40, 0x09, 0x09, 0xE9, -0x64, 0x20, 0x70, 0xD2, 0x02, 0xE6, 0x68, 0x90, -0xFF, 0x2A, 0x74, 0x02, 0xF0, 0xA3, 0x74, 0x00, -0xF0, 0x20, 0x1D, 0x08, 0x30, 0x25, 0x03, 0x30, -0x24, 0xF7, 0xD2, 0x24, 0x30, 0x24, 0x02, 0xC3, -0x22, 0x30, 0x40, 0x02, 0x80, 0x05, 0x15, 0x08, -0x02, 0xE5, 0x80, 0x30, 0x41, 0x16, 0x79, 0xCC, -0x12, 0x2F, 0x9B, 0xC2, 0x1A, 0x90, 0xEA, 0x47, -0xE0, 0x65, 0x1B, 0x60, 0x07, 0x12, 0x2F, 0x8C, -0x05, 0x1B, 0x80, 0xF1, 0xD2, 0x1A, 0xD3, 0x22, -0x79, 0xC3, 0x12, 0x2F, 0x9B, 0xC3, 0x22, 0xC0, -0x08, 0x30, 0x1E, 0x02, 0x80, 0x33, 0x75, 0x1A, -0x40, 0x75, 0x1D, 0xFF, 0x75, 0x08, 0x00, 0x20, -0x25, 0x02, 0x80, 0x25, 0x12, 0xE6, 0xAD, 0x50, -0x04, 0xD0, 0x08, 0xD3, 0x22, 0xA9, 0x08, 0xE9, -0x54, 0x07, 0x60, 0x02, 0x80, 0x08, 0x20, 0x25, -0x02, 0x80, 0x0E, 0x12, 0x2F, 0xB3, 0x05, 0x08, -0xE5, 0x08, 0x64, 0x20, 0x60, 0x03, 0x02, 0xE6, -0x7F, 0xD0, 0x08, 0xC3, 0x22, 0x90, 0xFE, 0x4C, -0xE0, 0xF0, 0x90, 0xFE, 0x4D, 0xE0, 0xF0, 0xC2, -0x1D, 0xC2, 0x24, 0x90, 0xFE, 0x50, 0x74, 0x87, -0xF0, 0x90, 0xFE, 0x40, 0x74, 0x00, 0xF0, 0x90, -0xFE, 0x40, 0x74, 0x00, 0xF0, 0x90, 0xFE, 0x40, -0x74, 0x10, 0xF0, 0x90, 0xFE, 0x40, 0x74, 0x0F, -0xF0, 0x90, 0xFE, 0x57, 0x74, 0x0F, 0xF0, 0x90, -0xFE, 0x44, 0x74, 0x01, 0xF0, 0x20, 0x1D, 0x08, -0x30, 0x25, 0x03, 0x30, 0x24, 0xF7, 0xD2, 0x24, -0x30, 0x24, 0x02, 0xC3, 0x22, 0x79, 0x00, 0x90, -0xFE, 0x46, 0xE0, 0x54, 0xF0, 0x49, 0xF0, 0x90, -0xFE, 0x4D, 0x30, 0x25, 0x07, 0xE0, 0x30, 0xE5, -0xF9, 0xD3, 0x80, 0x01, 0xC3, 0x40, 0x01, 0x22, -0x78, 0xB4, 0x12, 0x2F, 0xAA, 0x90, 0xEA, 0x44, -0xE0, 0x90, 0xFE, 0x40, 0xF0, 0x78, 0x17, 0x7D, -0x09, 0xE6, 0x08, 0x90, 0xFE, 0x40, 0xF0, 0xDD, -0xF8, 0x74, 0xFF, 0x90, 0xFE, 0x40, 0xF0, 0xF0, -0xF0, 0xF0, 0xC2, 0x1D, 0xC2, 0x24, 0xF0, 0x20, -0x1D, 0x08, 0x30, 0x25, 0x03, 0x30, 0x24, 0xF7, -0xD2, 0x24, 0x30, 0x24, 0x02, 0xC3, 0x22, 0x90, -0xFE, 0x4E, 0x30, 0x25, 0x07, 0xE0, 0x30, 0xE6, -0xF9, 0xD3, 0x80, 0x01, 0xC3, 0x79, 0x55, 0x7A, -0x01, 0x12, 0x2F, 0xAD, 0x40, 0x02, 0x80, 0x13, -0x12, 0x2F, 0xB0, 0x30, 0x24, 0x02, 0xC3, 0x22, -0xEF, 0x20, 0xE0, 0x07, 0x54, 0xC0, 0xB4, 0x80, -0x02, 0x80, 0x02, 0xC3, 0x22, 0xD3, 0x22, 0x30, -0x1E, 0x02, 0x80, 0x0A, 0x12, 0xE7, 0x88, 0x40, -0x03, 0x02, 0xE7, 0x86, 0xD3, 0x22, 0xC3, 0x22, -0xC0, 0x08, 0x75, 0x08, 0x00, 0x20, 0x25, 0x02, -0x80, 0x25, 0x12, 0x2F, 0xA1, 0x50, 0x03, 0xD0, -0x08, 0x22, 0xA9, 0x08, 0xE9, 0x54, 0x07, 0x60, -0x02, 0x80, 0x09, 0xA2, 0x25, 0x40, 0x02, 0x80, -0x0E, 0x12, 0x2F, 0xB3, 0x05, 0x08, 0xE5, 0x08, -0x64, 0x20, 0x60, 0x03, 0x02, 0xE7, 0x8D, 0xD0, -0x08, 0xC3, 0x22, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x4D, 0x53, 0x2D, 0x52, 0x57, 0x20, 0x20, 0x20, -0x20, 0x20, 0x20, 0x31, 0x30, 0x30, 0x30, 0x30 }; static BYTE SM_Init[] = { 0x7B, 0x09, 0x7C, 0xF0, 0x7D, 0x10, 0x7E, 0xE9, diff --git a/drivers/staging/keucr/ms.c b/drivers/staging/keucr/ms.c deleted file mode 100644 index 087ad73ff70f..000000000000 --- a/drivers/staging/keucr/ms.c +++ /dev/null @@ -1,1034 +0,0 @@ -#include -#include - -#include "usb.h" -#include "scsiglue.h" -#include "transport.h" -#include "ms.h" - -/* - * MS_ReaderCopyBlock() - */ -int MS_ReaderCopyBlock(struct us_data *us, WORD oldphy, WORD newphy, - WORD PhyBlockAddr, BYTE PageNum, PBYTE buf, WORD len) -{ - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result; - - /* printk(KERN_INFO "MS_ReaderCopyBlock --- PhyBlockAddr = %x, - PageNum = %x\n", PhyBlockAddr, PageNum); */ - result = ENE_LoadBinCode(us, MS_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = 0x200*len; - bcb->Flags = 0x00; - bcb->CDB[0] = 0xF0; - bcb->CDB[1] = 0x08; - bcb->CDB[4] = (BYTE)(oldphy); - bcb->CDB[3] = (BYTE)(oldphy>>8); - bcb->CDB[2] = 0; /* (BYTE)(oldphy>>16) */ - bcb->CDB[7] = (BYTE)(newphy); - bcb->CDB[6] = (BYTE)(newphy>>8); - bcb->CDB[5] = 0; /* (BYTE)(newphy>>16) */ - bcb->CDB[9] = (BYTE)(PhyBlockAddr); - bcb->CDB[8] = (BYTE)(PhyBlockAddr>>8); - bcb->CDB[10] = PageNum; - - result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - return USB_STOR_TRANSPORT_GOOD; -} - -/* - * MS_ReaderReadPage() - */ -int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, - BYTE PageNum, PDWORD PageBuf, MS_LibTypeExtdat *ExtraDat) -{ - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result; - BYTE ExtBuf[4]; - DWORD bn = PhyBlockAddr * 0x20 + PageNum; - - /* printk(KERN_INFO "MS --- MS_ReaderReadPage, - PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */ - - result = ENE_LoadBinCode(us, MS_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - /* Read Page Data */ - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = 0x200; - bcb->Flags = 0x80; - bcb->CDB[0] = 0xF1; - bcb->CDB[1] = 0x02; - bcb->CDB[5] = (BYTE)(bn); - bcb->CDB[4] = (BYTE)(bn>>8); - bcb->CDB[3] = (BYTE)(bn>>16); - bcb->CDB[2] = (BYTE)(bn>>24); - - result = ENE_SendScsiCmd(us, FDIR_READ, PageBuf, 0); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - /* Read Extra Data */ - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = 0x4; - bcb->Flags = 0x80; - bcb->CDB[0] = 0xF1; - bcb->CDB[1] = 0x03; - bcb->CDB[5] = (BYTE)(PageNum); - bcb->CDB[4] = (BYTE)(PhyBlockAddr); - bcb->CDB[3] = (BYTE)(PhyBlockAddr>>8); - bcb->CDB[2] = (BYTE)(PhyBlockAddr>>16); - bcb->CDB[6] = 0x01; - - result = ENE_SendScsiCmd(us, FDIR_READ, &ExtBuf, 0); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - ExtraDat->reserved = 0; - ExtraDat->intr = 0x80; /* Not yet,fireware support */ - ExtraDat->status0 = 0x10; /* Not yet,fireware support */ - ExtraDat->status1 = 0x00; /* Not yet,fireware support */ - ExtraDat->ovrflg = ExtBuf[0]; - ExtraDat->mngflg = ExtBuf[1]; - ExtraDat->logadr = MemStickLogAddr(ExtBuf[2], ExtBuf[3]); - - return USB_STOR_TRANSPORT_GOOD; -} - -/* - * MS_ReaderEraseBlock() - */ -int MS_ReaderEraseBlock(struct us_data *us, DWORD PhyBlockAddr) -{ - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result; - DWORD bn = PhyBlockAddr; - - /* printk(KERN_INFO "MS --- MS_ReaderEraseBlock, - PhyBlockAddr = %x\n", PhyBlockAddr); */ - result = ENE_LoadBinCode(us, MS_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = 0x200; - bcb->Flags = 0x80; - bcb->CDB[0] = 0xF2; - bcb->CDB[1] = 0x06; - bcb->CDB[4] = (BYTE)(bn); - bcb->CDB[3] = (BYTE)(bn>>8); - bcb->CDB[2] = (BYTE)(bn>>16); - - result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - return USB_STOR_TRANSPORT_GOOD; -} - -/* - * MS_CardInit() - */ -int MS_CardInit(struct us_data *us) -{ - DWORD result = 0; - WORD TmpBlock; - PBYTE PageBuffer0 = NULL, PageBuffer1 = NULL; - MS_LibTypeExtdat extdat; - WORD btBlk1st, btBlk2nd; - DWORD btBlk1stErred; - - printk(KERN_INFO "MS_CardInit start\n"); - - MS_LibFreeAllocatedArea(us); - - PageBuffer0 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); - PageBuffer1 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); - if ((PageBuffer0 == NULL) || (PageBuffer1 == NULL)) { - result = MS_NO_MEMORY_ERROR; - goto exit; - } - - btBlk1st = btBlk2nd = MS_LB_NOT_USED; - btBlk1stErred = 0; - - for (TmpBlock = 0; TmpBlock < MS_MAX_INITIAL_ERROR_BLOCKS+2; - TmpBlock++) { - switch (MS_ReaderReadPage(us, TmpBlock, 0, - (DWORD *)PageBuffer0, &extdat)) { - case MS_STATUS_SUCCESS: - break; - case MS_STATUS_INT_ERROR: - break; - case MS_STATUS_ERROR: - default: - continue; - } - - if ((extdat.ovrflg & MS_REG_OVR_BKST) == MS_REG_OVR_BKST_NG) - continue; - - if (((extdat.mngflg & MS_REG_MNG_SYSFLG) == MS_REG_MNG_SYSFLG_USER) || - (be16_to_cpu(((MemStickBootBlockPage0 *)PageBuffer0)->header.wBlockID) != MS_BOOT_BLOCK_ID) || - (be16_to_cpu(((MemStickBootBlockPage0 *)PageBuffer0)->header.wFormatVersion) != MS_BOOT_BLOCK_FORMAT_VERSION) || - (((MemStickBootBlockPage0 *)PageBuffer0)->header.bNumberOfDataEntry != MS_BOOT_BLOCK_DATA_ENTRIES)) - continue; - - if (btBlk1st != MS_LB_NOT_USED) { - btBlk2nd = TmpBlock; - break; - } - - btBlk1st = TmpBlock; - memcpy(PageBuffer1, PageBuffer0, MS_BYTES_PER_PAGE); - if (extdat.status1 & - (MS_REG_ST1_DTER | MS_REG_ST1_EXER | MS_REG_ST1_FGER)) - btBlk1stErred = 1; - } - - if (btBlk1st == MS_LB_NOT_USED) { - result = MS_STATUS_ERROR; - goto exit; - } - - /* write protect */ - if ((extdat.status0 & MS_REG_ST0_WP) == MS_REG_ST0_WP_ON) - MS_LibCtrlSet(us, MS_LIB_CTRL_WRPROTECT); - - result = MS_STATUS_ERROR; - /* 1st Boot Block */ - if (btBlk1stErred == 0) - result = MS_LibProcessBootBlock(us, btBlk1st, PageBuffer1); - /* 1st */ - /* 2nd Boot Block */ - if (result && (btBlk2nd != MS_LB_NOT_USED)) - result = MS_LibProcessBootBlock(us, btBlk2nd, PageBuffer0); - - if (result) { - result = MS_STATUS_ERROR; - goto exit; - } - - for (TmpBlock = 0; TmpBlock < btBlk1st; TmpBlock++) - us->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR; - - us->MS_Lib.Phy2LogMap[btBlk1st] = MS_LB_BOOT_BLOCK; - - if (btBlk2nd != MS_LB_NOT_USED) { - for (TmpBlock = btBlk1st + 1; TmpBlock < btBlk2nd; TmpBlock++) - us->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR; - us->MS_Lib.Phy2LogMap[btBlk2nd] = MS_LB_BOOT_BLOCK; - } - - result = MS_LibScanLogicalBlockNumber(us, btBlk1st); - if (result) - goto exit; - - for (TmpBlock = MS_PHYSICAL_BLOCKS_PER_SEGMENT; - TmpBlock < us->MS_Lib.NumberOfPhyBlock; - TmpBlock += MS_PHYSICAL_BLOCKS_PER_SEGMENT) { - if (MS_CountFreeBlock(us, TmpBlock) == 0) { - MS_LibCtrlSet(us, MS_LIB_CTRL_WRPROTECT); - break; - } - } - - /* write */ - if (MS_LibAllocWriteBuf(us)) { - result = MS_NO_MEMORY_ERROR; - goto exit; - } - - result = MS_STATUS_SUCCESS; - -exit: - kfree(PageBuffer1); - kfree(PageBuffer0); - - printk(KERN_INFO "MS_CardInit end\n"); - return result; -} - -/* - * MS_LibCheckDisableBlock() - */ -int MS_LibCheckDisableBlock(struct us_data *us, WORD PhyBlock) -{ - PWORD PageBuf = NULL; - DWORD result = MS_STATUS_SUCCESS; - DWORD blk, index = 0; - MS_LibTypeExtdat extdat; - - PageBuf = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); - if (PageBuf == NULL) { - result = MS_NO_MEMORY_ERROR; - goto exit; - } - - MS_ReaderReadPage(us, PhyBlock, 1, (DWORD *)PageBuf, &extdat); - do { - blk = be16_to_cpu(PageBuf[index]); - if (blk == MS_LB_NOT_USED) - break; - if (blk == us->MS_Lib.Log2PhyMap[0]) { - result = MS_ERROR_FLASH_READ; - break; - } - index++; - } while (1); - -exit: - kfree(PageBuf); - return result; -} - -/* - * MS_LibFreeAllocatedArea() - */ -void MS_LibFreeAllocatedArea(struct us_data *us) -{ - MS_LibFreeWriteBuf(us); - MS_LibFreeLogicalMap(us); - - us->MS_Lib.flags = 0; - us->MS_Lib.BytesPerSector = 0; - us->MS_Lib.SectorsPerCylinder = 0; - - us->MS_Lib.cardType = 0; - us->MS_Lib.blockSize = 0; - us->MS_Lib.PagesPerBlock = 0; - - us->MS_Lib.NumberOfPhyBlock = 0; - us->MS_Lib.NumberOfLogBlock = 0; -} - -/* - * MS_LibFreeWriteBuf() - */ -void MS_LibFreeWriteBuf(struct us_data *us) -{ - us->MS_Lib.wrtblk = (WORD)-1; /* set to -1 */ - - /* memset((fdoExt)->MS_Lib.pagemap, 0, - sizeof((fdoExt)->MS_Lib.pagemap)) */ - MS_LibClearPageMap(us); - - if (us->MS_Lib.blkpag) { - kfree((BYTE *)(us->MS_Lib.blkpag)); /* Arnold test ... */ - us->MS_Lib.blkpag = NULL; - } - - if (us->MS_Lib.blkext) { - kfree((BYTE *)(us->MS_Lib.blkext)); /* Arnold test ... */ - us->MS_Lib.blkext = NULL; - } -} - -/* - * MS_LibFreeLogicalMap() - */ -int MS_LibFreeLogicalMap(struct us_data *us) -{ - kfree(us->MS_Lib.Phy2LogMap); - us->MS_Lib.Phy2LogMap = NULL; - - kfree(us->MS_Lib.Log2PhyMap); - us->MS_Lib.Log2PhyMap = NULL; - - return 0; -} - -/* - * MS_LibProcessBootBlock() - */ -int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData) -{ - MemStickBootBlockSysEnt *SysEntry; - MemStickBootBlockSysInf *SysInfo; - DWORD i, result; - BYTE PageNumber; - BYTE *PageBuffer; - MS_LibTypeExtdat ExtraData; - - - PageBuffer = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); - if (PageBuffer == NULL) - return (DWORD)-1; - - result = (DWORD)-1; - - SysInfo = &(((MemStickBootBlockPage0 *)PageData)->sysinf); - - if ((SysInfo->bMsClass != MS_SYSINF_MSCLASS_TYPE_1) || - (be16_to_cpu(SysInfo->wPageSize) != MS_SYSINF_PAGE_SIZE) || - ((SysInfo->bSecuritySupport & MS_SYSINF_SECURITY) == MS_SYSINF_SECURITY_SUPPORT) || - (SysInfo->bReserved1 != MS_SYSINF_RESERVED1) || - (SysInfo->bReserved2 != MS_SYSINF_RESERVED2) || - (SysInfo->bFormatType != MS_SYSINF_FORMAT_FAT) || - (SysInfo->bUsage != MS_SYSINF_USAGE_GENERAL)) - goto exit; - - switch (us->MS_Lib.cardType = SysInfo->bCardType) { - case MS_SYSINF_CARDTYPE_RDONLY: - MS_LibCtrlSet(us, MS_LIB_CTRL_RDONLY); - break; - case MS_SYSINF_CARDTYPE_RDWR: - MS_LibCtrlReset(us, MS_LIB_CTRL_RDONLY); - break; - case MS_SYSINF_CARDTYPE_HYBRID: - default: - goto exit; - } - - us->MS_Lib.blockSize = be16_to_cpu(SysInfo->wBlockSize); - us->MS_Lib.NumberOfPhyBlock = be16_to_cpu(SysInfo->wBlockNumber); - us->MS_Lib.NumberOfLogBlock = be16_to_cpu(SysInfo->wTotalBlockNumber) - -2; - us->MS_Lib.PagesPerBlock = us->MS_Lib.blockSize * SIZE_OF_KIRO / - MS_BYTES_PER_PAGE; - us->MS_Lib.NumberOfSegment = us->MS_Lib.NumberOfPhyBlock / - MS_PHYSICAL_BLOCKS_PER_SEGMENT; - us->MS_Model = be16_to_cpu(SysInfo->wMemorySize); - - /*Allocate to all number of logicalblock and physicalblock */ - if (MS_LibAllocLogicalMap(us)) - goto exit; - - /* Mark the book block */ - MS_LibSetBootBlockMark(us, PhyBlock); - - SysEntry = &(((MemStickBootBlockPage0 *)PageData)->sysent); - - for (i = 0; i < MS_NUMBER_OF_SYSTEM_ENTRY; i++) { - DWORD EntryOffset, EntrySize; - - EntryOffset = be32_to_cpu(SysEntry->entry[i].dwStart); - - if (EntryOffset == 0xffffff) - continue; - EntrySize = be32_to_cpu(SysEntry->entry[i].dwSize); - - if (EntrySize == 0) - continue; - - if (EntryOffset + MS_BYTES_PER_PAGE + EntrySize > - us->MS_Lib.blockSize * (DWORD)SIZE_OF_KIRO) - continue; - - if (i == 0) { - BYTE PrevPageNumber = 0; - WORD phyblk; - - if (SysEntry->entry[i].bType != - MS_SYSENT_TYPE_INVALID_BLOCK) - goto exit; - - while (EntrySize > 0) { - - PageNumber = (BYTE)(EntryOffset / - MS_BYTES_PER_PAGE + 1); - if (PageNumber != PrevPageNumber) { - switch (MS_ReaderReadPage(us, PhyBlock, - PageNumber, (DWORD *)PageBuffer, - &ExtraData)) { - case MS_STATUS_SUCCESS: - break; - case MS_STATUS_WRITE_PROTECT: - case MS_ERROR_FLASH_READ: - case MS_STATUS_ERROR: - default: - goto exit; - } - - PrevPageNumber = PageNumber; - } - - phyblk = be16_to_cpu(*(WORD *)(PageBuffer + - (EntryOffset % MS_BYTES_PER_PAGE))); - if (phyblk < 0x0fff) - MS_LibSetInitialErrorBlock(us, phyblk); - - EntryOffset += 2; - EntrySize -= 2; - } - } else if (i == 1) { /* CIS/IDI */ - MemStickBootBlockIDI *idi; - - if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_CIS_IDI) - goto exit; - - switch (MS_ReaderReadPage(us, PhyBlock, - (BYTE)(EntryOffset / MS_BYTES_PER_PAGE + 1), - (DWORD *)PageBuffer, &ExtraData)) { - case MS_STATUS_SUCCESS: - break; - case MS_STATUS_WRITE_PROTECT: - case MS_ERROR_FLASH_READ: - case MS_STATUS_ERROR: - default: - goto exit; - } - - idi = &((MemStickBootBlockCIS_IDI *)(PageBuffer + - (EntryOffset % MS_BYTES_PER_PAGE)))->idi.idi; - if (le16_to_cpu(idi->wIDIgeneralConfiguration) != - MS_IDI_GENERAL_CONF) - goto exit; - - us->MS_Lib.BytesPerSector = - le16_to_cpu(idi->wIDIbytesPerSector); - if (us->MS_Lib.BytesPerSector != MS_BYTES_PER_PAGE) - goto exit; - } - } /* End for .. */ - - result = 0; - -exit: - if (result) - MS_LibFreeLogicalMap(us); - - kfree(PageBuffer); - - result = 0; - return result; -} - -/* - * MS_LibAllocLogicalMap() - */ -int MS_LibAllocLogicalMap(struct us_data *us) -{ - DWORD i; - - - us->MS_Lib.Phy2LogMap = kmalloc(us->MS_Lib.NumberOfPhyBlock * - sizeof(WORD), GFP_KERNEL); - us->MS_Lib.Log2PhyMap = kmalloc(us->MS_Lib.NumberOfLogBlock * - sizeof(WORD), GFP_KERNEL); - - if ((us->MS_Lib.Phy2LogMap == NULL) || - (us->MS_Lib.Log2PhyMap == NULL)) { - MS_LibFreeLogicalMap(us); - return (DWORD)-1; - } - - for (i = 0; i < us->MS_Lib.NumberOfPhyBlock; i++) - us->MS_Lib.Phy2LogMap[i] = MS_LB_NOT_USED; - - for (i = 0; i < us->MS_Lib.NumberOfLogBlock; i++) - us->MS_Lib.Log2PhyMap[i] = MS_LB_NOT_USED; - - return 0; -} - -/* - * MS_LibSetBootBlockMark() - */ -int MS_LibSetBootBlockMark(struct us_data *us, WORD phyblk) -{ - return MS_LibSetLogicalBlockMark(us, phyblk, MS_LB_BOOT_BLOCK); -} - -/* - * MS_LibSetLogicalBlockMark() - */ -int MS_LibSetLogicalBlockMark(struct us_data *us, WORD phyblk, WORD mark) -{ - if (phyblk >= us->MS_Lib.NumberOfPhyBlock) - return (DWORD)-1; - - us->MS_Lib.Phy2LogMap[phyblk] = mark; - - return 0; -} - -/* - * MS_LibSetInitialErrorBlock() - */ -int MS_LibSetInitialErrorBlock(struct us_data *us, WORD phyblk) -{ - return MS_LibSetLogicalBlockMark(us, phyblk, MS_LB_INITIAL_ERROR); -} - -/* - * MS_LibScanLogicalBlockNumber() - */ -int MS_LibScanLogicalBlockNumber(struct us_data *us, WORD btBlk1st) -{ - WORD PhyBlock, newblk, i; - WORD LogStart, LogEnde; - MS_LibTypeExtdat extdat; - BYTE buf[0x200]; - DWORD count = 0, index = 0; - - for (PhyBlock = 0; PhyBlock < us->MS_Lib.NumberOfPhyBlock;) { - MS_LibPhy2LogRange(PhyBlock, &LogStart, &LogEnde); - - for (i = 0; i < MS_PHYSICAL_BLOCKS_PER_SEGMENT; - i++, PhyBlock++) { - switch (MS_LibConv2Logical(us, PhyBlock)) { - case MS_STATUS_ERROR: - continue; - default: - break; - } - - if (count == PhyBlock) { - MS_LibReadExtraBlock(us, PhyBlock, - 0, 0x80, &buf); - count += 0x80; - } - index = (PhyBlock % 0x80) * 4; - - extdat.ovrflg = buf[index]; - extdat.mngflg = buf[index+1]; - extdat.logadr = MemStickLogAddr(buf[index+2], - buf[index+3]); - - if ((extdat.ovrflg & MS_REG_OVR_BKST) != - MS_REG_OVR_BKST_OK) { - MS_LibSetAcquiredErrorBlock(us, PhyBlock); - continue; - } - - if ((extdat.mngflg & MS_REG_MNG_ATFLG) == - MS_REG_MNG_ATFLG_ATTBL) { - MS_LibErasePhyBlock(us, PhyBlock); - continue; - } - - if (extdat.logadr != MS_LB_NOT_USED) { - if ((extdat.logadr < LogStart) || - (LogEnde <= extdat.logadr)) { - MS_LibErasePhyBlock(us, PhyBlock); - continue; - } - - newblk = MS_LibConv2Physical(us, extdat.logadr); - - if (newblk != MS_LB_NOT_USED) { - if (extdat.logadr == 0) { - MS_LibSetLogicalPair(us, - extdat.logadr, - PhyBlock); - if (MS_LibCheckDisableBlock(us, - btBlk1st)) { - MS_LibSetLogicalPair(us, - extdat.logadr, newblk); - continue; - } - } - - MS_LibReadExtra(us, newblk, 0, &extdat); - if ((extdat.ovrflg & MS_REG_OVR_UDST) == - MS_REG_OVR_UDST_UPDATING) { - MS_LibErasePhyBlock(us, - PhyBlock); - continue; - } else { - MS_LibErasePhyBlock(us, newblk); - } - } - - MS_LibSetLogicalPair(us, extdat.logadr, - PhyBlock); - } - } - } /* End for ... */ - - return MS_STATUS_SUCCESS; -} - -/* - * MS_LibAllocWriteBuf() - */ -int MS_LibAllocWriteBuf(struct us_data *us) -{ - us->MS_Lib.wrtblk = (WORD)-1; - - us->MS_Lib.blkpag = kmalloc(us->MS_Lib.PagesPerBlock * - us->MS_Lib.BytesPerSector, GFP_KERNEL); - us->MS_Lib.blkext = kmalloc(us->MS_Lib.PagesPerBlock * - sizeof(MS_LibTypeExtdat), GFP_KERNEL); - - if ((us->MS_Lib.blkpag == NULL) || (us->MS_Lib.blkext == NULL)) { - MS_LibFreeWriteBuf(us); - return (DWORD)-1; - } - - MS_LibClearWriteBuf(us); - - return 0; -} - -/* - * MS_LibClearWriteBuf() - */ -void MS_LibClearWriteBuf(struct us_data *us) -{ - int i; - - us->MS_Lib.wrtblk = (WORD)-1; - MS_LibClearPageMap(us); - - if (us->MS_Lib.blkpag) - memset(us->MS_Lib.blkpag, 0xff, - us->MS_Lib.PagesPerBlock * us->MS_Lib.BytesPerSector); - - if (us->MS_Lib.blkext) { - for (i = 0; i < us->MS_Lib.PagesPerBlock; i++) { - us->MS_Lib.blkext[i].status1 = MS_REG_ST1_DEFAULT; - us->MS_Lib.blkext[i].ovrflg = MS_REG_OVR_DEFAULT; - us->MS_Lib.blkext[i].mngflg = MS_REG_MNG_DEFAULT; - us->MS_Lib.blkext[i].logadr = MS_LB_NOT_USED; - } - } -} - -/* - * MS_LibPhy2LogRange() - */ -void MS_LibPhy2LogRange(WORD PhyBlock, WORD *LogStart, WORD *LogEnde) -{ - PhyBlock /= MS_PHYSICAL_BLOCKS_PER_SEGMENT; - - if (PhyBlock) { - *LogStart = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT + - (PhyBlock - 1) * MS_LOGICAL_BLOCKS_PER_SEGMENT;/*496*/ - *LogEnde = *LogStart + MS_LOGICAL_BLOCKS_PER_SEGMENT;/*496*/ - } else { - *LogStart = 0; - *LogEnde = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT;/*494*/ - } -} - -/* - * MS_LibReadExtraBlock() - */ -int MS_LibReadExtraBlock(struct us_data *us, DWORD PhyBlock, - BYTE PageNum, BYTE blen, void *buf) -{ - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result; - - /* printk("MS_LibReadExtraBlock --- PhyBlock = %x, - PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen); */ - - /* Read Extra Data */ - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = 0x4 * blen; - bcb->Flags = 0x80; - bcb->CDB[0] = 0xF1; - bcb->CDB[1] = 0x03; - bcb->CDB[5] = (BYTE)(PageNum); - bcb->CDB[4] = (BYTE)(PhyBlock); - bcb->CDB[3] = (BYTE)(PhyBlock>>8); - bcb->CDB[2] = (BYTE)(PhyBlock>>16); - bcb->CDB[6] = blen; - - result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - return USB_STOR_TRANSPORT_GOOD; -} - -/* - * MS_LibReadExtra() - */ -int MS_LibReadExtra(struct us_data *us, DWORD PhyBlock, - BYTE PageNum, MS_LibTypeExtdat *ExtraDat) -{ - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result; - BYTE ExtBuf[4]; - - /* printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n" - , PhyBlock, PageNum); */ - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = 0x4; - bcb->Flags = 0x80; - bcb->CDB[0] = 0xF1; - bcb->CDB[1] = 0x03; - bcb->CDB[5] = (BYTE)(PageNum); - bcb->CDB[4] = (BYTE)(PhyBlock); - bcb->CDB[3] = (BYTE)(PhyBlock>>8); - bcb->CDB[2] = (BYTE)(PhyBlock>>16); - bcb->CDB[6] = 0x01; - - result = ENE_SendScsiCmd(us, FDIR_READ, &ExtBuf, 0); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - ExtraDat->reserved = 0; - ExtraDat->intr = 0x80; /* Not yet, waiting for fireware support */ - ExtraDat->status0 = 0x10; /* Not yet, waiting for fireware support */ - ExtraDat->status1 = 0x00; /* Not yet, waiting for fireware support */ - ExtraDat->ovrflg = ExtBuf[0]; - ExtraDat->mngflg = ExtBuf[1]; - ExtraDat->logadr = MemStickLogAddr(ExtBuf[2], ExtBuf[3]); - - return USB_STOR_TRANSPORT_GOOD; -} - -/* - * MS_LibSetAcquiredErrorBlock() - */ -int MS_LibSetAcquiredErrorBlock(struct us_data *us, WORD phyblk) -{ - WORD log; - - if (phyblk >= us->MS_Lib.NumberOfPhyBlock) - return (DWORD)-1; - - log = us->MS_Lib.Phy2LogMap[phyblk]; - - if (log < us->MS_Lib.NumberOfLogBlock) - us->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED; - - if (us->MS_Lib.Phy2LogMap[phyblk] != MS_LB_INITIAL_ERROR) - us->MS_Lib.Phy2LogMap[phyblk] = MS_LB_ACQUIRED_ERROR; - - return 0; -} - -/* - * MS_LibErasePhyBlock() - */ -int MS_LibErasePhyBlock(struct us_data *us, WORD phyblk) -{ - WORD log; - - if (phyblk >= us->MS_Lib.NumberOfPhyBlock) - return MS_STATUS_ERROR; - - log = us->MS_Lib.Phy2LogMap[phyblk]; - - if (log < us->MS_Lib.NumberOfLogBlock) - us->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED; - - us->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED; - - if (MS_LibIsWritable(us)) { - switch (MS_ReaderEraseBlock(us, phyblk)) { - case MS_STATUS_SUCCESS: - us->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED_ERASED; - return MS_STATUS_SUCCESS; - case MS_ERROR_FLASH_ERASE: - case MS_STATUS_INT_ERROR: - MS_LibErrorPhyBlock(us, phyblk); - return MS_ERROR_FLASH_ERASE; - case MS_STATUS_ERROR: - default: - MS_LibCtrlSet(us, MS_LIB_CTRL_RDONLY); - MS_LibSetAcquiredErrorBlock(us, phyblk); - return MS_STATUS_ERROR; - } - } - - MS_LibSetAcquiredErrorBlock(us, phyblk); - - return MS_STATUS_SUCCESS; -} - -/* - * MS_LibErrorPhyBlock() - */ -int MS_LibErrorPhyBlock(struct us_data *us, WORD phyblk) -{ - if (phyblk >= us->MS_Lib.NumberOfPhyBlock) - return MS_STATUS_ERROR; - - MS_LibSetAcquiredErrorBlock(us, phyblk); - - if (MS_LibIsWritable(us)) - return MS_LibOverwriteExtra(us, phyblk, 0, - (BYTE)(~MS_REG_OVR_BKST & BYTE_MASK)); - - - return MS_STATUS_SUCCESS; -} - -/* - * MS_LibOverwriteExtra() - */ -int MS_LibOverwriteExtra(struct us_data *us, DWORD PhyBlockAddr, - BYTE PageNum, BYTE OverwriteFlag) -{ - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result; - - /* printk("MS --- MS_LibOverwriteExtra, \ - PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */ - result = ENE_LoadBinCode(us, MS_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = 0x4; - bcb->Flags = 0x80; - bcb->CDB[0] = 0xF2; - bcb->CDB[1] = 0x05; - bcb->CDB[5] = (BYTE)(PageNum); - bcb->CDB[4] = (BYTE)(PhyBlockAddr); - bcb->CDB[3] = (BYTE)(PhyBlockAddr>>8); - bcb->CDB[2] = (BYTE)(PhyBlockAddr>>16); - bcb->CDB[6] = OverwriteFlag; - bcb->CDB[7] = 0xFF; - bcb->CDB[8] = 0xFF; - bcb->CDB[9] = 0xFF; - - result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0); - if (result != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - return USB_STOR_TRANSPORT_GOOD; -} - -/* - * MS_LibForceSetLogicalPair() - */ -int MS_LibForceSetLogicalPair(struct us_data *us, WORD logblk, WORD phyblk) -{ - if (logblk == MS_LB_NOT_USED) - return 0; - - if ((logblk >= us->MS_Lib.NumberOfLogBlock) || - (phyblk >= us->MS_Lib.NumberOfPhyBlock)) - return (DWORD)-1; - - us->MS_Lib.Phy2LogMap[phyblk] = logblk; - us->MS_Lib.Log2PhyMap[logblk] = phyblk; - - return 0; -} - -/* - * MS_LibSetLogicalPair() - */ -int MS_LibSetLogicalPair(struct us_data *us, WORD logblk, WORD phyblk) -{ - if ((logblk >= us->MS_Lib.NumberOfLogBlock) || - (phyblk >= us->MS_Lib.NumberOfPhyBlock)) - return (DWORD)-1; - - us->MS_Lib.Phy2LogMap[phyblk] = logblk; - us->MS_Lib.Log2PhyMap[logblk] = phyblk; - - return 0; -} - -/* - * MS_CountFreeBlock() - */ -int MS_CountFreeBlock(struct us_data *us, WORD PhyBlock) -{ - DWORD Ende, Count; - - Ende = PhyBlock + MS_PHYSICAL_BLOCKS_PER_SEGMENT; - for (Count = 0; PhyBlock < Ende; PhyBlock++) { - switch (us->MS_Lib.Phy2LogMap[PhyBlock]) { - case MS_LB_NOT_USED: - case MS_LB_NOT_USED_ERASED: - Count++; - default: - break; - } - } - - return Count; -} - -/* - * MS_LibSearchBlockFromPhysical() - */ -int MS_LibSearchBlockFromPhysical(struct us_data *us, WORD phyblk) -{ - WORD Newblk; - WORD blk; - MS_LibTypeExtdat extdat; - - if (phyblk >= us->MS_Lib.NumberOfPhyBlock) - return MS_LB_ERROR; - - for (blk = phyblk + 1; blk != phyblk; blk++) { - if ((blk & MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK) == 0) - blk -= MS_PHYSICAL_BLOCKS_PER_SEGMENT; - - Newblk = us->MS_Lib.Phy2LogMap[blk]; - if (us->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED_ERASED) - return blk; - else if (us->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED) { - switch (MS_LibReadExtra(us, blk, 0, &extdat)) { - case MS_STATUS_SUCCESS: - case MS_STATUS_SUCCESS_WITH_ECC: - break; - case MS_NOCARD_ERROR: - return MS_NOCARD_ERROR; - case MS_STATUS_INT_ERROR: - return MS_LB_ERROR; - case MS_ERROR_FLASH_READ: - default: - MS_LibSetAcquiredErrorBlock(us, blk); - /* MS_LibErrorPhyBlock(fdoExt, blk); */ - continue; - } /* End switch */ - - if ((extdat.ovrflg & MS_REG_OVR_BKST) != - MS_REG_OVR_BKST_OK) { - MS_LibSetAcquiredErrorBlock(us, blk); - continue; - } - - switch (MS_LibErasePhyBlock(us, blk)) { - case MS_STATUS_SUCCESS: - return blk; - case MS_STATUS_ERROR: - return MS_LB_ERROR; - case MS_ERROR_FLASH_ERASE: - default: - MS_LibErrorPhyBlock(us, blk); - break; - } - } - } /* End for */ - - return MS_LB_ERROR; -} - -/* - * MS_LibSearchBlockFromLogical() - */ -int MS_LibSearchBlockFromLogical(struct us_data *us, WORD logblk) -{ - WORD phyblk; - - phyblk = MS_LibConv2Physical(us, logblk); - if (phyblk >= MS_LB_ERROR) { - if (logblk >= us->MS_Lib.NumberOfLogBlock) - return MS_LB_ERROR; - - phyblk = (logblk + MS_NUMBER_OF_BOOT_BLOCK) / - MS_LOGICAL_BLOCKS_PER_SEGMENT; - phyblk *= MS_PHYSICAL_BLOCKS_PER_SEGMENT; - phyblk += MS_PHYSICAL_BLOCKS_PER_SEGMENT - 1; - } - - return MS_LibSearchBlockFromPhysical(us, phyblk); -} diff --git a/drivers/staging/keucr/ms.h b/drivers/staging/keucr/ms.h deleted file mode 100644 index a3da4be3f556..000000000000 --- a/drivers/staging/keucr/ms.h +++ /dev/null @@ -1,401 +0,0 @@ -#ifndef MS_INCD -#define MS_INCD - -#include -#include "common.h" - -/* MemoryStick Register */ -/* Status Register 0 */ -#define MS_REG_ST0_MB 0x80 /* media busy */ -#define MS_REG_ST0_FB0 0x40 /* flush busy 0 */ -#define MS_REG_ST0_BE 0x20 /* buffer empty */ -#define MS_REG_ST0_BF 0x10 /* buffer full */ -#define MS_REG_ST0_SL 0x02 /* sleep */ -#define MS_REG_ST0_WP 0x01 /* write protected */ -#define MS_REG_ST0_WP_ON MS_REG_ST0_WP -#define MS_REG_ST0_WP_OFF 0x00 - -/* Status Register 1 */ -#define MS_REG_ST1_MB 0x80 /* media busy */ -#define MS_REG_ST1_FB1 0x40 /* flush busy 1 */ -#define MS_REG_ST1_DTER 0x20 /* error on data(corrected) */ -#define MS_REG_ST1_UCDT 0x10 /* unable to correct data */ -#define MS_REG_ST1_EXER 0x08 /* error on extra(corrected) */ -#define MS_REG_ST1_UCEX 0x04 /* unable to correct extra */ -#define MS_REG_ST1_FGER 0x02 /* error on overwrite flag(corrected) */ -#define MS_REG_ST1_UCFG 0x01 /* unable to correct overwrite flag */ -#define MS_REG_ST1_DEFAULT (MS_REG_ST1_MB | MS_REG_ST1_FB1 | \ - MS_REG_ST1_DTER | MS_REG_ST1_UCDT | \ - MS_REG_ST1_EXER | MS_REG_ST1_UCEX | \ - MS_REG_ST1_FGER | MS_REG_ST1_UCFG) - -/* System Parameter */ -#define MS_REG_SYSPAR_BAMD 0x80 /* block address mode */ -#define MS_REG_SYSPAR_BAND_LINEAR MS_REG_SYSPAR_BAMD /* linear mode */ -#define MS_REG_SYSPAR_BAND_CHIP 0x00 /* chip mode */ -#define MS_REG_SYSPAR_ATEN 0x40 /* attribute ROM enable */ -#define MS_REG_SYSPAR_ATEN_ENABLE MS_REG_SYSPAR_ATEN /* enable */ -#define MS_REG_SYSPAR_ATEN_DISABLE 0x00 /* disable */ -#define MS_REG_SYSPAR_RESERVED 0x2f - -/* Command Parameter */ -#define MS_REG_CMDPAR_CP2 0x80 -#define MS_REG_CMDPAR_CP1 0x40 -#define MS_REG_CMDPAR_CP0 0x20 -#define MS_REG_CMDPAR_BLOCK_ACCESS 0 -#define MS_REG_CMDPAR_PAGE_ACCESS MS_REG_CMDPAR_CP0 -#define MS_REG_CMDPAR_EXTRA_DATA MS_REG_CMDPAR_CP1 -#define MS_REG_CMDPAR_OVERWRITE MS_REG_CMDPAR_CP2 -#define MS_REG_CMDPAR_RESERVED 0x1f - -/* Overwrite Area */ -#define MS_REG_OVR_BKST 0x80 /* block status */ -#define MS_REG_OVR_BKST_OK MS_REG_OVR_BKST /* OK */ -#define MS_REG_OVR_BKST_NG 0x00 /* NG */ -#define MS_REG_OVR_PGST0 0x40 /* page status */ -#define MS_REG_OVR_PGST1 0x20 -#define MS_REG_OVR_PGST_MASK (MS_REG_OVR_PGST0 | MS_REG_OVR_PGST1) -#define MS_REG_OVR_PGST_OK (MS_REG_OVR_PGST0 | MS_REG_OVR_PGST1) /* OK */ -#define MS_REG_OVR_PGST_NG MS_REG_OVR_PGST1 /* NG */ -#define MS_REG_OVR_PGST_DATA_ERROR 0x00 /* data error */ -#define MS_REG_OVR_UDST 0x10 /* update status */ -#define MS_REG_OVR_UDST_UPDATING 0x00 /* updating */ -#define MS_REG_OVR_UDST_NO_UPDATE MS_REG_OVR_UDST -#define MS_REG_OVR_RESERVED 0x08 -#define MS_REG_OVR_DEFAULT (MS_REG_OVR_BKST_OK | \ - MS_REG_OVR_PGST_OK | \ - MS_REG_OVR_UDST_NO_UPDATE | \ - MS_REG_OVR_RESERVED) -/* Management Flag */ -#define MS_REG_MNG_SCMS0 0x20 /* serial copy management system */ -#define MS_REG_MNG_SCMS1 0x10 -#define MS_REG_MNG_SCMS_MASK (MS_REG_MNG_SCMS0 | MS_REG_MNG_SCMS1) -#define MS_REG_MNG_SCMS_COPY_OK (MS_REG_MNG_SCMS0 | MS_REG_MNG_SCMS1) -#define MS_REG_MNG_SCMS_ONE_COPY MS_REG_MNG_SCMS1 -#define MS_REG_MNG_SCMS_NO_COPY 0x00 -#define MS_REG_MNG_ATFLG 0x08 /* address transfer table flag */ -#define MS_REG_MNG_ATFLG_OTHER MS_REG_MNG_ATFLG /* other */ -#define MS_REG_MNG_ATFLG_ATTBL 0x00 /* address transfer table */ -#define MS_REG_MNG_SYSFLG 0x04 /* system flag */ -#define MS_REG_MNG_SYSFLG_USER MS_REG_MNG_SYSFLG /* user block */ -#define MS_REG_MNG_SYSFLG_BOOT 0x00 /* system block */ -#define MS_REG_MNG_RESERVED 0xc3 -#define MS_REG_MNG_DEFAULT (MS_REG_MNG_SCMS_COPY_OK | \ - MS_REG_MNG_ATFLG_OTHER | \ - MS_REG_MNG_SYSFLG_USER | \ - MS_REG_MNG_RESERVED) - -/* Error codes */ -#define MS_STATUS_SUCCESS 0x0000 -#define MS_ERROR_OUT_OF_SPACE 0x0103 -#define MS_STATUS_WRITE_PROTECT 0x0106 -#define MS_ERROR_READ_DATA 0x8002 -#define MS_ERROR_FLASH_READ 0x8003 -#define MS_ERROR_FLASH_WRITE 0x8004 -#define MS_ERROR_FLASH_ERASE 0x8005 -#define MS_ERROR_FLASH_COPY 0x8006 - -#define MS_STATUS_ERROR 0xfffe -#define MS_FIFO_ERROR 0xfffd -#define MS_UNDEFINED_ERROR 0xfffc -#define MS_KETIMEOUT_ERROR 0xfffb -#define MS_STATUS_INT_ERROR 0xfffa -#define MS_NO_MEMORY_ERROR 0xfff9 -#define MS_NOCARD_ERROR 0xfff8 -#define MS_LB_NOT_USED 0xffff -#define MS_LB_ERROR 0xfff0 -#define MS_LB_BOOT_BLOCK 0xfff1 -#define MS_LB_INITIAL_ERROR 0xfff2 -#define MS_STATUS_SUCCESS_WITH_ECC 0xfff3 -#define MS_LB_ACQUIRED_ERROR 0xfff4 -#define MS_LB_NOT_USED_ERASED 0xfff5 - -#define MS_LibConv2Physical(pdx, LogBlock) \ - (((LogBlock) >= (pdx)->MS_Lib.NumberOfLogBlock) ? \ - MS_STATUS_ERROR : (pdx)->MS_Lib.Log2PhyMap[LogBlock]) -#define MS_LibConv2Logical(pdx, PhyBlock) \ - (((PhyBlock) >= (pdx)->MS_Lib.NumberOfPhyBlock) ? \ - MS_STATUS_ERROR : (pdx)->MS_Lib.Phy2LogMap[PhyBlock]) - /*dphy->log table */ - -#define MS_LIB_CTRL_RDONLY 0 -#define MS_LIB_CTRL_WRPROTECT 1 -#define MS_LibCtrlCheck(pdx, Flag) ((pdx)->MS_Lib.flags & (1 << (Flag))) - -#define MS_LibCtrlSet(pdx, Flag) ((pdx)->MS_Lib.flags |= (1 << (Flag))) -#define MS_LibCtrlReset(pdx, Flag) ((pdx)->MS_Lib.flags &= ~(1 << (Flag))) -#define MS_LibIsWritable(pdx) \ - ((MS_LibCtrlCheck((pdx), MS_LIB_CTRL_RDONLY) == 0) && \ - (MS_LibCtrlCheck(pdx, MS_LIB_CTRL_WRPROTECT) == 0)) - -#define MS_MAX_PAGES_PER_BLOCK 32 -#define MS_LIB_BITS_PER_BYTE 8 - -#define MS_LibPageMapIdx(n) ((n) / MS_LIB_BITS_PER_BYTE) -#define MS_LibPageMapBit(n) (1 << ((n) % MS_LIB_BITS_PER_BYTE)) -#define MS_LibCheckPageMapBit(pdx, n) \ - ((pdx)->MS_Lib.pagemap[MS_LibPageMapIdx(n)] & MS_LibPageMapBit(n)) -#define MS_LibSetPageMapBit(pdx, n) \ - ((pdx)->MS_Lib.pagemap[MS_LibPageMapIdx(n)] |= MS_LibPageMapBit(n)) -#define MS_LibResetPageMapBit(pdx, n) \ - ((pdx)->MS_Lib.pagemap[MS_LibPageMapIdx(n)] &= ~MS_LibPageMapBit(n)) -#define MS_LibClearPageMap(pdx) \ - memset((pdx)->MS_Lib.pagemap, 0, sizeof((pdx)->MS_Lib.pagemap)) - - -#define MemStickLogAddr(logadr1, logadr0) \ - ((((WORD)(logadr1)) << 8) | (logadr0)) - -#define MS_BYTES_PER_PAGE 512 - -#define MS_MAX_INITIAL_ERROR_BLOCKS 10 -#define MS_NUMBER_OF_PAGES_FOR_BOOT_BLOCK 3 -#define MS_NUMBER_OF_PAGES_FOR_LPCTBL 2 - -#define MS_NUMBER_OF_BOOT_BLOCK 2 -#define MS_NUMBER_OF_SYSTEM_BLOCK 4 -#define MS_LOGICAL_BLOCKS_PER_SEGMENT 496 -#define MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT 494 -#define MS_PHYSICAL_BLOCKS_PER_SEGMENT 0x200 /* 512 */ -#define MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK 0x1ff - -#define MS_SECTOR_SIZE 512 -#define MBR_SIGNATURE 0xAA55 -#define PBR_SIGNATURE 0xAA55 - -#define PARTITION_FAT_12 1 -#define PARTITION_FAT_16 2 - -#define MS_BOOT_BLOCK_ID 0x0001 -#define MS_BOOT_BLOCK_FORMAT_VERSION 0x0100 -#define MS_BOOT_BLOCK_DATA_ENTRIES 2 - -#define MS_SYSINF_MSCLASS_TYPE_1 1 -#define MS_SYSINF_CARDTYPE_RDONLY 1 -#define MS_SYSINF_CARDTYPE_RDWR 2 -#define MS_SYSINF_CARDTYPE_HYBRID 3 -#define MS_SYSINF_SECURITY 0x01 -#define MS_SYSINF_SECURITY_NO_SUPPORT MS_SYSINF_SECURITY -#define MS_SYSINF_SECURITY_SUPPORT 0 -#define MS_SYSINF_FORMAT_MAT 0 /* ? */ -#define MS_SYSINF_FORMAT_FAT 1 -#define MS_SYSINF_USAGE_GENERAL 0 -#define MS_SYSINF_PAGE_SIZE MS_BYTES_PER_PAGE /* fixed */ -#define MS_SYSINF_RESERVED1 1 -#define MS_SYSINF_RESERVED2 1 - -#define MS_SYSENT_TYPE_INVALID_BLOCK 0x01 -#define MS_SYSENT_TYPE_CIS_IDI 0x0a /* CIS/IDI */ - -#define SIZE_OF_KIRO 1024 - -/* BOOT BLOCK */ -#define MS_NUMBER_OF_SYSTEM_ENTRY 4 - -/* - * MemStickRegisters - */ -/* Status registers (16 bytes) */ -typedef struct { - BYTE Reserved0; /* 00 */ - BYTE INTRegister; /* 01 */ - BYTE StatusRegister0; /* 02 */ - BYTE StatusRegister1; /* 03 */ - BYTE Reserved1[12]; /* 04-0F */ -} MemStickStatusRegisters; - -/* Parameter registers (6 bytes) */ -typedef struct { - BYTE SystemParameter; /* 10 */ - BYTE BlockAddress2; /* 11 */ - BYTE BlockAddress1; /* 12 */ - BYTE BlockAddress0; /* 13 */ - BYTE CMDParameter; /* 14 */ - BYTE PageAddress; /* 15 */ -} MemStickParameterRegisters; - -/* Extra registers (9 bytes) */ -typedef struct { - BYTE OverwriteFlag; /* 16 */ - BYTE ManagementFlag; /* 17 */ - BYTE LogicalAddress1; /* 18 */ - BYTE LogicalAddress0; /* 19 */ - BYTE ReservedArea[5]; /* 1A-1E */ -} MemStickExtraDataRegisters; - -/* All registers in Memory Stick (32 bytes, includes 1 byte padding) */ -typedef struct { - MemStickStatusRegisters status; - MemStickParameterRegisters param; - MemStickExtraDataRegisters extra; - BYTE padding; -} MemStickRegisters, *PMemStickRegisters; - -/* - * MemStickBootBlockPage0 - */ -typedef struct { - WORD wBlockID; - WORD wFormatVersion; - BYTE bReserved1[184]; - BYTE bNumberOfDataEntry; - BYTE bReserved2[179]; -} MemStickBootBlockHeader; - -typedef struct { - DWORD dwStart; - DWORD dwSize; - BYTE bType; - BYTE bReserved[3]; -} MemStickBootBlockSysEntRec; - -typedef struct { - MemStickBootBlockSysEntRec entry[MS_NUMBER_OF_SYSTEM_ENTRY]; -} MemStickBootBlockSysEnt; - -typedef struct { - BYTE bMsClass; /* must be 1 */ - BYTE bCardType; /* see below */ - WORD wBlockSize; /* n KB */ - WORD wBlockNumber; /* number of physical block */ - WORD wTotalBlockNumber; /* number of logical block */ - WORD wPageSize; /* must be 0x200 */ - BYTE bExtraSize; /* 0x10 */ - BYTE bSecuritySupport; - BYTE bAssemblyDate[8]; - BYTE bFactoryArea[4]; - BYTE bAssemblyMakerCode; - BYTE bAssemblyMachineCode[3]; - WORD wMemoryMakerCode; - WORD wMemoryDeviceCode; - WORD wMemorySize; - BYTE bReserved1; - BYTE bReserved2; - BYTE bVCC; - BYTE bVPP; - WORD wControllerChipNumber; - WORD wControllerFunction; /* New MS */ - BYTE bReserved3[9]; /* New MS */ - BYTE bParallelSupport; /* New MS */ - WORD wFormatValue; /* New MS */ - BYTE bFormatType; - BYTE bUsage; - BYTE bDeviceType; - BYTE bReserved4[22]; - BYTE bFUValue3; - BYTE bFUValue4; - BYTE bReserved5[15]; -} MemStickBootBlockSysInf; - -typedef struct { - MemStickBootBlockHeader header; - MemStickBootBlockSysEnt sysent; - MemStickBootBlockSysInf sysinf; -} MemStickBootBlockPage0; - -/* - * MemStickBootBlockCIS_IDI - */ -typedef struct { - BYTE bCistplDEVICE[6]; /* 0 */ - BYTE bCistplDEVICE0C[6]; /* 6 */ - BYTE bCistplJEDECC[4]; /* 12 */ - BYTE bCistplMANFID[6]; /* 16 */ - BYTE bCistplVER1[32]; /* 22 */ - BYTE bCistplFUNCID[4]; /* 54 */ - BYTE bCistplFUNCE0[4]; /* 58 */ - BYTE bCistplFUNCE1[5]; /* 62 */ - BYTE bCistplCONF[7]; /* 67 */ - BYTE bCistplCFTBLENT0[10]; /* 74 */ - BYTE bCistplCFTBLENT1[8]; /* 84 */ - BYTE bCistplCFTBLENT2[12]; /* 92 */ - BYTE bCistplCFTBLENT3[8]; /* 104 */ - BYTE bCistplCFTBLENT4[17]; /* 112 */ - BYTE bCistplCFTBLENT5[8]; /* 129 */ - BYTE bCistplCFTBLENT6[17]; /* 137 */ - BYTE bCistplCFTBLENT7[8]; /* 154 */ - BYTE bCistplNOLINK[3]; /* 162 */ -} MemStickBootBlockCIS; - -typedef struct { -#define MS_IDI_GENERAL_CONF 0x848A - WORD wIDIgeneralConfiguration; /* 0 */ - WORD wIDInumberOfCylinder; /* 1 */ - WORD wIDIreserved0; /* 2 */ - WORD wIDInumberOfHead; /* 3 */ - WORD wIDIbytesPerTrack; /* 4 */ - WORD wIDIbytesPerSector; /* 5 */ - WORD wIDIsectorsPerTrack; /* 6 */ - WORD wIDItotalSectors[2]; /* 7-8 high,low */ - WORD wIDIreserved1[11]; /* 9-19 */ - WORD wIDIbufferType; /* 20 */ - WORD wIDIbufferSize; /* 21 */ - WORD wIDIlongCmdECC; /* 22 */ - WORD wIDIfirmVersion[4]; /* 23-26 */ - WORD wIDImodelName[20]; /* 27-46 */ - WORD wIDIreserved2; /* 47 */ - WORD wIDIlongWordSupported; /* 48 */ - WORD wIDIdmaSupported; /* 49 */ - WORD wIDIreserved3; /* 50 */ - WORD wIDIpioTiming; /* 51 */ - WORD wIDIdmaTiming; /* 52 */ - WORD wIDItransferParameter; /* 53 */ - WORD wIDIformattedCylinder; /* 54 */ - WORD wIDIformattedHead; /* 55 */ - WORD wIDIformattedSectorsPerTrack; /* 56 */ - WORD wIDIformattedTotalSectors[2]; /* 57-58 */ - WORD wIDImultiSector; /* 59 */ - WORD wIDIlbaSectors[2]; /* 60-61 */ - WORD wIDIsingleWordDMA; /* 62 */ - WORD wIDImultiWordDMA; /* 63 */ - WORD wIDIreserved4[192]; /* 64-255 */ -} MemStickBootBlockIDI; - -typedef struct { - union { - MemStickBootBlockCIS cis; - BYTE dmy[256]; - } cis; - - union { - MemStickBootBlockIDI idi; - BYTE dmy[256]; - } idi; - -} MemStickBootBlockCIS_IDI; - -/* - * MS_LibControl - */ -typedef struct { - BYTE reserved; - BYTE intr; - BYTE status0; - BYTE status1; - BYTE ovrflg; - BYTE mngflg; - WORD logadr; -} MS_LibTypeExtdat; - -typedef struct { - DWORD flags; - DWORD BytesPerSector; - DWORD NumberOfCylinder; - DWORD SectorsPerCylinder; - WORD cardType; /* R/W, RO, Hybrid */ - WORD blockSize; - WORD PagesPerBlock; - WORD NumberOfPhyBlock; - WORD NumberOfLogBlock; - WORD NumberOfSegment; - WORD *Phy2LogMap; /* phy2log table */ - WORD *Log2PhyMap; /* log2phy table */ - WORD wrtblk; - BYTE pagemap[(MS_MAX_PAGES_PER_BLOCK + (MS_LIB_BITS_PER_BYTE-1)) / - MS_LIB_BITS_PER_BYTE]; - BYTE *blkpag; - MS_LibTypeExtdat *blkext; - BYTE copybuf[512]; -} MS_LibControl; - -#endif diff --git a/drivers/staging/keucr/msscsi.c b/drivers/staging/keucr/msscsi.c deleted file mode 100644 index cb7190e0e18a..000000000000 --- a/drivers/staging/keucr/msscsi.c +++ /dev/null @@ -1,344 +0,0 @@ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include - -#include -#include -#include - -#include "usb.h" -#include "scsiglue.h" -#include "transport.h" - -/* - * MS_SCSI_Test_Unit_Ready() - */ -int MS_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb) -{ - /* pr_info("MS_SCSI_Test_Unit_Ready\n"); */ - if (us->MS_Status.Insert && us->MS_Status.Ready) - return USB_STOR_TRANSPORT_GOOD; - else { - ENE_MSInit(us); - return USB_STOR_TRANSPORT_GOOD; - } - - return USB_STOR_TRANSPORT_GOOD; -} - -/* - * MS_SCSI_Inquiry() - */ -int MS_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb) -{ - /* pr_info("MS_SCSI_Inquiry\n"); */ - BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, - 0x00, 0x00, 0x55, 0x53, 0x42, 0x32, - 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x30, 0x31, 0x30, 0x30}; - - usb_stor_set_xfer_buf(us, data_ptr, 36, srb, TO_XFER_BUF); - return USB_STOR_TRANSPORT_GOOD; -} - -/* - * MS_SCSI_Mode_Sense() - */ -int MS_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb) -{ - BYTE mediaNoWP[12] = {0x0b, 0x00, 0x00, 0x08, 0x00, 0x00, - 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00}; - BYTE mediaWP[12] = {0x0b, 0x00, 0x80, 0x08, 0x00, 0x00, - 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00}; - - if (us->MS_Status.WtP) - usb_stor_set_xfer_buf(us, mediaWP, 12, srb, TO_XFER_BUF); - else - usb_stor_set_xfer_buf(us, mediaNoWP, 12, srb, TO_XFER_BUF); - - - return USB_STOR_TRANSPORT_GOOD; -} - -/* - * MS_SCSI_Read_Capacity() - */ -int MS_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb) -{ - unsigned int offset = 0; - struct scatterlist *sg = NULL; - DWORD bl_num; - WORD bl_len; - BYTE buf[8]; - - pr_info("MS_SCSI_Read_Capacity\n"); - - bl_len = 0x200; - if (us->MS_Status.IsMSPro) - bl_num = us->MSP_TotalBlock - 1; - else - bl_num = us->MS_Lib.NumberOfLogBlock * - us->MS_Lib.blockSize * 2 - 1; - - us->bl_num = bl_num; - pr_info("bl_len = %x\n", bl_len); - pr_info("bl_num = %x\n", bl_num); - - /* srb->request_bufflen = 8; */ - buf[0] = (bl_num >> 24) & 0xff; - buf[1] = (bl_num >> 16) & 0xff; - buf[2] = (bl_num >> 8) & 0xff; - buf[3] = (bl_num >> 0) & 0xff; - buf[4] = (bl_len >> 24) & 0xff; - buf[5] = (bl_len >> 16) & 0xff; - buf[6] = (bl_len >> 8) & 0xff; - buf[7] = (bl_len >> 0) & 0xff; - - usb_stor_access_xfer_buf(us, buf, 8, srb, &sg, &offset, TO_XFER_BUF); - /* usb_stor_set_xfer_buf(us, buf, srb->request_bufflen, - srb, TO_XFER_BUF); */ - - return USB_STOR_TRANSPORT_GOOD; -} - -/* - * MS_SCSI_Read() - */ -int MS_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) -{ - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result = 0; - PBYTE Cdb = srb->cmnd; - DWORD bn = ((Cdb[2] << 24) & 0xff000000) | - ((Cdb[3] << 16) & 0x00ff0000) | - ((Cdb[4] << 8) & 0x0000ff00) | - ((Cdb[5] << 0) & 0x000000ff); - WORD blen = ((Cdb[7] << 8) & 0xff00) | ((Cdb[8] << 0) & 0x00ff); - DWORD blenByte = blen * 0x200; - - /* pr_info("SCSIOP_READ --- bn = %X, blen = %X, srb->use_sg = %X\n", - bn, blen, srb->use_sg); */ - - if (bn > us->bl_num) - return USB_STOR_TRANSPORT_ERROR; - - if (us->MS_Status.IsMSPro) { - result = ENE_LoadBinCode(us, MSP_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) { - pr_info("Load MSP RW pattern Fail !!\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - /* set up the command wrapper */ - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = blenByte; - bcb->Flags = 0x80; - bcb->CDB[0] = 0xF1; - bcb->CDB[1] = 0x02; - bcb->CDB[5] = (BYTE)(bn); - bcb->CDB[4] = (BYTE)(bn>>8); - bcb->CDB[3] = (BYTE)(bn>>16); - bcb->CDB[2] = (BYTE)(bn>>24); - - result = ENE_SendScsiCmd(us, FDIR_READ, scsi_sglist(srb), 1); - } else { - void *buf; - int offset = 0; - WORD phyblk, logblk; - BYTE PageNum; - WORD len; - DWORD blkno; - - buf = kmalloc(blenByte, GFP_KERNEL); - if (buf == NULL) - return USB_STOR_TRANSPORT_ERROR; - - result = ENE_LoadBinCode(us, MS_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) { - pr_info("Load MS RW pattern Fail !!\n"); - result = USB_STOR_TRANSPORT_ERROR; - goto exit; - } - - logblk = (WORD)(bn / us->MS_Lib.PagesPerBlock); - PageNum = (BYTE)(bn % us->MS_Lib.PagesPerBlock); - - while (1) { - if (blen > (us->MS_Lib.PagesPerBlock-PageNum)) - len = us->MS_Lib.PagesPerBlock-PageNum; - else - len = blen; - - phyblk = MS_LibConv2Physical(us, logblk); - blkno = phyblk * 0x20 + PageNum; - - /* set up the command wrapper */ - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = 0x200 * len; - bcb->Flags = 0x80; - bcb->CDB[0] = 0xF1; - bcb->CDB[1] = 0x02; - bcb->CDB[5] = (BYTE)(blkno); - bcb->CDB[4] = (BYTE)(blkno>>8); - bcb->CDB[3] = (BYTE)(blkno>>16); - bcb->CDB[2] = (BYTE)(blkno>>24); - - result = ENE_SendScsiCmd(us, FDIR_READ, buf+offset, 0); - if (result != USB_STOR_XFER_GOOD) { - pr_info("MS_SCSI_Read --- result = %x\n", - result); - result = USB_STOR_TRANSPORT_ERROR; - goto exit; - } - - blen -= len; - if (blen <= 0) - break; - logblk++; - PageNum = 0; - offset += MS_BYTES_PER_PAGE*len; - } - usb_stor_set_xfer_buf(us, buf, blenByte, srb, TO_XFER_BUF); -exit: - kfree(buf); - } - return result; -} - -/* - * MS_SCSI_Write() - */ -int MS_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb) -{ - struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result = 0; - PBYTE Cdb = srb->cmnd; - DWORD bn = ((Cdb[2] << 24) & 0xff000000) | - ((Cdb[3] << 16) & 0x00ff0000) | - ((Cdb[4] << 8) & 0x0000ff00) | - ((Cdb[5] << 0) & 0x000000ff); - WORD blen = ((Cdb[7] << 8) & 0xff00) | ((Cdb[8] << 0) & 0x00ff); - DWORD blenByte = blen * 0x200; - - if (bn > us->bl_num) - return USB_STOR_TRANSPORT_ERROR; - - if (us->MS_Status.IsMSPro) { - result = ENE_LoadBinCode(us, MSP_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) { - pr_info("Load MSP RW pattern Fail !!\n"); - return USB_STOR_TRANSPORT_ERROR; - } - - /* set up the command wrapper */ - memset(bcb, 0, sizeof(struct bulk_cb_wrap)); - bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcb->DataTransferLength = blenByte; - bcb->Flags = 0x00; - bcb->CDB[0] = 0xF0; - bcb->CDB[1] = 0x04; - bcb->CDB[5] = (BYTE)(bn); - bcb->CDB[4] = (BYTE)(bn>>8); - bcb->CDB[3] = (BYTE)(bn>>16); - bcb->CDB[2] = (BYTE)(bn>>24); - - result = ENE_SendScsiCmd(us, FDIR_WRITE, scsi_sglist(srb), 1); - } else { - void *buf; - int offset = 0; - WORD PhyBlockAddr; - BYTE PageNum; - DWORD result; - WORD len, oldphy, newphy; - - buf = kmalloc(blenByte, GFP_KERNEL); - if (buf == NULL) - return USB_STOR_TRANSPORT_ERROR; - usb_stor_set_xfer_buf(us, buf, blenByte, srb, FROM_XFER_BUF); - - result = ENE_LoadBinCode(us, MS_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) { - pr_info("Load MS RW pattern Fail !!\n"); - result = USB_STOR_TRANSPORT_ERROR; - goto exit; - } - - PhyBlockAddr = (WORD)(bn / us->MS_Lib.PagesPerBlock); - PageNum = (BYTE)(bn % us->MS_Lib.PagesPerBlock); - - while (1) { - if (blen > (us->MS_Lib.PagesPerBlock-PageNum)) - len = us->MS_Lib.PagesPerBlock-PageNum; - else - len = blen; - - oldphy = MS_LibConv2Physical(us, PhyBlockAddr); - newphy = MS_LibSearchBlockFromLogical(us, PhyBlockAddr); - - result = MS_ReaderCopyBlock(us, oldphy, newphy, - PhyBlockAddr, PageNum, - buf+offset, len); - if (result != USB_STOR_XFER_GOOD) { - pr_info("MS_SCSI_Write --- result = %x\n", - result); - result = USB_STOR_TRANSPORT_ERROR; - goto exit; - } - - us->MS_Lib.Phy2LogMap[oldphy] = MS_LB_NOT_USED_ERASED; - MS_LibForceSetLogicalPair(us, PhyBlockAddr, newphy); - - blen -= len; - if (blen <= 0) - break; - PhyBlockAddr++; - PageNum = 0; - offset += MS_BYTES_PER_PAGE*len; - } -exit: - kfree(buf); - } - return result; -} - -/* - * MS_SCSIIrp() - */ -int MS_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb) -{ - int result; - - us->SrbStatus = SS_SUCCESS; - switch (srb->cmnd[0]) { - case TEST_UNIT_READY: - result = MS_SCSI_Test_Unit_Ready(us, srb); - break; /* 0x00 */ - case INQUIRY: - result = MS_SCSI_Inquiry(us, srb); - break; /* 0x12 */ - case MODE_SENSE: - result = MS_SCSI_Mode_Sense(us, srb); - break; /* 0x1A */ - case READ_CAPACITY: - result = MS_SCSI_Read_Capacity(us, srb); - break; /* 0x25 */ - case READ_10: - result = MS_SCSI_Read(us, srb); - break; /* 0x28 */ - case WRITE_10: - result = MS_SCSI_Write(us, srb); - break; /* 0x2A */ - default: - us->SrbStatus = SS_ILLEGAL_REQUEST; - result = USB_STOR_TRANSPORT_FAILED; - break; - } - return result; -} - diff --git a/drivers/staging/keucr/transport.c b/drivers/staging/keucr/transport.c index 0274cb0edd01..1a8837df0766 100644 --- a/drivers/staging/keucr/transport.c +++ b/drivers/staging/keucr/transport.c @@ -432,7 +432,7 @@ void ENE_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) usb_stor_print_cmd(srb); /* send the command to the transport layer */ scsi_set_resid(srb, 0); - if (!(us->MS_Status.Ready || us->SM_Status.Ready)) + if (!(us->SM_Status.Ready)) result = ENE_InitMedia(us); if (us->Power_IsResum == true) { @@ -440,8 +440,6 @@ void ENE_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) us->Power_IsResum = false; } - if (us->MS_Status.Ready) - result = MS_SCSIIrp(us, srb); if (us->SM_Status.Ready) result = SM_SCSIIrp(us, srb); diff --git a/drivers/staging/keucr/transport.h b/drivers/staging/keucr/transport.h index 75296152af76..4ae57d0145b2 100644 --- a/drivers/staging/keucr/transport.h +++ b/drivers/staging/keucr/transport.h @@ -95,7 +95,6 @@ extern void usb_stor_set_xfer_buf(struct us_data*, unsigned char *buffer, */ extern void ENE_stor_invoke_transport(struct scsi_cmnd *, struct us_data *); extern int ENE_InitMedia(struct us_data *); -extern int ENE_MSInit(struct us_data *); extern int ENE_SMInit(struct us_data *); extern int ENE_SendScsiCmd(struct us_data*, BYTE, void*, int); extern int ENE_LoadBinCode(struct us_data*, BYTE); @@ -107,51 +106,6 @@ extern void BuildSenseBuffer(struct scsi_cmnd *, int); /* * ENE scsi function */ -extern int MS_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb); extern int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb); -/* - * ENE MS function - */ -extern int MS_CardInit(struct us_data *us); -extern void MS_LibFreeAllocatedArea(struct us_data *us); -extern void MS_LibFreeWriteBuf(struct us_data *us); -extern int MS_LibFreeLogicalMap(struct us_data *us); -extern int MS_LibForceSetLogicalPair(struct us_data *us, WORD logblk, - WORD phyblk); -extern int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, - BYTE PageNum, DWORD *PageBuf, - MS_LibTypeExtdat *ExtraDat); -extern int MS_ReaderCopyBlock(struct us_data *us, WORD oldphy, - WORD newphy, WORD PhyBlockAddr, - BYTE PageNum, PBYTE buf, WORD len); -extern int MS_ReaderEraseBlock(struct us_data *us, DWORD PhyBlockAddr); -extern int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, - BYTE *PageData); -extern int MS_LibAllocLogicalMap(struct us_data *us); -extern int MS_LibSetBootBlockMark(struct us_data *us, WORD phyblk); -extern int MS_LibSetLogicalBlockMark(struct us_data *us, WORD phyblk, - WORD mark); -extern int MS_LibSetInitialErrorBlock(struct us_data *us, WORD phyblk); -extern int MS_LibScanLogicalBlockNumber(struct us_data *us, WORD phyblk); -extern int MS_LibAllocWriteBuf(struct us_data *us); -void MS_LibClearWriteBuf(struct us_data *us); -void MS_LibPhy2LogRange(WORD PhyBlock, WORD *LogStart, - WORD *LogEnde); -extern int MS_LibReadExtra(struct us_data *us, DWORD PhyBlock, - BYTE PageNum, MS_LibTypeExtdat *ExtraDat); -extern int MS_LibReadExtraBlock(struct us_data *us, DWORD PhyBlock, - BYTE PageNum, BYTE blen, void *buf); -extern int MS_LibSetAcquiredErrorBlock(struct us_data *us, WORD phyblk); -extern int MS_LibErasePhyBlock(struct us_data *us, WORD phyblk); -extern int MS_LibErrorPhyBlock(struct us_data *us, WORD phyblk); -extern int MS_LibOverwriteExtra(struct us_data *us, DWORD PhyBlockAddr, - BYTE PageNum, BYTE OverwriteFlag); -extern int MS_LibSetLogicalPair(struct us_data *us, - WORD logblk, WORD phyblk); -extern int MS_LibCheckDisableBlock(struct us_data *us, WORD PhyBlock); -extern int MS_CountFreeBlock(struct us_data *us, WORD PhyBlock); -extern int MS_LibSearchBlockFromLogical(struct us_data *us, WORD logblk); -extern int MS_LibSearchBlockFromPhysical(struct us_data *us, WORD phyblk); - #endif diff --git a/drivers/staging/keucr/usb.c b/drivers/staging/keucr/usb.c index d8c5c626be5c..66aad3a0d1fd 100644 --- a/drivers/staging/keucr/usb.c +++ b/drivers/staging/keucr/usb.c @@ -75,7 +75,6 @@ static int eucr_resume(struct usb_interface *iface) us->Power_IsResum = true; // //us->SD_Status.Ready = 0; //?? - us->MS_Status = *(PMS_STATUS)&tmp; us->SM_Status = *(PSM_STATUS)&tmp; return 0; @@ -98,7 +97,6 @@ static int eucr_reset_resume(struct usb_interface *iface) us->Power_IsResum = true; // //us->SD_Status.Ready = 0; //?? - us->MS_Status = *(PMS_STATUS)&tmp; us->SM_Status = *(PSM_STATUS)&tmp; return 0; } @@ -640,8 +638,7 @@ static int eucr_probe(struct usb_interface *intf, const struct usb_device_id *id /* Start up the thread for delayed SCSI-device scanning */ th = kthread_create(usb_stor_scan_thread, us, "eucr-stor-scan"); - if (IS_ERR(th)) - { + if (IS_ERR(th)) { pr_info("Unable to start the device-scanning thread\n"); complete(&us->scanning_done); quiesce_and_remove_host(us); diff --git a/drivers/staging/keucr/usb.h b/drivers/staging/keucr/usb.h index bbf578ad6316..a5f7a16c11c9 100644 --- a/drivers/staging/keucr/usb.h +++ b/drivers/staging/keucr/usb.h @@ -10,7 +10,6 @@ #include #include #include "common.h" -#include "ms.h" struct us_data; struct scsi_cmnd; @@ -201,7 +200,7 @@ struct us_data { //----- MS Control Data ---------------- BOOLEAN MS_SWWP; DWORD MSP_TotalBlock; - MS_LibControl MS_Lib; + /* MS_LibControl MS_Lib; */ BOOLEAN MS_IsRWPage; WORD MS_Model; diff --git a/drivers/staging/lirc/lirc_bt829.c b/drivers/staging/lirc/lirc_bt829.c index 33881025426b..c5a0d27a02dc 100644 --- a/drivers/staging/lirc/lirc_bt829.c +++ b/drivers/staging/lirc/lirc_bt829.c @@ -122,10 +122,10 @@ int init_module(void) pdev = do_pci_probe(); if (pdev == NULL) - return 1; + return -ENODEV; if (!atir_init_start()) - return 1; + return -ENODEV; strcpy(atir_driver.name, "ATIR"); atir_driver.minor = -1; diff --git a/drivers/staging/lirc/lirc_parallel.c b/drivers/staging/lirc/lirc_parallel.c index 50724c4e2484..792aac0a8e7b 100644 --- a/drivers/staging/lirc/lirc_parallel.c +++ b/drivers/staging/lirc/lirc_parallel.c @@ -615,9 +615,6 @@ static struct platform_driver lirc_parallel_driver = { }, }; -static int pf(void *handle); -static void kf(void *handle); - static int pf(void *handle) { parport_disable_irq(pport); @@ -730,6 +727,9 @@ static void __exit lirc_parallel_exit(void) { parport_unregister_device(ppdevice); lirc_unregister_driver(driver.minor); + + platform_device_unregister(lirc_parallel_dev); + platform_driver_unregister(&lirc_parallel_driver); } module_init(lirc_parallel_init); diff --git a/drivers/staging/lirc/lirc_ttusbir.c b/drivers/staging/lirc/lirc_ttusbir.c index e345ab9a004c..e4b329b8cafd 100644 --- a/drivers/staging/lirc/lirc_ttusbir.c +++ b/drivers/staging/lirc/lirc_ttusbir.c @@ -30,7 +30,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include #include #include diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c index 4e051f6b52db..0302d82a12f7 100644 --- a/drivers/staging/lirc/lirc_zilog.c +++ b/drivers/staging/lirc/lirc_zilog.c @@ -39,8 +39,6 @@ * */ - -#include #include #include #include diff --git a/drivers/staging/mei/init.c b/drivers/staging/mei/init.c index 685fcf639644..0fa8216fd0eb 100644 --- a/drivers/staging/mei/init.c +++ b/drivers/staging/mei/init.c @@ -29,54 +29,29 @@ const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, 0x81, 0x4c); /** - * mei_initialize_list - Sets up a queue list. + * mei_io_list_init - Sets up a queue list. * - * @list: An instance of our list structure + * @list: An instance io list structure * @dev: the device structure */ -void mei_initialize_list(struct mei_io_list *list, struct mei_device *dev) +void mei_io_list_init(struct mei_io_list *list) { /* initialize our queue list */ INIT_LIST_HEAD(&list->mei_cb.cb_list); list->status = 0; - list->device_extension = dev; } /** - * mei_flush_queues - flushes queue lists belonging to cl. - * - * @dev: the device structure - * @cl: private data of the file object - */ -void mei_flush_queues(struct mei_device *dev, struct mei_cl *cl) -{ - int i; - - if (!dev || !cl) - return; - - for (i = 0; i < MEI_IO_LISTS_NUMBER; i++) { - dev_dbg(&dev->pdev->dev, "remove list entry belonging to cl\n"); - mei_flush_list(dev->io_list_array[i], cl); - } -} - - -/** - * mei_flush_list - removes list entry belonging to cl. + * mei_io_list_flush - removes list entry belonging to cl. * * @list: An instance of our list structure * @cl: private data of the file object */ -void mei_flush_list(struct mei_io_list *list, struct mei_cl *cl) +void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl) { - struct mei_cl *cl_tmp; struct mei_cl_cb *cb_pos = NULL; struct mei_cl_cb *cb_next = NULL; - if (!list || !cl) - return; - if (list->status != 0) return; @@ -86,14 +61,36 @@ void mei_flush_list(struct mei_io_list *list, struct mei_cl *cl) list_for_each_entry_safe(cb_pos, cb_next, &list->mei_cb.cb_list, cb_list) { if (cb_pos) { - cl_tmp = (struct mei_cl *) - cb_pos->file_private; - if (cl_tmp && - mei_fe_same_id(cl, cl_tmp)) + struct mei_cl *cl_tmp; + cl_tmp = (struct mei_cl *)cb_pos->file_private; + if (mei_cl_cmp_id(cl, cl_tmp)) list_del(&cb_pos->cb_list); } } } +/** + * mei_cl_flush_queues - flushes queue lists belonging to cl. + * + * @dev: the device structure + * @cl: private data of the file object + */ +int mei_cl_flush_queues(struct mei_cl *cl) +{ + if (!cl || !cl->dev) + return -EINVAL; + + dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n"); + mei_io_list_flush(&cl->dev->read_list, cl); + mei_io_list_flush(&cl->dev->write_list, cl); + mei_io_list_flush(&cl->dev->write_waiting_list, cl); + mei_io_list_flush(&cl->dev->ctrl_wr_list, cl); + mei_io_list_flush(&cl->dev->ctrl_rd_list, cl); + mei_io_list_flush(&cl->dev->amthi_cmd_list, cl); + mei_io_list_flush(&cl->dev->amthi_read_complete_list, cl); + return 0; +} + + /** * mei_reset_iamthif_params - initializes mei device iamthif @@ -106,8 +103,8 @@ static void mei_reset_iamthif_params(struct mei_device *dev) dev->iamthif_current_cb = NULL; dev->iamthif_msg_buf_size = 0; dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = 0; - dev->iamthif_ioctl = 0; + dev->iamthif_canceled = false; + dev->iamthif_ioctl = false; dev->iamthif_state = MEI_IAMTHIF_IDLE; dev->iamthif_timer = 0; } @@ -119,9 +116,8 @@ static void mei_reset_iamthif_params(struct mei_device *dev) * * returns The mei_device_device pointer on success, NULL on failure. */ -struct mei_device *init_mei_device(struct pci_dev *pdev) +struct mei_device *mei_device_init(struct pci_dev *pdev) { - int i; struct mei_device *dev; dev = kzalloc(sizeof(struct mei_device), GFP_KERNEL); @@ -129,13 +125,6 @@ struct mei_device *init_mei_device(struct pci_dev *pdev) return NULL; /* setup our list array */ - dev->io_list_array[0] = &dev->read_list; - dev->io_list_array[1] = &dev->write_list; - dev->io_list_array[2] = &dev->write_waiting_list; - dev->io_list_array[3] = &dev->ctrl_wr_list; - dev->io_list_array[4] = &dev->ctrl_rd_list; - dev->io_list_array[5] = &dev->amthi_cmd_list; - dev->io_list_array[6] = &dev->amthi_read_complete_list; INIT_LIST_HEAD(&dev->file_list); INIT_LIST_HEAD(&dev->wd_cl.link); INIT_LIST_HEAD(&dev->iamthif_cl.link); @@ -144,8 +133,15 @@ struct mei_device *init_mei_device(struct pci_dev *pdev) init_waitqueue_head(&dev->wait_stop_wd); dev->mei_state = MEI_INITIALIZING; dev->iamthif_state = MEI_IAMTHIF_IDLE; - for (i = 0; i < MEI_IO_LISTS_NUMBER; i++) - mei_initialize_list(dev->io_list_array[i], dev); + + + mei_io_list_init(&dev->read_list); + mei_io_list_init(&dev->write_list); + mei_io_list_init(&dev->write_waiting_list); + mei_io_list_init(&dev->ctrl_wr_list); + mei_io_list_init(&dev->ctrl_rd_list); + mei_io_list_init(&dev->amthi_cmd_list); + mei_io_list_init(&dev->amthi_read_complete_list); dev->pdev = pdev; return dev; } @@ -173,7 +169,7 @@ int mei_hw_init(struct mei_device *dev) if ((dev->host_hw_state & H_IS) == H_IS) mei_reg_write(dev, H_CSR, dev->host_hw_state); - dev->recvd_msg = 0; + dev->recvd_msg = false; dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n"); mei_reset(dev, 1); @@ -223,7 +219,7 @@ int mei_hw_init(struct mei_device *dev) goto out; } - dev->recvd_msg = 0; + dev->recvd_msg = false; dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", dev->host_hw_state, dev->me_hw_state); dev_dbg(&dev->pdev->dev, "ME turn on ME_RDY and host turn on H_RDY.\n"); @@ -267,7 +263,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) bool unexpected; if (dev->mei_state == MEI_RECOVERING_FROM_RESET) { - dev->need_reset = 1; + dev->need_reset = true; return; } @@ -291,7 +287,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) dev_dbg(&dev->pdev->dev, "currently saved host_hw_state = 0x%08x.\n", dev->host_hw_state); - dev->need_reset = 0; + dev->need_reset = false; if (dev->mei_state != MEI_INITIALIZING) { if (dev->mei_state != MEI_DISABLED && @@ -318,10 +314,10 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) dev->extra_write_index = 0; } - dev->num_mei_me_clients = 0; + dev->me_clients_num = 0; dev->rd_msg_hdr = 0; - dev->stop = 0; - dev->wd_pending = 0; + dev->stop = false; + dev->wd_pending = false; /* update the state of the registers after reset */ dev->host_hw_state = mei_hcsr_read(dev); @@ -363,7 +359,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) * * returns none. */ -void host_start_message(struct mei_device *dev) +void mei_host_start_message(struct mei_device *dev) { struct mei_msg_hdr *mei_hdr; struct hbm_host_version_request *host_start_req; @@ -382,7 +378,7 @@ void host_start_message(struct mei_device *dev) host_start_req->cmd.cmd = HOST_START_REQ_CMD; host_start_req->host_version.major_version = HBM_MAJOR_VERSION; host_start_req->host_version.minor_version = HBM_MINOR_VERSION; - dev->recvd_msg = 0; + dev->recvd_msg = false; if (!mei_write_message(dev, mei_hdr, (unsigned char *) (host_start_req), mei_hdr->length)) { @@ -402,7 +398,7 @@ void host_start_message(struct mei_device *dev) * * returns none. */ -void host_enum_clients_message(struct mei_device *dev) +void mei_host_enum_clients_message(struct mei_device *dev) { struct mei_msg_hdr *mei_hdr; struct hbm_host_enum_request *host_enum_req; @@ -437,16 +433,16 @@ void host_enum_clients_message(struct mei_device *dev) * * returns none. */ -void allocate_me_clients_storage(struct mei_device *dev) +void mei_allocate_me_clients_storage(struct mei_device *dev) { struct mei_me_client *clients; int b; /* count how many ME clients we have */ for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX) - dev->num_mei_me_clients++; + dev->me_clients_num++; - if (dev->num_mei_me_clients <= 0) + if (dev->me_clients_num <= 0) return ; @@ -455,9 +451,9 @@ void allocate_me_clients_storage(struct mei_device *dev) dev->me_clients = NULL; } dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n", - dev->num_mei_me_clients * sizeof(struct mei_me_client)); + dev->me_clients_num * sizeof(struct mei_me_client)); /* allocate storage for ME clients representation */ - clients = kcalloc(dev->num_mei_me_clients, + clients = kcalloc(dev->me_clients_num, sizeof(struct mei_me_client), GFP_KERNEL); if (!clients) { dev_dbg(&dev->pdev->dev, "memory allocation for ME clients failed.\n"); @@ -475,7 +471,7 @@ void allocate_me_clients_storage(struct mei_device *dev) * * returns none. */ -void host_client_properties(struct mei_device *dev) +void mei_host_client_properties(struct mei_device *dev) { struct mei_msg_hdr *mei_header; struct hbm_props_request *host_cli_req; @@ -521,7 +517,6 @@ void host_client_properties(struct mei_device *dev) * with associated host client */ bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX); - dev->write_hang = -1; dev->open_handle_count = 0; bitmap_set(dev->host_clients_map, 0, 3); dev->mei_state = MEI_ENABLED; @@ -536,7 +531,7 @@ void host_client_properties(struct mei_device *dev) * @priv: private file structure to be initialized * @file: the file structure */ -void mei_init_file_private(struct mei_cl *priv, struct mei_device *dev) +void mei_cl_init(struct mei_cl *priv, struct mei_device *dev) { memset(priv, 0, sizeof(struct mei_cl)); init_waitqueue_head(&priv->wait); @@ -552,7 +547,7 @@ int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid) { int i, res = -1; - for (i = 0; i < dev->num_mei_me_clients; ++i) + for (i = 0; i < dev->me_clients_num; ++i) if (uuid_le_cmp(cuuid, dev->me_clients[i].props.protocol_name) == 0) { res = i; @@ -601,12 +596,12 @@ u8 mei_find_me_client_update_filext(struct mei_device *dev, struct mei_cl *priv, * @dev: the device structure * */ -void host_init_iamthif(struct mei_device *dev) +void mei_host_init_iamthif(struct mei_device *dev) { u8 i; unsigned char *msg_buf; - mei_init_file_private(&dev->iamthif_cl, dev); + mei_cl_init(&dev->iamthif_cl, dev); dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; /* find ME amthi client */ @@ -656,17 +651,17 @@ void host_init_iamthif(struct mei_device *dev) * * returns The allocated file or NULL on failure */ -struct mei_cl *mei_alloc_file_private(struct mei_device *dev) +struct mei_cl *mei_cl_allocate(struct mei_device *dev) { - struct mei_cl *priv; + struct mei_cl *cl; - priv = kmalloc(sizeof(struct mei_cl), GFP_KERNEL); - if (!priv) + cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL); + if (!cl) return NULL; - mei_init_file_private(priv, dev); + mei_cl_init(cl, dev); - return priv; + return cl; } @@ -701,7 +696,7 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) cb->file_private = cl; cb->major_file_operations = MEI_CLOSE; if (dev->mei_host_buffer_is_empty) { - dev->mei_host_buffer_is_empty = 0; + dev->mei_host_buffer_is_empty = false; if (mei_disconnect(dev, cl)) { mdelay(10); /* Wait for hardware disconnection ready */ list_add_tail(&cb->cb_list, @@ -739,8 +734,8 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n"); } - mei_flush_list(&dev->ctrl_rd_list, cl); - mei_flush_list(&dev->ctrl_wr_list, cl); + mei_io_list_flush(&dev->ctrl_rd_list, cl); + mei_io_list_flush(&dev->ctrl_wr_list, cl); free: mei_free_cb_private(cb); return rets; diff --git a/drivers/staging/mei/interface.c b/drivers/staging/mei/interface.c index 4959aae37b85..cfec92dfc1c4 100644 --- a/drivers/staging/mei/interface.c +++ b/drivers/staging/mei/interface.c @@ -179,7 +179,6 @@ int mei_write_message(struct mei_device *dev, if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) return 0; - dev->write_hang = 0; return 1; } @@ -256,13 +255,13 @@ int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl) { int i; - if (!dev->num_mei_me_clients) + if (!dev->me_clients_num) return 0; if (cl->mei_flow_ctrl_creds > 0) return 1; - for (i = 0; i < dev->num_mei_me_clients; i++) { + for (i = 0; i < dev->me_clients_num; i++) { struct mei_me_client *me_cl = &dev->me_clients[i]; if (me_cl->client_id == cl->me_client_id) { if (me_cl->mei_flow_ctrl_creds) { @@ -291,10 +290,10 @@ int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl) { int i; - if (!dev->num_mei_me_clients) + if (!dev->me_clients_num) return -ENOENT; - for (i = 0; i < dev->num_mei_me_clients; i++) { + for (i = 0; i < dev->me_clients_num; i++) { struct mei_me_client *me_cl = &dev->me_clients[i]; if (me_cl->client_id == cl->me_client_id) { if (me_cl->props.single_recv_buf != 0) { diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c index d1b9214c10c7..9cb186bf1874 100644 --- a/drivers/staging/mei/interrupt.c +++ b/drivers/staging/mei/interrupt.c @@ -94,7 +94,7 @@ static void _mei_cmpl_iamthif(struct mei_device *dev, struct mei_cl_cb *cb_pos) dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", dev->iamthif_timer); } else { - run_next_iamthif_cmd(dev); + mei_run_next_iamthif_cmd(dev); } dev_dbg(&dev->pdev->dev, "completing amthi call back.\n"); @@ -195,7 +195,7 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, { struct mei_cl *cl; struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; - unsigned char *buffer; + unsigned char *buffer = NULL; dev_dbg(&dev->pdev->dev, "start client msg\n"); if (!(dev->read_list.status == 0 && @@ -280,7 +280,7 @@ static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots) } else { dev_dbg(&dev->pdev->dev, "iamthif flow control success\n"); dev->iamthif_state = MEI_IAMTHIF_READING; - dev->iamthif_flow_control_pending = 0; + dev->iamthif_flow_control_pending = false; dev->iamthif_msg_buf_index = 0; dev->iamthif_msg_buf_size = 0; dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER; @@ -396,7 +396,7 @@ static void mei_client_connect_response(struct mei_device *dev, dev->wd_due_counter = (dev->wd_timeout) ? 1 : 0; dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n"); - host_init_iamthif(dev); + mei_host_init_iamthif(dev); return; } @@ -499,7 +499,7 @@ static void add_single_flow_creds(struct mei_device *dev, struct mei_me_client *client; int i; - for (i = 0; i < dev->num_mei_me_clients; i++) { + for (i = 0; i < dev->me_clients_num; i++) { client = &dev->me_clients[i]; if (client && flow->me_addr == client->client_id) { if (client->props.single_recv_buf) { @@ -593,7 +593,7 @@ static void mei_client_disconnect_request(struct mei_device *dev, cl_pos->timer_count = 0; if (cl_pos == &dev->wd_cl) { dev->wd_due_counter = 0; - dev->wd_pending = 0; + dev->wd_pending = false; } else if (cl_pos == &dev->iamthif_cl) dev->iamthif_timer = 0; @@ -659,9 +659,9 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, if (dev->mei_state == MEI_INIT_CLIENTS && dev->init_clients_state == MEI_START_MESSAGE) { dev->init_clients_timer = 0; - host_enum_clients_message(dev); + mei_host_enum_clients_message(dev); } else { - dev->recvd_msg = 0; + dev->recvd_msg = false; dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n"); mei_reset(dev, 1); return; @@ -690,7 +690,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, return; } - dev->recvd_msg = 1; + dev->recvd_msg = true; dev_dbg(&dev->pdev->dev, "host start response message received.\n"); break; @@ -734,7 +734,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, MEI_CLIENT_PROPERTIES_MESSAGE) { dev->me_client_index++; dev->me_client_presentation_num++; - host_client_properties(dev); + mei_host_client_properties(dev); } else { dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message"); mei_reset(dev, 1); @@ -755,10 +755,10 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, dev->init_clients_timer = 0; dev->me_client_presentation_num = 0; dev->me_client_index = 0; - allocate_me_clients_storage(dev); + mei_allocate_me_clients_storage(dev); dev->init_clients_state = MEI_CLIENT_PROPERTIES_MESSAGE; - host_client_properties(dev); + mei_host_client_properties(dev); } else { dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n"); mei_reset(dev, 1); @@ -1028,7 +1028,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, cb_pos->information = dev->iamthif_msg_buf_index; cl->status = 0; dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; - dev->iamthif_flow_control_pending = 1; + dev->iamthif_flow_control_pending = true; /* save iamthif cb sent to amthi client */ dev->iamthif_current_cb = cb_pos; list_move_tail(&cb_pos->cb_list, @@ -1192,7 +1192,6 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); return 0; } - dev->write_hang = -1; *slots = mei_count_empty_write_slots(dev); /* complete all waiting for write CB */ dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n"); @@ -1232,7 +1231,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, } if (dev->stop && !dev->wd_pending) { - dev->wd_stopped = 1; + dev->wd_stopped = true; wake_up_interruptible(&dev->wait_stop_wd); return 0; } @@ -1256,7 +1255,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, if (mei_flow_ctrl_reduce(dev, &dev->wd_cl)) return -ENODEV; - dev->wd_pending = 0; + dev->wd_pending = false; if (dev->wd_timeout) { *slots -= (sizeof(struct mei_msg_hdr) + @@ -1427,7 +1426,7 @@ void mei_wd_timer(struct work_struct *work) if (--dev->wd_due_counter == 0) { if (dev->mei_host_buffer_is_empty && mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) { - dev->mei_host_buffer_is_empty = 0; + dev->mei_host_buffer_is_empty = false; dev_dbg(&dev->pdev->dev, "send watchdog.\n"); if (mei_wd_send(dev)) @@ -1442,7 +1441,7 @@ void mei_wd_timer(struct work_struct *work) dev->wd_due_counter = 0; } else - dev->wd_pending = 1; + dev->wd_pending = true; } } @@ -1452,8 +1451,8 @@ void mei_wd_timer(struct work_struct *work) mei_reset(dev, 1); dev->iamthif_msg_buf_size = 0; dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = 0; - dev->iamthif_ioctl = 1; + dev->iamthif_canceled = false; + dev->iamthif_ioctl = true; dev->iamthif_state = MEI_IAMTHIF_IDLE; dev->iamthif_timer = 0; @@ -1462,7 +1461,7 @@ void mei_wd_timer(struct work_struct *work) dev->iamthif_file_object = NULL; dev->iamthif_current_cb = NULL; - run_next_iamthif_cmd(dev); + mei_run_next_iamthif_cmd(dev); } } @@ -1506,7 +1505,7 @@ void mei_wd_timer(struct work_struct *work) dev->iamthif_file_object = NULL; dev->iamthif_current_cb = NULL; dev->iamthif_timer = 0; - run_next_iamthif_cmd(dev); + mei_run_next_iamthif_cmd(dev); } } @@ -1539,7 +1538,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n"); /* initialize our complete list */ mutex_lock(&dev->device_lock); - mei_initialize_list(&complete_list, dev); + mei_io_list_init(&complete_list); dev->host_hw_state = mei_hcsr_read(dev); dev->me_hw_state = mei_mecsr_read(dev); @@ -1564,7 +1563,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) /* link is established * start sending messages. */ - host_start_message(dev); + mei_host_start_message(dev); mutex_unlock(&dev->device_lock); return IRQ_HANDLED; } else { diff --git a/drivers/staging/mei/iorw.c b/drivers/staging/mei/iorw.c index 697a2773d7cd..8a61d1266515 100644 --- a/drivers/staging/mei/iorw.c +++ b/drivers/staging/mei/iorw.c @@ -121,7 +121,7 @@ int mei_ioctl_connect_client(struct file *file, clear_bit(cl->host_client_id, dev->host_clients_map); list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if (mei_fe_same_id(cl, cl_pos)) { + if (mei_cl_cmp_id(cl, cl_pos)) { dev_dbg(&dev->pdev->dev, "remove file private data node host" " client = %d, ME client = %d.\n", @@ -161,7 +161,7 @@ int mei_ioctl_connect_client(struct file *file, if (dev->mei_host_buffer_is_empty && !mei_other_client_is_connecting(dev, cl)) { dev_dbg(&dev->pdev->dev, "Sending Connect Message\n"); - dev->mei_host_buffer_is_empty = 0; + dev->mei_host_buffer_is_empty = false; if (!mei_connect(dev, cl)) { dev_dbg(&dev->pdev->dev, "Sending connect message - failed\n"); rets = -ENODEV; @@ -204,8 +204,8 @@ int mei_ioctl_connect_client(struct file *file, } rets = -EFAULT; - mei_flush_list(&dev->ctrl_rd_list, cl); - mei_flush_list(&dev->ctrl_wr_list, cl); + mei_io_list_flush(&dev->ctrl_rd_list, cl); + mei_io_list_flush(&dev->ctrl_wr_list, cl); goto end; } rets = 0; @@ -277,13 +277,13 @@ int amthi_read(struct mei_device *dev, struct file *file, return -ETIMEDOUT; } - for (i = 0; i < dev->num_mei_me_clients; i++) { + for (i = 0; i < dev->me_clients_num; i++) { if (dev->me_clients[i].client_id == dev->iamthif_cl.me_client_id) break; } - if (i == dev->num_mei_me_clients) { + if (i == dev->me_clients_num) { dev_dbg(&dev->pdev->dev, "amthi client not found.\n"); return -ENODEV; } @@ -409,7 +409,7 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl) dev_dbg(&dev->pdev->dev, "allocation call back successful. host client = %d, ME client = %d\n", cl->host_client_id, cl->me_client_id); - for (i = 0; i < dev->num_mei_me_clients; i++) { + for (i = 0; i < dev->me_clients_num; i++) { if (dev->me_clients[i].client_id == cl->me_client_id) break; @@ -420,7 +420,7 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl) goto unlock; } - if (i == dev->num_mei_me_clients) { + if (i == dev->me_clients_num) { rets = -ENODEV; goto unlock; } @@ -439,7 +439,7 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl) cb->file_private = (void *) cl; cl->read_cb = cb; if (dev->mei_host_buffer_is_empty) { - dev->mei_host_buffer_is_empty = 0; + dev->mei_host_buffer_is_empty = false; if (!mei_send_flow_control(dev, cl)) { rets = -ENODEV; goto unlock; @@ -478,8 +478,8 @@ int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb) dev->iamthif_state = MEI_IAMTHIF_WRITING; dev->iamthif_current_cb = cb; dev->iamthif_file_object = cb->file_object; - dev->iamthif_canceled = 0; - dev->iamthif_ioctl = 1; + dev->iamthif_canceled = false; + dev->iamthif_ioctl = true; dev->iamthif_msg_buf_size = cb->request_buffer.size; memcpy(dev->iamthif_msg_buf, cb->request_buffer.data, cb->request_buffer.size); @@ -490,7 +490,7 @@ int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb) if (ret && dev->mei_host_buffer_is_empty) { ret = 0; - dev->mei_host_buffer_is_empty = 0; + dev->mei_host_buffer_is_empty = false; if (cb->request_buffer.size > (((dev->host_hw_state & H_CBD) >> 24) * sizeof(u32)) -sizeof(struct mei_msg_hdr)) { @@ -515,7 +515,7 @@ int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb) if (mei_hdr.msg_complete) { if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl)) return -ENODEV; - dev->iamthif_flow_control_pending = 1; + dev->iamthif_flow_control_pending = true; dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n"); dev->iamthif_current_cb = cb; @@ -547,7 +547,7 @@ int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb) * * returns 0 on success, <0 on failure. */ -void run_next_iamthif_cmd(struct mei_device *dev) +void mei_run_next_iamthif_cmd(struct mei_device *dev) { struct mei_cl *cl_tmp; struct mei_cl_cb *cb_pos = NULL; @@ -559,8 +559,8 @@ void run_next_iamthif_cmd(struct mei_device *dev) dev->iamthif_msg_buf_size = 0; dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = 0; - dev->iamthif_ioctl = 1; + dev->iamthif_canceled = false; + dev->iamthif_ioctl = true; dev->iamthif_state = MEI_IAMTHIF_IDLE; dev->iamthif_timer = 0; dev->iamthif_file_object = NULL; diff --git a/drivers/staging/mei/main.c b/drivers/staging/mei/main.c index bfd1b46ec748..de8825fcd8ce 100644 --- a/drivers/staging/mei/main.c +++ b/drivers/staging/mei/main.c @@ -14,8 +14,6 @@ * */ - - #include #include #include @@ -30,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -142,7 +139,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, goto disable_device; } /* allocates and initializes the mei dev structure */ - dev = init_mei_device(pdev); + dev = mei_device_init(pdev); if (!dev) { err = -ENOMEM; goto release_regions; @@ -240,7 +237,7 @@ static void __devexit mei_remove(struct pci_dev *pdev) mei_remove_client_from_file_list(dev, dev->iamthif_cl.host_client_id); dev->iamthif_current_cb = NULL; - dev->num_mei_me_clients = 0; + dev->me_clients_num = 0; mutex_unlock(&dev->device_lock); @@ -362,7 +359,6 @@ static struct mei_cl_cb *find_read_list_entry( { struct mei_cl_cb *cb_pos = NULL; struct mei_cl_cb *cb_next = NULL; - struct mei_cl *cl_list_temp; if (!dev->read_list.status && !list_empty(&dev->read_list.mei_cb.cb_list)) { @@ -370,14 +366,11 @@ static struct mei_cl_cb *find_read_list_entry( dev_dbg(&dev->pdev->dev, "remove read_list CB\n"); list_for_each_entry_safe(cb_pos, cb_next, &dev->read_list.mei_cb.cb_list, cb_list) { + struct mei_cl *cl_temp; + cl_temp = (struct mei_cl *)cb_pos->file_private; - cl_list_temp = (struct mei_cl *) - cb_pos->file_private; - - if (cl_list_temp && - mei_fe_same_id(cl, cl_list_temp)) + if (mei_cl_cmp_id(cl, cl_temp)) return cb_pos; - } } return NULL; @@ -407,7 +400,7 @@ static int mei_open(struct inode *inode, struct file *file) mutex_lock(&dev->device_lock); err = -ENOMEM; - cl = mei_alloc_file_private(dev); + cl = mei_cl_allocate(dev); if (!cl) goto out; @@ -478,7 +471,7 @@ static int mei_release(struct inode *inode, struct file *file) cl->me_client_id); rets = mei_disconnect_host_client(dev, cl); } - mei_flush_queues(dev, cl); + mei_cl_flush_queues(cl); dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n", cl->host_client_id, cl->me_client_id); @@ -519,10 +512,10 @@ static int mei_release(struct inode *inode, struct file *file) dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n", dev->iamthif_state); - dev->iamthif_canceled = 1; + dev->iamthif_canceled = true; if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) { dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n"); - run_next_iamthif_cmd(dev); + mei_run_next_iamthif_cmd(dev); } } @@ -800,7 +793,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, rets = -ENODEV; goto unlock_dev; } - for (i = 0; i < dev->num_mei_me_clients; i++) { + for (i = 0; i < dev->me_clients_num; i++) { if (dev->me_clients[i].client_id == dev->iamthif_cl.me_client_id) break; @@ -810,7 +803,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, rets = -ENODEV; goto unlock_dev; } - if (i == dev->num_mei_me_clients || + if (i == dev->me_clients_num || (dev->me_clients[i].client_id != dev->iamthif_cl.me_client_id)) { rets = -ENODEV; @@ -868,7 +861,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, cl->me_client_id); goto unlock_dev; } - for (i = 0; i < dev->num_mei_me_clients; i++) { + for (i = 0; i < dev->me_clients_num; i++) { if (dev->me_clients[i].client_id == cl->me_client_id) break; @@ -877,7 +870,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, rets = -ENODEV; goto unlock_dev; } - if (i == dev->num_mei_me_clients) { + if (i == dev->me_clients_num) { rets = -ENODEV; goto unlock_dev; } @@ -893,7 +886,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (rets && dev->mei_host_buffer_is_empty) { rets = 0; - dev->mei_host_buffer_is_empty = 0; + dev->mei_host_buffer_is_empty = false; if (length > ((((dev->host_hw_state & H_CBD) >> 24) * sizeof(u32)) - sizeof(struct mei_msg_hdr))) { @@ -1066,7 +1059,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait) dev->iamthif_file_object == file) { mask |= (POLLIN | POLLRDNORM); dev_dbg(&dev->pdev->dev, "run next amthi cb\n"); - run_next_iamthif_cmd(dev); + mei_run_next_iamthif_cmd(dev); } goto out; } @@ -1333,9 +1326,9 @@ module_init(mei_init_module); */ static void __exit mei_exit_module(void) { - pci_unregister_driver(&mei_driver); mei_sysfs_device_remove(); mei_unregister_cdev(); + pci_unregister_driver(&mei_driver); pr_debug("mei: Driver unloaded successfully.\n"); } diff --git a/drivers/staging/mei/mei_dev.h b/drivers/staging/mei/mei_dev.h index 6f3ec068ed69..d7bc10c612be 100644 --- a/drivers/staging/mei/mei_dev.h +++ b/drivers/staging/mei/mei_dev.h @@ -61,11 +61,6 @@ extern const u8 mei_wd_state_independence_msg[3][4]; */ #define MEI_MAX_OPEN_HANDLE_COUNT 253 -/* - * Number of queue lists used by this driver - */ -#define MEI_IO_LISTS_NUMBER 7 - /* * Number of Maximum MEI Clients */ @@ -169,7 +164,6 @@ struct mei_cl { struct mei_io_list { struct mei_cl_cb mei_cb; int status; - struct mei_device *device_extension; }; /* MEI private device struct */ @@ -179,7 +173,6 @@ struct mei_device { * lists of queues */ /* array of pointers to aio lists */ - struct mei_io_list *io_list_array[MEI_IO_LISTS_NUMBER]; struct mei_io_list read_list; /* driver read queue */ struct mei_io_list write_list; /* driver write queue */ struct mei_io_list write_waiting_list; /* write waiting queue */ @@ -193,6 +186,7 @@ struct mei_device { * list of files */ struct list_head file_list; + long open_handle_count; /* * memory of device */ @@ -203,8 +197,8 @@ struct mei_device { * lock for the device */ struct mutex device_lock; /* device lock */ - int recvd_msg; struct delayed_work wd_work; /* watch dog deleye work */ + bool recvd_msg; /* * hw states of host and fw(ME) */ @@ -222,7 +216,8 @@ struct mei_device { enum mei_states mei_state; enum mei_init_clients_states init_clients_state; u16 init_clients_timer; - int stop; + bool stop; + bool need_reset; u32 extra_write_index; u32 rd_msg_buf[128]; /* used for control messages */ @@ -232,81 +227,105 @@ struct mei_device { struct hbm_version version; - int mei_host_buffer_is_empty; - struct mei_cl wd_cl; struct mei_me_client *me_clients; /* Note: memory has to be allocated */ DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); - u8 num_mei_me_clients; + u8 me_clients_num; u8 me_client_presentation_num; u8 me_client_index; + bool mei_host_buffer_is_empty; - int wd_pending; - int wd_stopped; + struct mei_cl wd_cl; + bool wd_pending; + bool wd_stopped; + bool wd_bypass; /* if false, don't refresh watchdog ME client */ u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */ + u16 wd_due_counter; unsigned char wd_data[MEI_START_WD_DATA_SIZE]; - u16 wd_due_counter; - bool wd_bypass; /* if false, don't refresh watchdog ME client */ struct file *iamthif_file_object; struct mei_cl iamthif_cl; - int iamthif_ioctl; - int iamthif_canceled; + struct mei_cl_cb *iamthif_current_cb; int iamthif_mtu; unsigned long iamthif_timer; u32 iamthif_stall_timer; unsigned char *iamthif_msg_buf; /* Note: memory has to be allocated */ u32 iamthif_msg_buf_size; u32 iamthif_msg_buf_index; - int iamthif_flow_control_pending; enum iamthif_states iamthif_state; - struct mei_cl_cb *iamthif_current_cb; - u8 write_hang; - int need_reset; - long open_handle_count; - + bool iamthif_flow_control_pending; + bool iamthif_ioctl; + bool iamthif_canceled; }; /* * mei init function prototypes */ -struct mei_device *init_mei_device(struct pci_dev *pdev); +struct mei_device *mei_device_init(struct pci_dev *pdev); void mei_reset(struct mei_device *dev, int interrupts); int mei_hw_init(struct mei_device *dev); int mei_task_initialize_clients(void *data); int mei_initialize_clients(struct mei_device *dev); -struct mei_cl *mei_alloc_file_private(struct mei_device *dev); int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl); -void mei_initialize_list(struct mei_io_list *list, - struct mei_device *dev); -void mei_flush_list(struct mei_io_list *list, struct mei_cl *cl); -void mei_flush_queues(struct mei_device *dev, struct mei_cl *cl); -void mei_remove_client_from_file_list(struct mei_device *dev, - u8 host_client_id); -void host_init_iamthif(struct mei_device *dev); -void mei_init_file_private(struct mei_cl *priv, struct mei_device *dev); -void allocate_me_clients_storage(struct mei_device *dev); +void mei_remove_client_from_file_list(struct mei_device *dev, u8 host_client_id); +void mei_host_init_iamthif(struct mei_device *dev); +void mei_allocate_me_clients_storage(struct mei_device *dev); -void host_start_message(struct mei_device *dev); -void host_enum_clients_message(struct mei_device *dev); -void host_client_properties(struct mei_device *dev); u8 mei_find_me_client_update_filext(struct mei_device *dev, struct mei_cl *priv, const uuid_le *cguid, u8 client_id); /* - * interrupt functions prototype + * MEI IO List Functions + */ +void mei_io_list_init(struct mei_io_list *list); +void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl); + +/* + * MEI ME Client Functions + */ + +struct mei_cl *mei_cl_allocate(struct mei_device *dev); +void mei_cl_init(struct mei_cl *cl, struct mei_device *dev); +int mei_cl_flush_queues(struct mei_cl *cl); +/** + * mei_cl_cmp_id - tells if file private data have same id + * + * @fe1: private data of 1. file object + * @fe2: private data of 2. file object + * + * returns true - if ids are the same and not NULL + */ +static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, + const struct mei_cl *cl2) +{ + return cl1 && cl2 && + (cl1->host_client_id == cl2->host_client_id) && + (cl1->me_client_id == cl2->me_client_id); +} + + + +/* + * MEI Host Client Functions + */ +void mei_host_start_message(struct mei_device *dev); +void mei_host_enum_clients_message(struct mei_device *dev); +void mei_host_client_properties(struct mei_device *dev); + +/* + * MEI interrupt functions prototype */ irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id); -irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id); +irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id); void mei_wd_timer(struct work_struct *work); /* - * input output function prototype + * MEI input output function prototype */ int mei_ioctl_connect_client(struct file *file, struct mei_connect_client_data *data); @@ -321,7 +340,7 @@ int amthi_read(struct mei_device *dev, struct file *file, struct mei_cl_cb *find_amthi_read_list_entry(struct mei_device *dev, struct file *file); -void run_next_iamthif_cmd(struct mei_device *dev); +void mei_run_next_iamthif_cmd(struct mei_device *dev); void mei_free_cb_private(struct mei_cl_cb *priv_cb); @@ -339,8 +358,7 @@ int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid); * * returns the byte read. */ -static inline u32 mei_reg_read(struct mei_device *dev, - unsigned long offset) +static inline u32 mei_reg_read(struct mei_device *dev, unsigned long offset) { return ioread32(dev->mem_addr + offset); } @@ -404,19 +422,4 @@ void mei_csr_clear_his(struct mei_device *dev); void mei_enable_interrupts(struct mei_device *dev); void mei_disable_interrupts(struct mei_device *dev); -/** - * mei_fe_same_id - tells if file private data have same id - * - * @fe1: private data of 1. file object - * @fe2: private data of 2. file object - * - * returns !=0 - if ids are the same, 0 - if differ. - */ -static inline int mei_fe_same_id(const struct mei_cl *fe1, - const struct mei_cl *fe2) -{ - return ((fe1->host_client_id == fe2->host_client_id) && - (fe1->me_client_id == fe2->me_client_id)); -} - #endif diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c index fff53d0b5c6e..42f04efc90e4 100644 --- a/drivers/staging/mei/wd.c +++ b/drivers/staging/mei/wd.c @@ -65,7 +65,7 @@ void mei_wd_start_setup(struct mei_device *dev) */ void mei_wd_host_init(struct mei_device *dev) { - mei_init_file_private(&dev->wd_cl, dev); + mei_cl_init(&dev->wd_cl, dev); /* look for WD client and connect to it */ dev->wd_cl.state = MEI_FILE_DISCONNECTED; @@ -83,18 +83,18 @@ void mei_wd_host_init(struct mei_device *dev) dev_dbg(&dev->pdev->dev, "Failed to connect to WD client\n"); dev->wd_cl.state = MEI_FILE_DISCONNECTED; dev->wd_cl.host_client_id = 0; - host_init_iamthif(dev) ; + mei_host_init_iamthif(dev) ; } else { dev->wd_cl.timer_count = CONNECT_TIMEOUT; } } else { dev_dbg(&dev->pdev->dev, "Failed to find WD client\n"); - host_init_iamthif(dev) ; + mei_host_init_iamthif(dev) ; } } else { dev->wd_bypass = true; dev_dbg(&dev->pdev->dev, "WD requested to be disabled\n"); - host_init_iamthif(dev) ; + mei_host_init_iamthif(dev) ; } } @@ -141,7 +141,7 @@ int mei_wd_stop(struct mei_device *dev, bool preserve) dev->wd_timeout = 0; dev->wd_due_counter = 0; memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE); - dev->stop = 1; + dev->stop = true; ret = mei_flow_ctrl_creds(dev, &dev->wd_cl); if (ret < 0) @@ -149,7 +149,7 @@ int mei_wd_stop(struct mei_device *dev, bool preserve) if (ret && dev->mei_host_buffer_is_empty) { ret = 0; - dev->mei_host_buffer_is_empty = 0; + dev->mei_host_buffer_is_empty = false; if (!mei_wd_send(dev)) { ret = mei_flow_ctrl_reduce(dev, &dev->wd_cl); @@ -159,11 +159,11 @@ int mei_wd_stop(struct mei_device *dev, bool preserve) dev_dbg(&dev->pdev->dev, "send stop WD failed\n"); } - dev->wd_pending = 0; + dev->wd_pending = false; } else { - dev->wd_pending = 1; + dev->wd_pending = true; } - dev->wd_stopped = 0; + dev->wd_stopped = false; mutex_unlock(&dev->device_lock); ret = wait_event_interruptible_timeout(dev->wait_stop_wd, diff --git a/drivers/staging/msm/Kconfig b/drivers/staging/msm/Kconfig deleted file mode 100644 index c5309eec58fa..000000000000 --- a/drivers/staging/msm/Kconfig +++ /dev/null @@ -1,124 +0,0 @@ -config MSM_STAGING - tristate "MSM Frame Buffer Support" - depends on FB && ARCH_MSM && !FB_MSM - select FB_BACKLIGHT if FB_MSM_BACKLIGHT - select NEW_LEDS - select LEDS_CLASS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Support for MSM Framebuffer. - -if MSM_STAGING - -config FB_MSM_LCDC_HW - bool - default n - -choice - prompt "MDP HW version" - default FB_MSM_MDP31 - -config FB_MSM_MDP31 - select FB_MSM_LCDC_HW - bool "MDP HW ver3.1" - ---help--- - Support for MSM MDP HW revision 3.1 - Say Y here if this is msm8x50 variant platform. -endchoice - -config FB_MSM_LCDC - bool - default n - -config FB_MSM_TVOUT - bool - default n - -config FB_MSM_LCDC_PANEL - bool - select FB_MSM_LCDC - default n - -config FB_MSM_LCDC_PRISM_WVGA - bool - select FB_MSM_LCDC_PANEL - default n - -config FB_MSM_LCDC_ST15_WXGA - bool - select FB_MSM_LCDC_PANEL - default n - -choice - prompt "LCD Panel" - default FB_MSM_LCDC_ST15_PANEL - -config FB_MSM_LCDC_PRISM_WVGA_PANEL - depends on FB_MSM_LCDC_HW - bool "LCDC Prism WVGA Panel" - select FB_MSM_LCDC_PRISM_WVGA - ---help--- - Support for LCDC Prism WVGA (800x480) panel - - -config FB_MSM_LCDC_ST15_PANEL - depends on FB_MSM_LCDC_HW - bool "LCDC ST1.5 Panel" - select FB_MSM_LCDC_ST15_WXGA - ---help--- - Support for ST1.5 WXGA (1366x768) panel - -config FB_MSM_PANEL_NONE - bool "NONE" - ---help--- - This will disable LCD panel -endchoice - -choice - prompt "Secondary LCD Panel" - depends on FB_MSM_MDP31 - default FB_MSM_SECONDARY_PANEL_NONE - -config FB_MSM_SECONDARY_PANEL_NONE - bool "NONE" - ---help--- - No secondary panel -endchoice - -config FB_MSM_TVOUT_NTSC - bool - select FB_MSM_TVOUT - default n - -config FB_MSM_TVOUT_PAL - bool - select FB_MSM_TVOUT - default n - -choice - depends on (FB_MSM_MDP22 || FB_MSM_MDP31) - prompt "TVOut Region" - default FB_MSM_TVOUT_NTSC_M - -config FB_MSM_TVOUT_NTSC_M - bool "NTSC M" - select FB_MSM_TVOUT_NTSC - ---help--- - Support for NTSC M region (North American and Korea) - -config FB_MSM_TVOUT_NONE - bool "NONE" - ---help--- - This will disable TV Out functionality. -endchoice - -config PMEM_KERNEL_SIZE - int "PMEM for kernel components (in MB)" - default 2 - depends on ARCH_QSD8X50 - help - Configures the amount of PMEM for use by kernel components - (in MB; minimum 2MB) -endif diff --git a/drivers/staging/msm/Makefile b/drivers/staging/msm/Makefile deleted file mode 100644 index 07a89ecfcc2b..000000000000 --- a/drivers/staging/msm/Makefile +++ /dev/null @@ -1,88 +0,0 @@ -obj-y := msm_fb.o staging-devices.o memory.o - -obj-$(CONFIG_FB_MSM_LOGO) += logo.o -obj-$(CONFIG_FB_BACKLIGHT) += msm_fb_bl.o - -# MDP -obj-y += mdp.o - -ifeq ($(CONFIG_FB_MSM_MDP40),y) -obj-y += mdp4_util.o -obj-$(CONFIG_DEBUG_FS) += mdp4_debugfs.o -else -obj-y += mdp_hw_init.o -obj-y += mdp_ppp.o -ifeq ($(CONFIG_FB_MSM_MDP31),y) -obj-y += mdp_ppp_v31.o -obj-$(CONFIG_MDP_PPP_ASYNC_OP) += mdp_ppp_dq.o -else -obj-y += mdp_ppp_v20.o -endif -endif - -ifeq ($(CONFIG_FB_MSM_OVERLAY),y) -obj-y += mdp4_overlay.o -obj-y += mdp4_overlay_lcdc.o -obj-y += mdp4_overlay_mddi.o -else -obj-y += mdp_dma_lcdc.o -endif - -obj-y += mdp_dma.o -obj-y += mdp_dma_s.o -obj-y += mdp_vsync.o -obj-y += mdp_cursor.o -obj-y += mdp_dma_tv.o - -# EBI2 -obj-$(CONFIG_FB_MSM_EBI2) += ebi2_lcd.o - -# LCDC -obj-$(CONFIG_FB_MSM_LCDC) += lcdc.o - -# MDDI -msm_mddi-y := mddi.o mddihost.o mddihosti.o -obj-$(CONFIG_FB_MSM_MDDI) += msm_mddi.o - -# External MDDI -msm_mddi_ext-y := mddihost_e.o mddi_ext.o -obj-$(CONFIG_FB_MSM_EXTMDDI) += msm_mddi_ext.o - -# TVEnc -obj-$(CONFIG_FB_MSM_TVOUT) += tvenc.o - -# MSM FB Panel -obj-y += msm_fb_panel.o -obj-$(CONFIG_FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF) += ebi2_tmd20.o -obj-$(CONFIG_FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF) += ebi2_l2f.o - -ifeq ($(CONFIG_FB_MSM_MDDI_AUTO_DETECT),y) -obj-y += mddi_prism.o -obj-y += mddi_toshiba.o -obj-y += mddi_toshiba_vga.o -obj-y += mddi_toshiba_wvga_pt.o -obj-y += mddi_sharp.o -else -obj-$(CONFIG_FB_MSM_MDDI_PRISM_WVGA) += mddi_prism.o -obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON) += mddi_toshiba.o -obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON_VGA) += mddi_toshiba_vga.o -obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_WVGA_PORTRAIT) += mddi_toshiba_wvga_pt.o -obj-$(CONFIG_FB_MSM_MDDI_SHARP_QVGA_128x128) += mddi_sharp.o -endif - -obj-$(CONFIG_FB_MSM_LCDC_PANEL) += lcdc_panel.o -obj-$(CONFIG_FB_MSM_LCDC_PRISM_WVGA) += lcdc_prism.o -obj-$(CONFIG_FB_MSM_LCDC_EXTERNAL_WXGA) += lcdc_external.o -obj-$(CONFIG_FB_MSM_LCDC_GORDON_VGA) += lcdc_gordon.o -obj-$(CONFIG_FB_MSM_LCDC_TOSHIBA_WVGA_PT) += lcdc_toshiba_wvga_pt.o -obj-$(CONFIG_FB_MSM_LCDC_SHARP_WVGA_PT) += lcdc_sharp_wvga_pt.o -obj-$(CONFIG_FB_MSM_LCDC_ST15_WXGA) += lcdc_st15.o -obj-$(CONFIG_FB_MSM_HDMI_SII_EXTERNAL_720P) += hdmi_sii9022.o - -obj-$(CONFIG_FB_MSM_TVOUT_NTSC) += tv_ntsc.o -obj-$(CONFIG_FB_MSM_TVOUT_PAL) += tv_pal.o - -obj-$(CONFIG_FB_MSM_EXTMDDI_SVGA) += mddi_ext_lcd.o - -clean: - rm *.o .*cmd diff --git a/drivers/staging/msm/TODO b/drivers/staging/msm/TODO deleted file mode 100644 index 05107a7d516a..000000000000 --- a/drivers/staging/msm/TODO +++ /dev/null @@ -1,3 +0,0 @@ -- Merge this code with the existing MSM framebuffer -- General style clean ups. - diff --git a/drivers/staging/msm/ebi2_l2f.c b/drivers/staging/msm/ebi2_l2f.c deleted file mode 100644 index eea891d8f0f8..000000000000 --- a/drivers/staging/msm/ebi2_l2f.c +++ /dev/null @@ -1,569 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "msm_fb.h" - -#include -#include -#include -#include -#include -#include -#include "linux/proc_fs.h" - -#include - -#include -#include - -#include -#include - -/* The following are for MSM5100 on Gator -*/ -#ifdef FEATURE_PM1000 -#include "pm1000.h" -#endif /* FEATURE_PM1000 */ -/* The following are for MSM6050 on Bambi -*/ -#ifdef FEATURE_PMIC_LCDKBD_LED_DRIVER -#include "pm.h" -#endif /* FEATURE_PMIC_LCDKBD_LED_DRIVER */ - -#ifdef DISP_DEVICE_18BPP -#undef DISP_DEVICE_18BPP -#define DISP_DEVICE_16BPP -#endif - -#define QCIF_WIDTH 176 -#define QCIF_HEIGHT 220 - -static void *DISP_CMD_PORT; -static void *DISP_DATA_PORT; - -#define DISP_CMD_DISON 0xaf -#define DISP_CMD_DISOFF 0xae -#define DISP_CMD_DISNOR 0xa6 -#define DISP_CMD_DISINV 0xa7 -#define DISP_CMD_DISCTL 0xca -#define DISP_CMD_GCP64 0xcb -#define DISP_CMD_GCP16 0xcc -#define DISP_CMD_GSSET 0xcd -#define DISP_GS_2 0x02 -#define DISP_GS_16 0x01 -#define DISP_GS_64 0x00 -#define DISP_CMD_SLPIN 0x95 -#define DISP_CMD_SLPOUT 0x94 -#define DISP_CMD_SD_PSET 0x75 -#define DISP_CMD_MD_PSET 0x76 -#define DISP_CMD_SD_CSET 0x15 -#define DISP_CMD_MD_CSET 0x16 -#define DISP_CMD_DATCTL 0xbc -#define DISP_DATCTL_666 0x08 -#define DISP_DATCTL_565 0x28 -#define DISP_DATCTL_444 0x38 -#define DISP_CMD_RAMWR 0x5c -#define DISP_CMD_RAMRD 0x5d -#define DISP_CMD_PTLIN 0xa8 -#define DISP_CMD_PTLOUT 0xa9 -#define DISP_CMD_ASCSET 0xaa -#define DISP_CMD_SCSTART 0xab -#define DISP_CMD_VOLCTL 0xc6 -#define DISP_VOLCTL_TONE 0x80 -#define DISP_CMD_NOp 0x25 -#define DISP_CMD_OSSEL 0xd0 -#define DISP_CMD_3500KSET 0xd1 -#define DISP_CMD_3500KEND 0xd2 -#define DISP_CMD_14MSET 0xd3 -#define DISP_CMD_14MEND 0xd4 - -#define DISP_CMD_OUT(cmd) outpw(DISP_CMD_PORT, cmd); - -#define DISP_DATA_OUT(data) outpw(DISP_DATA_PORT, data); - -#define DISP_DATA_IN() inpw(DISP_DATA_PORT); - -/* Epson device column number starts at 2 -*/ -#define DISP_SET_RECT(ulhc_row, lrhc_row, ulhc_col, lrhc_col) \ - DISP_CMD_OUT(DISP_CMD_SD_PSET) \ - DISP_DATA_OUT((ulhc_row) & 0xFF) \ - DISP_DATA_OUT((ulhc_row) >> 8) \ - DISP_DATA_OUT((lrhc_row) & 0xFF) \ - DISP_DATA_OUT((lrhc_row) >> 8) \ - DISP_CMD_OUT(DISP_CMD_SD_CSET) \ - DISP_DATA_OUT(((ulhc_col)+2) & 0xFF) \ - DISP_DATA_OUT(((ulhc_col)+2) >> 8) \ - DISP_DATA_OUT(((lrhc_col)+2) & 0xFF) \ - DISP_DATA_OUT(((lrhc_col)+2) >> 8) - -#define DISP_MIN_CONTRAST 0 -#define DISP_MAX_CONTRAST 127 -#define DISP_DEFAULT_CONTRAST 80 - -#define DISP_MIN_BACKLIGHT 0 -#define DISP_MAX_BACKLIGHT 15 -#define DISP_DEFAULT_BACKLIGHT 2 - -#define WAIT_SEC(sec) mdelay((sec)/1000) - -static word disp_area_start_row; -static word disp_area_end_row; -static byte disp_contrast = DISP_DEFAULT_CONTRAST; -static boolean disp_powered_up; -static boolean disp_initialized = FALSE; -/* For some reason the contrast set at init time is not good. Need to do - * it again - */ -static boolean display_on = FALSE; -static void epsonQcif_disp_init(struct platform_device *pdev); -static void epsonQcif_disp_set_contrast(word contrast); -static void epsonQcif_disp_set_display_area(word start_row, word end_row); -static int epsonQcif_disp_off(struct platform_device *pdev); -static int epsonQcif_disp_on(struct platform_device *pdev); -static void epsonQcif_disp_set_rect(int x, int y, int xres, int yres); - -volatile word databack; -static void epsonQcif_disp_init(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - - int i; - - if (disp_initialized) - return; - - mfd = platform_get_drvdata(pdev); - - DISP_CMD_PORT = mfd->cmd_port; - DISP_DATA_PORT = mfd->data_port; - - /* Sleep in */ - DISP_CMD_OUT(DISP_CMD_SLPIN); - - /* Display off */ - DISP_CMD_OUT(DISP_CMD_DISOFF); - - /* Display normal */ - DISP_CMD_OUT(DISP_CMD_DISNOR); - - /* Set data mode */ - DISP_CMD_OUT(DISP_CMD_DATCTL); - DISP_DATA_OUT(DISP_DATCTL_565); - - /* Set display timing */ - DISP_CMD_OUT(DISP_CMD_DISCTL); - DISP_DATA_OUT(0x1c); /* p1 */ - DISP_DATA_OUT(0x02); /* p1 */ - DISP_DATA_OUT(0x82); /* p2 */ - DISP_DATA_OUT(0x00); /* p3 */ - DISP_DATA_OUT(0x00); /* p4 */ - DISP_DATA_OUT(0xe0); /* p5 */ - DISP_DATA_OUT(0x00); /* p5 */ - DISP_DATA_OUT(0xdc); /* p6 */ - DISP_DATA_OUT(0x00); /* p6 */ - DISP_DATA_OUT(0x02); /* p7 */ - DISP_DATA_OUT(0x00); /* p8 */ - - /* Set 64 gray scale level */ - DISP_CMD_OUT(DISP_CMD_GCP64); - DISP_DATA_OUT(0x08); /* p01 */ - DISP_DATA_OUT(0x00); - DISP_DATA_OUT(0x2a); /* p02 */ - DISP_DATA_OUT(0x00); - DISP_DATA_OUT(0x4e); /* p03 */ - DISP_DATA_OUT(0x00); - DISP_DATA_OUT(0x6b); /* p04 */ - DISP_DATA_OUT(0x00); - DISP_DATA_OUT(0x88); /* p05 */ - DISP_DATA_OUT(0x00); - DISP_DATA_OUT(0xa3); /* p06 */ - DISP_DATA_OUT(0x00); - DISP_DATA_OUT(0xba); /* p07 */ - DISP_DATA_OUT(0x00); - DISP_DATA_OUT(0xd1); /* p08 */ - DISP_DATA_OUT(0x00); - DISP_DATA_OUT(0xe5); /* p09 */ - DISP_DATA_OUT(0x00); - DISP_DATA_OUT(0xf3); /* p10 */ - DISP_DATA_OUT(0x00); - DISP_DATA_OUT(0x03); /* p11 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x13); /* p12 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x22); /* p13 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x2f); /* p14 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x3b); /* p15 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x46); /* p16 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x51); /* p17 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x5b); /* p18 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x64); /* p19 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x6c); /* p20 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x74); /* p21 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x7c); /* p22 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x83); /* p23 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x8a); /* p24 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x91); /* p25 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x98); /* p26 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x9f); /* p27 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xa6); /* p28 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xac); /* p29 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xb2); /* p30 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xb7); /* p31 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xbc); /* p32 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xc1); /* p33 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xc6); /* p34 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xcb); /* p35 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xd0); /* p36 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xd4); /* p37 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xd8); /* p38 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xdc); /* p39 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xe0); /* p40 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xe4); /* p41 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xe8); /* p42 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xec); /* p43 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xf0); /* p44 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xf4); /* p45 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xf8); /* p46 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xfb); /* p47 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xfe); /* p48 */ - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0x01); /* p49 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x03); /* p50 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x05); /* p51 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x07); /* p52 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x09); /* p53 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x0b); /* p54 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x0d); /* p55 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x0f); /* p56 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x11); /* p57 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x13); /* p58 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x15); /* p59 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x17); /* p60 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x19); /* p61 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x1b); /* p62 */ - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x1c); /* p63 */ - DISP_DATA_OUT(0x02); - - /* Set 16 gray scale level */ - DISP_CMD_OUT(DISP_CMD_GCP16); - DISP_DATA_OUT(0x1a); /* p01 */ - DISP_DATA_OUT(0x32); /* p02 */ - DISP_DATA_OUT(0x42); /* p03 */ - DISP_DATA_OUT(0x4c); /* p04 */ - DISP_DATA_OUT(0x58); /* p05 */ - DISP_DATA_OUT(0x5f); /* p06 */ - DISP_DATA_OUT(0x66); /* p07 */ - DISP_DATA_OUT(0x6b); /* p08 */ - DISP_DATA_OUT(0x70); /* p09 */ - DISP_DATA_OUT(0x74); /* p10 */ - DISP_DATA_OUT(0x78); /* p11 */ - DISP_DATA_OUT(0x7b); /* p12 */ - DISP_DATA_OUT(0x7e); /* p13 */ - DISP_DATA_OUT(0x80); /* p14 */ - DISP_DATA_OUT(0x82); /* p15 */ - - /* Set DSP column */ - DISP_CMD_OUT(DISP_CMD_MD_CSET); - DISP_DATA_OUT(0xff); - DISP_DATA_OUT(0x03); - DISP_DATA_OUT(0xff); - DISP_DATA_OUT(0x03); - - /* Set DSP page */ - DISP_CMD_OUT(DISP_CMD_MD_PSET); - DISP_DATA_OUT(0xff); - DISP_DATA_OUT(0x01); - DISP_DATA_OUT(0xff); - DISP_DATA_OUT(0x01); - - /* Set ARM column */ - DISP_CMD_OUT(DISP_CMD_SD_CSET); - DISP_DATA_OUT(0x02); - DISP_DATA_OUT(0x00); - DISP_DATA_OUT((QCIF_WIDTH + 1) & 0xFF); - DISP_DATA_OUT((QCIF_WIDTH + 1) >> 8); - - /* Set ARM page */ - DISP_CMD_OUT(DISP_CMD_SD_PSET); - DISP_DATA_OUT(0x00); - DISP_DATA_OUT(0x00); - DISP_DATA_OUT((QCIF_HEIGHT - 1) & 0xFF); - DISP_DATA_OUT((QCIF_HEIGHT - 1) >> 8); - - /* Set 64 gray scales */ - DISP_CMD_OUT(DISP_CMD_GSSET); - DISP_DATA_OUT(DISP_GS_64); - - DISP_CMD_OUT(DISP_CMD_OSSEL); - DISP_DATA_OUT(0); - - /* Sleep out */ - DISP_CMD_OUT(DISP_CMD_SLPOUT); - - WAIT_SEC(40000); - - /* Initialize power IC */ - DISP_CMD_OUT(DISP_CMD_VOLCTL); - DISP_DATA_OUT(DISP_VOLCTL_TONE); - - WAIT_SEC(40000); - - /* Set electronic volume, d'xx */ - DISP_CMD_OUT(DISP_CMD_VOLCTL); - DISP_DATA_OUT(DISP_DEFAULT_CONTRAST); /* value from 0 to 127 */ - - /* Initialize display data */ - DISP_SET_RECT(0, (QCIF_HEIGHT - 1), 0, (QCIF_WIDTH - 1)); - DISP_CMD_OUT(DISP_CMD_RAMWR); - for (i = 0; i < QCIF_HEIGHT * QCIF_WIDTH; i++) - DISP_DATA_OUT(0xffff); - - DISP_CMD_OUT(DISP_CMD_RAMRD); - databack = DISP_DATA_IN(); - databack = DISP_DATA_IN(); - databack = DISP_DATA_IN(); - databack = DISP_DATA_IN(); - - WAIT_SEC(80000); - - DISP_CMD_OUT(DISP_CMD_DISON); - - disp_area_start_row = 0; - disp_area_end_row = QCIF_HEIGHT - 1; - disp_powered_up = TRUE; - disp_initialized = TRUE; - epsonQcif_disp_set_display_area(0, QCIF_HEIGHT - 1); - display_on = TRUE; -} - -static void epsonQcif_disp_set_rect(int x, int y, int xres, int yres) -{ - if (!disp_initialized) - return; - - DISP_SET_RECT(y, y + yres - 1, x, x + xres - 1); - DISP_CMD_OUT(DISP_CMD_RAMWR); -} - -static void epsonQcif_disp_set_display_area(word start_row, word end_row) -{ - if (!disp_initialized) - return; - - if ((start_row == disp_area_start_row) - && (end_row == disp_area_end_row)) - return; - disp_area_start_row = start_row; - disp_area_end_row = end_row; - - /* Range checking - */ - if (end_row >= QCIF_HEIGHT) - end_row = QCIF_HEIGHT - 1; - if (start_row > end_row) - start_row = end_row; - - /* When display is not the full screen, gray scale is set to - ** 2; otherwise it is set to 64. - */ - if ((start_row == 0) && (end_row == (QCIF_HEIGHT - 1))) { - /* The whole screen */ - DISP_CMD_OUT(DISP_CMD_PTLOUT); - WAIT_SEC(10000); - DISP_CMD_OUT(DISP_CMD_DISOFF); - WAIT_SEC(100000); - DISP_CMD_OUT(DISP_CMD_GSSET); - DISP_DATA_OUT(DISP_GS_64); - WAIT_SEC(100000); - DISP_CMD_OUT(DISP_CMD_DISON); - } else { - /* partial screen */ - DISP_CMD_OUT(DISP_CMD_PTLIN); - DISP_DATA_OUT(start_row); - DISP_DATA_OUT(start_row >> 8); - DISP_DATA_OUT(end_row); - DISP_DATA_OUT(end_row >> 8); - DISP_CMD_OUT(DISP_CMD_GSSET); - DISP_DATA_OUT(DISP_GS_2); - } -} - -static int epsonQcif_disp_off(struct platform_device *pdev) -{ - if (!disp_initialized) - epsonQcif_disp_init(pdev); - - if (display_on) { - DISP_CMD_OUT(DISP_CMD_DISOFF); - DISP_CMD_OUT(DISP_CMD_SLPIN); - display_on = FALSE; - } - - return 0; -} - -static int epsonQcif_disp_on(struct platform_device *pdev) -{ - if (!disp_initialized) - epsonQcif_disp_init(pdev); - - if (!display_on) { - DISP_CMD_OUT(DISP_CMD_SLPOUT); - WAIT_SEC(40000); - DISP_CMD_OUT(DISP_CMD_DISON); - epsonQcif_disp_set_contrast(disp_contrast); - display_on = TRUE; - } - - return 0; -} - -static void epsonQcif_disp_set_contrast(word contrast) -{ - if (!disp_initialized) - return; - - /* Initialize power IC, d'24 */ - DISP_CMD_OUT(DISP_CMD_VOLCTL); - DISP_DATA_OUT(DISP_VOLCTL_TONE); - - WAIT_SEC(40000); - - /* Set electronic volume, d'xx */ - DISP_CMD_OUT(DISP_CMD_VOLCTL); - if (contrast > 127) - contrast = 127; - DISP_DATA_OUT(contrast); /* value from 0 to 127 */ - disp_contrast = (byte) contrast; -} /* End disp_set_contrast */ - -static void epsonQcif_disp_clear_screen_area( - word start_row, word end_row, word start_column, word end_column) { - int32 i; - - /* Clear the display screen */ - DISP_SET_RECT(start_row, end_row, start_column, end_column); - DISP_CMD_OUT(DISP_CMD_RAMWR); - i = (end_row - start_row + 1) * (end_column - start_column + 1); - for (; i > 0; i--) - DISP_DATA_OUT(0xffff); -} - -static int __init epsonQcif_probe(struct platform_device *pdev) -{ - msm_fb_add_device(pdev); - - return 0; -} - -static struct platform_driver this_driver = { - .probe = epsonQcif_probe, - .driver = { - .name = "ebi2_epson_qcif", - }, -}; - -static struct msm_fb_panel_data epsonQcif_panel_data = { - .on = epsonQcif_disp_on, - .off = epsonQcif_disp_off, - .set_rect = epsonQcif_disp_set_rect, -}; - -static struct platform_device this_device = { - .name = "ebi2_epson_qcif", - .id = 0, - .dev = { - .platform_data = &epsonQcif_panel_data, - } -}; - -static int __init epsonQcif_init(void) -{ - int ret; - struct msm_panel_info *pinfo; - - ret = platform_driver_register(&this_driver); - if (!ret) { - pinfo = &epsonQcif_panel_data.panel_info; - pinfo->xres = QCIF_WIDTH; - pinfo->yres = QCIF_HEIGHT; - pinfo->type = EBI2_PANEL; - pinfo->pdest = DISPLAY_2; - pinfo->wait_cycle = 0x808000; - pinfo->bpp = 16; - pinfo->fb_num = 2; - pinfo->lcd.vsync_enable = FALSE; - - ret = platform_device_register(&this_device); - if (ret) - platform_driver_unregister(&this_driver); - } - - return ret; -} - -module_init(epsonQcif_init); diff --git a/drivers/staging/msm/ebi2_lcd.c b/drivers/staging/msm/ebi2_lcd.c deleted file mode 100644 index b41e1230ceca..000000000000 --- a/drivers/staging/msm/ebi2_lcd.c +++ /dev/null @@ -1,250 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msm_fb.h" - -static int ebi2_lcd_probe(struct platform_device *pdev); -static int ebi2_lcd_remove(struct platform_device *pdev); - -static struct platform_driver ebi2_lcd_driver = { - .probe = ebi2_lcd_probe, - .remove = ebi2_lcd_remove, - .suspend = NULL, - .suspend_late = NULL, - .resume_early = NULL, - .resume = NULL, - .shutdown = NULL, - .driver = { - .name = "ebi2_lcd", - }, -}; - -static void *ebi2_base; -static void *ebi2_lcd_cfg0; -static void *ebi2_lcd_cfg1; -static void __iomem *lcd01_base; -static void __iomem *lcd02_base; -static int ebi2_lcd_resource_initialized; - -static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST]; -static int pdev_list_cnt; - -static int ebi2_lcd_probe(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - struct platform_device *mdp_dev = NULL; - struct msm_fb_panel_data *pdata = NULL; - int rc, i; - - if (pdev->id == 0) { - for (i = 0; i < pdev->num_resources; i++) { - if (!strncmp(pdev->resource[i].name, "base", 4)) { - ebi2_base = ioremap(pdev->resource[i].start, - pdev->resource[i].end - - pdev->resource[i].start + 1); - if (!ebi2_base) { - printk(KERN_ERR - "ebi2_base ioremap failed!\n"); - return -ENOMEM; - } - ebi2_lcd_cfg0 = (void *)(ebi2_base + 0x20); - ebi2_lcd_cfg1 = (void *)(ebi2_base + 0x24); - } else if (!strncmp(pdev->resource[i].name, - "lcd01", 5)) { - lcd01_base = ioremap(pdev->resource[i].start, - pdev->resource[i].end - - pdev->resource[i].start + 1); - if (!lcd01_base) { - printk(KERN_ERR - "lcd01_base ioremap failed!\n"); - return -ENOMEM; - } - } else if (!strncmp(pdev->resource[i].name, - "lcd02", 5)) { - lcd02_base = ioremap(pdev->resource[i].start, - pdev->resource[i].end - - pdev->resource[i].start + 1); - if (!lcd02_base) { - printk(KERN_ERR - "lcd02_base ioremap failed!\n"); - return -ENOMEM; - } - } - } - ebi2_lcd_resource_initialized = 1; - return 0; - } - - if (!ebi2_lcd_resource_initialized) - return -EPERM; - - mfd = platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST) - return -ENOMEM; - - if (ebi2_base == NULL) - return -ENOMEM; - - mdp_dev = platform_device_alloc("mdp", pdev->id); - if (!mdp_dev) - return -ENOMEM; - - /* link to the latest pdev */ - mfd->pdev = mdp_dev; - mfd->dest = DISPLAY_LCD; - - /* add panel data */ - if (platform_device_add_data - (mdp_dev, pdev->dev.platform_data, - sizeof(struct msm_fb_panel_data))) { - printk(KERN_ERR "ebi2_lcd_probe: platform_device_add_data failed!\n"); - platform_device_put(mdp_dev); - return -ENOMEM; - } - - /* data chain */ - pdata = mdp_dev->dev.platform_data; - pdata->on = panel_next_on; - pdata->off = panel_next_off; - pdata->next = pdev; - - /* get/set panel specific fb info */ - mfd->panel_info = pdata->panel_info; - - if (mfd->panel_info.bpp == 24) - mfd->fb_imgType = MDP_RGB_888; - else - mfd->fb_imgType = MDP_RGB_565; - - /* config msm ebi2 lcd register */ - if (mfd->panel_info.pdest == DISPLAY_1) { - outp32(ebi2_base, - (inp32(ebi2_base) & (~(EBI2_PRIM_LCD_CLR))) | - EBI2_PRIM_LCD_SEL); - /* - * current design has one set of cfg0/1 register to control - * both EBI2 channels. so, we're using the PRIM channel to - * configure both. - */ - outp32(ebi2_lcd_cfg0, mfd->panel_info.wait_cycle); - if (mfd->panel_info.bpp == 18) - outp32(ebi2_lcd_cfg1, 0x01000000); - else - outp32(ebi2_lcd_cfg1, 0x0); - } else { -#ifdef DEBUG_EBI2_LCD - /* - * confliting with QCOM SURF FPGA CS. - * OEM should enable below for their CS mapping - */ - outp32(ebi2_base, (inp32(ebi2_base)&(~(EBI2_SECD_LCD_CLR))) - |EBI2_SECD_LCD_SEL); -#endif - } - - /* - * map cs (chip select) address - */ - if (mfd->panel_info.pdest == DISPLAY_1) { - mfd->cmd_port = lcd01_base; - mfd->data_port = - (void *)((uint32) mfd->cmd_port + EBI2_PRIM_LCD_RS_PIN); - mfd->data_port_phys = - (void *)(LCD_PRIM_BASE_PHYS + EBI2_PRIM_LCD_RS_PIN); - } else { - mfd->cmd_port = lcd01_base; - mfd->data_port = - (void *)((uint32) mfd->cmd_port + EBI2_SECD_LCD_RS_PIN); - mfd->data_port_phys = - (void *)(LCD_SECD_BASE_PHYS + EBI2_SECD_LCD_RS_PIN); - } - - /* - * set driver data - */ - platform_set_drvdata(mdp_dev, mfd); - - /* - * register in mdp driver - */ - rc = platform_device_add(mdp_dev); - if (rc) { - goto ebi2_lcd_probe_err; - } - - pdev_list[pdev_list_cnt++] = pdev; - return 0; - - ebi2_lcd_probe_err: - platform_device_put(mdp_dev); - return rc; -} - -static int ebi2_lcd_remove(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - - mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); - - if (!mfd) - return 0; - - if (mfd->key != MFD_KEY) - return 0; - - iounmap(mfd->cmd_port); - - return 0; -} - -static int ebi2_lcd_register_driver(void) -{ - return platform_driver_register(&ebi2_lcd_driver); -} - -static int __init ebi2_lcd_driver_init(void) -{ - return ebi2_lcd_register_driver(); -} - -module_init(ebi2_lcd_driver_init); \ No newline at end of file diff --git a/drivers/staging/msm/ebi2_tmd20.c b/drivers/staging/msm/ebi2_tmd20.c deleted file mode 100644 index d66d03978253..000000000000 --- a/drivers/staging/msm/ebi2_tmd20.c +++ /dev/null @@ -1,1122 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "msm_fb.h" - -#include -#include -#include -#include -#include -#include -#include "linux/proc_fs.h" - -#include - -#include -#include - -#include -#include - -/* #define TMD20QVGA_LCD_18BPP */ -#define QVGA_WIDTH 240 -#define QVGA_HEIGHT 320 - -#ifdef TMD20QVGA_LCD_18BPP -#define DISP_QVGA_18BPP(x) ((((x)<<2) & 0x3FC00)|(( (x)<<1)& 0x1FE)) -#define DISP_REG(name) uint32 register_##name; -#define OUTPORT(x, y) outpdw(x, y) -#define INPORT(x) inpdw(x) -#else -#define DISP_QVGA_18BPP(x) (x) -#define DISP_REG(name) uint16 register_##name; -#define OUTPORT(x, y) outpw(x, y) -#define INPORT(x) intpw(x) -#endif - -static void *DISP_CMD_PORT; -static void *DISP_DATA_PORT; - -#define DISP_RNTI 0x10 - -#define DISP_CMD_OUT(cmd) OUTPORT(DISP_CMD_PORT, DISP_QVGA_18BPP(cmd)) -#define DISP_DATA_OUT(data) OUTPORT(DISP_DATA_PORT, data) -#define DISP_DATA_IN() INPORT(DISP_DATA_PORT) - -#if (defined(TMD20QVGA_LCD_18BPP)) -#define DISP_DATA_OUT_16TO18BPP(x) \ - DISP_DATA_OUT((((x)&0xf800)<<2|((x)&0x80000)>>3) \ - | (((x)&0x7e0)<<1) \ - | (((x)&0x1F)<<1|((x)&0x10)>>4)) -#else -#define DISP_DATA_OUT_16TO18BPP(x) \ - DISP_DATA_OUT(x) -#endif - -#define DISP_WRITE_OUT(addr, data) \ - register_##addr = DISP_QVGA_18BPP(data); \ - DISP_CMD_OUT(addr); \ - DISP_DATA_OUT(register_##addr); - -#define DISP_UPDATE_VALUE(addr, bitmask, data) \ - DISP_WRITE_OUT(##addr, (register_##addr & ~(bitmask)) | (data)); - -#define DISP_VAL_IF(bitvalue, bitmask) \ - ((bitvalue) ? (bitmask) : 0) - -/* QVGA = 256 x 320 */ -/* actual display is 240 x 320...offset by 0x10 */ -#define DISP_ROW_COL_TO_ADDR(row, col) ((row) * 0x100 + col) -#define DISP_SET_RECT(ulhc_row, lrhc_row, ulhc_col, lrhc_col) \ - { \ - DISP_WRITE_OUT(DISP_HORZ_RAM_ADDR_POS_1_ADDR, (ulhc_col) + tmd20qvga_panel_offset); \ - DISP_WRITE_OUT(DISP_HORZ_RAM_ADDR_POS_2_ADDR, (lrhc_col) + tmd20qvga_panel_offset); \ - DISP_WRITE_OUT(DISP_VERT_RAM_ADDR_POS_1_ADDR, (ulhc_row)); \ - DISP_WRITE_OUT(DISP_VERT_RAM_ADDR_POS_2_ADDR, (lrhc_row)); \ - DISP_WRITE_OUT(DISP_RAM_ADDR_SET_1_ADDR, (ulhc_col) + tmd20qvga_panel_offset); \ - DISP_WRITE_OUT(DISP_RAM_ADDR_SET_2_ADDR, (ulhc_row)); \ - } - -#define WAIT_MSEC(msec) mdelay(msec) - -/* - * TMD QVGA Address - */ -/* Display Control */ -#define DISP_START_OSCILLATION_ADDR 0x000 -DISP_REG(DISP_START_OSCILLATION_ADDR) -#define DISP_DRIVER_OUTPUT_CTL_ADDR 0x001 - DISP_REG(DISP_DRIVER_OUTPUT_CTL_ADDR) -#define DISP_LCD_DRIVING_SIG_ADDR 0x002 - DISP_REG(DISP_LCD_DRIVING_SIG_ADDR) -#define DISP_ENTRY_MODE_ADDR 0x003 - DISP_REG(DISP_ENTRY_MODE_ADDR) -#define DISP_DISPLAY_CTL_1_ADDR 0x007 - DISP_REG(DISP_DISPLAY_CTL_1_ADDR) -#define DISP_DISPLAY_CTL_2_ADDR 0x008 - DISP_REG(DISP_DISPLAY_CTL_2_ADDR) - -/* DISPLAY MODE 0x009 partial display not supported */ -#define DISP_POWER_SUPPLY_INTF_ADDR 0x00A - DISP_REG(DISP_POWER_SUPPLY_INTF_ADDR) - -/* DISPLAY MODE 0x00B xZoom feature is not supported */ -#define DISP_EXT_DISPLAY_CTL_1_ADDR 0x00C - DISP_REG(DISP_EXT_DISPLAY_CTL_1_ADDR) - -#define DISP_FRAME_CYCLE_CTL_ADDR 0x00D - DISP_REG(DISP_FRAME_CYCLE_CTL_ADDR) - -#define DISP_EXT_DISPLAY_CTL_2_ADDR 0x00E - DISP_REG(DISP_EXT_DISPLAY_CTL_2_ADDR) - -#define DISP_EXT_DISPLAY_CTL_3_ADDR 0x00F - DISP_REG(DISP_EXT_DISPLAY_CTL_3_ADDR) - -#define DISP_LTPS_CTL_1_ADDR 0x012 - DISP_REG(DISP_LTPS_CTL_1_ADDR) -#define DISP_LTPS_CTL_2_ADDR 0x013 - DISP_REG(DISP_LTPS_CTL_2_ADDR) -#define DISP_LTPS_CTL_3_ADDR 0x014 - DISP_REG(DISP_LTPS_CTL_3_ADDR) -#define DISP_LTPS_CTL_4_ADDR 0x018 - DISP_REG(DISP_LTPS_CTL_4_ADDR) -#define DISP_LTPS_CTL_5_ADDR 0x019 - DISP_REG(DISP_LTPS_CTL_5_ADDR) -#define DISP_LTPS_CTL_6_ADDR 0x01A - DISP_REG(DISP_LTPS_CTL_6_ADDR) -#define DISP_AMP_SETTING_ADDR 0x01C - DISP_REG(DISP_AMP_SETTING_ADDR) -#define DISP_MODE_SETTING_ADDR 0x01D - DISP_REG(DISP_MODE_SETTING_ADDR) -#define DISP_POFF_LN_SETTING_ADDR 0x01E - DISP_REG(DISP_POFF_LN_SETTING_ADDR) -/* Power Contol */ -#define DISP_POWER_CTL_1_ADDR 0x100 - DISP_REG(DISP_POWER_CTL_1_ADDR) -#define DISP_POWER_CTL_2_ADDR 0x101 - DISP_REG(DISP_POWER_CTL_2_ADDR) -#define DISP_POWER_CTL_3_ADDR 0x102 - DISP_REG(DISP_POWER_CTL_3_ADDR) -#define DISP_POWER_CTL_4_ADDR 0x103 - DISP_REG(DISP_POWER_CTL_4_ADDR) -#define DISP_POWER_CTL_5_ADDR 0x104 - DISP_REG(DISP_POWER_CTL_5_ADDR) -#define DISP_POWER_CTL_6_ADDR 0x105 - DISP_REG(DISP_POWER_CTL_6_ADDR) -#define DISP_POWER_CTL_7_ADDR 0x106 - DISP_REG(DISP_POWER_CTL_7_ADDR) -/* RAM Access */ -#define DISP_RAM_ADDR_SET_1_ADDR 0x200 - DISP_REG(DISP_RAM_ADDR_SET_1_ADDR) -#define DISP_RAM_ADDR_SET_2_ADDR 0x201 - DISP_REG(DISP_RAM_ADDR_SET_2_ADDR) -#define DISP_CMD_RAMRD DISP_CMD_RAMWR -#define DISP_CMD_RAMWR 0x202 - DISP_REG(DISP_CMD_RAMWR) -#define DISP_RAM_DATA_MASK_1_ADDR 0x203 - DISP_REG(DISP_RAM_DATA_MASK_1_ADDR) -#define DISP_RAM_DATA_MASK_2_ADDR 0x204 - DISP_REG(DISP_RAM_DATA_MASK_2_ADDR) -/* Gamma Control, Contrast, Gray Scale Setting */ -#define DISP_GAMMA_CONTROL_1_ADDR 0x300 - DISP_REG(DISP_GAMMA_CONTROL_1_ADDR) -#define DISP_GAMMA_CONTROL_2_ADDR 0x301 - DISP_REG(DISP_GAMMA_CONTROL_2_ADDR) -#define DISP_GAMMA_CONTROL_3_ADDR 0x302 - DISP_REG(DISP_GAMMA_CONTROL_3_ADDR) -#define DISP_GAMMA_CONTROL_4_ADDR 0x303 - DISP_REG(DISP_GAMMA_CONTROL_4_ADDR) -#define DISP_GAMMA_CONTROL_5_ADDR 0x304 - DISP_REG(DISP_GAMMA_CONTROL_5_ADDR) -/* Coordinate Control */ -#define DISP_VERT_SCROLL_CTL_1_ADDR 0x400 - DISP_REG(DISP_VERT_SCROLL_CTL_1_ADDR) -#define DISP_VERT_SCROLL_CTL_2_ADDR 0x401 - DISP_REG(DISP_VERT_SCROLL_CTL_2_ADDR) -#define DISP_SCREEN_1_DRV_POS_1_ADDR 0x402 - DISP_REG(DISP_SCREEN_1_DRV_POS_1_ADDR) -#define DISP_SCREEN_1_DRV_POS_2_ADDR 0x403 - DISP_REG(DISP_SCREEN_1_DRV_POS_2_ADDR) -#define DISP_SCREEN_2_DRV_POS_1_ADDR 0x404 - DISP_REG(DISP_SCREEN_2_DRV_POS_1_ADDR) -#define DISP_SCREEN_2_DRV_POS_2_ADDR 0x405 - DISP_REG(DISP_SCREEN_2_DRV_POS_2_ADDR) -#define DISP_HORZ_RAM_ADDR_POS_1_ADDR 0x406 - DISP_REG(DISP_HORZ_RAM_ADDR_POS_1_ADDR) -#define DISP_HORZ_RAM_ADDR_POS_2_ADDR 0x407 - DISP_REG(DISP_HORZ_RAM_ADDR_POS_2_ADDR) -#define DISP_VERT_RAM_ADDR_POS_1_ADDR 0x408 - DISP_REG(DISP_VERT_RAM_ADDR_POS_1_ADDR) -#define DISP_VERT_RAM_ADDR_POS_2_ADDR 0x409 - DISP_REG(DISP_VERT_RAM_ADDR_POS_2_ADDR) -#define DISP_TMD_700_ADDR 0x700 /* 0x700 */ - DISP_REG(DISP_TMD_700_ADDR) -#define DISP_TMD_015_ADDR 0x015 /* 0x700 */ - DISP_REG(DISP_TMD_015_ADDR) -#define DISP_TMD_305_ADDR 0x305 /* 0x700 */ - DISP_REG(DISP_TMD_305_ADDR) - -/* - * TMD QVGA Bit Definations - */ - -#define DISP_BIT_IB15 0x8000 -#define DISP_BIT_IB14 0x4000 -#define DISP_BIT_IB13 0x2000 -#define DISP_BIT_IB12 0x1000 -#define DISP_BIT_IB11 0x0800 -#define DISP_BIT_IB10 0x0400 -#define DISP_BIT_IB09 0x0200 -#define DISP_BIT_IB08 0x0100 -#define DISP_BIT_IB07 0x0080 -#define DISP_BIT_IB06 0x0040 -#define DISP_BIT_IB05 0x0020 -#define DISP_BIT_IB04 0x0010 -#define DISP_BIT_IB03 0x0008 -#define DISP_BIT_IB02 0x0004 -#define DISP_BIT_IB01 0x0002 -#define DISP_BIT_IB00 0x0001 -/* - * Display Control - * DISP_START_OSCILLATION_ADDR Start Oscillation - * DISP_DRIVER_OUTPUT_CTL_ADDR Driver Output Control - */ -#define DISP_BITMASK_SS DISP_BIT_IB08 -#define DISP_BITMASK_NL5 DISP_BIT_IB05 -#define DISP_BITMASK_NL4 DISP_BIT_IB04 -#define DISP_BITMASK_NL3 DISP_BIT_IB03 -#define DISP_BITMASK_NL2 DISP_BIT_IB02 -#define DISP_BITMASK_NL1 DISP_BIT_IB01 -#define DISP_BITMASK_NL0 DISP_BIT_IB00 -/* DISP_LCD_DRIVING_SIG_ADDR LCD Driving Signal Setting */ -#define DISP_BITMASK_BC DISP_BIT_IB09 -/* DISP_ENTRY_MODE_ADDR Entry Mode */ -#define DISP_BITMASK_TRI DISP_BIT_IB15 -#define DISP_BITMASK_DFM1 DISP_BIT_IB14 -#define DISP_BITMASK_DFM0 DISP_BIT_IB13 -#define DISP_BITMASK_BGR DISP_BIT_IB12 -#define DISP_BITMASK_HWM0 DISP_BIT_IB08 -#define DISP_BITMASK_ID1 DISP_BIT_IB05 -#define DISP_BITMASK_ID0 DISP_BIT_IB04 -#define DISP_BITMASK_AM DISP_BIT_IB03 -/* DISP_DISPLAY_CTL_1_ADDR Display Control (1) */ -#define DISP_BITMASK_COL1 DISP_BIT_IB15 -#define DISP_BITMASK_COL0 DISP_BIT_IB14 -#define DISP_BITMASK_VLE2 DISP_BIT_IB10 -#define DISP_BITMASK_VLE1 DISP_BIT_IB09 -#define DISP_BITMASK_SPT DISP_BIT_IB08 -#define DISP_BITMASK_PT1 DISP_BIT_IB07 -#define DISP_BITMASK_PT0 DISP_BIT_IB06 -#define DISP_BITMASK_REV DISP_BIT_IB02 -/* DISP_DISPLAY_CTL_2_ADDR Display Control (2) */ -#define DISP_BITMASK_FP3 DISP_BIT_IB11 -#define DISP_BITMASK_FP2 DISP_BIT_IB10 -#define DISP_BITMASK_FP1 DISP_BIT_IB09 -#define DISP_BITMASK_FP0 DISP_BIT_IB08 -#define DISP_BITMASK_BP3 DISP_BIT_IB03 -#define DISP_BITMASK_BP2 DISP_BIT_IB02 -#define DISP_BITMASK_BP1 DISP_BIT_IB01 -#define DISP_BITMASK_BP0 DISP_BIT_IB00 -/* DISP_POWER_SUPPLY_INTF_ADDR Power Supply IC Interface Control */ -#define DISP_BITMASK_CSE DISP_BIT_IB12 -#define DISP_BITMASK_TE DISP_BIT_IB08 -#define DISP_BITMASK_IX3 DISP_BIT_IB03 -#define DISP_BITMASK_IX2 DISP_BIT_IB02 -#define DISP_BITMASK_IX1 DISP_BIT_IB01 -#define DISP_BITMASK_IX0 DISP_BIT_IB00 -/* DISP_EXT_DISPLAY_CTL_1_ADDR External Display Interface Control (1) */ -#define DISP_BITMASK_RM DISP_BIT_IB08 -#define DISP_BITMASK_DM1 DISP_BIT_IB05 -#define DISP_BITMASK_DM0 DISP_BIT_IB04 -#define DISP_BITMASK_RIM1 DISP_BIT_IB01 -#define DISP_BITMASK_RIM0 DISP_BIT_IB00 -/* DISP_FRAME_CYCLE_CTL_ADDR Frame Frequency Adjustment Control */ -#define DISP_BITMASK_DIVI1 DISP_BIT_IB09 -#define DISP_BITMASK_DIVI0 DISP_BIT_IB08 -#define DISP_BITMASK_RTNI4 DISP_BIT_IB04 -#define DISP_BITMASK_RTNI3 DISP_BIT_IB03 -#define DISP_BITMASK_RTNI2 DISP_BIT_IB02 -#define DISP_BITMASK_RTNI1 DISP_BIT_IB01 -#define DISP_BITMASK_RTNI0 DISP_BIT_IB00 -/* DISP_EXT_DISPLAY_CTL_2_ADDR External Display Interface Control (2) */ -#define DISP_BITMASK_DIVE1 DISP_BIT_IB09 -#define DISP_BITMASK_DIVE0 DISP_BIT_IB08 -#define DISP_BITMASK_RTNE7 DISP_BIT_IB07 -#define DISP_BITMASK_RTNE6 DISP_BIT_IB06 -#define DISP_BITMASK_RTNE5 DISP_BIT_IB05 -#define DISP_BITMASK_RTNE4 DISP_BIT_IB04 -#define DISP_BITMASK_RTNE3 DISP_BIT_IB03 -#define DISP_BITMASK_RTNE2 DISP_BIT_IB02 -#define DISP_BITMASK_RTNE1 DISP_BIT_IB01 -#define DISP_BITMASK_RTNE0 DISP_BIT_IB00 -/* DISP_EXT_DISPLAY_CTL_3_ADDR External Display Interface Control (3) */ -#define DISP_BITMASK_VSPL DISP_BIT_IB04 -#define DISP_BITMASK_HSPL DISP_BIT_IB03 -#define DISP_BITMASK_VPL DISP_BIT_IB02 -#define DISP_BITMASK_EPL DISP_BIT_IB01 -#define DISP_BITMASK_DPL DISP_BIT_IB00 -/* DISP_LTPS_CTL_1_ADDR LTPS Interface Control (1) */ -#define DISP_BITMASK_CLWI3 DISP_BIT_IB11 -#define DISP_BITMASK_CLWI2 DISP_BIT_IB10 -#define DISP_BITMASK_CLWI1 DISP_BIT_IB09 -#define DISP_BITMASK_CLWI0 DISP_BIT_IB08 -#define DISP_BITMASK_CLTI1 DISP_BIT_IB01 -#define DISP_BITMASK_CLTI0 DISP_BIT_IB00 -/* DISP_LTPS_CTL_2_ADDR LTPS Interface Control (2) */ -#define DISP_BITMASK_OEVBI1 DISP_BIT_IB09 -#define DISP_BITMASK_OEVBI0 DISP_BIT_IB08 -#define DISP_BITMASK_OEVFI1 DISP_BIT_IB01 -#define DISP_BITMASK_OEVFI0 DISP_BIT_IB00 -/* DISP_LTPS_CTL_3_ADDR LTPS Interface Control (3) */ -#define DISP_BITMASK_SHI1 DISP_BIT_IB01 -#define DISP_BITMASK_SHI0 DISP_BIT_IB00 -/* DISP_LTPS_CTL_4_ADDR LTPS Interface Control (4) */ -#define DISP_BITMASK_CLWE5 DISP_BIT_IB13 -#define DISP_BITMASK_CLWE4 DISP_BIT_IB12 -#define DISP_BITMASK_CLWE3 DISP_BIT_IB11 -#define DISP_BITMASK_CLWE2 DISP_BIT_IB10 -#define DISP_BITMASK_CLWE1 DISP_BIT_IB09 -#define DISP_BITMASK_CLWE0 DISP_BIT_IB08 -#define DISP_BITMASK_CLTE3 DISP_BIT_IB03 -#define DISP_BITMASK_CLTE2 DISP_BIT_IB02 -#define DISP_BITMASK_CLTE1 DISP_BIT_IB01 -#define DISP_BITMASK_CLTE0 DISP_BIT_IB00 -/* DISP_LTPS_CTL_5_ADDR LTPS Interface Control (5) */ -#define DISP_BITMASK_OEVBE3 DISP_BIT_IB11 -#define DISP_BITMASK_OEVBE2 DISP_BIT_IB10 -#define DISP_BITMASK_OEVBE1 DISP_BIT_IB09 -#define DISP_BITMASK_OEVBE0 DISP_BIT_IB08 -#define DISP_BITMASK_OEVFE3 DISP_BIT_IB03 -#define DISP_BITMASK_OEVFE2 DISP_BIT_IB02 -#define DISP_BITMASK_OEVFE1 DISP_BIT_IB01 -#define DISP_BITMASK_OEVFE0 DISP_BIT_IB00 -/* DISP_LTPS_CTL_6_ADDR LTPS Interface Control (6) */ -#define DISP_BITMASK_SHE3 DISP_BIT_IB03 -#define DISP_BITMASK_SHE2 DISP_BIT_IB02 -#define DISP_BITMASK_SHE1 DISP_BIT_IB01 -#define DISP_BITMASK_SHE0 DISP_BIT_IB00 -/* DISP_AMP_SETTING_ADDR Amplify Setting */ -#define DISP_BITMASK_ABSW1 DISP_BIT_IB01 -#define DISP_BITMASK_ABSW0 DISP_BIT_IB00 -/* DISP_MODE_SETTING_ADDR Mode Setting */ -#define DISP_BITMASK_DSTB DISP_BIT_IB02 -#define DISP_BITMASK_STB DISP_BIT_IB00 -/* DISP_POFF_LN_SETTING_ADDR Power Off Line Setting */ -#define DISP_BITMASK_POFH3 DISP_BIT_IB03 -#define DISP_BITMASK_POFH2 DISP_BIT_IB02 -#define DISP_BITMASK_POFH1 DISP_BIT_IB01 -#define DISP_BITMASK_POFH0 DISP_BIT_IB00 - -/* Power Contol */ -/* DISP_POWER_CTL_1_ADDR Power Control (1) */ -#define DISP_BITMASK_PO DISP_BIT_IB11 -#define DISP_BITMASK_VCD DISP_BIT_IB09 -#define DISP_BITMASK_VSC DISP_BIT_IB08 -#define DISP_BITMASK_CON DISP_BIT_IB07 -#define DISP_BITMASK_ASW1 DISP_BIT_IB06 -#define DISP_BITMASK_ASW0 DISP_BIT_IB05 -#define DISP_BITMASK_OEV DISP_BIT_IB04 -#define DISP_BITMASK_OEVE DISP_BIT_IB03 -#define DISP_BITMASK_FR DISP_BIT_IB02 -#define DISP_BITMASK_D1 DISP_BIT_IB01 -#define DISP_BITMASK_D0 DISP_BIT_IB00 -/* DISP_POWER_CTL_2_ADDR Power Control (2) */ -#define DISP_BITMASK_DC4 DISP_BIT_IB15 -#define DISP_BITMASK_DC3 DISP_BIT_IB14 -#define DISP_BITMASK_SAP2 DISP_BIT_IB13 -#define DISP_BITMASK_SAP1 DISP_BIT_IB12 -#define DISP_BITMASK_SAP0 DISP_BIT_IB11 -#define DISP_BITMASK_BT2 DISP_BIT_IB10 -#define DISP_BITMASK_BT1 DISP_BIT_IB09 -#define DISP_BITMASK_BT0 DISP_BIT_IB08 -#define DISP_BITMASK_DC2 DISP_BIT_IB07 -#define DISP_BITMASK_DC1 DISP_BIT_IB06 -#define DISP_BITMASK_DC0 DISP_BIT_IB05 -#define DISP_BITMASK_AP2 DISP_BIT_IB04 -#define DISP_BITMASK_AP1 DISP_BIT_IB03 -#define DISP_BITMASK_AP0 DISP_BIT_IB02 -/* DISP_POWER_CTL_3_ADDR Power Control (3) */ -#define DISP_BITMASK_VGL4 DISP_BIT_IB10 -#define DISP_BITMASK_VGL3 DISP_BIT_IB09 -#define DISP_BITMASK_VGL2 DISP_BIT_IB08 -#define DISP_BITMASK_VGL1 DISP_BIT_IB07 -#define DISP_BITMASK_VGL0 DISP_BIT_IB06 -#define DISP_BITMASK_VGH4 DISP_BIT_IB04 -#define DISP_BITMASK_VGH3 DISP_BIT_IB03 -#define DISP_BITMASK_VGH2 DISP_BIT_IB02 -#define DISP_BITMASK_VGH1 DISP_BIT_IB01 -#define DISP_BITMASK_VGH0 DISP_BIT_IB00 -/* DISP_POWER_CTL_4_ADDR Power Control (4) */ -#define DISP_BITMASK_VC2 DISP_BIT_IB02 -#define DISP_BITMASK_VC1 DISP_BIT_IB01 -#define DISP_BITMASK_VC0 DISP_BIT_IB00 -/* DISP_POWER_CTL_5_ADDR Power Control (5) */ -#define DISP_BITMASK_VRL3 DISP_BIT_IB11 -#define DISP_BITMASK_VRL2 DISP_BIT_IB10 -#define DISP_BITMASK_VRL1 DISP_BIT_IB09 -#define DISP_BITMASK_VRL0 DISP_BIT_IB08 -#define DISP_BITMASK_PON DISP_BIT_IB04 -#define DISP_BITMASK_VRH3 DISP_BIT_IB03 -#define DISP_BITMASK_VRH2 DISP_BIT_IB02 -#define DISP_BITMASK_VRH1 DISP_BIT_IB01 -#define DISP_BITMASK_VRH0 DISP_BIT_IB00 -/* DISP_POWER_CTL_6_ADDR Power Control (6) */ -#define DISP_BITMASK_VCOMG DISP_BIT_IB13 -#define DISP_BITMASK_VDV4 DISP_BIT_IB12 -#define DISP_BITMASK_VDV3 DISP_BIT_IB11 -#define DISP_BITMASK_VDV2 DISP_BIT_IB10 -#define DISP_BITMASK_VDV1 DISP_BIT_IB09 -#define DISP_BITMASK_VDV0 DISP_BIT_IB08 -#define DISP_BITMASK_VCM4 DISP_BIT_IB04 -#define DISP_BITMASK_VCM3 DISP_BIT_IB03 -#define DISP_BITMASK_VCM2 DISP_BIT_IB02 -#define DISP_BITMASK_VCM1 DISP_BIT_IB01 -#define DISP_BITMASK_VCM0 DISP_BIT_IB00 -/* RAM Access */ -/* DISP_RAM_ADDR_SET_1_ADDR RAM Address Set (1) */ -#define DISP_BITMASK_AD7 DISP_BIT_IB07 -#define DISP_BITMASK_AD6 DISP_BIT_IB06 -#define DISP_BITMASK_AD5 DISP_BIT_IB05 -#define DISP_BITMASK_AD4 DISP_BIT_IB04 -#define DISP_BITMASK_AD3 DISP_BIT_IB03 -#define DISP_BITMASK_AD2 DISP_BIT_IB02 -#define DISP_BITMASK_AD1 DISP_BIT_IB01 -#define DISP_BITMASK_AD0 DISP_BIT_IB00 -/* DISP_RAM_ADDR_SET_2_ADDR RAM Address Set (2) */ -#define DISP_BITMASK_AD16 DISP_BIT_IB08 -#define DISP_BITMASK_AD15 DISP_BIT_IB07 -#define DISP_BITMASK_AD14 DISP_BIT_IB06 -#define DISP_BITMASK_AD13 DISP_BIT_IB05 -#define DISP_BITMASK_AD12 DISP_BIT_IB04 -#define DISP_BITMASK_AD11 DISP_BIT_IB03 -#define DISP_BITMASK_AD10 DISP_BIT_IB02 -#define DISP_BITMASK_AD9 DISP_BIT_IB01 -#define DISP_BITMASK_AD8 DISP_BIT_IB00 -/* - * DISP_CMD_RAMWR RAM Data Read/Write - * Use Data Bit Configuration - */ -/* DISP_RAM_DATA_MASK_1_ADDR RAM Write Data Mask (1) */ -#define DISP_BITMASK_WM11 DISP_BIT_IB13 -#define DISP_BITMASK_WM10 DISP_BIT_IB12 -#define DISP_BITMASK_WM9 DISP_BIT_IB11 -#define DISP_BITMASK_WM8 DISP_BIT_IB10 -#define DISP_BITMASK_WM7 DISP_BIT_IB09 -#define DISP_BITMASK_WM6 DISP_BIT_IB08 -#define DISP_BITMASK_WM5 DISP_BIT_IB05 -#define DISP_BITMASK_WM4 DISP_BIT_IB04 -#define DISP_BITMASK_WM3 DISP_BIT_IB03 -#define DISP_BITMASK_WM2 DISP_BIT_IB02 -#define DISP_BITMASK_WM1 DISP_BIT_IB01 -#define DISP_BITMASK_WM0 DISP_BIT_IB00 -/* DISP_RAM_DATA_MASK_2_ADDR RAM Write Data Mask (2) */ -#define DISP_BITMASK_WM17 DISP_BIT_IB05 -#define DISP_BITMASK_WM16 DISP_BIT_IB04 -#define DISP_BITMASK_WM15 DISP_BIT_IB03 -#define DISP_BITMASK_WM14 DISP_BIT_IB02 -#define DISP_BITMASK_WM13 DISP_BIT_IB01 -#define DISP_BITMASK_WM12 DISP_BIT_IB00 -/*Gamma Control */ -/* DISP_GAMMA_CONTROL_1_ADDR Gamma Control (1) */ -#define DISP_BITMASK_PKP12 DISP_BIT_IB10 -#define DISP_BITMASK_PKP11 DISP_BIT_IB08 -#define DISP_BITMASK_PKP10 DISP_BIT_IB09 -#define DISP_BITMASK_PKP02 DISP_BIT_IB02 -#define DISP_BITMASK_PKP01 DISP_BIT_IB01 -#define DISP_BITMASK_PKP00 DISP_BIT_IB00 -/* DISP_GAMMA_CONTROL_2_ADDR Gamma Control (2) */ -#define DISP_BITMASK_PKP32 DISP_BIT_IB10 -#define DISP_BITMASK_PKP31 DISP_BIT_IB09 -#define DISP_BITMASK_PKP30 DISP_BIT_IB08 -#define DISP_BITMASK_PKP22 DISP_BIT_IB02 -#define DISP_BITMASK_PKP21 DISP_BIT_IB01 -#define DISP_BITMASK_PKP20 DISP_BIT_IB00 -/* DISP_GAMMA_CONTROL_3_ADDR Gamma Control (3) */ -#define DISP_BITMASK_PKP52 DISP_BIT_IB10 -#define DISP_BITMASK_PKP51 DISP_BIT_IB09 -#define DISP_BITMASK_PKP50 DISP_BIT_IB08 -#define DISP_BITMASK_PKP42 DISP_BIT_IB02 -#define DISP_BITMASK_PKP41 DISP_BIT_IB01 -#define DISP_BITMASK_PKP40 DISP_BIT_IB00 -/* DISP_GAMMA_CONTROL_4_ADDR Gamma Control (4) */ -#define DISP_BITMASK_PRP12 DISP_BIT_IB10 -#define DISP_BITMASK_PRP11 DISP_BIT_IB08 -#define DISP_BITMASK_PRP10 DISP_BIT_IB09 -#define DISP_BITMASK_PRP02 DISP_BIT_IB02 -#define DISP_BITMASK_PRP01 DISP_BIT_IB01 -#define DISP_BITMASK_PRP00 DISP_BIT_IB00 -/* DISP_GAMMA_CONTROL_5_ADDR Gamma Control (5) */ -#define DISP_BITMASK_VRP14 DISP_BIT_IB12 -#define DISP_BITMASK_VRP13 DISP_BIT_IB11 -#define DISP_BITMASK_VRP12 DISP_BIT_IB10 -#define DISP_BITMASK_VRP11 DISP_BIT_IB08 -#define DISP_BITMASK_VRP10 DISP_BIT_IB09 -#define DISP_BITMASK_VRP03 DISP_BIT_IB03 -#define DISP_BITMASK_VRP02 DISP_BIT_IB02 -#define DISP_BITMASK_VRP01 DISP_BIT_IB01 -#define DISP_BITMASK_VRP00 DISP_BIT_IB00 -/* DISP_GAMMA_CONTROL_6_ADDR Gamma Control (6) */ -#define DISP_BITMASK_PKN12 DISP_BIT_IB10 -#define DISP_BITMASK_PKN11 DISP_BIT_IB08 -#define DISP_BITMASK_PKN10 DISP_BIT_IB09 -#define DISP_BITMASK_PKN02 DISP_BIT_IB02 -#define DISP_BITMASK_PKN01 DISP_BIT_IB01 -#define DISP_BITMASK_PKN00 DISP_BIT_IB00 -/* DISP_GAMMA_CONTROL_7_ADDR Gamma Control (7) */ -#define DISP_BITMASK_PKN32 DISP_BIT_IB10 -#define DISP_BITMASK_PKN31 DISP_BIT_IB08 -#define DISP_BITMASK_PKN30 DISP_BIT_IB09 -#define DISP_BITMASK_PKN22 DISP_BIT_IB02 -#define DISP_BITMASK_PKN21 DISP_BIT_IB01 -#define DISP_BITMASK_PKN20 DISP_BIT_IB00 -/* DISP_GAMMA_CONTROL_8_ADDR Gamma Control (8) */ -#define DISP_BITMASK_PKN52 DISP_BIT_IB10 -#define DISP_BITMASK_PKN51 DISP_BIT_IB08 -#define DISP_BITMASK_PKN50 DISP_BIT_IB09 -#define DISP_BITMASK_PKN42 DISP_BIT_IB02 -#define DISP_BITMASK_PKN41 DISP_BIT_IB01 -#define DISP_BITMASK_PKN40 DISP_BIT_IB00 -/* DISP_GAMMA_CONTROL_9_ADDR Gamma Control (9) */ -#define DISP_BITMASK_PRN12 DISP_BIT_IB10 -#define DISP_BITMASK_PRN11 DISP_BIT_IB08 -#define DISP_BITMASK_PRN10 DISP_BIT_IB09 -#define DISP_BITMASK_PRN02 DISP_BIT_IB02 -#define DISP_BITMASK_PRN01 DISP_BIT_IB01 -#define DISP_BITMASK_PRN00 DISP_BIT_IB00 -/* DISP_GAMMA_CONTROL_10_ADDR Gamma Control (10) */ -#define DISP_BITMASK_VRN14 DISP_BIT_IB12 -#define DISP_BITMASK_VRN13 DISP_BIT_IB11 -#define DISP_BITMASK_VRN12 DISP_BIT_IB10 -#define DISP_BITMASK_VRN11 DISP_BIT_IB08 -#define DISP_BITMASK_VRN10 DISP_BIT_IB09 -#define DISP_BITMASK_VRN03 DISP_BIT_IB03 -#define DISP_BITMASK_VRN02 DISP_BIT_IB02 -#define DISP_BITMASK_VRN01 DISP_BIT_IB01 -#define DISP_BITMASK_VRN00 DISP_BIT_IB00 -/* Coordinate Control */ -/* DISP_VERT_SCROLL_CTL_1_ADDR Vertical Scroll Control (1) */ -#define DISP_BITMASK_VL18 DISP_BIT_IB08 -#define DISP_BITMASK_VL17 DISP_BIT_IB07 -#define DISP_BITMASK_VL16 DISP_BIT_IB06 -#define DISP_BITMASK_VL15 DISP_BIT_IB05 -#define DISP_BITMASK_VL14 DISP_BIT_IB04 -#define DISP_BITMASK_VL13 DISP_BIT_IB03 -#define DISP_BITMASK_VL12 DISP_BIT_IB02 -#define DISP_BITMASK_VL11 DISP_BIT_IB01 -#define DISP_BITMASK_VL10 DISP_BIT_IB00 -/* DISP_VERT_SCROLL_CTL_2_ADDR Vertical Scroll Control (2) */ -#define DISP_BITMASK_VL28 DISP_BIT_IB08 -#define DISP_BITMASK_VL27 DISP_BIT_IB07 -#define DISP_BITMASK_VL26 DISP_BIT_IB06 -#define DISP_BITMASK_VL25 DISP_BIT_IB05 -#define DISP_BITMASK_VL24 DISP_BIT_IB04 -#define DISP_BITMASK_VL23 DISP_BIT_IB03 -#define DISP_BITMASK_VL22 DISP_BIT_IB02 -#define DISP_BITMASK_VL21 DISP_BIT_IB01 -#define DISP_BITMASK_VL20 DISP_BIT_IB00 -/* DISP_SCREEN_1_DRV_POS_1_ADDR First Screen Driving Position (1) */ -#define DISP_BITMASK_SS18 DISP_BIT_IB08 -#define DISP_BITMASK_SS17 DISP_BIT_IB07 -#define DISP_BITMASK_SS16 DISP_BIT_IB06 -#define DISP_BITMASK_SS15 DISP_BIT_IB05 -#define DISP_BITMASK_SS14 DISP_BIT_IB04 -#define DISP_BITMASK_SS13 DISP_BIT_IB03 -#define DISP_BITMASK_SS12 DISP_BIT_IB02 -#define DISP_BITMASK_SS11 DISP_BIT_IB01 -#define DISP_BITMASK_SS10 DISP_BIT_IB00 -/* DISP_SCREEN_1_DRV_POS_2_ADDR First Screen Driving Position (2) */ -#define DISP_BITMASK_SE18 DISP_BIT_IB08 -#define DISP_BITMASK_SE17 DISP_BIT_IB07 -#define DISP_BITMASK_SE16 DISP_BIT_IB06 -#define DISP_BITMASK_SE15 DISP_BIT_IB05 -#define DISP_BITMASK_SE14 DISP_BIT_IB04 -#define DISP_BITMASK_SE13 DISP_BIT_IB03 -#define DISP_BITMASK_SE12 DISP_BIT_IB02 -#define DISP_BITMASK_SE11 DISP_BIT_IB01 -#define DISP_BITMASK_SE10 DISP_BIT_IB00 -/* DISP_SCREEN_2_DRV_POS_1_ADDR Second Screen Driving Position (1) */ -#define DISP_BITMASK_SS28 DISP_BIT_IB08 -#define DISP_BITMASK_SS27 DISP_BIT_IB07 -#define DISP_BITMASK_SS26 DISP_BIT_IB06 -#define DISP_BITMASK_SS25 DISP_BIT_IB05 -#define DISP_BITMASK_SS24 DISP_BIT_IB04 -#define DISP_BITMASK_SS23 DISP_BIT_IB03 -#define DISP_BITMASK_SS22 DISP_BIT_IB02 -#define DISP_BITMASK_SS21 DISP_BIT_IB01 -#define DISP_BITMASK_SS20 DISP_BIT_IB00 -/* DISP_SCREEN_3_DRV_POS_2_ADDR Second Screen Driving Position (2) */ -#define DISP_BITMASK_SE28 DISP_BIT_IB08 -#define DISP_BITMASK_SE27 DISP_BIT_IB07 -#define DISP_BITMASK_SE26 DISP_BIT_IB06 -#define DISP_BITMASK_SE25 DISP_BIT_IB05 -#define DISP_BITMASK_SE24 DISP_BIT_IB04 -#define DISP_BITMASK_SE23 DISP_BIT_IB03 -#define DISP_BITMASK_SE22 DISP_BIT_IB02 -#define DISP_BITMASK_SE21 DISP_BIT_IB01 -#define DISP_BITMASK_SE20 DISP_BIT_IB00 -/* DISP_HORZ_RAM_ADDR_POS_1_ADDR Horizontal RAM Address Position (1) */ -#define DISP_BITMASK_HSA7 DISP_BIT_IB07 -#define DISP_BITMASK_HSA6 DISP_BIT_IB06 -#define DISP_BITMASK_HSA5 DISP_BIT_IB05 -#define DISP_BITMASK_HSA4 DISP_BIT_IB04 -#define DISP_BITMASK_HSA3 DISP_BIT_IB03 -#define DISP_BITMASK_HSA2 DISP_BIT_IB02 -#define DISP_BITMASK_HSA1 DISP_BIT_IB01 -#define DISP_BITMASK_HSA0 DISP_BIT_IB00 -/* DISP_HORZ_RAM_ADDR_POS_2_ADDR Horizontal RAM Address Position (2) */ -#define DISP_BITMASK_HEA7 DISP_BIT_IB07 -#define DISP_BITMASK_HEA6 DISP_BIT_IB06 -#define DISP_BITMASK_HEA5 DISP_BIT_IB05 -#define DISP_BITMASK_HEA4 DISP_BIT_IB04 -#define DISP_BITMASK_HEA3 DISP_BIT_IB03 -#define DISP_BITMASK_HEA2 DISP_BIT_IB02 -#define DISP_BITMASK_HEA1 DISP_BIT_IB01 -#define DISP_BITMASK_HEA0 DISP_BIT_IB00 -/* DISP_VERT_RAM_ADDR_POS_1_ADDR Vertical RAM Address Position (1) */ -#define DISP_BITMASK_VSA8 DISP_BIT_IB08 -#define DISP_BITMASK_VSA7 DISP_BIT_IB07 -#define DISP_BITMASK_VSA6 DISP_BIT_IB06 -#define DISP_BITMASK_VSA5 DISP_BIT_IB05 -#define DISP_BITMASK_VSA4 DISP_BIT_IB04 -#define DISP_BITMASK_VSA3 DISP_BIT_IB03 -#define DISP_BITMASK_VSA2 DISP_BIT_IB02 -#define DISP_BITMASK_VSA1 DISP_BIT_IB01 -#define DISP_BITMASK_VSA0 DISP_BIT_IB00 -/* DISP_VERT_RAM_ADDR_POS_2_ADDR Vertical RAM Address Position (2) */ -#define DISP_BITMASK_VEA8 DISP_BIT_IB08 -#define DISP_BITMASK_VEA7 DISP_BIT_IB07 -#define DISP_BITMASK_VEA6 DISP_BIT_IB06 -#define DISP_BITMASK_VEA5 DISP_BIT_IB05 -#define DISP_BITMASK_VEA4 DISP_BIT_IB04 -#define DISP_BITMASK_VEA3 DISP_BIT_IB03 -#define DISP_BITMASK_VEA2 DISP_BIT_IB02 -#define DISP_BITMASK_VEA1 DISP_BIT_IB01 -#define DISP_BITMASK_VEA0 DISP_BIT_IB00 -static word disp_area_start_row; -static word disp_area_end_row; -static boolean disp_initialized = FALSE; -/* For some reason the contrast set at init time is not good. Need to do -* it again -*/ -static boolean display_on = FALSE; - -static uint32 tmd20qvga_lcd_rev; -uint16 tmd20qvga_panel_offset; - -#ifdef DISP_DEVICE_8BPP -static word convert_8_to_16_tbl[256] = { - 0x0000, 0x2000, 0x4000, 0x6000, 0x8000, 0xA000, 0xC000, 0xE000, - 0x0100, 0x2100, 0x4100, 0x6100, 0x8100, 0xA100, 0xC100, 0xE100, - 0x0200, 0x2200, 0x4200, 0x6200, 0x8200, 0xA200, 0xC200, 0xE200, - 0x0300, 0x2300, 0x4300, 0x6300, 0x8300, 0xA300, 0xC300, 0xE300, - 0x0400, 0x2400, 0x4400, 0x6400, 0x8400, 0xA400, 0xC400, 0xE400, - 0x0500, 0x2500, 0x4500, 0x6500, 0x8500, 0xA500, 0xC500, 0xE500, - 0x0600, 0x2600, 0x4600, 0x6600, 0x8600, 0xA600, 0xC600, 0xE600, - 0x0700, 0x2700, 0x4700, 0x6700, 0x8700, 0xA700, 0xC700, 0xE700, - 0x0008, 0x2008, 0x4008, 0x6008, 0x8008, 0xA008, 0xC008, 0xE008, - 0x0108, 0x2108, 0x4108, 0x6108, 0x8108, 0xA108, 0xC108, 0xE108, - 0x0208, 0x2208, 0x4208, 0x6208, 0x8208, 0xA208, 0xC208, 0xE208, - 0x0308, 0x2308, 0x4308, 0x6308, 0x8308, 0xA308, 0xC308, 0xE308, - 0x0408, 0x2408, 0x4408, 0x6408, 0x8408, 0xA408, 0xC408, 0xE408, - 0x0508, 0x2508, 0x4508, 0x6508, 0x8508, 0xA508, 0xC508, 0xE508, - 0x0608, 0x2608, 0x4608, 0x6608, 0x8608, 0xA608, 0xC608, 0xE608, - 0x0708, 0x2708, 0x4708, 0x6708, 0x8708, 0xA708, 0xC708, 0xE708, - 0x0010, 0x2010, 0x4010, 0x6010, 0x8010, 0xA010, 0xC010, 0xE010, - 0x0110, 0x2110, 0x4110, 0x6110, 0x8110, 0xA110, 0xC110, 0xE110, - 0x0210, 0x2210, 0x4210, 0x6210, 0x8210, 0xA210, 0xC210, 0xE210, - 0x0310, 0x2310, 0x4310, 0x6310, 0x8310, 0xA310, 0xC310, 0xE310, - 0x0410, 0x2410, 0x4410, 0x6410, 0x8410, 0xA410, 0xC410, 0xE410, - 0x0510, 0x2510, 0x4510, 0x6510, 0x8510, 0xA510, 0xC510, 0xE510, - 0x0610, 0x2610, 0x4610, 0x6610, 0x8610, 0xA610, 0xC610, 0xE610, - 0x0710, 0x2710, 0x4710, 0x6710, 0x8710, 0xA710, 0xC710, 0xE710, - 0x0018, 0x2018, 0x4018, 0x6018, 0x8018, 0xA018, 0xC018, 0xE018, - 0x0118, 0x2118, 0x4118, 0x6118, 0x8118, 0xA118, 0xC118, 0xE118, - 0x0218, 0x2218, 0x4218, 0x6218, 0x8218, 0xA218, 0xC218, 0xE218, - 0x0318, 0x2318, 0x4318, 0x6318, 0x8318, 0xA318, 0xC318, 0xE318, - 0x0418, 0x2418, 0x4418, 0x6418, 0x8418, 0xA418, 0xC418, 0xE418, - 0x0518, 0x2518, 0x4518, 0x6518, 0x8518, 0xA518, 0xC518, 0xE518, - 0x0618, 0x2618, 0x4618, 0x6618, 0x8618, 0xA618, 0xC618, 0xE618, - 0x0718, 0x2718, 0x4718, 0x6718, 0x8718, 0xA718, 0xC718, 0xE718 -}; -#endif /* DISP_DEVICE_8BPP */ - -static void tmd20qvga_disp_set_rect(int x, int y, int xres, int yres); -static void tmd20qvga_disp_init(struct platform_device *pdev); -static void tmd20qvga_disp_set_contrast(void); -static void tmd20qvga_disp_set_display_area(word start_row, word end_row); -static int tmd20qvga_disp_off(struct platform_device *pdev); -static int tmd20qvga_disp_on(struct platform_device *pdev); -static void tmd20qvga_set_revId(int); - -/* future use */ -void tmd20qvga_disp_clear_screen_area(word start_row, word end_row, - word start_column, word end_column); - -static void tmd20qvga_set_revId(int id) -{ - - tmd20qvga_lcd_rev = id; - - if (tmd20qvga_lcd_rev == 1) - tmd20qvga_panel_offset = 0x10; - else - tmd20qvga_panel_offset = 0; -} - -static void tmd20qvga_disp_init(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - - if (disp_initialized) - return; - - mfd = platform_get_drvdata(pdev); - - DISP_CMD_PORT = mfd->cmd_port; - DISP_DATA_PORT = mfd->data_port; - -#ifdef TMD20QVGA_LCD_18BPP - tmd20qvga_set_revId(2); -#else - tmd20qvga_set_revId(1); -#endif - - disp_initialized = TRUE; - tmd20qvga_disp_set_contrast(); - tmd20qvga_disp_set_display_area(0, QVGA_HEIGHT - 1); -} - -static void tmd20qvga_disp_set_rect(int x, int y, int xres, int yres) -{ - if (!disp_initialized) - return; - - DISP_SET_RECT(y, y + yres - 1, x, x + xres - 1); - - DISP_CMD_OUT(DISP_CMD_RAMWR); -} - -static void tmd20qvga_disp_set_display_area(word start_row, word end_row) -{ - word start_driving = start_row; - word end_driving = end_row; - - if (!disp_initialized) - return; - - /* Range checking - */ - if (end_driving >= QVGA_HEIGHT) - end_driving = QVGA_HEIGHT - 1; - if (start_driving > end_driving) { - /* Probably Backwards Switch */ - start_driving = end_driving; - end_driving = start_row; /* Has not changed */ - if (end_driving >= QVGA_HEIGHT) - end_driving = QVGA_HEIGHT - 1; - } - - if ((start_driving == disp_area_start_row) - && (end_driving == disp_area_end_row)) - return; - - disp_area_start_row = start_driving; - disp_area_end_row = end_driving; - - DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_1_ADDR, - DISP_VAL_IF(start_driving & 0x100, - DISP_BITMASK_SS18) | - DISP_VAL_IF(start_driving & 0x080, - DISP_BITMASK_SS17) | - DISP_VAL_IF(start_driving & 0x040, - DISP_BITMASK_SS16) | - DISP_VAL_IF(start_driving & 0x020, - DISP_BITMASK_SS15) | - DISP_VAL_IF(start_driving & 0x010, - DISP_BITMASK_SS14) | - DISP_VAL_IF(start_driving & 0x008, - DISP_BITMASK_SS13) | - DISP_VAL_IF(start_driving & 0x004, - DISP_BITMASK_SS12) | - DISP_VAL_IF(start_driving & 0x002, - DISP_BITMASK_SS11) | - DISP_VAL_IF(start_driving & 0x001, DISP_BITMASK_SS10)); - - DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_2_ADDR, - DISP_VAL_IF(end_driving & 0x100, DISP_BITMASK_SE18) | - DISP_VAL_IF(end_driving & 0x080, DISP_BITMASK_SE17) | - DISP_VAL_IF(end_driving & 0x040, DISP_BITMASK_SE16) | - DISP_VAL_IF(end_driving & 0x020, DISP_BITMASK_SE15) | - DISP_VAL_IF(end_driving & 0x010, DISP_BITMASK_SE14) | - DISP_VAL_IF(end_driving & 0x008, DISP_BITMASK_SE13) | - DISP_VAL_IF(end_driving & 0x004, DISP_BITMASK_SE12) | - DISP_VAL_IF(end_driving & 0x002, DISP_BITMASK_SE11) | - DISP_VAL_IF(end_driving & 0x001, DISP_BITMASK_SE10)); -} - -static int tmd20qvga_disp_off(struct platform_device *pdev) -{ - if (!disp_initialized) - tmd20qvga_disp_init(pdev); - - if (display_on) { - if (tmd20qvga_lcd_rev == 2) { - DISP_WRITE_OUT(DISP_POFF_LN_SETTING_ADDR, 0x000A); - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xFFEE); - WAIT_MSEC(40); - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xF812); - WAIT_MSEC(40); - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xE811); - WAIT_MSEC(40); - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xC011); - WAIT_MSEC(40); - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x4011); - WAIT_MSEC(20); - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0010); - - } else { - DISP_WRITE_OUT(DISP_POFF_LN_SETTING_ADDR, 0x000F); - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0BFE); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100); - WAIT_MSEC(40); - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0BED); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100); - WAIT_MSEC(40); - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x00CD); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100); - WAIT_MSEC(20); - DISP_WRITE_OUT(DISP_START_OSCILLATION_ADDR, 0x0); - } - - DISP_WRITE_OUT(DISP_MODE_SETTING_ADDR, 0x0004); - DISP_WRITE_OUT(DISP_MODE_SETTING_ADDR, 0x0000); - - display_on = FALSE; - } - - return 0; -} - -static int tmd20qvga_disp_on(struct platform_device *pdev) -{ - if (!disp_initialized) - tmd20qvga_disp_init(pdev); - - if (!display_on) { - /* Deep Stand-by -> Stand-by */ - DISP_CMD_OUT(DISP_START_OSCILLATION_ADDR); - WAIT_MSEC(1); - DISP_CMD_OUT(DISP_START_OSCILLATION_ADDR); - WAIT_MSEC(1); - DISP_CMD_OUT(DISP_START_OSCILLATION_ADDR); - WAIT_MSEC(1); - - /* OFF -> Deep Stan-By -> Stand-by */ - /* let's change the state from "Stand-by" to "Sleep" */ - DISP_WRITE_OUT(DISP_MODE_SETTING_ADDR, 0x0005); - WAIT_MSEC(1); - - /* Sleep -> Displaying */ - DISP_WRITE_OUT(DISP_START_OSCILLATION_ADDR, 0x0001); - DISP_WRITE_OUT(DISP_DRIVER_OUTPUT_CTL_ADDR, 0x0127); - DISP_WRITE_OUT(DISP_LCD_DRIVING_SIG_ADDR, 0x200); - /* fast write mode */ - DISP_WRITE_OUT(DISP_ENTRY_MODE_ADDR, 0x0130); - if (tmd20qvga_lcd_rev == 2) - DISP_WRITE_OUT(DISP_TMD_700_ADDR, 0x0003); - /* back porch = 14 + front porch = 2 --> 16 lines */ - if (tmd20qvga_lcd_rev == 2) { -#ifdef TMD20QVGA_LCD_18BPP - /* 256k color */ - DISP_WRITE_OUT(DISP_DISPLAY_CTL_1_ADDR, 0x0000); -#else - /* 65k color */ - DISP_WRITE_OUT(DISP_DISPLAY_CTL_1_ADDR, 0x4000); -#endif - DISP_WRITE_OUT(DISP_DISPLAY_CTL_2_ADDR, 0x0302); - } else { -#ifdef TMD20QVGA_LCD_18BPP - /* 256k color */ - DISP_WRITE_OUT(DISP_DISPLAY_CTL_1_ADDR, 0x0004); -#else - /* 65k color */ - DISP_WRITE_OUT(DISP_DISPLAY_CTL_1_ADDR, 0x4004); -#endif - DISP_WRITE_OUT(DISP_DISPLAY_CTL_2_ADDR, 0x020E); - } - /* 16 bit one transfer */ - if (tmd20qvga_lcd_rev == 2) { - DISP_WRITE_OUT(DISP_EXT_DISPLAY_CTL_1_ADDR, 0x0000); - DISP_WRITE_OUT(DISP_FRAME_CYCLE_CTL_ADDR, 0x0010); - DISP_WRITE_OUT(DISP_LTPS_CTL_1_ADDR, 0x0302); - DISP_WRITE_OUT(DISP_LTPS_CTL_2_ADDR, 0x0102); - DISP_WRITE_OUT(DISP_LTPS_CTL_3_ADDR, 0x0000); - DISP_WRITE_OUT(DISP_TMD_015_ADDR, 0x2000); - - DISP_WRITE_OUT(DISP_AMP_SETTING_ADDR, 0x0000); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_1_ADDR, 0x0403); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_2_ADDR, 0x0304); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_3_ADDR, 0x0403); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_4_ADDR, 0x0303); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_5_ADDR, 0x0101); - DISP_WRITE_OUT(DISP_TMD_305_ADDR, 0); - - DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_1_ADDR, 0x0000); - DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_2_ADDR, 0x013F); - - DISP_WRITE_OUT(DISP_POWER_CTL_3_ADDR, 0x077D); - - DISP_WRITE_OUT(DISP_POWER_CTL_4_ADDR, 0x0005); - DISP_WRITE_OUT(DISP_POWER_CTL_5_ADDR, 0x0000); - DISP_WRITE_OUT(DISP_POWER_CTL_6_ADDR, 0x0015); - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xC010); - WAIT_MSEC(1); - - DISP_WRITE_OUT(DISP_POWER_CTL_2_ADDR, 0x0001); - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0xFFFE); - WAIT_MSEC(60); - } else { - DISP_WRITE_OUT(DISP_EXT_DISPLAY_CTL_1_ADDR, 0x0001); - DISP_WRITE_OUT(DISP_FRAME_CYCLE_CTL_ADDR, 0x0010); - DISP_WRITE_OUT(DISP_LTPS_CTL_1_ADDR, 0x0301); - DISP_WRITE_OUT(DISP_LTPS_CTL_2_ADDR, 0x0001); - DISP_WRITE_OUT(DISP_LTPS_CTL_3_ADDR, 0x0000); - DISP_WRITE_OUT(DISP_AMP_SETTING_ADDR, 0x0000); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_1_ADDR, 0x0507); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_2_ADDR, 0x0405); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_3_ADDR, 0x0607); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_4_ADDR, 0x0502); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_5_ADDR, 0x0301); - DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_1_ADDR, 0x0000); - DISP_WRITE_OUT(DISP_SCREEN_1_DRV_POS_2_ADDR, 0x013F); - DISP_WRITE_OUT(DISP_POWER_CTL_3_ADDR, 0x0795); - - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0102); - WAIT_MSEC(1); - - DISP_WRITE_OUT(DISP_POWER_CTL_4_ADDR, 0x0450); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0103); - WAIT_MSEC(1); - - DISP_WRITE_OUT(DISP_POWER_CTL_5_ADDR, 0x0008); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0104); - WAIT_MSEC(1); - - DISP_WRITE_OUT(DISP_POWER_CTL_6_ADDR, 0x0C00); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0105); - WAIT_MSEC(1); - - DISP_WRITE_OUT(DISP_POWER_CTL_7_ADDR, 0x0000); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0106); - WAIT_MSEC(1); - - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0801); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100); - WAIT_MSEC(1); - - DISP_WRITE_OUT(DISP_POWER_CTL_2_ADDR, 0x001F); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0101); - WAIT_MSEC(60); - - DISP_WRITE_OUT(DISP_POWER_CTL_2_ADDR, 0x009F); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0101); - WAIT_MSEC(10); - - DISP_WRITE_OUT(DISP_HORZ_RAM_ADDR_POS_1_ADDR, 0x0010); - DISP_WRITE_OUT(DISP_HORZ_RAM_ADDR_POS_2_ADDR, 0x00FF); - DISP_WRITE_OUT(DISP_VERT_RAM_ADDR_POS_1_ADDR, 0x0000); - DISP_WRITE_OUT(DISP_VERT_RAM_ADDR_POS_2_ADDR, 0x013F); - /* RAM starts at address 0x10 */ - DISP_WRITE_OUT(DISP_RAM_ADDR_SET_1_ADDR, 0x0010); - DISP_WRITE_OUT(DISP_RAM_ADDR_SET_2_ADDR, 0x0000); - - /* lcd controller uses internal clock, not ext. vsync */ - DISP_CMD_OUT(DISP_CMD_RAMWR); - - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0881); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100); - WAIT_MSEC(40); - - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0BE1); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100); - WAIT_MSEC(40); - - DISP_WRITE_OUT(DISP_POWER_CTL_1_ADDR, 0x0BFF); - DISP_WRITE_OUT(DISP_POWER_SUPPLY_INTF_ADDR, 0x0100); - } - display_on = TRUE; - } - - return 0; -} - -static void tmd20qvga_disp_set_contrast(void) -{ -#if (defined(TMD20QVGA_LCD_18BPP)) - - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_1_ADDR, 0x0403); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_2_ADDR, 0x0302); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_3_ADDR, 0x0403); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_4_ADDR, 0x0303); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_5_ADDR, 0x0F07); - -#else - int newcontrast = 0x46; - - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_1_ADDR, 0x0403); - - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_2_ADDR, - DISP_VAL_IF(newcontrast & 0x0001, DISP_BITMASK_PKP20) | - DISP_VAL_IF(newcontrast & 0x0002, DISP_BITMASK_PKP21) | - DISP_VAL_IF(newcontrast & 0x0004, DISP_BITMASK_PKP22) | - DISP_VAL_IF(newcontrast & 0x0010, DISP_BITMASK_PKP30) | - DISP_VAL_IF(newcontrast & 0x0020, DISP_BITMASK_PKP31) | - DISP_VAL_IF(newcontrast & 0x0040, DISP_BITMASK_PKP32)); - - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_3_ADDR, - DISP_VAL_IF(newcontrast & 0x0010, DISP_BITMASK_PKP40) | - DISP_VAL_IF(newcontrast & 0x0020, DISP_BITMASK_PKP41) | - DISP_VAL_IF(newcontrast & 0x0040, DISP_BITMASK_PKP42) | - DISP_VAL_IF(newcontrast & 0x0001, DISP_BITMASK_PKP50) | - DISP_VAL_IF(newcontrast & 0x0002, DISP_BITMASK_PKP51) | - DISP_VAL_IF(newcontrast & 0x0004, DISP_BITMASK_PKP52)); - - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_4_ADDR, 0x0303); - DISP_WRITE_OUT(DISP_GAMMA_CONTROL_5_ADDR, 0x0F07); - -#endif /* defined(TMD20QVGA_LCD_18BPP) */ - -} /* End disp_set_contrast */ - -void tmd20qvga_disp_clear_screen_area - (word start_row, word end_row, word start_column, word end_column) { - int32 i; - - /* Clear the display screen */ - DISP_SET_RECT(start_row, end_row, start_column, end_column); - DISP_CMD_OUT(DISP_CMD_RAMWR); - i = (end_row - start_row + 1) * (end_column - start_column + 1); - for (; i > 0; i--) - DISP_DATA_OUT_16TO18BPP(0x0); -} - -static int __init tmd20qvga_probe(struct platform_device *pdev) -{ - msm_fb_add_device(pdev); - - return 0; -} - -static struct platform_driver this_driver = { - .probe = tmd20qvga_probe, - .driver = { - .name = "ebi2_tmd_qvga", - }, -}; - -static struct msm_fb_panel_data tmd20qvga_panel_data = { - .on = tmd20qvga_disp_on, - .off = tmd20qvga_disp_off, - .set_rect = tmd20qvga_disp_set_rect, -}; - -static struct platform_device this_device = { - .name = "ebi2_tmd_qvga", - .id = 0, - .dev = { - .platform_data = &tmd20qvga_panel_data, - } -}; - -static int __init tmd20qvga_init(void) -{ - int ret; - struct msm_panel_info *pinfo; - - ret = platform_driver_register(&this_driver); - if (!ret) { - pinfo = &tmd20qvga_panel_data.panel_info; - pinfo->xres = 240; - pinfo->yres = 320; - pinfo->type = EBI2_PANEL; - pinfo->pdest = DISPLAY_1; - pinfo->wait_cycle = 0x808000; -#ifdef TMD20QVGA_LCD_18BPP - pinfo->bpp = 18; -#else - pinfo->bpp = 16; -#endif - pinfo->fb_num = 2; - pinfo->lcd.vsync_enable = TRUE; - pinfo->lcd.refx100 = 6000; - pinfo->lcd.v_back_porch = 16; - pinfo->lcd.v_front_porch = 4; - pinfo->lcd.v_pulse_width = 0; - pinfo->lcd.hw_vsync_mode = FALSE; - pinfo->lcd.vsync_notifier_period = 0; - - ret = platform_device_register(&this_device); - if (ret) - platform_driver_unregister(&this_driver); - } - - return ret; -} - -module_init(tmd20qvga_init); diff --git a/drivers/staging/msm/hdmi_sii9022.c b/drivers/staging/msm/hdmi_sii9022.c deleted file mode 100644 index 6b82b56a77b6..000000000000 --- a/drivers/staging/msm/hdmi_sii9022.c +++ /dev/null @@ -1,248 +0,0 @@ -/* 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include "msm_fb.h" - -#define DEVICE_NAME "sii9022" -#define SII9022_DEVICE_ID 0xB0 - -struct sii9022_i2c_addr_data{ - u8 addr; - u8 data; -}; - -/* video mode data */ -static u8 video_mode_data[] = { - 0x00, - 0xF9, 0x1C, 0x70, 0x17, 0x72, 0x06, 0xEE, 0x02, -}; - -static u8 avi_io_format[] = { - 0x09, - 0x00, 0x00, -}; - -/* power state */ -static struct sii9022_i2c_addr_data regset0[] = { - { 0x60, 0x04 }, - { 0x63, 0x00 }, - { 0x1E, 0x00 }, -}; - -static u8 video_infoframe[] = { - 0x0C, - 0xF0, 0x00, 0x68, 0x00, 0x04, 0x00, 0x19, 0x00, - 0xE9, 0x02, 0x04, 0x01, 0x04, 0x06, -}; - -/* configure audio */ -static struct sii9022_i2c_addr_data regset1[] = { - { 0x26, 0x90 }, - { 0x20, 0x90 }, - { 0x1F, 0x80 }, - { 0x26, 0x80 }, - { 0x24, 0x02 }, - { 0x25, 0x0B }, - { 0xBC, 0x02 }, - { 0xBD, 0x24 }, - { 0xBE, 0x02 }, -}; - -/* enable audio */ -static u8 misc_infoframe[] = { - 0xBF, - 0xC2, 0x84, 0x01, 0x0A, 0x6F, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -/* set HDMI, active */ -static struct sii9022_i2c_addr_data regset2[] = { - { 0x1A, 0x01 }, - { 0x3D, 0x00 }, -}; - -static int send_i2c_data(struct i2c_client *client, - struct sii9022_i2c_addr_data *regset, - int size) -{ - int i; - int rc = 0; - - for (i = 0; i < size; i++) { - rc = i2c_smbus_write_byte_data( - client, - regset[i].addr, regset[i].data); - if (rc) - break; - } - return rc; -} - -static int hdmi_sii_enable(struct i2c_client *client) -{ - int rc; - int retries = 10; - int count; - - rc = i2c_smbus_write_byte_data(client, 0xC7, 0x00); - if (rc) - goto enable_exit; - - do { - msleep(1); - rc = i2c_smbus_read_byte_data(client, 0x1B); - } while ((rc != SII9022_DEVICE_ID) && retries--); - - if (rc != SII9022_DEVICE_ID) - return -ENODEV; - - rc = i2c_smbus_write_byte_data(client, 0x1A, 0x11); - if (rc) - goto enable_exit; - - count = ARRAY_SIZE(video_mode_data); - rc = i2c_master_send(client, video_mode_data, count); - if (rc != count) { - rc = -EIO; - goto enable_exit; - } - - rc = i2c_smbus_write_byte_data(client, 0x08, 0x20); - if (rc) - goto enable_exit; - count = ARRAY_SIZE(avi_io_format); - rc = i2c_master_send(client, avi_io_format, count); - if (rc != count) { - rc = -EIO; - goto enable_exit; - } - - rc = send_i2c_data(client, regset0, ARRAY_SIZE(regset0)); - if (rc) - goto enable_exit; - - count = ARRAY_SIZE(video_infoframe); - rc = i2c_master_send(client, video_infoframe, count); - if (rc != count) { - rc = -EIO; - goto enable_exit; - } - - rc = send_i2c_data(client, regset1, ARRAY_SIZE(regset1)); - if (rc) - goto enable_exit; - - count = ARRAY_SIZE(misc_infoframe); - rc = i2c_master_send(client, misc_infoframe, count); - if (rc != count) { - rc = -EIO; - goto enable_exit; - } - - rc = send_i2c_data(client, regset2, ARRAY_SIZE(regset2)); - if (rc) - goto enable_exit; - - return 0; -enable_exit: - printk(KERN_ERR "%s: exited rc=%d\n", __func__, rc); - return rc; -} - -static const struct i2c_device_id hmdi_sii_id[] = { - { DEVICE_NAME, 0 }, - { } -}; - -static int hdmi_sii_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int rc; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C)) - return -ENODEV; - rc = hdmi_sii_enable(client); - return rc; -} - - -static struct i2c_driver hdmi_sii_i2c_driver = { - .driver = { - .name = DEVICE_NAME, - .owner = THIS_MODULE, - }, - .probe = hdmi_sii_probe, - .remove = __exit_p(hdmi_sii_remove), - .id_table = hmdi_sii_id, -}; - -static int __init hdmi_sii_init(void) -{ - int ret; - struct msm_panel_info pinfo; - - if (msm_fb_detect_client("hdmi_sii9022")) - return 0; - - pinfo.xres = 1280; - pinfo.yres = 720; - pinfo.type = HDMI_PANEL; - pinfo.pdest = DISPLAY_1; - pinfo.wait_cycle = 0; - pinfo.bpp = 24; - pinfo.fb_num = 2; - pinfo.clk_rate = 74250000; - - pinfo.lcdc.h_back_porch = 124; - pinfo.lcdc.h_front_porch = 110; - pinfo.lcdc.h_pulse_width = 136; - pinfo.lcdc.v_back_porch = 19; - pinfo.lcdc.v_front_porch = 5; - pinfo.lcdc.v_pulse_width = 6; - pinfo.lcdc.border_clr = 0; - pinfo.lcdc.underflow_clr = 0xff; - pinfo.lcdc.hsync_skew = 0; - - ret = lcdc_device_register(&pinfo); - if (ret) { - printk(KERN_ERR "%s: failed to register device\n", __func__); - goto init_exit; - } - - ret = i2c_add_driver(&hdmi_sii_i2c_driver); - if (ret) - printk(KERN_ERR "%s: failed to add i2c driver\n", __func__); - -init_exit: - return ret; -} - -static void __exit hdmi_sii_exit(void) -{ - i2c_del_driver(&hdmi_sii_i2c_driver); -} - -module_init(hdmi_sii_init); -module_exit(hdmi_sii_exit); -MODULE_LICENSE("GPL v2"); -MODULE_VERSION("0.1"); -MODULE_AUTHOR("Qualcomm Innovation Center, Inc."); -MODULE_DESCRIPTION("SiI9022 HDMI driver"); -MODULE_ALIAS("platform:hdmi-sii9022"); diff --git a/drivers/staging/msm/lcdc.c b/drivers/staging/msm/lcdc.c deleted file mode 100644 index 8183394aef76..000000000000 --- a/drivers/staging/msm/lcdc.c +++ /dev/null @@ -1,239 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "msm_fb.h" - -static int lcdc_probe(struct platform_device *pdev); -static int lcdc_remove(struct platform_device *pdev); - -static int lcdc_off(struct platform_device *pdev); -static int lcdc_on(struct platform_device *pdev); - -static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST]; -static int pdev_list_cnt; - -static struct clk *mdp_lcdc_pclk_clk; -static struct clk *mdp_lcdc_pad_pclk_clk; - -int mdp_lcdc_pclk_clk_rate; -int mdp_lcdc_pad_pclk_clk_rate; - -static struct platform_driver lcdc_driver = { - .probe = lcdc_probe, - .remove = lcdc_remove, - .suspend = NULL, - .resume = NULL, - .shutdown = NULL, - .driver = { - .name = "lcdc", - }, -}; - -static struct lcdc_platform_data *lcdc_pdata; - -static int lcdc_off(struct platform_device *pdev) -{ - int ret = 0; - - ret = panel_next_off(pdev); - - clk_disable(mdp_lcdc_pclk_clk); - clk_disable(mdp_lcdc_pad_pclk_clk); - - if (lcdc_pdata && lcdc_pdata->lcdc_power_save) - lcdc_pdata->lcdc_power_save(0); - - if (lcdc_pdata && lcdc_pdata->lcdc_gpio_config) - ret = lcdc_pdata->lcdc_gpio_config(0); - -// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc", -// PM_QOS_DEFAULT_VALUE); - - return ret; -} - -static int lcdc_on(struct platform_device *pdev) -{ - int ret = 0; - struct msm_fb_data_type *mfd; - unsigned long panel_pixclock_freq , pm_qos_freq; - - mfd = platform_get_drvdata(pdev); - panel_pixclock_freq = mfd->fbi->var.pixclock; - - if (panel_pixclock_freq > 58000000) - /* pm_qos_freq should be in Khz */ - pm_qos_freq = panel_pixclock_freq / 1000 ; - else - pm_qos_freq = 58000; - -// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc", -// pm_qos_freq); - mfd = platform_get_drvdata(pdev); - - clk_enable(mdp_lcdc_pclk_clk); - clk_enable(mdp_lcdc_pad_pclk_clk); - - if (lcdc_pdata && lcdc_pdata->lcdc_power_save) - lcdc_pdata->lcdc_power_save(1); - if (lcdc_pdata && lcdc_pdata->lcdc_gpio_config) - ret = lcdc_pdata->lcdc_gpio_config(1); - - clk_set_rate(mdp_lcdc_pclk_clk, mfd->fbi->var.pixclock); - clk_set_rate(mdp_lcdc_pad_pclk_clk, mfd->fbi->var.pixclock); - mdp_lcdc_pclk_clk_rate = clk_get_rate(mdp_lcdc_pclk_clk); - mdp_lcdc_pad_pclk_clk_rate = clk_get_rate(mdp_lcdc_pad_pclk_clk); - - ret = panel_next_on(pdev); - return ret; -} - -static int lcdc_probe(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - struct fb_info *fbi; - struct platform_device *mdp_dev = NULL; - struct msm_fb_panel_data *pdata = NULL; - int rc; - - if (pdev->id == 0) { - lcdc_pdata = pdev->dev.platform_data; - return 0; - } - - mfd = platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST) - return -ENOMEM; - - mdp_dev = platform_device_alloc("mdp", pdev->id); - if (!mdp_dev) - return -ENOMEM; - - /* - * link to the latest pdev - */ - mfd->pdev = mdp_dev; - mfd->dest = DISPLAY_LCDC; - - /* - * alloc panel device data - */ - if (platform_device_add_data - (mdp_dev, pdev->dev.platform_data, - sizeof(struct msm_fb_panel_data))) { - printk(KERN_ERR "lcdc_probe: platform_device_add_data failed!\n"); - platform_device_put(mdp_dev); - return -ENOMEM; - } - /* - * data chain - */ - pdata = (struct msm_fb_panel_data *)mdp_dev->dev.platform_data; - pdata->on = lcdc_on; - pdata->off = lcdc_off; - pdata->next = pdev; - - /* - * get/set panel specific fb info - */ - mfd->panel_info = pdata->panel_info; - mfd->fb_imgType = MDP_RGB_565; - - fbi = mfd->fbi; - fbi->var.pixclock = mfd->panel_info.clk_rate; - fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch; - fbi->var.right_margin = mfd->panel_info.lcdc.h_front_porch; - fbi->var.upper_margin = mfd->panel_info.lcdc.v_back_porch; - fbi->var.lower_margin = mfd->panel_info.lcdc.v_front_porch; - fbi->var.hsync_len = mfd->panel_info.lcdc.h_pulse_width; - fbi->var.vsync_len = mfd->panel_info.lcdc.v_pulse_width; - - /* - * set driver data - */ - platform_set_drvdata(mdp_dev, mfd); - - /* - * register in mdp driver - */ - rc = platform_device_add(mdp_dev); - if (rc) - goto lcdc_probe_err; - - pdev_list[pdev_list_cnt++] = pdev; - return 0; - -lcdc_probe_err: - platform_device_put(mdp_dev); - return rc; -} - -static int lcdc_remove(struct platform_device *pdev) -{ -// pm_qos_remove_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc"); - return 0; -} - -static int lcdc_register_driver(void) -{ - return platform_driver_register(&lcdc_driver); -} - -static int __init lcdc_driver_init(void) -{ - mdp_lcdc_pclk_clk = clk_get(NULL, "mdp_lcdc_pclk_clk"); - if (IS_ERR(mdp_lcdc_pclk_clk)) { - printk(KERN_ERR "error: can't get mdp_lcdc_pclk_clk!\n"); - return PTR_ERR(mdp_lcdc_pclk_clk); - } - mdp_lcdc_pad_pclk_clk = clk_get(NULL, "mdp_lcdc_pad_pclk_clk"); - if (IS_ERR(mdp_lcdc_pad_pclk_clk)) { - printk(KERN_ERR "error: can't get mdp_lcdc_pad_pclk_clk!\n"); - return PTR_ERR(mdp_lcdc_pad_pclk_clk); - } -// pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc", -// PM_QOS_DEFAULT_VALUE); - return lcdc_register_driver(); -} - -module_init(lcdc_driver_init); diff --git a/drivers/staging/msm/lcdc_external.c b/drivers/staging/msm/lcdc_external.c deleted file mode 100644 index 45ff78527111..000000000000 --- a/drivers/staging/msm/lcdc_external.c +++ /dev/null @@ -1,54 +0,0 @@ -/* 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "msm_fb.h" - -static int __init lcdc_external_init(void) -{ - int ret; - struct msm_panel_info pinfo; - - if (msm_fb_detect_client("lcdc_external")) - return 0; - - pinfo.xres = 1280; - pinfo.yres = 720; - pinfo.type = LCDC_PANEL; - pinfo.pdest = DISPLAY_1; - pinfo.wait_cycle = 0; - pinfo.bpp = 24; - pinfo.fb_num = 2; - pinfo.clk_rate = 74250000; - - pinfo.lcdc.h_back_porch = 124; - pinfo.lcdc.h_front_porch = 110; - pinfo.lcdc.h_pulse_width = 136; - pinfo.lcdc.v_back_porch = 19; - pinfo.lcdc.v_front_porch = 5; - pinfo.lcdc.v_pulse_width = 6; - pinfo.lcdc.border_clr = 0; /* blk */ - pinfo.lcdc.underflow_clr = 0xff; /* blue */ - pinfo.lcdc.hsync_skew = 0; - - ret = lcdc_device_register(&pinfo); - if (ret) - printk(KERN_ERR "%s: failed to register device!\n", __func__); - - return ret; -} - -module_init(lcdc_external_init); diff --git a/drivers/staging/msm/lcdc_gordon.c b/drivers/staging/msm/lcdc_gordon.c deleted file mode 100644 index 399ec8c791ec..000000000000 --- a/drivers/staging/msm/lcdc_gordon.c +++ /dev/null @@ -1,446 +0,0 @@ -/* 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include "msm_fb.h" - -/* registers */ -#define GORDON_REG_NOP 0x00 -#define GORDON_REG_IMGCTL1 0x10 -#define GORDON_REG_IMGCTL2 0x11 -#define GORDON_REG_IMGSET1 0x12 -#define GORDON_REG_IMGSET2 0x13 -#define GORDON_REG_IVBP1 0x14 -#define GORDON_REG_IHBP1 0x15 -#define GORDON_REG_IVNUM1 0x16 -#define GORDON_REG_IHNUM1 0x17 -#define GORDON_REG_IVBP2 0x18 -#define GORDON_REG_IHBP2 0x19 -#define GORDON_REG_IVNUM2 0x1A -#define GORDON_REG_IHNUM2 0x1B -#define GORDON_REG_LCDIFCTL1 0x30 -#define GORDON_REG_VALTRAN 0x31 -#define GORDON_REG_AVCTL 0x33 -#define GORDON_REG_LCDIFCTL2 0x34 -#define GORDON_REG_LCDIFCTL3 0x35 -#define GORDON_REG_LCDIFSET1 0x36 -#define GORDON_REG_PCCTL 0x3C -#define GORDON_REG_TPARAM1 0x40 -#define GORDON_REG_TLCDIF1 0x41 -#define GORDON_REG_TSSPB_ST1 0x42 -#define GORDON_REG_TSSPB_ED1 0x43 -#define GORDON_REG_TSCK_ST1 0x44 -#define GORDON_REG_TSCK_WD1 0x45 -#define GORDON_REG_TGSPB_VST1 0x46 -#define GORDON_REG_TGSPB_VED1 0x47 -#define GORDON_REG_TGSPB_CH1 0x48 -#define GORDON_REG_TGCK_ST1 0x49 -#define GORDON_REG_TGCK_ED1 0x4A -#define GORDON_REG_TPCTL_ST1 0x4B -#define GORDON_REG_TPCTL_ED1 0x4C -#define GORDON_REG_TPCHG_ED1 0x4D -#define GORDON_REG_TCOM_CH1 0x4E -#define GORDON_REG_THBP1 0x4F -#define GORDON_REG_TPHCTL1 0x50 -#define GORDON_REG_EVPH1 0x51 -#define GORDON_REG_EVPL1 0x52 -#define GORDON_REG_EVNH1 0x53 -#define GORDON_REG_EVNL1 0x54 -#define GORDON_REG_TBIAS1 0x55 -#define GORDON_REG_TPARAM2 0x56 -#define GORDON_REG_TLCDIF2 0x57 -#define GORDON_REG_TSSPB_ST2 0x58 -#define GORDON_REG_TSSPB_ED2 0x59 -#define GORDON_REG_TSCK_ST2 0x5A -#define GORDON_REG_TSCK_WD2 0x5B -#define GORDON_REG_TGSPB_VST2 0x5C -#define GORDON_REG_TGSPB_VED2 0x5D -#define GORDON_REG_TGSPB_CH2 0x5E -#define GORDON_REG_TGCK_ST2 0x5F -#define GORDON_REG_TGCK_ED2 0x60 -#define GORDON_REG_TPCTL_ST2 0x61 -#define GORDON_REG_TPCTL_ED2 0x62 -#define GORDON_REG_TPCHG_ED2 0x63 -#define GORDON_REG_TCOM_CH2 0x64 -#define GORDON_REG_THBP2 0x65 -#define GORDON_REG_TPHCTL2 0x66 -#define GORDON_REG_POWCTL 0x80 - -static int lcdc_gordon_panel_off(struct platform_device *pdev); - -static int spi_cs; -static int spi_sclk; -static int spi_sdo; -static int spi_sdi; -static int spi_dac; -static unsigned char bit_shift[8] = { (1 << 7), /* MSB */ - (1 << 6), - (1 << 5), - (1 << 4), - (1 << 3), - (1 << 2), - (1 << 1), - (1 << 0) /* LSB */ -}; - -struct gordon_state_type{ - boolean disp_initialized; - boolean display_on; - boolean disp_powered_up; -}; - -static struct gordon_state_type gordon_state = { 0 }; -static struct msm_panel_common_pdata *lcdc_gordon_pdata; - -static void serigo(uint16 reg, uint8 data) -{ - unsigned int tx_val = ((0x00FF & reg) << 8) | data; - unsigned char i, val = 0; - - /* Enable the Chip Select */ - gpio_set_value(spi_cs, 1); - udelay(33); - - /* Transmit it in two parts, Higher Byte first, then Lower Byte */ - val = (unsigned char)((tx_val & 0xFF00) >> 8); - - /* Clock should be Low before entering ! */ - for (i = 0; i < 8; i++) { - /* #1: Drive the Data (High or Low) */ - if (val & bit_shift[i]) - gpio_set_value(spi_sdi, 1); - else - gpio_set_value(spi_sdi, 0); - - /* #2: Drive the Clk High and then Low */ - udelay(33); - gpio_set_value(spi_sclk, 1); - udelay(33); - gpio_set_value(spi_sclk, 0); - } - - /* Idle state of SDO (MOSI) is Low */ - gpio_set_value(spi_sdi, 0); - /* ..then Lower Byte */ - val = (uint8) (tx_val & 0x00FF); - /* Before we enter here the Clock should be Low ! */ - - for (i = 0; i < 8; i++) { - /* #1: Drive the Data (High or Low) */ - if (val & bit_shift[i]) - gpio_set_value(spi_sdi, 1); - else - gpio_set_value(spi_sdi, 0); - - /* #2: Drive the Clk High and then Low */ - udelay(33); - - gpio_set_value(spi_sclk, 1); - udelay(33); - gpio_set_value(spi_sclk, 0); - } - - /* Idle state of SDO (MOSI) is Low */ - gpio_set_value(spi_sdi, 0); - - /* Now Disable the Chip Select */ - udelay(33); - gpio_set_value(spi_cs, 0); -} - -static void spi_init(void) -{ - /* Setting the Default GPIO's */ - spi_sclk = *(lcdc_gordon_pdata->gpio_num); - spi_cs = *(lcdc_gordon_pdata->gpio_num + 1); - spi_sdi = *(lcdc_gordon_pdata->gpio_num + 2); - spi_sdo = *(lcdc_gordon_pdata->gpio_num + 3); - - /* Set the output so that we dont disturb the slave device */ - gpio_set_value(spi_sclk, 0); - gpio_set_value(spi_sdi, 0); - - /* Set the Chip Select De-asserted */ - gpio_set_value(spi_cs, 0); - -} - -static void gordon_disp_powerup(void) -{ - if (!gordon_state.disp_powered_up && !gordon_state.display_on) { - /* Reset the hardware first */ - /* Include DAC power up implementation here */ - gordon_state.disp_powered_up = TRUE; - } -} - -static void gordon_init(void) -{ - /* Image interface settings */ - serigo(GORDON_REG_IMGCTL2, 0x00); - serigo(GORDON_REG_IMGSET1, 0x00); - - /* Exchange the RGB signal for J510(Softbank mobile) */ - serigo(GORDON_REG_IMGSET2, 0x12); - serigo(GORDON_REG_LCDIFSET1, 0x00); - - /* Pre-charge settings */ - serigo(GORDON_REG_PCCTL, 0x09); - serigo(GORDON_REG_LCDIFCTL2, 0x7B); - - mdelay(1); -} - -static void gordon_disp_on(void) -{ - if (gordon_state.disp_powered_up && !gordon_state.display_on) { - gordon_init(); - mdelay(20); - /* gordon_dispmode setting */ - serigo(GORDON_REG_TPARAM1, 0x30); - serigo(GORDON_REG_TLCDIF1, 0x00); - serigo(GORDON_REG_TSSPB_ST1, 0x8B); - serigo(GORDON_REG_TSSPB_ED1, 0x93); - serigo(GORDON_REG_TSCK_ST1, 0x88); - serigo(GORDON_REG_TSCK_WD1, 0x00); - serigo(GORDON_REG_TGSPB_VST1, 0x01); - serigo(GORDON_REG_TGSPB_VED1, 0x02); - serigo(GORDON_REG_TGSPB_CH1, 0x5E); - serigo(GORDON_REG_TGCK_ST1, 0x80); - serigo(GORDON_REG_TGCK_ED1, 0x3C); - serigo(GORDON_REG_TPCTL_ST1, 0x50); - serigo(GORDON_REG_TPCTL_ED1, 0x74); - serigo(GORDON_REG_TPCHG_ED1, 0x78); - serigo(GORDON_REG_TCOM_CH1, 0x50); - serigo(GORDON_REG_THBP1, 0x84); - serigo(GORDON_REG_TPHCTL1, 0x00); - serigo(GORDON_REG_EVPH1, 0x70); - serigo(GORDON_REG_EVPL1, 0x64); - serigo(GORDON_REG_EVNH1, 0x56); - serigo(GORDON_REG_EVNL1, 0x48); - serigo(GORDON_REG_TBIAS1, 0x88); - - /* QVGA settings */ - serigo(GORDON_REG_TPARAM2, 0x28); - serigo(GORDON_REG_TLCDIF2, 0x14); - serigo(GORDON_REG_TSSPB_ST2, 0x49); - serigo(GORDON_REG_TSSPB_ED2, 0x4B); - serigo(GORDON_REG_TSCK_ST2, 0x4A); - serigo(GORDON_REG_TSCK_WD2, 0x02); - serigo(GORDON_REG_TGSPB_VST2, 0x02); - serigo(GORDON_REG_TGSPB_VED2, 0x03); - serigo(GORDON_REG_TGSPB_CH2, 0x2F); - serigo(GORDON_REG_TGCK_ST2, 0x40); - serigo(GORDON_REG_TGCK_ED2, 0x1E); - serigo(GORDON_REG_TPCTL_ST2, 0x2C); - serigo(GORDON_REG_TPCTL_ED2, 0x3A); - serigo(GORDON_REG_TPCHG_ED2, 0x3C); - serigo(GORDON_REG_TCOM_CH2, 0x28); - serigo(GORDON_REG_THBP2, 0x4D); - serigo(GORDON_REG_TPHCTL2, 0x1A); - - /* VGA settings */ - serigo(GORDON_REG_IVBP1, 0x02); - serigo(GORDON_REG_IHBP1, 0x90); - serigo(GORDON_REG_IVNUM1, 0xA0); - serigo(GORDON_REG_IHNUM1, 0x78); - - /* QVGA settings */ - serigo(GORDON_REG_IVBP2, 0x02); - serigo(GORDON_REG_IHBP2, 0x48); - serigo(GORDON_REG_IVNUM2, 0x50); - serigo(GORDON_REG_IHNUM2, 0x3C); - - /* Gordon Charge pump settings and ON */ - serigo(GORDON_REG_POWCTL, 0x03); - mdelay(15); - serigo(GORDON_REG_POWCTL, 0x07); - mdelay(15); - - serigo(GORDON_REG_POWCTL, 0x0F); - mdelay(15); - - serigo(GORDON_REG_AVCTL, 0x03); - mdelay(15); - - serigo(GORDON_REG_POWCTL, 0x1F); - mdelay(15); - - serigo(GORDON_REG_POWCTL, 0x5F); - mdelay(15); - - serigo(GORDON_REG_POWCTL, 0x7F); - mdelay(15); - - serigo(GORDON_REG_LCDIFCTL1, 0x02); - mdelay(15); - - serigo(GORDON_REG_IMGCTL1, 0x00); - mdelay(15); - - serigo(GORDON_REG_LCDIFCTL3, 0x00); - mdelay(15); - - serigo(GORDON_REG_VALTRAN, 0x01); - mdelay(15); - - serigo(GORDON_REG_LCDIFCTL1, 0x03); - mdelay(1); - gordon_state.display_on = TRUE; - } -} - -static int lcdc_gordon_panel_on(struct platform_device *pdev) -{ - if (!gordon_state.disp_initialized) { - /* Configure reset GPIO that drives DAC */ - lcdc_gordon_pdata->panel_config_gpio(1); - spi_dac = *(lcdc_gordon_pdata->gpio_num + 4); - gpio_set_value(spi_dac, 0); - udelay(15); - gpio_set_value(spi_dac, 1); - spi_init(); /* LCD needs SPI */ - gordon_disp_powerup(); - gordon_disp_on(); - gordon_state.disp_initialized = TRUE; - } - return 0; -} - -static int lcdc_gordon_panel_off(struct platform_device *pdev) -{ - if (gordon_state.disp_powered_up && gordon_state.display_on) { - serigo(GORDON_REG_LCDIFCTL2, 0x7B); - serigo(GORDON_REG_VALTRAN, 0x01); - serigo(GORDON_REG_LCDIFCTL1, 0x02); - serigo(GORDON_REG_LCDIFCTL3, 0x01); - mdelay(20); - serigo(GORDON_REG_VALTRAN, 0x01); - serigo(GORDON_REG_IMGCTL1, 0x01); - serigo(GORDON_REG_LCDIFCTL1, 0x00); - mdelay(20); - - serigo(GORDON_REG_POWCTL, 0x1F); - mdelay(40); - - serigo(GORDON_REG_POWCTL, 0x07); - mdelay(40); - - serigo(GORDON_REG_POWCTL, 0x03); - mdelay(40); - - serigo(GORDON_REG_POWCTL, 0x00); - mdelay(40); - lcdc_gordon_pdata->panel_config_gpio(0); - gordon_state.display_on = FALSE; - gordon_state.disp_initialized = FALSE; - } - return 0; -} - -static void lcdc_gordon_set_backlight(struct msm_fb_data_type *mfd) -{ - int bl_level = mfd->bl_level; - - if (bl_level <= 1) { - /* keep back light OFF */ - serigo(GORDON_REG_LCDIFCTL2, 0x0B); - udelay(15); - serigo(GORDON_REG_VALTRAN, 0x01); - } else { - /* keep back light ON */ - serigo(GORDON_REG_LCDIFCTL2, 0x7B); - udelay(15); - serigo(GORDON_REG_VALTRAN, 0x01); - } -} - -static int __init gordon_probe(struct platform_device *pdev) -{ - if (pdev->id == 0) { - lcdc_gordon_pdata = pdev->dev.platform_data; - return 0; - } - msm_fb_add_device(pdev); - return 0; -} - -static struct platform_driver this_driver = { - .probe = gordon_probe, - .driver = { - .name = "lcdc_gordon_vga", - }, -}; - -static struct msm_fb_panel_data gordon_panel_data = { - .on = lcdc_gordon_panel_on, - .off = lcdc_gordon_panel_off, - .set_backlight = lcdc_gordon_set_backlight, -}; - -static struct platform_device this_device = { - .name = "lcdc_gordon_vga", - .id = 1, - .dev = { - .platform_data = &gordon_panel_data, - } -}; - -static int __init lcdc_gordon_panel_init(void) -{ - int ret; - struct msm_panel_info *pinfo; - -#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM - if (msm_fb_detect_client("lcdc_gordon_vga")) - return 0; -#endif - ret = platform_driver_register(&this_driver); - if (ret) - return ret; - - pinfo = &gordon_panel_data.panel_info; - pinfo->xres = 480; - pinfo->yres = 640; - pinfo->type = LCDC_PANEL; - pinfo->pdest = DISPLAY_1; - pinfo->wait_cycle = 0; - pinfo->bpp = 24; - pinfo->fb_num = 2; - pinfo->clk_rate = 24500000; - pinfo->bl_max = 4; - pinfo->bl_min = 1; - - pinfo->lcdc.h_back_porch = 84; - pinfo->lcdc.h_front_porch = 33; - pinfo->lcdc.h_pulse_width = 60; - pinfo->lcdc.v_back_porch = 0; - pinfo->lcdc.v_front_porch = 2; - pinfo->lcdc.v_pulse_width = 2; - pinfo->lcdc.border_clr = 0; /* blk */ - pinfo->lcdc.underflow_clr = 0xff; /* blue */ - pinfo->lcdc.hsync_skew = 0; - - ret = platform_device_register(&this_device); - if (ret) - platform_driver_unregister(&this_driver); - - return ret; -} - -module_init(lcdc_gordon_panel_init); diff --git a/drivers/staging/msm/lcdc_panel.c b/drivers/staging/msm/lcdc_panel.c deleted file mode 100644 index b40974e1f27c..000000000000 --- a/drivers/staging/msm/lcdc_panel.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "msm_fb.h" - -static int lcdc_panel_on(struct platform_device *pdev) -{ - return 0; -} - -static int lcdc_panel_off(struct platform_device *pdev) -{ - return 0; -} - -static int __init lcdc_panel_probe(struct platform_device *pdev) -{ - msm_fb_add_device(pdev); - - return 0; -} - -static struct platform_driver this_driver = { - .probe = lcdc_panel_probe, - .driver = { - .name = "lcdc_panel", - }, -}; - -static struct msm_fb_panel_data lcdc_panel_data = { - .on = lcdc_panel_on, - .off = lcdc_panel_off, -}; - -static int lcdc_dev_id; - -int lcdc_device_register(struct msm_panel_info *pinfo) -{ - struct platform_device *pdev = NULL; - int ret; - - pdev = platform_device_alloc("lcdc_panel", ++lcdc_dev_id); - if (!pdev) - return -ENOMEM; - - lcdc_panel_data.panel_info = *pinfo; - ret = platform_device_add_data(pdev, &lcdc_panel_data, - sizeof(lcdc_panel_data)); - if (ret) { - printk(KERN_ERR - "%s: platform_device_add_data failed!\n", __func__); - goto err_device_put; - } - - ret = platform_device_add(pdev); - if (ret) { - printk(KERN_ERR - "%s: platform_device_register failed!\n", __func__); - goto err_device_put; - } - - return 0; - -err_device_put: - platform_device_put(pdev); - return ret; -} - -static int __init lcdc_panel_init(void) -{ - return platform_driver_register(&this_driver); -} - -module_init(lcdc_panel_init); diff --git a/drivers/staging/msm/lcdc_prism.c b/drivers/staging/msm/lcdc_prism.c deleted file mode 100644 index d102c98447c1..000000000000 --- a/drivers/staging/msm/lcdc_prism.c +++ /dev/null @@ -1,64 +0,0 @@ -/* 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "msm_fb.h" - -#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM -#include "mddihosti.h" -#endif - -static int __init lcdc_prism_init(void) -{ - int ret; - struct msm_panel_info pinfo; - -#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM - ret = msm_fb_detect_client("lcdc_prism_wvga"); - if (ret == -ENODEV) - return 0; - - if (ret && (mddi_get_client_id() != 0)) - return 0; -#endif - - pinfo.xres = 800; - pinfo.yres = 480; - pinfo.type = LCDC_PANEL; - pinfo.pdest = DISPLAY_1; - pinfo.wait_cycle = 0; - pinfo.bpp = 24; - pinfo.fb_num = 2; - pinfo.clk_rate = 38460000; - - pinfo.lcdc.h_back_porch = 21; - pinfo.lcdc.h_front_porch = 81; - pinfo.lcdc.h_pulse_width = 60; - pinfo.lcdc.v_back_porch = 18; - pinfo.lcdc.v_front_porch = 27; - pinfo.lcdc.v_pulse_width = 2; - pinfo.lcdc.border_clr = 0; /* blk */ - pinfo.lcdc.underflow_clr = 0xff; /* blue */ - pinfo.lcdc.hsync_skew = 0; - - ret = lcdc_device_register(&pinfo); - if (ret) - printk(KERN_ERR "%s: failed to register device!\n", __func__); - - return ret; -} - -module_init(lcdc_prism_init); diff --git a/drivers/staging/msm/lcdc_sharp_wvga_pt.c b/drivers/staging/msm/lcdc_sharp_wvga_pt.c deleted file mode 100644 index 1f08cf9bc217..000000000000 --- a/drivers/staging/msm/lcdc_sharp_wvga_pt.c +++ /dev/null @@ -1,290 +0,0 @@ -/* 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#ifdef CONFIG_ARCH_MSM7X30 -#include -#endif -#include -#include "msm_fb.h" - -static int lcdc_sharp_panel_off(struct platform_device *pdev); - -static int spi_cs; -static int spi_sclk; -static int spi_mosi; -static int spi_miso; -static unsigned char bit_shift[8] = { (1 << 7), /* MSB */ - (1 << 6), - (1 << 5), - (1 << 4), - (1 << 3), - (1 << 2), - (1 << 1), - (1 << 0) /* LSB */ -}; - -struct sharp_state_type { - boolean disp_initialized; - boolean display_on; - boolean disp_powered_up; -}; - -struct sharp_spi_data { - u8 addr; - u8 data; -}; - -static struct sharp_spi_data init_sequence[] = { - { 15, 0x01 }, - { 5, 0x01 }, - { 7, 0x10 }, - { 9, 0x1E }, - { 10, 0x04 }, - { 17, 0xFF }, - { 21, 0x8A }, - { 22, 0x00 }, - { 23, 0x82 }, - { 24, 0x24 }, - { 25, 0x22 }, - { 26, 0x6D }, - { 27, 0xEB }, - { 28, 0xB9 }, - { 29, 0x3A }, - { 49, 0x1A }, - { 50, 0x16 }, - { 51, 0x05 }, - { 55, 0x7F }, - { 56, 0x15 }, - { 57, 0x7B }, - { 60, 0x05 }, - { 61, 0x0C }, - { 62, 0x80 }, - { 63, 0x00 }, - { 92, 0x90 }, - { 97, 0x01 }, - { 98, 0xFF }, - { 113, 0x11 }, - { 114, 0x02 }, - { 115, 0x08 }, - { 123, 0xAB }, - { 124, 0x04 }, - { 6, 0x02 }, - { 133, 0x00 }, - { 134, 0xFE }, - { 135, 0x22 }, - { 136, 0x0B }, - { 137, 0xFF }, - { 138, 0x0F }, - { 139, 0x00 }, - { 140, 0xFE }, - { 141, 0x22 }, - { 142, 0x0B }, - { 143, 0xFF }, - { 144, 0x0F }, - { 145, 0x00 }, - { 146, 0xFE }, - { 147, 0x22 }, - { 148, 0x0B }, - { 149, 0xFF }, - { 150, 0x0F }, - { 202, 0x30 }, - { 30, 0x01 }, - { 4, 0x01 }, - { 31, 0x41 }, -}; - -static struct sharp_state_type sharp_state = { 0 }; -static struct msm_panel_common_pdata *lcdc_sharp_pdata; - -static void sharp_spi_write_byte(u8 val) -{ - int i; - - /* Clock should be Low before entering */ - for (i = 0; i < 8; i++) { - /* #1: Drive the Data (High or Low) */ - if (val & bit_shift[i]) - gpio_set_value(spi_mosi, 1); - else - gpio_set_value(spi_mosi, 0); - - /* #2: Drive the Clk High and then Low */ - gpio_set_value(spi_sclk, 1); - gpio_set_value(spi_sclk, 0); - } -} - -static void serigo(u8 reg, u8 data) -{ - /* Enable the Chip Select - low */ - gpio_set_value(spi_cs, 0); - udelay(1); - - /* Transmit register address first, then data */ - sharp_spi_write_byte(reg); - - /* Idle state of MOSI is Low */ - gpio_set_value(spi_mosi, 0); - udelay(1); - sharp_spi_write_byte(data); - - gpio_set_value(spi_mosi, 0); - gpio_set_value(spi_cs, 1); -} - -static void sharp_spi_init(void) -{ - spi_sclk = *(lcdc_sharp_pdata->gpio_num); - spi_cs = *(lcdc_sharp_pdata->gpio_num + 1); - spi_mosi = *(lcdc_sharp_pdata->gpio_num + 2); - spi_miso = *(lcdc_sharp_pdata->gpio_num + 3); - - /* Set the output so that we don't disturb the slave device */ - gpio_set_value(spi_sclk, 0); - gpio_set_value(spi_mosi, 0); - - /* Set the Chip Select deasserted (active low) */ - gpio_set_value(spi_cs, 1); -} - -static void sharp_disp_powerup(void) -{ - if (!sharp_state.disp_powered_up && !sharp_state.display_on) - sharp_state.disp_powered_up = TRUE; -} - -static void sharp_disp_on(void) -{ - int i; - - if (sharp_state.disp_powered_up && !sharp_state.display_on) { - for (i = 0; i < ARRAY_SIZE(init_sequence); i++) { - serigo(init_sequence[i].addr, - init_sequence[i].data); - } - mdelay(10); - serigo(31, 0xC1); - mdelay(10); - serigo(31, 0xD9); - serigo(31, 0xDF); - - sharp_state.display_on = TRUE; - } -} - -static int lcdc_sharp_panel_on(struct platform_device *pdev) -{ - if (!sharp_state.disp_initialized) { - lcdc_sharp_pdata->panel_config_gpio(1); - sharp_spi_init(); - sharp_disp_powerup(); - sharp_disp_on(); - sharp_state.disp_initialized = TRUE; - } - return 0; -} - -static int lcdc_sharp_panel_off(struct platform_device *pdev) -{ - if (sharp_state.disp_powered_up && sharp_state.display_on) { - serigo(4, 0x00); - mdelay(40); - serigo(31, 0xC1); - mdelay(40); - serigo(31, 0x00); - mdelay(100); - sharp_state.display_on = FALSE; - sharp_state.disp_initialized = FALSE; - } - return 0; -} - -static int __init sharp_probe(struct platform_device *pdev) -{ - if (pdev->id == 0) { - lcdc_sharp_pdata = pdev->dev.platform_data; - return 0; - } - msm_fb_add_device(pdev); - return 0; -} - -static struct platform_driver this_driver = { - .probe = sharp_probe, - .driver = { - .name = "lcdc_sharp_wvga", - }, -}; - -static struct msm_fb_panel_data sharp_panel_data = { - .on = lcdc_sharp_panel_on, - .off = lcdc_sharp_panel_off, -}; - -static struct platform_device this_device = { - .name = "lcdc_sharp_wvga", - .id = 1, - .dev = { - .platform_data = &sharp_panel_data, - } -}; - -static int __init lcdc_sharp_panel_init(void) -{ - int ret; - struct msm_panel_info *pinfo; - -#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT - if (msm_fb_detect_client("lcdc_sharp_wvga_pt")) - return 0; -#endif - - ret = platform_driver_register(&this_driver); - if (ret) - return ret; - - pinfo = &sharp_panel_data.panel_info; - pinfo->xres = 480; - pinfo->yres = 800; - pinfo->type = LCDC_PANEL; - pinfo->pdest = DISPLAY_1; - pinfo->wait_cycle = 0; - pinfo->bpp = 18; - pinfo->fb_num = 2; - pinfo->clk_rate = 24500000; - pinfo->bl_max = 4; - pinfo->bl_min = 1; - - pinfo->lcdc.h_back_porch = 20; - pinfo->lcdc.h_front_porch = 10; - pinfo->lcdc.h_pulse_width = 10; - pinfo->lcdc.v_back_porch = 2; - pinfo->lcdc.v_front_porch = 2; - pinfo->lcdc.v_pulse_width = 2; - pinfo->lcdc.border_clr = 0; - pinfo->lcdc.underflow_clr = 0xff; - pinfo->lcdc.hsync_skew = 0; - - ret = platform_device_register(&this_device); - if (ret) - platform_driver_unregister(&this_driver); - - return ret; -} - -module_init(lcdc_sharp_panel_init); diff --git a/drivers/staging/msm/lcdc_st15.c b/drivers/staging/msm/lcdc_st15.c deleted file mode 100644 index fed8278eb153..000000000000 --- a/drivers/staging/msm/lcdc_st15.c +++ /dev/null @@ -1,237 +0,0 @@ -/* Copyright (c) 2010, 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include "msm_fb.h" - -#define DEVICE_NAME "sii9022" -#define SII9022_DEVICE_ID 0xB0 - -struct sii9022_i2c_addr_data{ - u8 addr; - u8 data; -}; - -/* video mode data */ -static u8 video_mode_data[] = { - 0x00, - 0xF9, 0x1C, 0x70, 0x17, 0x72, 0x06, 0xEE, 0x02, -}; - -static u8 avi_io_format[] = { - 0x09, - 0x00, 0x00, -}; - -/* power state */ -static struct sii9022_i2c_addr_data regset0[] = { - { 0x60, 0x04 }, - { 0x63, 0x00 }, - { 0x1E, 0x00 }, -}; - -static u8 video_infoframe[] = { - 0x0C, - 0xF0, 0x00, 0x68, 0x00, 0x04, 0x00, 0x19, 0x00, - 0xE9, 0x02, 0x04, 0x01, 0x04, 0x06, -}; - -/* configure audio */ -static struct sii9022_i2c_addr_data regset1[] = { - { 0x26, 0x90 }, - { 0x20, 0x90 }, - { 0x1F, 0x80 }, - { 0x26, 0x80 }, - { 0x24, 0x02 }, - { 0x25, 0x0B }, - { 0xBC, 0x02 }, - { 0xBD, 0x24 }, - { 0xBE, 0x02 }, -}; - -/* enable audio */ -static u8 misc_infoframe[] = { - 0xBF, - 0xC2, 0x84, 0x01, 0x0A, 0x6F, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -/* set HDMI, active */ -static struct sii9022_i2c_addr_data regset2[] = { - { 0x1A, 0x01 }, - { 0x3D, 0x00 }, -}; - -static int send_i2c_data(struct i2c_client *client, - struct sii9022_i2c_addr_data *regset, - int size) -{ - int i; - int rc = 0; - - for (i = 0; i < size; i++) { - rc = i2c_smbus_write_byte_data( - client, - regset[i].addr, regset[i].data); - if (rc) - break; - } - return rc; -} - -static int hdmi_sii_enable(struct i2c_client *client) -{ - int rc; - int retries = 10; - int count; - - rc = i2c_smbus_write_byte_data(client, 0xC7, 0x00); - if (rc) - goto enable_exit; - - do { - msleep(1); - rc = i2c_smbus_read_byte_data(client, 0x1B); - } while ((rc != SII9022_DEVICE_ID) && retries--); - - if (rc != SII9022_DEVICE_ID) - return -ENODEV; - - rc = i2c_smbus_write_byte_data(client, 0x1A, 0x11); - if (rc) - goto enable_exit; - - count = ARRAY_SIZE(video_mode_data); - rc = i2c_master_send(client, video_mode_data, count); - if (rc != count) { - rc = -EIO; - goto enable_exit; - } - - rc = i2c_smbus_write_byte_data(client, 0x08, 0x20); - if (rc) - goto enable_exit; - count = ARRAY_SIZE(avi_io_format); - rc = i2c_master_send(client, avi_io_format, count); - if (rc != count) { - rc = -EIO; - goto enable_exit; - } - - rc = send_i2c_data(client, regset0, ARRAY_SIZE(regset0)); - if (rc) - goto enable_exit; - - count = ARRAY_SIZE(video_infoframe); - rc = i2c_master_send(client, video_infoframe, count); - if (rc != count) { - rc = -EIO; - goto enable_exit; - } - - rc = send_i2c_data(client, regset1, ARRAY_SIZE(regset1)); - if (rc) - goto enable_exit; - - count = ARRAY_SIZE(misc_infoframe); - rc = i2c_master_send(client, misc_infoframe, count); - if (rc != count) { - rc = -EIO; - goto enable_exit; - } - - rc = send_i2c_data(client, regset2, ARRAY_SIZE(regset2)); - if (rc) - goto enable_exit; - - return 0; -enable_exit: - printk(KERN_ERR "%s: exited rc=%d\n", __func__, rc); - return rc; -} - -static const struct i2c_device_id hmdi_sii_id[] = { - { DEVICE_NAME, 0 }, - { } -}; - -static int hdmi_sii_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int rc; - - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C)) - return -ENODEV; - rc = hdmi_sii_enable(client); - return rc; -} - - -static struct i2c_driver hdmi_sii_i2c_driver = { - .driver = { - .name = DEVICE_NAME, - .owner = THIS_MODULE, - }, - .probe = hdmi_sii_probe, - .remove = __exit_p(hdmi_sii_remove), - .id_table = hmdi_sii_id, -}; - -static int __init lcdc_st15_init(void) -{ - int ret; - struct msm_panel_info pinfo; - - if (msm_fb_detect_client("lcdc_st15")) - return 0; - - pinfo.xres = 1366; - pinfo.yres = 768; - pinfo.type = LCDC_PANEL; - pinfo.pdest = DISPLAY_1; - pinfo.wait_cycle = 0; - pinfo.bpp = 24; - pinfo.fb_num = 2; - pinfo.clk_rate = 74250000; - - pinfo.lcdc.h_back_porch = 120; - pinfo.lcdc.h_front_porch = 20; - pinfo.lcdc.h_pulse_width = 40; - pinfo.lcdc.v_back_porch = 25; - pinfo.lcdc.v_front_porch = 1; - pinfo.lcdc.v_pulse_width = 7; - pinfo.lcdc.border_clr = 0; /* blk */ - pinfo.lcdc.underflow_clr = 0xff; /* blue */ - pinfo.lcdc.hsync_skew = 0; - - ret = lcdc_device_register(&pinfo); - if (ret) { - printk(KERN_ERR "%s: failed to register device!\n", __func__); - goto init_exit; - } - - ret = i2c_add_driver(&hdmi_sii_i2c_driver); - if (ret) - printk(KERN_ERR "%s: failed to add i2c driver\n", __func__); - -init_exit: - return ret; -} - -module_init(lcdc_st15_init); diff --git a/drivers/staging/msm/lcdc_toshiba_wvga_pt.c b/drivers/staging/msm/lcdc_toshiba_wvga_pt.c deleted file mode 100644 index edba78a3afcf..000000000000 --- a/drivers/staging/msm/lcdc_toshiba_wvga_pt.c +++ /dev/null @@ -1,374 +0,0 @@ -/* 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include "msm_fb.h" - -#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM -#include "mddihosti.h" -#endif - -static int spi_cs; -static int spi_sclk; -static int spi_mosi; -static int spi_miso; - -struct toshiba_state_type{ - boolean disp_initialized; - boolean display_on; - boolean disp_powered_up; -}; - -static struct toshiba_state_type toshiba_state = { 0 }; -static struct msm_panel_common_pdata *lcdc_toshiba_pdata; - -static void toshiba_spi_write_byte(char dc, uint8 data) -{ - uint32 bit; - int bnum; - - gpio_set_value(spi_sclk, 0); /* clk low */ - /* dc: 0 for command, 1 for parameter */ - gpio_set_value(spi_mosi, dc); - udelay(1); /* at least 20 ns */ - gpio_set_value(spi_sclk, 1); /* clk high */ - udelay(1); /* at least 20 ns */ - bnum = 8; /* 8 data bits */ - bit = 0x80; - while (bnum) { - gpio_set_value(spi_sclk, 0); /* clk low */ - if (data & bit) - gpio_set_value(spi_mosi, 1); - else - gpio_set_value(spi_mosi, 0); - udelay(1); - gpio_set_value(spi_sclk, 1); /* clk high */ - udelay(1); - bit >>= 1; - bnum--; - } -} - -static void toshiba_spi_write(char cmd, uint32 data, int num) -{ - char *bp; - - gpio_set_value(spi_cs, 1); /* cs high */ - - /* command byte first */ - toshiba_spi_write_byte(0, cmd); - - /* followed by parameter bytes */ - if (num) { - bp = (char *)&data; - bp += (num - 1); - while (num) { - toshiba_spi_write_byte(1, *bp); - num--; - bp--; - } - } - - gpio_set_value(spi_cs, 0); /* cs low */ - udelay(1); -} - -void toshiba_spi_read_bytes(char cmd, uint32 *data, int num) -{ - uint32 dbit, bits; - int bnum; - - gpio_set_value(spi_cs, 1); /* cs high */ - - /* command byte first */ - toshiba_spi_write_byte(0, cmd); - - if (num > 1) { - /* extra dc bit */ - gpio_set_value(spi_sclk, 0); /* clk low */ - udelay(1); - dbit = gpio_get_value(spi_miso);/* dc bit */ - udelay(1); - gpio_set_value(spi_sclk, 1); /* clk high */ - } - - /* followed by data bytes */ - bnum = num * 8; /* number of bits */ - bits = 0; - while (bnum) { - bits <<= 1; - gpio_set_value(spi_sclk, 0); /* clk low */ - udelay(1); - dbit = gpio_get_value(spi_miso); - udelay(1); - gpio_set_value(spi_sclk, 1); /* clk high */ - bits |= dbit; - bnum--; - } - - *data = bits; - - udelay(1); - gpio_set_value(spi_cs, 0); /* cs low */ - udelay(1); -} - -static void spi_pin_assign(void) -{ - /* Setting the Default GPIO's */ - spi_sclk = *(lcdc_toshiba_pdata->gpio_num); - spi_cs = *(lcdc_toshiba_pdata->gpio_num + 1); - spi_mosi = *(lcdc_toshiba_pdata->gpio_num + 2); - spi_miso = *(lcdc_toshiba_pdata->gpio_num + 3); -} - -static void toshiba_disp_powerup(void) -{ - if (!toshiba_state.disp_powered_up && !toshiba_state.display_on) { - /* Reset the hardware first */ - /* Include DAC power up implementation here */ - toshiba_state.disp_powered_up = TRUE; - } -} - -static void toshiba_disp_on(void) -{ - uint32 data; - - gpio_set_value(spi_cs, 0); /* low */ - gpio_set_value(spi_sclk, 1); /* high */ - gpio_set_value(spi_mosi, 0); - gpio_set_value(spi_miso, 0); - - if (toshiba_state.disp_powered_up && !toshiba_state.display_on) { - toshiba_spi_write(0, 0, 0); - mdelay(7); - toshiba_spi_write(0, 0, 0); - mdelay(7); - toshiba_spi_write(0, 0, 0); - mdelay(7); - toshiba_spi_write(0xba, 0x11, 1); - toshiba_spi_write(0x36, 0x00, 1); - mdelay(1); - toshiba_spi_write(0x3a, 0x60, 1); - toshiba_spi_write(0xb1, 0x5d, 1); - mdelay(1); - toshiba_spi_write(0xb2, 0x33, 1); - toshiba_spi_write(0xb3, 0x22, 1); - mdelay(1); - toshiba_spi_write(0xb4, 0x02, 1); - toshiba_spi_write(0xb5, 0x1e, 1); /* vcs -- adjust brightness */ - mdelay(1); - toshiba_spi_write(0xb6, 0x27, 1); - toshiba_spi_write(0xb7, 0x03, 1); - mdelay(1); - toshiba_spi_write(0xb9, 0x24, 1); - toshiba_spi_write(0xbd, 0xa1, 1); - mdelay(1); - toshiba_spi_write(0xbb, 0x00, 1); - toshiba_spi_write(0xbf, 0x01, 1); - mdelay(1); - toshiba_spi_write(0xbe, 0x00, 1); - toshiba_spi_write(0xc0, 0x11, 1); - mdelay(1); - toshiba_spi_write(0xc1, 0x11, 1); - toshiba_spi_write(0xc2, 0x11, 1); - mdelay(1); - toshiba_spi_write(0xc3, 0x3232, 2); - mdelay(1); - toshiba_spi_write(0xc4, 0x3232, 2); - mdelay(1); - toshiba_spi_write(0xc5, 0x3232, 2); - mdelay(1); - toshiba_spi_write(0xc6, 0x3232, 2); - mdelay(1); - toshiba_spi_write(0xc7, 0x6445, 2); - mdelay(1); - toshiba_spi_write(0xc8, 0x44, 1); - toshiba_spi_write(0xc9, 0x52, 1); - mdelay(1); - toshiba_spi_write(0xca, 0x00, 1); - mdelay(1); - toshiba_spi_write(0xec, 0x02a4, 2); /* 0x02a4 */ - mdelay(1); - toshiba_spi_write(0xcf, 0x01, 1); - mdelay(1); - toshiba_spi_write(0xd0, 0xc003, 2); /* c003 */ - mdelay(1); - toshiba_spi_write(0xd1, 0x01, 1); - mdelay(1); - toshiba_spi_write(0xd2, 0x0028, 2); - mdelay(1); - toshiba_spi_write(0xd3, 0x0028, 2); - mdelay(1); - toshiba_spi_write(0xd4, 0x26a4, 2); - mdelay(1); - toshiba_spi_write(0xd5, 0x20, 1); - mdelay(1); - toshiba_spi_write(0xef, 0x3200, 2); - mdelay(32); - toshiba_spi_write(0xbc, 0x80, 1); /* wvga pass through */ - toshiba_spi_write(0x3b, 0x00, 1); - mdelay(1); - toshiba_spi_write(0xb0, 0x16, 1); - mdelay(1); - toshiba_spi_write(0xb8, 0xfff5, 2); - mdelay(1); - toshiba_spi_write(0x11, 0, 0); - mdelay(5); - toshiba_spi_write(0x29, 0, 0); - mdelay(5); - toshiba_state.display_on = TRUE; - } - - data = 0; - toshiba_spi_read_bytes(0x04, &data, 3); - printk(KERN_INFO "toshiba_disp_on: id=%x\n", data); - -} - -static int lcdc_toshiba_panel_on(struct platform_device *pdev) -{ - if (!toshiba_state.disp_initialized) { - /* Configure reset GPIO that drives DAC */ - if (lcdc_toshiba_pdata->panel_config_gpio) - lcdc_toshiba_pdata->panel_config_gpio(1); - toshiba_disp_powerup(); - toshiba_disp_on(); - toshiba_state.disp_initialized = TRUE; - } - return 0; -} - -static int lcdc_toshiba_panel_off(struct platform_device *pdev) -{ - if (toshiba_state.disp_powered_up && toshiba_state.display_on) { - /* Main panel power off (Deep standby in) */ - - toshiba_spi_write(0x28, 0, 0); /* display off */ - mdelay(1); - toshiba_spi_write(0xb8, 0x8002, 2); /* output control */ - mdelay(1); - toshiba_spi_write(0x10, 0x00, 1); /* sleep mode in */ - mdelay(85); /* wait 85 msec */ - toshiba_spi_write(0xb0, 0x00, 1); /* deep standby in */ - mdelay(1); - if (lcdc_toshiba_pdata->panel_config_gpio) - lcdc_toshiba_pdata->panel_config_gpio(0); - toshiba_state.display_on = FALSE; - toshiba_state.disp_initialized = FALSE; - } - return 0; -} - -static void lcdc_toshiba_set_backlight(struct msm_fb_data_type *mfd) -{ - int bl_level; - int ret = -EPERM; - - bl_level = mfd->bl_level; - ret = pmic_set_led_intensity(LED_LCD, bl_level); - - if (ret) - printk(KERN_WARNING "%s: can't set lcd backlight!\n", - __func__); -} - -static int __init toshiba_probe(struct platform_device *pdev) -{ - if (pdev->id == 0) { - lcdc_toshiba_pdata = pdev->dev.platform_data; - spi_pin_assign(); - return 0; - } - msm_fb_add_device(pdev); - return 0; -} - -static struct platform_driver this_driver = { - .probe = toshiba_probe, - .driver = { - .name = "lcdc_toshiba_wvga", - }, -}; - -static struct msm_fb_panel_data toshiba_panel_data = { - .on = lcdc_toshiba_panel_on, - .off = lcdc_toshiba_panel_off, - .set_backlight = lcdc_toshiba_set_backlight, -}; - -static struct platform_device this_device = { - .name = "lcdc_toshiba_wvga", - .id = 1, - .dev = { - .platform_data = &toshiba_panel_data, - } -}; - -static int __init lcdc_toshiba_panel_init(void) -{ - int ret; - struct msm_panel_info *pinfo; -#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM - if (mddi_get_client_id() != 0) - return 0; - - ret = msm_fb_detect_client("lcdc_toshiba_wvga_pt"); - if (ret) - return 0; - -#endif - - ret = platform_driver_register(&this_driver); - if (ret) - return ret; - - pinfo = &toshiba_panel_data.panel_info; - pinfo->xres = 480; - pinfo->yres = 800; - pinfo->type = LCDC_PANEL; - pinfo->pdest = DISPLAY_1; - pinfo->wait_cycle = 0; - pinfo->bpp = 18; - pinfo->fb_num = 2; - /* 30Mhz mdp_lcdc_pclk and mdp_lcdc_pad_pcl */ - pinfo->clk_rate = 27648000; - pinfo->bl_max = 15; - pinfo->bl_min = 1; - - pinfo->lcdc.h_back_porch = 184; /* hsw = 8 + hbp=184 */ - pinfo->lcdc.h_front_porch = 4; - pinfo->lcdc.h_pulse_width = 8; - pinfo->lcdc.v_back_porch = 2; /* vsw=1 + vbp = 2 */ - pinfo->lcdc.v_front_porch = 3; - pinfo->lcdc.v_pulse_width = 1; - pinfo->lcdc.border_clr = 0; /* blk */ - pinfo->lcdc.underflow_clr = 0xff; /* blue */ - pinfo->lcdc.hsync_skew = 0; - - ret = platform_device_register(&this_device); - if (ret) - platform_driver_unregister(&this_driver); - - return ret; -} - -device_initcall(lcdc_toshiba_panel_init); diff --git a/drivers/staging/msm/logo.c b/drivers/staging/msm/logo.c deleted file mode 100644 index 7272765f48cd..000000000000 --- a/drivers/staging/msm/logo.c +++ /dev/null @@ -1,98 +0,0 @@ -/* drivers/video/msm/logo.c - * - * Show Logo in RLE 565 format - * - * Copyright (C) 2008 Google 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. - * - */ -#include -#include -#include -#include -#include -#include - -#include -#include - -#define fb_width(fb) ((fb)->var.xres) -#define fb_height(fb) ((fb)->var.yres) -#define fb_size(fb) ((fb)->var.xres * (fb)->var.yres * 2) - -static void memset16(void *_ptr, unsigned short val, unsigned count) -{ - unsigned short *ptr = _ptr; - count >>= 1; - while (count--) - *ptr++ = val; -} - -/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */ -int load_565rle_image(char *filename) -{ - struct fb_info *info; - int fd, err = 0; - unsigned count, max; - unsigned short *data, *bits, *ptr; - - info = registered_fb[0]; - if (!info) { - printk(KERN_WARNING "%s: Can not access framebuffer\n", - __func__); - return -ENODEV; - } - - fd = sys_open(filename, O_RDONLY, 0); - if (fd < 0) { - printk(KERN_WARNING "%s: Can not open %s\n", - __func__, filename); - return -ENOENT; - } - count = (unsigned)sys_lseek(fd, (off_t)0, 2); - if (count == 0) { - sys_close(fd); - err = -EIO; - goto err_logo_close_file; - } - sys_lseek(fd, (off_t)0, 0); - data = kmalloc(count, GFP_KERNEL); - if (!data) { - printk(KERN_WARNING "%s: Can not alloc data\n", __func__); - err = -ENOMEM; - goto err_logo_close_file; - } - if ((unsigned)sys_read(fd, (char *)data, count) != count) { - err = -EIO; - goto err_logo_free_data; - } - - max = fb_width(info) * fb_height(info); - ptr = data; - bits = (unsigned short *)(info->screen_base); - while (count > 3) { - unsigned n = ptr[0]; - if (n > max) - break; - memset16(bits, ptr[1], n << 1); - bits += n; - max -= n; - ptr += 2; - count -= 4; - } - -err_logo_free_data: - kfree(data); -err_logo_close_file: - sys_close(fd); - return err; -} -EXPORT_SYMBOL(load_565rle_image); diff --git a/drivers/staging/msm/mddi.c b/drivers/staging/msm/mddi.c deleted file mode 100644 index 132eb1adff16..000000000000 --- a/drivers/staging/msm/mddi.c +++ /dev/null @@ -1,375 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "msm_fb.h" -#include "mddihosti.h" -#include "mddihost.h" -#include -#include - -static int mddi_probe(struct platform_device *pdev); -static int mddi_remove(struct platform_device *pdev); - -static int mddi_off(struct platform_device *pdev); -static int mddi_on(struct platform_device *pdev); - -static int mddi_suspend(struct platform_device *pdev, pm_message_t state); -static int mddi_resume(struct platform_device *pdev); - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void mddi_early_suspend(struct early_suspend *h); -static void mddi_early_resume(struct early_suspend *h); -#endif - -static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST]; -static int pdev_list_cnt; -static struct clk *mddi_clk; -static struct clk *mddi_pclk; -static struct mddi_platform_data *mddi_pdata; - -static struct platform_driver mddi_driver = { - .probe = mddi_probe, - .remove = mddi_remove, -#ifndef CONFIG_HAS_EARLYSUSPEND -#ifdef CONFIG_PM - .suspend = mddi_suspend, - .resume = mddi_resume, -#endif -#endif - .suspend_late = NULL, - .resume_early = NULL, - .shutdown = NULL, - .driver = { - .name = "mddi", - }, -}; - -extern int int_mddi_pri_flag; - -static int mddi_off(struct platform_device *pdev) -{ - int ret = 0; - - ret = panel_next_off(pdev); - - if (mddi_pdata && mddi_pdata->mddi_power_save) - mddi_pdata->mddi_power_save(0); - - return ret; -} - -static int mddi_on(struct platform_device *pdev) -{ - int ret = 0; - u32 clk_rate; - struct msm_fb_data_type *mfd; - - mfd = platform_get_drvdata(pdev); - - if (mddi_pdata && mddi_pdata->mddi_power_save) - mddi_pdata->mddi_power_save(1); - - clk_rate = mfd->fbi->var.pixclock; - clk_rate = min(clk_rate, mfd->panel_info.clk_max); - - if (mddi_pdata && - mddi_pdata->mddi_sel_clk && - mddi_pdata->mddi_sel_clk(&clk_rate)) - printk(KERN_ERR - "%s: can't select mddi io clk targate rate = %d\n", - __func__, clk_rate); - - if (clk_set_min_rate(mddi_clk, clk_rate) < 0) - printk(KERN_ERR "%s: clk_set_min_rate failed\n", - __func__); - - ret = panel_next_on(pdev); - - return ret; -} - -static int mddi_resource_initialized; - -static int mddi_probe(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - struct platform_device *mdp_dev = NULL; - struct msm_fb_panel_data *pdata = NULL; - int rc; - resource_size_t size ; - u32 clk_rate; - - if ((pdev->id == 0) && (pdev->num_resources >= 0)) { - mddi_pdata = pdev->dev.platform_data; - - size = resource_size(&pdev->resource[0]); - msm_pmdh_base = ioremap(pdev->resource[0].start, size); - - MSM_FB_INFO("primary mddi base phy_addr = 0x%x virt = 0x%x\n", - pdev->resource[0].start, (int) msm_pmdh_base); - - if (unlikely(!msm_pmdh_base)) - return -ENOMEM; - - if (mddi_pdata && mddi_pdata->mddi_power_save) - mddi_pdata->mddi_power_save(1); - - mddi_resource_initialized = 1; - return 0; - } - - if (!mddi_resource_initialized) - return -EPERM; - - mfd = platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST) - return -ENOMEM; - - mdp_dev = platform_device_alloc("mdp", pdev->id); - if (!mdp_dev) - return -ENOMEM; - - /* - * link to the latest pdev - */ - mfd->pdev = mdp_dev; - mfd->dest = DISPLAY_LCD; - - /* - * alloc panel device data - */ - if (platform_device_add_data - (mdp_dev, pdev->dev.platform_data, - sizeof(struct msm_fb_panel_data))) { - printk(KERN_ERR "mddi_probe: platform_device_add_data failed!\n"); - platform_device_put(mdp_dev); - return -ENOMEM; - } - /* - * data chain - */ - pdata = mdp_dev->dev.platform_data; - pdata->on = mddi_on; - pdata->off = mddi_off; - pdata->next = pdev; - - /* - * get/set panel specific fb info - */ - mfd->panel_info = pdata->panel_info; - mfd->fb_imgType = MDP_RGB_565; - - clk_rate = mfd->panel_info.clk_max; - if (mddi_pdata && - mddi_pdata->mddi_sel_clk && - mddi_pdata->mddi_sel_clk(&clk_rate)) - printk(KERN_ERR - "%s: can't select mddi io clk targate rate = %d\n", - __func__, clk_rate); - - if (clk_set_max_rate(mddi_clk, clk_rate) < 0) - printk(KERN_ERR "%s: clk_set_max_rate failed\n", __func__); - mfd->panel_info.clk_rate = mfd->panel_info.clk_min; - - /* - * set driver data - */ - platform_set_drvdata(mdp_dev, mfd); - - /* - * register in mdp driver - */ - rc = platform_device_add(mdp_dev); - if (rc) - goto mddi_probe_err; - - pdev_list[pdev_list_cnt++] = pdev; - -#ifdef CONFIG_HAS_EARLYSUSPEND - mfd->mddi_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - mfd->mddi_early_suspend.suspend = mddi_early_suspend; - mfd->mddi_early_suspend.resume = mddi_early_resume; - register_early_suspend(&mfd->mddi_early_suspend); -#endif - - return 0; - -mddi_probe_err: - platform_device_put(mdp_dev); - return rc; -} - -static int mddi_pad_ctrl; -static int mddi_power_locked; -static int mddi_is_in_suspend; - -void mddi_disable(int lock) -{ - mddi_host_type host_idx = MDDI_HOST_PRIM; - - if (mddi_power_locked) - return; - - if (lock) - mddi_power_locked = 1; - - if (mddi_host_timer.function) - del_timer_sync(&mddi_host_timer); - - mddi_pad_ctrl = mddi_host_reg_in(PAD_CTL); - mddi_host_reg_out(PAD_CTL, 0x0); - - if (clk_set_min_rate(mddi_clk, 0) < 0) - printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__); - - clk_disable(mddi_clk); - if (mddi_pclk) - clk_disable(mddi_pclk); - disable_irq(INT_MDDI_PRI); - - if (mddi_pdata && mddi_pdata->mddi_power_save) - mddi_pdata->mddi_power_save(0); -} - -static int mddi_suspend(struct platform_device *pdev, pm_message_t state) -{ - if (mddi_is_in_suspend) - return 0; - - mddi_is_in_suspend = 1; - mddi_disable(0); - return 0; -} - -static int mddi_resume(struct platform_device *pdev) -{ - mddi_host_type host_idx = MDDI_HOST_PRIM; - - if (!mddi_is_in_suspend) - return 0; - - mddi_is_in_suspend = 0; - - if (mddi_power_locked) - return 0; - - enable_irq(INT_MDDI_PRI); - clk_enable(mddi_clk); - if (mddi_pclk) - clk_enable(mddi_pclk); - mddi_host_reg_out(PAD_CTL, mddi_pad_ctrl); - - if (mddi_host_timer.function) - mddi_host_timer_service(0); - - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void mddi_early_suspend(struct early_suspend *h) -{ - pm_message_t state; - struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type, - mddi_early_suspend); - - state.event = PM_EVENT_SUSPEND; - mddi_suspend(mfd->pdev, state); -} - -static void mddi_early_resume(struct early_suspend *h) -{ - struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type, - mddi_early_suspend); - mddi_resume(mfd->pdev); -} -#endif - -static int mddi_remove(struct platform_device *pdev) -{ - if (mddi_host_timer.function) - del_timer_sync(&mddi_host_timer); - - iounmap(msm_pmdh_base); - - return 0; -} - -static int mddi_register_driver(void) -{ - return platform_driver_register(&mddi_driver); -} - -static int __init mddi_driver_init(void) -{ - int ret; - - mddi_clk = clk_get(NULL, "mddi_clk"); - if (IS_ERR(mddi_clk)) { - printk(KERN_ERR "can't find mddi_clk \n"); - return PTR_ERR(mddi_clk); - } - clk_enable(mddi_clk); - - mddi_pclk = clk_get(NULL, "mddi_pclk"); - if (IS_ERR(mddi_pclk)) - mddi_pclk = NULL; - else - clk_enable(mddi_pclk); - - ret = mddi_register_driver(); - if (ret) { - clk_disable(mddi_clk); - clk_put(mddi_clk); - if (mddi_pclk) { - clk_disable(mddi_pclk); - clk_put(mddi_pclk); - } - printk(KERN_ERR "mddi_register_driver() failed!\n"); - return ret; - } - - mddi_init(); - - return ret; -} - -module_init(mddi_driver_init); diff --git a/drivers/staging/msm/mddi_ext.c b/drivers/staging/msm/mddi_ext.c deleted file mode 100644 index c0c168c7199d..000000000000 --- a/drivers/staging/msm/mddi_ext.c +++ /dev/null @@ -1,320 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "msm_fb.h" -#include "mddihosti.h" - -static int mddi_ext_probe(struct platform_device *pdev); -static int mddi_ext_remove(struct platform_device *pdev); - -static int mddi_ext_off(struct platform_device *pdev); -static int mddi_ext_on(struct platform_device *pdev); - -static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST]; -static int pdev_list_cnt; - -static int mddi_ext_suspend(struct platform_device *pdev, pm_message_t state); -static int mddi_ext_resume(struct platform_device *pdev); - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void mddi_ext_early_suspend(struct early_suspend *h); -static void mddi_ext_early_resume(struct early_suspend *h); -#endif - -static struct platform_driver mddi_ext_driver = { - .probe = mddi_ext_probe, - .remove = mddi_ext_remove, -#ifndef CONFIG_HAS_EARLYSUSPEND -#ifdef CONFIG_PM - .suspend = mddi_ext_suspend, - .resume = mddi_ext_resume, -#endif -#endif - .resume_early = NULL, - .resume = NULL, - .shutdown = NULL, - .driver = { - .name = "mddi_ext", - }, -}; - -static struct clk *mddi_ext_clk; -static struct mddi_platform_data *mddi_ext_pdata; - -extern int int_mddi_ext_flag; - -static int mddi_ext_off(struct platform_device *pdev) -{ - int ret = 0; - - ret = panel_next_off(pdev); - mddi_host_stop_ext_display(); - - return ret; -} - -static int mddi_ext_on(struct platform_device *pdev) -{ - int ret = 0; - u32 clk_rate; - struct msm_fb_data_type *mfd; - - mfd = platform_get_drvdata(pdev); - - clk_rate = mfd->fbi->var.pixclock; - clk_rate = min(clk_rate, mfd->panel_info.clk_max); - - if (mddi_ext_pdata && - mddi_ext_pdata->mddi_sel_clk && - mddi_ext_pdata->mddi_sel_clk(&clk_rate)) - printk(KERN_ERR - "%s: can't select mddi io clk targate rate = %d\n", - __func__, clk_rate); - - if (clk_set_min_rate(mddi_ext_clk, clk_rate) < 0) - printk(KERN_ERR "%s: clk_set_min_rate failed\n", - __func__); - - mddi_host_start_ext_display(); - ret = panel_next_on(pdev); - - return ret; -} - -static int mddi_ext_resource_initialized; - -static int mddi_ext_probe(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - struct platform_device *mdp_dev = NULL; - struct msm_fb_panel_data *pdata = NULL; - int rc; - resource_size_t size ; - u32 clk_rate; - - if ((pdev->id == 0) && (pdev->num_resources >= 0)) { - mddi_ext_pdata = pdev->dev.platform_data; - - size = resource_size(&pdev->resource[0]); - msm_emdh_base = ioremap(pdev->resource[0].start, size); - - MSM_FB_INFO("external mddi base address = 0x%x\n", - pdev->resource[0].start); - - if (unlikely(!msm_emdh_base)) - return -ENOMEM; - - mddi_ext_resource_initialized = 1; - return 0; - } - - if (!mddi_ext_resource_initialized) - return -EPERM; - - mfd = platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST) - return -ENOMEM; - - mdp_dev = platform_device_alloc("mdp", pdev->id); - if (!mdp_dev) - return -ENOMEM; - - /* - * link to the latest pdev - */ - mfd->pdev = mdp_dev; - mfd->dest = DISPLAY_EXT_MDDI; - - /* - * alloc panel device data - */ - if (platform_device_add_data - (mdp_dev, pdev->dev.platform_data, - sizeof(struct msm_fb_panel_data))) { - printk(KERN_ERR "mddi_ext_probe: platform_device_add_data failed!\n"); - platform_device_put(mdp_dev); - return -ENOMEM; - } - /* - * data chain - */ - pdata = mdp_dev->dev.platform_data; - pdata->on = mddi_ext_on; - pdata->off = mddi_ext_off; - pdata->next = pdev; - - /* - * get/set panel specific fb info - */ - mfd->panel_info = pdata->panel_info; - mfd->fb_imgType = MDP_RGB_565; - - clk_rate = mfd->panel_info.clk_max; - if (mddi_ext_pdata && - mddi_ext_pdata->mddi_sel_clk && - mddi_ext_pdata->mddi_sel_clk(&clk_rate)) - printk(KERN_ERR - "%s: can't select mddi io clk targate rate = %d\n", - __func__, clk_rate); - - if (clk_set_max_rate(mddi_ext_clk, clk_rate) < 0) - printk(KERN_ERR "%s: clk_set_max_rate failed\n", __func__); - mfd->panel_info.clk_rate = mfd->panel_info.clk_min; - - /* - * set driver data - */ - platform_set_drvdata(mdp_dev, mfd); - - /* - * register in mdp driver - */ - rc = platform_device_add(mdp_dev); - if (rc) - goto mddi_ext_probe_err; - - pdev_list[pdev_list_cnt++] = pdev; - -#ifdef CONFIG_HAS_EARLYSUSPEND - mfd->mddi_ext_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - mfd->mddi_ext_early_suspend.suspend = mddi_ext_early_suspend; - mfd->mddi_ext_early_suspend.resume = mddi_ext_early_resume; - register_early_suspend(&mfd->mddi_ext_early_suspend); -#endif - - return 0; - -mddi_ext_probe_err: - platform_device_put(mdp_dev); - return rc; -} - -static int mddi_ext_is_in_suspend; - -static int mddi_ext_suspend(struct platform_device *pdev, pm_message_t state) -{ - if (mddi_ext_is_in_suspend) - return 0; - - mddi_ext_is_in_suspend = 1; - - if (clk_set_min_rate(mddi_ext_clk, 0) < 0) - printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__); - - clk_disable(mddi_ext_clk); - disable_irq(INT_MDDI_EXT); - - return 0; -} - -static int mddi_ext_resume(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - - mfd = platform_get_drvdata(pdev); - - if (!mddi_ext_is_in_suspend) - return 0; - - mddi_ext_is_in_suspend = 0; - enable_irq(INT_MDDI_EXT); - - clk_enable(mddi_ext_clk); - - return 0; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void mddi_ext_early_suspend(struct early_suspend *h) -{ - pm_message_t state; - struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type, - mddi_ext_early_suspend); - - state.event = PM_EVENT_SUSPEND; - mddi_ext_suspend(mfd->pdev, state); -} - -static void mddi_ext_early_resume(struct early_suspend *h) -{ - struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type, - mddi_ext_early_suspend); - mddi_ext_resume(mfd->pdev); -} -#endif - -static int mddi_ext_remove(struct platform_device *pdev) -{ - iounmap(msm_emdh_base); - return 0; -} - -static int mddi_ext_register_driver(void) -{ - return platform_driver_register(&mddi_ext_driver); -} - -static int __init mddi_ext_driver_init(void) -{ - int ret; - - mddi_ext_clk = clk_get(NULL, "emdh_clk"); - if (IS_ERR(mddi_ext_clk)) { - printk(KERN_ERR "can't find emdh_clk\n"); - return PTR_ERR(mddi_ext_clk); - } - clk_enable(mddi_ext_clk); - - ret = mddi_ext_register_driver(); - if (ret) { - clk_disable(mddi_ext_clk); - clk_put(mddi_ext_clk); - printk(KERN_ERR "mddi_ext_register_driver() failed!\n"); - return ret; - } - mddi_init(); - - return ret; -} - -module_init(mddi_ext_driver_init); diff --git a/drivers/staging/msm/mddi_ext_lcd.c b/drivers/staging/msm/mddi_ext_lcd.c deleted file mode 100644 index 502e80d17ec7..000000000000 --- a/drivers/staging/msm/mddi_ext_lcd.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "msm_fb.h" -#include "mddihost.h" -#include "mddihosti.h" - -static int mddi_ext_lcd_on(struct platform_device *pdev); -static int mddi_ext_lcd_off(struct platform_device *pdev); - -static int mddi_ext_lcd_on(struct platform_device *pdev) -{ - return 0; -} - -static int mddi_ext_lcd_off(struct platform_device *pdev) -{ - return 0; -} - -static int __init mddi_ext_lcd_probe(struct platform_device *pdev) -{ - msm_fb_add_device(pdev); - - return 0; -} - -static struct platform_driver this_driver = { - .probe = mddi_ext_lcd_probe, - .driver = { - .name = "extmddi_svga", - }, -}; - -static struct msm_fb_panel_data mddi_ext_lcd_panel_data = { - .panel_info.xres = 800, - .panel_info.yres = 600, - .panel_info.type = EXT_MDDI_PANEL, - .panel_info.pdest = DISPLAY_1, - .panel_info.wait_cycle = 0, - .panel_info.bpp = 18, - .panel_info.fb_num = 2, - .panel_info.clk_rate = 122880000, - .panel_info.clk_min = 120000000, - .panel_info.clk_max = 125000000, - .on = mddi_ext_lcd_on, - .off = mddi_ext_lcd_off, -}; - -static struct platform_device this_device = { - .name = "extmddi_svga", - .id = 0, - .dev = { - .platform_data = &mddi_ext_lcd_panel_data, - } -}; - -static int __init mddi_ext_lcd_init(void) -{ - int ret; - struct msm_panel_info *pinfo; - - ret = platform_driver_register(&this_driver); - if (!ret) { - pinfo = &mddi_ext_lcd_panel_data.panel_info; - pinfo->lcd.vsync_enable = FALSE; - pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR; - - ret = platform_device_register(&this_device); - if (ret) - platform_driver_unregister(&this_driver); - } - - return ret; -} - -module_init(mddi_ext_lcd_init); diff --git a/drivers/staging/msm/mddi_prism.c b/drivers/staging/msm/mddi_prism.c deleted file mode 100644 index 489d40405a5f..000000000000 --- a/drivers/staging/msm/mddi_prism.c +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "msm_fb.h" -#include "mddihost.h" -#include "mddihosti.h" - -static int prism_lcd_on(struct platform_device *pdev); -static int prism_lcd_off(struct platform_device *pdev); - -static int prism_lcd_on(struct platform_device *pdev) -{ - /* Set the MDP pixel data attributes for Primary Display */ - mddi_host_write_pix_attr_reg(0x00C3); - - return 0; -} - -static int prism_lcd_off(struct platform_device *pdev) -{ - return 0; -} - -static int __init prism_probe(struct platform_device *pdev) -{ - msm_fb_add_device(pdev); - - return 0; -} - -static struct platform_driver this_driver = { - .probe = prism_probe, - .driver = { - .name = "mddi_prism_wvga", - }, -}; - -static struct msm_fb_panel_data prism_panel_data = { - .on = prism_lcd_on, - .off = prism_lcd_off, -}; - -static struct platform_device this_device = { - .name = "mddi_prism_wvga", - .id = 0, - .dev = { - .platform_data = &prism_panel_data, - } -}; - -static int __init prism_init(void) -{ - int ret; - struct msm_panel_info *pinfo; - -#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT - u32 id; - - ret = msm_fb_detect_client("mddi_prism_wvga"); - if (ret == -ENODEV) - return 0; - - if (ret) { - id = mddi_get_client_id(); - - if (((id >> 16) != 0x4474) || ((id & 0xffff) == 0x8960)) - return 0; - } -#endif - ret = platform_driver_register(&this_driver); - if (!ret) { - pinfo = &prism_panel_data.panel_info; - pinfo->xres = 800; - pinfo->yres = 480; - pinfo->type = MDDI_PANEL; - pinfo->pdest = DISPLAY_1; - pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR; - pinfo->wait_cycle = 0; - pinfo->bpp = 18; - pinfo->fb_num = 2; - pinfo->clk_rate = 153600000; - pinfo->clk_min = 150000000; - pinfo->clk_max = 160000000; - pinfo->lcd.vsync_enable = TRUE; - pinfo->lcd.refx100 = 6050; - pinfo->lcd.v_back_porch = 23; - pinfo->lcd.v_front_porch = 20; - pinfo->lcd.v_pulse_width = 105; - pinfo->lcd.hw_vsync_mode = TRUE; - pinfo->lcd.vsync_notifier_period = 0; - - ret = platform_device_register(&this_device); - if (ret) - platform_driver_unregister(&this_driver); - } - - return ret; -} - -module_init(prism_init); diff --git a/drivers/staging/msm/mddi_sharp.c b/drivers/staging/msm/mddi_sharp.c deleted file mode 100644 index 1da1be4052d0..000000000000 --- a/drivers/staging/msm/mddi_sharp.c +++ /dev/null @@ -1,892 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "msm_fb.h" -#include "mddihost.h" -#include "mddihosti.h" - -#define SHARP_QVGA_PRIM 1 -#define SHARP_128X128_SECD 2 - -extern uint32 mddi_host_core_version; -static boolean mddi_debug_prim_wait = FALSE; -static boolean mddi_sharp_vsync_wake = TRUE; -static boolean mddi_sharp_monitor_refresh_value = TRUE; -static boolean mddi_sharp_report_refresh_measurements = FALSE; -static uint32 mddi_sharp_rows_per_second = 13830; /* 5200000/376 */ -static uint32 mddi_sharp_rows_per_refresh = 338; -static uint32 mddi_sharp_usecs_per_refresh = 24440; /* (376+338)/5200000 */ -static boolean mddi_sharp_debug_60hz_refresh = FALSE; - -extern mddi_gpio_info_type mddi_gpio; -extern boolean mddi_vsync_detect_enabled; -static msm_fb_vsync_handler_type mddi_sharp_vsync_handler; -static void *mddi_sharp_vsync_handler_arg; -static uint16 mddi_sharp_vsync_attempts; - -static void mddi_sharp_prim_lcd_init(void); -static void mddi_sharp_sub_lcd_init(void); -static void mddi_sharp_lcd_set_backlight(struct msm_fb_data_type *mfd); -static void mddi_sharp_vsync_set_handler(msm_fb_vsync_handler_type handler, - void *); -static void mddi_sharp_lcd_vsync_detected(boolean detected); -static struct msm_panel_common_pdata *mddi_sharp_pdata; - -#define REG_SYSCTL 0x0000 -#define REG_INTR 0x0006 -#define REG_CLKCNF 0x000C -#define REG_CLKDIV1 0x000E -#define REG_CLKDIV2 0x0010 - -#define REG_GIOD 0x0040 -#define REG_GIOA 0x0042 - -#define REG_AGM 0x010A -#define REG_FLFT 0x0110 -#define REG_FRGT 0x0112 -#define REG_FTOP 0x0114 -#define REG_FBTM 0x0116 -#define REG_FSTRX 0x0118 -#define REG_FSTRY 0x011A -#define REG_VRAM 0x0202 -#define REG_SSDCTL 0x0330 -#define REG_SSD0 0x0332 -#define REG_PSTCTL1 0x0400 -#define REG_PSTCTL2 0x0402 -#define REG_PTGCTL 0x042A -#define REG_PTHP 0x042C -#define REG_PTHB 0x042E -#define REG_PTHW 0x0430 -#define REG_PTHF 0x0432 -#define REG_PTVP 0x0434 -#define REG_PTVB 0x0436 -#define REG_PTVW 0x0438 -#define REG_PTVF 0x043A -#define REG_VBLKS 0x0458 -#define REG_VBLKE 0x045A -#define REG_SUBCTL 0x0700 -#define REG_SUBTCMD 0x0702 -#define REG_SUBTCMDD 0x0704 -#define REG_REVBYTE 0x0A02 -#define REG_REVCNT 0x0A04 -#define REG_REVATTR 0x0A06 -#define REG_REVFMT 0x0A08 - -#define SHARP_SUB_UNKNOWN 0xffffffff -#define SHARP_SUB_HYNIX 1 -#define SHARP_SUB_ROHM 2 - -static uint32 sharp_subpanel_type = SHARP_SUB_UNKNOWN; - -static void sub_through_write(int sub_rs, uint32 sub_data) -{ - mddi_queue_register_write(REG_SUBTCMDD, sub_data, FALSE, 0); - - /* CS=1,RD=1,WE=1,RS=sub_rs */ - mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, FALSE, 0); - - /* CS=0,RD=1,WE=1,RS=sub_rs */ - mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0); - - /* CS=0,RD=1,WE=0,RS=sub_rs */ - mddi_queue_register_write(REG_SUBTCMD, 0x0004 | sub_rs, FALSE, 0); - - /* CS=0,RD=1,WE=1,RS=sub_rs */ - mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0); - - /* CS=1,RD=1,WE=1,RS=sub_rs */ - mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, TRUE, 0); -} - -static uint32 sub_through_read(int sub_rs) -{ - uint32 sub_data; - - /* CS=1,RD=1,WE=1,RS=sub_rs */ - mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, FALSE, 0); - - /* CS=0,RD=1,WE=1,RS=sub_rs */ - mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0); - - /* CS=0,RD=1,WE=0,RS=sub_rs */ - mddi_queue_register_write(REG_SUBTCMD, 0x0002 | sub_rs, TRUE, 0); - - mddi_queue_register_read(REG_SUBTCMDD, &sub_data, TRUE, 0); - - /* CS=0,RD=1,WE=1,RS=sub_rs */ - mddi_queue_register_write(REG_SUBTCMD, 0x0006 | sub_rs, FALSE, 0); - - /* CS=1,RD=1,WE=1,RS=sub_rs */ - mddi_queue_register_write(REG_SUBTCMD, 0x000e | sub_rs, TRUE, 0); - - return sub_data; -} - -static void serigo(uint32 ssd) -{ - uint32 ssdctl; - - mddi_queue_register_read(REG_SSDCTL, &ssdctl, TRUE, 0); - ssdctl = ((ssdctl & 0xE7) | 0x02); - - mddi_queue_register_write(REG_SSD0, ssd, FALSE, 0); - mddi_queue_register_write(REG_SSDCTL, ssdctl, TRUE, 0); - - do { - mddi_queue_register_read(REG_SSDCTL, &ssdctl, TRUE, 0); - } while ((ssdctl & 0x0002) != 0); - - if (mddi_debug_prim_wait) - mddi_wait(2); -} - -static void mddi_sharp_lcd_powerdown(void) -{ - serigo(0x0131); - serigo(0x0300); - mddi_wait(40); - serigo(0x0135); - mddi_wait(20); - serigo(0x2122); - mddi_wait(20); - serigo(0x0201); - mddi_wait(20); - serigo(0x2100); - mddi_wait(20); - serigo(0x2000); - mddi_wait(20); - - mddi_queue_register_write(REG_PSTCTL1, 0x1, TRUE, 0); - mddi_wait(100); - mddi_queue_register_write(REG_PSTCTL1, 0x0, TRUE, 0); - mddi_wait(2); - mddi_queue_register_write(REG_SYSCTL, 0x1, TRUE, 0); - mddi_wait(2); - mddi_queue_register_write(REG_CLKDIV1, 0x3, TRUE, 0); - mddi_wait(2); - mddi_queue_register_write(REG_SSDCTL, 0x0000, TRUE, 0); /* SSDRESET */ - mddi_queue_register_write(REG_SYSCTL, 0x0, TRUE, 0); - mddi_wait(2); -} - -static void mddi_sharp_lcd_set_backlight(struct msm_fb_data_type *mfd) -{ - uint32 regdata; - int32 level; - int max = mfd->panel_info.bl_max; - int min = mfd->panel_info.bl_min; - - if (mddi_sharp_pdata && mddi_sharp_pdata->backlight_level) { - level = mddi_sharp_pdata->backlight_level(mfd->bl_level, - max, - min); - - if (level < 0) - return; - - /* use Rodem GPIO(2:0) to give 8 levels of backlight (7-0) */ - /* Set lower 3 GPIOs as Outputs (set to 0) */ - mddi_queue_register_read(REG_GIOA, ®data, TRUE, 0); - mddi_queue_register_write(REG_GIOA, regdata & 0xfff8, TRUE, 0); - - /* Set lower 3 GPIOs as level */ - mddi_queue_register_read(REG_GIOD, ®data, TRUE, 0); - mddi_queue_register_write(REG_GIOD, - (regdata & 0xfff8) | (0x07 & level), TRUE, 0); - } -} - -static void mddi_sharp_prim_lcd_init(void) -{ - mddi_queue_register_write(REG_SYSCTL, 0x4000, TRUE, 0); - mddi_wait(1); - mddi_queue_register_write(REG_SYSCTL, 0x0000, TRUE, 0); - mddi_wait(5); - mddi_queue_register_write(REG_SYSCTL, 0x0001, FALSE, 0); - mddi_queue_register_write(REG_CLKDIV1, 0x000b, FALSE, 0); - - /* new reg write below */ - if (mddi_sharp_debug_60hz_refresh) - mddi_queue_register_write(REG_CLKCNF, 0x070d, FALSE, 0); - else - mddi_queue_register_write(REG_CLKCNF, 0x0708, FALSE, 0); - - mddi_queue_register_write(REG_SYSCTL, 0x0201, FALSE, 0); - mddi_queue_register_write(REG_PTGCTL, 0x0010, FALSE, 0); - mddi_queue_register_write(REG_PTHP, 4, FALSE, 0); - mddi_queue_register_write(REG_PTHB, 40, FALSE, 0); - mddi_queue_register_write(REG_PTHW, 240, FALSE, 0); - if (mddi_sharp_debug_60hz_refresh) - mddi_queue_register_write(REG_PTHF, 12, FALSE, 0); - else - mddi_queue_register_write(REG_PTHF, 92, FALSE, 0); - - mddi_wait(1); - - mddi_queue_register_write(REG_PTVP, 1, FALSE, 0); - mddi_queue_register_write(REG_PTVB, 2, FALSE, 0); - mddi_queue_register_write(REG_PTVW, 320, FALSE, 0); - mddi_queue_register_write(REG_PTVF, 15, FALSE, 0); - - mddi_wait(1); - - /* vram_color set REG_AGM???? */ - mddi_queue_register_write(REG_AGM, 0x0000, TRUE, 0); - - mddi_queue_register_write(REG_SSDCTL, 0x0000, FALSE, 0); - mddi_queue_register_write(REG_SSDCTL, 0x0001, TRUE, 0); - mddi_wait(1); - mddi_queue_register_write(REG_PSTCTL1, 0x0001, TRUE, 0); - mddi_wait(10); - - serigo(0x0701); - /* software reset */ - mddi_wait(1); - /* Wait over 50us */ - - serigo(0x0400); - /* DCLK~ACHSYNC~ACVSYNC polarity setting */ - serigo(0x2900); - /* EEPROM start read address setting */ - serigo(0x2606); - /* EEPROM start read register setting */ - mddi_wait(20); - /* Wait over 20ms */ - - serigo(0x0503); - /* Horizontal timing setting */ - serigo(0x062C); - /* Veritical timing setting */ - serigo(0x2001); - /* power initialize setting(VDC2) */ - mddi_wait(20); - /* Wait over 20ms */ - - serigo(0x2120); - /* Initialize power setting(CPS) */ - mddi_wait(20); - /* Wait over 20ms */ - - serigo(0x2130); - /* Initialize power setting(CPS) */ - mddi_wait(20); - /* Wait over 20ms */ - - serigo(0x2132); - /* Initialize power setting(CPS) */ - mddi_wait(10); - /* Wait over 10ms */ - - serigo(0x2133); - /* Initialize power setting(CPS) */ - mddi_wait(20); - /* Wait over 20ms */ - - serigo(0x0200); - /* Panel initialize release(INIT) */ - mddi_wait(1); - /* Wait over 1ms */ - - serigo(0x0131); - /* Panel setting(CPS) */ - mddi_wait(1); - /* Wait over 1ms */ - - mddi_queue_register_write(REG_PSTCTL1, 0x0003, TRUE, 0); - - /* if (FFA LCD is upside down) -> serigo(0x0100); */ - serigo(0x0130); - - /* Black mask release(display ON) */ - mddi_wait(1); - /* Wait over 1ms */ - - if (mddi_sharp_vsync_wake) { - mddi_queue_register_write(REG_VBLKS, 0x1001, TRUE, 0); - mddi_queue_register_write(REG_VBLKE, 0x1002, TRUE, 0); - } - - /* Set the MDP pixel data attributes for Primary Display */ - mddi_host_write_pix_attr_reg(0x00C3); - return; - -} - -void mddi_sharp_sub_lcd_init(void) -{ - - mddi_queue_register_write(REG_SYSCTL, 0x4000, FALSE, 0); - mddi_queue_register_write(REG_SYSCTL, 0x0000, TRUE, 0); - mddi_wait(100); - - mddi_queue_register_write(REG_SYSCTL, 0x0001, FALSE, 0); - mddi_queue_register_write(REG_CLKDIV1, 0x000b, FALSE, 0); - mddi_queue_register_write(REG_CLKCNF, 0x0708, FALSE, 0); - mddi_queue_register_write(REG_SYSCTL, 0x0201, FALSE, 0); - mddi_queue_register_write(REG_PTGCTL, 0x0010, FALSE, 0); - mddi_queue_register_write(REG_PTHP, 4, FALSE, 0); - mddi_queue_register_write(REG_PTHB, 40, FALSE, 0); - mddi_queue_register_write(REG_PTHW, 128, FALSE, 0); - mddi_queue_register_write(REG_PTHF, 92, FALSE, 0); - mddi_queue_register_write(REG_PTVP, 1, FALSE, 0); - mddi_queue_register_write(REG_PTVB, 2, FALSE, 0); - mddi_queue_register_write(REG_PTVW, 128, FALSE, 0); - mddi_queue_register_write(REG_PTVF, 15, FALSE, 0); - - /* Now the sub display..... */ - /* Reset High */ - mddi_queue_register_write(REG_SUBCTL, 0x0200, FALSE, 0); - /* CS=1,RD=1,WE=1,RS=1 */ - mddi_queue_register_write(REG_SUBTCMD, 0x000f, TRUE, 0); - mddi_wait(1); - /* Wait 5us */ - - if (sharp_subpanel_type == SHARP_SUB_UNKNOWN) { - uint32 data; - - sub_through_write(1, 0x05); - sub_through_write(1, 0x6A); - sub_through_write(1, 0x1D); - sub_through_write(1, 0x05); - data = sub_through_read(1); - if (data == 0x6A) { - sharp_subpanel_type = SHARP_SUB_HYNIX; - } else { - sub_through_write(0, 0x36); - sub_through_write(1, 0xA8); - sub_through_write(0, 0x09); - data = sub_through_read(1); - data = sub_through_read(1); - if (data == 0x54) { - sub_through_write(0, 0x36); - sub_through_write(1, 0x00); - sharp_subpanel_type = SHARP_SUB_ROHM; - } - } - } - - if (sharp_subpanel_type == SHARP_SUB_HYNIX) { - sub_through_write(1, 0x00); /* Display setting 1 */ - sub_through_write(1, 0x04); - sub_through_write(1, 0x01); - sub_through_write(1, 0x05); - sub_through_write(1, 0x0280); - sub_through_write(1, 0x0301); - sub_through_write(1, 0x0402); - sub_through_write(1, 0x0500); - sub_through_write(1, 0x0681); - sub_through_write(1, 0x077F); - sub_through_write(1, 0x08C0); - sub_through_write(1, 0x0905); - sub_through_write(1, 0x0A02); - sub_through_write(1, 0x0B00); - sub_through_write(1, 0x0C00); - sub_through_write(1, 0x0D00); - sub_through_write(1, 0x0E00); - sub_through_write(1, 0x0F00); - - sub_through_write(1, 0x100B); /* Display setting 2 */ - sub_through_write(1, 0x1103); - sub_through_write(1, 0x1237); - sub_through_write(1, 0x1300); - sub_through_write(1, 0x1400); - sub_through_write(1, 0x1500); - sub_through_write(1, 0x1605); - sub_through_write(1, 0x1700); - sub_through_write(1, 0x1800); - sub_through_write(1, 0x192E); - sub_through_write(1, 0x1A00); - sub_through_write(1, 0x1B00); - sub_through_write(1, 0x1C00); - - sub_through_write(1, 0x151A); /* Power setting */ - - sub_through_write(1, 0x2002); /* Gradation Palette setting */ - sub_through_write(1, 0x2107); - sub_through_write(1, 0x220C); - sub_through_write(1, 0x2310); - sub_through_write(1, 0x2414); - sub_through_write(1, 0x2518); - sub_through_write(1, 0x261C); - sub_through_write(1, 0x2720); - sub_through_write(1, 0x2824); - sub_through_write(1, 0x2928); - sub_through_write(1, 0x2A2B); - sub_through_write(1, 0x2B2E); - sub_through_write(1, 0x2C31); - sub_through_write(1, 0x2D34); - sub_through_write(1, 0x2E37); - sub_through_write(1, 0x2F3A); - sub_through_write(1, 0x303C); - sub_through_write(1, 0x313E); - sub_through_write(1, 0x323F); - sub_through_write(1, 0x3340); - sub_through_write(1, 0x3441); - sub_through_write(1, 0x3543); - sub_through_write(1, 0x3646); - sub_through_write(1, 0x3749); - sub_through_write(1, 0x384C); - sub_through_write(1, 0x394F); - sub_through_write(1, 0x3A52); - sub_through_write(1, 0x3B59); - sub_through_write(1, 0x3C60); - sub_through_write(1, 0x3D67); - sub_through_write(1, 0x3E6E); - sub_through_write(1, 0x3F7F); - sub_through_write(1, 0x4001); - sub_through_write(1, 0x4107); - sub_through_write(1, 0x420C); - sub_through_write(1, 0x4310); - sub_through_write(1, 0x4414); - sub_through_write(1, 0x4518); - sub_through_write(1, 0x461C); - sub_through_write(1, 0x4720); - sub_through_write(1, 0x4824); - sub_through_write(1, 0x4928); - sub_through_write(1, 0x4A2B); - sub_through_write(1, 0x4B2E); - sub_through_write(1, 0x4C31); - sub_through_write(1, 0x4D34); - sub_through_write(1, 0x4E37); - sub_through_write(1, 0x4F3A); - sub_through_write(1, 0x503C); - sub_through_write(1, 0x513E); - sub_through_write(1, 0x523F); - sub_through_write(1, 0x5340); - sub_through_write(1, 0x5441); - sub_through_write(1, 0x5543); - sub_through_write(1, 0x5646); - sub_through_write(1, 0x5749); - sub_through_write(1, 0x584C); - sub_through_write(1, 0x594F); - sub_through_write(1, 0x5A52); - sub_through_write(1, 0x5B59); - sub_through_write(1, 0x5C60); - sub_through_write(1, 0x5D67); - sub_through_write(1, 0x5E6E); - sub_through_write(1, 0x5F7E); - sub_through_write(1, 0x6000); - sub_through_write(1, 0x6107); - sub_through_write(1, 0x620C); - sub_through_write(1, 0x6310); - sub_through_write(1, 0x6414); - sub_through_write(1, 0x6518); - sub_through_write(1, 0x661C); - sub_through_write(1, 0x6720); - sub_through_write(1, 0x6824); - sub_through_write(1, 0x6928); - sub_through_write(1, 0x6A2B); - sub_through_write(1, 0x6B2E); - sub_through_write(1, 0x6C31); - sub_through_write(1, 0x6D34); - sub_through_write(1, 0x6E37); - sub_through_write(1, 0x6F3A); - sub_through_write(1, 0x703C); - sub_through_write(1, 0x713E); - sub_through_write(1, 0x723F); - sub_through_write(1, 0x7340); - sub_through_write(1, 0x7441); - sub_through_write(1, 0x7543); - sub_through_write(1, 0x7646); - sub_through_write(1, 0x7749); - sub_through_write(1, 0x784C); - sub_through_write(1, 0x794F); - sub_through_write(1, 0x7A52); - sub_through_write(1, 0x7B59); - sub_through_write(1, 0x7C60); - sub_through_write(1, 0x7D67); - sub_through_write(1, 0x7E6E); - sub_through_write(1, 0x7F7D); - - sub_through_write(1, 0x1851); /* Display on */ - - mddi_queue_register_write(REG_AGM, 0x0000, TRUE, 0); - - /* 1 pixel / 1 post clock */ - mddi_queue_register_write(REG_CLKDIV2, 0x3b00, FALSE, 0); - - /* SUB LCD select */ - mddi_queue_register_write(REG_PSTCTL2, 0x0080, FALSE, 0); - - /* RS=0,command initiate number=0,select master mode */ - mddi_queue_register_write(REG_SUBCTL, 0x0202, FALSE, 0); - - /* Sub LCD Data transform start */ - mddi_queue_register_write(REG_PSTCTL1, 0x0003, FALSE, 0); - - } else if (sharp_subpanel_type == SHARP_SUB_ROHM) { - - sub_through_write(0, 0x01); /* Display setting */ - sub_through_write(1, 0x00); - - mddi_wait(1); - /* Wait 100us <----- ******* Update 2005/01/24 */ - - sub_through_write(0, 0xB6); - sub_through_write(1, 0x0C); - sub_through_write(1, 0x4A); - sub_through_write(1, 0x20); - sub_through_write(0, 0x3A); - sub_through_write(1, 0x05); - sub_through_write(0, 0xB7); - sub_through_write(1, 0x01); - sub_through_write(0, 0xBA); - sub_through_write(1, 0x20); - sub_through_write(1, 0x02); - sub_through_write(0, 0x25); - sub_through_write(1, 0x4F); - sub_through_write(0, 0xBB); - sub_through_write(1, 0x00); - sub_through_write(0, 0x36); - sub_through_write(1, 0x00); - sub_through_write(0, 0xB1); - sub_through_write(1, 0x05); - sub_through_write(0, 0xBE); - sub_through_write(1, 0x80); - sub_through_write(0, 0x26); - sub_through_write(1, 0x01); - sub_through_write(0, 0x2A); - sub_through_write(1, 0x02); - sub_through_write(1, 0x81); - sub_through_write(0, 0x2B); - sub_through_write(1, 0x00); - sub_through_write(1, 0x7F); - - sub_through_write(0, 0x2C); - sub_through_write(0, 0x11); /* Sleep mode off */ - - mddi_wait(1); - /* Wait 100 ms <----- ******* Update 2005/01/24 */ - - sub_through_write(0, 0x29); /* Display on */ - sub_through_write(0, 0xB3); - sub_through_write(1, 0x20); - sub_through_write(1, 0xAA); - sub_through_write(1, 0xA0); - sub_through_write(1, 0x20); - sub_through_write(1, 0x30); - sub_through_write(1, 0xA6); - sub_through_write(1, 0xFF); - sub_through_write(1, 0x9A); - sub_through_write(1, 0x9F); - sub_through_write(1, 0xAF); - sub_through_write(1, 0xBC); - sub_through_write(1, 0xCF); - sub_through_write(1, 0xDF); - sub_through_write(1, 0x20); - sub_through_write(1, 0x9C); - sub_through_write(1, 0x8A); - - sub_through_write(0, 0x002C); /* Display on */ - - /* 1 pixel / 2 post clock */ - mddi_queue_register_write(REG_CLKDIV2, 0x7b00, FALSE, 0); - - /* SUB LCD select */ - mddi_queue_register_write(REG_PSTCTL2, 0x0080, FALSE, 0); - - /* RS=1,command initiate number=0,select master mode */ - mddi_queue_register_write(REG_SUBCTL, 0x0242, FALSE, 0); - - /* Sub LCD Data transform start */ - mddi_queue_register_write(REG_PSTCTL1, 0x0003, FALSE, 0); - - } - - /* Set the MDP pixel data attributes for Sub Display */ - mddi_host_write_pix_attr_reg(0x00C0); -} - -void mddi_sharp_lcd_vsync_detected(boolean detected) -{ - /* static timetick_type start_time = 0; */ - static struct timeval start_time; - static boolean first_time = TRUE; - /* uint32 mdp_cnt_val = 0; */ - /* timetick_type elapsed_us; */ - struct timeval now; - uint32 elapsed_us; - uint32 num_vsyncs; - - if ((detected) || (mddi_sharp_vsync_attempts > 5)) { - if ((detected) && (mddi_sharp_monitor_refresh_value)) { - /* if (start_time != 0) */ - if (!first_time) { - jiffies_to_timeval(jiffies, &now); - elapsed_us = - (now.tv_sec - start_time.tv_sec) * 1000000 + - now.tv_usec - start_time.tv_usec; - /* - * LCD is configured for a refresh every usecs, - * so to determine the number of vsyncs that - * have occurred since the last measurement add - * half that to the time difference and divide - * by the refresh rate. - */ - num_vsyncs = (elapsed_us + - (mddi_sharp_usecs_per_refresh >> - 1)) / - mddi_sharp_usecs_per_refresh; - /* - * LCD is configured for * hsyncs (rows) per - * refresh cycle. Calculate new rows_per_second - * value based upon these new measurements. - * MDP can update with this new value. - */ - mddi_sharp_rows_per_second = - (mddi_sharp_rows_per_refresh * 1000 * - num_vsyncs) / (elapsed_us / 1000); - } - /* start_time = timetick_get(); */ - first_time = FALSE; - jiffies_to_timeval(jiffies, &start_time); - if (mddi_sharp_report_refresh_measurements) { - /* mdp_cnt_val = MDP_LINE_COUNT; */ - } - } - /* if detected = TRUE, client initiated wakeup was detected */ - if (mddi_sharp_vsync_handler != NULL) { - (*mddi_sharp_vsync_handler) - (mddi_sharp_vsync_handler_arg); - mddi_sharp_vsync_handler = NULL; - } - mddi_vsync_detect_enabled = FALSE; - mddi_sharp_vsync_attempts = 0; - /* need to clear this vsync wakeup */ - if (!mddi_queue_register_write_int(REG_INTR, 0x0000)) { - MDDI_MSG_ERR("Vsync interrupt clear failed!\n"); - } - if (!detected) { - /* give up after 5 failed attempts but show error */ - MDDI_MSG_NOTICE("Vsync detection failed!\n"); - } else if ((mddi_sharp_monitor_refresh_value) && - (mddi_sharp_report_refresh_measurements)) { - MDDI_MSG_NOTICE(" Lines Per Second=%d!\n", - mddi_sharp_rows_per_second); - } - } else - /* if detected = FALSE, we woke up from hibernation, but did not - * detect client initiated wakeup. - */ - mddi_sharp_vsync_attempts++; -} - -/* ISR to be executed */ -void mddi_sharp_vsync_set_handler(msm_fb_vsync_handler_type handler, void *arg) -{ - boolean error = FALSE; - unsigned long flags; - - /* Disable interrupts */ - spin_lock_irqsave(&mddi_host_spin_lock, flags); - /* INTLOCK(); */ - - if (mddi_sharp_vsync_handler != NULL) - error = TRUE; - - /* Register the handler for this particular GROUP interrupt source */ - mddi_sharp_vsync_handler = handler; - mddi_sharp_vsync_handler_arg = arg; - - /* Restore interrupts */ - spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - /* INTFREE(); */ - - if (error) - MDDI_MSG_ERR("MDDI: Previous Vsync handler never called\n"); - - /* Enable the vsync wakeup */ - mddi_queue_register_write(REG_INTR, 0x8100, FALSE, 0); - - mddi_sharp_vsync_attempts = 1; - mddi_vsync_detect_enabled = TRUE; -} /* mddi_sharp_vsync_set_handler */ - -static int mddi_sharp_lcd_on(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - - mfd = platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - if (mfd->panel.id == SHARP_QVGA_PRIM) - mddi_sharp_prim_lcd_init(); - else - mddi_sharp_sub_lcd_init(); - - return 0; -} - -static int mddi_sharp_lcd_off(struct platform_device *pdev) -{ - mddi_sharp_lcd_powerdown(); - return 0; -} - -static int __init mddi_sharp_probe(struct platform_device *pdev) -{ - if (pdev->id == 0) { - mddi_sharp_pdata = pdev->dev.platform_data; - return 0; - } - - msm_fb_add_device(pdev); - - return 0; -} - -static struct platform_driver this_driver = { - .probe = mddi_sharp_probe, - .driver = { - .name = "mddi_sharp_qvga", - }, -}; - -static struct msm_fb_panel_data mddi_sharp_panel_data0 = { - .on = mddi_sharp_lcd_on, - .off = mddi_sharp_lcd_off, - .set_backlight = mddi_sharp_lcd_set_backlight, - .set_vsync_notifier = mddi_sharp_vsync_set_handler, -}; - -static struct platform_device this_device_0 = { - .name = "mddi_sharp_qvga", - .id = SHARP_QVGA_PRIM, - .dev = { - .platform_data = &mddi_sharp_panel_data0, - } -}; - -static struct msm_fb_panel_data mddi_sharp_panel_data1 = { - .on = mddi_sharp_lcd_on, - .off = mddi_sharp_lcd_off, -}; - -static struct platform_device this_device_1 = { - .name = "mddi_sharp_qvga", - .id = SHARP_128X128_SECD, - .dev = { - .platform_data = &mddi_sharp_panel_data1, - } -}; - -static int __init mddi_sharp_init(void) -{ - int ret; - struct msm_panel_info *pinfo; - -#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT - u32 id; - - ret = msm_fb_detect_client("mddi_sharp_qvga"); - if (ret == -ENODEV) - return 0; - - if (ret) { - id = mddi_get_client_id(); - - if (((id >> 16) != 0x0) || ((id & 0xffff) != 0x8835)) - return 0; - } -#endif - if (mddi_host_core_version > 8) { - /* can use faster refresh with newer hw revisions */ - mddi_sharp_debug_60hz_refresh = TRUE; - - /* Timing variables for tracking vsync */ - /* dot_clock = 6.00MHz - * horizontal count = 296 - * vertical count = 338 - * refresh rate = 6000000/(296+338) = 60Hz - */ - mddi_sharp_rows_per_second = 20270; /* 6000000/296 */ - mddi_sharp_rows_per_refresh = 338; - mddi_sharp_usecs_per_refresh = 16674; /* (296+338)/6000000 */ - } else { - /* Timing variables for tracking vsync */ - /* dot_clock = 5.20MHz - * horizontal count = 376 - * vertical count = 338 - * refresh rate = 5200000/(376+338) = 41Hz - */ - mddi_sharp_rows_per_second = 13830; /* 5200000/376 */ - mddi_sharp_rows_per_refresh = 338; - mddi_sharp_usecs_per_refresh = 24440; /* (376+338)/5200000 */ - } - - ret = platform_driver_register(&this_driver); - if (!ret) { - pinfo = &mddi_sharp_panel_data0.panel_info; - pinfo->xres = 240; - pinfo->yres = 320; - pinfo->type = MDDI_PANEL; - pinfo->pdest = DISPLAY_1; - pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR; - pinfo->wait_cycle = 0; - pinfo->bpp = 18; - pinfo->fb_num = 2; - pinfo->clk_rate = 122880000; - pinfo->clk_min = 120000000; - pinfo->clk_max = 125000000; - pinfo->lcd.vsync_enable = TRUE; - pinfo->lcd.refx100 = - (mddi_sharp_rows_per_second * 100) / - mddi_sharp_rows_per_refresh; - pinfo->lcd.v_back_porch = 12; - pinfo->lcd.v_front_porch = 6; - pinfo->lcd.v_pulse_width = 0; - pinfo->lcd.hw_vsync_mode = FALSE; - pinfo->lcd.vsync_notifier_period = (1 * HZ); - pinfo->bl_max = 7; - pinfo->bl_min = 1; - - ret = platform_device_register(&this_device_0); - if (ret) - platform_driver_unregister(&this_driver); - - pinfo = &mddi_sharp_panel_data1.panel_info; - pinfo->xres = 128; - pinfo->yres = 128; - pinfo->type = MDDI_PANEL; - pinfo->pdest = DISPLAY_2; - pinfo->mddi.vdopkt = 0x400; - pinfo->wait_cycle = 0; - pinfo->bpp = 18; - pinfo->clk_rate = 122880000; - pinfo->clk_min = 120000000; - pinfo->clk_max = 125000000; - pinfo->fb_num = 2; - - ret = platform_device_register(&this_device_1); - if (ret) { - platform_device_unregister(&this_device_0); - platform_driver_unregister(&this_driver); - } - } - - if (!ret) - mddi_lcd.vsync_detected = mddi_sharp_lcd_vsync_detected; - - return ret; -} - -module_init(mddi_sharp_init); diff --git a/drivers/staging/msm/mddi_toshiba.c b/drivers/staging/msm/mddi_toshiba.c deleted file mode 100644 index e96342d477a2..000000000000 --- a/drivers/staging/msm/mddi_toshiba.c +++ /dev/null @@ -1,1741 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "msm_fb.h" -#include "mddihost.h" -#include "mddihosti.h" -#include "mddi_toshiba.h" - -#define TM_GET_DID(id) ((id) & 0xff) -#define TM_GET_PID(id) (((id) & 0xff00)>>8) - -#define MDDI_CLIENT_CORE_BASE 0x108000 -#define LCD_CONTROL_BLOCK_BASE 0x110000 -#define SPI_BLOCK_BASE 0x120000 -#define PWM_BLOCK_BASE 0x140000 -#define SYSTEM_BLOCK1_BASE 0x160000 - -#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18) -#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C) -#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20) -#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24) -#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28) -#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C) - -#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44) -#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48) -#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C) -#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50) -#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54) - -#define SRST (LCD_CONTROL_BLOCK_BASE|0x00) -#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04) -#define START (LCD_CONTROL_BLOCK_BASE|0x08) -#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C) - -#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18) -#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C) -#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20) - -#define PXL (LCD_CONTROL_BLOCK_BASE|0x30) -#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34) -#define HSW (LCD_CONTROL_BLOCK_BASE|0x38) -#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C) -#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40) -#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44) -#define VSW (LCD_CONTROL_BLOCK_BASE|0x48) -#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C) -#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50) -#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54) -#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C) -#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60) -#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64) -#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68) -#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C) -#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70) -#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74) -#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78) -#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C) -#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80) -#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84) -#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88) -#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C) -#define MONI (LCD_CONTROL_BLOCK_BASE|0xB0) -#define VPOS (LCD_CONTROL_BLOCK_BASE|0xC0) - -#define SSICTL (SPI_BLOCK_BASE|0x00) -#define SSITIME (SPI_BLOCK_BASE|0x04) -#define SSITX (SPI_BLOCK_BASE|0x08) -#define SSIINTS (SPI_BLOCK_BASE|0x14) - -#define TIMER0LOAD (PWM_BLOCK_BASE|0x00) -#define TIMER0CTRL (PWM_BLOCK_BASE|0x08) -#define PWM0OFF (PWM_BLOCK_BASE|0x1C) -#define TIMER1LOAD (PWM_BLOCK_BASE|0x20) -#define TIMER1CTRL (PWM_BLOCK_BASE|0x28) -#define PWM1OFF (PWM_BLOCK_BASE|0x3C) -#define TIMER2LOAD (PWM_BLOCK_BASE|0x40) -#define TIMER2CTRL (PWM_BLOCK_BASE|0x48) -#define PWM2OFF (PWM_BLOCK_BASE|0x5C) -#define PWMCR (PWM_BLOCK_BASE|0x68) - -#define GPIOIS (GPIO_BLOCK_BASE|0x08) -#define GPIOIEV (GPIO_BLOCK_BASE|0x10) -#define GPIOIC (GPIO_BLOCK_BASE|0x20) - -#define WKREQ (SYSTEM_BLOCK1_BASE|0x00) -#define CLKENB (SYSTEM_BLOCK1_BASE|0x04) -#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08) -#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C) -#define CNT_DIS (SYSTEM_BLOCK1_BASE|0x10) - -typedef enum { - TOSHIBA_STATE_OFF, - TOSHIBA_STATE_PRIM_SEC_STANDBY, - TOSHIBA_STATE_PRIM_SEC_READY, - TOSHIBA_STATE_PRIM_NORMAL_MODE, - TOSHIBA_STATE_SEC_NORMAL_MODE -} mddi_toshiba_state_t; - -static uint32 mddi_toshiba_curr_vpos; -static boolean mddi_toshiba_monitor_refresh_value = FALSE; -static boolean mddi_toshiba_report_refresh_measurements = FALSE; - -boolean mddi_toshiba_61Hz_refresh = TRUE; - -/* Modifications to timing to increase refresh rate to > 60Hz. - * 20MHz dot clock. - * 646 total rows. - * 506 total columns. - * refresh rate = 61.19Hz - */ -static uint32 mddi_toshiba_rows_per_second = 39526; -static uint32 mddi_toshiba_usecs_per_refresh = 16344; -static uint32 mddi_toshiba_rows_per_refresh = 646; -extern boolean mddi_vsync_detect_enabled; - -static msm_fb_vsync_handler_type mddi_toshiba_vsync_handler; -static void *mddi_toshiba_vsync_handler_arg; -static uint16 mddi_toshiba_vsync_attempts; - -static mddi_toshiba_state_t toshiba_state = TOSHIBA_STATE_OFF; - -static struct msm_panel_common_pdata *mddi_toshiba_pdata; - -static int mddi_toshiba_lcd_on(struct platform_device *pdev); -static int mddi_toshiba_lcd_off(struct platform_device *pdev); - -static void mddi_toshiba_state_transition(mddi_toshiba_state_t a, - mddi_toshiba_state_t b) -{ - if (toshiba_state != a) { - MDDI_MSG_ERR("toshiba state trans. (%d->%d) found %d\n", a, b, - toshiba_state); - } - toshiba_state = b; -} - -#define GORDON_REG_IMGCTL1 0x10 /* Image interface control 1 */ -#define GORDON_REG_IMGCTL2 0x11 /* Image interface control 2 */ -#define GORDON_REG_IMGSET1 0x12 /* Image interface settings 1 */ -#define GORDON_REG_IMGSET2 0x13 /* Image interface settings 2 */ -#define GORDON_REG_IVBP1 0x14 /* DM0: Vert back porch */ -#define GORDON_REG_IHBP1 0x15 /* DM0: Horiz back porch */ -#define GORDON_REG_IVNUM1 0x16 /* DM0: Num of vert lines */ -#define GORDON_REG_IHNUM1 0x17 /* DM0: Num of pixels per line */ -#define GORDON_REG_IVBP2 0x18 /* DM1: Vert back porch */ -#define GORDON_REG_IHBP2 0x19 /* DM1: Horiz back porch */ -#define GORDON_REG_IVNUM2 0x1A /* DM1: Num of vert lines */ -#define GORDON_REG_IHNUM2 0x1B /* DM1: Num of pixels per line */ -#define GORDON_REG_LCDIFCTL1 0x30 /* LCD interface control 1 */ -#define GORDON_REG_VALTRAN 0x31 /* LCD IF ctl: VALTRAN sync flag */ -#define GORDON_REG_AVCTL 0x33 -#define GORDON_REG_LCDIFCTL2 0x34 /* LCD interface control 2 */ -#define GORDON_REG_LCDIFCTL3 0x35 /* LCD interface control 3 */ -#define GORDON_REG_LCDIFSET1 0x36 /* LCD interface settings 1 */ -#define GORDON_REG_PCCTL 0x3C -#define GORDON_REG_TPARAM1 0x40 -#define GORDON_REG_TLCDIF1 0x41 -#define GORDON_REG_TSSPB_ST1 0x42 -#define GORDON_REG_TSSPB_ED1 0x43 -#define GORDON_REG_TSCK_ST1 0x44 -#define GORDON_REG_TSCK_WD1 0x45 -#define GORDON_REG_TGSPB_VST1 0x46 -#define GORDON_REG_TGSPB_VED1 0x47 -#define GORDON_REG_TGSPB_CH1 0x48 -#define GORDON_REG_TGCK_ST1 0x49 -#define GORDON_REG_TGCK_ED1 0x4A -#define GORDON_REG_TPCTL_ST1 0x4B -#define GORDON_REG_TPCTL_ED1 0x4C -#define GORDON_REG_TPCHG_ED1 0x4D -#define GORDON_REG_TCOM_CH1 0x4E -#define GORDON_REG_THBP1 0x4F -#define GORDON_REG_TPHCTL1 0x50 -#define GORDON_REG_EVPH1 0x51 -#define GORDON_REG_EVPL1 0x52 -#define GORDON_REG_EVNH1 0x53 -#define GORDON_REG_EVNL1 0x54 -#define GORDON_REG_TBIAS1 0x55 -#define GORDON_REG_TPARAM2 0x56 -#define GORDON_REG_TLCDIF2 0x57 -#define GORDON_REG_TSSPB_ST2 0x58 -#define GORDON_REG_TSSPB_ED2 0x59 -#define GORDON_REG_TSCK_ST2 0x5A -#define GORDON_REG_TSCK_WD2 0x5B -#define GORDON_REG_TGSPB_VST2 0x5C -#define GORDON_REG_TGSPB_VED2 0x5D -#define GORDON_REG_TGSPB_CH2 0x5E -#define GORDON_REG_TGCK_ST2 0x5F -#define GORDON_REG_TGCK_ED2 0x60 -#define GORDON_REG_TPCTL_ST2 0x61 -#define GORDON_REG_TPCTL_ED2 0x62 -#define GORDON_REG_TPCHG_ED2 0x63 -#define GORDON_REG_TCOM_CH2 0x64 -#define GORDON_REG_THBP2 0x65 -#define GORDON_REG_TPHCTL2 0x66 -#define GORDON_REG_EVPH2 0x67 -#define GORDON_REG_EVPL2 0x68 -#define GORDON_REG_EVNH2 0x69 -#define GORDON_REG_EVNL2 0x6A -#define GORDON_REG_TBIAS2 0x6B -#define GORDON_REG_POWCTL 0x80 -#define GORDON_REG_POWOSC1 0x81 -#define GORDON_REG_POWOSC2 0x82 -#define GORDON_REG_POWSET 0x83 -#define GORDON_REG_POWTRM1 0x85 -#define GORDON_REG_POWTRM2 0x86 -#define GORDON_REG_POWTRM3 0x87 -#define GORDON_REG_POWTRMSEL 0x88 -#define GORDON_REG_POWHIZ 0x89 - -void serigo(uint16 reg, uint8 data) -{ - uint32 mddi_val = 0; - mddi_queue_register_read(SSIINTS, &mddi_val, TRUE, 0); - if (mddi_val & (1 << 8)) - mddi_wait(1); - /* No De-assert of CS and send 2 bytes */ - mddi_val = 0x90000 | ((0x00FF & reg) << 8) | data; - mddi_queue_register_write(SSITX, mddi_val, TRUE, 0); -} - -void gordon_init(void) -{ - /* Image interface settings ***/ - serigo(GORDON_REG_IMGCTL2, 0x00); - serigo(GORDON_REG_IMGSET1, 0x01); - - /* Exchange the RGB signal for J510(Softbank mobile) */ - serigo(GORDON_REG_IMGSET2, 0x12); - serigo(GORDON_REG_LCDIFSET1, 0x00); - mddi_wait(2); - - /* Pre-charge settings */ - serigo(GORDON_REG_PCCTL, 0x09); - serigo(GORDON_REG_LCDIFCTL2, 0x1B); - mddi_wait(1); -} - -void gordon_disp_on(void) -{ - /*gordon_dispmode setting */ - /*VGA settings */ - serigo(GORDON_REG_TPARAM1, 0x30); - serigo(GORDON_REG_TLCDIF1, 0x00); - serigo(GORDON_REG_TSSPB_ST1, 0x8B); - serigo(GORDON_REG_TSSPB_ED1, 0x93); - mddi_wait(2); - serigo(GORDON_REG_TSCK_ST1, 0x88); - serigo(GORDON_REG_TSCK_WD1, 0x00); - serigo(GORDON_REG_TGSPB_VST1, 0x01); - serigo(GORDON_REG_TGSPB_VED1, 0x02); - mddi_wait(2); - serigo(GORDON_REG_TGSPB_CH1, 0x5E); - serigo(GORDON_REG_TGCK_ST1, 0x80); - serigo(GORDON_REG_TGCK_ED1, 0x3C); - serigo(GORDON_REG_TPCTL_ST1, 0x50); - mddi_wait(2); - serigo(GORDON_REG_TPCTL_ED1, 0x74); - serigo(GORDON_REG_TPCHG_ED1, 0x78); - serigo(GORDON_REG_TCOM_CH1, 0x50); - serigo(GORDON_REG_THBP1, 0x84); - mddi_wait(2); - serigo(GORDON_REG_TPHCTL1, 0x00); - serigo(GORDON_REG_EVPH1, 0x70); - serigo(GORDON_REG_EVPL1, 0x64); - serigo(GORDON_REG_EVNH1, 0x56); - mddi_wait(2); - serigo(GORDON_REG_EVNL1, 0x48); - serigo(GORDON_REG_TBIAS1, 0x88); - mddi_wait(2); - serigo(GORDON_REG_TPARAM2, 0x28); - serigo(GORDON_REG_TLCDIF2, 0x14); - serigo(GORDON_REG_TSSPB_ST2, 0x49); - serigo(GORDON_REG_TSSPB_ED2, 0x4B); - mddi_wait(2); - serigo(GORDON_REG_TSCK_ST2, 0x4A); - serigo(GORDON_REG_TSCK_WD2, 0x02); - serigo(GORDON_REG_TGSPB_VST2, 0x02); - serigo(GORDON_REG_TGSPB_VED2, 0x03); - mddi_wait(2); - serigo(GORDON_REG_TGSPB_CH2, 0x2F); - serigo(GORDON_REG_TGCK_ST2, 0x40); - serigo(GORDON_REG_TGCK_ED2, 0x1E); - serigo(GORDON_REG_TPCTL_ST2, 0x2C); - mddi_wait(2); - serigo(GORDON_REG_TPCTL_ED2, 0x3A); - serigo(GORDON_REG_TPCHG_ED2, 0x3C); - serigo(GORDON_REG_TCOM_CH2, 0x28); - serigo(GORDON_REG_THBP2, 0x4D); - mddi_wait(2); - serigo(GORDON_REG_TPHCTL2, 0x1A); - mddi_wait(2); - serigo(GORDON_REG_IVBP1, 0x02); - serigo(GORDON_REG_IHBP1, 0x90); - serigo(GORDON_REG_IVNUM1, 0xA0); - serigo(GORDON_REG_IHNUM1, 0x78); - mddi_wait(2); - serigo(GORDON_REG_IVBP2, 0x02); - serigo(GORDON_REG_IHBP2, 0x48); - serigo(GORDON_REG_IVNUM2, 0x50); - serigo(GORDON_REG_IHNUM2, 0x3C); - mddi_wait(2); - serigo(GORDON_REG_POWCTL, 0x03); - mddi_wait(15); - serigo(GORDON_REG_POWCTL, 0x07); - mddi_wait(15); - serigo(GORDON_REG_POWCTL, 0x0F); - mddi_wait(15); - serigo(GORDON_REG_AVCTL, 0x03); - mddi_wait(15); - serigo(GORDON_REG_POWCTL, 0x1F); - mddi_wait(15); - serigo(GORDON_REG_POWCTL, 0x5F); - mddi_wait(15); - serigo(GORDON_REG_POWCTL, 0x7F); - mddi_wait(15); - serigo(GORDON_REG_LCDIFCTL1, 0x02); - mddi_wait(15); - serigo(GORDON_REG_IMGCTL1, 0x00); - mddi_wait(15); - serigo(GORDON_REG_LCDIFCTL3, 0x00); - mddi_wait(15); - serigo(GORDON_REG_VALTRAN, 0x01); - mddi_wait(15); - serigo(GORDON_REG_LCDIFCTL1, 0x03); - serigo(GORDON_REG_LCDIFCTL1, 0x03); - mddi_wait(1); -} - -void gordon_disp_off(void) -{ - serigo(GORDON_REG_LCDIFCTL2, 0x7B); - serigo(GORDON_REG_VALTRAN, 0x01); - serigo(GORDON_REG_LCDIFCTL1, 0x02); - serigo(GORDON_REG_LCDIFCTL3, 0x01); - mddi_wait(20); - serigo(GORDON_REG_VALTRAN, 0x01); - serigo(GORDON_REG_IMGCTL1, 0x01); - serigo(GORDON_REG_LCDIFCTL1, 0x00); - mddi_wait(20); - serigo(GORDON_REG_POWCTL, 0x1F); - mddi_wait(40); - serigo(GORDON_REG_POWCTL, 0x07); - mddi_wait(40); - serigo(GORDON_REG_POWCTL, 0x03); - mddi_wait(40); - serigo(GORDON_REG_POWCTL, 0x00); - mddi_wait(40); -} - -void gordon_disp_init(void) -{ - gordon_init(); - mddi_wait(20); - gordon_disp_on(); -} - -static void toshiba_common_initial_setup(struct msm_fb_data_type *mfd) -{ - if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT) { - write_client_reg(DPSET0 , 0x4bec0066, TRUE); - write_client_reg(DPSET1 , 0x00000113, TRUE); - write_client_reg(DPSUS , 0x00000000, TRUE); - write_client_reg(DPRUN , 0x00000001, TRUE); - mddi_wait(5); - write_client_reg(SYSCKENA , 0x00000001, TRUE); - write_client_reg(CLKENB , 0x0000a0e9, TRUE); - - write_client_reg(GPIODATA , 0x03FF0000, TRUE); - write_client_reg(GPIODIR , 0x0000024D, TRUE); - write_client_reg(GPIOSEL , 0x00000173, TRUE); - write_client_reg(GPIOPC , 0x03C300C0, TRUE); - write_client_reg(WKREQ , 0x00000000, TRUE); - write_client_reg(GPIOIS , 0x00000000, TRUE); - write_client_reg(GPIOIEV , 0x00000001, TRUE); - write_client_reg(GPIOIC , 0x000003FF, TRUE); - write_client_reg(GPIODATA , 0x00040004, TRUE); - - write_client_reg(GPIODATA , 0x00080008, TRUE); - write_client_reg(DRAMPWR , 0x00000001, TRUE); - write_client_reg(CLKENB , 0x0000a0eb, TRUE); - write_client_reg(PWMCR , 0x00000000, TRUE); - mddi_wait(1); - - write_client_reg(SSICTL , 0x00060399, TRUE); - write_client_reg(SSITIME , 0x00000100, TRUE); - write_client_reg(CNT_DIS , 0x00000002, TRUE); - write_client_reg(SSICTL , 0x0006039b, TRUE); - - write_client_reg(SSITX , 0x00000000, TRUE); - mddi_wait(7); - write_client_reg(SSITX , 0x00000000, TRUE); - mddi_wait(7); - write_client_reg(SSITX , 0x00000000, TRUE); - mddi_wait(7); - - write_client_reg(SSITX , 0x000800BA, TRUE); - write_client_reg(SSITX , 0x00000111, TRUE); - write_client_reg(SSITX , 0x00080036, TRUE); - write_client_reg(SSITX , 0x00000100, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x0008003A, TRUE); - write_client_reg(SSITX , 0x00000160, TRUE); - write_client_reg(SSITX , 0x000800B1, TRUE); - write_client_reg(SSITX , 0x0000015D, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800B2, TRUE); - write_client_reg(SSITX , 0x00000133, TRUE); - write_client_reg(SSITX , 0x000800B3, TRUE); - write_client_reg(SSITX , 0x00000122, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800B4, TRUE); - write_client_reg(SSITX , 0x00000102, TRUE); - write_client_reg(SSITX , 0x000800B5, TRUE); - write_client_reg(SSITX , 0x0000011E, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800B6, TRUE); - write_client_reg(SSITX , 0x00000127, TRUE); - write_client_reg(SSITX , 0x000800B7, TRUE); - write_client_reg(SSITX , 0x00000103, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800B9, TRUE); - write_client_reg(SSITX , 0x00000124, TRUE); - write_client_reg(SSITX , 0x000800BD, TRUE); - write_client_reg(SSITX , 0x000001A1, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800BB, TRUE); - write_client_reg(SSITX , 0x00000100, TRUE); - write_client_reg(SSITX , 0x000800BF, TRUE); - write_client_reg(SSITX , 0x00000101, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800BE, TRUE); - write_client_reg(SSITX , 0x00000100, TRUE); - write_client_reg(SSITX , 0x000800C0, TRUE); - write_client_reg(SSITX , 0x00000111, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800C1, TRUE); - write_client_reg(SSITX , 0x00000111, TRUE); - write_client_reg(SSITX , 0x000800C2, TRUE); - write_client_reg(SSITX , 0x00000111, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800C3, TRUE); - write_client_reg(SSITX , 0x00080132, TRUE); - write_client_reg(SSITX , 0x00000132, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800C4, TRUE); - write_client_reg(SSITX , 0x00080132, TRUE); - write_client_reg(SSITX , 0x00000132, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800C5, TRUE); - write_client_reg(SSITX , 0x00080132, TRUE); - write_client_reg(SSITX , 0x00000132, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800C6, TRUE); - write_client_reg(SSITX , 0x00080132, TRUE); - write_client_reg(SSITX , 0x00000132, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800C7, TRUE); - write_client_reg(SSITX , 0x00080164, TRUE); - write_client_reg(SSITX , 0x00000145, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800C8, TRUE); - write_client_reg(SSITX , 0x00000144, TRUE); - write_client_reg(SSITX , 0x000800C9, TRUE); - write_client_reg(SSITX , 0x00000152, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800CA, TRUE); - write_client_reg(SSITX , 0x00000100, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800EC, TRUE); - write_client_reg(SSITX , 0x00080101, TRUE); - write_client_reg(SSITX , 0x000001FC, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800CF, TRUE); - write_client_reg(SSITX , 0x00000101, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800D0, TRUE); - write_client_reg(SSITX , 0x00080110, TRUE); - write_client_reg(SSITX , 0x00000104, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800D1, TRUE); - write_client_reg(SSITX , 0x00000101, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800D2, TRUE); - write_client_reg(SSITX , 0x00080100, TRUE); - write_client_reg(SSITX , 0x00000128, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800D3, TRUE); - write_client_reg(SSITX , 0x00080100, TRUE); - write_client_reg(SSITX , 0x00000128, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800D4, TRUE); - write_client_reg(SSITX , 0x00080126, TRUE); - write_client_reg(SSITX , 0x000001A4, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800D5, TRUE); - write_client_reg(SSITX , 0x00000120, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800EF, TRUE); - write_client_reg(SSITX , 0x00080132, TRUE); - write_client_reg(SSITX , 0x00000100, TRUE); - mddi_wait(1); - - write_client_reg(BITMAP0 , 0x032001E0, TRUE); - write_client_reg(BITMAP1 , 0x032001E0, TRUE); - write_client_reg(BITMAP2 , 0x014000F0, TRUE); - write_client_reg(BITMAP3 , 0x014000F0, TRUE); - write_client_reg(BITMAP4 , 0x014000F0, TRUE); - write_client_reg(CLKENB , 0x0000A1EB, TRUE); - write_client_reg(PORT_ENB , 0x00000001, TRUE); - write_client_reg(PORT , 0x00000004, TRUE); - write_client_reg(PXL , 0x00000002, TRUE); - write_client_reg(MPLFBUF , 0x00000000, TRUE); - write_client_reg(HCYCLE , 0x000000FD, TRUE); - write_client_reg(HSW , 0x00000003, TRUE); - write_client_reg(HDE_START , 0x00000007, TRUE); - write_client_reg(HDE_SIZE , 0x000000EF, TRUE); - write_client_reg(VCYCLE , 0x00000325, TRUE); - write_client_reg(VSW , 0x00000001, TRUE); - write_client_reg(VDE_START , 0x00000003, TRUE); - write_client_reg(VDE_SIZE , 0x0000031F, TRUE); - write_client_reg(START , 0x00000001, TRUE); - mddi_wait(32); - write_client_reg(SSITX , 0x000800BC, TRUE); - write_client_reg(SSITX , 0x00000180, TRUE); - write_client_reg(SSITX , 0x0008003B, TRUE); - write_client_reg(SSITX , 0x00000100, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800B0, TRUE); - write_client_reg(SSITX , 0x00000116, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x000800B8, TRUE); - write_client_reg(SSITX , 0x000801FF, TRUE); - write_client_reg(SSITX , 0x000001F5, TRUE); - mddi_wait(1); - write_client_reg(SSITX , 0x00000011, TRUE); - mddi_wait(5); - write_client_reg(SSITX , 0x00000029, TRUE); - return; - } - - if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) { - write_client_reg(DPSET0, 0x4BEC0066, TRUE); - write_client_reg(DPSET1, 0x00000113, TRUE); - write_client_reg(DPSUS, 0x00000000, TRUE); - write_client_reg(DPRUN, 0x00000001, TRUE); - mddi_wait(14); - write_client_reg(SYSCKENA, 0x00000001, TRUE); - write_client_reg(CLKENB, 0x000000EF, TRUE); - write_client_reg(GPIO_BLOCK_BASE, 0x03FF0000, TRUE); - write_client_reg(GPIODIR, 0x0000024D, TRUE); - write_client_reg(SYSTEM_BLOCK2_BASE, 0x00000173, TRUE); - write_client_reg(GPIOPC, 0x03C300C0, TRUE); - write_client_reg(SYSTEM_BLOCK1_BASE, 0x00000000, TRUE); - write_client_reg(GPIOIS, 0x00000000, TRUE); - write_client_reg(GPIOIEV, 0x00000001, TRUE); - write_client_reg(GPIOIC, 0x000003FF, TRUE); - write_client_reg(GPIO_BLOCK_BASE, 0x00060006, TRUE); - write_client_reg(GPIO_BLOCK_BASE, 0x00080008, TRUE); - write_client_reg(GPIO_BLOCK_BASE, 0x02000200, TRUE); - write_client_reg(DRAMPWR, 0x00000001, TRUE); - write_client_reg(TIMER0CTRL, 0x00000060, TRUE); - write_client_reg(PWM_BLOCK_BASE, 0x00001388, TRUE); - write_client_reg(PWM0OFF, 0x00001387, TRUE); - write_client_reg(TIMER1CTRL, 0x00000060, TRUE); - write_client_reg(TIMER1LOAD, 0x00001388, TRUE); - write_client_reg(PWM1OFF, 0x00001387, TRUE); - write_client_reg(TIMER0CTRL, 0x000000E0, TRUE); - write_client_reg(TIMER1CTRL, 0x000000E0, TRUE); - write_client_reg(PWMCR, 0x00000003, TRUE); - mddi_wait(1); - write_client_reg(SPI_BLOCK_BASE, 0x00063111, TRUE); - write_client_reg(SSITIME, 0x00000100, TRUE); - write_client_reg(SPI_BLOCK_BASE, 0x00063113, TRUE); - mddi_wait(1); - write_client_reg(SSITX, 0x00000000, TRUE); - mddi_wait(1); - write_client_reg(SSITX, 0x00000000, TRUE); - mddi_wait(1); - write_client_reg(SSITX, 0x00000000, TRUE); - mddi_wait(1); - write_client_reg(CLKENB, 0x0000A1EF, TRUE); - write_client_reg(START, 0x00000000, TRUE); - write_client_reg(WRSTB, 0x0000003F, TRUE); - write_client_reg(RDSTB, 0x00000432, TRUE); - write_client_reg(PORT_ENB, 0x00000002, TRUE); - write_client_reg(VSYNIF, 0x00000000, TRUE); - write_client_reg(ASY_DATA, 0x80000000, TRUE); - write_client_reg(ASY_DATB, 0x00000001, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(10); - write_client_reg(ASY_DATA, 0x80000000, TRUE); - write_client_reg(ASY_DATB, 0x80000000, TRUE); - write_client_reg(ASY_DATC, 0x80000000, TRUE); - write_client_reg(ASY_DATD, 0x80000000, TRUE); - write_client_reg(ASY_CMDSET, 0x00000009, TRUE); - write_client_reg(ASY_CMDSET, 0x00000008, TRUE); - write_client_reg(ASY_DATA, 0x80000007, TRUE); - write_client_reg(ASY_DATB, 0x00004005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(20); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x00000000, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - - write_client_reg(VSYNIF, 0x00000001, TRUE); - write_client_reg(PORT_ENB, 0x00000001, TRUE); - } else { - write_client_reg(DPSET0, 0x4BEC0066, TRUE); - write_client_reg(DPSET1, 0x00000113, TRUE); - write_client_reg(DPSUS, 0x00000000, TRUE); - write_client_reg(DPRUN, 0x00000001, TRUE); - mddi_wait(14); - write_client_reg(SYSCKENA, 0x00000001, TRUE); - write_client_reg(CLKENB, 0x000000EF, TRUE); - write_client_reg(GPIODATA, 0x03FF0000, TRUE); - write_client_reg(GPIODIR, 0x0000024D, TRUE); - write_client_reg(GPIOSEL, 0x00000173, TRUE); - write_client_reg(GPIOPC, 0x03C300C0, TRUE); - write_client_reg(WKREQ, 0x00000000, TRUE); - write_client_reg(GPIOIS, 0x00000000, TRUE); - write_client_reg(GPIOIEV, 0x00000001, TRUE); - write_client_reg(GPIOIC, 0x000003FF, TRUE); - write_client_reg(GPIODATA, 0x00060006, TRUE); - write_client_reg(GPIODATA, 0x00080008, TRUE); - write_client_reg(GPIODATA, 0x02000200, TRUE); - - if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA) { - mddi_wait(400); - write_client_reg(DRAMPWR, 0x00000001, TRUE); - - write_client_reg(CNT_DIS, 0x00000002, TRUE); - write_client_reg(BITMAP0, 0x01E00320, TRUE); - write_client_reg(PORT_ENB, 0x00000001, TRUE); - write_client_reg(PORT, 0x00000004, TRUE); - write_client_reg(PXL, 0x0000003A, TRUE); - write_client_reg(MPLFBUF, 0x00000000, TRUE); - write_client_reg(HCYCLE, 0x00000253, TRUE); - write_client_reg(HSW, 0x00000003, TRUE); - write_client_reg(HDE_START, 0x00000017, TRUE); - write_client_reg(HDE_SIZE, 0x0000018F, TRUE); - write_client_reg(VCYCLE, 0x000001FF, TRUE); - write_client_reg(VSW, 0x00000001, TRUE); - write_client_reg(VDE_START, 0x00000003, TRUE); - write_client_reg(VDE_SIZE, 0x000001DF, TRUE); - write_client_reg(START, 0x00000001, TRUE); - mddi_wait(1); - write_client_reg(TIMER0CTRL, 0x00000060, TRUE); - write_client_reg(TIMER0LOAD, 0x00001388, TRUE); - write_client_reg(TIMER1CTRL, 0x00000060, TRUE); - write_client_reg(TIMER1LOAD, 0x00001388, TRUE); - write_client_reg(PWM1OFF, 0x00000087, TRUE); - } else { - write_client_reg(DRAMPWR, 0x00000001, TRUE); - write_client_reg(TIMER0CTRL, 0x00000060, TRUE); - write_client_reg(TIMER0LOAD, 0x00001388, TRUE); - write_client_reg(TIMER1CTRL, 0x00000060, TRUE); - write_client_reg(TIMER1LOAD, 0x00001388, TRUE); - write_client_reg(PWM1OFF, 0x00001387, TRUE); - } - - write_client_reg(TIMER0CTRL, 0x000000E0, TRUE); - write_client_reg(TIMER1CTRL, 0x000000E0, TRUE); - write_client_reg(PWMCR, 0x00000003, TRUE); - mddi_wait(1); - write_client_reg(SSICTL, 0x00000799, TRUE); - write_client_reg(SSITIME, 0x00000100, TRUE); - write_client_reg(SSICTL, 0x0000079b, TRUE); - write_client_reg(SSITX, 0x00000000, TRUE); - mddi_wait(1); - write_client_reg(SSITX, 0x00000000, TRUE); - mddi_wait(1); - write_client_reg(SSITX, 0x00000000, TRUE); - mddi_wait(1); - write_client_reg(SSITX, 0x000800BA, TRUE); - write_client_reg(SSITX, 0x00000111, TRUE); - write_client_reg(SSITX, 0x00080036, TRUE); - write_client_reg(SSITX, 0x00000100, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800BB, TRUE); - write_client_reg(SSITX, 0x00000100, TRUE); - write_client_reg(SSITX, 0x0008003A, TRUE); - write_client_reg(SSITX, 0x00000160, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800BF, TRUE); - write_client_reg(SSITX, 0x00000100, TRUE); - write_client_reg(SSITX, 0x000800B1, TRUE); - write_client_reg(SSITX, 0x0000015D, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800B2, TRUE); - write_client_reg(SSITX, 0x00000133, TRUE); - write_client_reg(SSITX, 0x000800B3, TRUE); - write_client_reg(SSITX, 0x00000122, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800B4, TRUE); - write_client_reg(SSITX, 0x00000102, TRUE); - write_client_reg(SSITX, 0x000800B5, TRUE); - write_client_reg(SSITX, 0x0000011F, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800B6, TRUE); - write_client_reg(SSITX, 0x00000128, TRUE); - write_client_reg(SSITX, 0x000800B7, TRUE); - write_client_reg(SSITX, 0x00000103, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800B9, TRUE); - write_client_reg(SSITX, 0x00000120, TRUE); - write_client_reg(SSITX, 0x000800BD, TRUE); - write_client_reg(SSITX, 0x00000102, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800BE, TRUE); - write_client_reg(SSITX, 0x00000100, TRUE); - write_client_reg(SSITX, 0x000800C0, TRUE); - write_client_reg(SSITX, 0x00000111, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800C1, TRUE); - write_client_reg(SSITX, 0x00000111, TRUE); - write_client_reg(SSITX, 0x000800C2, TRUE); - write_client_reg(SSITX, 0x00000111, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800C3, TRUE); - write_client_reg(SSITX, 0x0008010A, TRUE); - write_client_reg(SSITX, 0x0000010A, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800C4, TRUE); - write_client_reg(SSITX, 0x00080160, TRUE); - write_client_reg(SSITX, 0x00000160, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800C5, TRUE); - write_client_reg(SSITX, 0x00080160, TRUE); - write_client_reg(SSITX, 0x00000160, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800C6, TRUE); - write_client_reg(SSITX, 0x00080160, TRUE); - write_client_reg(SSITX, 0x00000160, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800C7, TRUE); - write_client_reg(SSITX, 0x00080133, TRUE); - write_client_reg(SSITX, 0x00000143, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800C8, TRUE); - write_client_reg(SSITX, 0x00000144, TRUE); - write_client_reg(SSITX, 0x000800C9, TRUE); - write_client_reg(SSITX, 0x00000133, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800CA, TRUE); - write_client_reg(SSITX, 0x00000100, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800EC, TRUE); - write_client_reg(SSITX, 0x00080102, TRUE); - write_client_reg(SSITX, 0x00000118, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800CF, TRUE); - write_client_reg(SSITX, 0x00000101, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800D0, TRUE); - write_client_reg(SSITX, 0x00080110, TRUE); - write_client_reg(SSITX, 0x00000104, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800D1, TRUE); - write_client_reg(SSITX, 0x00000101, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800D2, TRUE); - write_client_reg(SSITX, 0x00080100, TRUE); - write_client_reg(SSITX, 0x0000013A, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800D3, TRUE); - write_client_reg(SSITX, 0x00080100, TRUE); - write_client_reg(SSITX, 0x0000013A, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800D4, TRUE); - write_client_reg(SSITX, 0x00080124, TRUE); - write_client_reg(SSITX, 0x0000016E, TRUE); - mddi_wait(1); - write_client_reg(SSITX, 0x000800D5, TRUE); - write_client_reg(SSITX, 0x00000124, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800ED, TRUE); - write_client_reg(SSITX, 0x00080101, TRUE); - write_client_reg(SSITX, 0x0000010A, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800D6, TRUE); - write_client_reg(SSITX, 0x00000101, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800D7, TRUE); - write_client_reg(SSITX, 0x00080110, TRUE); - write_client_reg(SSITX, 0x0000010A, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800D8, TRUE); - write_client_reg(SSITX, 0x00000101, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800D9, TRUE); - write_client_reg(SSITX, 0x00080100, TRUE); - write_client_reg(SSITX, 0x00000114, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800DE, TRUE); - write_client_reg(SSITX, 0x00080100, TRUE); - write_client_reg(SSITX, 0x00000114, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800DF, TRUE); - write_client_reg(SSITX, 0x00080112, TRUE); - write_client_reg(SSITX, 0x0000013F, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800E0, TRUE); - write_client_reg(SSITX, 0x0000010B, TRUE); - write_client_reg(SSITX, 0x000800E2, TRUE); - write_client_reg(SSITX, 0x00000101, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800E3, TRUE); - write_client_reg(SSITX, 0x00000136, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800E4, TRUE); - write_client_reg(SSITX, 0x00080100, TRUE); - write_client_reg(SSITX, 0x00000103, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800E5, TRUE); - write_client_reg(SSITX, 0x00080102, TRUE); - write_client_reg(SSITX, 0x00000104, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800E6, TRUE); - write_client_reg(SSITX, 0x00000103, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800E7, TRUE); - write_client_reg(SSITX, 0x00080104, TRUE); - write_client_reg(SSITX, 0x0000010A, TRUE); - mddi_wait(2); - write_client_reg(SSITX, 0x000800E8, TRUE); - write_client_reg(SSITX, 0x00000104, TRUE); - write_client_reg(CLKENB, 0x000001EF, TRUE); - write_client_reg(START, 0x00000000, TRUE); - write_client_reg(WRSTB, 0x0000003F, TRUE); - write_client_reg(RDSTB, 0x00000432, TRUE); - write_client_reg(PORT_ENB, 0x00000002, TRUE); - write_client_reg(VSYNIF, 0x00000000, TRUE); - write_client_reg(ASY_DATA, 0x80000000, TRUE); - write_client_reg(ASY_DATB, 0x00000001, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(10); - write_client_reg(ASY_DATA, 0x80000000, TRUE); - write_client_reg(ASY_DATB, 0x80000000, TRUE); - write_client_reg(ASY_DATC, 0x80000000, TRUE); - write_client_reg(ASY_DATD, 0x80000000, TRUE); - write_client_reg(ASY_CMDSET, 0x00000009, TRUE); - write_client_reg(ASY_CMDSET, 0x00000008, TRUE); - write_client_reg(ASY_DATA, 0x80000007, TRUE); - write_client_reg(ASY_DATB, 0x00004005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(20); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x00000000, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - write_client_reg(VSYNIF, 0x00000001, TRUE); - write_client_reg(PORT_ENB, 0x00000001, TRUE); - } - - mddi_toshiba_state_transition(TOSHIBA_STATE_PRIM_SEC_STANDBY, - TOSHIBA_STATE_PRIM_SEC_READY); -} - -static void toshiba_prim_start(struct msm_fb_data_type *mfd) -{ - if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT) - return; - - if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) { - write_client_reg(BITMAP1, 0x01E000F0, TRUE); - write_client_reg(BITMAP2, 0x01E000F0, TRUE); - write_client_reg(BITMAP3, 0x01E000F0, TRUE); - write_client_reg(BITMAP4, 0x00DC00B0, TRUE); - write_client_reg(CLKENB, 0x000001EF, TRUE); - write_client_reg(PORT_ENB, 0x00000001, TRUE); - write_client_reg(PORT, 0x00000016, TRUE); - write_client_reg(PXL, 0x00000002, TRUE); - write_client_reg(MPLFBUF, 0x00000000, TRUE); - write_client_reg(HCYCLE, 0x00000185, TRUE); - write_client_reg(HSW, 0x00000018, TRUE); - write_client_reg(HDE_START, 0x0000004A, TRUE); - write_client_reg(HDE_SIZE, 0x000000EF, TRUE); - write_client_reg(VCYCLE, 0x0000028E, TRUE); - write_client_reg(VSW, 0x00000004, TRUE); - write_client_reg(VDE_START, 0x00000009, TRUE); - write_client_reg(VDE_SIZE, 0x0000027F, TRUE); - write_client_reg(START, 0x00000001, TRUE); - write_client_reg(SYSTEM_BLOCK1_BASE, 0x00000002, TRUE); - } else{ - - write_client_reg(VSYNIF, 0x00000001, TRUE); - write_client_reg(PORT_ENB, 0x00000001, TRUE); - write_client_reg(BITMAP1, 0x01E000F0, TRUE); - write_client_reg(BITMAP2, 0x01E000F0, TRUE); - write_client_reg(BITMAP3, 0x01E000F0, TRUE); - write_client_reg(BITMAP4, 0x00DC00B0, TRUE); - write_client_reg(CLKENB, 0x000001EF, TRUE); - write_client_reg(PORT_ENB, 0x00000001, TRUE); - write_client_reg(PORT, 0x00000004, TRUE); - write_client_reg(PXL, 0x00000002, TRUE); - write_client_reg(MPLFBUF, 0x00000000, TRUE); - - if (mddi_toshiba_61Hz_refresh) { - write_client_reg(HCYCLE, 0x000000FC, TRUE); - mddi_toshiba_rows_per_second = 39526; - mddi_toshiba_rows_per_refresh = 646; - mddi_toshiba_usecs_per_refresh = 16344; - } else { - write_client_reg(HCYCLE, 0x0000010b, TRUE); - mddi_toshiba_rows_per_second = 37313; - mddi_toshiba_rows_per_refresh = 646; - mddi_toshiba_usecs_per_refresh = 17313; - } - - write_client_reg(HSW, 0x00000003, TRUE); - write_client_reg(HDE_START, 0x00000007, TRUE); - write_client_reg(HDE_SIZE, 0x000000EF, TRUE); - write_client_reg(VCYCLE, 0x00000285, TRUE); - write_client_reg(VSW, 0x00000001, TRUE); - write_client_reg(VDE_START, 0x00000003, TRUE); - write_client_reg(VDE_SIZE, 0x0000027F, TRUE); - write_client_reg(START, 0x00000001, TRUE); - mddi_wait(10); - write_client_reg(SSITX, 0x000800BC, TRUE); - write_client_reg(SSITX, 0x00000180, TRUE); - write_client_reg(SSITX, 0x0008003B, TRUE); - write_client_reg(SSITX, 0x00000100, TRUE); - mddi_wait(1); - write_client_reg(SSITX, 0x000800B0, TRUE); - write_client_reg(SSITX, 0x00000116, TRUE); - mddi_wait(1); - write_client_reg(SSITX, 0x000800B8, TRUE); - write_client_reg(SSITX, 0x000801FF, TRUE); - write_client_reg(SSITX, 0x000001F5, TRUE); - mddi_wait(1); - write_client_reg(SSITX, 0x00000011, TRUE); - write_client_reg(SSITX, 0x00000029, TRUE); - write_client_reg(WKREQ, 0x00000000, TRUE); - write_client_reg(WAKEUP, 0x00000000, TRUE); - write_client_reg(INTMSK, 0x00000001, TRUE); - } - - mddi_toshiba_state_transition(TOSHIBA_STATE_PRIM_SEC_READY, - TOSHIBA_STATE_PRIM_NORMAL_MODE); -} - -static void toshiba_sec_start(struct msm_fb_data_type *mfd) -{ - if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT) - return; - - write_client_reg(VSYNIF, 0x00000000, TRUE); - write_client_reg(PORT_ENB, 0x00000002, TRUE); - write_client_reg(CLKENB, 0x000011EF, TRUE); - write_client_reg(BITMAP0, 0x028001E0, TRUE); - write_client_reg(BITMAP1, 0x00000000, TRUE); - write_client_reg(BITMAP2, 0x00000000, TRUE); - write_client_reg(BITMAP3, 0x00000000, TRUE); - write_client_reg(BITMAP4, 0x00DC00B0, TRUE); - write_client_reg(PORT, 0x00000000, TRUE); - write_client_reg(PXL, 0x00000000, TRUE); - write_client_reg(MPLFBUF, 0x00000004, TRUE); - write_client_reg(HCYCLE, 0x0000006B, TRUE); - write_client_reg(HSW, 0x00000003, TRUE); - write_client_reg(HDE_START, 0x00000007, TRUE); - write_client_reg(HDE_SIZE, 0x00000057, TRUE); - write_client_reg(VCYCLE, 0x000000E6, TRUE); - write_client_reg(VSW, 0x00000001, TRUE); - write_client_reg(VDE_START, 0x00000003, TRUE); - write_client_reg(VDE_SIZE, 0x000000DB, TRUE); - write_client_reg(ASY_DATA, 0x80000001, TRUE); - write_client_reg(ASY_DATB, 0x0000011B, TRUE); - write_client_reg(ASY_DATC, 0x80000002, TRUE); - write_client_reg(ASY_DATD, 0x00000700, TRUE); - write_client_reg(ASY_DATE, 0x80000003, TRUE); - write_client_reg(ASY_DATF, 0x00000230, TRUE); - write_client_reg(ASY_DATG, 0x80000008, TRUE); - write_client_reg(ASY_DATH, 0x00000402, TRUE); - write_client_reg(ASY_CMDSET, 0x00000001, TRUE); - write_client_reg(ASY_CMDSET, 0x00000000, TRUE); - write_client_reg(ASY_DATA, 0x80000009, TRUE); - write_client_reg(ASY_DATB, 0x00000000, TRUE); - write_client_reg(ASY_DATC, 0x8000000B, TRUE); - write_client_reg(ASY_DATD, 0x00000000, TRUE); - write_client_reg(ASY_DATE, 0x8000000C, TRUE); - write_client_reg(ASY_DATF, 0x00000000, TRUE); - write_client_reg(ASY_DATG, 0x8000000D, TRUE); - write_client_reg(ASY_DATH, 0x00000409, TRUE); - write_client_reg(ASY_CMDSET, 0x00000001, TRUE); - write_client_reg(ASY_CMDSET, 0x00000000, TRUE); - write_client_reg(ASY_DATA, 0x8000000E, TRUE); - write_client_reg(ASY_DATB, 0x00000409, TRUE); - write_client_reg(ASY_DATC, 0x80000030, TRUE); - write_client_reg(ASY_DATD, 0x00000000, TRUE); - write_client_reg(ASY_DATE, 0x80000031, TRUE); - write_client_reg(ASY_DATF, 0x00000100, TRUE); - write_client_reg(ASY_DATG, 0x80000032, TRUE); - write_client_reg(ASY_DATH, 0x00000104, TRUE); - write_client_reg(ASY_CMDSET, 0x00000001, TRUE); - write_client_reg(ASY_CMDSET, 0x00000000, TRUE); - write_client_reg(ASY_DATA, 0x80000033, TRUE); - write_client_reg(ASY_DATB, 0x00000400, TRUE); - write_client_reg(ASY_DATC, 0x80000034, TRUE); - write_client_reg(ASY_DATD, 0x00000306, TRUE); - write_client_reg(ASY_DATE, 0x80000035, TRUE); - write_client_reg(ASY_DATF, 0x00000706, TRUE); - write_client_reg(ASY_DATG, 0x80000036, TRUE); - write_client_reg(ASY_DATH, 0x00000707, TRUE); - write_client_reg(ASY_CMDSET, 0x00000001, TRUE); - write_client_reg(ASY_CMDSET, 0x00000000, TRUE); - write_client_reg(ASY_DATA, 0x80000037, TRUE); - write_client_reg(ASY_DATB, 0x00000004, TRUE); - write_client_reg(ASY_DATC, 0x80000038, TRUE); - write_client_reg(ASY_DATD, 0x00000000, TRUE); - write_client_reg(ASY_DATE, 0x80000039, TRUE); - write_client_reg(ASY_DATF, 0x00000000, TRUE); - write_client_reg(ASY_DATG, 0x8000003A, TRUE); - write_client_reg(ASY_DATH, 0x00000001, TRUE); - write_client_reg(ASY_CMDSET, 0x00000001, TRUE); - write_client_reg(ASY_CMDSET, 0x00000000, TRUE); - write_client_reg(ASY_DATA, 0x80000044, TRUE); - write_client_reg(ASY_DATB, 0x0000AF00, TRUE); - write_client_reg(ASY_DATC, 0x80000045, TRUE); - write_client_reg(ASY_DATD, 0x0000DB00, TRUE); - write_client_reg(ASY_DATE, 0x08000042, TRUE); - write_client_reg(ASY_DATF, 0x0000DB00, TRUE); - write_client_reg(ASY_DATG, 0x80000021, TRUE); - write_client_reg(ASY_DATH, 0x00000000, TRUE); - write_client_reg(ASY_CMDSET, 0x00000001, TRUE); - write_client_reg(ASY_CMDSET, 0x00000000, TRUE); - write_client_reg(PXL, 0x0000000C, TRUE); - write_client_reg(VSYNIF, 0x00000001, TRUE); - write_client_reg(ASY_DATA, 0x80000022, TRUE); - write_client_reg(ASY_CMDSET, 0x00000003, TRUE); - write_client_reg(START, 0x00000001, TRUE); - mddi_wait(60); - write_client_reg(PXL, 0x00000000, TRUE); - write_client_reg(VSYNIF, 0x00000000, TRUE); - write_client_reg(START, 0x00000000, TRUE); - write_client_reg(ASY_CMDSET, 0x00000000, TRUE); - write_client_reg(ASY_DATA, 0x80000050, TRUE); - write_client_reg(ASY_DATB, 0x00000000, TRUE); - write_client_reg(ASY_DATC, 0x80000051, TRUE); - write_client_reg(ASY_DATD, 0x00000E00, TRUE); - write_client_reg(ASY_DATE, 0x80000052, TRUE); - write_client_reg(ASY_DATF, 0x00000D01, TRUE); - write_client_reg(ASY_DATG, 0x80000053, TRUE); - write_client_reg(ASY_DATH, 0x00000000, TRUE); - write_client_reg(ASY_CMDSET, 0x00000001, TRUE); - write_client_reg(ASY_CMDSET, 0x00000000, TRUE); - write_client_reg(ASY_DATA, 0x80000058, TRUE); - write_client_reg(ASY_DATB, 0x00000000, TRUE); - write_client_reg(ASY_DATC, 0x8000005A, TRUE); - write_client_reg(ASY_DATD, 0x00000E01, TRUE); - write_client_reg(ASY_CMDSET, 0x00000009, TRUE); - write_client_reg(ASY_CMDSET, 0x00000008, TRUE); - write_client_reg(ASY_DATA, 0x80000011, TRUE); - write_client_reg(ASY_DATB, 0x00000812, TRUE); - write_client_reg(ASY_DATC, 0x80000012, TRUE); - write_client_reg(ASY_DATD, 0x00000003, TRUE); - write_client_reg(ASY_DATE, 0x80000013, TRUE); - write_client_reg(ASY_DATF, 0x00000909, TRUE); - write_client_reg(ASY_DATG, 0x80000010, TRUE); - write_client_reg(ASY_DATH, 0x00000040, TRUE); - write_client_reg(ASY_CMDSET, 0x00000001, TRUE); - write_client_reg(ASY_CMDSET, 0x00000000, TRUE); - mddi_wait(40); - write_client_reg(ASY_DATA, 0x80000010, TRUE); - write_client_reg(ASY_DATB, 0x00000340, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(60); - write_client_reg(ASY_DATA, 0x80000010, TRUE); - write_client_reg(ASY_DATB, 0x00003340, TRUE); - write_client_reg(ASY_DATC, 0x80000007, TRUE); - write_client_reg(ASY_DATD, 0x00004007, TRUE); - write_client_reg(ASY_CMDSET, 0x00000009, TRUE); - write_client_reg(ASY_CMDSET, 0x00000008, TRUE); - mddi_wait(1); - write_client_reg(ASY_DATA, 0x80000007, TRUE); - write_client_reg(ASY_DATB, 0x00004017, TRUE); - write_client_reg(ASY_DATC, 0x8000005B, TRUE); - write_client_reg(ASY_DATD, 0x00000000, TRUE); - write_client_reg(ASY_DATE, 0x80000059, TRUE); - write_client_reg(ASY_DATF, 0x00000011, TRUE); - write_client_reg(ASY_CMDSET, 0x0000000D, TRUE); - write_client_reg(ASY_CMDSET, 0x0000000C, TRUE); - mddi_wait(20); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - /* LTPS I/F control */ - write_client_reg(ASY_DATB, 0x00000019, TRUE); - /* Direct cmd transfer enable */ - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - /* Direct cmd transfer disable */ - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(20); - /* Index setting of SUB LCDD */ - write_client_reg(ASY_DATA, 0x80000059, TRUE); - /* LTPS I/F control */ - write_client_reg(ASY_DATB, 0x00000079, TRUE); - /* Direct cmd transfer enable */ - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - /* Direct cmd transfer disable */ - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(20); - /* Index setting of SUB LCDD */ - write_client_reg(ASY_DATA, 0x80000059, TRUE); - /* LTPS I/F control */ - write_client_reg(ASY_DATB, 0x000003FD, TRUE); - /* Direct cmd transfer enable */ - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - /* Direct cmd transfer disable */ - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(20); - mddi_toshiba_state_transition(TOSHIBA_STATE_PRIM_SEC_READY, - TOSHIBA_STATE_SEC_NORMAL_MODE); -} - -static void toshiba_prim_lcd_off(struct msm_fb_data_type *mfd) -{ - if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) { - gordon_disp_off(); - } else{ - - /* Main panel power off (Deep standby in) */ - write_client_reg(SSITX, 0x000800BC, TRUE); - write_client_reg(SSITX, 0x00000100, TRUE); - write_client_reg(SSITX, 0x00000028, TRUE); - mddi_wait(1); - write_client_reg(SSITX, 0x000800B8, TRUE); - write_client_reg(SSITX, 0x00000180, TRUE); - write_client_reg(SSITX, 0x00000102, TRUE); - write_client_reg(SSITX, 0x00000010, TRUE); - } - write_client_reg(PORT, 0x00000003, TRUE); - write_client_reg(REGENB, 0x00000001, TRUE); - mddi_wait(1); - write_client_reg(PXL, 0x00000000, TRUE); - write_client_reg(START, 0x00000000, TRUE); - write_client_reg(REGENB, 0x00000001, TRUE); - mddi_wait(3); - if (TM_GET_PID(mfd->panel.id) != LCD_SHARP_2P4_VGA) { - write_client_reg(SSITX, 0x000800B0, TRUE); - write_client_reg(SSITX, 0x00000100, TRUE); - } - mddi_toshiba_state_transition(TOSHIBA_STATE_PRIM_NORMAL_MODE, - TOSHIBA_STATE_PRIM_SEC_STANDBY); -} - -static void toshiba_sec_lcd_off(struct msm_fb_data_type *mfd) -{ - if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT) - return; - - write_client_reg(VSYNIF, 0x00000000, TRUE); - write_client_reg(PORT_ENB, 0x00000002, TRUE); - write_client_reg(ASY_DATA, 0x80000007, TRUE); - write_client_reg(ASY_DATB, 0x00004016, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x00000019, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x0000000B, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x00000002, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(4); - write_client_reg(ASY_DATA, 0x80000010, TRUE); - write_client_reg(ASY_DATB, 0x00000300, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(4); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x00000000, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); - write_client_reg(ASY_DATA, 0x80000007, TRUE); - write_client_reg(ASY_DATB, 0x00004004, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); - write_client_reg(PORT, 0x00000000, TRUE); - write_client_reg(PXL, 0x00000000, TRUE); - write_client_reg(START, 0x00000000, TRUE); - write_client_reg(VSYNIF, 0x00000001, TRUE); - write_client_reg(PORT_ENB, 0x00000001, TRUE); - write_client_reg(REGENB, 0x00000001, TRUE); - mddi_toshiba_state_transition(TOSHIBA_STATE_SEC_NORMAL_MODE, - TOSHIBA_STATE_PRIM_SEC_STANDBY); -} - -static void toshiba_sec_cont_update_start(struct msm_fb_data_type *mfd) -{ - - if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT) - return; - - write_client_reg(VSYNIF, 0x00000000, TRUE); - write_client_reg(PORT_ENB, 0x00000002, TRUE); - write_client_reg(INTMASK, 0x00000001, TRUE); - write_client_reg(TTBUSSEL, 0x0000000B, TRUE); - write_client_reg(MONI, 0x00000008, TRUE); - write_client_reg(CLKENB, 0x000000EF, TRUE); - write_client_reg(CLKENB, 0x000010EF, TRUE); - write_client_reg(CLKENB, 0x000011EF, TRUE); - write_client_reg(BITMAP4, 0x00DC00B0, TRUE); - write_client_reg(HCYCLE, 0x0000006B, TRUE); - write_client_reg(HSW, 0x00000003, TRUE); - write_client_reg(HDE_START, 0x00000002, TRUE); - write_client_reg(HDE_SIZE, 0x00000057, TRUE); - write_client_reg(VCYCLE, 0x000000E6, TRUE); - write_client_reg(VSW, 0x00000001, TRUE); - write_client_reg(VDE_START, 0x00000003, TRUE); - write_client_reg(VDE_SIZE, 0x000000DB, TRUE); - write_client_reg(WRSTB, 0x00000015, TRUE); - write_client_reg(MPLFBUF, 0x00000004, TRUE); - write_client_reg(ASY_DATA, 0x80000021, TRUE); - write_client_reg(ASY_DATB, 0x00000000, TRUE); - write_client_reg(ASY_DATC, 0x80000022, TRUE); - write_client_reg(ASY_CMDSET, 0x00000007, TRUE); - write_client_reg(PXL, 0x00000089, TRUE); - write_client_reg(VSYNIF, 0x00000001, TRUE); - mddi_wait(2); -} - -static void toshiba_sec_cont_update_stop(struct msm_fb_data_type *mfd) -{ - if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT) - return; - - write_client_reg(PXL, 0x00000000, TRUE); - write_client_reg(VSYNIF, 0x00000000, TRUE); - write_client_reg(START, 0x00000000, TRUE); - write_client_reg(ASY_CMDSET, 0x00000000, TRUE); - mddi_wait(3); - write_client_reg(SRST, 0x00000002, TRUE); - mddi_wait(3); - write_client_reg(SRST, 0x00000003, TRUE); -} - -static void toshiba_sec_backlight_on(struct msm_fb_data_type *mfd) -{ - if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT) - return; - - write_client_reg(TIMER0CTRL, 0x00000060, TRUE); - write_client_reg(TIMER0LOAD, 0x00001388, TRUE); - write_client_reg(PWM0OFF, 0x00000001, TRUE); - write_client_reg(TIMER1CTRL, 0x00000060, TRUE); - write_client_reg(TIMER1LOAD, 0x00001388, TRUE); - write_client_reg(PWM1OFF, 0x00001387, TRUE); - write_client_reg(TIMER0CTRL, 0x000000E0, TRUE); - write_client_reg(TIMER1CTRL, 0x000000E0, TRUE); - write_client_reg(PWMCR, 0x00000003, TRUE); -} - -static void toshiba_sec_sleep_in(struct msm_fb_data_type *mfd) -{ - if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT) - return; - - write_client_reg(VSYNIF, 0x00000000, TRUE); - write_client_reg(PORT_ENB, 0x00000002, TRUE); - write_client_reg(ASY_DATA, 0x80000007, TRUE); - write_client_reg(ASY_DATB, 0x00004016, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x00000019, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x0000000B, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x00000002, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(4); - write_client_reg(ASY_DATA, 0x80000010, TRUE); - write_client_reg(ASY_DATB, 0x00000300, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(4); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x00000000, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); - write_client_reg(ASY_DATA, 0x80000007, TRUE); - write_client_reg(ASY_DATB, 0x00004004, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); - write_client_reg(PORT, 0x00000000, TRUE); - write_client_reg(PXL, 0x00000000, TRUE); - write_client_reg(START, 0x00000000, TRUE); - write_client_reg(REGENB, 0x00000001, TRUE); - /* Sleep in sequence */ - write_client_reg(ASY_DATA, 0x80000010, TRUE); - write_client_reg(ASY_DATB, 0x00000302, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); -} - -static void toshiba_sec_sleep_out(struct msm_fb_data_type *mfd) -{ - if (TM_GET_PID(mfd->panel.id) == LCD_TOSHIBA_2P4_WVGA_PT) - return; - - write_client_reg(VSYNIF, 0x00000000, TRUE); - write_client_reg(PORT_ENB, 0x00000002, TRUE); - write_client_reg(ASY_DATA, 0x80000010, TRUE); - write_client_reg(ASY_DATB, 0x00000300, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - /* Display ON sequence */ - write_client_reg(ASY_DATA, 0x80000011, TRUE); - write_client_reg(ASY_DATB, 0x00000812, TRUE); - write_client_reg(ASY_DATC, 0x80000012, TRUE); - write_client_reg(ASY_DATD, 0x00000003, TRUE); - write_client_reg(ASY_DATE, 0x80000013, TRUE); - write_client_reg(ASY_DATF, 0x00000909, TRUE); - write_client_reg(ASY_DATG, 0x80000010, TRUE); - write_client_reg(ASY_DATH, 0x00000040, TRUE); - write_client_reg(ASY_CMDSET, 0x00000001, TRUE); - write_client_reg(ASY_CMDSET, 0x00000000, TRUE); - mddi_wait(4); - write_client_reg(ASY_DATA, 0x80000010, TRUE); - write_client_reg(ASY_DATB, 0x00000340, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(6); - write_client_reg(ASY_DATA, 0x80000010, TRUE); - write_client_reg(ASY_DATB, 0x00003340, TRUE); - write_client_reg(ASY_DATC, 0x80000007, TRUE); - write_client_reg(ASY_DATD, 0x00004007, TRUE); - write_client_reg(ASY_CMDSET, 0x00000009, TRUE); - write_client_reg(ASY_CMDSET, 0x00000008, TRUE); - mddi_wait(1); - write_client_reg(ASY_DATA, 0x80000007, TRUE); - write_client_reg(ASY_DATB, 0x00004017, TRUE); - write_client_reg(ASY_DATC, 0x8000005B, TRUE); - write_client_reg(ASY_DATD, 0x00000000, TRUE); - write_client_reg(ASY_DATE, 0x80000059, TRUE); - write_client_reg(ASY_DATF, 0x00000011, TRUE); - write_client_reg(ASY_CMDSET, 0x0000000D, TRUE); - write_client_reg(ASY_CMDSET, 0x0000000C, TRUE); - mddi_wait(2); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x00000019, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x00000079, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); - write_client_reg(ASY_DATA, 0x80000059, TRUE); - write_client_reg(ASY_DATB, 0x000003FD, TRUE); - write_client_reg(ASY_CMDSET, 0x00000005, TRUE); - write_client_reg(ASY_CMDSET, 0x00000004, TRUE); - mddi_wait(2); -} - -static void mddi_toshiba_lcd_set_backlight(struct msm_fb_data_type *mfd) -{ - int32 level; - int ret = -EPERM; - int max = mfd->panel_info.bl_max; - int min = mfd->panel_info.bl_min; - - if (mddi_toshiba_pdata && mddi_toshiba_pdata->pmic_backlight) { - ret = mddi_toshiba_pdata->pmic_backlight(mfd->bl_level); - if (!ret) - return; - } - - if (ret && mddi_toshiba_pdata && mddi_toshiba_pdata->backlight_level) { - level = mddi_toshiba_pdata->backlight_level(mfd->bl_level, - max, min); - - if (level < 0) - return; - - if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) - write_client_reg(TIMER0LOAD, 0x00001388, TRUE); - } else { - if (!max) - level = 0; - else - level = (mfd->bl_level * 4999) / max; - } - - write_client_reg(PWM0OFF, level, TRUE); -} - -static void mddi_toshiba_vsync_set_handler(msm_fb_vsync_handler_type handler, /* ISR to be executed */ - void *arg) -{ - boolean error = FALSE; - unsigned long flags; - - /* Disable interrupts */ - spin_lock_irqsave(&mddi_host_spin_lock, flags); - /* INTLOCK(); */ - - if (mddi_toshiba_vsync_handler != NULL) { - error = TRUE; - } else { - /* Register the handler for this particular GROUP interrupt source */ - mddi_toshiba_vsync_handler = handler; - mddi_toshiba_vsync_handler_arg = arg; - } - - /* Restore interrupts */ - spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - /* MDDI_INTFREE(); */ - if (error) { - MDDI_MSG_ERR("MDDI: Previous Vsync handler never called\n"); - } else { - /* Enable the vsync wakeup */ - mddi_queue_register_write(INTMSK, 0x0000, FALSE, 0); - - mddi_toshiba_vsync_attempts = 1; - mddi_vsync_detect_enabled = TRUE; - } -} /* mddi_toshiba_vsync_set_handler */ - -static void mddi_toshiba_lcd_vsync_detected(boolean detected) -{ - /* static timetick_type start_time = 0; */ - static struct timeval start_time; - static boolean first_time = TRUE; - /* uint32 mdp_cnt_val = 0; */ - /* timetick_type elapsed_us; */ - struct timeval now; - uint32 elapsed_us; - uint32 num_vsyncs; - - if ((detected) || (mddi_toshiba_vsync_attempts > 5)) { - if ((detected) && (mddi_toshiba_monitor_refresh_value)) { - /* if (start_time != 0) */ - if (!first_time) { - jiffies_to_timeval(jiffies, &now); - elapsed_us = - (now.tv_sec - start_time.tv_sec) * 1000000 + - now.tv_usec - start_time.tv_usec; - /* - * LCD is configured for a refresh every usecs, - * so to determine the number of vsyncs that - * have occurred since the last measurement - * add half that to the time difference and - * divide by the refresh rate. - */ - num_vsyncs = (elapsed_us + - (mddi_toshiba_usecs_per_refresh >> - 1)) / - mddi_toshiba_usecs_per_refresh; - /* - * LCD is configured for * hsyncs (rows) per - * refresh cycle. Calculate new rows_per_second - * value based upon these new measurements. - * MDP can update with this new value. - */ - mddi_toshiba_rows_per_second = - (mddi_toshiba_rows_per_refresh * 1000 * - num_vsyncs) / (elapsed_us / 1000); - } - /* start_time = timetick_get(); */ - first_time = FALSE; - jiffies_to_timeval(jiffies, &start_time); - if (mddi_toshiba_report_refresh_measurements) { - (void)mddi_queue_register_read_int(VPOS, - &mddi_toshiba_curr_vpos); - /* mdp_cnt_val = MDP_LINE_COUNT; */ - } - } - /* if detected = TRUE, client initiated wakeup was detected */ - if (mddi_toshiba_vsync_handler != NULL) { - (*mddi_toshiba_vsync_handler) - (mddi_toshiba_vsync_handler_arg); - mddi_toshiba_vsync_handler = NULL; - } - mddi_vsync_detect_enabled = FALSE; - mddi_toshiba_vsync_attempts = 0; - /* need to disable the interrupt wakeup */ - if (!mddi_queue_register_write_int(INTMSK, 0x0001)) - MDDI_MSG_ERR("Vsync interrupt disable failed!\n"); - if (!detected) { - /* give up after 5 failed attempts but show error */ - MDDI_MSG_NOTICE("Vsync detection failed!\n"); - } else if ((mddi_toshiba_monitor_refresh_value) && - (mddi_toshiba_report_refresh_measurements)) { - MDDI_MSG_NOTICE(" Last Line Counter=%d!\n", - mddi_toshiba_curr_vpos); - /* MDDI_MSG_NOTICE(" MDP Line Counter=%d!\n",mdp_cnt_val); */ - MDDI_MSG_NOTICE(" Lines Per Second=%d!\n", - mddi_toshiba_rows_per_second); - } - /* clear the interrupt */ - if (!mddi_queue_register_write_int(INTFLG, 0x0001)) - MDDI_MSG_ERR("Vsync interrupt clear failed!\n"); - } else { - /* if detected = FALSE, we woke up from hibernation, but did not - * detect client initiated wakeup. - */ - mddi_toshiba_vsync_attempts++; - } -} - -static void mddi_toshiba_prim_init(struct msm_fb_data_type *mfd) -{ - - switch (toshiba_state) { - case TOSHIBA_STATE_PRIM_SEC_READY: - break; - case TOSHIBA_STATE_OFF: - toshiba_state = TOSHIBA_STATE_PRIM_SEC_STANDBY; - toshiba_common_initial_setup(mfd); - break; - case TOSHIBA_STATE_PRIM_SEC_STANDBY: - toshiba_common_initial_setup(mfd); - break; - case TOSHIBA_STATE_SEC_NORMAL_MODE: - toshiba_sec_cont_update_stop(mfd); - toshiba_sec_sleep_in(mfd); - toshiba_sec_sleep_out(mfd); - toshiba_sec_lcd_off(mfd); - toshiba_common_initial_setup(mfd); - break; - default: - MDDI_MSG_ERR("mddi_toshiba_prim_init from state %d\n", - toshiba_state); - } - - toshiba_prim_start(mfd); - if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) - gordon_disp_init(); - mddi_host_write_pix_attr_reg(0x00C3); -} - -static void mddi_toshiba_sec_init(struct msm_fb_data_type *mfd) -{ - - switch (toshiba_state) { - case TOSHIBA_STATE_PRIM_SEC_READY: - break; - case TOSHIBA_STATE_PRIM_SEC_STANDBY: - toshiba_common_initial_setup(mfd); - break; - case TOSHIBA_STATE_PRIM_NORMAL_MODE: - toshiba_prim_lcd_off(mfd); - toshiba_common_initial_setup(mfd); - break; - default: - MDDI_MSG_ERR("mddi_toshiba_sec_init from state %d\n", - toshiba_state); - } - - toshiba_sec_start(mfd); - toshiba_sec_backlight_on(mfd); - toshiba_sec_cont_update_start(mfd); - mddi_host_write_pix_attr_reg(0x0400); -} - -static void mddi_toshiba_lcd_powerdown(struct msm_fb_data_type *mfd) -{ - switch (toshiba_state) { - case TOSHIBA_STATE_PRIM_SEC_READY: - mddi_toshiba_prim_init(mfd); - mddi_toshiba_lcd_powerdown(mfd); - return; - case TOSHIBA_STATE_PRIM_SEC_STANDBY: - break; - case TOSHIBA_STATE_PRIM_NORMAL_MODE: - toshiba_prim_lcd_off(mfd); - break; - case TOSHIBA_STATE_SEC_NORMAL_MODE: - toshiba_sec_cont_update_stop(mfd); - toshiba_sec_sleep_in(mfd); - toshiba_sec_sleep_out(mfd); - toshiba_sec_lcd_off(mfd); - break; - default: - MDDI_MSG_ERR("mddi_toshiba_lcd_powerdown from state %d\n", - toshiba_state); - } -} - -static int mddi_sharpgordon_firsttime = 1; - -static int mddi_toshiba_lcd_on(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - mfd = platform_get_drvdata(pdev); - if (!mfd) - return -ENODEV; - if (mfd->key != MFD_KEY) - return -EINVAL; - - if (TM_GET_DID(mfd->panel.id) == TOSHIBA_VGA_PRIM) - mddi_toshiba_prim_init(mfd); - else - mddi_toshiba_sec_init(mfd); - if (TM_GET_PID(mfd->panel.id) == LCD_SHARP_2P4_VGA) { - if (mddi_sharpgordon_firsttime) { - mddi_sharpgordon_firsttime = 0; - write_client_reg(REGENB, 0x00000001, TRUE); - } - } - return 0; -} - -static int mddi_toshiba_lcd_off(struct platform_device *pdev) -{ - mddi_toshiba_lcd_powerdown(platform_get_drvdata(pdev)); - return 0; -} - -static int __init mddi_toshiba_lcd_probe(struct platform_device *pdev) -{ - if (pdev->id == 0) { - mddi_toshiba_pdata = pdev->dev.platform_data; - return 0; - } - - msm_fb_add_device(pdev); - - return 0; -} - -static struct platform_driver this_driver = { - .probe = mddi_toshiba_lcd_probe, - .driver = { - .name = "mddi_toshiba", - }, -}; - -static struct msm_fb_panel_data toshiba_panel_data = { - .on = mddi_toshiba_lcd_on, - .off = mddi_toshiba_lcd_off, -}; - -static int ch_used[3]; - -int mddi_toshiba_device_register(struct msm_panel_info *pinfo, - u32 channel, u32 panel) -{ - struct platform_device *pdev = NULL; - int ret; - - if ((channel >= 3) || ch_used[channel]) - return -ENODEV; - - if ((channel != TOSHIBA_VGA_PRIM) && - mddi_toshiba_pdata && mddi_toshiba_pdata->panel_num) - if (mddi_toshiba_pdata->panel_num() < 2) - return -ENODEV; - - ch_used[channel] = TRUE; - - pdev = platform_device_alloc("mddi_toshiba", (panel << 8)|channel); - if (!pdev) - return -ENOMEM; - - if (channel == TOSHIBA_VGA_PRIM) { - toshiba_panel_data.set_backlight = - mddi_toshiba_lcd_set_backlight; - - if (pinfo->lcd.vsync_enable) { - toshiba_panel_data.set_vsync_notifier = - mddi_toshiba_vsync_set_handler; - mddi_lcd.vsync_detected = - mddi_toshiba_lcd_vsync_detected; - } - } else { - toshiba_panel_data.set_backlight = NULL; - toshiba_panel_data.set_vsync_notifier = NULL; - } - - toshiba_panel_data.panel_info = *pinfo; - - ret = platform_device_add_data(pdev, &toshiba_panel_data, - sizeof(toshiba_panel_data)); - if (ret) { - printk(KERN_ERR - "%s: platform_device_add_data failed!\n", __func__); - goto err_device_put; - } - - ret = platform_device_add(pdev); - if (ret) { - printk(KERN_ERR - "%s: platform_device_register failed!\n", __func__); - goto err_device_put; - } - - return 0; - -err_device_put: - platform_device_put(pdev); - return ret; -} - -static int __init mddi_toshiba_lcd_init(void) -{ - return platform_driver_register(&this_driver); -} - -module_init(mddi_toshiba_lcd_init); diff --git a/drivers/staging/msm/mddi_toshiba.h b/drivers/staging/msm/mddi_toshiba.h deleted file mode 100644 index cbeea0a26d6c..000000000000 --- a/drivers/staging/msm/mddi_toshiba.h +++ /dev/null @@ -1,36 +0,0 @@ -/* 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 and - * only 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. - */ - -#ifndef MDDI_TOSHIBA_H -#define MDDI_TOSHIBA_H - -#define TOSHIBA_VGA_PRIM 1 -#define TOSHIBA_VGA_SECD 2 - -#define LCD_TOSHIBA_2P4_VGA 0 -#define LCD_TOSHIBA_2P4_WVGA 1 -#define LCD_TOSHIBA_2P4_WVGA_PT 2 -#define LCD_SHARP_2P4_VGA 3 - -#define GPIO_BLOCK_BASE 0x150000 -#define SYSTEM_BLOCK2_BASE 0x170000 - -#define GPIODIR (GPIO_BLOCK_BASE|0x04) -#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00) -#define GPIOPC (GPIO_BLOCK_BASE|0x28) -#define GPIODATA (GPIO_BLOCK_BASE|0x00) - -#define write_client_reg(__X, __Y, __Z) {\ - mddi_queue_register_write(__X, __Y, TRUE, 0);\ -} - -#endif /* MDDI_TOSHIBA_H */ diff --git a/drivers/staging/msm/mddi_toshiba_vga.c b/drivers/staging/msm/mddi_toshiba_vga.c deleted file mode 100644 index 7e61d3a5b8f1..000000000000 --- a/drivers/staging/msm/mddi_toshiba_vga.c +++ /dev/null @@ -1,136 +0,0 @@ -/* 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "msm_fb.h" -#include "mddihost.h" -#include "mddihosti.h" -#include "mddi_toshiba.h" - -static uint32 read_client_reg(uint32 addr) -{ - uint32 val; - mddi_queue_register_read(addr, &val, TRUE, 0); - return val; -} - -static uint32 toshiba_lcd_gpio_read(void) -{ - uint32 val; - - write_client_reg(GPIODIR, 0x0000000C, TRUE); - write_client_reg(GPIOSEL, 0x00000000, TRUE); - write_client_reg(GPIOSEL, 0x00000000, TRUE); - write_client_reg(GPIOPC, 0x03CF00C0, TRUE); - val = read_client_reg(GPIODATA) & 0x2C0; - - return val; -} - -static u32 mddi_toshiba_panel_detect(void) -{ - mddi_host_type host_idx = MDDI_HOST_PRIM; - uint32 lcd_gpio; - u32 mddi_toshiba_lcd = LCD_TOSHIBA_2P4_VGA; - - /* Toshiba display requires larger drive_lo value */ - mddi_host_reg_out(DRIVE_LO, 0x0050); - - lcd_gpio = toshiba_lcd_gpio_read(); - switch (lcd_gpio) { - case 0x0080: - mddi_toshiba_lcd = LCD_SHARP_2P4_VGA; - break; - - case 0x00C0: - default: - mddi_toshiba_lcd = LCD_TOSHIBA_2P4_VGA; - break; - } - - return mddi_toshiba_lcd; -} - -static int __init mddi_toshiba_vga_init(void) -{ - int ret; - struct msm_panel_info pinfo; - u32 panel; - -#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT - u32 id; - - ret = msm_fb_detect_client("mddi_toshiba_vga"); - if (ret == -ENODEV) - return 0; - - if (ret) { - id = mddi_get_client_id(); - if ((id >> 16) != 0xD263) - return 0; - } -#endif - - panel = mddi_toshiba_panel_detect(); - - pinfo.xres = 480; - pinfo.yres = 640; - pinfo.type = MDDI_PANEL; - pinfo.pdest = DISPLAY_1; - pinfo.mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR; - pinfo.wait_cycle = 0; - pinfo.bpp = 18; - pinfo.lcd.vsync_enable = TRUE; - pinfo.lcd.refx100 = 6118; - pinfo.lcd.v_back_porch = 6; - pinfo.lcd.v_front_porch = 0; - pinfo.lcd.v_pulse_width = 0; - pinfo.lcd.hw_vsync_mode = FALSE; - pinfo.lcd.vsync_notifier_period = (1 * HZ); - pinfo.bl_max = 99; - pinfo.bl_min = 1; - pinfo.clk_rate = 122880000; - pinfo.clk_min = 120000000; - pinfo.clk_max = 200000000; - pinfo.fb_num = 2; - - ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_PRIM, panel); - if (ret) { - printk(KERN_ERR "%s: failed to register device!\n", __func__); - return ret; - } - - pinfo.xres = 176; - pinfo.yres = 220; - pinfo.type = MDDI_PANEL; - pinfo.pdest = DISPLAY_2; - pinfo.mddi.vdopkt = 0x400; - pinfo.wait_cycle = 0; - pinfo.bpp = 18; - pinfo.clk_rate = 122880000; - pinfo.clk_min = 120000000; - pinfo.clk_max = 200000000; - pinfo.fb_num = 2; - - ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_SECD, panel); - if (ret) - printk(KERN_WARNING - "%s: failed to register device!\n", __func__); - - return ret; -} - -module_init(mddi_toshiba_vga_init); diff --git a/drivers/staging/msm/mddi_toshiba_wvga_pt.c b/drivers/staging/msm/mddi_toshiba_wvga_pt.c deleted file mode 100644 index fc7d4e0d294f..000000000000 --- a/drivers/staging/msm/mddi_toshiba_wvga_pt.c +++ /dev/null @@ -1,64 +0,0 @@ -/* 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "msm_fb.h" -#include "mddihost.h" -#include "mddihosti.h" -#include "mddi_toshiba.h" - -static int __init mddi_toshiba_wvga_pt_init(void) -{ - int ret; - struct msm_panel_info pinfo; -#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT - uint id; - - ret = msm_fb_detect_client("mddi_toshiba_wvga_pt"); - if (ret == -ENODEV) - return 0; - - if (ret) { - id = mddi_get_client_id(); - if (id != 0xd2638722) - return 0; - } -#endif - - pinfo.xres = 480; - pinfo.yres = 800; - pinfo.type = MDDI_PANEL; - pinfo.pdest = DISPLAY_1; - pinfo.mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR; - pinfo.wait_cycle = 0; - pinfo.bpp = 18; - pinfo.lcd.vsync_enable = FALSE; - pinfo.bl_max = 15; - pinfo.bl_min = 1; - pinfo.clk_rate = 192000000; - pinfo.clk_min = 190000000; - pinfo.clk_max = 200000000; - pinfo.fb_num = 2; - - ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_PRIM, - LCD_TOSHIBA_2P4_WVGA_PT); - if (ret) - printk(KERN_ERR "%s: failed to register device!\n", __func__); - - return ret; -} - -module_init(mddi_toshiba_wvga_pt_init); diff --git a/drivers/staging/msm/mddihost.c b/drivers/staging/msm/mddihost.c deleted file mode 100644 index 58a86d5d995f..000000000000 --- a/drivers/staging/msm/mddihost.c +++ /dev/null @@ -1,377 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msm_fb.h" -#include "mddihost.h" -#include "mddihosti.h" - -#include -#include - -struct semaphore mddi_host_mutex; - -struct clk *mddi_io_clk; -static boolean mddi_host_powered = FALSE; -static boolean mddi_host_initialized = FALSE; -extern uint32 *mddi_reg_read_value_ptr; - -mddi_lcd_func_type mddi_lcd; - -extern mddi_client_capability_type mddi_client_capability_pkt; - -#ifdef FEATURE_MDDI_HITACHI -extern void mddi_hitachi_window_adjust(uint16 x1, - uint16 x2, uint16 y1, uint16 y2); -#endif - -extern void mddi_toshiba_lcd_init(void); - -#ifdef FEATURE_MDDI_S6D0142 -extern void mddi_s6d0142_lcd_init(void); -extern void mddi_s6d0142_window_adjust(uint16 x1, - uint16 x2, - uint16 y1, - uint16 y2, - mddi_llist_done_cb_type done_cb); -#endif - -void mddi_init(void) -{ - if (mddi_host_initialized) - return; - - mddi_host_initialized = TRUE; - - sema_init(&mddi_host_mutex, 1); - - if (!mddi_host_powered) { - down(&mddi_host_mutex); - mddi_host_init(MDDI_HOST_PRIM); - mddi_host_powered = TRUE; - up(&mddi_host_mutex); - mdelay(10); - } -} - -int mddi_host_register_read(uint32 reg_addr, - uint32 *reg_value_ptr, boolean wait, mddi_host_type host) { - mddi_linked_list_type *curr_llist_ptr; - mddi_register_access_packet_type *regacc_pkt_ptr; - uint16 curr_llist_idx; - int ret = 0; - - if (in_interrupt()) - MDDI_MSG_CRIT("Called from ISR context\n"); - - if (!mddi_host_powered) { - MDDI_MSG_ERR("MDDI powered down!\n"); - mddi_init(); - } - - down(&mddi_host_mutex); - - mddi_reg_read_value_ptr = reg_value_ptr; - curr_llist_idx = mddi_get_reg_read_llist_item(host, TRUE); - if (curr_llist_idx == UNASSIGNED_INDEX) { - up(&mddi_host_mutex); - - /* need to change this to some sort of wait */ - MDDI_MSG_ERR("Attempting to queue up more than 1 reg read\n"); - return -EINVAL; - } - - curr_llist_ptr = &llist_extern[host][curr_llist_idx]; - curr_llist_ptr->link_controller_flags = 0x11; - curr_llist_ptr->packet_header_count = 14; - curr_llist_ptr->packet_data_count = 0; - - curr_llist_ptr->next_packet_pointer = NULL; - curr_llist_ptr->packet_data_pointer = NULL; - curr_llist_ptr->reserved = 0; - - regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt; - - regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count; - regacc_pkt_ptr->packet_type = 146; /* register access packet */ - regacc_pkt_ptr->bClient_ID = 0; - regacc_pkt_ptr->read_write_info = 0x8001; - regacc_pkt_ptr->register_address = reg_addr; - - /* now adjust pointers */ - mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, wait, - NULL, host); - /* need to check if we can write the pointer or not */ - - up(&mddi_host_mutex); - - if (wait) { - int wait_ret; - - mddi_linked_list_notify_type *llist_notify_ptr; - llist_notify_ptr = &llist_extern_notify[host][curr_llist_idx]; - wait_ret = wait_for_completion_timeout( - &(llist_notify_ptr->done_comp), 5 * HZ); - - if (wait_ret <= 0) - ret = -EBUSY; - - if (wait_ret < 0) - printk(KERN_ERR "%s: failed to wait for completion!\n", - __func__); - else if (!wait_ret) - printk(KERN_ERR "%s: Timed out waiting!\n", __func__); - } - - MDDI_MSG_DEBUG("Reg Read value=0x%x\n", *reg_value_ptr); - - return ret; -} /* mddi_host_register_read */ - -int mddi_host_register_write(uint32 reg_addr, - uint32 reg_val, enum mddi_data_packet_size_type packet_size, - boolean wait, mddi_llist_done_cb_type done_cb, mddi_host_type host) { - mddi_linked_list_type *curr_llist_ptr; - mddi_linked_list_type *curr_llist_dma_ptr; - mddi_register_access_packet_type *regacc_pkt_ptr; - uint16 curr_llist_idx; - int ret = 0; - - if (in_interrupt()) - MDDI_MSG_CRIT("Called from ISR context\n"); - - if (!mddi_host_powered) { - MDDI_MSG_ERR("MDDI powered down!\n"); - mddi_init(); - } - - down(&mddi_host_mutex); - - curr_llist_idx = mddi_get_next_free_llist_item(host, TRUE); - curr_llist_ptr = &llist_extern[host][curr_llist_idx]; - curr_llist_dma_ptr = &llist_dma_extern[host][curr_llist_idx]; - - curr_llist_ptr->link_controller_flags = 1; - curr_llist_ptr->packet_header_count = 14; - curr_llist_ptr->packet_data_count = 4; - - curr_llist_ptr->next_packet_pointer = NULL; - curr_llist_ptr->reserved = 0; - - regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt; - - regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count + - (uint16)packet_size; - regacc_pkt_ptr->packet_type = 146; /* register access packet */ - regacc_pkt_ptr->bClient_ID = 0; - regacc_pkt_ptr->read_write_info = 0x0001; - regacc_pkt_ptr->register_address = reg_addr; - regacc_pkt_ptr->register_data_list = reg_val; - - MDDI_MSG_DEBUG("Reg Access write reg=0x%x, value=0x%x\n", - regacc_pkt_ptr->register_address, - regacc_pkt_ptr->register_data_list); - - regacc_pkt_ptr = &curr_llist_dma_ptr->packet_header.register_pkt; - curr_llist_ptr->packet_data_pointer = - (void *)(®acc_pkt_ptr->register_data_list); - - /* now adjust pointers */ - mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, wait, - done_cb, host); - - up(&mddi_host_mutex); - - if (wait) { - int wait_ret; - - mddi_linked_list_notify_type *llist_notify_ptr; - llist_notify_ptr = &llist_extern_notify[host][curr_llist_idx]; - wait_ret = wait_for_completion_timeout( - &(llist_notify_ptr->done_comp), 5 * HZ); - - if (wait_ret <= 0) - ret = -EBUSY; - - if (wait_ret < 0) - printk(KERN_ERR "%s: failed to wait for completion!\n", - __func__); - else if (!wait_ret) - printk(KERN_ERR "%s: Timed out waiting!\n", __func__); - } - - return ret; -} /* mddi_host_register_write */ - -boolean mddi_host_register_read_int - (uint32 reg_addr, uint32 *reg_value_ptr, mddi_host_type host) { - mddi_linked_list_type *curr_llist_ptr; - mddi_register_access_packet_type *regacc_pkt_ptr; - uint16 curr_llist_idx; - - if (!in_interrupt()) - MDDI_MSG_CRIT("Called from TASK context\n"); - - if (!mddi_host_powered) { - MDDI_MSG_ERR("MDDI powered down!\n"); - return FALSE; - } - - if (down_trylock(&mddi_host_mutex) != 0) - return FALSE; - - mddi_reg_read_value_ptr = reg_value_ptr; - curr_llist_idx = mddi_get_reg_read_llist_item(host, FALSE); - if (curr_llist_idx == UNASSIGNED_INDEX) { - up(&mddi_host_mutex); - return FALSE; - } - - curr_llist_ptr = &llist_extern[host][curr_llist_idx]; - curr_llist_ptr->link_controller_flags = 0x11; - curr_llist_ptr->packet_header_count = 14; - curr_llist_ptr->packet_data_count = 0; - - curr_llist_ptr->next_packet_pointer = NULL; - curr_llist_ptr->packet_data_pointer = NULL; - curr_llist_ptr->reserved = 0; - - regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt; - - regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count; - regacc_pkt_ptr->packet_type = 146; /* register access packet */ - regacc_pkt_ptr->bClient_ID = 0; - regacc_pkt_ptr->read_write_info = 0x8001; - regacc_pkt_ptr->register_address = reg_addr; - - /* now adjust pointers */ - mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, FALSE, - NULL, host); - /* need to check if we can write the pointer or not */ - - up(&mddi_host_mutex); - - return TRUE; - -} /* mddi_host_register_read */ - -boolean mddi_host_register_write_int - (uint32 reg_addr, - uint32 reg_val, mddi_llist_done_cb_type done_cb, mddi_host_type host) { - mddi_linked_list_type *curr_llist_ptr; - mddi_linked_list_type *curr_llist_dma_ptr; - mddi_register_access_packet_type *regacc_pkt_ptr; - uint16 curr_llist_idx; - - if (!in_interrupt()) - MDDI_MSG_CRIT("Called from TASK context\n"); - - if (!mddi_host_powered) { - MDDI_MSG_ERR("MDDI powered down!\n"); - return FALSE; - } - - if (down_trylock(&mddi_host_mutex) != 0) - return FALSE; - - curr_llist_idx = mddi_get_next_free_llist_item(host, FALSE); - if (curr_llist_idx == UNASSIGNED_INDEX) { - up(&mddi_host_mutex); - return FALSE; - } - - curr_llist_ptr = &llist_extern[host][curr_llist_idx]; - curr_llist_dma_ptr = &llist_dma_extern[host][curr_llist_idx]; - - curr_llist_ptr->link_controller_flags = 1; - curr_llist_ptr->packet_header_count = 14; - curr_llist_ptr->packet_data_count = 4; - - curr_llist_ptr->next_packet_pointer = NULL; - curr_llist_ptr->reserved = 0; - - regacc_pkt_ptr = &curr_llist_ptr->packet_header.register_pkt; - - regacc_pkt_ptr->packet_length = curr_llist_ptr->packet_header_count + 4; - regacc_pkt_ptr->packet_type = 146; /* register access packet */ - regacc_pkt_ptr->bClient_ID = 0; - regacc_pkt_ptr->read_write_info = 0x0001; - regacc_pkt_ptr->register_address = reg_addr; - regacc_pkt_ptr->register_data_list = reg_val; - - regacc_pkt_ptr = &curr_llist_dma_ptr->packet_header.register_pkt; - curr_llist_ptr->packet_data_pointer = - (void *)(&(regacc_pkt_ptr->register_data_list)); - - /* now adjust pointers */ - mddi_queue_forward_packets(curr_llist_idx, curr_llist_idx, FALSE, - done_cb, host); - up(&mddi_host_mutex); - - return TRUE; - -} /* mddi_host_register_write */ - -void mddi_wait(uint16 time_ms) -{ - mdelay(time_ms); -} - -void mddi_client_lcd_vsync_detected(boolean detected) -{ - if (mddi_lcd.vsync_detected) - (*mddi_lcd.vsync_detected) (detected); -} - -/* extended version of function includes done callback */ -void mddi_window_adjust_ext(struct msm_fb_data_type *mfd, - uint16 x1, - uint16 x2, - uint16 y1, - uint16 y2, mddi_llist_done_cb_type done_cb) -{ -#ifdef FEATURE_MDDI_HITACHI - if (mfd->panel.id == HITACHI) - mddi_hitachi_window_adjust(x1, x2, y1, y2); -#elif defined(FEATURE_MDDI_S6D0142) - if (mfd->panel.id == MDDI_LCD_S6D0142) - mddi_s6d0142_window_adjust(x1, x2, y1, y2, done_cb); -#else - /* Do nothing then... except avoid lint/compiler warnings */ - (void)x1; - (void)x2; - (void)y1; - (void)y2; - (void)done_cb; -#endif -} - -void mddi_window_adjust(struct msm_fb_data_type *mfd, - uint16 x1, uint16 x2, uint16 y1, uint16 y2) -{ - mddi_window_adjust_ext(mfd, x1, x2, y1, y2, NULL); -} diff --git a/drivers/staging/msm/mddihost.h b/drivers/staging/msm/mddihost.h deleted file mode 100644 index 8f532d05f83d..000000000000 --- a/drivers/staging/msm/mddihost.h +++ /dev/null @@ -1,207 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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. - */ - -#ifndef MDDIHOST_H -#define MDDIHOST_H - -#include -#include -#include -#include -#include -#include "linux/proc_fs.h" -#include -#include -#include - -#include -#include - -#include -#include - -#include "msm_fb_panel.h" - -#undef FEATURE_MDDI_MC4 -#undef FEATURE_MDDI_S6D0142 -#undef FEATURE_MDDI_HITACHI -#define FEATURE_MDDI_SHARP -#define FEATURE_MDDI_TOSHIBA -#undef FEATURE_MDDI_E751 -#define FEATURE_MDDI_CORONA -#define FEATURE_MDDI_PRISM - -#define T_MSM7500 - -typedef enum { - format_16bpp, - format_18bpp, - format_24bpp -} mddi_video_format; - -typedef enum { - MDDI_LCD_NONE = 0, - MDDI_LCD_MC4, - MDDI_LCD_S6D0142, - MDDI_LCD_SHARP, - MDDI_LCD_E751, - MDDI_LCD_CORONA, - MDDI_LCD_HITACHI, - MDDI_LCD_TOSHIBA, - MDDI_LCD_PRISM, - MDDI_LCD_TP2, - MDDI_NUM_LCD_TYPES, - MDDI_LCD_DEFAULT = MDDI_LCD_TOSHIBA -} mddi_lcd_type; - -typedef enum { - MDDI_HOST_PRIM = 0, - MDDI_HOST_EXT, - MDDI_NUM_HOST_CORES -} mddi_host_type; - -typedef enum { - MDDI_DRIVER_RESET, /* host core registers have not been written. */ - MDDI_DRIVER_DISABLED, /* registers written, interrupts disabled. */ - MDDI_DRIVER_ENABLED /* registers written, interrupts enabled. */ -} mddi_host_driver_state_type; - -typedef enum { - MDDI_GPIO_INT_0 = 0, - MDDI_GPIO_INT_1, - MDDI_GPIO_INT_2, - MDDI_GPIO_INT_3, - MDDI_GPIO_INT_4, - MDDI_GPIO_INT_5, - MDDI_GPIO_INT_6, - MDDI_GPIO_INT_7, - MDDI_GPIO_INT_8, - MDDI_GPIO_INT_9, - MDDI_GPIO_INT_10, - MDDI_GPIO_INT_11, - MDDI_GPIO_INT_12, - MDDI_GPIO_INT_13, - MDDI_GPIO_INT_14, - MDDI_GPIO_INT_15, - MDDI_GPIO_NUM_INTS -} mddi_gpio_int_type; - -enum mddi_data_packet_size_type { - MDDI_DATA_PACKET_4_BYTES = 4, - MDDI_DATA_PACKET_8_BYTES = 8, - MDDI_DATA_PACKET_12_BYTES = 12, - MDDI_DATA_PACKET_16_BYTES = 16, - MDDI_DATA_PACKET_24_BYTES = 24 -}; - -typedef struct { - uint32 addr; - uint32 value; -} mddi_reg_write_type; - -boolean mddi_vsync_set_handler(msm_fb_vsync_handler_type handler, void *arg); - -typedef void (*mddi_llist_done_cb_type) (void); - -typedef void (*mddi_rev_handler_type) (void *); - -boolean mddi_set_rev_handler(mddi_rev_handler_type handler, uint16 pkt_type); - -#define MDDI_DEFAULT_PRIM_PIX_ATTR 0xC3 -#define MDDI_DEFAULT_SECD_PIX_ATTR 0xC0 - -typedef int gpio_int_polarity_type; -typedef int gpio_int_handler_type; - -typedef struct { - void (*vsync_detected) (boolean); -} mddi_lcd_func_type; - -extern mddi_lcd_func_type mddi_lcd; -void mddi_init(void); - -void mddi_powerdown(void); - -void mddi_host_start_ext_display(void); -void mddi_host_stop_ext_display(void); - -extern spinlock_t mddi_host_spin_lock; -#ifdef T_MSM7500 -void mddi_reset(void); -#ifdef FEATURE_DUAL_PROC_MODEM_DISPLAY -void mddi_host_switch_proc_control(boolean on); -#endif -#endif -void mddi_host_exit_power_collapse(void); - -void mddi_queue_splash_screen - (void *buf_ptr, - boolean clear_area, - int16 src_width, - int16 src_starting_row, - int16 src_starting_column, - int16 num_of_rows, - int16 num_of_columns, int16 dst_starting_row, int16 dst_starting_column); - -void mddi_queue_image - (void *buf_ptr, - uint8 stereo_video, - boolean clear_area, - int16 src_width, - int16 src_starting_row, - int16 src_starting_column, - int16 num_of_rows, - int16 num_of_columns, int16 dst_starting_row, int16 dst_starting_column); - -int mddi_host_register_read - (uint32 reg_addr, - uint32 *reg_value_ptr, boolean wait, mddi_host_type host_idx); -int mddi_host_register_write - (uint32 reg_addr, uint32 reg_val, - enum mddi_data_packet_size_type packet_size, - boolean wait, mddi_llist_done_cb_type done_cb, mddi_host_type host); -boolean mddi_host_register_write_int - (uint32 reg_addr, - uint32 reg_val, mddi_llist_done_cb_type done_cb, mddi_host_type host); -boolean mddi_host_register_read_int - (uint32 reg_addr, uint32 *reg_value_ptr, mddi_host_type host_idx); -void mddi_queue_register_write_static - (uint32 reg_addr, - uint32 reg_val, boolean wait, mddi_llist_done_cb_type done_cb); -void mddi_queue_static_window_adjust - (const mddi_reg_write_type *reg_write, - uint16 num_writes, mddi_llist_done_cb_type done_cb); - -#define mddi_queue_register_read(reg, val_ptr, wait, sig) \ - mddi_host_register_read(reg, val_ptr, wait, MDDI_HOST_PRIM) -#define mddi_queue_register_write(reg, val, wait, sig) \ - mddi_host_register_write(reg, val, MDDI_DATA_PACKET_4_BYTES,\ - wait, NULL, MDDI_HOST_PRIM) -#define mddi_queue_register_write_extn(reg, val, pkt_size, wait, sig) \ - mddi_host_register_write(reg, val, pkt_size, \ - wait, NULL, MDDI_HOST_PRIM) -#define mddi_queue_register_write_int(reg, val) \ - mddi_host_register_write_int(reg, val, NULL, MDDI_HOST_PRIM) -#define mddi_queue_register_read_int(reg, val_ptr) \ - mddi_host_register_read_int(reg, val_ptr, MDDI_HOST_PRIM) -#define mddi_queue_register_writes(reg_ptr, val, wait, sig) \ - mddi_host_register_writes(reg_ptr, val, wait, sig, MDDI_HOST_PRIM) - -void mddi_wait(uint16 time_ms); -void mddi_assign_max_pkt_dimensions(uint16 image_cols, - uint16 image_rows, - uint16 bpp, - uint16 *max_cols, uint16 * max_rows); -uint16 mddi_assign_pkt_height(uint16 pkt_width, uint16 pkt_height, uint16 bpp); -void mddi_queue_reverse_encapsulation(boolean wait); -void mddi_disable(int lock); -#endif /* MDDIHOST_H */ diff --git a/drivers/staging/msm/mddihost_e.c b/drivers/staging/msm/mddihost_e.c deleted file mode 100644 index 7de5eda71ce3..000000000000 --- a/drivers/staging/msm/mddihost_e.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msm_fb.h" -#include "mddihost.h" -#include "mddihosti.h" - -#include -#include - -extern struct semaphore mddi_host_mutex; -static boolean mddi_host_ext_powered = FALSE; - -void mddi_host_start_ext_display(void) -{ - down(&mddi_host_mutex); - - if (!mddi_host_ext_powered) { - mddi_host_init(MDDI_HOST_EXT); - - mddi_host_ext_powered = TRUE; - } - - up(&mddi_host_mutex); -} - -void mddi_host_stop_ext_display(void) -{ - down(&mddi_host_mutex); - - if (mddi_host_ext_powered) { - mddi_host_powerdown(MDDI_HOST_EXT); - - mddi_host_ext_powered = FALSE; - } - - up(&mddi_host_mutex); -} diff --git a/drivers/staging/msm/mddihosti.c b/drivers/staging/msm/mddihosti.c deleted file mode 100644 index f9d6e91e8d5d..000000000000 --- a/drivers/staging/msm/mddihosti.c +++ /dev/null @@ -1,2239 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msm_fb_panel.h" -#include "mddihost.h" -#include "mddihosti.h" - -#define FEATURE_MDDI_UNDERRUN_RECOVERY -#ifndef FEATURE_MDDI_DISABLE_REVERSE -static void mddi_read_rev_packet(byte *data_ptr); -#endif - -struct timer_list mddi_host_timer; - -#define MDDI_DEFAULT_TIMER_LENGTH 5000 /* 5 seconds */ -uint32 mddi_rtd_frequency = 60000; /* send RTD every 60 seconds */ -uint32 mddi_client_status_frequency = 60000; /* get status pkt every 60 secs */ - -boolean mddi_vsync_detect_enabled = FALSE; -mddi_gpio_info_type mddi_gpio; - -uint32 mddi_host_core_version; -boolean mddi_debug_log_statistics = FALSE; -/* #define FEATURE_MDDI_HOST_ENABLE_EARLY_HIBERNATION */ -/* default to TRUE in case MDP does not vote */ -static boolean mddi_host_mdp_active_flag = TRUE; -static uint32 mddi_log_stats_counter; -uint32 mddi_log_stats_frequency = 4000; - -#define MDDI_DEFAULT_REV_PKT_SIZE 0x20 - -#ifndef FEATURE_MDDI_DISABLE_REVERSE -static boolean mddi_rev_ptr_workaround = TRUE; -static uint32 mddi_reg_read_retry; -static uint32 mddi_reg_read_retry_max = 20; -static boolean mddi_enable_reg_read_retry = TRUE; -static boolean mddi_enable_reg_read_retry_once = FALSE; - -#define MDDI_MAX_REV_PKT_SIZE 0x60 - -#define MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE 0x60 - -#define MDDI_VIDEO_REV_PKT_SIZE 0x40 -#define MDDI_REV_BUFFER_SIZE MDDI_MAX_REV_PKT_SIZE -static byte rev_packet_data[MDDI_MAX_REV_PKT_SIZE]; -#endif /* FEATURE_MDDI_DISABLE_REVERSE */ -/* leave these variables so graphics will compile */ - -#define MDDI_MAX_REV_DATA_SIZE 128 -/*lint -d__align(x) */ -boolean mddi_debug_clear_rev_data = TRUE; - -uint32 *mddi_reg_read_value_ptr; - -mddi_client_capability_type mddi_client_capability_pkt; -static boolean mddi_client_capability_request = FALSE; - -#ifndef FEATURE_MDDI_DISABLE_REVERSE - -#define MAX_MDDI_REV_HANDLERS 2 -#define INVALID_PKT_TYPE 0xFFFF - -typedef struct { - mddi_rev_handler_type handler; /* ISR to be executed */ - uint16 pkt_type; -} mddi_rev_pkt_handler_type; -static mddi_rev_pkt_handler_type mddi_rev_pkt_handler[MAX_MDDI_REV_HANDLERS] = - { {NULL, INVALID_PKT_TYPE}, {NULL, INVALID_PKT_TYPE} }; - -static boolean mddi_rev_encap_user_request = FALSE; -static mddi_linked_list_notify_type mddi_rev_user; - -spinlock_t mddi_host_spin_lock; -extern uint32 mdp_in_processing; -#endif - -typedef enum { - MDDI_REV_IDLE -#ifndef FEATURE_MDDI_DISABLE_REVERSE - , MDDI_REV_REG_READ_ISSUED, - MDDI_REV_REG_READ_SENT, - MDDI_REV_ENCAP_ISSUED, - MDDI_REV_STATUS_REQ_ISSUED, - MDDI_REV_CLIENT_CAP_ISSUED -#endif -} mddi_rev_link_state_type; - -typedef enum { - MDDI_LINK_DISABLED, - MDDI_LINK_HIBERNATING, - MDDI_LINK_ACTIVATING, - MDDI_LINK_ACTIVE -} mddi_host_link_state_type; - -typedef struct { - uint32 count; - uint32 in_count; - uint32 disp_req_count; - uint32 state_change_count; - uint32 ll_done_count; - uint32 rev_avail_count; - uint32 error_count; - uint32 rev_encap_count; - uint32 llist_ptr_write_1; - uint32 llist_ptr_write_2; -} mddi_host_int_type; - -typedef struct { - uint32 fwd_crc_count; - uint32 rev_crc_count; - uint32 pri_underflow; - uint32 sec_underflow; - uint32 rev_overflow; - uint32 pri_overwrite; - uint32 sec_overwrite; - uint32 rev_overwrite; - uint32 dma_failure; - uint32 rtd_failure; - uint32 reg_read_failure; -#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY - uint32 pri_underrun_detected; -#endif -} mddi_host_stat_type; - -typedef struct { - uint32 rtd_cnt; - uint32 rev_enc_cnt; - uint32 vid_cnt; - uint32 reg_acc_cnt; - uint32 cli_stat_cnt; - uint32 cli_cap_cnt; - uint32 reg_read_cnt; - uint32 link_active_cnt; - uint32 link_hibernate_cnt; - uint32 vsync_response_cnt; - uint32 fwd_crc_cnt; - uint32 rev_crc_cnt; -} mddi_log_params_struct_type; - -typedef struct { - uint32 rtd_value; - uint32 rtd_counter; - uint32 client_status_cnt; - boolean rev_ptr_written; - uint8 *rev_ptr_start; - uint8 *rev_ptr_curr; - uint32 mddi_rev_ptr_write_val; - dma_addr_t rev_data_dma_addr; - uint16 rev_pkt_size; - mddi_rev_link_state_type rev_state; - mddi_host_link_state_type link_state; - mddi_host_driver_state_type driver_state; - boolean disable_hibernation; - uint32 saved_int_reg; - uint32 saved_int_en; - mddi_linked_list_type *llist_ptr; - dma_addr_t llist_dma_addr; - mddi_linked_list_type *llist_dma_ptr; - uint32 *rev_data_buf; - struct completion mddi_llist_avail_comp; - boolean mddi_waiting_for_llist_avail; - mddi_host_int_type int_type; - mddi_host_stat_type stats; - mddi_log_params_struct_type log_parms; - mddi_llist_info_type llist_info; - mddi_linked_list_notify_type llist_notify[MDDI_MAX_NUM_LLIST_ITEMS]; -} mddi_host_cntl_type; - -static mddi_host_type mddi_curr_host = MDDI_HOST_PRIM; -static mddi_host_cntl_type mhctl[MDDI_NUM_HOST_CORES]; -mddi_linked_list_type *llist_extern[MDDI_NUM_HOST_CORES]; -mddi_linked_list_type *llist_dma_extern[MDDI_NUM_HOST_CORES]; -mddi_linked_list_notify_type *llist_extern_notify[MDDI_NUM_HOST_CORES]; -static mddi_log_params_struct_type prev_parms[MDDI_NUM_HOST_CORES]; - -extern uint32 mdp_total_vdopkts; - -static boolean mddi_host_io_clock_on = FALSE; -static boolean mddi_host_hclk_on = FALSE; - -int int_mddi_pri_flag = FALSE; -int int_mddi_ext_flag = FALSE; - -static void mddi_report_errors(uint32 int_reg) -{ - mddi_host_type host_idx = mddi_curr_host; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - if (int_reg & MDDI_INT_PRI_UNDERFLOW) { - pmhctl->stats.pri_underflow++; - MDDI_MSG_ERR("!!! MDDI Primary Underflow !!!\n"); - } - if (int_reg & MDDI_INT_SEC_UNDERFLOW) { - pmhctl->stats.sec_underflow++; - MDDI_MSG_ERR("!!! MDDI Secondary Underflow !!!\n"); - } -#ifndef FEATURE_MDDI_DISABLE_REVERSE - if (int_reg & MDDI_INT_REV_OVERFLOW) { - pmhctl->stats.rev_overflow++; - MDDI_MSG_ERR("!!! MDDI Reverse Overflow !!!\n"); - pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; - mddi_host_reg_out(REV_PTR, pmhctl->mddi_rev_ptr_write_val); - - } - if (int_reg & MDDI_INT_CRC_ERROR) - MDDI_MSG_ERR("!!! MDDI Reverse CRC Error !!!\n"); -#endif - if (int_reg & MDDI_INT_PRI_OVERWRITE) { - pmhctl->stats.pri_overwrite++; - MDDI_MSG_ERR("!!! MDDI Primary Overwrite !!!\n"); - } - if (int_reg & MDDI_INT_SEC_OVERWRITE) { - pmhctl->stats.sec_overwrite++; - MDDI_MSG_ERR("!!! MDDI Secondary Overwrite !!!\n"); - } -#ifndef FEATURE_MDDI_DISABLE_REVERSE - if (int_reg & MDDI_INT_REV_OVERWRITE) { - pmhctl->stats.rev_overwrite++; - /* This will show up normally and is not a problem */ - MDDI_MSG_DEBUG("MDDI Reverse Overwrite!\n"); - } - if (int_reg & MDDI_INT_RTD_FAILURE) { - mddi_host_reg_outm(INTEN, MDDI_INT_RTD_FAILURE, 0); - pmhctl->stats.rtd_failure++; - MDDI_MSG_ERR("!!! MDDI RTD Failure !!!\n"); - } -#endif - if (int_reg & MDDI_INT_DMA_FAILURE) { - pmhctl->stats.dma_failure++; - MDDI_MSG_ERR("!!! MDDI DMA Abort !!!\n"); - } -} - -static void mddi_host_enable_io_clock(void) -{ - if (!MDDI_HOST_IS_IO_CLOCK_ON) - MDDI_HOST_ENABLE_IO_CLOCK; -} - -static void mddi_host_enable_hclk(void) -{ - - if (!MDDI_HOST_IS_HCLK_ON) - MDDI_HOST_ENABLE_HCLK; -} - -static void mddi_host_disable_io_clock(void) -{ -#ifndef FEATURE_MDDI_HOST_IO_CLOCK_CONTROL_DISABLE - if (MDDI_HOST_IS_IO_CLOCK_ON) - MDDI_HOST_DISABLE_IO_CLOCK; -#endif -} - -static void mddi_host_disable_hclk(void) -{ -#ifndef FEATURE_MDDI_HOST_HCLK_CONTROL_DISABLE - if (MDDI_HOST_IS_HCLK_ON) - MDDI_HOST_DISABLE_HCLK; -#endif -} - -static void mddi_vote_to_sleep(mddi_host_type host_idx, boolean sleep) -{ - uint16 vote_mask; - - if (host_idx == MDDI_HOST_PRIM) - vote_mask = 0x01; - else - vote_mask = 0x02; -} - -static void mddi_report_state_change(uint32 int_reg) -{ - mddi_host_type host_idx = mddi_curr_host; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - if ((pmhctl->saved_int_reg & MDDI_INT_IN_HIBERNATION) && - (pmhctl->saved_int_reg & MDDI_INT_LINK_ACTIVE)) { - /* recover from condition where the io_clock was turned off by the - clock driver during a transition to hibernation. The io_clock - disable is to prevent MDP/MDDI underruns when changing ARM - clock speeds. In the process of halting the ARM, the hclk - divider needs to be set to 1. When it is set to 1, there is - a small time (usecs) when hclk is off or slow, and this can - cause an underrun. To prevent the underrun, clock driver turns - off the MDDI io_clock before making the change. */ - mddi_host_reg_out(CMD, MDDI_CMD_POWERUP); - } - - if (int_reg & MDDI_INT_LINK_ACTIVE) { - pmhctl->link_state = MDDI_LINK_ACTIVE; - pmhctl->log_parms.link_active_cnt++; - pmhctl->rtd_value = mddi_host_reg_in(RTD_VAL); - MDDI_MSG_DEBUG("!!! MDDI Active RTD:0x%x!!!\n", - pmhctl->rtd_value); - /* now interrupt on hibernation */ - mddi_host_reg_outm(INTEN, - (MDDI_INT_IN_HIBERNATION | - MDDI_INT_LINK_ACTIVE), - MDDI_INT_IN_HIBERNATION); - -#ifdef DEBUG_MDDIHOSTI - /* if gpio interrupt is enabled, start polling at fastest - * registered rate - */ - if (mddi_gpio.polling_enabled) { - timer_reg(&mddi_gpio_poll_timer, - mddi_gpio_poll_timer_cb, 0, mddi_gpio.polling_interval, 0); - } -#endif -#ifndef FEATURE_MDDI_DISABLE_REVERSE - if (mddi_rev_ptr_workaround) { - /* HW CR: need to reset reverse register stuff */ - pmhctl->rev_ptr_written = FALSE; - pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; - } -#endif - /* vote on sleep */ - mddi_vote_to_sleep(host_idx, FALSE); - - if (host_idx == MDDI_HOST_PRIM) { - if (mddi_vsync_detect_enabled) { - /* - * Indicate to client specific code that vsync - * was enabled, but we did not detect a client - * intiated wakeup. The client specific - * handler can either reassert vsync detection, - * or treat this as a valid vsync. - */ - mddi_client_lcd_vsync_detected(FALSE); - pmhctl->log_parms.vsync_response_cnt++; - } - } - } - if (int_reg & MDDI_INT_IN_HIBERNATION) { - pmhctl->link_state = MDDI_LINK_HIBERNATING; - pmhctl->log_parms.link_hibernate_cnt++; - MDDI_MSG_DEBUG("!!! MDDI Hibernating !!!\n"); - /* now interrupt on link_active */ -#ifdef FEATURE_MDDI_DISABLE_REVERSE - mddi_host_reg_outm(INTEN, - (MDDI_INT_MDDI_IN | - MDDI_INT_IN_HIBERNATION | - MDDI_INT_LINK_ACTIVE), - MDDI_INT_LINK_ACTIVE); -#else - mddi_host_reg_outm(INTEN, - (MDDI_INT_MDDI_IN | - MDDI_INT_IN_HIBERNATION | - MDDI_INT_LINK_ACTIVE), - (MDDI_INT_MDDI_IN | MDDI_INT_LINK_ACTIVE)); - - pmhctl->rtd_counter = mddi_rtd_frequency; - - if (pmhctl->rev_state != MDDI_REV_IDLE) { - /* a rev_encap will not wake up the link, so we do that here */ - pmhctl->link_state = MDDI_LINK_ACTIVATING; - mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE); - } -#endif - - if (pmhctl->disable_hibernation) { - mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE); - mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE); - pmhctl->link_state = MDDI_LINK_ACTIVATING; - } -#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY - if ((pmhctl->llist_info.transmitting_start_idx != - UNASSIGNED_INDEX) - && - ((pmhctl-> - saved_int_reg & (MDDI_INT_PRI_LINK_LIST_DONE | - MDDI_INT_PRI_PTR_READ)) == - MDDI_INT_PRI_PTR_READ)) { - mddi_linked_list_type *llist_dma; - llist_dma = pmhctl->llist_dma_ptr; - /* - * All indications are that we have not received a - * linked list done interrupt, due to an underrun - * condition. Recovery attempt is to send again. - */ - dma_coherent_pre_ops(); - /* Write to primary pointer register again */ - mddi_host_reg_out(PRI_PTR, - &llist_dma[pmhctl->llist_info. - transmitting_start_idx]); - pmhctl->stats.pri_underrun_detected++; - } -#endif - - /* vote on sleep */ - if (pmhctl->link_state == MDDI_LINK_HIBERNATING) { - mddi_vote_to_sleep(host_idx, TRUE); - } - -#ifdef DEBUG_MDDIHOSTI - /* need to stop polling timer */ - if (mddi_gpio.polling_enabled) { - (void) timer_clr(&mddi_gpio_poll_timer, T_NONE); - } -#endif - } -} - -void mddi_host_timer_service(unsigned long data) -{ -#ifndef FEATURE_MDDI_DISABLE_REVERSE - unsigned long flags; -#endif - mddi_host_type host_idx; - mddi_host_cntl_type *pmhctl; - - unsigned long time_ms = MDDI_DEFAULT_TIMER_LENGTH; - init_timer(&mddi_host_timer); - mddi_host_timer.function = mddi_host_timer_service; - mddi_host_timer.data = 0; - - mddi_host_timer.expires = jiffies + ((time_ms * HZ) / 1000); - add_timer(&mddi_host_timer); - - for (host_idx = MDDI_HOST_PRIM; host_idx < MDDI_NUM_HOST_CORES; - host_idx++) { - pmhctl = &(mhctl[host_idx]); - mddi_log_stats_counter += (uint32) time_ms; -#ifndef FEATURE_MDDI_DISABLE_REVERSE - pmhctl->rtd_counter += (uint32) time_ms; - pmhctl->client_status_cnt += (uint32) time_ms; - - if (host_idx == MDDI_HOST_PRIM) { - if (pmhctl->client_status_cnt >= - mddi_client_status_frequency) { - if ((pmhctl->link_state == - MDDI_LINK_HIBERNATING) - && (pmhctl->client_status_cnt > - mddi_client_status_frequency)) { - /* - * special case where we are hibernating - * and mddi_host_isr is not firing, so - * kick the link so that the status can - * be retrieved - */ - - /* need to wake up link before issuing - * rev encap command - */ - MDDI_MSG_INFO("wake up link!\n"); - spin_lock_irqsave(&mddi_host_spin_lock, - flags); - mddi_host_enable_hclk(); - mddi_host_enable_io_clock(); - pmhctl->link_state = - MDDI_LINK_ACTIVATING; - mddi_host_reg_out(CMD, - MDDI_CMD_LINK_ACTIVE); - spin_unlock_irqrestore - (&mddi_host_spin_lock, flags); - } else - if ((pmhctl->link_state == MDDI_LINK_ACTIVE) - && pmhctl->disable_hibernation) { - /* - * special case where we have disabled - * hibernation and mddi_host_isr - * is not firing, so enable interrupt - * for no pkts pending, which will - * generate an interrupt - */ - MDDI_MSG_INFO("kick isr!\n"); - spin_lock_irqsave(&mddi_host_spin_lock, - flags); - mddi_host_enable_hclk(); - mddi_host_reg_outm(INTEN, - MDDI_INT_NO_CMD_PKTS_PEND, - MDDI_INT_NO_CMD_PKTS_PEND); - spin_unlock_irqrestore - (&mddi_host_spin_lock, flags); - } - } - } -#endif /* #ifndef FEATURE_MDDI_DISABLE_REVERSE */ - } - - /* Check if logging is turned on */ - for (host_idx = MDDI_HOST_PRIM; host_idx < MDDI_NUM_HOST_CORES; - host_idx++) { - mddi_log_params_struct_type *prev_ptr = &(prev_parms[host_idx]); - pmhctl = &(mhctl[host_idx]); - - if (mddi_debug_log_statistics) { - - /* get video pkt count from MDP, since MDDI sw cannot know this */ - pmhctl->log_parms.vid_cnt = mdp_total_vdopkts; - - if (mddi_log_stats_counter >= mddi_log_stats_frequency) { - /* mddi_log_stats_counter = 0; */ - if (mddi_debug_log_statistics) { - MDDI_MSG_NOTICE - ("MDDI Statistics since last report:\n"); - MDDI_MSG_NOTICE(" Packets sent:\n"); - MDDI_MSG_NOTICE - (" %d RTD packet(s)\n", - pmhctl->log_parms.rtd_cnt - - prev_ptr->rtd_cnt); - if (prev_ptr->rtd_cnt != - pmhctl->log_parms.rtd_cnt) { - unsigned long flags; - spin_lock_irqsave - (&mddi_host_spin_lock, - flags); - mddi_host_enable_hclk(); - pmhctl->rtd_value = - mddi_host_reg_in(RTD_VAL); - spin_unlock_irqrestore - (&mddi_host_spin_lock, - flags); - MDDI_MSG_NOTICE - (" RTD value=%d\n", - pmhctl->rtd_value); - } - MDDI_MSG_NOTICE - (" %d VIDEO packets\n", - pmhctl->log_parms.vid_cnt - - prev_ptr->vid_cnt); - MDDI_MSG_NOTICE - (" %d Register Access packets\n", - pmhctl->log_parms.reg_acc_cnt - - prev_ptr->reg_acc_cnt); - MDDI_MSG_NOTICE - (" %d Reverse Encapsulation packet(s)\n", - pmhctl->log_parms.rev_enc_cnt - - prev_ptr->rev_enc_cnt); - if (prev_ptr->rev_enc_cnt != - pmhctl->log_parms.rev_enc_cnt) { - /* report # of reverse CRC errors */ - MDDI_MSG_NOTICE - (" %d reverse CRC errors detected\n", - pmhctl->log_parms. - rev_crc_cnt - - prev_ptr->rev_crc_cnt); - } - MDDI_MSG_NOTICE - (" Packets received:\n"); - MDDI_MSG_NOTICE - (" %d Client Status packets", - pmhctl->log_parms.cli_stat_cnt - - prev_ptr->cli_stat_cnt); - if (prev_ptr->cli_stat_cnt != - pmhctl->log_parms.cli_stat_cnt) { - MDDI_MSG_NOTICE - (" %d forward CRC errors reported\n", - pmhctl->log_parms. - fwd_crc_cnt - - prev_ptr->fwd_crc_cnt); - } - MDDI_MSG_NOTICE - (" %d Register Access Read packets\n", - pmhctl->log_parms.reg_read_cnt - - prev_ptr->reg_read_cnt); - - if (pmhctl->link_state == - MDDI_LINK_ACTIVE) { - MDDI_MSG_NOTICE - (" Current Link Status: Active\n"); - } else - if ((pmhctl->link_state == - MDDI_LINK_HIBERNATING) - || (pmhctl->link_state == - MDDI_LINK_ACTIVATING)) { - MDDI_MSG_NOTICE - (" Current Link Status: Hibernation\n"); - } else { - MDDI_MSG_NOTICE - (" Current Link Status: Inactive\n"); - } - MDDI_MSG_NOTICE - (" Active state entered %d times\n", - pmhctl->log_parms.link_active_cnt - - prev_ptr->link_active_cnt); - MDDI_MSG_NOTICE - (" Hibernation state entered %d times\n", - pmhctl->log_parms. - link_hibernate_cnt - - prev_ptr->link_hibernate_cnt); - } - } - prev_parms[host_idx] = pmhctl->log_parms; - } - } - if (mddi_log_stats_counter >= mddi_log_stats_frequency) - mddi_log_stats_counter = 0; - - return; -} /* mddi_host_timer_cb */ - -static void mddi_process_link_list_done(void) -{ - mddi_host_type host_idx = mddi_curr_host; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - /* normal forward linked list packet(s) were sent */ - if (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) { - MDDI_MSG_ERR("**** getting LL done, but no list ****\n"); - } else { - uint16 idx; - -#ifndef FEATURE_MDDI_DISABLE_REVERSE - if (pmhctl->rev_state == MDDI_REV_REG_READ_ISSUED) { - /* special case where a register read packet was sent */ - pmhctl->rev_state = MDDI_REV_REG_READ_SENT; - if (pmhctl->llist_info.reg_read_idx == UNASSIGNED_INDEX) { - MDDI_MSG_ERR - ("**** getting LL done, but no list ****\n"); - } - } -#endif - for (idx = pmhctl->llist_info.transmitting_start_idx;;) { - uint16 next_idx = pmhctl->llist_notify[idx].next_idx; - /* with reg read we don't release the waiting tcb until after - * the reverse encapsulation has completed. - */ - if (idx != pmhctl->llist_info.reg_read_idx) { - /* notify task that may be waiting on this completion */ - if (pmhctl->llist_notify[idx].waiting) { - complete(& - (pmhctl->llist_notify[idx]. - done_comp)); - } - if (pmhctl->llist_notify[idx].done_cb != NULL) { - (*(pmhctl->llist_notify[idx].done_cb)) - (); - } - - pmhctl->llist_notify[idx].in_use = FALSE; - pmhctl->llist_notify[idx].waiting = FALSE; - pmhctl->llist_notify[idx].done_cb = NULL; - if (idx < MDDI_NUM_DYNAMIC_LLIST_ITEMS) { - /* static LLIST items are configured only once */ - pmhctl->llist_notify[idx].next_idx = - UNASSIGNED_INDEX; - } - /* - * currently, all linked list packets are - * register access, so we can increment the - * counter for that packet type here. - */ - pmhctl->log_parms.reg_acc_cnt++; - } - if (idx == pmhctl->llist_info.transmitting_end_idx) - break; - idx = next_idx; - if (idx == UNASSIGNED_INDEX) - MDDI_MSG_CRIT("MDDI linked list corruption!\n"); - } - - pmhctl->llist_info.transmitting_start_idx = UNASSIGNED_INDEX; - pmhctl->llist_info.transmitting_end_idx = UNASSIGNED_INDEX; - - if (pmhctl->mddi_waiting_for_llist_avail) { - if (! - (pmhctl-> - llist_notify[pmhctl->llist_info.next_free_idx]. - in_use)) { - pmhctl->mddi_waiting_for_llist_avail = FALSE; - complete(&(pmhctl->mddi_llist_avail_comp)); - } - } - } - - /* Turn off MDDI_INT_PRI_LINK_LIST_DONE interrupt */ - mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE, 0); - -} - -static void mddi_queue_forward_linked_list(void) -{ - uint16 first_pkt_index; - mddi_linked_list_type *llist_dma; - mddi_host_type host_idx = mddi_curr_host; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - llist_dma = pmhctl->llist_dma_ptr; - - first_pkt_index = UNASSIGNED_INDEX; - - if (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) { -#ifndef FEATURE_MDDI_DISABLE_REVERSE - if (pmhctl->llist_info.reg_read_waiting) { - if (pmhctl->rev_state == MDDI_REV_IDLE) { - /* - * we have a register read to send and - * can send it now - */ - pmhctl->rev_state = MDDI_REV_REG_READ_ISSUED; - mddi_reg_read_retry = 0; - first_pkt_index = - pmhctl->llist_info.waiting_start_idx; - pmhctl->llist_info.reg_read_waiting = FALSE; - } - } else -#endif - { - /* - * not register read to worry about, go ahead and write - * anything that may be on the waiting list. - */ - first_pkt_index = pmhctl->llist_info.waiting_start_idx; - } - } - - if (first_pkt_index != UNASSIGNED_INDEX) { - pmhctl->llist_info.transmitting_start_idx = - pmhctl->llist_info.waiting_start_idx; - pmhctl->llist_info.transmitting_end_idx = - pmhctl->llist_info.waiting_end_idx; - pmhctl->llist_info.waiting_start_idx = UNASSIGNED_INDEX; - pmhctl->llist_info.waiting_end_idx = UNASSIGNED_INDEX; - - /* write to the primary pointer register */ - MDDI_MSG_DEBUG("MDDI writing primary ptr with idx=%d\n", - first_pkt_index); - - pmhctl->int_type.llist_ptr_write_2++; - - dma_coherent_pre_ops(); - mddi_host_reg_out(PRI_PTR, &llist_dma[first_pkt_index]); - - /* enable interrupt when complete */ - mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE, - MDDI_INT_PRI_LINK_LIST_DONE); - - } - -} - -#ifndef FEATURE_MDDI_DISABLE_REVERSE -static void mddi_read_rev_packet(byte *data_ptr) -{ - uint16 i, length; - mddi_host_type host_idx = mddi_curr_host; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - uint8 *rev_ptr_overflow = - (pmhctl->rev_ptr_start + MDDI_REV_BUFFER_SIZE); - - /* first determine the length and handle invalid lengths */ - length = *pmhctl->rev_ptr_curr++; - if (pmhctl->rev_ptr_curr >= rev_ptr_overflow) - pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; - length |= ((*pmhctl->rev_ptr_curr++) << 8); - if (pmhctl->rev_ptr_curr >= rev_ptr_overflow) - pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; - if (length > (pmhctl->rev_pkt_size - 2)) { - MDDI_MSG_ERR("Invalid rev pkt length %d\n", length); - /* rev_pkt_size should always be <= rev_ptr_size so limit to packet size */ - length = pmhctl->rev_pkt_size - 2; - } - - /* If the data pointer is NULL, just increment the pmhctl->rev_ptr_curr. - * Loop around if necessary. Don't bother reading the data. - */ - if (data_ptr == NULL) { - pmhctl->rev_ptr_curr += length; - if (pmhctl->rev_ptr_curr >= rev_ptr_overflow) - pmhctl->rev_ptr_curr -= MDDI_REV_BUFFER_SIZE; - return; - } - - data_ptr[0] = length & 0x0ff; - data_ptr[1] = length >> 8; - data_ptr += 2; - /* copy the data to data_ptr byte-at-a-time */ - for (i = 0; (i < length) && (pmhctl->rev_ptr_curr < rev_ptr_overflow); - i++) - *data_ptr++ = *pmhctl->rev_ptr_curr++; - if (pmhctl->rev_ptr_curr >= rev_ptr_overflow) - pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; - for (; (i < length) && (pmhctl->rev_ptr_curr < rev_ptr_overflow); i++) - *data_ptr++ = *pmhctl->rev_ptr_curr++; -} - -static void mddi_process_rev_packets(void) -{ - uint32 rev_packet_count; - word i; - uint32 crc_errors; - boolean mddi_reg_read_successful = FALSE; - mddi_host_type host_idx = mddi_curr_host; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - pmhctl->log_parms.rev_enc_cnt++; - if ((pmhctl->rev_state != MDDI_REV_ENCAP_ISSUED) && - (pmhctl->rev_state != MDDI_REV_STATUS_REQ_ISSUED) && - (pmhctl->rev_state != MDDI_REV_CLIENT_CAP_ISSUED)) { - MDDI_MSG_ERR("Wrong state %d for reverse int\n", - pmhctl->rev_state); - } - /* Turn off MDDI_INT_REV_AVAIL interrupt */ - mddi_host_reg_outm(INTEN, MDDI_INT_REV_DATA_AVAIL, 0); - - /* Clear rev data avail int */ - mddi_host_reg_out(INT, MDDI_INT_REV_DATA_AVAIL); - - /* Get Number of packets */ - rev_packet_count = mddi_host_reg_in(REV_PKT_CNT); - -#ifndef T_MSM7500 - /* Clear out rev packet counter */ - mddi_host_reg_out(REV_PKT_CNT, 0x0000); -#endif - -#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40) - if ((pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED) && - (rev_packet_count > 0) && - (mddi_host_core_version == 0x28 || - mddi_host_core_version == 0x30)) { - - uint32 int_reg; - uint32 max_count = 0; - - mddi_host_reg_out(REV_PTR, pmhctl->mddi_rev_ptr_write_val); - int_reg = mddi_host_reg_in(INT); - while ((int_reg & 0x100000) == 0) { - udelay(3); - int_reg = mddi_host_reg_in(INT); - if (++max_count > 100) - break; - } - } -#endif - - /* Get CRC error count */ - crc_errors = mddi_host_reg_in(REV_CRC_ERR); - if (crc_errors != 0) { - pmhctl->log_parms.rev_crc_cnt += crc_errors; - pmhctl->stats.rev_crc_count += crc_errors; - MDDI_MSG_ERR("!!! MDDI %d Reverse CRC Error(s) !!!\n", - crc_errors); -#ifndef T_MSM7500 - /* Clear CRC error count */ - mddi_host_reg_out(REV_CRC_ERR, 0x0000); -#endif - /* also issue an RTD to attempt recovery */ - pmhctl->rtd_counter = mddi_rtd_frequency; - } - - pmhctl->rtd_value = mddi_host_reg_in(RTD_VAL); - - MDDI_MSG_DEBUG("MDDI rev pkt cnt=%d, ptr=0x%x, RTD:0x%x\n", - rev_packet_count, - pmhctl->rev_ptr_curr - pmhctl->rev_ptr_start, - pmhctl->rtd_value); - - if (rev_packet_count >= 1) { - mddi_invalidate_cache_lines((uint32 *) pmhctl->rev_ptr_start, - MDDI_REV_BUFFER_SIZE); - } - /* order the reads */ - dma_coherent_post_ops(); - for (i = 0; i < rev_packet_count; i++) { - mddi_rev_packet_type *rev_pkt_ptr; - - mddi_read_rev_packet(rev_packet_data); - - rev_pkt_ptr = (mddi_rev_packet_type *) rev_packet_data; - - if (rev_pkt_ptr->packet_length > pmhctl->rev_pkt_size) { - MDDI_MSG_ERR("!!!invalid packet size: %d\n", - rev_pkt_ptr->packet_length); - } - - MDDI_MSG_DEBUG("MDDI rev pkt 0x%x size 0x%x\n", - rev_pkt_ptr->packet_type, - rev_pkt_ptr->packet_length); - - /* Do whatever you want to do with the data based on the packet type */ - switch (rev_pkt_ptr->packet_type) { - case 66: /* Client Capability */ - { - mddi_client_capability_type - *client_capability_pkt_ptr; - - client_capability_pkt_ptr = - (mddi_client_capability_type *) - rev_packet_data; - MDDI_MSG_NOTICE - ("Client Capability: Week=%d, Year=%d\n", - client_capability_pkt_ptr-> - Week_of_Manufacture, - client_capability_pkt_ptr-> - Year_of_Manufacture); - memcpy((void *)&mddi_client_capability_pkt, - (void *)rev_packet_data, - sizeof(mddi_client_capability_type)); - pmhctl->log_parms.cli_cap_cnt++; - } - break; - - case 70: /* Display Status */ - { - mddi_client_status_type *client_status_pkt_ptr; - - client_status_pkt_ptr = - (mddi_client_status_type *) rev_packet_data; - if ((client_status_pkt_ptr->crc_error_count != - 0) - || (client_status_pkt_ptr-> - reverse_link_request != 0)) { - MDDI_MSG_ERR - ("Client Status: RevReq=%d, CrcErr=%d\n", - client_status_pkt_ptr-> - reverse_link_request, - client_status_pkt_ptr-> - crc_error_count); - } else { - MDDI_MSG_DEBUG - ("Client Status: RevReq=%d, CrcErr=%d\n", - client_status_pkt_ptr-> - reverse_link_request, - client_status_pkt_ptr-> - crc_error_count); - } - pmhctl->log_parms.fwd_crc_cnt += - client_status_pkt_ptr->crc_error_count; - pmhctl->stats.fwd_crc_count += - client_status_pkt_ptr->crc_error_count; - pmhctl->log_parms.cli_stat_cnt++; - } - break; - - case 146: /* register access packet */ - { - mddi_register_access_packet_type - * regacc_pkt_ptr; - - regacc_pkt_ptr = - (mddi_register_access_packet_type *) - rev_packet_data; - - MDDI_MSG_DEBUG - ("Reg Acc parse reg=0x%x, value=0x%x\n", - regacc_pkt_ptr->register_address, - regacc_pkt_ptr->register_data_list); - - /* Copy register value to location passed in */ - if (mddi_reg_read_value_ptr) { -#if defined(T_MSM6280) && !defined(T_MSM7200) - /* only least significant 16 bits are valid with 6280 */ - *mddi_reg_read_value_ptr = - regacc_pkt_ptr-> - register_data_list & 0x0000ffff; -#else - *mddi_reg_read_value_ptr = - regacc_pkt_ptr->register_data_list; -#endif - mddi_reg_read_successful = TRUE; - mddi_reg_read_value_ptr = NULL; - } - -#ifdef DEBUG_MDDIHOSTI - if ((mddi_gpio.polling_enabled) && - (regacc_pkt_ptr->register_address == - mddi_gpio.polling_reg)) { - /* - * ToDo: need to call Linux GPIO call - * here... - */ - mddi_client_lcd_gpio_poll( - regacc_pkt_ptr->register_data_list); - } -#endif - pmhctl->log_parms.reg_read_cnt++; - } - break; - - default: /* any other packet */ - { - uint16 hdlr; - - for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS; - hdlr++) { - if (mddi_rev_pkt_handler[hdlr]. - pkt_type == - rev_pkt_ptr->packet_type) { - (* - (mddi_rev_pkt_handler[hdlr]. - handler)) (rev_pkt_ptr); - /* pmhctl->rev_state = MDDI_REV_IDLE; */ - break; - } - } - if (hdlr >= MAX_MDDI_REV_HANDLERS) - MDDI_MSG_ERR("MDDI unknown rev pkt\n"); - } - break; - } - } - if ((pmhctl->rev_ptr_curr + pmhctl->rev_pkt_size) >= - (pmhctl->rev_ptr_start + MDDI_REV_BUFFER_SIZE)) { - pmhctl->rev_ptr_written = FALSE; - } - - if (pmhctl->rev_state == MDDI_REV_ENCAP_ISSUED) { - pmhctl->rev_state = MDDI_REV_IDLE; - if (mddi_rev_user.waiting) { - mddi_rev_user.waiting = FALSE; - complete(&(mddi_rev_user.done_comp)); - } else if (pmhctl->llist_info.reg_read_idx == UNASSIGNED_INDEX) { - MDDI_MSG_ERR - ("Reverse Encap state, but no reg read in progress\n"); - } else { - if ((!mddi_reg_read_successful) && - (mddi_reg_read_retry < mddi_reg_read_retry_max) && - (mddi_enable_reg_read_retry)) { - /* - * There is a race condition that can happen - * where the reverse encapsulation message is - * sent out by the MDDI host before the register - * read packet is sent. As a work-around for - * that problem we issue the reverse - * encapsulation one more time before giving up. - */ - if (mddi_enable_reg_read_retry_once) - mddi_reg_read_retry = - mddi_reg_read_retry_max; - pmhctl->rev_state = MDDI_REV_REG_READ_SENT; - pmhctl->stats.reg_read_failure++; - } else { - uint16 reg_read_idx = - pmhctl->llist_info.reg_read_idx; - - mddi_reg_read_retry = 0; - if (pmhctl->llist_notify[reg_read_idx].waiting) { - complete(& - (pmhctl-> - llist_notify[reg_read_idx]. - done_comp)); - } - pmhctl->llist_info.reg_read_idx = - UNASSIGNED_INDEX; - if (pmhctl->llist_notify[reg_read_idx]. - done_cb != NULL) { - (* - (pmhctl->llist_notify[reg_read_idx]. - done_cb)) (); - } - pmhctl->llist_notify[reg_read_idx].next_idx = - UNASSIGNED_INDEX; - pmhctl->llist_notify[reg_read_idx].in_use = - FALSE; - pmhctl->llist_notify[reg_read_idx].waiting = - FALSE; - pmhctl->llist_notify[reg_read_idx].done_cb = - NULL; - if (!mddi_reg_read_successful) - pmhctl->stats.reg_read_failure++; - } - } - } else if (pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED) { -#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40) - if (mddi_host_core_version == 0x28 || - mddi_host_core_version == 0x30) { - mddi_host_reg_out(FIFO_ALLOC, 0x00); - pmhctl->rev_ptr_written = TRUE; - mddi_host_reg_out(REV_PTR, - pmhctl->mddi_rev_ptr_write_val); - pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; - mddi_host_reg_out(CMD, 0xC00); - } -#endif - - if (mddi_rev_user.waiting) { - mddi_rev_user.waiting = FALSE; - complete(&(mddi_rev_user.done_comp)); - } - pmhctl->rev_state = MDDI_REV_IDLE; - } else { - pmhctl->rev_state = MDDI_REV_IDLE; - } - - /* pmhctl->rev_state = MDDI_REV_IDLE; */ - - /* Re-enable interrupt */ - mddi_host_reg_outm(INTEN, MDDI_INT_REV_DATA_AVAIL, - MDDI_INT_REV_DATA_AVAIL); - -} - -static void mddi_issue_reverse_encapsulation(void) -{ - mddi_host_type host_idx = mddi_curr_host; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - /* Only issue a reverse encapsulation packet if: - * 1) another reverse is not in progress (MDDI_REV_IDLE). - * 2) a register read has been sent (MDDI_REV_REG_READ_SENT). - * 3) forward is not in progress, because of a hw bug in client that - * causes forward crc errors on packet immediately after rev encap. - */ - if (((pmhctl->rev_state == MDDI_REV_IDLE) || - (pmhctl->rev_state == MDDI_REV_REG_READ_SENT)) && - (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) && - (!mdp_in_processing)) { - uint32 mddi_command = MDDI_CMD_SEND_REV_ENCAP; - - if ((pmhctl->rev_state == MDDI_REV_REG_READ_SENT) || - (mddi_rev_encap_user_request == TRUE)) { - mddi_host_enable_io_clock(); - if (pmhctl->link_state == MDDI_LINK_HIBERNATING) { - /* need to wake up link before issuing rev encap command */ - MDDI_MSG_DEBUG("wake up link!\n"); - pmhctl->link_state = MDDI_LINK_ACTIVATING; - mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE); - } else { - if (pmhctl->rtd_counter >= mddi_rtd_frequency) { - MDDI_MSG_DEBUG - ("mddi sending RTD command!\n"); - mddi_host_reg_out(CMD, - MDDI_CMD_SEND_RTD); - pmhctl->rtd_counter = 0; - pmhctl->log_parms.rtd_cnt++; - } - if (pmhctl->rev_state != MDDI_REV_REG_READ_SENT) { - /* this is generic reverse request by user, so - * reset the waiting flag. */ - mddi_rev_encap_user_request = FALSE; - } - /* link is active so send reverse encap to get register read results */ - pmhctl->rev_state = MDDI_REV_ENCAP_ISSUED; - mddi_command = MDDI_CMD_SEND_REV_ENCAP; - MDDI_MSG_DEBUG("sending rev encap!\n"); - } - } else - if ((pmhctl->client_status_cnt >= - mddi_client_status_frequency) - || mddi_client_capability_request) { - mddi_host_enable_io_clock(); - if (pmhctl->link_state == MDDI_LINK_HIBERNATING) { - /* only wake up the link if it client status is overdue */ - if ((pmhctl->client_status_cnt >= - (mddi_client_status_frequency * 2)) - || mddi_client_capability_request) { - /* need to wake up link before issuing rev encap command */ - MDDI_MSG_DEBUG("wake up link!\n"); - pmhctl->link_state = - MDDI_LINK_ACTIVATING; - mddi_host_reg_out(CMD, - MDDI_CMD_LINK_ACTIVE); - } - } else { - if (pmhctl->rtd_counter >= mddi_rtd_frequency) { - MDDI_MSG_DEBUG - ("mddi sending RTD command!\n"); - mddi_host_reg_out(CMD, - MDDI_CMD_SEND_RTD); - pmhctl->rtd_counter = 0; - pmhctl->log_parms.rtd_cnt++; - } - /* periodically get client status */ - MDDI_MSG_DEBUG - ("mddi sending rev enc! (get status)\n"); - if (mddi_client_capability_request) { - pmhctl->rev_state = - MDDI_REV_CLIENT_CAP_ISSUED; - mddi_command = MDDI_CMD_GET_CLIENT_CAP; - mddi_client_capability_request = FALSE; - } else { - pmhctl->rev_state = - MDDI_REV_STATUS_REQ_ISSUED; - pmhctl->client_status_cnt = 0; - mddi_command = - MDDI_CMD_GET_CLIENT_STATUS; - } - } - } - if ((pmhctl->rev_state == MDDI_REV_ENCAP_ISSUED) || - (pmhctl->rev_state == MDDI_REV_STATUS_REQ_ISSUED) || - (pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED)) { - pmhctl->int_type.rev_encap_count++; -#if defined(T_MSM6280) && !defined(T_MSM7200) - mddi_rev_pointer_written = TRUE; - mddi_host_reg_out(REV_PTR, mddi_rev_ptr_write_val); - mddi_rev_ptr_curr = mddi_rev_ptr_start; - /* force new rev ptr command */ - mddi_host_reg_out(CMD, 0xC00); -#else - if (!pmhctl->rev_ptr_written) { - MDDI_MSG_DEBUG("writing reverse pointer!\n"); - pmhctl->rev_ptr_written = TRUE; -#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40) - if ((pmhctl->rev_state == - MDDI_REV_CLIENT_CAP_ISSUED) && - (mddi_host_core_version == 0x28 || - mddi_host_core_version == 0x30)) { - pmhctl->rev_ptr_written = FALSE; - mddi_host_reg_out(FIFO_ALLOC, 0x02); - } else - mddi_host_reg_out(REV_PTR, - pmhctl-> - mddi_rev_ptr_write_val); -#else - mddi_host_reg_out(REV_PTR, - pmhctl-> - mddi_rev_ptr_write_val); -#endif - } -#endif - if (mddi_debug_clear_rev_data) { - uint16 i; - for (i = 0; i < MDDI_MAX_REV_DATA_SIZE / 4; i++) - pmhctl->rev_data_buf[i] = 0xdddddddd; - /* clean cache */ - mddi_flush_cache_lines(pmhctl->rev_data_buf, - MDDI_MAX_REV_DATA_SIZE); - } - - /* send reverse encapsulation to get needed data */ - mddi_host_reg_out(CMD, mddi_command); - } - } - -} - -static void mddi_process_client_initiated_wakeup(void) -{ - mddi_host_type host_idx = mddi_curr_host; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - /* Disable MDDI_INT Interrupt, we detect client initiated wakeup one - * time for each entry into hibernation */ - mddi_host_reg_outm(INTEN, MDDI_INT_MDDI_IN, 0); - - if (host_idx == MDDI_HOST_PRIM) { - if (mddi_vsync_detect_enabled) { - mddi_host_enable_io_clock(); -#ifndef MDDI_HOST_DISP_LISTEN - /* issue command to bring up link */ - /* need to do this to clear the vsync condition */ - if (pmhctl->link_state == MDDI_LINK_HIBERNATING) { - pmhctl->link_state = MDDI_LINK_ACTIVATING; - mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE); - } -#endif - /* - * Indicate to client specific code that vsync was - * enabled, and we did not detect a client initiated - * wakeup. The client specific handler can clear the - * condition if necessary to prevent subsequent - * client initiated wakeups. - */ - mddi_client_lcd_vsync_detected(TRUE); - pmhctl->log_parms.vsync_response_cnt++; - MDDI_MSG_NOTICE("MDDI_INT_IN condition\n"); - - } - } - - if (mddi_gpio.polling_enabled) { - mddi_host_enable_io_clock(); - /* check interrupt status now */ - (void)mddi_queue_register_read_int(mddi_gpio.polling_reg, - &mddi_gpio.polling_val); - } -} -#endif /* FEATURE_MDDI_DISABLE_REVERSE */ - -static void mddi_host_isr(void) -{ - uint32 int_reg, int_en; -#ifndef FEATURE_MDDI_DISABLE_REVERSE - uint32 status_reg; -#endif - mddi_host_type host_idx = mddi_curr_host; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - if (!MDDI_HOST_IS_HCLK_ON) { - MDDI_HOST_ENABLE_HCLK; - MDDI_MSG_DEBUG("HCLK disabled, but isr is firing\n"); - } - int_reg = mddi_host_reg_in(INT); - int_en = mddi_host_reg_in(INTEN); - pmhctl->saved_int_reg = int_reg; - pmhctl->saved_int_en = int_en; - int_reg = int_reg & int_en; - pmhctl->int_type.count++; - - -#ifndef FEATURE_MDDI_DISABLE_REVERSE - status_reg = mddi_host_reg_in(STAT); - - if ((int_reg & MDDI_INT_MDDI_IN) || - ((int_en & MDDI_INT_MDDI_IN) && - ((int_reg == 0) || (status_reg & MDDI_STAT_CLIENT_WAKEUP_REQ)))) { - /* - * The MDDI_IN condition will clear itself, and so it is - * possible that MDDI_IN was the reason for the isr firing, - * even though the interrupt register does not have the - * MDDI_IN bit set. To check if this was the case we need to - * look at the status register bit that signifies a client - * initiated wakeup. If the status register bit is set, as well - * as the MDDI_IN interrupt enabled, then we treat this as a - * client initiated wakeup. - */ - if (int_reg & MDDI_INT_MDDI_IN) - pmhctl->int_type.in_count++; - mddi_process_client_initiated_wakeup(); - } -#endif - - if (int_reg & MDDI_INT_LINK_STATE_CHANGES) { - pmhctl->int_type.state_change_count++; - mddi_report_state_change(int_reg); - } - - if (int_reg & MDDI_INT_PRI_LINK_LIST_DONE) { - pmhctl->int_type.ll_done_count++; - mddi_process_link_list_done(); - } -#ifndef FEATURE_MDDI_DISABLE_REVERSE - if (int_reg & MDDI_INT_REV_DATA_AVAIL) { - pmhctl->int_type.rev_avail_count++; - mddi_process_rev_packets(); - } -#endif - - if (int_reg & MDDI_INT_ERROR_CONDITIONS) { - pmhctl->int_type.error_count++; - mddi_report_errors(int_reg); - - mddi_host_reg_out(INT, int_reg & MDDI_INT_ERROR_CONDITIONS); - } -#ifndef FEATURE_MDDI_DISABLE_REVERSE - mddi_issue_reverse_encapsulation(); - - if ((pmhctl->rev_state != MDDI_REV_ENCAP_ISSUED) && - (pmhctl->rev_state != MDDI_REV_STATUS_REQ_ISSUED)) -#endif - /* don't want simultaneous reverse and forward with Eagle */ - mddi_queue_forward_linked_list(); - - if (int_reg & MDDI_INT_NO_CMD_PKTS_PEND) { - /* this interrupt is used to kick the isr when hibernation is disabled */ - mddi_host_reg_outm(INTEN, MDDI_INT_NO_CMD_PKTS_PEND, 0); - } - - if ((!mddi_host_mdp_active_flag) && - (!mddi_vsync_detect_enabled) && - (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) && - (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) && - (pmhctl->rev_state == MDDI_REV_IDLE)) { - if (pmhctl->link_state == MDDI_LINK_HIBERNATING) { - mddi_host_disable_io_clock(); - mddi_host_disable_hclk(); - } -#ifdef FEATURE_MDDI_HOST_ENABLE_EARLY_HIBERNATION - else if ((pmhctl->link_state == MDDI_LINK_ACTIVE) && - (!pmhctl->disable_hibernation)) { - mddi_host_reg_out(CMD, MDDI_CMD_POWERDOWN); - } -#endif - } -} - -static void mddi_host_isr_primary(void) -{ - mddi_curr_host = MDDI_HOST_PRIM; - mddi_host_isr(); -} - -irqreturn_t mddi_pmdh_isr_proxy(int irq, void *ptr) -{ - mddi_host_isr_primary(); - return IRQ_HANDLED; -} - -static void mddi_host_isr_external(void) -{ - mddi_curr_host = MDDI_HOST_EXT; - mddi_host_isr(); - mddi_curr_host = MDDI_HOST_PRIM; -} - -irqreturn_t mddi_emdh_isr_proxy(int irq, void *ptr) -{ - mddi_host_isr_external(); - return IRQ_HANDLED; -} - -static void mddi_host_initialize_registers(mddi_host_type host_idx) -{ - uint32 pad_reg_val; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - if (pmhctl->driver_state == MDDI_DRIVER_ENABLED) - return; - - /* turn on HCLK to MDDI host core */ - mddi_host_enable_hclk(); - - /* MDDI Reset command */ - mddi_host_reg_out(CMD, MDDI_CMD_RESET); - - /* Version register (= 0x01) */ - mddi_host_reg_out(VERSION, 0x0001); - - /* Bytes per subframe register */ - mddi_host_reg_out(BPS, MDDI_HOST_BYTES_PER_SUBFRAME); - - /* Subframes per media frames register (= 0x03) */ - mddi_host_reg_out(SPM, 0x0003); - - /* Turn Around 1 register (= 0x05) */ - mddi_host_reg_out(TA1_LEN, 0x0005); - - /* Turn Around 2 register (= 0x0C) */ - mddi_host_reg_out(TA2_LEN, MDDI_HOST_TA2_LEN); - - /* Drive hi register (= 0x96) */ - mddi_host_reg_out(DRIVE_HI, 0x0096); - - /* Drive lo register (= 0x32) */ - mddi_host_reg_out(DRIVE_LO, 0x0032); - - /* Display wakeup count register (= 0x3c) */ - mddi_host_reg_out(DISP_WAKE, 0x003c); - - /* Reverse Rate Divisor register (= 0x2) */ - mddi_host_reg_out(REV_RATE_DIV, MDDI_HOST_REV_RATE_DIV); - -#ifndef FEATURE_MDDI_DISABLE_REVERSE - /* Reverse Pointer Size */ - mddi_host_reg_out(REV_SIZE, MDDI_REV_BUFFER_SIZE); - - /* Rev Encap Size */ - mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size); -#endif - - /* Periodic Rev Encap */ - /* don't send periodically */ - mddi_host_reg_out(CMD, MDDI_CMD_PERIODIC_REV_ENCAP); - - pad_reg_val = mddi_host_reg_in(PAD_CTL); - if (pad_reg_val == 0) { - /* If we are turning on band gap, need to wait 5us before turning - * on the rest of the PAD */ - mddi_host_reg_out(PAD_CTL, 0x08000); - udelay(5); - } -#ifdef T_MSM7200 - /* Recommendation from PAD hw team */ - mddi_host_reg_out(PAD_CTL, 0xa850a); -#else - /* Recommendation from PAD hw team */ - mddi_host_reg_out(PAD_CTL, 0xa850f); -#endif - -#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40) - mddi_host_reg_out(PAD_IO_CTL, 0x00320000); - mddi_host_reg_out(PAD_CAL, 0x00220020); -#endif - - mddi_host_core_version = mddi_host_reg_inm(CORE_VER, 0xffff); - -#ifndef FEATURE_MDDI_DISABLE_REVERSE - if (mddi_host_core_version >= 8) - mddi_rev_ptr_workaround = FALSE; - pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; -#endif - - if ((mddi_host_core_version > 8) && (mddi_host_core_version < 0x19)) - mddi_host_reg_out(TEST, 0x2); - - /* Need an even number for counts */ - mddi_host_reg_out(DRIVER_START_CNT, 0x60006); - -#ifndef T_MSM7500 - /* Setup defaults for MDP related register */ - mddi_host_reg_out(MDP_VID_FMT_DES, 0x5666); - mddi_host_reg_out(MDP_VID_PIX_ATTR, 0x00C3); - mddi_host_reg_out(MDP_VID_CLIENTID, 0); -#endif - - /* automatically hibernate after 1 empty subframe */ - if (pmhctl->disable_hibernation) - mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE); - else - mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1); - - /* Bring up link if display (client) requests it */ -#ifdef MDDI_HOST_DISP_LISTEN - mddi_host_reg_out(CMD, MDDI_CMD_DISP_LISTEN); -#else - mddi_host_reg_out(CMD, MDDI_CMD_DISP_IGNORE); -#endif - -} - -void mddi_host_configure_interrupts(mddi_host_type host_idx, boolean enable) -{ - unsigned long flags; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - spin_lock_irqsave(&mddi_host_spin_lock, flags); - - /* turn on HCLK to MDDI host core if it has been disabled */ - mddi_host_enable_hclk(); - /* Clear MDDI Interrupt enable reg */ - mddi_host_reg_out(INTEN, 0); - - spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - - if (enable) { - pmhctl->driver_state = MDDI_DRIVER_ENABLED; - - if (host_idx == MDDI_HOST_PRIM) { - if (request_irq - (INT_MDDI_PRI, mddi_pmdh_isr_proxy, IRQF_DISABLED, - "PMDH", 0) != 0) - printk(KERN_ERR - "a mddi: unable to request_irq\n"); - else - int_mddi_pri_flag = TRUE; - } else { - if (request_irq - (INT_MDDI_EXT, mddi_emdh_isr_proxy, IRQF_DISABLED, - "EMDH", 0) != 0) - printk(KERN_ERR - "b mddi: unable to request_irq\n"); - else - int_mddi_ext_flag = TRUE; - } - - /* Set MDDI Interrupt enable reg -- Enable Reverse data avail */ -#ifdef FEATURE_MDDI_DISABLE_REVERSE - mddi_host_reg_out(INTEN, - MDDI_INT_ERROR_CONDITIONS | - MDDI_INT_LINK_STATE_CHANGES); -#else - /* Reverse Pointer register */ - pmhctl->rev_ptr_written = FALSE; - - mddi_host_reg_out(INTEN, - MDDI_INT_REV_DATA_AVAIL | - MDDI_INT_ERROR_CONDITIONS | - MDDI_INT_LINK_STATE_CHANGES); - pmhctl->rtd_counter = mddi_rtd_frequency; - pmhctl->client_status_cnt = 0; -#endif - } else { - if (pmhctl->driver_state == MDDI_DRIVER_ENABLED) - pmhctl->driver_state = MDDI_DRIVER_DISABLED; - } - -} - -static void mddi_host_powerup(mddi_host_type host_idx) -{ - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - if (pmhctl->link_state != MDDI_LINK_DISABLED) - return; - - /* enable IO_CLK and hclk to MDDI host core */ - mddi_host_enable_io_clock(); - - mddi_host_initialize_registers(host_idx); - mddi_host_configure_interrupts(host_idx, TRUE); - - pmhctl->link_state = MDDI_LINK_ACTIVATING; - - /* Link activate command */ - mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE); - -#ifdef CLKRGM_MDDI_IO_CLOCK_IN_MHZ - MDDI_MSG_NOTICE("MDDI Host: Activating Link %d Mbps\n", - CLKRGM_MDDI_IO_CLOCK_IN_MHZ * 2); -#else - MDDI_MSG_NOTICE("MDDI Host: Activating Link\n"); -#endif - - /* Initialize the timer */ - if (host_idx == MDDI_HOST_PRIM) - mddi_host_timer_service(0); -} - -void mddi_host_init(mddi_host_type host_idx) -/* Write out the MDDI configuration registers */ -{ - static boolean initialized = FALSE; - mddi_host_cntl_type *pmhctl; - - if (host_idx >= MDDI_NUM_HOST_CORES) { - MDDI_MSG_ERR("Invalid host core index\n"); - return; - } - - if (!initialized) { - uint16 idx; - mddi_host_type host; - for (host = MDDI_HOST_PRIM; host < MDDI_NUM_HOST_CORES; host++) { - pmhctl = &(mhctl[host]); - initialized = TRUE; - - pmhctl->llist_ptr = - dma_alloc_coherent(NULL, MDDI_LLIST_POOL_SIZE, - &(pmhctl->llist_dma_addr), - GFP_KERNEL); - pmhctl->llist_dma_ptr = - (mddi_linked_list_type *) (void *)pmhctl-> - llist_dma_addr; -#ifdef FEATURE_MDDI_DISABLE_REVERSE - pmhctl->rev_data_buf = NULL; - if (pmhctl->llist_ptr == NULL) -#else - mddi_rev_user.waiting = FALSE; - init_completion(&(mddi_rev_user.done_comp)); - pmhctl->rev_data_buf = - dma_alloc_coherent(NULL, MDDI_MAX_REV_DATA_SIZE, - &(pmhctl->rev_data_dma_addr), - GFP_KERNEL); - if ((pmhctl->llist_ptr == NULL) - || (pmhctl->rev_data_buf == NULL)) -#endif - { - MDDI_MSG_CRIT - ("unable to alloc non-cached memory\n"); - } - llist_extern[host] = pmhctl->llist_ptr; - llist_dma_extern[host] = pmhctl->llist_dma_ptr; - llist_extern_notify[host] = pmhctl->llist_notify; - - for (idx = 0; idx < UNASSIGNED_INDEX; idx++) { - init_completion(& - (pmhctl->llist_notify[idx]. - done_comp)); - } - init_completion(&(pmhctl->mddi_llist_avail_comp)); - spin_lock_init(&mddi_host_spin_lock); - pmhctl->mddi_waiting_for_llist_avail = FALSE; - pmhctl->mddi_rev_ptr_write_val = - (uint32) (void *)(pmhctl->rev_data_dma_addr); - pmhctl->rev_ptr_start = (void *)pmhctl->rev_data_buf; - - pmhctl->rev_pkt_size = MDDI_DEFAULT_REV_PKT_SIZE; - pmhctl->rev_state = MDDI_REV_IDLE; -#ifdef IMAGE_MODEM_PROC - /* assume hibernation state is last state from APPS proc, so that - * we don't reinitialize the host core */ - pmhctl->link_state = MDDI_LINK_HIBERNATING; -#else - pmhctl->link_state = MDDI_LINK_DISABLED; -#endif - pmhctl->driver_state = MDDI_DRIVER_DISABLED; - pmhctl->disable_hibernation = FALSE; - - /* initialize llist variables */ - pmhctl->llist_info.transmitting_start_idx = - UNASSIGNED_INDEX; - pmhctl->llist_info.transmitting_end_idx = - UNASSIGNED_INDEX; - pmhctl->llist_info.waiting_start_idx = UNASSIGNED_INDEX; - pmhctl->llist_info.waiting_end_idx = UNASSIGNED_INDEX; - pmhctl->llist_info.reg_read_idx = UNASSIGNED_INDEX; - pmhctl->llist_info.next_free_idx = - MDDI_FIRST_DYNAMIC_LLIST_IDX; - pmhctl->llist_info.reg_read_waiting = FALSE; - - mddi_vsync_detect_enabled = FALSE; - mddi_gpio.polling_enabled = FALSE; - - pmhctl->int_type.count = 0; - pmhctl->int_type.in_count = 0; - pmhctl->int_type.disp_req_count = 0; - pmhctl->int_type.state_change_count = 0; - pmhctl->int_type.ll_done_count = 0; - pmhctl->int_type.rev_avail_count = 0; - pmhctl->int_type.error_count = 0; - pmhctl->int_type.rev_encap_count = 0; - pmhctl->int_type.llist_ptr_write_1 = 0; - pmhctl->int_type.llist_ptr_write_2 = 0; - - pmhctl->stats.fwd_crc_count = 0; - pmhctl->stats.rev_crc_count = 0; - pmhctl->stats.pri_underflow = 0; - pmhctl->stats.sec_underflow = 0; - pmhctl->stats.rev_overflow = 0; - pmhctl->stats.pri_overwrite = 0; - pmhctl->stats.sec_overwrite = 0; - pmhctl->stats.rev_overwrite = 0; - pmhctl->stats.dma_failure = 0; - pmhctl->stats.rtd_failure = 0; - pmhctl->stats.reg_read_failure = 0; -#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY - pmhctl->stats.pri_underrun_detected = 0; -#endif - - pmhctl->log_parms.rtd_cnt = 0; - pmhctl->log_parms.rev_enc_cnt = 0; - pmhctl->log_parms.vid_cnt = 0; - pmhctl->log_parms.reg_acc_cnt = 0; - pmhctl->log_parms.cli_stat_cnt = 0; - pmhctl->log_parms.cli_cap_cnt = 0; - pmhctl->log_parms.reg_read_cnt = 0; - pmhctl->log_parms.link_active_cnt = 0; - pmhctl->log_parms.link_hibernate_cnt = 0; - pmhctl->log_parms.fwd_crc_cnt = 0; - pmhctl->log_parms.rev_crc_cnt = 0; - pmhctl->log_parms.vsync_response_cnt = 0; - - prev_parms[host_idx] = pmhctl->log_parms; - mddi_client_capability_pkt.packet_length = 0; - } - -#ifndef T_MSM7500 - /* tell clock driver we are user of this PLL */ - MDDI_HOST_ENABLE_IO_CLOCK; -#endif - } - - mddi_host_powerup(host_idx); - pmhctl = &(mhctl[host_idx]); -} - -#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT -static uint32 mddi_client_id; - -uint32 mddi_get_client_id(void) -{ - -#ifndef FEATURE_MDDI_DISABLE_REVERSE - mddi_host_type host_idx = MDDI_HOST_PRIM; - static boolean client_detection_try = FALSE; - mddi_host_cntl_type *pmhctl; - unsigned long flags; - uint16 saved_rev_pkt_size; - - if (!client_detection_try) { - /* Toshiba display requires larger drive_lo value */ - mddi_host_reg_out(DRIVE_LO, 0x0050); - - pmhctl = &(mhctl[MDDI_HOST_PRIM]); - - saved_rev_pkt_size = pmhctl->rev_pkt_size; - - /* Increase Rev Encap Size */ - pmhctl->rev_pkt_size = MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE; - mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size); - - /* disable hibernation temporarily */ - if (!pmhctl->disable_hibernation) - mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE); - - mddi_rev_user.waiting = TRUE; - INIT_COMPLETION(mddi_rev_user.done_comp); - - spin_lock_irqsave(&mddi_host_spin_lock, flags); - - /* turn on clock(s), if they have been disabled */ - mddi_host_enable_hclk(); - mddi_host_enable_io_clock(); - - mddi_client_capability_request = TRUE; - - if (pmhctl->rev_state == MDDI_REV_IDLE) { - /* attempt to send the reverse encapsulation now */ - mddi_issue_reverse_encapsulation(); - } - spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - - wait_for_completion_killable(&(mddi_rev_user.done_comp)); - - /* Set Rev Encap Size back to its original value */ - pmhctl->rev_pkt_size = saved_rev_pkt_size; - mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size); - - /* reenable auto-hibernate */ - if (!pmhctl->disable_hibernation) - mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1); - - mddi_host_reg_out(DRIVE_LO, 0x0032); - client_detection_try = TRUE; - - mddi_client_id = (mddi_client_capability_pkt.Mfr_Name<<16) | - mddi_client_capability_pkt.Product_Code; - - if (!mddi_client_id) - mddi_disable(1); - } - -#if 0 - switch (mddi_client_capability_pkt.Mfr_Name) { - case 0x4474: - if ((mddi_client_capability_pkt.Product_Code != 0x8960) && - (target == DISPLAY_1)) { - ret = PRISM_WVGA; - } - break; - - case 0xD263: - if (target == DISPLAY_1) - ret = TOSHIBA_VGA_PRIM; - else if (target == DISPLAY_2) - ret = TOSHIBA_QCIF_SECD; - break; - - case 0: - if (mddi_client_capability_pkt.Product_Code == 0x8835) { - if (target == DISPLAY_1) - ret = SHARP_QVGA_PRIM; - else if (target == DISPLAY_2) - ret = SHARP_128x128_SECD; - } - break; - - default: - break; - } - - if ((!client_detection_try) && (ret != TOSHIBA_VGA_PRIM) - && (ret != TOSHIBA_QCIF_SECD)) { - /* Not a Toshiba display, so change drive_lo back to default value */ - mddi_host_reg_out(DRIVE_LO, 0x0032); - } -#endif - -#endif - - return mddi_client_id; -} -#endif - -void mddi_host_powerdown(mddi_host_type host_idx) -{ - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - if (host_idx >= MDDI_NUM_HOST_CORES) { - MDDI_MSG_ERR("Invalid host core index\n"); - return; - } - - if (pmhctl->driver_state == MDDI_DRIVER_RESET) { - return; - } - - if (host_idx == MDDI_HOST_PRIM) { - /* disable timer */ - del_timer(&mddi_host_timer); - } - - mddi_host_configure_interrupts(host_idx, FALSE); - - /* turn on HCLK to MDDI host core if it has been disabled */ - mddi_host_enable_hclk(); - - /* MDDI Reset command */ - mddi_host_reg_out(CMD, MDDI_CMD_RESET); - - /* Pad Control Register */ - mddi_host_reg_out(PAD_CTL, 0x0); - - /* disable IO_CLK and hclk to MDDI host core */ - mddi_host_disable_io_clock(); - mddi_host_disable_hclk(); - - pmhctl->link_state = MDDI_LINK_DISABLED; - pmhctl->driver_state = MDDI_DRIVER_RESET; - - MDDI_MSG_NOTICE("MDDI Host: Disabling Link\n"); - -} - -uint16 mddi_get_next_free_llist_item(mddi_host_type host_idx, boolean wait) -{ - unsigned long flags; - uint16 ret_idx; - boolean forced_wait = FALSE; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - ret_idx = pmhctl->llist_info.next_free_idx; - - pmhctl->llist_info.next_free_idx++; - if (pmhctl->llist_info.next_free_idx >= MDDI_NUM_DYNAMIC_LLIST_ITEMS) - pmhctl->llist_info.next_free_idx = MDDI_FIRST_DYNAMIC_LLIST_IDX; - spin_lock_irqsave(&mddi_host_spin_lock, flags); - if (pmhctl->llist_notify[ret_idx].in_use) { - if (!wait) { - pmhctl->llist_info.next_free_idx = ret_idx; - ret_idx = UNASSIGNED_INDEX; - } else { - forced_wait = TRUE; - INIT_COMPLETION(pmhctl->mddi_llist_avail_comp); - } - } - spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - - if (forced_wait) { - wait_for_completion_killable(& - (pmhctl-> - mddi_llist_avail_comp)); - MDDI_MSG_ERR("task waiting on mddi llist item\n"); - } - - if (ret_idx != UNASSIGNED_INDEX) { - pmhctl->llist_notify[ret_idx].waiting = FALSE; - pmhctl->llist_notify[ret_idx].done_cb = NULL; - pmhctl->llist_notify[ret_idx].in_use = TRUE; - pmhctl->llist_notify[ret_idx].next_idx = UNASSIGNED_INDEX; - } - - return ret_idx; -} - -uint16 mddi_get_reg_read_llist_item(mddi_host_type host_idx, boolean wait) -{ -#ifdef FEATURE_MDDI_DISABLE_REVERSE - MDDI_MSG_CRIT("No reverse link available\n"); - (void)wait; - return FALSE; -#else - unsigned long flags; - uint16 ret_idx; - boolean error = FALSE; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - spin_lock_irqsave(&mddi_host_spin_lock, flags); - if (pmhctl->llist_info.reg_read_idx != UNASSIGNED_INDEX) { - /* need to block here or is this an error condition? */ - error = TRUE; - ret_idx = UNASSIGNED_INDEX; - } - spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - - if (!error) { - ret_idx = pmhctl->llist_info.reg_read_idx = - mddi_get_next_free_llist_item(host_idx, wait); - /* clear the reg_read_waiting flag */ - pmhctl->llist_info.reg_read_waiting = FALSE; - } - - if (error) - MDDI_MSG_ERR("***** Reg read still in progress! ****\n"); - return ret_idx; -#endif - -} - -void mddi_queue_forward_packets(uint16 first_llist_idx, - uint16 last_llist_idx, - boolean wait, - mddi_llist_done_cb_type llist_done_cb, - mddi_host_type host_idx) -{ - unsigned long flags; - mddi_linked_list_type *llist; - mddi_linked_list_type *llist_dma; - mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - - if ((first_llist_idx >= UNASSIGNED_INDEX) || - (last_llist_idx >= UNASSIGNED_INDEX)) { - MDDI_MSG_ERR("MDDI queueing invalid linked list\n"); - return; - } - - if (pmhctl->link_state == MDDI_LINK_DISABLED) - MDDI_MSG_CRIT("MDDI host powered down!\n"); - - llist = pmhctl->llist_ptr; - llist_dma = pmhctl->llist_dma_ptr; - - /* clean cache so MDDI host can read data */ - memory_barrier(); - - pmhctl->llist_notify[last_llist_idx].waiting = wait; - if (wait) - INIT_COMPLETION(pmhctl->llist_notify[last_llist_idx].done_comp); - pmhctl->llist_notify[last_llist_idx].done_cb = llist_done_cb; - - spin_lock_irqsave(&mddi_host_spin_lock, flags); - - if ((pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) && - (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) && - (pmhctl->rev_state == MDDI_REV_IDLE)) { - /* no packets are currently transmitting */ -#ifndef FEATURE_MDDI_DISABLE_REVERSE - if (first_llist_idx == pmhctl->llist_info.reg_read_idx) { - /* This is the special case where the packet is a register read. */ - pmhctl->rev_state = MDDI_REV_REG_READ_ISSUED; - mddi_reg_read_retry = 0; - /* mddi_rev_reg_read_attempt = 1; */ - } -#endif - /* assign transmitting index values */ - pmhctl->llist_info.transmitting_start_idx = first_llist_idx; - pmhctl->llist_info.transmitting_end_idx = last_llist_idx; - - /* turn on clock(s), if they have been disabled */ - mddi_host_enable_hclk(); - mddi_host_enable_io_clock(); - pmhctl->int_type.llist_ptr_write_1++; - /* Write to primary pointer register */ - dma_coherent_pre_ops(); - mddi_host_reg_out(PRI_PTR, &llist_dma[first_llist_idx]); - - /* enable interrupt when complete */ - mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE, - MDDI_INT_PRI_LINK_LIST_DONE); - - } else if (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) { -#ifndef FEATURE_MDDI_DISABLE_REVERSE - if (first_llist_idx == pmhctl->llist_info.reg_read_idx) { - /* - * we have a register read to send but need to wait - * for current reverse activity to end or there are - * packets currently transmitting - */ - /* mddi_rev_reg_read_attempt = 0; */ - pmhctl->llist_info.reg_read_waiting = TRUE; - } -#endif - - /* assign waiting index values */ - pmhctl->llist_info.waiting_start_idx = first_llist_idx; - pmhctl->llist_info.waiting_end_idx = last_llist_idx; - } else { - uint16 prev_end_idx = pmhctl->llist_info.waiting_end_idx; -#ifndef FEATURE_MDDI_DISABLE_REVERSE - if (first_llist_idx == pmhctl->llist_info.reg_read_idx) { - /* - * we have a register read to send but need to wait - * for current reverse activity to end or there are - * packets currently transmitting - */ - /* mddi_rev_reg_read_attempt = 0; */ - pmhctl->llist_info.reg_read_waiting = TRUE; - } -#endif - - llist = pmhctl->llist_ptr; - - /* clear end flag in previous last packet */ - llist[prev_end_idx].link_controller_flags = 0; - pmhctl->llist_notify[prev_end_idx].next_idx = first_llist_idx; - - /* set the next_packet_pointer of the previous last packet */ - llist[prev_end_idx].next_packet_pointer = - (void *)(&llist_dma[first_llist_idx]); - - /* clean cache so MDDI host can read data */ - memory_barrier(); - - /* assign new waiting last index value */ - pmhctl->llist_info.waiting_end_idx = last_llist_idx; - } - - spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - -} - -void mddi_host_write_pix_attr_reg(uint32 value) -{ - (void)value; -} - -void mddi_queue_reverse_encapsulation(boolean wait) -{ -#ifdef FEATURE_MDDI_DISABLE_REVERSE - MDDI_MSG_CRIT("No reverse link available\n"); - (void)wait; -#else - unsigned long flags; - boolean error = FALSE; - mddi_host_type host_idx = MDDI_HOST_PRIM; - mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]); - - spin_lock_irqsave(&mddi_host_spin_lock, flags); - - /* turn on clock(s), if they have been disabled */ - mddi_host_enable_hclk(); - mddi_host_enable_io_clock(); - - if (wait) { - if (!mddi_rev_user.waiting) { - mddi_rev_user.waiting = TRUE; - INIT_COMPLETION(mddi_rev_user.done_comp); - } else - error = TRUE; - } - mddi_rev_encap_user_request = TRUE; - - if (pmhctl->rev_state == MDDI_REV_IDLE) { - /* attempt to send the reverse encapsulation now */ - mddi_host_type orig_host_idx = mddi_curr_host; - mddi_curr_host = host_idx; - mddi_issue_reverse_encapsulation(); - mddi_curr_host = orig_host_idx; - } - spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - - if (error) { - MDDI_MSG_ERR("Reverse Encap request already in progress\n"); - } else if (wait) - wait_for_completion_killable(&(mddi_rev_user.done_comp)); -#endif -} - -/* ISR to be executed */ -boolean mddi_set_rev_handler(mddi_rev_handler_type handler, uint16 pkt_type) -{ -#ifdef FEATURE_MDDI_DISABLE_REVERSE - MDDI_MSG_CRIT("No reverse link available\n"); - (void)handler; - (void)pkt_type; - return (FALSE); -#else - unsigned long flags; - uint16 hdlr; - boolean handler_set = FALSE; - boolean overwrite = FALSE; - mddi_host_type host_idx = MDDI_HOST_PRIM; - mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]); - - /* Disable interrupts */ - spin_lock_irqsave(&mddi_host_spin_lock, flags); - - for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS; hdlr++) { - if (mddi_rev_pkt_handler[hdlr].pkt_type == pkt_type) { - mddi_rev_pkt_handler[hdlr].handler = handler; - if (handler == NULL) { - /* clearing handler from table */ - mddi_rev_pkt_handler[hdlr].pkt_type = - INVALID_PKT_TYPE; - handler_set = TRUE; - if (pkt_type == 0x10) { /* video stream packet */ - /* ensure HCLK on to MDDI host core before register write */ - mddi_host_enable_hclk(); - /* No longer getting video, so reset rev encap size to default */ - pmhctl->rev_pkt_size = - MDDI_DEFAULT_REV_PKT_SIZE; - mddi_host_reg_out(REV_ENCAP_SZ, - pmhctl->rev_pkt_size); - } - } else { - /* already a handler for this packet */ - overwrite = TRUE; - } - break; - } - } - if ((hdlr >= MAX_MDDI_REV_HANDLERS) && (handler != NULL)) { - /* assigning new handler */ - for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS; hdlr++) { - if (mddi_rev_pkt_handler[hdlr].pkt_type == - INVALID_PKT_TYPE) { - if ((pkt_type == 0x10) && /* video stream packet */ - (pmhctl->rev_pkt_size < - MDDI_VIDEO_REV_PKT_SIZE)) { - /* ensure HCLK on to MDDI host core before register write */ - mddi_host_enable_hclk(); - /* Increase Rev Encap Size */ - pmhctl->rev_pkt_size = - MDDI_VIDEO_REV_PKT_SIZE; - mddi_host_reg_out(REV_ENCAP_SZ, - pmhctl->rev_pkt_size); - } - mddi_rev_pkt_handler[hdlr].handler = handler; - mddi_rev_pkt_handler[hdlr].pkt_type = pkt_type; - handler_set = TRUE; - break; - } - } - } - - /* Restore interrupts */ - spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - - if (overwrite) - MDDI_MSG_ERR("Overwriting previous rev packet handler\n"); - - return handler_set; - -#endif -} /* mddi_set_rev_handler */ - -void mddi_host_disable_hibernation(boolean disable) -{ - mddi_host_type host_idx = MDDI_HOST_PRIM; - mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]); - - if (disable) { - pmhctl->disable_hibernation = TRUE; - /* hibernation will be turned off by isr next time it is entered */ - } else { - if (pmhctl->disable_hibernation) { - unsigned long flags; - spin_lock_irqsave(&mddi_host_spin_lock, flags); - if (!MDDI_HOST_IS_HCLK_ON) - MDDI_HOST_ENABLE_HCLK; - mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1); - spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - pmhctl->disable_hibernation = FALSE; - } - } -} - -void mddi_mhctl_remove(mddi_host_type host_idx) -{ - mddi_host_cntl_type *pmhctl; - - pmhctl = &(mhctl[host_idx]); - - dma_free_coherent(NULL, MDDI_LLIST_POOL_SIZE, (void *)pmhctl->llist_ptr, - pmhctl->llist_dma_addr); - - dma_free_coherent(NULL, MDDI_MAX_REV_DATA_SIZE, - (void *)pmhctl->rev_data_buf, - pmhctl->rev_data_dma_addr); -} diff --git a/drivers/staging/msm/mddihosti.h b/drivers/staging/msm/mddihosti.h deleted file mode 100644 index 79eb39914ac1..000000000000 --- a/drivers/staging/msm/mddihosti.h +++ /dev/null @@ -1,531 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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. - */ - -#ifndef MDDIHOSTI_H -#define MDDIHOSTI_H - -#include "msm_fb.h" -#include "mddihost.h" -#include - -/* Register offsets in MDDI, applies to both msm_pmdh_base and - * (u32)msm_emdh_base. */ -#define MDDI_CMD 0x0000 -#define MDDI_VERSION 0x0004 -#define MDDI_PRI_PTR 0x0008 -#define MDDI_BPS 0x0010 -#define MDDI_SPM 0x0014 -#define MDDI_INT 0x0018 -#define MDDI_INTEN 0x001c -#define MDDI_REV_PTR 0x0020 -#define MDDI_REV_SIZE 0x0024 -#define MDDI_STAT 0x0028 -#define MDDI_REV_RATE_DIV 0x002c -#define MDDI_REV_CRC_ERR 0x0030 -#define MDDI_TA1_LEN 0x0034 -#define MDDI_TA2_LEN 0x0038 -#define MDDI_TEST 0x0040 -#define MDDI_REV_PKT_CNT 0x0044 -#define MDDI_DRIVE_HI 0x0048 -#define MDDI_DRIVE_LO 0x004c -#define MDDI_DISP_WAKE 0x0050 -#define MDDI_REV_ENCAP_SZ 0x0054 -#define MDDI_RTD_VAL 0x0058 -#define MDDI_PAD_CTL 0x0068 -#define MDDI_DRIVER_START_CNT 0x006c -#define MDDI_CORE_VER 0x008c -#define MDDI_FIFO_ALLOC 0x0090 -#define MDDI_PAD_IO_CTL 0x00a0 -#define MDDI_PAD_CAL 0x00a4 - -extern u32 mddi_msg_level; - -/* No longer need to write to clear these registers */ -#define xxxx_mddi_host_reg_outm(reg, mask, val) \ -do { \ - if (host_idx == MDDI_HOST_PRIM) \ - mddi_host_reg_outm_pmdh(reg, mask, val); \ - else \ - mddi_host_reg_outm_emdh(reg, mask, val); \ -} while (0) - -#define mddi_host_reg_outm(reg, mask, val) \ -do { \ - unsigned long __addr; \ - if (host_idx == MDDI_HOST_PRIM) \ - __addr = (u32)msm_pmdh_base + MDDI_##reg; \ - else \ - __addr = (u32)msm_emdh_base + MDDI_##reg; \ - writel((readl(__addr) & ~(mask)) | ((val) & (mask)), __addr); \ -} while (0) - -#define xxxx_mddi_host_reg_out(reg, val) \ -do { \ - if (host_idx == MDDI_HOST_PRIM) \ - mddi_host_reg_out_pmdh(reg, val); \ - else \ - mddi_host_reg_out_emdh(reg, val); \ - } while (0) - -#define mddi_host_reg_out(reg, val) \ -do { \ - if (host_idx == MDDI_HOST_PRIM) \ - writel(val, (u32)msm_pmdh_base + MDDI_##reg); \ - else \ - writel(val, (u32)msm_emdh_base + MDDI_##reg); \ -} while (0) - -#define xxxx_mddi_host_reg_in(reg) \ - ((host_idx) ? \ - mddi_host_reg_in_emdh(reg) : mddi_host_reg_in_pmdh(reg)); - -#define mddi_host_reg_in(reg) \ -((host_idx) ? \ - readl((u32)msm_emdh_base + MDDI_##reg) : \ - readl((u32)msm_pmdh_base + MDDI_##reg)) \ - -#define xxxx_mddi_host_reg_inm(reg, mask) \ - ((host_idx) ? \ - mddi_host_reg_inm_emdh(reg, mask) : \ - mddi_host_reg_inm_pmdh(reg, mask);) - -#define mddi_host_reg_inm(reg, mask) \ -((host_idx) ? \ - readl((u32)msm_emdh_base + MDDI_##reg) & (mask) : \ - readl((u32)msm_pmdh_base + MDDI_##reg) & (mask)) \ - -/* Using non-cacheable pmem, so do nothing */ -#define mddi_invalidate_cache_lines(addr_start, num_bytes) -/* - * Using non-cacheable pmem, so do nothing with cache - * but, ensure write goes out to memory - */ -#define mddi_flush_cache_lines(addr_start, num_bytes) \ - (void) addr_start; \ - (void) num_bytes; \ - memory_barrier() - -/* Since this translates to Remote Procedure Calls to check on clock status -* just use a local variable to keep track of io_clock */ -#define MDDI_HOST_IS_IO_CLOCK_ON mddi_host_io_clock_on -#define MDDI_HOST_ENABLE_IO_CLOCK -#define MDDI_HOST_DISABLE_IO_CLOCK -#define MDDI_HOST_IS_HCLK_ON mddi_host_hclk_on -#define MDDI_HOST_ENABLE_HCLK -#define MDDI_HOST_DISABLE_HCLK -#define FEATURE_MDDI_HOST_IO_CLOCK_CONTROL_DISABLE -#define FEATURE_MDDI_HOST_HCLK_CONTROL_DISABLE - -#define TRAMP_MDDI_HOST_ISR TRAMP_MDDI_PRI_ISR -#define TRAMP_MDDI_HOST_EXT_ISR TRAMP_MDDI_EXT_ISR -#define MDP_LINE_COUNT_BMSK 0x3ff -#define MDP_SYNC_STATUS 0x000c -#define MDP_LINE_COUNT \ -(readl(msm_mdp_base + MDP_SYNC_STATUS) & MDP_LINE_COUNT_BMSK) - -/* MDP sends 256 pixel packets, so lower value hibernates more without -* significantly increasing latency of waiting for next subframe */ -#define MDDI_HOST_BYTES_PER_SUBFRAME 0x3C00 - -#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40) -#define MDDI_HOST_TA2_LEN 0x001a -#define MDDI_HOST_REV_RATE_DIV 0x0004 -#else -#define MDDI_HOST_TA2_LEN 0x000c -#define MDDI_HOST_REV_RATE_DIV 0x0002 -#endif - -#define MDDI_MSG_EMERG(msg, ...) \ - if (mddi_msg_level > 0) \ - printk(KERN_EMERG msg, ## __VA_ARGS__); -#define MDDI_MSG_ALERT(msg, ...) \ - if (mddi_msg_level > 1) \ - printk(KERN_ALERT msg, ## __VA_ARGS__); -#define MDDI_MSG_CRIT(msg, ...) \ - if (mddi_msg_level > 2) \ - printk(KERN_CRIT msg, ## __VA_ARGS__); -#define MDDI_MSG_ERR(msg, ...) \ - if (mddi_msg_level > 3) \ - printk(KERN_ERR msg, ## __VA_ARGS__); -#define MDDI_MSG_WARNING(msg, ...) \ - if (mddi_msg_level > 4) \ - printk(KERN_WARNING msg, ## __VA_ARGS__); -#define MDDI_MSG_NOTICE(msg, ...) \ - if (mddi_msg_level > 5) \ - printk(KERN_NOTICE msg, ## __VA_ARGS__); -#define MDDI_MSG_INFO(msg, ...) \ - if (mddi_msg_level > 6) \ - printk(KERN_INFO msg, ## __VA_ARGS__); -#define MDDI_MSG_DEBUG(msg, ...) \ - if (mddi_msg_level > 7) \ - printk(KERN_DEBUG msg, ## __VA_ARGS__); - -#define GCC_PACKED __attribute__((packed)) -typedef struct GCC_PACKED { - uint16 packet_length; - /* total # of bytes in the packet not including - the packet_length field. */ - - uint16 packet_type; - /* A Packet Type of 70 identifies the packet as - a Client status Packet. */ - - uint16 bClient_ID; - /* This field is reserved for future use and shall - be set to zero. */ - -} mddi_rev_packet_type; - -typedef struct GCC_PACKED { - uint16 packet_length; - /* total # of bytes in the packet not including - the packet_length field. */ - - uint16 packet_type; - /* A Packet Type of 70 identifies the packet as - a Client status Packet. */ - - uint16 bClient_ID; - /* This field is reserved for future use and shall - be set to zero. */ - - uint16 reverse_link_request; - /* 16 bit unsigned integer with number of bytes client - needs in the * reverse encapsulation message - to transmit data. */ - - uint8 crc_error_count; - uint8 capability_change; - uint16 graphics_busy_flags; - - uint16 parameter_CRC; - /* 16-bit CRC of all the bytes in the packet - including Packet Length. */ - -} mddi_client_status_type; - -typedef struct GCC_PACKED { - uint16 packet_length; - /* total # of bytes in the packet not including - the packet_length field. */ - - uint16 packet_type; - /* A Packet Type of 66 identifies the packet as - a Client Capability Packet. */ - - uint16 bClient_ID; - /* This field is reserved for future use and - shall be set to zero. */ - - uint16 Protocol_Version; - uint16 Minimum_Protocol_Version; - uint16 Data_Rate_Capability; - uint8 Interface_Type_Capability; - uint8 Number_of_Alt_Displays; - uint16 PostCal_Data_Rate; - uint16 Bitmap_Width; - uint16 Bitmap_Height; - uint16 Display_Window_Width; - uint16 Display_Window_Height; - uint32 Color_Map_Size; - uint16 Color_Map_RGB_Width; - uint16 RGB_Capability; - uint8 Monochrome_Capability; - uint8 Reserved_1; - uint16 Y_Cb_Cr_Capability; - uint16 Bayer_Capability; - uint16 Alpha_Cursor_Image_Planes; - uint32 Client_Feature_Capability_Indicators; - uint8 Maximum_Video_Frame_Rate_Capability; - uint8 Minimum_Video_Frame_Rate_Capability; - uint16 Minimum_Sub_frame_Rate; - uint16 Audio_Buffer_Depth; - uint16 Audio_Channel_Capability; - uint16 Audio_Sample_Rate_Capability; - uint8 Audio_Sample_Resolution; - uint8 Mic_Audio_Sample_Resolution; - uint16 Mic_Sample_Rate_Capability; - uint8 Keyboard_Data_Format; - uint8 pointing_device_data_format; - uint16 content_protection_type; - uint16 Mfr_Name; - uint16 Product_Code; - uint16 Reserved_3; - uint32 Serial_Number; - uint8 Week_of_Manufacture; - uint8 Year_of_Manufacture; - - uint16 parameter_CRC; - /* 16-bit CRC of all the bytes in the packet including Packet Length. */ - -} mddi_client_capability_type; - -typedef struct GCC_PACKED { - uint16 packet_length; - /* total # of bytes in the packet not including the packet_length field. */ - - uint16 packet_type; - /* A Packet Type of 16 identifies the packet as a Video Stream Packet. */ - - uint16 bClient_ID; - /* This field is reserved for future use and shall be set to zero. */ - - uint16 video_data_format_descriptor; - /* format of each pixel in the Pixel Data in the present stream in the - * present packet. - * If bits [15:13] = 000 monochrome - * If bits [15:13] = 001 color pixels (palette). - * If bits [15:13] = 010 color pixels in raw RGB - * If bits [15:13] = 011 data in 4:2:2 Y Cb Cr format - * If bits [15:13] = 100 Bayer pixels - */ - - uint16 pixel_data_attributes; - /* interpreted as follows: - * Bits [1:0] = 11 pixel data is displayed to both eyes - * Bits [1:0] = 10 pixel data is routed to the left eye only. - * Bits [1:0] = 01 pixel data is routed to the right eye only. - * Bits [1:0] = 00 pixel data is routed to the alternate display. - * Bit 2 is 0 Pixel Data is in the standard progressive format. - * Bit 2 is 1 Pixel Data is in interlace format. - * Bit 3 is 0 Pixel Data is in the standard progressive format. - * Bit 3 is 1 Pixel Data is in alternate pixel format. - * Bit 4 is 0 Pixel Data is to or from the display frame buffer. - * Bit 4 is 1 Pixel Data is to or from the camera. - * Bit 5 is 0 pixel data contains the next consecutive row of pixels. - * Bit 5 is 1 X Left Edge, Y Top Edge, X Right Edge, Y Bottom Edge, - * X Start, and Y Start parameters are not defined and - * shall be ignored by the client. - * Bits [7:6] = 01 Pixel data is written to the offline image buffer. - * Bits [7:6] = 00 Pixel data is written to the buffer to refresh display. - * Bits [7:6] = 11 Pixel data is written to all image buffers. - * Bits [7:6] = 10 Invalid. Reserved for future use. - * Bits 8 through 11 alternate display number. - * Bits 12 through 14 are reserved for future use and shall be set to zero. - * Bit 15 is 1 the row of pixels is the last row of pixels in a frame. - */ - - uint16 x_left_edge; - uint16 y_top_edge; - /* X,Y coordinate of the top left edge of the screen window */ - - uint16 x_right_edge; - uint16 y_bottom_edge; - /* X,Y coordinate of the bottom right edge of the window being updated. */ - - uint16 x_start; - uint16 y_start; - /* (X Start, Y Start) is the first pixel in the Pixel Data field below. */ - - uint16 pixel_count; - /* number of pixels in the Pixel Data field below. */ - - uint16 parameter_CRC; - /* 16-bit CRC of all bytes from the Packet Length to the Pixel Count. */ - - uint16 reserved; - /* 16-bit variable to make structure align on 4 byte boundary */ - -} mddi_video_stream_packet_type; - -typedef struct GCC_PACKED { - uint16 packet_length; - /* total # of bytes in the packet not including the packet_length field. */ - - uint16 packet_type; - /* A Packet Type of 146 identifies the packet as a Register Access Packet. */ - - uint16 bClient_ID; - /* This field is reserved for future use and shall be set to zero. */ - - uint16 read_write_info; - /* Bits 13:0 a 14-bit unsigned integer that specifies the number of - * 32-bit Register Data List items to be transferred in the - * Register Data List field. - * Bits[15:14] = 00 Write to register(s); - * Bits[15:14] = 10 Read from register(s); - * Bits[15:14] = 11 Response to a Read. - * Bits[15:14] = 01 this value is reserved for future use. */ - - uint32 register_address; - /* the register address that is to be written to or read from. */ - - uint16 parameter_CRC; - /* 16-bit CRC of all bytes from the Packet Length to the Register Address. */ - - uint32 register_data_list; - /* list of 4-byte register data values for/from client registers */ - -} mddi_register_access_packet_type; - -typedef union GCC_PACKED { - mddi_video_stream_packet_type video_pkt; - mddi_register_access_packet_type register_pkt; - /* add 48 byte pad to ensure 64 byte llist struct, that can be - * manipulated easily with cache */ - uint32 alignment_pad[12]; /* 48 bytes */ -} mddi_packet_header_type; - -typedef struct GCC_PACKED mddi_host_llist_struct { - uint16 link_controller_flags; - uint16 packet_header_count; - uint16 packet_data_count; - void *packet_data_pointer; - struct mddi_host_llist_struct *next_packet_pointer; - uint16 reserved; - mddi_packet_header_type packet_header; -} mddi_linked_list_type; - -typedef struct { - struct completion done_comp; - mddi_llist_done_cb_type done_cb; - uint16 next_idx; - boolean waiting; - boolean in_use; -} mddi_linked_list_notify_type; - -#define MDDI_LLIST_POOL_SIZE 0x1000 -#define MDDI_MAX_NUM_LLIST_ITEMS (MDDI_LLIST_POOL_SIZE / \ - sizeof(mddi_linked_list_type)) -#define UNASSIGNED_INDEX MDDI_MAX_NUM_LLIST_ITEMS -#define MDDI_FIRST_DYNAMIC_LLIST_IDX 0 - -/* Static llist items can be used for applications that frequently send - * the same set of packets using the linked list interface. */ -/* Here we configure for 6 static linked list items: - * The 1st is used for a the adaptive backlight setting. - * and the remaining 5 are used for sending window adjustments for - * MDDI clients that need windowing info sent separate from video - * packets. */ -#define MDDI_NUM_STATIC_ABL_ITEMS 1 -#define MDDI_NUM_STATIC_WINDOW_ITEMS 5 -#define MDDI_NUM_STATIC_LLIST_ITEMS (MDDI_NUM_STATIC_ABL_ITEMS + \ - MDDI_NUM_STATIC_WINDOW_ITEMS) -#define MDDI_NUM_DYNAMIC_LLIST_ITEMS (MDDI_MAX_NUM_LLIST_ITEMS - \ - MDDI_NUM_STATIC_LLIST_ITEMS) - -#define MDDI_FIRST_STATIC_LLIST_IDX MDDI_NUM_DYNAMIC_LLIST_ITEMS -#define MDDI_FIRST_STATIC_ABL_IDX MDDI_FIRST_STATIC_LLIST_IDX -#define MDDI_FIRST_STATIC_WINDOW_IDX (MDDI_FIRST_STATIC_LLIST_IDX + \ - MDDI_NUM_STATIC_ABL_ITEMS) - -/* GPIO registers */ -#define VSYNC_WAKEUP_REG 0x80 -#define GPIO_REG 0x81 -#define GPIO_OUTPUT_REG 0x82 -#define GPIO_INTERRUPT_REG 0x83 -#define GPIO_INTERRUPT_ENABLE_REG 0x84 -#define GPIO_POLARITY_REG 0x85 - -/* Interrupt Bits */ -#define MDDI_INT_PRI_PTR_READ 0x0001 -#define MDDI_INT_SEC_PTR_READ 0x0002 -#define MDDI_INT_REV_DATA_AVAIL 0x0004 -#define MDDI_INT_DISP_REQ 0x0008 -#define MDDI_INT_PRI_UNDERFLOW 0x0010 -#define MDDI_INT_SEC_UNDERFLOW 0x0020 -#define MDDI_INT_REV_OVERFLOW 0x0040 -#define MDDI_INT_CRC_ERROR 0x0080 -#define MDDI_INT_MDDI_IN 0x0100 -#define MDDI_INT_PRI_OVERWRITE 0x0200 -#define MDDI_INT_SEC_OVERWRITE 0x0400 -#define MDDI_INT_REV_OVERWRITE 0x0800 -#define MDDI_INT_DMA_FAILURE 0x1000 -#define MDDI_INT_LINK_ACTIVE 0x2000 -#define MDDI_INT_IN_HIBERNATION 0x4000 -#define MDDI_INT_PRI_LINK_LIST_DONE 0x8000 -#define MDDI_INT_SEC_LINK_LIST_DONE 0x10000 -#define MDDI_INT_NO_CMD_PKTS_PEND 0x20000 -#define MDDI_INT_RTD_FAILURE 0x40000 - -#define MDDI_INT_ERROR_CONDITIONS ( \ - MDDI_INT_PRI_UNDERFLOW | MDDI_INT_SEC_UNDERFLOW | \ - MDDI_INT_REV_OVERFLOW | MDDI_INT_CRC_ERROR | \ - MDDI_INT_PRI_OVERWRITE | MDDI_INT_SEC_OVERWRITE | \ - MDDI_INT_RTD_FAILURE | \ - MDDI_INT_REV_OVERWRITE | MDDI_INT_DMA_FAILURE) - -#define MDDI_INT_LINK_STATE_CHANGES ( \ - MDDI_INT_LINK_ACTIVE | MDDI_INT_IN_HIBERNATION) - -/* Status Bits */ -#define MDDI_STAT_LINK_ACTIVE 0x0001 -#define MDDI_STAT_NEW_REV_PTR 0x0002 -#define MDDI_STAT_NEW_PRI_PTR 0x0004 -#define MDDI_STAT_NEW_SEC_PTR 0x0008 -#define MDDI_STAT_IN_HIBERNATION 0x0010 -#define MDDI_STAT_PRI_LINK_LIST_DONE 0x0020 -#define MDDI_STAT_SEC_LINK_LIST_DONE 0x0040 -#define MDDI_STAT_PENDING_TIMING_PKT 0x0080 -#define MDDI_STAT_PENDING_REV_ENCAP 0x0100 -#define MDDI_STAT_PENDING_POWERDOWN 0x0200 -#define MDDI_STAT_RTD_MEAS_FAIL 0x0800 -#define MDDI_STAT_CLIENT_WAKEUP_REQ 0x1000 - -/* Command Bits */ -#define MDDI_CMD_POWERDOWN 0x0100 -#define MDDI_CMD_POWERUP 0x0200 -#define MDDI_CMD_HIBERNATE 0x0300 -#define MDDI_CMD_RESET 0x0400 -#define MDDI_CMD_DISP_IGNORE 0x0501 -#define MDDI_CMD_DISP_LISTEN 0x0500 -#define MDDI_CMD_SEND_REV_ENCAP 0x0600 -#define MDDI_CMD_GET_CLIENT_CAP 0x0601 -#define MDDI_CMD_GET_CLIENT_STATUS 0x0602 -#define MDDI_CMD_SEND_RTD 0x0700 -#define MDDI_CMD_LINK_ACTIVE 0x0900 -#define MDDI_CMD_PERIODIC_REV_ENCAP 0x0A00 - -extern void mddi_host_init(mddi_host_type host); -extern void mddi_host_powerdown(mddi_host_type host); -extern uint16 mddi_get_next_free_llist_item(mddi_host_type host, boolean wait); -extern uint16 mddi_get_reg_read_llist_item(mddi_host_type host, boolean wait); -extern void mddi_queue_forward_packets(uint16 first_llist_idx, - uint16 last_llist_idx, - boolean wait, - mddi_llist_done_cb_type llist_done_cb, - mddi_host_type host); - -extern void mddi_host_write_pix_attr_reg(uint32 value); -extern void mddi_client_lcd_gpio_poll(uint32 poll_reg_val); -extern void mddi_client_lcd_vsync_detected(boolean detected); -extern void mddi_host_disable_hibernation(boolean disable); - -extern mddi_linked_list_type *llist_extern[]; -extern mddi_linked_list_type *llist_dma_extern[]; -extern mddi_linked_list_notify_type *llist_extern_notify[]; -extern struct timer_list mddi_host_timer; - -typedef struct { - uint16 transmitting_start_idx; - uint16 transmitting_end_idx; - uint16 waiting_start_idx; - uint16 waiting_end_idx; - uint16 reg_read_idx; - uint16 next_free_idx; - boolean reg_read_waiting; -} mddi_llist_info_type; - -extern mddi_llist_info_type mddi_llist; - -#define MDDI_GPIO_DEFAULT_POLLING_INTERVAL 200 -typedef struct { - uint32 polling_reg; - uint32 polling_val; - uint32 polling_interval; - boolean polling_enabled; -} mddi_gpio_info_type; - -uint32 mddi_get_client_id(void); -void mddi_mhctl_remove(mddi_host_type host_idx); -void mddi_host_timer_service(unsigned long data); -#endif /* MDDIHOSTI_H */ diff --git a/drivers/staging/msm/mdp.c b/drivers/staging/msm/mdp.c deleted file mode 100644 index 58cb40462930..000000000000 --- a/drivers/staging/msm/mdp.c +++ /dev/null @@ -1,1113 +0,0 @@ -/* Copyright (c) 2008-2010, 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "mdp.h" -#include "msm_fb.h" -#ifdef CONFIG_FB_MSM_MDP40 -#include "mdp4.h" -#endif - -static struct clk *mdp_clk; -static struct clk *mdp_pclk; - -struct completion mdp_ppp_comp; -struct semaphore mdp_ppp_mutex; -struct semaphore mdp_pipe_ctrl_mutex; - -unsigned long mdp_timer_duration = (HZ); /* 1 sec */ -/* unsigned long mdp_mdp_timer_duration=0; */ - -boolean mdp_ppp_waiting = FALSE; -uint32 mdp_tv_underflow_cnt; -uint32 mdp_lcdc_underflow_cnt; - -boolean mdp_current_clk_on = FALSE; -boolean mdp_is_in_isr = FALSE; - -/* - * legacy mdp_in_processing is only for DMA2-MDDI - * this applies to DMA2 block only - */ -uint32 mdp_in_processing = FALSE; - -#ifdef CONFIG_FB_MSM_MDP40 -uint32 mdp_intr_mask = MDP4_ANY_INTR_MASK; -#else -uint32 mdp_intr_mask = MDP_ANY_INTR_MASK; -#endif - -MDP_BLOCK_TYPE mdp_debug[MDP_MAX_BLOCK]; - -int32 mdp_block_power_cnt[MDP_MAX_BLOCK]; - -spinlock_t mdp_spin_lock; -struct workqueue_struct *mdp_dma_wq; /*mdp dma wq */ -struct workqueue_struct *mdp_vsync_wq; /*mdp vsync wq */ - -static struct workqueue_struct *mdp_pipe_ctrl_wq; /* mdp mdp pipe ctrl wq */ -static struct delayed_work mdp_pipe_ctrl_worker; - -#ifdef CONFIG_FB_MSM_MDP40 -struct mdp_dma_data dma2_data; -struct mdp_dma_data dma_s_data; -struct mdp_dma_data dma_e_data; -#else -static struct mdp_dma_data dma2_data; -static struct mdp_dma_data dma_s_data; -static struct mdp_dma_data dma_e_data; -#endif -static struct mdp_dma_data dma3_data; - -extern ktime_t mdp_dma2_last_update_time; - -extern uint32 mdp_dma2_update_time_in_usec; -extern int mdp_lcd_rd_cnt_offset_slow; -extern int mdp_lcd_rd_cnt_offset_fast; -extern int mdp_usec_diff_threshold; - -#ifdef CONFIG_FB_MSM_LCDC -extern int mdp_lcdc_pclk_clk_rate; -extern int mdp_lcdc_pad_pclk_clk_rate; -extern int first_pixel_start_x; -extern int first_pixel_start_y; -#endif - -#ifdef MSM_FB_ENABLE_DBGFS -struct dentry *mdp_dir; -#endif - -#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND) -static int mdp_suspend(struct platform_device *pdev, pm_message_t state); -#else -#define mdp_suspend NULL -#endif - -struct timeval mdp_dma2_timeval; -struct timeval mdp_ppp_timeval; - -#ifdef CONFIG_HAS_EARLYSUSPEND -static struct early_suspend early_suspend; -#endif - -#ifndef CONFIG_FB_MSM_MDP22 -DEFINE_MUTEX(mdp_lut_push_sem); -static int mdp_lut_i; -static int mdp_lut_hw_update(struct fb_cmap *cmap) -{ - int i; - u16 *c[3]; - u16 r, g, b; - - c[0] = cmap->green; - c[1] = cmap->blue; - c[2] = cmap->red; - - for (i = 0; i < cmap->len; i++) { - if (copy_from_user(&r, cmap->red++, sizeof(r)) || - copy_from_user(&g, cmap->green++, sizeof(g)) || - copy_from_user(&b, cmap->blue++, sizeof(b))) - return -EFAULT; - -#ifdef CONFIG_FB_MSM_MDP40 - MDP_OUTP(MDP_BASE + 0x94800 + -#else - MDP_OUTP(MDP_BASE + 0x93800 + -#endif - (0x400*mdp_lut_i) + cmap->start*4 + i*4, - ((g & 0xff) | - ((b & 0xff) << 8) | - ((r & 0xff) << 16))); - } - - return 0; -} - -static int mdp_lut_push; -static int mdp_lut_push_i; -static int mdp_lut_update_nonlcdc(struct fb_info *info, struct fb_cmap *cmap) -{ - int ret; - - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - ret = mdp_lut_hw_update(cmap); - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - - if (ret) - return ret; - - mutex_lock(&mdp_lut_push_sem); - mdp_lut_push = 1; - mdp_lut_push_i = mdp_lut_i; - mutex_unlock(&mdp_lut_push_sem); - - mdp_lut_i = (mdp_lut_i + 1)%2; - - return 0; -} - -static int mdp_lut_update_lcdc(struct fb_info *info, struct fb_cmap *cmap) -{ - int ret; - - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - ret = mdp_lut_hw_update(cmap); - - if (ret) { - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - return ret; - } - - MDP_OUTP(MDP_BASE + 0x90070, (mdp_lut_i << 10) | 0x17); - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - mdp_lut_i = (mdp_lut_i + 1)%2; - - return 0; -} - -#define MDP_HIST_MAX_BIN 32 -static __u32 mdp_hist_r[MDP_HIST_MAX_BIN]; -static __u32 mdp_hist_g[MDP_HIST_MAX_BIN]; -static __u32 mdp_hist_b[MDP_HIST_MAX_BIN]; - -#ifdef CONFIG_FB_MSM_MDP40 -struct mdp_histogram mdp_hist; -struct completion mdp_hist_comp; -#else -static struct mdp_histogram mdp_hist; -static struct completion mdp_hist_comp; -#endif - -static int mdp_do_histogram(struct fb_info *info, struct mdp_histogram *hist) -{ - int ret = 0; - - if (!hist->frame_cnt || (hist->bin_cnt == 0) || - (hist->bin_cnt > MDP_HIST_MAX_BIN)) - return -EINVAL; - - INIT_COMPLETION(mdp_hist_comp); - - mdp_hist.bin_cnt = hist->bin_cnt; - mdp_hist.r = (hist->r) ? mdp_hist_r : 0; - mdp_hist.g = (hist->g) ? mdp_hist_g : 0; - mdp_hist.b = (hist->b) ? mdp_hist_b : 0; - -#ifdef CONFIG_FB_MSM_MDP40 - MDP_OUTP(MDP_BASE + 0x95004, hist->frame_cnt); - MDP_OUTP(MDP_BASE + 0x95000, 1); -#else - MDP_OUTP(MDP_BASE + 0x94004, hist->frame_cnt); - MDP_OUTP(MDP_BASE + 0x94000, 1); -#endif - wait_for_completion_killable(&mdp_hist_comp); - - if (hist->r) { - ret = copy_to_user(hist->r, mdp_hist.r, hist->bin_cnt*4); - if (ret) - goto hist_err; - } - if (hist->g) { - ret = copy_to_user(hist->g, mdp_hist.g, hist->bin_cnt*4); - if (ret) - goto hist_err; - } - if (hist->b) { - ret = copy_to_user(hist->b, mdp_hist.b, hist->bin_cnt*4); - if (ret) - goto hist_err; - } - return 0; - -hist_err: - printk(KERN_ERR "%s: invalid hist buffer\n", __func__); - return ret; -} -#endif - -/* Returns < 0 on error, 0 on timeout, or > 0 on successful wait */ - -int mdp_ppp_pipe_wait(void) -{ - int ret = 1; - - /* wait 5 seconds for the operation to complete before declaring - the MDP hung */ - - if (mdp_ppp_waiting == TRUE) { - ret = wait_for_completion_interruptible_timeout(&mdp_ppp_comp, - 5 * HZ); - - if (!ret) - printk(KERN_ERR "%s: Timed out waiting for the MDP.\n", - __func__); - } - - return ret; -} - -static DEFINE_SPINLOCK(mdp_lock); -static int mdp_irq_mask; -static int mdp_irq_enabled; - -void mdp_enable_irq(uint32 term) -{ - unsigned long irq_flags; - - spin_lock_irqsave(&mdp_lock, irq_flags); - if (mdp_irq_mask & term) { - printk(KERN_ERR "MDP IRQ term-0x%x is already set\n", term); - } else { - mdp_irq_mask |= term; - if (mdp_irq_mask && !mdp_irq_enabled) { - mdp_irq_enabled = 1; - enable_irq(INT_MDP); - } - } - spin_unlock_irqrestore(&mdp_lock, irq_flags); -} - -void mdp_disable_irq(uint32 term) -{ - unsigned long irq_flags; - - spin_lock_irqsave(&mdp_lock, irq_flags); - if (!(mdp_irq_mask & term)) { - printk(KERN_ERR "MDP IRQ term-0x%x is not set\n", term); - } else { - mdp_irq_mask &= ~term; - if (!mdp_irq_mask && mdp_irq_enabled) { - mdp_irq_enabled = 0; - disable_irq(INT_MDP); - } - } - spin_unlock_irqrestore(&mdp_lock, irq_flags); -} - -void mdp_disable_irq_nolock(uint32 term) -{ - - if (!(mdp_irq_mask & term)) { - printk(KERN_ERR "MDP IRQ term-0x%x is not set\n", term); - } else { - mdp_irq_mask &= ~term; - if (!mdp_irq_mask && mdp_irq_enabled) { - mdp_irq_enabled = 0; - disable_irq(INT_MDP); - } - } -} - -void mdp_pipe_kickoff(uint32 term, struct msm_fb_data_type *mfd) -{ - - dmb(); /* memory barrier */ - - /* kick off PPP engine */ - if (term == MDP_PPP_TERM) { - if (mdp_debug[MDP_PPP_BLOCK]) - jiffies_to_timeval(jiffies, &mdp_ppp_timeval); - - /* let's turn on PPP block */ - mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - - mdp_enable_irq(term); - INIT_COMPLETION(mdp_ppp_comp); - mdp_ppp_waiting = TRUE; - outpdw(MDP_BASE + 0x30, 0x1000); - wait_for_completion_killable(&mdp_ppp_comp); - mdp_disable_irq(term); - - if (mdp_debug[MDP_PPP_BLOCK]) { - struct timeval now; - - jiffies_to_timeval(jiffies, &now); - mdp_ppp_timeval.tv_usec = - now.tv_usec - mdp_ppp_timeval.tv_usec; - MSM_FB_INFO("MDP-PPP: %d\n", - (int)mdp_ppp_timeval.tv_usec); - } - } else if (term == MDP_DMA2_TERM) { - if (mdp_debug[MDP_DMA2_BLOCK]) { - MSM_FB_INFO("MDP-DMA2: %d\n", - (int)mdp_dma2_timeval.tv_usec); - jiffies_to_timeval(jiffies, &mdp_dma2_timeval); - } - /* DMA update timestamp */ - mdp_dma2_last_update_time = ktime_get_real(); - /* let's turn on DMA2 block */ -#if 0 - mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE); -#endif -#ifdef CONFIG_FB_MSM_MDP22 - outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x0044, 0x0);/* start DMA */ -#else - if (mdp_lut_push) { - mutex_lock(&mdp_lut_push_sem); - mdp_lut_push = 0; - MDP_OUTP(MDP_BASE + 0x90070, - (mdp_lut_push_i << 10) | 0x17); - mutex_unlock(&mdp_lut_push_sem); - } -#ifdef CONFIG_FB_MSM_MDP40 - outpdw(MDP_BASE + 0x000c, 0x0); /* start DMA */ -#else - outpdw(MDP_BASE + 0x0044, 0x0); /* start DMA */ -#endif -#endif -#ifdef CONFIG_FB_MSM_MDP40 - } else if (term == MDP_DMA_S_TERM) { - mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - outpdw(MDP_BASE + 0x0010, 0x0); /* start DMA */ - } else if (term == MDP_DMA_E_TERM) { - mdp_pipe_ctrl(MDP_DMA_E_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - outpdw(MDP_BASE + 0x0014, 0x0); /* start DMA */ - } else if (term == MDP_OVERLAY0_TERM) { - mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - outpdw(MDP_BASE + 0x0004, 0); - } else if (term == MDP_OVERLAY1_TERM) { - mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - outpdw(MDP_BASE + 0x0008, 0); - } -#else - } else if (term == MDP_DMA_S_TERM) { - mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - outpdw(MDP_BASE + 0x0048, 0x0); /* start DMA */ - } -#endif -} - -static void mdp_pipe_ctrl_workqueue_handler(struct work_struct *work) -{ - mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); -} - -void mdp_pipe_ctrl(MDP_BLOCK_TYPE block, MDP_BLOCK_POWER_STATE state, - boolean isr) -{ - boolean mdp_all_blocks_off = TRUE; - int i; - unsigned long flag; - - spin_lock_irqsave(&mdp_spin_lock, flag); - if (MDP_BLOCK_POWER_ON == state) { - mdp_block_power_cnt[block]++; - - if (MDP_DMA2_BLOCK == block) - mdp_in_processing = TRUE; - } else { - mdp_block_power_cnt[block]--; - - if (mdp_block_power_cnt[block] < 0) { - /* - * Master has to serve a request to power off MDP always - * It also has a timer to power off. So, in case of - * timer expires first and DMA2 finishes later, - * master has to power off two times - * There shouldn't be multiple power-off request for - * other blocks - */ - if (block != MDP_MASTER_BLOCK) { - MSM_FB_INFO("mdp_block_power_cnt[block=%d] \ - multiple power-off request\n", block); - } - mdp_block_power_cnt[block] = 0; - } - - if (MDP_DMA2_BLOCK == block) - mdp_in_processing = FALSE; - } - spin_unlock_irqrestore(&mdp_spin_lock, flag); - - /* - * If it's in isr, we send our request to workqueue. - * Otherwise, processing happens in the current context - */ - if (isr) { - /* checking all blocks power state */ - for (i = 0; i < MDP_MAX_BLOCK; i++) { - if (mdp_block_power_cnt[i] > 0) - mdp_all_blocks_off = FALSE; - } - - if ((mdp_all_blocks_off) && (mdp_current_clk_on)) { - /* send workqueue to turn off mdp power */ - queue_delayed_work(mdp_pipe_ctrl_wq, - &mdp_pipe_ctrl_worker, - mdp_timer_duration); - } - } else { - down(&mdp_pipe_ctrl_mutex); - /* checking all blocks power state */ - for (i = 0; i < MDP_MAX_BLOCK; i++) { - if (mdp_block_power_cnt[i] > 0) - mdp_all_blocks_off = FALSE; - } - - /* - * find out whether a delayable work item is currently - * pending - */ - - if (delayed_work_pending(&mdp_pipe_ctrl_worker)) { - /* - * try to cancel the current work if it fails to - * stop (which means del_timer can't delete it - * from the list, it's about to expire and run), - * we have to let it run. queue_delayed_work won't - * accept the next job which is same as - * queue_delayed_work(mdp_timer_duration = 0) - */ - cancel_delayed_work(&mdp_pipe_ctrl_worker); - } - - if ((mdp_all_blocks_off) && (mdp_current_clk_on)) { - if (block == MDP_MASTER_BLOCK) { - mdp_current_clk_on = FALSE; - /* turn off MDP clks */ - if (mdp_clk != NULL) { - clk_disable(mdp_clk); - MSM_FB_DEBUG("MDP CLK OFF\n"); - } - if (mdp_pclk != NULL) { - clk_disable(mdp_pclk); - MSM_FB_DEBUG("MDP PCLK OFF\n"); - } - } else { - /* send workqueue to turn off mdp power */ - queue_delayed_work(mdp_pipe_ctrl_wq, - &mdp_pipe_ctrl_worker, - mdp_timer_duration); - } - } else if ((!mdp_all_blocks_off) && (!mdp_current_clk_on)) { - mdp_current_clk_on = TRUE; - /* turn on MDP clks */ - if (mdp_clk != NULL) { - clk_enable(mdp_clk); - MSM_FB_DEBUG("MDP CLK ON\n"); - } - if (mdp_pclk != NULL) { - clk_enable(mdp_pclk); - MSM_FB_DEBUG("MDP PCLK ON\n"); - } - } - up(&mdp_pipe_ctrl_mutex); - } -} - -#ifndef CONFIG_FB_MSM_MDP40 -irqreturn_t mdp_isr(int irq, void *ptr) -{ - uint32 mdp_interrupt = 0; - struct mdp_dma_data *dma; - - mdp_is_in_isr = TRUE; - do { - mdp_interrupt = inp32(MDP_INTR_STATUS); - outp32(MDP_INTR_CLEAR, mdp_interrupt); - - mdp_interrupt &= mdp_intr_mask; - - if (mdp_interrupt & TV_ENC_UNDERRUN) { - mdp_interrupt &= ~(TV_ENC_UNDERRUN); - mdp_tv_underflow_cnt++; - } - - if (!mdp_interrupt) - break; - - /* DMA3 TV-Out Start */ - if (mdp_interrupt & TV_OUT_DMA3_START) { - /* let's disable TV out interrupt */ - mdp_intr_mask &= ~TV_OUT_DMA3_START; - outp32(MDP_INTR_ENABLE, mdp_intr_mask); - - dma = &dma3_data; - if (dma->waiting) { - dma->waiting = FALSE; - complete(&dma->comp); - } - } -#ifndef CONFIG_FB_MSM_MDP22 - if (mdp_interrupt & MDP_HIST_DONE) { - outp32(MDP_BASE + 0x94018, 0x3); - outp32(MDP_INTR_CLEAR, MDP_HIST_DONE); - if (mdp_hist.r) - memcpy(mdp_hist.r, MDP_BASE + 0x94100, - mdp_hist.bin_cnt*4); - if (mdp_hist.g) - memcpy(mdp_hist.g, MDP_BASE + 0x94200, - mdp_hist.bin_cnt*4); - if (mdp_hist.b) - memcpy(mdp_hist.b, MDP_BASE + 0x94300, - mdp_hist.bin_cnt*4); - complete(&mdp_hist_comp); - } - - /* LCDC UnderFlow */ - if (mdp_interrupt & LCDC_UNDERFLOW) { - mdp_lcdc_underflow_cnt++; - } - /* LCDC Frame Start */ - if (mdp_interrupt & LCDC_FRAME_START) { - /* let's disable LCDC interrupt */ - mdp_intr_mask &= ~LCDC_FRAME_START; - outp32(MDP_INTR_ENABLE, mdp_intr_mask); - - dma = &dma2_data; - if (dma->waiting) { - dma->waiting = FALSE; - complete(&dma->comp); - } - } - - /* DMA2 LCD-Out Complete */ - if (mdp_interrupt & MDP_DMA_S_DONE) { - dma = &dma_s_data; - dma->busy = FALSE; - mdp_pipe_ctrl(MDP_DMA_S_BLOCK, MDP_BLOCK_POWER_OFF, - TRUE); - complete(&dma->comp); - } -#endif - - /* DMA2 LCD-Out Complete */ - if (mdp_interrupt & MDP_DMA_P_DONE) { - struct timeval now; - ktime_t now_k; - - now_k = ktime_get_real(); - mdp_dma2_last_update_time.tv.sec = - now_k.tv.sec - mdp_dma2_last_update_time.tv.sec; - mdp_dma2_last_update_time.tv.nsec = - now_k.tv.nsec - mdp_dma2_last_update_time.tv.nsec; - - if (mdp_debug[MDP_DMA2_BLOCK]) { - jiffies_to_timeval(jiffies, &now); - mdp_dma2_timeval.tv_usec = - now.tv_usec - mdp_dma2_timeval.tv_usec; - } - - dma = &dma2_data; - dma->busy = FALSE; - mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF, - TRUE); - complete(&dma->comp); - } - /* PPP Complete */ - if (mdp_interrupt & MDP_PPP_DONE) { -#ifdef CONFIG_MDP_PPP_ASYNC_OP - mdp_ppp_djob_done(); -#else - mdp_pipe_ctrl(MDP_PPP_BLOCK, - MDP_BLOCK_POWER_OFF, TRUE); - if (mdp_ppp_waiting) { - mdp_ppp_waiting = FALSE; - complete(&mdp_ppp_comp); - } -#endif - } - } while (1); - - mdp_is_in_isr = FALSE; - - return IRQ_HANDLED; -} -#endif - -static void mdp_drv_init(void) -{ - int i; - - for (i = 0; i < MDP_MAX_BLOCK; i++) { - mdp_debug[i] = 0; - } - - /* initialize spin lock and workqueue */ - spin_lock_init(&mdp_spin_lock); - mdp_dma_wq = create_singlethread_workqueue("mdp_dma_wq"); - mdp_vsync_wq = create_singlethread_workqueue("mdp_vsync_wq"); - mdp_pipe_ctrl_wq = create_singlethread_workqueue("mdp_pipe_ctrl_wq"); - INIT_DELAYED_WORK(&mdp_pipe_ctrl_worker, - mdp_pipe_ctrl_workqueue_handler); -#ifdef CONFIG_MDP_PPP_ASYNC_OP - mdp_ppp_dq_init(); -#endif - - /* initialize semaphore */ - init_completion(&mdp_ppp_comp); - sema_init(&mdp_ppp_mutex, 1); - sema_init(&mdp_pipe_ctrl_mutex, 1); - - dma2_data.busy = FALSE; - dma2_data.waiting = FALSE; - init_completion(&dma2_data.comp); - sema_init(&dma2_data.mutex, 1); - mutex_init(&dma2_data.ov_mutex); - - dma3_data.busy = FALSE; - dma3_data.waiting = FALSE; - init_completion(&dma3_data.comp); - sema_init(&dma3_data.mutex, 1); - - dma_s_data.busy = FALSE; - dma_s_data.waiting = FALSE; - init_completion(&dma_s_data.comp); - sema_init(&dma_s_data.mutex, 1); - - dma_e_data.busy = FALSE; - dma_e_data.waiting = FALSE; - init_completion(&dma_e_data.comp); - -#ifndef CONFIG_FB_MSM_MDP22 - init_completion(&mdp_hist_comp); -#endif - - /* initializing mdp power block counter to 0 */ - for (i = 0; i < MDP_MAX_BLOCK; i++) { - mdp_block_power_cnt[i] = 0; - } - -#ifdef MSM_FB_ENABLE_DBGFS - { - struct dentry *root; - char sub_name[] = "mdp"; - - root = msm_fb_get_debugfs_root(); - if (root != NULL) { - mdp_dir = debugfs_create_dir(sub_name, root); - - if (mdp_dir) { - msm_fb_debugfs_file_create(mdp_dir, - "dma2_update_time_in_usec", - (u32 *) &mdp_dma2_update_time_in_usec); - msm_fb_debugfs_file_create(mdp_dir, - "vs_rdcnt_slow", - (u32 *) &mdp_lcd_rd_cnt_offset_slow); - msm_fb_debugfs_file_create(mdp_dir, - "vs_rdcnt_fast", - (u32 *) &mdp_lcd_rd_cnt_offset_fast); - msm_fb_debugfs_file_create(mdp_dir, - "mdp_usec_diff_threshold", - (u32 *) &mdp_usec_diff_threshold); - msm_fb_debugfs_file_create(mdp_dir, - "mdp_current_clk_on", - (u32 *) &mdp_current_clk_on); -#ifdef CONFIG_FB_MSM_LCDC - msm_fb_debugfs_file_create(mdp_dir, - "lcdc_start_x", - (u32 *) &first_pixel_start_x); - msm_fb_debugfs_file_create(mdp_dir, - "lcdc_start_y", - (u32 *) &first_pixel_start_y); - msm_fb_debugfs_file_create(mdp_dir, - "mdp_lcdc_pclk_clk_rate", - (u32 *) &mdp_lcdc_pclk_clk_rate); - msm_fb_debugfs_file_create(mdp_dir, - "mdp_lcdc_pad_pclk_clk_rate", - (u32 *) &mdp_lcdc_pad_pclk_clk_rate); -#endif - } - } - } -#endif -} - -static int mdp_probe(struct platform_device *pdev); -static int mdp_remove(struct platform_device *pdev); - -static struct platform_driver mdp_driver = { - .probe = mdp_probe, - .remove = mdp_remove, -#ifndef CONFIG_HAS_EARLYSUSPEND - .suspend = mdp_suspend, - .resume = NULL, -#endif - .shutdown = NULL, - .driver = { - /* - * Driver name must match the device name added in - * platform.c. - */ - .name = "mdp", - }, -}; - -static int mdp_off(struct platform_device *pdev) -{ - int ret = 0; - -#ifdef MDP_HW_VSYNC - struct msm_fb_data_type *mfd = platform_get_drvdata(pdev); -#endif - - ret = panel_next_off(pdev); - -#ifdef MDP_HW_VSYNC - mdp_hw_vsync_clk_disable(mfd); -#endif - - return ret; -} - -static int mdp_on(struct platform_device *pdev) -{ -#ifdef MDP_HW_VSYNC - struct msm_fb_data_type *mfd = platform_get_drvdata(pdev); -#endif - - int ret = 0; - -#ifdef MDP_HW_VSYNC - mdp_hw_vsync_clk_enable(mfd); -#endif - - ret = panel_next_on(pdev); - - return ret; -} - -static int mdp_irq_clk_setup(void) -{ - int ret; - -#ifdef CONFIG_FB_MSM_MDP40 - ret = request_irq(INT_MDP, mdp4_isr, IRQF_DISABLED, "MDP", 0); -#else - ret = request_irq(INT_MDP, mdp_isr, IRQF_DISABLED, "MDP", 0); -#endif - if (ret) { - printk(KERN_ERR "mdp request_irq() failed!\n"); - return ret; - } - disable_irq(INT_MDP); - - mdp_clk = clk_get(NULL, "mdp_clk"); - - if (IS_ERR(mdp_clk)) { - ret = PTR_ERR(mdp_clk); - printk(KERN_ERR "can't get mdp_clk error:%d!\n", ret); - free_irq(INT_MDP, 0); - return ret; - } - - mdp_pclk = clk_get(NULL, "mdp_pclk"); - if (IS_ERR(mdp_pclk)) - mdp_pclk = NULL; - - -#ifdef CONFIG_FB_MSM_MDP40 - /* - * mdp_clk should greater than mdp_pclk always - */ - clk_set_rate(mdp_clk, 122880000); /* 122.88 Mhz */ - printk(KERN_INFO "mdp_clk: mdp_clk=%d mdp_pclk=%d\n", - (int)clk_get_rate(mdp_clk), (int)clk_get_rate(mdp_pclk)); -#endif - - return 0; -} - -static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST]; -static int pdev_list_cnt; -static int mdp_resource_initialized; -static struct msm_panel_common_pdata *mdp_pdata; - -static int mdp_probe(struct platform_device *pdev) -{ - struct platform_device *msm_fb_dev = NULL; - struct msm_fb_data_type *mfd; - struct msm_fb_panel_data *pdata = NULL; - int rc; - resource_size_t size ; -#ifdef CONFIG_FB_MSM_MDP40 - int intf, if_no; -#else - unsigned long flag; -#endif - - if ((pdev->id == 0) && (pdev->num_resources > 0)) { - mdp_pdata = pdev->dev.platform_data; - - size = resource_size(&pdev->resource[0]); - msm_mdp_base = ioremap(pdev->resource[0].start, size); - - MSM_FB_INFO("MDP HW Base phy_Address = 0x%x virt = 0x%x\n", - (int)pdev->resource[0].start, (int)msm_mdp_base); - - if (unlikely(!msm_mdp_base)) - return -ENOMEM; - - printk("irq clk setup\n"); - rc = mdp_irq_clk_setup(); - printk("irq clk setup done\n"); - if (rc) - return rc; - - /* initializing mdp hw */ -#ifdef CONFIG_FB_MSM_MDP40 - mdp4_hw_init(); -#else - mdp_hw_init(); -#endif - - mdp_resource_initialized = 1; - return 0; - } - - if (!mdp_resource_initialized) - return -EPERM; - - mfd = platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST) - return -ENOMEM; - - msm_fb_dev = platform_device_alloc("msm_fb", pdev->id); - if (!msm_fb_dev) - return -ENOMEM; - - /* link to the latest pdev */ - mfd->pdev = msm_fb_dev; - - /* add panel data */ - if (platform_device_add_data - (msm_fb_dev, pdev->dev.platform_data, - sizeof(struct msm_fb_panel_data))) { - printk(KERN_ERR "mdp_probe: platform_device_add_data failed!\n"); - rc = -ENOMEM; - goto mdp_probe_err; - } - /* data chain */ - pdata = msm_fb_dev->dev.platform_data; - pdata->on = mdp_on; - pdata->off = mdp_off; - pdata->next = pdev; - - switch (mfd->panel.type) { - case EXT_MDDI_PANEL: - case MDDI_PANEL: - case EBI2_PANEL: - INIT_WORK(&mfd->dma_update_worker, - mdp_lcd_update_workqueue_handler); - INIT_WORK(&mfd->vsync_resync_worker, - mdp_vsync_resync_workqueue_handler); - mfd->hw_refresh = FALSE; - - if (mfd->panel.type == EXT_MDDI_PANEL) { - /* 15 fps -> 66 msec */ - mfd->refresh_timer_duration = (66 * HZ / 1000); - } else { - /* 24 fps -> 42 msec */ - mfd->refresh_timer_duration = (42 * HZ / 1000); - } - -#ifdef CONFIG_FB_MSM_MDP22 - mfd->dma_fnc = mdp_dma2_update; - mfd->dma = &dma2_data; -#else - if (mfd->panel_info.pdest == DISPLAY_1) { -#ifdef CONFIG_FB_MSM_OVERLAY - mfd->dma_fnc = mdp4_mddi_overlay; -#else - mfd->dma_fnc = mdp_dma2_update; -#endif - mfd->dma = &dma2_data; - mfd->lut_update = mdp_lut_update_nonlcdc; - mfd->do_histogram = mdp_do_histogram; - } else { - mfd->dma_fnc = mdp_dma_s_update; - mfd->dma = &dma_s_data; - } -#endif - if (mdp_pdata) - mfd->vsync_gpio = mdp_pdata->gpio; - else - mfd->vsync_gpio = -1; - -#ifdef CONFIG_FB_MSM_MDP40 - if (mfd->panel.type == EBI2_PANEL) - intf = EBI2_INTF; - else - intf = MDDI_INTF; - - if (mfd->panel_info.pdest == DISPLAY_1) - if_no = PRIMARY_INTF_SEL; - else - if_no = SECONDARY_INTF_SEL; - - mdp4_display_intf_sel(if_no, intf); -#endif - mdp_config_vsync(mfd); - break; - - case HDMI_PANEL: - case LCDC_PANEL: - pdata->on = mdp_lcdc_on; - pdata->off = mdp_lcdc_off; - mfd->hw_refresh = TRUE; - mfd->cursor_update = mdp_hw_cursor_update; -#ifndef CONFIG_FB_MSM_MDP22 - mfd->lut_update = mdp_lut_update_lcdc; - mfd->do_histogram = mdp_do_histogram; -#endif -#ifdef CONFIG_FB_MSM_OVERLAY - mfd->dma_fnc = mdp4_lcdc_overlay; -#else - mfd->dma_fnc = mdp_lcdc_update; -#endif - -#ifdef CONFIG_FB_MSM_MDP40 - if (mfd->panel.type == HDMI_PANEL) { - mfd->dma = &dma_e_data; - mdp4_display_intf_sel(EXTERNAL_INTF_SEL, LCDC_RGB_INTF); - } else { - mfd->dma = &dma2_data; - mdp4_display_intf_sel(PRIMARY_INTF_SEL, LCDC_RGB_INTF); - } -#else - mfd->dma = &dma2_data; - spin_lock_irqsave(&mdp_spin_lock, flag); - mdp_intr_mask &= ~MDP_DMA_P_DONE; - outp32(MDP_INTR_ENABLE, mdp_intr_mask); - spin_unlock_irqrestore(&mdp_spin_lock, flag); -#endif - break; - - case TV_PANEL: - pdata->on = mdp_dma3_on; - pdata->off = mdp_dma3_off; - mfd->hw_refresh = TRUE; - mfd->dma_fnc = mdp_dma3_update; - mfd->dma = &dma3_data; - break; - - default: - printk(KERN_ERR "mdp_probe: unknown device type!\n"); - rc = -ENODEV; - goto mdp_probe_err; - } - - /* set driver data */ - platform_set_drvdata(msm_fb_dev, mfd); - - rc = platform_device_add(msm_fb_dev); - if (rc) { - goto mdp_probe_err; - } - - pdev_list[pdev_list_cnt++] = pdev; - return 0; - - mdp_probe_err: - platform_device_put(msm_fb_dev); - return rc; -} - -static void mdp_suspend_sub(void) -{ - /* cancel pipe ctrl worker */ - cancel_delayed_work(&mdp_pipe_ctrl_worker); - - /* for workder can't be cancelled... */ - flush_workqueue(mdp_pipe_ctrl_wq); - - /* let's wait for PPP completion */ - while (mdp_block_power_cnt[MDP_PPP_BLOCK] > 0) ; - - /* try to power down */ - mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); -} - -#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND) -static int mdp_suspend(struct platform_device *pdev, pm_message_t state) -{ - mdp_suspend_sub(); - return 0; -} -#endif - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void mdp_early_suspend(struct early_suspend *h) -{ - mdp_suspend_sub(); -} -#endif - -static int mdp_remove(struct platform_device *pdev) -{ - iounmap(msm_mdp_base); - return 0; -} - -static int mdp_register_driver(void) -{ -#ifdef CONFIG_HAS_EARLYSUSPEND - early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1; - early_suspend.suspend = mdp_early_suspend; - register_early_suspend(&early_suspend); -#endif - - return platform_driver_register(&mdp_driver); -} - -static int __init mdp_driver_init(void) -{ - int ret; - - mdp_drv_init(); - - ret = mdp_register_driver(); - if (ret) { - printk(KERN_ERR "mdp_register_driver() failed!\n"); - return ret; - } - -#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_FB_MSM_MDP40) - mdp4_debugfs_init(); -#endif - - return 0; - -} - -module_init(mdp_driver_init); diff --git a/drivers/staging/msm/mdp.h b/drivers/staging/msm/mdp.h deleted file mode 100644 index 44b114700dac..000000000000 --- a/drivers/staging/msm/mdp.h +++ /dev/null @@ -1,679 +0,0 @@ -/* Copyright (c) 2008-2010, 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 and - * only 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. - */ - -#ifndef MDP_H -#define MDP_H - -#include -#include -#include -#include -#include -#include -#include -#include "msm_mdp.h" - -#include -#include - -#include -#include - -#include "msm_fb_panel.h" - -#ifdef CONFIG_MDP_PPP_ASYNC_OP -#include "mdp_ppp_dq.h" -#endif - -#ifdef BIT -#undef BIT -#endif - -#define BIT(x) (1<<(x)) - -#define MDPOP_NOP 0 -#define MDPOP_LR BIT(0) /* left to right flip */ -#define MDPOP_UD BIT(1) /* up and down flip */ -#define MDPOP_ROT90 BIT(2) /* rotate image to 90 degree */ -#define MDPOP_ROT180 (MDPOP_UD|MDPOP_LR) -#define MDPOP_ROT270 (MDPOP_ROT90|MDPOP_UD|MDPOP_LR) -#define MDPOP_ASCALE BIT(7) -#define MDPOP_ALPHAB BIT(8) /* enable alpha blending */ -#define MDPOP_TRANSP BIT(9) /* enable transparency */ -#define MDPOP_DITHER BIT(10) /* enable dither */ -#define MDPOP_SHARPENING BIT(11) /* enable sharpening */ -#define MDPOP_BLUR BIT(12) /* enable blur */ -#define MDPOP_FG_PM_ALPHA BIT(13) - -struct mdp_table_entry { - uint32_t reg; - uint32_t val; -}; - -extern struct mdp_ccs mdp_ccs_yuv2rgb ; -extern struct mdp_ccs mdp_ccs_rgb2yuv ; - -/* - * MDP Image Structure - */ -typedef struct mdpImg_ { - uint32 imgType; /* Image type */ - uint32 *bmy_addr; /* bitmap or y addr */ - uint32 *cbcr_addr; /* cbcr addr */ - uint32 width; /* image width */ - uint32 mdpOp; /* image opertion (rotation,flip up/down, alpha/tp) */ - uint32 tpVal; /* transparency color */ - uint32 alpha; /* alpha percentage 0%(0x0) ~ 100%(0x100) */ - int sp_value; /* sharpening strength */ -} MDPIMG; - -#ifdef CONFIG_MDP_PPP_ASYNC_OP -#define MDP_OUTP(addr, data) mdp_ppp_outdw((uint32_t)(addr), \ - (uint32_t)(data)) -#else -#define MDP_OUTP(addr, data) outpdw((addr), (data)) -#endif - -#define MDP_KTIME2USEC(kt) (kt.tv.sec*1000000 + kt.tv.nsec/1000) - -#define MDP_BASE msm_mdp_base - -typedef enum { - MDP_BC_SCALE_POINT2_POINT4, - MDP_BC_SCALE_POINT4_POINT6, - MDP_BC_SCALE_POINT6_POINT8, - MDP_BC_SCALE_POINT8_1, - MDP_BC_SCALE_UP, - MDP_PR_SCALE_POINT2_POINT4, - MDP_PR_SCALE_POINT4_POINT6, - MDP_PR_SCALE_POINT6_POINT8, - MDP_PR_SCALE_POINT8_1, - MDP_PR_SCALE_UP, - MDP_SCALE_BLUR, - MDP_INIT_SCALE -} MDP_SCALE_MODE; - -typedef enum { - MDP_BLOCK_POWER_OFF, - MDP_BLOCK_POWER_ON -} MDP_BLOCK_POWER_STATE; - -typedef enum { - MDP_MASTER_BLOCK, - MDP_CMD_BLOCK, - MDP_PPP_BLOCK, - MDP_DMA2_BLOCK, - MDP_DMA3_BLOCK, - MDP_DMA_S_BLOCK, - MDP_DMA_E_BLOCK, - MDP_OVERLAY0_BLOCK, - MDP_OVERLAY1_BLOCK, - MDP_MAX_BLOCK -} MDP_BLOCK_TYPE; - -/* Let's keep Q Factor power of 2 for optimization */ -#define MDP_SCALE_Q_FACTOR 512 - -#ifdef CONFIG_FB_MSM_MDP31 -#define MDP_MAX_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*8) -#define MDP_MIN_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/8) -#define MDP_MAX_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*8) -#define MDP_MIN_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/8) -#else -#define MDP_MAX_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*4) -#define MDP_MIN_X_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/4) -#define MDP_MAX_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR*4) -#define MDP_MIN_Y_SCALE_FACTOR (MDP_SCALE_Q_FACTOR/4) -#endif - -/* SHIM Q Factor */ -#define PHI_Q_FACTOR 29 -#define PQF_PLUS_5 (PHI_Q_FACTOR + 5) /* due to 32 phases */ -#define PQF_PLUS_4 (PHI_Q_FACTOR + 4) -#define PQF_PLUS_2 (PHI_Q_FACTOR + 2) /* to get 4.0 */ -#define PQF_MINUS_2 (PHI_Q_FACTOR - 2) /* to get 0.25 */ -#define PQF_PLUS_5_PLUS_2 (PQF_PLUS_5 + 2) -#define PQF_PLUS_5_MINUS_2 (PQF_PLUS_5 - 2) - -#define MDP_CONVTP(tpVal) (((tpVal&0xF800)<<8)|((tpVal&0x7E0)<<5)|((tpVal&0x1F)<<3)) - -#define MDPOP_ROTATION (MDPOP_ROT90|MDPOP_LR|MDPOP_UD) -#define MDP_CHKBIT(val, bit) ((bit) == ((val) & (bit))) - -/* overlay interface API defines */ -typedef enum { - MORE_IBUF, - FINAL_IBUF, - COMPLETE_IBUF -} MDP_IBUF_STATE; - -struct mdp_dirty_region { - __u32 xoffset; /* source origin in the x-axis */ - __u32 yoffset; /* source origin in the y-axis */ - __u32 width; /* number of pixels in the x-axis */ - __u32 height; /* number of pixels in the y-axis */ -}; - -/* - * MDP extended data types - */ -typedef struct mdp_roi_s { - uint32 x; - uint32 y; - uint32 width; - uint32 height; - int32 lcd_x; - int32 lcd_y; - uint32 dst_width; - uint32 dst_height; -} MDP_ROI; - -typedef struct mdp_ibuf_s { - uint8 *buf; - uint32 bpp; - uint32 ibuf_type; - uint32 ibuf_width; - uint32 ibuf_height; - - MDP_ROI roi; - MDPIMG mdpImg; - - int32 dma_x; - int32 dma_y; - uint32 dma_w; - uint32 dma_h; - - uint32 vsync_enable; - uint32 visible_swapped; -} MDPIBUF; - -struct mdp_dma_data { - boolean busy; - boolean waiting; - struct mutex ov_mutex; - struct semaphore mutex; - struct completion comp; -}; - -#define MDP_CMD_DEBUG_ACCESS_BASE (MDP_BASE+0x10000) - -#define MDP_DMA2_TERM 0x1 -#define MDP_DMA3_TERM 0x2 -#define MDP_PPP_TERM 0x4 -#define MDP_DMA_S_TERM 0x8 -#ifdef CONFIG_FB_MSM_MDP40 -#define MDP_DMA_E_TERM 0x10 -#define MDP_OVERLAY0_TERM 0x20 -#define MDP_OVERLAY1_TERM 0x40 -#endif - -#define ACTIVE_START_X_EN BIT(31) -#define ACTIVE_START_Y_EN BIT(31) -#define ACTIVE_HIGH 0 -#define ACTIVE_LOW 1 -#define MDP_DMA_S_DONE BIT(2) -#define LCDC_FRAME_START BIT(15) -#define LCDC_UNDERFLOW BIT(16) - -#ifdef CONFIG_FB_MSM_MDP22 -#define MDP_DMA_P_DONE BIT(2) -#else -#define MDP_DMA_P_DONE BIT(14) -#endif - -#define MDP_PPP_DONE BIT(0) -#define TV_OUT_DMA3_DONE BIT(6) -#define TV_ENC_UNDERRUN BIT(7) -#define TV_OUT_DMA3_START BIT(13) -#define MDP_HIST_DONE BIT(20) - -#ifdef CONFIG_FB_MSM_MDP22 -#define MDP_ANY_INTR_MASK (MDP_PPP_DONE| \ - MDP_DMA_P_DONE| \ - TV_ENC_UNDERRUN) -#else -#define MDP_ANY_INTR_MASK (MDP_PPP_DONE| \ - MDP_DMA_P_DONE| \ - MDP_DMA_S_DONE| \ - LCDC_UNDERFLOW| \ - MDP_HIST_DONE| \ - TV_ENC_UNDERRUN) -#endif - -#define MDP_TOP_LUMA 16 -#define MDP_TOP_CHROMA 0 -#define MDP_BOTTOM_LUMA 19 -#define MDP_BOTTOM_CHROMA 3 -#define MDP_LEFT_LUMA 22 -#define MDP_LEFT_CHROMA 6 -#define MDP_RIGHT_LUMA 25 -#define MDP_RIGHT_CHROMA 9 - -#define CLR_G 0x0 -#define CLR_B 0x1 -#define CLR_R 0x2 -#define CLR_ALPHA 0x3 - -#define CLR_Y CLR_G -#define CLR_CB CLR_B -#define CLR_CR CLR_R - -/* from lsb to msb */ -#define MDP_GET_PACK_PATTERN(a,x,y,z,bit) (((a)<<(bit*3))|((x)<<(bit*2))|((y)< -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "mdp.h" -#include "msm_fb.h" -#include "mdp4.h" - - -#define MDP4_DEBUG_BUF 128 - - -static char mdp4_debug_buf[MDP4_DEBUG_BUF]; -static ulong mdp4_debug_offset; -static ulong mdp4_base_addr; - -static int mdp4_offset_set(void *data, u64 val) -{ - mdp4_debug_offset = (int)val; - return 0; -} - -static int mdp4_offset_get(void *data, u64 *val) -{ - *val = (u64)mdp4_debug_offset; - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE( - mdp4_offset_fops, - mdp4_offset_get, - mdp4_offset_set, - "%llx\n"); - - -static int mdp4_debugfs_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static ssize_t mdp4_debugfs_write( - struct file *file, - const char __user *buff, - size_t count, - loff_t *ppos) -{ - int cnt; - unsigned int data; - - printk(KERN_INFO "%s: offset=%d count=%d *ppos=%d\n", - __func__, (int)mdp4_debug_offset, (int)count, (int)*ppos); - - if (count > sizeof(mdp4_debug_buf)) - return -EFAULT; - - if (copy_from_user(mdp4_debug_buf, buff, count)) - return -EFAULT; - - - mdp4_debug_buf[count] = 0; /* end of string */ - - cnt = sscanf(mdp4_debug_buf, "%x", &data); - if (cnt < 1) { - printk(KERN_ERR "%s: sscanf failed cnt=%d" , __func__, cnt); - return -EINVAL; - } - - writel(&data, mdp4_base_addr + mdp4_debug_offset); - - return 0; -} - -static ssize_t mdp4_debugfs_read( - struct file *file, - char __user *buff, - size_t count, - loff_t *ppos) -{ - int len = 0; - unsigned int data; - - printk(KERN_INFO "%s: offset=%d count=%d *ppos=%d\n", - __func__, (int)mdp4_debug_offset, (int)count, (int)*ppos); - - if (*ppos) - return 0; /* the end */ - - data = readl(mdp4_base_addr + mdp4_debug_offset); - - len = snprintf(mdp4_debug_buf, 4, "%x\n", data); - - if (len > 0) { - if (len > count) - len = count; - if (copy_to_user(buff, mdp4_debug_buf, len)) - return -EFAULT; - } - - printk(KERN_INFO "%s: len=%d\n", __func__, len); - - if (len < 0) - return 0; - - *ppos += len; /* increase offset */ - - return len; -} - -static const struct file_operations mdp4_debugfs_fops = { - .open = nonseekable_open, - .release = mdp4_debugfs_release, - .read = mdp4_debugfs_read, - .write = mdp4_debugfs_write, - .llseek = no_llseek, -}; - -int mdp4_debugfs_init(void) -{ - struct dentry *dent = debugfs_create_dir("mdp4", NULL); - - if (IS_ERR(dent)) { - printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n", - __FILE__, __LINE__, PTR_ERR(dent)); - return -1; - } - - if (debugfs_create_file("offset", 0644, dent, 0, &mdp4_offset_fops) - == NULL) { - printk(KERN_ERR "%s(%d): debugfs_create_file: offset fail\n", - __FILE__, __LINE__); - return -1; - } - - if (debugfs_create_file("regs", 0644, dent, 0, &mdp4_debugfs_fops) - == NULL) { - printk(KERN_ERR "%s(%d): debugfs_create_file: regs fail\n", - __FILE__, __LINE__); - return -1; - } - - mdp4_debug_offset = 0; - mdp4_base_addr = (ulong) msm_mdp_base; /* defined at msm_fb_def.h */ - - return 0; -} diff --git a/drivers/staging/msm/mdp4_overlay.c b/drivers/staging/msm/mdp4_overlay.c deleted file mode 100644 index b9acf5299297..000000000000 --- a/drivers/staging/msm/mdp4_overlay.c +++ /dev/null @@ -1,1259 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "android_pmem.h" -#include -#include -#include -#include -#include -#include - -#include "mdp.h" -#include "msm_fb.h" -#include "mdp4.h" - - -struct mdp4_overlay_ctrl { - struct mdp4_overlay_pipe plist[MDP4_MAX_OVERLAY_PIPE]; - struct mdp4_overlay_pipe *stage[MDP4_MAX_MIXER][MDP4_MAX_STAGE]; -} mdp4_overlay_db; - -static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db; - - -void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc) -{ - uint32 dma2_cfg_reg; - - dma2_cfg_reg = DMA_DITHER_EN; - - if (mfd->fb_imgType == MDP_BGR_565) - dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; - else - dma2_cfg_reg |= DMA_PACK_PATTERN_RGB; - - - if (mfd->panel_info.bpp == 18) { - dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */ - DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; - } else if (mfd->panel_info.bpp == 16) { - dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */ - DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; - } else { - dma2_cfg_reg |= DMA_DSTC0G_8BITS | /* 888 16BPP */ - DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS; - } - - if (lcdc) - dma2_cfg_reg |= DMA_PACK_ALIGN_MSB; - - /* dma2 config register */ - MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg); - -} - -void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe) -{ - - /* dma_p source */ - MDP_OUTP(MDP_BASE + 0x90004, - (pipe->src_height << 16 | pipe->src_width)); - MDP_OUTP(MDP_BASE + 0x90008, pipe->srcp0_addr); - MDP_OUTP(MDP_BASE + 0x9000c, pipe->srcp0_ystride); - - /* dma_p dest */ - MDP_OUTP(MDP_BASE + 0x90010, (pipe->dst_y << 16 | pipe->dst_x)); -} - -#define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000 -#define MDP4_VG_PHASE_STEP_SHIFT 29 - -static int mdp4_leading_0(uint32 num) -{ - uint32 bit = 0x80000000; - int i; - - for (i = 0; i < 32; i++) { - if (bit & num) - return i; - bit >>= 1; - } - - return i; -} - -static uint32 mdp4_scale_phase_step(int f_num, uint32 src, uint32 dst) -{ - uint32 val; - int n; - - n = mdp4_leading_0(src); - if (n > f_num) - n = f_num; - val = src << n; /* maximum to reduce lose of resolution */ - val /= dst; - if (n < f_num) { - n = f_num - n; - val <<= n; - } - - return val; -} - -static void mdp4_scale_setup(struct mdp4_overlay_pipe *pipe) -{ - - pipe->phasex_step = MDP4_VG_PHASE_STEP_DEFAULT; - pipe->phasey_step = MDP4_VG_PHASE_STEP_DEFAULT; - - if (pipe->dst_h && pipe->src_h != pipe->dst_h) { - if (pipe->dst_h >= pipe->src_h * 8) /* too much */ - return; - pipe->op_mode |= MDP4_OP_SCALEY_EN; - - if (pipe->pipe_type == OVERLAY_TYPE_VG) { - if (pipe->dst_h <= (pipe->src_h / 4)) - pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE; - else - pipe->op_mode |= MDP4_OP_SCALEY_FIR; - } - - pipe->phasey_step = mdp4_scale_phase_step(29, - pipe->src_h, pipe->dst_h); - } - - if (pipe->dst_w && pipe->src_w != pipe->dst_w) { - if (pipe->dst_w >= pipe->src_w * 8) /* too much */ - return; - pipe->op_mode |= MDP4_OP_SCALEX_EN; - - if (pipe->pipe_type == OVERLAY_TYPE_VG) { - if (pipe->dst_w <= (pipe->src_w / 4)) - pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE; - else - pipe->op_mode |= MDP4_OP_SCALEY_FIR; - } - - pipe->phasex_step = mdp4_scale_phase_step(29, - pipe->src_w, pipe->dst_w); - } -} - -void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe) -{ - char *rgb_base; - uint32 src_size, src_xy, dst_size, dst_xy; - uint32 format, pattern; - - rgb_base = MDP_BASE + MDP4_RGB_BASE; - rgb_base += (MDP4_RGB_OFF * pipe->pipe_num); - - src_size = ((pipe->src_h << 16) | pipe->src_w); - src_xy = ((pipe->src_y << 16) | pipe->src_x); - dst_size = ((pipe->dst_h << 16) | pipe->dst_w); - dst_xy = ((pipe->dst_y << 16) | pipe->dst_x); - - format = mdp4_overlay_format(pipe); - pattern = mdp4_overlay_unpack_pattern(pipe); - - pipe->op_mode |= MDP4_OP_IGC_LUT_EN; - - mdp4_scale_setup(pipe); - - outpdw(rgb_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */ - outpdw(rgb_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */ - outpdw(rgb_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */ - outpdw(rgb_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */ - - outpdw(rgb_base + 0x0010, pipe->srcp0_addr); - outpdw(rgb_base + 0x0040, pipe->srcp0_ystride); - - outpdw(rgb_base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */ - outpdw(rgb_base + 0x0054, pattern);/* MDP_RGB_SRC_UNPACK_PATTERN */ - outpdw(rgb_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */ - outpdw(rgb_base + 0x005c, pipe->phasex_step); - outpdw(rgb_base + 0x0060, pipe->phasey_step); - - /* 16 bytes-burst x 3 req <= 48 bytes */ - outpdw(rgb_base + 0x1004, 0xc2); /* MDP_RGB_FETCH_CFG */ -} - -void mdp4_overlay_vg_setup(struct mdp4_overlay_pipe *pipe) -{ - char *vg_base; - uint32 frame_size, src_size, src_xy, dst_size, dst_xy; - uint32 format, pattern; - - vg_base = MDP_BASE + MDP4_VIDEO_BASE; - vg_base += (MDP4_VIDEO_OFF * pipe->pipe_num); - - frame_size = ((pipe->src_height << 16) | pipe->src_width); - src_size = ((pipe->src_h << 16) | pipe->src_w); - src_xy = ((pipe->src_y << 16) | pipe->src_x); - dst_size = ((pipe->dst_h << 16) | pipe->dst_w); - dst_xy = ((pipe->dst_y << 16) | pipe->dst_x); - - format = mdp4_overlay_format(pipe); - pattern = mdp4_overlay_unpack_pattern(pipe); - - pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR | - MDP4_OP_IGC_LUT_EN); - - mdp4_scale_setup(pipe); - - outpdw(vg_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */ - outpdw(vg_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */ - outpdw(vg_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */ - outpdw(vg_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */ - outpdw(vg_base + 0x0048, frame_size); /* TILE frame size */ - - /* luma component plane */ - outpdw(vg_base + 0x0010, pipe->srcp0_addr); - - /* chroma component plane */ - outpdw(vg_base + 0x0014, pipe->srcp1_addr); - - outpdw(vg_base + 0x0040, - pipe->srcp1_ystride << 16 | pipe->srcp0_ystride); - - outpdw(vg_base + 0x0050, format); /* MDP_RGB_SRC_FORMAT */ - outpdw(vg_base + 0x0054, pattern); /* MDP_RGB_SRC_UNPACK_PATTERN */ - outpdw(vg_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */ - outpdw(vg_base + 0x005c, pipe->phasex_step); - outpdw(vg_base + 0x0060, pipe->phasey_step); - - if (pipe->op_mode & MDP4_OP_DITHER_EN) { - outpdw(vg_base + 0x0068, - pipe->r_bit << 4 | pipe->b_bit << 2 | pipe->g_bit); - } - - /* 16 bytes-burst x 3 req <= 48 bytes */ - outpdw(vg_base + 0x1004, 0xc2); /* MDP_VG_FETCH_CFG */ -} - -int mdp4_overlay_format2type(uint32 format) -{ - switch (format) { - case MDP_RGB_565: - case MDP_RGB_888: - case MDP_BGR_565: - case MDP_ARGB_8888: - case MDP_RGBA_8888: - case MDP_BGRA_8888: - return OVERLAY_TYPE_RGB; - case MDP_YCRYCB_H2V1: - case MDP_Y_CRCB_H2V1: - case MDP_Y_CBCR_H2V1: - case MDP_Y_CRCB_H2V2: - case MDP_Y_CBCR_H2V2: - case MDP_Y_CBCR_H2V2_TILE: - case MDP_Y_CRCB_H2V2_TILE: - return OVERLAY_TYPE_VG; - default: - return -ERANGE; - } - -} - -#define C3_ALPHA 3 /* alpha */ -#define C2_R_Cr 2 /* R/Cr */ -#define C1_B_Cb 1 /* B/Cb */ -#define C0_G_Y 0 /* G/luma */ - -int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe) -{ - switch (pipe->src_format) { - case MDP_RGB_565: - pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR; - pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED; - pipe->a_bit = 0; - pipe->r_bit = 1; /* R, 5 bits */ - pipe->b_bit = 1; /* B, 5 bits */ - pipe->g_bit = 2; /* G, 6 bits */ - pipe->alpha_enable = 0; - pipe->unpack_tight = 1; - pipe->unpack_align_msb = 0; - pipe->unpack_count = 2; - pipe->element2 = C2_R_Cr; /* R */ - pipe->element1 = C0_G_Y; /* G */ - pipe->element0 = C1_B_Cb; /* B */ - pipe->bpp = 2; /* 2 bpp */ - break; - case MDP_RGB_888: - pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR; - pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED; - pipe->a_bit = 0; - pipe->r_bit = 3; /* R, 8 bits */ - pipe->b_bit = 3; /* B, 8 bits */ - pipe->g_bit = 3; /* G, 8 bits */ - pipe->alpha_enable = 0; - pipe->unpack_tight = 1; - pipe->unpack_align_msb = 0; - pipe->unpack_count = 2; - pipe->element2 = C2_R_Cr; /* R */ - pipe->element1 = C0_G_Y; /* G */ - pipe->element0 = C1_B_Cb; /* B */ - pipe->bpp = 3; /* 3 bpp */ - break; - case MDP_BGR_565: - pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR; - pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED; - pipe->a_bit = 0; - pipe->r_bit = 1; /* R, 5 bits */ - pipe->b_bit = 1; /* B, 5 bits */ - pipe->g_bit = 2; /* G, 6 bits */ - pipe->alpha_enable = 0; - pipe->unpack_tight = 1; - pipe->unpack_align_msb = 0; - pipe->unpack_count = 2; - pipe->element2 = C1_B_Cb; /* B */ - pipe->element1 = C0_G_Y; /* G */ - pipe->element0 = C2_R_Cr; /* R */ - pipe->bpp = 2; /* 2 bpp */ - break; - case MDP_ARGB_8888: - pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR; - pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED; - pipe->a_bit = 3; /* alpha, 4 bits */ - pipe->r_bit = 3; /* R, 8 bits */ - pipe->b_bit = 3; /* B, 8 bits */ - pipe->g_bit = 3; /* G, 8 bits */ - pipe->alpha_enable = 1; - pipe->unpack_tight = 1; - pipe->unpack_align_msb = 0; - pipe->unpack_count = 3; - pipe->element3 = C3_ALPHA; /* alpha */ - pipe->element2 = C2_R_Cr; /* R */ - pipe->element1 = C0_G_Y; /* G */ - pipe->element0 = C1_B_Cb; /* B */ - pipe->bpp = 4; /* 4 bpp */ - break; - case MDP_RGBA_8888: - pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR; - pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED; - pipe->a_bit = 3; /* alpha, 4 bits */ - pipe->r_bit = 3; /* R, 8 bits */ - pipe->b_bit = 3; /* B, 8 bits */ - pipe->g_bit = 3; /* G, 8 bits */ - pipe->alpha_enable = 1; - pipe->unpack_tight = 1; - pipe->unpack_align_msb = 0; - pipe->unpack_count = 3; - pipe->element3 = C2_R_Cr; /* R */ - pipe->element2 = C0_G_Y; /* G */ - pipe->element1 = C1_B_Cb; /* B */ - pipe->element0 = C3_ALPHA; /* alpha */ - pipe->bpp = 4; /* 4 bpp */ - break; - case MDP_BGRA_8888: - pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR; - pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED; - pipe->a_bit = 3; /* alpha, 4 bits */ - pipe->r_bit = 3; /* R, 8 bits */ - pipe->b_bit = 3; /* B, 8 bits */ - pipe->g_bit = 3; /* G, 8 bits */ - pipe->alpha_enable = 1; - pipe->unpack_tight = 1; - pipe->unpack_align_msb = 0; - pipe->unpack_count = 3; - pipe->element3 = C1_B_Cb; /* B */ - pipe->element2 = C0_G_Y; /* G */ - pipe->element1 = C2_R_Cr; /* R */ - pipe->element0 = C3_ALPHA; /* alpha */ - pipe->bpp = 4; /* 4 bpp */ - break; - case MDP_YCRYCB_H2V1: - pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR; - pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED; - pipe->a_bit = 0; /* alpha, 4 bits */ - pipe->r_bit = 3; /* R, 8 bits */ - pipe->b_bit = 3; /* B, 8 bits */ - pipe->g_bit = 3; /* G, 8 bits */ - pipe->alpha_enable = 0; - pipe->unpack_tight = 1; - pipe->unpack_align_msb = 0; - pipe->unpack_count = 3; - pipe->element3 = C0_G_Y; /* G */ - pipe->element2 = C2_R_Cr; /* R */ - pipe->element1 = C0_G_Y; /* G */ - pipe->element0 = C1_B_Cb; /* B */ - pipe->bpp = 2; /* 2 bpp */ - pipe->chroma_sample = MDP4_CHROMA_H2V1; - break; - case MDP_Y_CRCB_H2V1: - case MDP_Y_CBCR_H2V1: - case MDP_Y_CRCB_H2V2: - case MDP_Y_CBCR_H2V2: - pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR; - pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR; - pipe->a_bit = 0; - pipe->r_bit = 3; /* R, 8 bits */ - pipe->b_bit = 3; /* B, 8 bits */ - pipe->g_bit = 3; /* G, 8 bits */ - pipe->alpha_enable = 0; - pipe->unpack_tight = 1; - pipe->unpack_align_msb = 0; - pipe->unpack_count = 1; /* 2 */ - pipe->element3 = C0_G_Y; /* not used */ - pipe->element2 = C0_G_Y; /* not used */ - if (pipe->src_format == MDP_Y_CRCB_H2V1) { - pipe->element1 = C2_R_Cr; /* R */ - pipe->element0 = C1_B_Cb; /* B */ - pipe->chroma_sample = MDP4_CHROMA_H2V1; - } else if (pipe->src_format == MDP_Y_CBCR_H2V1) { - pipe->element1 = C1_B_Cb; /* B */ - pipe->element0 = C2_R_Cr; /* R */ - pipe->chroma_sample = MDP4_CHROMA_H2V1; - } else if (pipe->src_format == MDP_Y_CRCB_H2V2) { - pipe->element1 = C2_R_Cr; /* R */ - pipe->element0 = C1_B_Cb; /* B */ - pipe->chroma_sample = MDP4_CHROMA_420; - } else if (pipe->src_format == MDP_Y_CBCR_H2V2) { - pipe->element1 = C1_B_Cb; /* B */ - pipe->element0 = C2_R_Cr; /* R */ - pipe->chroma_sample = MDP4_CHROMA_420; - } - pipe->bpp = 2; /* 2 bpp */ - break; - case MDP_Y_CBCR_H2V2_TILE: - case MDP_Y_CRCB_H2V2_TILE: - pipe->frame_format = MDP4_FRAME_FORMAT_VIDEO_SUPERTILE; - pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR; - pipe->a_bit = 0; - pipe->r_bit = 3; /* R, 8 bits */ - pipe->b_bit = 3; /* B, 8 bits */ - pipe->g_bit = 3; /* G, 8 bits */ - pipe->alpha_enable = 0; - pipe->unpack_tight = 1; - pipe->unpack_align_msb = 0; - pipe->unpack_count = 1; /* 2 */ - pipe->element3 = C0_G_Y; /* not used */ - pipe->element2 = C0_G_Y; /* not used */ - if (pipe->src_format == MDP_Y_CRCB_H2V2_TILE) { - pipe->element1 = C2_R_Cr; /* R */ - pipe->element0 = C1_B_Cb; /* B */ - pipe->chroma_sample = MDP4_CHROMA_420; - } else if (pipe->src_format == MDP_Y_CBCR_H2V2_TILE) { - pipe->element1 = C1_B_Cb; /* B */ - pipe->element0 = C2_R_Cr; /* R */ - pipe->chroma_sample = MDP4_CHROMA_420; - } - pipe->bpp = 2; /* 2 bpp */ - break; - default: - /* not likely */ - return -ERANGE; - } - - return 0; -} - -/* - * color_key_convert: output with 12 bits color key - */ -static uint32 color_key_convert(int start, int num, uint32 color) -{ - - uint32 data; - - data = (color >> start) & ((1 << num) - 1); - - if (num == 5) - data = (data << 7) + (data << 2) + (data >> 3); - else if (num == 6) - data = (data << 6) + data; - else /* 8 bits */ - data = (data << 4) + (data >> 4); - - return data; - -} - -void transp_color_key(int format, uint32 transp, - uint32 *c0, uint32 *c1, uint32 *c2) -{ - int b_start, g_start, r_start; - int b_num, g_num, r_num; - - switch (format) { - case MDP_RGB_565: - b_start = 0; - g_start = 5; - r_start = 11; - r_num = 5; - g_num = 6; - b_num = 5; - break; - case MDP_RGB_888: - case MDP_XRGB_8888: - case MDP_ARGB_8888: - b_start = 0; - g_start = 8; - r_start = 16; - r_num = 8; - g_num = 8; - b_num = 8; - break; - case MDP_BGR_565: - b_start = 11; - g_start = 5; - r_start = 0; - r_num = 5; - g_num = 6; - b_num = 5; - break; - case MDP_Y_CBCR_H2V2: - case MDP_Y_CBCR_H2V1: - b_start = 8; - g_start = 16; - r_start = 0; - r_num = 8; - g_num = 8; - b_num = 8; - break; - case MDP_Y_CRCB_H2V2: - case MDP_Y_CRCB_H2V1: - b_start = 0; - g_start = 16; - r_start = 8; - r_num = 8; - g_num = 8; - b_num = 8; - break; - default: - b_start = 0; - g_start = 8; - r_start = 16; - r_num = 8; - g_num = 8; - b_num = 8; - break; - } - - *c0 = color_key_convert(g_start, g_num, transp); - *c1 = color_key_convert(b_start, b_num, transp); - *c2 = color_key_convert(r_start, r_num, transp); -} - -uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe) -{ - uint32 format; - - format = 0; - - if (pipe->solid_fill) - format |= MDP4_FORMAT_SOLID_FILL; - - if (pipe->unpack_align_msb) - format |= MDP4_FORMAT_UNPACK_ALIGN_MSB; - - if (pipe->unpack_tight) - format |= MDP4_FORMAT_UNPACK_TIGHT; - - if (pipe->alpha_enable) - format |= MDP4_FORMAT_ALPHA_ENABLE; - - format |= (pipe->unpack_count << 13); - format |= ((pipe->bpp - 1) << 9); - format |= (pipe->a_bit << 6); - format |= (pipe->r_bit << 4); - format |= (pipe->b_bit << 2); - format |= pipe->g_bit; - - format |= (pipe->frame_format << 29); - - if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) { - /* video/graphic */ - format |= (pipe->fetch_plane << 19); - format |= (pipe->chroma_site << 28); - format |= (pipe->chroma_sample << 26); - } - - return format; -} - -uint32 mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe) -{ - return (pipe->element3 << 24) | (pipe->element2 << 16) | - (pipe->element1 << 8) | pipe->element0; -} - -void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe) -{ - uint32 data; - char *overlay_base; - - if (pipe->mixer_num == MDP4_MIXER1) - overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */ - else - overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */ - - /* MDP_OVERLAYPROC_CFG */ - outpdw(overlay_base + 0x0004, 0x01); /* directout */ - data = pipe->src_height; - data <<= 16; - data |= pipe->src_width; - outpdw(overlay_base + 0x0008, data); /* ROI, height + width */ - outpdw(overlay_base + 0x000c, pipe->srcp0_addr); - outpdw(overlay_base + 0x0010, pipe->srcp0_ystride); - outpdw(overlay_base + 0x0014, 0x4); /* GC_LUT_EN, 888 */ -} - -int mdp4_overlay_active(int mixer) -{ - uint32 data, mask, i; - int p1, p2; - - data = inpdw(MDP_BASE + 0x10100); - p1 = 0; - p2 = 0; - for (i = 0; i < 8; i++) { - mask = data & 0x0f; - if (mask) { - if (mask <= 4) - p1++; - else - p2++; - } - data >>= 4; - } - - if (mixer) - return p2; - else - return p1; -} - -void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe) -{ - uint32 data, mask, snum, stage, mixer; - - stage = pipe->mixer_stage; - mixer = pipe->mixer_num; - - /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */ - data = inpdw(MDP_BASE + 0x10100); - - if (mixer == MDP4_MIXER1) - stage += 8; - - if (pipe->pipe_type == OVERLAY_TYPE_VG) {/* VG1 and VG2 */ - snum = 0; - snum += (4 * pipe->pipe_num); - } else { - snum = 8; - snum += (4 * pipe->pipe_num); /* RGB1 and RGB2 */ - } - - mask = 0x0f; - mask <<= snum; - stage <<= snum; - data &= ~mask; /* clear old bits */ - - data |= stage; - - outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */ - - data = inpdw(MDP_BASE + 0x10100); - - ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = pipe; /* keep it */ -} - -void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe) -{ - uint32 data, mask, snum, stage, mixer; - - stage = pipe->mixer_stage; - mixer = pipe->mixer_num; - - if (pipe != ctrl->stage[mixer][stage]) /* not running */ - return; - - /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */ - data = inpdw(MDP_BASE + 0x10100); - - if (mixer == MDP4_MIXER1) - stage += 8; - - if (pipe->pipe_type == OVERLAY_TYPE_VG) {/* VG1 and VG2 */ - snum = 0; - snum += (4 * pipe->pipe_num); - } else { - snum = 8; - snum += (4 * pipe->pipe_num); /* RGB1 and RGB2 */ - } - - mask = 0x0f; - mask <<= snum; - data &= ~mask; /* clear old bits */ - - outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */ - - data = inpdw(MDP_BASE + 0x10100); - - ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = NULL; /* clear it */ -} - -void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe) -{ - unsigned char *overlay_base; - uint32 c0, c1, c2, blend_op; - int off; - - if (pipe->mixer_num) /* mixer number, /dev/fb0, /dev/fb1 */ - overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */ - else - overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */ - - /* stage 0 to stage 2 */ - off = 0x20 * (pipe->mixer_stage - MDP4_MIXER_STAGE0); - - blend_op = 0; - if (pipe->alpha_enable) /* ARGB */ - blend_op = MDP4_BLEND_FG_ALPHA_FG_PIXEL | - MDP4_BLEND_BG_ALPHA_FG_PIXEL; - else - blend_op = (MDP4_BLEND_BG_ALPHA_BG_CONST | - MDP4_BLEND_FG_ALPHA_FG_CONST); - - - if (pipe->alpha_enable == 0) { /* not ARGB */ - if (pipe->is_fg) { - outpdw(overlay_base + off + 0x108, pipe->alpha); - outpdw(overlay_base + off + 0x10c, 0xff - pipe->alpha); - } else { - outpdw(overlay_base + off + 0x108, 0xff - pipe->alpha); - outpdw(overlay_base + off + 0x10c, pipe->alpha); - } - } - - if (pipe->transp != MDP_TRANSP_NOP) { - transp_color_key(pipe->src_format, pipe->transp, &c0, &c1, &c2); - if (pipe->is_fg) { - blend_op |= MDP4_BLEND_FG_TRANSP_EN; /* Fg blocked */ - /* lower limit */ - if (c0 > 0x10) - c0 -= 0x10; - if (c1 > 0x10) - c1 -= 0x10; - if (c2 > 0x10) - c2 -= 0x10; - outpdw(overlay_base + off + 0x110, - (c1 << 16 | c0));/* low */ - outpdw(overlay_base + off + 0x114, c2);/* low */ - /* upper limit */ - if ((c0 + 0x20) < 0x0fff) - c0 += 0x20; - else - c0 = 0x0fff; - if ((c1 + 0x20) < 0x0fff) - c1 += 0x20; - else - c1 = 0x0fff; - if ((c2 + 0x20) < 0x0fff) - c2 += 0x20; - else - c2 = 0x0fff; - outpdw(overlay_base + off + 0x118, - (c1 << 16 | c0));/* high */ - outpdw(overlay_base + off + 0x11c, c2);/* high */ - } else { - blend_op |= MDP4_BLEND_BG_TRANSP_EN; /* bg blocked */ - /* lower limit */ - if (c0 > 0x10) - c0 -= 0x10; - if (c1 > 0x10) - c1 -= 0x10; - if (c2 > 0x10) - c2 -= 0x10; - outpdw(overlay_base + 0x180, - (c1 << 16 | c0));/* low */ - outpdw(overlay_base + 0x184, c2);/* low */ - /* upper limit */ - if ((c0 + 0x20) < 0x0fff) - c0 += 0x20; - else - c0 = 0x0fff; - if ((c1 + 0x20) < 0x0fff) - c1 += 0x20; - else - c1 = 0x0fff; - if ((c2 + 0x20) < 0x0fff) - c2 += 0x20; - else - c2 = 0x0fff; - outpdw(overlay_base + 0x188, - (c1 << 16 | c0));/* high */ - outpdw(overlay_base + 0x18c, c2);/* high */ - } - } - outpdw(overlay_base + off + 0x104, blend_op); -} - -void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all) -{ - uint32 bits = 0; - - if (pipe->mixer_num == MDP4_MIXER1) - bits |= 0x02; - else - bits |= 0x01; - - if (all) { - if (pipe->pipe_type == OVERLAY_TYPE_RGB) { - if (pipe->pipe_num == OVERLAY_PIPE_RGB2) - bits |= 0x20; - else - bits |= 0x10; - } else { - if (pipe->pipe_num == OVERLAY_PIPE_VG2) - bits |= 0x08; - else - bits |= 0x04; - } - } - - outpdw(MDP_BASE + 0x18000, bits); /* MDP_OVERLAY_REG_FLUSH */ - - while (inpdw(MDP_BASE + 0x18000) & bits) /* self clear when complete */ - ; -} - -struct mdp4_overlay_pipe *mdp4_overlay_ndx2pipe(int ndx) -{ - struct mdp4_overlay_pipe *pipe; - - if (ndx == 0 || ndx >= MDP4_MAX_OVERLAY_PIPE) - return NULL; - - pipe = &ctrl->plist[ndx - 1]; /* ndx start from 1 */ - - if (pipe->pipe_ndx == 0) - return NULL; - - return pipe; -} - -struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(void) -{ - int i; - struct mdp4_overlay_pipe *pipe; - - pipe = &ctrl->plist[0]; - for (i = 0; i < MDP4_MAX_OVERLAY_PIPE; i++) { - if (pipe->pipe_ndx == 0) { - pipe->pipe_ndx = i + 1; /* start from 1 */ - init_completion(&pipe->comp); - printk(KERN_INFO "mdp4_overlay_pipe_alloc: pipe=%p ndx=%d\n", - pipe, pipe->pipe_ndx); - return pipe; - } - pipe++; - } - - return NULL; -} - - -void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe) -{ - printk(KERN_INFO "mdp4_overlay_pipe_free: pipe=%p ndx=%d\n", - pipe, pipe->pipe_ndx); - memset(pipe, 0, sizeof(*pipe)); -} - -static int get_pipe_num(int ptype, int stage) -{ - if (ptype == OVERLAY_TYPE_RGB) { - if (stage == MDP4_MIXER_STAGE_BASE) - return OVERLAY_PIPE_RGB1; - else - return OVERLAY_PIPE_RGB2; - } else { - if (stage == MDP4_MIXER_STAGE0) - return OVERLAY_PIPE_VG1; - else - return OVERLAY_PIPE_VG2; - } -} - -int mdp4_overlay_req_check(uint32 id, uint32 z_order, uint32 mixer) -{ - struct mdp4_overlay_pipe *pipe; - - pipe = ctrl->stage[mixer][z_order]; - - if (pipe == NULL) - return 0; - - if (pipe->pipe_ndx == id) /* same req, recycle */ - return 0; - - return -EPERM; -} - -static int mdp4_overlay_req2pipe(struct mdp_overlay *req, int mixer, - struct mdp4_overlay_pipe **ppipe) -{ - struct mdp4_overlay_pipe *pipe; - int ret, ptype; - - if (mixer >= MDP4_MAX_MIXER) { - printk(KERN_ERR "mpd_overlay_req2pipe: mixer out of range!\n"); - return -ERANGE; - } - - if (req->z_order < 0 || req->z_order > 2) { - printk(KERN_ERR "mpd_overlay_req2pipe: z_order=%d out of range!\n", - req->z_order); - return -ERANGE; - } - - if (req->src_rect.h == 0 || req->src_rect.w == 0) { - printk(KERN_ERR "mpd_overlay_req2pipe: src img of zero size!\n"); - return -EINVAL; - } - - ret = mdp4_overlay_req_check(req->id, req->z_order, mixer); - if (ret < 0) - return ret; - - ptype = mdp4_overlay_format2type(req->src.format); - if (ptype < 0) - return ptype; - - if (req->id == MSMFB_NEW_REQUEST) /* new request */ - pipe = mdp4_overlay_pipe_alloc(); - else - pipe = mdp4_overlay_ndx2pipe(req->id); - - if (pipe == NULL) - return -ENOMEM; - - pipe->src_format = req->src.format; - ret = mdp4_overlay_format2pipe(pipe); - - if (ret < 0) - return ret; - - /* - * base layer == 1, reserved for frame buffer - * zorder 0 == stage 0 == 2 - * zorder 1 == stage 1 == 3 - * zorder 2 == stage 2 == 4 - */ - if (req->id == MSMFB_NEW_REQUEST) { /* new request */ - pipe->mixer_stage = req->z_order + MDP4_MIXER_STAGE0; - pipe->pipe_type = ptype; - pipe->pipe_num = get_pipe_num(ptype, pipe->mixer_stage); - printk(KERN_INFO "mpd4_overlay_req2pipe: zorder=%d pipe_num=%d\n", - req->z_order, pipe->pipe_num); - } - - pipe->src_width = req->src.width & 0x07ff; /* source img width */ - pipe->src_height = req->src.height & 0x07ff; /* source img height */ - pipe->src_h = req->src_rect.h & 0x07ff; - pipe->src_w = req->src_rect.w & 0x07ff; - pipe->src_y = req->src_rect.y & 0x07ff; - pipe->src_x = req->src_rect.x & 0x07ff; - pipe->dst_h = req->dst_rect.h & 0x07ff; - pipe->dst_w = req->dst_rect.w & 0x07ff; - pipe->dst_y = req->dst_rect.y & 0x07ff; - pipe->dst_x = req->dst_rect.x & 0x07ff; - - if (req->flags & MDP_FLIP_LR) - pipe->op_mode |= MDP4_OP_FLIP_LR; - - if (req->flags & MDP_FLIP_UD) - pipe->op_mode |= MDP4_OP_FLIP_UD; - - if (req->flags & MDP_DITHER) - pipe->op_mode |= MDP4_OP_DITHER_EN; - - if (req->flags & MDP_DEINTERLACE) - pipe->op_mode |= MDP4_OP_DEINT_ODD_REF; - - pipe->is_fg = req->is_fg;/* control alpha and color key */ - - pipe->alpha = req->alpha & 0x0ff; - - pipe->transp = req->transp_mask; - - *ppipe = pipe; - - return 0; -} - -int get_img(struct msmfb_data *img, struct fb_info *info, - unsigned long *start, unsigned long *len, struct file **pp_file) -{ - int put_needed, ret = 0; - struct file *file; -#ifdef CONFIG_ANDROID_PMEM - unsigned long vstart; -#endif - -#ifdef CONFIG_ANDROID_PMEM - if (!get_pmem_file(img->memory_id, start, &vstart, len, pp_file)) - return 0; -#endif - file = fget_light(img->memory_id, &put_needed); - if (file == NULL) - return -1; - - if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) { - *start = info->fix.smem_start; - *len = info->fix.smem_len; - *pp_file = file; - } else { - ret = -1; - fput_light(file, put_needed); - } - return ret; -} -int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req) -{ - struct mdp4_overlay_pipe *pipe; - - pipe = mdp4_overlay_ndx2pipe(req->id); - if (pipe == NULL) - return -ENODEV; - - *req = pipe->req_data; - - return 0; -} - -int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - int ret, mixer; - struct mdp4_overlay_pipe *pipe; - int lcdc; - - if (mfd == NULL) - return -ENODEV; - - if (req->src.format == MDP_FB_FORMAT) - req->src.format = mfd->fb_imgType; - - if (mutex_lock_interruptible(&mfd->dma->ov_mutex)) - return -EINTR; - - mixer = info->node; /* minor number of char device */ - - ret = mdp4_overlay_req2pipe(req, mixer, &pipe); - if (ret < 0) { - mutex_unlock(&mfd->dma->ov_mutex); - return ret; - } - - lcdc = inpdw(MDP_BASE + 0xc0000); - - if (lcdc == 0) { /* mddi */ - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - } - - /* return id back to user */ - req->id = pipe->pipe_ndx; /* pipe_ndx start from 1 */ - pipe->req_data = *req; /* keep original req */ - - mutex_unlock(&mfd->dma->ov_mutex); - - return 0; -} - -int mdp4_overlay_unset(struct fb_info *info, int ndx) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - struct mdp4_overlay_pipe *pipe; - int lcdc; - - if (mfd == NULL) - return -ENODEV; - - if (mutex_lock_interruptible(&mfd->dma->ov_mutex)) - return -EINTR; - - pipe = mdp4_overlay_ndx2pipe(ndx); - - if (pipe == NULL) { - mutex_unlock(&mfd->dma->ov_mutex); - return -ENODEV; - } - - lcdc = inpdw(MDP_BASE + 0xc0000); - - mdp4_mixer_stage_down(pipe); - - if (lcdc == 0) { /* mddi */ - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - } - - if (lcdc) /* LCDC mode */ - mdp4_overlay_reg_flush(pipe, 0); - - mdp4_overlay_pipe_free(pipe); - - if (lcdc == 0) { /* mddi */ - mdp4_mddi_overlay_restore(); - } - - mutex_unlock(&mfd->dma->ov_mutex); - - return 0; -} - -struct tile_desc { - uint32 width; /* tile's width */ - uint32 height; /* tile's height */ - uint32 row_tile_w; /* tiles per row's width */ - uint32 row_tile_h; /* tiles per row's height */ -}; - -void tile_samsung(struct tile_desc *tp) -{ - /* - * each row of samsung tile consists of two tiles in height - * and two tiles in width which means width should align to - * 64 x 2 bytes and height should align to 32 x 2 bytes. - * video decoder generate two tiles in width and one tile - * in height which ends up height align to 32 X 1 bytes. - */ - tp->width = 64; /* 64 bytes */ - tp->row_tile_w = 2; /* 2 tiles per row's width */ - tp->height = 32; /* 32 bytes */ - tp->row_tile_h = 1; /* 1 tiles per row's height */ -} - -uint32 tile_mem_size(struct mdp4_overlay_pipe *pipe, struct tile_desc *tp) -{ - uint32 tile_w, tile_h; - uint32 row_num_w, row_num_h; - - - tile_w = tp->width * tp->row_tile_w; - tile_h = tp->height * tp->row_tile_h; - - row_num_w = (pipe->src_width + tile_w - 1) / tile_w; - row_num_h = (pipe->src_height + tile_h - 1) / tile_h; - - return row_num_w * row_num_h * tile_w * tile_h; -} - -int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req, - struct file **pp_src_file) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - struct msmfb_data *img; - struct mdp4_overlay_pipe *pipe; - ulong start, addr; - ulong len = 0; - struct file *p_src_file = 0; - int lcdc; - - if (mfd == NULL) - return -ENODEV; - - pipe = mdp4_overlay_ndx2pipe(req->id); - if (pipe == NULL) - return -ENODEV; - - if (mutex_lock_interruptible(&mfd->dma->ov_mutex)) - return -EINTR; - - img = &req->data; - get_img(img, info, &start, &len, &p_src_file); - if (len == 0) { - mutex_unlock(&mfd->dma->ov_mutex); - printk(KERN_ERR "mdp_overlay_play: could not retrieve" - " image from memory\n"); - return -1; - } - *pp_src_file = p_src_file; - - addr = start + img->offset; - pipe->srcp0_addr = addr; - pipe->srcp0_ystride = pipe->src_width * pipe->bpp; - - if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) { - if (pipe->frame_format == MDP4_FRAME_FORMAT_VIDEO_SUPERTILE) { - struct tile_desc tile; - - tile_samsung(&tile); - pipe->srcp1_addr = addr + tile_mem_size(pipe, &tile); - } else - pipe->srcp1_addr = addr + - pipe->src_width * pipe->src_height; - - pipe->srcp0_ystride = pipe->src_width; - pipe->srcp1_ystride = pipe->src_width; - } - - lcdc = inpdw(MDP_BASE + 0xc0000); - lcdc &= 0x01; /* LCDC mode */ - - if (pipe->pipe_type == OVERLAY_TYPE_VG) - mdp4_overlay_vg_setup(pipe); /* video/graphic pipe */ - else - mdp4_overlay_rgb_setup(pipe); /* rgb pipe */ - - mdp4_mixer_blend_setup(pipe); - mdp4_mixer_stage_up(pipe); - - if (lcdc) { /* LCDC mode */ - mdp4_overlay_reg_flush(pipe, 1); - } - - if (lcdc) { /* LCDC mode */ - if (pipe->mixer_stage != MDP4_MIXER_STAGE_BASE) { /* done */ - mutex_unlock(&mfd->dma->ov_mutex); - return 0; - } - } - - if (lcdc == 0) { /* MDDI mode */ -#ifdef MDP4_NONBLOCKING - if (mfd->panel_power_on) -#else - if (!mfd->dma->busy && mfd->panel_power_on) -#endif - mdp4_mddi_overlay_kickoff(mfd, pipe); - } - - mutex_unlock(&mfd->dma->ov_mutex); - - return 0; -} diff --git a/drivers/staging/msm/mdp4_overlay_lcdc.c b/drivers/staging/msm/mdp4_overlay_lcdc.c deleted file mode 100644 index a6ab8ec83f55..000000000000 --- a/drivers/staging/msm/mdp4_overlay_lcdc.c +++ /dev/null @@ -1,313 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "mdp.h" -#include "msm_fb.h" -#include "mdp4.h" - -#ifdef CONFIG_FB_MSM_MDP40 -#define LCDC_BASE 0xC0000 -#else -#define LCDC_BASE 0xE0000 -#endif - -int first_pixel_start_x; -int first_pixel_start_y; - -static struct mdp4_overlay_pipe *lcdc_pipe; - -int mdp_lcdc_on(struct platform_device *pdev) -{ - int lcdc_width; - int lcdc_height; - int lcdc_bpp; - int lcdc_border_clr; - int lcdc_underflow_clr; - int lcdc_hsync_skew; - - int hsync_period; - int hsync_ctrl; - int vsync_period; - int display_hctl; - int display_v_start; - int display_v_end; - int active_hctl; - int active_h_start; - int active_h_end; - int active_v_start; - int active_v_end; - int ctrl_polarity; - int h_back_porch; - int h_front_porch; - int v_back_porch; - int v_front_porch; - int hsync_pulse_width; - int vsync_pulse_width; - int hsync_polarity; - int vsync_polarity; - int data_en_polarity; - int hsync_start_x; - int hsync_end_x; - uint8 *buf; - int bpp, ptype; - uint32 format; - struct fb_info *fbi; - struct fb_var_screeninfo *var; - struct msm_fb_data_type *mfd; - struct mdp4_overlay_pipe *pipe; - int ret; - - mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - fbi = mfd->fbi; - var = &fbi->var; - - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - - bpp = fbi->var.bits_per_pixel / 8; - buf = (uint8 *) fbi->fix.smem_start; - buf += fbi->var.xoffset * bpp + - fbi->var.yoffset * fbi->fix.line_length; - - if (bpp == 2) - format = MDP_RGB_565; - else if (bpp == 3) - format = MDP_RGB_888; - else - format = MDP_ARGB_8888; - - - if (lcdc_pipe == NULL) { - ptype = mdp4_overlay_format2type(format); - pipe = mdp4_overlay_pipe_alloc(); - pipe->pipe_type = ptype; - /* use RGB1 pipe */ - pipe->pipe_num = OVERLAY_PIPE_RGB1; - pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; - pipe->mixer_num = MDP4_MIXER0; - pipe->src_format = format; - mdp4_overlay_format2pipe(pipe); - - lcdc_pipe = pipe; /* keep it */ - } else { - pipe = lcdc_pipe; - } - - pipe->src_height = fbi->var.yres; - pipe->src_width = fbi->var.xres; - pipe->src_h = fbi->var.yres; - pipe->src_w = fbi->var.xres; - pipe->src_y = 0; - pipe->src_x = 0; - pipe->srcp0_addr = (uint32) buf; - pipe->srcp0_ystride = fbi->fix.line_length; - - mdp4_overlay_dmap_xy(pipe); - mdp4_overlay_dmap_cfg(mfd, 1); - - mdp4_overlay_rgb_setup(pipe); - - mdp4_mixer_stage_up(pipe); - - mdp4_overlayproc_cfg(pipe); - - /* - * LCDC timing setting - */ - h_back_porch = var->left_margin; - h_front_porch = var->right_margin; - v_back_porch = var->upper_margin; - v_front_porch = var->lower_margin; - hsync_pulse_width = var->hsync_len; - vsync_pulse_width = var->vsync_len; - lcdc_border_clr = mfd->panel_info.lcdc.border_clr; - lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr; - lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew; - - lcdc_width = mfd->panel_info.xres; - lcdc_height = mfd->panel_info.yres; - lcdc_bpp = mfd->panel_info.bpp; - - hsync_period = - hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch; - hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; - hsync_start_x = hsync_pulse_width + h_back_porch; - hsync_end_x = hsync_period - h_front_porch - 1; - display_hctl = (hsync_end_x << 16) | hsync_start_x; - - vsync_period = - (vsync_pulse_width + v_back_porch + lcdc_height + - v_front_porch) * hsync_period; - display_v_start = - (vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew; - display_v_end = - vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1; - - if (lcdc_width != var->xres) { - active_h_start = hsync_start_x + first_pixel_start_x; - active_h_end = active_h_start + var->xres - 1; - active_hctl = - ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start; - } else { - active_hctl = 0; - } - - if (lcdc_height != var->yres) { - active_v_start = - display_v_start + first_pixel_start_y * hsync_period; - active_v_end = active_v_start + (var->yres) * hsync_period - 1; - active_v_start |= ACTIVE_START_Y_EN; - } else { - active_v_start = 0; - active_v_end = 0; - } - - -#ifdef CONFIG_FB_MSM_MDP40 - hsync_polarity = 1; - vsync_polarity = 1; - lcdc_underflow_clr |= 0x80000000; /* enable recovery */ -#else - hsync_polarity = 0; - vsync_polarity = 0; -#endif - data_en_polarity = 0; - - ctrl_polarity = - (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); - - MDP_OUTP(MDP_BASE + LCDC_BASE + 0x4, hsync_ctrl); - MDP_OUTP(MDP_BASE + LCDC_BASE + 0x8, vsync_period); - MDP_OUTP(MDP_BASE + LCDC_BASE + 0xc, vsync_pulse_width * hsync_period); - MDP_OUTP(MDP_BASE + LCDC_BASE + 0x10, display_hctl); - MDP_OUTP(MDP_BASE + LCDC_BASE + 0x14, display_v_start); - MDP_OUTP(MDP_BASE + LCDC_BASE + 0x18, display_v_end); - MDP_OUTP(MDP_BASE + LCDC_BASE + 0x28, lcdc_border_clr); - MDP_OUTP(MDP_BASE + LCDC_BASE + 0x2c, lcdc_underflow_clr); - MDP_OUTP(MDP_BASE + LCDC_BASE + 0x30, lcdc_hsync_skew); - MDP_OUTP(MDP_BASE + LCDC_BASE + 0x38, ctrl_polarity); - MDP_OUTP(MDP_BASE + LCDC_BASE + 0x1c, active_hctl); - MDP_OUTP(MDP_BASE + LCDC_BASE + 0x20, active_v_start); - MDP_OUTP(MDP_BASE + LCDC_BASE + 0x24, active_v_end); - - ret = panel_next_on(pdev); - if (ret == 0) { - /* enable LCDC block */ - MDP_OUTP(MDP_BASE + LCDC_BASE, 1); - mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - } - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - - return ret; -} - -int mdp_lcdc_off(struct platform_device *pdev) -{ - int ret = 0; - struct mdp4_overlay_pipe *pipe; - - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - MDP_OUTP(MDP_BASE + LCDC_BASE, 0); - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - - ret = panel_next_off(pdev); - - /* delay to make sure the last frame finishes */ - mdelay(100); - - /* dis-engage rgb0 from mixer */ - pipe = lcdc_pipe; - mdp4_mixer_stage_down(pipe); - - return ret; -} - -/* - * mdp4_overlay0_done_lcdc: called from isr - */ -void mdp4_overlay0_done_lcdc() -{ - complete(&lcdc_pipe->comp); -} - -void mdp4_lcdc_overlay(struct msm_fb_data_type *mfd) -{ - struct fb_info *fbi = mfd->fbi; - uint8 *buf; - int bpp; - unsigned long flag; - struct mdp4_overlay_pipe *pipe; - - if (!mfd->panel_power_on) - return; - - /* no need to power on cmd block since it's lcdc mode */ - bpp = fbi->var.bits_per_pixel / 8; - buf = (uint8 *) fbi->fix.smem_start; - buf += fbi->var.xoffset * bpp + - fbi->var.yoffset * fbi->fix.line_length; - - mutex_lock(&mfd->dma->ov_mutex); - - pipe = lcdc_pipe; - pipe->srcp0_addr = (uint32) buf; - mdp4_overlay_rgb_setup(pipe); - mdp4_overlay_reg_flush(pipe, 1); /* rgb1 and mixer0 */ - - /* enable irq */ - spin_lock_irqsave(&mdp_spin_lock, flag); - mdp_enable_irq(MDP_OVERLAY0_TERM); - INIT_COMPLETION(lcdc_pipe->comp); - mfd->dma->waiting = TRUE; - outp32(MDP_INTR_CLEAR, INTR_OVERLAY0_DONE); - mdp_intr_mask |= INTR_OVERLAY0_DONE; - outp32(MDP_INTR_ENABLE, mdp_intr_mask); - spin_unlock_irqrestore(&mdp_spin_lock, flag); - wait_for_completion_killable(&lcdc_pipe->comp); - mdp_disable_irq(MDP_OVERLAY0_TERM); - - mutex_unlock(&mfd->dma->ov_mutex); -} diff --git a/drivers/staging/msm/mdp4_overlay_mddi.c b/drivers/staging/msm/mdp4_overlay_mddi.c deleted file mode 100644 index be1b2874185b..000000000000 --- a/drivers/staging/msm/mdp4_overlay_mddi.c +++ /dev/null @@ -1,254 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "mdp.h" -#include "msm_fb.h" -#include "mdp4.h" - -static struct mdp4_overlay_pipe *mddi_pipe; -static struct mdp4_overlay_pipe *pending_pipe; -static struct msm_fb_data_type *mddi_mfd; - -#define WHOLESCREEN - -void mdp4_overlay_update_lcd(struct msm_fb_data_type *mfd) -{ - MDPIBUF *iBuf = &mfd->ibuf; - uint8 *src; - int bpp, ptype; - uint32 format; - uint32 mddi_ld_param; - uint16 mddi_vdo_packet_reg; - struct mdp4_overlay_pipe *pipe; - - if (mfd->key != MFD_KEY) - return; - - mddi_mfd = mfd; /* keep it */ - - bpp = iBuf->bpp; - - if (bpp == 2) - format = MDP_RGB_565; - else if (bpp == 3) - format = MDP_RGB_888; - else - format = MDP_ARGB_8888; - - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - - if (mddi_pipe == NULL) { - ptype = mdp4_overlay_format2type(format); - pipe = mdp4_overlay_pipe_alloc(); - pipe->pipe_type = ptype; - /* use RGB1 pipe */ - pipe->pipe_num = OVERLAY_PIPE_RGB1; - pipe->mixer_num = MDP4_MIXER0; - pipe->src_format = format; - mdp4_overlay_format2pipe(pipe); - - mddi_pipe = pipe; /* keep it */ - - mddi_ld_param = 0; - mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt; - - if (mfd->panel_info.type == MDDI_PANEL) { - if (mfd->panel_info.pdest == DISPLAY_1) - mddi_ld_param = 0; - else - mddi_ld_param = 1; - } else { - mddi_ld_param = 2; - } - - MDP_OUTP(MDP_BASE + 0x00090, mddi_ld_param); - MDP_OUTP(MDP_BASE + 0x00094, - (MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg); - } else { - pipe = mddi_pipe; - } - - - src = (uint8 *) iBuf->buf; - -#ifdef WHOLESCREEN - { - struct fb_info *fbi; - - fbi = mfd->fbi; - pipe->src_height = fbi->var.yres; - pipe->src_width = fbi->var.xres; - pipe->src_h = fbi->var.yres; - pipe->src_w = fbi->var.xres; - pipe->src_y = 0; - pipe->src_x = 0; - pipe->dst_h = fbi->var.yres; - pipe->dst_w = fbi->var.xres; - pipe->dst_y = 0; - pipe->dst_x = 0; - pipe->srcp0_addr = (uint32)src; - pipe->srcp0_ystride = fbi->var.xres_virtual * bpp; - } - -#else - if (mdp4_overlay_active(MDP4_MIXER0)) { - struct fb_info *fbi; - - fbi = mfd->fbi; - pipe->src_height = fbi->var.yres; - pipe->src_width = fbi->var.xres; - pipe->src_h = fbi->var.yres; - pipe->src_w = fbi->var.xres; - pipe->src_y = 0; - pipe->src_x = 0; - pipe->dst_h = fbi->var.yres; - pipe->dst_w = fbi->var.xres; - pipe->dst_y = 0; - pipe->dst_x = 0; - pipe->srcp0_addr = (uint32) src; - pipe->srcp0_ystride = fbi->var.xres_virtual * bpp; - } else { - /* starting input address */ - src += (iBuf->dma_x + iBuf->dma_y * iBuf->ibuf_width) * bpp; - - pipe->src_height = iBuf->dma_h; - pipe->src_width = iBuf->dma_w; - pipe->src_h = iBuf->dma_h; - pipe->src_w = iBuf->dma_w; - pipe->src_y = 0; - pipe->src_x = 0; - pipe->dst_h = iBuf->dma_h; - pipe->dst_w = iBuf->dma_w; - pipe->dst_y = iBuf->dma_y; - pipe->dst_x = iBuf->dma_x; - pipe->srcp0_addr = (uint32) src; - pipe->srcp0_ystride = iBuf->ibuf_width * bpp; - } -#endif - - pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; - - mdp4_overlay_rgb_setup(pipe); - - mdp4_mixer_stage_up(pipe); - - mdp4_overlayproc_cfg(pipe); - - mdp4_overlay_dmap_xy(pipe); - - mdp4_overlay_dmap_cfg(mfd, 0); - - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - -} - -/* - * mdp4_overlay0_done_mddi: called from isr - */ -void mdp4_overlay0_done_mddi() -{ - if (pending_pipe) - complete(&pending_pipe->comp); -} - -void mdp4_mddi_overlay_restore(void) -{ - /* mutex holded by caller */ - mdp4_overlay_update_lcd(mddi_mfd); - mdp4_mddi_overlay_kickoff(mddi_mfd, mddi_pipe); -} - -void mdp4_mddi_overlay_kickoff(struct msm_fb_data_type *mfd, - struct mdp4_overlay_pipe *pipe) -{ -#ifdef MDP4_NONBLOCKING - unsigned long flag; - - spin_lock_irqsave(&mdp_spin_lock, flag); - if (mfd->dma->busy == TRUE) { - INIT_COMPLETION(pipe->comp); - pending_pipe = pipe; - } - spin_unlock_irqrestore(&mdp_spin_lock, flag); - - if (pending_pipe != NULL) { - /* wait until DMA finishes the current job */ - wait_for_completion_killable(&pipe->comp); - pending_pipe = NULL; - } - down(&mfd->sem); - mdp_enable_irq(MDP_OVERLAY0_TERM); - mfd->dma->busy = TRUE; - /* start OVERLAY pipe */ - mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd); - up(&mfd->sem); -#else - down(&mfd->sem); - mdp_enable_irq(MDP_OVERLAY0_TERM); - mfd->dma->busy = TRUE; - INIT_COMPLETION(pipe->comp); - pending_pipe = pipe; - - /* start OVERLAY pipe */ - mdp_pipe_kickoff(MDP_OVERLAY0_TERM, mfd); - up(&mfd->sem); - - /* wait until DMA finishes the current job */ - wait_for_completion_killable(&pipe->comp); - mdp_disable_irq(MDP_OVERLAY0_TERM); -#endif - -} - -void mdp4_mddi_overlay(struct msm_fb_data_type *mfd) -{ - mutex_lock(&mfd->dma->ov_mutex); - - if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) { - mdp4_overlay_update_lcd(mfd); - - mdp4_mddi_overlay_kickoff(mfd, mddi_pipe); - - /* signal if pan function is waiting for the update completion */ - if (mfd->pan_waiting) { - mfd->pan_waiting = FALSE; - complete(&mfd->pan_comp); - } - } - - mutex_unlock(&mfd->dma->ov_mutex); -} diff --git a/drivers/staging/msm/mdp4_util.c b/drivers/staging/msm/mdp4_util.c deleted file mode 100644 index fd97f5205992..000000000000 --- a/drivers/staging/msm/mdp4_util.c +++ /dev/null @@ -1,1686 +0,0 @@ - -/* 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "mdp.h" -#include "msm_fb.h" -#include "mdp4.h" - -void mdp4_sw_reset(ulong bits) -{ - bits &= 0x1f; /* 5 bits */ - outpdw(MDP_BASE + 0x001c, bits); /* MDP_SW_RESET */ - - while (inpdw(MDP_BASE + 0x001c) & bits) /* self clear when complete */ - ; - MSM_FB_INFO("mdp4_sw_reset: 0x%x\n", (int)bits); -} - -void mdp4_overlay_cfg(int overlayer, int blt_mode, int refresh, int direct_out) -{ - ulong bits = 0; - - if (blt_mode) - bits |= (1 << 3); - refresh &= 0x03; /* 2 bites */ - bits |= (refresh << 1); - direct_out &= 0x01; - bits |= direct_out; - - if (overlayer == MDP4_MIXER0) - outpdw(MDP_BASE + 0x10004, bits); /* MDP_OVERLAY0_CFG */ - else - outpdw(MDP_BASE + 0x18004, bits); /* MDP_OVERLAY1_CFG */ - - MSM_FB_INFO("mdp4_overlay_cfg: 0x%x\n", (int)inpdw(MDP_BASE + 0x10004)); -} - -void mdp4_display_intf_sel(int output, ulong intf) -{ - ulong bits, mask; - - bits = inpdw(MDP_BASE + 0x0038); /* MDP_DISP_INTF_SEL */ - - mask = 0x03; /* 2 bits */ - intf &= 0x03; /* 2 bits */ - - switch (output) { - case EXTERNAL_INTF_SEL: - intf <<= 4; - mask <<= 4; - break; - case SECONDARY_INTF_SEL: - intf &= 0x02; /* only MDDI and EBI2 support */ - intf <<= 2; - mask <<= 2; - break; - default: - break; - } - - - bits &= ~mask; - bits |= intf; - - outpdw(MDP_BASE + 0x0038, bits); /* MDP_DISP_INTF_SEL */ - - MSM_FB_INFO("mdp4_display_intf_sel: 0x%x\n", (int)inpdw(MDP_BASE + 0x0038)); -} - -unsigned long mdp4_display_status(void) -{ - return inpdw(MDP_BASE + 0x0018) & 0x3ff; /* MDP_DISPLAY_STATUS */ -} - -void mdp4_ebi2_lcd_setup(int lcd, ulong base, int ystride) -{ - /* always use memory map */ - ystride &= 0x01fff; /* 13 bits */ - if (lcd == EBI2_LCD0) { - outpdw(MDP_BASE + 0x0060, base);/* MDP_EBI2_LCD0 */ - outpdw(MDP_BASE + 0x0068, ystride);/* MDP_EBI2_LCD0_YSTRIDE */ - } else { - outpdw(MDP_BASE + 0x0064, base);/* MDP_EBI2_LCD1 */ - outpdw(MDP_BASE + 0x006c, ystride);/* MDP_EBI2_LCD1_YSTRIDE */ - } -} - -void mdp4_mddi_setup(int mddi, unsigned long id) -{ - ulong bits; - - if (mddi == MDDI_EXTERNAL_SET) - bits = 0x02; - else if (mddi == MDDI_SECONDARY_SET) - bits = 0x01; - else - bits = 0; /* PRIMARY_SET */ - - id <<= 16; - - bits |= id; - - outpdw(MDP_BASE + 0x0090, bits); /* MDP_MDDI_PARAM_WR_SEL */ -} - -int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req, - struct file **pp_src_file, struct file **pp_dst_file) -{ - - /* not implemented yet */ - return -1; -} - -void mdp4_hw_init(void) -{ - ulong bits; - - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - -#ifdef MDP4_ERROR - /* - * Issue software reset on DMA_P will casue DMA_P dma engine stall - * on LCDC mode. However DMA_P does not stall at MDDI mode. - * This need further investigation. - */ - mdp4_sw_reset(0x17); -#endif - - mdp4_clear_lcdc(); - - mdp4_mixer_blend_init(0); - mdp4_mixer_blend_init(1); - mdp4_vg_qseed_init(0); - mdp4_vg_qseed_init(1); - mdp4_vg_csc_mv_setup(0); - mdp4_vg_csc_mv_setup(1); - mdp4_vg_csc_pre_bv_setup(0); - mdp4_vg_csc_pre_bv_setup(1); - mdp4_vg_csc_post_bv_setup(0); - mdp4_vg_csc_post_bv_setup(1); - mdp4_vg_csc_pre_lv_setup(0); - mdp4_vg_csc_pre_lv_setup(1); - mdp4_vg_csc_post_lv_setup(0); - mdp4_vg_csc_post_lv_setup(1); - - mdp4_mixer_gc_lut_setup(0); - mdp4_mixer_gc_lut_setup(1); - - mdp4_vg_igc_lut_setup(0); - mdp4_vg_igc_lut_setup(1); - - mdp4_rgb_igc_lut_setup(0); - mdp4_rgb_igc_lut_setup(1); - - outp32(MDP_EBI2_PORTMAP_MODE, 0x3); - - /* system interrupts */ - - bits = mdp_intr_mask; - outpdw(MDP_BASE + 0x0050, bits);/* enable specififed interrupts */ - - /* histogram */ - MDP_OUTP(MDP_BASE + 0x95010, 1); /* auto clear HIST */ - - /* enable histogram interrupts */ - outpdw(MDP_BASE + 0x9501c, INTR_HIST_DONE); - - /* For the max read pending cmd config below, if the MDP clock */ - /* is less than the AXI clock, then we must use 3 pending */ - /* pending requests. Otherwise, we should use 8 pending requests. */ - /* In the future we should do this detection automatically. */ - - /* max read pending cmd config */ - outpdw(MDP_BASE + 0x004c, 0x02222); /* 3 pending requests */ - - /* dma_p fetch config */ - outpdw(MDP_BASE + 0x91004, 0x27); /* burst size of 8 */ - -#ifndef CONFIG_FB_MSM_OVERLAY - /* both REFRESH_MODE and DIRECT_OUT are ignored at BLT mode */ - mdp4_overlay_cfg(MDP4_MIXER0, OVERLAY_MODE_BLT, 0, 0); - mdp4_overlay_cfg(MDP4_MIXER1, OVERLAY_MODE_BLT, 0, 0); -#endif - - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); -} - - -void mdp4_clear_lcdc(void) -{ - uint32 bits; - - bits = inpdw(MDP_BASE + 0xc0000); - if (bits & 0x01) /* enabled already */ - return; - - outpdw(MDP_BASE + 0xc0004, 0); /* vsync ctrl out */ - outpdw(MDP_BASE + 0xc0008, 0); /* vsync period */ - outpdw(MDP_BASE + 0xc000c, 0); /* vsync pusle width */ - outpdw(MDP_BASE + 0xc0010, 0); /* lcdc display HCTL */ - outpdw(MDP_BASE + 0xc0014, 0); /* lcdc display v start */ - outpdw(MDP_BASE + 0xc0018, 0); /* lcdc display v end */ - outpdw(MDP_BASE + 0xc001c, 0); /* lcdc active hctl */ - outpdw(MDP_BASE + 0xc0020, 0); /* lcdc active v start */ - outpdw(MDP_BASE + 0xc0024, 0); /* lcdc active v end */ - outpdw(MDP_BASE + 0xc0028, 0); /* lcdc board color */ - outpdw(MDP_BASE + 0xc002c, 0); /* lcdc underflow ctrl */ - outpdw(MDP_BASE + 0xc0030, 0); /* lcdc hsync skew */ - outpdw(MDP_BASE + 0xc0034, 0); /* lcdc test ctl */ - outpdw(MDP_BASE + 0xc0038, 0); /* lcdc ctl polarity */ -} - -static struct mdp_dma_data overlay1_data; -static int intr_dma_p; -static int intr_dma_s; -static int intr_dma_e; -static int intr_overlay0; -static int intr_overlay1; - -irqreturn_t mdp4_isr(int irq, void *ptr) -{ - uint32 isr, mask, lcdc; - struct mdp_dma_data *dma; - - mdp_is_in_isr = TRUE; - - while (1) { - isr = inpdw(MDP_INTR_STATUS); - if (isr == 0) - break; - - mask = inpdw(MDP_INTR_ENABLE); - outpdw(MDP_INTR_CLEAR, isr); - - isr &= mask; - - if (unlikely(isr == 0)) - break; - - if (isr & INTR_DMA_P_DONE) { - intr_dma_p++; - lcdc = inpdw(MDP_BASE + 0xc0000); - dma = &dma2_data; - if (lcdc & 0x01) { /* LCDC enable */ - /* disable LCDC interrupt */ - mdp_intr_mask &= ~INTR_DMA_P_DONE; - outp32(MDP_INTR_ENABLE, mdp_intr_mask); - dma->waiting = FALSE; - } else { - dma->busy = FALSE; - mdp_pipe_ctrl(MDP_DMA2_BLOCK, - MDP_BLOCK_POWER_OFF, TRUE); - } - complete(&dma->comp); - } - if (isr & INTR_DMA_S_DONE) { - intr_dma_s++; - dma = &dma_s_data; - dma->busy = FALSE; - mdp_pipe_ctrl(MDP_DMA_S_BLOCK, - MDP_BLOCK_POWER_OFF, TRUE); - complete(&dma->comp); - } - if (isr & INTR_DMA_E_DONE) { - intr_dma_e++; - dma = &dma_e_data; - mdp_intr_mask &= ~INTR_DMA_E_DONE; - outp32(MDP_INTR_ENABLE, mdp_intr_mask); - dma->busy = FALSE; - - if (dma->waiting) { - dma->waiting = FALSE; - complete(&dma->comp); - } - } - if (isr & INTR_OVERLAY0_DONE) { - intr_overlay0++; - lcdc = inpdw(MDP_BASE + 0xc0000); - dma = &dma2_data; - if (lcdc & 0x01) { /* LCDC enable */ - /* disable LCDC interrupt */ - mdp_intr_mask &= ~INTR_OVERLAY0_DONE; - outp32(MDP_INTR_ENABLE, mdp_intr_mask); - dma->waiting = FALSE; - mdp4_overlay0_done_lcdc(); - } else { /* MDDI */ - dma->busy = FALSE; -#ifdef MDP4_NONBLOCKING - mdp_disable_irq_nolock(MDP_OVERLAY0_TERM); -#endif - mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, - MDP_BLOCK_POWER_OFF, TRUE); - mdp4_overlay0_done_mddi(); - } - } - if (isr & INTR_OVERLAY1_DONE) { - intr_overlay1++; - dma = &overlay1_data; - dma->busy = FALSE; - mdp_pipe_ctrl(MDP_OVERLAY1_BLOCK, - MDP_BLOCK_POWER_OFF, TRUE); - complete(&dma->comp); - } - if (isr & INTR_DMA_P_HISTOGRAM) { - isr = inpdw(MDP_DMA_P_HIST_INTR_STATUS); - mask = inpdw(MDP_DMA_P_HIST_INTR_ENABLE); - outpdw(MDP_DMA_P_HIST_INTR_CLEAR, isr); - isr &= mask; - if (isr & INTR_HIST_DONE) { - if (mdp_hist.r) - memcpy(mdp_hist.r, MDP_BASE + 0x95100, - mdp_hist.bin_cnt*4); - if (mdp_hist.g) - memcpy(mdp_hist.g, MDP_BASE + 0x95200, - mdp_hist.bin_cnt*4); - if (mdp_hist.b) - memcpy(mdp_hist.b, MDP_BASE + 0x95300, - mdp_hist.bin_cnt*4); - complete(&mdp_hist_comp); - } - } - } - - mdp_is_in_isr = FALSE; - - return IRQ_HANDLED; -} - - -/* - * QSEED tables - */ - -static uint32 vg_qseed_table0[] = { - 0x5556aaff, 0x00000000, 0x00000000, 0x00000000 -}; - -static uint32 vg_qseed_table1[] = { - 0x76543210, 0xfedcba98 -}; - -static uint32 vg_qseed_table2[] = { - 0x02000000, 0x00000000, 0x02060ff2, 0x00000008, - 0x02090fe4, 0x00000013, 0x020a0fd9, 0x0ffc0021, - 0x02080fce, 0x0ffa0030, 0x02030fc5, 0x0ff60042, - 0x01fd0fbe, 0x0ff10054, 0x01f50fb6, 0x0fed0068, - 0x01e90fb1, 0x0fe60080, 0x01dc0fae, 0x0fe10095, - 0x01ca0fae, 0x0fda00ae, 0x01b70fad, 0x0fd600c6, - 0x01a40fad, 0x0fcf00e0, 0x018f0faf, 0x0fc800fa, - 0x01780fb1, 0x0fc30114, 0x015f0fb5, 0x0fbf012d, - 0x01490fb7, 0x0fb70149, 0x012d0fbf, 0x0fb5015f, - 0x01140fc3, 0x0fb10178, 0x00fa0fc8, 0x0faf018f, - 0x00e00fcf, 0x0fad01a4, 0x00c60fd6, 0x0fad01b7, - 0x00ae0fda, 0x0fae01ca, 0x00950fe1, 0x0fae01dc, - 0x00800fe6, 0x0fb101e9, 0x00680fed, 0x0fb601f5, - 0x00540ff1, 0x0fbe01fd, 0x00420ff6, 0x0fc50203, - 0x00300ffa, 0x0fce0208, 0x00210ffc, 0x0fd9020a, - 0x00130000, 0x0fe40209, 0x00080000, 0x0ff20206, - 0x02000000, 0x00000000, 0x02040ff2, 0x0000000a, - 0x02040fe4, 0x00000018, 0x02010fda, 0x0ffc0029, - 0x01fc0fcf, 0x0ffa003b, 0x01f30fc7, 0x0ff60050, - 0x01e90fc0, 0x0ff20065, 0x01dc0fba, 0x0fee007c, - 0x01cc0fb6, 0x0fe80096, 0x01ba0fb4, 0x0fe400ae, - 0x01a70fb4, 0x0fdd00c8, 0x018f0fb5, 0x0fda00e2, - 0x017a0fb5, 0x0fd400fd, 0x01630fb8, 0x0fce0117, - 0x014c0fba, 0x0fca0130, 0x01320fbf, 0x0fc70148, - 0x011b0fc1, 0x0fc10163, 0x01010fc8, 0x0fc00177, - 0x00e90fcd, 0x0fbd018d, 0x00d10fd1, 0x0fbc01a2, - 0x00ba0fd7, 0x0fbb01b4, 0x00a30fdd, 0x0fbc01c4, - 0x008e0fe1, 0x0fbd01d4, 0x00790fe7, 0x0fbe01e2, - 0x00670feb, 0x0fc001ee, 0x00540ff1, 0x0fc501f6, - 0x00430ff4, 0x0fcb01fe, 0x00340ff8, 0x0fd10203, - 0x00260ffb, 0x0fd80207, 0x001a0ffd, 0x0fe10208, - 0x000f0000, 0x0fea0207, 0x00060000, 0x0ff50205, - 0x02000000, 0x00000000, 0x02020ff2, 0x0000000c, - 0x02000fe4, 0x0000001c, 0x01fa0fda, 0x0ffc0030, - 0x01f10fd0, 0x0ffa0045, 0x01e50fc8, 0x0ff6005d, - 0x01d60fc3, 0x0ff30074, 0x01c60fbd, 0x0fef008e, - 0x01b30fba, 0x0fe900aa, 0x019e0fb9, 0x0fe500c4, - 0x01870fba, 0x0fe000df, 0x016f0fbb, 0x0fdd00f9, - 0x01580fbc, 0x0fd80114, 0x01400fbf, 0x0fd3012e, - 0x01280fc2, 0x0fd00146, 0x010f0fc6, 0x0fce015d, - 0x00f90fc9, 0x0fc90175, 0x00e00fcf, 0x0fc90188, - 0x00ca0fd4, 0x0fc6019c, 0x00b40fd8, 0x0fc601ae, - 0x009f0fdd, 0x0fc501bf, 0x008b0fe3, 0x0fc601cc, - 0x00780fe6, 0x0fc701db, 0x00660feb, 0x0fc801e7, - 0x00560fef, 0x0fcb01f0, 0x00460ff3, 0x0fcf01f8, - 0x00380ff6, 0x0fd401fe, 0x002c0ff9, 0x0fd90202, - 0x00200ffc, 0x0fdf0205, 0x00160ffe, 0x0fe60206, - 0x000c0000, 0x0fed0207, 0x00050000, 0x0ff70204, - 0x02000000, 0x00000000, 0x01fe0ff3, 0x0000000f, - 0x01f60fe5, 0x00000025, 0x01ea0fdb, 0x0ffd003e, - 0x01db0fd2, 0x0ffb0058, 0x01c80fcc, 0x0ff70075, - 0x01b50fc7, 0x0ff40090, 0x01a00fc3, 0x0ff000ad, - 0x01880fc1, 0x0feb00cc, 0x01700fc1, 0x0fe800e7, - 0x01550fc3, 0x0fe40104, 0x013b0fc5, 0x0fe2011e, - 0x01240fc6, 0x0fde0138, 0x010c0fca, 0x0fda0150, - 0x00f40fcd, 0x0fd90166, 0x00dd0fd1, 0x0fd7017b, - 0x00c80fd4, 0x0fd40190, 0x00b20fd9, 0x0fd401a1, - 0x009f0fdd, 0x0fd301b1, 0x008c0fe1, 0x0fd301c0, - 0x007b0fe5, 0x0fd301cd, 0x006a0fea, 0x0fd401d8, - 0x005c0fec, 0x0fd501e3, 0x004d0ff0, 0x0fd601ed, - 0x00410ff3, 0x0fd801f4, 0x00340ff7, 0x0fdb01fa, - 0x002a0ff9, 0x0fdf01fe, 0x00200ffb, 0x0fe30202, - 0x00180ffd, 0x0fe70204, 0x00100ffe, 0x0fed0205, - 0x00090000, 0x0ff20205, 0x00040000, 0x0ff90203, - 0x02000000, 0x00000000, 0x02050ff5, 0x00000006, - 0x02070fea, 0x0000000f, 0x02080fe1, 0x0ffd001a, - 0x02070fd8, 0x0ffb0026, 0x02030fd1, 0x0ff80034, - 0x01fe0fcb, 0x0ff40043, 0x01f60fc5, 0x0ff10054, - 0x01ee0fc0, 0x0feb0067, 0x01e20fbe, 0x0fe70079, - 0x01d40fbd, 0x0fe1008e, 0x01c40fbc, 0x0fdd00a3, - 0x01b40fbb, 0x0fd700ba, 0x01a20fbc, 0x0fd100d1, - 0x018d0fbd, 0x0fcd00e9, 0x01770fc0, 0x0fc80101, - 0x01630fc1, 0x0fc1011b, 0x01480fc7, 0x0fbf0132, - 0x01300fca, 0x0fba014c, 0x01170fce, 0x0fb80163, - 0x00fd0fd4, 0x0fb5017a, 0x00e20fda, 0x0fb5018f, - 0x00c80fdd, 0x0fb401a7, 0x00ae0fe4, 0x0fb401ba, - 0x00960fe8, 0x0fb601cc, 0x007c0fee, 0x0fba01dc, - 0x00650ff2, 0x0fc001e9, 0x00500ff6, 0x0fc701f3, - 0x003b0ffa, 0x0fcf01fc, 0x00290ffc, 0x0fda0201, - 0x00180000, 0x0fe40204, 0x000a0000, 0x0ff20204, - 0x02000000, 0x00000000, 0x02030ff5, 0x00000008, - 0x02030fea, 0x00000013, 0x02020fe1, 0x0ffd0020, - 0x01fc0fd9, 0x0ffc002f, 0x01f60fd2, 0x0ff80040, - 0x01ed0fcd, 0x0ff50051, 0x01e30fc7, 0x0ff10065, - 0x01d70fc3, 0x0fec007a, 0x01c60fc2, 0x0fe9008f, - 0x01b60fc1, 0x0fe300a6, 0x01a20fc1, 0x0fe000bd, - 0x018f0fc1, 0x0fdb00d5, 0x017b0fc2, 0x0fd500ee, - 0x01640fc4, 0x0fd20106, 0x014d0fc8, 0x0fce011d, - 0x01370fc9, 0x0fc90137, 0x011d0fce, 0x0fc8014d, - 0x01060fd2, 0x0fc40164, 0x00ee0fd5, 0x0fc2017b, - 0x00d50fdb, 0x0fc1018f, 0x00bd0fe0, 0x0fc101a2, - 0x00a60fe3, 0x0fc101b6, 0x008f0fe9, 0x0fc201c6, - 0x007a0fec, 0x0fc301d7, 0x00650ff1, 0x0fc701e3, - 0x00510ff5, 0x0fcd01ed, 0x00400ff8, 0x0fd201f6, - 0x002f0ffc, 0x0fd901fc, 0x00200ffd, 0x0fe10202, - 0x00130000, 0x0fea0203, 0x00080000, 0x0ff50203, - 0x02000000, 0x00000000, 0x02020ff5, 0x00000009, - 0x01ff0fea, 0x00000017, 0x01fb0fe2, 0x0ffd0026, - 0x01f30fda, 0x0ffc0037, 0x01ea0fd3, 0x0ff8004b, - 0x01df0fce, 0x0ff5005e, 0x01d10fc9, 0x0ff20074, - 0x01c10fc6, 0x0fed008c, 0x01ae0fc5, 0x0fea00a3, - 0x019b0fc5, 0x0fe500bb, 0x01850fc6, 0x0fe200d3, - 0x01700fc6, 0x0fde00ec, 0x015a0fc8, 0x0fd90105, - 0x01430fca, 0x0fd6011d, 0x012b0fcd, 0x0fd30135, - 0x01150fcf, 0x0fcf014d, 0x00fc0fd4, 0x0fce0162, - 0x00e50fd8, 0x0fcc0177, 0x00cf0fdb, 0x0fca018c, - 0x00b80fe0, 0x0fc9019f, 0x00a20fe5, 0x0fca01af, - 0x008e0fe8, 0x0fcb01bf, 0x00790fec, 0x0fcb01d0, - 0x00670fef, 0x0fcd01dd, 0x00550ff4, 0x0fd001e7, - 0x00440ff7, 0x0fd501f0, 0x00350ffa, 0x0fda01f7, - 0x00270ffc, 0x0fdf01fe, 0x001b0ffe, 0x0fe70200, - 0x00100000, 0x0fee0202, 0x00060000, 0x0ff70203, - 0x02000000, 0x00000000, 0x01ff0ff5, 0x0000000c, - 0x01f80fea, 0x0000001e, 0x01ef0fe2, 0x0ffd0032, - 0x01e20fdb, 0x0ffc0047, 0x01d30fd5, 0x0ff9005f, - 0x01c20fd1, 0x0ff60077, 0x01b00fcd, 0x0ff30090, - 0x019b0fcb, 0x0fef00ab, 0x01850fcb, 0x0fec00c4, - 0x016e0fcc, 0x0fe800de, 0x01550fcd, 0x0fe600f8, - 0x013f0fce, 0x0fe20111, 0x01280fd0, 0x0fdf0129, - 0x01110fd2, 0x0fdd0140, 0x00f90fd6, 0x0fdb0156, - 0x00e40fd8, 0x0fd8016c, 0x00cd0fdd, 0x0fd8017e, - 0x00b80fe0, 0x0fd60192, 0x00a40fe3, 0x0fd601a3, - 0x00910fe7, 0x0fd501b3, 0x007f0feb, 0x0fd601c0, - 0x006e0fed, 0x0fd701ce, 0x005d0ff1, 0x0fd701db, - 0x004f0ff3, 0x0fd901e5, 0x00400ff7, 0x0fdc01ed, - 0x00330ff9, 0x0fe001f4, 0x00280ffb, 0x0fe301fa, - 0x001d0ffd, 0x0fe801fe, 0x00140ffe, 0x0fed0201, - 0x000c0000, 0x0ff20202, 0x00050000, 0x0ff90202, - 0x02000000, 0x00000000, 0x02040ff7, 0x00000005, - 0x02070fed, 0x0000000c, 0x02060fe6, 0x0ffe0016, - 0x02050fdf, 0x0ffc0020, 0x02020fd9, 0x0ff9002c, - 0x01fe0fd4, 0x0ff60038, 0x01f80fcf, 0x0ff30046, - 0x01f00fcb, 0x0fef0056, 0x01e70fc8, 0x0feb0066, - 0x01db0fc7, 0x0fe60078, 0x01cc0fc6, 0x0fe3008b, - 0x01bf0fc5, 0x0fdd009f, 0x01ae0fc6, 0x0fd800b4, - 0x019c0fc6, 0x0fd400ca, 0x01880fc9, 0x0fcf00e0, - 0x01750fc9, 0x0fc900f9, 0x015d0fce, 0x0fc6010f, - 0x01460fd0, 0x0fc20128, 0x012e0fd3, 0x0fbf0140, - 0x01140fd8, 0x0fbc0158, 0x00f90fdd, 0x0fbb016f, - 0x00df0fe0, 0x0fba0187, 0x00c40fe5, 0x0fb9019e, - 0x00aa0fe9, 0x0fba01b3, 0x008e0fef, 0x0fbd01c6, - 0x00740ff3, 0x0fc301d6, 0x005d0ff6, 0x0fc801e5, - 0x00450ffa, 0x0fd001f1, 0x00300ffc, 0x0fda01fa, - 0x001c0000, 0x0fe40200, 0x000c0000, 0x0ff20202, - 0x02000000, 0x00000000, 0x02030ff7, 0x00000006, - 0x02020fee, 0x00000010, 0x02000fe7, 0x0ffe001b, - 0x01fe0fdf, 0x0ffc0027, 0x01f70fda, 0x0ffa0035, - 0x01f00fd5, 0x0ff70044, 0x01e70fd0, 0x0ff40055, - 0x01dd0fcd, 0x0fef0067, 0x01d00fcb, 0x0fec0079, - 0x01bf0fcb, 0x0fe8008e, 0x01af0fca, 0x0fe500a2, - 0x019f0fc9, 0x0fe000b8, 0x018c0fca, 0x0fdb00cf, - 0x01770fcc, 0x0fd800e5, 0x01620fce, 0x0fd400fc, - 0x014d0fcf, 0x0fcf0115, 0x01350fd3, 0x0fcd012b, - 0x011d0fd6, 0x0fca0143, 0x01050fd9, 0x0fc8015a, - 0x00ec0fde, 0x0fc60170, 0x00d30fe2, 0x0fc60185, - 0x00bb0fe5, 0x0fc5019b, 0x00a30fea, 0x0fc501ae, - 0x008c0fed, 0x0fc601c1, 0x00740ff2, 0x0fc901d1, - 0x005e0ff5, 0x0fce01df, 0x004b0ff8, 0x0fd301ea, - 0x00370ffc, 0x0fda01f3, 0x00260ffd, 0x0fe201fb, - 0x00170000, 0x0fea01ff, 0x00090000, 0x0ff50202, - 0x02000000, 0x00000000, 0x02010ff7, 0x00000008, - 0x01ff0fee, 0x00000013, 0x01fb0fe7, 0x0ffe0020, - 0x01f60fe0, 0x0ffc002e, 0x01ed0fda, 0x0ffa003f, - 0x01e40fd6, 0x0ff7004f, 0x01d80fd2, 0x0ff40062, - 0x01ca0fcf, 0x0ff00077, 0x01bb0fcd, 0x0fed008b, - 0x01a90fcd, 0x0fe900a1, 0x01960fcd, 0x0fe600b7, - 0x01830fcd, 0x0fe200ce, 0x016d0fcf, 0x0fde00e6, - 0x01580fd0, 0x0fdb00fd, 0x01410fd3, 0x0fd80114, - 0x012c0fd4, 0x0fd4012c, 0x01140fd8, 0x0fd30141, - 0x00fd0fdb, 0x0fd00158, 0x00e60fde, 0x0fcf016d, - 0x00ce0fe2, 0x0fcd0183, 0x00b70fe6, 0x0fcd0196, - 0x00a10fe9, 0x0fcd01a9, 0x008b0fed, 0x0fcd01bb, - 0x00770ff0, 0x0fcf01ca, 0x00620ff4, 0x0fd201d8, - 0x004f0ff7, 0x0fd601e4, 0x003f0ffa, 0x0fda01ed, - 0x002e0ffc, 0x0fe001f6, 0x00200ffe, 0x0fe701fb, - 0x00130000, 0x0fee01ff, 0x00080000, 0x0ff70201, - 0x02000000, 0x00000000, 0x01ff0ff7, 0x0000000a, - 0x01f90fee, 0x00000019, 0x01f10fe7, 0x0ffe002a, - 0x01e60fe1, 0x0ffd003c, 0x01d90fdc, 0x0ffa0051, - 0x01cc0fd8, 0x0ff70065, 0x01bb0fd5, 0x0ff5007b, - 0x01a80fd3, 0x0ff10094, 0x01950fd2, 0x0fef00aa, - 0x01800fd2, 0x0feb00c3, 0x016a0fd3, 0x0fe900da, - 0x01540fd3, 0x0fe600f3, 0x013f0fd5, 0x0fe2010a, - 0x01280fd7, 0x0fe00121, 0x01100fda, 0x0fde0138, - 0x00fb0fdb, 0x0fdb014f, 0x00e40fdf, 0x0fdb0162, - 0x00ce0fe2, 0x0fd90177, 0x00b90fe4, 0x0fd8018b, - 0x00a50fe8, 0x0fd8019b, 0x00910fec, 0x0fd801ab, - 0x007e0fee, 0x0fd801bc, 0x006c0ff2, 0x0fd901c9, - 0x005c0ff4, 0x0fda01d6, 0x004b0ff7, 0x0fdd01e1, - 0x003c0ff9, 0x0fe001eb, 0x002f0ffb, 0x0fe401f2, - 0x00230ffd, 0x0fe801f8, 0x00180ffe, 0x0fed01fd, - 0x000e0000, 0x0ff20200, 0x00060000, 0x0ff90201, - 0x02000000, 0x00000000, 0x02030ff9, 0x00000004, - 0x02050ff2, 0x00000009, 0x02050fed, 0x0ffe0010, - 0x02040fe7, 0x0ffd0018, 0x02020fe3, 0x0ffb0020, - 0x01fe0fdf, 0x0ff9002a, 0x01fa0fdb, 0x0ff70034, - 0x01f40fd8, 0x0ff30041, 0x01ed0fd6, 0x0ff0004d, - 0x01e30fd5, 0x0fec005c, 0x01d80fd4, 0x0fea006a, - 0x01cd0fd3, 0x0fe5007b, 0x01c00fd3, 0x0fe1008c, - 0x01b10fd3, 0x0fdd009f, 0x01a10fd4, 0x0fd900b2, - 0x01900fd4, 0x0fd400c8, 0x017b0fd7, 0x0fd100dd, - 0x01660fd9, 0x0fcd00f4, 0x01500fda, 0x0fca010c, - 0x01380fde, 0x0fc60124, 0x011e0fe2, 0x0fc5013b, - 0x01040fe4, 0x0fc30155, 0x00e70fe8, 0x0fc10170, - 0x00cc0feb, 0x0fc10188, 0x00ad0ff0, 0x0fc301a0, - 0x00900ff4, 0x0fc701b5, 0x00750ff7, 0x0fcc01c8, - 0x00580ffb, 0x0fd201db, 0x003e0ffd, 0x0fdb01ea, - 0x00250000, 0x0fe501f6, 0x000f0000, 0x0ff301fe, - 0x02000000, 0x00000000, 0x02020ff9, 0x00000005, - 0x02020ff2, 0x0000000c, 0x02010fed, 0x0ffe0014, - 0x01fe0fe8, 0x0ffd001d, 0x01fa0fe3, 0x0ffb0028, - 0x01f40fe0, 0x0ff90033, 0x01ed0fdc, 0x0ff70040, - 0x01e50fd9, 0x0ff3004f, 0x01db0fd7, 0x0ff1005d, - 0x01ce0fd7, 0x0fed006e, 0x01c00fd6, 0x0feb007f, - 0x01b30fd5, 0x0fe70091, 0x01a30fd6, 0x0fe300a4, - 0x01920fd6, 0x0fe000b8, 0x017e0fd8, 0x0fdd00cd, - 0x016c0fd8, 0x0fd800e4, 0x01560fdb, 0x0fd600f9, - 0x01400fdd, 0x0fd20111, 0x01290fdf, 0x0fd00128, - 0x01110fe2, 0x0fce013f, 0x00f80fe6, 0x0fcd0155, - 0x00de0fe8, 0x0fcc016e, 0x00c40fec, 0x0fcb0185, - 0x00ab0fef, 0x0fcb019b, 0x00900ff3, 0x0fcd01b0, - 0x00770ff6, 0x0fd101c2, 0x005f0ff9, 0x0fd501d3, - 0x00470ffc, 0x0fdb01e2, 0x00320ffd, 0x0fe201ef, - 0x001e0000, 0x0fea01f8, 0x000c0000, 0x0ff501ff, - 0x02000000, 0x00000000, 0x02010ff9, 0x00000006, - 0x02000ff2, 0x0000000e, 0x01fd0fed, 0x0ffe0018, - 0x01f80fe8, 0x0ffd0023, 0x01f20fe4, 0x0ffb002f, - 0x01eb0fe0, 0x0ff9003c, 0x01e10fdd, 0x0ff7004b, - 0x01d60fda, 0x0ff4005c, 0x01c90fd9, 0x0ff2006c, - 0x01bc0fd8, 0x0fee007e, 0x01ab0fd8, 0x0fec0091, - 0x019b0fd8, 0x0fe800a5, 0x018b0fd8, 0x0fe400b9, - 0x01770fd9, 0x0fe200ce, 0x01620fdb, 0x0fdf00e4, - 0x014f0fdb, 0x0fdb00fb, 0x01380fde, 0x0fda0110, - 0x01210fe0, 0x0fd70128, 0x010a0fe2, 0x0fd5013f, - 0x00f30fe6, 0x0fd30154, 0x00da0fe9, 0x0fd3016a, - 0x00c30feb, 0x0fd20180, 0x00aa0fef, 0x0fd20195, - 0x00940ff1, 0x0fd301a8, 0x007b0ff5, 0x0fd501bb, - 0x00650ff7, 0x0fd801cc, 0x00510ffa, 0x0fdc01d9, - 0x003c0ffd, 0x0fe101e6, 0x002a0ffe, 0x0fe701f1, - 0x00190000, 0x0fee01f9, 0x000a0000, 0x0ff701ff, - 0x02000000, 0x00000000, 0x01ff0ff9, 0x00000008, - 0x01fb0ff2, 0x00000013, 0x01f50fed, 0x0ffe0020, - 0x01ed0fe8, 0x0ffd002e, 0x01e30fe4, 0x0ffb003e, - 0x01d80fe1, 0x0ff9004e, 0x01cb0fde, 0x0ff70060, - 0x01bc0fdc, 0x0ff40074, 0x01ac0fdb, 0x0ff20087, - 0x019a0fdb, 0x0fef009c, 0x01870fdb, 0x0fed00b1, - 0x01740fdb, 0x0fea00c7, 0x01600fdc, 0x0fe700dd, - 0x014b0fdd, 0x0fe500f3, 0x01350fdf, 0x0fe30109, - 0x01200fe0, 0x0fe00120, 0x01090fe3, 0x0fdf0135, - 0x00f30fe5, 0x0fdd014b, 0x00dd0fe7, 0x0fdc0160, - 0x00c70fea, 0x0fdb0174, 0x00b10fed, 0x0fdb0187, - 0x009c0fef, 0x0fdb019a, 0x00870ff2, 0x0fdb01ac, - 0x00740ff4, 0x0fdc01bc, 0x00600ff7, 0x0fde01cb, - 0x004e0ff9, 0x0fe101d8, 0x003e0ffb, 0x0fe401e3, - 0x002e0ffd, 0x0fe801ed, 0x00200ffe, 0x0fed01f5, - 0x00130000, 0x0ff201fb, 0x00080000, 0x0ff901ff, - 0x02000000, 0x00000000, 0x02060ff2, 0x00000008, - 0x02090fe4, 0x00000013, 0x020a0fd9, 0x0ffc0021, - 0x02080fce, 0x0ffa0030, 0x02030fc5, 0x0ff60042, - 0x01fd0fbe, 0x0ff10054, 0x01f50fb6, 0x0fed0068, - 0x01e90fb1, 0x0fe60080, 0x01dc0fae, 0x0fe10095, - 0x01ca0fae, 0x0fda00ae, 0x01b70fad, 0x0fd600c6, - 0x01a40fad, 0x0fcf00e0, 0x018f0faf, 0x0fc800fa, - 0x01780fb1, 0x0fc30114, 0x015f0fb5, 0x0fbf012d, - 0x01490fb7, 0x0fb70149, 0x012d0fbf, 0x0fb5015f, - 0x01140fc3, 0x0fb10178, 0x00fa0fc8, 0x0faf018f, - 0x00e00fcf, 0x0fad01a4, 0x00c60fd6, 0x0fad01b7, - 0x00ae0fda, 0x0fae01ca, 0x00950fe1, 0x0fae01dc, - 0x00800fe6, 0x0fb101e9, 0x00680fed, 0x0fb601f5, - 0x00540ff1, 0x0fbe01fd, 0x00420ff6, 0x0fc50203, - 0x00300ffa, 0x0fce0208, 0x00210ffc, 0x0fd9020a, - 0x00130000, 0x0fe40209, 0x00080000, 0x0ff20206, - 0x02000000, 0x00000000, 0x02040ff2, 0x0000000a, - 0x02040fe4, 0x00000018, 0x02010fda, 0x0ffc0029, - 0x01fc0fcf, 0x0ffa003b, 0x01f30fc7, 0x0ff60050, - 0x01e90fc0, 0x0ff20065, 0x01dc0fba, 0x0fee007c, - 0x01cc0fb6, 0x0fe80096, 0x01ba0fb4, 0x0fe400ae, - 0x01a70fb4, 0x0fdd00c8, 0x018f0fb5, 0x0fda00e2, - 0x017a0fb5, 0x0fd400fd, 0x01630fb8, 0x0fce0117, - 0x014c0fba, 0x0fca0130, 0x01320fbf, 0x0fc70148, - 0x011b0fc1, 0x0fc10163, 0x01010fc8, 0x0fc00177, - 0x00e90fcd, 0x0fbd018d, 0x00d10fd1, 0x0fbc01a2, - 0x00ba0fd7, 0x0fbb01b4, 0x00a30fdd, 0x0fbc01c4, - 0x008e0fe1, 0x0fbd01d4, 0x00790fe7, 0x0fbe01e2, - 0x00670feb, 0x0fc001ee, 0x00540ff1, 0x0fc501f6, - 0x00430ff4, 0x0fcb01fe, 0x00340ff8, 0x0fd10203, - 0x00260ffb, 0x0fd80207, 0x001a0ffd, 0x0fe10208, - 0x000f0000, 0x0fea0207, 0x00060000, 0x0ff50205, - 0x02000000, 0x00000000, 0x02020ff2, 0x0000000c, - 0x02000fe4, 0x0000001c, 0x01fa0fda, 0x0ffc0030, - 0x01f10fd0, 0x0ffa0045, 0x01e50fc8, 0x0ff6005d, - 0x01d60fc3, 0x0ff30074, 0x01c60fbd, 0x0fef008e, - 0x01b30fba, 0x0fe900aa, 0x019e0fb9, 0x0fe500c4, - 0x01870fba, 0x0fe000df, 0x016f0fbb, 0x0fdd00f9, - 0x01580fbc, 0x0fd80114, 0x01400fbf, 0x0fd3012e, - 0x01280fc2, 0x0fd00146, 0x010f0fc6, 0x0fce015d, - 0x00f90fc9, 0x0fc90175, 0x00e00fcf, 0x0fc90188, - 0x00ca0fd4, 0x0fc6019c, 0x00b40fd8, 0x0fc601ae, - 0x009f0fdd, 0x0fc501bf, 0x008b0fe3, 0x0fc601cc, - 0x00780fe6, 0x0fc701db, 0x00660feb, 0x0fc801e7, - 0x00560fef, 0x0fcb01f0, 0x00460ff3, 0x0fcf01f8, - 0x00380ff6, 0x0fd401fe, 0x002c0ff9, 0x0fd90202, - 0x00200ffc, 0x0fdf0205, 0x00160ffe, 0x0fe60206, - 0x000c0000, 0x0fed0207, 0x00050000, 0x0ff70204, - 0x02000000, 0x00000000, 0x01fe0ff3, 0x0000000f, - 0x01f60fe5, 0x00000025, 0x01ea0fdb, 0x0ffd003e, - 0x01db0fd2, 0x0ffb0058, 0x01c80fcc, 0x0ff70075, - 0x01b50fc7, 0x0ff40090, 0x01a00fc3, 0x0ff000ad, - 0x01880fc1, 0x0feb00cc, 0x01700fc1, 0x0fe800e7, - 0x01550fc3, 0x0fe40104, 0x013b0fc5, 0x0fe2011e, - 0x01240fc6, 0x0fde0138, 0x010c0fca, 0x0fda0150, - 0x00f40fcd, 0x0fd90166, 0x00dd0fd1, 0x0fd7017b, - 0x00c80fd4, 0x0fd40190, 0x00b20fd9, 0x0fd401a1, - 0x009f0fdd, 0x0fd301b1, 0x008c0fe1, 0x0fd301c0, - 0x007b0fe5, 0x0fd301cd, 0x006a0fea, 0x0fd401d8, - 0x005c0fec, 0x0fd501e3, 0x004d0ff0, 0x0fd601ed, - 0x00410ff3, 0x0fd801f4, 0x00340ff7, 0x0fdb01fa, - 0x002a0ff9, 0x0fdf01fe, 0x00200ffb, 0x0fe30202, - 0x00180ffd, 0x0fe70204, 0x00100ffe, 0x0fed0205, - 0x00090000, 0x0ff20205, 0x00040000, 0x0ff90203, - 0x02000000, 0x00000000, 0x02050ff5, 0x00000006, - 0x02070fea, 0x0000000f, 0x02080fe1, 0x0ffd001a, - 0x02070fd8, 0x0ffb0026, 0x02030fd1, 0x0ff80034, - 0x01fe0fcb, 0x0ff40043, 0x01f60fc5, 0x0ff10054, - 0x01ee0fc0, 0x0feb0067, 0x01e20fbe, 0x0fe70079, - 0x01d40fbd, 0x0fe1008e, 0x01c40fbc, 0x0fdd00a3, - 0x01b40fbb, 0x0fd700ba, 0x01a20fbc, 0x0fd100d1, - 0x018d0fbd, 0x0fcd00e9, 0x01770fc0, 0x0fc80101, - 0x01630fc1, 0x0fc1011b, 0x01480fc7, 0x0fbf0132, - 0x01300fca, 0x0fba014c, 0x01170fce, 0x0fb80163, - 0x00fd0fd4, 0x0fb5017a, 0x00e20fda, 0x0fb5018f, - 0x00c80fdd, 0x0fb401a7, 0x00ae0fe4, 0x0fb401ba, - 0x00960fe8, 0x0fb601cc, 0x007c0fee, 0x0fba01dc, - 0x00650ff2, 0x0fc001e9, 0x00500ff6, 0x0fc701f3, - 0x003b0ffa, 0x0fcf01fc, 0x00290ffc, 0x0fda0201, - 0x00180000, 0x0fe40204, 0x000a0000, 0x0ff20204, - 0x02000000, 0x00000000, 0x02030ff5, 0x00000008, - 0x02030fea, 0x00000013, 0x02020fe1, 0x0ffd0020, - 0x01fc0fd9, 0x0ffc002f, 0x01f60fd2, 0x0ff80040, - 0x01ed0fcd, 0x0ff50051, 0x01e30fc7, 0x0ff10065, - 0x01d70fc3, 0x0fec007a, 0x01c60fc2, 0x0fe9008f, - 0x01b60fc1, 0x0fe300a6, 0x01a20fc1, 0x0fe000bd, - 0x018f0fc1, 0x0fdb00d5, 0x017b0fc2, 0x0fd500ee, - 0x01640fc4, 0x0fd20106, 0x014d0fc8, 0x0fce011d, - 0x01370fc9, 0x0fc90137, 0x011d0fce, 0x0fc8014d, - 0x01060fd2, 0x0fc40164, 0x00ee0fd5, 0x0fc2017b, - 0x00d50fdb, 0x0fc1018f, 0x00bd0fe0, 0x0fc101a2, - 0x00a60fe3, 0x0fc101b6, 0x008f0fe9, 0x0fc201c6, - 0x007a0fec, 0x0fc301d7, 0x00650ff1, 0x0fc701e3, - 0x00510ff5, 0x0fcd01ed, 0x00400ff8, 0x0fd201f6, - 0x002f0ffc, 0x0fd901fc, 0x00200ffd, 0x0fe10202, - 0x00130000, 0x0fea0203, 0x00080000, 0x0ff50203, - 0x02000000, 0x00000000, 0x02020ff5, 0x00000009, - 0x01ff0fea, 0x00000017, 0x01fb0fe2, 0x0ffd0026, - 0x01f30fda, 0x0ffc0037, 0x01ea0fd3, 0x0ff8004b, - 0x01df0fce, 0x0ff5005e, 0x01d10fc9, 0x0ff20074, - 0x01c10fc6, 0x0fed008c, 0x01ae0fc5, 0x0fea00a3, - 0x019b0fc5, 0x0fe500bb, 0x01850fc6, 0x0fe200d3, - 0x01700fc6, 0x0fde00ec, 0x015a0fc8, 0x0fd90105, - 0x01430fca, 0x0fd6011d, 0x012b0fcd, 0x0fd30135, - 0x01150fcf, 0x0fcf014d, 0x00fc0fd4, 0x0fce0162, - 0x00e50fd8, 0x0fcc0177, 0x00cf0fdb, 0x0fca018c, - 0x00b80fe0, 0x0fc9019f, 0x00a20fe5, 0x0fca01af, - 0x008e0fe8, 0x0fcb01bf, 0x00790fec, 0x0fcb01d0, - 0x00670fef, 0x0fcd01dd, 0x00550ff4, 0x0fd001e7, - 0x00440ff7, 0x0fd501f0, 0x00350ffa, 0x0fda01f7, - 0x00270ffc, 0x0fdf01fe, 0x001b0ffe, 0x0fe70200, - 0x00100000, 0x0fee0202, 0x00060000, 0x0ff70203, - 0x02000000, 0x00000000, 0x01ff0ff5, 0x0000000c, - 0x01f80fea, 0x0000001e, 0x01ef0fe2, 0x0ffd0032, - 0x01e20fdb, 0x0ffc0047, 0x01d30fd5, 0x0ff9005f, - 0x01c20fd1, 0x0ff60077, 0x01b00fcd, 0x0ff30090, - 0x019b0fcb, 0x0fef00ab, 0x01850fcb, 0x0fec00c4, - 0x016e0fcc, 0x0fe800de, 0x01550fcd, 0x0fe600f8, - 0x013f0fce, 0x0fe20111, 0x01280fd0, 0x0fdf0129, - 0x01110fd2, 0x0fdd0140, 0x00f90fd6, 0x0fdb0156, - 0x00e40fd8, 0x0fd8016c, 0x00cd0fdd, 0x0fd8017e, - 0x00b80fe0, 0x0fd60192, 0x00a40fe3, 0x0fd601a3, - 0x00910fe7, 0x0fd501b3, 0x007f0feb, 0x0fd601c0, - 0x006e0fed, 0x0fd701ce, 0x005d0ff1, 0x0fd701db, - 0x004f0ff3, 0x0fd901e5, 0x00400ff7, 0x0fdc01ed, - 0x00330ff9, 0x0fe001f4, 0x00280ffb, 0x0fe301fa, - 0x001d0ffd, 0x0fe801fe, 0x00140ffe, 0x0fed0201, - 0x000c0000, 0x0ff20202, 0x00050000, 0x0ff90202, - 0x02000000, 0x00000000, 0x02040ff7, 0x00000005, - 0x02070fed, 0x0000000c, 0x02060fe6, 0x0ffe0016, - 0x02050fdf, 0x0ffc0020, 0x02020fd9, 0x0ff9002c, - 0x01fe0fd4, 0x0ff60038, 0x01f80fcf, 0x0ff30046, - 0x01f00fcb, 0x0fef0056, 0x01e70fc8, 0x0feb0066, - 0x01db0fc7, 0x0fe60078, 0x01cc0fc6, 0x0fe3008b, - 0x01bf0fc5, 0x0fdd009f, 0x01ae0fc6, 0x0fd800b4, - 0x019c0fc6, 0x0fd400ca, 0x01880fc9, 0x0fcf00e0, - 0x01750fc9, 0x0fc900f9, 0x015d0fce, 0x0fc6010f, - 0x01460fd0, 0x0fc20128, 0x012e0fd3, 0x0fbf0140, - 0x01140fd8, 0x0fbc0158, 0x00f90fdd, 0x0fbb016f, - 0x00df0fe0, 0x0fba0187, 0x00c40fe5, 0x0fb9019e, - 0x00aa0fe9, 0x0fba01b3, 0x008e0fef, 0x0fbd01c6, - 0x00740ff3, 0x0fc301d6, 0x005d0ff6, 0x0fc801e5, - 0x00450ffa, 0x0fd001f1, 0x00300ffc, 0x0fda01fa, - 0x001c0000, 0x0fe40200, 0x000c0000, 0x0ff20202, - 0x02000000, 0x00000000, 0x02030ff7, 0x00000006, - 0x02020fee, 0x00000010, 0x02000fe7, 0x0ffe001b, - 0x01fe0fdf, 0x0ffc0027, 0x01f70fda, 0x0ffa0035, - 0x01f00fd5, 0x0ff70044, 0x01e70fd0, 0x0ff40055, - 0x01dd0fcd, 0x0fef0067, 0x01d00fcb, 0x0fec0079, - 0x01bf0fcb, 0x0fe8008e, 0x01af0fca, 0x0fe500a2, - 0x019f0fc9, 0x0fe000b8, 0x018c0fca, 0x0fdb00cf, - 0x01770fcc, 0x0fd800e5, 0x01620fce, 0x0fd400fc, - 0x014d0fcf, 0x0fcf0115, 0x01350fd3, 0x0fcd012b, - 0x011d0fd6, 0x0fca0143, 0x01050fd9, 0x0fc8015a, - 0x00ec0fde, 0x0fc60170, 0x00d30fe2, 0x0fc60185, - 0x00bb0fe5, 0x0fc5019b, 0x00a30fea, 0x0fc501ae, - 0x008c0fed, 0x0fc601c1, 0x00740ff2, 0x0fc901d1, - 0x005e0ff5, 0x0fce01df, 0x004b0ff8, 0x0fd301ea, - 0x00370ffc, 0x0fda01f3, 0x00260ffd, 0x0fe201fb, - 0x00170000, 0x0fea01ff, 0x00090000, 0x0ff50202, - 0x02000000, 0x00000000, 0x02010ff7, 0x00000008, - 0x01ff0fee, 0x00000013, 0x01fb0fe7, 0x0ffe0020, - 0x01f60fe0, 0x0ffc002e, 0x01ed0fda, 0x0ffa003f, - 0x01e40fd6, 0x0ff7004f, 0x01d80fd2, 0x0ff40062, - 0x01ca0fcf, 0x0ff00077, 0x01bb0fcd, 0x0fed008b, - 0x01a90fcd, 0x0fe900a1, 0x01960fcd, 0x0fe600b7, - 0x01830fcd, 0x0fe200ce, 0x016d0fcf, 0x0fde00e6, - 0x01580fd0, 0x0fdb00fd, 0x01410fd3, 0x0fd80114, - 0x012c0fd4, 0x0fd4012c, 0x01140fd8, 0x0fd30141, - 0x00fd0fdb, 0x0fd00158, 0x00e60fde, 0x0fcf016d, - 0x00ce0fe2, 0x0fcd0183, 0x00b70fe6, 0x0fcd0196, - 0x00a10fe9, 0x0fcd01a9, 0x008b0fed, 0x0fcd01bb, - 0x00770ff0, 0x0fcf01ca, 0x00620ff4, 0x0fd201d8, - 0x004f0ff7, 0x0fd601e4, 0x003f0ffa, 0x0fda01ed, - 0x002e0ffc, 0x0fe001f6, 0x00200ffe, 0x0fe701fb, - 0x00130000, 0x0fee01ff, 0x00080000, 0x0ff70201, - 0x02000000, 0x00000000, 0x01ff0ff7, 0x0000000a, - 0x01f90fee, 0x00000019, 0x01f10fe7, 0x0ffe002a, - 0x01e60fe1, 0x0ffd003c, 0x01d90fdc, 0x0ffa0051, - 0x01cc0fd8, 0x0ff70065, 0x01bb0fd5, 0x0ff5007b, - 0x01a80fd3, 0x0ff10094, 0x01950fd2, 0x0fef00aa, - 0x01800fd2, 0x0feb00c3, 0x016a0fd3, 0x0fe900da, - 0x01540fd3, 0x0fe600f3, 0x013f0fd5, 0x0fe2010a, - 0x01280fd7, 0x0fe00121, 0x01100fda, 0x0fde0138, - 0x00fb0fdb, 0x0fdb014f, 0x00e40fdf, 0x0fdb0162, - 0x00ce0fe2, 0x0fd90177, 0x00b90fe4, 0x0fd8018b, - 0x00a50fe8, 0x0fd8019b, 0x00910fec, 0x0fd801ab, - 0x007e0fee, 0x0fd801bc, 0x006c0ff2, 0x0fd901c9, - 0x005c0ff4, 0x0fda01d6, 0x004b0ff7, 0x0fdd01e1, - 0x003c0ff9, 0x0fe001eb, 0x002f0ffb, 0x0fe401f2, - 0x00230ffd, 0x0fe801f8, 0x00180ffe, 0x0fed01fd, - 0x000e0000, 0x0ff20200, 0x00060000, 0x0ff90201, - 0x02000000, 0x00000000, 0x02030ff9, 0x00000004, - 0x02050ff2, 0x00000009, 0x02050fed, 0x0ffe0010, - 0x02040fe7, 0x0ffd0018, 0x02020fe3, 0x0ffb0020, - 0x01fe0fdf, 0x0ff9002a, 0x01fa0fdb, 0x0ff70034, - 0x01f40fd8, 0x0ff30041, 0x01ed0fd6, 0x0ff0004d, - 0x01e30fd5, 0x0fec005c, 0x01d80fd4, 0x0fea006a, - 0x01cd0fd3, 0x0fe5007b, 0x01c00fd3, 0x0fe1008c, - 0x01b10fd3, 0x0fdd009f, 0x01a10fd4, 0x0fd900b2, - 0x01900fd4, 0x0fd400c8, 0x017b0fd7, 0x0fd100dd, - 0x01660fd9, 0x0fcd00f4, 0x01500fda, 0x0fca010c, - 0x01380fde, 0x0fc60124, 0x011e0fe2, 0x0fc5013b, - 0x01040fe4, 0x0fc30155, 0x00e70fe8, 0x0fc10170, - 0x00cc0feb, 0x0fc10188, 0x00ad0ff0, 0x0fc301a0, - 0x00900ff4, 0x0fc701b5, 0x00750ff7, 0x0fcc01c8, - 0x00580ffb, 0x0fd201db, 0x003e0ffd, 0x0fdb01ea, - 0x00250000, 0x0fe501f6, 0x000f0000, 0x0ff301fe, - 0x02000000, 0x00000000, 0x02020ff9, 0x00000005, - 0x02020ff2, 0x0000000c, 0x02010fed, 0x0ffe0014, - 0x01fe0fe8, 0x0ffd001d, 0x01fa0fe3, 0x0ffb0028, - 0x01f40fe0, 0x0ff90033, 0x01ed0fdc, 0x0ff70040, - 0x01e50fd9, 0x0ff3004f, 0x01db0fd7, 0x0ff1005d, - 0x01ce0fd7, 0x0fed006e, 0x01c00fd6, 0x0feb007f, - 0x01b30fd5, 0x0fe70091, 0x01a30fd6, 0x0fe300a4, - 0x01920fd6, 0x0fe000b8, 0x017e0fd8, 0x0fdd00cd, - 0x016c0fd8, 0x0fd800e4, 0x01560fdb, 0x0fd600f9, - 0x01400fdd, 0x0fd20111, 0x01290fdf, 0x0fd00128, - 0x01110fe2, 0x0fce013f, 0x00f80fe6, 0x0fcd0155, - 0x00de0fe8, 0x0fcc016e, 0x00c40fec, 0x0fcb0185, - 0x00ab0fef, 0x0fcb019b, 0x00900ff3, 0x0fcd01b0, - 0x00770ff6, 0x0fd101c2, 0x005f0ff9, 0x0fd501d3, - 0x00470ffc, 0x0fdb01e2, 0x00320ffd, 0x0fe201ef, - 0x001e0000, 0x0fea01f8, 0x000c0000, 0x0ff501ff, - 0x02000000, 0x00000000, 0x02010ff9, 0x00000006, - 0x02000ff2, 0x0000000e, 0x01fd0fed, 0x0ffe0018, - 0x01f80fe8, 0x0ffd0023, 0x01f20fe4, 0x0ffb002f, - 0x01eb0fe0, 0x0ff9003c, 0x01e10fdd, 0x0ff7004b, - 0x01d60fda, 0x0ff4005c, 0x01c90fd9, 0x0ff2006c, - 0x01bc0fd8, 0x0fee007e, 0x01ab0fd8, 0x0fec0091, - 0x019b0fd8, 0x0fe800a5, 0x018b0fd8, 0x0fe400b9, - 0x01770fd9, 0x0fe200ce, 0x01620fdb, 0x0fdf00e4, - 0x014f0fdb, 0x0fdb00fb, 0x01380fde, 0x0fda0110, - 0x01210fe0, 0x0fd70128, 0x010a0fe2, 0x0fd5013f, - 0x00f30fe6, 0x0fd30154, 0x00da0fe9, 0x0fd3016a, - 0x00c30feb, 0x0fd20180, 0x00aa0fef, 0x0fd20195, - 0x00940ff1, 0x0fd301a8, 0x007b0ff5, 0x0fd501bb, - 0x00650ff7, 0x0fd801cc, 0x00510ffa, 0x0fdc01d9, - 0x003c0ffd, 0x0fe101e6, 0x002a0ffe, 0x0fe701f1, - 0x00190000, 0x0fee01f9, 0x000a0000, 0x0ff701ff, - 0x02000000, 0x00000000, 0x01ff0ff9, 0x00000008, - 0x01fb0ff2, 0x00000013, 0x01f50fed, 0x0ffe0020, - 0x01ed0fe8, 0x0ffd002e, 0x01e30fe4, 0x0ffb003e, - 0x01d80fe1, 0x0ff9004e, 0x01cb0fde, 0x0ff70060, - 0x01bc0fdc, 0x0ff40074, 0x01ac0fdb, 0x0ff20087, - 0x019a0fdb, 0x0fef009c, 0x01870fdb, 0x0fed00b1, - 0x01740fdb, 0x0fea00c7, 0x01600fdc, 0x0fe700dd, - 0x014b0fdd, 0x0fe500f3, 0x01350fdf, 0x0fe30109, - 0x01200fe0, 0x0fe00120, 0x01090fe3, 0x0fdf0135, - 0x00f30fe5, 0x0fdd014b, 0x00dd0fe7, 0x0fdc0160, - 0x00c70fea, 0x0fdb0174, 0x00b10fed, 0x0fdb0187, - 0x009c0fef, 0x0fdb019a, 0x00870ff2, 0x0fdb01ac, - 0x00740ff4, 0x0fdc01bc, 0x00600ff7, 0x0fde01cb, - 0x004e0ff9, 0x0fe101d8, 0x003e0ffb, 0x0fe401e3, - 0x002e0ffd, 0x0fe801ed, 0x00200ffe, 0x0fed01f5, - 0x00130000, 0x0ff201fb, 0x00080000, 0x0ff901ff -}; - - -#define MDP4_QSEED_TABLE0_OFF 0x8100 -#define MDP4_QSEED_TABLE1_OFF 0x8200 -#define MDP4_QSEED_TABLE2_OFF 0x9000 - -void mdp4_vg_qseed_init(int vp_num) -{ - uint32 *off; - int i, voff; - - voff = MDP4_VIDEO_OFF * vp_num; - off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff + - MDP4_QSEED_TABLE0_OFF); - for (i = 0; i < (sizeof(vg_qseed_table0) / sizeof(uint32)); i++) { - outpdw(off, vg_qseed_table0[i]); - off++; - } - - off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff + - MDP4_QSEED_TABLE1_OFF); - for (i = 0; i < (sizeof(vg_qseed_table1) / sizeof(uint32)); i++) { - outpdw(off, vg_qseed_table1[i]); - off++; - } - - off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff + - MDP4_QSEED_TABLE2_OFF); - for (i = 0; i < (sizeof(vg_qseed_table2) / sizeof(uint32)); i++) { - outpdw(off, vg_qseed_table2[i]); - off++; - } - -} - -void mdp4_mixer_blend_init(mixer_num) -{ - unsigned char *overlay_base; - int off; - - if (mixer_num) /* mixer number, /dev/fb0, /dev/fb1 */ - overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */ - else - overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */ - - /* stage 0 to stage 2 */ - off = 0; - outpdw(overlay_base + off + 0x104, 0x010); - outpdw(overlay_base + off + 0x108, 0xff);/* FG */ - outpdw(overlay_base + off + 0x10c, 0x00);/* BG */ - - off += 0x20; - outpdw(overlay_base + off + 0x104, 0x010); - outpdw(overlay_base + off + 0x108, 0xff);/* FG */ - outpdw(overlay_base + off + 0x10c, 0x00);/* BG */ - - off += 0x20; - outpdw(overlay_base + off + 0x104, 0x010); - outpdw(overlay_base + off + 0x108, 0xff);/* FG */ - outpdw(overlay_base + off + 0x10c, 0x00);/* BG */ -} - - -static uint32 csc_matrix_tab[9] = { - 0x0254, 0x0000, 0x0331, - 0x0254, 0xff37, 0xfe60, - 0x0254, 0x0409, 0x0000 -}; - -static uint32 csc_pre_bv_tab[3] = {0xfff0, 0xff80, 0xff80 }; -static uint32 csc_post_bv_tab[3] = {0, 0, 0 }; - -static uint32 csc_pre_lv_tab[6] = {0, 0xff, 0, 0xff, 0, 0xff }; -static uint32 csc_post_lv_tab[6] = {0, 0xff, 0, 0xff, 0, 0xff }; - -#define MDP4_CSC_MV_OFF 0x4400 -#define MDP4_CSC_PRE_BV_OFF 0x4500 -#define MDP4_CSC_POST_BV_OFF 0x4580 -#define MDP4_CSC_PRE_LV_OFF 0x4600 -#define MDP4_CSC_POST_LV_OFF 0x4680 - -void mdp4_vg_csc_mv_setup(int vp_num) -{ - uint32 *off; - int i, voff; - - voff = MDP4_VIDEO_OFF * vp_num; - off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff + - MDP4_CSC_MV_OFF); - for (i = 0; i < 9; i++) { - outpdw(off, csc_matrix_tab[i]); - off++; - } -} - -void mdp4_vg_csc_pre_bv_setup(int vp_num) -{ - uint32 *off; - int i, voff; - - voff = MDP4_VIDEO_OFF * vp_num; - off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff + - MDP4_CSC_PRE_BV_OFF); - for (i = 0; i < 3; i++) { - outpdw(off, csc_pre_bv_tab[i]); - off++; - } -} - -void mdp4_vg_csc_post_bv_setup(int vp_num) -{ - uint32 *off; - int i, voff; - - voff = MDP4_VIDEO_OFF * vp_num; - off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff + - MDP4_CSC_POST_BV_OFF); - for (i = 0; i < 3; i++) { - outpdw(off, csc_post_bv_tab[i]); - off++; - } -} - -void mdp4_vg_csc_pre_lv_setup(int vp_num) -{ - uint32 *off; - int i, voff; - - voff = MDP4_VIDEO_OFF * vp_num; - off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff + - MDP4_CSC_PRE_LV_OFF); - - for (i = 0; i < 6; i++) { - outpdw(off, csc_pre_lv_tab[i]); - off++; - } -} - -void mdp4_vg_csc_post_lv_setup(int vp_num) -{ - uint32 *off; - int i, voff; - - voff = MDP4_VIDEO_OFF * vp_num; - off = (uint32 *)(MDP_BASE + MDP4_VIDEO_BASE + voff + - MDP4_CSC_POST_LV_OFF); - - for (i = 0; i < 6; i++) { - outpdw(off, csc_post_lv_tab[i]); - off++; - } -} - -char gc_lut[] = { - 0x0, 0x1, 0x2, 0x2, 0x3, 0x4, 0x5, 0x6, - 0x6, 0x7, 0x8, 0x9, 0xA, 0xA, 0xB, 0xC, - 0xD, 0xD, 0xE, 0xF, 0xF, 0x10, 0x10, 0x11, - 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, - 0x16, 0x16, 0x17, 0x17, 0x17, 0x18, 0x18, 0x19, - 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1C, - 0x1C, 0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, 0x1F, - 0x1F, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, - 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, - 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26, - 0x26, 0x26, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28, - 0x28, 0x29, 0x29, 0x29, 0x29, 0x2A, 0x2A, 0x2A, - 0x2A, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2C, 0x2C, - 0x2C, 0x2C, 0x2D, 0x2D, 0x2D, 0x2D, 0x2E, 0x2E, - 0x2E, 0x2E, 0x2E, 0x2F, 0x2F, 0x2F, 0x2F, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31, - 0x31, 0x32, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, - 0x33, 0x33, 0x33, 0x34, 0x34, 0x34, 0x34, 0x34, - 0x35, 0x35, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, - 0x38, 0x38, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39, - 0x39, 0x39, 0x39, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, - 0x3A, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3C, - 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3D, 0x3D, 0x3D, - 0x3D, 0x3D, 0x3D, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, - 0x3E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, - 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, - 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x43, 0x43, - 0x43, 0x43, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, - 0x44, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, - 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x47, - 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x48, 0x48, - 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x49, 0x49, - 0x49, 0x49, 0x49, 0x49, 0x49, 0x4A, 0x4A, 0x4A, - 0x4A, 0x4A, 0x4A, 0x4A, 0x4A, 0x4B, 0x4B, 0x4B, - 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4C, 0x4C, 0x4C, - 0x4C, 0x4C, 0x4C, 0x4C, 0x4D, 0x4D, 0x4D, 0x4D, - 0x4D, 0x4D, 0x4D, 0x4D, 0x4E, 0x4E, 0x4E, 0x4E, - 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4F, 0x4F, 0x4F, - 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x50, 0x50, 0x50, - 0x50, 0x50, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51, - 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52, - 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x53, 0x53, - 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x54, - 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x58, 0x58, - 0x58, 0x58, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, - 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x5A, 0x5A, - 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, - 0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B, - 0x5B, 0x5B, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, - 0x5C, 0x5C, 0x5C, 0x5C, 0x5D, 0x5D, 0x5D, 0x5D, - 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5D, 0x5E, 0x5E, - 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, - 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, - 0x5F, 0x5F, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, - 0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, - 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x62, - 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, - 0x62, 0x62, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x64, 0x64, 0x64, - 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, - 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, - 0x65, 0x65, 0x65, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x67, - 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, - 0x67, 0x67, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, - 0x68, 0x68, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, - 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, - 0x69, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, - 0x6A, 0x6A, 0x6A, 0x6A, 0x6A, 0x6B, 0x6B, 0x6B, - 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, 0x6B, - 0x6B, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, - 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6D, 0x6D, 0x6D, - 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, 0x6D, - 0x6D, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, - 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6F, 0x6F, 0x6F, - 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, - 0x6F, 0x6F, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x71, 0x71, - 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, - 0x71, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, 0x72, - 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, - 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, - 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, - 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, - 0x74, 0x74, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, - 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, - 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, 0x76, - 0x76, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, - 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, - 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x78, 0x78, - 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, - 0x78, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, - 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7A, 0x7A, - 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, - 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, - 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, - 0x7B, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, - 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, - 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, - 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, - 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, - 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x81, - 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, - 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x82, 0x82, - 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, - 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, - 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, - 0x83, 0x83, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, - 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, - 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, - 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, - 0x85, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, - 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, - 0x86, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, - 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, - 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, - 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, - 0x88, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, - 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, - 0x89, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, - 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, 0x8A, - 0x8A, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, - 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, - 0x8B, 0x8B, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, - 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, 0x8C, - 0x8C, 0x8C, 0x8C, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, - 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, 0x8D, - 0x8D, 0x8D, 0x8D, 0x8D, 0x8E, 0x8E, 0x8E, 0x8E, - 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, - 0x8E, 0x8E, 0x8E, 0x8E, 0x8E, 0x8F, 0x8F, 0x8F, - 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, - 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x91, - 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, - 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, - 0x91, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, - 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, - 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, - 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, - 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x95, 0x95, - 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, - 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, - 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, - 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, - 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x97, 0x97, - 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, - 0x97, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, - 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, - 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, - 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, - 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, - 0x99, 0x99, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, - 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, - 0x9A, 0x9A, 0x9A, 0x9A, 0x9A, 0x9B, 0x9B, 0x9B, - 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, - 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, - 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, - 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, - 0x9C, 0x9C, 0x9C, 0x9C, 0x9D, 0x9D, 0x9D, 0x9D, - 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, - 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9E, - 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, - 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, 0x9E, - 0x9E, 0x9E, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, - 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, - 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0x9F, 0xA0, 0xA0, - 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, - 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, - 0xA0, 0xA0, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, - 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, - 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA2, 0xA2, - 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, - 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, 0xA2, - 0xA2, 0xA2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, - 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, - 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA4, 0xA4, - 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, - 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, 0xA4, - 0xA4, 0xA4, 0xA4, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, - 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, - 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, - 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, - 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, - 0xA6, 0xA6, 0xA6, 0xA6, 0xA7, 0xA7, 0xA7, 0xA7, - 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, - 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, 0xA7, - 0xA7, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, - 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, - 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA8, 0xA9, - 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, - 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, - 0xA9, 0xA9, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, - 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, - 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, - 0xAA, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, - 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, - 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAC, - 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, - 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, - 0xAC, 0xAC, 0xAC, 0xAC, 0xAC, 0xAD, 0xAD, 0xAD, - 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, - 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, - 0xAD, 0xAD, 0xAD, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, - 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, - 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, 0xAE, - 0xAE, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, - 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, - 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xB0, - 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, - 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, - 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB1, 0xB1, - 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, - 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, 0xB1, - 0xB1, 0xB1, 0xB1, 0xB1, 0xB2, 0xB2, 0xB2, 0xB2, - 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, - 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, 0xB2, - 0xB2, 0xB2, 0xB2, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, - 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, - 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, - 0xB3, 0xB3, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, - 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, - 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, - 0xB4, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, - 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, - 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, 0xB5, - 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, - 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, - 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, - 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, - 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, - 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB8, - 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, - 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, - 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB8, 0xB9, - 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, - 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, - 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0xBA, - 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, - 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, - 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBA, 0xBB, - 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, - 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, - 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, - 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, - 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, - 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, 0xBC, - 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, - 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, - 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, - 0xBD, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, - 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, - 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, 0xBE, - 0xBE, 0xBE, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, - 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, - 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, - 0xBF, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, - 0xC0, 0xC0, 0xC0, 0xC0, 0xC1, 0xC1, 0xC1, 0xC1, - 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, - 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, - 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC2, 0xC2, 0xC2, - 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, - 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, - 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC3, 0xC3, - 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, - 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, - 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, - 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, - 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, - 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, - 0xC4, 0xC4, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, - 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, - 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, 0xC5, - 0xC5, 0xC5, 0xC5, 0xC5, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, - 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC7, 0xC7, - 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, - 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, - 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, 0xC7, - 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, - 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, - 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, - 0xC8, 0xC8, 0xC8, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, - 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, - 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, - 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xC9, 0xCA, 0xCA, - 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, - 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, - 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, 0xCA, - 0xCA, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, - 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, - 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, - 0xCB, 0xCB, 0xCB, 0xCB, 0xCC, 0xCC, 0xCC, 0xCC, - 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, - 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, - 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCD, - 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, - 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, - 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, 0xCD, - 0xCD, 0xCD, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, - 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, - 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, - 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCE, 0xCF, 0xCF, - 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, - 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, - 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, 0xCF, - 0xCF, 0xCF, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, - 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, - 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, - 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD1, 0xD1, 0xD1, - 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, - 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, - 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, 0xD1, - 0xD1, 0xD1, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, - 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, - 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, - 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD2, 0xD3, 0xD3, - 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, - 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, - 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, 0xD3, - 0xD3, 0xD3, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, - 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, - 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, - 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD4, 0xD5, - 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, - 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, - 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, - 0xD5, 0xD5, 0xD5, 0xD5, 0xD6, 0xD6, 0xD6, 0xD6, - 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, - 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, - 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, - 0xD6, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, - 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, - 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, - 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD7, 0xD8, 0xD8, - 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, - 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, - 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, - 0xD8, 0xD8, 0xD8, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, - 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, - 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, - 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, - 0xD9, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, - 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, - 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, - 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDB, 0xDB, - 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, - 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, - 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, - 0xDB, 0xDB, 0xDB, 0xDB, 0xDC, 0xDC, 0xDC, 0xDC, - 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, - 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, - 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, - 0xDC, 0xDC, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, - 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, - 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, - 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, - 0xDD, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, - 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, - 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, - 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDF, - 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, - 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, - 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, - 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE0, 0xE0, - 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, - 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, - 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, - 0xE0, 0xE0, 0xE0, 0xE0, 0xE1, 0xE1, 0xE1, 0xE1, - 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, - 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, - 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, 0xE1, - 0xE1, 0xE1, 0xE1, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, - 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, - 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, - 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, - 0xE2, 0xE2, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, - 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, - 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, - 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, - 0xE3, 0xE3, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, - 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, - 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, - 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, - 0xE4, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, - 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, - 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, - 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, - 0xE5, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, - 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, - 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, - 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, - 0xE6, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, - 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, - 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, - 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, - 0xE7, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, - 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, - 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, - 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, - 0xE8, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, - 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, - 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, - 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, - 0xE9, 0xE9, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, - 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, - 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, - 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, 0xEA, - 0xEA, 0xEA, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, - 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, - 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, - 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, 0xEB, - 0xEB, 0xEB, 0xEB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, - 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, - 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, - 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, - 0xEC, 0xEC, 0xEC, 0xEC, 0xED, 0xED, 0xED, 0xED, - 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, - 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, - 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, - 0xED, 0xED, 0xED, 0xED, 0xED, 0xEE, 0xEE, 0xEE, - 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, - 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, - 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, - 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEF, 0xEF, - 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, - 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, - 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, - 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, - 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, - 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, - 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, - 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, - 0xF0, 0xF0, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, - 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, - 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, - 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, 0xF1, - 0xF1, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, 0xF2, 0xF2, - 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, - 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, - 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, - 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF3, 0xF3, - 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, - 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, - 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, - 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, - 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, - 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, - 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, - 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, - 0xF4, 0xF4, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, - 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, - 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, - 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, - 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF6, 0xF6, 0xF6, - 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, - 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, - 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, - 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, - 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, - 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, - 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, - 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, - 0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, - 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, - 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, - 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, - 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF9, 0xF9, - 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, - 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, - 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, - 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, - 0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, - 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, - 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, - 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, - 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, - 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, - 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, - 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, - 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, - 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, - 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, - 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, - 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, - 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, - 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, - 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -}; - -void mdp4_mixer_gc_lut_setup(int mixer_num) -{ - unsigned char *base; - uint32 data; - char val; - int i, off; - - if (mixer_num) /* mixer number, /dev/fb0, /dev/fb1 */ - base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */ - else - base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */ - - base += 0x4000; /* GC_LUT offset */ - - off = 0; - for (i = 0; i < 4096; i++) { - val = gc_lut[i]; - data = (val << 16 | val << 8 | val); /* R, B, and G are same */ - outpdw(base + off, data); - off += 4; - } -} - -uint32 igc_video_lut[] = { /* non linear */ - 0x0, 0x1, 0x2, 0x4, 0x5, 0x6, 0x7, 0x9, - 0xA, 0xB, 0xC, 0xE, 0xF, 0x10, 0x12, 0x14, - 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F, 0x21, 0x23, - 0x25, 0x28, 0x2A, 0x2D, 0x30, 0x32, 0x35, 0x38, - 0x3B, 0x3E, 0x42, 0x45, 0x48, 0x4C, 0x4F, 0x53, - 0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, 0x70, 0x74, - 0x79, 0x7E, 0x83, 0x88, 0x8D, 0x92, 0x97, 0x9C, - 0xA2, 0xA8, 0xAD, 0xB3, 0xB9, 0xBF, 0xC5, 0xCC, - 0xD2, 0xD8, 0xDF, 0xE6, 0xED, 0xF4, 0xFB, 0x102, - 0x109, 0x111, 0x118, 0x120, 0x128, 0x130, 0x138, 0x140, - 0x149, 0x151, 0x15A, 0x162, 0x16B, 0x174, 0x17D, 0x186, - 0x190, 0x199, 0x1A3, 0x1AC, 0x1B6, 0x1C0, 0x1CA, 0x1D5, - 0x1DF, 0x1EA, 0x1F4, 0x1FF, 0x20A, 0x215, 0x220, 0x22B, - 0x237, 0x242, 0x24E, 0x25A, 0x266, 0x272, 0x27F, 0x28B, - 0x298, 0x2A4, 0x2B1, 0x2BE, 0x2CB, 0x2D8, 0x2E6, 0x2F3, - 0x301, 0x30F, 0x31D, 0x32B, 0x339, 0x348, 0x356, 0x365, - 0x374, 0x383, 0x392, 0x3A1, 0x3B1, 0x3C0, 0x3D0, 0x3E0, - 0x3F0, 0x400, 0x411, 0x421, 0x432, 0x443, 0x454, 0x465, - 0x476, 0x487, 0x499, 0x4AB, 0x4BD, 0x4CF, 0x4E1, 0x4F3, - 0x506, 0x518, 0x52B, 0x53E, 0x551, 0x565, 0x578, 0x58C, - 0x5A0, 0x5B3, 0x5C8, 0x5DC, 0x5F0, 0x605, 0x61A, 0x62E, - 0x643, 0x659, 0x66E, 0x684, 0x699, 0x6AF, 0x6C5, 0x6DB, - 0x6F2, 0x708, 0x71F, 0x736, 0x74D, 0x764, 0x77C, 0x793, - 0x7AB, 0x7C3, 0x7DB, 0x7F3, 0x80B, 0x824, 0x83D, 0x855, - 0x86F, 0x888, 0x8A1, 0x8BB, 0x8D4, 0x8EE, 0x908, 0x923, - 0x93D, 0x958, 0x973, 0x98E, 0x9A9, 0x9C4, 0x9DF, 0x9FB, - 0xA17, 0xA33, 0xA4F, 0xA6C, 0xA88, 0xAA5, 0xAC2, 0xADF, - 0xAFC, 0xB19, 0xB37, 0xB55, 0xB73, 0xB91, 0xBAF, 0xBCE, - 0xBEC, 0xC0B, 0xC2A, 0xC4A, 0xC69, 0xC89, 0xCA8, 0xCC8, - 0xCE8, 0xD09, 0xD29, 0xD4A, 0xD6B, 0xD8C, 0xDAD, 0xDCF, - 0xDF0, 0xE12, 0xE34, 0xE56, 0xE79, 0xE9B, 0xEBE, 0xEE1, - 0xF04, 0xF27, 0xF4B, 0xF6E, 0xF92, 0xFB6, 0xFDB, 0xFFF, -}; - -void mdp4_vg_igc_lut_setup(int vp_num) -{ - unsigned char *base; - int i, voff, off; - uint32 data, val; - - voff = MDP4_VIDEO_OFF * vp_num; - base = MDP_BASE + MDP4_VIDEO_BASE + voff + 0x5000; - - off = 0; - for (i = 0; i < 256; i++) { - val = igc_video_lut[i]; - data = (val << 16 | val); /* color 0 and 1 */ - outpdw(base + off, data); - outpdw(base + off + 0x800, val); /* color 2 */ - off += 4; - } -} - -uint32 igc_rgb_lut[] = { /* linear */ - 0x0, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, - 0x80, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, - 0x101, 0x111, 0x121, 0x131, 0x141, 0x151, 0x161, 0x171, - 0x181, 0x191, 0x1A2, 0x1B2, 0x1C2, 0x1D2, 0x1E2, 0x1F2, - 0x202, 0x212, 0x222, 0x232, 0x242, 0x252, 0x262, 0x272, - 0x282, 0x292, 0x2A2, 0x2B3, 0x2C3, 0x2D3, 0x2E3, 0x2F3, - 0x303, 0x313, 0x323, 0x333, 0x343, 0x353, 0x363, 0x373, - 0x383, 0x393, 0x3A3, 0x3B3, 0x3C4, 0x3D4, 0x3E4, 0x3F4, - 0x404, 0x414, 0x424, 0x434, 0x444, 0x454, 0x464, 0x474, - 0x484, 0x494, 0x4A4, 0x4B4, 0x4C4, 0x4D5, 0x4E5, 0x4F5, - 0x505, 0x515, 0x525, 0x535, 0x545, 0x555, 0x565, 0x575, - 0x585, 0x595, 0x5A5, 0x5B5, 0x5C5, 0x5D5, 0x5E6, 0x5F6, - 0x606, 0x616, 0x626, 0x636, 0x646, 0x656, 0x666, 0x676, - 0x686, 0x696, 0x6A6, 0x6B6, 0x6C6, 0x6D6, 0x6E6, 0x6F7, - 0x707, 0x717, 0x727, 0x737, 0x747, 0x757, 0x767, 0x777, - 0x787, 0x797, 0x7A7, 0x7B7, 0x7C7, 0x7D7, 0x7E7, 0x7F7, - 0x808, 0x818, 0x828, 0x838, 0x848, 0x858, 0x868, 0x878, - 0x888, 0x898, 0x8A8, 0x8B8, 0x8C8, 0x8D8, 0x8E8, 0x8F8, - 0x908, 0x919, 0x929, 0x939, 0x949, 0x959, 0x969, 0x979, - 0x989, 0x999, 0x9A9, 0x9B9, 0x9C9, 0x9D9, 0x9E9, 0x9F9, - 0xA09, 0xA19, 0xA2A, 0xA3A, 0xA4A, 0xA5A, 0xA6A, 0xA7A, - 0xA8A, 0xA9A, 0xAAA, 0xABA, 0xACA, 0xADA, 0xAEA, 0xAFA, - 0xB0A, 0xB1A, 0xB2A, 0xB3B, 0xB4B, 0xB5B, 0xB6B, 0xB7B, - 0xB8B, 0xB9B, 0xBAB, 0xBBB, 0xBCB, 0xBDB, 0xBEB, 0xBFB, - 0xC0B, 0xC1B, 0xC2B, 0xC3B, 0xC4C, 0xC5C, 0xC6C, 0xC7C, - 0xC8C, 0xC9C, 0xCAC, 0xCBC, 0xCCC, 0xCDC, 0xCEC, 0xCFC, - 0xD0C, 0xD1C, 0xD2C, 0xD3C, 0xD4C, 0xD5D, 0xD6D, 0xD7D, - 0xD8D, 0xD9D, 0xDAD, 0xDBD, 0xDCD, 0xDDD, 0xDED, 0xDFD, - 0xE0D, 0xE1D, 0xE2D, 0xE3D, 0xE4D, 0xE5D, 0xE6E, 0xE7E, - 0xE8E, 0xE9E, 0xEAE, 0xEBE, 0xECE, 0xEDE, 0xEEE, 0xEFE, - 0xF0E, 0xF1E, 0xF2E, 0xF3E, 0xF4E, 0xF5E, 0xF6E, 0xF7F, - 0xF8F, 0xF9F, 0xFAF, 0xFBF, 0xFCF, 0xFDF, 0xFEF, 0xFFF, -}; - -void mdp4_rgb_igc_lut_setup(int num) -{ - unsigned char *base; - int i, voff, off; - uint32 data, val; - - voff = MDP4_RGB_OFF * num; - base = MDP_BASE + MDP4_RGB_BASE + voff + 0x5000; - - off = 0; - for (i = 0; i < 256; i++) { - val = igc_rgb_lut[i]; - data = (val << 16 | val); /* color 0 and 1 */ - outpdw(base + off, data); - outpdw(base + off + 0x800, val); /* color 2 */ - off += 4; - } -} diff --git a/drivers/staging/msm/mdp_cursor.c b/drivers/staging/msm/mdp_cursor.c deleted file mode 100644 index 7d28f30d9313..000000000000 --- a/drivers/staging/msm/mdp_cursor.c +++ /dev/null @@ -1,104 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include "mdp.h" -#include "msm_fb.h" - -static int cursor_enabled; - -int mdp_hw_cursor_update(struct fb_info *info, struct fb_cursor *cursor) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - struct fb_image *img = &cursor->image; - int calpha_en, transp_en; - int alpha; - int ret = 0; - - if ((img->width > MDP_CURSOR_WIDTH) || - (img->height > MDP_CURSOR_HEIGHT) || - (img->depth != 32)) - return -EINVAL; - - if (cursor->set & FB_CUR_SETPOS) - MDP_OUTP(MDP_BASE + 0x9004c, (img->dy << 16) | img->dx); - - if (cursor->set & FB_CUR_SETIMAGE) { - ret = copy_from_user(mfd->cursor_buf, img->data, - img->width*img->height*4); - if (ret) - return ret; - - if (img->bg_color == 0xffffffff) - transp_en = 0; - else - transp_en = 1; - - alpha = (img->fg_color & 0xff000000) >> 24; - - if (alpha) - calpha_en = 0x2; /* xrgb */ - else - calpha_en = 0x1; /* argb */ - - MDP_OUTP(MDP_BASE + 0x90044, (img->height << 16) | img->width); - MDP_OUTP(MDP_BASE + 0x90048, mfd->cursor_buf_phys); - /* order the writes the cursor_buf before updating the - * hardware */ -// dma_coherent_pre_ops(); - MDP_OUTP(MDP_BASE + 0x90060, - (transp_en << 3) | (calpha_en << 1) | - (inp32(MDP_BASE + 0x90060) & 0x1)); -#ifdef CONFIG_FB_MSM_MDP40 - MDP_OUTP(MDP_BASE + 0x90064, (alpha << 24)); - MDP_OUTP(MDP_BASE + 0x90068, (0xffffff & img->bg_color)); - MDP_OUTP(MDP_BASE + 0x9006C, (0xffffff & img->bg_color)); -#else - MDP_OUTP(MDP_BASE + 0x90064, - (alpha << 24) | (0xffffff & img->bg_color)); - MDP_OUTP(MDP_BASE + 0x90068, 0); -#endif - } - - if ((cursor->enable) && (!cursor_enabled)) { - cursor_enabled = 1; - MDP_OUTP(MDP_BASE + 0x90060, inp32(MDP_BASE + 0x90060) | 0x1); - } else if ((!cursor->enable) && (cursor_enabled)) { - cursor_enabled = 0; - MDP_OUTP(MDP_BASE + 0x90060, - inp32(MDP_BASE + 0x90060) & (~0x1)); - } - - return 0; -} diff --git a/drivers/staging/msm/mdp_dma.c b/drivers/staging/msm/mdp_dma.c deleted file mode 100644 index 639918b143b4..000000000000 --- a/drivers/staging/msm/mdp_dma.c +++ /dev/null @@ -1,561 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include "mdp.h" -#include "msm_fb.h" -#include "mddihost.h" - -static uint32 mdp_last_dma2_update_width; -static uint32 mdp_last_dma2_update_height; -static uint32 mdp_curr_dma2_update_width; -static uint32 mdp_curr_dma2_update_height; - -ktime_t mdp_dma2_last_update_time = { 0 }; - -int mdp_lcd_rd_cnt_offset_slow = 20; -int mdp_lcd_rd_cnt_offset_fast = 20; -int mdp_vsync_usec_wait_line_too_short = 5; -uint32 mdp_dma2_update_time_in_usec; -uint32 mdp_total_vdopkts; - -extern u32 msm_fb_debug_enabled; -extern struct workqueue_struct *mdp_dma_wq; - -int vsync_start_y_adjust = 4; - -static void mdp_dma2_update_lcd(struct msm_fb_data_type *mfd) -{ - MDPIBUF *iBuf = &mfd->ibuf; - int mddi_dest = FALSE; - uint32 outBpp = iBuf->bpp; - uint32 dma2_cfg_reg; - uint8 *src; - uint32 mddi_ld_param; - uint16 mddi_vdo_packet_reg; - struct msm_fb_panel_data *pdata = - (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data; - uint32 ystride = mfd->fbi->fix.line_length; - - dma2_cfg_reg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_LSB | - DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS; - -#ifdef CONFIG_FB_MSM_MDP30 - /* - * Software workaround: On 7x25/7x27, the MDP will not - * respond if dma_w is 1 pixel. Set the update width to - * 2 pixels and adjust the x offset if needed. - */ - if (iBuf->dma_w == 1) { - iBuf->dma_w = 2; - if (iBuf->dma_x == (iBuf->ibuf_width - 2)) - iBuf->dma_x--; - } -#endif - - if (mfd->fb_imgType == MDP_BGR_565) - dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; - else - dma2_cfg_reg |= DMA_PACK_PATTERN_RGB; - - if (outBpp == 4) - dma2_cfg_reg |= DMA_IBUF_C3ALPHA_EN; - - if (outBpp == 2) - dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565; - - mddi_ld_param = 0; - mddi_vdo_packet_reg = mfd->panel_info.mddi.vdopkt; - - if ((mfd->panel_info.type == MDDI_PANEL) || - (mfd->panel_info.type == EXT_MDDI_PANEL)) { - dma2_cfg_reg |= DMA_OUT_SEL_MDDI; - mddi_dest = TRUE; - - if (mfd->panel_info.type == MDDI_PANEL) { - mdp_total_vdopkts++; - if (mfd->panel_info.pdest == DISPLAY_1) { - dma2_cfg_reg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY; - mddi_ld_param = 0; -#ifdef MDDI_HOST_WINDOW_WORKAROUND - mddi_window_adjust(mfd, iBuf->dma_x, - iBuf->dma_w - 1, iBuf->dma_y, - iBuf->dma_h - 1); -#endif - } else { - dma2_cfg_reg |= - DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY; - mddi_ld_param = 1; -#ifdef MDDI_HOST_WINDOW_WORKAROUND - mddi_window_adjust(mfd, iBuf->dma_x, - iBuf->dma_w - 1, iBuf->dma_y, - iBuf->dma_h - 1); -#endif - } - } else { - dma2_cfg_reg |= DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL; - mddi_ld_param = 2; - } - } else { - if (mfd->panel_info.pdest == DISPLAY_1) { - dma2_cfg_reg |= DMA_AHBM_LCD_SEL_PRIMARY; - outp32(MDP_EBI2_LCD0, mfd->data_port_phys); - } else { - dma2_cfg_reg |= DMA_AHBM_LCD_SEL_SECONDARY; - outp32(MDP_EBI2_LCD1, mfd->data_port_phys); - } - } - - dma2_cfg_reg |= DMA_DITHER_EN; - - src = (uint8 *) iBuf->buf; - /* starting input address */ - src += iBuf->dma_x * outBpp + iBuf->dma_y * ystride; - - mdp_curr_dma2_update_width = iBuf->dma_w; - mdp_curr_dma2_update_height = iBuf->dma_h; - - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - -#ifdef CONFIG_FB_MSM_MDP22 - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0184, - (iBuf->dma_h << 16 | iBuf->dma_w)); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0188, src); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x018C, ystride); -#else - MDP_OUTP(MDP_BASE + 0x90004, (iBuf->dma_h << 16 | iBuf->dma_w)); - MDP_OUTP(MDP_BASE + 0x90008, src); - MDP_OUTP(MDP_BASE + 0x9000c, ystride); -#endif - - if (mfd->panel_info.bpp == 18) { - dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */ - DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; - } else { - dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */ - DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; - } - - if (mddi_dest) { -#ifdef CONFIG_FB_MSM_MDP22 - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0194, - (iBuf->dma_y << 16) | iBuf->dma_x); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0, mddi_ld_param); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4, - (MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg); -#else - MDP_OUTP(MDP_BASE + 0x90010, (iBuf->dma_y << 16) | iBuf->dma_x); - MDP_OUTP(MDP_BASE + 0x00090, mddi_ld_param); - MDP_OUTP(MDP_BASE + 0x00094, - (MDDI_VDO_PACKET_DESC << 16) | mddi_vdo_packet_reg); -#endif - } else { - /* setting EBI2 LCDC write window */ - pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w, - iBuf->dma_h); - } - - /* dma2 config register */ -#ifdef MDP_HW_VSYNC - MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg); - - if ((mfd->use_mdp_vsync) && - (mfd->ibuf.vsync_enable) && (mfd->panel_info.lcd.vsync_enable)) { - uint32 start_y; - - if (vsync_start_y_adjust <= iBuf->dma_y) - start_y = iBuf->dma_y - vsync_start_y_adjust; - else - start_y = - (mfd->total_lcd_lines - 1) - (vsync_start_y_adjust - - iBuf->dma_y); - - /* - * MDP VSYNC clock must be On by now so, we don't have to - * re-enable it - */ - MDP_OUTP(MDP_BASE + 0x210, start_y); - MDP_OUTP(MDP_BASE + 0x20c, 1); /* enable prim vsync */ - } else { - MDP_OUTP(MDP_BASE + 0x20c, 0); /* disable prim vsync */ - } -#else -#ifdef CONFIG_FB_MSM_MDP22 - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0180, dma2_cfg_reg); -#else - MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg); -#endif -#endif /* MDP_HW_VSYNC */ - - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); -} - -static ktime_t vt = { 0 }; -int mdp_usec_diff_threshold = 100; -int mdp_expected_usec_wait; - -enum hrtimer_restart mdp_dma2_vsync_hrtimer_handler(struct hrtimer *ht) -{ - struct msm_fb_data_type *mfd = NULL; - - mfd = container_of(ht, struct msm_fb_data_type, dma_hrtimer); - - mdp_pipe_kickoff(MDP_DMA2_TERM, mfd); - - if (msm_fb_debug_enabled) { - ktime_t t; - int usec_diff; - int actual_wait; - - t = ktime_get_real(); - - actual_wait = - (t.tv.sec - vt.tv.sec) * 1000000 + (t.tv.nsec - - vt.tv.nsec) / 1000; - usec_diff = actual_wait - mdp_expected_usec_wait; - - if ((mdp_usec_diff_threshold < usec_diff) || (usec_diff < 0)) - MSM_FB_DEBUG - ("HRT Diff = %d usec Exp=%d usec Act=%d usec\n", - usec_diff, mdp_expected_usec_wait, actual_wait); - } - - return HRTIMER_NORESTART; -} - -static void mdp_dma_schedule(struct msm_fb_data_type *mfd, uint32 term) -{ - /* - * dma2 configure VSYNC block - * vsync supported on Primary LCD only for now - */ - int32 mdp_lcd_rd_cnt; - uint32 usec_wait_time; - uint32 start_y; - - /* - * ToDo: if we can move HRT timer callback to workqueue, we can - * move DMA2 power on under mdp_pipe_kickoff(). - * This will save a power for hrt time wait. - * However if the latency for context switch (hrt irq -> workqueue) - * is too big, we will miss the vsync timing. - */ - if (term == MDP_DMA2_TERM) - mdp_pipe_ctrl(MDP_DMA2_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - - mdp_dma2_update_time_in_usec = - MDP_KTIME2USEC(mdp_dma2_last_update_time); - - if ((!mfd->ibuf.vsync_enable) || (!mfd->panel_info.lcd.vsync_enable) - || (mfd->use_mdp_vsync)) { - mdp_pipe_kickoff(term, mfd); - return; - } - /* SW vsync logic starts here */ - - /* get current rd counter */ - mdp_lcd_rd_cnt = mdp_get_lcd_line_counter(mfd); - if (mdp_dma2_update_time_in_usec != 0) { - uint32 num, den; - - /* - * roi width boundary calculation to know the size of pixel - * width that MDP can send faster or slower than LCD read - * pointer - */ - - num = mdp_last_dma2_update_width * mdp_last_dma2_update_height; - den = - (((mfd->panel_info.lcd.refx100 * mfd->total_lcd_lines) / - 1000) * (mdp_dma2_update_time_in_usec / 100)) / 1000; - - if (den == 0) - mfd->vsync_width_boundary[mdp_last_dma2_update_width] = - mfd->panel_info.xres + 1; - else - mfd->vsync_width_boundary[mdp_last_dma2_update_width] = - (int)(num / den); - } - - if (mfd->vsync_width_boundary[mdp_last_dma2_update_width] > - mdp_curr_dma2_update_width) { - /* MDP wrp is faster than LCD rdp */ - mdp_lcd_rd_cnt += mdp_lcd_rd_cnt_offset_fast; - } else { - /* MDP wrp is slower than LCD rdp */ - mdp_lcd_rd_cnt -= mdp_lcd_rd_cnt_offset_slow; - } - - if (mdp_lcd_rd_cnt < 0) - mdp_lcd_rd_cnt = mfd->total_lcd_lines + mdp_lcd_rd_cnt; - else if (mdp_lcd_rd_cnt > mfd->total_lcd_lines) - mdp_lcd_rd_cnt = mdp_lcd_rd_cnt - mfd->total_lcd_lines - 1; - - /* get wrt pointer position */ - start_y = mfd->ibuf.dma_y; - - /* measure line difference between start_y and rd counter */ - if (start_y > mdp_lcd_rd_cnt) { - /* - * *100 for lcd_ref_hzx100 was already multiplied by 100 - * *1000000 is for usec conversion - */ - - if ((start_y - mdp_lcd_rd_cnt) <= - mdp_vsync_usec_wait_line_too_short) - usec_wait_time = 0; - else - usec_wait_time = - ((start_y - - mdp_lcd_rd_cnt) * 1000000) / - ((mfd->total_lcd_lines * - mfd->panel_info.lcd.refx100) / 100); - } else { - if ((start_y + (mfd->total_lcd_lines - mdp_lcd_rd_cnt)) <= - mdp_vsync_usec_wait_line_too_short) - usec_wait_time = 0; - else - usec_wait_time = - ((start_y + - (mfd->total_lcd_lines - - mdp_lcd_rd_cnt)) * 1000000) / - ((mfd->total_lcd_lines * - mfd->panel_info.lcd.refx100) / 100); - } - - mdp_last_dma2_update_width = mdp_curr_dma2_update_width; - mdp_last_dma2_update_height = mdp_curr_dma2_update_height; - - if (usec_wait_time == 0) { - mdp_pipe_kickoff(term, mfd); - } else { - ktime_t wait_time; - - wait_time.tv.sec = 0; - wait_time.tv.nsec = usec_wait_time * 1000; - - if (msm_fb_debug_enabled) { - vt = ktime_get_real(); - mdp_expected_usec_wait = usec_wait_time; - } - hrtimer_start(&mfd->dma_hrtimer, wait_time, HRTIMER_MODE_REL); - } -} - -#ifdef MDDI_HOST_WINDOW_WORKAROUND -void mdp_dma2_update(struct msm_fb_data_type *mfd) -{ - MDPIBUF *iBuf; - uint32 upper_height; - - if (mfd->panel.type == EXT_MDDI_PANEL) { - mdp_dma2_update_sub(mfd); - return; - } - - iBuf = &mfd->ibuf; - - upper_height = - (uint32) mddi_assign_pkt_height((uint16) iBuf->dma_w, - (uint16) iBuf->dma_h, 18); - - if (upper_height >= iBuf->dma_h) { - mdp_dma2_update_sub(mfd); - } else { - MDPIBUF lower_height; - - /* sending the upper region first */ - lower_height = iBuf->dma_h - upper_height; - iBuf->dma_h = upper_height; - mdp_dma2_update_sub(mfd); - - /* sending the lower region second */ - iBuf->dma_h = lower_height; - iBuf->dma_y += lower_height; - iBuf->vsync_enable = FALSE; - mdp_dma2_update_sub(mfd); - } -} - -void mdp_dma2_update_sub(struct msm_fb_data_type *mfd) -#else -void mdp_dma2_update(struct msm_fb_data_type *mfd) -#endif -{ - down(&mfd->dma->mutex); - if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) { - down(&mfd->sem); - mfd->ibuf_flushed = TRUE; - mdp_dma2_update_lcd(mfd); - - mdp_enable_irq(MDP_DMA2_TERM); - mfd->dma->busy = TRUE; - INIT_COMPLETION(mfd->dma->comp); - - /* schedule DMA to start */ - mdp_dma_schedule(mfd, MDP_DMA2_TERM); - up(&mfd->sem); - - /* wait until DMA finishes the current job */ - wait_for_completion_killable(&mfd->dma->comp); - mdp_disable_irq(MDP_DMA2_TERM); - - /* signal if pan function is waiting for the update completion */ - if (mfd->pan_waiting) { - mfd->pan_waiting = FALSE; - complete(&mfd->pan_comp); - } - } - up(&mfd->dma->mutex); -} - -void mdp_lcd_update_workqueue_handler(struct work_struct *work) -{ - struct msm_fb_data_type *mfd = NULL; - - mfd = container_of(work, struct msm_fb_data_type, dma_update_worker); - if (mfd) - mfd->dma_fnc(mfd); -} - -void mdp_set_dma_pan_info(struct fb_info *info, struct mdp_dirty_region *dirty, - boolean sync) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - MDPIBUF *iBuf; - int bpp = info->var.bits_per_pixel / 8; - - down(&mfd->sem); - iBuf = &mfd->ibuf; - iBuf->buf = (uint8 *) info->fix.smem_start; - iBuf->buf += info->var.xoffset * bpp + - info->var.yoffset * info->fix.line_length; - - iBuf->ibuf_width = info->var.xres_virtual; - iBuf->bpp = bpp; - - iBuf->vsync_enable = sync; - - if (dirty) { - /* - * ToDo: dirty region check inside var.xoffset+xres - * <-> var.yoffset+yres - */ - iBuf->dma_x = dirty->xoffset % info->var.xres; - iBuf->dma_y = dirty->yoffset % info->var.yres; - iBuf->dma_w = dirty->width; - iBuf->dma_h = dirty->height; - } else { - iBuf->dma_x = 0; - iBuf->dma_y = 0; - iBuf->dma_w = info->var.xres; - iBuf->dma_h = info->var.yres; - } - mfd->ibuf_flushed = FALSE; - up(&mfd->sem); -} - -void mdp_set_offset_info(struct fb_info *info, uint32 addr, uint32 sync) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - MDPIBUF *iBuf; - - int bpp = info->var.bits_per_pixel / 8; - - down(&mfd->sem); - iBuf = &mfd->ibuf; - iBuf->ibuf_width = info->var.xres_virtual; - iBuf->bpp = bpp; - iBuf->vsync_enable = sync; - iBuf->dma_x = 0; - iBuf->dma_y = 0; - iBuf->dma_w = info->var.xres; - iBuf->dma_h = info->var.yres; - iBuf->buf = (uint8 *) addr; - - mfd->ibuf_flushed = FALSE; - up(&mfd->sem); -} - -void mdp_dma_pan_update(struct fb_info *info) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - MDPIBUF *iBuf; - - iBuf = &mfd->ibuf; - - if (mfd->sw_currently_refreshing) { - /* we need to wait for the pending update */ - mfd->pan_waiting = TRUE; - if (!mfd->ibuf_flushed) { - wait_for_completion_killable(&mfd->pan_comp); - } - /* waiting for this update to complete */ - mfd->pan_waiting = TRUE; - wait_for_completion_killable(&mfd->pan_comp); - } else - mfd->dma_fnc(mfd); -} - -void mdp_refresh_screen(unsigned long data) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data; - - if ((mfd->sw_currently_refreshing) && (mfd->sw_refreshing_enable)) { - init_timer(&mfd->refresh_timer); - mfd->refresh_timer.function = mdp_refresh_screen; - mfd->refresh_timer.data = data; - - if (mfd->dma->busy) - /* come back in 1 msec */ - mfd->refresh_timer.expires = jiffies + (HZ / 1000); - else - mfd->refresh_timer.expires = - jiffies + mfd->refresh_timer_duration; - - add_timer(&mfd->refresh_timer); - - if (!mfd->dma->busy) { - if (!queue_work(mdp_dma_wq, &mfd->dma_update_worker)) { - MSM_FB_DEBUG("mdp_dma: can't queue_work! -> \ - MDP/MDDI/LCD clock speed needs to be increased\n"); - } - } - } else { - if (!mfd->hw_refresh) - complete(&mfd->refresher_comp); - } -} diff --git a/drivers/staging/msm/mdp_dma_lcdc.c b/drivers/staging/msm/mdp_dma_lcdc.c deleted file mode 100644 index b57fa1a0ceb0..000000000000 --- a/drivers/staging/msm/mdp_dma_lcdc.c +++ /dev/null @@ -1,379 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "mdp.h" -#include "msm_fb.h" -#include "mdp4.h" - -#ifdef CONFIG_FB_MSM_MDP40 -#define LCDC_BASE 0xC0000 -#define DTV_BASE 0xD0000 -#define DMA_E_BASE 0xB0000 -#else -#define LCDC_BASE 0xE0000 -#endif - -#define DMA_P_BASE 0x90000 - -extern spinlock_t mdp_spin_lock; -#ifndef CONFIG_FB_MSM_MDP40 -extern uint32 mdp_intr_mask; -#endif - -int first_pixel_start_x; -int first_pixel_start_y; - -int mdp_lcdc_on(struct platform_device *pdev) -{ - int lcdc_width; - int lcdc_height; - int lcdc_bpp; - int lcdc_border_clr; - int lcdc_underflow_clr; - int lcdc_hsync_skew; - - int hsync_period; - int hsync_ctrl; - int vsync_period; - int display_hctl; - int display_v_start; - int display_v_end; - int active_hctl; - int active_h_start; - int active_h_end; - int active_v_start; - int active_v_end; - int ctrl_polarity; - int h_back_porch; - int h_front_porch; - int v_back_porch; - int v_front_porch; - int hsync_pulse_width; - int vsync_pulse_width; - int hsync_polarity; - int vsync_polarity; - int data_en_polarity; - int hsync_start_x; - int hsync_end_x; - uint8 *buf; - int bpp; - uint32 dma2_cfg_reg; - struct fb_info *fbi; - struct fb_var_screeninfo *var; - struct msm_fb_data_type *mfd; - uint32 dma_base; - uint32 timer_base = LCDC_BASE; - uint32 block = MDP_DMA2_BLOCK; - int ret; - - mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - fbi = mfd->fbi; - var = &fbi->var; - - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - - bpp = fbi->var.bits_per_pixel / 8; - buf = (uint8 *) fbi->fix.smem_start; - buf += fbi->var.xoffset * bpp + fbi->var.yoffset * fbi->fix.line_length; - - dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_DITHER_EN | DMA_OUT_SEL_LCDC; - - if (mfd->fb_imgType == MDP_BGR_565) - dma2_cfg_reg |= DMA_PACK_PATTERN_BGR; - else - dma2_cfg_reg |= DMA_PACK_PATTERN_RGB; - - if (bpp == 2) - dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB565; - else if (bpp == 3) - dma2_cfg_reg |= DMA_IBUF_FORMAT_RGB888; - else - dma2_cfg_reg |= DMA_IBUF_FORMAT_xRGB8888_OR_ARGB8888; - - switch (mfd->panel_info.bpp) { - case 24: - dma2_cfg_reg |= DMA_DSTC0G_8BITS | - DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS; - break; - - case 18: - dma2_cfg_reg |= DMA_DSTC0G_6BITS | - DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; - break; - - case 16: - dma2_cfg_reg |= DMA_DSTC0G_6BITS | - DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; - break; - - default: - printk(KERN_ERR "mdp lcdc can't support format %d bpp!\n", - mfd->panel_info.bpp); - return -ENODEV; - } - - /* DMA register config */ - - dma_base = DMA_P_BASE; - -#ifdef CONFIG_FB_MSM_MDP40 - if (mfd->panel.type == HDMI_PANEL) - dma_base = DMA_E_BASE; -#endif - - /* starting address */ - MDP_OUTP(MDP_BASE + dma_base + 0x8, (uint32) buf); - /* active window width and height */ - MDP_OUTP(MDP_BASE + dma_base + 0x4, ((fbi->var.yres) << 16) | - (fbi->var.xres)); - /* buffer ystride */ - MDP_OUTP(MDP_BASE + dma_base + 0xc, fbi->fix.line_length); - /* x/y coordinate = always 0 for lcdc */ - MDP_OUTP(MDP_BASE + dma_base + 0x10, 0); - /* dma config */ - MDP_OUTP(MDP_BASE + dma_base, dma2_cfg_reg); - - /* - * LCDC timing setting - */ - h_back_porch = var->left_margin; - h_front_porch = var->right_margin; - v_back_porch = var->upper_margin; - v_front_porch = var->lower_margin; - hsync_pulse_width = var->hsync_len; - vsync_pulse_width = var->vsync_len; - lcdc_border_clr = mfd->panel_info.lcdc.border_clr; - lcdc_underflow_clr = mfd->panel_info.lcdc.underflow_clr; - lcdc_hsync_skew = mfd->panel_info.lcdc.hsync_skew; - - lcdc_width = mfd->panel_info.xres; - lcdc_height = mfd->panel_info.yres; - lcdc_bpp = mfd->panel_info.bpp; - - hsync_period = - hsync_pulse_width + h_back_porch + lcdc_width + h_front_porch; - hsync_ctrl = (hsync_period << 16) | hsync_pulse_width; - hsync_start_x = hsync_pulse_width + h_back_porch; - hsync_end_x = hsync_period - h_front_porch - 1; - display_hctl = (hsync_end_x << 16) | hsync_start_x; - - vsync_period = - (vsync_pulse_width + v_back_porch + lcdc_height + - v_front_porch) * hsync_period; - display_v_start = - (vsync_pulse_width + v_back_porch) * hsync_period + lcdc_hsync_skew; - display_v_end = - vsync_period - (v_front_porch * hsync_period) + lcdc_hsync_skew - 1; - - if (lcdc_width != var->xres) { - active_h_start = hsync_start_x + first_pixel_start_x; - active_h_end = active_h_start + var->xres - 1; - active_hctl = - ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start; - } else { - active_hctl = 0; - } - - if (lcdc_height != var->yres) { - active_v_start = - display_v_start + first_pixel_start_y * hsync_period; - active_v_end = active_v_start + (var->yres) * hsync_period - 1; - active_v_start |= ACTIVE_START_Y_EN; - } else { - active_v_start = 0; - active_v_end = 0; - } - - -#ifdef CONFIG_FB_MSM_MDP40 - if (mfd->panel.type == HDMI_PANEL) { - block = MDP_DMA_E_BLOCK; - timer_base = DTV_BASE; - hsync_polarity = 0; - vsync_polarity = 0; - } else { - hsync_polarity = 1; - vsync_polarity = 1; - } - - lcdc_underflow_clr |= 0x80000000; /* enable recovery */ -#else - hsync_polarity = 0; - vsync_polarity = 0; -#endif - data_en_polarity = 0; - - ctrl_polarity = - (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity); - - MDP_OUTP(MDP_BASE + timer_base + 0x4, hsync_ctrl); - MDP_OUTP(MDP_BASE + timer_base + 0x8, vsync_period); - MDP_OUTP(MDP_BASE + timer_base + 0xc, vsync_pulse_width * hsync_period); - if (timer_base == LCDC_BASE) { - MDP_OUTP(MDP_BASE + timer_base + 0x10, display_hctl); - MDP_OUTP(MDP_BASE + timer_base + 0x14, display_v_start); - MDP_OUTP(MDP_BASE + timer_base + 0x18, display_v_end); - MDP_OUTP(MDP_BASE + timer_base + 0x28, lcdc_border_clr); - MDP_OUTP(MDP_BASE + timer_base + 0x2c, lcdc_underflow_clr); - MDP_OUTP(MDP_BASE + timer_base + 0x30, lcdc_hsync_skew); - MDP_OUTP(MDP_BASE + timer_base + 0x38, ctrl_polarity); - MDP_OUTP(MDP_BASE + timer_base + 0x1c, active_hctl); - MDP_OUTP(MDP_BASE + timer_base + 0x20, active_v_start); - MDP_OUTP(MDP_BASE + timer_base + 0x24, active_v_end); - } else { - MDP_OUTP(MDP_BASE + timer_base + 0x18, display_hctl); - MDP_OUTP(MDP_BASE + timer_base + 0x1c, display_v_start); - MDP_OUTP(MDP_BASE + timer_base + 0x20, display_v_end); - MDP_OUTP(MDP_BASE + timer_base + 0x40, lcdc_border_clr); - MDP_OUTP(MDP_BASE + timer_base + 0x44, lcdc_underflow_clr); - MDP_OUTP(MDP_BASE + timer_base + 0x48, lcdc_hsync_skew); - MDP_OUTP(MDP_BASE + timer_base + 0x50, ctrl_polarity); - MDP_OUTP(MDP_BASE + timer_base + 0x2c, active_hctl); - MDP_OUTP(MDP_BASE + timer_base + 0x30, active_v_start); - MDP_OUTP(MDP_BASE + timer_base + 0x38, active_v_end); - } - - ret = panel_next_on(pdev); - if (ret == 0) { - /* enable LCDC block */ - MDP_OUTP(MDP_BASE + timer_base, 1); - mdp_pipe_ctrl(block, MDP_BLOCK_POWER_ON, FALSE); - } - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - - return ret; -} - -int mdp_lcdc_off(struct platform_device *pdev) -{ - int ret = 0; - struct msm_fb_data_type *mfd; - uint32 timer_base = LCDC_BASE; - uint32 block = MDP_DMA2_BLOCK; - - mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); - -#ifdef CONFIG_FB_MSM_MDP40 - if (mfd->panel.type == HDMI_PANEL) { - block = MDP_DMA_E_BLOCK; - timer_base = DTV_BASE; - } -#endif - - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - MDP_OUTP(MDP_BASE + timer_base, 0); - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - mdp_pipe_ctrl(block, MDP_BLOCK_POWER_OFF, FALSE); - - ret = panel_next_off(pdev); - - /* delay to make sure the last frame finishes */ - mdelay(100); - - return ret; -} - -void mdp_lcdc_update(struct msm_fb_data_type *mfd) -{ - struct fb_info *fbi = mfd->fbi; - uint8 *buf; - int bpp; - unsigned long flag; - uint32 dma_base; - int irq_block = MDP_DMA2_TERM; -#ifdef CONFIG_FB_MSM_MDP40 - int intr = INTR_DMA_P_DONE; -#endif - - if (!mfd->panel_power_on) - return; - - /* no need to power on cmd block since it's lcdc mode */ - - if (!mfd->ibuf.visible_swapped) { - bpp = fbi->var.bits_per_pixel / 8; - buf = (uint8 *) fbi->fix.smem_start; - buf += fbi->var.xoffset * bpp + - fbi->var.yoffset * fbi->fix.line_length; - } else { - /* we've done something to update the pointer. */ - bpp = mfd->ibuf.bpp; - buf = mfd->ibuf.buf; - } - - dma_base = DMA_P_BASE; - -#ifdef CONFIG_FB_MSM_MDP40 - if (mfd->panel.type == HDMI_PANEL) { - intr = INTR_DMA_E_DONE; - irq_block = MDP_DMA_E_TERM; - dma_base = DMA_E_BASE; - } -#endif - - /* starting address */ - MDP_OUTP(MDP_BASE + dma_base + 0x8, (uint32) buf); - - /* enable LCDC irq */ - spin_lock_irqsave(&mdp_spin_lock, flag); - mdp_enable_irq(irq_block); - INIT_COMPLETION(mfd->dma->comp); - mfd->dma->waiting = TRUE; -#ifdef CONFIG_FB_MSM_MDP40 - outp32(MDP_INTR_CLEAR, intr); - mdp_intr_mask |= intr; - outp32(MDP_INTR_ENABLE, mdp_intr_mask); -#else - outp32(MDP_INTR_CLEAR, LCDC_FRAME_START); - mdp_intr_mask |= LCDC_FRAME_START; - outp32(MDP_INTR_ENABLE, mdp_intr_mask); -#endif - spin_unlock_irqrestore(&mdp_spin_lock, flag); - - if (mfd->ibuf.vsync_enable) - wait_for_completion_killable(&mfd->dma->comp); - mdp_disable_irq(irq_block); -} diff --git a/drivers/staging/msm/mdp_dma_s.c b/drivers/staging/msm/mdp_dma_s.c deleted file mode 100644 index 0c34a1010f17..000000000000 --- a/drivers/staging/msm/mdp_dma_s.c +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include "mdp.h" -#include "msm_fb.h" - -static void mdp_dma_s_update_lcd(struct msm_fb_data_type *mfd) -{ - MDPIBUF *iBuf = &mfd->ibuf; - int mddi_dest = FALSE; - uint32 outBpp = iBuf->bpp; - uint32 dma_s_cfg_reg; - uint8 *src; - struct msm_fb_panel_data *pdata = - (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data; - - dma_s_cfg_reg = DMA_PACK_TIGHT | DMA_PACK_ALIGN_LSB | - DMA_OUT_SEL_AHB | DMA_IBUF_NONCONTIGUOUS; - - if (mfd->fb_imgType == MDP_BGR_565) - dma_s_cfg_reg |= DMA_PACK_PATTERN_BGR; - else - dma_s_cfg_reg |= DMA_PACK_PATTERN_RGB; - - if (outBpp == 4) - dma_s_cfg_reg |= DMA_IBUF_C3ALPHA_EN; - - if (outBpp == 2) - dma_s_cfg_reg |= DMA_IBUF_FORMAT_RGB565; - - if (mfd->panel_info.pdest != DISPLAY_2) { - printk(KERN_ERR "error: non-secondary type through dma_s!\n"); - return; - } - - if (mfd->panel_info.type == MDDI_PANEL) { - dma_s_cfg_reg |= DMA_OUT_SEL_MDDI; - mddi_dest = TRUE; - } else { - dma_s_cfg_reg |= DMA_AHBM_LCD_SEL_SECONDARY; - outp32(MDP_EBI2_LCD1, mfd->data_port_phys); - } - - dma_s_cfg_reg |= DMA_DITHER_EN; - - src = (uint8 *) iBuf->buf; - /* starting input address */ - src += (iBuf->dma_x + iBuf->dma_y * iBuf->ibuf_width) * outBpp; - - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - /* PIXELSIZE */ - MDP_OUTP(MDP_BASE + 0xa0004, (iBuf->dma_h << 16 | iBuf->dma_w)); - MDP_OUTP(MDP_BASE + 0xa0008, src); /* ibuf address */ - MDP_OUTP(MDP_BASE + 0xa000c, iBuf->ibuf_width * outBpp);/* ystride */ - - if (mfd->panel_info.bpp == 18) { - dma_s_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */ - DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; - } else { - dma_s_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */ - DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; - } - - if (mddi_dest) { - MDP_OUTP(MDP_BASE + 0xa0010, (iBuf->dma_y << 16) | iBuf->dma_x); - MDP_OUTP(MDP_BASE + 0x00090, 1); - MDP_OUTP(MDP_BASE + 0x00094, - (MDDI_VDO_PACKET_DESC << 16) | - mfd->panel_info.mddi.vdopkt); - } else { - /* setting LCDC write window */ - pdata->set_rect(iBuf->dma_x, iBuf->dma_y, iBuf->dma_w, - iBuf->dma_h); - } - - MDP_OUTP(MDP_BASE + 0xa0000, dma_s_cfg_reg); - - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - mdp_pipe_kickoff(MDP_DMA_S_TERM, mfd); -} - -void mdp_dma_s_update(struct msm_fb_data_type *mfd) -{ - down(&mfd->dma->mutex); - if ((mfd) && (!mfd->dma->busy) && (mfd->panel_power_on)) { - down(&mfd->sem); - mdp_enable_irq(MDP_DMA_S_TERM); - mfd->dma->busy = TRUE; - INIT_COMPLETION(mfd->dma->comp); - mfd->ibuf_flushed = TRUE; - mdp_dma_s_update_lcd(mfd); - up(&mfd->sem); - - /* wait until DMA finishes the current job */ - wait_for_completion_killable(&mfd->dma->comp); - mdp_disable_irq(MDP_DMA_S_TERM); - - /* signal if pan function is waiting for the update completion */ - if (mfd->pan_waiting) { - mfd->pan_waiting = FALSE; - complete(&mfd->pan_comp); - } - } - up(&mfd->dma->mutex); -} diff --git a/drivers/staging/msm/mdp_dma_tv.c b/drivers/staging/msm/mdp_dma_tv.c deleted file mode 100644 index 70989fb32c1d..000000000000 --- a/drivers/staging/msm/mdp_dma_tv.c +++ /dev/null @@ -1,142 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include "mdp.h" -#include "msm_fb.h" - -extern spinlock_t mdp_spin_lock; -extern uint32 mdp_intr_mask; - -int mdp_dma3_on(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - struct fb_info *fbi; - uint8 *buf; - int bpp; - int ret = 0; - - mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - fbi = mfd->fbi; - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - - bpp = fbi->var.bits_per_pixel / 8; - buf = (uint8 *) fbi->fix.smem_start; - buf += fbi->var.xoffset * bpp + - fbi->var.yoffset * fbi->fix.line_length; - - /* starting address[31..8] of Video frame buffer is CS0 */ - MDP_OUTP(MDP_BASE + 0xC0008, (uint32) buf >> 3); - - mdp_pipe_ctrl(MDP_DMA3_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - - MDP_OUTP(MDP_BASE + 0xC0004, 0x4c60674); /* flicker filter enabled */ - MDP_OUTP(MDP_BASE + 0xC0010, 0x20); /* sobel treshold */ - - MDP_OUTP(MDP_BASE + 0xC0018, 0xeb0010); /* Y Max, Y min */ - MDP_OUTP(MDP_BASE + 0xC001C, 0xf00010); /* Cb Max, Cb min */ - MDP_OUTP(MDP_BASE + 0xC0020, 0xf00010); /* Cb Max, Cb min */ - - MDP_OUTP(MDP_BASE + 0xC000C, 0x67686970); /* add a few chars for CC */ - MDP_OUTP(MDP_BASE + 0xC0000, 0x1); /* MDP tv out enable */ - - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - - ret = panel_next_on(pdev); - - return ret; -} - -int mdp_dma3_off(struct platform_device *pdev) -{ - int ret = 0; - - ret = panel_next_off(pdev); - if (ret) - return ret; - - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - MDP_OUTP(MDP_BASE + 0xC0000, 0x0); - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - - mdp_pipe_ctrl(MDP_DMA3_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - - /* delay to make sure the last frame finishes */ - mdelay(100); - - return ret; -} - -void mdp_dma3_update(struct msm_fb_data_type *mfd) -{ - struct fb_info *fbi = mfd->fbi; - uint8 *buf; - int bpp; - unsigned long flag; - - if (!mfd->panel_power_on) - return; - - /* no need to power on cmd block since dma3 is running */ - bpp = fbi->var.bits_per_pixel / 8; - buf = (uint8 *) fbi->fix.smem_start; - buf += fbi->var.xoffset * bpp + - fbi->var.yoffset * fbi->fix.line_length; - MDP_OUTP(MDP_BASE + 0xC0008, (uint32) buf >> 3); - - spin_lock_irqsave(&mdp_spin_lock, flag); - mdp_enable_irq(MDP_DMA3_TERM); - INIT_COMPLETION(mfd->dma->comp); - mfd->dma->waiting = TRUE; - - outp32(MDP_INTR_CLEAR, TV_OUT_DMA3_START); - mdp_intr_mask |= TV_OUT_DMA3_START; - outp32(MDP_INTR_ENABLE, mdp_intr_mask); - spin_unlock_irqrestore(&mdp_spin_lock, flag); - - wait_for_completion_killable(&mfd->dma->comp); - mdp_disable_irq(MDP_DMA3_TERM); -} diff --git a/drivers/staging/msm/mdp_hw_init.c b/drivers/staging/msm/mdp_hw_init.c deleted file mode 100644 index 807362ac592c..000000000000 --- a/drivers/staging/msm/mdp_hw_init.c +++ /dev/null @@ -1,720 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "mdp.h" - -/* mdp primary csc limit vector */ -uint32 mdp_plv[] = { 0x10, 0xeb, 0x10, 0xf0 }; - -/* Color Coefficient matrix for YUV -> RGB */ -struct mdp_ccs mdp_ccs_yuv2rgb = { - MDP_CCS_YUV2RGB, - { - 0x254, - 0x000, - 0x331, - 0x254, - 0xff38, - 0xfe61, - 0x254, - 0x409, - 0x000, - }, - { -#ifdef CONFIG_FB_MSM_MDP31 - 0x1f0, - 0x180, - 0x180 -#else - 0x10, - 0x80, - 0x80 -#endif - } -}; - -/* Color Coefficient matrix for RGB -> YUV */ -struct mdp_ccs mdp_ccs_rgb2yuv = { - MDP_CCS_RGB2YUV, - { - 0x83, - 0x102, - 0x32, - 0xffb5, - 0xff6c, - 0xe1, - 0xe1, - 0xff45, - 0xffdc, - }, -#ifdef CONFIG_FB_MSM_MDP31 - { - 0x10, - 0x80, - 0x80 - } -#endif -}; - -static void mdp_load_lut_param(void) -{ - outpdw(MDP_BASE + 0x40800, 0x0); - outpdw(MDP_BASE + 0x40804, 0x151515); - outpdw(MDP_BASE + 0x40808, 0x1d1d1d); - outpdw(MDP_BASE + 0x4080c, 0x232323); - outpdw(MDP_BASE + 0x40810, 0x272727); - outpdw(MDP_BASE + 0x40814, 0x2b2b2b); - outpdw(MDP_BASE + 0x40818, 0x2f2f2f); - outpdw(MDP_BASE + 0x4081c, 0x333333); - outpdw(MDP_BASE + 0x40820, 0x363636); - outpdw(MDP_BASE + 0x40824, 0x393939); - outpdw(MDP_BASE + 0x40828, 0x3b3b3b); - outpdw(MDP_BASE + 0x4082c, 0x3e3e3e); - outpdw(MDP_BASE + 0x40830, 0x404040); - outpdw(MDP_BASE + 0x40834, 0x434343); - outpdw(MDP_BASE + 0x40838, 0x454545); - outpdw(MDP_BASE + 0x4083c, 0x474747); - outpdw(MDP_BASE + 0x40840, 0x494949); - outpdw(MDP_BASE + 0x40844, 0x4b4b4b); - outpdw(MDP_BASE + 0x40848, 0x4d4d4d); - outpdw(MDP_BASE + 0x4084c, 0x4f4f4f); - outpdw(MDP_BASE + 0x40850, 0x515151); - outpdw(MDP_BASE + 0x40854, 0x535353); - outpdw(MDP_BASE + 0x40858, 0x555555); - outpdw(MDP_BASE + 0x4085c, 0x565656); - outpdw(MDP_BASE + 0x40860, 0x585858); - outpdw(MDP_BASE + 0x40864, 0x5a5a5a); - outpdw(MDP_BASE + 0x40868, 0x5b5b5b); - outpdw(MDP_BASE + 0x4086c, 0x5d5d5d); - outpdw(MDP_BASE + 0x40870, 0x5e5e5e); - outpdw(MDP_BASE + 0x40874, 0x606060); - outpdw(MDP_BASE + 0x40878, 0x616161); - outpdw(MDP_BASE + 0x4087c, 0x636363); - outpdw(MDP_BASE + 0x40880, 0x646464); - outpdw(MDP_BASE + 0x40884, 0x666666); - outpdw(MDP_BASE + 0x40888, 0x676767); - outpdw(MDP_BASE + 0x4088c, 0x686868); - outpdw(MDP_BASE + 0x40890, 0x6a6a6a); - outpdw(MDP_BASE + 0x40894, 0x6b6b6b); - outpdw(MDP_BASE + 0x40898, 0x6c6c6c); - outpdw(MDP_BASE + 0x4089c, 0x6e6e6e); - outpdw(MDP_BASE + 0x408a0, 0x6f6f6f); - outpdw(MDP_BASE + 0x408a4, 0x707070); - outpdw(MDP_BASE + 0x408a8, 0x717171); - outpdw(MDP_BASE + 0x408ac, 0x727272); - outpdw(MDP_BASE + 0x408b0, 0x747474); - outpdw(MDP_BASE + 0x408b4, 0x757575); - outpdw(MDP_BASE + 0x408b8, 0x767676); - outpdw(MDP_BASE + 0x408bc, 0x777777); - outpdw(MDP_BASE + 0x408c0, 0x787878); - outpdw(MDP_BASE + 0x408c4, 0x797979); - outpdw(MDP_BASE + 0x408c8, 0x7a7a7a); - outpdw(MDP_BASE + 0x408cc, 0x7c7c7c); - outpdw(MDP_BASE + 0x408d0, 0x7d7d7d); - outpdw(MDP_BASE + 0x408d4, 0x7e7e7e); - outpdw(MDP_BASE + 0x408d8, 0x7f7f7f); - outpdw(MDP_BASE + 0x408dc, 0x808080); - outpdw(MDP_BASE + 0x408e0, 0x818181); - outpdw(MDP_BASE + 0x408e4, 0x828282); - outpdw(MDP_BASE + 0x408e8, 0x838383); - outpdw(MDP_BASE + 0x408ec, 0x848484); - outpdw(MDP_BASE + 0x408f0, 0x858585); - outpdw(MDP_BASE + 0x408f4, 0x868686); - outpdw(MDP_BASE + 0x408f8, 0x878787); - outpdw(MDP_BASE + 0x408fc, 0x888888); - outpdw(MDP_BASE + 0x40900, 0x898989); - outpdw(MDP_BASE + 0x40904, 0x8a8a8a); - outpdw(MDP_BASE + 0x40908, 0x8b8b8b); - outpdw(MDP_BASE + 0x4090c, 0x8c8c8c); - outpdw(MDP_BASE + 0x40910, 0x8d8d8d); - outpdw(MDP_BASE + 0x40914, 0x8e8e8e); - outpdw(MDP_BASE + 0x40918, 0x8f8f8f); - outpdw(MDP_BASE + 0x4091c, 0x8f8f8f); - outpdw(MDP_BASE + 0x40920, 0x909090); - outpdw(MDP_BASE + 0x40924, 0x919191); - outpdw(MDP_BASE + 0x40928, 0x929292); - outpdw(MDP_BASE + 0x4092c, 0x939393); - outpdw(MDP_BASE + 0x40930, 0x949494); - outpdw(MDP_BASE + 0x40934, 0x959595); - outpdw(MDP_BASE + 0x40938, 0x969696); - outpdw(MDP_BASE + 0x4093c, 0x969696); - outpdw(MDP_BASE + 0x40940, 0x979797); - outpdw(MDP_BASE + 0x40944, 0x989898); - outpdw(MDP_BASE + 0x40948, 0x999999); - outpdw(MDP_BASE + 0x4094c, 0x9a9a9a); - outpdw(MDP_BASE + 0x40950, 0x9b9b9b); - outpdw(MDP_BASE + 0x40954, 0x9c9c9c); - outpdw(MDP_BASE + 0x40958, 0x9c9c9c); - outpdw(MDP_BASE + 0x4095c, 0x9d9d9d); - outpdw(MDP_BASE + 0x40960, 0x9e9e9e); - outpdw(MDP_BASE + 0x40964, 0x9f9f9f); - outpdw(MDP_BASE + 0x40968, 0xa0a0a0); - outpdw(MDP_BASE + 0x4096c, 0xa0a0a0); - outpdw(MDP_BASE + 0x40970, 0xa1a1a1); - outpdw(MDP_BASE + 0x40974, 0xa2a2a2); - outpdw(MDP_BASE + 0x40978, 0xa3a3a3); - outpdw(MDP_BASE + 0x4097c, 0xa4a4a4); - outpdw(MDP_BASE + 0x40980, 0xa4a4a4); - outpdw(MDP_BASE + 0x40984, 0xa5a5a5); - outpdw(MDP_BASE + 0x40988, 0xa6a6a6); - outpdw(MDP_BASE + 0x4098c, 0xa7a7a7); - outpdw(MDP_BASE + 0x40990, 0xa7a7a7); - outpdw(MDP_BASE + 0x40994, 0xa8a8a8); - outpdw(MDP_BASE + 0x40998, 0xa9a9a9); - outpdw(MDP_BASE + 0x4099c, 0xaaaaaa); - outpdw(MDP_BASE + 0x409a0, 0xaaaaaa); - outpdw(MDP_BASE + 0x409a4, 0xababab); - outpdw(MDP_BASE + 0x409a8, 0xacacac); - outpdw(MDP_BASE + 0x409ac, 0xadadad); - outpdw(MDP_BASE + 0x409b0, 0xadadad); - outpdw(MDP_BASE + 0x409b4, 0xaeaeae); - outpdw(MDP_BASE + 0x409b8, 0xafafaf); - outpdw(MDP_BASE + 0x409bc, 0xafafaf); - outpdw(MDP_BASE + 0x409c0, 0xb0b0b0); - outpdw(MDP_BASE + 0x409c4, 0xb1b1b1); - outpdw(MDP_BASE + 0x409c8, 0xb2b2b2); - outpdw(MDP_BASE + 0x409cc, 0xb2b2b2); - outpdw(MDP_BASE + 0x409d0, 0xb3b3b3); - outpdw(MDP_BASE + 0x409d4, 0xb4b4b4); - outpdw(MDP_BASE + 0x409d8, 0xb4b4b4); - outpdw(MDP_BASE + 0x409dc, 0xb5b5b5); - outpdw(MDP_BASE + 0x409e0, 0xb6b6b6); - outpdw(MDP_BASE + 0x409e4, 0xb6b6b6); - outpdw(MDP_BASE + 0x409e8, 0xb7b7b7); - outpdw(MDP_BASE + 0x409ec, 0xb8b8b8); - outpdw(MDP_BASE + 0x409f0, 0xb8b8b8); - outpdw(MDP_BASE + 0x409f4, 0xb9b9b9); - outpdw(MDP_BASE + 0x409f8, 0xbababa); - outpdw(MDP_BASE + 0x409fc, 0xbababa); - outpdw(MDP_BASE + 0x40a00, 0xbbbbbb); - outpdw(MDP_BASE + 0x40a04, 0xbcbcbc); - outpdw(MDP_BASE + 0x40a08, 0xbcbcbc); - outpdw(MDP_BASE + 0x40a0c, 0xbdbdbd); - outpdw(MDP_BASE + 0x40a10, 0xbebebe); - outpdw(MDP_BASE + 0x40a14, 0xbebebe); - outpdw(MDP_BASE + 0x40a18, 0xbfbfbf); - outpdw(MDP_BASE + 0x40a1c, 0xc0c0c0); - outpdw(MDP_BASE + 0x40a20, 0xc0c0c0); - outpdw(MDP_BASE + 0x40a24, 0xc1c1c1); - outpdw(MDP_BASE + 0x40a28, 0xc1c1c1); - outpdw(MDP_BASE + 0x40a2c, 0xc2c2c2); - outpdw(MDP_BASE + 0x40a30, 0xc3c3c3); - outpdw(MDP_BASE + 0x40a34, 0xc3c3c3); - outpdw(MDP_BASE + 0x40a38, 0xc4c4c4); - outpdw(MDP_BASE + 0x40a3c, 0xc5c5c5); - outpdw(MDP_BASE + 0x40a40, 0xc5c5c5); - outpdw(MDP_BASE + 0x40a44, 0xc6c6c6); - outpdw(MDP_BASE + 0x40a48, 0xc6c6c6); - outpdw(MDP_BASE + 0x40a4c, 0xc7c7c7); - outpdw(MDP_BASE + 0x40a50, 0xc8c8c8); - outpdw(MDP_BASE + 0x40a54, 0xc8c8c8); - outpdw(MDP_BASE + 0x40a58, 0xc9c9c9); - outpdw(MDP_BASE + 0x40a5c, 0xc9c9c9); - outpdw(MDP_BASE + 0x40a60, 0xcacaca); - outpdw(MDP_BASE + 0x40a64, 0xcbcbcb); - outpdw(MDP_BASE + 0x40a68, 0xcbcbcb); - outpdw(MDP_BASE + 0x40a6c, 0xcccccc); - outpdw(MDP_BASE + 0x40a70, 0xcccccc); - outpdw(MDP_BASE + 0x40a74, 0xcdcdcd); - outpdw(MDP_BASE + 0x40a78, 0xcecece); - outpdw(MDP_BASE + 0x40a7c, 0xcecece); - outpdw(MDP_BASE + 0x40a80, 0xcfcfcf); - outpdw(MDP_BASE + 0x40a84, 0xcfcfcf); - outpdw(MDP_BASE + 0x40a88, 0xd0d0d0); - outpdw(MDP_BASE + 0x40a8c, 0xd0d0d0); - outpdw(MDP_BASE + 0x40a90, 0xd1d1d1); - outpdw(MDP_BASE + 0x40a94, 0xd2d2d2); - outpdw(MDP_BASE + 0x40a98, 0xd2d2d2); - outpdw(MDP_BASE + 0x40a9c, 0xd3d3d3); - outpdw(MDP_BASE + 0x40aa0, 0xd3d3d3); - outpdw(MDP_BASE + 0x40aa4, 0xd4d4d4); - outpdw(MDP_BASE + 0x40aa8, 0xd4d4d4); - outpdw(MDP_BASE + 0x40aac, 0xd5d5d5); - outpdw(MDP_BASE + 0x40ab0, 0xd6d6d6); - outpdw(MDP_BASE + 0x40ab4, 0xd6d6d6); - outpdw(MDP_BASE + 0x40ab8, 0xd7d7d7); - outpdw(MDP_BASE + 0x40abc, 0xd7d7d7); - outpdw(MDP_BASE + 0x40ac0, 0xd8d8d8); - outpdw(MDP_BASE + 0x40ac4, 0xd8d8d8); - outpdw(MDP_BASE + 0x40ac8, 0xd9d9d9); - outpdw(MDP_BASE + 0x40acc, 0xd9d9d9); - outpdw(MDP_BASE + 0x40ad0, 0xdadada); - outpdw(MDP_BASE + 0x40ad4, 0xdbdbdb); - outpdw(MDP_BASE + 0x40ad8, 0xdbdbdb); - outpdw(MDP_BASE + 0x40adc, 0xdcdcdc); - outpdw(MDP_BASE + 0x40ae0, 0xdcdcdc); - outpdw(MDP_BASE + 0x40ae4, 0xdddddd); - outpdw(MDP_BASE + 0x40ae8, 0xdddddd); - outpdw(MDP_BASE + 0x40aec, 0xdedede); - outpdw(MDP_BASE + 0x40af0, 0xdedede); - outpdw(MDP_BASE + 0x40af4, 0xdfdfdf); - outpdw(MDP_BASE + 0x40af8, 0xdfdfdf); - outpdw(MDP_BASE + 0x40afc, 0xe0e0e0); - outpdw(MDP_BASE + 0x40b00, 0xe0e0e0); - outpdw(MDP_BASE + 0x40b04, 0xe1e1e1); - outpdw(MDP_BASE + 0x40b08, 0xe1e1e1); - outpdw(MDP_BASE + 0x40b0c, 0xe2e2e2); - outpdw(MDP_BASE + 0x40b10, 0xe3e3e3); - outpdw(MDP_BASE + 0x40b14, 0xe3e3e3); - outpdw(MDP_BASE + 0x40b18, 0xe4e4e4); - outpdw(MDP_BASE + 0x40b1c, 0xe4e4e4); - outpdw(MDP_BASE + 0x40b20, 0xe5e5e5); - outpdw(MDP_BASE + 0x40b24, 0xe5e5e5); - outpdw(MDP_BASE + 0x40b28, 0xe6e6e6); - outpdw(MDP_BASE + 0x40b2c, 0xe6e6e6); - outpdw(MDP_BASE + 0x40b30, 0xe7e7e7); - outpdw(MDP_BASE + 0x40b34, 0xe7e7e7); - outpdw(MDP_BASE + 0x40b38, 0xe8e8e8); - outpdw(MDP_BASE + 0x40b3c, 0xe8e8e8); - outpdw(MDP_BASE + 0x40b40, 0xe9e9e9); - outpdw(MDP_BASE + 0x40b44, 0xe9e9e9); - outpdw(MDP_BASE + 0x40b48, 0xeaeaea); - outpdw(MDP_BASE + 0x40b4c, 0xeaeaea); - outpdw(MDP_BASE + 0x40b50, 0xebebeb); - outpdw(MDP_BASE + 0x40b54, 0xebebeb); - outpdw(MDP_BASE + 0x40b58, 0xececec); - outpdw(MDP_BASE + 0x40b5c, 0xececec); - outpdw(MDP_BASE + 0x40b60, 0xededed); - outpdw(MDP_BASE + 0x40b64, 0xededed); - outpdw(MDP_BASE + 0x40b68, 0xeeeeee); - outpdw(MDP_BASE + 0x40b6c, 0xeeeeee); - outpdw(MDP_BASE + 0x40b70, 0xefefef); - outpdw(MDP_BASE + 0x40b74, 0xefefef); - outpdw(MDP_BASE + 0x40b78, 0xf0f0f0); - outpdw(MDP_BASE + 0x40b7c, 0xf0f0f0); - outpdw(MDP_BASE + 0x40b80, 0xf1f1f1); - outpdw(MDP_BASE + 0x40b84, 0xf1f1f1); - outpdw(MDP_BASE + 0x40b88, 0xf2f2f2); - outpdw(MDP_BASE + 0x40b8c, 0xf2f2f2); - outpdw(MDP_BASE + 0x40b90, 0xf2f2f2); - outpdw(MDP_BASE + 0x40b94, 0xf3f3f3); - outpdw(MDP_BASE + 0x40b98, 0xf3f3f3); - outpdw(MDP_BASE + 0x40b9c, 0xf4f4f4); - outpdw(MDP_BASE + 0x40ba0, 0xf4f4f4); - outpdw(MDP_BASE + 0x40ba4, 0xf5f5f5); - outpdw(MDP_BASE + 0x40ba8, 0xf5f5f5); - outpdw(MDP_BASE + 0x40bac, 0xf6f6f6); - outpdw(MDP_BASE + 0x40bb0, 0xf6f6f6); - outpdw(MDP_BASE + 0x40bb4, 0xf7f7f7); - outpdw(MDP_BASE + 0x40bb8, 0xf7f7f7); - outpdw(MDP_BASE + 0x40bbc, 0xf8f8f8); - outpdw(MDP_BASE + 0x40bc0, 0xf8f8f8); - outpdw(MDP_BASE + 0x40bc4, 0xf9f9f9); - outpdw(MDP_BASE + 0x40bc8, 0xf9f9f9); - outpdw(MDP_BASE + 0x40bcc, 0xfafafa); - outpdw(MDP_BASE + 0x40bd0, 0xfafafa); - outpdw(MDP_BASE + 0x40bd4, 0xfafafa); - outpdw(MDP_BASE + 0x40bd8, 0xfbfbfb); - outpdw(MDP_BASE + 0x40bdc, 0xfbfbfb); - outpdw(MDP_BASE + 0x40be0, 0xfcfcfc); - outpdw(MDP_BASE + 0x40be4, 0xfcfcfc); - outpdw(MDP_BASE + 0x40be8, 0xfdfdfd); - outpdw(MDP_BASE + 0x40bec, 0xfdfdfd); - outpdw(MDP_BASE + 0x40bf0, 0xfefefe); - outpdw(MDP_BASE + 0x40bf4, 0xfefefe); - outpdw(MDP_BASE + 0x40bf8, 0xffffff); - outpdw(MDP_BASE + 0x40bfc, 0xffffff); - outpdw(MDP_BASE + 0x40c00, 0x0); - outpdw(MDP_BASE + 0x40c04, 0x0); - outpdw(MDP_BASE + 0x40c08, 0x0); - outpdw(MDP_BASE + 0x40c0c, 0x0); - outpdw(MDP_BASE + 0x40c10, 0x0); - outpdw(MDP_BASE + 0x40c14, 0x0); - outpdw(MDP_BASE + 0x40c18, 0x0); - outpdw(MDP_BASE + 0x40c1c, 0x0); - outpdw(MDP_BASE + 0x40c20, 0x0); - outpdw(MDP_BASE + 0x40c24, 0x0); - outpdw(MDP_BASE + 0x40c28, 0x0); - outpdw(MDP_BASE + 0x40c2c, 0x0); - outpdw(MDP_BASE + 0x40c30, 0x0); - outpdw(MDP_BASE + 0x40c34, 0x0); - outpdw(MDP_BASE + 0x40c38, 0x0); - outpdw(MDP_BASE + 0x40c3c, 0x0); - outpdw(MDP_BASE + 0x40c40, 0x10101); - outpdw(MDP_BASE + 0x40c44, 0x10101); - outpdw(MDP_BASE + 0x40c48, 0x10101); - outpdw(MDP_BASE + 0x40c4c, 0x10101); - outpdw(MDP_BASE + 0x40c50, 0x10101); - outpdw(MDP_BASE + 0x40c54, 0x10101); - outpdw(MDP_BASE + 0x40c58, 0x10101); - outpdw(MDP_BASE + 0x40c5c, 0x10101); - outpdw(MDP_BASE + 0x40c60, 0x10101); - outpdw(MDP_BASE + 0x40c64, 0x10101); - outpdw(MDP_BASE + 0x40c68, 0x20202); - outpdw(MDP_BASE + 0x40c6c, 0x20202); - outpdw(MDP_BASE + 0x40c70, 0x20202); - outpdw(MDP_BASE + 0x40c74, 0x20202); - outpdw(MDP_BASE + 0x40c78, 0x20202); - outpdw(MDP_BASE + 0x40c7c, 0x20202); - outpdw(MDP_BASE + 0x40c80, 0x30303); - outpdw(MDP_BASE + 0x40c84, 0x30303); - outpdw(MDP_BASE + 0x40c88, 0x30303); - outpdw(MDP_BASE + 0x40c8c, 0x30303); - outpdw(MDP_BASE + 0x40c90, 0x30303); - outpdw(MDP_BASE + 0x40c94, 0x40404); - outpdw(MDP_BASE + 0x40c98, 0x40404); - outpdw(MDP_BASE + 0x40c9c, 0x40404); - outpdw(MDP_BASE + 0x40ca0, 0x40404); - outpdw(MDP_BASE + 0x40ca4, 0x40404); - outpdw(MDP_BASE + 0x40ca8, 0x50505); - outpdw(MDP_BASE + 0x40cac, 0x50505); - outpdw(MDP_BASE + 0x40cb0, 0x50505); - outpdw(MDP_BASE + 0x40cb4, 0x50505); - outpdw(MDP_BASE + 0x40cb8, 0x60606); - outpdw(MDP_BASE + 0x40cbc, 0x60606); - outpdw(MDP_BASE + 0x40cc0, 0x60606); - outpdw(MDP_BASE + 0x40cc4, 0x70707); - outpdw(MDP_BASE + 0x40cc8, 0x70707); - outpdw(MDP_BASE + 0x40ccc, 0x70707); - outpdw(MDP_BASE + 0x40cd0, 0x70707); - outpdw(MDP_BASE + 0x40cd4, 0x80808); - outpdw(MDP_BASE + 0x40cd8, 0x80808); - outpdw(MDP_BASE + 0x40cdc, 0x80808); - outpdw(MDP_BASE + 0x40ce0, 0x90909); - outpdw(MDP_BASE + 0x40ce4, 0x90909); - outpdw(MDP_BASE + 0x40ce8, 0xa0a0a); - outpdw(MDP_BASE + 0x40cec, 0xa0a0a); - outpdw(MDP_BASE + 0x40cf0, 0xa0a0a); - outpdw(MDP_BASE + 0x40cf4, 0xb0b0b); - outpdw(MDP_BASE + 0x40cf8, 0xb0b0b); - outpdw(MDP_BASE + 0x40cfc, 0xb0b0b); - outpdw(MDP_BASE + 0x40d00, 0xc0c0c); - outpdw(MDP_BASE + 0x40d04, 0xc0c0c); - outpdw(MDP_BASE + 0x40d08, 0xd0d0d); - outpdw(MDP_BASE + 0x40d0c, 0xd0d0d); - outpdw(MDP_BASE + 0x40d10, 0xe0e0e); - outpdw(MDP_BASE + 0x40d14, 0xe0e0e); - outpdw(MDP_BASE + 0x40d18, 0xe0e0e); - outpdw(MDP_BASE + 0x40d1c, 0xf0f0f); - outpdw(MDP_BASE + 0x40d20, 0xf0f0f); - outpdw(MDP_BASE + 0x40d24, 0x101010); - outpdw(MDP_BASE + 0x40d28, 0x101010); - outpdw(MDP_BASE + 0x40d2c, 0x111111); - outpdw(MDP_BASE + 0x40d30, 0x111111); - outpdw(MDP_BASE + 0x40d34, 0x121212); - outpdw(MDP_BASE + 0x40d38, 0x121212); - outpdw(MDP_BASE + 0x40d3c, 0x131313); - outpdw(MDP_BASE + 0x40d40, 0x131313); - outpdw(MDP_BASE + 0x40d44, 0x141414); - outpdw(MDP_BASE + 0x40d48, 0x151515); - outpdw(MDP_BASE + 0x40d4c, 0x151515); - outpdw(MDP_BASE + 0x40d50, 0x161616); - outpdw(MDP_BASE + 0x40d54, 0x161616); - outpdw(MDP_BASE + 0x40d58, 0x171717); - outpdw(MDP_BASE + 0x40d5c, 0x171717); - outpdw(MDP_BASE + 0x40d60, 0x181818); - outpdw(MDP_BASE + 0x40d64, 0x191919); - outpdw(MDP_BASE + 0x40d68, 0x191919); - outpdw(MDP_BASE + 0x40d6c, 0x1a1a1a); - outpdw(MDP_BASE + 0x40d70, 0x1b1b1b); - outpdw(MDP_BASE + 0x40d74, 0x1b1b1b); - outpdw(MDP_BASE + 0x40d78, 0x1c1c1c); - outpdw(MDP_BASE + 0x40d7c, 0x1c1c1c); - outpdw(MDP_BASE + 0x40d80, 0x1d1d1d); - outpdw(MDP_BASE + 0x40d84, 0x1e1e1e); - outpdw(MDP_BASE + 0x40d88, 0x1f1f1f); - outpdw(MDP_BASE + 0x40d8c, 0x1f1f1f); - outpdw(MDP_BASE + 0x40d90, 0x202020); - outpdw(MDP_BASE + 0x40d94, 0x212121); - outpdw(MDP_BASE + 0x40d98, 0x212121); - outpdw(MDP_BASE + 0x40d9c, 0x222222); - outpdw(MDP_BASE + 0x40da0, 0x232323); - outpdw(MDP_BASE + 0x40da4, 0x242424); - outpdw(MDP_BASE + 0x40da8, 0x242424); - outpdw(MDP_BASE + 0x40dac, 0x252525); - outpdw(MDP_BASE + 0x40db0, 0x262626); - outpdw(MDP_BASE + 0x40db4, 0x272727); - outpdw(MDP_BASE + 0x40db8, 0x272727); - outpdw(MDP_BASE + 0x40dbc, 0x282828); - outpdw(MDP_BASE + 0x40dc0, 0x292929); - outpdw(MDP_BASE + 0x40dc4, 0x2a2a2a); - outpdw(MDP_BASE + 0x40dc8, 0x2b2b2b); - outpdw(MDP_BASE + 0x40dcc, 0x2c2c2c); - outpdw(MDP_BASE + 0x40dd0, 0x2c2c2c); - outpdw(MDP_BASE + 0x40dd4, 0x2d2d2d); - outpdw(MDP_BASE + 0x40dd8, 0x2e2e2e); - outpdw(MDP_BASE + 0x40ddc, 0x2f2f2f); - outpdw(MDP_BASE + 0x40de0, 0x303030); - outpdw(MDP_BASE + 0x40de4, 0x313131); - outpdw(MDP_BASE + 0x40de8, 0x323232); - outpdw(MDP_BASE + 0x40dec, 0x333333); - outpdw(MDP_BASE + 0x40df0, 0x333333); - outpdw(MDP_BASE + 0x40df4, 0x343434); - outpdw(MDP_BASE + 0x40df8, 0x353535); - outpdw(MDP_BASE + 0x40dfc, 0x363636); - outpdw(MDP_BASE + 0x40e00, 0x373737); - outpdw(MDP_BASE + 0x40e04, 0x383838); - outpdw(MDP_BASE + 0x40e08, 0x393939); - outpdw(MDP_BASE + 0x40e0c, 0x3a3a3a); - outpdw(MDP_BASE + 0x40e10, 0x3b3b3b); - outpdw(MDP_BASE + 0x40e14, 0x3c3c3c); - outpdw(MDP_BASE + 0x40e18, 0x3d3d3d); - outpdw(MDP_BASE + 0x40e1c, 0x3e3e3e); - outpdw(MDP_BASE + 0x40e20, 0x3f3f3f); - outpdw(MDP_BASE + 0x40e24, 0x404040); - outpdw(MDP_BASE + 0x40e28, 0x414141); - outpdw(MDP_BASE + 0x40e2c, 0x424242); - outpdw(MDP_BASE + 0x40e30, 0x434343); - outpdw(MDP_BASE + 0x40e34, 0x444444); - outpdw(MDP_BASE + 0x40e38, 0x464646); - outpdw(MDP_BASE + 0x40e3c, 0x474747); - outpdw(MDP_BASE + 0x40e40, 0x484848); - outpdw(MDP_BASE + 0x40e44, 0x494949); - outpdw(MDP_BASE + 0x40e48, 0x4a4a4a); - outpdw(MDP_BASE + 0x40e4c, 0x4b4b4b); - outpdw(MDP_BASE + 0x40e50, 0x4c4c4c); - outpdw(MDP_BASE + 0x40e54, 0x4d4d4d); - outpdw(MDP_BASE + 0x40e58, 0x4f4f4f); - outpdw(MDP_BASE + 0x40e5c, 0x505050); - outpdw(MDP_BASE + 0x40e60, 0x515151); - outpdw(MDP_BASE + 0x40e64, 0x525252); - outpdw(MDP_BASE + 0x40e68, 0x535353); - outpdw(MDP_BASE + 0x40e6c, 0x545454); - outpdw(MDP_BASE + 0x40e70, 0x565656); - outpdw(MDP_BASE + 0x40e74, 0x575757); - outpdw(MDP_BASE + 0x40e78, 0x585858); - outpdw(MDP_BASE + 0x40e7c, 0x595959); - outpdw(MDP_BASE + 0x40e80, 0x5b5b5b); - outpdw(MDP_BASE + 0x40e84, 0x5c5c5c); - outpdw(MDP_BASE + 0x40e88, 0x5d5d5d); - outpdw(MDP_BASE + 0x40e8c, 0x5e5e5e); - outpdw(MDP_BASE + 0x40e90, 0x606060); - outpdw(MDP_BASE + 0x40e94, 0x616161); - outpdw(MDP_BASE + 0x40e98, 0x626262); - outpdw(MDP_BASE + 0x40e9c, 0x646464); - outpdw(MDP_BASE + 0x40ea0, 0x656565); - outpdw(MDP_BASE + 0x40ea4, 0x666666); - outpdw(MDP_BASE + 0x40ea8, 0x686868); - outpdw(MDP_BASE + 0x40eac, 0x696969); - outpdw(MDP_BASE + 0x40eb0, 0x6a6a6a); - outpdw(MDP_BASE + 0x40eb4, 0x6c6c6c); - outpdw(MDP_BASE + 0x40eb8, 0x6d6d6d); - outpdw(MDP_BASE + 0x40ebc, 0x6f6f6f); - outpdw(MDP_BASE + 0x40ec0, 0x707070); - outpdw(MDP_BASE + 0x40ec4, 0x717171); - outpdw(MDP_BASE + 0x40ec8, 0x737373); - outpdw(MDP_BASE + 0x40ecc, 0x747474); - outpdw(MDP_BASE + 0x40ed0, 0x767676); - outpdw(MDP_BASE + 0x40ed4, 0x777777); - outpdw(MDP_BASE + 0x40ed8, 0x797979); - outpdw(MDP_BASE + 0x40edc, 0x7a7a7a); - outpdw(MDP_BASE + 0x40ee0, 0x7c7c7c); - outpdw(MDP_BASE + 0x40ee4, 0x7d7d7d); - outpdw(MDP_BASE + 0x40ee8, 0x7f7f7f); - outpdw(MDP_BASE + 0x40eec, 0x808080); - outpdw(MDP_BASE + 0x40ef0, 0x828282); - outpdw(MDP_BASE + 0x40ef4, 0x838383); - outpdw(MDP_BASE + 0x40ef8, 0x858585); - outpdw(MDP_BASE + 0x40efc, 0x868686); - outpdw(MDP_BASE + 0x40f00, 0x888888); - outpdw(MDP_BASE + 0x40f04, 0x898989); - outpdw(MDP_BASE + 0x40f08, 0x8b8b8b); - outpdw(MDP_BASE + 0x40f0c, 0x8d8d8d); - outpdw(MDP_BASE + 0x40f10, 0x8e8e8e); - outpdw(MDP_BASE + 0x40f14, 0x909090); - outpdw(MDP_BASE + 0x40f18, 0x919191); - outpdw(MDP_BASE + 0x40f1c, 0x939393); - outpdw(MDP_BASE + 0x40f20, 0x959595); - outpdw(MDP_BASE + 0x40f24, 0x969696); - outpdw(MDP_BASE + 0x40f28, 0x989898); - outpdw(MDP_BASE + 0x40f2c, 0x9a9a9a); - outpdw(MDP_BASE + 0x40f30, 0x9b9b9b); - outpdw(MDP_BASE + 0x40f34, 0x9d9d9d); - outpdw(MDP_BASE + 0x40f38, 0x9f9f9f); - outpdw(MDP_BASE + 0x40f3c, 0xa1a1a1); - outpdw(MDP_BASE + 0x40f40, 0xa2a2a2); - outpdw(MDP_BASE + 0x40f44, 0xa4a4a4); - outpdw(MDP_BASE + 0x40f48, 0xa6a6a6); - outpdw(MDP_BASE + 0x40f4c, 0xa7a7a7); - outpdw(MDP_BASE + 0x40f50, 0xa9a9a9); - outpdw(MDP_BASE + 0x40f54, 0xababab); - outpdw(MDP_BASE + 0x40f58, 0xadadad); - outpdw(MDP_BASE + 0x40f5c, 0xafafaf); - outpdw(MDP_BASE + 0x40f60, 0xb0b0b0); - outpdw(MDP_BASE + 0x40f64, 0xb2b2b2); - outpdw(MDP_BASE + 0x40f68, 0xb4b4b4); - outpdw(MDP_BASE + 0x40f6c, 0xb6b6b6); - outpdw(MDP_BASE + 0x40f70, 0xb8b8b8); - outpdw(MDP_BASE + 0x40f74, 0xbababa); - outpdw(MDP_BASE + 0x40f78, 0xbbbbbb); - outpdw(MDP_BASE + 0x40f7c, 0xbdbdbd); - outpdw(MDP_BASE + 0x40f80, 0xbfbfbf); - outpdw(MDP_BASE + 0x40f84, 0xc1c1c1); - outpdw(MDP_BASE + 0x40f88, 0xc3c3c3); - outpdw(MDP_BASE + 0x40f8c, 0xc5c5c5); - outpdw(MDP_BASE + 0x40f90, 0xc7c7c7); - outpdw(MDP_BASE + 0x40f94, 0xc9c9c9); - outpdw(MDP_BASE + 0x40f98, 0xcbcbcb); - outpdw(MDP_BASE + 0x40f9c, 0xcdcdcd); - outpdw(MDP_BASE + 0x40fa0, 0xcfcfcf); - outpdw(MDP_BASE + 0x40fa4, 0xd1d1d1); - outpdw(MDP_BASE + 0x40fa8, 0xd3d3d3); - outpdw(MDP_BASE + 0x40fac, 0xd5d5d5); - outpdw(MDP_BASE + 0x40fb0, 0xd7d7d7); - outpdw(MDP_BASE + 0x40fb4, 0xd9d9d9); - outpdw(MDP_BASE + 0x40fb8, 0xdbdbdb); - outpdw(MDP_BASE + 0x40fbc, 0xdddddd); - outpdw(MDP_BASE + 0x40fc0, 0xdfdfdf); - outpdw(MDP_BASE + 0x40fc4, 0xe1e1e1); - outpdw(MDP_BASE + 0x40fc8, 0xe3e3e3); - outpdw(MDP_BASE + 0x40fcc, 0xe5e5e5); - outpdw(MDP_BASE + 0x40fd0, 0xe7e7e7); - outpdw(MDP_BASE + 0x40fd4, 0xe9e9e9); - outpdw(MDP_BASE + 0x40fd8, 0xebebeb); - outpdw(MDP_BASE + 0x40fdc, 0xeeeeee); - outpdw(MDP_BASE + 0x40fe0, 0xf0f0f0); - outpdw(MDP_BASE + 0x40fe4, 0xf2f2f2); - outpdw(MDP_BASE + 0x40fe8, 0xf4f4f4); - outpdw(MDP_BASE + 0x40fec, 0xf6f6f6); - outpdw(MDP_BASE + 0x40ff0, 0xf8f8f8); - outpdw(MDP_BASE + 0x40ff4, 0xfbfbfb); - outpdw(MDP_BASE + 0x40ff8, 0xfdfdfd); - outpdw(MDP_BASE + 0x40ffc, 0xffffff); -} - -#define IRQ_EN_1__MDP_IRQ___M 0x00000800 - -void mdp_hw_init(void) -{ - int i; - - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - - /* debug interface write access */ - outpdw(MDP_BASE + 0x60, 1); - - outp32(MDP_INTR_ENABLE, MDP_ANY_INTR_MASK); - outp32(MDP_EBI2_PORTMAP_MODE, 0x3); - outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8, 0x0); - outpdw(MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc, 0x0); - outpdw(MDP_BASE + 0x60, 0x1); - mdp_load_lut_param(); - - /* - * clear up unused fg/main registers - */ - /* comp.plane 2&3 ystride */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0120, 0x0); - /* unpacked pattern */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x012c, 0x0); - /* unpacked pattern */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0130, 0x0); - /* unpacked pattern */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0134, 0x0); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0158, 0x0); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x15c, 0x0); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0160, 0x0); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0170, 0x0); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0174, 0x0); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x017c, 0x0); - - /* comp.plane 2 */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0114, 0x0); - /* comp.plane 3 */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0118, 0x0); - - /* clear up unused bg registers */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8, 0); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0, 0); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc, 0); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0, 0); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4, 0); - -#ifndef CONFIG_FB_MSM_MDP22 - MDP_OUTP(MDP_BASE + 0xE0000, 0); - MDP_OUTP(MDP_BASE + 0x100, 0xffffffff); - MDP_OUTP(MDP_BASE + 0x90070, 0); - MDP_OUTP(MDP_BASE + 0x94010, 1); - MDP_OUTP(MDP_BASE + 0x9401c, 2); -#endif - - /* - * limit vector - * pre gets applied before color matrix conversion - * post is after ccs - */ - writel(mdp_plv[0], MDP_CSC_PRE_LV1n(0)); - writel(mdp_plv[1], MDP_CSC_PRE_LV1n(1)); - writel(mdp_plv[2], MDP_CSC_PRE_LV1n(2)); - writel(mdp_plv[3], MDP_CSC_PRE_LV1n(3)); - -#ifdef CONFIG_FB_MSM_MDP31 - writel(mdp_plv[2], MDP_CSC_PRE_LV1n(4)); - writel(mdp_plv[3], MDP_CSC_PRE_LV1n(5)); - - writel(0, MDP_CSC_POST_LV1n(0)); - writel(0xff, MDP_CSC_POST_LV1n(1)); - writel(0, MDP_CSC_POST_LV1n(2)); - writel(0xff, MDP_CSC_POST_LV1n(3)); - writel(0, MDP_CSC_POST_LV1n(4)); - writel(0xff, MDP_CSC_POST_LV1n(5)); - - writel(0, MDP_CSC_PRE_LV2n(0)); - writel(0xff, MDP_CSC_PRE_LV2n(1)); - writel(0, MDP_CSC_PRE_LV2n(2)); - writel(0xff, MDP_CSC_PRE_LV2n(3)); - writel(0, MDP_CSC_PRE_LV2n(4)); - writel(0xff, MDP_CSC_PRE_LV2n(5)); - - writel(mdp_plv[0], MDP_CSC_POST_LV2n(0)); - writel(mdp_plv[1], MDP_CSC_POST_LV2n(1)); - writel(mdp_plv[2], MDP_CSC_POST_LV2n(2)); - writel(mdp_plv[3], MDP_CSC_POST_LV2n(3)); - writel(mdp_plv[2], MDP_CSC_POST_LV2n(4)); - writel(mdp_plv[3], MDP_CSC_POST_LV2n(5)); -#endif - - /* primary forward matrix */ - for (i = 0; i < MDP_CCS_SIZE; i++) - writel(mdp_ccs_rgb2yuv.ccs[i], MDP_CSC_PFMVn(i)); - -#ifdef CONFIG_FB_MSM_MDP31 - for (i = 0; i < MDP_BV_SIZE; i++) - writel(mdp_ccs_rgb2yuv.bv[i], MDP_CSC_POST_BV2n(i)); - - writel(0, MDP_CSC_PRE_BV2n(0)); - writel(0, MDP_CSC_PRE_BV2n(1)); - writel(0, MDP_CSC_PRE_BV2n(2)); -#endif - /* primary reverse matrix */ - for (i = 0; i < MDP_CCS_SIZE; i++) - writel(mdp_ccs_yuv2rgb.ccs[i], MDP_CSC_PRMVn(i)); - - for (i = 0; i < MDP_BV_SIZE; i++) - writel(mdp_ccs_yuv2rgb.bv[i], MDP_CSC_PRE_BV1n(i)); - -#ifdef CONFIG_FB_MSM_MDP31 - writel(0, MDP_CSC_POST_BV1n(0)); - writel(0, MDP_CSC_POST_BV1n(1)); - writel(0, MDP_CSC_POST_BV1n(2)); - - outpdw(MDP_BASE + 0x30010, 0x03e0); - outpdw(MDP_BASE + 0x30014, 0x0360); - outpdw(MDP_BASE + 0x30018, 0x0120); - outpdw(MDP_BASE + 0x3001c, 0x0140); -#endif - mdp_init_scale_table(); - -#ifndef CONFIG_FB_MSM_MDP31 - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0104, - ((16 << 6) << 16) | (16) << 6); -#endif - - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); -} \ No newline at end of file diff --git a/drivers/staging/msm/mdp_ppp.c b/drivers/staging/msm/mdp_ppp.c deleted file mode 100644 index c35a6aebca14..000000000000 --- a/drivers/staging/msm/mdp_ppp.c +++ /dev/null @@ -1,1502 +0,0 @@ -/* drivers/video/msm/src/drv/mdp/mdp_ppp.c - * - * Copyright (C) 2007 Google Incorporated - * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. - * - * 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 "linux/proc_fs.h" - -#include -#include - -#include -#include -#include - -#include "mdp.h" -#include "msm_fb.h" - -#define MDP_IS_IMGTYPE_BAD(x) (((x) >= MDP_IMGTYPE_LIMIT) && \ - (((x) < MDP_IMGTYPE2_START) || \ - ((x) >= MDP_IMGTYPE_LIMIT2))) - -static uint32_t bytes_per_pixel[] = { - [MDP_RGB_565] = 2, - [MDP_RGB_888] = 3, - [MDP_XRGB_8888] = 4, - [MDP_ARGB_8888] = 4, - [MDP_RGBA_8888] = 4, - [MDP_BGRA_8888] = 4, - [MDP_Y_CBCR_H2V1] = 1, - [MDP_Y_CBCR_H2V2] = 1, - [MDP_Y_CRCB_H2V1] = 1, - [MDP_Y_CRCB_H2V2] = 1, - [MDP_YCRYCB_H2V1] = 2, - [MDP_BGR_565] = 2 -}; - -extern uint32 mdp_plv[]; -extern struct semaphore mdp_ppp_mutex; - -uint32_t mdp_get_bytes_per_pixel(uint32_t format) -{ - uint32_t bpp = 0; - if (format < ARRAY_SIZE(bytes_per_pixel)) - bpp = bytes_per_pixel[format]; - - BUG_ON(!bpp); - return bpp; -} - -static uint32 mdp_conv_matx_rgb2yuv(uint32 input_pixel, - uint16 *matrix_and_bias_vector, - uint32 *clamp_vector, - uint32 *look_up_table) -{ - uint8 input_C2, input_C0, input_C1; - uint32 output; - int32 comp_C2, comp_C1, comp_C0, temp; - int32 temp1, temp2, temp3; - int32 matrix[9]; - int32 bias_vector[3]; - int32 Y_low_limit, Y_high_limit, C_low_limit, C_high_limit; - int32 i; - uint32 _is_lookup_table_enabled; - - input_C2 = (input_pixel >> 16) & 0xFF; - input_C1 = (input_pixel >> 8) & 0xFF; - input_C0 = (input_pixel >> 0) & 0xFF; - - comp_C0 = input_C0; - comp_C1 = input_C1; - comp_C2 = input_C2; - - for (i = 0; i < 9; i++) - matrix[i] = - ((int32) (((int32) matrix_and_bias_vector[i]) << 20)) >> 20; - - bias_vector[0] = (int32) (matrix_and_bias_vector[9] & 0xFF); - bias_vector[1] = (int32) (matrix_and_bias_vector[10] & 0xFF); - bias_vector[2] = (int32) (matrix_and_bias_vector[11] & 0xFF); - - Y_low_limit = (int32) clamp_vector[0]; - Y_high_limit = (int32) clamp_vector[1]; - C_low_limit = (int32) clamp_vector[2]; - C_high_limit = (int32) clamp_vector[3]; - - if (look_up_table == 0) /* check for NULL point */ - _is_lookup_table_enabled = 0; - else - _is_lookup_table_enabled = 1; - - if (_is_lookup_table_enabled == 1) { - comp_C2 = (look_up_table[comp_C2] >> 16) & 0xFF; - comp_C1 = (look_up_table[comp_C1] >> 8) & 0xFF; - comp_C0 = (look_up_table[comp_C0] >> 0) & 0xFF; - } - /* - * Color Conversion - * reorder input colors - */ - temp = comp_C2; - comp_C2 = comp_C1; - comp_C1 = comp_C0; - comp_C0 = temp; - - /* matrix multiplication */ - temp1 = comp_C0 * matrix[0] + comp_C1 * matrix[1] + comp_C2 * matrix[2]; - temp2 = comp_C0 * matrix[3] + comp_C1 * matrix[4] + comp_C2 * matrix[5]; - temp3 = comp_C0 * matrix[6] + comp_C1 * matrix[7] + comp_C2 * matrix[8]; - - comp_C0 = temp1 + 0x100; - comp_C1 = temp2 + 0x100; - comp_C2 = temp3 + 0x100; - - /* take interger part */ - comp_C0 >>= 9; - comp_C1 >>= 9; - comp_C2 >>= 9; - - /* post bias (+) */ - comp_C0 += bias_vector[0]; - comp_C1 += bias_vector[1]; - comp_C2 += bias_vector[2]; - - /* limit pixel to 8-bit */ - if (comp_C0 < 0) - comp_C0 = 0; - - if (comp_C0 > 255) - comp_C0 = 255; - - if (comp_C1 < 0) - comp_C1 = 0; - - if (comp_C1 > 255) - comp_C1 = 255; - - if (comp_C2 < 0) - comp_C2 = 0; - - if (comp_C2 > 255) - comp_C2 = 255; - - /* clamp */ - if (comp_C0 < Y_low_limit) - comp_C0 = Y_low_limit; - - if (comp_C0 > Y_high_limit) - comp_C0 = Y_high_limit; - - if (comp_C1 < C_low_limit) - comp_C1 = C_low_limit; - - if (comp_C1 > C_high_limit) - comp_C1 = C_high_limit; - - if (comp_C2 < C_low_limit) - comp_C2 = C_low_limit; - - if (comp_C2 > C_high_limit) - comp_C2 = C_high_limit; - - output = (comp_C2 << 16) | (comp_C1 << 8) | comp_C0; - return output; -} - -uint32 mdp_conv_matx_yuv2rgb(uint32 input_pixel, - uint16 *matrix_and_bias_vector, - uint32 *clamp_vector, uint32 *look_up_table) -{ - uint8 input_C2, input_C0, input_C1; - uint32 output; - int32 comp_C2, comp_C1, comp_C0, temp; - int32 temp1, temp2, temp3; - int32 matrix[9]; - int32 bias_vector[3]; - int32 Y_low_limit, Y_high_limit, C_low_limit, C_high_limit; - int32 i; - uint32 _is_lookup_table_enabled; - - input_C2 = (input_pixel >> 16) & 0xFF; - input_C1 = (input_pixel >> 8) & 0xFF; - input_C0 = (input_pixel >> 0) & 0xFF; - - comp_C0 = input_C0; - comp_C1 = input_C1; - comp_C2 = input_C2; - - for (i = 0; i < 9; i++) - matrix[i] = - ((int32) (((int32) matrix_and_bias_vector[i]) << 20)) >> 20; - - bias_vector[0] = (int32) (matrix_and_bias_vector[9] & 0xFF); - bias_vector[1] = (int32) (matrix_and_bias_vector[10] & 0xFF); - bias_vector[2] = (int32) (matrix_and_bias_vector[11] & 0xFF); - - Y_low_limit = (int32) clamp_vector[0]; - Y_high_limit = (int32) clamp_vector[1]; - C_low_limit = (int32) clamp_vector[2]; - C_high_limit = (int32) clamp_vector[3]; - - if (look_up_table == 0) /* check for NULL point */ - _is_lookup_table_enabled = 0; - else - _is_lookup_table_enabled = 1; - - /* clamp */ - if (comp_C0 < Y_low_limit) - comp_C0 = Y_low_limit; - - if (comp_C0 > Y_high_limit) - comp_C0 = Y_high_limit; - - if (comp_C1 < C_low_limit) - comp_C1 = C_low_limit; - - if (comp_C1 > C_high_limit) - comp_C1 = C_high_limit; - - if (comp_C2 < C_low_limit) - comp_C2 = C_low_limit; - - if (comp_C2 > C_high_limit) - comp_C2 = C_high_limit; - - /* - * Color Conversion - * pre bias (-) - */ - comp_C0 -= bias_vector[0]; - comp_C1 -= bias_vector[1]; - comp_C2 -= bias_vector[2]; - - /* matrix multiplication */ - temp1 = comp_C0 * matrix[0] + comp_C1 * matrix[1] + comp_C2 * matrix[2]; - temp2 = comp_C0 * matrix[3] + comp_C1 * matrix[4] + comp_C2 * matrix[5]; - temp3 = comp_C0 * matrix[6] + comp_C1 * matrix[7] + comp_C2 * matrix[8]; - - comp_C0 = temp1 + 0x100; - comp_C1 = temp2 + 0x100; - comp_C2 = temp3 + 0x100; - - /* take interger part */ - comp_C0 >>= 9; - comp_C1 >>= 9; - comp_C2 >>= 9; - - /* reorder output colors */ - temp = comp_C0; - comp_C0 = comp_C1; - comp_C1 = comp_C2; - comp_C2 = temp; - - /* limit pixel to 8-bit */ - if (comp_C0 < 0) - comp_C0 = 0; - - if (comp_C0 > 255) - comp_C0 = 255; - - if (comp_C1 < 0) - comp_C1 = 0; - - if (comp_C1 > 255) - comp_C1 = 255; - - if (comp_C2 < 0) - comp_C2 = 0; - - if (comp_C2 > 255) - comp_C2 = 255; - - /* Look-up table */ - if (_is_lookup_table_enabled == 1) { - comp_C2 = (look_up_table[comp_C2] >> 16) & 0xFF; - comp_C1 = (look_up_table[comp_C1] >> 8) & 0xFF; - comp_C0 = (look_up_table[comp_C0] >> 0) & 0xFF; - } - - output = (comp_C2 << 16) | (comp_C1 << 8) | comp_C0; - return output; -} - -static uint32 mdp_calc_tpval(MDPIMG *mdpImg) -{ - uint32 tpVal; - uint8 plane_tp; - - tpVal = 0; - if ((mdpImg->imgType == MDP_RGB_565) - || (mdpImg->imgType == MDP_BGR_565)) { - /* - * transparent color conversion into 24 bpp - * - * C2R_8BIT - * left shift the entire bit and or it with the upper most bits - */ - plane_tp = (uint8) ((mdpImg->tpVal & 0xF800) >> 11); - tpVal |= ((plane_tp << 3) | ((plane_tp & 0x1C) >> 2)) << 16; - - /* C1B_8BIT */ - plane_tp = (uint8) (mdpImg->tpVal & 0x1F); - tpVal |= ((plane_tp << 3) | ((plane_tp & 0x1C) >> 2)) << 8; - - /* C0G_8BIT */ - plane_tp = (uint8) ((mdpImg->tpVal & 0x7E0) >> 5); - tpVal |= ((plane_tp << 2) | ((plane_tp & 0x30) >> 4)); - } else { - /* 24bit RGB to RBG conversion */ - - tpVal = (mdpImg->tpVal & 0xFF00) >> 8; - tpVal |= (mdpImg->tpVal & 0xFF) << 8; - tpVal |= (mdpImg->tpVal & 0xFF0000); - } - - return tpVal; -} - -static uint8 *mdp_get_chroma_addr(MDPIBUF *iBuf) -{ - uint8 *dest1; - - dest1 = NULL; - switch (iBuf->ibuf_type) { - case MDP_Y_CBCR_H2V2: - case MDP_Y_CRCB_H2V2: - case MDP_Y_CBCR_H2V1: - case MDP_Y_CRCB_H2V1: - dest1 = (uint8 *) iBuf->buf; - dest1 += iBuf->ibuf_width * iBuf->ibuf_height * iBuf->bpp; - break; - - default: - break; - } - - return dest1; -} - -static void mdp_ppp_setbg(MDPIBUF *iBuf) -{ - uint8 *bg0_addr; - uint8 *bg1_addr; - uint32 bg0_ystride, bg1_ystride; - uint32 ppp_src_cfg_reg, unpack_pattern; - int v_slice, h_slice; - - v_slice = h_slice = 1; - bg0_addr = (uint8 *) iBuf->buf; - bg1_addr = mdp_get_chroma_addr(iBuf); - - bg0_ystride = iBuf->ibuf_width * iBuf->bpp; - bg1_ystride = iBuf->ibuf_width * iBuf->bpp; - - switch (iBuf->ibuf_type) { - case MDP_BGR_565: - case MDP_RGB_565: - /* 888 = 3bytes - * RGB = 3Components - * RGB interleaved - */ - ppp_src_cfg_reg = PPP_SRC_C2R_5BITS | PPP_SRC_C0G_6BITS | - PPP_SRC_C1B_5BITS | PPP_SRC_BPP_INTERLVD_2BYTES | - PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT | - PPP_SRC_UNPACK_ALIGN_LSB | - PPP_SRC_FETCH_PLANES_INTERLVD; - - if (iBuf->ibuf_type == MDP_RGB_565) - unpack_pattern = - MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8); - else - unpack_pattern = - MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8); - break; - - case MDP_RGB_888: - /* - * 888 = 3bytes - * RGB = 3Components - * RGB interleaved - */ - ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS | - PPP_SRC_C1B_8BITS | PPP_SRC_BPP_INTERLVD_3BYTES | - PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT | - PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_INTERLVD; - - unpack_pattern = - MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8); - break; - - case MDP_BGRA_8888: - case MDP_RGBA_8888: - case MDP_ARGB_8888: - case MDP_XRGB_8888: - /* - * 8888 = 4bytes - * ARGB = 4Components - * ARGB interleaved - */ - ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS | - PPP_SRC_C1B_8BITS | PPP_SRC_C3A_8BITS | PPP_SRC_C3_ALPHA_EN | - PPP_SRC_BPP_INTERLVD_4BYTES | PPP_SRC_INTERLVD_4COMPONENTS | - PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB | - PPP_SRC_FETCH_PLANES_INTERLVD; - - if (iBuf->ibuf_type == MDP_BGRA_8888) - unpack_pattern = - MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, - 8); - else if (iBuf->ibuf_type == MDP_RGBA_8888) - unpack_pattern = - MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, - 8); - else - unpack_pattern = - MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, - 8); - break; - - case MDP_Y_CBCR_H2V2: - case MDP_Y_CRCB_H2V2: - ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | - PPP_SRC_C0G_8BITS | - PPP_SRC_C1B_8BITS | - PPP_SRC_C3A_8BITS | - PPP_SRC_BPP_INTERLVD_2BYTES | - PPP_SRC_INTERLVD_2COMPONENTS | - PPP_SRC_UNPACK_TIGHT | - PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_PSEUDOPLNR; - - if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1) - unpack_pattern = - MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8); - else - unpack_pattern = - MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8); - v_slice = h_slice = 2; - break; - - case MDP_YCRYCB_H2V1: - ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | - PPP_SRC_C0G_8BITS | - PPP_SRC_C1B_8BITS | - PPP_SRC_C3A_8BITS | - PPP_SRC_BPP_INTERLVD_2BYTES | - PPP_SRC_INTERLVD_4COMPONENTS | - PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB; - - unpack_pattern = - MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8); - h_slice = 2; - break; - - case MDP_Y_CBCR_H2V1: - case MDP_Y_CRCB_H2V1: - ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | - PPP_SRC_C0G_8BITS | - PPP_SRC_C1B_8BITS | - PPP_SRC_C3A_8BITS | - PPP_SRC_BPP_INTERLVD_2BYTES | - PPP_SRC_INTERLVD_2COMPONENTS | - PPP_SRC_UNPACK_TIGHT | - PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_PSEUDOPLNR; - - if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1) - unpack_pattern = - MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8); - else - unpack_pattern = - MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8); - h_slice = 2; - break; - - default: - return; - } - - /* starting input address adjustment */ - mdp_adjust_start_addr(&bg0_addr, &bg1_addr, v_slice, h_slice, - iBuf->roi.lcd_x, iBuf->roi.lcd_y, - iBuf->ibuf_width, iBuf->ibuf_height, iBuf->bpp, - iBuf, 1); - - /* - * 0x01c0: background plane 0 addr - * 0x01c4: background plane 1 addr - * 0x01c8: background plane 2 addr - * 0x01cc: bg y stride for plane 0 and 1 - * 0x01d0: bg y stride for plane 2 - * 0x01d4: bg src PPP config - * 0x01d8: unpack pattern - */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c0, bg0_addr); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01c4, bg1_addr); - - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01cc, - (bg1_ystride << 16) | bg0_ystride); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d4, ppp_src_cfg_reg); - - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01d8, unpack_pattern); -} - -#define IS_PSEUDOPLNR(img) ((img == MDP_Y_CRCB_H2V2) | \ - (img == MDP_Y_CBCR_H2V2) | \ - (img == MDP_Y_CRCB_H2V1) | \ - (img == MDP_Y_CBCR_H2V1)) - -#define IMG_LEN(rect_h, w, rect_w, bpp) (((rect_h) * w) * bpp) - -#define Y_TO_CRCB_RATIO(format) \ - ((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CRCB_H2V2) ? 2 :\ - (format == MDP_Y_CBCR_H2V1 || format == MDP_Y_CRCB_H2V1) ? 1 : 1) - -static void get_len(struct mdp_img *img, struct mdp_rect *rect, uint32_t bpp, - uint32_t *len0, uint32_t *len1) -{ - *len0 = IMG_LEN(rect->h, img->width, rect->w, bpp); - if (IS_PSEUDOPLNR(img->format)) - *len1 = *len0/Y_TO_CRCB_RATIO(img->format); - else - *len1 = 0; -} - -static void flush_imgs(struct mdp_blit_req *req, int src_bpp, int dst_bpp, - struct file *p_src_file, struct file *p_dst_file) -{ -#ifdef CONFIG_ANDROID_PMEM - uint32_t src0_len, src1_len, dst0_len, dst1_len; - - /* flush src images to memory before dma to mdp */ - get_len(&req->src, &req->src_rect, src_bpp, - &src0_len, &src1_len); - - flush_pmem_file(p_src_file, - req->src.offset, src0_len); - - if (IS_PSEUDOPLNR(req->src.format)) - flush_pmem_file(p_src_file, - req->src.offset + src0_len, src1_len); - - get_len(&req->dst, &req->dst_rect, dst_bpp, &dst0_len, &dst1_len); - flush_pmem_file(p_dst_file, req->dst.offset, dst0_len); - - if (IS_PSEUDOPLNR(req->dst.format)) - flush_pmem_file(p_dst_file, - req->dst.offset + dst0_len, dst1_len); -#endif -} - -static void mdp_start_ppp(struct msm_fb_data_type *mfd, MDPIBUF *iBuf, -struct mdp_blit_req *req, struct file *p_src_file, struct file *p_dst_file) -{ - uint8 *src0, *src1; - uint8 *dest0, *dest1; - uint16 inpBpp; - uint32 dest0_ystride; - uint32 src_width; - uint32 src_height; - uint32 src0_ystride; - uint32 dst_roi_width; - uint32 dst_roi_height; - uint32 ppp_src_cfg_reg, ppp_operation_reg, ppp_dst_cfg_reg; - uint32 alpha, tpVal; - uint32 packPattern; - uint32 dst_packPattern; - boolean inputRGB, outputRGB, pseudoplanr_output; - int sv_slice, sh_slice; - int dv_slice, dh_slice; - boolean perPixelAlpha = FALSE; - boolean ppp_lookUp_enable = FALSE; - - sv_slice = sh_slice = dv_slice = dh_slice = 1; - alpha = tpVal = 0; - src_width = iBuf->mdpImg.width; - src_height = iBuf->roi.y + iBuf->roi.height; - src1 = NULL; - dest1 = NULL; - - inputRGB = outputRGB = TRUE; - pseudoplanr_output = FALSE; - ppp_operation_reg = 0; - ppp_dst_cfg_reg = 0; - ppp_src_cfg_reg = 0; - - /* Wait for the pipe to clear */ - do { } while (mdp_ppp_pipe_wait() <= 0); - - /* - * destination config - */ - switch (iBuf->ibuf_type) { - case MDP_RGB_888: - dst_packPattern = - MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8); - ppp_dst_cfg_reg = - PPP_DST_C0G_8BIT | PPP_DST_C1B_8BIT | PPP_DST_C2R_8BIT | - PPP_DST_PACKET_CNT_INTERLVD_3ELEM | PPP_DST_PACK_TIGHT | - PPP_DST_PACK_ALIGN_LSB | PPP_DST_OUT_SEL_AXI | - PPP_DST_BPP_3BYTES | PPP_DST_PLANE_INTERLVD; - break; - - case MDP_XRGB_8888: - case MDP_ARGB_8888: - case MDP_RGBA_8888: - if (iBuf->ibuf_type == MDP_BGRA_8888) - dst_packPattern = - MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, - 8); - else if (iBuf->ibuf_type == MDP_RGBA_8888) - dst_packPattern = - MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, - 8); - else - dst_packPattern = - MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, - 8); - - ppp_dst_cfg_reg = PPP_DST_C0G_8BIT | - PPP_DST_C1B_8BIT | - PPP_DST_C2R_8BIT | - PPP_DST_C3A_8BIT | - PPP_DST_C3ALPHA_EN | - PPP_DST_PACKET_CNT_INTERLVD_4ELEM | - PPP_DST_PACK_TIGHT | - PPP_DST_PACK_ALIGN_LSB | - PPP_DST_OUT_SEL_AXI | - PPP_DST_BPP_4BYTES | PPP_DST_PLANE_INTERLVD; - break; - - case MDP_Y_CBCR_H2V2: - case MDP_Y_CRCB_H2V2: - if (iBuf->ibuf_type == MDP_Y_CBCR_H2V2) - dst_packPattern = - MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8); - else - dst_packPattern = - MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8); - - ppp_dst_cfg_reg = PPP_DST_C2R_8BIT | - PPP_DST_C0G_8BIT | - PPP_DST_C1B_8BIT | - PPP_DST_C3A_8BIT | - PPP_DST_PACKET_CNT_INTERLVD_2ELEM | - PPP_DST_PACK_TIGHT | - PPP_DST_PACK_ALIGN_LSB | - PPP_DST_OUT_SEL_AXI | PPP_DST_BPP_2BYTES; - - ppp_operation_reg |= PPP_OP_DST_CHROMA_420; - outputRGB = FALSE; - pseudoplanr_output = TRUE; - /* - * vertically (y direction) and horizontally (x direction) - * sample reduction by 2 - */ - - /* - * H2V2(YUV420) Cosite - * - * Y Y Y Y - * CbCr CbCr - * Y Y Y Y - * Y Y Y Y - * CbCr CbCr - * Y Y Y Y - */ - dv_slice = dh_slice = 2; - - /* (x,y) and (width,height) must be even numbern */ - iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2; - iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2; - iBuf->roi.x = (iBuf->roi.x / 2) * 2; - iBuf->roi.width = (iBuf->roi.width / 2) * 2; - - iBuf->roi.lcd_y = (iBuf->roi.lcd_y / 2) * 2; - iBuf->roi.dst_height = (iBuf->roi.dst_height / 2) * 2; - iBuf->roi.y = (iBuf->roi.y / 2) * 2; - iBuf->roi.height = (iBuf->roi.height / 2) * 2; - break; - - case MDP_YCRYCB_H2V1: - dst_packPattern = - MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8); - ppp_dst_cfg_reg = - PPP_DST_C2R_8BIT | PPP_DST_C0G_8BIT | PPP_DST_C1B_8BIT | - PPP_DST_C3A_8BIT | PPP_DST_PACKET_CNT_INTERLVD_4ELEM | - PPP_DST_PACK_TIGHT | PPP_DST_PACK_ALIGN_LSB | - PPP_DST_OUT_SEL_AXI | PPP_DST_BPP_2BYTES | - PPP_DST_PLANE_INTERLVD; - - ppp_operation_reg |= PPP_OP_DST_CHROMA_H2V1; - outputRGB = FALSE; - /* - * horizontally (x direction) sample reduction by 2 - * - * H2V1(YUV422) Cosite - * - * YCbCr Y YCbCr Y - * YCbCr Y YCbCr Y - * YCbCr Y YCbCr Y - * YCbCr Y YCbCr Y - */ - dh_slice = 2; - - /* - * if it's TV-Out/MDP_YCRYCB_H2V1, let's go through the - * preloaded gamma setting of 2.2 when the content is - * non-linear ppp_lookUp_enable = TRUE; - */ - - /* x and width must be even number */ - iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2; - iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2; - iBuf->roi.x = (iBuf->roi.x / 2) * 2; - iBuf->roi.width = (iBuf->roi.width / 2) * 2; - break; - - case MDP_Y_CBCR_H2V1: - case MDP_Y_CRCB_H2V1: - if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1) - dst_packPattern = - MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8); - else - dst_packPattern = - MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8); - - ppp_dst_cfg_reg = PPP_DST_C2R_8BIT | - PPP_DST_C0G_8BIT | - PPP_DST_C1B_8BIT | - PPP_DST_C3A_8BIT | - PPP_DST_PACKET_CNT_INTERLVD_2ELEM | - PPP_DST_PACK_TIGHT | - PPP_DST_PACK_ALIGN_LSB | - PPP_DST_OUT_SEL_AXI | PPP_DST_BPP_2BYTES; - - ppp_operation_reg |= PPP_OP_DST_CHROMA_H2V1; - outputRGB = FALSE; - pseudoplanr_output = TRUE; - /* horizontally (x direction) sample reduction by 2 */ - dh_slice = 2; - - /* x and width must be even number */ - iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2; - iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2; - iBuf->roi.x = (iBuf->roi.x / 2) * 2; - iBuf->roi.width = (iBuf->roi.width / 2) * 2; - break; - - case MDP_BGR_565: - case MDP_RGB_565: - default: - if (iBuf->ibuf_type == MDP_RGB_565) - dst_packPattern = - MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8); - else - dst_packPattern = - MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8); - - ppp_dst_cfg_reg = PPP_DST_C0G_6BIT | - PPP_DST_C1B_5BIT | - PPP_DST_C2R_5BIT | - PPP_DST_PACKET_CNT_INTERLVD_3ELEM | - PPP_DST_PACK_TIGHT | - PPP_DST_PACK_ALIGN_LSB | - PPP_DST_OUT_SEL_AXI | - PPP_DST_BPP_2BYTES | PPP_DST_PLANE_INTERLVD; - break; - } - - /* source config */ - switch (iBuf->mdpImg.imgType) { - case MDP_RGB_888: - inpBpp = 3; - /* - * 565 = 2bytes - * RGB = 3Components - * RGB interleaved - */ - ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS | - PPP_SRC_C1B_8BITS | PPP_SRC_BPP_INTERLVD_3BYTES | - PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT | - PPP_SRC_UNPACK_ALIGN_LSB | - PPP_SRC_FETCH_PLANES_INTERLVD; - - packPattern = MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8); - - ppp_operation_reg |= PPP_OP_COLOR_SPACE_RGB | - PPP_OP_SRC_CHROMA_RGB | PPP_OP_DST_CHROMA_RGB; - break; - - case MDP_BGRA_8888: - case MDP_RGBA_8888: - case MDP_ARGB_8888: - perPixelAlpha = TRUE; - case MDP_XRGB_8888: - inpBpp = 4; - /* - * 8888 = 4bytes - * ARGB = 4Components - * ARGB interleaved - */ - ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS | - PPP_SRC_C1B_8BITS | PPP_SRC_C3A_8BITS | - PPP_SRC_C3_ALPHA_EN | PPP_SRC_BPP_INTERLVD_4BYTES | - PPP_SRC_INTERLVD_4COMPONENTS | PPP_SRC_UNPACK_TIGHT | - PPP_SRC_UNPACK_ALIGN_LSB | - PPP_SRC_FETCH_PLANES_INTERLVD; - - if (iBuf->mdpImg.imgType == MDP_BGRA_8888) - packPattern = - MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, - 8); - else if (iBuf->mdpImg.imgType == MDP_RGBA_8888) - packPattern = - MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R, - 8); - else - packPattern = - MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B, - 8); - - ppp_operation_reg |= PPP_OP_COLOR_SPACE_RGB | - PPP_OP_SRC_CHROMA_RGB | PPP_OP_DST_CHROMA_RGB; - break; - - case MDP_Y_CBCR_H2V2: - case MDP_Y_CRCB_H2V2: - inpBpp = 1; - src1 = (uint8 *) iBuf->mdpImg.cbcr_addr; - - /* - * CbCr = 2bytes - * CbCr = 2Components - * Y+CbCr - */ - ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | PPP_SRC_C0G_8BITS | - PPP_SRC_C1B_8BITS | PPP_SRC_BPP_INTERLVD_2BYTES | - PPP_SRC_INTERLVD_2COMPONENTS | PPP_SRC_UNPACK_TIGHT | - PPP_SRC_UNPACK_ALIGN_LSB | - PPP_SRC_FETCH_PLANES_PSEUDOPLNR; - - if (iBuf->mdpImg.imgType == MDP_Y_CRCB_H2V2) - packPattern = - MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8); - else - packPattern = - MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8); - - ppp_operation_reg |= PPP_OP_COLOR_SPACE_YCBCR | - PPP_OP_SRC_CHROMA_420 | - PPP_OP_SRC_CHROMA_COSITE | - PPP_OP_DST_CHROMA_RGB | PPP_OP_DST_CHROMA_COSITE; - - inputRGB = FALSE; - sh_slice = sv_slice = 2; - break; - - case MDP_YCRYCB_H2V1: - inpBpp = 2; - ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | - PPP_SRC_C0G_8BITS | - PPP_SRC_C1B_8BITS | - PPP_SRC_C3A_8BITS | - PPP_SRC_BPP_INTERLVD_2BYTES | - PPP_SRC_INTERLVD_4COMPONENTS | - PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB; - - packPattern = - MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8); - - ppp_operation_reg |= PPP_OP_SRC_CHROMA_H2V1 | - PPP_OP_SRC_CHROMA_COSITE | PPP_OP_DST_CHROMA_COSITE; - - /* - * if it's TV-Out/MDP_YCRYCB_H2V1, let's go through the - * preloaded inverse gamma setting of 2.2 since they're - * symetric when the content is non-linear - * ppp_lookUp_enable = TRUE; - */ - - /* x and width must be even number */ - iBuf->roi.lcd_x = (iBuf->roi.lcd_x / 2) * 2; - iBuf->roi.dst_width = (iBuf->roi.dst_width / 2) * 2; - iBuf->roi.x = (iBuf->roi.x / 2) * 2; - iBuf->roi.width = (iBuf->roi.width / 2) * 2; - - inputRGB = FALSE; - sh_slice = 2; - break; - - case MDP_Y_CBCR_H2V1: - case MDP_Y_CRCB_H2V1: - inpBpp = 1; - src1 = (uint8 *) iBuf->mdpImg.cbcr_addr; - - ppp_src_cfg_reg = PPP_SRC_C2R_8BITS | - PPP_SRC_C0G_8BITS | - PPP_SRC_C1B_8BITS | - PPP_SRC_C3A_8BITS | - PPP_SRC_BPP_INTERLVD_2BYTES | - PPP_SRC_INTERLVD_2COMPONENTS | - PPP_SRC_UNPACK_TIGHT | - PPP_SRC_UNPACK_ALIGN_LSB | PPP_SRC_FETCH_PLANES_PSEUDOPLNR; - - if (iBuf->mdpImg.imgType == MDP_Y_CBCR_H2V1) - packPattern = - MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8); - else - packPattern = - MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8); - - ppp_operation_reg |= PPP_OP_SRC_CHROMA_H2V1 | - PPP_OP_SRC_CHROMA_COSITE | PPP_OP_DST_CHROMA_COSITE; - inputRGB = FALSE; - sh_slice = 2; - break; - - case MDP_BGR_565: - case MDP_RGB_565: - default: - inpBpp = 2; - /* - * 565 = 2bytes - * RGB = 3Components - * RGB interleaved - */ - ppp_src_cfg_reg = PPP_SRC_C2R_5BITS | PPP_SRC_C0G_6BITS | - PPP_SRC_C1B_5BITS | PPP_SRC_BPP_INTERLVD_2BYTES | - PPP_SRC_INTERLVD_3COMPONENTS | PPP_SRC_UNPACK_TIGHT | - PPP_SRC_UNPACK_ALIGN_LSB | - PPP_SRC_FETCH_PLANES_INTERLVD; - - if (iBuf->mdpImg.imgType == MDP_RGB_565) - packPattern = - MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8); - else - packPattern = - MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8); - - ppp_operation_reg |= PPP_OP_COLOR_SPACE_RGB | - PPP_OP_SRC_CHROMA_RGB | PPP_OP_DST_CHROMA_RGB; - break; - - } - - if (pseudoplanr_output) - ppp_dst_cfg_reg |= PPP_DST_PLANE_PSEUDOPLN; - - /* YCbCr to RGB color conversion flag */ - if ((!inputRGB) && (outputRGB)) { - ppp_operation_reg |= PPP_OP_CONVERT_YCBCR2RGB | - PPP_OP_CONVERT_ON; - - /* - * primary/secondary is sort of misleading term...but - * in mdp2.2/3.0 we only use primary matrix (forward/rev) - * in mdp3.1 we use set1(prim) and set2(secd) - */ -#ifdef CONFIG_FB_MSM_MDP31 - ppp_operation_reg |= PPP_OP_CONVERT_MATRIX_SECONDARY | - PPP_OP_DST_RGB; - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0240, 0); -#endif - - if (ppp_lookUp_enable) { - ppp_operation_reg |= PPP_OP_LUT_C0_ON | - PPP_OP_LUT_C1_ON | PPP_OP_LUT_C2_ON; - } - } - /* RGB to YCbCr color conversion flag */ - if ((inputRGB) && (!outputRGB)) { - ppp_operation_reg |= PPP_OP_CONVERT_RGB2YCBCR | - PPP_OP_CONVERT_ON; - -#ifdef CONFIG_FB_MSM_MDP31 - ppp_operation_reg |= PPP_OP_CONVERT_MATRIX_PRIMARY | - PPP_OP_DST_YCBCR; - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0240, 0x1e); -#endif - - if (ppp_lookUp_enable) { - ppp_operation_reg |= PPP_OP_LUT_C0_ON | - PPP_OP_LUT_C1_ON | PPP_OP_LUT_C2_ON; - } - } - /* YCbCr to YCbCr color conversion flag */ - if ((!inputRGB) && (!outputRGB)) { - if ((ppp_lookUp_enable) && - (iBuf->mdpImg.imgType != iBuf->ibuf_type)) { - ppp_operation_reg |= PPP_OP_LUT_C0_ON; - } - } - - ppp_src_cfg_reg |= (iBuf->roi.x % 2) ? PPP_SRC_BPP_ROI_ODD_X : 0; - ppp_src_cfg_reg |= (iBuf->roi.y % 2) ? PPP_SRC_BPP_ROI_ODD_Y : 0; - - if (req->flags & MDP_DEINTERLACE) - ppp_operation_reg |= PPP_OP_DEINT_EN; - - /* Dither at DMA side only since iBuf format is RGB888 */ - if (iBuf->mdpImg.mdpOp & MDPOP_DITHER) - ppp_operation_reg |= PPP_OP_DITHER_EN; - - if (iBuf->mdpImg.mdpOp & MDPOP_ROTATION) { - ppp_operation_reg |= PPP_OP_ROT_ON; - - if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) { - ppp_operation_reg |= PPP_OP_ROT_90; - } - if (iBuf->mdpImg.mdpOp & MDPOP_LR) { - ppp_operation_reg |= PPP_OP_FLIP_LR; - } - if (iBuf->mdpImg.mdpOp & MDPOP_UD) { - ppp_operation_reg |= PPP_OP_FLIP_UD; - } - } - - src0_ystride = src_width * inpBpp; - dest0_ystride = iBuf->ibuf_width * iBuf->bpp; - - /* no need to care about rotation since it's the real-XY. */ - dst_roi_width = iBuf->roi.dst_width; - dst_roi_height = iBuf->roi.dst_height; - - src0 = (uint8 *) iBuf->mdpImg.bmy_addr; - dest0 = (uint8 *) iBuf->buf; - - /* Jumping from Y-Plane to Chroma Plane */ - dest1 = mdp_get_chroma_addr(iBuf); - - /* first pixel addr calculation */ - mdp_adjust_start_addr(&src0, &src1, sv_slice, sh_slice, iBuf->roi.x, - iBuf->roi.y, src_width, src_height, inpBpp, iBuf, - 0); - mdp_adjust_start_addr(&dest0, &dest1, dv_slice, dh_slice, - iBuf->roi.lcd_x, iBuf->roi.lcd_y, - iBuf->ibuf_width, iBuf->ibuf_height, iBuf->bpp, - iBuf, 2); - - /* set scale operation */ - mdp_set_scale(iBuf, dst_roi_width, dst_roi_height, - inputRGB, outputRGB, &ppp_operation_reg); - - /* - * setting background source for blending - */ - mdp_set_blend_attr(iBuf, &alpha, &tpVal, perPixelAlpha, - &ppp_operation_reg); - - if (ppp_operation_reg & PPP_OP_BLEND_ON) { - mdp_ppp_setbg(iBuf); - - if (iBuf->ibuf_type == MDP_YCRYCB_H2V1) { - ppp_operation_reg |= PPP_OP_BG_CHROMA_H2V1; - - if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP) { - tpVal = mdp_conv_matx_rgb2yuv(tpVal, - (uint16 *) & - mdp_ccs_rgb2yuv, - &mdp_plv[0], NULL); - } - } - } - - /* - * 0x0004: enable dbg bus - * 0x0100: "don't care" Edge Condit until scaling is on - * 0x0104: xrc tile x&y size u7.6 format = 7bit.6bit - * 0x0108: src pixel size - * 0x010c: component plane 0 starting address - * 0x011c: component plane 0 ystride - * 0x0124: PPP source config register - * 0x0128: unpacked pattern from lsb to msb (eg. RGB->BGR) - */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0108, (iBuf->roi.height << 16 | - iBuf->roi.width)); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x010c, src0); /* comp.plane 0 */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0110, src1); /* comp.plane 1 */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x011c, - (src0_ystride << 16 | src0_ystride)); - - /* setup for rgb 565 */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0124, ppp_src_cfg_reg); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0128, packPattern); - /* - * 0x0138: PPP destination operation register - * 0x014c: constant_alpha|transparent_color - * 0x0150: PPP destination config register - * 0x0154: PPP packing pattern - */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0138, ppp_operation_reg); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x014c, alpha << 24 | tpVal); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0150, ppp_dst_cfg_reg); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0154, dst_packPattern); - - /* - * 0x0164: ROI height and width - * 0x0168: Component Plane 0 starting addr - * 0x016c: Component Plane 1 starting addr - * 0x0178: Component Plane 1/0 y stride - */ - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0164, - (dst_roi_height << 16 | dst_roi_width)); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0168, dest0); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x016c, dest1); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0178, - (dest0_ystride << 16 | dest0_ystride)); - - flush_imgs(req, inpBpp, iBuf->bpp, p_src_file, p_dst_file); -#ifdef CONFIG_MDP_PPP_ASYNC_OP - mdp_ppp_process_curr_djob(); -#else - mdp_pipe_kickoff(MDP_PPP_TERM, mfd); -#endif -} - -static int mdp_ppp_verify_req(struct mdp_blit_req *req) -{ - u32 src_width, src_height, dst_width, dst_height; - - if (req == NULL) - return -1; - - if (MDP_IS_IMGTYPE_BAD(req->src.format) || - MDP_IS_IMGTYPE_BAD(req->dst.format)) - return -1; - - if ((req->src.width == 0) || (req->src.height == 0) || - (req->src_rect.w == 0) || (req->src_rect.h == 0) || - (req->dst.width == 0) || (req->dst.height == 0) || - (req->dst_rect.w == 0) || (req->dst_rect.h == 0)) - - return -1; - - if (((req->src_rect.x + req->src_rect.w) > req->src.width) || - ((req->src_rect.y + req->src_rect.h) > req->src.height)) - return -1; - - if (((req->dst_rect.x + req->dst_rect.w) > req->dst.width) || - ((req->dst_rect.y + req->dst_rect.h) > req->dst.height)) - return -1; - - /* - * scaling range check - */ - src_width = req->src_rect.w; - src_height = req->src_rect.h; - - if (req->flags & MDP_ROT_90) { - dst_width = req->dst_rect.h; - dst_height = req->dst_rect.w; - } else { - dst_width = req->dst_rect.w; - dst_height = req->dst_rect.h; - } - - switch (req->dst.format) { - case MDP_Y_CRCB_H2V2: - case MDP_Y_CBCR_H2V2: - src_width = (src_width / 2) * 2; - src_height = (src_height / 2) * 2; - dst_width = (src_width / 2) * 2; - dst_height = (src_height / 2) * 2; - break; - - case MDP_Y_CRCB_H2V1: - case MDP_Y_CBCR_H2V1: - case MDP_YCRYCB_H2V1: - src_width = (src_width / 2) * 2; - dst_width = (src_width / 2) * 2; - break; - - default: - break; - } - - if (((MDP_SCALE_Q_FACTOR * dst_width) / src_width > - MDP_MAX_X_SCALE_FACTOR) - || ((MDP_SCALE_Q_FACTOR * dst_width) / src_width < - MDP_MIN_X_SCALE_FACTOR)) - return -1; - - if (((MDP_SCALE_Q_FACTOR * dst_height) / src_height > - MDP_MAX_Y_SCALE_FACTOR) - || ((MDP_SCALE_Q_FACTOR * dst_height) / src_height < - MDP_MIN_Y_SCALE_FACTOR)) - return -1; - - return 0; -} - -/** - * get_gem_img() - retrieve drm obj's start address and size - * @img: contains drm file descriptor and gem handle - * @start: repository of starting address of drm obj allocated memory - * @len: repository of size of drm obj alloacted memory - * - **/ -int get_gem_img(struct mdp_img *img, unsigned long *start, unsigned long *len) -{ - panic("waaaaaaaah"); - //return kgsl_gem_obj_addr(img->memory_id, (int)img->priv, start, len); -} - -int get_img(struct mdp_img *img, struct fb_info *info, unsigned long *start, - unsigned long *len, struct file **pp_file) -{ - int put_needed, ret = 0; - struct file *file; - unsigned long vstart; -#ifdef CONFIG_ANDROID_PMEM - if (!get_pmem_file(img->memory_id, start, &vstart, len, pp_file)) - return 0; -#endif - file = fget_light(img->memory_id, &put_needed); - if (file == NULL) - return -1; - - if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) { - *start = info->fix.smem_start; - *len = info->fix.smem_len; - *pp_file = file; - } else { - ret = -1; - fput_light(file, put_needed); - } - return ret; -} - -int mdp_ppp_blit(struct fb_info *info, struct mdp_blit_req *req, - struct file **pp_src_file, struct file **pp_dst_file) -{ - unsigned long src_start, dst_start; - unsigned long src_len = 0; - unsigned long dst_len = 0; - MDPIBUF iBuf; - u32 dst_width, dst_height; - struct file *p_src_file = 0 , *p_dst_file = 0; - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - - if (req->dst.format == MDP_FB_FORMAT) - req->dst.format = mfd->fb_imgType; - if (req->src.format == MDP_FB_FORMAT) - req->src.format = mfd->fb_imgType; - - if (req->flags & MDP_BLIT_SRC_GEM) { - if (get_gem_img(&req->src, &src_start, &src_len) < 0) - return -1; - } else { - get_img(&req->src, info, &src_start, &src_len, &p_src_file); - } - if (src_len == 0) { - printk(KERN_ERR "mdp_ppp: could not retrieve image from " - "memory\n"); - return -1; - } - - if (req->flags & MDP_BLIT_DST_GEM) { - if (get_gem_img(&req->dst, &dst_start, &dst_len) < 0) - return -1; - } else { - get_img(&req->dst, info, &dst_start, &dst_len, &p_dst_file); - } - if (dst_len == 0) { - printk(KERN_ERR "mdp_ppp: could not retrieve image from " - "memory\n"); - return -1; - } - *pp_src_file = p_src_file; - *pp_dst_file = p_dst_file; - if (mdp_ppp_verify_req(req)) { - printk(KERN_ERR "mdp_ppp: invalid image!\n"); - return -1; - } - - iBuf.ibuf_width = req->dst.width; - iBuf.ibuf_height = req->dst.height; - iBuf.bpp = bytes_per_pixel[req->dst.format]; - - iBuf.ibuf_type = req->dst.format; - iBuf.buf = (uint8 *) dst_start; - iBuf.buf += req->dst.offset; - - iBuf.roi.lcd_x = req->dst_rect.x; - iBuf.roi.lcd_y = req->dst_rect.y; - iBuf.roi.dst_width = req->dst_rect.w; - iBuf.roi.dst_height = req->dst_rect.h; - - iBuf.roi.x = req->src_rect.x; - iBuf.roi.width = req->src_rect.w; - iBuf.roi.y = req->src_rect.y; - iBuf.roi.height = req->src_rect.h; - - iBuf.mdpImg.width = req->src.width; - iBuf.mdpImg.imgType = req->src.format; - - iBuf.mdpImg.bmy_addr = (uint32 *) (src_start + req->src.offset); - iBuf.mdpImg.cbcr_addr = - (uint32 *) ((uint32) iBuf.mdpImg.bmy_addr + - req->src.width * req->src.height); - - iBuf.mdpImg.mdpOp = MDPOP_NOP; - - /* blending check */ - if (req->transp_mask != MDP_TRANSP_NOP) { - iBuf.mdpImg.mdpOp |= MDPOP_TRANSP; - iBuf.mdpImg.tpVal = req->transp_mask; - iBuf.mdpImg.tpVal = mdp_calc_tpval(&iBuf.mdpImg); - } - - req->alpha &= 0xff; - if (req->alpha < MDP_ALPHA_NOP) { - iBuf.mdpImg.mdpOp |= MDPOP_ALPHAB; - iBuf.mdpImg.alpha = req->alpha; - } - - /* rotation check */ - if (req->flags & MDP_FLIP_LR) - iBuf.mdpImg.mdpOp |= MDPOP_LR; - if (req->flags & MDP_FLIP_UD) - iBuf.mdpImg.mdpOp |= MDPOP_UD; - if (req->flags & MDP_ROT_90) - iBuf.mdpImg.mdpOp |= MDPOP_ROT90; - if (req->flags & MDP_DITHER) - iBuf.mdpImg.mdpOp |= MDPOP_DITHER; - - if (req->flags & MDP_BLEND_FG_PREMULT) { -#ifdef CONFIG_FB_MSM_MDP31 - iBuf.mdpImg.mdpOp |= MDPOP_FG_PM_ALPHA; -#else - return -EINVAL; -#endif - } - - if (req->flags & MDP_DEINTERLACE) { -#ifdef CONFIG_FB_MSM_MDP31 - if ((req->src.format != MDP_Y_CBCR_H2V2) && - (req->src.format != MDP_Y_CRCB_H2V2)) -#endif - return -EINVAL; - } - - /* scale check */ - if (req->flags & MDP_ROT_90) { - dst_width = req->dst_rect.h; - dst_height = req->dst_rect.w; - } else { - dst_width = req->dst_rect.w; - dst_height = req->dst_rect.h; - } - - if ((iBuf.roi.width != dst_width) || (iBuf.roi.height != dst_height)) - iBuf.mdpImg.mdpOp |= MDPOP_ASCALE; - - if (req->flags & MDP_BLUR) { -#ifdef CONFIG_FB_MSM_MDP31 - if (req->flags & MDP_SHARPENING) - printk(KERN_WARNING - "mdp: MDP_SHARPENING is set with MDP_BLUR!\n"); - req->flags |= MDP_SHARPENING; - req->sharpening_strength = -127; -#else - iBuf.mdpImg.mdpOp |= MDPOP_ASCALE | MDPOP_BLUR; - -#endif - } - - if (req->flags & MDP_SHARPENING) { -#ifdef CONFIG_FB_MSM_MDP31 - if ((req->sharpening_strength > 127) || - (req->sharpening_strength < -127)) { - printk(KERN_ERR - "%s: sharpening strength out of range\n", - __func__); - return -EINVAL; - } - - iBuf.mdpImg.mdpOp |= MDPOP_ASCALE | MDPOP_SHARPENING; - iBuf.mdpImg.sp_value = req->sharpening_strength & 0xff; -#else - return -EINVAL; -#endif - } - - down(&mdp_ppp_mutex); - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - -#ifdef CONFIG_FB_MSM_MDP31 - mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file); -#else - /* bg tile fetching HW workaround */ - if (((iBuf.mdpImg.mdpOp & (MDPOP_TRANSP | MDPOP_ALPHAB)) || - (req->src.format == MDP_ARGB_8888) || - (req->src.format == MDP_BGRA_8888) || - (req->src.format == MDP_RGBA_8888)) && - (iBuf.mdpImg.mdpOp & MDPOP_ROT90) && (req->dst_rect.w <= 16)) { - int dst_h, src_w, i; - - src_w = req->src_rect.w; - dst_h = iBuf.roi.dst_height; - - for (i = 0; i < (req->dst_rect.h / 16); i++) { - /* this tile size */ - iBuf.roi.dst_height = 16; - iBuf.roi.width = - (16 * req->src_rect.w) / req->dst_rect.h; - - /* if it's out of scale range... */ - if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) / - iBuf.roi.width) > MDP_MAX_X_SCALE_FACTOR) - iBuf.roi.width = - (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) / - MDP_MAX_X_SCALE_FACTOR; - else if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) / - iBuf.roi.width) < MDP_MIN_X_SCALE_FACTOR) - iBuf.roi.width = - (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) / - MDP_MIN_X_SCALE_FACTOR; - - mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file); - - /* next tile location */ - iBuf.roi.lcd_y += 16; - iBuf.roi.x += iBuf.roi.width; - - /* this is for a remainder update */ - dst_h -= 16; - src_w -= iBuf.roi.width; - } - - if ((dst_h < 0) || (src_w < 0)) - printk - ("msm_fb: mdp_blt_ex() unexpected result! line:%d\n", - __LINE__); - - /* remainder update */ - if ((dst_h > 0) && (src_w > 0)) { - u32 tmp_v; - - iBuf.roi.dst_height = dst_h; - iBuf.roi.width = src_w; - - if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) / - iBuf.roi.width) > MDP_MAX_X_SCALE_FACTOR) { - tmp_v = - (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) / - MDP_MAX_X_SCALE_FACTOR + - (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) % - MDP_MAX_X_SCALE_FACTOR ? 1 : 0; - - /* move x location as roi width gets bigger */ - iBuf.roi.x -= tmp_v - iBuf.roi.width; - iBuf.roi.width = tmp_v; - } else - if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) / - iBuf.roi.width) < MDP_MIN_X_SCALE_FACTOR) { - tmp_v = - (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) / - MDP_MIN_X_SCALE_FACTOR + - (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) % - MDP_MIN_X_SCALE_FACTOR ? 1 : 0; - - /* - * we don't move x location for continuity of - * source image - */ - iBuf.roi.width = tmp_v; - } - - mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file); - } - } else { - mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file); - } -#endif - - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - up(&mdp_ppp_mutex); - - return 0; -} diff --git a/drivers/staging/msm/mdp_ppp_dq.c b/drivers/staging/msm/mdp_ppp_dq.c deleted file mode 100644 index 3a687c7a5695..000000000000 --- a/drivers/staging/msm/mdp_ppp_dq.c +++ /dev/null @@ -1,347 +0,0 @@ -/* Copyright (c) 2009-2010, 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "mdp.h" - -static boolean mdp_ppp_intr_flag = FALSE; -static boolean mdp_ppp_busy_flag = FALSE; - -/* Queue to keep track of the completed jobs for cleaning */ -static LIST_HEAD(mdp_ppp_djob_clnrq); -static DEFINE_SPINLOCK(mdp_ppp_djob_clnrq_lock); - -/* Worker to cleanup Display Jobs */ -static struct workqueue_struct *mdp_ppp_djob_clnr; - -/* Display Queue (DQ) for MDP PPP Block */ -static LIST_HEAD(mdp_ppp_dq); -static DEFINE_SPINLOCK(mdp_ppp_dq_lock); - -/* Current Display Job for MDP PPP */ -static struct mdp_ppp_djob *curr_djob; - -/* Track ret code for the last opeartion */ -static int mdp_ppp_ret_code; - -inline int mdp_ppp_get_ret_code(void) -{ - return mdp_ppp_ret_code; -} - -/* Push pair into DQ (if available) to later - * program the MDP PPP Block */ -inline void mdp_ppp_outdw(uint32_t addr, uint32_t data) -{ - if (curr_djob) { - - /* get the last node of the list. */ - struct mdp_ppp_roi_cmd_set *node = - list_entry(curr_djob->roi_cmd_list.prev, - struct mdp_ppp_roi_cmd_set, node); - - /* If a node is already full, create a new one and add it to - * the list (roi_cmd_list). - */ - if (node->ncmds == MDP_PPP_ROI_NODE_SIZE) { - node = kmalloc(sizeof(struct mdp_ppp_roi_cmd_set), - GFP_KERNEL); - if (!node) { - printk(KERN_ERR - "MDP_PPP: not enough memory.\n"); - mdp_ppp_ret_code = -EINVAL; - return; - } - - /* no ROI commands initially */ - node->ncmds = 0; - - /* add one node to roi_cmd_list. */ - list_add_tail(&node->node, &curr_djob->roi_cmd_list); - } - - /* register ROI commands */ - node->cmd[node->ncmds].reg = addr; - node->cmd[node->ncmds].val = data; - node->ncmds++; - } else - /* program MDP PPP block now */ - outpdw((addr), (data)); -} - -/* Initialize DQ */ -inline void mdp_ppp_dq_init(void) -{ - mdp_ppp_djob_clnr = create_singlethread_workqueue("MDPDJobClnrThrd"); -} - -/* Release resources of a job (DJob). */ -static void mdp_ppp_del_djob(struct mdp_ppp_djob *job) -{ - struct mdp_ppp_roi_cmd_set *node, *tmp; - - /* release mem */ - mdp_ppp_put_img(job->p_src_file, job->p_dst_file); - - /* release roi_cmd_list */ - list_for_each_entry_safe(node, tmp, &job->roi_cmd_list, node) { - list_del(&node->node); - kfree(node); - } - - /* release job struct */ - kfree(job); -} - -/* Worker thread to reclaim resources once a display job is done */ -static void mdp_ppp_djob_cleaner(struct work_struct *work) -{ - struct mdp_ppp_djob *job; - - MDP_PPP_DEBUG_MSG("mdp ppp display job cleaner started \n"); - - /* cleanup display job */ - job = container_of(work, struct mdp_ppp_djob, cleaner.work); - if (likely(work && job)) - mdp_ppp_del_djob(job); -} - -/* Create a new Display Job (DJob) */ -inline struct mdp_ppp_djob *mdp_ppp_new_djob(void) -{ - struct mdp_ppp_djob *job; - struct mdp_ppp_roi_cmd_set *node; - - /* create a new djob */ - job = kmalloc(sizeof(struct mdp_ppp_djob), GFP_KERNEL); - if (!job) - return NULL; - - /* add the first node to curr_djob->roi_cmd_list */ - node = kmalloc(sizeof(struct mdp_ppp_roi_cmd_set), GFP_KERNEL); - if (!node) { - kfree(job); - return NULL; - } - - /* make this current djob container to keep track of the curr djob not - * used in the async path i.e. no sync needed - * - * Should not contain any references from the past djob - */ - BUG_ON(curr_djob); - curr_djob = job; - INIT_LIST_HEAD(&curr_djob->roi_cmd_list); - - /* no ROI commands initially */ - node->ncmds = 0; - INIT_LIST_HEAD(&node->node); - list_add_tail(&node->node, &curr_djob->roi_cmd_list); - - /* register this djob with the djob cleaner - * initializes 'work' data struct - */ - INIT_DELAYED_WORK(&curr_djob->cleaner, mdp_ppp_djob_cleaner); - INIT_LIST_HEAD(&curr_djob->entry); - - curr_djob->p_src_file = 0; - curr_djob->p_dst_file = 0; - - return job; -} - -/* Undo the effect of mdp_ppp_new_djob() */ -inline void mdp_ppp_clear_curr_djob(void) -{ - if (likely(curr_djob)) { - mdp_ppp_del_djob(curr_djob); - curr_djob = NULL; - } -} - -/* Cleanup dirty djobs */ -static void mdp_ppp_flush_dirty_djobs(void *cond) -{ - unsigned long flags; - struct mdp_ppp_djob *job; - - /* Flush the jobs from the djob clnr queue */ - while (cond && test_bit(0, (unsigned long *)cond)) { - - /* Until we are done with the cleanup queue */ - spin_lock_irqsave(&mdp_ppp_djob_clnrq_lock, flags); - if (list_empty(&mdp_ppp_djob_clnrq)) { - spin_unlock_irqrestore(&mdp_ppp_djob_clnrq_lock, flags); - break; - } - - MDP_PPP_DEBUG_MSG("flushing djobs ... loop \n"); - - /* Retrieve the job that needs to be cleaned */ - job = list_entry(mdp_ppp_djob_clnrq.next, - struct mdp_ppp_djob, entry); - list_del_init(&job->entry); - spin_unlock_irqrestore(&mdp_ppp_djob_clnrq_lock, flags); - - /* Keep mem state coherent */ - msm_fb_ensure_mem_coherency_after_dma(job->info, &job->req, 1); - - /* Schedule jobs for cleanup - * A separate worker thread does this */ - queue_delayed_work(mdp_ppp_djob_clnr, &job->cleaner, - mdp_timer_duration); - } -} - -/* If MDP PPP engine is busy, wait until it is available again */ -void mdp_ppp_wait(void) -{ - unsigned long flags; - int cond = 1; - - /* keep flushing dirty djobs as long as MDP PPP engine is busy */ - mdp_ppp_flush_dirty_djobs(&mdp_ppp_busy_flag); - - /* block if MDP PPP engine is still busy */ - spin_lock_irqsave(&mdp_ppp_dq_lock, flags); - if (test_bit(0, (unsigned long *)&mdp_ppp_busy_flag)) { - - /* prepare for the wakeup event */ - test_and_set_bit(0, (unsigned long *)&mdp_ppp_waiting); - INIT_COMPLETION(mdp_ppp_comp); - spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags); - - /* block uninterruptibly until available */ - MDP_PPP_DEBUG_MSG("waiting for mdp... \n"); - wait_for_completion_killable(&mdp_ppp_comp); - - /* if MDP PPP engine is still free, - * disable INT_MDP if enabled - */ - spin_lock_irqsave(&mdp_ppp_dq_lock, flags); - if (!test_bit(0, (unsigned long *)&mdp_ppp_busy_flag) && - test_and_clear_bit(0, (unsigned long *)&mdp_ppp_intr_flag)) - mdp_disable_irq(MDP_PPP_TERM); - } - spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags); - - /* flush remaining dirty djobs, if any */ - mdp_ppp_flush_dirty_djobs(&cond); -} - -/* Program MDP PPP block to process this ROI */ -static void mdp_ppp_process_roi(struct list_head *roi_cmd_list) -{ - - /* program PPP engine with registered ROI commands */ - struct mdp_ppp_roi_cmd_set *node; - list_for_each_entry(node, roi_cmd_list, node) { - int i = 0; - for (; i < node->ncmds; i++) { - MDP_PPP_DEBUG_MSG("%d: reg: 0x%x val: 0x%x \n", - i, node->cmd[i].reg, node->cmd[i].val); - outpdw(node->cmd[i].reg, node->cmd[i].val); - } - } - - /* kickoff MDP PPP engine */ - MDP_PPP_DEBUG_MSG("kicking off mdp \n"); - outpdw(MDP_BASE + 0x30, 0x1000); -} - -/* Submit this display job to MDP PPP engine */ -static void mdp_ppp_dispatch_djob(struct mdp_ppp_djob *job) -{ - /* enable INT_MDP if disabled */ - if (!test_and_set_bit(0, (unsigned long *)&mdp_ppp_intr_flag)) - mdp_enable_irq(MDP_PPP_TERM); - - /* turn on PPP and CMD blocks */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - - /* process this ROI */ - mdp_ppp_process_roi(&job->roi_cmd_list); -} - -/* Enqueue this display job to be cleaned up later in "mdp_ppp_djob_done" */ -static inline void mdp_ppp_enqueue_djob(struct mdp_ppp_djob *job) -{ - unsigned long flags; - - spin_lock_irqsave(&mdp_ppp_dq_lock, flags); - list_add_tail(&job->entry, &mdp_ppp_dq); - spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags); -} - -/* First enqueue display job for cleanup and dispatch immediately - * if MDP PPP engine is free */ -void mdp_ppp_process_curr_djob(void) -{ - /* enqueue djob */ - mdp_ppp_enqueue_djob(curr_djob); - - /* dispatch now if MDP PPP engine is free */ - if (!test_and_set_bit(0, (unsigned long *)&mdp_ppp_busy_flag)) - mdp_ppp_dispatch_djob(curr_djob); - - /* done with the current djob */ - curr_djob = NULL; -} - -/* Called from mdp_isr - cleanup finished job and start with next - * if available else set MDP PPP engine free */ -void mdp_ppp_djob_done(void) -{ - struct mdp_ppp_djob *curr, *next; - unsigned long flags; - - /* dequeue current */ - spin_lock_irqsave(&mdp_ppp_dq_lock, flags); - curr = list_entry(mdp_ppp_dq.next, struct mdp_ppp_djob, entry); - list_del_init(&curr->entry); - spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags); - - /* cleanup current - enqueue in the djob clnr queue */ - spin_lock_irqsave(&mdp_ppp_djob_clnrq_lock, flags); - list_add_tail(&curr->entry, &mdp_ppp_djob_clnrq); - spin_unlock_irqrestore(&mdp_ppp_djob_clnrq_lock, flags); - - /* grab next pending */ - spin_lock_irqsave(&mdp_ppp_dq_lock, flags); - if (!list_empty(&mdp_ppp_dq)) { - next = list_entry(mdp_ppp_dq.next, struct mdp_ppp_djob, - entry); - spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags); - - /* process next in the queue */ - mdp_ppp_process_roi(&next->roi_cmd_list); - } else { - /* no pending display job */ - spin_unlock_irqrestore(&mdp_ppp_dq_lock, flags); - - /* turn off PPP and CMD blocks - "in_isr" is TRUE */ - mdp_pipe_ctrl(MDP_PPP_BLOCK, MDP_BLOCK_POWER_OFF, TRUE); - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, TRUE); - - /* notify if waiting */ - if (test_and_clear_bit(0, (unsigned long *)&mdp_ppp_waiting)) - complete(&mdp_ppp_comp); - - /* set free */ - test_and_clear_bit(0, (unsigned long *)&mdp_ppp_busy_flag); - } -} diff --git a/drivers/staging/msm/mdp_ppp_dq.h b/drivers/staging/msm/mdp_ppp_dq.h deleted file mode 100644 index 759abc20e9ff..000000000000 --- a/drivers/staging/msm/mdp_ppp_dq.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 2009-2010, 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 and - * only 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. - */ - -#ifndef MDP_PPP_DQ_H -#define MDP_PPP_DQ_H - -#include "msm_fb_def.h" - -#define MDP_PPP_DEBUG_MSG MSM_FB_DEBUG - -/* The maximum number of pairs in an mdp_ppp_roi_cmd_set structure (a - * node) - */ -#define MDP_PPP_ROI_NODE_SIZE 32 - -/* ROI config command ( pair) for MDP PPP block */ -struct mdp_ppp_roi_cmd { - uint32_t reg; - uint32_t val; -}; - -/* ROI config commands for MDP PPP block are stored in a list of - * mdp_ppp_roi_cmd_set structures (nodes). - */ -struct mdp_ppp_roi_cmd_set { - struct list_head node; - uint32_t ncmds; /* number of commands in this set (node). */ - struct mdp_ppp_roi_cmd cmd[MDP_PPP_ROI_NODE_SIZE]; -}; - -/* MDP PPP Display Job (DJob) */ -struct mdp_ppp_djob { - struct list_head entry; - /* One ROI per MDP PPP DJob */ - struct list_head roi_cmd_list; - struct mdp_blit_req req; - struct fb_info *info; - struct delayed_work cleaner; - struct file *p_src_file, *p_dst_file; -}; - -extern struct completion mdp_ppp_comp; -extern boolean mdp_ppp_waiting; -extern unsigned long mdp_timer_duration; - -unsigned int mdp_ppp_async_op_get(void); -void mdp_ppp_async_op_set(unsigned int flag); -void msm_fb_ensure_mem_coherency_after_dma(struct fb_info *info, - struct mdp_blit_req *req_list, int req_list_count); -void mdp_ppp_put_img(struct file *p_src_file, struct file *p_dst_file); -void mdp_ppp_dq_init(void); -void mdp_ppp_outdw(uint32_t addr, uint32_t data); -struct mdp_ppp_djob *mdp_ppp_new_djob(void); -void mdp_ppp_clear_curr_djob(void); -void mdp_ppp_process_curr_djob(void); -int mdp_ppp_get_ret_code(void); -void mdp_ppp_djob_done(void); -void mdp_ppp_wait(void); - -#endif /* MDP_PPP_DQ_H */ diff --git a/drivers/staging/msm/mdp_ppp_v20.c b/drivers/staging/msm/mdp_ppp_v20.c deleted file mode 100644 index b5b7271921e0..000000000000 --- a/drivers/staging/msm/mdp_ppp_v20.c +++ /dev/null @@ -1,2486 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "linux/proc_fs.h" - -#include -#include - -#include -#include -#include -#include - -#include "mdp.h" -#include "msm_fb.h" - -static MDP_SCALE_MODE mdp_curr_up_scale_xy; -static MDP_SCALE_MODE mdp_curr_down_scale_x; -static MDP_SCALE_MODE mdp_curr_down_scale_y; - -static long long mdp_do_div(long long num, long long den) -{ - do_div(num, den); - return num; -} - -struct mdp_table_entry mdp_gaussian_blur_table[] = { - /* max variance */ - { 0x5fffc, 0x20000080 }, - { 0x50280, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50284, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50288, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x5028c, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50290, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50294, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50298, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x5029c, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502a0, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502a4, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502a8, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502ac, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502b0, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502b4, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502b8, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502bc, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502c0, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502c4, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502c8, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502cc, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502d0, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502d4, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502d8, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502dc, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502e0, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502e4, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502e8, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502ec, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502f0, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502f4, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502f8, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x502fc, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50300, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50304, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50308, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x5030c, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50310, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50314, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50318, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x5031c, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50320, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50324, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50328, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x5032c, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50330, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50334, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50338, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x5033c, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50340, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50344, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50348, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x5034c, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50350, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50354, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50358, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x5035c, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50360, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50364, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50368, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x5036c, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50370, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50374, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x50378, 0x20000080 }, - { 0x5fffc, 0x20000080 }, - { 0x5037c, 0x20000080 }, -}; - -static void load_scale_table( - struct mdp_table_entry *table, int len) -{ - int i; - for (i = 0; i < len; i++) - MDP_OUTP(MDP_BASE + table[i].reg, table[i].val); -} - -static void mdp_load_pr_upscale_table(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50200, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50204, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50208, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5020c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50210, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50214, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50218, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5021c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50220, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50224, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50228, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5022c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50230, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50234, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50238, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5023c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50240, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50244, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50248, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5024c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50250, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50254, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50258, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5025c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50260, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50264, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50268, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5026c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50270, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50274, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50278, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5027c, 0x0); -} - -static void mdp_load_pr_downscale_table_x_point2TOpoint4(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50284, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50288, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5028c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50290, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50294, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50298, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5029c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502a0, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502a4, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502a8, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502ac, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502b0, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502b4, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502b8, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502bc, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502c0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502c4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502c8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502cc, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502d0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502d4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502d8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502dc, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502e0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502e4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502e8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502ec, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502f0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502f4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502f8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502fc, 0x0); -} - -static void mdp_load_pr_downscale_table_y_point2TOpoint4(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50304, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50308, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5030c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50310, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50314, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50318, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5031c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50320, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50324, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50328, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5032c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50330, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50334, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50338, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5033c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50340, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50344, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50348, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5034c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50350, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50354, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50358, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5035c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50360, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50364, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50368, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5036c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50370, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50374, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50378, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5037c, 0x0); -} - -static void mdp_load_pr_downscale_table_x_point4TOpoint6(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50284, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50288, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5028c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50290, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50294, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50298, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5029c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502a0, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502a4, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502a8, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502ac, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502b0, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502b4, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502b8, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502bc, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502c0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502c4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502c8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502cc, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502d0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502d4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502d8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502dc, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502e0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502e4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502e8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502ec, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502f0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502f4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502f8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502fc, 0x0); -} - -static void mdp_load_pr_downscale_table_y_point4TOpoint6(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50304, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50308, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5030c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50310, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50314, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50318, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5031c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50320, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50324, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50328, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5032c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50330, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50334, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50338, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5033c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50340, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50344, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50348, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5034c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50350, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50354, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50358, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5035c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50360, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50364, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50368, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5036c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50370, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50374, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50378, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5037c, 0x0); -} - -static void mdp_load_pr_downscale_table_x_point6TOpoint8(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50284, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50288, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5028c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50290, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50294, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50298, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5029c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502a0, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502a4, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502a8, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502ac, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502b0, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502b4, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502b8, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502bc, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502c0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502c4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502c8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502cc, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502d0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502d4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502d8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502dc, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502e0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502e4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502e8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502ec, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502f0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502f4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502f8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502fc, 0x0); -} - -static void mdp_load_pr_downscale_table_y_point6TOpoint8(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50304, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50308, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5030c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50310, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50314, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50318, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5031c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50320, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50324, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50328, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5032c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50330, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50334, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50338, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5033c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50340, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50344, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50348, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5034c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50350, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50354, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50358, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5035c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50360, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50364, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50368, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5036c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50370, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50374, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50378, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5037c, 0x0); -} - -static void mdp_load_pr_downscale_table_x_point8TO1(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50284, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50288, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5028c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50290, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50294, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50298, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5029c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502a0, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502a4, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502a8, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502ac, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502b0, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502b4, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502b8, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x502bc, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502c0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502c4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502c8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502cc, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502d0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502d4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502d8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502dc, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502e0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502e4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502e8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502ec, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502f0, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502f4, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502f8, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x502fc, 0x0); -} - -static void mdp_load_pr_downscale_table_y_point8TO1(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50304, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50308, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5030c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50310, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50314, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50318, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5031c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50320, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50324, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50328, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5032c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50330, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50334, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50338, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x5033c, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50340, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50344, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50348, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5034c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50350, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50354, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50358, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5035c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50360, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50364, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50368, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5036c, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50370, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50374, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x50378, 0x0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ff); - MDP_OUTP(MDP_BASE + 0x5037c, 0x0); -} - -static void mdp_load_bc_upscale_table(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50200, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xff80000d); - MDP_OUTP(MDP_BASE + 0x50204, 0x7ec003f9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec0001c); - MDP_OUTP(MDP_BASE + 0x50208, 0x7d4003f3); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40002b); - MDP_OUTP(MDP_BASE + 0x5020c, 0x7b8003ed); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfd80003c); - MDP_OUTP(MDP_BASE + 0x50210, 0x794003e8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc0004d); - MDP_OUTP(MDP_BASE + 0x50214, 0x76c003e4); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfc40005f); - MDP_OUTP(MDP_BASE + 0x50218, 0x73c003e0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb800071); - MDP_OUTP(MDP_BASE + 0x5021c, 0x708003de); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfac00085); - MDP_OUTP(MDP_BASE + 0x50220, 0x6d0003db); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa000098); - MDP_OUTP(MDP_BASE + 0x50224, 0x698003d9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf98000ac); - MDP_OUTP(MDP_BASE + 0x50228, 0x654003d8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8c000c1); - MDP_OUTP(MDP_BASE + 0x5022c, 0x610003d7); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf84000d5); - MDP_OUTP(MDP_BASE + 0x50230, 0x5c8003d7); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf7c000e9); - MDP_OUTP(MDP_BASE + 0x50234, 0x580003d7); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf74000fd); - MDP_OUTP(MDP_BASE + 0x50238, 0x534003d8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c00112); - MDP_OUTP(MDP_BASE + 0x5023c, 0x4e8003d8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6800126); - MDP_OUTP(MDP_BASE + 0x50240, 0x494003da); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600013a); - MDP_OUTP(MDP_BASE + 0x50244, 0x448003db); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600014d); - MDP_OUTP(MDP_BASE + 0x50248, 0x3f4003dd); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00160); - MDP_OUTP(MDP_BASE + 0x5024c, 0x3a4003df); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00172); - MDP_OUTP(MDP_BASE + 0x50250, 0x354003e1); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00184); - MDP_OUTP(MDP_BASE + 0x50254, 0x304003e3); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6000195); - MDP_OUTP(MDP_BASE + 0x50258, 0x2b0003e6); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf64001a6); - MDP_OUTP(MDP_BASE + 0x5025c, 0x260003e8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c001b4); - MDP_OUTP(MDP_BASE + 0x50260, 0x214003eb); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf78001c2); - MDP_OUTP(MDP_BASE + 0x50264, 0x1c4003ee); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf80001cf); - MDP_OUTP(MDP_BASE + 0x50268, 0x17c003f1); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf90001db); - MDP_OUTP(MDP_BASE + 0x5026c, 0x134003f3); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa0001e5); - MDP_OUTP(MDP_BASE + 0x50270, 0xf0003f6); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb4001ee); - MDP_OUTP(MDP_BASE + 0x50274, 0xac003f9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc001f5); - MDP_OUTP(MDP_BASE + 0x50278, 0x70003fb); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe4001fb); - MDP_OUTP(MDP_BASE + 0x5027c, 0x34003fe); -} - -static void mdp_load_bc_downscale_table_x_point2TOpoint4(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ac00084); - MDP_OUTP(MDP_BASE + 0x50280, 0x23400083); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b000084); - MDP_OUTP(MDP_BASE + 0x50284, 0x23000083); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b400084); - MDP_OUTP(MDP_BASE + 0x50288, 0x23000082); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b400085); - MDP_OUTP(MDP_BASE + 0x5028c, 0x23000081); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b800085); - MDP_OUTP(MDP_BASE + 0x50290, 0x23000080); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1bc00086); - MDP_OUTP(MDP_BASE + 0x50294, 0x22c0007f); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c000086); - MDP_OUTP(MDP_BASE + 0x50298, 0x2280007f); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c400086); - MDP_OUTP(MDP_BASE + 0x5029c, 0x2280007e); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c800086); - MDP_OUTP(MDP_BASE + 0x502a0, 0x2280007d); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc00086); - MDP_OUTP(MDP_BASE + 0x502a4, 0x2240007d); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc00087); - MDP_OUTP(MDP_BASE + 0x502a8, 0x2240007c); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d000087); - MDP_OUTP(MDP_BASE + 0x502ac, 0x2240007b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d400087); - MDP_OUTP(MDP_BASE + 0x502b0, 0x2200007b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d400088); - MDP_OUTP(MDP_BASE + 0x502b4, 0x22400079); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d800088); - MDP_OUTP(MDP_BASE + 0x502b8, 0x22400078); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc00088); - MDP_OUTP(MDP_BASE + 0x502bc, 0x22400077); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc00089); - MDP_OUTP(MDP_BASE + 0x502c0, 0x22000077); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1e000089); - MDP_OUTP(MDP_BASE + 0x502c4, 0x22000076); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1e400089); - MDP_OUTP(MDP_BASE + 0x502c8, 0x22000075); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec00088); - MDP_OUTP(MDP_BASE + 0x502cc, 0x21c00075); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec00089); - MDP_OUTP(MDP_BASE + 0x502d0, 0x21c00074); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f000089); - MDP_OUTP(MDP_BASE + 0x502d4, 0x21c00073); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f400089); - MDP_OUTP(MDP_BASE + 0x502d8, 0x21800073); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f40008a); - MDP_OUTP(MDP_BASE + 0x502dc, 0x21800072); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f80008a); - MDP_OUTP(MDP_BASE + 0x502e0, 0x21800071); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1fc0008a); - MDP_OUTP(MDP_BASE + 0x502e4, 0x21800070); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1fc0008b); - MDP_OUTP(MDP_BASE + 0x502e8, 0x2180006f); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x2000008c); - MDP_OUTP(MDP_BASE + 0x502ec, 0x2140006e); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x2040008c); - MDP_OUTP(MDP_BASE + 0x502f0, 0x2140006d); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x2080008c); - MDP_OUTP(MDP_BASE + 0x502f4, 0x2100006d); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x20c0008c); - MDP_OUTP(MDP_BASE + 0x502f8, 0x2100006c); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x20c0008d); - MDP_OUTP(MDP_BASE + 0x502fc, 0x2100006b); -} - -static void mdp_load_bc_downscale_table_y_point2TOpoint4(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ac00084); - MDP_OUTP(MDP_BASE + 0x50300, 0x23400083); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b000084); - MDP_OUTP(MDP_BASE + 0x50304, 0x23000083); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b400084); - MDP_OUTP(MDP_BASE + 0x50308, 0x23000082); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b400085); - MDP_OUTP(MDP_BASE + 0x5030c, 0x23000081); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1b800085); - MDP_OUTP(MDP_BASE + 0x50310, 0x23000080); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1bc00086); - MDP_OUTP(MDP_BASE + 0x50314, 0x22c0007f); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c000086); - MDP_OUTP(MDP_BASE + 0x50318, 0x2280007f); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c400086); - MDP_OUTP(MDP_BASE + 0x5031c, 0x2280007e); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1c800086); - MDP_OUTP(MDP_BASE + 0x50320, 0x2280007d); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc00086); - MDP_OUTP(MDP_BASE + 0x50324, 0x2240007d); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc00087); - MDP_OUTP(MDP_BASE + 0x50328, 0x2240007c); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d000087); - MDP_OUTP(MDP_BASE + 0x5032c, 0x2240007b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d400087); - MDP_OUTP(MDP_BASE + 0x50330, 0x2200007b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d400088); - MDP_OUTP(MDP_BASE + 0x50334, 0x22400079); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1d800088); - MDP_OUTP(MDP_BASE + 0x50338, 0x22400078); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc00088); - MDP_OUTP(MDP_BASE + 0x5033c, 0x22400077); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc00089); - MDP_OUTP(MDP_BASE + 0x50340, 0x22000077); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1e000089); - MDP_OUTP(MDP_BASE + 0x50344, 0x22000076); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1e400089); - MDP_OUTP(MDP_BASE + 0x50348, 0x22000075); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec00088); - MDP_OUTP(MDP_BASE + 0x5034c, 0x21c00075); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec00089); - MDP_OUTP(MDP_BASE + 0x50350, 0x21c00074); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f000089); - MDP_OUTP(MDP_BASE + 0x50354, 0x21c00073); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f400089); - MDP_OUTP(MDP_BASE + 0x50358, 0x21800073); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f40008a); - MDP_OUTP(MDP_BASE + 0x5035c, 0x21800072); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1f80008a); - MDP_OUTP(MDP_BASE + 0x50360, 0x21800071); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1fc0008a); - MDP_OUTP(MDP_BASE + 0x50364, 0x21800070); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1fc0008b); - MDP_OUTP(MDP_BASE + 0x50368, 0x2180006f); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x2000008c); - MDP_OUTP(MDP_BASE + 0x5036c, 0x2140006e); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x2040008c); - MDP_OUTP(MDP_BASE + 0x50370, 0x2140006d); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x2080008c); - MDP_OUTP(MDP_BASE + 0x50374, 0x2100006d); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x20c0008c); - MDP_OUTP(MDP_BASE + 0x50378, 0x2100006c); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x20c0008d); - MDP_OUTP(MDP_BASE + 0x5037c, 0x2100006b); -} - -static void mdp_load_bc_downscale_table_x_point4TOpoint6(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x740008c); - MDP_OUTP(MDP_BASE + 0x50280, 0x33800088); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x800008e); - MDP_OUTP(MDP_BASE + 0x50284, 0x33400084); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x8400092); - MDP_OUTP(MDP_BASE + 0x50288, 0x33000080); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x9000094); - MDP_OUTP(MDP_BASE + 0x5028c, 0x3300007b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x9c00098); - MDP_OUTP(MDP_BASE + 0x50290, 0x32400077); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xa40009b); - MDP_OUTP(MDP_BASE + 0x50294, 0x32000073); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xb00009d); - MDP_OUTP(MDP_BASE + 0x50298, 0x31c0006f); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xbc000a0); - MDP_OUTP(MDP_BASE + 0x5029c, 0x3140006b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xc8000a2); - MDP_OUTP(MDP_BASE + 0x502a0, 0x31000067); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xd8000a5); - MDP_OUTP(MDP_BASE + 0x502a4, 0x30800062); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xe4000a8); - MDP_OUTP(MDP_BASE + 0x502a8, 0x2fc0005f); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xec000aa); - MDP_OUTP(MDP_BASE + 0x502ac, 0x2fc0005b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8000ad); - MDP_OUTP(MDP_BASE + 0x502b0, 0x2f400057); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x108000b0); - MDP_OUTP(MDP_BASE + 0x502b4, 0x2e400054); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x114000b2); - MDP_OUTP(MDP_BASE + 0x502b8, 0x2e000050); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x124000b4); - MDP_OUTP(MDP_BASE + 0x502bc, 0x2d80004c); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x130000b6); - MDP_OUTP(MDP_BASE + 0x502c0, 0x2d000049); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x140000b8); - MDP_OUTP(MDP_BASE + 0x502c4, 0x2c800045); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x150000b9); - MDP_OUTP(MDP_BASE + 0x502c8, 0x2c000042); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x15c000bd); - MDP_OUTP(MDP_BASE + 0x502cc, 0x2b40003e); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x16c000bf); - MDP_OUTP(MDP_BASE + 0x502d0, 0x2a80003b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x17c000bf); - MDP_OUTP(MDP_BASE + 0x502d4, 0x2a000039); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x188000c2); - MDP_OUTP(MDP_BASE + 0x502d8, 0x29400036); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x19c000c4); - MDP_OUTP(MDP_BASE + 0x502dc, 0x28800032); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ac000c5); - MDP_OUTP(MDP_BASE + 0x502e0, 0x2800002f); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1bc000c7); - MDP_OUTP(MDP_BASE + 0x502e4, 0x2740002c); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc000c8); - MDP_OUTP(MDP_BASE + 0x502e8, 0x26c00029); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc000c9); - MDP_OUTP(MDP_BASE + 0x502ec, 0x26000027); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec000cc); - MDP_OUTP(MDP_BASE + 0x502f0, 0x25000024); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x200000cc); - MDP_OUTP(MDP_BASE + 0x502f4, 0x24800021); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x210000cd); - MDP_OUTP(MDP_BASE + 0x502f8, 0x23800020); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x220000ce); - MDP_OUTP(MDP_BASE + 0x502fc, 0x2300001d); -} - -static void mdp_load_bc_downscale_table_y_point4TOpoint6(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x740008c); - MDP_OUTP(MDP_BASE + 0x50300, 0x33800088); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x800008e); - MDP_OUTP(MDP_BASE + 0x50304, 0x33400084); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x8400092); - MDP_OUTP(MDP_BASE + 0x50308, 0x33000080); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x9000094); - MDP_OUTP(MDP_BASE + 0x5030c, 0x3300007b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x9c00098); - MDP_OUTP(MDP_BASE + 0x50310, 0x32400077); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xa40009b); - MDP_OUTP(MDP_BASE + 0x50314, 0x32000073); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xb00009d); - MDP_OUTP(MDP_BASE + 0x50318, 0x31c0006f); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xbc000a0); - MDP_OUTP(MDP_BASE + 0x5031c, 0x3140006b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xc8000a2); - MDP_OUTP(MDP_BASE + 0x50320, 0x31000067); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xd8000a5); - MDP_OUTP(MDP_BASE + 0x50324, 0x30800062); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xe4000a8); - MDP_OUTP(MDP_BASE + 0x50328, 0x2fc0005f); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xec000aa); - MDP_OUTP(MDP_BASE + 0x5032c, 0x2fc0005b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8000ad); - MDP_OUTP(MDP_BASE + 0x50330, 0x2f400057); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x108000b0); - MDP_OUTP(MDP_BASE + 0x50334, 0x2e400054); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x114000b2); - MDP_OUTP(MDP_BASE + 0x50338, 0x2e000050); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x124000b4); - MDP_OUTP(MDP_BASE + 0x5033c, 0x2d80004c); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x130000b6); - MDP_OUTP(MDP_BASE + 0x50340, 0x2d000049); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x140000b8); - MDP_OUTP(MDP_BASE + 0x50344, 0x2c800045); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x150000b9); - MDP_OUTP(MDP_BASE + 0x50348, 0x2c000042); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x15c000bd); - MDP_OUTP(MDP_BASE + 0x5034c, 0x2b40003e); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x16c000bf); - MDP_OUTP(MDP_BASE + 0x50350, 0x2a80003b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x17c000bf); - MDP_OUTP(MDP_BASE + 0x50354, 0x2a000039); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x188000c2); - MDP_OUTP(MDP_BASE + 0x50358, 0x29400036); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x19c000c4); - MDP_OUTP(MDP_BASE + 0x5035c, 0x28800032); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ac000c5); - MDP_OUTP(MDP_BASE + 0x50360, 0x2800002f); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1bc000c7); - MDP_OUTP(MDP_BASE + 0x50364, 0x2740002c); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1cc000c8); - MDP_OUTP(MDP_BASE + 0x50368, 0x26c00029); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1dc000c9); - MDP_OUTP(MDP_BASE + 0x5036c, 0x26000027); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1ec000cc); - MDP_OUTP(MDP_BASE + 0x50370, 0x25000024); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x200000cc); - MDP_OUTP(MDP_BASE + 0x50374, 0x24800021); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x210000cd); - MDP_OUTP(MDP_BASE + 0x50378, 0x23800020); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x220000ce); - MDP_OUTP(MDP_BASE + 0x5037c, 0x2300001d); -} - -static void mdp_load_bc_downscale_table_x_point6TOpoint8(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000070); - MDP_OUTP(MDP_BASE + 0x50280, 0x4bc00068); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000078); - MDP_OUTP(MDP_BASE + 0x50284, 0x4bc00060); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000080); - MDP_OUTP(MDP_BASE + 0x50288, 0x4b800059); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000089); - MDP_OUTP(MDP_BASE + 0x5028c, 0x4b000052); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe400091); - MDP_OUTP(MDP_BASE + 0x50290, 0x4a80004b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40009a); - MDP_OUTP(MDP_BASE + 0x50294, 0x4a000044); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe8000a3); - MDP_OUTP(MDP_BASE + 0x50298, 0x4940003d); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec000ac); - MDP_OUTP(MDP_BASE + 0x5029c, 0x48400037); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xff0000b4); - MDP_OUTP(MDP_BASE + 0x502a0, 0x47800031); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xff8000bd); - MDP_OUTP(MDP_BASE + 0x502a4, 0x4640002b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xc5); - MDP_OUTP(MDP_BASE + 0x502a8, 0x45000026); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x8000ce); - MDP_OUTP(MDP_BASE + 0x502ac, 0x43800021); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x10000d6); - MDP_OUTP(MDP_BASE + 0x502b0, 0x4240001c); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x18000df); - MDP_OUTP(MDP_BASE + 0x502b4, 0x40800018); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x24000e6); - MDP_OUTP(MDP_BASE + 0x502b8, 0x3f000014); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x30000ee); - MDP_OUTP(MDP_BASE + 0x502bc, 0x3d400010); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x40000f5); - MDP_OUTP(MDP_BASE + 0x502c0, 0x3b80000c); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x50000fc); - MDP_OUTP(MDP_BASE + 0x502c4, 0x39800009); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x6000102); - MDP_OUTP(MDP_BASE + 0x502c8, 0x37c00006); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x7000109); - MDP_OUTP(MDP_BASE + 0x502cc, 0x35800004); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x840010e); - MDP_OUTP(MDP_BASE + 0x502d0, 0x33800002); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x9800114); - MDP_OUTP(MDP_BASE + 0x502d4, 0x31400000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xac00119); - MDP_OUTP(MDP_BASE + 0x502d8, 0x2f4003fe); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xc40011e); - MDP_OUTP(MDP_BASE + 0x502dc, 0x2d0003fc); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xdc00121); - MDP_OUTP(MDP_BASE + 0x502e0, 0x2b0003fb); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf400125); - MDP_OUTP(MDP_BASE + 0x502e4, 0x28c003fa); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x11000128); - MDP_OUTP(MDP_BASE + 0x502e8, 0x268003f9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x12c0012a); - MDP_OUTP(MDP_BASE + 0x502ec, 0x244003f9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1480012c); - MDP_OUTP(MDP_BASE + 0x502f0, 0x224003f8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1640012e); - MDP_OUTP(MDP_BASE + 0x502f4, 0x200003f8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1800012f); - MDP_OUTP(MDP_BASE + 0x502f8, 0x1e0003f8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1a00012f); - MDP_OUTP(MDP_BASE + 0x502fc, 0x1c0003f8); -} - -static void mdp_load_bc_downscale_table_y_point6TOpoint8(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000070); - MDP_OUTP(MDP_BASE + 0x50300, 0x4bc00068); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000078); - MDP_OUTP(MDP_BASE + 0x50304, 0x4bc00060); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000080); - MDP_OUTP(MDP_BASE + 0x50308, 0x4b800059); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe000089); - MDP_OUTP(MDP_BASE + 0x5030c, 0x4b000052); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe400091); - MDP_OUTP(MDP_BASE + 0x50310, 0x4a80004b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40009a); - MDP_OUTP(MDP_BASE + 0x50314, 0x4a000044); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe8000a3); - MDP_OUTP(MDP_BASE + 0x50318, 0x4940003d); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec000ac); - MDP_OUTP(MDP_BASE + 0x5031c, 0x48400037); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xff0000b4); - MDP_OUTP(MDP_BASE + 0x50320, 0x47800031); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xff8000bd); - MDP_OUTP(MDP_BASE + 0x50324, 0x4640002b); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xc5); - MDP_OUTP(MDP_BASE + 0x50328, 0x45000026); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x8000ce); - MDP_OUTP(MDP_BASE + 0x5032c, 0x43800021); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x10000d6); - MDP_OUTP(MDP_BASE + 0x50330, 0x4240001c); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x18000df); - MDP_OUTP(MDP_BASE + 0x50334, 0x40800018); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x24000e6); - MDP_OUTP(MDP_BASE + 0x50338, 0x3f000014); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x30000ee); - MDP_OUTP(MDP_BASE + 0x5033c, 0x3d400010); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x40000f5); - MDP_OUTP(MDP_BASE + 0x50340, 0x3b80000c); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x50000fc); - MDP_OUTP(MDP_BASE + 0x50344, 0x39800009); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x6000102); - MDP_OUTP(MDP_BASE + 0x50348, 0x37c00006); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x7000109); - MDP_OUTP(MDP_BASE + 0x5034c, 0x35800004); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x840010e); - MDP_OUTP(MDP_BASE + 0x50350, 0x33800002); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x9800114); - MDP_OUTP(MDP_BASE + 0x50354, 0x31400000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xac00119); - MDP_OUTP(MDP_BASE + 0x50358, 0x2f4003fe); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xc40011e); - MDP_OUTP(MDP_BASE + 0x5035c, 0x2d0003fc); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xdc00121); - MDP_OUTP(MDP_BASE + 0x50360, 0x2b0003fb); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf400125); - MDP_OUTP(MDP_BASE + 0x50364, 0x28c003fa); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x11000128); - MDP_OUTP(MDP_BASE + 0x50368, 0x268003f9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x12c0012a); - MDP_OUTP(MDP_BASE + 0x5036c, 0x244003f9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1480012c); - MDP_OUTP(MDP_BASE + 0x50370, 0x224003f8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1640012e); - MDP_OUTP(MDP_BASE + 0x50374, 0x200003f8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1800012f); - MDP_OUTP(MDP_BASE + 0x50378, 0x1e0003f8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0x1a00012f); - MDP_OUTP(MDP_BASE + 0x5037c, 0x1c0003f8); -} - -static void mdp_load_bc_downscale_table_x_point8TO1(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50280, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xff80000d); - MDP_OUTP(MDP_BASE + 0x50284, 0x7ec003f9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec0001c); - MDP_OUTP(MDP_BASE + 0x50288, 0x7d4003f3); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40002b); - MDP_OUTP(MDP_BASE + 0x5028c, 0x7b8003ed); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfd80003c); - MDP_OUTP(MDP_BASE + 0x50290, 0x794003e8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc0004d); - MDP_OUTP(MDP_BASE + 0x50294, 0x76c003e4); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfc40005f); - MDP_OUTP(MDP_BASE + 0x50298, 0x73c003e0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb800071); - MDP_OUTP(MDP_BASE + 0x5029c, 0x708003de); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfac00085); - MDP_OUTP(MDP_BASE + 0x502a0, 0x6d0003db); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa000098); - MDP_OUTP(MDP_BASE + 0x502a4, 0x698003d9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf98000ac); - MDP_OUTP(MDP_BASE + 0x502a8, 0x654003d8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8c000c1); - MDP_OUTP(MDP_BASE + 0x502ac, 0x610003d7); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf84000d5); - MDP_OUTP(MDP_BASE + 0x502b0, 0x5c8003d7); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf7c000e9); - MDP_OUTP(MDP_BASE + 0x502b4, 0x580003d7); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf74000fd); - MDP_OUTP(MDP_BASE + 0x502b8, 0x534003d8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c00112); - MDP_OUTP(MDP_BASE + 0x502bc, 0x4e8003d8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6800126); - MDP_OUTP(MDP_BASE + 0x502c0, 0x494003da); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600013a); - MDP_OUTP(MDP_BASE + 0x502c4, 0x448003db); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600014d); - MDP_OUTP(MDP_BASE + 0x502c8, 0x3f4003dd); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00160); - MDP_OUTP(MDP_BASE + 0x502cc, 0x3a4003df); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00172); - MDP_OUTP(MDP_BASE + 0x502d0, 0x354003e1); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00184); - MDP_OUTP(MDP_BASE + 0x502d4, 0x304003e3); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6000195); - MDP_OUTP(MDP_BASE + 0x502d8, 0x2b0003e6); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf64001a6); - MDP_OUTP(MDP_BASE + 0x502dc, 0x260003e8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c001b4); - MDP_OUTP(MDP_BASE + 0x502e0, 0x214003eb); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf78001c2); - MDP_OUTP(MDP_BASE + 0x502e4, 0x1c4003ee); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf80001cf); - MDP_OUTP(MDP_BASE + 0x502e8, 0x17c003f1); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf90001db); - MDP_OUTP(MDP_BASE + 0x502ec, 0x134003f3); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa0001e5); - MDP_OUTP(MDP_BASE + 0x502f0, 0xf0003f6); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb4001ee); - MDP_OUTP(MDP_BASE + 0x502f4, 0xac003f9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc001f5); - MDP_OUTP(MDP_BASE + 0x502f8, 0x70003fb); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe4001fb); - MDP_OUTP(MDP_BASE + 0x502fc, 0x34003fe); -} - -static void mdp_load_bc_downscale_table_y_point8TO1(void) -{ - MDP_OUTP(MDP_BASE + 0x5fffc, 0x0); - MDP_OUTP(MDP_BASE + 0x50300, 0x7fc00000); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xff80000d); - MDP_OUTP(MDP_BASE + 0x50304, 0x7ec003f9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfec0001c); - MDP_OUTP(MDP_BASE + 0x50308, 0x7d4003f3); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe40002b); - MDP_OUTP(MDP_BASE + 0x5030c, 0x7b8003ed); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfd80003c); - MDP_OUTP(MDP_BASE + 0x50310, 0x794003e8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc0004d); - MDP_OUTP(MDP_BASE + 0x50314, 0x76c003e4); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfc40005f); - MDP_OUTP(MDP_BASE + 0x50318, 0x73c003e0); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb800071); - MDP_OUTP(MDP_BASE + 0x5031c, 0x708003de); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfac00085); - MDP_OUTP(MDP_BASE + 0x50320, 0x6d0003db); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa000098); - MDP_OUTP(MDP_BASE + 0x50324, 0x698003d9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf98000ac); - MDP_OUTP(MDP_BASE + 0x50328, 0x654003d8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf8c000c1); - MDP_OUTP(MDP_BASE + 0x5032c, 0x610003d7); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf84000d5); - MDP_OUTP(MDP_BASE + 0x50330, 0x5c8003d7); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf7c000e9); - MDP_OUTP(MDP_BASE + 0x50334, 0x580003d7); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf74000fd); - MDP_OUTP(MDP_BASE + 0x50338, 0x534003d8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c00112); - MDP_OUTP(MDP_BASE + 0x5033c, 0x4e8003d8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6800126); - MDP_OUTP(MDP_BASE + 0x50340, 0x494003da); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600013a); - MDP_OUTP(MDP_BASE + 0x50344, 0x448003db); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf600014d); - MDP_OUTP(MDP_BASE + 0x50348, 0x3f4003dd); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00160); - MDP_OUTP(MDP_BASE + 0x5034c, 0x3a4003df); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00172); - MDP_OUTP(MDP_BASE + 0x50350, 0x354003e1); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf5c00184); - MDP_OUTP(MDP_BASE + 0x50354, 0x304003e3); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6000195); - MDP_OUTP(MDP_BASE + 0x50358, 0x2b0003e6); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf64001a6); - MDP_OUTP(MDP_BASE + 0x5035c, 0x260003e8); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf6c001b4); - MDP_OUTP(MDP_BASE + 0x50360, 0x214003eb); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf78001c2); - MDP_OUTP(MDP_BASE + 0x50364, 0x1c4003ee); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf80001cf); - MDP_OUTP(MDP_BASE + 0x50368, 0x17c003f1); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xf90001db); - MDP_OUTP(MDP_BASE + 0x5036c, 0x134003f3); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfa0001e5); - MDP_OUTP(MDP_BASE + 0x50370, 0xf0003f6); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfb4001ee); - MDP_OUTP(MDP_BASE + 0x50374, 0xac003f9); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfcc001f5); - MDP_OUTP(MDP_BASE + 0x50378, 0x70003fb); - MDP_OUTP(MDP_BASE + 0x5fffc, 0xfe4001fb); - MDP_OUTP(MDP_BASE + 0x5037c, 0x34003fe); -} - -static int mdp_get_edge_cond(MDPIBUF *iBuf, uint32 *dup, uint32 *dup2) -{ - uint32 reg; - uint32 dst_roi_width; /* Dimensions of DST ROI. */ - uint32 dst_roi_height; /* Used to calculate scaling ratios. */ - - /* - * positions of the luma pixel(relative to the image ) required for - * scaling the ROI - */ - int32 luma_interp_point_left = 0; /* left-most luma pixel needed */ - int32 luma_interp_point_right = 0; /* right-most luma pixel needed */ - int32 luma_interp_point_top = 0; /* top-most luma pixel needed */ - int32 luma_interp_point_bottom = 0; /* bottom-most luma pixel needed */ - - /* - * positions of the chroma pixel(relative to the image ) required for - * interpolating a chroma value at all required luma positions - */ - /* left-most chroma pixel needed */ - int32 chroma_interp_point_left = 0; - /* right-most chroma pixel needed */ - int32 chroma_interp_point_right = 0; - /* top-most chroma pixel needed */ - int32 chroma_interp_point_top = 0; - /* bottom-most chroma pixel needed */ - int32 chroma_interp_point_bottom = 0; - - /* - * a rectangular region within the chroma plane of the "image". - * Chroma pixels falling inside of this rectangle belongs to the ROI - */ - int32 chroma_bound_left = 0; - int32 chroma_bound_right = 0; - int32 chroma_bound_top = 0; - int32 chroma_bound_bottom = 0; - - /* - * number of chroma pixels to replicate on the left, right, - * top and bottom edge of the ROI. - */ - int32 chroma_repeat_left = 0; - int32 chroma_repeat_right = 0; - int32 chroma_repeat_top = 0; - int32 chroma_repeat_bottom = 0; - - /* - * number of luma pixels to replicate on the left, right, - * top and bottom edge of the ROI. - */ - int32 luma_repeat_left = 0; - int32 luma_repeat_right = 0; - int32 luma_repeat_top = 0; - int32 luma_repeat_bottom = 0; - - boolean chroma_edge_enable; - - uint32 _is_scale_enabled = 0; - uint32 _is_yuv_offsite_vertical = 0; - - /* fg edge duplicate */ - reg = 0x0; - - if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) { /* if scaling enabled */ - - _is_scale_enabled = 1; - - /* - * if rotation mode involves a 90 deg rotation, flip - * dst_roi_width with dst_roi_height. - * Scaling ratios is based on source ROI dimensions, and - * dst ROI dimensions before rotation. - */ - if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) { - dst_roi_width = iBuf->roi.dst_height; - dst_roi_height = iBuf->roi.dst_width; - } else { - dst_roi_width = iBuf->roi.dst_width; - dst_roi_height = iBuf->roi.dst_height; - } - - /* - * Find out the luma pixels needed for scaling in the - * x direction (LEFT and RIGHT). Locations of pixels are - * relative to the ROI. Upper-left corner of ROI corresponds - * to coordinates (0,0). Also set the number of luma pixel - * to repeat. - */ - if (iBuf->roi.width > 3 * dst_roi_width) { - /* scale factor < 1/3 */ - luma_interp_point_left = 0; - luma_interp_point_right = (iBuf->roi.width - 1); - luma_repeat_left = 0; - luma_repeat_right = 0; - } else if (iBuf->roi.width == 3 * dst_roi_width) { - /* scale factor == 1/3 */ - luma_interp_point_left = 0; - luma_interp_point_right = (iBuf->roi.width - 1) + 1; - luma_repeat_left = 0; - luma_repeat_right = 1; - } else if ((iBuf->roi.width > dst_roi_width) && - (iBuf->roi.width < 3 * dst_roi_width)) { - /* 1/3 < scale factor < 1 */ - luma_interp_point_left = -1; - luma_interp_point_right = (iBuf->roi.width - 1) + 1; - luma_repeat_left = 1; - luma_repeat_right = 1; - } - - else if (iBuf->roi.width == dst_roi_width) { - /* scale factor == 1 */ - luma_interp_point_left = -1; - luma_interp_point_right = (iBuf->roi.width - 1) + 2; - luma_repeat_left = 1; - luma_repeat_right = 2; - } else { /* (iBuf->roi.width < dst_roi_width) */ - /* scale factor > 1 */ - luma_interp_point_left = -2; - luma_interp_point_right = (iBuf->roi.width - 1) + 2; - luma_repeat_left = 2; - luma_repeat_right = 2; - } - - /* - * Find out the number of pixels needed for scaling in the - * y direction (TOP and BOTTOM). Locations of pixels are - * relative to the ROI. Upper-left corner of ROI corresponds - * to coordinates (0,0). Also set the number of luma pixel - * to repeat. - */ - if (iBuf->roi.height > 3 * dst_roi_height) { - /* scale factor < 1/3 */ - luma_interp_point_top = 0; - luma_interp_point_bottom = (iBuf->roi.height - 1); - luma_repeat_top = 0; - luma_repeat_bottom = 0; - } else if (iBuf->roi.height == 3 * dst_roi_height) { - /* scale factor == 1/3 */ - luma_interp_point_top = 0; - luma_interp_point_bottom = (iBuf->roi.height - 1) + 1; - luma_repeat_top = 0; - luma_repeat_bottom = 1; - } else if ((iBuf->roi.height > dst_roi_height) && - (iBuf->roi.height < 3 * dst_roi_height)) { - /* 1/3 < scale factor < 1 */ - luma_interp_point_top = -1; - luma_interp_point_bottom = (iBuf->roi.height - 1) + 1; - luma_repeat_top = 1; - luma_repeat_bottom = 1; - } else if (iBuf->roi.height == dst_roi_height) { - /* scale factor == 1 */ - luma_interp_point_top = -1; - luma_interp_point_bottom = (iBuf->roi.height - 1) + 2; - luma_repeat_top = 1; - luma_repeat_bottom = 2; - } else { /* (iBuf->roi.height < dst_roi_height) */ - /* scale factor > 1 */ - luma_interp_point_top = -2; - luma_interp_point_bottom = (iBuf->roi.height - 1) + 2; - luma_repeat_top = 2; - luma_repeat_bottom = 2; - } - } /* if (iBuf->scale.scale_flag) */ - else { /* scaling disabled */ - /* - * Since no scaling needed, Tile Fetch does not require any - * more luma pixel than what the ROI contains. - */ - luma_interp_point_left = (int32) 0; - luma_interp_point_right = (int32) (iBuf->roi.width - 1); - luma_interp_point_top = (int32) 0; - luma_interp_point_bottom = (int32) (iBuf->roi.height - 1); - - luma_repeat_left = 0; - luma_repeat_right = 0; - luma_repeat_top = 0; - luma_repeat_bottom = 0; - } - - /* After adding the ROI offsets, we have locations of - * luma_interp_points relative to the image. - */ - luma_interp_point_left += (int32) (iBuf->roi.x); - luma_interp_point_right += (int32) (iBuf->roi.x); - luma_interp_point_top += (int32) (iBuf->roi.y); - luma_interp_point_bottom += (int32) (iBuf->roi.y); - - /* - * After adding the ROI offsets, we have locations of - * chroma_interp_points relative to the image. - */ - chroma_interp_point_left = luma_interp_point_left; - chroma_interp_point_right = luma_interp_point_right; - chroma_interp_point_top = luma_interp_point_top; - chroma_interp_point_bottom = luma_interp_point_bottom; - - chroma_edge_enable = TRUE; - /* find out which chroma pixels are needed for chroma upsampling. */ - switch (iBuf->mdpImg.imgType) { - /* - * cosite in horizontal axis - * fully sampled in vertical axis - */ - case MDP_Y_CBCR_H2V1: - case MDP_Y_CRCB_H2V1: - case MDP_YCRYCB_H2V1: - /* floor( luma_interp_point_left / 2 ); */ - chroma_interp_point_left = luma_interp_point_left >> 1; - /* floor( ( luma_interp_point_right + 1 ) / 2 ); */ - chroma_interp_point_right = (luma_interp_point_right + 1) >> 1; - - chroma_interp_point_top = luma_interp_point_top; - chroma_interp_point_bottom = luma_interp_point_bottom; - break; - - /* - * cosite in horizontal axis - * offsite in vertical axis - */ - case MDP_Y_CBCR_H2V2: - case MDP_Y_CRCB_H2V2: - /* floor( luma_interp_point_left / 2) */ - chroma_interp_point_left = luma_interp_point_left >> 1; - - /* floor( ( luma_interp_point_right + 1 )/ 2 ) */ - chroma_interp_point_right = (luma_interp_point_right + 1) >> 1; - - /* floor( (luma_interp_point_top - 1 ) / 2 ) */ - chroma_interp_point_top = (luma_interp_point_top - 1) >> 1; - - /* floor( ( luma_interp_point_bottom + 1 ) / 2 ) */ - chroma_interp_point_bottom = - (luma_interp_point_bottom + 1) >> 1; - - _is_yuv_offsite_vertical = 1; - break; - - default: - chroma_edge_enable = FALSE; - chroma_interp_point_left = luma_interp_point_left; - chroma_interp_point_right = luma_interp_point_right; - chroma_interp_point_top = luma_interp_point_top; - chroma_interp_point_bottom = luma_interp_point_bottom; - - break; - } - - /* only if the image type is in YUV domain, we calculate chroma edge */ - if (chroma_edge_enable) { - /* Defines which chroma pixels belongs to the roi */ - switch (iBuf->mdpImg.imgType) { - /* - * Cosite in horizontal direction, and fully sampled - * in vertical direction. - */ - case MDP_Y_CBCR_H2V1: - case MDP_Y_CRCB_H2V1: - case MDP_YCRYCB_H2V1: - /* - * width of chroma ROI is 1/2 of size of luma ROI - * height of chroma ROI same as size of luma ROI - */ - chroma_bound_left = iBuf->roi.x / 2; - - /* there are half as many chroma pixel as luma pixels */ - chroma_bound_right = - (iBuf->roi.width + iBuf->roi.x - 1) / 2; - chroma_bound_top = iBuf->roi.y; - chroma_bound_bottom = - (iBuf->roi.height + iBuf->roi.y - 1); - break; - - case MDP_Y_CBCR_H2V2: - case MDP_Y_CRCB_H2V2: - /* - * cosite in horizontal dir, and offsite in vertical dir - * width of chroma ROI is 1/2 of size of luma ROI - * height of chroma ROI is 1/2 of size of luma ROI - */ - - chroma_bound_left = iBuf->roi.x / 2; - chroma_bound_right = - (iBuf->roi.width + iBuf->roi.x - 1) / 2; - chroma_bound_top = iBuf->roi.y / 2; - chroma_bound_bottom = - (iBuf->roi.height + iBuf->roi.y - 1) / 2; - break; - - default: - /* - * If no valid chroma sub-sampling format specified, - * assume 4:4:4 ( i.e. fully sampled). Set ROI - * boundaries for chroma same as ROI boundaries for - * luma. - */ - chroma_bound_left = iBuf->roi.x; - chroma_bound_right = iBuf->roi.width + iBuf->roi.x - 1; - chroma_bound_top = iBuf->roi.y; - chroma_bound_bottom = - (iBuf->roi.height + iBuf->roi.y - 1); - break; - } - - /* - * Knowing which chroma pixels are needed, and which chroma - * pixels belong to the ROI (i.e. available for fetching ), - * calculate how many chroma pixels Tile Fetch needs to - * duplicate. If any required chroma pixels falls outside - * of the ROI, Tile Fetch must obtain them by replicating - * pixels. - */ - if (chroma_bound_left > chroma_interp_point_left) - chroma_repeat_left = - chroma_bound_left - chroma_interp_point_left; - else - chroma_repeat_left = 0; - - if (chroma_interp_point_right > chroma_bound_right) - chroma_repeat_right = - chroma_interp_point_right - chroma_bound_right; - else - chroma_repeat_right = 0; - - if (chroma_bound_top > chroma_interp_point_top) - chroma_repeat_top = - chroma_bound_top - chroma_interp_point_top; - else - chroma_repeat_top = 0; - - if (chroma_interp_point_bottom > chroma_bound_bottom) - chroma_repeat_bottom = - chroma_interp_point_bottom - chroma_bound_bottom; - else - chroma_repeat_bottom = 0; - - if (_is_scale_enabled && (iBuf->roi.height == 1) - && _is_yuv_offsite_vertical) { - chroma_repeat_bottom = 3; - chroma_repeat_top = 0; - } - } - /* make sure chroma repeats are non-negative */ - if ((chroma_repeat_left < 0) || (chroma_repeat_right < 0) || - (chroma_repeat_top < 0) || (chroma_repeat_bottom < 0)) - return -1; - - /* make sure chroma repeats are no larger than 3 pixels */ - if ((chroma_repeat_left > 3) || (chroma_repeat_right > 3) || - (chroma_repeat_top > 3) || (chroma_repeat_bottom > 3)) - return -1; - - /* make sure luma repeats are non-negative */ - if ((luma_repeat_left < 0) || (luma_repeat_right < 0) || - (luma_repeat_top < 0) || (luma_repeat_bottom < 0)) - return -1; - - /* make sure luma repeats are no larger than 3 pixels */ - if ((luma_repeat_left > 3) || (luma_repeat_right > 3) || - (luma_repeat_top > 3) || (luma_repeat_bottom > 3)) - return -1; - - /* write chroma_repeat_left to register */ - reg |= (chroma_repeat_left & 3) << MDP_LEFT_CHROMA; - - /* write chroma_repeat_right to register */ - reg |= (chroma_repeat_right & 3) << MDP_RIGHT_CHROMA; - - /* write chroma_repeat_top to register */ - reg |= (chroma_repeat_top & 3) << MDP_TOP_CHROMA; - - /* write chroma_repeat_bottom to register */ - reg |= (chroma_repeat_bottom & 3) << MDP_BOTTOM_CHROMA; - - /* write luma_repeat_left to register */ - reg |= (luma_repeat_left & 3) << MDP_LEFT_LUMA; - - /* write luma_repeat_right to register */ - reg |= (luma_repeat_right & 3) << MDP_RIGHT_LUMA; - - /* write luma_repeat_top to register */ - reg |= (luma_repeat_top & 3) << MDP_TOP_LUMA; - - /* write luma_repeat_bottom to register */ - reg |= (luma_repeat_bottom & 3) << MDP_BOTTOM_LUMA; - - /* done with reg */ - *dup = reg; - - /* bg edge duplicate */ - reg = 0x0; - - switch (iBuf->ibuf_type) { - case MDP_Y_CBCR_H2V2: - case MDP_Y_CRCB_H2V2: - /* - * Edge condition for MDP_Y_CRCB/CBCR_H2V2 cosite only. - * For 420 cosite, 1 chroma replicated on all sides except - * left, so reg 101b8 should be 0x0209. For 420 offsite, - * 1 chroma replicated all sides. - */ - if (iBuf->roi.lcd_y == 0) { - reg |= BIT(MDP_TOP_CHROMA); - } - - if ((iBuf->roi.lcd_y + iBuf->roi.dst_height) == - iBuf->ibuf_height) { - reg |= BIT(MDP_BOTTOM_CHROMA); - } - - if (((iBuf->roi.lcd_x + iBuf->roi.dst_width) == - iBuf->ibuf_width) && ((iBuf->roi.dst_width % 2) == 0)) { - reg |= BIT(MDP_RIGHT_CHROMA); - } - - break; - - case MDP_Y_CBCR_H2V1: - case MDP_Y_CRCB_H2V1: - case MDP_YCRYCB_H2V1: - if (((iBuf->roi.lcd_x + iBuf->roi.dst_width) == - iBuf->ibuf_width) && ((iBuf->roi.dst_width % 2) == 0)) { - reg |= BIT(MDP_RIGHT_CHROMA); - } - break; - default: - break; - } - - *dup2 = reg; - - return 0; -} - -#define ADJUST_IP /* for 1/3 scale factor fix */ - -static int mdp_calc_scale_params( -/* ROI origin coordinate for the dimension */ - uint32 org, -/* src ROI dimension */ - uint32 dim_in, -/* scaled ROI dimension*/ - uint32 dim_out, -/* is this ROI width dimension? */ - boolean is_W, -/* initial phase location address */ - int32 *phase_init_ptr, -/* phase increment location address */ - uint32 *phase_step_ptr, -/* ROI start over-fetch location address */ - uint32 *num_repl_beg_ptr, -/* ROI end over-fetch location address */ - uint32 *num_repl_end_ptr) -{ - boolean rpa_on = FALSE; - int init_phase = 0; - uint32 beg_of = 0; - uint32 end_of = 0; - uint64 numer = 0; - uint64 denom = 0; - /*uint64 inverter = 1; */ - int64 point5 = 1; - int64 one = 1; - int64 k1, k2, k3, k4; /* linear equation coefficients */ - uint64 int_mask; - uint64 fract_mask; - uint64 Os; - int64 Osprime; - int64 Od; - int64 Odprime; - int64 Oreq; - uint64 Es; - uint64 Ed; - uint64 Ereq; -#ifdef ADJUST_IP - int64 IP64; - int64 delta; -#endif - uint32 mult; - - /* - * The phase accumulator should really be rational for all cases in a - * general purpose polyphase scaler for a tiled architecture with - * non-zero * origin capability because there is no way to represent - * certain scale factors in fixed point regardless of precision. - * The error incurred in attempting to use fixed point is most - * eggregious for SF where 1/SF is an integral multiple of 1/3. - * - * However, since the MDP2 has already been committed to HW, we - * only use the rational phase accumulator (RPA) when 1/SF is an - * integral multiple of 1/3. This will help minimize regressions in - * matching the HW to the C-Sim. - */ - /* - * Set the RPA flag for this dimension. - * - * In order for 1/SF (dim_in/dim_out) to be an integral multiple of - * 1/3, dim_out must be an integral multiple of 3. - */ - if (!(dim_out % 3)) { - mult = dim_out / 3; - rpa_on = (!(dim_in % mult)); - } - - numer = dim_out; - denom = dim_in; - - /* - * convert to U30.34 before division - * - * The K vectors carry 4 extra bits of precision - * and are rounded. - * - * We initially go 5 bits over then round by adding - * 1 and right shifting by 1 - * so final result is U31.33 - */ - numer <<= PQF_PLUS_5; - - /* now calculate the scale factor (aka k3) */ - k3 = ((mdp_do_div(numer, denom) + 1) >> 1); - - /* check scale factor for legal range [0.25 - 4.0] */ - if (((k3 >> 4) < (1LL << PQF_MINUS_2)) || - ((k3 >> 4) > (1LL << PQF_PLUS_2))) { - return -1; - } - - /* calculate inverse scale factor (aka k1) for phase init */ - numer = dim_in; - denom = dim_out; - numer <<= PQF_PLUS_5; - k1 = ((mdp_do_div(numer, denom) + 1) >> 1); - - /* - * calculate initial phase and ROI overfetch - */ - /* convert point5 & one to S39.24 (will always be positive) */ - point5 <<= (PQF_PLUS_4 - 1); - one <<= PQF_PLUS_4; - k2 = ((k1 - one) >> 1); - init_phase = (int)(k2 >> 4); - k4 = ((k3 - one) >> 1); - if (k3 == one) { - /* the simple case; SF = 1.0 */ - beg_of = 1; - end_of = 2; - } else { - /* calculate the masks */ - fract_mask = one - 1; - int_mask = ~fract_mask; - - if (!rpa_on) { - /* - * FIXED POINT IMPLEMENTATION - */ - if (!org) { - /* A fairly simple case; ROI origin = 0 */ - if (k1 < one) { - /* upscaling */ - beg_of = end_of = 2; - } - /* 0.33 <= SF < 1.0 */ - else if (k1 < (3LL << PQF_PLUS_4)) - beg_of = end_of = 1; - /* 0.33 == SF */ - else if (k1 == (3LL << PQF_PLUS_4)) { - beg_of = 0; - end_of = 1; - } - /* 0.25 <= SF < 0.33 */ - else - beg_of = end_of = 0; - } else { - /* - * The complicated case; ROI origin != 0 - * init_phase needs to be adjusted - * OF is also position dependent - */ - - /* map (org - .5) into destination space */ - Os = ((uint64) org << 1) - 1; - Od = ((k3 * Os) >> 1) + k4; - - /* take the ceiling */ - Odprime = (Od & int_mask); - if (Odprime != Od) - Odprime += one; - - /* now map that back to source space */ - Osprime = (k1 * (Odprime >> PQF_PLUS_4)) + k2; - - /* then floor & decrement to calculate the required - starting coordinate */ - Oreq = (Osprime & int_mask) - one; - - /* calculate end coord in destination space then map to - source space */ - Ed = Odprime + - ((uint64) dim_out << PQF_PLUS_4) - one; - Es = (k1 * (Ed >> PQF_PLUS_4)) + k2; - - /* now floor & increment by 2 to calculate the required - ending coordinate */ - Ereq = (Es & int_mask) + (one << 1); - - /* calculate initial phase */ -#ifdef ADJUST_IP - - IP64 = Osprime - Oreq; - delta = ((int64) (org) << PQF_PLUS_4) - Oreq; - IP64 -= delta; - - /* limit to valid range before the left shift */ - delta = (IP64 & (1LL << 63)) ? 4 : -4; - delta <<= PQF_PLUS_4; - while (abs((int)(IP64 >> PQF_PLUS_4)) > 4) - IP64 += delta; - - /* right shift to account for extra bits of precision */ - init_phase = (int)(IP64 >> 4); - -#else /* ADJUST_IP */ - - /* just calculate the real initial phase */ - init_phase = (int)((Osprime - Oreq) >> 4); - -#endif /* ADJUST_IP */ - - /* calculate the overfetch */ - beg_of = org - (uint32) (Oreq >> PQF_PLUS_4); - end_of = - (uint32) (Ereq >> PQF_PLUS_4) - (org + - dim_in - - 1); - } - } else { - /* - * RPA IMPLEMENTATION - * - * init_phase needs to be calculated in all RPA_on cases - * because it's a numerator, not a fixed point value. - */ - - /* map (org - .5) into destination space */ - Os = ((uint64) org << PQF_PLUS_4) - point5; - Od = mdp_do_div((dim_out * (Os + point5)), - dim_in) - point5; - - /* take the ceiling */ - Odprime = (Od & int_mask); - if (Odprime != Od) - Odprime += one; - - /* now map that back to source space */ - Osprime = - mdp_do_div((dim_in * (Odprime + point5)), - dim_out) - point5; - - /* then floor & decrement to calculate the required - starting coordinate */ - Oreq = (Osprime & int_mask) - one; - - /* calculate end coord in destination space then map to - source space */ - Ed = Odprime + ((uint64) dim_out << PQF_PLUS_4) - one; - Es = mdp_do_div((dim_in * (Ed + point5)), - dim_out) - point5; - - /* now floor & increment by 2 to calculate the required - ending coordinate */ - Ereq = (Es & int_mask) + (one << 1); - - /* calculate initial phase */ - -#ifdef ADJUST_IP - - IP64 = Osprime - Oreq; - delta = ((int64) (org) << PQF_PLUS_4) - Oreq; - IP64 -= delta; - - /* limit to valid range before the left shift */ - delta = (IP64 & (1LL << 63)) ? 4 : -4; - delta <<= PQF_PLUS_4; - while (abs((int)(IP64 >> PQF_PLUS_4)) > 4) - IP64 += delta; - - /* right shift to account for extra bits of precision */ - init_phase = (int)(IP64 >> 4); - -#else /* ADJUST_IP */ - - /* just calculate the real initial phase */ - init_phase = (int)((Osprime - Oreq) >> 4); - -#endif /* ADJUST_IP */ - - /* calculate the overfetch */ - beg_of = org - (uint32) (Oreq >> PQF_PLUS_4); - end_of = - (uint32) (Ereq >> PQF_PLUS_4) - (org + dim_in - 1); - } - } - - /* return the scale parameters */ - *phase_init_ptr = init_phase; - *phase_step_ptr = (uint32) (k1 >> 4); - *num_repl_beg_ptr = beg_of; - *num_repl_end_ptr = end_of; - - return 0; -} - -static uint8 *mdp_adjust_rot_addr(MDPIBUF *iBuf, uint8 *addr, uint32 uv) -{ - uint32 dest_ystride = iBuf->ibuf_width * iBuf->bpp; - uint32 h_slice = 1; - - if (uv && ((iBuf->ibuf_type == MDP_Y_CBCR_H2V2) || - (iBuf->ibuf_type == MDP_Y_CRCB_H2V2))) - h_slice = 2; - - if (MDP_CHKBIT(iBuf->mdpImg.mdpOp, MDPOP_ROT90) ^ - MDP_CHKBIT(iBuf->mdpImg.mdpOp, MDPOP_LR)) { - addr = - addr + (iBuf->roi.dst_width - - MIN(16, iBuf->roi.dst_width)) * iBuf->bpp; - } - if (MDP_CHKBIT(iBuf->mdpImg.mdpOp, MDPOP_UD)) { - addr = - addr + ((iBuf->roi.dst_height - - MIN(16, iBuf->roi.dst_height))/h_slice) * dest_ystride; - } - - return addr; -} - -void mdp_set_scale(MDPIBUF *iBuf, - uint32 dst_roi_width, - uint32 dst_roi_height, - boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr) -{ - uint32 dst_roi_width_scale; - uint32 dst_roi_height_scale; - boolean use_pr; - uint32 phasex_step = 0; - uint32 phasey_step = 0; - int32 phasex_init = 0; - int32 phasey_init = 0; - uint32 lines_dup = 0; - uint32 lines_dup_bg = 0; - uint32 dummy; - uint32 mdp_blur = 0; - - if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) { - if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) { - dst_roi_width_scale = dst_roi_height; - dst_roi_height_scale = dst_roi_width; - } else { - dst_roi_width_scale = dst_roi_width; - dst_roi_height_scale = dst_roi_height; - } - - mdp_blur = iBuf->mdpImg.mdpOp & MDPOP_BLUR; - - if ((dst_roi_width_scale != iBuf->roi.width) || - (dst_roi_height_scale != iBuf->roi.height) || - mdp_blur) { - *pppop_reg_ptr |= - (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON); - - /* let's use SHIM logic to calculate the partial ROI scaling */ -#if 0 - phasex_step = - (uint32) mdp_do_div(0x20000000 * iBuf->roi.width, - dst_roi_width_scale); - phasey_step = - (uint32) mdp_do_div(0x20000000 * iBuf->roi.height, - dst_roi_height_scale); - -/* - phasex_step= ((long long) iBuf->roi.width * 0x20000000)/dst_roi_width_scale; - phasey_step= ((long long)iBuf->roi.height * 0x20000000)/dst_roi_height_scale; -*/ - - phasex_init = - (((long long)phasex_step - 0x20000000) >> 1); - phasey_init = - (((long long)phasey_step - 0x20000000) >> 1); - -#else - mdp_calc_scale_params(iBuf->roi.x, iBuf->roi.width, - dst_roi_width_scale, 1, - &phasex_init, &phasex_step, - &dummy, &dummy); - mdp_calc_scale_params(iBuf->roi.y, iBuf->roi.height, - dst_roi_height_scale, 0, - &phasey_init, &phasey_step, - &dummy, &dummy); -#endif - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x013c, - phasex_init); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0140, - phasey_init); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0144, - phasex_step); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0148, - phasey_step); - - use_pr = (inputRGB) && (outputRGB); - - if ((dst_roi_width_scale > iBuf->roi.width) || - (dst_roi_height_scale > iBuf->roi.height)) { - if ((use_pr) - && (mdp_curr_up_scale_xy != - MDP_PR_SCALE_UP)) { - mdp_load_pr_upscale_table(); - mdp_curr_up_scale_xy = MDP_PR_SCALE_UP; - } else if ((!use_pr) - && (mdp_curr_up_scale_xy != - MDP_BC_SCALE_UP)) { - mdp_load_bc_upscale_table(); - mdp_curr_up_scale_xy = MDP_BC_SCALE_UP; - } - } - - if (mdp_blur) { - load_scale_table(mdp_gaussian_blur_table, - ARRAY_SIZE(mdp_gaussian_blur_table)); - mdp_curr_down_scale_x = MDP_SCALE_BLUR; - mdp_curr_down_scale_y = MDP_SCALE_BLUR; - } - - /* 0.2 < x <= 1 scaling factor */ - if ((dst_roi_width_scale <= iBuf->roi.width) && - !mdp_blur) { - if (((dst_roi_width_scale * 10) / - iBuf->roi.width) > 8) { - if ((use_pr) - && (mdp_curr_down_scale_x != - MDP_PR_SCALE_POINT8_1)) { - mdp_load_pr_downscale_table_x_point8TO1 - (); - mdp_curr_down_scale_x = - MDP_PR_SCALE_POINT8_1; - } else if ((!use_pr) - && (mdp_curr_down_scale_x != - MDP_BC_SCALE_POINT8_1)) { - mdp_load_bc_downscale_table_x_point8TO1 - (); - mdp_curr_down_scale_x = - MDP_BC_SCALE_POINT8_1; - } - } else - if (((dst_roi_width_scale * 10) / - iBuf->roi.width) > 6) { - if ((use_pr) - && (mdp_curr_down_scale_x != - MDP_PR_SCALE_POINT6_POINT8)) { - mdp_load_pr_downscale_table_x_point6TOpoint8 - (); - mdp_curr_down_scale_x = - MDP_PR_SCALE_POINT6_POINT8; - } else if ((!use_pr) - && (mdp_curr_down_scale_x != - MDP_BC_SCALE_POINT6_POINT8)) - { - mdp_load_bc_downscale_table_x_point6TOpoint8 - (); - mdp_curr_down_scale_x = - MDP_BC_SCALE_POINT6_POINT8; - } - } else - if (((dst_roi_width_scale * 10) / - iBuf->roi.width) > 4) { - if ((use_pr) - && (mdp_curr_down_scale_x != - MDP_PR_SCALE_POINT4_POINT6)) { - mdp_load_pr_downscale_table_x_point4TOpoint6 - (); - mdp_curr_down_scale_x = - MDP_PR_SCALE_POINT4_POINT6; - } else if ((!use_pr) - && (mdp_curr_down_scale_x != - MDP_BC_SCALE_POINT4_POINT6)) - { - mdp_load_bc_downscale_table_x_point4TOpoint6 - (); - mdp_curr_down_scale_x = - MDP_BC_SCALE_POINT4_POINT6; - } - } else { - if ((use_pr) - && (mdp_curr_down_scale_x != - MDP_PR_SCALE_POINT2_POINT4)) { - mdp_load_pr_downscale_table_x_point2TOpoint4 - (); - mdp_curr_down_scale_x = - MDP_PR_SCALE_POINT2_POINT4; - } else if ((!use_pr) - && (mdp_curr_down_scale_x != - MDP_BC_SCALE_POINT2_POINT4)) - { - mdp_load_bc_downscale_table_x_point2TOpoint4 - (); - mdp_curr_down_scale_x = - MDP_BC_SCALE_POINT2_POINT4; - } - } - } - /* 0.2 < y <= 1 scaling factor */ - if ((dst_roi_height_scale <= iBuf->roi.height) && - !mdp_blur) { - if (((dst_roi_height_scale * 10) / - iBuf->roi.height) > 8) { - if ((use_pr) - && (mdp_curr_down_scale_y != - MDP_PR_SCALE_POINT8_1)) { - mdp_load_pr_downscale_table_y_point8TO1 - (); - mdp_curr_down_scale_y = - MDP_PR_SCALE_POINT8_1; - } else if ((!use_pr) - && (mdp_curr_down_scale_y != - MDP_BC_SCALE_POINT8_1)) { - mdp_load_bc_downscale_table_y_point8TO1 - (); - mdp_curr_down_scale_y = - MDP_BC_SCALE_POINT8_1; - } - } else - if (((dst_roi_height_scale * 10) / - iBuf->roi.height) > 6) { - if ((use_pr) - && (mdp_curr_down_scale_y != - MDP_PR_SCALE_POINT6_POINT8)) { - mdp_load_pr_downscale_table_y_point6TOpoint8 - (); - mdp_curr_down_scale_y = - MDP_PR_SCALE_POINT6_POINT8; - } else if ((!use_pr) - && (mdp_curr_down_scale_y != - MDP_BC_SCALE_POINT6_POINT8)) - { - mdp_load_bc_downscale_table_y_point6TOpoint8 - (); - mdp_curr_down_scale_y = - MDP_BC_SCALE_POINT6_POINT8; - } - } else - if (((dst_roi_height_scale * 10) / - iBuf->roi.height) > 4) { - if ((use_pr) - && (mdp_curr_down_scale_y != - MDP_PR_SCALE_POINT4_POINT6)) { - mdp_load_pr_downscale_table_y_point4TOpoint6 - (); - mdp_curr_down_scale_y = - MDP_PR_SCALE_POINT4_POINT6; - } else if ((!use_pr) - && (mdp_curr_down_scale_y != - MDP_BC_SCALE_POINT4_POINT6)) - { - mdp_load_bc_downscale_table_y_point4TOpoint6 - (); - mdp_curr_down_scale_y = - MDP_BC_SCALE_POINT4_POINT6; - } - } else { - if ((use_pr) - && (mdp_curr_down_scale_y != - MDP_PR_SCALE_POINT2_POINT4)) { - mdp_load_pr_downscale_table_y_point2TOpoint4 - (); - mdp_curr_down_scale_y = - MDP_PR_SCALE_POINT2_POINT4; - } else if ((!use_pr) - && (mdp_curr_down_scale_y != - MDP_BC_SCALE_POINT2_POINT4)) - { - mdp_load_bc_downscale_table_y_point2TOpoint4 - (); - mdp_curr_down_scale_y = - MDP_BC_SCALE_POINT2_POINT4; - } - } - } - } else { - iBuf->mdpImg.mdpOp &= ~(MDPOP_ASCALE); - } - } - /* setting edge condition here after scaling check */ - if (mdp_get_edge_cond(iBuf, &lines_dup, &lines_dup_bg)) - printk(KERN_ERR "msm_fb: mdp_get_edge_cond() error!\n"); - - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01b8, lines_dup); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x01bc, lines_dup_bg); -} - -void mdp_init_scale_table(void) -{ - mdp_curr_up_scale_xy = MDP_INIT_SCALE; - mdp_curr_down_scale_x = MDP_INIT_SCALE; - mdp_curr_down_scale_y = MDP_INIT_SCALE; -} - -void mdp_adjust_start_addr(uint8 **src0, - uint8 **src1, - int v_slice, - int h_slice, - int x, - int y, - uint32 width, - uint32 height, int bpp, MDPIBUF *iBuf, int layer) -{ - *src0 += (x + y * width) * bpp; - - /* if it's dest/bg buffer, we need to adjust it for rotation */ - if (layer != 0) - *src0 = mdp_adjust_rot_addr(iBuf, *src0, 0); - - if (*src1) { - /* - * MDP_Y_CBCR_H2V2/MDP_Y_CRCB_H2V2 cosite for now - * we need to shift x direction same as y dir for offsite - */ - *src1 += - ((x / h_slice) * h_slice + - ((y == 0) ? 0 : ((y + 1) / v_slice - 1) * width)) * bpp; - - /* if it's dest/bg buffer, we need to adjust it for rotation */ - if (layer != 0) - *src1 = mdp_adjust_rot_addr(iBuf, *src1, 1); - } -} - -void mdp_set_blend_attr(MDPIBUF *iBuf, - uint32 *alpha, - uint32 *tpVal, - uint32 perPixelAlpha, uint32 *pppop_reg_ptr) -{ - if (perPixelAlpha) { - *pppop_reg_ptr |= PPP_OP_ROT_ON | - PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA; - } else { - if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB) - && (iBuf->mdpImg.alpha == 0xff)) { - iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB); - } - - if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB) - && (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) { - *pppop_reg_ptr |= - PPP_OP_ROT_ON | PPP_OP_BLEND_ON | - PPP_OP_BLEND_CONSTANT_ALPHA | - PPP_OP_BLEND_ALPHA_BLEND_NORMAL | - PPP_BLEND_CALPHA_TRNASP; - - *alpha = iBuf->mdpImg.alpha; - *tpVal = iBuf->mdpImg.tpVal; - } else { - if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP) { - *pppop_reg_ptr |= PPP_OP_ROT_ON | - PPP_OP_BLEND_ON | - PPP_OP_BLEND_SRCPIXEL_TRANSP; - *tpVal = iBuf->mdpImg.tpVal; - } else if (iBuf->mdpImg.mdpOp & MDPOP_ALPHAB) { - *pppop_reg_ptr |= PPP_OP_ROT_ON | - PPP_OP_BLEND_ON | - PPP_OP_BLEND_ALPHA_BLEND_NORMAL | - PPP_OP_BLEND_CONSTANT_ALPHA; - *alpha = iBuf->mdpImg.alpha; - } - } - } -} diff --git a/drivers/staging/msm/mdp_ppp_v31.c b/drivers/staging/msm/mdp_ppp_v31.c deleted file mode 100644 index 76495dbe4e64..000000000000 --- a/drivers/staging/msm/mdp_ppp_v31.c +++ /dev/null @@ -1,828 +0,0 @@ -/* Copyright (c) 2008-2010, 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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "linux/proc_fs.h" - -#include -#include - -#include -#include -#include -#include - -#include "mdp.h" -#include "msm_fb.h" - -#define MDP_SCALE_COEFF_NUM 32 -#define MDP_SCALE_0P2_TO_0P4_INDEX 0 -#define MDP_SCALE_0P4_TO_0P6_INDEX 32 -#define MDP_SCALE_0P6_TO_0P8_INDEX 64 -#define MDP_SCALE_0P8_TO_8P0_INDEX 96 -#define MDP_SCALE_COEFF_MASK 0x3ff - -#define MDP_SCALE_PR 0 -#define MDP_SCALE_FIR 1 - -static uint32 mdp_scale_0p8_to_8p0_mode; -static uint32 mdp_scale_0p6_to_0p8_mode; -static uint32 mdp_scale_0p4_to_0p6_mode; -static uint32 mdp_scale_0p2_to_0p4_mode; - -/* -------- All scaling range, "pixel repeat" -------- */ -static int16 mdp_scale_pixel_repeat_C0[MDP_SCALE_COEFF_NUM] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static int16 mdp_scale_pixel_repeat_C1[MDP_SCALE_COEFF_NUM] = { - 511, 511, 511, 511, 511, 511, 511, 511, - 511, 511, 511, 511, 511, 511, 511, 511, - 511, 511, 511, 511, 511, 511, 511, 511, - 511, 511, 511, 511, 511, 511, 511, 511 -}; - -static int16 mdp_scale_pixel_repeat_C2[MDP_SCALE_COEFF_NUM] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static int16 mdp_scale_pixel_repeat_C3[MDP_SCALE_COEFF_NUM] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* --------------------------- FIR ------------------------------------- */ -/* -------- Downscale, ranging from 0.8x to 8.0x of original size -------- */ - -static int16 mdp_scale_0p8_to_8p0_C0[MDP_SCALE_COEFF_NUM] = { - 0, -7, -13, -19, -24, -28, -32, -34, -37, -39, - -40, -41, -41, -41, -40, -40, -38, -37, -35, -33, - -31, -29, -26, -24, -21, -18, -15, -13, -10, -7, - -5, -2 -}; - -static int16 mdp_scale_0p8_to_8p0_C1[MDP_SCALE_COEFF_NUM] = { - 511, 507, 501, 494, 485, 475, 463, 450, 436, 422, - 405, 388, 370, 352, 333, 314, 293, 274, 253, 233, - 213, 193, 172, 152, 133, 113, 95, 77, 60, 43, - 28, 13 -}; - -static int16 mdp_scale_0p8_to_8p0_C2[MDP_SCALE_COEFF_NUM] = { - 0, 13, 28, 43, 60, 77, 95, 113, 133, 152, - 172, 193, 213, 233, 253, 274, 294, 314, 333, 352, - 370, 388, 405, 422, 436, 450, 463, 475, 485, 494, - 501, 507, -}; - -static int16 mdp_scale_0p8_to_8p0_C3[MDP_SCALE_COEFF_NUM] = { - 0, -2, -5, -7, -10, -13, -15, -18, -21, -24, - -26, -29, -31, -33, -35, -37, -38, -40, -40, -41, - -41, -41, -40, -39, -37, -34, -32, -28, -24, -19, - -13, -7 -}; - -/* -------- Downscale, ranging from 0.6x to 0.8x of original size -------- */ - -static int16 mdp_scale_0p6_to_0p8_C0[MDP_SCALE_COEFF_NUM] = { - 104, 96, 89, 82, 75, 68, 61, 55, 49, 43, - 38, 33, 28, 24, 20, 16, 12, 9, 6, 4, - 2, 0, -2, -4, -5, -6, -7, -7, -8, -8, - -8, -8 -}; - -static int16 mdp_scale_0p6_to_0p8_C1[MDP_SCALE_COEFF_NUM] = { - 303, 303, 302, 300, 298, 296, 293, 289, 286, 281, - 276, 270, 265, 258, 252, 245, 238, 230, 223, 214, - 206, 197, 189, 180, 172, 163, 154, 145, 137, 128, - 120, 112 -}; - -static int16 mdp_scale_0p6_to_0p8_C2[MDP_SCALE_COEFF_NUM] = { - 112, 120, 128, 137, 145, 154, 163, 172, 180, 189, - 197, 206, 214, 223, 230, 238, 245, 252, 258, 265, - 270, 276, 281, 286, 289, 293, 296, 298, 300, 302, - 303, 303 -}; - -static int16 mdp_scale_0p6_to_0p8_C3[MDP_SCALE_COEFF_NUM] = { - -8, -8, -8, -8, -7, -7, -6, -5, -4, -2, - 0, 2, 4, 6, 9, 12, 16, 20, 24, 28, - 33, 38, 43, 49, 55, 61, 68, 75, 82, 89, - 96, 104 -}; - -/* -------- Downscale, ranging from 0.4x to 0.6x of original size -------- */ - -static int16 mdp_scale_0p4_to_0p6_C0[MDP_SCALE_COEFF_NUM] = { - 136, 132, 128, 123, 119, 115, 111, 107, 103, 98, - 95, 91, 87, 84, 80, 76, 73, 69, 66, 62, - 59, 57, 54, 50, 47, 44, 41, 39, 36, 33, - 32, 29 -}; - -static int16 mdp_scale_0p4_to_0p6_C1[MDP_SCALE_COEFF_NUM] = { - 206, 205, 204, 204, 201, 200, 199, 197, 196, 194, - 191, 191, 189, 185, 184, 182, 180, 178, 176, 173, - 170, 168, 165, 162, 160, 157, 155, 152, 148, 146, - 142, 140 -}; - -static int16 mdp_scale_0p4_to_0p6_C2[MDP_SCALE_COEFF_NUM] = { - 140, 142, 146, 148, 152, 155, 157, 160, 162, 165, - 168, 170, 173, 176, 178, 180, 182, 184, 185, 189, - 191, 191, 194, 196, 197, 199, 200, 201, 204, 204, - 205, 206 -}; - -static int16 mdp_scale_0p4_to_0p6_C3[MDP_SCALE_COEFF_NUM] = { - 29, 32, 33, 36, 39, 41, 44, 47, 50, 54, - 57, 59, 62, 66, 69, 73, 76, 80, 84, 87, - 91, 95, 98, 103, 107, 111, 115, 119, 123, 128, - 132, 136 -}; - -/* -------- Downscale, ranging from 0.2x to 0.4x of original size -------- */ - -static int16 mdp_scale_0p2_to_0p4_C0[MDP_SCALE_COEFF_NUM] = { - 131, 131, 130, 129, 128, 127, 127, 126, 125, 125, - 124, 123, 123, 121, 120, 119, 119, 118, 117, 117, - 116, 115, 115, 114, 113, 112, 111, 110, 109, 109, - 108, 107 -}; - -static int16 mdp_scale_0p2_to_0p4_C1[MDP_SCALE_COEFF_NUM] = { - 141, 140, 140, 140, 140, 139, 138, 138, 138, 137, - 137, 137, 136, 137, 137, 137, 136, 136, 136, 135, - 135, 135, 134, 134, 134, 134, 134, 133, 133, 132, - 132, 132 -}; - -static int16 mdp_scale_0p2_to_0p4_C2[MDP_SCALE_COEFF_NUM] = { - 132, 132, 132, 133, 133, 134, 134, 134, 134, 134, - 135, 135, 135, 136, 136, 136, 137, 137, 137, 136, - 137, 137, 137, 138, 138, 138, 139, 140, 140, 140, - 140, 141 -}; - -static int16 mdp_scale_0p2_to_0p4_C3[MDP_SCALE_COEFF_NUM] = { - 107, 108, 109, 109, 110, 111, 112, 113, 114, 115, - 115, 116, 117, 117, 118, 119, 119, 120, 121, 123, - 123, 124, 125, 125, 126, 127, 127, 128, 129, 130, - 131, 131 -}; - -static void mdp_update_scale_table(int index, int16 *c0, int16 *c1, - int16 *c2, int16 *c3) -{ - int i, val; - - for (i = 0; i < MDP_SCALE_COEFF_NUM; i++) { - val = - ((MDP_SCALE_COEFF_MASK & c1[i]) << 16) | - (MDP_SCALE_COEFF_MASK & c0[i]); - MDP_OUTP(MDP_PPP_SCALE_COEFF_LSBn(index), val); - val = - ((MDP_SCALE_COEFF_MASK & c3[i]) << 16) | - (MDP_SCALE_COEFF_MASK & c2[i]); - MDP_OUTP(MDP_PPP_SCALE_COEFF_MSBn(index), val); - index++; - } -} - -void mdp_init_scale_table(void) -{ - mdp_scale_0p2_to_0p4_mode = MDP_SCALE_FIR; - mdp_update_scale_table(MDP_SCALE_0P2_TO_0P4_INDEX, - mdp_scale_0p2_to_0p4_C0, - mdp_scale_0p2_to_0p4_C1, - mdp_scale_0p2_to_0p4_C2, - mdp_scale_0p2_to_0p4_C3); - - mdp_scale_0p4_to_0p6_mode = MDP_SCALE_FIR; - mdp_update_scale_table(MDP_SCALE_0P4_TO_0P6_INDEX, - mdp_scale_0p4_to_0p6_C0, - mdp_scale_0p4_to_0p6_C1, - mdp_scale_0p4_to_0p6_C2, - mdp_scale_0p4_to_0p6_C3); - - mdp_scale_0p6_to_0p8_mode = MDP_SCALE_FIR; - mdp_update_scale_table(MDP_SCALE_0P6_TO_0P8_INDEX, - mdp_scale_0p6_to_0p8_C0, - mdp_scale_0p6_to_0p8_C1, - mdp_scale_0p6_to_0p8_C2, - mdp_scale_0p6_to_0p8_C3); - - mdp_scale_0p8_to_8p0_mode = MDP_SCALE_FIR; - mdp_update_scale_table(MDP_SCALE_0P8_TO_8P0_INDEX, - mdp_scale_0p8_to_8p0_C0, - mdp_scale_0p8_to_8p0_C1, - mdp_scale_0p8_to_8p0_C2, - mdp_scale_0p8_to_8p0_C3); -} - -static long long mdp_do_div(long long num, long long den) -{ - do_div(num, den); - return num; -} - -#define SCALER_PHASE_BITS 29 -#define HAL_MDP_PHASE_STEP_2P50 0x50000000 -#define HAL_MDP_PHASE_STEP_1P66 0x35555555 -#define HAL_MDP_PHASE_STEP_1P25 0x28000000 - -struct phase_val { - int phase_init_x; - int phase_init_y; - int phase_step_x; - int phase_step_y; -}; - -static void mdp_calc_scaleInitPhase_3p1(uint32 in_w, - uint32 in_h, - uint32 out_w, - uint32 out_h, - boolean is_rotate, - boolean is_pp_x, - boolean is_pp_y, struct phase_val *pval) -{ - uint64 dst_ROI_width; - uint64 dst_ROI_height; - uint64 src_ROI_width; - uint64 src_ROI_height; - - /* - * phase_step_x, phase_step_y, phase_init_x and phase_init_y - * are represented in fixed-point, unsigned 3.29 format - */ - uint32 phase_step_x = 0; - uint32 phase_step_y = 0; - uint32 phase_init_x = 0; - uint32 phase_init_y = 0; - uint32 yscale_filter_sel, xscale_filter_sel; - uint32 scale_unit_sel_x, scale_unit_sel_y; - - uint64 numerator, denominator; - uint64 temp_dim; - - src_ROI_width = in_w; - src_ROI_height = in_h; - dst_ROI_width = out_w; - dst_ROI_height = out_h; - - /* if there is a 90 degree rotation */ - if (is_rotate) { - /* decide whether to use FIR or M/N for scaling */ - - /* if down-scaling by a factor smaller than 1/4 */ - if (src_ROI_width > (4 * dst_ROI_height)) - scale_unit_sel_x = 1; /* use M/N scalar */ - else - scale_unit_sel_x = 0; /* use FIR scalar */ - - /* if down-scaling by a factor smaller than 1/4 */ - if (src_ROI_height > (4 * dst_ROI_width)) - scale_unit_sel_y = 1; /* use M/N scalar */ - else - scale_unit_sel_y = 0; /* use FIR scalar */ - } else { - /* decide whether to use FIR or M/N for scaling */ - - if (src_ROI_width > (4 * dst_ROI_width)) - scale_unit_sel_x = 1; /* use M/N scalar */ - else - scale_unit_sel_x = 0; /* use FIR scalar */ - - if (src_ROI_height > (4 * dst_ROI_height)) - scale_unit_sel_y = 1; /* use M/N scalar */ - else - scale_unit_sel_y = 0; /* use FIR scalar */ - - } - - /* if there is a 90 degree rotation */ - if (is_rotate) { - /* swap the width and height of dst ROI */ - temp_dim = dst_ROI_width; - dst_ROI_width = dst_ROI_height; - dst_ROI_height = temp_dim; - } - - /* calculate phase step for the x direction */ - - /* if destination is only 1 pixel wide, the value of phase_step_x - is unimportant. Assigning phase_step_x to src ROI width - as an arbitrary value. */ - if (dst_ROI_width == 1) - phase_step_x = (uint32) ((src_ROI_width) << SCALER_PHASE_BITS); - - /* if using FIR scalar */ - else if (scale_unit_sel_x == 0) { - - /* Calculate the quotient ( src_ROI_width - 1 ) / ( dst_ROI_width - 1) - with u3.29 precision. Quotient is rounded up to the larger - 29th decimal point. */ - numerator = (src_ROI_width - 1) << SCALER_PHASE_BITS; - denominator = (dst_ROI_width - 1); /* never equals to 0 because of the "( dst_ROI_width == 1 ) case" */ - phase_step_x = (uint32) mdp_do_div((numerator + denominator - 1), denominator); /* divide and round up to the larger 29th decimal point. */ - - } - - /* if M/N scalar */ - else if (scale_unit_sel_x == 1) { - /* Calculate the quotient ( src_ROI_width ) / ( dst_ROI_width) - with u3.29 precision. Quotient is rounded down to the - smaller 29th decimal point. */ - numerator = (src_ROI_width) << SCALER_PHASE_BITS; - denominator = (dst_ROI_width); - phase_step_x = (uint32) mdp_do_div(numerator, denominator); - } - /* calculate phase step for the y direction */ - - /* if destination is only 1 pixel wide, the value of - phase_step_x is unimportant. Assigning phase_step_x - to src ROI width as an arbitrary value. */ - if (dst_ROI_height == 1) - phase_step_y = (uint32) ((src_ROI_height) << SCALER_PHASE_BITS); - - /* if FIR scalar */ - else if (scale_unit_sel_y == 0) { - /* Calculate the quotient ( src_ROI_height - 1 ) / ( dst_ROI_height - 1) - with u3.29 precision. Quotient is rounded up to the larger - 29th decimal point. */ - numerator = (src_ROI_height - 1) << SCALER_PHASE_BITS; - denominator = (dst_ROI_height - 1); /* never equals to 0 because of the "( dst_ROI_height == 1 )" case */ - phase_step_y = (uint32) mdp_do_div((numerator + denominator - 1), denominator); /* Quotient is rounded up to the larger 29th decimal point. */ - - } - - /* if M/N scalar */ - else if (scale_unit_sel_y == 1) { - /* Calculate the quotient ( src_ROI_height ) / ( dst_ROI_height) - with u3.29 precision. Quotient is rounded down to the smaller - 29th decimal point. */ - numerator = (src_ROI_height) << SCALER_PHASE_BITS; - denominator = (dst_ROI_height); - phase_step_y = (uint32) mdp_do_div(numerator, denominator); - } - - /* decide which set of FIR coefficients to use */ - if (phase_step_x > HAL_MDP_PHASE_STEP_2P50) - xscale_filter_sel = 0; - else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66) - xscale_filter_sel = 1; - else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25) - xscale_filter_sel = 2; - else - xscale_filter_sel = 3; - - if (phase_step_y > HAL_MDP_PHASE_STEP_2P50) - yscale_filter_sel = 0; - else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66) - yscale_filter_sel = 1; - else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25) - yscale_filter_sel = 2; - else - yscale_filter_sel = 3; - - /* calculate phase init for the x direction */ - - /* if using FIR scalar */ - if (scale_unit_sel_x == 0) { - if (dst_ROI_width == 1) - phase_init_x = - (uint32) ((src_ROI_width - 1) << SCALER_PHASE_BITS); - else - phase_init_x = 0; - - } - /* M over N scalar */ - else if (scale_unit_sel_x == 1) - phase_init_x = 0; - - /* calculate phase init for the y direction - if using FIR scalar */ - if (scale_unit_sel_y == 0) { - if (dst_ROI_height == 1) - phase_init_y = - (uint32) ((src_ROI_height - - 1) << SCALER_PHASE_BITS); - else - phase_init_y = 0; - - } - /* M over N scalar */ - else if (scale_unit_sel_y == 1) - phase_init_y = 0; - - /* write registers */ - pval->phase_step_x = (uint32) phase_step_x; - pval->phase_step_y = (uint32) phase_step_y; - pval->phase_init_x = (uint32) phase_init_x; - pval->phase_init_y = (uint32) phase_init_y; - - return; -} - -void mdp_set_scale(MDPIBUF *iBuf, - uint32 dst_roi_width, - uint32 dst_roi_height, - boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr) -{ - uint32 dst_roi_width_scale; - uint32 dst_roi_height_scale; - struct phase_val pval; - boolean use_pr; - uint32 ppp_scale_config = 0; - - if (!inputRGB) - ppp_scale_config |= BIT(6); - - if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) { - if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) { - dst_roi_width_scale = dst_roi_height; - dst_roi_height_scale = dst_roi_width; - } else { - dst_roi_width_scale = dst_roi_width; - dst_roi_height_scale = dst_roi_height; - } - - if ((dst_roi_width_scale != iBuf->roi.width) || - (dst_roi_height_scale != iBuf->roi.height) || - (iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) { - *pppop_reg_ptr |= - (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON); - - mdp_calc_scaleInitPhase_3p1(iBuf->roi.width, - iBuf->roi.height, - dst_roi_width, - dst_roi_height, - iBuf->mdpImg. - mdpOp & MDPOP_ROT90, 1, 1, - &pval); - - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x013c, - pval.phase_init_x); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0140, - pval.phase_init_y); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0144, - pval.phase_step_x); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0148, - pval.phase_step_y); - - use_pr = (inputRGB) && (outputRGB); - - /* x-direction */ - if ((dst_roi_width_scale == iBuf->roi.width) && - !(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) { - *pppop_reg_ptr &= ~PPP_OP_SCALE_X_ON; - } else - if (((dst_roi_width_scale * 10) / iBuf->roi.width) > - 8) { - if ((use_pr) - && (mdp_scale_0p8_to_8p0_mode != - MDP_SCALE_PR)) { - mdp_scale_0p8_to_8p0_mode = - MDP_SCALE_PR; - mdp_update_scale_table - (MDP_SCALE_0P8_TO_8P0_INDEX, - mdp_scale_pixel_repeat_C0, - mdp_scale_pixel_repeat_C1, - mdp_scale_pixel_repeat_C2, - mdp_scale_pixel_repeat_C3); - } else if ((!use_pr) - && (mdp_scale_0p8_to_8p0_mode != - MDP_SCALE_FIR)) { - mdp_scale_0p8_to_8p0_mode = - MDP_SCALE_FIR; - mdp_update_scale_table - (MDP_SCALE_0P8_TO_8P0_INDEX, - mdp_scale_0p8_to_8p0_C0, - mdp_scale_0p8_to_8p0_C1, - mdp_scale_0p8_to_8p0_C2, - mdp_scale_0p8_to_8p0_C3); - } - ppp_scale_config |= (SCALE_U1_SET << 2); - } else - if (((dst_roi_width_scale * 10) / iBuf->roi.width) > - 6) { - if ((use_pr) - && (mdp_scale_0p6_to_0p8_mode != - MDP_SCALE_PR)) { - mdp_scale_0p6_to_0p8_mode = - MDP_SCALE_PR; - mdp_update_scale_table - (MDP_SCALE_0P6_TO_0P8_INDEX, - mdp_scale_pixel_repeat_C0, - mdp_scale_pixel_repeat_C1, - mdp_scale_pixel_repeat_C2, - mdp_scale_pixel_repeat_C3); - } else if ((!use_pr) - && (mdp_scale_0p6_to_0p8_mode != - MDP_SCALE_FIR)) { - mdp_scale_0p6_to_0p8_mode = - MDP_SCALE_FIR; - mdp_update_scale_table - (MDP_SCALE_0P6_TO_0P8_INDEX, - mdp_scale_0p6_to_0p8_C0, - mdp_scale_0p6_to_0p8_C1, - mdp_scale_0p6_to_0p8_C2, - mdp_scale_0p6_to_0p8_C3); - } - ppp_scale_config |= (SCALE_D2_SET << 2); - } else - if (((dst_roi_width_scale * 10) / iBuf->roi.width) > - 4) { - if ((use_pr) - && (mdp_scale_0p4_to_0p6_mode != - MDP_SCALE_PR)) { - mdp_scale_0p4_to_0p6_mode = - MDP_SCALE_PR; - mdp_update_scale_table - (MDP_SCALE_0P4_TO_0P6_INDEX, - mdp_scale_pixel_repeat_C0, - mdp_scale_pixel_repeat_C1, - mdp_scale_pixel_repeat_C2, - mdp_scale_pixel_repeat_C3); - } else if ((!use_pr) - && (mdp_scale_0p4_to_0p6_mode != - MDP_SCALE_FIR)) { - mdp_scale_0p4_to_0p6_mode = - MDP_SCALE_FIR; - mdp_update_scale_table - (MDP_SCALE_0P4_TO_0P6_INDEX, - mdp_scale_0p4_to_0p6_C0, - mdp_scale_0p4_to_0p6_C1, - mdp_scale_0p4_to_0p6_C2, - mdp_scale_0p4_to_0p6_C3); - } - ppp_scale_config |= (SCALE_D1_SET << 2); - } else - if (((dst_roi_width_scale * 4) / iBuf->roi.width) >= - 1) { - if ((use_pr) - && (mdp_scale_0p2_to_0p4_mode != - MDP_SCALE_PR)) { - mdp_scale_0p2_to_0p4_mode = - MDP_SCALE_PR; - mdp_update_scale_table - (MDP_SCALE_0P2_TO_0P4_INDEX, - mdp_scale_pixel_repeat_C0, - mdp_scale_pixel_repeat_C1, - mdp_scale_pixel_repeat_C2, - mdp_scale_pixel_repeat_C3); - } else if ((!use_pr) - && (mdp_scale_0p2_to_0p4_mode != - MDP_SCALE_FIR)) { - mdp_scale_0p2_to_0p4_mode = - MDP_SCALE_FIR; - mdp_update_scale_table - (MDP_SCALE_0P2_TO_0P4_INDEX, - mdp_scale_0p2_to_0p4_C0, - mdp_scale_0p2_to_0p4_C1, - mdp_scale_0p2_to_0p4_C2, - mdp_scale_0p2_to_0p4_C3); - } - ppp_scale_config |= (SCALE_D0_SET << 2); - } else - ppp_scale_config |= BIT(0); - - /* y-direction */ - if ((dst_roi_height_scale == iBuf->roi.height) && - !(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) { - *pppop_reg_ptr &= ~PPP_OP_SCALE_Y_ON; - } else if (((dst_roi_height_scale * 10) / - iBuf->roi.height) > 8) { - if ((use_pr) - && (mdp_scale_0p8_to_8p0_mode != - MDP_SCALE_PR)) { - mdp_scale_0p8_to_8p0_mode = - MDP_SCALE_PR; - mdp_update_scale_table - (MDP_SCALE_0P8_TO_8P0_INDEX, - mdp_scale_pixel_repeat_C0, - mdp_scale_pixel_repeat_C1, - mdp_scale_pixel_repeat_C2, - mdp_scale_pixel_repeat_C3); - } else if ((!use_pr) - && (mdp_scale_0p8_to_8p0_mode != - MDP_SCALE_FIR)) { - mdp_scale_0p8_to_8p0_mode = - MDP_SCALE_FIR; - mdp_update_scale_table - (MDP_SCALE_0P8_TO_8P0_INDEX, - mdp_scale_0p8_to_8p0_C0, - mdp_scale_0p8_to_8p0_C1, - mdp_scale_0p8_to_8p0_C2, - mdp_scale_0p8_to_8p0_C3); - } - ppp_scale_config |= (SCALE_U1_SET << 4); - } else - if (((dst_roi_height_scale * 10) / - iBuf->roi.height) > 6) { - if ((use_pr) - && (mdp_scale_0p6_to_0p8_mode != - MDP_SCALE_PR)) { - mdp_scale_0p6_to_0p8_mode = - MDP_SCALE_PR; - mdp_update_scale_table - (MDP_SCALE_0P6_TO_0P8_INDEX, - mdp_scale_pixel_repeat_C0, - mdp_scale_pixel_repeat_C1, - mdp_scale_pixel_repeat_C2, - mdp_scale_pixel_repeat_C3); - } else if ((!use_pr) - && (mdp_scale_0p6_to_0p8_mode != - MDP_SCALE_FIR)) { - mdp_scale_0p6_to_0p8_mode = - MDP_SCALE_FIR; - mdp_update_scale_table - (MDP_SCALE_0P6_TO_0P8_INDEX, - mdp_scale_0p6_to_0p8_C0, - mdp_scale_0p6_to_0p8_C1, - mdp_scale_0p6_to_0p8_C2, - mdp_scale_0p6_to_0p8_C3); - } - ppp_scale_config |= (SCALE_D2_SET << 4); - } else - if (((dst_roi_height_scale * 10) / - iBuf->roi.height) > 4) { - if ((use_pr) - && (mdp_scale_0p4_to_0p6_mode != - MDP_SCALE_PR)) { - mdp_scale_0p4_to_0p6_mode = - MDP_SCALE_PR; - mdp_update_scale_table - (MDP_SCALE_0P4_TO_0P6_INDEX, - mdp_scale_pixel_repeat_C0, - mdp_scale_pixel_repeat_C1, - mdp_scale_pixel_repeat_C2, - mdp_scale_pixel_repeat_C3); - } else if ((!use_pr) - && (mdp_scale_0p4_to_0p6_mode != - MDP_SCALE_FIR)) { - mdp_scale_0p4_to_0p6_mode = - MDP_SCALE_FIR; - mdp_update_scale_table - (MDP_SCALE_0P4_TO_0P6_INDEX, - mdp_scale_0p4_to_0p6_C0, - mdp_scale_0p4_to_0p6_C1, - mdp_scale_0p4_to_0p6_C2, - mdp_scale_0p4_to_0p6_C3); - } - ppp_scale_config |= (SCALE_D1_SET << 4); - } else - if (((dst_roi_height_scale * 4) / - iBuf->roi.height) >= 1) { - if ((use_pr) - && (mdp_scale_0p2_to_0p4_mode != - MDP_SCALE_PR)) { - mdp_scale_0p2_to_0p4_mode = - MDP_SCALE_PR; - mdp_update_scale_table - (MDP_SCALE_0P2_TO_0P4_INDEX, - mdp_scale_pixel_repeat_C0, - mdp_scale_pixel_repeat_C1, - mdp_scale_pixel_repeat_C2, - mdp_scale_pixel_repeat_C3); - } else if ((!use_pr) - && (mdp_scale_0p2_to_0p4_mode != - MDP_SCALE_FIR)) { - mdp_scale_0p2_to_0p4_mode = - MDP_SCALE_FIR; - mdp_update_scale_table - (MDP_SCALE_0P2_TO_0P4_INDEX, - mdp_scale_0p2_to_0p4_C0, - mdp_scale_0p2_to_0p4_C1, - mdp_scale_0p2_to_0p4_C2, - mdp_scale_0p2_to_0p4_C3); - } - ppp_scale_config |= (SCALE_D0_SET << 4); - } else - ppp_scale_config |= BIT(1); - - if (iBuf->mdpImg.mdpOp & MDPOP_SHARPENING) { - ppp_scale_config |= BIT(7); - MDP_OUTP(MDP_BASE + 0x50020, - iBuf->mdpImg.sp_value); - } - - MDP_OUTP(MDP_BASE + 0x10230, ppp_scale_config); - } else { - iBuf->mdpImg.mdpOp &= ~(MDPOP_ASCALE); - } - } -} - -void mdp_adjust_start_addr(uint8 **src0, - uint8 **src1, - int v_slice, - int h_slice, - int x, - int y, - uint32 width, - uint32 height, int bpp, MDPIBUF *iBuf, int layer) -{ - switch (layer) { - case 0: - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0200, (y << 16) | (x)); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0208, - (height << 16) | (width)); - break; - - case 1: - /* MDP 3.1 HW bug workaround */ - if (iBuf->ibuf_type == MDP_YCRYCB_H2V1) { - *src0 += (x + y * width) * bpp; - x = y = 0; - width = iBuf->roi.dst_width; - height = iBuf->roi.dst_height; - } - - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0204, (y << 16) | (x)); - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x020c, - (height << 16) | (width)); - break; - - case 2: - MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x019c, (y << 16) | (x)); - break; - } -} - -void mdp_set_blend_attr(MDPIBUF *iBuf, - uint32 *alpha, - uint32 *tpVal, - uint32 perPixelAlpha, uint32 *pppop_reg_ptr) -{ - int bg_alpha; - - *alpha = iBuf->mdpImg.alpha; - *tpVal = iBuf->mdpImg.tpVal; - - if (iBuf->mdpImg.mdpOp & MDPOP_FG_PM_ALPHA) { - *pppop_reg_ptr |= PPP_OP_ROT_ON | - PPP_OP_BLEND_ON | PPP_OP_BLEND_CONSTANT_ALPHA; - - bg_alpha = PPP_BLEND_BG_USE_ALPHA_SEL | - PPP_BLEND_BG_ALPHA_REVERSE; - - if (perPixelAlpha) - bg_alpha |= PPP_BLEND_BG_SRCPIXEL_ALPHA; - else - bg_alpha |= PPP_BLEND_BG_CONSTANT_ALPHA; - - outpdw(MDP_BASE + 0x70010, bg_alpha); - - if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP) - *pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP; - } else if (perPixelAlpha) { - *pppop_reg_ptr |= PPP_OP_ROT_ON | - PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA; - } else { - if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB) - && (iBuf->mdpImg.alpha == 0xff)) { - iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB); - } - - if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB) - || (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) { - *pppop_reg_ptr |= - PPP_OP_ROT_ON | PPP_OP_BLEND_ON | - PPP_OP_BLEND_CONSTANT_ALPHA | - PPP_OP_BLEND_ALPHA_BLEND_NORMAL; - } - - if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP) - *pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP; - } -} diff --git a/drivers/staging/msm/mdp_vsync.c b/drivers/staging/msm/mdp_vsync.c deleted file mode 100644 index bbd456044356..000000000000 --- a/drivers/staging/msm/mdp_vsync.c +++ /dev/null @@ -1,389 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include "mdp.h" -#include "msm_fb.h" -#include "mddihost.h" - -#ifdef CONFIG_FB_MSM_MDP40 -#define MDP_SYNC_CFG_0 0x100 -#define MDP_SYNC_STATUS_0 0x10c -#define MDP_PRIM_VSYNC_OUT_CTRL 0x118 -#define MDP_PRIM_VSYNC_INIT_VAL 0x128 -#else -#define MDP_SYNC_CFG_0 0x300 -#define MDP_SYNC_STATUS_0 0x30c -#define MDP_PRIM_VSYNC_OUT_CTRL 0x318 -#define MDP_PRIM_VSYNC_INIT_VAL 0x328 -#endif - -extern mddi_lcd_type mddi_lcd_idx; -extern spinlock_t mdp_spin_lock; -extern struct workqueue_struct *mdp_vsync_wq; -extern int lcdc_mode; -extern int vsync_mode; - -#ifdef MDP_HW_VSYNC -int vsync_above_th = 4; -int vsync_start_th = 1; -int vsync_load_cnt; - -struct clk *mdp_vsync_clk; - -void mdp_hw_vsync_clk_enable(struct msm_fb_data_type *mfd) -{ - if (mfd->use_mdp_vsync) - clk_enable(mdp_vsync_clk); -} - -void mdp_hw_vsync_clk_disable(struct msm_fb_data_type *mfd) -{ - if (mfd->use_mdp_vsync) - clk_disable(mdp_vsync_clk); -} -#endif - -static void mdp_set_vsync(unsigned long data) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data; - struct msm_fb_panel_data *pdata = NULL; - - pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data; - - if ((pdata) && (pdata->set_vsync_notifier == NULL)) - return; - - init_timer(&mfd->vsync_resync_timer); - mfd->vsync_resync_timer.function = mdp_set_vsync; - mfd->vsync_resync_timer.data = data; - mfd->vsync_resync_timer.expires = - jiffies + mfd->panel_info.lcd.vsync_notifier_period; - add_timer(&mfd->vsync_resync_timer); - - if ((mfd->panel_info.lcd.vsync_enable) && (mfd->panel_power_on) - && (!mfd->vsync_handler_pending)) { - mfd->vsync_handler_pending = TRUE; - if (!queue_work(mdp_vsync_wq, &mfd->vsync_resync_worker)) { - MSM_FB_INFO - ("mdp_set_vsync: can't queue_work! -> needs to increase vsync_resync_timer_duration\n"); - } - } else { - MSM_FB_DEBUG - ("mdp_set_vsync failed! EN:%d PWR:%d PENDING:%d\n", - mfd->panel_info.lcd.vsync_enable, mfd->panel_power_on, - mfd->vsync_handler_pending); - } -} - -static void mdp_vsync_handler(void *data) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data; - - if (mfd->use_mdp_vsync) { -#ifdef MDP_HW_VSYNC - if (mfd->panel_power_on) - MDP_OUTP(MDP_BASE + MDP_SYNC_STATUS_0, vsync_load_cnt); - - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, TRUE); -#endif - } else { - mfd->last_vsync_timetick = ktime_get_real(); - } - - mfd->vsync_handler_pending = FALSE; -} - -irqreturn_t mdp_hw_vsync_handler_proxy(int irq, void *data) -{ - /* - * ToDo: tried enabling/disabling GPIO MDP HW VSYNC interrupt - * but getting inaccurate timing in mdp_vsync_handler() - * disable_irq(MDP_HW_VSYNC_IRQ); - */ - mdp_vsync_handler(data); - - return IRQ_HANDLED; -} - -#ifdef MDP_HW_VSYNC -static void mdp_set_sync_cfg_0(struct msm_fb_data_type *mfd, int vsync_cnt) -{ - unsigned long cfg; - - cfg = mfd->total_lcd_lines - 1; - cfg <<= MDP_SYNCFG_HGT_LOC; - if (mfd->panel_info.lcd.hw_vsync_mode) - cfg |= MDP_SYNCFG_VSYNC_EXT_EN; - cfg |= (MDP_SYNCFG_VSYNC_INT_EN | vsync_cnt); - - MDP_OUTP(MDP_BASE + MDP_SYNC_CFG_0, cfg); -} -#endif - -void mdp_config_vsync(struct msm_fb_data_type *mfd) -{ - - /* vsync on primary lcd only for now */ - if ((mfd->dest != DISPLAY_LCD) || (mfd->panel_info.pdest != DISPLAY_1) - || (!vsync_mode)) { - goto err_handle; - } - - if (mfd->panel_info.lcd.vsync_enable) { - mfd->total_porch_lines = mfd->panel_info.lcd.v_back_porch + - mfd->panel_info.lcd.v_front_porch + - mfd->panel_info.lcd.v_pulse_width; - mfd->total_lcd_lines = - mfd->panel_info.yres + mfd->total_porch_lines; - mfd->lcd_ref_usec_time = - 100000000 / mfd->panel_info.lcd.refx100; - mfd->vsync_handler_pending = FALSE; - mfd->last_vsync_timetick.tv.sec = 0; - mfd->last_vsync_timetick.tv.nsec = 0; - -#ifdef MDP_HW_VSYNC - if (mdp_vsync_clk == NULL) - mdp_vsync_clk = clk_get(NULL, "mdp_vsync_clk"); - - if (IS_ERR(mdp_vsync_clk)) { - printk(KERN_ERR "error: can't get mdp_vsync_clk!\n"); - mfd->use_mdp_vsync = 0; - } else - mfd->use_mdp_vsync = 1; - - if (mfd->use_mdp_vsync) { - uint32 vsync_cnt_cfg, vsync_cnt_cfg_dem; - uint32 mdp_vsync_clk_speed_hz; - - mdp_vsync_clk_speed_hz = clk_get_rate(mdp_vsync_clk); - - if (mdp_vsync_clk_speed_hz == 0) { - mfd->use_mdp_vsync = 0; - } else { - /* - * Do this calculation in 2 steps for - * rounding uint32 properly. - */ - vsync_cnt_cfg_dem = - (mfd->panel_info.lcd.refx100 * - mfd->total_lcd_lines) / 100; - vsync_cnt_cfg = - (mdp_vsync_clk_speed_hz) / - vsync_cnt_cfg_dem; - - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, - FALSE); - mdp_hw_vsync_clk_enable(mfd); - - mdp_set_sync_cfg_0(mfd, vsync_cnt_cfg); - - /* - * load the last line + 1 to be in the - * safety zone - */ - vsync_load_cnt = mfd->panel_info.yres; - - /* line counter init value at the next pulse */ - MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_INIT_VAL, - vsync_load_cnt); - - /* - * external vsync source pulse width and - * polarity flip - */ - MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_OUT_CTRL, - BIT(30) | BIT(0)); - - - /* threshold */ - MDP_OUTP(MDP_BASE + 0x200, - (vsync_above_th << 16) | - (vsync_start_th)); - - mdp_hw_vsync_clk_disable(mfd); - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, - MDP_BLOCK_POWER_OFF, FALSE); - } - } -#else - mfd->use_mdp_vsync = 0; - hrtimer_init(&mfd->dma_hrtimer, CLOCK_MONOTONIC, - HRTIMER_MODE_REL); - mfd->dma_hrtimer.function = mdp_dma2_vsync_hrtimer_handler; - mfd->vsync_width_boundary = vmalloc(mfd->panel_info.xres * 4); -#endif - - mfd->channel_irq = 0; - if (mfd->panel_info.lcd.hw_vsync_mode) { - u32 vsync_gpio = mfd->vsync_gpio; - u32 ret; - - if (vsync_gpio == -1) { - MSM_FB_INFO("vsync_gpio not defined!\n"); - goto err_handle; - } - - ret = gpio_tlmm_config(GPIO_CFG - (vsync_gpio, - (mfd->use_mdp_vsync) ? 1 : 0, - GPIO_INPUT, - GPIO_PULL_DOWN, - GPIO_2MA), - GPIO_ENABLE); - if (ret) - goto err_handle; - - if (!mfd->use_mdp_vsync) { - mfd->channel_irq = MSM_GPIO_TO_INT(vsync_gpio); - if (request_irq - (mfd->channel_irq, - &mdp_hw_vsync_handler_proxy, - IRQF_TRIGGER_FALLING, "VSYNC_GPIO", - (void *)mfd)) { - MSM_FB_INFO - ("irq=%d failed! vsync_gpio=%d\n", - mfd->channel_irq, - vsync_gpio); - goto err_handle; - } - } - } - - mdp_set_vsync((unsigned long)mfd); - } - - return; - -err_handle: - if (mfd->vsync_width_boundary) - vfree(mfd->vsync_width_boundary); - mfd->panel_info.lcd.vsync_enable = FALSE; - printk(KERN_ERR "%s: failed!\n", __func__); -} - -void mdp_vsync_resync_workqueue_handler(struct work_struct *work) -{ - struct msm_fb_data_type *mfd = NULL; - int vsync_fnc_enabled = FALSE; - struct msm_fb_panel_data *pdata = NULL; - - mfd = container_of(work, struct msm_fb_data_type, vsync_resync_worker); - - if (mfd) { - if (mfd->panel_power_on) { - pdata = - (struct msm_fb_panel_data *)mfd->pdev->dev. - platform_data; - - /* - * we need to turn on MDP power if it uses MDP vsync - * HW block in SW mode - */ - if ((!mfd->panel_info.lcd.hw_vsync_mode) && - (mfd->use_mdp_vsync) && - (pdata) && (pdata->set_vsync_notifier != NULL)) { - /* - * enable pwr here since we can't enable it in - * vsync callback in isr mode - */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, - FALSE); - } - - if (pdata->set_vsync_notifier != NULL) { - vsync_fnc_enabled = TRUE; - pdata->set_vsync_notifier(mdp_vsync_handler, - (void *)mfd); - } - } - } - - if ((mfd) && (!vsync_fnc_enabled)) - mfd->vsync_handler_pending = FALSE; -} - -boolean mdp_hw_vsync_set_handler(msm_fb_vsync_handler_type handler, void *data) -{ - /* - * ToDo: tried enabling/disabling GPIO MDP HW VSYNC interrupt - * but getting inaccurate timing in mdp_vsync_handler() - * enable_irq(MDP_HW_VSYNC_IRQ); - */ - - return TRUE; -} - -uint32 mdp_get_lcd_line_counter(struct msm_fb_data_type *mfd) -{ - uint32 elapsed_usec_time; - uint32 lcd_line; - ktime_t last_vsync_timetick_local; - ktime_t curr_time; - unsigned long flag; - - if ((!mfd->panel_info.lcd.vsync_enable) || (!vsync_mode)) - return 0; - - spin_lock_irqsave(&mdp_spin_lock, flag); - last_vsync_timetick_local = mfd->last_vsync_timetick; - spin_unlock_irqrestore(&mdp_spin_lock, flag); - - curr_time = ktime_get_real(); - elapsed_usec_time = - ((curr_time.tv.sec - last_vsync_timetick_local.tv.sec) * 1000000) + - ((curr_time.tv.nsec - last_vsync_timetick_local.tv.nsec) / 1000); - - elapsed_usec_time = elapsed_usec_time % mfd->lcd_ref_usec_time; - - /* lcd line calculation referencing to line counter = 0 */ - lcd_line = - (elapsed_usec_time * mfd->total_lcd_lines) / mfd->lcd_ref_usec_time; - - /* lcd line adjusment referencing to the actual line counter at vsync */ - lcd_line = - (mfd->total_lcd_lines - mfd->panel_info.lcd.v_back_porch + - lcd_line) % (mfd->total_lcd_lines + 1); - - if (lcd_line > mfd->total_lcd_lines) { - MSM_FB_INFO - ("mdp_get_lcd_line_counter: mdp_lcd_rd_cnt >= mfd->total_lcd_lines error!\n"); - } - - return lcd_line; -} diff --git a/drivers/staging/msm/memory.c b/drivers/staging/msm/memory.c deleted file mode 100644 index cc80fdf17d61..000000000000 --- a/drivers/staging/msm/memory.c +++ /dev/null @@ -1,214 +0,0 @@ -/* arch/arm/mach-msm/memory.c - * - * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. - * - * 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 "memory_ll.h" -#include -#if defined(CONFIG_MSM_NPA_REMOTE) -#include "npa_remote.h" -#include -#include -#endif - -int arch_io_remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, - unsigned long pfn, unsigned long size, pgprot_t prot) -{ - unsigned long pfn_addr = pfn << PAGE_SHIFT; -/* - if ((pfn_addr >= 0x88000000) && (pfn_addr < 0xD0000000)) { - prot = pgprot_device(prot); - printk("remapping device %lx\n", prot); - } -*/ - panic("Memory remap PFN stuff not done\n"); - return remap_pfn_range(vma, addr, pfn, size, prot); -} - -void *zero_page_strongly_ordered; - -static void map_zero_page_strongly_ordered(void) -{ - if (zero_page_strongly_ordered) - return; -/* - zero_page_strongly_ordered = - ioremap_strongly_ordered(page_to_pfn(empty_zero_page) - << PAGE_SHIFT, PAGE_SIZE); -*/ - panic("Strongly ordered memory functions not implemented\n"); -} - -void write_to_strongly_ordered_memory(void) -{ - map_zero_page_strongly_ordered(); - *(int *)zero_page_strongly_ordered = 0; -} -EXPORT_SYMBOL(write_to_strongly_ordered_memory); - -void flush_axi_bus_buffer(void) -{ - __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ - : : "r" (0) : "memory"); - write_to_strongly_ordered_memory(); -} - -#define CACHE_LINE_SIZE 32 - -/* These cache related routines make the assumption that the associated - * physical memory is contiguous. They will operate on all (L1 - * and L2 if present) caches. - */ -void clean_and_invalidate_caches(unsigned long vstart, - unsigned long length, unsigned long pstart) -{ - unsigned long vaddr; - - for (vaddr = vstart; vaddr < vstart + length; vaddr += CACHE_LINE_SIZE) - asm ("mcr p15, 0, %0, c7, c14, 1" : : "r" (vaddr)); -#ifdef CONFIG_OUTER_CACHE - outer_flush_range(pstart, pstart + length); -#endif - asm ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); - asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0)); - - flush_axi_bus_buffer(); -} - -void clean_caches(unsigned long vstart, - unsigned long length, unsigned long pstart) -{ - unsigned long vaddr; - - for (vaddr = vstart; vaddr < vstart + length; vaddr += CACHE_LINE_SIZE) - asm ("mcr p15, 0, %0, c7, c10, 1" : : "r" (vaddr)); -#ifdef CONFIG_OUTER_CACHE - outer_clean_range(pstart, pstart + length); -#endif - asm ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); - asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0)); - - flush_axi_bus_buffer(); -} - -void invalidate_caches(unsigned long vstart, - unsigned long length, unsigned long pstart) -{ - unsigned long vaddr; - - for (vaddr = vstart; vaddr < vstart + length; vaddr += CACHE_LINE_SIZE) - asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (vaddr)); -#ifdef CONFIG_OUTER_CACHE - outer_inv_range(pstart, pstart + length); -#endif - asm ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)); - asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0)); - - flush_axi_bus_buffer(); -} - -void *alloc_bootmem_aligned(unsigned long size, unsigned long alignment) -{ - void *unused_addr = NULL; - unsigned long addr, tmp_size, unused_size; - - /* Allocate maximum size needed, see where it ends up. - * Then free it -- in this path there are no other allocators - * so we can depend on getting the same address back - * when we allocate a smaller piece that is aligned - * at the end (if necessary) and the piece we really want, - * then free the unused first piece. - */ - - tmp_size = size + alignment - PAGE_SIZE; - addr = (unsigned long)alloc_bootmem(tmp_size); - free_bootmem(__pa(addr), tmp_size); - - unused_size = alignment - (addr % alignment); - if (unused_size) - unused_addr = alloc_bootmem(unused_size); - - addr = (unsigned long)alloc_bootmem(size); - if (unused_size) - free_bootmem(__pa(unused_addr), unused_size); - - return (void *)addr; -} - -#if defined(CONFIG_MSM_NPA_REMOTE) -struct npa_client *npa_memory_client; -#endif - -static int change_memory_power_state(unsigned long start_pfn, - unsigned long nr_pages, int state) -{ -#if defined(CONFIG_MSM_NPA_REMOTE) - static atomic_t node_created_flag = ATOMIC_INIT(1); -#else - unsigned long start; - unsigned long size; - unsigned long virtual; -#endif - int rc = 0; - -#if defined(CONFIG_MSM_NPA_REMOTE) - if (atomic_dec_and_test(&node_created_flag)) { - /* Create NPA 'required' client. */ - npa_memory_client = npa_create_sync_client(NPA_MEMORY_NODE_NAME, - "memory node", NPA_CLIENT_REQUIRED); - if (IS_ERR(npa_memory_client)) { - rc = PTR_ERR(npa_memory_client); - return rc; - } - } - - rc = npa_issue_required_request(npa_memory_client, state); -#else - if (state == MEMORY_DEEP_POWERDOWN) { - /* simulate turning off memory by writing bit pattern into it */ - start = start_pfn << PAGE_SHIFT; - size = nr_pages << PAGE_SHIFT; - virtual = __phys_to_virt(start); - memset((void *)virtual, 0x27, size); - } -#endif - return rc; -} - -int platform_physical_remove_pages(unsigned long start_pfn, - unsigned long nr_pages) -{ - return change_memory_power_state(start_pfn, nr_pages, - MEMORY_DEEP_POWERDOWN); -} - -int platform_physical_add_pages(unsigned long start_pfn, - unsigned long nr_pages) -{ - return change_memory_power_state(start_pfn, nr_pages, MEMORY_ACTIVE); -} - -int platform_physical_low_power_pages(unsigned long start_pfn, - unsigned long nr_pages) -{ - return change_memory_power_state(start_pfn, nr_pages, - MEMORY_SELF_REFRESH); -} diff --git a/drivers/staging/msm/memory_ll.h b/drivers/staging/msm/memory_ll.h deleted file mode 100644 index 18a239a89a78..000000000000 --- a/drivers/staging/msm/memory_ll.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2007 Google, Inc. - * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. - * - * 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 __ASM_ARCH_MEMORY_LL_H -#define __ASM_ARCH_MEMORY_LL_H - -#define MAX_PHYSMEM_BITS 32 -#define SECTION_SIZE_BITS 25 - -#define HAS_ARCH_IO_REMAP_PFN_RANGE - -#ifndef __ASSEMBLY__ -void *alloc_bootmem_aligned(unsigned long size, unsigned long alignment); -void clean_and_invalidate_caches(unsigned long, unsigned long, unsigned long); -void clean_caches(unsigned long, unsigned long, unsigned long); -void invalidate_caches(unsigned long, unsigned long, unsigned long); -int platform_physical_remove_pages(unsigned long, unsigned long); -int platform_physical_add_pages(unsigned long, unsigned long); -int platform_physical_low_power_pages(unsigned long, unsigned long); - -#ifdef CONFIG_ARCH_MSM_ARM11 -void write_to_strongly_ordered_memory(void); - -#include - -#define arch_barrier_extra() do \ - { if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) \ - write_to_strongly_ordered_memory(); \ - } while (0) -#endif - -#ifdef CONFIG_CACHE_L2X0 -extern void l2x0_cache_sync(void); -#define finish_arch_switch(prev) do { l2x0_cache_sync(); } while (0) -#endif - -#endif - -#ifdef CONFIG_ARCH_MSM_SCORPION -#define arch_has_speculative_dfetch() 1 -#endif - -#endif - -/* these correspond to values known by the modem */ -#define MEMORY_DEEP_POWERDOWN 0 -#define MEMORY_SELF_REFRESH 1 -#define MEMORY_ACTIVE 2 - -#define NPA_MEMORY_NODE_NAME "/mem/ebi1/cs1" diff --git a/drivers/staging/msm/msm_fb.c b/drivers/staging/msm/msm_fb.c deleted file mode 100644 index e7ef836eb8de..000000000000 --- a/drivers/staging/msm/msm_fb.c +++ /dev/null @@ -1,2354 +0,0 @@ -/* - * - * Core MSM framebuffer driver. - * - * Copyright (C) 2007 Google Incorporated - * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. - * - * 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 "msm_mdp.h" -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define MSM_FB_C -#include "msm_fb.h" -#include "mddihosti.h" -#include "tvenc.h" -#include "mdp.h" -#include "mdp4.h" - -#ifdef CONFIG_FB_MSM_LOGO -#define INIT_IMAGE_FILE "/logo.rle" -extern int load_565rle_image(char *filename); -#endif - - -#define pgprot_noncached(prot) \ - __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED) -#define pgprot_writecombine(prot) \ - __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE) -#define pgprot_device(prot) \ - __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_DEV_NONSHARED) -#define pgprot_writethroughcache(prot) \ - __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_WRITETHROUGH) -#define pgprot_writebackcache(prot) \ - __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_WRITEBACK) -#define pgprot_writebackwacache(prot) \ - __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_WRITEALLOC) - -static unsigned char *fbram; -static unsigned char *fbram_phys; -static int fbram_size; - -static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST]; -static int pdev_list_cnt; - -int vsync_mode = 1; - -#define MAX_FBI_LIST 32 -static struct fb_info *fbi_list[MAX_FBI_LIST]; -static int fbi_list_index; - -static struct msm_fb_data_type *mfd_list[MAX_FBI_LIST]; -static int mfd_list_index; - -static u32 msm_fb_pseudo_palette[16] = { - 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff -}; - -u32 msm_fb_debug_enabled; -/* Setting msm_fb_msg_level to 8 prints out ALL messages */ -u32 msm_fb_msg_level = 7; - -/* Setting mddi_msg_level to 8 prints out ALL messages */ -u32 mddi_msg_level = 5; - -extern int32 mdp_block_power_cnt[MDP_MAX_BLOCK]; -extern unsigned long mdp_timer_duration; - -static int msm_fb_register(struct msm_fb_data_type *mfd); -static int msm_fb_open(struct fb_info *info, int user); -static int msm_fb_release(struct fb_info *info, int user); -static int msm_fb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info); -static int msm_fb_stop_sw_refresher(struct msm_fb_data_type *mfd); -int msm_fb_resume_sw_refresher(struct msm_fb_data_type *mfd); -static int msm_fb_check_var(struct fb_var_screeninfo *var, - struct fb_info *info); -static int msm_fb_set_par(struct fb_info *info); -static int msm_fb_blank_sub(int blank_mode, struct fb_info *info, - boolean op_enable); -static int msm_fb_suspend_sub(struct msm_fb_data_type *mfd); -static int msm_fb_resume_sub(struct msm_fb_data_type *mfd); -static int msm_fb_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg); -static int msm_fb_mmap(struct fb_info *info, struct vm_area_struct * vma); - -#ifdef MSM_FB_ENABLE_DBGFS - -#define MSM_FB_MAX_DBGFS 1024 -#define MAX_BACKLIGHT_BRIGHTNESS 255 - -int msm_fb_debugfs_file_index; -struct dentry *msm_fb_debugfs_root; -struct dentry *msm_fb_debugfs_file[MSM_FB_MAX_DBGFS]; - -struct dentry *msm_fb_get_debugfs_root(void) -{ - if (msm_fb_debugfs_root == NULL) - msm_fb_debugfs_root = debugfs_create_dir("msm_fb", NULL); - - return msm_fb_debugfs_root; -} - -void msm_fb_debugfs_file_create(struct dentry *root, const char *name, - u32 *var) -{ - if (msm_fb_debugfs_file_index >= MSM_FB_MAX_DBGFS) - return; - - msm_fb_debugfs_file[msm_fb_debugfs_file_index++] = - debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var); -} -#endif - -int msm_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - - if (!mfd->cursor_update) - return -ENODEV; - - return mfd->cursor_update(info, cursor); -} - -static int msm_fb_resource_initialized; - -#ifndef CONFIG_FB_BACKLIGHT -static int lcd_backlight_registered; - -static void msm_fb_set_bl_brightness(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct msm_fb_data_type *mfd = dev_get_drvdata(led_cdev->dev->parent); - int bl_lvl; - - if (value > MAX_BACKLIGHT_BRIGHTNESS) - value = MAX_BACKLIGHT_BRIGHTNESS; - - /* This maps android backlight level 0 to 255 into - driver backlight level 0 to bl_max with rounding */ - bl_lvl = (2 * value * mfd->panel_info.bl_max + MAX_BACKLIGHT_BRIGHTNESS) - /(2 * MAX_BACKLIGHT_BRIGHTNESS); - - if (!bl_lvl && value) - bl_lvl = 1; - - msm_fb_set_backlight(mfd, bl_lvl, 1); -} - -static struct led_classdev backlight_led = { - .name = "lcd-backlight", - .brightness = MAX_BACKLIGHT_BRIGHTNESS, - .brightness_set = msm_fb_set_bl_brightness, -}; -#endif - -static struct msm_fb_platform_data *msm_fb_pdata; - -int msm_fb_detect_client(const char *name) -{ - int ret = -EPERM; -#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT - u32 id; -#endif - - if (msm_fb_pdata && msm_fb_pdata->detect_client) { - ret = msm_fb_pdata->detect_client(name); - - /* if it's non mddi panel, we need to pre-scan - mddi client to see if we can disable mddi host */ - -#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT - if (!ret && msm_fb_pdata->mddi_prescan) - id = mddi_get_client_id(); -#endif - } - - return ret; -} - -static int msm_fb_probe(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - int rc; - - MSM_FB_DEBUG("msm_fb_probe\n"); - - if ((pdev->id == 0) && (pdev->num_resources > 0)) { - msm_fb_pdata = pdev->dev.platform_data; - fbram_size = - pdev->resource[0].end - pdev->resource[0].start + 1; - fbram_phys = (char *)pdev->resource[0].start; - fbram = ioremap((unsigned long)fbram_phys, fbram_size); - - if (!fbram) { - printk(KERN_ERR "fbram ioremap failed!\n"); - return -ENOMEM; - } - MSM_FB_INFO("msm_fb_probe: phy_Addr = 0x%x virt = 0x%x\n", - (int)fbram_phys, (int)fbram); - - msm_fb_resource_initialized = 1; - return 0; - } - - if (!msm_fb_resource_initialized) - return -EPERM; - - mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST) - return -ENOMEM; - - mfd->panel_info.frame_count = 0; - mfd->bl_level = mfd->panel_info.bl_max; - - if (mfd->panel_info.type == LCDC_PANEL) - mfd->allow_set_offset = - msm_fb_pdata->allow_set_offset != NULL ? - msm_fb_pdata->allow_set_offset() : 0; - else - mfd->allow_set_offset = 0; - - rc = msm_fb_register(mfd); - if (rc) - return rc; - -#ifdef CONFIG_FB_BACKLIGHT - msm_fb_config_backlight(mfd); -#else - /* android supports only one lcd-backlight/lcd for now */ - if (!lcd_backlight_registered) { - if (led_classdev_register(&pdev->dev, &backlight_led)) - printk(KERN_ERR "led_classdev_register failed\n"); - else - lcd_backlight_registered = 1; - } -#endif - - pdev_list[pdev_list_cnt++] = pdev; - return 0; -} - -static int msm_fb_remove(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - - MSM_FB_DEBUG("msm_fb_remove\n"); - - mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - if (msm_fb_suspend_sub(mfd)) - printk(KERN_ERR "msm_fb_remove: can't stop the device %d\n", mfd->index); - - if (mfd->channel_irq != 0) - free_irq(mfd->channel_irq, (void *)mfd); - - if (mfd->vsync_width_boundary) - vfree(mfd->vsync_width_boundary); - - if (mfd->vsync_resync_timer.function) - del_timer(&mfd->vsync_resync_timer); - - if (mfd->refresh_timer.function) - del_timer(&mfd->refresh_timer); - - if (mfd->dma_hrtimer.function) - hrtimer_cancel(&mfd->dma_hrtimer); - - /* remove /dev/fb* */ - unregister_framebuffer(mfd->fbi); - -#ifdef CONFIG_FB_BACKLIGHT - /* remove /sys/class/backlight */ - backlight_device_unregister(mfd->fbi->bl_dev); -#else - if (lcd_backlight_registered) { - lcd_backlight_registered = 0; - led_classdev_unregister(&backlight_led); - } -#endif - -#ifdef MSM_FB_ENABLE_DBGFS - if (mfd->sub_dir) - debugfs_remove(mfd->sub_dir); -#endif - - return 0; -} - -#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND) -static int msm_fb_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct msm_fb_data_type *mfd; - int ret = 0; - - MSM_FB_DEBUG("msm_fb_suspend\n"); - - mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); - - if ((!mfd) || (mfd->key != MFD_KEY)) - return 0; - - console_lock(); - fb_set_suspend(mfd->fbi, 1); - - ret = msm_fb_suspend_sub(mfd); - if (ret != 0) { - printk(KERN_ERR "msm_fb: failed to suspend! %d\n", ret); - fb_set_suspend(mfd->fbi, 0); - } else { - pdev->dev.power.power_state = state; - } - - console_unlock(); - return ret; -} -#else -#define msm_fb_suspend NULL -#endif - -static int msm_fb_suspend_sub(struct msm_fb_data_type *mfd) -{ - int ret = 0; - - if ((!mfd) || (mfd->key != MFD_KEY)) - return 0; - - /* - * suspend this channel - */ - mfd->suspend.sw_refreshing_enable = mfd->sw_refreshing_enable; - mfd->suspend.op_enable = mfd->op_enable; - mfd->suspend.panel_power_on = mfd->panel_power_on; - - if (mfd->op_enable) { - ret = - msm_fb_blank_sub(FB_BLANK_POWERDOWN, mfd->fbi, - mfd->suspend.op_enable); - if (ret) { - MSM_FB_INFO - ("msm_fb_suspend: can't turn off display!\n"); - return ret; - } - mfd->op_enable = FALSE; - } - /* - * try to power down - */ - mdp_pipe_ctrl(MDP_MASTER_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - - /* - * detach display channel irq if there's any - * or wait until vsync-resync completes - */ - if ((mfd->dest == DISPLAY_LCD)) { - if (mfd->panel_info.lcd.vsync_enable) { - if (mfd->panel_info.lcd.hw_vsync_mode) { - if (mfd->channel_irq != 0) - disable_irq(mfd->channel_irq); - } else { - volatile boolean vh_pending; - do { - vh_pending = mfd->vsync_handler_pending; - } while (vh_pending); - } - } - } - - return 0; -} - -#if defined(CONFIG_PM) && !defined(CONFIG_HAS_EARLYSUSPEND) -static int msm_fb_resume(struct platform_device *pdev) -{ - /* This resume function is called when interrupt is enabled. - */ - int ret = 0; - struct msm_fb_data_type *mfd; - - MSM_FB_DEBUG("msm_fb_resume\n"); - - mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev); - - if ((!mfd) || (mfd->key != MFD_KEY)) - return 0; - - console_lock(); - ret = msm_fb_resume_sub(mfd); - pdev->dev.power.power_state = PMSG_ON; - fb_set_suspend(mfd->fbi, 1); - console_unlock(); - - return ret; -} -#else -#define msm_fb_resume NULL -#endif - -static int msm_fb_resume_sub(struct msm_fb_data_type *mfd) -{ - int ret = 0; - - if ((!mfd) || (mfd->key != MFD_KEY)) - return 0; - - /* attach display channel irq if there's any */ - if (mfd->channel_irq != 0) - enable_irq(mfd->channel_irq); - - /* resume state var recover */ - mfd->sw_refreshing_enable = mfd->suspend.sw_refreshing_enable; - mfd->op_enable = mfd->suspend.op_enable; - - if (mfd->suspend.panel_power_on) { - ret = - msm_fb_blank_sub(FB_BLANK_UNBLANK, mfd->fbi, - mfd->op_enable); - if (ret) - MSM_FB_INFO("msm_fb_resume: can't turn on display!\n"); - } - - return ret; -} - -static struct platform_driver msm_fb_driver = { - .probe = msm_fb_probe, - .remove = msm_fb_remove, -#ifndef CONFIG_HAS_EARLYSUSPEND - .suspend = msm_fb_suspend, - .resume = msm_fb_resume, -#endif - .shutdown = NULL, - .driver = { - /* Driver name must match the device name added in platform.c. */ - .name = "msm_fb", - }, -}; - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void msmfb_early_suspend(struct early_suspend *h) -{ - struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type, - early_suspend); - msm_fb_suspend_sub(mfd); -} - -static void msmfb_early_resume(struct early_suspend *h) -{ - struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type, - early_suspend); - msm_fb_resume_sub(mfd); -} -#endif - -void msm_fb_set_backlight(struct msm_fb_data_type *mfd, __u32 bkl_lvl, u32 save) -{ - struct msm_fb_panel_data *pdata; - - pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data; - - if ((pdata) && (pdata->set_backlight)) { - down(&mfd->sem); - if ((bkl_lvl != mfd->bl_level) || (!save)) { - u32 old_lvl; - - old_lvl = mfd->bl_level; - mfd->bl_level = bkl_lvl; - pdata->set_backlight(mfd); - - if (!save) - mfd->bl_level = old_lvl; - } - up(&mfd->sem); - } -} - -static int msm_fb_blank_sub(int blank_mode, struct fb_info *info, - boolean op_enable) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - struct msm_fb_panel_data *pdata = NULL; - int ret = 0; - - if (!op_enable) - return -EPERM; - - pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data; - if ((!pdata) || (!pdata->on) || (!pdata->off)) { - printk(KERN_ERR "msm_fb_blank_sub: no panel operation detected!\n"); - return -ENODEV; - } - - switch (blank_mode) { - case FB_BLANK_UNBLANK: - if (!mfd->panel_power_on) { - mdelay(100); - ret = pdata->on(mfd->pdev); - if (ret == 0) { - mfd->panel_power_on = TRUE; - - msm_fb_set_backlight(mfd, - mfd->bl_level, 0); - -/* ToDo: possible conflict with android which doesn't expect sw refresher */ -/* - if (!mfd->hw_refresh) - { - if ((ret = msm_fb_resume_sw_refresher(mfd)) != 0) - { - MSM_FB_INFO("msm_fb_blank_sub: msm_fb_resume_sw_refresher failed = %d!\n",ret); - } - } -*/ - } - } - break; - - case FB_BLANK_VSYNC_SUSPEND: - case FB_BLANK_HSYNC_SUSPEND: - case FB_BLANK_NORMAL: - case FB_BLANK_POWERDOWN: - default: - if (mfd->panel_power_on) { - int curr_pwr_state; - - mfd->op_enable = FALSE; - curr_pwr_state = mfd->panel_power_on; - mfd->panel_power_on = FALSE; - - mdelay(100); - ret = pdata->off(mfd->pdev); - if (ret) - mfd->panel_power_on = curr_pwr_state; - - msm_fb_set_backlight(mfd, 0, 0); - mfd->op_enable = TRUE; - } - break; - } - - return ret; -} - -static void msm_fb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - - cfb_fillrect(info, rect); - if (!mfd->hw_refresh && (info->var.yoffset == 0) && - !mfd->sw_currently_refreshing) { - struct fb_var_screeninfo var; - - var = info->var; - var.reserved[0] = 0x54445055; - var.reserved[1] = (rect->dy << 16) | (rect->dx); - var.reserved[2] = ((rect->dy + rect->height) << 16) | - (rect->dx + rect->width); - - msm_fb_pan_display(&var, info); - } -} - -static void msm_fb_copyarea(struct fb_info *info, - const struct fb_copyarea *area) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - - cfb_copyarea(info, area); - if (!mfd->hw_refresh && (info->var.yoffset == 0) && - !mfd->sw_currently_refreshing) { - struct fb_var_screeninfo var; - - var = info->var; - var.reserved[0] = 0x54445055; - var.reserved[1] = (area->dy << 16) | (area->dx); - var.reserved[2] = ((area->dy + area->height) << 16) | - (area->dx + area->width); - - msm_fb_pan_display(&var, info); - } -} - -static void msm_fb_imageblit(struct fb_info *info, const struct fb_image *image) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - - cfb_imageblit(info, image); - if (!mfd->hw_refresh && (info->var.yoffset == 0) && - !mfd->sw_currently_refreshing) { - struct fb_var_screeninfo var; - - var = info->var; - var.reserved[0] = 0x54445055; - var.reserved[1] = (image->dy << 16) | (image->dx); - var.reserved[2] = ((image->dy + image->height) << 16) | - (image->dx + image->width); - - msm_fb_pan_display(&var, info); - } -} - -static int msm_fb_blank(int blank_mode, struct fb_info *info) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - return msm_fb_blank_sub(blank_mode, info, mfd->op_enable); -} - -static int msm_fb_set_lut(struct fb_cmap *cmap, struct fb_info *info) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - - if (!mfd->lut_update) - return -ENODEV; - - mfd->lut_update(info, cmap); - return 0; -} - -/* - * Custom Framebuffer mmap() function for MSM driver. - * Differs from standard mmap() function by allowing for customized - * page-protection. - */ -static int msm_fb_mmap(struct fb_info *info, struct vm_area_struct * vma) -{ - /* Get frame buffer memory range. */ - unsigned long start = info->fix.smem_start; - u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); - unsigned long off = vma->vm_pgoff << PAGE_SHIFT; - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - if (off >= len) { - /* memory mapped io */ - off -= len; - if (info->var.accel_flags) { - mutex_unlock(&info->lock); - return -EINVAL; - } - start = info->fix.mmio_start; - len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); - } - - /* Set VM flags. */ - start &= PAGE_MASK; - if ((vma->vm_end - vma->vm_start + off) > len) - return -EINVAL; - off += start; - vma->vm_pgoff = off >> PAGE_SHIFT; - /* This is an IO map - tell maydump to skip this VMA */ - vma->vm_flags |= VM_IO | VM_RESERVED; - - /* Set VM page protection */ - if (mfd->mdp_fb_page_protection == MDP_FB_PAGE_PROTECTION_WRITECOMBINE) - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - else if (mfd->mdp_fb_page_protection == - MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE) - vma->vm_page_prot = pgprot_writethroughcache(vma->vm_page_prot); - else if (mfd->mdp_fb_page_protection == - MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE) - vma->vm_page_prot = pgprot_writebackcache(vma->vm_page_prot); - else if (mfd->mdp_fb_page_protection == - MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE) - vma->vm_page_prot = pgprot_writebackwacache(vma->vm_page_prot); - else - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - /* Remap the frame buffer I/O range */ - if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) - return -EAGAIN; - - return 0; -} - -static struct fb_ops msm_fb_ops = { - .owner = THIS_MODULE, - .fb_open = msm_fb_open, - .fb_release = msm_fb_release, - .fb_read = NULL, - .fb_write = NULL, - .fb_cursor = NULL, - .fb_check_var = msm_fb_check_var, /* vinfo check */ - .fb_set_par = msm_fb_set_par, /* set the video mode according to info->var */ - .fb_setcolreg = NULL, /* set color register */ - .fb_blank = msm_fb_blank, /* blank display */ - .fb_pan_display = msm_fb_pan_display, /* pan display */ - .fb_fillrect = msm_fb_fillrect, /* Draws a rectangle */ - .fb_copyarea = msm_fb_copyarea, /* Copy data from area to another */ - .fb_imageblit = msm_fb_imageblit, /* Draws a image to the display */ - .fb_rotate = NULL, - .fb_sync = NULL, /* wait for blit idle, optional */ - .fb_ioctl = msm_fb_ioctl, /* perform fb specific ioctl (optional) */ - .fb_mmap = msm_fb_mmap, -}; - -static int msm_fb_register(struct msm_fb_data_type *mfd) -{ - int ret = -ENODEV; - int bpp; - struct msm_panel_info *panel_info = &mfd->panel_info; - struct fb_info *fbi = mfd->fbi; - struct fb_fix_screeninfo *fix; - struct fb_var_screeninfo *var; - int *id; - int fbram_offset; - - /* - * fb info initialization - */ - fix = &fbi->fix; - var = &fbi->var; - - fix->type_aux = 0; /* if type == FB_TYPE_INTERLEAVED_PLANES */ - fix->visual = FB_VISUAL_TRUECOLOR; /* True Color */ - fix->ywrapstep = 0; /* No support */ - fix->mmio_start = 0; /* No MMIO Address */ - fix->mmio_len = 0; /* No MMIO Address */ - fix->accel = FB_ACCEL_NONE;/* FB_ACCEL_MSM needes to be added in fb.h */ - - var->xoffset = 0, /* Offset from virtual to visible */ - var->yoffset = 0, /* resolution */ - var->grayscale = 0, /* No graylevels */ - var->nonstd = 0, /* standard pixel format */ - var->activate = FB_ACTIVATE_VBL, /* activate it at vsync */ - var->height = -1, /* height of picture in mm */ - var->width = -1, /* width of picture in mm */ - var->accel_flags = 0, /* acceleration flags */ - var->sync = 0, /* see FB_SYNC_* */ - var->rotate = 0, /* angle we rotate counter clockwise */ - mfd->op_enable = FALSE; - - switch (mfd->fb_imgType) { - case MDP_RGB_565: - fix->type = FB_TYPE_PACKED_PIXELS; - fix->xpanstep = 1; - fix->ypanstep = 1; - var->vmode = FB_VMODE_NONINTERLACED; - var->blue.offset = 0; - var->green.offset = 5; - var->red.offset = 11; - var->blue.length = 5; - var->green.length = 6; - var->red.length = 5; - var->blue.msb_right = 0; - var->green.msb_right = 0; - var->red.msb_right = 0; - var->transp.offset = 0; - var->transp.length = 0; - bpp = 2; - break; - - case MDP_RGB_888: - fix->type = FB_TYPE_PACKED_PIXELS; - fix->xpanstep = 1; - fix->ypanstep = 1; - var->vmode = FB_VMODE_NONINTERLACED; - var->blue.offset = 0; - var->green.offset = 8; - var->red.offset = 16; - var->blue.length = 8; - var->green.length = 8; - var->red.length = 8; - var->blue.msb_right = 0; - var->green.msb_right = 0; - var->red.msb_right = 0; - var->transp.offset = 0; - var->transp.length = 0; - bpp = 3; - break; - - case MDP_ARGB_8888: - fix->type = FB_TYPE_PACKED_PIXELS; - fix->xpanstep = 1; - fix->ypanstep = 1; - var->vmode = FB_VMODE_NONINTERLACED; - var->blue.offset = 0; - var->green.offset = 8; - var->red.offset = 16; - var->blue.length = 8; - var->green.length = 8; - var->red.length = 8; - var->blue.msb_right = 0; - var->green.msb_right = 0; - var->red.msb_right = 0; - var->transp.offset = 24; - var->transp.length = 8; - bpp = 3; - break; - - case MDP_YCRYCB_H2V1: - /* ToDo: need to check TV-Out YUV422i framebuffer format */ - /* we might need to create new type define */ - fix->type = FB_TYPE_INTERLEAVED_PLANES; - fix->xpanstep = 2; - fix->ypanstep = 1; - var->vmode = FB_VMODE_NONINTERLACED; - - /* how about R/G/B offset? */ - var->blue.offset = 0; - var->green.offset = 5; - var->red.offset = 11; - var->blue.length = 5; - var->green.length = 6; - var->red.length = 5; - var->blue.msb_right = 0; - var->green.msb_right = 0; - var->red.msb_right = 0; - var->transp.offset = 0; - var->transp.length = 0; - bpp = 2; - break; - - default: - MSM_FB_ERR("msm_fb_init: fb %d unknown image type!\n", - mfd->index); - return ret; - } - - /* The adreno GPU hardware requires that the pitch be aligned to - 32 pixels for color buffers, so for the cases where the GPU - is writing directly to fb0, the framebuffer pitch - also needs to be 32 pixel aligned */ - - if (mfd->index == 0) - fix->line_length = ALIGN(panel_info->xres * bpp, 32); - else - fix->line_length = panel_info->xres * bpp; - - fix->smem_len = fix->line_length * panel_info->yres * mfd->fb_page; - - mfd->var_xres = panel_info->xres; - mfd->var_yres = panel_info->yres; - - var->pixclock = mfd->panel_info.clk_rate; - mfd->var_pixclock = var->pixclock; - - var->xres = panel_info->xres; - var->yres = panel_info->yres; - var->xres_virtual = panel_info->xres; - var->yres_virtual = panel_info->yres * mfd->fb_page; - var->bits_per_pixel = bpp * 8, /* FrameBuffer color depth */ - /* - * id field for fb app - */ - id = (int *)&mfd->panel; - -#if defined(CONFIG_FB_MSM_MDP22) - snprintf(fix->id, sizeof(fix->id), "msmfb22_%x", (__u32) *id); -#elif defined(CONFIG_FB_MSM_MDP30) - snprintf(fix->id, sizeof(fix->id), "msmfb30_%x", (__u32) *id); -#elif defined(CONFIG_FB_MSM_MDP31) - snprintf(fix->id, sizeof(fix->id), "msmfb31_%x", (__u32) *id); -#elif defined(CONFIG_FB_MSM_MDP40) - snprintf(fix->id, sizeof(fix->id), "msmfb40_%x", (__u32) *id); -#else - error CONFIG_FB_MSM_MDP undefined ! -#endif - fbi->fbops = &msm_fb_ops; - fbi->flags = FBINFO_FLAG_DEFAULT; - fbi->pseudo_palette = msm_fb_pseudo_palette; - - mfd->ref_cnt = 0; - mfd->sw_currently_refreshing = FALSE; - mfd->sw_refreshing_enable = TRUE; - mfd->panel_power_on = FALSE; - - mfd->pan_waiting = FALSE; - init_completion(&mfd->pan_comp); - init_completion(&mfd->refresher_comp); - sema_init(&mfd->sem, 1); - - fbram_offset = PAGE_ALIGN((int)fbram)-(int)fbram; - fbram += fbram_offset; - fbram_phys += fbram_offset; - fbram_size -= fbram_offset; - - if (fbram_size < fix->smem_len) { - printk(KERN_ERR "error: no more framebuffer memory!\n"); - return -ENOMEM; - } - - fbi->screen_base = fbram; - fbi->fix.smem_start = (unsigned long)fbram_phys; - - memset(fbi->screen_base, 0x0, fix->smem_len); - - mfd->op_enable = TRUE; - mfd->panel_power_on = FALSE; - - /* cursor memory allocation */ - if (mfd->cursor_update) { - mfd->cursor_buf = dma_alloc_coherent(NULL, - MDP_CURSOR_SIZE, - (dma_addr_t *) &mfd->cursor_buf_phys, - GFP_KERNEL); - if (!mfd->cursor_buf) - mfd->cursor_update = 0; - } - - if (mfd->lut_update) { - ret = fb_alloc_cmap(&fbi->cmap, 256, 0); - if (ret) - printk(KERN_ERR "%s: fb_alloc_cmap() failed!\n", - __func__); - } - - if (register_framebuffer(fbi) < 0) { - if (mfd->lut_update) - fb_dealloc_cmap(&fbi->cmap); - - if (mfd->cursor_buf) - dma_free_coherent(NULL, - MDP_CURSOR_SIZE, - mfd->cursor_buf, - (dma_addr_t) mfd->cursor_buf_phys); - - mfd->op_enable = FALSE; - return -EPERM; - } - - fbram += fix->smem_len; - fbram_phys += fix->smem_len; - fbram_size -= fix->smem_len; - - MSM_FB_INFO - ("FrameBuffer[%d] %dx%d size=%d bytes is registered successfully!\n", - mfd->index, fbi->var.xres, fbi->var.yres, fbi->fix.smem_len); - -#ifdef CONFIG_FB_MSM_LOGO - if (!load_565rle_image(INIT_IMAGE_FILE)) ; /* Flip buffer */ -#endif - ret = 0; - -#ifdef CONFIG_HAS_EARLYSUSPEND - mfd->early_suspend.suspend = msmfb_early_suspend; - mfd->early_suspend.resume = msmfb_early_resume; - mfd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 2; - register_early_suspend(&mfd->early_suspend); -#endif - -#ifdef MSM_FB_ENABLE_DBGFS - { - struct dentry *root; - struct dentry *sub_dir; - char sub_name[2]; - - root = msm_fb_get_debugfs_root(); - if (root != NULL) { - sub_name[0] = (char)(mfd->index + 0x30); - sub_name[1] = '\0'; - sub_dir = debugfs_create_dir(sub_name, root); - } else { - sub_dir = NULL; - } - - mfd->sub_dir = sub_dir; - - if (sub_dir) { - msm_fb_debugfs_file_create(sub_dir, "op_enable", - (u32 *) &mfd->op_enable); - msm_fb_debugfs_file_create(sub_dir, "panel_power_on", - (u32 *) &mfd-> - panel_power_on); - msm_fb_debugfs_file_create(sub_dir, "ref_cnt", - (u32 *) &mfd->ref_cnt); - msm_fb_debugfs_file_create(sub_dir, "fb_imgType", - (u32 *) &mfd->fb_imgType); - msm_fb_debugfs_file_create(sub_dir, - "sw_currently_refreshing", - (u32 *) &mfd-> - sw_currently_refreshing); - msm_fb_debugfs_file_create(sub_dir, - "sw_refreshing_enable", - (u32 *) &mfd-> - sw_refreshing_enable); - - msm_fb_debugfs_file_create(sub_dir, "xres", - (u32 *) &mfd->panel_info. - xres); - msm_fb_debugfs_file_create(sub_dir, "yres", - (u32 *) &mfd->panel_info. - yres); - msm_fb_debugfs_file_create(sub_dir, "bpp", - (u32 *) &mfd->panel_info. - bpp); - msm_fb_debugfs_file_create(sub_dir, "type", - (u32 *) &mfd->panel_info. - type); - msm_fb_debugfs_file_create(sub_dir, "wait_cycle", - (u32 *) &mfd->panel_info. - wait_cycle); - msm_fb_debugfs_file_create(sub_dir, "pdest", - (u32 *) &mfd->panel_info. - pdest); - msm_fb_debugfs_file_create(sub_dir, "backbuff", - (u32 *) &mfd->panel_info. - fb_num); - msm_fb_debugfs_file_create(sub_dir, "clk_rate", - (u32 *) &mfd->panel_info. - clk_rate); - msm_fb_debugfs_file_create(sub_dir, "frame_count", - (u32 *) &mfd->panel_info. - frame_count); - - - switch (mfd->dest) { - case DISPLAY_LCD: - msm_fb_debugfs_file_create(sub_dir, - "vsync_enable", - (u32 *)&mfd->panel_info.lcd.vsync_enable); - msm_fb_debugfs_file_create(sub_dir, - "refx100", - (u32 *) &mfd->panel_info.lcd. refx100); - msm_fb_debugfs_file_create(sub_dir, - "v_back_porch", - (u32 *) &mfd->panel_info.lcd.v_back_porch); - msm_fb_debugfs_file_create(sub_dir, - "v_front_porch", - (u32 *) &mfd->panel_info.lcd.v_front_porch); - msm_fb_debugfs_file_create(sub_dir, - "v_pulse_width", - (u32 *) &mfd->panel_info.lcd.v_pulse_width); - msm_fb_debugfs_file_create(sub_dir, - "hw_vsync_mode", - (u32 *) &mfd->panel_info.lcd.hw_vsync_mode); - msm_fb_debugfs_file_create(sub_dir, - "vsync_notifier_period", (u32 *) - &mfd->panel_info.lcd.vsync_notifier_period); - break; - - case DISPLAY_LCDC: - msm_fb_debugfs_file_create(sub_dir, - "h_back_porch", - (u32 *) &mfd->panel_info.lcdc.h_back_porch); - msm_fb_debugfs_file_create(sub_dir, - "h_front_porch", - (u32 *) &mfd->panel_info.lcdc.h_front_porch); - msm_fb_debugfs_file_create(sub_dir, - "h_pulse_width", - (u32 *) &mfd->panel_info.lcdc.h_pulse_width); - msm_fb_debugfs_file_create(sub_dir, - "v_back_porch", - (u32 *) &mfd->panel_info.lcdc.v_back_porch); - msm_fb_debugfs_file_create(sub_dir, - "v_front_porch", - (u32 *) &mfd->panel_info.lcdc.v_front_porch); - msm_fb_debugfs_file_create(sub_dir, - "v_pulse_width", - (u32 *) &mfd->panel_info.lcdc.v_pulse_width); - msm_fb_debugfs_file_create(sub_dir, - "border_clr", - (u32 *) &mfd->panel_info.lcdc.border_clr); - msm_fb_debugfs_file_create(sub_dir, - "underflow_clr", - (u32 *) &mfd->panel_info.lcdc.underflow_clr); - msm_fb_debugfs_file_create(sub_dir, - "hsync_skew", - (u32 *) &mfd->panel_info.lcdc.hsync_skew); - break; - - default: - break; - } - } - } -#endif /* MSM_FB_ENABLE_DBGFS */ - - return ret; -} - -static int msm_fb_open(struct fb_info *info, int user) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - - if (!mfd->ref_cnt) { - mdp_set_dma_pan_info(info, NULL, TRUE); - - if (msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable)) { - printk(KERN_ERR "msm_fb_open: can't turn on display!\n"); - return -1; - } - } - - mfd->ref_cnt++; - return 0; -} - -static int msm_fb_release(struct fb_info *info, int user) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - int ret = 0; - - if (!mfd->ref_cnt) { - MSM_FB_INFO("msm_fb_release: try to close unopened fb %d!\n", - mfd->index); - return -EINVAL; - } - - mfd->ref_cnt--; - - if (!mfd->ref_cnt) { - if ((ret = - msm_fb_blank_sub(FB_BLANK_POWERDOWN, info, - mfd->op_enable)) != 0) { - printk(KERN_ERR "msm_fb_release: can't turn off display!\n"); - return ret; - } - } - - return ret; -} - -DEFINE_SEMAPHORE(msm_fb_pan_sem); - -static int msm_fb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *info) -{ - struct mdp_dirty_region dirty; - struct mdp_dirty_region *dirtyPtr = NULL; - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - - if ((!mfd->op_enable) || (!mfd->panel_power_on)) - return -EPERM; - - if (var->xoffset > (info->var.xres_virtual - info->var.xres)) - return -EINVAL; - - if (var->yoffset > (info->var.yres_virtual - info->var.yres)) - return -EINVAL; - - if (info->fix.xpanstep) - info->var.xoffset = - (var->xoffset / info->fix.xpanstep) * info->fix.xpanstep; - - if (info->fix.ypanstep) - info->var.yoffset = - (var->yoffset / info->fix.ypanstep) * info->fix.ypanstep; - - /* "UPDT" */ - if (var->reserved[0] == 0x54445055) { - dirty.xoffset = var->reserved[1] & 0xffff; - dirty.yoffset = (var->reserved[1] >> 16) & 0xffff; - - if ((var->reserved[2] & 0xffff) <= dirty.xoffset) - return -EINVAL; - if (((var->reserved[2] >> 16) & 0xffff) <= dirty.yoffset) - return -EINVAL; - - dirty.width = (var->reserved[2] & 0xffff) - dirty.xoffset; - dirty.height = - ((var->reserved[2] >> 16) & 0xffff) - dirty.yoffset; - info->var.yoffset = var->yoffset; - - if (dirty.xoffset < 0) - return -EINVAL; - - if (dirty.yoffset < 0) - return -EINVAL; - - if ((dirty.xoffset + dirty.width) > info->var.xres) - return -EINVAL; - - if ((dirty.yoffset + dirty.height) > info->var.yres) - return -EINVAL; - - if ((dirty.width <= 0) || (dirty.height <= 0)) - return -EINVAL; - - dirtyPtr = &dirty; - } - - /* Flip */ - /* A constant value is used to indicate that we should change the DMA - output buffer instead of just panning */ - - if (var->reserved[0] == 0x466c6970) { - unsigned long length, address; - struct file *p_src_file; - struct mdp_img imgdata; - int bpp; - - if (mfd->allow_set_offset) { - imgdata.memory_id = var->reserved[1]; - imgdata.priv = var->reserved[2]; - - /* If there is no memory ID then we want to reset back - to the original fb visibility */ - if (var->reserved[1]) { - if (var->reserved[4] == MDP_BLIT_SRC_GEM) { - panic("waaaaaaaaaaaaaah"); - if ( /*get_gem_img(&imgdata, - (unsigned long *) &address, - &length)*/ -1 < 0) { - return -1; - } - } else { - /*get_img(&imgdata, info, &address, - &length, &p_src_file);*/ - panic("waaaaaah"); - } - mfd->ibuf.visible_swapped = TRUE; - } else { - /* Flip back to the original address - adjusted for xoffset and yoffset */ - - bpp = info->var.bits_per_pixel / 8; - address = (unsigned long) info->fix.smem_start; - address += info->var.xoffset * bpp + - info->var.yoffset * info->fix.line_length; - - mfd->ibuf.visible_swapped = FALSE; - } - - mdp_set_offset_info(info, address, - (var->activate == FB_ACTIVATE_VBL)); - - mfd->dma_fnc(mfd); - return 0; - } else - return -EINVAL; - } - - down(&msm_fb_pan_sem); - mdp_set_dma_pan_info(info, dirtyPtr, - (var->activate == FB_ACTIVATE_VBL)); - mdp_dma_pan_update(info); - up(&msm_fb_pan_sem); - - ++mfd->panel_info.frame_count; - return 0; -} - -static int msm_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - - if (var->rotate != FB_ROTATE_UR) - return -EINVAL; - if (var->grayscale != info->var.grayscale) - return -EINVAL; - - switch (var->bits_per_pixel) { - case 16: - if ((var->green.offset != 5) || - !((var->blue.offset == 11) - || (var->blue.offset == 0)) || - !((var->red.offset == 11) - || (var->red.offset == 0)) || - (var->blue.length != 5) || - (var->green.length != 6) || - (var->red.length != 5) || - (var->blue.msb_right != 0) || - (var->green.msb_right != 0) || - (var->red.msb_right != 0) || - (var->transp.offset != 0) || - (var->transp.length != 0)) - return -EINVAL; - break; - - case 24: - if ((var->blue.offset != 0) || - (var->green.offset != 8) || - (var->red.offset != 16) || - (var->blue.length != 8) || - (var->green.length != 8) || - (var->red.length != 8) || - (var->blue.msb_right != 0) || - (var->green.msb_right != 0) || - (var->red.msb_right != 0) || - !(((var->transp.offset == 0) && - (var->transp.length == 0)) || - ((var->transp.offset == 24) && - (var->transp.length == 8)))) - return -EINVAL; - break; - - default: - return -EINVAL; - } - - if ((var->xres_virtual <= 0) || (var->yres_virtual <= 0)) - return -EINVAL; - - if (info->fix.smem_len < - (var->xres_virtual*var->yres_virtual*(var->bits_per_pixel/8))) - return -EINVAL; - - if ((var->xres == 0) || (var->yres == 0)) - return -EINVAL; - - if ((var->xres > mfd->panel_info.xres) || - (var->yres > mfd->panel_info.yres)) - return -EINVAL; - - if (var->xoffset > (var->xres_virtual - var->xres)) - return -EINVAL; - - if (var->yoffset > (var->yres_virtual - var->yres)) - return -EINVAL; - - return 0; -} - -static int msm_fb_set_par(struct fb_info *info) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - struct fb_var_screeninfo *var = &info->var; - int old_imgType; - int blank = 0; - - old_imgType = mfd->fb_imgType; - switch (var->bits_per_pixel) { - case 16: - if (var->red.offset == 0) - mfd->fb_imgType = MDP_BGR_565; - else - mfd->fb_imgType = MDP_RGB_565; - break; - - case 24: - if ((var->transp.offset == 0) && (var->transp.length == 0)) - mfd->fb_imgType = MDP_RGB_888; - else if ((var->transp.offset == 24) && - (var->transp.length == 8)) { - mfd->fb_imgType = MDP_ARGB_8888; - info->var.bits_per_pixel = 32; - } - break; - - default: - return -EINVAL; - } - - if ((mfd->var_pixclock != var->pixclock) || - (mfd->hw_refresh && ((mfd->fb_imgType != old_imgType) || - (mfd->var_pixclock != var->pixclock) || - (mfd->var_xres != var->xres) || - (mfd->var_yres != var->yres)))) { - mfd->var_xres = var->xres; - mfd->var_yres = var->yres; - mfd->var_pixclock = var->pixclock; - blank = 1; - } - - if (blank) { - msm_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable); - msm_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable); - } - - return 0; -} - -static int msm_fb_stop_sw_refresher(struct msm_fb_data_type *mfd) -{ - if (mfd->hw_refresh) - return -EPERM; - - if (mfd->sw_currently_refreshing) { - down(&mfd->sem); - mfd->sw_currently_refreshing = FALSE; - up(&mfd->sem); - - /* wait until the refresher finishes the last job */ - wait_for_completion_killable(&mfd->refresher_comp); - } - - return 0; -} - -int msm_fb_resume_sw_refresher(struct msm_fb_data_type *mfd) -{ - boolean do_refresh; - - if (mfd->hw_refresh) - return -EPERM; - - down(&mfd->sem); - if ((!mfd->sw_currently_refreshing) && (mfd->sw_refreshing_enable)) { - do_refresh = TRUE; - mfd->sw_currently_refreshing = TRUE; - } else { - do_refresh = FALSE; - } - up(&mfd->sem); - - if (do_refresh) - mdp_refresh_screen((unsigned long)mfd); - - return 0; -} - -void mdp_ppp_put_img(struct file *p_src_file, struct file *p_dst_file) -{ -#ifdef CONFIG_ANDROID_PMEM - if (p_src_file) - put_pmem_file(p_src_file); - if (p_dst_file) - put_pmem_file(p_dst_file); -#endif -} - -int mdp_blit(struct fb_info *info, struct mdp_blit_req *req) -{ - int ret; - struct file *p_src_file = 0, *p_dst_file = 0; - if (unlikely(req->src_rect.h == 0 || req->src_rect.w == 0)) { - printk(KERN_ERR "mpd_ppp: src img of zero size!\n"); - return -EINVAL; - } - if (unlikely(req->dst_rect.h == 0 || req->dst_rect.w == 0)) - return 0; - - ret = mdp_ppp_blit(info, req, &p_src_file, &p_dst_file); - mdp_ppp_put_img(p_src_file, p_dst_file); - return ret; -} - -typedef void (*msm_dma_barrier_function_pointer) (void *, size_t); - -static inline void msm_fb_dma_barrier_for_rect(struct fb_info *info, - struct mdp_img *img, struct mdp_rect *rect, - msm_dma_barrier_function_pointer dma_barrier_fp - ) -{ - /* - * Compute the start and end addresses of the rectangles. - * NOTE: As currently implemented, the data between - * the end of one row and the start of the next is - * included in the address range rather than - * doing multiple calls for each row. - */ - - char * const pmem_start = info->screen_base; -/* int bytes_per_pixel = mdp_get_bytes_per_pixel(img->format); - unsigned long start = (unsigned long)pmem_start + img->offset + - (img->width * rect->y + rect->x) * bytes_per_pixel; - size_t size = ((rect->h - 1) * img->width + rect->w) * bytes_per_pixel; - (*dma_barrier_fp) ((void *) start, size); -*/ - panic("waaaaah"); -} - -static inline void msm_dma_nc_pre(void) -{ - dmb(); -} -static inline void msm_dma_wt_pre(void) -{ - dmb(); -} -static inline void msm_dma_todevice_wb_pre(void *start, size_t size) -{ - #warning this -// dma_cache_pre_ops(start, size, DMA_TO_DEVICE); -} - -static inline void msm_dma_fromdevice_wb_pre(void *start, size_t size) -{ - #warning this -// dma_cache_pre_ops(start, size, DMA_FROM_DEVICE); -} - -static inline void msm_dma_nc_post(void) -{ - dmb(); -} - -static inline void msm_dma_fromdevice_wt_post(void *start, size_t size) -{ - #warning this -// dma_cache_post_ops(start, size, DMA_FROM_DEVICE); -} - -static inline void msm_dma_todevice_wb_post(void *start, size_t size) -{ - #warning this -// dma_cache_post_ops(start, size, DMA_TO_DEVICE); -} - -static inline void msm_dma_fromdevice_wb_post(void *start, size_t size) -{ - #warning this -// dma_cache_post_ops(start, size, DMA_FROM_DEVICE); -} - -/* - * Do the write barriers required to guarantee data is committed to RAM - * (from CPU cache or internal buffers) before a DMA operation starts. - * NOTE: As currently implemented, the data between - * the end of one row and the start of the next is - * included in the address range rather than - * doing multiple calls for each row. -*/ -static void msm_fb_ensure_memory_coherency_before_dma(struct fb_info *info, - struct mdp_blit_req *req_list, - int req_list_count) -{ -#ifdef CONFIG_ARCH_QSD8X50 - int i; - - /* - * Normally, do the requested barriers for each address - * range that corresponds to a rectangle. - * - * But if at least one write barrier is requested for data - * going to or from the device but no address range is - * needed for that barrier, then do the barrier, but do it - * only once, no matter how many requests there are. - */ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - switch (mfd->mdp_fb_page_protection) { - default: - case MDP_FB_PAGE_PROTECTION_NONCACHED: - case MDP_FB_PAGE_PROTECTION_WRITECOMBINE: - /* - * The following barrier is only done at most once, - * since further calls would be redundant. - */ - for (i = 0; i < req_list_count; i++) { - if (!(req_list[i].flags - & MDP_NO_DMA_BARRIER_START)) { - msm_dma_nc_pre(); - break; - } - } - break; - - case MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE: - /* - * The following barrier is only done at most once, - * since further calls would be redundant. - */ - for (i = 0; i < req_list_count; i++) { - if (!(req_list[i].flags - & MDP_NO_DMA_BARRIER_START)) { - msm_dma_wt_pre(); - break; - } - } - break; - - case MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE: - case MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE: - for (i = 0; i < req_list_count; i++) { - if (!(req_list[i].flags & - MDP_NO_DMA_BARRIER_START)) { - - msm_fb_dma_barrier_for_rect(info, - &(req_list[i].src), - &(req_list[i].src_rect), - msm_dma_todevice_wb_pre - ); - - msm_fb_dma_barrier_for_rect(info, - &(req_list[i].dst), - &(req_list[i].dst_rect), - msm_dma_todevice_wb_pre - ); - } - } - break; - } -#else - dmb(); -#endif -} - - -/* - * Do the write barriers required to guarantee data will be re-read from RAM by - * the CPU after a DMA operation ends. - * NOTE: As currently implemented, the data between - * the end of one row and the start of the next is - * included in the address range rather than - * doing multiple calls for each row. -*/ -static void msm_fb_ensure_memory_coherency_after_dma(struct fb_info *info, - struct mdp_blit_req *req_list, - int req_list_count) -{ -#ifdef CONFIG_ARCH_QSD8X50 - int i; - - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - switch (mfd->mdp_fb_page_protection) { - default: - case MDP_FB_PAGE_PROTECTION_NONCACHED: - case MDP_FB_PAGE_PROTECTION_WRITECOMBINE: - /* - * The following barrier is only done at most once, - * since further calls would be redundant. - */ - for (i = 0; i < req_list_count; i++) { - if (!(req_list[i].flags - & MDP_NO_DMA_BARRIER_END)) { - msm_dma_nc_post(); - break; - } - } - break; - - case MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE: - for (i = 0; i < req_list_count; i++) { - if (!(req_list[i].flags & - MDP_NO_DMA_BARRIER_END)) { - - msm_fb_dma_barrier_for_rect(info, - &(req_list[i].dst), - &(req_list[i].dst_rect), - msm_dma_fromdevice_wt_post - ); - } - } - break; - case MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE: - case MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE: - for (i = 0; i < req_list_count; i++) { - if (!(req_list[i].flags & - MDP_NO_DMA_BARRIER_END)) { - - msm_fb_dma_barrier_for_rect(info, - &(req_list[i].dst), - &(req_list[i].dst_rect), - msm_dma_fromdevice_wb_post - ); - } - } - break; - } -#else - dmb(); -#endif -} - -#ifdef CONFIG_MDP_PPP_ASYNC_OP -void msm_fb_ensure_mem_coherency_after_dma(struct fb_info *info, - struct mdp_blit_req *req_list, int req_list_count) -{ - BUG_ON(!info); - - /* - * Ensure that CPU cache and other internal CPU state is - * updated to reflect any change in memory modified by MDP blit - * DMA. - */ - msm_fb_ensure_memory_coherency_after_dma(info, - req_list, req_list_count); -} - -static int msmfb_async_blit(struct fb_info *info, void __user *p) -{ - /* - * CAUTION: The names of the struct types intentionally *DON'T* match - * the names of the variables declared -- they appear to be swapped. - * Read the code carefully and you should see that the variable names - * make sense. - */ - const int MAX_LIST_WINDOW = 16; - struct mdp_blit_req req_list[MAX_LIST_WINDOW]; - struct mdp_blit_req_list req_list_header; - - int count, i, req_list_count; - - /* Get the count size for the total BLIT request. */ - if (copy_from_user(&req_list_header, p, sizeof(req_list_header))) - return -EFAULT; - p += sizeof(req_list_header); - count = req_list_header.count; - while (count > 0) { - /* - * Access the requests through a narrow window to decrease copy - * overhead and make larger requests accessible to the - * coherency management code. - * NOTE: The window size is intended to be larger than the - * typical request size, but not require more than 2 - * kbytes of stack storage. - */ - req_list_count = count; - if (req_list_count > MAX_LIST_WINDOW) - req_list_count = MAX_LIST_WINDOW; - if (copy_from_user(&req_list, p, - sizeof(struct mdp_blit_req)*req_list_count)) - return -EFAULT; - - /* - * Ensure that any data CPU may have previously written to - * internal state (but not yet committed to memory) is - * guaranteed to be committed to memory now. - */ - msm_fb_ensure_memory_coherency_before_dma(info, - req_list, req_list_count); - - /* - * Do the blit DMA, if required -- returning early only if - * there is a failure. - */ - for (i = 0; i < req_list_count; i++) { - if (!(req_list[i].flags & MDP_NO_BLIT)) { - int ret = 0; - struct mdp_ppp_djob *job = NULL; - - if (unlikely(req_list[i].src_rect.h == 0 || - req_list[i].src_rect.w == 0)) { - MSM_FB_ERR("mpd_ppp: " - "src img of zero size!\n"); - return -EINVAL; - } - - if (unlikely(req_list[i].dst_rect.h == 0 || - req_list[i].dst_rect.w == 0)) - continue; - - /* create a new display job */ - job = mdp_ppp_new_djob(); - if (unlikely(!job)) - return -ENOMEM; - - job->info = info; - memcpy(&job->req, &req_list[i], - sizeof(struct mdp_blit_req)); - - /* Do the actual blit. */ - ret = mdp_ppp_blit(info, &job->req, - &job->p_src_file, &job->p_dst_file); - - /* - * Note that early returns don't guarantee - * memory coherency. - */ - if (ret || mdp_ppp_get_ret_code()) { - mdp_ppp_clear_curr_djob(); - return ret; - } - } - } - - /* Go to next window of requests. */ - count -= req_list_count; - p += sizeof(struct mdp_blit_req)*req_list_count; - } - return 0; -} -#else - -/* - * NOTE: The userspace issues blit operations in a sequence, the sequence - * start with a operation marked START and ends in an operation marked - * END. It is guaranteed by the userspace that all the blit operations - * between START and END are only within the regions of areas designated - * by the START and END operations and that the userspace doesn't modify - * those areas. Hence it would be enough to perform barrier/cache operations - * only on the START and END operations. - */ -static int msmfb_blit(struct fb_info *info, void __user *p) -{ - /* - * CAUTION: The names of the struct types intentionally *DON'T* match - * the names of the variables declared -- they appear to be swapped. - * Read the code carefully and you should see that the variable names - * make sense. - */ - const int MAX_LIST_WINDOW = 16; - struct mdp_blit_req req_list[MAX_LIST_WINDOW]; - struct mdp_blit_req_list req_list_header; - - int count, i, req_list_count; - - /* Get the count size for the total BLIT request. */ - if (copy_from_user(&req_list_header, p, sizeof(req_list_header))) - return -EFAULT; - p += sizeof(req_list_header); - count = req_list_header.count; - while (count > 0) { - /* - * Access the requests through a narrow window to decrease copy - * overhead and make larger requests accessible to the - * coherency management code. - * NOTE: The window size is intended to be larger than the - * typical request size, but not require more than 2 - * kbytes of stack storage. - */ - req_list_count = count; - if (req_list_count > MAX_LIST_WINDOW) - req_list_count = MAX_LIST_WINDOW; - if (copy_from_user(&req_list, p, - sizeof(struct mdp_blit_req)*req_list_count)) - return -EFAULT; - - /* - * Ensure that any data CPU may have previously written to - * internal state (but not yet committed to memory) is - * guaranteed to be committed to memory now. - */ - msm_fb_ensure_memory_coherency_before_dma(info, - req_list, req_list_count); - - /* - * Do the blit DMA, if required -- returning early only if - * there is a failure. - */ - for (i = 0; i < req_list_count; i++) { - if (!(req_list[i].flags & MDP_NO_BLIT)) { - /* Do the actual blit. */ - int ret = mdp_blit(info, &(req_list[i])); - - /* - * Note that early returns don't guarantee - * memory coherency. - */ - if (ret) - return ret; - } - } - - /* - * Ensure that CPU cache and other internal CPU state is - * updated to reflect any change in memory modified by MDP blit - * DMA. - */ - msm_fb_ensure_memory_coherency_after_dma(info, - req_list, - req_list_count); - - /* Go to next window of requests. */ - count -= req_list_count; - p += sizeof(struct mdp_blit_req)*req_list_count; - } - return 0; -} -#endif - -#ifdef CONFIG_FB_MSM_OVERLAY -static int msmfb_overlay_get(struct fb_info *info, void __user *p) -{ - struct mdp_overlay req; - int ret; - - if (copy_from_user(&req, p, sizeof(req))) - return -EFAULT; - - ret = mdp4_overlay_get(info, &req); - if (ret) { - printk(KERN_ERR "%s: ioctl failed \n", - __func__); - return ret; - } - if (copy_to_user(p, &req, sizeof(req))) { - printk(KERN_ERR "%s: copy2user failed \n", - __func__); - return -EFAULT; - } - - return 0; -} - -static int msmfb_overlay_set(struct fb_info *info, void __user *p) -{ - struct mdp_overlay req; - int ret; - - if (copy_from_user(&req, p, sizeof(req))) - return -EFAULT; - - ret = mdp4_overlay_set(info, &req); - if (ret) { - printk(KERN_ERR "%s:ioctl failed \n", - __func__); - return ret; - } - - if (copy_to_user(p, &req, sizeof(req))) { - printk(KERN_ERR "%s: copy2user failed \n", - __func__); - return -EFAULT; - } - - return 0; -} - -static int msmfb_overlay_unset(struct fb_info *info, unsigned long *argp) -{ - int ret, ndx; - - ret = copy_from_user(&ndx, argp, sizeof(ndx)); - if (ret) { - printk(KERN_ERR "%s:msmfb_overlay_unset ioctl failed \n", - __func__); - return ret; - } - - return mdp4_overlay_unset(info, ndx); -} - -static int msmfb_overlay_play(struct fb_info *info, unsigned long *argp) -{ - int ret; - struct msmfb_overlay_data req; - struct file *p_src_file = 0; - - ret = copy_from_user(&req, argp, sizeof(req)); - if (ret) { - printk(KERN_ERR "%s:msmfb_overlay_play ioctl failed \n", - __func__); - return ret; - } - - ret = mdp4_overlay_play(info, &req, &p_src_file); - - if (p_src_file) - put_pmem_file(p_src_file); - - return ret; -} - -#endif - -DEFINE_SEMAPHORE(msm_fb_ioctl_ppp_sem); -DEFINE_MUTEX(msm_fb_ioctl_lut_sem); -DEFINE_MUTEX(msm_fb_ioctl_hist_sem); - -/* Set color conversion matrix from user space */ - -#ifndef CONFIG_FB_MSM_MDP40 -static void msmfb_set_color_conv(struct mdp_ccs *p) -{ - int i; - - if (p->direction == MDP_CCS_RGB2YUV) { - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - - /* RGB->YUV primary forward matrix */ - for (i = 0; i < MDP_CCS_SIZE; i++) - writel(p->ccs[i], MDP_CSC_PFMVn(i)); - - #ifdef CONFIG_FB_MSM_MDP31 - for (i = 0; i < MDP_BV_SIZE; i++) - writel(p->bv[i], MDP_CSC_POST_BV2n(i)); - #endif - - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - } else { - /* MDP cmd block enable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - - /* YUV->RGB primary reverse matrix */ - for (i = 0; i < MDP_CCS_SIZE; i++) - writel(p->ccs[i], MDP_CSC_PRMVn(i)); - for (i = 0; i < MDP_BV_SIZE; i++) - writel(p->bv[i], MDP_CSC_PRE_BV1n(i)); - - /* MDP cmd block disable */ - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE); - } -} -#endif - - -static int msm_fb_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg) -{ - struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par; - void __user *argp = (void __user *)arg; - struct fb_cursor cursor; - struct fb_cmap cmap; - struct mdp_histogram hist; -#ifndef CONFIG_FB_MSM_MDP40 - struct mdp_ccs ccs_matrix; -#endif - struct mdp_page_protection fb_page_protection; - int ret = 0; - - if (!mfd->op_enable) - return -EPERM; - - switch (cmd) { -#ifdef CONFIG_FB_MSM_OVERLAY - case MSMFB_OVERLAY_GET: - down(&msm_fb_ioctl_ppp_sem); - ret = msmfb_overlay_get(info, argp); - up(&msm_fb_ioctl_ppp_sem); - break; - case MSMFB_OVERLAY_SET: - down(&msm_fb_ioctl_ppp_sem); - ret = msmfb_overlay_set(info, argp); - up(&msm_fb_ioctl_ppp_sem); - break; - case MSMFB_OVERLAY_UNSET: - down(&msm_fb_ioctl_ppp_sem); - ret = msmfb_overlay_unset(info, argp); - up(&msm_fb_ioctl_ppp_sem); - break; - case MSMFB_OVERLAY_PLAY: - down(&msm_fb_ioctl_ppp_sem); - ret = msmfb_overlay_play(info, argp); - up(&msm_fb_ioctl_ppp_sem); - break; -#endif - case MSMFB_BLIT: - down(&msm_fb_ioctl_ppp_sem); -#ifdef CONFIG_MDP_PPP_ASYNC_OP - ret = msmfb_async_blit(info, argp); - mdp_ppp_wait(); /* Wait for all blits to be finished. */ -#else - ret = msmfb_blit(info, argp); -#endif - up(&msm_fb_ioctl_ppp_sem); - - break; - - /* Ioctl for setting ccs matrix from user space */ - case MSMFB_SET_CCS_MATRIX: -#ifndef CONFIG_FB_MSM_MDP40 - ret = copy_from_user(&ccs_matrix, argp, sizeof(ccs_matrix)); - if (ret) { - printk(KERN_ERR - "%s:MSMFB_SET_CCS_MATRIX ioctl failed \n", - __func__); - return ret; - } - - down(&msm_fb_ioctl_ppp_sem); - if (ccs_matrix.direction == MDP_CCS_RGB2YUV) - mdp_ccs_rgb2yuv = ccs_matrix; - else - mdp_ccs_yuv2rgb = ccs_matrix; - - msmfb_set_color_conv(&ccs_matrix) ; - up(&msm_fb_ioctl_ppp_sem); -#else - ret = -EINVAL; -#endif - - break; - - /* Ioctl for getting ccs matrix to user space */ - case MSMFB_GET_CCS_MATRIX: -#ifndef CONFIG_FB_MSM_MDP40 - ret = copy_from_user(&ccs_matrix, argp, sizeof(ccs_matrix)) ; - if (ret) { - printk(KERN_ERR - "%s:MSMFB_GET_CCS_MATRIX ioctl failed \n", - __func__); - return ret; - } - - down(&msm_fb_ioctl_ppp_sem); - if (ccs_matrix.direction == MDP_CCS_RGB2YUV) - ccs_matrix = mdp_ccs_rgb2yuv; - else - ccs_matrix = mdp_ccs_yuv2rgb; - - ret = copy_to_user(argp, &ccs_matrix, sizeof(ccs_matrix)); - - if (ret) { - printk(KERN_ERR - "%s:MSMFB_GET_CCS_MATRIX ioctl failed \n", - __func__); - return ret ; - } - up(&msm_fb_ioctl_ppp_sem); -#else - ret = -EINVAL; -#endif - - break; - -#ifdef CONFIG_MDP_PPP_ASYNC_OP - case MSMFB_ASYNC_BLIT: - down(&msm_fb_ioctl_ppp_sem); - ret = msmfb_async_blit(info, argp); - up(&msm_fb_ioctl_ppp_sem); - break; - - case MSMFB_BLIT_FLUSH: - down(&msm_fb_ioctl_ppp_sem); - mdp_ppp_wait(); - up(&msm_fb_ioctl_ppp_sem); - break; -#endif - - case MSMFB_GRP_DISP: -#ifdef CONFIG_FB_MSM_MDP22 - { - unsigned long grp_id; - - ret = copy_from_user(&grp_id, argp, sizeof(grp_id)); - if (ret) - return ret; - - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE); - writel(grp_id, MDP_FULL_BYPASS_WORD43); - mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, - FALSE); - break; - } -#else - return -EFAULT; -#endif - case MSMFB_SUSPEND_SW_REFRESHER: - if (!mfd->panel_power_on) - return -EPERM; - - mfd->sw_refreshing_enable = FALSE; - ret = msm_fb_stop_sw_refresher(mfd); - break; - - case MSMFB_RESUME_SW_REFRESHER: - if (!mfd->panel_power_on) - return -EPERM; - - mfd->sw_refreshing_enable = TRUE; - ret = msm_fb_resume_sw_refresher(mfd); - break; - - case MSMFB_CURSOR: - ret = copy_from_user(&cursor, argp, sizeof(cursor)); - if (ret) - return ret; - - ret = msm_fb_cursor(info, &cursor); - break; - - case MSMFB_SET_LUT: - ret = copy_from_user(&cmap, argp, sizeof(cmap)); - if (ret) - return ret; - - mutex_lock(&msm_fb_ioctl_lut_sem); - ret = msm_fb_set_lut(&cmap, info); - mutex_unlock(&msm_fb_ioctl_lut_sem); - break; - - case MSMFB_HISTOGRAM: - if (!mfd->do_histogram) - return -ENODEV; - - ret = copy_from_user(&hist, argp, sizeof(hist)); - if (ret) - return ret; - - mutex_lock(&msm_fb_ioctl_hist_sem); - ret = mfd->do_histogram(info, &hist); - mutex_unlock(&msm_fb_ioctl_hist_sem); - break; - - case MSMFB_GET_PAGE_PROTECTION: - fb_page_protection.page_protection - = mfd->mdp_fb_page_protection; - ret = copy_to_user(argp, &fb_page_protection, - sizeof(fb_page_protection)); - if (ret) - return ret; - break; - - case MSMFB_SET_PAGE_PROTECTION: -#ifdef CONFIG_ARCH_QSD8X50 - ret = copy_from_user(&fb_page_protection, argp, - sizeof(fb_page_protection)); - if (ret) - return ret; - - /* Validate the proposed page protection settings. */ - switch (fb_page_protection.page_protection) { - case MDP_FB_PAGE_PROTECTION_NONCACHED: - case MDP_FB_PAGE_PROTECTION_WRITECOMBINE: - case MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE: - /* Write-back cache (read allocate) */ - case MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE: - /* Write-back cache (write allocate) */ - case MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE: - mfd->mdp_fb_page_protection = - fb_page_protection.page_protection; - break; - default: - ret = -EINVAL; - break; - } -#else - /* - * Don't allow caching until 7k DMA cache operations are - * available. - */ - ret = -EINVAL; -#endif - break; - - default: - MSM_FB_INFO("MDP: unknown ioctl (cmd=%d) received!\n", cmd); - ret = -EINVAL; - break; - } - - return ret; -} - -static int msm_fb_register_driver(void) -{ - return platform_driver_register(&msm_fb_driver); -} - -void msm_fb_add_device(struct platform_device *pdev) -{ - struct msm_fb_panel_data *pdata; - struct platform_device *this_dev = NULL; - struct fb_info *fbi; - struct msm_fb_data_type *mfd = NULL; - u32 type, id, fb_num; - - if (!pdev) - return; - id = pdev->id; - - pdata = pdev->dev.platform_data; - if (!pdata) - return; - type = pdata->panel_info.type; - fb_num = pdata->panel_info.fb_num; - - if (fb_num <= 0) - return; - - if (fbi_list_index >= MAX_FBI_LIST) { - printk(KERN_ERR "msm_fb: no more framebuffer info list!\n"); - return; - } - /* - * alloc panel device data - */ - this_dev = msm_fb_device_alloc(pdata, type, id); - - if (!this_dev) { - printk(KERN_ERR - "%s: msm_fb_device_alloc failed!\n", __func__); - return; - } - - /* - * alloc framebuffer info + par data - */ - fbi = framebuffer_alloc(sizeof(struct msm_fb_data_type), NULL); - if (fbi == NULL) { - platform_device_put(this_dev); - printk(KERN_ERR "msm_fb: can't alloca framebuffer info data!\n"); - return; - } - - mfd = (struct msm_fb_data_type *)fbi->par; - mfd->key = MFD_KEY; - mfd->fbi = fbi; - mfd->panel.type = type; - mfd->panel.id = id; - mfd->fb_page = fb_num; - mfd->index = fbi_list_index; - mfd->mdp_fb_page_protection = MDP_FB_PAGE_PROTECTION_WRITECOMBINE; - - /* link to the latest pdev */ - mfd->pdev = this_dev; - - mfd_list[mfd_list_index++] = mfd; - fbi_list[fbi_list_index++] = fbi; - - /* - * set driver data - */ - platform_set_drvdata(this_dev, mfd); - - if (platform_device_add(this_dev)) { - printk(KERN_ERR "msm_fb: platform_device_add failed!\n"); - platform_device_put(this_dev); - framebuffer_release(fbi); - fbi_list_index--; - return; - } -} -EXPORT_SYMBOL(msm_fb_add_device); - -int __init msm_fb_init(void) -{ - int rc = -ENODEV; - - if (msm_fb_register_driver()) - return rc; - -#ifdef MSM_FB_ENABLE_DBGFS - { - struct dentry *root; - - if ((root = msm_fb_get_debugfs_root()) != NULL) { - msm_fb_debugfs_file_create(root, - "msm_fb_msg_printing_level", - (u32 *) &msm_fb_msg_level); - msm_fb_debugfs_file_create(root, - "mddi_msg_printing_level", - (u32 *) &mddi_msg_level); - msm_fb_debugfs_file_create(root, "msm_fb_debug_enabled", - (u32 *) &msm_fb_debug_enabled); - } - } -#endif - - return 0; -} - -module_init(msm_fb_init); diff --git a/drivers/staging/msm/msm_fb.h b/drivers/staging/msm/msm_fb.h deleted file mode 100644 index 4bca6d243f1c..000000000000 --- a/drivers/staging/msm/msm_fb.h +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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. - */ - -#ifndef MSM_FB_H -#define MSM_FB_H - -#include -#include -#include -#include -#include -#include -#include "linux/proc_fs.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif - -#include "msm_fb_panel.h" -#include "mdp.h" - -#define MSM_FB_DEFAULT_PAGE_SIZE 2 -#define MFD_KEY 0x11161126 -#define MSM_FB_MAX_DEV_LIST 32 - -struct disp_info_type_suspend { - boolean op_enable; - boolean sw_refreshing_enable; - boolean panel_power_on; -}; - -struct msm_fb_data_type { - __u32 key; - __u32 index; - __u32 ref_cnt; - __u32 fb_page; - - panel_id_type panel; - struct msm_panel_info panel_info; - - DISP_TARGET dest; - struct fb_info *fbi; - - boolean op_enable; - uint32 fb_imgType; - boolean sw_currently_refreshing; - boolean sw_refreshing_enable; - boolean hw_refresh; - - MDPIBUF ibuf; - boolean ibuf_flushed; - struct timer_list refresh_timer; - struct completion refresher_comp; - - boolean pan_waiting; - struct completion pan_comp; - - /* vsync */ - boolean use_mdp_vsync; - __u32 vsync_gpio; - __u32 total_lcd_lines; - __u32 total_porch_lines; - __u32 lcd_ref_usec_time; - __u32 refresh_timer_duration; - - struct hrtimer dma_hrtimer; - - boolean panel_power_on; - struct work_struct dma_update_worker; - struct semaphore sem; - - struct timer_list vsync_resync_timer; - boolean vsync_handler_pending; - struct work_struct vsync_resync_worker; - - ktime_t last_vsync_timetick; - - __u32 *vsync_width_boundary; - - unsigned int pmem_id; - struct disp_info_type_suspend suspend; - - __u32 channel_irq; - - struct mdp_dma_data *dma; - void (*dma_fnc) (struct msm_fb_data_type *mfd); - int (*cursor_update) (struct fb_info *info, - struct fb_cursor *cursor); - int (*lut_update) (struct fb_info *info, - struct fb_cmap *cmap); - int (*do_histogram) (struct fb_info *info, - struct mdp_histogram *hist); - void *cursor_buf; - void *cursor_buf_phys; - - void *cmd_port; - void *data_port; - void *data_port_phys; - - __u32 bl_level; - - struct platform_device *pdev; - - __u32 var_xres; - __u32 var_yres; - __u32 var_pixclock; - -#ifdef MSM_FB_ENABLE_DBGFS - struct dentry *sub_dir; -#endif - -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; - struct early_suspend mddi_early_suspend; - struct early_suspend mddi_ext_early_suspend; -#endif - u32 mdp_fb_page_protection; - int allow_set_offset; -}; - -struct dentry *msm_fb_get_debugfs_root(void); -void msm_fb_debugfs_file_create(struct dentry *root, const char *name, - u32 *var); -void msm_fb_set_backlight(struct msm_fb_data_type *mfd, __u32 bkl_lvl, - u32 save); - -void msm_fb_add_device(struct platform_device *pdev); - -int msm_fb_detect_client(const char *name); - -#ifdef CONFIG_FB_BACKLIGHT -void msm_fb_config_backlight(struct msm_fb_data_type *mfd); -#endif - -#endif /* MSM_FB_H */ diff --git a/drivers/staging/msm/msm_fb_bl.c b/drivers/staging/msm/msm_fb_bl.c deleted file mode 100644 index 2a8077511fc0..000000000000 --- a/drivers/staging/msm/msm_fb_bl.c +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msm_fb.h" - -static int msm_fb_bl_get_brightness(struct backlight_device *pbd) -{ - return pbd->props.brightness; -} - -static int msm_fb_bl_update_status(struct backlight_device *pbd) -{ - struct msm_fb_data_type *mfd = bl_get_data(pbd); - __u32 bl_lvl; - - bl_lvl = pbd->props.brightness; - bl_lvl = mfd->fbi->bl_curve[bl_lvl]; - msm_fb_set_backlight(mfd, bl_lvl, 1); - return 0; -} - -static const struct backlight_ops msm_fb_bl_ops = { - .get_brightness = msm_fb_bl_get_brightness, - .update_status = msm_fb_bl_update_status, -}; - -void msm_fb_config_backlight(struct msm_fb_data_type *mfd) -{ - struct msm_fb_panel_data *pdata; - struct backlight_device *pbd; - struct fb_info *fbi; - char name[16]; - - fbi = mfd->fbi; - pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data; - - if ((pdata) && (pdata->set_backlight)) { - snprintf(name, sizeof(name), "msmfb_bl%d", mfd->index); - pbd = - backlight_device_register(name, fbi->dev, mfd, - &msm_fb_bl_ops); - if (!IS_ERR(pbd)) { - fbi->bl_dev = pbd; - fb_bl_default_curve(fbi, - 0, - mfd->panel_info.bl_min, - mfd->panel_info.bl_max); - pbd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; - pbd->props.brightness = FB_BACKLIGHT_LEVELS - 1; - backlight_update_status(pbd); - } else { - fbi->bl_dev = NULL; - printk(KERN_ERR "msm_fb: backlight_device_register failed!\n"); - } - } -} diff --git a/drivers/staging/msm/msm_fb_def.h b/drivers/staging/msm/msm_fb_def.h deleted file mode 100644 index bc7f2562cc03..000000000000 --- a/drivers/staging/msm/msm_fb_def.h +++ /dev/null @@ -1,181 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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. - */ - -#ifndef MSM_FB_DEF_H -#define MSM_FB_DEF_H - -#include -#include -#include -#include -#include -#include -#include -#include "msm_mdp.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -typedef s64 int64; -typedef s32 int32; -typedef s16 int16; -typedef s8 int8; - -typedef u64 uint64; -typedef u32 uint32; -typedef u16 uint16; -typedef u8 uint8; - -typedef s32 int4; -typedef s16 int2; -typedef s8 int1; - -typedef u32 uint4; -typedef u16 uint2; -typedef u8 uint1; - -typedef u32 dword; -typedef u16 word; -typedef u8 byte; - -typedef unsigned int boolean; - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#define MSM_FB_ENABLE_DBGFS -#define FEATURE_MDDI - -#define outp32(addr, val) writel(val, addr) -#define outp16(addr, val) writew(val, addr) -#define outp8(addr, val) writeb(val, addr) -#define outp(addr, val) outp32(addr, val) - -#ifndef MAX -#define MAX( x, y ) (((x) > (y)) ? (x) : (y)) -#endif - -#ifndef MIN -#define MIN( x, y ) (((x) < (y)) ? (x) : (y)) -#endif - -/*--------------------------------------------------------------------------*/ - -#define inp32(addr) readl(addr) -#define inp16(addr) readw(addr) -#define inp8(addr) readb(addr) -#define inp(addr) inp32(addr) - -#define inpw(port) readw(port) -#define outpw(port, val) writew(val, port) -#define inpdw(port) readl(port) -#define outpdw(port, val) writel(val, port) - - -#define clk_busy_wait(x) msleep_interruptible((x)/1000) - -#define memory_barrier() - -#define assert(expr) \ - if(!(expr)) { \ - printk(KERN_ERR "msm_fb: assertion failed! %s,%s,%s,line=%d\n",\ - #expr, __FILE__, __func__, __LINE__); \ - } - -#define ASSERT(x) assert(x) - -#define DISP_EBI2_LOCAL_DEFINE -#ifdef DISP_EBI2_LOCAL_DEFINE -#define LCD_PRIM_BASE_PHYS 0x98000000 -#define LCD_SECD_BASE_PHYS 0x9c000000 -#define EBI2_PRIM_LCD_RS_PIN 0x20000 -#define EBI2_SECD_LCD_RS_PIN 0x20000 - -#define EBI2_PRIM_LCD_CLR 0xC0 -#define EBI2_PRIM_LCD_SEL 0x40 - -#define EBI2_SECD_LCD_CLR 0x300 -#define EBI2_SECD_LCD_SEL 0x100 -#endif - -extern u32 msm_fb_msg_level; - -/* - * Message printing priorities: - * LEVEL 0 KERN_EMERG (highest priority) - * LEVEL 1 KERN_ALERT - * LEVEL 2 KERN_CRIT - * LEVEL 3 KERN_ERR - * LEVEL 4 KERN_WARNING - * LEVEL 5 KERN_NOTICE - * LEVEL 6 KERN_INFO - * LEVEL 7 KERN_DEBUG (Lowest priority) - */ -#define MSM_FB_EMERG(msg, ...) \ - if (msm_fb_msg_level > 0) \ - printk(KERN_EMERG msg, ## __VA_ARGS__); -#define MSM_FB_ALERT(msg, ...) \ - if (msm_fb_msg_level > 1) \ - printk(KERN_ALERT msg, ## __VA_ARGS__); -#define MSM_FB_CRIT(msg, ...) \ - if (msm_fb_msg_level > 2) \ - printk(KERN_CRIT msg, ## __VA_ARGS__); -#define MSM_FB_ERR(msg, ...) \ - if (msm_fb_msg_level > 3) \ - printk(KERN_ERR msg, ## __VA_ARGS__); -#define MSM_FB_WARNING(msg, ...) \ - if (msm_fb_msg_level > 4) \ - printk(KERN_WARNING msg, ## __VA_ARGS__); -#define MSM_FB_NOTICE(msg, ...) \ - if (msm_fb_msg_level > 5) \ - printk(KERN_NOTICE msg, ## __VA_ARGS__); -#define MSM_FB_INFO(msg, ...) \ - if (msm_fb_msg_level > 6) \ - printk(KERN_INFO msg, ## __VA_ARGS__); -#define MSM_FB_DEBUG(msg, ...) \ - if (msm_fb_msg_level > 7) \ - printk(KERN_DEBUG msg, ## __VA_ARGS__); - -#ifdef MSM_FB_C -unsigned char *msm_mdp_base; -unsigned char *msm_pmdh_base; -unsigned char *msm_emdh_base; -#else -extern unsigned char *msm_mdp_base; -extern unsigned char *msm_pmdh_base; -extern unsigned char *msm_emdh_base; -#endif - -#endif /* MSM_FB_DEF_H */ diff --git a/drivers/staging/msm/msm_fb_panel.c b/drivers/staging/msm/msm_fb_panel.c deleted file mode 100644 index b17a239a1bc7..000000000000 --- a/drivers/staging/msm/msm_fb_panel.c +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msm_fb_panel.h" - -int panel_next_on(struct platform_device *pdev) -{ - int ret = 0; - struct msm_fb_panel_data *pdata; - struct msm_fb_panel_data *next_pdata; - struct platform_device *next_pdev; - - pdata = (struct msm_fb_panel_data *)pdev->dev.platform_data; - - if (pdata) { - next_pdev = pdata->next; - if (next_pdev) { - next_pdata = - (struct msm_fb_panel_data *)next_pdev->dev. - platform_data; - if ((next_pdata) && (next_pdata->on)) - ret = next_pdata->on(next_pdev); - } - } - - return ret; -} - -int panel_next_off(struct platform_device *pdev) -{ - int ret = 0; - struct msm_fb_panel_data *pdata; - struct msm_fb_panel_data *next_pdata; - struct platform_device *next_pdev; - - pdata = (struct msm_fb_panel_data *)pdev->dev.platform_data; - - if (pdata) { - next_pdev = pdata->next; - if (next_pdev) { - next_pdata = - (struct msm_fb_panel_data *)next_pdev->dev. - platform_data; - if ((next_pdata) && (next_pdata->on)) - ret = next_pdata->off(next_pdev); - } - } - - return ret; -} - -struct platform_device *msm_fb_device_alloc(struct msm_fb_panel_data *pdata, - u32 type, u32 id) -{ - struct platform_device *this_dev = NULL; - char dev_name[16]; - - switch (type) { - case EBI2_PANEL: - snprintf(dev_name, sizeof(dev_name), "ebi2_lcd"); - break; - - case MDDI_PANEL: - snprintf(dev_name, sizeof(dev_name), "mddi"); - break; - - case EXT_MDDI_PANEL: - snprintf(dev_name, sizeof(dev_name), "mddi_ext"); - break; - - case TV_PANEL: - snprintf(dev_name, sizeof(dev_name), "tvenc"); - break; - - case HDMI_PANEL: - case LCDC_PANEL: - snprintf(dev_name, sizeof(dev_name), "lcdc"); - break; - - default: - return NULL; - } - - if (pdata != NULL) - pdata->next = NULL; - else - return NULL; - - this_dev = - platform_device_alloc(dev_name, ((u32) type << 16) | (u32) id); - - if (this_dev) { - if (platform_device_add_data - (this_dev, pdata, sizeof(struct msm_fb_panel_data))) { - printk - ("msm_fb_device_alloc: platform_device_add_data failed!\n"); - platform_device_put(this_dev); - return NULL; - } - } - - return this_dev; -} diff --git a/drivers/staging/msm/msm_fb_panel.h b/drivers/staging/msm/msm_fb_panel.h deleted file mode 100644 index 6375976f09da..000000000000 --- a/drivers/staging/msm/msm_fb_panel.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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. - */ - -#ifndef MSM_FB_PANEL_H -#define MSM_FB_PANEL_H - -#include "msm_fb_def.h" - -struct msm_fb_data_type; - -typedef void (*msm_fb_vsync_handler_type) (void *arg); - -/* panel id type */ -typedef struct panel_id_s { - uint16 id; - uint16 type; -} panel_id_type; - -/* panel type list */ -#define NO_PANEL 0xffff /* No Panel */ -#define MDDI_PANEL 1 /* MDDI */ -#define EBI2_PANEL 2 /* EBI2 */ -#define LCDC_PANEL 3 /* internal LCDC type */ -#define EXT_MDDI_PANEL 4 /* Ext.MDDI */ -#define TV_PANEL 5 /* TV */ -#define HDMI_PANEL 6 /* HDMI TV */ - -/* panel class */ -typedef enum { - DISPLAY_LCD = 0, /* lcd = ebi2/mddi */ - DISPLAY_LCDC, /* lcdc */ - DISPLAY_TV, /* TV Out */ - DISPLAY_EXT_MDDI, /* External MDDI */ -} DISP_TARGET; - -/* panel device locaiton */ -typedef enum { - DISPLAY_1 = 0, /* attached as first device */ - DISPLAY_2, /* attached on second device */ - MAX_PHYS_TARGET_NUM, -} DISP_TARGET_PHYS; - -/* panel info type */ -struct lcd_panel_info { - __u32 vsync_enable; - __u32 refx100; - __u32 v_back_porch; - __u32 v_front_porch; - __u32 v_pulse_width; - __u32 hw_vsync_mode; - __u32 vsync_notifier_period; -}; - -struct lcdc_panel_info { - __u32 h_back_porch; - __u32 h_front_porch; - __u32 h_pulse_width; - __u32 v_back_porch; - __u32 v_front_porch; - __u32 v_pulse_width; - __u32 border_clr; - __u32 underflow_clr; - __u32 hsync_skew; -}; - -struct mddi_panel_info { - __u32 vdopkt; -}; - -struct msm_panel_info { - __u32 xres; - __u32 yres; - __u32 bpp; - __u32 type; - __u32 wait_cycle; - DISP_TARGET_PHYS pdest; - __u32 bl_max; - __u32 bl_min; - __u32 fb_num; - __u32 clk_rate; - __u32 clk_min; - __u32 clk_max; - __u32 frame_count; - - union { - struct mddi_panel_info mddi; - }; - - union { - struct lcd_panel_info lcd; - struct lcdc_panel_info lcdc; - }; -}; - -struct msm_fb_panel_data { - struct msm_panel_info panel_info; - void (*set_rect) (int x, int y, int xres, int yres); - void (*set_vsync_notifier) (msm_fb_vsync_handler_type, void *arg); - void (*set_backlight) (struct msm_fb_data_type *); - - /* function entry chain */ - int (*on) (struct platform_device *pdev); - int (*off) (struct platform_device *pdev); - struct platform_device *next; -}; - -/*=========================================================================== - FUNCTIONS PROTOTYPES -============================================================================*/ -struct platform_device *msm_fb_device_alloc(struct msm_fb_panel_data *pdata, - u32 type, u32 id); -int panel_next_on(struct platform_device *pdev); -int panel_next_off(struct platform_device *pdev); - -int lcdc_device_register(struct msm_panel_info *pinfo); - -int mddi_toshiba_device_register(struct msm_panel_info *pinfo, - u32 channel, u32 panel); - -#endif /* MSM_FB_PANEL_H */ diff --git a/drivers/staging/msm/msm_mdp.h b/drivers/staging/msm/msm_mdp.h deleted file mode 100644 index 2d5323f5b62d..000000000000 --- a/drivers/staging/msm/msm_mdp.h +++ /dev/null @@ -1,245 +0,0 @@ -/* include/linux/msm_mdp.h - * - * Copyright (C) 2007 Google Incorporated - * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. - * - * 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 _MSM_MDP_H_ -#define _MSM_MDP_H_ - -#include -#include - -#define MSMFB_IOCTL_MAGIC 'm' -#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int) -#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int) -#define MSMFB_SUSPEND_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 128, unsigned int) -#define MSMFB_RESUME_SW_REFRESHER _IOW(MSMFB_IOCTL_MAGIC, 129, unsigned int) -#define MSMFB_CURSOR _IOW(MSMFB_IOCTL_MAGIC, 130, struct fb_cursor) -#define MSMFB_SET_LUT _IOW(MSMFB_IOCTL_MAGIC, 131, struct fb_cmap) -#define MSMFB_HISTOGRAM _IOWR(MSMFB_IOCTL_MAGIC, 132, struct mdp_histogram) -/* new ioctls's for set/get ccs matrix */ -#define MSMFB_GET_CCS_MATRIX _IOWR(MSMFB_IOCTL_MAGIC, 133, struct mdp_ccs) -#define MSMFB_SET_CCS_MATRIX _IOW(MSMFB_IOCTL_MAGIC, 134, struct mdp_ccs) -#define MSMFB_OVERLAY_SET _IOWR(MSMFB_IOCTL_MAGIC, 135, \ - struct mdp_overlay) -#define MSMFB_OVERLAY_UNSET _IOW(MSMFB_IOCTL_MAGIC, 136, unsigned int) -#define MSMFB_OVERLAY_PLAY _IOW(MSMFB_IOCTL_MAGIC, 137, \ - struct msmfb_overlay_data) -#define MSMFB_GET_PAGE_PROTECTION _IOR(MSMFB_IOCTL_MAGIC, 138, \ - struct mdp_page_protection) -#define MSMFB_SET_PAGE_PROTECTION _IOW(MSMFB_IOCTL_MAGIC, 139, \ - struct mdp_page_protection) -#define MSMFB_OVERLAY_GET _IOR(MSMFB_IOCTL_MAGIC, 140, \ - struct mdp_overlay) - -/* new ioctls for async MDP ops */ -#define MSMFB_ASYNC_BLIT _IOW(MSMFB_IOCTL_MAGIC, 141, unsigned int) -#define MSMFB_BLIT_FLUSH _IOR(MSMFB_IOCTL_MAGIC, 142, unsigned int) - -#define MDP_IMGTYPE2_START 0x10000 - -enum { - MDP_RGB_565, /* RGB 565 planer */ - MDP_XRGB_8888, /* RGB 888 padded */ - MDP_Y_CBCR_H2V2, /* Y and CbCr, pseudo planer w/ Cb is in MSB */ - MDP_ARGB_8888, /* ARGB 888 */ - MDP_RGB_888, /* RGB 888 planer */ - MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planer w/ Cr is in MSB */ - MDP_YCRYCB_H2V1, /* YCrYCb interleave */ - MDP_Y_CRCB_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */ - MDP_Y_CBCR_H2V1, /* Y and CrCb, pseduo planer w/ Cr is in MSB */ - MDP_RGBA_8888, /* ARGB 888 */ - MDP_BGRA_8888, /* ABGR 888 */ - MDP_Y_CRCB_H2V2_TILE, /* Y and CrCb, pseudo planer tile */ - MDP_Y_CBCR_H2V2_TILE, /* Y and CbCr, pseudo planer tile */ - MDP_IMGTYPE_LIMIT, - MDP_BGR_565 = MDP_IMGTYPE2_START, /* BGR 565 planer */ - MDP_FB_FORMAT, /* framebuffer format */ - MDP_IMGTYPE_LIMIT2 /* Non valid image type after this enum */ -}; - -enum { - PMEM_IMG, - FB_IMG, -}; - -/* mdp_blit_req flag values */ -#define MDP_ROT_NOP 0 -#define MDP_FLIP_LR 0x1 -#define MDP_FLIP_UD 0x2 -#define MDP_ROT_90 0x4 -#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR) -#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR) -#define MDP_DITHER 0x8 -#define MDP_BLUR 0x10 -#define MDP_BLEND_FG_PREMULT 0x20000 - -#define MDP_DEINTERLACE 0x80000000 -#define MDP_SHARPENING 0x40000000 - -#define MDP_NO_DMA_BARRIER_START 0x20000000 -#define MDP_NO_DMA_BARRIER_END 0x10000000 -#define MDP_NO_BLIT 0x08000000 -#define MDP_BLIT_WITH_DMA_BARRIERS 0x000 -#define MDP_BLIT_WITH_NO_DMA_BARRIERS \ - (MDP_NO_DMA_BARRIER_START | MDP_NO_DMA_BARRIER_END) -#define MDP_TRANSP_NOP 0xffffffff -#define MDP_ALPHA_NOP 0xff - -#define MDP_BLIT_SRC_GEM 0x02000000 /* set for GEM, clear for PMEM */ -#define MDP_BLIT_DST_GEM 0x01000000 /* set for GEM, clear for PMEM */ - -#define MDP_FB_PAGE_PROTECTION_NONCACHED (0) -#define MDP_FB_PAGE_PROTECTION_WRITECOMBINE (1) -#define MDP_FB_PAGE_PROTECTION_WRITETHROUGHCACHE (2) -#define MDP_FB_PAGE_PROTECTION_WRITEBACKCACHE (3) -#define MDP_FB_PAGE_PROTECTION_WRITEBACKWACACHE (4) -/* Sentinel: Don't use! */ -#define MDP_FB_PAGE_PROTECTION_INVALID (5) -/* Count of the number of MDP_FB_PAGE_PROTECTION_... values. */ -#define MDP_NUM_FB_PAGE_PROTECTION_VALUES (5) - -struct mdp_rect { - uint32_t x; - uint32_t y; - uint32_t w; - uint32_t h; -}; - -struct mdp_img { - uint32_t width; - uint32_t height; - uint32_t format; - uint32_t offset; - int memory_id; /* the file descriptor */ - uint32_t priv; -}; - -/* - * {3x3} + {3} ccs matrix - */ - -#define MDP_CCS_RGB2YUV 0 -#define MDP_CCS_YUV2RGB 1 - -#define MDP_CCS_SIZE 9 -#define MDP_BV_SIZE 3 - -struct mdp_ccs { - int direction; /* MDP_CCS_RGB2YUV or YUV2RGB */ - uint16_t ccs[MDP_CCS_SIZE]; /* 3x3 color coefficients */ - uint16_t bv[MDP_BV_SIZE]; /* 1x3 bias vector */ -}; - -/* The version of the mdp_blit_req structure so that - * user applications can selectively decide which functionality - * to include - */ - -#define MDP_BLIT_REQ_VERSION 2 - -struct mdp_blit_req { - struct mdp_img src; - struct mdp_img dst; - struct mdp_rect src_rect; - struct mdp_rect dst_rect; - uint32_t alpha; - uint32_t transp_mask; - uint32_t flags; - int sharpening_strength; /* -127 <--> 127, default 64 */ -}; - -struct mdp_blit_req_list { - uint32_t count; - struct mdp_blit_req req[]; -}; - -struct msmfb_data { - uint32_t offset; - int memory_id; - int id; -}; - -#define MSMFB_NEW_REQUEST -1 - -struct msmfb_overlay_data { - uint32_t id; - struct msmfb_data data; -}; - -struct msmfb_img { - uint32_t width; - uint32_t height; - uint32_t format; -}; - -struct mdp_overlay { - struct msmfb_img src; - struct mdp_rect src_rect; - struct mdp_rect dst_rect; - uint32_t z_order; /* stage number */ - uint32_t is_fg; /* control alpha & transp */ - uint32_t alpha; - uint32_t transp_mask; - uint32_t flags; - uint32_t id; - uint32_t user_data[8]; -}; - -struct mdp_histogram { - uint32_t frame_cnt; - uint32_t bin_cnt; - uint32_t *r; - uint32_t *g; - uint32_t *b; -}; - -struct mdp_page_protection { - uint32_t page_protection; -}; - - -struct msm_panel_common_pdata { - int gpio; - int (*backlight_level)(int level, int max, int min); - int (*pmic_backlight)(int level); - int (*panel_num)(void); - void (*panel_config_gpio)(int); - int *gpio_num; -}; - -struct lcdc_platform_data { - int (*lcdc_gpio_config)(int on); - void (*lcdc_power_save)(int); -}; - -struct tvenc_platform_data { - int (*pm_vid_en)(int on); -}; - -struct mddi_platform_data { - void (*mddi_power_save)(int on); - int (*mddi_sel_clk)(u32 *clk_rate); -}; - -struct msm_fb_platform_data { - int (*detect_client)(const char *name); - int mddi_prescan; - int (*allow_set_offset)(void); -}; - -struct msm_hdmi_platform_data { - int irq; - int (*cable_detect)(int insert); -}; - -#endif /*_MSM_MDP_H_*/ diff --git a/drivers/staging/msm/staging-devices.c b/drivers/staging/msm/staging-devices.c deleted file mode 100644 index d6cd919469dd..000000000000 --- a/drivers/staging/msm/staging-devices.c +++ /dev/null @@ -1,312 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "msm_mdp.h" -#include "memory_ll.h" -//#include "android_pmem.h" - -#ifdef CONFIG_MSM_SOC_REV_A -#define MSM_SMI_BASE 0xE0000000 -#else -#define MSM_SMI_BASE 0x00000000 -#endif - - -#define TOUCHPAD_SUSPEND 34 -#define TOUCHPAD_IRQ 38 - -#define MSM_PMEM_MDP_SIZE 0x1591000 - -#ifdef CONFIG_MSM_SOC_REV_A -#define SMEM_SPINLOCK_I2C "D:I2C02000021" -#else -#define SMEM_SPINLOCK_I2C "S:6" -#endif - -#define MSM_PMEM_ADSP_SIZE 0x1C00000 - -#define MSM_FB_SIZE 0x500000 -#define MSM_FB_SIZE_ST15 0x800000 -#define MSM_AUDIO_SIZE 0x80000 -#define MSM_GPU_PHYS_SIZE SZ_2M - -#ifdef CONFIG_MSM_SOC_REV_A -#define MSM_SMI_BASE 0xE0000000 -#else -#define MSM_SMI_BASE 0x00000000 -#endif - -#define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000) - -#define MSM_PMEM_SMI_BASE (MSM_SMI_BASE + 0x02B00000) -#define MSM_PMEM_SMI_SIZE 0x01500000 - -#define MSM_FB_BASE MSM_PMEM_SMI_BASE -#define MSM_GPU_PHYS_BASE (MSM_FB_BASE + MSM_FB_SIZE) -#define MSM_PMEM_SMIPOOL_BASE (MSM_GPU_PHYS_BASE + MSM_GPU_PHYS_SIZE) -#define MSM_PMEM_SMIPOOL_SIZE (MSM_PMEM_SMI_SIZE - MSM_FB_SIZE \ - - MSM_GPU_PHYS_SIZE) - -#if defined(CONFIG_FB_MSM_MDP40) -#define MDP_BASE 0xA3F00000 -#define PMDH_BASE 0xAD600000 -#define EMDH_BASE 0xAD700000 -#define TVENC_BASE 0xAD400000 -#else -#define MDP_BASE 0xAA200000 -#define PMDH_BASE 0xAA600000 -#define EMDH_BASE 0xAA700000 -#define TVENC_BASE 0xAA400000 -#endif - -#define PMEM_KERNEL_EBI1_SIZE (CONFIG_PMEM_KERNEL_SIZE * 1024 * 1024) - -static struct resource msm_fb_resources[] = { - { - .flags = IORESOURCE_DMA, - } -}; - -static struct resource msm_mdp_resources[] = { - { - .name = "mdp", - .start = MDP_BASE, - .end = MDP_BASE + 0x000F0000 - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device msm_mdp_device = { - .name = "mdp", - .id = 0, - .num_resources = ARRAY_SIZE(msm_mdp_resources), - .resource = msm_mdp_resources, -}; - -static struct platform_device msm_lcdc_device = { - .name = "lcdc", - .id = 0, -}; - -static int msm_fb_detect_panel(const char *name) -{ - int ret = -EPERM; - - if (machine_is_qsd8x50_ffa() || machine_is_qsd8x50a_ffa()) { - if (!strncmp(name, "mddi_toshiba_wvga_pt", 20)) - ret = 0; - else - ret = -ENODEV; - } else if ((machine_is_qsd8x50_surf() || machine_is_qsd8x50a_surf()) - && !strcmp(name, "lcdc_external")) - ret = 0; - else if (machine_is_qsd8x50a_st1_5()) { - if (!strcmp(name, "lcdc_st15") || - !strcmp(name, "hdmi_sii9022")) - ret = 0; - else - ret = -ENODEV; - } - - return ret; -} - -/* Only allow a small subset of machines to set the offset via - FB PAN_DISPLAY */ - -static int msm_fb_allow_set_offset(void) -{ - return (machine_is_qsd8x50_st1() || - machine_is_qsd8x50a_st1_5()) ? 1 : 0; -} - - -static struct msm_fb_platform_data msm_fb_pdata = { - .detect_client = msm_fb_detect_panel, - .allow_set_offset = msm_fb_allow_set_offset, -}; - -static struct platform_device msm_fb_device = { - .name = "msm_fb", - .id = 0, - .num_resources = ARRAY_SIZE(msm_fb_resources), - .resource = msm_fb_resources, - .dev = { - .platform_data = &msm_fb_pdata, - } -}; - -static void __init qsd8x50_allocate_memory_regions(void) -{ - void *addr; - unsigned long size; - if (machine_is_qsd8x50a_st1_5()) - size = MSM_FB_SIZE_ST15; - else - size = MSM_FB_SIZE; - - addr = alloc_bootmem(size); // (void *)MSM_FB_BASE; - if (!addr) - printk("Failed to allocate bootmem for framebuffer\n"); - - - msm_fb_resources[0].start = __pa(addr); - msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1; - pr_info("using %lu bytes of SMI at %lx physical for fb\n", - size, (unsigned long)addr); -} - -static int msm_fb_lcdc_gpio_config(int on) -{ -// return 0; - if (machine_is_qsd8x50_st1()) { - if (on) { - gpio_set_value(32, 1); - mdelay(100); - gpio_set_value(20, 1); - gpio_set_value(17, 1); - gpio_set_value(19, 1); - } else { - gpio_set_value(17, 0); - gpio_set_value(19, 0); - gpio_set_value(20, 0); - mdelay(100); - gpio_set_value(32, 0); - } - } else if (machine_is_qsd8x50a_st1_5()) { - if (on) { - gpio_set_value(17, 1); - gpio_set_value(19, 1); - gpio_set_value(20, 1); - gpio_set_value(22, 0); - gpio_set_value(32, 1); - gpio_set_value(155, 1); - //st15_hdmi_power(1); - gpio_set_value(22, 1); - - } else { - gpio_set_value(17, 0); - gpio_set_value(19, 0); - gpio_set_value(22, 0); - gpio_set_value(32, 0); - gpio_set_value(155, 0); - // st15_hdmi_power(0); - } - } - return 0; -} - - -static struct lcdc_platform_data lcdc_pdata = { - .lcdc_gpio_config = msm_fb_lcdc_gpio_config, -}; - -static struct msm_gpio msm_fb_st15_gpio_config_data[] = { - { GPIO_CFG(17, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en0" }, - { GPIO_CFG(19, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "dat_pwr_sv" }, - { GPIO_CFG(20, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lvds_pwr_dn" }, - { GPIO_CFG(22, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en1" }, - { GPIO_CFG(32, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en2" }, - { GPIO_CFG(103, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA), "hdmi_irq" }, - { GPIO_CFG(155, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "hdmi_3v3" }, -}; - -static struct msm_panel_common_pdata mdp_pdata = { - .gpio = 98, -}; - -static struct platform_device *devices[] __initdata = { - &msm_fb_device, -}; - - -static void __init msm_register_device(struct platform_device *pdev, void *data) -{ - int ret; - - pdev->dev.platform_data = data; - - ret = platform_device_register(pdev); - if (ret) - dev_err(&pdev->dev, - "%s: platform_device_register() failed = %d\n", - __func__, ret); -} - -void __init msm_fb_register_device(char *name, void *data) -{ - if (!strncmp(name, "mdp", 3)) - msm_register_device(&msm_mdp_device, data); -/* - else if (!strncmp(name, "pmdh", 4)) - msm_register_device(&msm_mddi_device, data); - else if (!strncmp(name, "emdh", 4)) - msm_register_device(&msm_mddi_ext_device, data); - else if (!strncmp(name, "ebi2", 4)) - msm_register_device(&msm_ebi2_lcd_device, data); - else if (!strncmp(name, "tvenc", 5)) - msm_register_device(&msm_tvenc_device, data); - else */ - - if (!strncmp(name, "lcdc", 4)) - msm_register_device(&msm_lcdc_device, data); - /*else - printk(KERN_ERR "%s: unknown device! %s\n", __func__, name); -*/ -} - -static void __init msm_fb_add_devices(void) -{ - int rc; - msm_fb_register_device("mdp", &mdp_pdata); -// msm_fb_register_device("pmdh", &mddi_pdata); -// msm_fb_register_device("emdh", &mddi_pdata); -// msm_fb_register_device("tvenc", 0); - - if (machine_is_qsd8x50a_st1_5()) { -/* rc = st15_hdmi_vreg_init(); - if (rc) - return; -*/ - rc = msm_gpios_request_enable( - msm_fb_st15_gpio_config_data, - ARRAY_SIZE(msm_fb_st15_gpio_config_data)); - if (rc) { - printk(KERN_ERR "%s: unable to init lcdc gpios\n", - __func__); - return; - } - msm_fb_register_device("lcdc", &lcdc_pdata); - } else - msm_fb_register_device("lcdc", 0); -} - -int __init staging_init_pmem(void) -{ - qsd8x50_allocate_memory_regions(); - return 0; -} - -int __init staging_init_devices(void) -{ - platform_add_devices(devices, ARRAY_SIZE(devices)); - msm_fb_add_devices(); - return 0; -} - -arch_initcall(staging_init_pmem); -arch_initcall(staging_init_devices); diff --git a/drivers/staging/msm/tv_ntsc.c b/drivers/staging/msm/tv_ntsc.c deleted file mode 100644 index 5eb67611661a..000000000000 --- a/drivers/staging/msm/tv_ntsc.c +++ /dev/null @@ -1,163 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "msm_fb.h" -#include "tvenc.h" - -#define NTSC_TV_DIMENSION_WIDTH 720 -#define NTSC_TV_DIMENSION_HEIGHT 480 - -static int ntsc_off(struct platform_device *pdev); -static int ntsc_on(struct platform_device *pdev); - -static int ntsc_on(struct platform_device *pdev) -{ - uint32 reg = 0; - int ret = 0; - struct msm_fb_data_type *mfd; - - mfd = platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ - - if (mfd->panel.id == NTSC_M) { - /* Cr gain 11, Cb gain C6, y_gain 97 */ - TV_OUT(TV_GAIN, 0x0081B697); - } else { - /* Cr gain 11, Cb gain C6, y_gain 97 */ - TV_OUT(TV_GAIN, 0x008bc4a3); - reg |= TVENC_CTL_NTSCJ_MODE; - } - - TV_OUT(TV_CGMS, 0x0); - /* NTSC Timing */ - TV_OUT(TV_SYNC_1, 0x0020009e); - TV_OUT(TV_SYNC_2, 0x011306B4); - TV_OUT(TV_SYNC_3, 0x0006000C); - TV_OUT(TV_SYNC_4, 0x0028020D); - TV_OUT(TV_SYNC_5, 0x005E02FB); - TV_OUT(TV_SYNC_6, 0x0006000C); - TV_OUT(TV_SYNC_7, 0x00000012); - TV_OUT(TV_BURST_V1, 0x0013020D); - TV_OUT(TV_BURST_V2, 0x0014020C); - TV_OUT(TV_BURST_V3, 0x0013020D); - TV_OUT(TV_BURST_V4, 0x0014020C); - TV_OUT(TV_BURST_H, 0x00AE00F2); - TV_OUT(TV_SOL_REQ_ODD, 0x00280208); - TV_OUT(TV_SOL_REQ_EVEN, 0x00290209); - - reg |= TVENC_CTL_TV_MODE_NTSC_M_PAL60; - - reg |= TVENC_CTL_Y_FILTER_EN | - TVENC_CTL_CR_FILTER_EN | - TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN; -#ifdef CONFIG_FB_MSM_TVOUT_SVIDEO - reg |= TVENC_CTL_S_VIDEO_EN; -#endif - - TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */ - TV_OUT(TV_OFFSET, 0x008080f0); - -#ifdef CONFIG_FB_MSM_MDP31 - TV_OUT(TV_DAC_INTF, 0x29); -#endif - TV_OUT(TV_ENC_CTL, reg); - - reg |= TVENC_CTL_ENC_EN; - TV_OUT(TV_ENC_CTL, reg); - - return ret; -} - -static int ntsc_off(struct platform_device *pdev) -{ - TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ - return 0; -} - -static int __init ntsc_probe(struct platform_device *pdev) -{ - msm_fb_add_device(pdev); - - return 0; -} - -static struct platform_driver this_driver = { - .probe = ntsc_probe, - .driver = { - .name = "tv_ntsc", - }, -}; - -static struct msm_fb_panel_data ntsc_panel_data = { - .panel_info.xres = NTSC_TV_DIMENSION_WIDTH, - .panel_info.yres = NTSC_TV_DIMENSION_HEIGHT, - .panel_info.type = TV_PANEL, - .panel_info.pdest = DISPLAY_1, - .panel_info.wait_cycle = 0, - .panel_info.bpp = 16, - .panel_info.fb_num = 2, - .on = ntsc_on, - .off = ntsc_off, -}; - -static struct platform_device this_device = { - .name = "tv_ntsc", - .id = 0, - .dev = { - .platform_data = &ntsc_panel_data, - } -}; - -static int __init ntsc_init(void) -{ - int ret; - - ret = platform_driver_register(&this_driver); - if (!ret) { - ret = platform_device_register(&this_device); - if (ret) - platform_driver_unregister(&this_driver); - } - - return ret; -} - -module_init(ntsc_init); \ No newline at end of file diff --git a/drivers/staging/msm/tv_pal.c b/drivers/staging/msm/tv_pal.c deleted file mode 100644 index 204da514660e..000000000000 --- a/drivers/staging/msm/tv_pal.c +++ /dev/null @@ -1,213 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "msm_fb.h" -#include "tvenc.h" - -#ifdef CONFIG_FB_MSM_TVOUT_PAL_M -#define PAL_TV_DIMENSION_WIDTH 720 -#define PAL_TV_DIMENSION_HEIGHT 480 -#else -#define PAL_TV_DIMENSION_WIDTH 720 -#define PAL_TV_DIMENSION_HEIGHT 576 -#endif - -static int pal_on(struct platform_device *pdev) -{ - uint32 reg = 0; - int ret = 0; - struct msm_fb_data_type *mfd; - - mfd = platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ - - switch (mfd->panel.id) { - case PAL_BDGHIN: - /* Cr gain 11, Cb gain C6, y_gain 97 */ - TV_OUT(TV_GAIN, 0x0088c1a0); - TV_OUT(TV_CGMS, 0x00012345); - TV_OUT(TV_TEST_MUX, 0x0); - /* PAL Timing */ - TV_OUT(TV_SYNC_1, 0x00180097); - TV_OUT(TV_SYNC_2, 0x011f06c0); - TV_OUT(TV_SYNC_3, 0x0005000a); - TV_OUT(TV_SYNC_4, 0x00320271); - TV_OUT(TV_SYNC_5, 0x005602f9); - TV_OUT(TV_SYNC_6, 0x0005000a); - TV_OUT(TV_SYNC_7, 0x0000000f); - TV_OUT(TV_BURST_V1, 0x0012026e); - TV_OUT(TV_BURST_V2, 0x0011026d); - TV_OUT(TV_BURST_V3, 0x00100270); - TV_OUT(TV_BURST_V4, 0x0013026f); - TV_OUT(TV_BURST_H, 0x00af00ea); - TV_OUT(TV_SOL_REQ_ODD, 0x0030026e); - TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f); - - reg |= TVENC_CTL_TV_MODE_PAL_BDGHIN; - break; - case PAL_M: - /* Cr gain 11, Cb gain C6, y_gain 97 */ - TV_OUT(TV_GAIN, 0x0081b697); - TV_OUT(TV_CGMS, 0x000af317); - TV_OUT(TV_TEST_MUX, 0x000001c3); - TV_OUT(TV_TEST_MODE, 0x00000002); - /* PAL Timing */ - TV_OUT(TV_SYNC_1, 0x0020009e); - TV_OUT(TV_SYNC_2, 0x011306b4); - TV_OUT(TV_SYNC_3, 0x0006000c); - TV_OUT(TV_SYNC_4, 0x0028020D); - TV_OUT(TV_SYNC_5, 0x005e02fb); - TV_OUT(TV_SYNC_6, 0x0006000c); - TV_OUT(TV_SYNC_7, 0x00000012); - TV_OUT(TV_BURST_V1, 0x0012020b); - TV_OUT(TV_BURST_V2, 0x0016020c); - TV_OUT(TV_BURST_V3, 0x00150209); - TV_OUT(TV_BURST_V4, 0x0013020c); - TV_OUT(TV_BURST_H, 0x00bf010b); - TV_OUT(TV_SOL_REQ_ODD, 0x00280208); - TV_OUT(TV_SOL_REQ_EVEN, 0x00290209); - - reg |= TVENC_CTL_TV_MODE_PAL_M; - break; - case PAL_N: - /* Cr gain 11, Cb gain C6, y_gain 97 */ - TV_OUT(TV_GAIN, 0x0081b697); - TV_OUT(TV_CGMS, 0x000af317); - TV_OUT(TV_TEST_MUX, 0x000001c3); - TV_OUT(TV_TEST_MODE, 0x00000002); - /* PAL Timing */ - TV_OUT(TV_SYNC_1, 0x00180097); - TV_OUT(TV_SYNC_2, 0x12006c0); - TV_OUT(TV_SYNC_3, 0x0005000a); - TV_OUT(TV_SYNC_4, 0x00320271); - TV_OUT(TV_SYNC_5, 0x005602f9); - TV_OUT(TV_SYNC_6, 0x0005000a); - TV_OUT(TV_SYNC_7, 0x0000000f); - TV_OUT(TV_BURST_V1, 0x0012026e); - TV_OUT(TV_BURST_V2, 0x0011026d); - TV_OUT(TV_BURST_V3, 0x00100270); - TV_OUT(TV_BURST_V4, 0x0013026f); - TV_OUT(TV_BURST_H, 0x00af00fa); - TV_OUT(TV_SOL_REQ_ODD, 0x0030026e); - TV_OUT(TV_SOL_REQ_EVEN, 0x0031026f); - - reg |= TVENC_CTL_TV_MODE_PAL_N; - break; - - default: - return -ENODEV; - } - - reg |= TVENC_CTL_Y_FILTER_EN | - TVENC_CTL_CR_FILTER_EN | - TVENC_CTL_CB_FILTER_EN | TVENC_CTL_SINX_FILTER_EN; -#ifdef CONFIG_FB_MSM_TVOUT_SVIDEO - reg |= TVENC_CTL_S_VIDEO_EN; -#endif - - TV_OUT(TV_LEVEL, 0x00000000); /* DC offset to 0. */ - TV_OUT(TV_OFFSET, 0x008080f0); - -#ifdef CONFIG_FB_MSM_MDP31 - TV_OUT(TV_DAC_INTF, 0x29); -#endif - TV_OUT(TV_ENC_CTL, reg); - - reg |= TVENC_CTL_ENC_EN; - TV_OUT(TV_ENC_CTL, reg); - - return ret; -} - -static int pal_off(struct platform_device *pdev) -{ - TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ - return 0; -} - -static int __init pal_probe(struct platform_device *pdev) -{ - msm_fb_add_device(pdev); - - return 0; -} - -static struct platform_driver this_driver = { - .probe = pal_probe, - .driver = { - .name = "tv_pal", - }, -}; - -static struct msm_fb_panel_data pal_panel_data = { - .panel_info.xres = PAL_TV_DIMENSION_WIDTH, - .panel_info.yres = PAL_TV_DIMENSION_HEIGHT, - .panel_info.type = TV_PANEL, - .panel_info.pdest = DISPLAY_1, - .panel_info.wait_cycle = 0, - .panel_info.bpp = 16, - .panel_info.fb_num = 2, - .on = pal_on, - .off = pal_off, -}; - -static struct platform_device this_device = { - .name = "tv_pal", - .id = 0, - .dev = { - .platform_data = &pal_panel_data, - } -}; - -static int __init pal_init(void) -{ - int ret; - - ret = platform_driver_register(&this_driver); - if (!ret) { - ret = platform_device_register(&this_device); - if (ret) - platform_driver_unregister(&this_driver); - } - - return ret; -} - -module_init(pal_init); diff --git a/drivers/staging/msm/tvenc.c b/drivers/staging/msm/tvenc.c deleted file mode 100644 index 4fbb77b253d3..000000000000 --- a/drivers/staging/msm/tvenc.c +++ /dev/null @@ -1,296 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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 Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define TVENC_C -#include "tvenc.h" -#include "msm_fb.h" - -static int tvenc_probe(struct platform_device *pdev); -static int tvenc_remove(struct platform_device *pdev); - -static int tvenc_off(struct platform_device *pdev); -static int tvenc_on(struct platform_device *pdev); - -static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST]; -static int pdev_list_cnt; - -static struct clk *tvenc_clk; -static struct clk *tvdac_clk; - -static struct platform_driver tvenc_driver = { - .probe = tvenc_probe, - .remove = tvenc_remove, - .suspend = NULL, -// .suspend_late = NULL, -// .resume_early = NULL, - .resume = NULL, - .shutdown = NULL, - .driver = { - .name = "tvenc", - }, -}; - -static struct tvenc_platform_data *tvenc_pdata; - -static int tvenc_off(struct platform_device *pdev) -{ - int ret = 0; - - ret = panel_next_off(pdev); - - clk_disable(tvenc_clk); - clk_disable(tvdac_clk); - - if (tvenc_pdata && tvenc_pdata->pm_vid_en) - ret = tvenc_pdata->pm_vid_en(0); - - //pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc", - // PM_QOS_DEFAULT_VALUE); - - if (ret) - printk(KERN_ERR "%s: pm_vid_en(off) failed! %d\n", - __func__, ret); - - return ret; -} - -static int tvenc_on(struct platform_device *pdev) -{ - int ret = 0; - -// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc", -// 128000); - if (tvenc_pdata && tvenc_pdata->pm_vid_en) - ret = tvenc_pdata->pm_vid_en(1); - - if (ret) { - printk(KERN_ERR "%s: pm_vid_en(on) failed! %d\n", - __func__, ret); - return ret; - } - - clk_enable(tvenc_clk); - clk_enable(tvdac_clk); - - ret = panel_next_on(pdev); - - return ret; -} - -void tvenc_gen_test_pattern(struct msm_fb_data_type *mfd) -{ - uint32 reg = 0, i; - - reg = readl(MSM_TV_ENC_CTL); - reg |= TVENC_CTL_TEST_PATT_EN; - - for (i = 0; i < 3; i++) { - TV_OUT(TV_ENC_CTL, 0); /* disable TV encoder */ - - switch (i) { - /* - * TV Encoder - Color Bar Test Pattern - */ - case 0: - reg |= TVENC_CTL_TPG_CLRBAR; - break; - /* - * TV Encoder - Red Frame Test Pattern - */ - case 1: - reg |= TVENC_CTL_TPG_REDCLR; - break; - /* - * TV Encoder - Modulated Ramp Test Pattern - */ - default: - reg |= TVENC_CTL_TPG_MODRAMP; - break; - } - - TV_OUT(TV_ENC_CTL, reg); - mdelay(5000); - - switch (i) { - /* - * TV Encoder - Color Bar Test Pattern - */ - case 0: - reg &= ~TVENC_CTL_TPG_CLRBAR; - break; - /* - * TV Encoder - Red Frame Test Pattern - */ - case 1: - reg &= ~TVENC_CTL_TPG_REDCLR; - break; - /* - * TV Encoder - Modulated Ramp Test Pattern - */ - default: - reg &= ~TVENC_CTL_TPG_MODRAMP; - break; - } - } -} - -static int tvenc_resource_initialized; - -static int tvenc_probe(struct platform_device *pdev) -{ - struct msm_fb_data_type *mfd; - struct platform_device *mdp_dev = NULL; - struct msm_fb_panel_data *pdata = NULL; - int rc; - - if (pdev->id == 0) { - tvenc_base = ioremap(pdev->resource[0].start, - pdev->resource[0].end - - pdev->resource[0].start + 1); - if (!tvenc_base) { - printk(KERN_ERR - "tvenc_base ioremap failed!\n"); - return -ENOMEM; - } - tvenc_pdata = pdev->dev.platform_data; - tvenc_resource_initialized = 1; - return 0; - } - - if (!tvenc_resource_initialized) - return -EPERM; - - mfd = platform_get_drvdata(pdev); - - if (!mfd) - return -ENODEV; - - if (mfd->key != MFD_KEY) - return -EINVAL; - - if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST) - return -ENOMEM; - - if (tvenc_base == NULL) - return -ENOMEM; - - mdp_dev = platform_device_alloc("mdp", pdev->id); - if (!mdp_dev) - return -ENOMEM; - - /* - * link to the latest pdev - */ - mfd->pdev = mdp_dev; - mfd->dest = DISPLAY_TV; - - /* - * alloc panel device data - */ - if (platform_device_add_data - (mdp_dev, pdev->dev.platform_data, - sizeof(struct msm_fb_panel_data))) { - printk(KERN_ERR "tvenc_probe: platform_device_add_data failed!\n"); - platform_device_put(mdp_dev); - return -ENOMEM; - } - /* - * data chain - */ - pdata = mdp_dev->dev.platform_data; - pdata->on = tvenc_on; - pdata->off = tvenc_off; - pdata->next = pdev; - - /* - * get/set panel specific fb info - */ - mfd->panel_info = pdata->panel_info; - mfd->fb_imgType = MDP_YCRYCB_H2V1; - - /* - * set driver data - */ - platform_set_drvdata(mdp_dev, mfd); - - /* - * register in mdp driver - */ - rc = platform_device_add(mdp_dev); - if (rc) - goto tvenc_probe_err; - - pdev_list[pdev_list_cnt++] = pdev; - return 0; - -tvenc_probe_err: - platform_device_put(mdp_dev); - return rc; -} - -static int tvenc_remove(struct platform_device *pdev) -{ -// pm_qos_remove_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc"); - return 0; -} - -static int tvenc_register_driver(void) -{ - return platform_driver_register(&tvenc_driver); -} - -static int __init tvenc_driver_init(void) -{ - tvenc_clk = clk_get(NULL, "tv_enc_clk"); - tvdac_clk = clk_get(NULL, "tv_dac_clk"); - - if (IS_ERR(tvenc_clk)) { - printk(KERN_ERR "error: can't get tvenc_clk!\n"); - return PTR_ERR(tvenc_clk); - } - - if (IS_ERR(tvdac_clk)) { - printk(KERN_ERR "error: can't get tvdac_clk!\n"); - clk_put(tvenc_clk); - return PTR_ERR(tvdac_clk); - } - -// pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc", -// PM_QOS_DEFAULT_VALUE); - return tvenc_register_driver(); -} - -module_init(tvenc_driver_init); diff --git a/drivers/staging/msm/tvenc.h b/drivers/staging/msm/tvenc.h deleted file mode 100644 index 6bb375d7a5ad..000000000000 --- a/drivers/staging/msm/tvenc.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (c) 2008-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 and - * only 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. - */ - -#ifndef TVENC_H -#define TVENC_H - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "msm_fb_panel.h" - -#define NTSC_M 0 /* North America, Korea */ -#define NTSC_J 1 /* Japan */ -#define PAL_BDGHIN 2 /* Non-argentina PAL-N */ -#define PAL_M 3 /* PAL-M */ -#define PAL_N 4 /* Argentina PAL-N */ - -/* 3.57954545 Mhz */ -#define TVENC_CTL_TV_MODE_NTSC_M_PAL60 0 -/* 3.57961149 Mhz */ -#define TVENC_CTL_TV_MODE_PAL_M BIT(0) -/*non-Argintina = 4.3361875 Mhz */ -#define TVENC_CTL_TV_MODE_PAL_BDGHIN BIT(1) -/*Argentina = 3.582055625 Mhz */ -#define TVENC_CTL_TV_MODE_PAL_N (BIT(1)|BIT(0)) - -#define TVENC_CTL_ENC_EN BIT(2) -#define TVENC_CTL_CC_EN BIT(3) -#define TVENC_CTL_CGMS_EN BIT(4) -#define TVENC_CTL_MACRO_EN BIT(5) -#define TVENC_CTL_Y_FILTER_W_NOTCH BIT(6) -#define TVENC_CTL_Y_FILTER_WO_NOTCH 0 -#define TVENC_CTL_Y_FILTER_EN BIT(7) -#define TVENC_CTL_CR_FILTER_EN BIT(8) -#define TVENC_CTL_CB_FILTER_EN BIT(9) -#define TVENC_CTL_SINX_FILTER_EN BIT(10) -#define TVENC_CTL_TEST_PATT_EN BIT(11) -#define TVENC_CTL_OUTPUT_INV BIT(12) -#define TVENC_CTL_PAL60_MODE BIT(13) -#define TVENC_CTL_NTSCJ_MODE BIT(14) -#define TVENC_CTL_TPG_CLRBAR 0 -#define TVENC_CTL_TPG_MODRAMP BIT(15) -#define TVENC_CTL_TPG_REDCLR BIT(16) -#define TVENC_CTL_S_VIDEO_EN BIT(19) - -#ifdef TVENC_C -void *tvenc_base; -#else -extern void *tvenc_base; -#endif - -#define TV_OUT(reg, v) writel(v, tvenc_base + MSM_##reg) - -#define MSM_TV_ENC_CTL 0x00 -#define MSM_TV_LEVEL 0x04 -#define MSM_TV_GAIN 0x08 -#define MSM_TV_OFFSET 0x0c -#define MSM_TV_CGMS 0x10 -#define MSM_TV_SYNC_1 0x14 -#define MSM_TV_SYNC_2 0x18 -#define MSM_TV_SYNC_3 0x1c -#define MSM_TV_SYNC_4 0x20 -#define MSM_TV_SYNC_5 0x24 -#define MSM_TV_SYNC_6 0x28 -#define MSM_TV_SYNC_7 0x2c -#define MSM_TV_BURST_V1 0x30 -#define MSM_TV_BURST_V2 0x34 -#define MSM_TV_BURST_V3 0x38 -#define MSM_TV_BURST_V4 0x3c -#define MSM_TV_BURST_H 0x40 -#define MSM_TV_SOL_REQ_ODD 0x44 -#define MSM_TV_SOL_REQ_EVEN 0x48 -#define MSM_TV_DAC_CTL 0x4c -#define MSM_TV_TEST_MUX 0x50 -#define MSM_TV_TEST_MODE 0x54 -#define MSM_TV_TEST_MISR_RESET 0x58 -#define MSM_TV_TEST_EXPORT_MISR 0x5c -#define MSM_TV_TEST_MISR_CURR_VAL 0x60 -#define MSM_TV_TEST_SOF_CFG 0x64 -#define MSM_TV_DAC_INTF 0x100 - -#endif /* TVENC_H */ diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c index 8a11ffcd7de8..f18e3e140413 100644 --- a/drivers/staging/octeon/ethernet-mdio.c +++ b/drivers/staging/octeon/ethernet-mdio.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -129,22 +130,22 @@ static void cvm_oct_adjust_link(struct net_device *dev) if (priv->last_link) { netif_carrier_on(dev); if (priv->queue != -1) - DEBUGPRINT("%s: %u Mbps %s duplex, " - "port %2d, queue %2d\n", - dev->name, priv->phydev->speed, - priv->phydev->duplex ? - "Full" : "Half", - priv->port, priv->queue); + printk_ratelimited("%s: %u Mbps %s duplex, " + "port %2d, queue %2d\n", + dev->name, priv->phydev->speed, + priv->phydev->duplex ? + "Full" : "Half", + priv->port, priv->queue); else - DEBUGPRINT("%s: %u Mbps %s duplex, " - "port %2d, POW\n", - dev->name, priv->phydev->speed, - priv->phydev->duplex ? - "Full" : "Half", - priv->port); + printk_ratelimited("%s: %u Mbps %s duplex, " + "port %2d, POW\n", + dev->name, priv->phydev->speed, + priv->phydev->duplex ? + "Full" : "Half", + priv->port); } else { netif_carrier_off(dev); - DEBUGPRINT("%s: Link down\n", dev->name); + printk_ratelimited("%s: Link down\n", dev->name); } } } diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c index a0d4d4b98bdc..9c0d2936e486 100644 --- a/drivers/staging/octeon/ethernet-rgmii.c +++ b/drivers/staging/octeon/ethernet-rgmii.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -116,9 +117,9 @@ static void cvm_oct_rgmii_poll(struct net_device *dev) cvmx_write_csr(CVMX_GMXX_RXX_INT_REG (index, interface), gmxx_rxx_int_reg.u64); - DEBUGPRINT("%s: Using 10Mbps with software " - "preamble removal\n", - dev->name); + printk_ratelimited("%s: Using 10Mbps with software " + "preamble removal\n", + dev->name); } } @@ -174,23 +175,23 @@ static void cvm_oct_rgmii_poll(struct net_device *dev) if (!netif_carrier_ok(dev)) netif_carrier_on(dev); if (priv->queue != -1) - DEBUGPRINT("%s: %u Mbps %s duplex, " - "port %2d, queue %2d\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? - "Full" : "Half", - priv->port, priv->queue); + printk_ratelimited("%s: %u Mbps %s duplex, " + "port %2d, queue %2d\n", + dev->name, link_info.s.speed, + (link_info.s.full_duplex) ? + "Full" : "Half", + priv->port, priv->queue); else - DEBUGPRINT("%s: %u Mbps %s duplex, " - "port %2d, POW\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? - "Full" : "Half", - priv->port); + printk_ratelimited("%s: %u Mbps %s duplex, " + "port %2d, POW\n", + dev->name, link_info.s.speed, + (link_info.s.full_duplex) ? + "Full" : "Half", + priv->port); } else { if (netif_carrier_ok(dev)) netif_carrier_off(dev); - DEBUGPRINT("%s: Link down\n", dev->name); + printk_ratelimited("%s: Link down\n", dev->name); } } } diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index cb38f9eb2cc0..0f22f0f47446 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_XFRM @@ -186,13 +187,13 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) if (*ptr == 0xd5) { /* - DEBUGPRINT("Port %d received 0xd5 preamble\n", work->ipprt); + printk_ratelimited("Port %d received 0xd5 preamble\n", work->ipprt); */ work->packet_ptr.s.addr += i + 1; work->len -= i + 5; } else if ((*ptr & 0xf) == 0xd) { /* - DEBUGPRINT("Port %d received 0x?d preamble\n", work->ipprt); + printk_ratelimited("Port %d received 0x?d preamble\n", work->ipprt); */ work->packet_ptr.s.addr += i; work->len -= i + 4; @@ -203,9 +204,9 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) ptr++; } } else { - DEBUGPRINT("Port %d unknown preamble, packet " - "dropped\n", - work->ipprt); + printk_ratelimited("Port %d unknown preamble, packet " + "dropped\n", + work->ipprt); /* cvmx_helper_dump_packet(work); */ @@ -214,8 +215,8 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) } } } else { - DEBUGPRINT("Port %d receive error code %d, packet dropped\n", - work->ipprt, work->word2.snoip.err_code); + printk_ratelimited("Port %d receive error code %d, packet dropped\n", + work->ipprt, work->word2.snoip.err_code); cvm_oct_free_work(work); return 1; } @@ -334,8 +335,9 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) */ skb = dev_alloc_skb(work->len); if (!skb) { - DEBUGPRINT("Port %d failed to allocate skbuff, packet dropped\n", - work->ipprt); + printk_ratelimited("Port %d failed to allocate " + "skbuff, packet dropped\n", + work->ipprt); cvm_oct_free_work(work); continue; } @@ -429,7 +431,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) } else { /* Drop any packet received for a device that isn't up */ /* - DEBUGPRINT("%s: Device not up, packet dropped\n", + printk_ratelimited("%s: Device not up, packet dropped\n", dev->name); */ #ifdef CONFIG_64BIT @@ -444,7 +446,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) * Drop any packet received for a device that * doesn't exist. */ - DEBUGPRINT("Port %d not controlled by Linux, packet dropped\n", + printk_ratelimited("Port %d not controlled by Linux, packet dropped\n", work->ipprt); dev_kfree_skb_irq(skb); } diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c index 2d8589eb461e..5e148b512c97 100644 --- a/drivers/staging/octeon/ethernet-sgmii.c +++ b/drivers/staging/octeon/ethernet-sgmii.c @@ -26,6 +26,7 @@ **********************************************************************/ #include #include +#include #include #include @@ -90,20 +91,21 @@ static void cvm_oct_sgmii_poll(struct net_device *dev) if (!netif_carrier_ok(dev)) netif_carrier_on(dev); if (priv->queue != -1) - DEBUGPRINT + printk_ratelimited ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", dev->name, link_info.s.speed, (link_info.s.full_duplex) ? "Full" : "Half", priv->port, priv->queue); else - DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? "Full" : "Half", - priv->port); + printk_ratelimited + ("%s: %u Mbps %s duplex, port %2d, POW\n", + dev->name, link_info.s.speed, + (link_info.s.full_duplex) ? "Full" : "Half", + priv->port); } else { if (netif_carrier_ok(dev)) netif_carrier_off(dev); - DEBUGPRINT("%s: Link down\n", dev->name); + printk_ratelimited("%s: Link down\n", dev->name); } } diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index afc2b734d554..6227571149f5 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_XFRM @@ -446,7 +447,7 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) priv->queue + qos, pko_command, hw_buffer, CVMX_PKO_LOCK_NONE))) { - DEBUGPRINT("%s: Failed to send the packet\n", dev->name); + printk_ratelimited("%s: Failed to send the packet\n", dev->name); queue_type = QUEUE_DROP; } skip_xmit: @@ -525,8 +526,8 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) /* Get a work queue entry */ cvmx_wqe_t *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL); if (unlikely(work == NULL)) { - DEBUGPRINT("%s: Failed to allocate a work queue entry\n", - dev->name); + printk_ratelimited("%s: Failed to allocate a work " + "queue entry\n", dev->name); priv->stats.tx_dropped++; dev_kfree_skb(skb); return 0; @@ -535,8 +536,8 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) /* Get a packet buffer */ packet_buffer = cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL); if (unlikely(packet_buffer == NULL)) { - DEBUGPRINT("%s: Failed to allocate a packet buffer\n", - dev->name); + printk_ratelimited("%s: Failed to allocate a packet buffer\n", + dev->name); cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1)); priv->stats.tx_dropped++; dev_kfree_skb(skb); diff --git a/drivers/staging/octeon/ethernet-util.h b/drivers/staging/octeon/ethernet-util.h index c745a72a0594..144fb99bf50c 100644 --- a/drivers/staging/octeon/ethernet-util.h +++ b/drivers/staging/octeon/ethernet-util.h @@ -25,10 +25,6 @@ * Contact Cavium Networks for more information *********************************************************************/ -#define DEBUGPRINT(format, ...) do { if (printk_ratelimit()) \ - printk(format, ##__VA_ARGS__); \ - } while (0) - /** * cvm_oct_get_buffer_ptr - convert packet data address to pointer * @packet_ptr: Packet data hardware address diff --git a/drivers/staging/octeon/ethernet-xaui.c b/drivers/staging/octeon/ethernet-xaui.c index 3fca1cc31ed8..861a4b3fe857 100644 --- a/drivers/staging/octeon/ethernet-xaui.c +++ b/drivers/staging/octeon/ethernet-xaui.c @@ -26,6 +26,7 @@ **********************************************************************/ #include #include +#include #include #include @@ -89,20 +90,21 @@ static void cvm_oct_xaui_poll(struct net_device *dev) if (!netif_carrier_ok(dev)) netif_carrier_on(dev); if (priv->queue != -1) - DEBUGPRINT - ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? "Full" : "Half", - priv->port, priv->queue); + printk_ratelimited + ("%s: %u Mbps %s duplex, port %2d, queue %2d\n", + dev->name, link_info.s.speed, + (link_info.s.full_duplex) ? "Full" : "Half", + priv->port, priv->queue); else - DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n", - dev->name, link_info.s.speed, - (link_info.s.full_duplex) ? "Full" : "Half", - priv->port); + printk_ratelimited + ("%s: %u Mbps %s duplex, port %2d, POW\n", + dev->name, link_info.s.speed, + (link_info.s.full_duplex) ? "Full" : "Half", + priv->port); } else { if (netif_carrier_ok(dev)) netif_carrier_off(dev); - DEBUGPRINT("%s: Link down\n", dev->name); + printk_ratelimited("%s: Link down\n", dev->name); } } diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index 6885f9a46609..b303b7e42b63 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h index 4384d9358c41..e79a7e212979 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h @@ -25,7 +25,6 @@ #define IEEE80211_H #include /* ETH_ALEN */ #include /* ARRAY_SIZE */ -#include #include #include #include diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c index c8dbcb925915..b3882ae9d974 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c @@ -12,7 +12,6 @@ */ //#include -#include #include #include #include diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c index 731d2686411e..6aaaa2fd57f4 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c @@ -10,7 +10,6 @@ */ //#include -#include #include #include #include diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c index ee71ee90fd89..da24e430ca13 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c @@ -10,7 +10,6 @@ */ //#include -#include #include #include #include diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c index f790cd65f107..58f3eeb2143e 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c @@ -10,7 +10,6 @@ */ //#include -#include #include #include #include diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c index 9d58a429c565..9422573bfeaa 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 00ee02f841ad..38e67f0bf624 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -822,7 +821,7 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS); if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT)) - cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT)); + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); crypt = ieee->crypt[ieee->tx_keyidx]; @@ -2569,11 +2568,8 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) ieee->beacon_timer.data = (unsigned long) ieee; ieee->beacon_timer.function = ieee80211_send_beacon_cb; -#ifdef PF_SYNCTHREAD - ieee->wq = create_workqueue(DRV_NAME,0); -#else ieee->wq = create_workqueue(DRV_NAME); -#endif + INIT_DELAYED_WORK(&ieee->start_ibss_wq,(void*) ieee80211_start_ibss_wq); INIT_WORK(&ieee->associate_complete_wq,(void*) ieee80211_associate_complete_wq); INIT_WORK(&ieee->associate_procedure_wq,(void*) ieee80211_associate_procedure_wq); diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c index 6cb31e1760ac..552115cd760e 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c @@ -445,7 +445,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) bytes_per_frag -= IEEE80211_FCS_LEN; - /* Each fragment may need to have room for encryptiong pre/postfix */ + /* Each fragment may need to have room for encryption pre/postfix */ if (encrypt) bytes_per_frag -= crypt->ops->extra_prefix_len + crypt->ops->extra_postfix_len; diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h index 106ebcfa7d7d..8e644614f21d 100644 --- a/drivers/staging/rtl8192e/dot11d.h +++ b/drivers/staging/rtl8192e/dot11d.h @@ -4,30 +4,30 @@ #ifdef ENABLE_DOT11D #include "ieee80211.h" -typedef struct _CHNL_TXPOWER_TRIPLE { +struct _CHNL_TXPOWER_TRIPLE { u8 FirstChnl; u8 NumChnls; u8 MaxTxPowerInDbm; -} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE; +}; -typedef enum _DOT11D_STATE { +enum _DOT11D_STATE { DOT11D_STATE_NONE = 0, DOT11D_STATE_LEARNED, DOT11D_STATE_DONE, -} DOT11D_STATE; +}; /** * struct _RT_DOT11D_INFO * @CountryIeLen: value greater than 0 if @CountryIeBuf contains - * valid country information element. + * valid country information element. * @chanell_map: holds channel values * 0 - invalid, * 1 - valid (active scan), - * 2 - valid (passive scan) + * 2 - valid (passive scan) * @CountryIeSrcAddr - Source AP of the country IE */ -typedef struct _RT_DOT11D_INFO { +struct _RT_DOT11D_INFO { bool bEnabled; u16 CountryIeLen; @@ -39,7 +39,7 @@ typedef struct _RT_DOT11D_INFO { u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; DOT11D_STATE State; -} RT_DOT11D_INFO, *PRT_DOT11D_INFO; +}; static inline void cpMacAddr(unsigned char *des, unsigned char *src) { @@ -49,7 +49,7 @@ static inline void cpMacAddr(unsigned char *des, unsigned char *src) #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) @@ -66,9 +66,10 @@ static inline void cpMacAddr(unsigned char *des, unsigned char *src) (__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) diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h index 82bc59a8be05..6d7963e5b6ae 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h @@ -25,7 +25,6 @@ #define IEEE80211_H #include /* ETH_ALEN */ #include /* ARRAY_SIZE */ -#include #include #include #include diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c index ae5037918904..61fd4ced4524 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c @@ -12,7 +12,6 @@ */ //#include -#include #include #include #include diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c index 9b8533f2fcbb..48267a058d1d 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c @@ -10,7 +10,6 @@ */ //#include -#include #include #include #include diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c index b32b7e67f688..ed623a911e4b 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c @@ -10,7 +10,6 @@ */ //#include -#include #include #include #include diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c index e6264727d94d..55043913afc7 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c @@ -9,7 +9,6 @@ * more details. */ -#include #include #include #include diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c index c2901b50dbfe..37a65ff4b12c 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c index ed5a38023094..022086d2a3f7 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c index 7d4cba3a7c12..60e9a09d9330 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #ifdef ENABLE_DOT11D #include "dot11d.h" @@ -778,7 +777,7 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT)) - cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT)); + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); crypt = ieee->crypt[ieee->tx_keyidx]; if (encrypt) diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c index 995346def24f..424dd48da661 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -762,7 +761,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) bytes_per_frag -= IEEE80211_FCS_LEN; - /* Each fragment may need to have room for encryptiong pre/postfix */ + /* Each fragment may need to have room for encryption pre/postfix */ if (encrypt) bytes_per_frag -= crypt->ops->extra_prefix_len + crypt->ops->extra_postfix_len; diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h index 89fe8fc3d6c2..137f66b034bb 100644 --- a/drivers/staging/rtl8192e/r8192E.h +++ b/drivers/staging/rtl8192e/r8192E.h @@ -35,7 +35,6 @@ #include // Necessary because we use the proc fs #include #include -#include #include #include #include "ieee80211/rtl819x_HT.h" diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index 8550794c6b91..94d9c8d5d090 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -4532,6 +4532,7 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, u8 unit = 0; int ret = -ENODEV; unsigned long pmem_start, pmem_len, pmem_flags; + u8 revisionid; RT_TRACE(COMP_INIT,"Configuring chip resources\n"); @@ -4592,6 +4593,11 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, pci_write_config_byte(pdev, 0x41, 0x00); + pci_read_config_byte(pdev, 0x08, &revisionid); + /* If the revisionid is 0x10, the device uses rtl8192se. */ + if (pdev->device == 0x8192 && revisionid == 0x10) + goto fail1; + pci_read_config_byte(pdev, 0x05, &unit); pci_write_config_byte(pdev, 0x05, unit & (~0x04)); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 23332571c3cf..463cc2618904 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -25,7 +25,6 @@ #define IEEE80211_H #include /* ETH_ALEN */ #include /* ARRAY_SIZE */ -#include #include #include #include diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c index 8707eba4f905..a464d111d738 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt.c @@ -12,7 +12,6 @@ */ //#include -#include #include #include #include diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c index 4b078e536382..fec0176888e2 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_ccmp.c @@ -10,7 +10,6 @@ */ //#include -#include #include #include #include diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c index a98584c845b8..555eb8038e95 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_tkip.c @@ -10,7 +10,6 @@ */ //#include -#include #include #include #include diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c index 96c2c9d67fd1..3801f125f8f2 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_crypt_wep.c @@ -10,7 +10,6 @@ */ //#include -#include #include #include #include diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c index d315b256b7a7..e3d47bcf4cab 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_module.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index a414303aef54..c9bdc7f6bdce 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 4ec0a6520ddc..b00eb0e65f33 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "dot11d.h" @@ -777,7 +776,7 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT)) - cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT)); + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); crypt = ieee->crypt[ieee->tx_keyidx]; if (encrypt) @@ -2726,11 +2725,7 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) ieee->beacon_timer.data = (unsigned long) ieee; ieee->beacon_timer.function = ieee80211_send_beacon_cb; -#ifdef PF_SYNCTHREAD - ieee->wq = create_workqueue(DRV_NAME,0); -#else ieee->wq = create_workqueue(DRV_NAME); -#endif INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq); INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c index ec7845ecdb7e..59c45a510efb 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c @@ -723,7 +723,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) bytes_per_frag -= IEEE80211_FCS_LEN; - /* Each fragment may need to have room for encryptiong pre/postfix */ + /* Each fragment may need to have room for encryption pre/postfix */ if (encrypt) bytes_per_frag -= crypt->ops->extra_prefix_len + crypt->ops->extra_postfix_len; diff --git a/drivers/staging/rtl8192u/r8192U.h b/drivers/staging/rtl8192u/r8192U.h index 0205079b13e9..9b81f26d40fe 100644 --- a/drivers/staging/rtl8192u/r8192U.h +++ b/drivers/staging/rtl8192u/r8192U.h @@ -37,7 +37,6 @@ #include // Necessary because we use the proc fs #include #include -#include #include #include "ieee80211/ieee80211.h" diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 6a1b5c179027..ee86fe8509ed 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -2850,11 +2850,7 @@ static void rtl8192_init_priv_task(struct net_device* dev) { struct r8192_priv *priv = ieee80211_priv(dev); -#ifdef PF_SYNCTHREAD - priv->priv_wq = create_workqueue(DRV_NAME,0); -#else priv->priv_wq = create_workqueue(DRV_NAME); -#endif INIT_WORK(&priv->reset_wq, rtl8192_restart); diff --git a/drivers/staging/rtl8712/ieee80211.h b/drivers/staging/rtl8712/ieee80211.h index 1f4d147c4b68..d62c6ac09550 100644 --- a/drivers/staging/rtl8712/ieee80211.h +++ b/drivers/staging/rtl8712/ieee80211.h @@ -4,6 +4,7 @@ #include "osdep_service.h" #include "drv_types.h" #include "wifi.h" +#include #include #define MGMT_QUEUE_NUM 5 @@ -123,7 +124,7 @@ struct ieee80211_hdr { u8 addr3[ETH_ALEN]; u16 seq_ctl; u8 addr4[ETH_ALEN]; -} __attribute__ ((packed)); +} __packed; struct ieee80211_hdr_3addr { u16 frame_ctl; @@ -132,7 +133,7 @@ struct ieee80211_hdr_3addr { u8 addr2[ETH_ALEN]; u8 addr3[ETH_ALEN]; u16 seq_ctl; -} __attribute__ ((packed)); +} __packed; struct ieee80211_hdr_qos { @@ -144,7 +145,7 @@ struct ieee80211_hdr_qos { u16 seq_ctl; u8 addr4[ETH_ALEN]; u16 qc; -} __attribute__ ((packed)); +} __packed; struct ieee80211_hdr_3addr_qos { u16 frame_ctl; @@ -154,7 +155,7 @@ struct ieee80211_hdr_3addr_qos { u8 addr3[ETH_ALEN]; u16 seq_ctl; u16 qc; -} __attribute__ ((packed)); +} __packed; struct eapol { u8 snap[6]; @@ -162,7 +163,7 @@ struct eapol { u8 version; u8 type; u16 length; -} __attribute__ ((packed)); +} __packed; enum eap_type { @@ -260,7 +261,7 @@ struct ieee80211_snap_hdr { u8 ssap; /* always 0xAA */ u8 ctrl; /* always 0x03 */ u8 oui[P80211_OUI_LEN]; /* organizational universal id */ -} __attribute__ ((packed)); +} __packed; #define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) @@ -510,7 +511,7 @@ struct ieee80211_security { u8 keys[WEP_KEYS][WEP_KEY_LEN]; u8 level; u16 flags; -} __attribute__ ((packed)); +} __packed; /* @@ -555,13 +556,13 @@ struct ieee80211_header_data { struct ieee80211_info_element_hdr { u8 id; u8 len; -} __attribute__ ((packed)); +} __packed; struct ieee80211_info_element { u8 id; u8 len; u8 data[0]; -} __attribute__ ((packed)); +} __packed; /* * These are the data types that can make up management packets @@ -574,7 +575,7 @@ struct ieee80211_info_element { u16 listen_interval; struct { u16 association_id:14, reserved:2; - } __attribute__ ((packed)); + } __packed; u32 time_stamp[2]; u16 reason; u16 status; @@ -588,7 +589,7 @@ struct ieee80211_authentication { u16 algorithm; u16 transaction; u16 status; -} __attribute__ ((packed)); +} __packed; struct ieee80211_probe_response { struct ieee80211_header_data header; @@ -596,25 +597,25 @@ struct ieee80211_probe_response { u16 beacon_interval; u16 capability; struct ieee80211_info_element info_element; -} __attribute__ ((packed)); +} __packed; struct ieee80211_probe_request { struct ieee80211_header_data header; -} __attribute__ ((packed)); +} __packed; struct ieee80211_assoc_request_frame { struct ieee80211_hdr_3addr header; u16 capability; u16 listen_interval; struct ieee80211_info_element_hdr info_element; -} __attribute__ ((packed)); +} __packed; struct ieee80211_assoc_response_frame { struct ieee80211_hdr_3addr header; u16 capability; u16 status; u16 aid; -} __attribute__ ((packed)); +} __packed; struct ieee80211_txb { u8 nr_frags; diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h index 505395cff282..c683d7609e6c 100644 --- a/drivers/staging/rtl8712/osdep_service.h +++ b/drivers/staging/rtl8712/osdep_service.h @@ -5,9 +5,7 @@ #define _FAIL 0 #include "basic_types.h" -#include #include - #include #include #include @@ -29,7 +27,7 @@ #include #include #include -#include +#include #include #include #include "ethernet.h" @@ -235,7 +233,5 @@ static inline u32 _RND512(u32 sz) return ((sz >> 9) + ((sz & 511) ? 1 : 0)) << 9; } -#define STRUCT_PACKED __attribute__ ((packed)) - #endif diff --git a/drivers/staging/rtl8712/rtl8712_hal.h b/drivers/staging/rtl8712/rtl8712_hal.h index 66baa87cd4b0..c696dd8a2ea4 100644 --- a/drivers/staging/rtl8712/rtl8712_hal.h +++ b/drivers/staging/rtl8712/rtl8712_hal.h @@ -113,7 +113,7 @@ struct fw_hdr {/*8-byte alinment required*/ struct fw_priv fwpriv; }; -struct hal_priv{ +struct hal_priv { /*Endpoint handles*/ struct net_device *pipehdls_r8712[10]; u8 (*hal_bus_init)(struct _adapter *adapter); diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h index 6032cdc65394..427ab7e27050 100644 --- a/drivers/staging/rtl8712/wifi.h +++ b/drivers/staging/rtl8712/wifi.h @@ -2,6 +2,7 @@ #define _WIFI_H_ #include "rtl871x_byteorder.h" +#include #ifdef BIT #undef BIT @@ -523,7 +524,7 @@ struct ieee80211_bar { unsigned char ta[6]; unsigned short control; unsigned short start_seq_num; -} __attribute__((packed)); +} __packed; /* 802.11 BAR control masks */ #define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000 @@ -544,7 +545,7 @@ struct ieee80211_ht_cap { unsigned short extended_ht_cap_info; unsigned int tx_BF_cap_info; unsigned char antenna_selection_info; -} __attribute__ ((packed)); +} __packed; /** * struct ieee80211_ht_cap - HT additional information @@ -558,7 +559,7 @@ struct ieee80211_ht_addt_info { unsigned short operation_mode; unsigned short stbc_param; unsigned char basic_set[16]; -} __attribute__ ((packed)); +} __packed; /* 802.11n HT capabilities masks */ #define IEEE80211_HT_CAP_SUP_WIDTH 0x0002 diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c index 2e8258754c96..66341dff8c99 100644 --- a/drivers/staging/rts_pstor/ms.c +++ b/drivers/staging/rts_pstor/ms.c @@ -2064,11 +2064,10 @@ static int ms_init_l2p_tbl(struct rtsx_chip *chip) RTSX_DEBUGP("ms_card->segment_cnt = %d\n", ms_card->segment_cnt); size = ms_card->segment_cnt * sizeof(struct zone_entry); - ms_card->segment = (struct zone_entry *)vmalloc(size); + ms_card->segment = vzalloc(size); if (ms_card->segment == NULL) { TRACE_RET(chip, STATUS_FAIL); } - memset(ms_card->segment, 0, size); retval = ms_read_page(chip, ms_card->boot_block, 1); if (retval != STATUS_SUCCESS) { diff --git a/drivers/staging/rts_pstor/rtsx.h b/drivers/staging/rts_pstor/rtsx.h index 6afb6358e775..247615ba1d2a 100644 --- a/drivers/staging/rts_pstor/rtsx.h +++ b/drivers/staging/rts_pstor/rtsx.h @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/rts_pstor/rtsx_chip.c b/drivers/staging/rts_pstor/rtsx_chip.c index 4e60780ea804..5452069fbe08 100644 --- a/drivers/staging/rts_pstor/rtsx_chip.c +++ b/drivers/staging/rts_pstor/rtsx_chip.c @@ -1596,18 +1596,16 @@ int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int l } RTSX_DEBUGP("dw_len = %d\n", dw_len); - data = (u32 *)vmalloc(dw_len * 4); + data = vzalloc(dw_len * 4); if (!data) { TRACE_RET(chip, STATUS_NOMEM); } - memset(data, 0, dw_len * 4); - mask = (u32 *)vmalloc(dw_len * 4); + mask = vzalloc(dw_len * 4); if (!mask) { vfree(data); TRACE_RET(chip, STATUS_NOMEM); } - memset(mask, 0, dw_len * 4); j = 0; for (i = 0; i < len; i++) { diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index cdae497d5467..8db14ddbeb7b 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -2661,7 +2661,7 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) retval = sd_send_cmd_get_rsp(chip, BUSTEST_W, 0, SD_RSP_TYPE_R1, NULL, 0); if (retval != STATUS_SUCCESS) { - TRACE_RET(chip, STATUS_FAIL); + TRACE_RET(chip, SWITCH_FAIL); } if (width == MMC_8BIT_BUS) { @@ -2678,7 +2678,9 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) } if (!CHECK_PID(chip, 0x5209)) { - RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x02, 0x02); + retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0x02); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, SWITCH_ERR); } retval = sd_write_data(chip, SD_TM_AUTO_WRITE_3, @@ -2690,17 +2692,19 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) rtsx_read_register(chip, REG_SD_STAT2, &val2); rtsx_clear_sd_error(chip); if ((val1 & 0xE0) || val2) { - TRACE_RET(chip, STATUS_FAIL); + TRACE_RET(chip, SWITCH_ERR); } } else { rtsx_clear_sd_error(chip); rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0); - TRACE_RET(chip, STATUS_FAIL); + TRACE_RET(chip, SWITCH_ERR); } } if (!CHECK_PID(chip, 0x5209)) { - RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x02, 0); + retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, SWITCH_ERR); } RTSX_DEBUGP("SD/MMC CMD %d\n", BUSTEST_R); @@ -2733,7 +2737,7 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) retval = rtsx_send_cmd(chip, SD_CARD, 100); if (retval < 0) { rtsx_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); + TRACE_RET(chip, SWITCH_ERR); } ptr = rtsx_get_cmd_data(chip) + 1; @@ -2751,7 +2755,7 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) } retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, SD_RSP_TYPE_R1b, rsp, 5); if ((retval == STATUS_SUCCESS) && !(rsp[4] & MMC_SWITCH_ERR)) { - return STATUS_SUCCESS; + return SWITCH_SUCCESS; } } } else { @@ -2767,12 +2771,12 @@ static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) } retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, SD_RSP_TYPE_R1b, rsp, 5); if ((retval == STATUS_SUCCESS) && !(rsp[4] & MMC_SWITCH_ERR)) { - return STATUS_SUCCESS; + return SWITCH_SUCCESS; } } } - TRACE_RET(chip, STATUS_FAIL); + TRACE_RET(chip, SWITCH_FAIL); } @@ -2880,21 +2884,30 @@ static int mmc_switch_timing_bus(struct rtsx_chip *chip, int switch_ddr) TRACE_RET(chip, STATUS_FAIL); } - if (mmc_test_switch_bus(chip, MMC_8BIT_BUS) == STATUS_SUCCESS) { + /* Test Bus Procedure */ + retval = mmc_test_switch_bus(chip, MMC_8BIT_BUS); + if (retval == SWITCH_SUCCESS) { SET_MMC_8BIT(sd_card); chip->card_bus_width[chip->card2lun[SD_CARD]] = 8; #ifdef SUPPORT_SD_LOCK sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; #endif - } else if (mmc_test_switch_bus(chip, MMC_4BIT_BUS) == STATUS_SUCCESS) { - SET_MMC_4BIT(sd_card); - chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; + } else if (retval == SWITCH_FAIL) { + retval = mmc_test_switch_bus(chip, MMC_4BIT_BUS); + if (retval == SWITCH_SUCCESS) { + SET_MMC_4BIT(sd_card); + chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; #ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; + sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; #endif + } else if (retval == SWITCH_FAIL) { + CLR_MMC_8BIT(sd_card); + CLR_MMC_4BIT(sd_card); + } else { + TRACE_RET(chip, STATUS_FAIL); + } } else { - CLR_MMC_8BIT(sd_card); - CLR_MMC_4BIT(sd_card); + TRACE_RET(chip, STATUS_FAIL); } return STATUS_SUCCESS; @@ -2915,8 +2928,7 @@ static int reset_mmc(struct rtsx_chip *chip) goto MMC_UNLOCK_ENTRY; #endif -DDR_TUNING_FAIL: - +Switch_Fail: retval = sd_prepare_reset(chip); if (retval != STATUS_SUCCESS) { TRACE_RET(chip, retval); @@ -3017,7 +3029,15 @@ static int reset_mmc(struct rtsx_chip *chip) if (!sd_card->mmc_dont_switch_bus) { if (spec_ver == 4) { - (void)mmc_switch_timing_bus(chip, switch_ddr); + /* MMC 4.x Cards */ + retval = mmc_switch_timing_bus(chip, switch_ddr); + if (retval != STATUS_SUCCESS) { + retval = sd_init_power(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + sd_card->mmc_dont_switch_bus = 1; + TRACE_GOTO(chip, Switch_Fail); + } } if (CHK_MMC_SECTOR_MODE(sd_card) && (sd_card->capacity == 0)) { @@ -3037,7 +3057,7 @@ static int reset_mmc(struct rtsx_chip *chip) TRACE_RET(chip, STATUS_FAIL); } switch_ddr = 0; - goto DDR_TUNING_FAIL; + TRACE_GOTO(chip, Switch_Fail); } retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); @@ -3049,7 +3069,7 @@ static int reset_mmc(struct rtsx_chip *chip) TRACE_RET(chip, STATUS_FAIL); } switch_ddr = 0; - goto DDR_TUNING_FAIL; + TRACE_GOTO(chip, Switch_Fail); } } } @@ -3727,7 +3747,7 @@ int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, if ((ptr[3] & 0x1E) != 0x04) { TRACE_RET(chip, STATUS_FAIL); } - } else if (rsp_type == SD_RSP_TYPE_R2) { + } else if (rsp_type == SD_RSP_TYPE_R0) { if ((ptr[3] & 0x1E) != 0x03) { TRACE_RET(chip, STATUS_FAIL); } diff --git a/drivers/staging/rts_pstor/sd.h b/drivers/staging/rts_pstor/sd.h index d62e690e963f..1df1aa75e93a 100644 --- a/drivers/staging/rts_pstor/sd.h +++ b/drivers/staging/rts_pstor/sd.h @@ -38,6 +38,11 @@ #define SD_RSP_TIMEOUT 0x04 #define SD_IO_ERR 0x02 +/* Return code for MMC switch bus */ +#define SWITCH_SUCCESS 0 +#define SWITCH_ERR 1 +#define SWITCH_FAIL 2 + /* MMC/SD Command Index */ /* Basic command (class 0) */ #define GO_IDLE_STATE 0 diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 848b4c57531d..bf7286e01a39 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -200,7 +200,7 @@ static int sep_singleton_release(struct inode *inode, struct file *filp) } /** - * sep_request_daemonopen - request daemon open method + * sep_request_daemon_open - request daemon open method * @inode: inode of SEP device * @filp: file handle to SEP device * @@ -1101,9 +1101,9 @@ static int sep_lock_user_pages(struct sep_device *sep, "lli_array[%x].bus_address is " "%08lx, lli_array[%x].block_size is %x\n", num_pages - 1, - (unsigned long)lli_array[num_pages -1].bus_address, + (unsigned long)lli_array[num_pages - 1].bus_address, num_pages - 1, - lli_array[num_pages -1].block_size); + lli_array[num_pages - 1].block_size); } /* Set output params according to the in_out flag */ diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index 1033425c9c30..d6bfd2455222 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -180,7 +180,7 @@ held by the process (struct file) */ /* offset of the caller id area */ #define SEP_CALLER_ID_OFFSET_BYTES \ (SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES + \ - SEP_DRIVER_SYSTEM_RAR_MEMORY_SIZE_IN_BYTES) + SEP_DRIVER_SYSTEM_RAR_MEMORY_SIZE_IN_BYTES) /* offset of the DCB area */ #define SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES \ diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 42fcf7e9cb64..8be560458977 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -23,7 +23,6 @@ */ #include -#include #include #include #include /* __get_free_page() and friends */ diff --git a/drivers/staging/speakup/speakup.h b/drivers/staging/speakup/speakup.h index 46edabe2d32c..412b87947f66 100644 --- a/drivers/staging/speakup/speakup.h +++ b/drivers/staging/speakup/speakup.h @@ -1,6 +1,5 @@ #ifndef _SPEAKUP_H #define _SPEAKUP_H -#include #include "spk_types.h" #include "i18n.h" diff --git a/drivers/staging/speakup/speakup_soft.c b/drivers/staging/speakup/speakup_soft.c index a2c3dc4098b9..42cdafeea35e 100644 --- a/drivers/staging/speakup/speakup_soft.c +++ b/drivers/staging/speakup/speakup_soft.c @@ -273,15 +273,8 @@ static ssize_t softsynth_write(struct file *fp, const char *buf, size_t count, { unsigned long supplied_index = 0; int converted; - char indbuf[5]; - if (count >= sizeof(indbuf)) - return -EINVAL; - if (copy_from_user(indbuf, buf, count)) - return -EFAULT; - indbuf[count] = '\0'; - - converted = strict_strtoul(indbuf, 0, &supplied_index); + converted = kstrtoul_from_user(buf, count, 0, &supplied_index); if (converted < 0) return converted; diff --git a/drivers/staging/spectra/lld_nand.c b/drivers/staging/spectra/lld_nand.c index 0be7adc96b8c..60a14ff26c7f 100644 --- a/drivers/staging/spectra/lld_nand.c +++ b/drivers/staging/spectra/lld_nand.c @@ -2397,6 +2397,12 @@ static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) struct mrst_nand_info *pndev = &info; u32 int_mask; + ret = pci_enable_device(dev); + if (ret) { + printk(KERN_ERR "Spectra: pci_enable_device failed.\n"); + return ret; + } + nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n", __FILE__, __LINE__, __func__); @@ -2404,7 +2410,7 @@ static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) GLOB_HWCTL_REG_SIZE); if (!FlashReg) { printk(KERN_ERR "Spectra: ioremap_nocache failed!"); - return -ENOMEM; + goto failed_disable; } nand_dbg_print(NAND_DBG_WARN, "Spectra: Remapped reg base address: " @@ -2416,7 +2422,7 @@ static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) if (!FlashMem) { printk(KERN_ERR "Spectra: ioremap_nocache failed!"); iounmap(FlashReg); - return -ENOMEM; + goto failed_disable; } nand_dbg_print(NAND_DBG_WARN, "Spectra: Remapped flash base address: " @@ -2479,11 +2485,6 @@ static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) iowrite32(0, FlashReg + TWO_ROW_ADDR_CYCLES); iowrite32(1, FlashReg + ECC_ENABLE); enable_ecc = 1; - ret = pci_enable_device(dev); - if (ret) { - printk(KERN_ERR "Spectra: pci_enable_device failed.\n"); - goto failed_req_csr; - } pci_set_master(dev); pndev->dev = dev; @@ -2558,9 +2559,10 @@ static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) failed_remap_csr: pci_release_regions(dev); failed_req_csr: - pci_disable_device(dev); iounmap(FlashMem); iounmap(FlashReg); +failed_disable: + pci_disable_device(dev); return ret; } diff --git a/drivers/staging/ste_rmi4/Makefile b/drivers/staging/ste_rmi4/Makefile index 6cce2ed187ef..176f46900571 100644 --- a/drivers/staging/ste_rmi4/Makefile +++ b/drivers/staging/ste_rmi4/Makefile @@ -2,3 +2,4 @@ # Makefile for the RMI4 touchscreen driver. # obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += synaptics_i2c_rmi4.o +obj-$(CONFIG_MACH_U8500) += board-mop500-u8500uib-rmi4.o diff --git a/drivers/staging/ste_rmi4/board-mop500-u8500uib-rmi4.c b/drivers/staging/ste_rmi4/board-mop500-u8500uib-rmi4.c new file mode 100644 index 000000000000..a272e488e5b9 --- /dev/null +++ b/drivers/staging/ste_rmi4/board-mop500-u8500uib-rmi4.c @@ -0,0 +1,32 @@ +/* + * Some platform data for the RMI4 touchscreen that will override the __weak + * platform data in the Ux500 machine if this driver is activated. + */ +#include +#include +#include +#include +#include +#include "synaptics_i2c_rmi4.h" + +/* + * Synaptics RMI4 touchscreen interface on the U8500 UIB + */ + +/* + * Descriptor structure. + * Describes the number of i2c devices on the bus that speak RMI. + */ +static struct synaptics_rmi4_platform_data rmi4_i2c_dev_platformdata = { + .irq_number = NOMADIK_GPIO_TO_IRQ(84), + .irq_type = (IRQF_TRIGGER_FALLING | IRQF_SHARED), + .x_flip = false, + .y_flip = true, +}; + +struct i2c_board_info __initdata mop500_i2c3_devices_u8500[] = { + { + I2C_BOARD_INFO("synaptics_rmi4_i2c", 0x4B), + .platform_data = &rmi4_i2c_dev_platformdata, + }, +}; diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c index 3e68d58fdffd..36f4cb77567c 100644 --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c @@ -926,17 +926,19 @@ static int __devinit synaptics_rmi4_probe goto err_input; } - if (platformdata->regulator_en) { - rmi4_data->regulator = regulator_get(&client->dev, "vdd"); - if (IS_ERR(rmi4_data->regulator)) { - dev_err(&client->dev, "%s:get regulator failed\n", - __func__); - retval = PTR_ERR(rmi4_data->regulator); - goto err_regulator; - } - regulator_enable(rmi4_data->regulator); + rmi4_data->regulator = regulator_get(&client->dev, "vdd"); + if (IS_ERR(rmi4_data->regulator)) { + dev_err(&client->dev, "%s:get regulator failed\n", + __func__); + retval = PTR_ERR(rmi4_data->regulator); + goto err_get_regulator; + } + retval = regulator_enable(rmi4_data->regulator); + if (retval < 0) { + dev_err(&client->dev, "%s:regulator enable failed\n", + __func__); + goto err_regulator_enable; } - init_waitqueue_head(&rmi4_data->wait); /* * Copy i2c_client pointer into RTID's i2c_client pointer for @@ -1011,11 +1013,10 @@ static int __devinit synaptics_rmi4_probe err_free_irq: free_irq(platformdata->irq_number, rmi4_data); err_query_dev: - if (platformdata->regulator_en) { - regulator_disable(rmi4_data->regulator); - regulator_put(rmi4_data->regulator); - } -err_regulator: + regulator_disable(rmi4_data->regulator); +err_regulator_enable: + regulator_put(rmi4_data->regulator); +err_get_regulator: input_free_device(rmi4_data->input_dev); rmi4_data->input_dev = NULL; err_input: @@ -1039,10 +1040,8 @@ static int __devexit synaptics_rmi4_remove(struct i2c_client *client) wake_up(&rmi4_data->wait); free_irq(pdata->irq_number, rmi4_data); input_unregister_device(rmi4_data->input_dev); - if (pdata->regulator_en) { - regulator_disable(rmi4_data->regulator); - regulator_put(rmi4_data->regulator); - } + regulator_disable(rmi4_data->regulator); + regulator_put(rmi4_data->regulator); kfree(rmi4_data); return 0; @@ -1080,8 +1079,7 @@ static int synaptics_rmi4_suspend(struct device *dev) if (retval < 0) return retval; - if (pdata->regulator_en) - regulator_disable(rmi4_data->regulator); + regulator_disable(rmi4_data->regulator); return 0; } @@ -1099,8 +1097,7 @@ static int synaptics_rmi4_resume(struct device *dev) struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); const struct synaptics_rmi4_platform_data *pdata = rmi4_data->board; - if (pdata->regulator_en) - regulator_enable(rmi4_data->regulator); + regulator_enable(rmi4_data->regulator); enable_irq(pdata->irq_number); rmi4_data->touch_stopped = false; diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h index 3686a2ff5964..384436ef8068 100644 --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h @@ -34,7 +34,6 @@ * @irq_type: irq type * @x flip: x flip flag * @y flip: y flip flag - * @regulator_en: regulator enable flag * * This structure gives platform data for rmi4. */ @@ -43,7 +42,6 @@ struct synaptics_rmi4_platform_data { int irq_type; bool x_flip; bool y_flip; - bool regulator_en; }; #endif diff --git a/drivers/staging/tidspbridge/include/dspbridge/host_os.h b/drivers/staging/tidspbridge/include/dspbridge/host_os.h index b1b8acb5d3c3..1a38896f4331 100644 --- a/drivers/staging/tidspbridge/include/dspbridge/host_os.h +++ b/drivers/staging/tidspbridge/include/dspbridge/host_os.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c index 2b96047c2983..ddfd7c33361b 100644 --- a/drivers/staging/tm6000/tm6000-alsa.c +++ b/drivers/staging/tm6000/tm6000-alsa.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include @@ -255,7 +255,7 @@ static int tm6000_fillbuf(struct tm6000_core *core, char *buf, int size) length * stride); #ifndef NO_PCM_LOCK - snd_pcm_stream_lock(substream); + snd_pcm_stream_lock(substream); #endif chip->buf_pos += length; @@ -269,7 +269,7 @@ static int tm6000_fillbuf(struct tm6000_core *core, char *buf, int size) } #ifndef NO_PCM_LOCK - snd_pcm_stream_unlock(substream); + snd_pcm_stream_unlock(substream); #endif if (period_elapsed) @@ -461,7 +461,7 @@ int tm6000_audio_init(struct tm6000_core *dev) if (rc < 0) goto error_chip; - dprintk(1,"Registered audio driver for %s\n", card->longname); + dprintk(1, "Registered audio driver for %s\n", card->longname); return 0; diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c index a69c82e11991..9227db5d8955 100644 --- a/drivers/staging/tm6000/tm6000-cards.c +++ b/drivers/staging/tm6000/tm6000-cards.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -994,11 +993,7 @@ static int fill_board_specific_data(struct tm6000_core *dev) if (rc < 0) return rc; - rc = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev); - if (rc < 0) - return rc; - - return rc; + return v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev); } diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c index ff04c89e45a3..0e0dfce05821 100644 --- a/drivers/staging/tm6000/tm6000-dvb.c +++ b/drivers/staging/tm6000/tm6000-dvb.c @@ -98,7 +98,7 @@ static void tm6000_urb_received(struct urb *urb) if (dev->dvb->streams > 0) { ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret < 0) { - printk(KERN_ERR "tm6000: error %s\n", __FUNCTION__); + printk(KERN_ERR "tm6000: error %s\n", __func__); kfree(urb->transfer_buffer); usb_free_urb(urb); } @@ -111,7 +111,7 @@ int tm6000_start_stream(struct tm6000_core *dev) unsigned int pipe, size; struct tm6000_dvb *dvb = dev->dvb; - printk(KERN_INFO "tm6000: got start stream request %s\n", __FUNCTION__); + printk(KERN_INFO "tm6000: got start stream request %s\n", __func__); if (dev->mode != TM6000_MODE_DIGITAL) { tm6000_init_digital_mode(dev); @@ -145,7 +145,7 @@ int tm6000_start_stream(struct tm6000_core *dev) ret = usb_clear_halt(dev->udev, pipe); if (ret < 0) { printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n", - ret, __FUNCTION__); + ret, __func__); return ret; } else printk(KERN_ERR "tm6000: pipe resetted\n"); @@ -185,7 +185,7 @@ int tm6000_start_feed(struct dvb_demux_feed *feed) struct dvb_demux *demux = feed->demux; struct tm6000_core *dev = demux->priv; struct tm6000_dvb *dvb = dev->dvb; - printk(KERN_INFO "tm6000: got start feed request %s\n", __FUNCTION__); + printk(KERN_INFO "tm6000: got start feed request %s\n", __func__); mutex_lock(&dvb->mutex); if (dvb->streams == 0) { @@ -205,7 +205,7 @@ int tm6000_stop_feed(struct dvb_demux_feed *feed) struct tm6000_core *dev = demux->priv; struct tm6000_dvb *dvb = dev->dvb; - printk(KERN_INFO "tm6000: got stop feed request %s\n", __FUNCTION__); + printk(KERN_INFO "tm6000: got stop feed request %s\n", __func__); mutex_lock(&dvb->mutex); diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c index 8828c120b5ca..5a651ea5f60a 100644 --- a/drivers/staging/tm6000/tm6000-i2c.c +++ b/drivers/staging/tm6000/tm6000-i2c.c @@ -40,7 +40,7 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); #define i2c_dprintk(lvl, fmt, args...) if (i2c_debug >= lvl) do { \ printk(KERN_DEBUG "%s at %s: " fmt, \ - dev->name, __FUNCTION__ , ##args); } while (0) + dev->name, __func__, ##args); } while (0) static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, __u8 reg, char *buf, int len) diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c index dae2f1fdcc5b..70a2c5f557c1 100644 --- a/drivers/staging/tm6000/tm6000-input.c +++ b/drivers/staging/tm6000/tm6000-input.c @@ -449,9 +449,8 @@ int tm6000_ir_fini(struct tm6000_core *dev) rc_unregister_device(ir->rc); - if (ir->int_urb) { + if (ir->int_urb) tm6000_ir_int_stop(dev); - } kfree(ir); dev->ir = NULL; diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c index 4264064a727e..8d8b939915d8 100644 --- a/drivers/staging/tm6000/tm6000-video.c +++ b/drivers/staging/tm6000/tm6000-video.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -180,9 +179,6 @@ static inline void get_next_buf(struct tm6000_dmaqueue *dma_q, *buf = list_entry(dma_q->active.next, struct tm6000_buffer, vb.queue); - if (!buf) - return; - /* Cleans up buffer - Useful for testing for frame/URB loss */ outp = videobuf_to_vmalloc(&(*buf)->vb); @@ -777,7 +773,8 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, } if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - if (0 != (rc = videobuf_iolock(vq, &buf->vb, NULL))) + rc = videobuf_iolock(vq, &buf->vb, NULL); + if (rc != 0) goto fail; urb_init = 1; } @@ -1048,12 +1045,12 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) if (!res_get(dev, fh, false)) return -EBUSY; - return (videobuf_streamon(&fh->vb_vidq)); + return videobuf_streamon(&fh->vb_vidq); } static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) { - struct tm6000_fh *fh=priv; + struct tm6000_fh *fh = priv; struct tm6000_core *dev = fh->dev; if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) @@ -1062,15 +1059,15 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) return -EINVAL; videobuf_streamoff(&fh->vb_vidq); - res_free(dev,fh); + res_free(dev, fh); - return (0); + return 0; } -static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm) +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) { - int rc=0; - struct tm6000_fh *fh=priv; + int rc = 0; + struct tm6000_fh *fh = priv; struct tm6000_core *dev = fh->dev; dev->norm = *norm; @@ -1079,7 +1076,7 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm) fh->width = dev->width; fh->height = dev->height; - if (rc<0) + if (rc < 0) return rc; v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); @@ -1087,7 +1084,7 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm) return 0; } -static const char *iname [] = { +static const char *iname[] = { [TM6000_INPUT_TV] = "Television", [TM6000_INPUT_COMPOSITE1] = "Composite 1", [TM6000_INPUT_COMPOSITE2] = "Composite 2", @@ -1394,10 +1391,10 @@ static int radio_g_input(struct file *filp, void *priv, unsigned int *i) struct tm6000_fh *fh = priv; struct tm6000_core *dev = fh->dev; - if (dev->input !=5) + if (dev->input != 5) return -EINVAL; - *i = dev->input -5; + *i = dev->input - 5; return 0; } @@ -1508,18 +1505,18 @@ static int tm6000_open(struct file *file) fh->fmt = format_by_fourcc(dev->fourcc); - tm6000_get_std_res (dev); + tm6000_get_std_res(dev); fh->width = dev->width; fh->height = dev->height; dprintk(dev, V4L2_DEBUG_OPEN, "Open: fh=0x%08lx, dev=0x%08lx, " "dev->vidq=0x%08lx\n", - (unsigned long)fh,(unsigned long)dev,(unsigned long)&dev->vidq); + (unsigned long)fh, (unsigned long)dev, (unsigned long)&dev->vidq); dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty " - "queued=%d\n",list_empty(&dev->vidq.queued)); + "queued=%d\n", list_empty(&dev->vidq.queued)); dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty " - "active=%d\n",list_empty(&dev->vidq.active)); + "active=%d\n", list_empty(&dev->vidq.active)); /* initialize hardware on analog mode */ rc = tm6000_init_analog_mode(dev); @@ -1557,7 +1554,7 @@ tm6000_read(struct file *file, char __user *data, size_t count, loff_t *pos) { struct tm6000_fh *fh = file->private_data; - if (fh->type==V4L2_BUF_TYPE_VIDEO_CAPTURE) { + if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { if (!res_get(fh->dev, fh, true)) return -EBUSY; @@ -1583,7 +1580,7 @@ tm6000_poll(struct file *file, struct poll_table_struct *wait) /* streaming capture */ if (list_empty(&fh->vb_vidq.stream)) return POLLERR; - buf = list_entry(fh->vb_vidq.stream.next,struct tm6000_buffer,vb.stream); + buf = list_entry(fh->vb_vidq.stream.next, struct tm6000_buffer, vb.stream); } else { /* read() capture */ return videobuf_poll_stream(file, &fh->vb_vidq, @@ -1699,7 +1696,7 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { struct video_device tm6000_radio_template = { .name = "tm6000", .fops = &radio_fops, - .ioctl_ops = &radio_ioctl_ops, + .ioctl_ops = &radio_ioctl_ops, }; /* ----------------------------------------------------------------- diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h index ae6369b9a90c..c56da628dbef 100644 --- a/drivers/staging/tm6000/tm6000.h +++ b/drivers/staging/tm6000/tm6000.h @@ -30,8 +30,7 @@ #include #include #include - - +#include #include #include "dvb_demux.h" #include "dvb_frontend.h" diff --git a/drivers/staging/tty/Kconfig b/drivers/staging/tty/Kconfig deleted file mode 100644 index 77103a07abbd..000000000000 --- a/drivers/staging/tty/Kconfig +++ /dev/null @@ -1,87 +0,0 @@ -config STALLION - tristate "Stallion EasyIO or EC8/32 support" - depends on STALDRV && (ISA || EISA || PCI) - help - If you have an EasyIO or EasyConnection 8/32 multiport Stallion - card, then this is for you; say Y. Make sure to read - . - - To compile this driver as a module, choose M here: the - module will be called stallion. - -config ISTALLION - tristate "Stallion EC8/64, ONboard, Brumby support" - depends on STALDRV && (ISA || EISA || PCI) - help - If you have an EasyConnection 8/64, ONboard, Brumby or Stallion - serial multiport card, say Y here. Make sure to read - . - - To compile this driver as a module, choose M here: the - module will be called istallion. - -config DIGIEPCA - tristate "Digiboard Intelligent Async Support" - depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) - ---help--- - This is a driver for Digi International's Xx, Xeve, and Xem series - of cards which provide multiple serial ports. You would need - something like this to connect more than two modems to your Linux - box, for instance in order to become a dial-in server. This driver - supports the original PC (ISA) boards as well as PCI, and EISA. If - you have a card like this, say Y here and read the file - . - - To compile this driver as a module, choose M here: the - module will be called epca. - -config RISCOM8 - tristate "SDL RISCom/8 card support" - depends on SERIAL_NONSTANDARD - help - This is a driver for the SDL Communications RISCom/8 multiport card, - which gives you many serial ports. You would need something like - this to connect more than two modems to your Linux box, for instance - in order to become a dial-in server. If you have a card like that, - say Y here and read the file . - - Also it's possible to say M here and compile this driver as kernel - loadable module; the module will be called riscom8. - -config SPECIALIX - tristate "Specialix IO8+ card support" - depends on SERIAL_NONSTANDARD - help - This is a driver for the Specialix IO8+ multiport card (both the - ISA and the PCI version) which gives you many serial ports. You - would need something like this to connect more than two modems to - your Linux box, for instance in order to become a dial-in server. - - If you have a card like that, say Y here and read the file - . Also it's possible to say - M here and compile this driver as kernel loadable module which will be - called specialix. - -config COMPUTONE - tristate "Computone IntelliPort Plus serial support" - depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI) - ---help--- - This driver supports the entire family of Intelliport II/Plus - controllers with the exception of the MicroChannel controllers and - products previous to the Intelliport II. These are multiport cards, - which give you many serial ports. You would need something like this - to connect more than two modems to your Linux box, for instance in - order to become a dial-in server. If you have a card like that, say - Y here and read . - - To compile this driver as module, choose M here: the - module will be called ip2. - -config SERIAL167 - bool "CD2401 support for MVME166/7 serial ports" - depends on MVME16x - help - This is the driver for the serial ports on the Motorola MVME166, - 167, and 172 boards. Everyone using one of these boards should say - Y here. - diff --git a/drivers/staging/tty/Makefile b/drivers/staging/tty/Makefile deleted file mode 100644 index ac57c105611b..000000000000 --- a/drivers/staging/tty/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -obj-$(CONFIG_STALLION) += stallion.o -obj-$(CONFIG_ISTALLION) += istallion.o -obj-$(CONFIG_DIGIEPCA) += epca.o -obj-$(CONFIG_SERIAL167) += serial167.o -obj-$(CONFIG_SPECIALIX) += specialix.o -obj-$(CONFIG_RISCOM8) += riscom8.o -obj-$(CONFIG_COMPUTONE) += ip2/ diff --git a/drivers/staging/tty/TODO b/drivers/staging/tty/TODO deleted file mode 100644 index 88756453ac6c..000000000000 --- a/drivers/staging/tty/TODO +++ /dev/null @@ -1,6 +0,0 @@ -These are a few tty/serial drivers that either do not build, -or work if they do build, or if they seem to work, are for obsolete -hardware, or are full of unfixable races and no one uses them anymore. - -If no one steps up to adopt any of these drivers, they will be removed -in the 2.6.41 release. diff --git a/drivers/staging/tty/cd1865.h b/drivers/staging/tty/cd1865.h deleted file mode 100644 index 8c2ad654b79d..000000000000 --- a/drivers/staging/tty/cd1865.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - * linux/drivers/char/cd1865.h -- Definitions relating to the CD1865 - * for the Specialix IO8+ multiport serial driver. - * - * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) - * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) - * - * Specialix pays for the development and support of this driver. - * Please DO contact io8-linux@specialix.co.uk if you require - * support. - * - * This driver was developed in the BitWizard linux device - * driver service. If you require a linux device driver for your - * product, please contact devices@BitWizard.nl for a quote. - * - */ - -/* - * Definitions for Driving CD180/CD1864/CD1865 based eightport serial cards. - */ - - -/* Values of choice for Interrupt ACKs */ -/* These values are "obligatory" if you use the register based - * interrupt acknowledgements. See page 99-101 of V2.0 of the CD1865 - * databook */ -#define SX_ACK_MINT 0x75 /* goes to PILR1 */ -#define SX_ACK_TINT 0x76 /* goes to PILR2 */ -#define SX_ACK_RINT 0x77 /* goes to PILR3 */ - -/* Chip ID (is used when chips ar daisy chained.) */ -#define SX_ID 0x10 - -/* Definitions for Cirrus Logic CL-CD186x 8-port async mux chip */ - -#define CD186x_NCH 8 /* Total number of channels */ -#define CD186x_TPC 16 /* Ticks per character */ -#define CD186x_NFIFO 8 /* TX FIFO size */ - - -/* Global registers */ - -#define CD186x_GIVR 0x40 /* Global Interrupt Vector Register */ -#define CD186x_GICR 0x41 /* Global Interrupting Channel Register */ -#define CD186x_PILR1 0x61 /* Priority Interrupt Level Register 1 */ -#define CD186x_PILR2 0x62 /* Priority Interrupt Level Register 2 */ -#define CD186x_PILR3 0x63 /* Priority Interrupt Level Register 3 */ -#define CD186x_CAR 0x64 /* Channel Access Register */ -#define CD186x_SRSR 0x65 /* Channel Access Register */ -#define CD186x_GFRCR 0x6b /* Global Firmware Revision Code Register */ -#define CD186x_PPRH 0x70 /* Prescaler Period Register High */ -#define CD186x_PPRL 0x71 /* Prescaler Period Register Low */ -#define CD186x_RDR 0x78 /* Receiver Data Register */ -#define CD186x_RCSR 0x7a /* Receiver Character Status Register */ -#define CD186x_TDR 0x7b /* Transmit Data Register */ -#define CD186x_EOIR 0x7f /* End of Interrupt Register */ -#define CD186x_MRAR 0x75 /* Modem Request Acknowledge register */ -#define CD186x_TRAR 0x76 /* Transmit Request Acknowledge register */ -#define CD186x_RRAR 0x77 /* Receive Request Acknowledge register */ -#define CD186x_SRCR 0x66 /* Service Request Configuration register */ - -/* Channel Registers */ - -#define CD186x_CCR 0x01 /* Channel Command Register */ -#define CD186x_IER 0x02 /* Interrupt Enable Register */ -#define CD186x_COR1 0x03 /* Channel Option Register 1 */ -#define CD186x_COR2 0x04 /* Channel Option Register 2 */ -#define CD186x_COR3 0x05 /* Channel Option Register 3 */ -#define CD186x_CCSR 0x06 /* Channel Control Status Register */ -#define CD186x_RDCR 0x07 /* Receive Data Count Register */ -#define CD186x_SCHR1 0x09 /* Special Character Register 1 */ -#define CD186x_SCHR2 0x0a /* Special Character Register 2 */ -#define CD186x_SCHR3 0x0b /* Special Character Register 3 */ -#define CD186x_SCHR4 0x0c /* Special Character Register 4 */ -#define CD186x_MCOR1 0x10 /* Modem Change Option 1 Register */ -#define CD186x_MCOR2 0x11 /* Modem Change Option 2 Register */ -#define CD186x_MCR 0x12 /* Modem Change Register */ -#define CD186x_RTPR 0x18 /* Receive Timeout Period Register */ -#define CD186x_MSVR 0x28 /* Modem Signal Value Register */ -#define CD186x_MSVRTS 0x29 /* Modem Signal Value Register */ -#define CD186x_MSVDTR 0x2a /* Modem Signal Value Register */ -#define CD186x_RBPRH 0x31 /* Receive Baud Rate Period Register High */ -#define CD186x_RBPRL 0x32 /* Receive Baud Rate Period Register Low */ -#define CD186x_TBPRH 0x39 /* Transmit Baud Rate Period Register High */ -#define CD186x_TBPRL 0x3a /* Transmit Baud Rate Period Register Low */ - - -/* Global Interrupt Vector Register (R/W) */ - -#define GIVR_ITMASK 0x07 /* Interrupt type mask */ -#define GIVR_IT_MODEM 0x01 /* Modem Signal Change Interrupt */ -#define GIVR_IT_TX 0x02 /* Transmit Data Interrupt */ -#define GIVR_IT_RCV 0x03 /* Receive Good Data Interrupt */ -#define GIVR_IT_REXC 0x07 /* Receive Exception Interrupt */ - - -/* Global Interrupt Channel Register (R/W) */ - -#define GICR_CHAN 0x1c /* Channel Number Mask */ -#define GICR_CHAN_OFF 2 /* Channel Number shift */ - - -/* Channel Address Register (R/W) */ - -#define CAR_CHAN 0x07 /* Channel Number Mask */ -#define CAR_A7 0x08 /* A7 Address Extension (unused) */ - - -/* Receive Character Status Register (R/O) */ - -#define RCSR_TOUT 0x80 /* Rx Timeout */ -#define RCSR_SCDET 0x70 /* Special Character Detected Mask */ -#define RCSR_NO_SC 0x00 /* No Special Characters Detected */ -#define RCSR_SC_1 0x10 /* Special Char 1 (or 1 & 3) Detected */ -#define RCSR_SC_2 0x20 /* Special Char 2 (or 2 & 4) Detected */ -#define RCSR_SC_3 0x30 /* Special Char 3 Detected */ -#define RCSR_SC_4 0x40 /* Special Char 4 Detected */ -#define RCSR_BREAK 0x08 /* Break has been detected */ -#define RCSR_PE 0x04 /* Parity Error */ -#define RCSR_FE 0x02 /* Frame Error */ -#define RCSR_OE 0x01 /* Overrun Error */ - - -/* Channel Command Register (R/W) (commands in groups can be OR-ed) */ - -#define CCR_HARDRESET 0x81 /* Reset the chip */ - -#define CCR_SOFTRESET 0x80 /* Soft Channel Reset */ - -#define CCR_CORCHG1 0x42 /* Channel Option Register 1 Changed */ -#define CCR_CORCHG2 0x44 /* Channel Option Register 2 Changed */ -#define CCR_CORCHG3 0x48 /* Channel Option Register 3 Changed */ - -#define CCR_SSCH1 0x21 /* Send Special Character 1 */ - -#define CCR_SSCH2 0x22 /* Send Special Character 2 */ - -#define CCR_SSCH3 0x23 /* Send Special Character 3 */ - -#define CCR_SSCH4 0x24 /* Send Special Character 4 */ - -#define CCR_TXEN 0x18 /* Enable Transmitter */ -#define CCR_RXEN 0x12 /* Enable Receiver */ - -#define CCR_TXDIS 0x14 /* Disable Transmitter */ -#define CCR_RXDIS 0x11 /* Disable Receiver */ - - -/* Interrupt Enable Register (R/W) */ - -#define IER_DSR 0x80 /* Enable interrupt on DSR change */ -#define IER_CD 0x40 /* Enable interrupt on CD change */ -#define IER_CTS 0x20 /* Enable interrupt on CTS change */ -#define IER_RXD 0x10 /* Enable interrupt on Receive Data */ -#define IER_RXSC 0x08 /* Enable interrupt on Receive Spec. Char */ -#define IER_TXRDY 0x04 /* Enable interrupt on TX FIFO empty */ -#define IER_TXEMPTY 0x02 /* Enable interrupt on TX completely empty */ -#define IER_RET 0x01 /* Enable interrupt on RX Exc. Timeout */ - - -/* Channel Option Register 1 (R/W) */ - -#define COR1_ODDP 0x80 /* Odd Parity */ -#define COR1_PARMODE 0x60 /* Parity Mode mask */ -#define COR1_NOPAR 0x00 /* No Parity */ -#define COR1_FORCEPAR 0x20 /* Force Parity */ -#define COR1_NORMPAR 0x40 /* Normal Parity */ -#define COR1_IGNORE 0x10 /* Ignore Parity on RX */ -#define COR1_STOPBITS 0x0c /* Number of Stop Bits */ -#define COR1_1SB 0x00 /* 1 Stop Bit */ -#define COR1_15SB 0x04 /* 1.5 Stop Bits */ -#define COR1_2SB 0x08 /* 2 Stop Bits */ -#define COR1_CHARLEN 0x03 /* Character Length */ -#define COR1_5BITS 0x00 /* 5 bits */ -#define COR1_6BITS 0x01 /* 6 bits */ -#define COR1_7BITS 0x02 /* 7 bits */ -#define COR1_8BITS 0x03 /* 8 bits */ - - -/* Channel Option Register 2 (R/W) */ - -#define COR2_IXM 0x80 /* Implied XON mode */ -#define COR2_TXIBE 0x40 /* Enable In-Band (XON/XOFF) Flow Control */ -#define COR2_ETC 0x20 /* Embedded Tx Commands Enable */ -#define COR2_LLM 0x10 /* Local Loopback Mode */ -#define COR2_RLM 0x08 /* Remote Loopback Mode */ -#define COR2_RTSAO 0x04 /* RTS Automatic Output Enable */ -#define COR2_CTSAE 0x02 /* CTS Automatic Enable */ -#define COR2_DSRAE 0x01 /* DSR Automatic Enable */ - - -/* Channel Option Register 3 (R/W) */ - -#define COR3_XONCH 0x80 /* XON is a pair of characters (1 & 3) */ -#define COR3_XOFFCH 0x40 /* XOFF is a pair of characters (2 & 4) */ -#define COR3_FCT 0x20 /* Flow-Control Transparency Mode */ -#define COR3_SCDE 0x10 /* Special Character Detection Enable */ -#define COR3_RXTH 0x0f /* RX FIFO Threshold value (1-8) */ - - -/* Channel Control Status Register (R/O) */ - -#define CCSR_RXEN 0x80 /* Receiver Enabled */ -#define CCSR_RXFLOFF 0x40 /* Receive Flow Off (XOFF was sent) */ -#define CCSR_RXFLON 0x20 /* Receive Flow On (XON was sent) */ -#define CCSR_TXEN 0x08 /* Transmitter Enabled */ -#define CCSR_TXFLOFF 0x04 /* Transmit Flow Off (got XOFF) */ -#define CCSR_TXFLON 0x02 /* Transmit Flow On (got XON) */ - - -/* Modem Change Option Register 1 (R/W) */ - -#define MCOR1_DSRZD 0x80 /* Detect 0->1 transition of DSR */ -#define MCOR1_CDZD 0x40 /* Detect 0->1 transition of CD */ -#define MCOR1_CTSZD 0x20 /* Detect 0->1 transition of CTS */ -#define MCOR1_DTRTH 0x0f /* Auto DTR flow control Threshold (1-8) */ -#define MCOR1_NODTRFC 0x0 /* Automatic DTR flow control disabled */ - - -/* Modem Change Option Register 2 (R/W) */ - -#define MCOR2_DSROD 0x80 /* Detect 1->0 transition of DSR */ -#define MCOR2_CDOD 0x40 /* Detect 1->0 transition of CD */ -#define MCOR2_CTSOD 0x20 /* Detect 1->0 transition of CTS */ - -/* Modem Change Register (R/W) */ - -#define MCR_DSRCHG 0x80 /* DSR Changed */ -#define MCR_CDCHG 0x40 /* CD Changed */ -#define MCR_CTSCHG 0x20 /* CTS Changed */ - - -/* Modem Signal Value Register (R/W) */ - -#define MSVR_DSR 0x80 /* Current state of DSR input */ -#define MSVR_CD 0x40 /* Current state of CD input */ -#define MSVR_CTS 0x20 /* Current state of CTS input */ -#define MSVR_DTR 0x02 /* Current state of DTR output */ -#define MSVR_RTS 0x01 /* Current state of RTS output */ - - -/* Escape characters */ - -#define CD186x_C_ESC 0x00 /* Escape character */ -#define CD186x_C_SBRK 0x81 /* Start sending BREAK */ -#define CD186x_C_DELAY 0x82 /* Delay output */ -#define CD186x_C_EBRK 0x83 /* Stop sending BREAK */ - -#define SRSR_RREQint 0x10 /* This chip wants "rec" serviced */ -#define SRSR_TREQint 0x04 /* This chip wants "transmit" serviced */ -#define SRSR_MREQint 0x01 /* This chip wants "mdm change" serviced */ - - - -#define SRCR_PKGTYPE 0x80 -#define SRCR_REGACKEN 0x40 -#define SRCR_DAISYEN 0x20 -#define SRCR_GLOBPRI 0x10 -#define SRCR_UNFAIR 0x08 -#define SRCR_AUTOPRI 0x02 -#define SRCR_PRISEL 0x01 - - diff --git a/drivers/staging/tty/digi1.h b/drivers/staging/tty/digi1.h deleted file mode 100644 index 94d4eab5d3ca..000000000000 --- a/drivers/staging/tty/digi1.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Definitions for DigiBoard ditty(1) command. */ - -#if !defined(TIOCMODG) -#define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */ -#define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */ -#endif - -#if !defined(TIOCMSET) -#define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */ -#define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */ -#endif - -#if !defined(TIOCMBIC) -#define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */ -#define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */ -#endif - -#if !defined(TIOCSDTR) -#define TIOCSDTR (('e'<<8) | 0) /* set DTR */ -#define TIOCCDTR (('e'<<8) | 1) /* clear DTR */ -#endif - -/************************************************************************ - * Ioctl command arguments for DIGI parameters. - ************************************************************************/ -#define DIGI_GETA (('e'<<8) | 94) /* Read params */ - -#define DIGI_SETA (('e'<<8) | 95) /* Set params */ -#define DIGI_SETAW (('e'<<8) | 96) /* Drain & set params */ -#define DIGI_SETAF (('e'<<8) | 97) /* Drain, flush & set params */ - -#define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */ - /* control characters */ -#define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */ - /* control characters */ -#define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */ - /* flow control chars */ -#define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */ - /* flow control chars */ - -#define DIGI_GETINFO (('e'<<8) | 103) /* Fill in digi_info */ -#define DIGI_POLLER (('e'<<8) | 104) /* Turn on/off poller */ -#define DIGI_INIT (('e'<<8) | 105) /* Allow things to run. */ - -struct digiflow_struct -{ - unsigned char startc; /* flow cntl start char */ - unsigned char stopc; /* flow cntl stop char */ -}; - -typedef struct digiflow_struct digiflow_t; - - -/************************************************************************ - * Values for digi_flags - ************************************************************************/ -#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */ -#define DIGI_FAST 0x0002 /* Fast baud rates */ -#define RTSPACE 0x0004 /* RTS input flow control */ -#define CTSPACE 0x0008 /* CTS output flow control */ -#define DSRPACE 0x0010 /* DSR output flow control */ -#define DCDPACE 0x0020 /* DCD output flow control */ -#define DTRPACE 0x0040 /* DTR input flow control */ -#define DIGI_FORCEDCD 0x0100 /* Force carrier */ -#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */ -#define DIGI_AIXON 0x0400 /* Aux flow control in fep */ - - -/************************************************************************ - * Values for digiDload - ************************************************************************/ -#define NORMAL 0 -#define PCI_CTL 1 - -#define SIZE8 0 -#define SIZE16 1 -#define SIZE32 2 - -/************************************************************************ - * Structure used with ioctl commands for DIGI parameters. - ************************************************************************/ -struct digi_struct -{ - unsigned short digi_flags; /* Flags (see above) */ -}; - -typedef struct digi_struct digi_t; - -struct digi_info -{ - unsigned long board; /* Which board is this ? */ - unsigned char status; /* Alive or dead */ - unsigned char type; /* see epca.h */ - unsigned char subtype; /* For future XEM, XR, etc ... */ - unsigned short numports; /* Number of ports configured */ - unsigned char *port; /* I/O Address */ - unsigned char *membase; /* DPR Address */ - unsigned char *version; /* For future ... */ - unsigned short windowData; /* For future ... */ -} ; diff --git a/drivers/staging/tty/digiFep1.h b/drivers/staging/tty/digiFep1.h deleted file mode 100644 index 3c1f1922c798..000000000000 --- a/drivers/staging/tty/digiFep1.h +++ /dev/null @@ -1,136 +0,0 @@ - -#define CSTART 0x400L -#define CMAX 0x800L -#define ISTART 0x800L -#define IMAX 0xC00L -#define CIN 0xD10L -#define GLOBAL 0xD10L -#define EIN 0xD18L -#define FEPSTAT 0xD20L -#define CHANSTRUCT 0x1000L -#define RXTXBUF 0x4000L - - -struct global_data -{ - u16 cin; - u16 cout; - u16 cstart; - u16 cmax; - u16 ein; - u16 eout; - u16 istart; - u16 imax; -}; - - -struct board_chan -{ - u32 filler1; - u32 filler2; - u16 tseg; - u16 tin; - u16 tout; - u16 tmax; - - u16 rseg; - u16 rin; - u16 rout; - u16 rmax; - - u16 tlow; - u16 rlow; - u16 rhigh; - u16 incr; - - u16 etime; - u16 edelay; - unchar *dev; - - u16 iflag; - u16 oflag; - u16 cflag; - u16 gmask; - - u16 col; - u16 delay; - u16 imask; - u16 tflush; - - u32 filler3; - u32 filler4; - u32 filler5; - u32 filler6; - - u8 num; - u8 ract; - u8 bstat; - u8 tbusy; - u8 iempty; - u8 ilow; - u8 idata; - u8 eflag; - - u8 tflag; - u8 rflag; - u8 xmask; - u8 xval; - u8 mstat; - u8 mchange; - u8 mint; - u8 lstat; - - u8 mtran; - u8 orun; - u8 startca; - u8 stopca; - u8 startc; - u8 stopc; - u8 vnext; - u8 hflow; - - u8 fillc; - u8 ochar; - u8 omask; - - u8 filler7; - u8 filler8[28]; -}; - - -#define SRXLWATER 0xE0 -#define SRXHWATER 0xE1 -#define STOUT 0xE2 -#define PAUSETX 0xE3 -#define RESUMETX 0xE4 -#define SAUXONOFFC 0xE6 -#define SENDBREAK 0xE8 -#define SETMODEM 0xE9 -#define SETIFLAGS 0xEA -#define SONOFFC 0xEB -#define STXLWATER 0xEC -#define PAUSERX 0xEE -#define RESUMERX 0xEF -#define SETBUFFER 0xF2 -#define SETCOOKED 0xF3 -#define SETHFLOW 0xF4 -#define SETCTRLFLAGS 0xF5 -#define SETVNEXT 0xF6 - - - -#define BREAK_IND 0x01 -#define LOWTX_IND 0x02 -#define EMPTYTX_IND 0x04 -#define DATA_IND 0x08 -#define MODEMCHG_IND 0x20 - -#define FEP_HUPCL 0002000 -#if 0 -#define RTS 0x02 -#define CD 0x08 -#define DSR 0x10 -#define CTS 0x20 -#define RI 0x40 -#define DTR 0x80 -#endif diff --git a/drivers/staging/tty/digiPCI.h b/drivers/staging/tty/digiPCI.h deleted file mode 100644 index 6ca7819e5069..000000000000 --- a/drivers/staging/tty/digiPCI.h +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************************* - * Defines and structure definitions for PCI BIOS Interface - *************************************************************************/ -#define PCIMAX 32 /* maximum number of PCI boards */ - - -#define PCI_VENDOR_DIGI 0x114F -#define PCI_DEVICE_EPC 0x0002 -#define PCI_DEVICE_RIGHTSWITCH 0x0003 /* For testing */ -#define PCI_DEVICE_XEM 0x0004 -#define PCI_DEVICE_XR 0x0005 -#define PCI_DEVICE_CX 0x0006 -#define PCI_DEVICE_XRJ 0x0009 /* Jupiter boards with */ -#define PCI_DEVICE_EPCJ 0x000a /* PLX 9060 chip for PCI */ - - -/* - * On the PCI boards, there is no IO space allocated - * The I/O registers will be in the first 3 bytes of the - * upper 2MB of the 4MB memory space. The board memory - * will be mapped into the low 2MB of the 4MB memory space - */ - -/* Potential location of PCI Bios from E0000 to FFFFF*/ -#define PCI_BIOS_SIZE 0x00020000 - -/* Size of Memory and I/O for PCI (4MB) */ -#define PCI_RAM_SIZE 0x00400000 - -/* Size of Memory (2MB) */ -#define PCI_MEM_SIZE 0x00200000 - -/* Offset of I/0 in Memory (2MB) */ -#define PCI_IO_OFFSET 0x00200000 - -#define MEMOUTB(basemem, pnum, setmemval) *(caddr_t)((basemem) + ( PCI_IO_OFFSET | pnum << 4 | pnum )) = (setmemval) -#define MEMINB(basemem, pnum) *(caddr_t)((basemem) + (PCI_IO_OFFSET | pnum << 4 | pnum )) /* for PCI I/O */ - - - - - diff --git a/drivers/staging/tty/epca.c b/drivers/staging/tty/epca.c deleted file mode 100644 index 7f1369e5b418..000000000000 --- a/drivers/staging/tty/epca.c +++ /dev/null @@ -1,2784 +0,0 @@ -/* - Copyright (C) 1996 Digi International. - - For technical support please email digiLinux@dgii.com or - call Digi tech support at (612) 912-3456 - - ** This driver is no longer supported by Digi ** - - Much of this design and code came from epca.c which was - copyright (C) 1994, 1995 Troy De Jongh, and subsequently - modified by David Nugent, Christoph Lameter, Mike McLagan. - - 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. -*/ -/* See README.epca for change history --DAT*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "digiPCI.h" - - -#include "digi1.h" -#include "digiFep1.h" -#include "epca.h" -#include "epcaconfig.h" - -#define VERSION "1.3.0.1-LK2.6" - -/* This major needs to be submitted to Linux to join the majors list */ -#define DIGIINFOMAJOR 35 /* For Digi specific ioctl */ - - -#define MAXCARDS 7 -#define epcaassert(x, msg) if (!(x)) epca_error(__LINE__, msg) - -#define PFX "epca: " - -static int nbdevs, num_cards, liloconfig; -static int digi_poller_inhibited = 1 ; - -static int setup_error_code; -static int invalid_lilo_config; - -/* - * The ISA boards do window flipping into the same spaces so its only sane with - * a single lock. It's still pretty efficient. This lock guards the hardware - * and the tty_port lock guards the kernel side stuff like use counts. Take - * this lock inside the port lock if you must take both. - */ -static DEFINE_SPINLOCK(epca_lock); - -/* MAXBOARDS is typically 12, but ISA and EISA cards are restricted - to 7 below. */ -static struct board_info boards[MAXBOARDS]; - -static struct tty_driver *pc_driver; -static struct tty_driver *pc_info; - -/* ------------------ Begin Digi specific structures -------------------- */ - -/* - * digi_channels represents an array of structures that keep track of each - * channel of the Digi product. Information such as transmit and receive - * pointers, termio data, and signal definitions (DTR, CTS, etc ...) are stored - * here. This structure is NOT used to overlay the cards physical channel - * structure. - */ -static struct channel digi_channels[MAX_ALLOC]; - -/* - * card_ptr is an array used to hold the address of the first channel structure - * of each card. This array will hold the addresses of various channels located - * in digi_channels. - */ -static struct channel *card_ptr[MAXCARDS]; - -static struct timer_list epca_timer; - -/* - * Begin generic memory functions. These functions will be alias (point at) - * more specific functions dependent on the board being configured. - */ -static void memwinon(struct board_info *b, unsigned int win); -static void memwinoff(struct board_info *b, unsigned int win); -static void globalwinon(struct channel *ch); -static void rxwinon(struct channel *ch); -static void txwinon(struct channel *ch); -static void memoff(struct channel *ch); -static void assertgwinon(struct channel *ch); -static void assertmemoff(struct channel *ch); - -/* ---- Begin more 'specific' memory functions for cx_like products --- */ - -static void pcxem_memwinon(struct board_info *b, unsigned int win); -static void pcxem_memwinoff(struct board_info *b, unsigned int win); -static void pcxem_globalwinon(struct channel *ch); -static void pcxem_rxwinon(struct channel *ch); -static void pcxem_txwinon(struct channel *ch); -static void pcxem_memoff(struct channel *ch); - -/* ------ Begin more 'specific' memory functions for the pcxe ------- */ - -static void pcxe_memwinon(struct board_info *b, unsigned int win); -static void pcxe_memwinoff(struct board_info *b, unsigned int win); -static void pcxe_globalwinon(struct channel *ch); -static void pcxe_rxwinon(struct channel *ch); -static void pcxe_txwinon(struct channel *ch); -static void pcxe_memoff(struct channel *ch); - -/* ---- Begin more 'specific' memory functions for the pc64xe and pcxi ---- */ -/* Note : pc64xe and pcxi share the same windowing routines */ - -static void pcxi_memwinon(struct board_info *b, unsigned int win); -static void pcxi_memwinoff(struct board_info *b, unsigned int win); -static void pcxi_globalwinon(struct channel *ch); -static void pcxi_rxwinon(struct channel *ch); -static void pcxi_txwinon(struct channel *ch); -static void pcxi_memoff(struct channel *ch); - -/* - Begin 'specific' do nothing memory functions needed for some cards - */ - -static void dummy_memwinon(struct board_info *b, unsigned int win); -static void dummy_memwinoff(struct board_info *b, unsigned int win); -static void dummy_globalwinon(struct channel *ch); -static void dummy_rxwinon(struct channel *ch); -static void dummy_txwinon(struct channel *ch); -static void dummy_memoff(struct channel *ch); -static void dummy_assertgwinon(struct channel *ch); -static void dummy_assertmemoff(struct channel *ch); - -static struct channel *verifyChannel(struct tty_struct *); -static void pc_sched_event(struct channel *, int); -static void epca_error(int, char *); -static void pc_close(struct tty_struct *, struct file *); -static void shutdown(struct channel *, struct tty_struct *tty); -static void pc_hangup(struct tty_struct *); -static int pc_write_room(struct tty_struct *); -static int pc_chars_in_buffer(struct tty_struct *); -static void pc_flush_buffer(struct tty_struct *); -static void pc_flush_chars(struct tty_struct *); -static int pc_open(struct tty_struct *, struct file *); -static void post_fep_init(unsigned int crd); -static void epcapoll(unsigned long); -static void doevent(int); -static void fepcmd(struct channel *, int, int, int, int, int); -static unsigned termios2digi_h(struct channel *ch, unsigned); -static unsigned termios2digi_i(struct channel *ch, unsigned); -static unsigned termios2digi_c(struct channel *ch, unsigned); -static void epcaparam(struct tty_struct *, struct channel *); -static void receive_data(struct channel *, struct tty_struct *tty); -static int pc_ioctl(struct tty_struct *, - unsigned int, unsigned long); -static int info_ioctl(struct tty_struct *, - unsigned int, unsigned long); -static void pc_set_termios(struct tty_struct *, struct ktermios *); -static void do_softint(struct work_struct *work); -static void pc_stop(struct tty_struct *); -static void pc_start(struct tty_struct *); -static void pc_throttle(struct tty_struct *tty); -static void pc_unthrottle(struct tty_struct *tty); -static int pc_send_break(struct tty_struct *tty, int msec); -static void setup_empty_event(struct tty_struct *tty, struct channel *ch); - -static int pc_write(struct tty_struct *, const unsigned char *, int); -static int pc_init(void); -static int init_PCI(void); - -/* - * Table of functions for each board to handle memory. Mantaining parallelism - * is a *very* good idea here. The idea is for the runtime code to blindly call - * these functions, not knowing/caring about the underlying hardware. This - * stuff should contain no conditionals; if more functionality is needed a - * different entry should be established. These calls are the interface calls - * and are the only functions that should be accessed. Anyone caught making - * direct calls deserves what they get. - */ -static void memwinon(struct board_info *b, unsigned int win) -{ - b->memwinon(b, win); -} - -static void memwinoff(struct board_info *b, unsigned int win) -{ - b->memwinoff(b, win); -} - -static void globalwinon(struct channel *ch) -{ - ch->board->globalwinon(ch); -} - -static void rxwinon(struct channel *ch) -{ - ch->board->rxwinon(ch); -} - -static void txwinon(struct channel *ch) -{ - ch->board->txwinon(ch); -} - -static void memoff(struct channel *ch) -{ - ch->board->memoff(ch); -} -static void assertgwinon(struct channel *ch) -{ - ch->board->assertgwinon(ch); -} - -static void assertmemoff(struct channel *ch) -{ - ch->board->assertmemoff(ch); -} - -/* PCXEM windowing is the same as that used in the PCXR and CX series cards. */ -static void pcxem_memwinon(struct board_info *b, unsigned int win) -{ - outb_p(FEPWIN | win, b->port + 1); -} - -static void pcxem_memwinoff(struct board_info *b, unsigned int win) -{ - outb_p(0, b->port + 1); -} - -static void pcxem_globalwinon(struct channel *ch) -{ - outb_p(FEPWIN, (int)ch->board->port + 1); -} - -static void pcxem_rxwinon(struct channel *ch) -{ - outb_p(ch->rxwin, (int)ch->board->port + 1); -} - -static void pcxem_txwinon(struct channel *ch) -{ - outb_p(ch->txwin, (int)ch->board->port + 1); -} - -static void pcxem_memoff(struct channel *ch) -{ - outb_p(0, (int)ch->board->port + 1); -} - -/* ----------------- Begin pcxe memory window stuff ------------------ */ -static void pcxe_memwinon(struct board_info *b, unsigned int win) -{ - outb_p(FEPWIN | win, b->port + 1); -} - -static void pcxe_memwinoff(struct board_info *b, unsigned int win) -{ - outb_p(inb(b->port) & ~FEPMEM, b->port + 1); - outb_p(0, b->port + 1); -} - -static void pcxe_globalwinon(struct channel *ch) -{ - outb_p(FEPWIN, (int)ch->board->port + 1); -} - -static void pcxe_rxwinon(struct channel *ch) -{ - outb_p(ch->rxwin, (int)ch->board->port + 1); -} - -static void pcxe_txwinon(struct channel *ch) -{ - outb_p(ch->txwin, (int)ch->board->port + 1); -} - -static void pcxe_memoff(struct channel *ch) -{ - outb_p(0, (int)ch->board->port); - outb_p(0, (int)ch->board->port + 1); -} - -/* ------------- Begin pc64xe and pcxi memory window stuff -------------- */ -static void pcxi_memwinon(struct board_info *b, unsigned int win) -{ - outb_p(inb(b->port) | FEPMEM, b->port); -} - -static void pcxi_memwinoff(struct board_info *b, unsigned int win) -{ - outb_p(inb(b->port) & ~FEPMEM, b->port); -} - -static void pcxi_globalwinon(struct channel *ch) -{ - outb_p(FEPMEM, ch->board->port); -} - -static void pcxi_rxwinon(struct channel *ch) -{ - outb_p(FEPMEM, ch->board->port); -} - -static void pcxi_txwinon(struct channel *ch) -{ - outb_p(FEPMEM, ch->board->port); -} - -static void pcxi_memoff(struct channel *ch) -{ - outb_p(0, ch->board->port); -} - -static void pcxi_assertgwinon(struct channel *ch) -{ - epcaassert(inb(ch->board->port) & FEPMEM, "Global memory off"); -} - -static void pcxi_assertmemoff(struct channel *ch) -{ - epcaassert(!(inb(ch->board->port) & FEPMEM), "Memory on"); -} - -/* - * Not all of the cards need specific memory windowing routines. Some cards - * (Such as PCI) needs no windowing routines at all. We provide these do - * nothing routines so that the same code base can be used. The driver will - * ALWAYS call a windowing routine if it thinks it needs to; regardless of the - * card. However, dependent on the card the routine may or may not do anything. - */ -static void dummy_memwinon(struct board_info *b, unsigned int win) -{ -} - -static void dummy_memwinoff(struct board_info *b, unsigned int win) -{ -} - -static void dummy_globalwinon(struct channel *ch) -{ -} - -static void dummy_rxwinon(struct channel *ch) -{ -} - -static void dummy_txwinon(struct channel *ch) -{ -} - -static void dummy_memoff(struct channel *ch) -{ -} - -static void dummy_assertgwinon(struct channel *ch) -{ -} - -static void dummy_assertmemoff(struct channel *ch) -{ -} - -static struct channel *verifyChannel(struct tty_struct *tty) -{ - /* - * This routine basically provides a sanity check. It insures that the - * channel returned is within the proper range of addresses as well as - * properly initialized. If some bogus info gets passed in - * through tty->driver_data this should catch it. - */ - if (tty) { - struct channel *ch = tty->driver_data; - if (ch >= &digi_channels[0] && ch < &digi_channels[nbdevs]) { - if (ch->magic == EPCA_MAGIC) - return ch; - } - } - return NULL; -} - -static void pc_sched_event(struct channel *ch, int event) -{ - /* - * We call this to schedule interrupt processing on some event. The - * kernel sees our request and calls the related routine in OUR driver. - */ - ch->event |= 1 << event; - schedule_work(&ch->tqueue); -} - -static void epca_error(int line, char *msg) -{ - printk(KERN_ERR "epca_error (Digi): line = %d %s\n", line, msg); -} - -static void pc_close(struct tty_struct *tty, struct file *filp) -{ - struct channel *ch; - struct tty_port *port; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch == NULL) - return; - port = &ch->port; - - if (tty_port_close_start(port, tty, filp) == 0) - return; - - pc_flush_buffer(tty); - shutdown(ch, tty); - - tty_port_close_end(port, tty); - ch->event = 0; /* FIXME: review ch->event locking */ - tty_port_tty_set(port, NULL); -} - -static void shutdown(struct channel *ch, struct tty_struct *tty) -{ - unsigned long flags; - struct board_chan __iomem *bc; - struct tty_port *port = &ch->port; - - if (!(port->flags & ASYNC_INITIALIZED)) - return; - - spin_lock_irqsave(&epca_lock, flags); - - globalwinon(ch); - bc = ch->brdchan; - - /* - * In order for an event to be generated on the receipt of data the - * idata flag must be set. Since we are shutting down, this is not - * necessary clear this flag. - */ - if (bc) - writeb(0, &bc->idata); - - /* If we're a modem control device and HUPCL is on, drop RTS & DTR. */ - if (tty->termios->c_cflag & HUPCL) { - ch->omodem &= ~(ch->m_rts | ch->m_dtr); - fepcmd(ch, SETMODEM, 0, ch->m_dtr | ch->m_rts, 10, 1); - } - memoff(ch); - - /* - * The channel has officially been closed. The next time it is opened it - * will have to reinitialized. Set a flag to indicate this. - */ - /* Prevent future Digi programmed interrupts from coming active */ - port->flags &= ~ASYNC_INITIALIZED; - spin_unlock_irqrestore(&epca_lock, flags); -} - -static void pc_hangup(struct tty_struct *tty) -{ - struct channel *ch; - - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - pc_flush_buffer(tty); - tty_ldisc_flush(tty); - shutdown(ch, tty); - - ch->event = 0; /* FIXME: review locking of ch->event */ - tty_port_hangup(&ch->port); - } -} - -static int pc_write(struct tty_struct *tty, - const unsigned char *buf, int bytesAvailable) -{ - unsigned int head, tail; - int dataLen; - int size; - int amountCopied; - struct channel *ch; - unsigned long flags; - int remain; - struct board_chan __iomem *bc; - - /* - * pc_write is primarily called directly by the kernel routine - * tty_write (Though it can also be called by put_char) found in - * tty_io.c. pc_write is passed a line discipline buffer where the data - * to be written out is stored. The line discipline implementation - * itself is done at the kernel level and is not brought into the - * driver. - */ - - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch == NULL) - return 0; - - /* Make a pointer to the channel data structure found on the board. */ - bc = ch->brdchan; - size = ch->txbufsize; - amountCopied = 0; - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - - head = readw(&bc->tin) & (size - 1); - tail = readw(&bc->tout); - - if (tail != readw(&bc->tout)) - tail = readw(&bc->tout); - tail &= (size - 1); - - if (head >= tail) { - /* head has not wrapped */ - /* - * remain (much like dataLen above) represents the total amount - * of space available on the card for data. Here dataLen - * represents the space existing between the head pointer and - * the end of buffer. This is important because a memcpy cannot - * be told to automatically wrap around when it hits the buffer - * end. - */ - dataLen = size - head; - remain = size - (head - tail) - 1; - } else { - /* head has wrapped around */ - remain = tail - head - 1; - dataLen = remain; - } - /* - * Check the space on the card. If we have more data than space; reduce - * the amount of data to fit the space. - */ - bytesAvailable = min(remain, bytesAvailable); - txwinon(ch); - while (bytesAvailable > 0) { - /* there is data to copy onto card */ - - /* - * If head is not wrapped, the below will make sure the first - * data copy fills to the end of card buffer. - */ - dataLen = min(bytesAvailable, dataLen); - memcpy_toio(ch->txptr + head, buf, dataLen); - buf += dataLen; - head += dataLen; - amountCopied += dataLen; - bytesAvailable -= dataLen; - - if (head >= size) { - head = 0; - dataLen = tail; - } - } - ch->statusflags |= TXBUSY; - globalwinon(ch); - writew(head, &bc->tin); - - if ((ch->statusflags & LOWWAIT) == 0) { - ch->statusflags |= LOWWAIT; - writeb(1, &bc->ilow); - } - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - return amountCopied; -} - -static int pc_write_room(struct tty_struct *tty) -{ - int remain = 0; - struct channel *ch; - unsigned long flags; - unsigned int head, tail; - struct board_chan __iomem *bc; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - - bc = ch->brdchan; - head = readw(&bc->tin) & (ch->txbufsize - 1); - tail = readw(&bc->tout); - - if (tail != readw(&bc->tout)) - tail = readw(&bc->tout); - /* Wrap tail if necessary */ - tail &= (ch->txbufsize - 1); - remain = tail - head - 1; - if (remain < 0) - remain += ch->txbufsize; - - if (remain && (ch->statusflags & LOWWAIT) == 0) { - ch->statusflags |= LOWWAIT; - writeb(1, &bc->ilow); - } - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - } - /* Return how much room is left on card */ - return remain; -} - -static int pc_chars_in_buffer(struct tty_struct *tty) -{ - int chars; - unsigned int ctail, head, tail; - int remain; - unsigned long flags; - struct channel *ch; - struct board_chan __iomem *bc; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch == NULL) - return 0; - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - - bc = ch->brdchan; - tail = readw(&bc->tout); - head = readw(&bc->tin); - ctail = readw(&ch->mailbox->cout); - - if (tail == head && readw(&ch->mailbox->cin) == ctail && - readb(&bc->tbusy) == 0) - chars = 0; - else { /* Begin if some space on the card has been used */ - head = readw(&bc->tin) & (ch->txbufsize - 1); - tail &= (ch->txbufsize - 1); - /* - * The logic here is basically opposite of the above - * pc_write_room here we are finding the amount of bytes in the - * buffer filled. Not the amount of bytes empty. - */ - remain = tail - head - 1; - if (remain < 0) - remain += ch->txbufsize; - chars = (int)(ch->txbufsize - remain); - /* - * Make it possible to wakeup anything waiting for output in - * tty_ioctl.c, etc. - * - * If not already set. Setup an event to indicate when the - * transmit buffer empties. - */ - if (!(ch->statusflags & EMPTYWAIT)) - setup_empty_event(tty, ch); - } /* End if some space on the card has been used */ - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - /* Return number of characters residing on card. */ - return chars; -} - -static void pc_flush_buffer(struct tty_struct *tty) -{ - unsigned int tail; - unsigned long flags; - struct channel *ch; - struct board_chan __iomem *bc; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch == NULL) - return; - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - bc = ch->brdchan; - tail = readw(&bc->tout); - /* Have FEP move tout pointer; effectively flushing transmit buffer */ - fepcmd(ch, STOUT, (unsigned) tail, 0, 0, 0); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - tty_wakeup(tty); -} - -static void pc_flush_chars(struct tty_struct *tty) -{ - struct channel *ch; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - unsigned long flags; - spin_lock_irqsave(&epca_lock, flags); - /* - * If not already set and the transmitter is busy setup an - * event to indicate when the transmit empties. - */ - if ((ch->statusflags & TXBUSY) && - !(ch->statusflags & EMPTYWAIT)) - setup_empty_event(tty, ch); - spin_unlock_irqrestore(&epca_lock, flags); - } -} - -static int epca_carrier_raised(struct tty_port *port) -{ - struct channel *ch = container_of(port, struct channel, port); - if (ch->imodem & ch->dcd) - return 1; - return 0; -} - -static void epca_dtr_rts(struct tty_port *port, int onoff) -{ -} - -static int pc_open(struct tty_struct *tty, struct file *filp) -{ - struct channel *ch; - struct tty_port *port; - unsigned long flags; - int line, retval, boardnum; - struct board_chan __iomem *bc; - unsigned int head; - - line = tty->index; - if (line < 0 || line >= nbdevs) - return -ENODEV; - - ch = &digi_channels[line]; - port = &ch->port; - boardnum = ch->boardnum; - - /* Check status of board configured in system. */ - - /* - * I check to see if the epca_setup routine detected a user error. It - * might be better to put this in pc_init, but for the moment it goes - * here. - */ - if (invalid_lilo_config) { - if (setup_error_code & INVALID_BOARD_TYPE) - printk(KERN_ERR "epca: pc_open: Invalid board type specified in kernel options.\n"); - if (setup_error_code & INVALID_NUM_PORTS) - printk(KERN_ERR "epca: pc_open: Invalid number of ports specified in kernel options.\n"); - if (setup_error_code & INVALID_MEM_BASE) - printk(KERN_ERR "epca: pc_open: Invalid board memory address specified in kernel options.\n"); - if (setup_error_code & INVALID_PORT_BASE) - printk(KERN_ERR "epca; pc_open: Invalid board port address specified in kernel options.\n"); - if (setup_error_code & INVALID_BOARD_STATUS) - printk(KERN_ERR "epca: pc_open: Invalid board status specified in kernel options.\n"); - if (setup_error_code & INVALID_ALTPIN) - printk(KERN_ERR "epca: pc_open: Invalid board altpin specified in kernel options;\n"); - tty->driver_data = NULL; /* Mark this device as 'down' */ - return -ENODEV; - } - if (boardnum >= num_cards || boards[boardnum].status == DISABLED) { - tty->driver_data = NULL; /* Mark this device as 'down' */ - return(-ENODEV); - } - - bc = ch->brdchan; - if (bc == NULL) { - tty->driver_data = NULL; - return -ENODEV; - } - - spin_lock_irqsave(&port->lock, flags); - /* - * Every time a channel is opened, increment a counter. This is - * necessary because we do not wish to flush and shutdown the channel - * until the last app holding the channel open, closes it. - */ - port->count++; - /* - * Set a kernel structures pointer to our local channel structure. This - * way we can get to it when passed only a tty struct. - */ - tty->driver_data = ch; - port->tty = tty; - /* - * If this is the first time the channel has been opened, initialize - * the tty->termios struct otherwise let pc_close handle it. - */ - spin_lock(&epca_lock); - globalwinon(ch); - ch->statusflags = 0; - - /* Save boards current modem status */ - ch->imodem = readb(&bc->mstat); - - /* - * Set receive head and tail ptrs to each other. This indicates no data - * available to read. - */ - head = readw(&bc->rin); - writew(head, &bc->rout); - - /* Set the channels associated tty structure */ - - /* - * The below routine generally sets up parity, baud, flow control - * issues, etc.... It effect both control flags and input flags. - */ - epcaparam(tty, ch); - memoff(ch); - spin_unlock(&epca_lock); - port->flags |= ASYNC_INITIALIZED; - spin_unlock_irqrestore(&port->lock, flags); - - retval = tty_port_block_til_ready(port, tty, filp); - if (retval) - return retval; - /* - * Set this again in case a hangup set it to zero while this open() was - * waiting for the line... - */ - spin_lock_irqsave(&port->lock, flags); - port->tty = tty; - spin_lock(&epca_lock); - globalwinon(ch); - /* Enable Digi Data events */ - writeb(1, &bc->idata); - memoff(ch); - spin_unlock(&epca_lock); - spin_unlock_irqrestore(&port->lock, flags); - return 0; -} - -static int __init epca_module_init(void) -{ - return pc_init(); -} -module_init(epca_module_init); - -static struct pci_driver epca_driver; - -static void __exit epca_module_exit(void) -{ - int count, crd; - struct board_info *bd; - struct channel *ch; - - del_timer_sync(&epca_timer); - - if (tty_unregister_driver(pc_driver) || - tty_unregister_driver(pc_info)) { - printk(KERN_WARNING "epca: cleanup_module failed to un-register tty driver\n"); - return; - } - put_tty_driver(pc_driver); - put_tty_driver(pc_info); - - for (crd = 0; crd < num_cards; crd++) { - bd = &boards[crd]; - if (!bd) { /* sanity check */ - printk(KERN_ERR " - Digi : cleanup_module failed\n"); - return; - } - ch = card_ptr[crd]; - for (count = 0; count < bd->numports; count++, ch++) { - struct tty_struct *tty = tty_port_tty_get(&ch->port); - if (tty) { - tty_hangup(tty); - tty_kref_put(tty); - } - } - } - pci_unregister_driver(&epca_driver); -} -module_exit(epca_module_exit); - -static const struct tty_operations pc_ops = { - .open = pc_open, - .close = pc_close, - .write = pc_write, - .write_room = pc_write_room, - .flush_buffer = pc_flush_buffer, - .chars_in_buffer = pc_chars_in_buffer, - .flush_chars = pc_flush_chars, - .ioctl = pc_ioctl, - .set_termios = pc_set_termios, - .stop = pc_stop, - .start = pc_start, - .throttle = pc_throttle, - .unthrottle = pc_unthrottle, - .hangup = pc_hangup, - .break_ctl = pc_send_break -}; - -static const struct tty_port_operations epca_port_ops = { - .carrier_raised = epca_carrier_raised, - .dtr_rts = epca_dtr_rts, -}; - -static int info_open(struct tty_struct *tty, struct file *filp) -{ - return 0; -} - -static const struct tty_operations info_ops = { - .open = info_open, - .ioctl = info_ioctl, -}; - -static int __init pc_init(void) -{ - int crd; - struct board_info *bd; - unsigned char board_id = 0; - int err = -ENOMEM; - - int pci_boards_found, pci_count; - - pci_count = 0; - - pc_driver = alloc_tty_driver(MAX_ALLOC); - if (!pc_driver) - goto out1; - - pc_info = alloc_tty_driver(MAX_ALLOC); - if (!pc_info) - goto out2; - - /* - * If epca_setup has not been ran by LILO set num_cards to defaults; - * copy board structure defined by digiConfig into drivers board - * structure. Note : If LILO has ran epca_setup then epca_setup will - * handle defining num_cards as well as copying the data into the board - * structure. - */ - if (!liloconfig) { - /* driver has been configured via. epcaconfig */ - nbdevs = NBDEVS; - num_cards = NUMCARDS; - memcpy(&boards, &static_boards, - sizeof(struct board_info) * NUMCARDS); - } - - /* - * Note : If lilo was used to configure the driver and the ignore - * epcaconfig option was chosen (digiepca=2) then nbdevs and num_cards - * will equal 0 at this point. This is okay; PCI cards will still be - * picked up if detected. - */ - - /* - * Set up interrupt, we will worry about memory allocation in - * post_fep_init. - */ - printk(KERN_INFO "DIGI epca driver version %s loaded.\n", VERSION); - - /* - * NOTE : This code assumes that the number of ports found in the - * boards array is correct. This could be wrong if the card in question - * is PCI (And therefore has no ports entry in the boards structure.) - * The rest of the information will be valid for PCI because the - * beginning of pc_init scans for PCI and determines i/o and base - * memory addresses. I am not sure if it is possible to read the number - * of ports supported by the card prior to it being booted (Since that - * is the state it is in when pc_init is run). Because it is not - * possible to query the number of supported ports until after the card - * has booted; we are required to calculate the card_ptrs as the card - * is initialized (Inside post_fep_init). The negative thing about this - * approach is that digiDload's call to GET_INFO will have a bad port - * value. (Since this is called prior to post_fep_init.) - */ - pci_boards_found = 0; - if (num_cards < MAXBOARDS) - pci_boards_found += init_PCI(); - num_cards += pci_boards_found; - - pc_driver->owner = THIS_MODULE; - pc_driver->name = "ttyD"; - pc_driver->major = DIGI_MAJOR; - pc_driver->minor_start = 0; - pc_driver->type = TTY_DRIVER_TYPE_SERIAL; - pc_driver->subtype = SERIAL_TYPE_NORMAL; - pc_driver->init_termios = tty_std_termios; - pc_driver->init_termios.c_iflag = 0; - pc_driver->init_termios.c_oflag = 0; - pc_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; - pc_driver->init_termios.c_lflag = 0; - pc_driver->init_termios.c_ispeed = 9600; - pc_driver->init_termios.c_ospeed = 9600; - pc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK; - tty_set_operations(pc_driver, &pc_ops); - - pc_info->owner = THIS_MODULE; - pc_info->name = "digi_ctl"; - pc_info->major = DIGIINFOMAJOR; - pc_info->minor_start = 0; - pc_info->type = TTY_DRIVER_TYPE_SERIAL; - pc_info->subtype = SERIAL_TYPE_INFO; - pc_info->init_termios = tty_std_termios; - pc_info->init_termios.c_iflag = 0; - pc_info->init_termios.c_oflag = 0; - pc_info->init_termios.c_lflag = 0; - pc_info->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; - pc_info->init_termios.c_ispeed = 9600; - pc_info->init_termios.c_ospeed = 9600; - pc_info->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(pc_info, &info_ops); - - - for (crd = 0; crd < num_cards; crd++) { - /* - * This is where the appropriate memory handlers for the - * hardware is set. Everything at runtime blindly jumps through - * these vectors. - */ - - /* defined in epcaconfig.h */ - bd = &boards[crd]; - - switch (bd->type) { - case PCXEM: - case EISAXEM: - bd->memwinon = pcxem_memwinon; - bd->memwinoff = pcxem_memwinoff; - bd->globalwinon = pcxem_globalwinon; - bd->txwinon = pcxem_txwinon; - bd->rxwinon = pcxem_rxwinon; - bd->memoff = pcxem_memoff; - bd->assertgwinon = dummy_assertgwinon; - bd->assertmemoff = dummy_assertmemoff; - break; - - case PCIXEM: - case PCIXRJ: - case PCIXR: - bd->memwinon = dummy_memwinon; - bd->memwinoff = dummy_memwinoff; - bd->globalwinon = dummy_globalwinon; - bd->txwinon = dummy_txwinon; - bd->rxwinon = dummy_rxwinon; - bd->memoff = dummy_memoff; - bd->assertgwinon = dummy_assertgwinon; - bd->assertmemoff = dummy_assertmemoff; - break; - - case PCXE: - case PCXEVE: - bd->memwinon = pcxe_memwinon; - bd->memwinoff = pcxe_memwinoff; - bd->globalwinon = pcxe_globalwinon; - bd->txwinon = pcxe_txwinon; - bd->rxwinon = pcxe_rxwinon; - bd->memoff = pcxe_memoff; - bd->assertgwinon = dummy_assertgwinon; - bd->assertmemoff = dummy_assertmemoff; - break; - - case PCXI: - case PC64XE: - bd->memwinon = pcxi_memwinon; - bd->memwinoff = pcxi_memwinoff; - bd->globalwinon = pcxi_globalwinon; - bd->txwinon = pcxi_txwinon; - bd->rxwinon = pcxi_rxwinon; - bd->memoff = pcxi_memoff; - bd->assertgwinon = pcxi_assertgwinon; - bd->assertmemoff = pcxi_assertmemoff; - break; - - default: - break; - } - - /* - * Some cards need a memory segment to be defined for use in - * transmit and receive windowing operations. These boards are - * listed in the below switch. In the case of the XI the amount - * of memory on the board is variable so the memory_seg is also - * variable. This code determines what they segment should be. - */ - switch (bd->type) { - case PCXE: - case PCXEVE: - case PC64XE: - bd->memory_seg = 0xf000; - break; - - case PCXI: - board_id = inb((int)bd->port); - if ((board_id & 0x1) == 0x1) { - /* it's an XI card */ - /* Is it a 64K board */ - if ((board_id & 0x30) == 0) - bd->memory_seg = 0xf000; - - /* Is it a 128K board */ - if ((board_id & 0x30) == 0x10) - bd->memory_seg = 0xe000; - - /* Is is a 256K board */ - if ((board_id & 0x30) == 0x20) - bd->memory_seg = 0xc000; - - /* Is it a 512K board */ - if ((board_id & 0x30) == 0x30) - bd->memory_seg = 0x8000; - } else - printk(KERN_ERR "epca: Board at 0x%x doesn't appear to be an XI\n", (int)bd->port); - break; - } - } - - err = tty_register_driver(pc_driver); - if (err) { - printk(KERN_ERR "Couldn't register Digi PC/ driver"); - goto out3; - } - - err = tty_register_driver(pc_info); - if (err) { - printk(KERN_ERR "Couldn't register Digi PC/ info "); - goto out4; - } - - /* Start up the poller to check for events on all enabled boards */ - init_timer(&epca_timer); - epca_timer.function = epcapoll; - mod_timer(&epca_timer, jiffies + HZ/25); - return 0; - -out4: - tty_unregister_driver(pc_driver); -out3: - put_tty_driver(pc_info); -out2: - put_tty_driver(pc_driver); -out1: - return err; -} - -static void post_fep_init(unsigned int crd) -{ - int i; - void __iomem *memaddr; - struct global_data __iomem *gd; - struct board_info *bd; - struct board_chan __iomem *bc; - struct channel *ch; - int shrinkmem = 0, lowwater; - - /* - * This call is made by the user via. the ioctl call DIGI_INIT. It is - * responsible for setting up all the card specific stuff. - */ - bd = &boards[crd]; - - /* - * If this is a PCI board, get the port info. Remember PCI cards do not - * have entries into the epcaconfig.h file, so we can't get the number - * of ports from it. Unfortunetly, this means that anyone doing a - * DIGI_GETINFO before the board has booted will get an invalid number - * of ports returned (It should return 0). Calls to DIGI_GETINFO after - * DIGI_INIT has been called will return the proper values. - */ - if (bd->type >= PCIXEM) { /* Begin get PCI number of ports */ - /* - * Below we use XEMPORTS as a memory offset regardless of which - * PCI card it is. This is because all of the supported PCI - * cards have the same memory offset for the channel data. This - * will have to be changed if we ever develop a PCI/XE card. - * NOTE : The FEP manual states that the port offset is 0xC22 - * as opposed to 0xC02. This is only true for PC/XE, and PC/XI - * cards; not for the XEM, or CX series. On the PCI cards the - * number of ports is determined by reading a ID PROM located - * in the box attached to the card. The card can then determine - * the index the id to determine the number of ports available. - * (FYI - The id should be located at 0x1ac (And may use up to - * 4 bytes if the box in question is a XEM or CX)). - */ - /* PCI cards are already remapped at this point ISA are not */ - bd->numports = readw(bd->re_map_membase + XEMPORTS); - epcaassert(bd->numports <= 64, "PCI returned a invalid number of ports"); - nbdevs += (bd->numports); - } else { - /* Fix up the mappings for ISA/EISA etc */ - /* FIXME: 64K - can we be smarter ? */ - bd->re_map_membase = ioremap_nocache(bd->membase, 0x10000); - } - - if (crd != 0) - card_ptr[crd] = card_ptr[crd-1] + boards[crd-1].numports; - else - card_ptr[crd] = &digi_channels[crd]; /* <- For card 0 only */ - - ch = card_ptr[crd]; - epcaassert(ch <= &digi_channels[nbdevs - 1], "ch out of range"); - - memaddr = bd->re_map_membase; - - /* - * The below assignment will set bc to point at the BEGINNING of the - * cards channel structures. For 1 card there will be between 8 and 64 - * of these structures. - */ - bc = memaddr + CHANSTRUCT; - - /* - * The below assignment will set gd to point at the BEGINNING of global - * memory address 0xc00. The first data in that global memory actually - * starts at address 0xc1a. The command in pointer begins at 0xd10. - */ - gd = memaddr + GLOBAL; - - /* - * XEPORTS (address 0xc22) points at the number of channels the card - * supports. (For 64XE, XI, XEM, and XR use 0xc02) - */ - if ((bd->type == PCXEVE || bd->type == PCXE) && - (readw(memaddr + XEPORTS) < 3)) - shrinkmem = 1; - if (bd->type < PCIXEM) - if (!request_region((int)bd->port, 4, board_desc[bd->type])) - return; - memwinon(bd, 0); - - /* - * Remember ch is the main drivers channels structure, while bc is the - * cards channel structure. - */ - for (i = 0; i < bd->numports; i++, ch++, bc++) { - unsigned long flags; - u16 tseg, rseg; - - tty_port_init(&ch->port); - ch->port.ops = &epca_port_ops; - ch->brdchan = bc; - ch->mailbox = gd; - INIT_WORK(&ch->tqueue, do_softint); - ch->board = &boards[crd]; - - spin_lock_irqsave(&epca_lock, flags); - switch (bd->type) { - /* - * Since some of the boards use different bitmaps for - * their control signals we cannot hard code these - * values and retain portability. We virtualize this - * data here. - */ - case EISAXEM: - case PCXEM: - case PCIXEM: - case PCIXRJ: - case PCIXR: - ch->m_rts = 0x02; - ch->m_dcd = 0x80; - ch->m_dsr = 0x20; - ch->m_cts = 0x10; - ch->m_ri = 0x40; - ch->m_dtr = 0x01; - break; - - case PCXE: - case PCXEVE: - case PCXI: - case PC64XE: - ch->m_rts = 0x02; - ch->m_dcd = 0x08; - ch->m_dsr = 0x10; - ch->m_cts = 0x20; - ch->m_ri = 0x40; - ch->m_dtr = 0x80; - break; - } - - if (boards[crd].altpin) { - ch->dsr = ch->m_dcd; - ch->dcd = ch->m_dsr; - ch->digiext.digi_flags |= DIGI_ALTPIN; - } else { - ch->dcd = ch->m_dcd; - ch->dsr = ch->m_dsr; - } - - ch->boardnum = crd; - ch->channelnum = i; - ch->magic = EPCA_MAGIC; - tty_port_tty_set(&ch->port, NULL); - - if (shrinkmem) { - fepcmd(ch, SETBUFFER, 32, 0, 0, 0); - shrinkmem = 0; - } - - tseg = readw(&bc->tseg); - rseg = readw(&bc->rseg); - - switch (bd->type) { - case PCIXEM: - case PCIXRJ: - case PCIXR: - /* Cover all the 2MEG cards */ - ch->txptr = memaddr + ((tseg << 4) & 0x1fffff); - ch->rxptr = memaddr + ((rseg << 4) & 0x1fffff); - ch->txwin = FEPWIN | (tseg >> 11); - ch->rxwin = FEPWIN | (rseg >> 11); - break; - - case PCXEM: - case EISAXEM: - /* Cover all the 32K windowed cards */ - /* Mask equal to window size - 1 */ - ch->txptr = memaddr + ((tseg << 4) & 0x7fff); - ch->rxptr = memaddr + ((rseg << 4) & 0x7fff); - ch->txwin = FEPWIN | (tseg >> 11); - ch->rxwin = FEPWIN | (rseg >> 11); - break; - - case PCXEVE: - case PCXE: - ch->txptr = memaddr + (((tseg - bd->memory_seg) << 4) - & 0x1fff); - ch->txwin = FEPWIN | ((tseg - bd->memory_seg) >> 9); - ch->rxptr = memaddr + (((rseg - bd->memory_seg) << 4) - & 0x1fff); - ch->rxwin = FEPWIN | ((rseg - bd->memory_seg) >> 9); - break; - - case PCXI: - case PC64XE: - ch->txptr = memaddr + ((tseg - bd->memory_seg) << 4); - ch->rxptr = memaddr + ((rseg - bd->memory_seg) << 4); - ch->txwin = ch->rxwin = 0; - break; - } - - ch->txbufhead = 0; - ch->txbufsize = readw(&bc->tmax) + 1; - - ch->rxbufhead = 0; - ch->rxbufsize = readw(&bc->rmax) + 1; - - lowwater = ch->txbufsize >= 2000 ? 1024 : (ch->txbufsize / 2); - - /* Set transmitter low water mark */ - fepcmd(ch, STXLWATER, lowwater, 0, 10, 0); - - /* Set receiver low water mark */ - fepcmd(ch, SRXLWATER, (ch->rxbufsize / 4), 0, 10, 0); - - /* Set receiver high water mark */ - fepcmd(ch, SRXHWATER, (3 * ch->rxbufsize / 4), 0, 10, 0); - - writew(100, &bc->edelay); - writeb(1, &bc->idata); - - ch->startc = readb(&bc->startc); - ch->stopc = readb(&bc->stopc); - ch->startca = readb(&bc->startca); - ch->stopca = readb(&bc->stopca); - - ch->fepcflag = 0; - ch->fepiflag = 0; - ch->fepoflag = 0; - ch->fepstartc = 0; - ch->fepstopc = 0; - ch->fepstartca = 0; - ch->fepstopca = 0; - - ch->port.close_delay = 50; - - spin_unlock_irqrestore(&epca_lock, flags); - } - - printk(KERN_INFO - "Digi PC/Xx Driver V%s: %s I/O = 0x%lx Mem = 0x%lx Ports = %d\n", - VERSION, board_desc[bd->type], (long)bd->port, - (long)bd->membase, bd->numports); - memwinoff(bd, 0); -} - -static void epcapoll(unsigned long ignored) -{ - unsigned long flags; - int crd; - unsigned int head, tail; - struct channel *ch; - struct board_info *bd; - - /* - * This routine is called upon every timer interrupt. Even though the - * Digi series cards are capable of generating interrupts this method - * of non-looping polling is more efficient. This routine checks for - * card generated events (Such as receive data, are transmit buffer - * empty) and acts on those events. - */ - for (crd = 0; crd < num_cards; crd++) { - bd = &boards[crd]; - ch = card_ptr[crd]; - - if ((bd->status == DISABLED) || digi_poller_inhibited) - continue; - - /* - * assertmemoff is not needed here; indeed it is an empty - * subroutine. It is being kept because future boards may need - * this as well as some legacy boards. - */ - spin_lock_irqsave(&epca_lock, flags); - - assertmemoff(ch); - - globalwinon(ch); - - /* - * In this case head and tail actually refer to the event queue - * not the transmit or receive queue. - */ - head = readw(&ch->mailbox->ein); - tail = readw(&ch->mailbox->eout); - - /* If head isn't equal to tail we have an event */ - if (head != tail) - doevent(crd); - memoff(ch); - - spin_unlock_irqrestore(&epca_lock, flags); - } /* End for each card */ - mod_timer(&epca_timer, jiffies + (HZ / 25)); -} - -static void doevent(int crd) -{ - void __iomem *eventbuf; - struct channel *ch, *chan0; - static struct tty_struct *tty; - struct board_info *bd; - struct board_chan __iomem *bc; - unsigned int tail, head; - int event, channel; - int mstat, lstat; - - /* - * This subroutine is called by epcapoll when an event is detected - * in the event queue. This routine responds to those events. - */ - bd = &boards[crd]; - - chan0 = card_ptr[crd]; - epcaassert(chan0 <= &digi_channels[nbdevs - 1], "ch out of range"); - assertgwinon(chan0); - while ((tail = readw(&chan0->mailbox->eout)) != - (head = readw(&chan0->mailbox->ein))) { - /* Begin while something in event queue */ - assertgwinon(chan0); - eventbuf = bd->re_map_membase + tail + ISTART; - /* Get the channel the event occurred on */ - channel = readb(eventbuf); - /* Get the actual event code that occurred */ - event = readb(eventbuf + 1); - /* - * The two assignments below get the current modem status - * (mstat) and the previous modem status (lstat). These are - * useful because an event could signal a change in modem - * signals itself. - */ - mstat = readb(eventbuf + 2); - lstat = readb(eventbuf + 3); - - ch = chan0 + channel; - if ((unsigned)channel >= bd->numports || !ch) { - if (channel >= bd->numports) - ch = chan0; - bc = ch->brdchan; - goto next; - } - - bc = ch->brdchan; - if (bc == NULL) - goto next; - - tty = tty_port_tty_get(&ch->port); - if (event & DATA_IND) { /* Begin DATA_IND */ - receive_data(ch, tty); - assertgwinon(ch); - } /* End DATA_IND */ - /* else *//* Fix for DCD transition missed bug */ - if (event & MODEMCHG_IND) { - /* A modem signal change has been indicated */ - ch->imodem = mstat; - if (test_bit(ASYNCB_CHECK_CD, &ch->port.flags)) { - /* We are now receiving dcd */ - if (mstat & ch->dcd) - wake_up_interruptible(&ch->port.open_wait); - else /* No dcd; hangup */ - pc_sched_event(ch, EPCA_EVENT_HANGUP); - } - } - if (tty) { - if (event & BREAK_IND) { - /* A break has been indicated */ - tty_insert_flip_char(tty, 0, TTY_BREAK); - tty_schedule_flip(tty); - } else if (event & LOWTX_IND) { - if (ch->statusflags & LOWWAIT) { - ch->statusflags &= ~LOWWAIT; - tty_wakeup(tty); - } - } else if (event & EMPTYTX_IND) { - /* This event is generated by - setup_empty_event */ - ch->statusflags &= ~TXBUSY; - if (ch->statusflags & EMPTYWAIT) { - ch->statusflags &= ~EMPTYWAIT; - tty_wakeup(tty); - } - } - tty_kref_put(tty); - } -next: - globalwinon(ch); - BUG_ON(!bc); - writew(1, &bc->idata); - writew((tail + 4) & (IMAX - ISTART - 4), &chan0->mailbox->eout); - globalwinon(chan0); - } /* End while something in event queue */ -} - -static void fepcmd(struct channel *ch, int cmd, int word_or_byte, - int byte2, int ncmds, int bytecmd) -{ - unchar __iomem *memaddr; - unsigned int head, cmdTail, cmdStart, cmdMax; - long count; - int n; - - /* This is the routine in which commands may be passed to the card. */ - - if (ch->board->status == DISABLED) - return; - assertgwinon(ch); - /* Remember head (As well as max) is just an offset not a base addr */ - head = readw(&ch->mailbox->cin); - /* cmdStart is a base address */ - cmdStart = readw(&ch->mailbox->cstart); - /* - * We do the addition below because we do not want a max pointer - * relative to cmdStart. We want a max pointer that points at the - * physical end of the command queue. - */ - cmdMax = (cmdStart + 4 + readw(&ch->mailbox->cmax)); - memaddr = ch->board->re_map_membase; - - if (head >= (cmdMax - cmdStart) || (head & 03)) { - printk(KERN_ERR "line %d: Out of range, cmd = %x, head = %x\n", - __LINE__, cmd, head); - printk(KERN_ERR "line %d: Out of range, cmdMax = %x, cmdStart = %x\n", - __LINE__, cmdMax, cmdStart); - return; - } - if (bytecmd) { - writeb(cmd, memaddr + head + cmdStart + 0); - writeb(ch->channelnum, memaddr + head + cmdStart + 1); - /* Below word_or_byte is bits to set */ - writeb(word_or_byte, memaddr + head + cmdStart + 2); - /* Below byte2 is bits to reset */ - writeb(byte2, memaddr + head + cmdStart + 3); - } else { - writeb(cmd, memaddr + head + cmdStart + 0); - writeb(ch->channelnum, memaddr + head + cmdStart + 1); - writeb(word_or_byte, memaddr + head + cmdStart + 2); - } - head = (head + 4) & (cmdMax - cmdStart - 4); - writew(head, &ch->mailbox->cin); - count = FEPTIMEOUT; - - for (;;) { - count--; - if (count == 0) { - printk(KERN_ERR " - Fep not responding in fepcmd()\n"); - return; - } - head = readw(&ch->mailbox->cin); - cmdTail = readw(&ch->mailbox->cout); - n = (head - cmdTail) & (cmdMax - cmdStart - 4); - /* - * Basically this will break when the FEP acknowledges the - * command by incrementing cmdTail (Making it equal to head). - */ - if (n <= ncmds * (sizeof(short) * 4)) - break; - } -} - -/* - * Digi products use fields in their channels structures that are very similar - * to the c_cflag and c_iflag fields typically found in UNIX termios - * structures. The below three routines allow mappings between these hardware - * "flags" and their respective Linux flags. - */ -static unsigned termios2digi_h(struct channel *ch, unsigned cflag) -{ - unsigned res = 0; - - if (cflag & CRTSCTS) { - ch->digiext.digi_flags |= (RTSPACE | CTSPACE); - res |= ((ch->m_cts) | (ch->m_rts)); - } - - if (ch->digiext.digi_flags & RTSPACE) - res |= ch->m_rts; - - if (ch->digiext.digi_flags & DTRPACE) - res |= ch->m_dtr; - - if (ch->digiext.digi_flags & CTSPACE) - res |= ch->m_cts; - - if (ch->digiext.digi_flags & DSRPACE) - res |= ch->dsr; - - if (ch->digiext.digi_flags & DCDPACE) - res |= ch->dcd; - - if (res & (ch->m_rts)) - ch->digiext.digi_flags |= RTSPACE; - - if (res & (ch->m_cts)) - ch->digiext.digi_flags |= CTSPACE; - - return res; -} - -static unsigned termios2digi_i(struct channel *ch, unsigned iflag) -{ - unsigned res = iflag & (IGNBRK | BRKINT | IGNPAR | PARMRK | - INPCK | ISTRIP | IXON | IXANY | IXOFF); - if (ch->digiext.digi_flags & DIGI_AIXON) - res |= IAIXON; - return res; -} - -static unsigned termios2digi_c(struct channel *ch, unsigned cflag) -{ - unsigned res = 0; - if (cflag & CBAUDEX) { - ch->digiext.digi_flags |= DIGI_FAST; - /* - * HUPCL bit is used by FEP to indicate fast baud table is to - * be used. - */ - res |= FEP_HUPCL; - } else - ch->digiext.digi_flags &= ~DIGI_FAST; - /* - * CBAUD has bit position 0x1000 set these days to indicate Linux - * baud rate remap. Digi hardware can't handle the bit assignment. - * (We use a different bit assignment for high speed.). Clear this - * bit out. - */ - res |= cflag & ((CBAUD ^ CBAUDEX) | PARODD | PARENB | CSTOPB | CSIZE); - /* - * This gets a little confusing. The Digi cards have their own - * representation of c_cflags controlling baud rate. For the most part - * this is identical to the Linux implementation. However; Digi - * supports one rate (76800) that Linux doesn't. This means that the - * c_cflag entry that would normally mean 76800 for Digi actually means - * 115200 under Linux. Without the below mapping, a stty 115200 would - * only drive the board at 76800. Since the rate 230400 is also found - * after 76800, the same problem afflicts us when we choose a rate of - * 230400. Without the below modificiation stty 230400 would actually - * give us 115200. - * - * There are two additional differences. The Linux value for CLOCAL - * (0x800; 0004000) has no meaning to the Digi hardware. Also in later - * releases of Linux; the CBAUD define has CBAUDEX (0x1000; 0010000) - * ored into it (CBAUD = 0x100f as opposed to 0xf). CBAUDEX should be - * checked for a screened out prior to termios2digi_c returning. Since - * CLOCAL isn't used by the board this can be ignored as long as the - * returned value is used only by Digi hardware. - */ - if (cflag & CBAUDEX) { - /* - * The below code is trying to guarantee that only baud rates - * 115200 and 230400 are remapped. We use exclusive or because - * the various baud rates share common bit positions and - * therefore can't be tested for easily. - */ - if ((!((cflag & 0x7) ^ (B115200 & ~CBAUDEX))) || - (!((cflag & 0x7) ^ (B230400 & ~CBAUDEX)))) - res += 1; - } - return res; -} - -/* Caller must hold the locks */ -static void epcaparam(struct tty_struct *tty, struct channel *ch) -{ - unsigned int cmdHead; - struct ktermios *ts; - struct board_chan __iomem *bc; - unsigned mval, hflow, cflag, iflag; - - bc = ch->brdchan; - epcaassert(bc != NULL, "bc out of range"); - - assertgwinon(ch); - ts = tty->termios; - if ((ts->c_cflag & CBAUD) == 0) { /* Begin CBAUD detected */ - cmdHead = readw(&bc->rin); - writew(cmdHead, &bc->rout); - cmdHead = readw(&bc->tin); - /* Changing baud in mid-stream transmission can be wonderful */ - /* - * Flush current transmit buffer by setting cmdTail pointer - * (tout) to cmdHead pointer (tin). Hopefully the transmit - * buffer is empty. - */ - fepcmd(ch, STOUT, (unsigned) cmdHead, 0, 0, 0); - mval = 0; - } else { /* Begin CBAUD not detected */ - /* - * c_cflags have changed but that change had nothing to do with - * BAUD. Propagate the change to the card. - */ - cflag = termios2digi_c(ch, ts->c_cflag); - if (cflag != ch->fepcflag) { - ch->fepcflag = cflag; - /* Set baud rate, char size, stop bits, parity */ - fepcmd(ch, SETCTRLFLAGS, (unsigned) cflag, 0, 0, 0); - } - /* - * If the user has not forced CLOCAL and if the device is not a - * CALLOUT device (Which is always CLOCAL) we set flags such - * that the driver will wait on carrier detect. - */ - if (ts->c_cflag & CLOCAL) - clear_bit(ASYNCB_CHECK_CD, &ch->port.flags); - else - set_bit(ASYNCB_CHECK_CD, &ch->port.flags); - mval = ch->m_dtr | ch->m_rts; - } /* End CBAUD not detected */ - iflag = termios2digi_i(ch, ts->c_iflag); - /* Check input mode flags */ - if (iflag != ch->fepiflag) { - ch->fepiflag = iflag; - /* - * Command sets channels iflag structure on the board. Such - * things as input soft flow control, handling of parity - * errors, and break handling are all set here. - * - * break handling, parity handling, input stripping, - * flow control chars - */ - fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0); - } - /* - * Set the board mint value for this channel. This will cause hardware - * events to be generated each time the DCD signal (Described in mint) - * changes. - */ - writeb(ch->dcd, &bc->mint); - if ((ts->c_cflag & CLOCAL) || (ch->digiext.digi_flags & DIGI_FORCEDCD)) - if (ch->digiext.digi_flags & DIGI_FORCEDCD) - writeb(0, &bc->mint); - ch->imodem = readb(&bc->mstat); - hflow = termios2digi_h(ch, ts->c_cflag); - if (hflow != ch->hflow) { - ch->hflow = hflow; - /* - * Hard flow control has been selected but the board is not - * using it. Activate hard flow control now. - */ - fepcmd(ch, SETHFLOW, hflow, 0xff, 0, 1); - } - mval ^= ch->modemfake & (mval ^ ch->modem); - - if (ch->omodem ^ mval) { - ch->omodem = mval; - /* - * The below command sets the DTR and RTS mstat structure. If - * hard flow control is NOT active these changes will drive the - * output of the actual DTR and RTS lines. If hard flow control - * is active, the changes will be saved in the mstat structure - * and only asserted when hard flow control is turned off. - */ - - /* First reset DTR & RTS; then set them */ - fepcmd(ch, SETMODEM, 0, ((ch->m_dtr)|(ch->m_rts)), 0, 1); - fepcmd(ch, SETMODEM, mval, 0, 0, 1); - } - if (ch->startc != ch->fepstartc || ch->stopc != ch->fepstopc) { - ch->fepstartc = ch->startc; - ch->fepstopc = ch->stopc; - /* - * The XON / XOFF characters have changed; propagate these - * changes to the card. - */ - fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1); - } - if (ch->startca != ch->fepstartca || ch->stopca != ch->fepstopca) { - ch->fepstartca = ch->startca; - ch->fepstopca = ch->stopca; - /* - * Similar to the above, this time the auxilarly XON / XOFF - * characters have changed; propagate these changes to the card. - */ - fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1); - } -} - -/* Caller holds lock */ -static void receive_data(struct channel *ch, struct tty_struct *tty) -{ - unchar *rptr; - struct ktermios *ts = NULL; - struct board_chan __iomem *bc; - int dataToRead, wrapgap, bytesAvailable; - unsigned int tail, head; - unsigned int wrapmask; - - /* - * This routine is called by doint when a receive data event has taken - * place. - */ - globalwinon(ch); - if (ch->statusflags & RXSTOPPED) - return; - if (tty) - ts = tty->termios; - bc = ch->brdchan; - BUG_ON(!bc); - wrapmask = ch->rxbufsize - 1; - - /* - * Get the head and tail pointers to the receiver queue. Wrap the head - * pointer if it has reached the end of the buffer. - */ - head = readw(&bc->rin); - head &= wrapmask; - tail = readw(&bc->rout) & wrapmask; - - bytesAvailable = (head - tail) & wrapmask; - if (bytesAvailable == 0) - return; - - /* If CREAD bit is off or device not open, set TX tail to head */ - if (!tty || !ts || !(ts->c_cflag & CREAD)) { - writew(head, &bc->rout); - return; - } - - if (tty_buffer_request_room(tty, bytesAvailable + 1) == 0) - return; - - if (readb(&bc->orun)) { - writeb(0, &bc->orun); - printk(KERN_WARNING "epca; overrun! DigiBoard device %s\n", - tty->name); - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - rxwinon(ch); - while (bytesAvailable > 0) { - /* Begin while there is data on the card */ - wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail; - /* - * Even if head has wrapped around only report the amount of - * data to be equal to the size - tail. Remember memcpy can't - * automatically wrap around the receive buffer. - */ - dataToRead = (wrapgap < bytesAvailable) ? wrapgap - : bytesAvailable; - /* Make sure we don't overflow the buffer */ - dataToRead = tty_prepare_flip_string(tty, &rptr, dataToRead); - if (dataToRead == 0) - break; - /* - * Move data read from our card into the line disciplines - * buffer for translation if necessary. - */ - memcpy_fromio(rptr, ch->rxptr + tail, dataToRead); - tail = (tail + dataToRead) & wrapmask; - bytesAvailable -= dataToRead; - } /* End while there is data on the card */ - globalwinon(ch); - writew(tail, &bc->rout); - /* Must be called with global data */ - tty_schedule_flip(tty); -} - -static int info_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case DIGI_GETINFO: - { - struct digi_info di; - int brd; - - if (get_user(brd, (unsigned int __user *)arg)) - return -EFAULT; - if (brd < 0 || brd >= num_cards || num_cards == 0) - return -ENODEV; - - memset(&di, 0, sizeof(di)); - - di.board = brd; - di.status = boards[brd].status; - di.type = boards[brd].type ; - di.numports = boards[brd].numports ; - /* Legacy fixups - just move along nothing to see */ - di.port = (unsigned char *)boards[brd].port ; - di.membase = (unsigned char *)boards[brd].membase ; - - if (copy_to_user((void __user *)arg, &di, sizeof(di))) - return -EFAULT; - break; - - } - - case DIGI_POLLER: - { - int brd = arg & 0xff000000 >> 16; - unsigned char state = arg & 0xff; - - if (brd < 0 || brd >= num_cards) { - printk(KERN_ERR "epca: DIGI POLLER : brd not valid!\n"); - return -ENODEV; - } - digi_poller_inhibited = state; - break; - } - - case DIGI_INIT: - { - /* - * This call is made by the apps to complete the - * initialization of the board(s). This routine is - * responsible for setting the card to its initial - * state and setting the drivers control fields to the - * sutianle settings for the card in question. - */ - int crd; - for (crd = 0; crd < num_cards; crd++) - post_fep_init(crd); - break; - } - default: - return -ENOTTY; - } - return 0; -} - -static int pc_tiocmget(struct tty_struct *tty) -{ - struct channel *ch = tty->driver_data; - struct board_chan __iomem *bc; - unsigned int mstat, mflag = 0; - unsigned long flags; - - if (ch) - bc = ch->brdchan; - else - return -EINVAL; - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - mstat = readb(&bc->mstat); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - - if (mstat & ch->m_dtr) - mflag |= TIOCM_DTR; - if (mstat & ch->m_rts) - mflag |= TIOCM_RTS; - if (mstat & ch->m_cts) - mflag |= TIOCM_CTS; - if (mstat & ch->dsr) - mflag |= TIOCM_DSR; - if (mstat & ch->m_ri) - mflag |= TIOCM_RI; - if (mstat & ch->dcd) - mflag |= TIOCM_CD; - return mflag; -} - -static int pc_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct channel *ch = tty->driver_data; - unsigned long flags; - - if (!ch) - return -EINVAL; - - spin_lock_irqsave(&epca_lock, flags); - /* - * I think this modemfake stuff is broken. It doesn't correctly reflect - * the behaviour desired by the TIOCM* ioctls. Therefore this is - * probably broken. - */ - if (set & TIOCM_RTS) { - ch->modemfake |= ch->m_rts; - ch->modem |= ch->m_rts; - } - if (set & TIOCM_DTR) { - ch->modemfake |= ch->m_dtr; - ch->modem |= ch->m_dtr; - } - if (clear & TIOCM_RTS) { - ch->modemfake |= ch->m_rts; - ch->modem &= ~ch->m_rts; - } - if (clear & TIOCM_DTR) { - ch->modemfake |= ch->m_dtr; - ch->modem &= ~ch->m_dtr; - } - globalwinon(ch); - /* - * The below routine generally sets up parity, baud, flow control - * issues, etc.... It effect both control flags and input flags. - */ - epcaparam(tty, ch); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - return 0; -} - -static int pc_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - digiflow_t dflow; - unsigned long flags; - unsigned int mflag, mstat; - unsigned char startc, stopc; - struct board_chan __iomem *bc; - struct channel *ch = tty->driver_data; - void __user *argp = (void __user *)arg; - - if (ch) - bc = ch->brdchan; - else - return -EINVAL; - switch (cmd) { - case TIOCMODG: - mflag = pc_tiocmget(tty); - if (put_user(mflag, (unsigned long __user *)argp)) - return -EFAULT; - break; - case TIOCMODS: - if (get_user(mstat, (unsigned __user *)argp)) - return -EFAULT; - return pc_tiocmset(tty, mstat, ~mstat); - case TIOCSDTR: - spin_lock_irqsave(&epca_lock, flags); - ch->omodem |= ch->m_dtr; - globalwinon(ch); - fepcmd(ch, SETMODEM, ch->m_dtr, 0, 10, 1); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - break; - - case TIOCCDTR: - spin_lock_irqsave(&epca_lock, flags); - ch->omodem &= ~ch->m_dtr; - globalwinon(ch); - fepcmd(ch, SETMODEM, 0, ch->m_dtr, 10, 1); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - break; - case DIGI_GETA: - if (copy_to_user(argp, &ch->digiext, sizeof(digi_t))) - return -EFAULT; - break; - case DIGI_SETAW: - case DIGI_SETAF: - if (cmd == DIGI_SETAW) { - /* Setup an event to indicate when the transmit - buffer empties */ - spin_lock_irqsave(&epca_lock, flags); - setup_empty_event(tty, ch); - spin_unlock_irqrestore(&epca_lock, flags); - tty_wait_until_sent(tty, 0); - } else { - /* ldisc lock already held in ioctl */ - if (tty->ldisc->ops->flush_buffer) - tty->ldisc->ops->flush_buffer(tty); - } - /* Fall Thru */ - case DIGI_SETA: - if (copy_from_user(&ch->digiext, argp, sizeof(digi_t))) - return -EFAULT; - - if (ch->digiext.digi_flags & DIGI_ALTPIN) { - ch->dcd = ch->m_dsr; - ch->dsr = ch->m_dcd; - } else { - ch->dcd = ch->m_dcd; - ch->dsr = ch->m_dsr; - } - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - - /* - * The below routine generally sets up parity, baud, flow - * control issues, etc.... It effect both control flags and - * input flags. - */ - epcaparam(tty, ch); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - break; - - case DIGI_GETFLOW: - case DIGI_GETAFLOW: - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - if (cmd == DIGI_GETFLOW) { - dflow.startc = readb(&bc->startc); - dflow.stopc = readb(&bc->stopc); - } else { - dflow.startc = readb(&bc->startca); - dflow.stopc = readb(&bc->stopca); - } - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - - if (copy_to_user(argp, &dflow, sizeof(dflow))) - return -EFAULT; - break; - - case DIGI_SETAFLOW: - case DIGI_SETFLOW: - if (cmd == DIGI_SETFLOW) { - startc = ch->startc; - stopc = ch->stopc; - } else { - startc = ch->startca; - stopc = ch->stopca; - } - - if (copy_from_user(&dflow, argp, sizeof(dflow))) - return -EFAULT; - - if (dflow.startc != startc || dflow.stopc != stopc) { - /* Begin if setflow toggled */ - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - - if (cmd == DIGI_SETFLOW) { - ch->fepstartc = ch->startc = dflow.startc; - ch->fepstopc = ch->stopc = dflow.stopc; - fepcmd(ch, SONOFFC, ch->fepstartc, - ch->fepstopc, 0, 1); - } else { - ch->fepstartca = ch->startca = dflow.startc; - ch->fepstopca = ch->stopca = dflow.stopc; - fepcmd(ch, SAUXONOFFC, ch->fepstartca, - ch->fepstopca, 0, 1); - } - - if (ch->statusflags & TXSTOPPED) - pc_start(tty); - - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - } /* End if setflow toggled */ - break; - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - struct channel *ch; - unsigned long flags; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - - if (ch != NULL) { /* Begin if channel valid */ - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - epcaparam(tty, ch); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - - if ((old_termios->c_cflag & CRTSCTS) && - ((tty->termios->c_cflag & CRTSCTS) == 0)) - tty->hw_stopped = 0; - - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&ch->port.open_wait); - - } /* End if channel valid */ -} - -static void do_softint(struct work_struct *work) -{ - struct channel *ch = container_of(work, struct channel, tqueue); - /* Called in response to a modem change event */ - if (ch && ch->magic == EPCA_MAGIC) { - struct tty_struct *tty = tty_port_tty_get(&ch->port); - - if (tty && tty->driver_data) { - if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) { - tty_hangup(tty); - wake_up_interruptible(&ch->port.open_wait); - clear_bit(ASYNCB_NORMAL_ACTIVE, - &ch->port.flags); - } - } - tty_kref_put(tty); - } -} - -/* - * pc_stop and pc_start provide software flow control to the routine and the - * pc_ioctl routine. - */ -static void pc_stop(struct tty_struct *tty) -{ - struct channel *ch; - unsigned long flags; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - spin_lock_irqsave(&epca_lock, flags); - if ((ch->statusflags & TXSTOPPED) == 0) { - /* Begin if transmit stop requested */ - globalwinon(ch); - /* STOP transmitting now !! */ - fepcmd(ch, PAUSETX, 0, 0, 0, 0); - ch->statusflags |= TXSTOPPED; - memoff(ch); - } /* End if transmit stop requested */ - spin_unlock_irqrestore(&epca_lock, flags); - } -} - -static void pc_start(struct tty_struct *tty) -{ - struct channel *ch; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - unsigned long flags; - spin_lock_irqsave(&epca_lock, flags); - /* Just in case output was resumed because of a change - in Digi-flow */ - if (ch->statusflags & TXSTOPPED) { - /* Begin transmit resume requested */ - struct board_chan __iomem *bc; - globalwinon(ch); - bc = ch->brdchan; - if (ch->statusflags & LOWWAIT) - writeb(1, &bc->ilow); - /* Okay, you can start transmitting again... */ - fepcmd(ch, RESUMETX, 0, 0, 0, 0); - ch->statusflags &= ~TXSTOPPED; - memoff(ch); - } /* End transmit resume requested */ - spin_unlock_irqrestore(&epca_lock, flags); - } -} - -/* - * The below routines pc_throttle and pc_unthrottle are used to slow (And - * resume) the receipt of data into the kernels receive buffers. The exact - * occurrence of this depends on the size of the kernels receive buffer and - * what the 'watermarks' are set to for that buffer. See the n_ttys.c file for - * more details. - */ -static void pc_throttle(struct tty_struct *tty) -{ - struct channel *ch; - unsigned long flags; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - spin_lock_irqsave(&epca_lock, flags); - if ((ch->statusflags & RXSTOPPED) == 0) { - globalwinon(ch); - fepcmd(ch, PAUSERX, 0, 0, 0, 0); - ch->statusflags |= RXSTOPPED; - memoff(ch); - } - spin_unlock_irqrestore(&epca_lock, flags); - } -} - -static void pc_unthrottle(struct tty_struct *tty) -{ - struct channel *ch; - unsigned long flags; - /* - * verifyChannel returns the channel from the tty struct if it is - * valid. This serves as a sanity check. - */ - ch = verifyChannel(tty); - if (ch != NULL) { - /* Just in case output was resumed because of a change - in Digi-flow */ - spin_lock_irqsave(&epca_lock, flags); - if (ch->statusflags & RXSTOPPED) { - globalwinon(ch); - fepcmd(ch, RESUMERX, 0, 0, 0, 0); - ch->statusflags &= ~RXSTOPPED; - memoff(ch); - } - spin_unlock_irqrestore(&epca_lock, flags); - } -} - -static int pc_send_break(struct tty_struct *tty, int msec) -{ - struct channel *ch = tty->driver_data; - unsigned long flags; - - if (msec == -1) - msec = 0xFFFF; - else if (msec > 0xFFFE) - msec = 0xFFFE; - else if (msec < 1) - msec = 1; - - spin_lock_irqsave(&epca_lock, flags); - globalwinon(ch); - /* - * Maybe I should send an infinite break here, schedule() for msec - * amount of time, and then stop the break. This way, the user can't - * screw up the FEP by causing digi_send_break() to be called (i.e. via - * an ioctl()) more than once in msec amount of time. - * Try this for now... - */ - fepcmd(ch, SENDBREAK, msec, 0, 10, 0); - memoff(ch); - spin_unlock_irqrestore(&epca_lock, flags); - return 0; -} - -/* Caller MUST hold the lock */ -static void setup_empty_event(struct tty_struct *tty, struct channel *ch) -{ - struct board_chan __iomem *bc = ch->brdchan; - - globalwinon(ch); - ch->statusflags |= EMPTYWAIT; - /* - * When set the iempty flag request a event to be generated when the - * transmit buffer is empty (If there is no BREAK in progress). - */ - writeb(1, &bc->iempty); - memoff(ch); -} - -#ifndef MODULE -static void __init epca_setup(char *str, int *ints) -{ - struct board_info board; - int index, loop, last; - char *temp, *t2; - unsigned len; - - /* - * If this routine looks a little strange it is because it is only - * called if a LILO append command is given to boot the kernel with - * parameters. In this way, we can provide the user a method of - * changing his board configuration without rebuilding the kernel. - */ - if (!liloconfig) - liloconfig = 1; - - memset(&board, 0, sizeof(board)); - - /* Assume the data is int first, later we can change it */ - /* I think that array position 0 of ints holds the number of args */ - for (last = 0, index = 1; index <= ints[0]; index++) - switch (index) { /* Begin parse switch */ - case 1: - board.status = ints[index]; - /* - * We check for 2 (As opposed to 1; because 2 is a flag - * instructing the driver to ignore epcaconfig.) For - * this reason we check for 2. - */ - if (board.status == 2) { - /* Begin ignore epcaconfig as well as lilo cmd line */ - nbdevs = 0; - num_cards = 0; - return; - } /* End ignore epcaconfig as well as lilo cmd line */ - - if (board.status > 2) { - printk(KERN_ERR "epca_setup: Invalid board status 0x%x\n", - board.status); - invalid_lilo_config = 1; - setup_error_code |= INVALID_BOARD_STATUS; - return; - } - last = index; - break; - case 2: - board.type = ints[index]; - if (board.type >= PCIXEM) { - printk(KERN_ERR "epca_setup: Invalid board type 0x%x\n", board.type); - invalid_lilo_config = 1; - setup_error_code |= INVALID_BOARD_TYPE; - return; - } - last = index; - break; - case 3: - board.altpin = ints[index]; - if (board.altpin > 1) { - printk(KERN_ERR "epca_setup: Invalid board altpin 0x%x\n", board.altpin); - invalid_lilo_config = 1; - setup_error_code |= INVALID_ALTPIN; - return; - } - last = index; - break; - - case 4: - board.numports = ints[index]; - if (board.numports < 2 || board.numports > 256) { - printk(KERN_ERR "epca_setup: Invalid board numports 0x%x\n", board.numports); - invalid_lilo_config = 1; - setup_error_code |= INVALID_NUM_PORTS; - return; - } - nbdevs += board.numports; - last = index; - break; - - case 5: - board.port = ints[index]; - if (ints[index] <= 0) { - printk(KERN_ERR "epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port); - invalid_lilo_config = 1; - setup_error_code |= INVALID_PORT_BASE; - return; - } - last = index; - break; - - case 6: - board.membase = ints[index]; - if (ints[index] <= 0) { - printk(KERN_ERR "epca_setup: Invalid memory base 0x%x\n", - (unsigned int)board.membase); - invalid_lilo_config = 1; - setup_error_code |= INVALID_MEM_BASE; - return; - } - last = index; - break; - - default: - printk(KERN_ERR " - epca_setup: Too many integer parms\n"); - return; - - } /* End parse switch */ - - while (str && *str) { /* Begin while there is a string arg */ - /* find the next comma or terminator */ - temp = str; - /* While string is not null, and a comma hasn't been found */ - while (*temp && (*temp != ',')) - temp++; - if (!*temp) - temp = NULL; - else - *temp++ = 0; - /* Set index to the number of args + 1 */ - index = last + 1; - - switch (index) { - case 1: - len = strlen(str); - if (strncmp("Disable", str, len) == 0) - board.status = 0; - else if (strncmp("Enable", str, len) == 0) - board.status = 1; - else { - printk(KERN_ERR "epca_setup: Invalid status %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_BOARD_STATUS; - return; - } - last = index; - break; - - case 2: - for (loop = 0; loop < EPCA_NUM_TYPES; loop++) - if (strcmp(board_desc[loop], str) == 0) - break; - /* - * If the index incremented above refers to a - * legitimate board type set it here. - */ - if (index < EPCA_NUM_TYPES) - board.type = loop; - else { - printk(KERN_ERR "epca_setup: Invalid board type: %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_BOARD_TYPE; - return; - } - last = index; - break; - - case 3: - len = strlen(str); - if (strncmp("Disable", str, len) == 0) - board.altpin = 0; - else if (strncmp("Enable", str, len) == 0) - board.altpin = 1; - else { - printk(KERN_ERR "epca_setup: Invalid altpin %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_ALTPIN; - return; - } - last = index; - break; - - case 4: - t2 = str; - while (isdigit(*t2)) - t2++; - - if (*t2) { - printk(KERN_ERR "epca_setup: Invalid port count %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_NUM_PORTS; - return; - } - - /* - * There is not a man page for simple_strtoul but the - * code can be found in vsprintf.c. The first argument - * is the string to translate (To an unsigned long - * obviously), the second argument can be the address - * of any character variable or a NULL. If a variable - * is given, the end pointer of the string will be - * stored in that variable; if a NULL is given the end - * pointer will not be returned. The last argument is - * the base to use. If a 0 is indicated, the routine - * will attempt to determine the proper base by looking - * at the values prefix (A '0' for octal, a 'x' for - * hex, etc ... If a value is given it will use that - * value as the base. - */ - board.numports = simple_strtoul(str, NULL, 0); - nbdevs += board.numports; - last = index; - break; - - case 5: - t2 = str; - while (isxdigit(*t2)) - t2++; - - if (*t2) { - printk(KERN_ERR "epca_setup: Invalid i/o address %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_PORT_BASE; - return; - } - - board.port = simple_strtoul(str, NULL, 16); - last = index; - break; - - case 6: - t2 = str; - while (isxdigit(*t2)) - t2++; - - if (*t2) { - printk(KERN_ERR "epca_setup: Invalid memory base %s\n", str); - invalid_lilo_config = 1; - setup_error_code |= INVALID_MEM_BASE; - return; - } - board.membase = simple_strtoul(str, NULL, 16); - last = index; - break; - default: - printk(KERN_ERR "epca: Too many string parms\n"); - return; - } - str = temp; - } /* End while there is a string arg */ - - if (last < 6) { - printk(KERN_ERR "epca: Insufficient parms specified\n"); - return; - } - - /* I should REALLY validate the stuff here */ - /* Copies our local copy of board into boards */ - memcpy((void *)&boards[num_cards], (void *)&board, sizeof(board)); - /* Does this get called once per lilo arg are what ? */ - printk(KERN_INFO "PC/Xx: Added board %i, %s %i ports at 0x%4.4X base 0x%6.6X\n", - num_cards, board_desc[board.type], - board.numports, (int)board.port, (unsigned int) board.membase); - num_cards++; -} - -static int __init epca_real_setup(char *str) -{ - int ints[11]; - - epca_setup(get_options(str, 11, ints), ints); - return 1; -} - -__setup("digiepca", epca_real_setup); -#endif - -enum epic_board_types { - brd_xr = 0, - brd_xem, - brd_cx, - brd_xrj, -}; - -/* indexed directly by epic_board_types enum */ -static struct { - unsigned char board_type; - unsigned bar_idx; /* PCI base address region */ -} epca_info_tbl[] = { - { PCIXR, 0, }, - { PCIXEM, 0, }, - { PCICX, 0, }, - { PCIXRJ, 2, }, -}; - -static int __devinit epca_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - static int board_num = -1; - int board_idx, info_idx = ent->driver_data; - unsigned long addr; - - if (pci_enable_device(pdev)) - return -EIO; - - board_num++; - board_idx = board_num + num_cards; - if (board_idx >= MAXBOARDS) - goto err_out; - - addr = pci_resource_start(pdev, epca_info_tbl[info_idx].bar_idx); - if (!addr) { - printk(KERN_ERR PFX "PCI region #%d not available (size 0)\n", - epca_info_tbl[info_idx].bar_idx); - goto err_out; - } - - boards[board_idx].status = ENABLED; - boards[board_idx].type = epca_info_tbl[info_idx].board_type; - boards[board_idx].numports = 0x0; - boards[board_idx].port = addr + PCI_IO_OFFSET; - boards[board_idx].membase = addr; - - if (!request_mem_region(addr + PCI_IO_OFFSET, 0x200000, "epca")) { - printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", - 0x200000, addr + PCI_IO_OFFSET); - goto err_out; - } - - boards[board_idx].re_map_port = ioremap_nocache(addr + PCI_IO_OFFSET, - 0x200000); - if (!boards[board_idx].re_map_port) { - printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", - 0x200000, addr + PCI_IO_OFFSET); - goto err_out_free_pciio; - } - - if (!request_mem_region(addr, 0x200000, "epca")) { - printk(KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", - 0x200000, addr); - goto err_out_free_iounmap; - } - - boards[board_idx].re_map_membase = ioremap_nocache(addr, 0x200000); - if (!boards[board_idx].re_map_membase) { - printk(KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", - 0x200000, addr + PCI_IO_OFFSET); - goto err_out_free_memregion; - } - - /* - * I don't know what the below does, but the hardware guys say its - * required on everything except PLX (In this case XRJ). - */ - if (info_idx != brd_xrj) { - pci_write_config_byte(pdev, 0x40, 0); - pci_write_config_byte(pdev, 0x46, 0); - } - - return 0; - -err_out_free_memregion: - release_mem_region(addr, 0x200000); -err_out_free_iounmap: - iounmap(boards[board_idx].re_map_port); -err_out_free_pciio: - release_mem_region(addr + PCI_IO_OFFSET, 0x200000); -err_out: - return -ENODEV; -} - - -static struct pci_device_id epca_pci_tbl[] = { - { PCI_VENDOR_DIGI, PCI_DEVICE_XR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xr }, - { PCI_VENDOR_DIGI, PCI_DEVICE_XEM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xem }, - { PCI_VENDOR_DIGI, PCI_DEVICE_CX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_cx }, - { PCI_VENDOR_DIGI, PCI_DEVICE_XRJ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xrj }, - { 0, } -}; - -MODULE_DEVICE_TABLE(pci, epca_pci_tbl); - -static int __init init_PCI(void) -{ - memset(&epca_driver, 0, sizeof(epca_driver)); - epca_driver.name = "epca"; - epca_driver.id_table = epca_pci_tbl; - epca_driver.probe = epca_init_one; - - return pci_register_driver(&epca_driver); -} - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/tty/epca.h b/drivers/staging/tty/epca.h deleted file mode 100644 index d414bf2dbf7c..000000000000 --- a/drivers/staging/tty/epca.h +++ /dev/null @@ -1,158 +0,0 @@ -#define XEMPORTS 0xC02 -#define XEPORTS 0xC22 - -#define MAX_ALLOC 0x100 - -#define MAXBOARDS 12 -#define FEPCODESEG 0x0200L -#define FEPCODE 0x2000L -#define BIOSCODE 0xf800L - -#define MISCGLOBAL 0x0C00L -#define NPORT 0x0C22L -#define MBOX 0x0C40L -#define PORTBASE 0x0C90L - -/* Begin code defines used for epca_setup */ - -#define INVALID_BOARD_TYPE 0x1 -#define INVALID_NUM_PORTS 0x2 -#define INVALID_MEM_BASE 0x4 -#define INVALID_PORT_BASE 0x8 -#define INVALID_BOARD_STATUS 0x10 -#define INVALID_ALTPIN 0x20 - -/* End code defines used for epca_setup */ - - -#define FEPCLR 0x00 -#define FEPMEM 0x02 -#define FEPRST 0x04 -#define FEPINT 0x08 -#define FEPMASK 0x0e -#define FEPWIN 0x80 - -#define PCXE 0 -#define PCXEVE 1 -#define PCXEM 2 -#define EISAXEM 3 -#define PC64XE 4 -#define PCXI 5 -#define PCIXEM 7 -#define PCICX 8 -#define PCIXR 9 -#define PCIXRJ 10 -#define EPCA_NUM_TYPES 6 - - -static char *board_desc[] = -{ - "PC/Xe", - "PC/Xeve", - "PC/Xem", - "EISA/Xem", - "PC/64Xe", - "PC/Xi", - "unknown", - "PCI/Xem", - "PCI/CX", - "PCI/Xr", - "PCI/Xrj", -}; - -#define STARTC 021 -#define STOPC 023 -#define IAIXON 0x2000 - - -#define TXSTOPPED 0x1 -#define LOWWAIT 0x2 -#define EMPTYWAIT 0x4 -#define RXSTOPPED 0x8 -#define TXBUSY 0x10 - -#define DISABLED 0 -#define ENABLED 1 -#define OFF 0 -#define ON 1 - -#define FEPTIMEOUT 200000 -#define SERIAL_TYPE_INFO 3 -#define EPCA_EVENT_HANGUP 1 -#define EPCA_MAGIC 0x5c6df104L - -struct channel -{ - long magic; - struct tty_port port; - unsigned char boardnum; - unsigned char channelnum; - unsigned char omodem; /* FEP output modem status */ - unsigned char imodem; /* FEP input modem status */ - unsigned char modemfake; /* Modem values to be forced */ - unsigned char modem; /* Force values */ - unsigned char hflow; - unsigned char dsr; - unsigned char dcd; - unsigned char m_rts ; /* The bits used in whatever FEP */ - unsigned char m_dcd ; /* is indiginous to this board to */ - unsigned char m_dsr ; /* represent each of the physical */ - unsigned char m_cts ; /* handshake lines */ - unsigned char m_ri ; - unsigned char m_dtr ; - unsigned char stopc; - unsigned char startc; - unsigned char stopca; - unsigned char startca; - unsigned char fepstopc; - unsigned char fepstartc; - unsigned char fepstopca; - unsigned char fepstartca; - unsigned char txwin; - unsigned char rxwin; - unsigned short fepiflag; - unsigned short fepcflag; - unsigned short fepoflag; - unsigned short txbufhead; - unsigned short txbufsize; - unsigned short rxbufhead; - unsigned short rxbufsize; - int close_delay; - unsigned long event; - uint dev; - unsigned long statusflags; - unsigned long c_iflag; - unsigned long c_cflag; - unsigned long c_lflag; - unsigned long c_oflag; - unsigned char __iomem *txptr; - unsigned char __iomem *rxptr; - struct board_info *board; - struct board_chan __iomem *brdchan; - struct digi_struct digiext; - struct work_struct tqueue; - struct global_data __iomem *mailbox; -}; - -struct board_info -{ - unsigned char status; - unsigned char type; - unsigned char altpin; - unsigned short numports; - unsigned long port; - unsigned long membase; - void __iomem *re_map_port; - void __iomem *re_map_membase; - unsigned long memory_seg; - void ( * memwinon ) (struct board_info *, unsigned int) ; - void ( * memwinoff ) (struct board_info *, unsigned int) ; - void ( * globalwinon ) (struct channel *) ; - void ( * txwinon ) (struct channel *) ; - void ( * rxwinon ) (struct channel *) ; - void ( * memoff ) (struct channel *) ; - void ( * assertgwinon ) (struct channel *) ; - void ( * assertmemoff ) (struct channel *) ; - unsigned char poller_inhibited ; -}; - diff --git a/drivers/staging/tty/epcaconfig.h b/drivers/staging/tty/epcaconfig.h deleted file mode 100644 index 55dec067078e..000000000000 --- a/drivers/staging/tty/epcaconfig.h +++ /dev/null @@ -1,7 +0,0 @@ -#define NUMCARDS 0 -#define NBDEVS 0 - -struct board_info static_boards[NUMCARDS]={ -}; - -/* DO NOT HAND EDIT THIS FILE! */ diff --git a/drivers/staging/tty/ip2/Makefile b/drivers/staging/tty/ip2/Makefile deleted file mode 100644 index 7b78e0dfc5b0..000000000000 --- a/drivers/staging/tty/ip2/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for the Computone IntelliPort Plus Driver -# - -obj-$(CONFIG_COMPUTONE) += ip2.o - -ip2-y := ip2main.o - diff --git a/drivers/staging/tty/ip2/i2cmd.c b/drivers/staging/tty/ip2/i2cmd.c deleted file mode 100644 index e7af647800b6..000000000000 --- a/drivers/staging/tty/ip2/i2cmd.c +++ /dev/null @@ -1,210 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Definition table for In-line and Bypass commands. Applicable -* only when the standard loadware is active. (This is included -* source code, not a separate compilation module.) -* -*******************************************************************************/ - -//------------------------------------------------------------------------------ -// -// Revision History: -// -// 10 October 1991 MAG First Draft -// 7 November 1991 MAG Reflects additional commands. -// 24 February 1992 MAG Additional commands for 1.4.x loadware -// 11 March 1992 MAG Additional commands -// 30 March 1992 MAG Additional command: CMD_DSS_NOW -// 18 May 1992 MAG Discovered commands 39 & 40 must be at the end of a -// packet: affects implementation. -//------------------------------------------------------------------------------ - -//************ -//* Includes * -//************ - -#include "i2cmd.h" /* To get some bit-defines */ - -//------------------------------------------------------------------------------ -// Here is the table of global arrays which represent each type of command -// supported in the IntelliPort standard loadware. See also i2cmd.h -// for a more complete explanation of what is going on. -//------------------------------------------------------------------------------ - -// Here are the various globals: note that the names are not used except through -// the macros defined in i2cmd.h. Also note that although they are character -// arrays here (for extendability) they are cast to structure pointers in the -// i2cmd.h macros. See i2cmd.h for flags definitions. - -// Length Flags Command -static UCHAR ct02[] = { 1, BTH, 0x02 }; // DTR UP -static UCHAR ct03[] = { 1, BTH, 0x03 }; // DTR DN -static UCHAR ct04[] = { 1, BTH, 0x04 }; // RTS UP -static UCHAR ct05[] = { 1, BTH, 0x05 }; // RTS DN -static UCHAR ct06[] = { 1, BYP, 0x06 }; // START FL -static UCHAR ct07[] = { 2, BTH, 0x07,0 }; // BAUD -static UCHAR ct08[] = { 2, BTH, 0x08,0 }; // BITS -static UCHAR ct09[] = { 2, BTH, 0x09,0 }; // STOP -static UCHAR ct10[] = { 2, BTH, 0x0A,0 }; // PARITY -static UCHAR ct11[] = { 2, BTH, 0x0B,0 }; // XON -static UCHAR ct12[] = { 2, BTH, 0x0C,0 }; // XOFF -static UCHAR ct13[] = { 1, BTH, 0x0D }; // STOP FL -static UCHAR ct14[] = { 1, BYP|VIP, 0x0E }; // ACK HOTK -//static UCHAR ct15[]={ 2, BTH|VIP, 0x0F,0 }; // IRQ SET -static UCHAR ct16[] = { 2, INL, 0x10,0 }; // IXONOPTS -static UCHAR ct17[] = { 2, INL, 0x11,0 }; // OXONOPTS -static UCHAR ct18[] = { 1, INL, 0x12 }; // CTSENAB -static UCHAR ct19[] = { 1, BTH, 0x13 }; // CTSDSAB -static UCHAR ct20[] = { 1, INL, 0x14 }; // DCDENAB -static UCHAR ct21[] = { 1, BTH, 0x15 }; // DCDDSAB -static UCHAR ct22[] = { 1, BTH, 0x16 }; // DSRENAB -static UCHAR ct23[] = { 1, BTH, 0x17 }; // DSRDSAB -static UCHAR ct24[] = { 1, BTH, 0x18 }; // RIENAB -static UCHAR ct25[] = { 1, BTH, 0x19 }; // RIDSAB -static UCHAR ct26[] = { 2, BTH, 0x1A,0 }; // BRKENAB -static UCHAR ct27[] = { 1, BTH, 0x1B }; // BRKDSAB -//static UCHAR ct28[]={ 2, BTH, 0x1C,0 }; // MAXBLOKSIZE -//static UCHAR ct29[]={ 2, 0, 0x1D,0 }; // reserved -static UCHAR ct30[] = { 1, INL, 0x1E }; // CTSFLOWENAB -static UCHAR ct31[] = { 1, INL, 0x1F }; // CTSFLOWDSAB -static UCHAR ct32[] = { 1, INL, 0x20 }; // RTSFLOWENAB -static UCHAR ct33[] = { 1, INL, 0x21 }; // RTSFLOWDSAB -static UCHAR ct34[] = { 2, BTH, 0x22,0 }; // ISTRIPMODE -static UCHAR ct35[] = { 2, BTH|END, 0x23,0 }; // SENDBREAK -static UCHAR ct36[] = { 2, BTH, 0x24,0 }; // SETERRMODE -//static UCHAR ct36a[]={ 3, INL, 0x24,0,0 }; // SET_REPLACE - -// The following is listed for completeness, but should never be sent directly -// by user-level code. It is sent only by library routines in response to data -// movement. -//static UCHAR ct37[]={ 5, BYP|VIP, 0x25,0,0,0,0 }; // FLOW PACKET - -// Back to normal -//static UCHAR ct38[] = {11, BTH|VAR, 0x26,0,0,0,0,0,0,0,0,0,0 }; // DEF KEY SEQ -//static UCHAR ct39[]={ 3, BTH|END, 0x27,0,0 }; // OPOSTON -//static UCHAR ct40[]={ 1, BTH|END, 0x28 }; // OPOSTOFF -static UCHAR ct41[] = { 1, BYP, 0x29 }; // RESUME -//static UCHAR ct42[]={ 2, BTH, 0x2A,0 }; // TXBAUD -//static UCHAR ct43[]={ 2, BTH, 0x2B,0 }; // RXBAUD -//static UCHAR ct44[]={ 2, BTH, 0x2C,0 }; // MS PING -//static UCHAR ct45[]={ 1, BTH, 0x2D }; // HOTENAB -//static UCHAR ct46[]={ 1, BTH, 0x2E }; // HOTDSAB -//static UCHAR ct47[]={ 7, BTH, 0x2F,0,0,0,0,0,0 }; // UNIX FLAGS -//static UCHAR ct48[]={ 1, BTH, 0x30 }; // DSRFLOWENAB -//static UCHAR ct49[]={ 1, BTH, 0x31 }; // DSRFLOWDSAB -//static UCHAR ct50[]={ 1, BTH, 0x32 }; // DTRFLOWENAB -//static UCHAR ct51[]={ 1, BTH, 0x33 }; // DTRFLOWDSAB -//static UCHAR ct52[]={ 1, BTH, 0x34 }; // BAUDTABRESET -//static UCHAR ct53[] = { 3, BTH, 0x35,0,0 }; // BAUDREMAP -static UCHAR ct54[] = { 3, BTH, 0x36,0,0 }; // CUSTOMBAUD1 -static UCHAR ct55[] = { 3, BTH, 0x37,0,0 }; // CUSTOMBAUD2 -static UCHAR ct56[] = { 2, BTH|END, 0x38,0 }; // PAUSE -static UCHAR ct57[] = { 1, BYP, 0x39 }; // SUSPEND -static UCHAR ct58[] = { 1, BYP, 0x3A }; // UNSUSPEND -static UCHAR ct59[] = { 2, BTH, 0x3B,0 }; // PARITYCHK -static UCHAR ct60[] = { 1, INL|VIP, 0x3C }; // BOOKMARKREQ -//static UCHAR ct61[]={ 2, BTH, 0x3D,0 }; // INTERNALLOOP -//static UCHAR ct62[]={ 2, BTH, 0x3E,0 }; // HOTKTIMEOUT -static UCHAR ct63[] = { 2, INL, 0x3F,0 }; // SETTXON -static UCHAR ct64[] = { 2, INL, 0x40,0 }; // SETTXOFF -//static UCHAR ct65[]={ 2, BTH, 0x41,0 }; // SETAUTORTS -//static UCHAR ct66[]={ 2, BTH, 0x42,0 }; // SETHIGHWAT -//static UCHAR ct67[]={ 2, BYP, 0x43,0 }; // STARTSELFL -//static UCHAR ct68[]={ 2, INL, 0x44,0 }; // ENDSELFL -//static UCHAR ct69[]={ 1, BYP, 0x45 }; // HWFLOW_OFF -//static UCHAR ct70[]={ 1, BTH, 0x46 }; // ODSRFL_ENAB -//static UCHAR ct71[]={ 1, BTH, 0x47 }; // ODSRFL_DSAB -//static UCHAR ct72[]={ 1, BTH, 0x48 }; // ODCDFL_ENAB -//static UCHAR ct73[]={ 1, BTH, 0x49 }; // ODCDFL_DSAB -//static UCHAR ct74[]={ 2, BTH, 0x4A,0 }; // LOADLEVEL -//static UCHAR ct75[]={ 2, BTH, 0x4B,0 }; // STATDATA -//static UCHAR ct76[]={ 1, BYP, 0x4C }; // BREAK_ON -//static UCHAR ct77[]={ 1, BYP, 0x4D }; // BREAK_OFF -//static UCHAR ct78[]={ 1, BYP, 0x4E }; // GETFC -static UCHAR ct79[] = { 2, BYP, 0x4F,0 }; // XMIT_NOW -//static UCHAR ct80[]={ 4, BTH, 0x50,0,0,0 }; // DIVISOR_LATCH -//static UCHAR ct81[]={ 1, BYP, 0x51 }; // GET_STATUS -//static UCHAR ct82[]={ 1, BYP, 0x52 }; // GET_TXCNT -//static UCHAR ct83[]={ 1, BYP, 0x53 }; // GET_RXCNT -//static UCHAR ct84[]={ 1, BYP, 0x54 }; // GET_BOXIDS -//static UCHAR ct85[]={10, BYP, 0x55,0,0,0,0,0,0,0,0,0 }; // ENAB_MULT -//static UCHAR ct86[]={ 2, BTH, 0x56,0 }; // RCV_ENABLE -static UCHAR ct87[] = { 1, BYP, 0x57 }; // HW_TEST -//static UCHAR ct88[]={ 3, BTH, 0x58,0,0 }; // RCV_THRESHOLD -//static UCHAR ct90[]={ 3, BYP, 0x5A,0,0 }; // Set SILO -//static UCHAR ct91[]={ 2, BYP, 0x5B,0 }; // timed break - -// Some composite commands as well -//static UCHAR cc01[]={ 2, BTH, 0x02,0x04 }; // DTR & RTS UP -//static UCHAR cc02[]={ 2, BTH, 0x03,0x05 }; // DTR & RTS DN - -//******** -//* Code * -//******** - -//****************************************************************************** -// Function: i2cmdUnixFlags(iflag, cflag, lflag) -// Parameters: Unix tty flags -// -// Returns: Pointer to command structure -// -// Description: -// -// This routine sets the parameters of command 47 and returns a pointer to the -// appropriate structure. -//****************************************************************************** -#if 0 -cmdSyntaxPtr -i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag) -{ - cmdSyntaxPtr pCM = (cmdSyntaxPtr) ct47; - - pCM->cmd[1] = (unsigned char) iflag; - pCM->cmd[2] = (unsigned char) (iflag >> 8); - pCM->cmd[3] = (unsigned char) cflag; - pCM->cmd[4] = (unsigned char) (cflag >> 8); - pCM->cmd[5] = (unsigned char) lflag; - pCM->cmd[6] = (unsigned char) (lflag >> 8); - return pCM; -} -#endif /* 0 */ - -//****************************************************************************** -// Function: i2cmdBaudDef(which, rate) -// Parameters: ? -// -// Returns: Pointer to command structure -// -// Description: -// -// This routine sets the parameters of commands 54 or 55 (according to the -// argument which), and returns a pointer to the appropriate structure. -//****************************************************************************** -static cmdSyntaxPtr -i2cmdBaudDef(int which, unsigned short rate) -{ - cmdSyntaxPtr pCM; - - switch(which) - { - case 1: - pCM = (cmdSyntaxPtr) ct54; - break; - default: - case 2: - pCM = (cmdSyntaxPtr) ct55; - break; - } - pCM->cmd[1] = (unsigned char) rate; - pCM->cmd[2] = (unsigned char) (rate >> 8); - return pCM; -} - diff --git a/drivers/staging/tty/ip2/i2cmd.h b/drivers/staging/tty/ip2/i2cmd.h deleted file mode 100644 index 29277ec6b8ed..000000000000 --- a/drivers/staging/tty/ip2/i2cmd.h +++ /dev/null @@ -1,630 +0,0 @@ -/******************************************************************************* -* -* (c) 1999 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Definitions and support for In-line and Bypass commands. -* Applicable only when the standard loadware is active. -* -*******************************************************************************/ -//------------------------------------------------------------------------------ -// Revision History: -// -// 10 October 1991 MAG First Draft -// 7 November 1991 MAG Reflects some new commands -// 20 February 1992 MAG CMD_HOTACK corrected: no argument. -// 24 February 1992 MAG Support added for new commands for 1.4.x loadware. -// 11 March 1992 MAG Additional commands. -// 16 March 1992 MAG Additional commands. -// 30 March 1992 MAG Additional command: CMD_DSS_NOW -// 18 May 1992 MAG Changed CMD_OPOST -// -//------------------------------------------------------------------------------ -#ifndef I2CMD_H // To prevent multiple includes -#define I2CMD_H 1 - -#include "ip2types.h" - -// This module is designed to provide a uniform method of sending commands to -// the board through command packets. The difficulty is, some commands take -// parameters, others do not. Furthermore, it is often useful to send several -// commands to the same channel as part of the same packet. (See also i2pack.h.) -// -// This module is designed so that the caller should not be responsible for -// remembering the exact syntax of each command, or at least so that the -// compiler could check things somewhat. I'll explain as we go... -// -// First, a structure which can embody the syntax of each type of command. -// -typedef struct _cmdSyntax -{ - UCHAR length; // Number of bytes in the command - UCHAR flags; // Information about the command (see below) - - // The command and its parameters, which may be of arbitrary length. Don't - // worry yet how the parameters will be initialized; macros later take care - // of it. Also, don't worry about the arbitrary length issue; this structure - // is never used to allocate space (see i2cmd.c). - UCHAR cmd[2]; -} cmdSyntax, *cmdSyntaxPtr; - -// Bit assignments for flags - -#define INL 1 // Set if suitable for inline commands -#define BYP 2 // Set if suitable for bypass commands -#define BTH (INL|BYP) // suitable for either! -#define END 4 // Set if this must be the last command in a block -#define VIP 8 // Set if this command is special in some way and really - // should only be sent from the library-level and not - // directly from user-level -#define VAR 0x10 // This command is of variable length! - -// Declarations for the global arrays used to bear the commands and their -// arguments. -// -// Note: Since these are globals and the arguments might change, it is important -// that the library routine COPY these into buffers from whence they would be -// sent, rather than merely storing the pointers. In multi-threaded -// environments, important that the copy should obtain before any context switch -// is allowed. Also, for parameterized commands, DO NOT ISSUE THE SAME COMMAND -// MORE THAN ONCE WITH THE SAME PARAMETERS in the same call. -// -static UCHAR ct02[]; -static UCHAR ct03[]; -static UCHAR ct04[]; -static UCHAR ct05[]; -static UCHAR ct06[]; -static UCHAR ct07[]; -static UCHAR ct08[]; -static UCHAR ct09[]; -static UCHAR ct10[]; -static UCHAR ct11[]; -static UCHAR ct12[]; -static UCHAR ct13[]; -static UCHAR ct14[]; -static UCHAR ct15[]; -static UCHAR ct16[]; -static UCHAR ct17[]; -static UCHAR ct18[]; -static UCHAR ct19[]; -static UCHAR ct20[]; -static UCHAR ct21[]; -static UCHAR ct22[]; -static UCHAR ct23[]; -static UCHAR ct24[]; -static UCHAR ct25[]; -static UCHAR ct26[]; -static UCHAR ct27[]; -static UCHAR ct28[]; -static UCHAR ct29[]; -static UCHAR ct30[]; -static UCHAR ct31[]; -static UCHAR ct32[]; -static UCHAR ct33[]; -static UCHAR ct34[]; -static UCHAR ct35[]; -static UCHAR ct36[]; -static UCHAR ct36a[]; -static UCHAR ct41[]; -static UCHAR ct42[]; -static UCHAR ct43[]; -static UCHAR ct44[]; -static UCHAR ct45[]; -static UCHAR ct46[]; -static UCHAR ct48[]; -static UCHAR ct49[]; -static UCHAR ct50[]; -static UCHAR ct51[]; -static UCHAR ct52[]; -static UCHAR ct56[]; -static UCHAR ct57[]; -static UCHAR ct58[]; -static UCHAR ct59[]; -static UCHAR ct60[]; -static UCHAR ct61[]; -static UCHAR ct62[]; -static UCHAR ct63[]; -static UCHAR ct64[]; -static UCHAR ct65[]; -static UCHAR ct66[]; -static UCHAR ct67[]; -static UCHAR ct68[]; -static UCHAR ct69[]; -static UCHAR ct70[]; -static UCHAR ct71[]; -static UCHAR ct72[]; -static UCHAR ct73[]; -static UCHAR ct74[]; -static UCHAR ct75[]; -static UCHAR ct76[]; -static UCHAR ct77[]; -static UCHAR ct78[]; -static UCHAR ct79[]; -static UCHAR ct80[]; -static UCHAR ct81[]; -static UCHAR ct82[]; -static UCHAR ct83[]; -static UCHAR ct84[]; -static UCHAR ct85[]; -static UCHAR ct86[]; -static UCHAR ct87[]; -static UCHAR ct88[]; -static UCHAR ct89[]; -static UCHAR ct90[]; -static UCHAR ct91[]; -static UCHAR cc01[]; -static UCHAR cc02[]; - -// Now, refer to i2cmd.c, and see the character arrays defined there. They are -// cast here to cmdSyntaxPtr. -// -// There are library functions for issuing bypass or inline commands. These -// functions take one or more arguments of the type cmdSyntaxPtr. The routine -// then can figure out how long each command is supposed to be and easily add it -// to the list. -// -// For ease of use, we define manifests which return pointers to appropriate -// cmdSyntaxPtr things. But some commands also take arguments. If a single -// argument is used, we define a macro which performs the single assignment and -// (through the expedient of a comma expression) references the appropriate -// pointer. For commands requiring several arguments, we actually define a -// function to perform the assignments. - -#define CMD_DTRUP (cmdSyntaxPtr)(ct02) // Raise DTR -#define CMD_DTRDN (cmdSyntaxPtr)(ct03) // Lower DTR -#define CMD_RTSUP (cmdSyntaxPtr)(ct04) // Raise RTS -#define CMD_RTSDN (cmdSyntaxPtr)(ct05) // Lower RTS -#define CMD_STARTFL (cmdSyntaxPtr)(ct06) // Start Flushing Data - -#define CMD_DTRRTS_UP (cmdSyntaxPtr)(cc01) // Raise DTR and RTS -#define CMD_DTRRTS_DN (cmdSyntaxPtr)(cc02) // Lower DTR and RTS - -// Set Baud Rate for transmit and receive -#define CMD_SETBAUD(arg) \ - (((cmdSyntaxPtr)(ct07))->cmd[1] = (arg),(cmdSyntaxPtr)(ct07)) - -#define CBR_50 1 -#define CBR_75 2 -#define CBR_110 3 -#define CBR_134 4 -#define CBR_150 5 -#define CBR_200 6 -#define CBR_300 7 -#define CBR_600 8 -#define CBR_1200 9 -#define CBR_1800 10 -#define CBR_2400 11 -#define CBR_4800 12 -#define CBR_9600 13 -#define CBR_19200 14 -#define CBR_38400 15 -#define CBR_2000 16 -#define CBR_3600 17 -#define CBR_7200 18 -#define CBR_56000 19 -#define CBR_57600 20 -#define CBR_64000 21 -#define CBR_76800 22 -#define CBR_115200 23 -#define CBR_C1 24 // Custom baud rate 1 -#define CBR_C2 25 // Custom baud rate 2 -#define CBR_153600 26 -#define CBR_230400 27 -#define CBR_307200 28 -#define CBR_460800 29 -#define CBR_921600 30 - -// Set Character size -// -#define CMD_SETBITS(arg) \ - (((cmdSyntaxPtr)(ct08))->cmd[1] = (arg),(cmdSyntaxPtr)(ct08)) - -#define CSZ_5 0 -#define CSZ_6 1 -#define CSZ_7 2 -#define CSZ_8 3 - -// Set number of stop bits -// -#define CMD_SETSTOP(arg) \ - (((cmdSyntaxPtr)(ct09))->cmd[1] = (arg),(cmdSyntaxPtr)(ct09)) - -#define CST_1 0 -#define CST_15 1 // 1.5 stop bits -#define CST_2 2 - -// Set parity option -// -#define CMD_SETPAR(arg) \ - (((cmdSyntaxPtr)(ct10))->cmd[1] = (arg),(cmdSyntaxPtr)(ct10)) - -#define CSP_NP 0 // no parity -#define CSP_OD 1 // odd parity -#define CSP_EV 2 // Even parity -#define CSP_SP 3 // Space parity -#define CSP_MK 4 // Mark parity - -// Define xon char for transmitter flow control -// -#define CMD_DEF_IXON(arg) \ - (((cmdSyntaxPtr)(ct11))->cmd[1] = (arg),(cmdSyntaxPtr)(ct11)) - -// Define xoff char for transmitter flow control -// -#define CMD_DEF_IXOFF(arg) \ - (((cmdSyntaxPtr)(ct12))->cmd[1] = (arg),(cmdSyntaxPtr)(ct12)) - -#define CMD_STOPFL (cmdSyntaxPtr)(ct13) // Stop Flushing data - -// Acknowledge receipt of hotkey signal -// -#define CMD_HOTACK (cmdSyntaxPtr)(ct14) - -// Define irq level to use. Should actually be sent by library-level code, not -// directly from user... -// -#define CMDVALUE_IRQ 15 // For library use at initialization. Until this command - // is sent, board processing doesn't really start. -#define CMD_SET_IRQ(arg) \ - (((cmdSyntaxPtr)(ct15))->cmd[1] = (arg),(cmdSyntaxPtr)(ct15)) - -#define CIR_POLL 0 // No IRQ - Poll -#define CIR_3 3 // IRQ 3 -#define CIR_4 4 // IRQ 4 -#define CIR_5 5 // IRQ 5 -#define CIR_7 7 // IRQ 7 -#define CIR_10 10 // IRQ 10 -#define CIR_11 11 // IRQ 11 -#define CIR_12 12 // IRQ 12 -#define CIR_15 15 // IRQ 15 - -// Select transmit flow xon/xoff options -// -#define CMD_IXON_OPT(arg) \ - (((cmdSyntaxPtr)(ct16))->cmd[1] = (arg),(cmdSyntaxPtr)(ct16)) - -#define CIX_NONE 0 // Incoming Xon/Xoff characters not special -#define CIX_XON 1 // Xoff disable, Xon enable -#define CIX_XANY 2 // Xoff disable, any key enable - -// Select receive flow xon/xoff options -// -#define CMD_OXON_OPT(arg) \ - (((cmdSyntaxPtr)(ct17))->cmd[1] = (arg),(cmdSyntaxPtr)(ct17)) - -#define COX_NONE 0 // Don't send Xon/Xoff -#define COX_XON 1 // Send xon/xoff to start/stop incoming data - - -#define CMD_CTS_REP (cmdSyntaxPtr)(ct18) // Enable CTS reporting -#define CMD_CTS_NREP (cmdSyntaxPtr)(ct19) // Disable CTS reporting - -#define CMD_DCD_REP (cmdSyntaxPtr)(ct20) // Enable DCD reporting -#define CMD_DCD_NREP (cmdSyntaxPtr)(ct21) // Disable DCD reporting - -#define CMD_DSR_REP (cmdSyntaxPtr)(ct22) // Enable DSR reporting -#define CMD_DSR_NREP (cmdSyntaxPtr)(ct23) // Disable DSR reporting - -#define CMD_RI_REP (cmdSyntaxPtr)(ct24) // Enable RI reporting -#define CMD_RI_NREP (cmdSyntaxPtr)(ct25) // Disable RI reporting - -// Enable break reporting and select style -// -#define CMD_BRK_REP(arg) \ - (((cmdSyntaxPtr)(ct26))->cmd[1] = (arg),(cmdSyntaxPtr)(ct26)) - -#define CBK_STAT 0x00 // Report breaks as a status (exception,irq) -#define CBK_NULL 0x01 // Report breaks as a good null -#define CBK_STAT_SEQ 0x02 // Report breaks as a status AND as in-band character - // sequence FFh, 01h, 10h -#define CBK_SEQ 0x03 // Report breaks as the in-band - //sequence FFh, 01h, 10h ONLY. -#define CBK_FLSH 0x04 // if this bit set also flush input data -#define CBK_POSIX 0x08 // if this bit set report as FF,0,0 sequence -#define CBK_SINGLE 0x10 // if this bit set with CBK_SEQ or CBK_STAT_SEQ - //then reports single null instead of triple - -#define CMD_BRK_NREP (cmdSyntaxPtr)(ct27) // Disable break reporting - -// Specify maximum block size for received data -// -#define CMD_MAX_BLOCK(arg) \ - (((cmdSyntaxPtr)(ct28))->cmd[1] = (arg),(cmdSyntaxPtr)(ct28)) - -// -- COMMAND 29 is reserved -- - -#define CMD_CTSFL_ENAB (cmdSyntaxPtr)(ct30) // Enable CTS flow control -#define CMD_CTSFL_DSAB (cmdSyntaxPtr)(ct31) // Disable CTS flow control -#define CMD_RTSFL_ENAB (cmdSyntaxPtr)(ct32) // Enable RTS flow control -#define CMD_RTSFL_DSAB (cmdSyntaxPtr)(ct33) // Disable RTS flow control - -// Specify istrip option -// -#define CMD_ISTRIP_OPT(arg) \ - (((cmdSyntaxPtr)(ct34))->cmd[1] = (arg),(cmdSyntaxPtr)(ct34)) - -#define CIS_NOSTRIP 0 // Strip characters to character size -#define CIS_STRIP 1 // Strip any 8-bit characters to 7 bits - -// Send a break of arg milliseconds -// -#define CMD_SEND_BRK(arg) \ - (((cmdSyntaxPtr)(ct35))->cmd[1] = (arg),(cmdSyntaxPtr)(ct35)) - -// Set error reporting mode -// -#define CMD_SET_ERROR(arg) \ - (((cmdSyntaxPtr)(ct36))->cmd[1] = (arg),(cmdSyntaxPtr)(ct36)) - -#define CSE_ESTAT 0 // Report error in a status packet -#define CSE_NOREP 1 // Treat character as though it were good -#define CSE_DROP 2 // Discard the character -#define CSE_NULL 3 // Replace with a null -#define CSE_MARK 4 // Replace with a 3-character sequence (as Unix) - -#define CSE_REPLACE 0x8 // Replace the errored character with the - // replacement character defined here - -#define CSE_STAT_REPLACE 0x18 // Replace the errored character with the - // replacement character defined here AND - // report the error as a status packet (as in - // CSE_ESTAT). - - -// COMMAND 37, to send flow control packets, is handled only by low-level -// library code in response to data movement and shouldn't ever be sent by the -// user code. See i2pack.h and the body of i2lib.c for details. - -// Enable on-board post-processing, using options given in oflag argument. -// Formerly, this command was automatically preceded by a CMD_OPOST_OFF command -// because the loadware does not permit sending back-to-back CMD_OPOST_ON -// commands without an intervening CMD_OPOST_OFF. BUT, WE LEARN 18 MAY 92, that -// CMD_OPOST_ON and CMD_OPOST_OFF must each be at the end of a packet (or in a -// solo packet). This means the caller must specify separately CMD_OPOST_OFF, -// CMD_OPOST_ON(parm) when he calls i2QueueCommands(). That function will ensure -// each gets a separate packet. Extra CMD_OPOST_OFF's are always ok. -// -#define CMD_OPOST_ON(oflag) \ - (*(USHORT *)(((cmdSyntaxPtr)(ct39))->cmd[1]) = (oflag), \ - (cmdSyntaxPtr)(ct39)) - -#define CMD_OPOST_OFF (cmdSyntaxPtr)(ct40) // Disable on-board post-proc - -#define CMD_RESUME (cmdSyntaxPtr)(ct41) // Resume: behave as though an XON - // were received; - -// Set Transmit baud rate (see command 7 for arguments) -// -#define CMD_SETBAUD_TX(arg) \ - (((cmdSyntaxPtr)(ct42))->cmd[1] = (arg),(cmdSyntaxPtr)(ct42)) - -// Set Receive baud rate (see command 7 for arguments) -// -#define CMD_SETBAUD_RX(arg) \ - (((cmdSyntaxPtr)(ct43))->cmd[1] = (arg),(cmdSyntaxPtr)(ct43)) - -// Request interrupt from board each arg milliseconds. Interrupt will specify -// "received data", even though there may be no data present. If arg == 0, -// disables any such interrupts. -// -#define CMD_PING_REQ(arg) \ - (((cmdSyntaxPtr)(ct44))->cmd[1] = (arg),(cmdSyntaxPtr)(ct44)) - -#define CMD_HOT_ENAB (cmdSyntaxPtr)(ct45) // Enable Hot-key checking -#define CMD_HOT_DSAB (cmdSyntaxPtr)(ct46) // Disable Hot-key checking - -#if 0 -// COMMAND 47: Send Protocol info via Unix flags: -// iflag = Unix tty t_iflag -// cflag = Unix tty t_cflag -// lflag = Unix tty t_lflag -// See System V Unix/Xenix documentation for the meanings of the bit fields -// within these flags -// -#define CMD_UNIX_FLAGS(iflag,cflag,lflag) i2cmdUnixFlags(iflag,cflag,lflag) -#endif /* 0 */ - -#define CMD_DSRFL_ENAB (cmdSyntaxPtr)(ct48) // Enable DSR receiver ctrl -#define CMD_DSRFL_DSAB (cmdSyntaxPtr)(ct49) // Disable DSR receiver ctrl -#define CMD_DTRFL_ENAB (cmdSyntaxPtr)(ct50) // Enable DTR flow control -#define CMD_DTRFL_DSAB (cmdSyntaxPtr)(ct51) // Disable DTR flow control -#define CMD_BAUD_RESET (cmdSyntaxPtr)(ct52) // Reset baudrate table - -// COMMAND 54: Define custom rate #1 -// rate = (short) 1/10 of the desired baud rate -// -#define CMD_BAUD_DEF1(rate) i2cmdBaudDef(1,rate) - -// COMMAND 55: Define custom rate #2 -// rate = (short) 1/10 of the desired baud rate -// -#define CMD_BAUD_DEF2(rate) i2cmdBaudDef(2,rate) - -// Pause arg hundredths of seconds. (Note, this is NOT milliseconds.) -// -#define CMD_PAUSE(arg) \ - (((cmdSyntaxPtr)(ct56))->cmd[1] = (arg),(cmdSyntaxPtr)(ct56)) - -#define CMD_SUSPEND (cmdSyntaxPtr)(ct57) // Suspend output -#define CMD_UNSUSPEND (cmdSyntaxPtr)(ct58) // Un-Suspend output - -// Set parity-checking options -// -#define CMD_PARCHK(arg) \ - (((cmdSyntaxPtr)(ct59))->cmd[1] = (arg),(cmdSyntaxPtr)(ct59)) - -#define CPK_ENAB 0 // Enable parity checking on input -#define CPK_DSAB 1 // Disable parity checking on input - -#define CMD_BMARK_REQ (cmdSyntaxPtr)(ct60) // Bookmark request - - -// Enable/Disable internal loopback mode -// -#define CMD_INLOOP(arg) \ - (((cmdSyntaxPtr)(ct61))->cmd[1] = (arg),(cmdSyntaxPtr)(ct61)) - -#define CIN_DISABLE 0 // Normal operation (default) -#define CIN_ENABLE 1 // Internal (local) loopback -#define CIN_REMOTE 2 // Remote loopback - -// Specify timeout for hotkeys: Delay will be (arg x 10) milliseconds, arg == 0 -// --> no timeout: wait forever. -// -#define CMD_HOT_TIME(arg) \ - (((cmdSyntaxPtr)(ct62))->cmd[1] = (arg),(cmdSyntaxPtr)(ct62)) - - -// Define (outgoing) xon for receive flow control -// -#define CMD_DEF_OXON(arg) \ - (((cmdSyntaxPtr)(ct63))->cmd[1] = (arg),(cmdSyntaxPtr)(ct63)) - -// Define (outgoing) xoff for receiver flow control -// -#define CMD_DEF_OXOFF(arg) \ - (((cmdSyntaxPtr)(ct64))->cmd[1] = (arg),(cmdSyntaxPtr)(ct64)) - -// Enable/Disable RTS on transmit (1/2 duplex-style) -// -#define CMD_RTS_XMIT(arg) \ - (((cmdSyntaxPtr)(ct65))->cmd[1] = (arg),(cmdSyntaxPtr)(ct65)) - -#define CHD_DISABLE 0 -#define CHD_ENABLE 1 - -// Set high-water-mark level (debugging use only) -// -#define CMD_SETHIGHWAT(arg) \ - (((cmdSyntaxPtr)(ct66))->cmd[1] = (arg),(cmdSyntaxPtr)(ct66)) - -// Start flushing tagged data (tag = 0-14) -// -#define CMD_START_SELFL(tag) \ - (((cmdSyntaxPtr)(ct67))->cmd[1] = (tag),(cmdSyntaxPtr)(ct67)) - -// End flushing tagged data (tag = 0-14) -// -#define CMD_END_SELFL(tag) \ - (((cmdSyntaxPtr)(ct68))->cmd[1] = (tag),(cmdSyntaxPtr)(ct68)) - -#define CMD_HWFLOW_OFF (cmdSyntaxPtr)(ct69) // Disable HW TX flow control -#define CMD_ODSRFL_ENAB (cmdSyntaxPtr)(ct70) // Enable DSR output f/c -#define CMD_ODSRFL_DSAB (cmdSyntaxPtr)(ct71) // Disable DSR output f/c -#define CMD_ODCDFL_ENAB (cmdSyntaxPtr)(ct72) // Enable DCD output f/c -#define CMD_ODCDFL_DSAB (cmdSyntaxPtr)(ct73) // Disable DCD output f/c - -// Set transmit interrupt load level. Count should be an even value 2-12 -// -#define CMD_LOADLEVEL(count) \ - (((cmdSyntaxPtr)(ct74))->cmd[1] = (count),(cmdSyntaxPtr)(ct74)) - -// If reporting DSS changes, map to character sequence FFh, 2, MSR -// -#define CMD_STATDATA(arg) \ - (((cmdSyntaxPtr)(ct75))->cmd[1] = (arg),(cmdSyntaxPtr)(ct75)) - -#define CSTD_DISABLE// Report DSS changes as status packets only (default) -#define CSTD_ENABLE // Report DSS changes as in-band data sequence as well as - // by status packet. - -#define CMD_BREAK_ON (cmdSyntaxPtr)(ct76)// Set break and stop xmit -#define CMD_BREAK_OFF (cmdSyntaxPtr)(ct77)// End break and restart xmit -#define CMD_GETFC (cmdSyntaxPtr)(ct78)// Request for flow control packet - // from board. - -// Transmit this character immediately -// -#define CMD_XMIT_NOW(ch) \ - (((cmdSyntaxPtr)(ct79))->cmd[1] = (ch),(cmdSyntaxPtr)(ct79)) - -// Set baud rate via "divisor latch" -// -#define CMD_DIVISOR_LATCH(which,value) \ - (((cmdSyntaxPtr)(ct80))->cmd[1] = (which), \ - *(USHORT *)(((cmdSyntaxPtr)(ct80))->cmd[2]) = (value), \ - (cmdSyntaxPtr)(ct80)) - -#define CDL_RX 1 // Set receiver rate -#define CDL_TX 2 // Set transmit rate - // (CDL_TX | CDL_RX) Set both rates - -// Request for special diagnostic status pkt from the board. -// -#define CMD_GET_STATUS (cmdSyntaxPtr)(ct81) - -// Request time-stamped transmit character count packet. -// -#define CMD_GET_TXCNT (cmdSyntaxPtr)(ct82) - -// Request time-stamped receive character count packet. -// -#define CMD_GET_RXCNT (cmdSyntaxPtr)(ct83) - -// Request for box/board I.D. packet. -#define CMD_GET_BOXIDS (cmdSyntaxPtr)(ct84) - -// Enable or disable multiple channels according to bit-mapped ushorts box 1-4 -// -#define CMD_ENAB_MULT(enable, box1, box2, box3, box4) \ - (((cmdSytaxPtr)(ct85))->cmd[1] = (enable), \ - *(USHORT *)(((cmdSyntaxPtr)(ct85))->cmd[2]) = (box1), \ - *(USHORT *)(((cmdSyntaxPtr)(ct85))->cmd[4]) = (box2), \ - *(USHORT *)(((cmdSyntaxPtr)(ct85))->cmd[6]) = (box3), \ - *(USHORT *)(((cmdSyntaxPtr)(ct85))->cmd[8]) = (box4), \ - (cmdSyntaxPtr)(ct85)) - -#define CEM_DISABLE 0 -#define CEM_ENABLE 1 - -// Enable or disable receiver or receiver interrupts (default both enabled) -// -#define CMD_RCV_ENABLE(ch) \ - (((cmdSyntaxPtr)(ct86))->cmd[1] = (ch),(cmdSyntaxPtr)(ct86)) - -#define CRE_OFF 0 // Disable the receiver -#define CRE_ON 1 // Enable the receiver -#define CRE_INTOFF 2 // Disable receiver interrupts (to loadware) -#define CRE_INTON 3 // Enable receiver interrupts (to loadware) - -// Starts up a hardware test process, which runs transparently, and sends a -// STAT_HWFAIL packet in case a hardware failure is detected. -// -#define CMD_HW_TEST (cmdSyntaxPtr)(ct87) - -// Change receiver threshold and timeout value: -// Defaults: timeout = 20mS -// threshold count = 8 when DTRflow not in use, -// threshold count = 5 when DTRflow in use. -// -#define CMD_RCV_THRESHOLD(count,ms) \ - (((cmdSyntaxPtr)(ct88))->cmd[1] = (count), \ - ((cmdSyntaxPtr)(ct88))->cmd[2] = (ms), \ - (cmdSyntaxPtr)(ct88)) - -// Makes the loadware report DSS signals for this channel immediately. -// -#define CMD_DSS_NOW (cmdSyntaxPtr)(ct89) - -// Set the receive silo parameters -// timeout is ms idle wait until delivery (~VTIME) -// threshold is max characters cause interrupt (~VMIN) -// -#define CMD_SET_SILO(timeout,threshold) \ - (((cmdSyntaxPtr)(ct90))->cmd[1] = (timeout), \ - ((cmdSyntaxPtr)(ct90))->cmd[2] = (threshold), \ - (cmdSyntaxPtr)(ct90)) - -// Set timed break in decisecond (1/10s) -// -#define CMD_LBREAK(ds) \ - (((cmdSyntaxPtr)(ct91))->cmd[1] = (ds),(cmdSyntaxPtr)(ct66)) - - - -#endif // I2CMD_H diff --git a/drivers/staging/tty/ip2/i2ellis.c b/drivers/staging/tty/ip2/i2ellis.c deleted file mode 100644 index 29db44de399f..000000000000 --- a/drivers/staging/tty/ip2/i2ellis.c +++ /dev/null @@ -1,1403 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Low-level interface code for the device driver -* (This is included source code, not a separate compilation -* module.) -* -*******************************************************************************/ -//--------------------------------------------- -// Function declarations private to this module -//--------------------------------------------- -// Functions called only indirectly through i2eBordStr entries. - -static int iiWriteBuf16(i2eBordStrPtr, unsigned char *, int); -static int iiWriteBuf8(i2eBordStrPtr, unsigned char *, int); -static int iiReadBuf16(i2eBordStrPtr, unsigned char *, int); -static int iiReadBuf8(i2eBordStrPtr, unsigned char *, int); - -static unsigned short iiReadWord16(i2eBordStrPtr); -static unsigned short iiReadWord8(i2eBordStrPtr); -static void iiWriteWord16(i2eBordStrPtr, unsigned short); -static void iiWriteWord8(i2eBordStrPtr, unsigned short); - -static int iiWaitForTxEmptyII(i2eBordStrPtr, int); -static int iiWaitForTxEmptyIIEX(i2eBordStrPtr, int); -static int iiTxMailEmptyII(i2eBordStrPtr); -static int iiTxMailEmptyIIEX(i2eBordStrPtr); -static int iiTrySendMailII(i2eBordStrPtr, unsigned char); -static int iiTrySendMailIIEX(i2eBordStrPtr, unsigned char); - -static unsigned short iiGetMailII(i2eBordStrPtr); -static unsigned short iiGetMailIIEX(i2eBordStrPtr); - -static void iiEnableMailIrqII(i2eBordStrPtr); -static void iiEnableMailIrqIIEX(i2eBordStrPtr); -static void iiWriteMaskII(i2eBordStrPtr, unsigned char); -static void iiWriteMaskIIEX(i2eBordStrPtr, unsigned char); - -static void ii2Nop(void); - -//*************** -//* Static Data * -//*************** - -static int ii2Safe; // Safe I/O address for delay routine - -static int iiDelayed; // Set when the iiResetDelay function is - // called. Cleared when ANY board is reset. -static DEFINE_RWLOCK(Dl_spinlock); - -//******** -//* Code * -//******** - -//======================================================= -// Initialization Routines -// -// iiSetAddress -// iiReset -// iiResetDelay -// iiInitialize -//======================================================= - -//****************************************************************************** -// Function: iiSetAddress(pB, address, delay) -// Parameters: pB - pointer to the board structure -// address - the purported I/O address of the board -// delay - pointer to the 1-ms delay function to use -// in this and any future operations to this board -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// This routine (roughly) checks for address validity, sets the i2eValid OK and -// sets the state to II_STATE_COLD which means that we haven't even sent a reset -// yet. -// -//****************************************************************************** -static int -iiSetAddress( i2eBordStrPtr pB, int address, delayFunc_t delay ) -{ - // Should any failure occur before init is finished... - pB->i2eValid = I2E_INCOMPLETE; - - // Cannot check upper limit except extremely: Might be microchannel - // Address must be on an 8-byte boundary - - if ((unsigned int)address <= 0x100 - || (unsigned int)address >= 0xfff8 - || (address & 0x7) - ) - { - I2_COMPLETE(pB, I2EE_BADADDR); - } - - // Initialize accelerators - pB->i2eBase = address; - pB->i2eData = address + FIFO_DATA; - pB->i2eStatus = address + FIFO_STATUS; - pB->i2ePointer = address + FIFO_PTR; - pB->i2eXMail = address + FIFO_MAIL; - pB->i2eXMask = address + FIFO_MASK; - - // Initialize i/o address for ii2DelayIO - ii2Safe = address + FIFO_NOP; - - // Initialize the delay routine - pB->i2eDelay = ((delay != (delayFunc_t)NULL) ? delay : (delayFunc_t)ii2Nop); - - pB->i2eValid = I2E_MAGIC; - pB->i2eState = II_STATE_COLD; - - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiReset(pB) -// Parameters: pB - pointer to the board structure -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Attempts to reset the board (see also i2hw.h). Normally, we would use this to -// reset a board immediately after iiSetAddress(), but it is valid to reset a -// board from any state, say, in order to change or re-load loadware. (Under -// such circumstances, no reason to re-run iiSetAddress(), which is why it is a -// separate routine and not included in this routine. -// -//****************************************************************************** -static int -iiReset(i2eBordStrPtr pB) -{ - // Magic number should be set, else even the address is suspect - if (pB->i2eValid != I2E_MAGIC) - { - I2_COMPLETE(pB, I2EE_BADMAGIC); - } - - outb(0, pB->i2eBase + FIFO_RESET); /* Any data will do */ - iiDelay(pB, 50); // Pause between resets - outb(0, pB->i2eBase + FIFO_RESET); /* Second reset */ - - // We must wait before even attempting to read anything from the FIFO: the - // board's P.O.S.T may actually attempt to read and write its end of the - // FIFO in order to check flags, loop back (where supported), etc. On - // completion of this testing it would reset the FIFO, and on completion - // of all // P.O.S.T., write the message. We must not mistake data which - // might have been sent for testing as part of the reset message. To - // better utilize time, say, when resetting several boards, we allow the - // delay to be performed externally; in this way the caller can reset - // several boards, delay a single time, then call the initialization - // routine for all. - - pB->i2eState = II_STATE_RESET; - - iiDelayed = 0; // i.e., the delay routine hasn't been called since the most - // recent reset. - - // Ensure anything which would have been of use to standard loadware is - // blanked out, since board has now forgotten everything!. - - pB->i2eUsingIrq = I2_IRQ_UNDEFINED; /* to not use an interrupt so far */ - pB->i2eWaitingForEmptyFifo = 0; - pB->i2eOutMailWaiting = 0; - pB->i2eChannelPtr = NULL; - pB->i2eChannelCnt = 0; - - pB->i2eLeadoffWord[0] = 0; - pB->i2eFifoInInts = 0; - pB->i2eFifoOutInts = 0; - pB->i2eFatalTrap = NULL; - pB->i2eFatal = 0; - - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiResetDelay(pB) -// Parameters: pB - pointer to the board structure -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Using the delay defined in board structure, waits two seconds (for board to -// reset). -// -//****************************************************************************** -static int -iiResetDelay(i2eBordStrPtr pB) -{ - if (pB->i2eValid != I2E_MAGIC) { - I2_COMPLETE(pB, I2EE_BADMAGIC); - } - if (pB->i2eState != II_STATE_RESET) { - I2_COMPLETE(pB, I2EE_BADSTATE); - } - iiDelay(pB,2000); /* Now we wait for two seconds. */ - iiDelayed = 1; /* Delay has been called: ok to initialize */ - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiInitialize(pB) -// Parameters: pB - pointer to the board structure -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Attempts to read the Power-on reset message. Initializes any remaining fields -// in the pB structure. -// -// This should be called as the third step of a process beginning with -// iiReset(), then iiResetDelay(). This routine checks to see that the structure -// is "valid" and in the reset state, also confirms that the delay routine has -// been called since the latest reset (to any board! overly strong!). -// -//****************************************************************************** -static int -iiInitialize(i2eBordStrPtr pB) -{ - int itemp; - unsigned char c; - unsigned short utemp; - unsigned int ilimit; - - if (pB->i2eValid != I2E_MAGIC) - { - I2_COMPLETE(pB, I2EE_BADMAGIC); - } - - if (pB->i2eState != II_STATE_RESET || !iiDelayed) - { - I2_COMPLETE(pB, I2EE_BADSTATE); - } - - // In case there is a failure short of our completely reading the power-up - // message. - pB->i2eValid = I2E_INCOMPLETE; - - - // Now attempt to read the message. - - for (itemp = 0; itemp < sizeof(porStr); itemp++) - { - // We expect the entire message is ready. - if (!I2_HAS_INPUT(pB)) { - pB->i2ePomSize = itemp; - I2_COMPLETE(pB, I2EE_PORM_SHORT); - } - - pB->i2ePom.c[itemp] = c = inb(pB->i2eData); - - // We check the magic numbers as soon as they are supposed to be read - // (rather than after) to minimize effect of reading something we - // already suspect can't be "us". - if ( (itemp == POR_1_INDEX && c != POR_MAGIC_1) || - (itemp == POR_2_INDEX && c != POR_MAGIC_2)) - { - pB->i2ePomSize = itemp+1; - I2_COMPLETE(pB, I2EE_BADMAGIC); - } - } - - pB->i2ePomSize = itemp; - - // Ensure that this was all the data... - if (I2_HAS_INPUT(pB)) - I2_COMPLETE(pB, I2EE_PORM_LONG); - - // For now, we'll fail to initialize if P.O.S.T reports bad chip mapper: - // Implying we will not be able to download any code either: That's ok: the - // condition is pretty explicit. - if (pB->i2ePom.e.porDiag1 & POR_BAD_MAPPER) - { - I2_COMPLETE(pB, I2EE_POSTERR); - } - - // Determine anything which must be done differently depending on the family - // of boards! - switch (pB->i2ePom.e.porID & POR_ID_FAMILY) - { - case POR_ID_FII: // IntelliPort-II - - pB->i2eFifoStyle = FIFO_II; - pB->i2eFifoSize = 512; // 512 bytes, always - pB->i2eDataWidth16 = false; - - pB->i2eMaxIrq = 15; // Because board cannot tell us it is in an 8-bit - // slot, we do allow it to be done (documentation!) - - pB->i2eGoodMap[1] = - pB->i2eGoodMap[2] = - pB->i2eGoodMap[3] = - pB->i2eChannelMap[1] = - pB->i2eChannelMap[2] = - pB->i2eChannelMap[3] = 0; - - switch (pB->i2ePom.e.porID & POR_ID_SIZE) - { - case POR_ID_II_4: - pB->i2eGoodMap[0] = - pB->i2eChannelMap[0] = 0x0f; // four-port - - // Since porPorts1 is based on the Hardware ID register, the numbers - // should always be consistent for IntelliPort-II. Ditto below... - if (pB->i2ePom.e.porPorts1 != 4) - { - I2_COMPLETE(pB, I2EE_INCONSIST); - } - break; - - case POR_ID_II_8: - case POR_ID_II_8R: - pB->i2eGoodMap[0] = - pB->i2eChannelMap[0] = 0xff; // Eight port - if (pB->i2ePom.e.porPorts1 != 8) - { - I2_COMPLETE(pB, I2EE_INCONSIST); - } - break; - - case POR_ID_II_6: - pB->i2eGoodMap[0] = - pB->i2eChannelMap[0] = 0x3f; // Six Port - if (pB->i2ePom.e.porPorts1 != 6) - { - I2_COMPLETE(pB, I2EE_INCONSIST); - } - break; - } - - // Fix up the "good channel list based on any errors reported. - if (pB->i2ePom.e.porDiag1 & POR_BAD_UART1) - { - pB->i2eGoodMap[0] &= ~0x0f; - } - - if (pB->i2ePom.e.porDiag1 & POR_BAD_UART2) - { - pB->i2eGoodMap[0] &= ~0xf0; - } - - break; // POR_ID_FII case - - case POR_ID_FIIEX: // IntelliPort-IIEX - - pB->i2eFifoStyle = FIFO_IIEX; - - itemp = pB->i2ePom.e.porFifoSize; - - // Implicit assumption that fifo would not grow beyond 32k, - // nor would ever be less than 256. - - if (itemp < 8 || itemp > 15) - { - I2_COMPLETE(pB, I2EE_INCONSIST); - } - pB->i2eFifoSize = (1 << itemp); - - // These are based on what P.O.S.T thinks should be there, based on - // box ID registers - ilimit = pB->i2ePom.e.porNumBoxes; - if (ilimit > ABS_MAX_BOXES) - { - ilimit = ABS_MAX_BOXES; - } - - // For as many boxes as EXIST, gives the type of box. - // Added 8/6/93: check for the ISA-4 (asic) which looks like an - // expandable but for whom "8 or 16?" is not the right question. - - utemp = pB->i2ePom.e.porFlags; - if (utemp & POR_CEX4) - { - pB->i2eChannelMap[0] = 0x000f; - } else { - utemp &= POR_BOXES; - for (itemp = 0; itemp < ilimit; itemp++) - { - pB->i2eChannelMap[itemp] = - ((utemp & POR_BOX_16) ? 0xffff : 0x00ff); - utemp >>= 1; - } - } - - // These are based on what P.O.S.T actually found. - - utemp = (pB->i2ePom.e.porPorts2 << 8) + pB->i2ePom.e.porPorts1; - - for (itemp = 0; itemp < ilimit; itemp++) - { - pB->i2eGoodMap[itemp] = 0; - if (utemp & 1) pB->i2eGoodMap[itemp] |= 0x000f; - if (utemp & 2) pB->i2eGoodMap[itemp] |= 0x00f0; - if (utemp & 4) pB->i2eGoodMap[itemp] |= 0x0f00; - if (utemp & 8) pB->i2eGoodMap[itemp] |= 0xf000; - utemp >>= 4; - } - - // Now determine whether we should transfer in 8 or 16-bit mode. - switch (pB->i2ePom.e.porBus & (POR_BUS_SLOT16 | POR_BUS_DIP16) ) - { - case POR_BUS_SLOT16 | POR_BUS_DIP16: - pB->i2eDataWidth16 = true; - pB->i2eMaxIrq = 15; - break; - - case POR_BUS_SLOT16: - pB->i2eDataWidth16 = false; - pB->i2eMaxIrq = 15; - break; - - case 0: - case POR_BUS_DIP16: // In an 8-bit slot, DIP switch don't care. - default: - pB->i2eDataWidth16 = false; - pB->i2eMaxIrq = 7; - break; - } - break; // POR_ID_FIIEX case - - default: // Unknown type of board - I2_COMPLETE(pB, I2EE_BAD_FAMILY); - break; - } // End the switch based on family - - // Temporarily, claim there is no room in the outbound fifo. - // We will maintain this whenever we check for an empty outbound FIFO. - pB->i2eFifoRemains = 0; - - // Now, based on the bus type, should we expect to be able to re-configure - // interrupts (say, for testing purposes). - switch (pB->i2ePom.e.porBus & POR_BUS_TYPE) - { - case POR_BUS_T_ISA: - case POR_BUS_T_UNK: // If the type of bus is undeclared, assume ok. - case POR_BUS_T_MCA: - case POR_BUS_T_EISA: - break; - default: - I2_COMPLETE(pB, I2EE_BADBUS); - } - - if (pB->i2eDataWidth16) - { - pB->i2eWriteBuf = iiWriteBuf16; - pB->i2eReadBuf = iiReadBuf16; - pB->i2eWriteWord = iiWriteWord16; - pB->i2eReadWord = iiReadWord16; - } else { - pB->i2eWriteBuf = iiWriteBuf8; - pB->i2eReadBuf = iiReadBuf8; - pB->i2eWriteWord = iiWriteWord8; - pB->i2eReadWord = iiReadWord8; - } - - switch(pB->i2eFifoStyle) - { - case FIFO_II: - pB->i2eWaitForTxEmpty = iiWaitForTxEmptyII; - pB->i2eTxMailEmpty = iiTxMailEmptyII; - pB->i2eTrySendMail = iiTrySendMailII; - pB->i2eGetMail = iiGetMailII; - pB->i2eEnableMailIrq = iiEnableMailIrqII; - pB->i2eWriteMask = iiWriteMaskII; - - break; - - case FIFO_IIEX: - pB->i2eWaitForTxEmpty = iiWaitForTxEmptyIIEX; - pB->i2eTxMailEmpty = iiTxMailEmptyIIEX; - pB->i2eTrySendMail = iiTrySendMailIIEX; - pB->i2eGetMail = iiGetMailIIEX; - pB->i2eEnableMailIrq = iiEnableMailIrqIIEX; - pB->i2eWriteMask = iiWriteMaskIIEX; - - break; - - default: - I2_COMPLETE(pB, I2EE_INCONSIST); - } - - // Initialize state information. - pB->i2eState = II_STATE_READY; // Ready to load loadware. - - // Some Final cleanup: - // For some boards, the bootstrap firmware may perform some sort of test - // resulting in a stray character pending in the incoming mailbox. If one is - // there, it should be read and discarded, especially since for the standard - // firmware, it's the mailbox that interrupts the host. - - pB->i2eStartMail = iiGetMail(pB); - - // Throw it away and clear the mailbox structure element - pB->i2eStartMail = NO_MAIL_HERE; - - // Everything is ok now, return with good status/ - - pB->i2eValid = I2E_MAGIC; - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: ii2DelayTimer(mseconds) -// Parameters: mseconds - number of milliseconds to delay -// -// Returns: Nothing -// -// Description: -// -// This routine delays for approximately mseconds milliseconds and is intended -// to be called indirectly through i2Delay field in i2eBordStr. It uses the -// Linux timer_list mechanism. -// -// The Linux timers use a unit called "jiffies" which are 10mS in the Intel -// architecture. This function rounds the delay period up to the next "jiffy". -// In the Alpha architecture the "jiffy" is 1mS, but this driver is not intended -// for Alpha platforms at this time. -// -//****************************************************************************** -static void -ii2DelayTimer(unsigned int mseconds) -{ - msleep_interruptible(mseconds); -} - -#if 0 -//static void ii2DelayIO(unsigned int); -//****************************************************************************** -// !!! Not Used, this is DOS crap, some of you young folks may be interested in -// in how things were done in the stone age of caculating machines !!! -// Function: ii2DelayIO(mseconds) -// Parameters: mseconds - number of milliseconds to delay -// -// Returns: Nothing -// -// Description: -// -// This routine delays for approximately mseconds milliseconds and is intended -// to be called indirectly through i2Delay field in i2eBordStr. It is intended -// for use where a clock-based function is impossible: for example, DOS drivers. -// -// This function uses the IN instruction to place bounds on the timing and -// assumes that ii2Safe has been set. This is because I/O instructions are not -// subject to caching and will therefore take a certain minimum time. To ensure -// the delay is at least long enough on fast machines, it is based on some -// fastest-case calculations. On slower machines this may cause VERY long -// delays. (3 x fastest case). In the fastest case, everything is cached except -// the I/O instruction itself. -// -// Timing calculations: -// The fastest bus speed for I/O operations is likely to be 10 MHz. The I/O -// operation in question is a byte operation to an odd address. For 8-bit -// operations, the architecture generally enforces two wait states. At 10 MHz, a -// single cycle time is 100nS. A read operation at two wait states takes 6 -// cycles for a total time of 600nS. Therefore approximately 1666 iterations -// would be required to generate a single millisecond delay. The worst -// (reasonable) case would be an 8MHz system with no cacheing. In this case, the -// I/O instruction would take 125nS x 6 cyles = 750 nS. More importantly, code -// fetch of other instructions in the loop would take time (zero wait states, -// however) and would be hard to estimate. This is minimized by using in-line -// assembler for the in inner loop of IN instructions. This consists of just a -// few bytes. So we'll guess about four code fetches per loop. Each code fetch -// should take four cycles, so we have 125nS * 8 = 1000nS. Worst case then is -// that what should have taken 1 mS takes instead 1666 * (1750) = 2.9 mS. -// -// So much for theoretical timings: results using 1666 value on some actual -// machines: -// IBM 286 6MHz 3.15 mS -// Zenith 386 33MHz 2.45 mS -// (brandX) 386 33MHz 1.90 mS (has cache) -// (brandY) 486 33MHz 2.35 mS -// NCR 486 ?? 1.65 mS (microchannel) -// -// For most machines, it is probably safe to scale this number back (remember, -// for robust operation use an actual timed delay if possible), so we are using -// a value of 1190. This yields 1.17 mS for the fastest machine in our sample, -// 1.75 mS for typical 386 machines, and 2.25 mS the absolute slowest machine. -// -// 1/29/93: -// The above timings are too slow. Actual cycle times might be faster. ISA cycle -// times could approach 500 nS, and ... -// The IBM model 77 being microchannel has no wait states for 8-bit reads and -// seems to be accessing the I/O at 440 nS per access (from start of one to -// start of next). This would imply we need 1000/.440 = 2272 iterations to -// guarantee we are fast enough. In actual testing, we see that 2 * 1190 are in -// fact enough. For diagnostics, we keep the level at 1190, but developers note -// this needs tuning. -// -// Safe assumption: 2270 i/o reads = 1 millisecond -// -//****************************************************************************** - - -static int ii2DelValue = 1190; // See timing calculations below - // 1666 for fastest theoretical machine - // 1190 safe for most fast 386 machines - // 1000 for fastest machine tested here - // 540 (sic) for AT286/6Mhz -static void -ii2DelayIO(unsigned int mseconds) -{ - if (!ii2Safe) - return; /* Do nothing if this variable uninitialized */ - - while(mseconds--) { - int i = ii2DelValue; - while ( i-- ) { - inb(ii2Safe); - } - } -} -#endif - -//****************************************************************************** -// Function: ii2Nop() -// Parameters: None -// -// Returns: Nothing -// -// Description: -// -// iiInitialize will set i2eDelay to this if the delay parameter is NULL. This -// saves checking for a NULL pointer at every call. -//****************************************************************************** -static void -ii2Nop(void) -{ - return; // no mystery here -} - -//======================================================= -// Routines which are available in 8/16-bit versions, or -// in different fifo styles. These are ALL called -// indirectly through the board structure. -//======================================================= - -//****************************************************************************** -// Function: iiWriteBuf16(pB, address, count) -// Parameters: pB - pointer to board structure -// address - address of data to write -// count - number of data bytes to write -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Writes 'count' bytes from 'address' to the data fifo specified by the board -// structure pointer pB. Should count happen to be odd, an extra pad byte is -// sent (identity unknown...). Uses 16-bit (word) operations. Is called -// indirectly through pB->i2eWriteBuf. -// -//****************************************************************************** -static int -iiWriteBuf16(i2eBordStrPtr pB, unsigned char *address, int count) -{ - // Rudimentary sanity checking here. - if (pB->i2eValid != I2E_MAGIC) - I2_COMPLETE(pB, I2EE_INVALID); - - I2_OUTSW(pB->i2eData, address, count); - - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiWriteBuf8(pB, address, count) -// Parameters: pB - pointer to board structure -// address - address of data to write -// count - number of data bytes to write -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Writes 'count' bytes from 'address' to the data fifo specified by the board -// structure pointer pB. Should count happen to be odd, an extra pad byte is -// sent (identity unknown...). This is to be consistent with the 16-bit version. -// Uses 8-bit (byte) operations. Is called indirectly through pB->i2eWriteBuf. -// -//****************************************************************************** -static int -iiWriteBuf8(i2eBordStrPtr pB, unsigned char *address, int count) -{ - /* Rudimentary sanity checking here */ - if (pB->i2eValid != I2E_MAGIC) - I2_COMPLETE(pB, I2EE_INVALID); - - I2_OUTSB(pB->i2eData, address, count); - - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiReadBuf16(pB, address, count) -// Parameters: pB - pointer to board structure -// address - address to put data read -// count - number of data bytes to read -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Reads 'count' bytes into 'address' from the data fifo specified by the board -// structure pointer pB. Should count happen to be odd, an extra pad byte is -// received (identity unknown...). Uses 16-bit (word) operations. Is called -// indirectly through pB->i2eReadBuf. -// -//****************************************************************************** -static int -iiReadBuf16(i2eBordStrPtr pB, unsigned char *address, int count) -{ - // Rudimentary sanity checking here. - if (pB->i2eValid != I2E_MAGIC) - I2_COMPLETE(pB, I2EE_INVALID); - - I2_INSW(pB->i2eData, address, count); - - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiReadBuf8(pB, address, count) -// Parameters: pB - pointer to board structure -// address - address to put data read -// count - number of data bytes to read -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Reads 'count' bytes into 'address' from the data fifo specified by the board -// structure pointer pB. Should count happen to be odd, an extra pad byte is -// received (identity unknown...). This to match the 16-bit behaviour. Uses -// 8-bit (byte) operations. Is called indirectly through pB->i2eReadBuf. -// -//****************************************************************************** -static int -iiReadBuf8(i2eBordStrPtr pB, unsigned char *address, int count) -{ - // Rudimentary sanity checking here. - if (pB->i2eValid != I2E_MAGIC) - I2_COMPLETE(pB, I2EE_INVALID); - - I2_INSB(pB->i2eData, address, count); - - I2_COMPLETE(pB, I2EE_GOOD); -} - -//****************************************************************************** -// Function: iiReadWord16(pB) -// Parameters: pB - pointer to board structure -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Returns the word read from the data fifo specified by the board-structure -// pointer pB. Uses a 16-bit operation. Is called indirectly through -// pB->i2eReadWord. -// -//****************************************************************************** -static unsigned short -iiReadWord16(i2eBordStrPtr pB) -{ - return inw(pB->i2eData); -} - -//****************************************************************************** -// Function: iiReadWord8(pB) -// Parameters: pB - pointer to board structure -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Returns the word read from the data fifo specified by the board-structure -// pointer pB. Uses two 8-bit operations. Bytes are assumed to be LSB first. Is -// called indirectly through pB->i2eReadWord. -// -//****************************************************************************** -static unsigned short -iiReadWord8(i2eBordStrPtr pB) -{ - unsigned short urs; - - urs = inb(pB->i2eData); - - return (inb(pB->i2eData) << 8) | urs; -} - -//****************************************************************************** -// Function: iiWriteWord16(pB, value) -// Parameters: pB - pointer to board structure -// value - data to write -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Writes the word 'value' to the data fifo specified by the board-structure -// pointer pB. Uses 16-bit operation. Is called indirectly through -// pB->i2eWriteWord. -// -//****************************************************************************** -static void -iiWriteWord16(i2eBordStrPtr pB, unsigned short value) -{ - outw((int)value, pB->i2eData); -} - -//****************************************************************************** -// Function: iiWriteWord8(pB, value) -// Parameters: pB - pointer to board structure -// value - data to write -// -// Returns: True if everything appears copacetic. -// False if there is any error: the pB->i2eError field has the error -// -// Description: -// -// Writes the word 'value' to the data fifo specified by the board-structure -// pointer pB. Uses two 8-bit operations (writes LSB first). Is called -// indirectly through pB->i2eWriteWord. -// -//****************************************************************************** -static void -iiWriteWord8(i2eBordStrPtr pB, unsigned short value) -{ - outb((char)value, pB->i2eData); - outb((char)(value >> 8), pB->i2eData); -} - -//****************************************************************************** -// Function: iiWaitForTxEmptyII(pB, mSdelay) -// Parameters: pB - pointer to board structure -// mSdelay - period to wait before returning -// -// Returns: True if the FIFO is empty. -// False if it not empty in the required time: the pB->i2eError -// field has the error. -// -// Description: -// -// Waits up to "mSdelay" milliseconds for the outgoing FIFO to become empty; if -// not empty by the required time, returns false and error in pB->i2eError, -// otherwise returns true. -// -// mSdelay == 0 is taken to mean must be empty on the first test. -// -// This version operates on IntelliPort-II - style FIFO's -// -// Note this routine is organized so that if status is ok there is no delay at -// all called either before or after the test. Is called indirectly through -// pB->i2eWaitForTxEmpty. -// -//****************************************************************************** -static int -iiWaitForTxEmptyII(i2eBordStrPtr pB, int mSdelay) -{ - unsigned long flags; - int itemp; - - for (;;) - { - // This routine hinges on being able to see the "other" status register - // (as seen by the local processor). His incoming fifo is our outgoing - // FIFO. - // - // By the nature of this routine, you would be using this as part of a - // larger atomic context: i.e., you would use this routine to ensure the - // fifo empty, then act on this information. Between these two halves, - // you will generally not want to service interrupts or in any way - // disrupt the assumptions implicit in the larger context. - // - // Even worse, however, this routine "shifts" the status register to - // point to the local status register which is not the usual situation. - // Therefore for extra safety, we force the critical section to be - // completely atomic, and pick up after ourselves before allowing any - // interrupts of any kind. - - - write_lock_irqsave(&Dl_spinlock, flags); - outb(SEL_COMMAND, pB->i2ePointer); - outb(SEL_CMD_SH, pB->i2ePointer); - - itemp = inb(pB->i2eStatus); - - outb(SEL_COMMAND, pB->i2ePointer); - outb(SEL_CMD_UNSH, pB->i2ePointer); - - if (itemp & ST_IN_EMPTY) - { - I2_UPDATE_FIFO_ROOM(pB); - write_unlock_irqrestore(&Dl_spinlock, flags); - I2_COMPLETE(pB, I2EE_GOOD); - } - - write_unlock_irqrestore(&Dl_spinlock, flags); - - if (mSdelay-- == 0) - break; - - iiDelay(pB, 1); /* 1 mS granularity on checking condition */ - } - I2_COMPLETE(pB, I2EE_TXE_TIME); -} - -//****************************************************************************** -// Function: iiWaitForTxEmptyIIEX(pB, mSdelay) -// Parameters: pB - pointer to board structure -// mSdelay - period to wait before returning -// -// Returns: True if the FIFO is empty. -// False if it not empty in the required time: the pB->i2eError -// field has the error. -// -// Description: -// -// Waits up to "mSdelay" milliseconds for the outgoing FIFO to become empty; if -// not empty by the required time, returns false and error in pB->i2eError, -// otherwise returns true. -// -// mSdelay == 0 is taken to mean must be empty on the first test. -// -// This version operates on IntelliPort-IIEX - style FIFO's -// -// Note this routine is organized so that if status is ok there is no delay at -// all called either before or after the test. Is called indirectly through -// pB->i2eWaitForTxEmpty. -// -//****************************************************************************** -static int -iiWaitForTxEmptyIIEX(i2eBordStrPtr pB, int mSdelay) -{ - unsigned long flags; - - for (;;) - { - // By the nature of this routine, you would be using this as part of a - // larger atomic context: i.e., you would use this routine to ensure the - // fifo empty, then act on this information. Between these two halves, - // you will generally not want to service interrupts or in any way - // disrupt the assumptions implicit in the larger context. - - write_lock_irqsave(&Dl_spinlock, flags); - - if (inb(pB->i2eStatus) & STE_OUT_MT) { - I2_UPDATE_FIFO_ROOM(pB); - write_unlock_irqrestore(&Dl_spinlock, flags); - I2_COMPLETE(pB, I2EE_GOOD); - } - write_unlock_irqrestore(&Dl_spinlock, flags); - - if (mSdelay-- == 0) - break; - - iiDelay(pB, 1); // 1 mS granularity on checking condition - } - I2_COMPLETE(pB, I2EE_TXE_TIME); -} - -//****************************************************************************** -// Function: iiTxMailEmptyII(pB) -// Parameters: pB - pointer to board structure -// -// Returns: True if the transmit mailbox is empty. -// False if it not empty. -// -// Description: -// -// Returns true or false according to whether the transmit mailbox is empty (and -// therefore able to accept more mail) -// -// This version operates on IntelliPort-II - style FIFO's -// -//****************************************************************************** -static int -iiTxMailEmptyII(i2eBordStrPtr pB) -{ - int port = pB->i2ePointer; - outb(SEL_OUTMAIL, port); - return inb(port) == 0; -} - -//****************************************************************************** -// Function: iiTxMailEmptyIIEX(pB) -// Parameters: pB - pointer to board structure -// -// Returns: True if the transmit mailbox is empty. -// False if it not empty. -// -// Description: -// -// Returns true or false according to whether the transmit mailbox is empty (and -// therefore able to accept more mail) -// -// This version operates on IntelliPort-IIEX - style FIFO's -// -//****************************************************************************** -static int -iiTxMailEmptyIIEX(i2eBordStrPtr pB) -{ - return !(inb(pB->i2eStatus) & STE_OUT_MAIL); -} - -//****************************************************************************** -// Function: iiTrySendMailII(pB,mail) -// Parameters: pB - pointer to board structure -// mail - value to write to mailbox -// -// Returns: True if the transmit mailbox is empty, and mail is sent. -// False if it not empty. -// -// Description: -// -// If outgoing mailbox is empty, sends mail and returns true. If outgoing -// mailbox is not empty, returns false. -// -// This version operates on IntelliPort-II - style FIFO's -// -//****************************************************************************** -static int -iiTrySendMailII(i2eBordStrPtr pB, unsigned char mail) -{ - int port = pB->i2ePointer; - - outb(SEL_OUTMAIL, port); - if (inb(port) == 0) { - outb(SEL_OUTMAIL, port); - outb(mail, port); - return 1; - } - return 0; -} - -//****************************************************************************** -// Function: iiTrySendMailIIEX(pB,mail) -// Parameters: pB - pointer to board structure -// mail - value to write to mailbox -// -// Returns: True if the transmit mailbox is empty, and mail is sent. -// False if it not empty. -// -// Description: -// -// If outgoing mailbox is empty, sends mail and returns true. If outgoing -// mailbox is not empty, returns false. -// -// This version operates on IntelliPort-IIEX - style FIFO's -// -//****************************************************************************** -static int -iiTrySendMailIIEX(i2eBordStrPtr pB, unsigned char mail) -{ - if (inb(pB->i2eStatus) & STE_OUT_MAIL) - return 0; - outb(mail, pB->i2eXMail); - return 1; -} - -//****************************************************************************** -// Function: iiGetMailII(pB,mail) -// Parameters: pB - pointer to board structure -// -// Returns: Mailbox data or NO_MAIL_HERE. -// -// Description: -// -// If no mail available, returns NO_MAIL_HERE otherwise returns the data from -// the mailbox, which is guaranteed != NO_MAIL_HERE. -// -// This version operates on IntelliPort-II - style FIFO's -// -//****************************************************************************** -static unsigned short -iiGetMailII(i2eBordStrPtr pB) -{ - if (I2_HAS_MAIL(pB)) { - outb(SEL_INMAIL, pB->i2ePointer); - return inb(pB->i2ePointer); - } else { - return NO_MAIL_HERE; - } -} - -//****************************************************************************** -// Function: iiGetMailIIEX(pB,mail) -// Parameters: pB - pointer to board structure -// -// Returns: Mailbox data or NO_MAIL_HERE. -// -// Description: -// -// If no mail available, returns NO_MAIL_HERE otherwise returns the data from -// the mailbox, which is guaranteed != NO_MAIL_HERE. -// -// This version operates on IntelliPort-IIEX - style FIFO's -// -//****************************************************************************** -static unsigned short -iiGetMailIIEX(i2eBordStrPtr pB) -{ - if (I2_HAS_MAIL(pB)) - return inb(pB->i2eXMail); - else - return NO_MAIL_HERE; -} - -//****************************************************************************** -// Function: iiEnableMailIrqII(pB) -// Parameters: pB - pointer to board structure -// -// Returns: Nothing -// -// Description: -// -// Enables board to interrupt host (only) by writing to host's in-bound mailbox. -// -// This version operates on IntelliPort-II - style FIFO's -// -//****************************************************************************** -static void -iiEnableMailIrqII(i2eBordStrPtr pB) -{ - outb(SEL_MASK, pB->i2ePointer); - outb(ST_IN_MAIL, pB->i2ePointer); -} - -//****************************************************************************** -// Function: iiEnableMailIrqIIEX(pB) -// Parameters: pB - pointer to board structure -// -// Returns: Nothing -// -// Description: -// -// Enables board to interrupt host (only) by writing to host's in-bound mailbox. -// -// This version operates on IntelliPort-IIEX - style FIFO's -// -//****************************************************************************** -static void -iiEnableMailIrqIIEX(i2eBordStrPtr pB) -{ - outb(MX_IN_MAIL, pB->i2eXMask); -} - -//****************************************************************************** -// Function: iiWriteMaskII(pB) -// Parameters: pB - pointer to board structure -// -// Returns: Nothing -// -// Description: -// -// Writes arbitrary value to the mask register. -// -// This version operates on IntelliPort-II - style FIFO's -// -//****************************************************************************** -static void -iiWriteMaskII(i2eBordStrPtr pB, unsigned char value) -{ - outb(SEL_MASK, pB->i2ePointer); - outb(value, pB->i2ePointer); -} - -//****************************************************************************** -// Function: iiWriteMaskIIEX(pB) -// Parameters: pB - pointer to board structure -// -// Returns: Nothing -// -// Description: -// -// Writes arbitrary value to the mask register. -// -// This version operates on IntelliPort-IIEX - style FIFO's -// -//****************************************************************************** -static void -iiWriteMaskIIEX(i2eBordStrPtr pB, unsigned char value) -{ - outb(value, pB->i2eXMask); -} - -//****************************************************************************** -// Function: iiDownloadBlock(pB, pSource, isStandard) -// Parameters: pB - pointer to board structure -// pSource - loadware block to download -// isStandard - True if "standard" loadware, else false. -// -// Returns: Success or Failure -// -// Description: -// -// Downloads a single block (at pSource)to the board referenced by pB. Caller -// sets isStandard to true/false according to whether the "standard" loadware is -// what's being loaded. The normal process, then, is to perform an iiInitialize -// to the board, then perform some number of iiDownloadBlocks using the returned -// state to determine when download is complete. -// -// Possible return values: (see I2ELLIS.H) -// II_DOWN_BADVALID -// II_DOWN_BADFILE -// II_DOWN_CONTINUING -// II_DOWN_GOOD -// II_DOWN_BAD -// II_DOWN_BADSTATE -// II_DOWN_TIMEOUT -// -// Uses the i2eState and i2eToLoad fields (initialized at iiInitialize) to -// determine whether this is the first block, whether to check for magic -// numbers, how many blocks there are to go... -// -//****************************************************************************** -static int -iiDownloadBlock ( i2eBordStrPtr pB, loadHdrStrPtr pSource, int isStandard) -{ - int itemp; - int loadedFirst; - - if (pB->i2eValid != I2E_MAGIC) return II_DOWN_BADVALID; - - switch(pB->i2eState) - { - case II_STATE_READY: - - // Loading the first block after reset. Must check the magic number of the - // loadfile, store the number of blocks we expect to load. - if (pSource->e.loadMagic != MAGIC_LOADFILE) - { - return II_DOWN_BADFILE; - } - - // Next we store the total number of blocks to load, including this one. - pB->i2eToLoad = 1 + pSource->e.loadBlocksMore; - - // Set the state, store the version numbers. ('Cause this may have come - // from a file - we might want to report these versions and revisions in - // case of an error! - pB->i2eState = II_STATE_LOADING; - pB->i2eLVersion = pSource->e.loadVersion; - pB->i2eLRevision = pSource->e.loadRevision; - pB->i2eLSub = pSource->e.loadSubRevision; - - // The time and date of compilation is also available but don't bother - // storing it for normal purposes. - loadedFirst = 1; - break; - - case II_STATE_LOADING: - loadedFirst = 0; - break; - - default: - return II_DOWN_BADSTATE; - } - - // Now we must be in the II_STATE_LOADING state, and we assume i2eToLoad - // must be positive still, because otherwise we would have cleaned up last - // time and set the state to II_STATE_LOADED. - if (!iiWaitForTxEmpty(pB, MAX_DLOAD_READ_TIME)) { - return II_DOWN_TIMEOUT; - } - - if (!iiWriteBuf(pB, pSource->c, LOADWARE_BLOCK_SIZE)) { - return II_DOWN_BADVALID; - } - - // If we just loaded the first block, wait for the fifo to empty an extra - // long time to allow for any special startup code in the firmware, like - // sending status messages to the LCD's. - - if (loadedFirst) { - if (!iiWaitForTxEmpty(pB, MAX_DLOAD_START_TIME)) { - return II_DOWN_TIMEOUT; - } - } - - // Determine whether this was our last block! - if (--(pB->i2eToLoad)) { - return II_DOWN_CONTINUING; // more to come... - } - - // It WAS our last block: Clean up operations... - // ...Wait for last buffer to drain from the board... - if (!iiWaitForTxEmpty(pB, MAX_DLOAD_READ_TIME)) { - return II_DOWN_TIMEOUT; - } - // If there were only a single block written, this would come back - // immediately and be harmless, though not strictly necessary. - itemp = MAX_DLOAD_ACK_TIME/10; - while (--itemp) { - if (I2_HAS_INPUT(pB)) { - switch (inb(pB->i2eData)) { - case LOADWARE_OK: - pB->i2eState = - isStandard ? II_STATE_STDLOADED :II_STATE_LOADED; - - // Some revisions of the bootstrap firmware (e.g. ISA-8 1.0.2) - // will, // if there is a debug port attached, require some - // time to send information to the debug port now. It will do - // this before // executing any of the code we just downloaded. - // It may take up to 700 milliseconds. - if (pB->i2ePom.e.porDiag2 & POR_DEBUG_PORT) { - iiDelay(pB, 700); - } - - return II_DOWN_GOOD; - - case LOADWARE_BAD: - default: - return II_DOWN_BAD; - } - } - - iiDelay(pB, 10); // 10 mS granularity on checking condition - } - - // Drop-through --> timed out waiting for firmware confirmation - - pB->i2eState = II_STATE_BADLOAD; - return II_DOWN_TIMEOUT; -} - -//****************************************************************************** -// Function: iiDownloadAll(pB, pSource, isStandard, size) -// Parameters: pB - pointer to board structure -// pSource - loadware block to download -// isStandard - True if "standard" loadware, else false. -// size - size of data to download (in bytes) -// -// Returns: Success or Failure -// -// Description: -// -// Given a pointer to a board structure, a pointer to the beginning of some -// loadware, whether it is considered the "standard loadware", and the size of -// the array in bytes loads the entire array to the board as loadware. -// -// Assumes the board has been freshly reset and the power-up reset message read. -// (i.e., in II_STATE_READY). Complains if state is bad, or if there seems to be -// too much or too little data to load, or if iiDownloadBlock complains. -//****************************************************************************** -static int -iiDownloadAll(i2eBordStrPtr pB, loadHdrStrPtr pSource, int isStandard, int size) -{ - int status; - - // We know (from context) board should be ready for the first block of - // download. Complain if not. - if (pB->i2eState != II_STATE_READY) return II_DOWN_BADSTATE; - - while (size > 0) { - size -= LOADWARE_BLOCK_SIZE; // How much data should there be left to - // load after the following operation ? - - // Note we just bump pSource by "one", because its size is actually that - // of an entire block, same as LOADWARE_BLOCK_SIZE. - status = iiDownloadBlock(pB, pSource++, isStandard); - - switch(status) - { - case II_DOWN_GOOD: - return ( (size > 0) ? II_DOWN_OVER : II_DOWN_GOOD); - - case II_DOWN_CONTINUING: - break; - - default: - return status; - } - } - - // We shouldn't drop out: it means "while" caught us with nothing left to - // download, yet the previous DownloadBlock did not return complete. Ergo, - // not enough data to match the size byte in the header. - return II_DOWN_UNDER; -} diff --git a/drivers/staging/tty/ip2/i2ellis.h b/drivers/staging/tty/ip2/i2ellis.h deleted file mode 100644 index fb6df2456018..000000000000 --- a/drivers/staging/tty/ip2/i2ellis.h +++ /dev/null @@ -1,566 +0,0 @@ -/******************************************************************************* -* -* (c) 1999 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Mainline code for the device driver -* -*******************************************************************************/ -//------------------------------------------------------------------------------ -// i2ellis.h -// -// IntelliPort-II and IntelliPort-IIEX -// -// Extremely -// Low -// Level -// Interface -// Services -// -// Structure Definitions and declarations for "ELLIS" service routines found in -// i2ellis.c -// -// These routines are based on properties of the IntelliPort-II and -IIEX -// hardware and bootstrap firmware, and are not sensitive to particular -// conventions of any particular loadware. -// -// Unlike i2hw.h, which provides IRONCLAD hardware definitions, the material -// here and in i2ellis.c is intended to provice a useful, but not required, -// layer of insulation from the hardware specifics. -//------------------------------------------------------------------------------ -#ifndef I2ELLIS_H /* To prevent multiple includes */ -#define I2ELLIS_H 1 -//------------------------------------------------ -// Revision History: -// -// 30 September 1991 MAG First Draft Started -// 12 October 1991 ...continued... -// -// 20 December 1996 AKM Linux version -//------------------------------------------------- - -//---------------------- -// Mandatory Includes: -//---------------------- -#include "ip2types.h" -#include "i2hw.h" // The hardware definitions - -//------------------------------------------ -// STAT_BOXIDS packets -//------------------------------------------ -#define MAX_BOX 4 - -typedef struct _bidStat -{ - unsigned char bid_value[MAX_BOX]; -} bidStat, *bidStatPtr; - -// This packet is sent in response to a CMD_GET_BOXIDS bypass command. For -IIEX -// boards, reports the hardware-specific "asynchronous resource register" on -// each expansion box. Boxes not present report 0xff. For -II boards, the first -// element contains 0x80 for 8-port, 0x40 for 4-port boards. - -// Box IDs aka ARR or Async Resource Register (more than you want to know) -// 7 6 5 4 3 2 1 0 -// F F N N L S S S -// ============================= -// F F - Product Family Designator -// =====+++++++++++++++++++++++++++++++ -// 0 0 - Intelliport II EX / ISA-8 -// 1 0 - IntelliServer -// 0 1 - SAC - Port Device (Intelliport III ??? ) -// =====+++++++++++++++++++++++++++++++++++++++ -// N N - Number of Ports -// 0 0 - 8 (eight) -// 0 1 - 4 (four) -// 1 0 - 12 (twelve) -// 1 1 - 16 (sixteen) -// =++++++++++++++++++++++++++++++++++ -// L - LCD Display Module Present -// 0 - No -// 1 - LCD module present -// =========+++++++++++++++++++++++++++++++++++++ -// S S S - Async Signals Supported Designator -// 0 0 0 - 8dss, Mod DCE DB25 Female -// 0 0 1 - 6dss, RJ-45 -// 0 1 0 - RS-232/422 dss, DB25 Female -// 0 1 1 - RS-232/422 dss, separate 232/422 DB25 Female -// 1 0 0 - 6dss, 921.6 I/F with ST654's -// 1 0 1 - RS-423/232 8dss, RJ-45 10Pin -// 1 1 0 - 6dss, Mod DCE DB25 Female -// 1 1 1 - NO BOX PRESENT - -#define FF(c) ((c & 0xC0) >> 6) -#define NN(c) ((c & 0x30) >> 4) -#define L(c) ((c & 0x08) >> 3) -#define SSS(c) (c & 0x07) - -#define BID_HAS_654(x) (SSS(x) == 0x04) -#define BID_NO_BOX 0xff /* no box */ -#define BID_8PORT 0x80 /* IP2-8 port */ -#define BID_4PORT 0x81 /* IP2-4 port */ -#define BID_EXP_MASK 0x30 /* IP2-EX */ -#define BID_EXP_8PORT 0x00 /* 8, */ -#define BID_EXP_4PORT 0x10 /* 4, */ -#define BID_EXP_UNDEF 0x20 /* UNDEF, */ -#define BID_EXP_16PORT 0x30 /* 16, */ -#define BID_LCD_CTRL 0x08 /* LCD Controller */ -#define BID_LCD_NONE 0x00 /* - no controller present */ -#define BID_LCD_PRES 0x08 /* - controller present */ -#define BID_CON_MASK 0x07 /* - connector pinouts */ -#define BID_CON_DB25 0x00 /* - DB-25 F */ -#define BID_CON_RJ45 0x01 /* - rj45 */ - -//------------------------------------------------------------------------------ -// i2eBordStr -// -// This structure contains all the information the ELLIS routines require in -// dealing with a particular board. -//------------------------------------------------------------------------------ -// There are some queues here which are guaranteed to never contain the entry -// for a single channel twice. So they must be slightly larger to allow -// unambiguous full/empty management -// -#define CH_QUEUE_SIZE ABS_MOST_PORTS+2 - -typedef struct _i2eBordStr -{ - porStr i2ePom; // Structure containing the power-on message. - - unsigned short i2ePomSize; - // The number of bytes actually read if - // different from sizeof i2ePom, indicates - // there is an error! - - unsigned short i2eStartMail; - // Contains whatever inbound mailbox data - // present at startup. NO_MAIL_HERE indicates - // nothing was present. No special - // significance as of this writing, but may be - // useful for diagnostic reasons. - - unsigned short i2eValid; - // Indicates validity of the structure; if - // i2eValid == I2E_MAGIC, then we can trust - // the other fields. Some (especially - // initialization) functions are good about - // checking for validity. Many functions do - // not, it being assumed that the larger - // context assures we are using a valid - // i2eBordStrPtr. - - unsigned short i2eError; - // Used for returning an error condition from - // several functions which use i2eBordStrPtr - // as an argument. - - // Accelerators to characterize separate features of a board, derived from a - // number of sources. - - unsigned short i2eFifoSize; - // Always, the size of the FIFO. For - // IntelliPort-II, always the same, for -IIEX - // taken from the Power-On reset message. - - volatile - unsigned short i2eFifoRemains; - // Used during normal operation to indicate a - // lower bound on the amount of data which - // might be in the outbound fifo. - - unsigned char i2eFifoStyle; - // Accelerator which tells which style (-II or - // -IIEX) FIFO we are using. - - unsigned char i2eDataWidth16; - // Accelerator which tells whether we should - // do 8 or 16-bit data transfers. - - unsigned char i2eMaxIrq; - // The highest allowable IRQ, based on the - // slot size. - - // Accelerators for various addresses on the board - int i2eBase; // I/O Address of the Board - int i2eData; // From here data transfers happen - int i2eStatus; // From here status reads happen - int i2ePointer; // (IntelliPort-II: pointer/commands) - int i2eXMail; // (IntelliPOrt-IIEX: mailboxes - int i2eXMask; // (IntelliPort-IIEX: mask write - - //------------------------------------------------------- - // Information presented in a common format across boards - // For each box, bit map of the channels present. Box closest to - // the host is box 0. LSB is channel 0. IntelliPort-II (non-expandable) - // is taken to be box 0. These are derived from product i.d. registers. - - unsigned short i2eChannelMap[ABS_MAX_BOXES]; - - // Same as above, except each is derived from firmware attempting to detect - // the uart presence (by reading a valid GFRCR register). If bits are set in - // i2eChannelMap and not in i2eGoodMap, there is a potential problem. - - unsigned short i2eGoodMap[ABS_MAX_BOXES]; - - // --------------------------- - // For indirect function calls - - // Routine to cause an N-millisecond delay: Patched by the ii2Initialize - // function. - - void (*i2eDelay)(unsigned int); - - // Routine to write N bytes to the board through the FIFO. Returns true if - // all copacetic, otherwise returns false and error is in i2eError field. - // IF COUNT IS ODD, ROUNDS UP TO THE NEXT EVEN NUMBER. - - int (*i2eWriteBuf)(struct _i2eBordStr *, unsigned char *, int); - - // Routine to read N bytes from the board through the FIFO. Returns true if - // copacetic, otherwise returns false and error in i2eError. - // IF COUNT IS ODD, ROUNDS UP TO THE NEXT EVEN NUMBER. - - int (*i2eReadBuf)(struct _i2eBordStr *, unsigned char *, int); - - // Returns a word from FIFO. Will use 2 byte operations if needed. - - unsigned short (*i2eReadWord)(struct _i2eBordStr *); - - // Writes a word to FIFO. Will use 2 byte operations if needed. - - void (*i2eWriteWord)(struct _i2eBordStr *, unsigned short); - - // Waits specified time for the Transmit FIFO to go empty. Returns true if - // ok, otherwise returns false and error in i2eError. - - int (*i2eWaitForTxEmpty)(struct _i2eBordStr *, int); - - // Returns true or false according to whether the outgoing mailbox is empty. - - int (*i2eTxMailEmpty)(struct _i2eBordStr *); - - // Checks whether outgoing mailbox is empty. If so, sends mail and returns - // true. Otherwise returns false. - - int (*i2eTrySendMail)(struct _i2eBordStr *, unsigned char); - - // If no mail available, returns NO_MAIL_HERE, else returns the value in the - // mailbox (guaranteed can't be NO_MAIL_HERE). - - unsigned short (*i2eGetMail)(struct _i2eBordStr *); - - // Enables the board to interrupt the host when it writes to the mailbox. - // Irqs will not occur, however, until the loadware separately enables - // interrupt generation to the host. The standard loadware does this in - // response to a command packet sent by the host. (Also, disables - // any other potential interrupt sources from the board -- other than the - // inbound mailbox). - - void (*i2eEnableMailIrq)(struct _i2eBordStr *); - - // Writes an arbitrary value to the mask register. - - void (*i2eWriteMask)(struct _i2eBordStr *, unsigned char); - - - // State information - - // During downloading, indicates the number of blocks remaining to download - // to the board. - - short i2eToLoad; - - // State of board (see manifests below) (e.g., whether in reset condition, - // whether standard loadware is installed, etc. - - unsigned char i2eState; - - // These three fields are only valid when there is loadware running on the - // board. (i2eState == II_STATE_LOADED or i2eState == II_STATE_STDLOADED ) - - unsigned char i2eLVersion; // Loadware version - unsigned char i2eLRevision; // Loadware revision - unsigned char i2eLSub; // Loadware subrevision - - // Flags which only have meaning in the context of the standard loadware. - // Somewhat violates the layering concept, but there is so little additional - // needed at the board level (while much additional at the channel level), - // that this beats maintaining two different per-board structures. - - // Indicates which IRQ the board has been initialized (from software) to use - // For MicroChannel boards, any value different from IRQ_UNDEFINED means - // that the software command has been sent to enable interrupts (or specify - // they are disabled). Special value: IRQ_UNDEFINED indicates that the - // software command to select the interrupt has not yet been sent, therefore - // (since the standard loadware insists that it be sent before any other - // packets are sent) no other packets should be sent yet. - - unsigned short i2eUsingIrq; - - // This is set when we hit the MB_OUT_STUFFED mailbox, which prevents us - // putting more in the mailbox until an appropriate mailbox message is - // received. - - unsigned char i2eWaitingForEmptyFifo; - - // Any mailbox bits waiting to be sent to the board are OR'ed in here. - - unsigned char i2eOutMailWaiting; - - // The head of any incoming packet is read into here, is then examined and - // we dispatch accordingly. - - unsigned short i2eLeadoffWord[1]; - - // Running counter of interrupts where the mailbox indicated incoming data. - - unsigned short i2eFifoInInts; - - // Running counter of interrupts where the mailbox indicated outgoing data - // had been stripped. - - unsigned short i2eFifoOutInts; - - // If not void, gives the address of a routine to call if fatal board error - // is found (only applies to standard l/w). - - void (*i2eFatalTrap)(struct _i2eBordStr *); - - // Will point to an array of some sort of channel structures (whose format - // is unknown at this level, being a function of what loadware is - // installed and the code configuration (max sizes of buffers, etc.)). - - void *i2eChannelPtr; - - // Set indicates that the board has gone fatal. - - unsigned short i2eFatal; - - // The number of elements pointed to by i2eChannelPtr. - - unsigned short i2eChannelCnt; - - // Ring-buffers of channel structures whose channels have particular needs. - - rwlock_t Fbuf_spinlock; - volatile - unsigned short i2Fbuf_strip; // Strip index - volatile - unsigned short i2Fbuf_stuff; // Stuff index - void *i2Fbuf[CH_QUEUE_SIZE]; // An array of channel pointers - // of channels who need to send - // flow control packets. - rwlock_t Dbuf_spinlock; - volatile - unsigned short i2Dbuf_strip; // Strip index - volatile - unsigned short i2Dbuf_stuff; // Stuff index - void *i2Dbuf[CH_QUEUE_SIZE]; // An array of channel pointers - // of channels who need to send - // data or in-line command packets. - rwlock_t Bbuf_spinlock; - volatile - unsigned short i2Bbuf_strip; // Strip index - volatile - unsigned short i2Bbuf_stuff; // Stuff index - void *i2Bbuf[CH_QUEUE_SIZE]; // An array of channel pointers - // of channels who need to send - // bypass command packets. - - /* - * A set of flags to indicate that certain events have occurred on at least - * one of the ports on this board. We use this to decide whether to spin - * through the channels looking for breaks, etc. - */ - int got_input; - int status_change; - bidStat channelBtypes; - - /* - * Debugging counters, etc. - */ - unsigned long debugFlowQueued; - unsigned long debugInlineQueued; - unsigned long debugDataQueued; - unsigned long debugBypassQueued; - unsigned long debugFlowCount; - unsigned long debugInlineCount; - unsigned long debugBypassCount; - - rwlock_t read_fifo_spinlock; - rwlock_t write_fifo_spinlock; - -// For queuing interrupt bottom half handlers. /\/\|=mhw=|\/\/ - struct work_struct tqueue_interrupt; - - struct timer_list SendPendingTimer; // Used by iiSendPending - unsigned int SendPendingRetry; -} i2eBordStr, *i2eBordStrPtr; - -//------------------------------------------------------------------- -// Macro Definitions for the indirect calls defined in the i2eBordStr -//------------------------------------------------------------------- -// -#define iiDelay(a,b) (*(a)->i2eDelay)(b) -#define iiWriteBuf(a,b,c) (*(a)->i2eWriteBuf)(a,b,c) -#define iiReadBuf(a,b,c) (*(a)->i2eReadBuf)(a,b,c) - -#define iiWriteWord(a,b) (*(a)->i2eWriteWord)(a,b) -#define iiReadWord(a) (*(a)->i2eReadWord)(a) - -#define iiWaitForTxEmpty(a,b) (*(a)->i2eWaitForTxEmpty)(a,b) - -#define iiTxMailEmpty(a) (*(a)->i2eTxMailEmpty)(a) -#define iiTrySendMail(a,b) (*(a)->i2eTrySendMail)(a,b) - -#define iiGetMail(a) (*(a)->i2eGetMail)(a) -#define iiEnableMailIrq(a) (*(a)->i2eEnableMailIrq)(a) -#define iiDisableMailIrq(a) (*(a)->i2eWriteMask)(a,0) -#define iiWriteMask(a,b) (*(a)->i2eWriteMask)(a,b) - -//------------------------------------------- -// Manifests for i2eBordStr: -//------------------------------------------- - -typedef void (*delayFunc_t)(unsigned int); - -// i2eValid -// -#define I2E_MAGIC 0x4251 // Structure is valid. -#define I2E_INCOMPLETE 0x1122 // Structure failed during init. - - -// i2eError -// -#define I2EE_GOOD 0 // Operation successful -#define I2EE_BADADDR 1 // Address out of range -#define I2EE_BADSTATE 2 // Attempt to perform a function when the board - // structure was in the incorrect state -#define I2EE_BADMAGIC 3 // Bad magic number from Power On test (i2ePomSize - // reflects what was read -#define I2EE_PORM_SHORT 4 // Power On message too short -#define I2EE_PORM_LONG 5 // Power On message too long -#define I2EE_BAD_FAMILY 6 // Un-supported board family type -#define I2EE_INCONSIST 7 // Firmware reports something impossible, - // e.g. unexpected number of ports... Almost no - // excuse other than bad FIFO... -#define I2EE_POSTERR 8 // Power-On self test reported a bad error -#define I2EE_BADBUS 9 // Unknown Bus type declared in message -#define I2EE_TXE_TIME 10 // Timed out waiting for TX Fifo to empty -#define I2EE_INVALID 11 // i2eValid field does not indicate a valid and - // complete board structure (for functions which - // require this be so.) -#define I2EE_BAD_PORT 12 // Discrepancy between channels actually found and - // what the product is supposed to have. Check - // i2eGoodMap vs i2eChannelMap for details. -#define I2EE_BAD_IRQ 13 // Someone specified an unsupported IRQ -#define I2EE_NOCHANNELS 14 // No channel structures have been defined (for - // functions requiring this). - -// i2eFifoStyle -// -#define FIFO_II 0 /* IntelliPort-II style: see also i2hw.h */ -#define FIFO_IIEX 1 /* IntelliPort-IIEX style */ - -// i2eGetMail -// -#define NO_MAIL_HERE 0x1111 // Since mail is unsigned char, cannot possibly - // promote to 0x1111. -// i2eState -// -#define II_STATE_COLD 0 // Addresses have been defined, but board not even - // reset yet. -#define II_STATE_RESET 1 // Board,if it exists, has just been reset -#define II_STATE_READY 2 // Board ready for its first block -#define II_STATE_LOADING 3 // Board continuing load -#define II_STATE_LOADED 4 // Board has finished load: status ok -#define II_STATE_BADLOAD 5 // Board has finished load: failed! -#define II_STATE_STDLOADED 6 // Board has finished load: standard firmware - -// i2eUsingIrq -// -#define I2_IRQ_UNDEFINED 0x1352 /* No valid irq (or polling = 0) can - * ever promote to this! */ -//------------------------------------------ -// Handy Macros for i2ellis.c and others -// Note these are common to -II and -IIEX -//------------------------------------------ - -// Given a pointer to the board structure, does the input FIFO have any data or -// not? -// -#define I2_HAS_INPUT(pB) !(inb(pB->i2eStatus) & ST_IN_EMPTY) - -// Given a pointer to the board structure, is there anything in the incoming -// mailbox? -// -#define I2_HAS_MAIL(pB) (inb(pB->i2eStatus) & ST_IN_MAIL) - -#define I2_UPDATE_FIFO_ROOM(pB) ((pB)->i2eFifoRemains = (pB)->i2eFifoSize) - -//------------------------------------------ -// Function Declarations for i2ellis.c -//------------------------------------------ -// -// Functions called directly -// -// Initialization of a board & structure is in four (five!) parts: -// -// 1) iiSetAddress() - Define the board address & delay function for a board. -// 2) iiReset() - Reset the board (provided it exists) -// -- Note you may do this to several boards -- -// 3) iiResetDelay() - Delay for 2 seconds (once for all boards) -// 4) iiInitialize() - Attempt to read Power-up message; further initialize -// accelerators -// -// Then you may use iiDownloadAll() or iiDownloadFile() (in i2file.c) to write -// loadware. To change loadware, you must begin again with step 2, resetting -// the board again (step 1 not needed). - -static int iiSetAddress(i2eBordStrPtr, int, delayFunc_t ); -static int iiReset(i2eBordStrPtr); -static int iiResetDelay(i2eBordStrPtr); -static int iiInitialize(i2eBordStrPtr); - -// Routine to validate that all channels expected are there. -// -extern int iiValidateChannels(i2eBordStrPtr); - -// Routine used to download a block of loadware. -// -static int iiDownloadBlock(i2eBordStrPtr, loadHdrStrPtr, int); - -// Return values given by iiDownloadBlock, iiDownloadAll, iiDownloadFile: -// -#define II_DOWN_BADVALID 0 // board structure is invalid -#define II_DOWN_CONTINUING 1 // So far, so good, firmware expects more -#define II_DOWN_GOOD 2 // Download complete, CRC good -#define II_DOWN_BAD 3 // Download complete, but CRC bad -#define II_DOWN_BADFILE 4 // Bad magic number in loadware file -#define II_DOWN_BADSTATE 5 // Board is in an inappropriate state for - // downloading loadware. (see i2eState) -#define II_DOWN_TIMEOUT 6 // Timeout waiting for firmware -#define II_DOWN_OVER 7 // Too much data -#define II_DOWN_UNDER 8 // Not enough data -#define II_DOWN_NOFILE 9 // Loadware file not found - -// Routine to download an entire loadware module: Return values are a subset of -// iiDownloadBlock's, excluding, of course, II_DOWN_CONTINUING -// -static int iiDownloadAll(i2eBordStrPtr, loadHdrStrPtr, int, int); - -// Many functions defined here return True if good, False otherwise, with an -// error code in i2eError field. Here is a handy macro for setting the error -// code and returning. -// -#define I2_COMPLETE(pB,code) do { \ - pB->i2eError = code; \ - return (code == I2EE_GOOD);\ - } while (0) - -#endif // I2ELLIS_H diff --git a/drivers/staging/tty/ip2/i2hw.h b/drivers/staging/tty/ip2/i2hw.h deleted file mode 100644 index 8df2f487217a..000000000000 --- a/drivers/staging/tty/ip2/i2hw.h +++ /dev/null @@ -1,652 +0,0 @@ -/******************************************************************************* -* -* (c) 1999 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Definitions limited to properties of the hardware or the -* bootstrap firmware. As such, they are applicable regardless of -* operating system or loadware (standard or diagnostic). -* -*******************************************************************************/ -#ifndef I2HW_H -#define I2HW_H 1 -//------------------------------------------------------------------------------ -// Revision History: -// -// 23 September 1991 MAG First Draft Started...through... -// 11 October 1991 ... Continuing development... -// 6 August 1993 Added support for ISA-4 (asic) which is architected -// as an ISA-CEX with a single 4-port box. -// -// 20 December 1996 AKM Version for Linux -// -//------------------------------------------------------------------------------ -/*------------------------------------------------------------------------------ - -HARDWARE DESCRIPTION: - -Introduction: - -The IntelliPort-II and IntelliPort-IIEX products occupy a block of eight (8) -addresses in the host's I/O space. - -Some addresses are used to transfer data to/from the board, some to transfer -so-called "mailbox" messages, and some to read bit-mapped status information. -While all the products in the line are functionally similar, some use a 16-bit -data path to transfer data while others use an 8-bit path. Also, the use of -command /status/mailbox registers differs slightly between the II and IIEX -branches of the family. - -The host determines what type of board it is dealing with by reading a string of -sixteen characters from the board. These characters are always placed in the -fifo by the board's local processor whenever the board is reset (either from -power-on or under software control) and are known as the "Power-on Reset -Message." In order that this message can be read from either type of board, the -hardware registers used in reading this message are the same. Once this message -has been read by the host, then it has the information required to operate. - -General Differences between boards: - -The greatest structural difference is between the -II and -IIEX families of -product. The -II boards use the Am4701 dual 512x8 bidirectional fifo to support -the data path, mailbox registers, and status registers. This chip contains some -features which are not used in the IntelliPort-II products; a description of -these is omitted here. Because of these many features, it contains many -registers, too many to access directly within a small address space. They are -accessed by first writing a value to a "pointer" register. This value selects -the register to be accessed. The next read or write to that address accesses -the selected register rather than the pointer register. - -The -IIEX boards use a proprietary design similar to the Am4701 in function. But -because of a simpler, more streamlined design it doesn't require so many -registers. This means they can be accessed directly in single operations rather -than through a pointer register. - -Besides these differences, there are differences in whether 8-bit or 16-bit -transfers are used to move data to the board. - -The -II boards are capable only of 8-bit data transfers, while the -IIEX boards -may be configured for either 8-bit or 16-bit data transfers. If the on-board DIP -switch #8 is ON, and the card has been installed in a 16-bit slot, 16-bit -transfers are supported (and will be expected by the standard loadware). The -on-board firmware can determine the position of the switch, and whether the -board is installed in a 16-bit slot; it supplies this information to the host as -part of the power-up reset message. - -The configuration switch (#8) and slot selection do not directly configure the -hardware. It is up to the on-board loadware and host-based drivers to act -according to the selected options. That is, loadware and drivers could be -written to perform 8-bit transfers regardless of the state of the DIP switch or -slot (and in a diagnostic environment might well do so). Likewise, 16-bit -transfers could be performed as long as the card is in a 16-bit slot. - -Note the slot selection and DIP switch selection are provided separately: a -board running in 8-bit mode in a 16-bit slot has a greater range of possible -interrupts to choose from; information of potential use to the host. - -All 8-bit data transfers are done in the same way, regardless of whether on a --II board or a -IIEX board. - -The host must consider two things then: 1) whether a -II or -IIEX product is -being used, and 2) whether an 8-bit or 16-bit data path is used. - -A further difference is that -II boards always have a 512-byte fifo operating in -each direction. -IIEX boards may use fifos of varying size; this size is -reported as part of the power-up message. - -I/O Map Of IntelliPort-II and IntelliPort-IIEX boards: -(Relative to the chosen base address) - -Addr R/W IntelliPort-II IntelliPort-IIEX ----- --- -------------- ---------------- -0 R/W Data Port (byte) Data Port (byte or word) -1 R/W (Not used) (MSB of word-wide data written to Data Port) -2 R Status Register Status Register -2 W Pointer Register Interrupt Mask Register -3 R/W (Not used) Mailbox Registers (6 bits: 11111100) -4,5 -- Reserved for future products -6 -- Reserved for future products -7 R Guaranteed to have no effect -7 W Hardware reset of board. - - -Rules: -All data transfers are performed using the even i/o address. If byte-wide data -transfers are being used, do INB/OUTB operations on the data port. If word-wide -transfers are used, do INW/OUTW operations. In some circumstances (such as -reading the power-up message) you will do INB from the data port, but in this -case the MSB of each word read is lost. When accessing all other unreserved -registers, use byte operations only. -------------------------------------------------------------------------------*/ - -//------------------------------------------------ -// Mandatory Includes: -//------------------------------------------------ -// -#include "ip2types.h" - -//------------------------------------------------------------------------- -// Manifests for the I/O map: -//------------------------------------------------------------------------- -// R/W: Data port (byte) for IntelliPort-II, -// R/W: Data port (byte or word) for IntelliPort-IIEX -// Incoming or outgoing data passes through a FIFO, the status of which is -// available in some of the bits in FIFO_STATUS. This (bidirectional) FIFO is -// the primary means of transferring data, commands, flow-control, and status -// information between the host and board. -// -#define FIFO_DATA 0 - -// Another way of passing information between the board and the host is -// through "mailboxes". Unlike a FIFO, a mailbox holds only a single byte of -// data. Writing data to the mailbox causes a status bit to be set, and -// potentially interrupting the intended receiver. The sender has some way to -// determine whether the data has been read yet; as soon as it has, it may send -// more. The mailboxes are handled differently on -II and -IIEX products, as -// suggested below. -//------------------------------------------------------------------------------ -// Read: Status Register for IntelliPort-II or -IIEX -// The presence of any bit set here will cause an interrupt to the host, -// provided the corresponding bit has been unmasked in the interrupt mask -// register. Furthermore, interrupts to the host are disabled globally until the -// loadware selects the irq line to use. With the exception of STN_MR, the bits -// remain set so long as the associated condition is true. -// -#define FIFO_STATUS 2 - -// Bit map of status bits which are identical for -II and -IIEX -// -#define ST_OUT_FULL 0x40 // Outbound FIFO full -#define ST_IN_EMPTY 0x20 // Inbound FIFO empty -#define ST_IN_MAIL 0x04 // Inbound Mailbox full - -// The following exists only on the Intelliport-IIEX, and indicates that the -// board has not read the last outgoing mailbox data yet. In the IntelliPort-II, -// the outgoing mailbox may be read back: a zero indicates the board has read -// the data. -// -#define STE_OUT_MAIL 0x80 // Outbound mailbox full (!) - -// The following bits are defined differently for -II and -IIEX boards. Code -// which relies on these bits will need to be functionally different for the two -// types of boards and should be generally avoided because of the additional -// complexity this creates: - -// Bit map of status bits only on -II - -// Fifo has been RESET (cleared when the status register is read). Note that -// this condition cannot be masked and would always interrupt the host, except -// that the hardware reset also disables interrupts globally from the board -// until re-enabled by loadware. This could also arise from the -// Am4701-supported command to reset the chip, but this command is generally not -// used here. -// -#define STN_MR 0x80 - -// See the AMD Am4701 data sheet for details on the following four bits. They -// are not presently used by Computone drivers. -// -#define STN_OUT_AF 0x10 // Outbound FIFO almost full (programmable) -#define STN_IN_AE 0x08 // Inbound FIFO almost empty (programmable) -#define STN_BD 0x02 // Inbound byte detected -#define STN_PE 0x01 // Parity/Framing condition detected - -// Bit-map of status bits only on -IIEX -// -#define STE_OUT_HF 0x10 // Outbound FIFO half full -#define STE_IN_HF 0x08 // Inbound FIFO half full -#define STE_IN_FULL 0x02 // Inbound FIFO full -#define STE_OUT_MT 0x01 // Outbound FIFO empty - -//------------------------------------------------------------------------------ - -// Intelliport-II -- Write Only: the pointer register. -// Values are written to this register to select the Am4701 internal register to -// be accessed on the next operation. -// -#define FIFO_PTR 0x02 - -// Values for the pointer register -// -#define SEL_COMMAND 0x1 // Selects the Am4701 command register - -// Some possible commands: -// -#define SEL_CMD_MR 0x80 // Am4701 command to reset the chip -#define SEL_CMD_SH 0x40 // Am4701 command to map the "other" port into the - // status register. -#define SEL_CMD_UNSH 0 // Am4701 command to "unshift": port maps into its - // own status register. -#define SEL_MASK 0x2 // Selects the Am4701 interrupt mask register. The - // interrupt mask register is bit-mapped to match - // the status register (FIFO_STATUS) except for - // STN_MR. (See above.) -#define SEL_BYTE_DET 0x3 // Selects the Am4701 byte-detect register. (Not - // normally used except in diagnostics.) -#define SEL_OUTMAIL 0x4 // Selects the outbound mailbox (R/W). Reading back - // a value of zero indicates that the mailbox has - // been read by the board and is available for more - // data./ Writing to the mailbox optionally - // interrupts the board, depending on the loadware's - // setting of its interrupt mask register. -#define SEL_AEAF 0x5 // Selects AE/AF threshold register. -#define SEL_INMAIL 0x6 // Selects the inbound mailbox (Read) - -//------------------------------------------------------------------------------ -// IntelliPort-IIEX -- Write Only: interrupt mask (and misc flags) register: -// Unlike IntelliPort-II, bit assignments do NOT match those of the status -// register. -// -#define FIFO_MASK 0x2 - -// Mailbox readback select: -// If set, reads to FIFO_MAIL will read the OUTBOUND mailbox (host to board). If -// clear (default on reset) reads to FIFO_MAIL will read the INBOUND mailbox. -// This is the normal situation. The clearing of a mailbox is determined on -// -IIEX boards by waiting for the STE_OUT_MAIL bit to clear. Readback -// capability is provided for diagnostic purposes only. -// -#define MX_OUTMAIL_RSEL 0x80 - -#define MX_IN_MAIL 0x40 // Enables interrupts when incoming mailbox goes - // full (ST_IN_MAIL set). -#define MX_IN_FULL 0x20 // Enables interrupts when incoming FIFO goes full - // (STE_IN_FULL). -#define MX_IN_MT 0x08 // Enables interrupts when incoming FIFO goes empty - // (ST_IN_MT). -#define MX_OUT_FULL 0x04 // Enables interrupts when outgoing FIFO goes full - // (ST_OUT_FULL). -#define MX_OUT_MT 0x01 // Enables interrupts when outgoing FIFO goes empty - // (STE_OUT_MT). - -// Any remaining bits are reserved, and should be written to ZERO for -// compatibility with future Computone products. - -//------------------------------------------------------------------------------ -// IntelliPort-IIEX: -- These are only 6-bit mailboxes !!! -- 11111100 (low two -// bits always read back 0). -// Read: One of the mailboxes, usually Inbound. -// Inbound Mailbox (MX_OUTMAIL_RSEL = 0) -// Outbound Mailbox (MX_OUTMAIL_RSEL = 1) -// Write: Outbound Mailbox -// For the IntelliPort-II boards, the outbound mailbox is read back to determine -// whether the board has read the data (0 --> data has been read). For the -// IntelliPort-IIEX, this is done by reading a status register. To determine -// whether mailbox is available for more outbound data, use the STE_OUT_MAIL bit -// in FIFO_STATUS. Moreover, although the Outbound Mailbox can be read back by -// setting MX_OUTMAIL_RSEL, it is NOT cleared when the board reads it, as is the -// case with the -II boards. For this reason, FIFO_MAIL is normally used to read -// the inbound FIFO, and MX_OUTMAIL_RSEL kept clear. (See above for -// MX_OUTMAIL_RSEL description.) -// -#define FIFO_MAIL 0x3 - -//------------------------------------------------------------------------------ -// WRITE ONLY: Resets the board. (Data doesn't matter). -// -#define FIFO_RESET 0x7 - -//------------------------------------------------------------------------------ -// READ ONLY: Will have no effect. (Data is undefined.) -// Actually, there will be an effect, in that the operation is sure to generate -// a bus cycle: viz., an I/O byte Read. This fact can be used to enforce short -// delays when no comparable time constant is available. -// -#define FIFO_NOP 0x7 - -//------------------------------------------------------------------------------ -// RESET & POWER-ON RESET MESSAGE -/*------------------------------------------------------------------------------ -RESET: - -The IntelliPort-II and -IIEX boards are reset in three ways: Power-up, channel -reset, and via a write to the reset register described above. For products using -the ISA bus, these three sources of reset are equvalent. For MCA and EISA buses, -the Power-up and channel reset sources cause additional hardware initialization -which should only occur at system startup time. - -The third type of reset, called a "command reset", is done by writing any data -to the FIFO_RESET address described above. This resets the on-board processor, -FIFO, UARTS, and associated hardware. - -This passes control of the board to the bootstrap firmware, which performs a -Power-On Self Test and which detects its current configuration. For example, --IIEX products determine the size of FIFO which has been installed, and the -number and type of expansion boxes attached. - -This and other information is then written to the FIFO in a 16-byte data block -to be read by the host. This block is guaranteed to be present within two (2) -seconds of having received the command reset. The firmware is now ready to -receive loadware from the host. - -It is good practice to perform a command reset to the board explicitly as part -of your software initialization. This allows your code to properly restart from -a soft boot. (Many systems do not issue channel reset on soft boot). - -Because of a hardware reset problem on some of the Cirrus Logic 1400's which are -used on the product, it is recommended that you reset the board twice, separated -by an approximately 50 milliseconds delay. (VERY approximately: probably ok to -be off by a factor of five. The important point is that the first command reset -in fact generates a reset pulse on the board. This pulse is guaranteed to last -less than 10 milliseconds. The additional delay ensures the 1400 has had the -chance to respond sufficiently to the first reset. Why not a longer delay? Much -more than 50 milliseconds gets to be noticeable, but the board would still work. - -Once all 16 bytes of the Power-on Reset Message have been read, the bootstrap -firmware is ready to receive loadware. - -Note on Power-on Reset Message format: -The various fields have been designed with future expansion in view. -Combinations of bitfields and values have been defined which define products -which may not currently exist. This has been done to allow drivers to anticipate -the possible introduction of products in a systematic fashion. This is not -intended to suggest that each potential product is actually under consideration. -------------------------------------------------------------------------------*/ - -//---------------------------------------- -// Format of Power-on Reset Message -//---------------------------------------- - -typedef union _porStr // "por" stands for Power On Reset -{ - unsigned char c[16]; // array used when considering the message as a - // string of undifferentiated characters - - struct // Elements used when considering values - { - // The first two bytes out of the FIFO are two magic numbers. These are - // intended to establish that there is indeed a member of the - // IntelliPort-II(EX) family present. The remaining bytes may be - // expected // to be valid. When reading the Power-on Reset message, - // if the magic numbers do not match it is probably best to stop - // reading immediately. You are certainly not reading our board (unless - // hardware is faulty), and may in fact be reading some other piece of - // hardware. - - unsigned char porMagic1; // magic number: first byte == POR_MAGIC_1 - unsigned char porMagic2; // magic number: second byte == POR_MAGIC_2 - - // The Version, Revision, and Subrevision are stored as absolute numbers - // and would normally be displayed in the format V.R.S (e.g. 1.0.2) - - unsigned char porVersion; // Bootstrap firmware version number - unsigned char porRevision; // Bootstrap firmware revision number - unsigned char porSubRev; // Bootstrap firmware sub-revision number - - unsigned char porID; // Product ID: Bit-mapped according to - // conventions described below. Among other - // things, this allows us to distinguish - // IntelliPort-II boards from IntelliPort-IIEX - // boards. - - unsigned char porBus; // IntelliPort-II: Unused - // IntelliPort-IIEX: Bus Information: - // Bit-mapped below - - unsigned char porMemory; // On-board DRAM size: in 32k blocks - - // porPorts1 (and porPorts2) are used to determine the ports which are - // available to the board. For non-expandable product, a single number - // is sufficient. For expandable product, the board may be connected - // to as many as four boxes. Each box may be (so far) either a 16-port - // or an 8-port size. Whenever an 8-port box is used, the remaining 8 - // ports leave gaps between existing channels. For that reason, - // expandable products must report a MAP of available channels. Since - // each UART supports four ports, we represent each UART found by a - // single bit. Using two bytes to supply the mapping information we - // report the presence or absence of up to 16 UARTS, or 64 ports in - // steps of 4 ports. For -IIEX products, the ports are numbered - // starting at the box closest to the controller in the "chain". - - // Interpreted Differently for IntelliPort-II and -IIEX. - // -II: Number of ports (Derived actually from product ID). See - // Diag1&2 to indicate if uart was actually detected. - // -IIEX: Bit-map of UARTS found, LSB (see below for MSB of this). This - // bitmap is based on detecting the uarts themselves; - // see porFlags for information from the box i.d's. - unsigned char porPorts1; - - unsigned char porDiag1; // Results of on-board P.O.S.T, 1st byte - unsigned char porDiag2; // Results of on-board P.O.S.T, 2nd byte - unsigned char porSpeed; // Speed of local CPU: given as MHz x10 - // e.g., 16.0 MHz CPU is reported as 160 - unsigned char porFlags; // Misc information (see manifests below) - // Bit-mapped: CPU type, UART's present - - unsigned char porPorts2; // -II: Undefined - // -IIEX: Bit-map of UARTS found, MSB (see - // above for LSB) - - // IntelliPort-II: undefined - // IntelliPort-IIEX: 1 << porFifoSize gives the size, in bytes, of the - // host interface FIFO, in each direction. When running the -IIEX in - // 8-bit mode, fifo capacity is halved. The bootstrap firmware will - // have already accounted for this fact in generating this number. - unsigned char porFifoSize; - - // IntelliPort-II: undefined - // IntelliPort-IIEX: The number of boxes connected. (Presently 1-4) - unsigned char porNumBoxes; - } e; -} porStr, *porStrPtr; - -//-------------------------- -// Values for porStr fields -//-------------------------- - -//--------------------- -// porMagic1, porMagic2 -//---------------------- -// -#define POR_MAGIC_1 0x96 // The only valid value for porMagic1 -#define POR_MAGIC_2 0x35 // The only valid value for porMagic2 -#define POR_1_INDEX 0 // Byte position of POR_MAGIC_1 -#define POR_2_INDEX 1 // Ditto for POR_MAGIC_2 - -//---------------------- -// porID -//---------------------- -// -#define POR_ID_FAMILY 0xc0 // These bits indicate the general family of - // product. -#define POR_ID_FII 0x00 // Family is "IntelliPort-II" -#define POR_ID_FIIEX 0x40 // Family is "IntelliPort-IIEX" - -// These bits are reserved, presently zero. May be used at a later date to -// convey other product information. -// -#define POR_ID_RESERVED 0x3c - -#define POR_ID_SIZE 0x03 // Remaining bits indicate number of ports & - // Connector information. -#define POR_ID_II_8 0x00 // For IntelliPort-II, indicates 8-port using - // standard brick. -#define POR_ID_II_8R 0x01 // For IntelliPort-II, indicates 8-port using - // RJ11's (no CTS) -#define POR_ID_II_6 0x02 // For IntelliPort-II, indicates 6-port using - // RJ45's -#define POR_ID_II_4 0x03 // For IntelliPort-II, indicates 4-port using - // 4xRJ45 connectors -#define POR_ID_EX 0x00 // For IntelliPort-IIEX, indicates standard - // expandable controller (other values reserved) - -//---------------------- -// porBus -//---------------------- - -// IntelliPort-IIEX only: Board is installed in a 16-bit slot -// -#define POR_BUS_SLOT16 0x20 - -// IntelliPort-IIEX only: DIP switch #8 is on, selecting 16-bit host interface -// operation. -// -#define POR_BUS_DIP16 0x10 - -// Bits 0-2 indicate type of bus: This information is stored in the bootstrap -// loadware, different loadware being used on different products for different -// buses. For most situations, the drivers do not need this information; but it -// is handy in a diagnostic environment. For example, on microchannel boards, -// you would not want to try to test several interrupts, only the one for which -// you were configured. -// -#define POR_BUS_TYPE 0x07 - -// Unknown: this product doesn't know what bus it is running in. (e.g. if same -// bootstrap firmware were wanted for two different buses.) -// -#define POR_BUS_T_UNK 0 - -// Note: existing firmware for ISA-8 and MC-8 currently report the POR_BUS_T_UNK -// state, since the same bootstrap firmware is used for each. - -#define POR_BUS_T_MCA 1 // MCA BUS */ -#define POR_BUS_T_EISA 2 // EISA BUS */ -#define POR_BUS_T_ISA 3 // ISA BUS */ - -// Values 4-7 Reserved - -// Remaining bits are reserved - -//---------------------- -// porDiag1 -//---------------------- - -#define POR_BAD_MAPPER 0x80 // HW failure on P.O.S.T: Chip mapper failed - -// These two bits valid only for the IntelliPort-II -// -#define POR_BAD_UART1 0x01 // First 1400 bad -#define POR_BAD_UART2 0x02 // Second 1400 bad - -//---------------------- -// porDiag2 -//---------------------- - -#define POR_DEBUG_PORT 0x80 // debug port was detected by the P.O.S.T -#define POR_DIAG_OK 0x00 // Indicates passage: Failure codes not yet - // available. - // Other bits undefined. -//---------------------- -// porFlags -//---------------------- - -#define POR_CPU 0x03 // These bits indicate supposed CPU type -#define POR_CPU_8 0x01 // Board uses an 80188 (no such thing yet) -#define POR_CPU_6 0x02 // Board uses an 80186 (all existing products) -#define POR_CEX4 0x04 // If set, this is an ISA-CEX/4: An ISA-4 (asic) - // which is architected like an ISA-CEX connected - // to a (hitherto impossible) 4-port box. -#define POR_BOXES 0xf0 // Valid for IntelliPort-IIEX only: Map of Box - // sizes based on box I.D. -#define POR_BOX_16 0x10 // Set indicates 16-port, clear 8-port - -//------------------------------------- -// LOADWARE and DOWNLOADING CODE -//------------------------------------- - -/* -Loadware may be sent to the board in two ways: -1) It may be read from a (binary image) data file block by block as each block - is sent to the board. This is only possible when the initialization is - performed by code which can access your file system. This is most suitable - for diagnostics and appications which use the interface library directly. - -2) It may be hard-coded into your source by including a .h file (typically - supplied by Computone), which declares a data array and initializes every - element. This achieves the same result as if an entire loadware file had - been read into the array. - - This requires more data space in your program, but access to the file system - is not required. This method is more suited to driver code, which typically - is running at a level too low to access the file system directly. - -At present, loadware can only be generated at Computone. - -All Loadware begins with a header area which has a particular format. This -includes a magic number which identifies the file as being (purportedly) -loadware, CRC (for the loader), and version information. -*/ - - -//----------------------------------------------------------------------------- -// Format of loadware block -// -// This is defined as a union so we can pass a pointer to one of these items -// and (if it is the first block) pick out the version information, etc. -// -// Otherwise, to deal with this as a simple character array -//------------------------------------------------------------------------------ - -#define LOADWARE_BLOCK_SIZE 512 // Number of bytes in each block of loadware - -typedef union _loadHdrStr -{ - unsigned char c[LOADWARE_BLOCK_SIZE]; // Valid for every block - - struct // These fields are valid for only the first block of loadware. - { - unsigned char loadMagic; // Magic number: see below - unsigned char loadBlocksMore; // How many more blocks? - unsigned char loadCRC[2]; // Two CRC bytes: used by loader - unsigned char loadVersion; // Version number - unsigned char loadRevision; // Revision number - unsigned char loadSubRevision; // Sub-revision number - unsigned char loadSpares[9]; // Presently unused - unsigned char loadDates[32]; // Null-terminated string which can give - // date and time of compilation - } e; -} loadHdrStr, *loadHdrStrPtr; - -//------------------------------------ -// Defines for downloading code: -//------------------------------------ - -// The loadMagic field in the first block of the loadfile must be this, else the -// file is not valid. -// -#define MAGIC_LOADFILE 0x3c - -// How do we know the load was successful? On completion of the load, the -// bootstrap firmware returns a code to indicate whether it thought the download -// was valid and intends to execute it. These are the only possible valid codes: -// -#define LOADWARE_OK 0xc3 // Download was ok -#define LOADWARE_BAD 0x5a // Download was bad (CRC error) - -// Constants applicable to writing blocks of loadware: -// The first block of loadware might take 600 mS to load, in extreme cases. -// (Expandable board: worst case for sending startup messages to the LCD's). -// The 600mS figure is not really a calculation, but a conservative -// guess/guarantee. Usually this will be within 100 mS, like subsequent blocks. -// -#define MAX_DLOAD_START_TIME 1000 // 1000 mS -#define MAX_DLOAD_READ_TIME 100 // 100 mS - -// Firmware should respond with status (see above) within this long of host -// having sent the final block. -// -#define MAX_DLOAD_ACK_TIME 100 // 100 mS, again! - -//------------------------------------------------------ -// MAXIMUM NUMBER OF PORTS PER BOARD: -// This is fixed for now (with the expandable), but may -// be expanding according to even newer products. -//------------------------------------------------------ -// -#define ABS_MAX_BOXES 4 // Absolute most boxes per board -#define ABS_BIGGEST_BOX 16 // Absolute the most ports per box -#define ABS_MOST_PORTS (ABS_MAX_BOXES * ABS_BIGGEST_BOX) - -#define I2_OUTSW(port, addr, count) outsw((port), (addr), (((count)+1)/2)) -#define I2_OUTSB(port, addr, count) outsb((port), (addr), (((count)+1))&-2) -#define I2_INSW(port, addr, count) insw((port), (addr), (((count)+1)/2)) -#define I2_INSB(port, addr, count) insb((port), (addr), (((count)+1))&-2) - -#endif // I2HW_H - diff --git a/drivers/staging/tty/ip2/i2lib.c b/drivers/staging/tty/ip2/i2lib.c deleted file mode 100644 index 13a3caba85f2..000000000000 --- a/drivers/staging/tty/ip2/i2lib.c +++ /dev/null @@ -1,2214 +0,0 @@ -/******************************************************************************* -* -* (c) 1999 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport -* serial I/O controllers. -* -* DESCRIPTION: High-level interface code for the device driver. Uses the -* Extremely Low Level Interface Support (i2ellis.c). Provides an -* interface to the standard loadware, to support drivers or -* application code. (This is included source code, not a separate -* compilation module.) -* -*******************************************************************************/ -//------------------------------------------------------------------------------ -// Note on Strategy: -// Once the board has been initialized, it will interrupt us when: -// 1) It has something in the fifo for us to read (incoming data, flow control -// packets, or whatever). -// 2) It has stripped whatever we have sent last time in the FIFO (and -// consequently is ready for more). -// -// Note also that the buffer sizes declared in i2lib.h are VERY SMALL. This -// worsens performance considerably, but is done so that a great many channels -// might use only a little memory. -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// Revision History: -// -// 0.00 - 4/16/91 --- First Draft -// 0.01 - 4/29/91 --- 1st beta release -// 0.02 - 6/14/91 --- Changes to allow small model compilation -// 0.03 - 6/17/91 MAG Break reporting protected from interrupts routines with -// in-line asm added for moving data to/from ring buffers, -// replacing a variety of methods used previously. -// 0.04 - 6/21/91 MAG Initial flow-control packets not queued until -// i2_enable_interrupts time. Former versions would enqueue -// them at i2_init_channel time, before we knew how many -// channels were supposed to exist! -// 0.05 - 10/12/91 MAG Major changes: works through the ellis.c routines now; -// supports new 16-bit protocol and expandable boards. -// - 10/24/91 MAG Most changes in place and stable. -// 0.06 - 2/20/92 MAG Format of CMD_HOTACK corrected: the command takes no -// argument. -// 0.07 -- 3/11/92 MAG Support added to store special packet types at interrupt -// level (mostly responses to specific commands.) -// 0.08 -- 3/30/92 MAG Support added for STAT_MODEM packet -// 0.09 -- 6/24/93 MAG i2Link... needed to update number of boards BEFORE -// turning on the interrupt. -// 0.10 -- 6/25/93 MAG To avoid gruesome death from a bad board, we sanity check -// some incoming. -// -// 1.1 - 12/25/96 AKM Linux version. -// - 10/09/98 DMC Revised Linux version. -//------------------------------------------------------------------------------ - -//************ -//* Includes * -//************ - -#include -#include "i2lib.h" - - -//*********************** -//* Function Prototypes * -//*********************** -static void i2QueueNeeds(i2eBordStrPtr, i2ChanStrPtr, int); -static i2ChanStrPtr i2DeQueueNeeds(i2eBordStrPtr, int ); -static void i2StripFifo(i2eBordStrPtr); -static void i2StuffFifoBypass(i2eBordStrPtr); -static void i2StuffFifoFlow(i2eBordStrPtr); -static void i2StuffFifoInline(i2eBordStrPtr); -static int i2RetryFlushOutput(i2ChanStrPtr); - -// Not a documented part of the library routines (careful...) but the Diagnostic -// i2diag.c finds them useful to help the throughput in certain limited -// single-threaded operations. -static void iiSendPendingMail(i2eBordStrPtr); -static void serviceOutgoingFifo(i2eBordStrPtr); - -// Functions defined in ip2.c as part of interrupt handling -static void do_input(struct work_struct *); -static void do_status(struct work_struct *); - -//*************** -//* Debug Data * -//*************** -#ifdef DEBUG_FIFO - -unsigned char DBGBuf[0x4000]; -unsigned short I = 0; - -static void -WriteDBGBuf(char *s, unsigned char *src, unsigned short n ) -{ - char *p = src; - - // XXX: We need a spin lock here if we ever use this again - - while (*s) { // copy label - DBGBuf[I] = *s++; - I = I++ & 0x3fff; - } - while (n--) { // copy data - DBGBuf[I] = *p++; - I = I++ & 0x3fff; - } -} - -static void -fatality(i2eBordStrPtr pB ) -{ - int i; - - for (i=0;i= ' ' && DBGBuf[i] <= '~') { - printk(" %c ",DBGBuf[i]); - } else { - printk(" . "); - } - } - printk("\n"); - printk("Last index %x\n",I); -} -#endif /* DEBUG_FIFO */ - -//******** -//* Code * -//******** - -static inline int -i2Validate ( i2ChanStrPtr pCh ) -{ - //ip2trace(pCh->port_index, ITRC_VERIFY,ITRC_ENTER,2,pCh->validity, - // (CHANNEL_MAGIC | CHANNEL_SUPPORT)); - return ((pCh->validity & (CHANNEL_MAGIC_BITS | CHANNEL_SUPPORT)) - == (CHANNEL_MAGIC | CHANNEL_SUPPORT)); -} - -static void iiSendPendingMail_t(unsigned long data) -{ - i2eBordStrPtr pB = (i2eBordStrPtr)data; - - iiSendPendingMail(pB); -} - -//****************************************************************************** -// Function: iiSendPendingMail(pB) -// Parameters: Pointer to a board structure -// Returns: Nothing -// -// Description: -// If any outgoing mail bits are set and there is outgoing mailbox is empty, -// send the mail and clear the bits. -//****************************************************************************** -static void -iiSendPendingMail(i2eBordStrPtr pB) -{ - if (pB->i2eOutMailWaiting && (!pB->i2eWaitingForEmptyFifo) ) - { - if (iiTrySendMail(pB, pB->i2eOutMailWaiting)) - { - /* If we were already waiting for fifo to empty, - * or just sent MB_OUT_STUFFED, then we are - * still waiting for it to empty, until we should - * receive an MB_IN_STRIPPED from the board. - */ - pB->i2eWaitingForEmptyFifo |= - (pB->i2eOutMailWaiting & MB_OUT_STUFFED); - pB->i2eOutMailWaiting = 0; - pB->SendPendingRetry = 0; - } else { -/* The only time we hit this area is when "iiTrySendMail" has - failed. That only occurs when the outbound mailbox is - still busy with the last message. We take a short breather - to let the board catch up with itself and then try again. - 16 Retries is the limit - then we got a borked board. - /\/\|=mhw=|\/\/ */ - - if( ++pB->SendPendingRetry < 16 ) { - setup_timer(&pB->SendPendingTimer, - iiSendPendingMail_t, (unsigned long)pB); - mod_timer(&pB->SendPendingTimer, jiffies + 1); - } else { - printk( KERN_ERR "IP2: iiSendPendingMail unable to queue outbound mail\n" ); - } - } - } -} - -//****************************************************************************** -// Function: i2InitChannels(pB, nChannels, pCh) -// Parameters: Pointer to Ellis Board structure -// Number of channels to initialize -// Pointer to first element in an array of channel structures -// Returns: Success or failure -// -// Description: -// -// This function patches pointers, back-pointers, and initializes all the -// elements in the channel structure array. -// -// This should be run after the board structure is initialized, through having -// loaded the standard loadware (otherwise it complains). -// -// In any case, it must be done before any serious work begins initializing the -// irq's or sending commands... -// -//****************************************************************************** -static int -i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh) -{ - int index, stuffIndex; - i2ChanStrPtr *ppCh; - - if (pB->i2eValid != I2E_MAGIC) { - I2_COMPLETE(pB, I2EE_BADMAGIC); - } - if (pB->i2eState != II_STATE_STDLOADED) { - I2_COMPLETE(pB, I2EE_BADSTATE); - } - - rwlock_init(&pB->read_fifo_spinlock); - rwlock_init(&pB->write_fifo_spinlock); - rwlock_init(&pB->Dbuf_spinlock); - rwlock_init(&pB->Bbuf_spinlock); - rwlock_init(&pB->Fbuf_spinlock); - - // NO LOCK needed yet - this is init - - pB->i2eChannelPtr = pCh; - pB->i2eChannelCnt = nChannels; - - pB->i2Fbuf_strip = pB->i2Fbuf_stuff = 0; - pB->i2Dbuf_strip = pB->i2Dbuf_stuff = 0; - pB->i2Bbuf_strip = pB->i2Bbuf_stuff = 0; - - pB->SendPendingRetry = 0; - - memset ( pCh, 0, sizeof (i2ChanStr) * nChannels ); - - for (index = stuffIndex = 0, ppCh = (i2ChanStrPtr *)(pB->i2Fbuf); - nChannels && index < ABS_MOST_PORTS; - index++) - { - if ( !(pB->i2eChannelMap[index >> 4] & (1 << (index & 0xf)) ) ) { - continue; - } - rwlock_init(&pCh->Ibuf_spinlock); - rwlock_init(&pCh->Obuf_spinlock); - rwlock_init(&pCh->Cbuf_spinlock); - rwlock_init(&pCh->Pbuf_spinlock); - // NO LOCK needed yet - this is init - // Set up validity flag according to support level - if (pB->i2eGoodMap[index >> 4] & (1 << (index & 0xf)) ) { - pCh->validity = CHANNEL_MAGIC | CHANNEL_SUPPORT; - } else { - pCh->validity = CHANNEL_MAGIC; - } - pCh->pMyBord = pB; /* Back-pointer */ - - // Prepare an outgoing flow-control packet to send as soon as the chance - // occurs. - if ( pCh->validity & CHANNEL_SUPPORT ) { - pCh->infl.hd.i2sChannel = index; - pCh->infl.hd.i2sCount = 5; - pCh->infl.hd.i2sType = PTYPE_BYPASS; - pCh->infl.fcmd = 37; - pCh->infl.asof = 0; - pCh->infl.room = IBUF_SIZE - 1; - - pCh->whenSendFlow = (IBUF_SIZE/5)*4; // when 80% full - - // The following is similar to calling i2QueueNeeds, except that this - // is done in longhand, since we are setting up initial conditions on - // many channels at once. - pCh->channelNeeds = NEED_FLOW; // Since starting from scratch - pCh->sinceLastFlow = 0; // No bytes received since last flow - // control packet was queued - stuffIndex++; - *ppCh++ = pCh; // List this channel as needing - // initial flow control packet sent - } - - // Don't allow anything to be sent until the status packets come in from - // the board. - - pCh->outfl.asof = 0; - pCh->outfl.room = 0; - - // Initialize all the ring buffers - - pCh->Ibuf_stuff = pCh->Ibuf_strip = 0; - pCh->Obuf_stuff = pCh->Obuf_strip = 0; - pCh->Cbuf_stuff = pCh->Cbuf_strip = 0; - - memset( &pCh->icount, 0, sizeof (struct async_icount) ); - pCh->hotKeyIn = HOT_CLEAR; - pCh->channelOptions = 0; - pCh->bookMarks = 0; - init_waitqueue_head(&pCh->pBookmarkWait); - - init_waitqueue_head(&pCh->open_wait); - init_waitqueue_head(&pCh->close_wait); - init_waitqueue_head(&pCh->delta_msr_wait); - - // Set base and divisor so default custom rate is 9600 - pCh->BaudBase = 921600; // MAX for ST654, changed after we get - pCh->BaudDivisor = 96; // the boxids (UART types) later - - pCh->dataSetIn = 0; - pCh->dataSetOut = 0; - - pCh->wopen = 0; - pCh->throttled = 0; - - pCh->speed = CBR_9600; - - pCh->flags = 0; - - pCh->ClosingDelay = 5*HZ/10; - pCh->ClosingWaitTime = 30*HZ; - - // Initialize task queue objects - INIT_WORK(&pCh->tqueue_input, do_input); - INIT_WORK(&pCh->tqueue_status, do_status); - -#ifdef IP2DEBUG_TRACE - pCh->trace = ip2trace; -#endif - - ++pCh; - --nChannels; - } - // No need to check for wrap here; this is initialization. - pB->i2Fbuf_stuff = stuffIndex; - I2_COMPLETE(pB, I2EE_GOOD); - -} - -//****************************************************************************** -// Function: i2DeQueueNeeds(pB, type) -// Parameters: Pointer to a board structure -// type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW -// Returns: -// Pointer to a channel structure -// -// Description: Returns pointer struct of next channel that needs service of -// the type specified. Otherwise returns a NULL reference. -// -//****************************************************************************** -static i2ChanStrPtr -i2DeQueueNeeds(i2eBordStrPtr pB, int type) -{ - unsigned short queueIndex; - unsigned long flags; - - i2ChanStrPtr pCh = NULL; - - switch(type) { - - case NEED_INLINE: - - write_lock_irqsave(&pB->Dbuf_spinlock, flags); - if ( pB->i2Dbuf_stuff != pB->i2Dbuf_strip) - { - queueIndex = pB->i2Dbuf_strip; - pCh = pB->i2Dbuf[queueIndex]; - queueIndex++; - if (queueIndex >= CH_QUEUE_SIZE) { - queueIndex = 0; - } - pB->i2Dbuf_strip = queueIndex; - pCh->channelNeeds &= ~NEED_INLINE; - } - write_unlock_irqrestore(&pB->Dbuf_spinlock, flags); - break; - - case NEED_BYPASS: - - write_lock_irqsave(&pB->Bbuf_spinlock, flags); - if (pB->i2Bbuf_stuff != pB->i2Bbuf_strip) - { - queueIndex = pB->i2Bbuf_strip; - pCh = pB->i2Bbuf[queueIndex]; - queueIndex++; - if (queueIndex >= CH_QUEUE_SIZE) { - queueIndex = 0; - } - pB->i2Bbuf_strip = queueIndex; - pCh->channelNeeds &= ~NEED_BYPASS; - } - write_unlock_irqrestore(&pB->Bbuf_spinlock, flags); - break; - - case NEED_FLOW: - - write_lock_irqsave(&pB->Fbuf_spinlock, flags); - if (pB->i2Fbuf_stuff != pB->i2Fbuf_strip) - { - queueIndex = pB->i2Fbuf_strip; - pCh = pB->i2Fbuf[queueIndex]; - queueIndex++; - if (queueIndex >= CH_QUEUE_SIZE) { - queueIndex = 0; - } - pB->i2Fbuf_strip = queueIndex; - pCh->channelNeeds &= ~NEED_FLOW; - } - write_unlock_irqrestore(&pB->Fbuf_spinlock, flags); - break; - default: - printk(KERN_ERR "i2DeQueueNeeds called with bad type:%x\n",type); - break; - } - return pCh; -} - -//****************************************************************************** -// Function: i2QueueNeeds(pB, pCh, type) -// Parameters: Pointer to a board structure -// Pointer to a channel structure -// type bit map: may include NEED_INLINE, NEED_BYPASS, or NEED_FLOW -// Returns: Nothing -// -// Description: -// For each type of need selected, if the given channel is not already in the -// queue, adds it, and sets the flag indicating it is in the queue. -//****************************************************************************** -static void -i2QueueNeeds(i2eBordStrPtr pB, i2ChanStrPtr pCh, int type) -{ - unsigned short queueIndex; - unsigned long flags; - - // We turn off all the interrupts during this brief process, since the - // interrupt-level code might want to put things on the queue as well. - - switch (type) { - - case NEED_INLINE: - - write_lock_irqsave(&pB->Dbuf_spinlock, flags); - if ( !(pCh->channelNeeds & NEED_INLINE) ) - { - pCh->channelNeeds |= NEED_INLINE; - queueIndex = pB->i2Dbuf_stuff; - pB->i2Dbuf[queueIndex++] = pCh; - if (queueIndex >= CH_QUEUE_SIZE) - queueIndex = 0; - pB->i2Dbuf_stuff = queueIndex; - } - write_unlock_irqrestore(&pB->Dbuf_spinlock, flags); - break; - - case NEED_BYPASS: - - write_lock_irqsave(&pB->Bbuf_spinlock, flags); - if ((type & NEED_BYPASS) && !(pCh->channelNeeds & NEED_BYPASS)) - { - pCh->channelNeeds |= NEED_BYPASS; - queueIndex = pB->i2Bbuf_stuff; - pB->i2Bbuf[queueIndex++] = pCh; - if (queueIndex >= CH_QUEUE_SIZE) - queueIndex = 0; - pB->i2Bbuf_stuff = queueIndex; - } - write_unlock_irqrestore(&pB->Bbuf_spinlock, flags); - break; - - case NEED_FLOW: - - write_lock_irqsave(&pB->Fbuf_spinlock, flags); - if ((type & NEED_FLOW) && !(pCh->channelNeeds & NEED_FLOW)) - { - pCh->channelNeeds |= NEED_FLOW; - queueIndex = pB->i2Fbuf_stuff; - pB->i2Fbuf[queueIndex++] = pCh; - if (queueIndex >= CH_QUEUE_SIZE) - queueIndex = 0; - pB->i2Fbuf_stuff = queueIndex; - } - write_unlock_irqrestore(&pB->Fbuf_spinlock, flags); - break; - - case NEED_CREDIT: - pCh->channelNeeds |= NEED_CREDIT; - break; - default: - printk(KERN_ERR "i2QueueNeeds called with bad type:%x\n",type); - break; - } - return; -} - -//****************************************************************************** -// Function: i2QueueCommands(type, pCh, timeout, nCommands, pCs,...) -// Parameters: type - PTYPE_BYPASS or PTYPE_INLINE -// pointer to the channel structure -// maximum period to wait -// number of commands (n) -// n commands -// Returns: Number of commands sent, or -1 for error -// -// get board lock before calling -// -// Description: -// Queues up some commands to be sent to a channel. To send possibly several -// bypass or inline commands to the given channel. The timeout parameter -// indicates how many HUNDREDTHS OF SECONDS to wait until there is room: -// 0 = return immediately if no room, -ive = wait forever, +ive = number of -// 1/100 seconds to wait. Return values: -// -1 Some kind of nasty error: bad channel structure or invalid arguments. -// 0 No room to send all the commands -// (+) Number of commands sent -//****************************************************************************** -static int -i2QueueCommands(int type, i2ChanStrPtr pCh, int timeout, int nCommands, - cmdSyntaxPtr pCs0,...) -{ - int totalsize = 0; - int blocksize; - int lastended; - cmdSyntaxPtr *ppCs; - cmdSyntaxPtr pCs; - int count; - int flag; - i2eBordStrPtr pB; - - unsigned short maxBlock; - unsigned short maxBuff; - short bufroom; - unsigned short stuffIndex; - unsigned char *pBuf; - unsigned char *pInsert; - unsigned char *pDest, *pSource; - unsigned short channel; - int cnt; - unsigned long flags = 0; - rwlock_t *lock_var_p = NULL; - - // Make sure the channel exists, otherwise do nothing - if ( !i2Validate ( pCh ) ) { - return -1; - } - - ip2trace (CHANN, ITRC_QUEUE, ITRC_ENTER, 0 ); - - pB = pCh->pMyBord; - - // Board must also exist, and THE INTERRUPT COMMAND ALREADY SENT - if (pB->i2eValid != I2E_MAGIC || pB->i2eUsingIrq == I2_IRQ_UNDEFINED) - return -2; - // If the board has gone fatal, return bad, and also hit the trap routine if - // it exists. - if (pB->i2eFatal) { - if ( pB->i2eFatalTrap ) { - (*(pB)->i2eFatalTrap)(pB); - } - return -3; - } - // Set up some variables, Which buffers are we using? How big are they? - switch(type) - { - case PTYPE_INLINE: - flag = INL; - maxBlock = MAX_OBUF_BLOCK; - maxBuff = OBUF_SIZE; - pBuf = pCh->Obuf; - break; - case PTYPE_BYPASS: - flag = BYP; - maxBlock = MAX_CBUF_BLOCK; - maxBuff = CBUF_SIZE; - pBuf = pCh->Cbuf; - break; - default: - return -4; - } - // Determine the total size required for all the commands - totalsize = blocksize = sizeof(i2CmdHeader); - lastended = 0; - ppCs = &pCs0; - for ( count = nCommands; count; count--, ppCs++) - { - pCs = *ppCs; - cnt = pCs->length; - // Will a new block be needed for this one? - // Two possible reasons: too - // big or previous command has to be at the end of a packet. - if ((blocksize + cnt > maxBlock) || lastended) { - blocksize = sizeof(i2CmdHeader); - totalsize += sizeof(i2CmdHeader); - } - totalsize += cnt; - blocksize += cnt; - - // If this command had to end a block, then we will make sure to - // account for it should there be any more blocks. - lastended = pCs->flags & END; - } - for (;;) { - // Make sure any pending flush commands go out before we add more data. - if ( !( pCh->flush_flags && i2RetryFlushOutput( pCh ) ) ) { - // How much room (this time through) ? - switch(type) { - case PTYPE_INLINE: - lock_var_p = &pCh->Obuf_spinlock; - write_lock_irqsave(lock_var_p, flags); - stuffIndex = pCh->Obuf_stuff; - bufroom = pCh->Obuf_strip - stuffIndex; - break; - case PTYPE_BYPASS: - lock_var_p = &pCh->Cbuf_spinlock; - write_lock_irqsave(lock_var_p, flags); - stuffIndex = pCh->Cbuf_stuff; - bufroom = pCh->Cbuf_strip - stuffIndex; - break; - default: - return -5; - } - if (--bufroom < 0) { - bufroom += maxBuff; - } - - ip2trace (CHANN, ITRC_QUEUE, 2, 1, bufroom ); - - // Check for overflow - if (totalsize <= bufroom) { - // Normal Expected path - We still hold LOCK - break; /* from for()- Enough room: goto proceed */ - } - ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize); - write_unlock_irqrestore(lock_var_p, flags); - } else - ip2trace(CHANN, ITRC_QUEUE, 3, 1, totalsize); - - /* Prepare to wait for buffers to empty */ - serviceOutgoingFifo(pB); // Dump what we got - - if (timeout == 0) { - return 0; // Tired of waiting - } - if (timeout > 0) - timeout--; // So negative values == forever - - if (!in_interrupt()) { - schedule_timeout_interruptible(1); // short nap - } else { - // we cannot sched/sleep in interrupt silly - return 0; - } - if (signal_pending(current)) { - return 0; // Wake up! Time to die!!! - } - - ip2trace (CHANN, ITRC_QUEUE, 4, 0 ); - - } // end of for(;;) - - // At this point we have room and the lock - stick them in. - channel = pCh->infl.hd.i2sChannel; - pInsert = &pBuf[stuffIndex]; // Pointer to start of packet - pDest = CMD_OF(pInsert); // Pointer to start of command - - // When we start counting, the block is the size of the header - for (blocksize = sizeof(i2CmdHeader), count = nCommands, - lastended = 0, ppCs = &pCs0; - count; - count--, ppCs++) - { - pCs = *ppCs; // Points to command protocol structure - - // If this is a bookmark request command, post the fact that a bookmark - // request is pending. NOTE THIS TRICK ONLY WORKS BECAUSE CMD_BMARK_REQ - // has no parameters! The more general solution would be to reference - // pCs->cmd[0]. - if (pCs == CMD_BMARK_REQ) { - pCh->bookMarks++; - - ip2trace (CHANN, ITRC_DRAIN, 30, 1, pCh->bookMarks ); - - } - cnt = pCs->length; - - // If this command would put us over the maximum block size or - // if the last command had to be at the end of a block, we end - // the existing block here and start a new one. - if ((blocksize + cnt > maxBlock) || lastended) { - - ip2trace (CHANN, ITRC_QUEUE, 5, 0 ); - - PTYPE_OF(pInsert) = type; - CHANNEL_OF(pInsert) = channel; - // count here does not include the header - CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader); - stuffIndex += blocksize; - if(stuffIndex >= maxBuff) { - stuffIndex = 0; - pInsert = pBuf; - } - pInsert = &pBuf[stuffIndex]; // Pointer to start of next pkt - pDest = CMD_OF(pInsert); - blocksize = sizeof(i2CmdHeader); - } - // Now we know there is room for this one in the current block - - blocksize += cnt; // Total bytes in this command - pSource = pCs->cmd; // Copy the command into the buffer - while (cnt--) { - *pDest++ = *pSource++; - } - // If this command had to end a block, then we will make sure to account - // for it should there be any more blocks. - lastended = pCs->flags & END; - } // end for - // Clean up the final block by writing header, etc - - PTYPE_OF(pInsert) = type; - CHANNEL_OF(pInsert) = channel; - // count here does not include the header - CMD_COUNT_OF(pInsert) = blocksize - sizeof(i2CmdHeader); - stuffIndex += blocksize; - if(stuffIndex >= maxBuff) { - stuffIndex = 0; - pInsert = pBuf; - } - // Updates the index, and post the need for service. When adding these to - // the queue of channels, we turn off the interrupt while doing so, - // because at interrupt level we might want to push a channel back to the - // end of the queue. - switch(type) - { - case PTYPE_INLINE: - pCh->Obuf_stuff = stuffIndex; // Store buffer pointer - write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); - - pB->debugInlineQueued++; - // Add the channel pointer to list of channels needing service (first - // come...), if it's not already there. - i2QueueNeeds(pB, pCh, NEED_INLINE); - break; - - case PTYPE_BYPASS: - pCh->Cbuf_stuff = stuffIndex; // Store buffer pointer - write_unlock_irqrestore(&pCh->Cbuf_spinlock, flags); - - pB->debugBypassQueued++; - // Add the channel pointer to list of channels needing service (first - // come...), if it's not already there. - i2QueueNeeds(pB, pCh, NEED_BYPASS); - break; - } - - ip2trace (CHANN, ITRC_QUEUE, ITRC_RETURN, 1, nCommands ); - - return nCommands; // Good status: number of commands sent -} - -//****************************************************************************** -// Function: i2GetStatus(pCh,resetBits) -// Parameters: Pointer to a channel structure -// Bit map of status bits to clear -// Returns: Bit map of current status bits -// -// Description: -// Returns the state of data set signals, and whether a break has been received, -// (see i2lib.h for bit-mapped result). resetBits is a bit-map of any status -// bits to be cleared: I2_BRK, I2_PAR, I2_FRA, I2_OVR,... These are cleared -// AFTER the condition is passed. If pCh does not point to a valid channel, -// returns -1 (which would be impossible otherwise. -//****************************************************************************** -static int -i2GetStatus(i2ChanStrPtr pCh, int resetBits) -{ - unsigned short status; - i2eBordStrPtr pB; - - ip2trace (CHANN, ITRC_STATUS, ITRC_ENTER, 2, pCh->dataSetIn, resetBits ); - - // Make sure the channel exists, otherwise do nothing */ - if ( !i2Validate ( pCh ) ) - return -1; - - pB = pCh->pMyBord; - - status = pCh->dataSetIn; - - // Clear any specified error bits: but note that only actual error bits can - // be cleared, regardless of the value passed. - if (resetBits) - { - pCh->dataSetIn &= ~(resetBits & (I2_BRK | I2_PAR | I2_FRA | I2_OVR)); - pCh->dataSetIn &= ~(I2_DDCD | I2_DCTS | I2_DDSR | I2_DRI); - } - - ip2trace (CHANN, ITRC_STATUS, ITRC_RETURN, 1, pCh->dataSetIn ); - - return status; -} - -//****************************************************************************** -// Function: i2Input(pChpDest,count) -// Parameters: Pointer to a channel structure -// Pointer to data buffer -// Number of bytes to read -// Returns: Number of bytes read, or -1 for error -// -// Description: -// Strips data from the input buffer and writes it to pDest. If there is a -// colossal blunder, (invalid structure pointers or the like), returns -1. -// Otherwise, returns the number of bytes read. -//****************************************************************************** -static int -i2Input(i2ChanStrPtr pCh) -{ - int amountToMove; - unsigned short stripIndex; - int count; - unsigned long flags = 0; - - ip2trace (CHANN, ITRC_INPUT, ITRC_ENTER, 0); - - // Ensure channel structure seems real - if ( !i2Validate( pCh ) ) { - count = -1; - goto i2Input_exit; - } - write_lock_irqsave(&pCh->Ibuf_spinlock, flags); - - // initialize some accelerators and private copies - stripIndex = pCh->Ibuf_strip; - - count = pCh->Ibuf_stuff - stripIndex; - - // If buffer is empty or requested data count was 0, (trivial case) return - // without any further thought. - if ( count == 0 ) { - write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - goto i2Input_exit; - } - // Adjust for buffer wrap - if ( count < 0 ) { - count += IBUF_SIZE; - } - // Don't give more than can be taken by the line discipline - amountToMove = pCh->pTTY->receive_room; - if (count > amountToMove) { - count = amountToMove; - } - // How much could we copy without a wrap? - amountToMove = IBUF_SIZE - stripIndex; - - if (amountToMove > count) { - amountToMove = count; - } - // Move the first block - pCh->pTTY->ldisc->ops->receive_buf( pCh->pTTY, - &(pCh->Ibuf[stripIndex]), NULL, amountToMove ); - // If we needed to wrap, do the second data move - if (count > amountToMove) { - pCh->pTTY->ldisc->ops->receive_buf( pCh->pTTY, - pCh->Ibuf, NULL, count - amountToMove ); - } - // Bump and wrap the stripIndex all at once by the amount of data read. This - // method is good regardless of whether the data was in one or two pieces. - stripIndex += count; - if (stripIndex >= IBUF_SIZE) { - stripIndex -= IBUF_SIZE; - } - pCh->Ibuf_strip = stripIndex; - - // Update our flow control information and possibly queue ourselves to send - // it, depending on how much data has been stripped since the last time a - // packet was sent. - pCh->infl.asof += count; - - if ((pCh->sinceLastFlow += count) >= pCh->whenSendFlow) { - pCh->sinceLastFlow -= pCh->whenSendFlow; - write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW); - } else { - write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - } - -i2Input_exit: - - ip2trace (CHANN, ITRC_INPUT, ITRC_RETURN, 1, count); - - return count; -} - -//****************************************************************************** -// Function: i2InputFlush(pCh) -// Parameters: Pointer to a channel structure -// Returns: Number of bytes stripped, or -1 for error -// -// Description: -// Strips any data from the input buffer. If there is a colossal blunder, -// (invalid structure pointers or the like), returns -1. Otherwise, returns the -// number of bytes stripped. -//****************************************************************************** -static int -i2InputFlush(i2ChanStrPtr pCh) -{ - int count; - unsigned long flags; - - // Ensure channel structure seems real - if ( !i2Validate ( pCh ) ) - return -1; - - ip2trace (CHANN, ITRC_INPUT, 10, 0); - - write_lock_irqsave(&pCh->Ibuf_spinlock, flags); - count = pCh->Ibuf_stuff - pCh->Ibuf_strip; - - // Adjust for buffer wrap - if (count < 0) { - count += IBUF_SIZE; - } - - // Expedient way to zero out the buffer - pCh->Ibuf_strip = pCh->Ibuf_stuff; - - - // Update our flow control information and possibly queue ourselves to send - // it, depending on how much data has been stripped since the last time a - // packet was sent. - - pCh->infl.asof += count; - - if ( (pCh->sinceLastFlow += count) >= pCh->whenSendFlow ) - { - pCh->sinceLastFlow -= pCh->whenSendFlow; - write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - i2QueueNeeds(pCh->pMyBord, pCh, NEED_FLOW); - } else { - write_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - } - - ip2trace (CHANN, ITRC_INPUT, 19, 1, count); - - return count; -} - -//****************************************************************************** -// Function: i2InputAvailable(pCh) -// Parameters: Pointer to a channel structure -// Returns: Number of bytes available, or -1 for error -// -// Description: -// If there is a colossal blunder, (invalid structure pointers or the like), -// returns -1. Otherwise, returns the number of bytes stripped. Otherwise, -// returns the number of bytes available in the buffer. -//****************************************************************************** -#if 0 -static int -i2InputAvailable(i2ChanStrPtr pCh) -{ - int count; - - // Ensure channel structure seems real - if ( !i2Validate ( pCh ) ) return -1; - - - // initialize some accelerators and private copies - read_lock_irqsave(&pCh->Ibuf_spinlock, flags); - count = pCh->Ibuf_stuff - pCh->Ibuf_strip; - read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - - // Adjust for buffer wrap - if (count < 0) - { - count += IBUF_SIZE; - } - - return count; -} -#endif - -//****************************************************************************** -// Function: i2Output(pCh, pSource, count) -// Parameters: Pointer to channel structure -// Pointer to source data -// Number of bytes to send -// Returns: Number of bytes sent, or -1 for error -// -// Description: -// Queues the data at pSource to be sent as data packets to the board. If there -// is a colossal blunder, (invalid structure pointers or the like), returns -1. -// Otherwise, returns the number of bytes written. What if there is not enough -// room for all the data? If pCh->channelOptions & CO_NBLOCK_WRITE is set, then -// we transfer as many characters as we can now, then return. If this bit is -// clear (default), routine will spin along until all the data is buffered. -// Should this occur, the 1-ms delay routine is called while waiting to avoid -// applications that one cannot break out of. -//****************************************************************************** -static int -i2Output(i2ChanStrPtr pCh, const char *pSource, int count) -{ - i2eBordStrPtr pB; - unsigned char *pInsert; - int amountToMove; - int countOriginal = count; - unsigned short channel; - unsigned short stuffIndex; - unsigned long flags; - - int bailout = 10; - - ip2trace (CHANN, ITRC_OUTPUT, ITRC_ENTER, 2, count, 0 ); - - // Ensure channel structure seems real - if ( !i2Validate ( pCh ) ) - return -1; - - // initialize some accelerators and private copies - pB = pCh->pMyBord; - channel = pCh->infl.hd.i2sChannel; - - // If the board has gone fatal, return bad, and also hit the trap routine if - // it exists. - if (pB->i2eFatal) { - if (pB->i2eFatalTrap) { - (*(pB)->i2eFatalTrap)(pB); - } - return -1; - } - // Proceed as though we would do everything - while ( count > 0 ) { - - // How much room in output buffer is there? - read_lock_irqsave(&pCh->Obuf_spinlock, flags); - amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1; - read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); - if (amountToMove < 0) { - amountToMove += OBUF_SIZE; - } - // Subtract off the headers size and see how much room there is for real - // data. If this is negative, we will discover later. - amountToMove -= sizeof (i2DataHeader); - - // Don't move more (now) than can go in a single packet - if ( amountToMove > (int)(MAX_OBUF_BLOCK - sizeof(i2DataHeader)) ) { - amountToMove = MAX_OBUF_BLOCK - sizeof(i2DataHeader); - } - // Don't move more than the count we were given - if (amountToMove > count) { - amountToMove = count; - } - // Now we know how much we must move: NB because the ring buffers have - // an overflow area at the end, we needn't worry about wrapping in the - // middle of a packet. - -// Small WINDOW here with no LOCK but I can't call Flush with LOCK -// We would be flushing (or ending flush) anyway - - ip2trace (CHANN, ITRC_OUTPUT, 10, 1, amountToMove ); - - if ( !(pCh->flush_flags && i2RetryFlushOutput(pCh) ) - && amountToMove > 0 ) - { - write_lock_irqsave(&pCh->Obuf_spinlock, flags); - stuffIndex = pCh->Obuf_stuff; - - // Had room to move some data: don't know whether the block size, - // buffer space, or what was the limiting factor... - pInsert = &(pCh->Obuf[stuffIndex]); - - // Set up the header - CHANNEL_OF(pInsert) = channel; - PTYPE_OF(pInsert) = PTYPE_DATA; - TAG_OF(pInsert) = 0; - ID_OF(pInsert) = ID_ORDINARY_DATA; - DATA_COUNT_OF(pInsert) = amountToMove; - - // Move the data - memcpy( (char*)(DATA_OF(pInsert)), pSource, amountToMove ); - // Adjust pointers and indices - pSource += amountToMove; - pCh->Obuf_char_count += amountToMove; - stuffIndex += amountToMove + sizeof(i2DataHeader); - count -= amountToMove; - - if (stuffIndex >= OBUF_SIZE) { - stuffIndex = 0; - } - pCh->Obuf_stuff = stuffIndex; - - write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); - - ip2trace (CHANN, ITRC_OUTPUT, 13, 1, stuffIndex ); - - } else { - - // Cannot move data - // becuz we need to stuff a flush - // or amount to move is <= 0 - - ip2trace(CHANN, ITRC_OUTPUT, 14, 3, - amountToMove, pB->i2eFifoRemains, - pB->i2eWaitingForEmptyFifo ); - - // Put this channel back on queue - // this ultimatly gets more data or wakes write output - i2QueueNeeds(pB, pCh, NEED_INLINE); - - if ( pB->i2eWaitingForEmptyFifo ) { - - ip2trace (CHANN, ITRC_OUTPUT, 16, 0 ); - - // or schedule - if (!in_interrupt()) { - - ip2trace (CHANN, ITRC_OUTPUT, 61, 0 ); - - schedule_timeout_interruptible(2); - if (signal_pending(current)) { - break; - } - continue; - } else { - - ip2trace (CHANN, ITRC_OUTPUT, 62, 0 ); - - // let interrupt in = WAS restore_flags() - // We hold no lock nor is irq off anymore??? - - break; - } - break; // from while(count) - } - else if ( pB->i2eFifoRemains < 32 && !pB->i2eTxMailEmpty ( pB ) ) - { - ip2trace (CHANN, ITRC_OUTPUT, 19, 2, - pB->i2eFifoRemains, - pB->i2eTxMailEmpty ); - - break; // from while(count) - } else if ( pCh->channelNeeds & NEED_CREDIT ) { - - ip2trace (CHANN, ITRC_OUTPUT, 22, 0 ); - - break; // from while(count) - } else if ( --bailout) { - - // Try to throw more things (maybe not us) in the fifo if we're - // not already waiting for it. - - ip2trace (CHANN, ITRC_OUTPUT, 20, 0 ); - - serviceOutgoingFifo(pB); - //break; CONTINUE; - } else { - ip2trace (CHANN, ITRC_OUTPUT, 21, 3, - pB->i2eFifoRemains, - pB->i2eOutMailWaiting, - pB->i2eWaitingForEmptyFifo ); - - break; // from while(count) - } - } - } // End of while(count) - - i2QueueNeeds(pB, pCh, NEED_INLINE); - - // We drop through either when the count expires, or when there is some - // count left, but there was a non-blocking write. - if (countOriginal > count) { - - ip2trace (CHANN, ITRC_OUTPUT, 17, 2, countOriginal, count ); - - serviceOutgoingFifo( pB ); - } - - ip2trace (CHANN, ITRC_OUTPUT, ITRC_RETURN, 2, countOriginal, count ); - - return countOriginal - count; -} - -//****************************************************************************** -// Function: i2FlushOutput(pCh) -// Parameters: Pointer to a channel structure -// Returns: Nothing -// -// Description: -// Sends bypass command to start flushing (waiting possibly forever until there -// is room), then sends inline command to stop flushing output, (again waiting -// possibly forever). -//****************************************************************************** -static inline void -i2FlushOutput(i2ChanStrPtr pCh) -{ - - ip2trace (CHANN, ITRC_FLUSH, 1, 1, pCh->flush_flags ); - - if (pCh->flush_flags) - return; - - if ( 1 != i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) { - pCh->flush_flags = STARTFL_FLAG; // Failed - flag for later - - ip2trace (CHANN, ITRC_FLUSH, 2, 0 ); - - } else if ( 1 != i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL) ) { - pCh->flush_flags = STOPFL_FLAG; // Failed - flag for later - - ip2trace (CHANN, ITRC_FLUSH, 3, 0 ); - } -} - -static int -i2RetryFlushOutput(i2ChanStrPtr pCh) -{ - int old_flags = pCh->flush_flags; - - ip2trace (CHANN, ITRC_FLUSH, 14, 1, old_flags ); - - pCh->flush_flags = 0; // Clear flag so we can avoid recursion - // and queue the commands - - if ( old_flags & STARTFL_FLAG ) { - if ( 1 == i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_STARTFL) ) { - old_flags = STOPFL_FLAG; //Success - send stop flush - } else { - old_flags = STARTFL_FLAG; //Failure - Flag for retry later - } - - ip2trace (CHANN, ITRC_FLUSH, 15, 1, old_flags ); - - } - if ( old_flags & STOPFL_FLAG ) { - if (1 == i2QueueCommands(PTYPE_INLINE, pCh, 0, 1, CMD_STOPFL)) { - old_flags = 0; // Success - clear flags - } - - ip2trace (CHANN, ITRC_FLUSH, 16, 1, old_flags ); - } - pCh->flush_flags = old_flags; - - ip2trace (CHANN, ITRC_FLUSH, 17, 1, old_flags ); - - return old_flags; -} - -//****************************************************************************** -// Function: i2DrainOutput(pCh,timeout) -// Parameters: Pointer to a channel structure -// Maximum period to wait -// Returns: ? -// -// Description: -// Uses the bookmark request command to ask the board to send a bookmark back as -// soon as all the data is completely sent. -//****************************************************************************** -static void -i2DrainWakeup(unsigned long d) -{ - i2ChanStrPtr pCh = (i2ChanStrPtr)d; - - ip2trace (CHANN, ITRC_DRAIN, 10, 1, pCh->BookmarkTimer.expires ); - - pCh->BookmarkTimer.expires = 0; - wake_up_interruptible( &pCh->pBookmarkWait ); -} - -static void -i2DrainOutput(i2ChanStrPtr pCh, int timeout) -{ - wait_queue_t wait; - i2eBordStrPtr pB; - - ip2trace (CHANN, ITRC_DRAIN, ITRC_ENTER, 1, pCh->BookmarkTimer.expires); - - pB = pCh->pMyBord; - // If the board has gone fatal, return bad, - // and also hit the trap routine if it exists. - if (pB->i2eFatal) { - if (pB->i2eFatalTrap) { - (*(pB)->i2eFatalTrap)(pB); - } - return; - } - if ((timeout > 0) && (pCh->BookmarkTimer.expires == 0 )) { - // One per customer (channel) - setup_timer(&pCh->BookmarkTimer, i2DrainWakeup, - (unsigned long)pCh); - - ip2trace (CHANN, ITRC_DRAIN, 1, 1, pCh->BookmarkTimer.expires ); - - mod_timer(&pCh->BookmarkTimer, jiffies + timeout); - } - - i2QueueCommands( PTYPE_INLINE, pCh, -1, 1, CMD_BMARK_REQ ); - - init_waitqueue_entry(&wait, current); - add_wait_queue(&(pCh->pBookmarkWait), &wait); - set_current_state( TASK_INTERRUPTIBLE ); - - serviceOutgoingFifo( pB ); - - schedule(); // Now we take our interruptible sleep on - - // Clean up the queue - set_current_state( TASK_RUNNING ); - remove_wait_queue(&(pCh->pBookmarkWait), &wait); - - // if expires == 0 then timer poped, then do not need to del_timer - if ((timeout > 0) && pCh->BookmarkTimer.expires && - time_before(jiffies, pCh->BookmarkTimer.expires)) { - del_timer( &(pCh->BookmarkTimer) ); - pCh->BookmarkTimer.expires = 0; - - ip2trace (CHANN, ITRC_DRAIN, 3, 1, pCh->BookmarkTimer.expires ); - - } - ip2trace (CHANN, ITRC_DRAIN, ITRC_RETURN, 1, pCh->BookmarkTimer.expires ); - return; -} - -//****************************************************************************** -// Function: i2OutputFree(pCh) -// Parameters: Pointer to a channel structure -// Returns: Space in output buffer -// -// Description: -// Returns -1 if very gross error. Otherwise returns the amount of bytes still -// free in the output buffer. -//****************************************************************************** -static int -i2OutputFree(i2ChanStrPtr pCh) -{ - int amountToMove; - unsigned long flags; - - // Ensure channel structure seems real - if ( !i2Validate ( pCh ) ) { - return -1; - } - read_lock_irqsave(&pCh->Obuf_spinlock, flags); - amountToMove = pCh->Obuf_strip - pCh->Obuf_stuff - 1; - read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); - - if (amountToMove < 0) { - amountToMove += OBUF_SIZE; - } - // If this is negative, we will discover later - amountToMove -= sizeof(i2DataHeader); - - return (amountToMove < 0) ? 0 : amountToMove; -} -static void - -ip2_owake( PTTY tp) -{ - i2ChanStrPtr pCh; - - if (tp == NULL) return; - - pCh = tp->driver_data; - - ip2trace (CHANN, ITRC_SICMD, 10, 2, tp->flags, - (1 << TTY_DO_WRITE_WAKEUP) ); - - tty_wakeup(tp); -} - -static inline void -set_baud_params(i2eBordStrPtr pB) -{ - int i,j; - i2ChanStrPtr *pCh; - - pCh = (i2ChanStrPtr *) pB->i2eChannelPtr; - - for (i = 0; i < ABS_MAX_BOXES; i++) { - if (pB->channelBtypes.bid_value[i]) { - if (BID_HAS_654(pB->channelBtypes.bid_value[i])) { - for (j = 0; j < ABS_BIGGEST_BOX; j++) { - if (pCh[i*16+j] == NULL) - break; - (pCh[i*16+j])->BaudBase = 921600; // MAX for ST654 - (pCh[i*16+j])->BaudDivisor = 96; - } - } else { // has cirrus cd1400 - for (j = 0; j < ABS_BIGGEST_BOX; j++) { - if (pCh[i*16+j] == NULL) - break; - (pCh[i*16+j])->BaudBase = 115200; // MAX for CD1400 - (pCh[i*16+j])->BaudDivisor = 12; - } - } - } - } -} - -//****************************************************************************** -// Function: i2StripFifo(pB) -// Parameters: Pointer to a board structure -// Returns: ? -// -// Description: -// Strips all the available data from the incoming FIFO, identifies the type of -// packet, and either buffers the data or does what needs to be done. -// -// Note there is no overflow checking here: if the board sends more data than it -// ought to, we will not detect it here, but blindly overflow... -//****************************************************************************** - -// A buffer for reading in blocks for unknown channels -static unsigned char junkBuffer[IBUF_SIZE]; - -// A buffer to read in a status packet. Because of the size of the count field -// for these things, the maximum packet size must be less than MAX_CMD_PACK_SIZE -static unsigned char cmdBuffer[MAX_CMD_PACK_SIZE + 4]; - -// This table changes the bit order from MSR order given by STAT_MODEM packet to -// status bits used in our library. -static char xlatDss[16] = { -0 | 0 | 0 | 0 , -0 | 0 | 0 | I2_CTS , -0 | 0 | I2_DSR | 0 , -0 | 0 | I2_DSR | I2_CTS , -0 | I2_RI | 0 | 0 , -0 | I2_RI | 0 | I2_CTS , -0 | I2_RI | I2_DSR | 0 , -0 | I2_RI | I2_DSR | I2_CTS , -I2_DCD | 0 | 0 | 0 , -I2_DCD | 0 | 0 | I2_CTS , -I2_DCD | 0 | I2_DSR | 0 , -I2_DCD | 0 | I2_DSR | I2_CTS , -I2_DCD | I2_RI | 0 | 0 , -I2_DCD | I2_RI | 0 | I2_CTS , -I2_DCD | I2_RI | I2_DSR | 0 , -I2_DCD | I2_RI | I2_DSR | I2_CTS }; - -static inline void -i2StripFifo(i2eBordStrPtr pB) -{ - i2ChanStrPtr pCh; - int channel; - int count; - unsigned short stuffIndex; - int amountToRead; - unsigned char *pc, *pcLimit; - unsigned char uc; - unsigned char dss_change; - unsigned long bflags,cflags; - -// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_ENTER, 0 ); - - while (I2_HAS_INPUT(pB)) { -// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 2, 0 ); - - // Process packet from fifo a one atomic unit - write_lock_irqsave(&pB->read_fifo_spinlock, bflags); - - // The first word (or two bytes) will have channel number and type of - // packet, possibly other information - pB->i2eLeadoffWord[0] = iiReadWord(pB); - - switch(PTYPE_OF(pB->i2eLeadoffWord)) - { - case PTYPE_DATA: - pB->got_input = 1; - -// ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 3, 0 ); - - channel = CHANNEL_OF(pB->i2eLeadoffWord); /* Store channel */ - count = iiReadWord(pB); /* Count is in the next word */ - -// NEW: Check the count for sanity! Should the hardware fail, our death -// is more pleasant. While an oversize channel is acceptable (just more -// than the driver supports), an over-length count clearly means we are -// sick! - if ( ((unsigned int)count) > IBUF_SIZE ) { - pB->i2eFatal = 2; - write_unlock_irqrestore(&pB->read_fifo_spinlock, - bflags); - return; /* Bail out ASAP */ - } - // Channel is illegally big ? - if ((channel >= pB->i2eChannelCnt) || - (NULL==(pCh = ((i2ChanStrPtr*)pB->i2eChannelPtr)[channel]))) - { - iiReadBuf(pB, junkBuffer, count); - write_unlock_irqrestore(&pB->read_fifo_spinlock, - bflags); - break; /* From switch: ready for next packet */ - } - - // Channel should be valid, then - - // If this is a hot-key, merely post its receipt for now. These are - // always supposed to be 1-byte packets, so we won't even check the - // count. Also we will post an acknowledgement to the board so that - // more data can be forthcoming. Note that we are not trying to use - // these sequences in this driver, merely to robustly ignore them. - if(ID_OF(pB->i2eLeadoffWord) == ID_HOT_KEY) - { - pCh->hotKeyIn = iiReadWord(pB) & 0xff; - write_unlock_irqrestore(&pB->read_fifo_spinlock, - bflags); - i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_HOTACK); - break; /* From the switch: ready for next packet */ - } - - // Normal data! We crudely assume there is room for the data in our - // buffer because the board wouldn't have exceeded his credit limit. - write_lock_irqsave(&pCh->Ibuf_spinlock, cflags); - // We have 2 locks now - stuffIndex = pCh->Ibuf_stuff; - amountToRead = IBUF_SIZE - stuffIndex; - if (amountToRead > count) - amountToRead = count; - - // stuffIndex would have been already adjusted so there would - // always be room for at least one, and count is always at least - // one. - - iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead); - pCh->icount.rx += amountToRead; - - // Update the stuffIndex by the amount of data moved. Note we could - // never ask for more data than would just fit. However, we might - // have read in one more byte than we wanted because the read - // rounds up to even bytes. If this byte is on the end of the - // packet, and is padding, we ignore it. If the byte is part of - // the actual data, we need to move it. - - stuffIndex += amountToRead; - - if (stuffIndex >= IBUF_SIZE) { - if ((amountToRead & 1) && (count > amountToRead)) { - pCh->Ibuf[0] = pCh->Ibuf[IBUF_SIZE]; - amountToRead++; - stuffIndex = 1; - } else { - stuffIndex = 0; - } - } - - // If there is anything left over, read it as well - if (count > amountToRead) { - amountToRead = count - amountToRead; - iiReadBuf(pB, &(pCh->Ibuf[stuffIndex]), amountToRead); - pCh->icount.rx += amountToRead; - stuffIndex += amountToRead; - } - - // Update stuff index - pCh->Ibuf_stuff = stuffIndex; - write_unlock_irqrestore(&pCh->Ibuf_spinlock, cflags); - write_unlock_irqrestore(&pB->read_fifo_spinlock, - bflags); - -#ifdef USE_IQ - schedule_work(&pCh->tqueue_input); -#else - do_input(&pCh->tqueue_input); -#endif - - // Note we do not need to maintain any flow-control credits at this - // time: if we were to increment .asof and decrement .room, there - // would be no net effect. Instead, when we strip data, we will - // increment .asof and leave .room unchanged. - - break; // From switch: ready for next packet - - case PTYPE_STATUS: - ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 4, 0 ); - - count = CMD_COUNT_OF(pB->i2eLeadoffWord); - - iiReadBuf(pB, cmdBuffer, count); - // We can release early with buffer grab - write_unlock_irqrestore(&pB->read_fifo_spinlock, - bflags); - - pc = cmdBuffer; - pcLimit = &(cmdBuffer[count]); - - while (pc < pcLimit) { - channel = *pc++; - - ip2trace (channel, ITRC_SFIFO, 7, 2, channel, *pc ); - - /* check for valid channel */ - if (channel < pB->i2eChannelCnt - && - (pCh = (((i2ChanStrPtr*)pB->i2eChannelPtr)[channel])) != NULL - ) - { - dss_change = 0; - - switch (uc = *pc++) - { - /* Breaks and modem signals are easy: just update status */ - case STAT_CTS_UP: - if ( !(pCh->dataSetIn & I2_CTS) ) - { - pCh->dataSetIn |= I2_DCTS; - pCh->icount.cts++; - dss_change = 1; - } - pCh->dataSetIn |= I2_CTS; - break; - - case STAT_CTS_DN: - if ( pCh->dataSetIn & I2_CTS ) - { - pCh->dataSetIn |= I2_DCTS; - pCh->icount.cts++; - dss_change = 1; - } - pCh->dataSetIn &= ~I2_CTS; - break; - - case STAT_DCD_UP: - ip2trace (channel, ITRC_MODEM, 1, 1, pCh->dataSetIn ); - - if ( !(pCh->dataSetIn & I2_DCD) ) - { - ip2trace (CHANN, ITRC_MODEM, 2, 0 ); - pCh->dataSetIn |= I2_DDCD; - pCh->icount.dcd++; - dss_change = 1; - } - pCh->dataSetIn |= I2_DCD; - - ip2trace (channel, ITRC_MODEM, 3, 1, pCh->dataSetIn ); - break; - - case STAT_DCD_DN: - ip2trace (channel, ITRC_MODEM, 4, 1, pCh->dataSetIn ); - if ( pCh->dataSetIn & I2_DCD ) - { - ip2trace (channel, ITRC_MODEM, 5, 0 ); - pCh->dataSetIn |= I2_DDCD; - pCh->icount.dcd++; - dss_change = 1; - } - pCh->dataSetIn &= ~I2_DCD; - - ip2trace (channel, ITRC_MODEM, 6, 1, pCh->dataSetIn ); - break; - - case STAT_DSR_UP: - if ( !(pCh->dataSetIn & I2_DSR) ) - { - pCh->dataSetIn |= I2_DDSR; - pCh->icount.dsr++; - dss_change = 1; - } - pCh->dataSetIn |= I2_DSR; - break; - - case STAT_DSR_DN: - if ( pCh->dataSetIn & I2_DSR ) - { - pCh->dataSetIn |= I2_DDSR; - pCh->icount.dsr++; - dss_change = 1; - } - pCh->dataSetIn &= ~I2_DSR; - break; - - case STAT_RI_UP: - if ( !(pCh->dataSetIn & I2_RI) ) - { - pCh->dataSetIn |= I2_DRI; - pCh->icount.rng++; - dss_change = 1; - } - pCh->dataSetIn |= I2_RI ; - break; - - case STAT_RI_DN: - // to be compat with serial.c - //if ( pCh->dataSetIn & I2_RI ) - //{ - // pCh->dataSetIn |= I2_DRI; - // pCh->icount.rng++; - // dss_change = 1; - //} - pCh->dataSetIn &= ~I2_RI ; - break; - - case STAT_BRK_DET: - pCh->dataSetIn |= I2_BRK; - pCh->icount.brk++; - dss_change = 1; - break; - - // Bookmarks? one less request we're waiting for - case STAT_BMARK: - pCh->bookMarks--; - if (pCh->bookMarks <= 0 ) { - pCh->bookMarks = 0; - wake_up_interruptible( &pCh->pBookmarkWait ); - - ip2trace (channel, ITRC_DRAIN, 20, 1, pCh->BookmarkTimer.expires ); - } - break; - - // Flow control packets? Update the new credits, and if - // someone was waiting for output, queue him up again. - case STAT_FLOW: - pCh->outfl.room = - ((flowStatPtr)pc)->room - - (pCh->outfl.asof - ((flowStatPtr)pc)->asof); - - ip2trace (channel, ITRC_STFLW, 1, 1, pCh->outfl.room ); - - if (pCh->channelNeeds & NEED_CREDIT) - { - ip2trace (channel, ITRC_STFLW, 2, 1, pCh->channelNeeds); - - pCh->channelNeeds &= ~NEED_CREDIT; - i2QueueNeeds(pB, pCh, NEED_INLINE); - if ( pCh->pTTY ) - ip2_owake(pCh->pTTY); - } - - ip2trace (channel, ITRC_STFLW, 3, 1, pCh->channelNeeds); - - pc += sizeof(flowStat); - break; - - /* Special packets: */ - /* Just copy the information into the channel structure */ - - case STAT_STATUS: - - pCh->channelStatus = *((debugStatPtr)pc); - pc += sizeof(debugStat); - break; - - case STAT_TXCNT: - - pCh->channelTcount = *((cntStatPtr)pc); - pc += sizeof(cntStat); - break; - - case STAT_RXCNT: - - pCh->channelRcount = *((cntStatPtr)pc); - pc += sizeof(cntStat); - break; - - case STAT_BOXIDS: - pB->channelBtypes = *((bidStatPtr)pc); - pc += sizeof(bidStat); - set_baud_params(pB); - break; - - case STAT_HWFAIL: - i2QueueCommands (PTYPE_INLINE, pCh, 0, 1, CMD_HW_TEST); - pCh->channelFail = *((failStatPtr)pc); - pc += sizeof(failStat); - break; - - /* No explicit match? then - * Might be an error packet... - */ - default: - switch (uc & STAT_MOD_ERROR) - { - case STAT_ERROR: - if (uc & STAT_E_PARITY) { - pCh->dataSetIn |= I2_PAR; - pCh->icount.parity++; - } - if (uc & STAT_E_FRAMING){ - pCh->dataSetIn |= I2_FRA; - pCh->icount.frame++; - } - if (uc & STAT_E_OVERRUN){ - pCh->dataSetIn |= I2_OVR; - pCh->icount.overrun++; - } - break; - - case STAT_MODEM: - // the answer to DSS_NOW request (not change) - pCh->dataSetIn = (pCh->dataSetIn - & ~(I2_RI | I2_CTS | I2_DCD | I2_DSR) ) - | xlatDss[uc & 0xf]; - wake_up_interruptible ( &pCh->dss_now_wait ); - default: - break; - } - } /* End of switch on status type */ - if (dss_change) { -#ifdef USE_IQ - schedule_work(&pCh->tqueue_status); -#else - do_status(&pCh->tqueue_status); -#endif - } - } - else /* Or else, channel is invalid */ - { - // Even though the channel is invalid, we must test the - // status to see how much additional data it has (to be - // skipped) - switch (*pc++) - { - case STAT_FLOW: - pc += 4; /* Skip the data */ - break; - - default: - break; - } - } - } // End of while (there is still some status packet left) - break; - - default: // Neither packet? should be impossible - ip2trace (ITRC_NO_PORT, ITRC_SFIFO, 5, 1, - PTYPE_OF(pB->i2eLeadoffWord) ); - write_unlock_irqrestore(&pB->read_fifo_spinlock, - bflags); - - break; - } // End of switch on type of packets - } /*while(board I2_HAS_INPUT)*/ - - ip2trace (ITRC_NO_PORT, ITRC_SFIFO, ITRC_RETURN, 0 ); - - // Send acknowledgement to the board even if there was no data! - pB->i2eOutMailWaiting |= MB_IN_STRIPPED; - return; -} - -//****************************************************************************** -// Function: i2Write2Fifo(pB,address,count) -// Parameters: Pointer to a board structure, source address, byte count -// Returns: bytes written -// -// Description: -// Writes count bytes to board io address(implied) from source -// Adjusts count, leaves reserve for next time around bypass cmds -//****************************************************************************** -static int -i2Write2Fifo(i2eBordStrPtr pB, unsigned char *source, int count,int reserve) -{ - int rc = 0; - unsigned long flags; - write_lock_irqsave(&pB->write_fifo_spinlock, flags); - if (!pB->i2eWaitingForEmptyFifo) { - if (pB->i2eFifoRemains > (count+reserve)) { - pB->i2eFifoRemains -= count; - iiWriteBuf(pB, source, count); - pB->i2eOutMailWaiting |= MB_OUT_STUFFED; - rc = count; - } - } - write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); - return rc; -} -//****************************************************************************** -// Function: i2StuffFifoBypass(pB) -// Parameters: Pointer to a board structure -// Returns: Nothing -// -// Description: -// Stuffs as many bypass commands into the fifo as possible. This is simpler -// than stuffing data or inline commands to fifo, since we do not have -// flow-control to deal with. -//****************************************************************************** -static inline void -i2StuffFifoBypass(i2eBordStrPtr pB) -{ - i2ChanStrPtr pCh; - unsigned char *pRemove; - unsigned short stripIndex; - unsigned short packetSize; - unsigned short paddedSize; - unsigned short notClogged = 1; - unsigned long flags; - - int bailout = 1000; - - // Continue processing so long as there are entries, or there is room in the - // fifo. Each entry represents a channel with something to do. - while ( --bailout && notClogged && - (NULL != (pCh = i2DeQueueNeeds(pB,NEED_BYPASS)))) - { - write_lock_irqsave(&pCh->Cbuf_spinlock, flags); - stripIndex = pCh->Cbuf_strip; - - // as long as there are packets for this channel... - - while (stripIndex != pCh->Cbuf_stuff) { - pRemove = &(pCh->Cbuf[stripIndex]); - packetSize = CMD_COUNT_OF(pRemove) + sizeof(i2CmdHeader); - paddedSize = roundup(packetSize, 2); - - if (paddedSize > 0) { - if ( 0 == i2Write2Fifo(pB, pRemove, paddedSize,0)) { - notClogged = 0; /* fifo full */ - i2QueueNeeds(pB, pCh, NEED_BYPASS); // Put back on queue - break; // Break from the channel - } - } -#ifdef DEBUG_FIFO -WriteDBGBuf("BYPS", pRemove, paddedSize); -#endif /* DEBUG_FIFO */ - pB->debugBypassCount++; - - pRemove += packetSize; - stripIndex += packetSize; - if (stripIndex >= CBUF_SIZE) { - stripIndex = 0; - pRemove = pCh->Cbuf; - } - } - // Done with this channel. Move to next, removing this one from - // the queue of channels if we cleaned it out (i.e., didn't get clogged. - pCh->Cbuf_strip = stripIndex; - write_unlock_irqrestore(&pCh->Cbuf_spinlock, flags); - } // Either clogged or finished all the work - -#ifdef IP2DEBUG_TRACE - if ( !bailout ) { - ip2trace (ITRC_NO_PORT, ITRC_ERROR, 1, 0 ); - } -#endif -} - -//****************************************************************************** -// Function: i2StuffFifoFlow(pB) -// Parameters: Pointer to a board structure -// Returns: Nothing -// -// Description: -// Stuffs as many flow control packets into the fifo as possible. This is easier -// even than doing normal bypass commands, because there is always at most one -// packet, already assembled, for each channel. -//****************************************************************************** -static inline void -i2StuffFifoFlow(i2eBordStrPtr pB) -{ - i2ChanStrPtr pCh; - unsigned short paddedSize = roundup(sizeof(flowIn), 2); - - ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_ENTER, 2, - pB->i2eFifoRemains, paddedSize ); - - // Continue processing so long as there are entries, or there is room in the - // fifo. Each entry represents a channel with something to do. - while ( (NULL != (pCh = i2DeQueueNeeds(pB,NEED_FLOW)))) { - pB->debugFlowCount++; - - // NO Chan LOCK needed ??? - if ( 0 == i2Write2Fifo(pB,(unsigned char *)&(pCh->infl),paddedSize,0)) { - break; - } -#ifdef DEBUG_FIFO - WriteDBGBuf("FLOW",(unsigned char *) &(pCh->infl), paddedSize); -#endif /* DEBUG_FIFO */ - - } // Either clogged or finished all the work - - ip2trace (ITRC_NO_PORT, ITRC_SFLOW, ITRC_RETURN, 0 ); -} - -//****************************************************************************** -// Function: i2StuffFifoInline(pB) -// Parameters: Pointer to a board structure -// Returns: Nothing -// -// Description: -// Stuffs as much data and inline commands into the fifo as possible. This is -// the most complex fifo-stuffing operation, since there if now the channel -// flow-control issue to deal with. -//****************************************************************************** -static inline void -i2StuffFifoInline(i2eBordStrPtr pB) -{ - i2ChanStrPtr pCh; - unsigned char *pRemove; - unsigned short stripIndex; - unsigned short packetSize; - unsigned short paddedSize; - unsigned short notClogged = 1; - unsigned short flowsize; - unsigned long flags; - - int bailout = 1000; - int bailout2; - - ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_ENTER, 3, pB->i2eFifoRemains, - pB->i2Dbuf_strip, pB->i2Dbuf_stuff ); - - // Continue processing so long as there are entries, or there is room in the - // fifo. Each entry represents a channel with something to do. - while ( --bailout && notClogged && - (NULL != (pCh = i2DeQueueNeeds(pB,NEED_INLINE))) ) - { - write_lock_irqsave(&pCh->Obuf_spinlock, flags); - stripIndex = pCh->Obuf_strip; - - ip2trace (CHANN, ITRC_SICMD, 3, 2, stripIndex, pCh->Obuf_stuff ); - - // as long as there are packets for this channel... - bailout2 = 1000; - while ( --bailout2 && stripIndex != pCh->Obuf_stuff) { - pRemove = &(pCh->Obuf[stripIndex]); - - // Must determine whether this be a data or command packet to - // calculate correctly the header size and the amount of - // flow-control credit this type of packet will use. - if (PTYPE_OF(pRemove) == PTYPE_DATA) { - flowsize = DATA_COUNT_OF(pRemove); - packetSize = flowsize + sizeof(i2DataHeader); - } else { - flowsize = CMD_COUNT_OF(pRemove); - packetSize = flowsize + sizeof(i2CmdHeader); - } - flowsize = CREDIT_USAGE(flowsize); - paddedSize = roundup(packetSize, 2); - - ip2trace (CHANN, ITRC_SICMD, 4, 2, pB->i2eFifoRemains, paddedSize ); - - // If we don't have enough credits from the board to send the data, - // flag the channel that we are waiting for flow control credit, and - // break out. This will clean up this channel and remove us from the - // queue of hot things to do. - - ip2trace (CHANN, ITRC_SICMD, 5, 2, pCh->outfl.room, flowsize ); - - if (pCh->outfl.room <= flowsize) { - // Do Not have the credits to send this packet. - i2QueueNeeds(pB, pCh, NEED_CREDIT); - notClogged = 0; - break; // So to do next channel - } - if ( (paddedSize > 0) - && ( 0 == i2Write2Fifo(pB, pRemove, paddedSize, 128))) { - // Do Not have room in fifo to send this packet. - notClogged = 0; - i2QueueNeeds(pB, pCh, NEED_INLINE); - break; // Break from the channel - } -#ifdef DEBUG_FIFO -WriteDBGBuf("DATA", pRemove, paddedSize); -#endif /* DEBUG_FIFO */ - pB->debugInlineCount++; - - pCh->icount.tx += flowsize; - // Update current credits - pCh->outfl.room -= flowsize; - pCh->outfl.asof += flowsize; - if (PTYPE_OF(pRemove) == PTYPE_DATA) { - pCh->Obuf_char_count -= DATA_COUNT_OF(pRemove); - } - pRemove += packetSize; - stripIndex += packetSize; - - ip2trace (CHANN, ITRC_SICMD, 6, 2, stripIndex, pCh->Obuf_strip); - - if (stripIndex >= OBUF_SIZE) { - stripIndex = 0; - pRemove = pCh->Obuf; - - ip2trace (CHANN, ITRC_SICMD, 7, 1, stripIndex ); - - } - } /* while */ - if ( !bailout2 ) { - ip2trace (CHANN, ITRC_ERROR, 3, 0 ); - } - // Done with this channel. Move to next, removing this one from the - // queue of channels if we cleaned it out (i.e., didn't get clogged. - pCh->Obuf_strip = stripIndex; - write_unlock_irqrestore(&pCh->Obuf_spinlock, flags); - if ( notClogged ) - { - - ip2trace (CHANN, ITRC_SICMD, 8, 0 ); - - if ( pCh->pTTY ) { - ip2_owake(pCh->pTTY); - } - } - } // Either clogged or finished all the work - - if ( !bailout ) { - ip2trace (ITRC_NO_PORT, ITRC_ERROR, 4, 0 ); - } - - ip2trace (ITRC_NO_PORT, ITRC_SICMD, ITRC_RETURN, 1,pB->i2Dbuf_strip); -} - -//****************************************************************************** -// Function: serviceOutgoingFifo(pB) -// Parameters: Pointer to a board structure -// Returns: Nothing -// -// Description: -// Helper routine to put data in the outgoing fifo, if we aren't already waiting -// for something to be there. If the fifo has only room for a very little data, -// go head and hit the board with a mailbox hit immediately. Otherwise, it will -// have to happen later in the interrupt processing. Since this routine may be -// called both at interrupt and foreground time, we must turn off interrupts -// during the entire process. -//****************************************************************************** -static void -serviceOutgoingFifo(i2eBordStrPtr pB) -{ - // If we aren't currently waiting for the board to empty our fifo, service - // everything that is pending, in priority order (especially, Bypass before - // Inline). - if ( ! pB->i2eWaitingForEmptyFifo ) - { - i2StuffFifoFlow(pB); - i2StuffFifoBypass(pB); - i2StuffFifoInline(pB); - - iiSendPendingMail(pB); - } -} - -//****************************************************************************** -// Function: i2ServiceBoard(pB) -// Parameters: Pointer to a board structure -// Returns: Nothing -// -// Description: -// Normally this is called from interrupt level, but there is deliberately -// nothing in here specific to being called from interrupt level. All the -// hardware-specific, interrupt-specific things happen at the outer levels. -// -// For example, a timer interrupt could drive this routine for some sort of -// polled operation. The only requirement is that the programmer deal with any -// atomiticity/concurrency issues that result. -// -// This routine responds to the board's having sent mailbox information to the -// host (which would normally cause an interrupt). This routine reads the -// incoming mailbox. If there is no data in it, this board did not create the -// interrupt and/or has nothing to be done to it. (Except, if we have been -// waiting to write mailbox data to it, we may do so. -// -// Based on the value in the mailbox, we may take various actions. -// -// No checking here of pB validity: after all, it shouldn't have been called by -// the handler unless pB were on the list. -//****************************************************************************** -static inline int -i2ServiceBoard ( i2eBordStrPtr pB ) -{ - unsigned inmail; - unsigned long flags; - - - /* This should be atomic because of the way we are called... */ - if (NO_MAIL_HERE == ( inmail = pB->i2eStartMail ) ) { - inmail = iiGetMail(pB); - } - pB->i2eStartMail = NO_MAIL_HERE; - - ip2trace (ITRC_NO_PORT, ITRC_INTR, 2, 1, inmail ); - - if (inmail != NO_MAIL_HERE) { - // If the board has gone fatal, nothing to do but hit a bit that will - // alert foreground tasks to protest! - if ( inmail & MB_FATAL_ERROR ) { - pB->i2eFatal = 1; - goto exit_i2ServiceBoard; - } - - /* Assuming no fatal condition, we proceed to do work */ - if ( inmail & MB_IN_STUFFED ) { - pB->i2eFifoInInts++; - i2StripFifo(pB); /* There might be incoming packets */ - } - - if (inmail & MB_OUT_STRIPPED) { - pB->i2eFifoOutInts++; - write_lock_irqsave(&pB->write_fifo_spinlock, flags); - pB->i2eFifoRemains = pB->i2eFifoSize; - pB->i2eWaitingForEmptyFifo = 0; - write_unlock_irqrestore(&pB->write_fifo_spinlock, - flags); - - ip2trace (ITRC_NO_PORT, ITRC_INTR, 30, 1, pB->i2eFifoRemains ); - - } - serviceOutgoingFifo(pB); - } - - ip2trace (ITRC_NO_PORT, ITRC_INTR, 8, 0 ); - -exit_i2ServiceBoard: - - return 0; -} diff --git a/drivers/staging/tty/ip2/i2lib.h b/drivers/staging/tty/ip2/i2lib.h deleted file mode 100644 index e559e9bac06d..000000000000 --- a/drivers/staging/tty/ip2/i2lib.h +++ /dev/null @@ -1,351 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Header file for high level library functions -* -*******************************************************************************/ -#ifndef I2LIB_H -#define I2LIB_H 1 -//------------------------------------------------------------------------------ -// I2LIB.H -// -// IntelliPort-II and IntelliPort-IIEX -// -// Defines, structure definitions, and external declarations for i2lib.c -//------------------------------------------------------------------------------ -//-------------------------------------- -// Mandatory Includes: -//-------------------------------------- -#include "ip2types.h" -#include "i2ellis.h" -#include "i2pack.h" -#include "i2cmd.h" -#include - -//------------------------------------------------------------------------------ -// i2ChanStr -- Channel Structure: -// Used to track per-channel information for the library routines using standard -// loadware. Note also, a pointer to an array of these structures is patched -// into the i2eBordStr (see i2ellis.h) -//------------------------------------------------------------------------------ -// -// If we make some limits on the maximum block sizes, we can avoid dealing with -// buffer wrap. The wrapping of the buffer is based on where the start of the -// packet is. Then there is always room for the packet contiguously. -// -// Maximum total length of an outgoing data or in-line command block. The limit -// of 36 on data is quite arbitrary and based more on DOS memory limitations -// than the board interface. However, for commands, the maximum packet length is -// MAX_CMD_PACK_SIZE, because the field size for the count is only a few bits -// (see I2PACK.H) in such packets. For data packets, the count field size is not -// the limiting factor. As of this writing, MAX_OBUF_BLOCK < MAX_CMD_PACK_SIZE, -// but be careful if wanting to modify either. -// -#define MAX_OBUF_BLOCK 36 - -// Another note on maximum block sizes: we are buffering packets here. Data is -// put into the buffer (if there is room) regardless of the credits from the -// board. The board sends new credits whenever it has removed from his buffers a -// number of characters equal to 80% of total buffer size. (Of course, the total -// buffer size is what is reported when the very first set of flow control -// status packets are received from the board. Therefore, to be robust, you must -// always fill the board to at least 80% of the current credit limit, else you -// might not give it enough to trigger a new report. These conditions are -// obtained here so long as the maximum output block size is less than 20% the -// size of the board's output buffers. This is true at present by "coincidence" -// or "infernal knowledge": the board's output buffers are at least 700 bytes -// long (20% = 140 bytes, at least). The 80% figure is "official", so the safest -// strategy might be to trap the first flow control report and guarantee that -// the effective maxObufBlock is the minimum of MAX_OBUF_BLOCK and 20% of first -// reported buffer credit. -// -#define MAX_CBUF_BLOCK 6 // Maximum total length of a bypass command block - -#define IBUF_SIZE 512 // character capacity of input buffer per channel -#define OBUF_SIZE 1024// character capacity of output buffer per channel -#define CBUF_SIZE 10 // character capacity of output bypass buffer - -typedef struct _i2ChanStr -{ - // First, back-pointers so that given a pointer to this structure, you can - // determine the correct board and channel number to reference, (say, when - // issuing commands, etc. (Note, channel number is in infl.hd.i2sChannel.) - - int port_index; // Index of port in channel structure array attached - // to board structure. - PTTY pTTY; // Pointer to tty structure for port (OS specific) - USHORT validity; // Indicates whether the given channel has been - // initialized, really exists (or is a missing - // channel, e.g. channel 9 on an 8-port box.) - - i2eBordStrPtr pMyBord; // Back-pointer to this channel's board structure - - int wopen; // waiting fer carrier - - int throttled; // Set if upper layer can take no data - - int flags; // Defined in tty.h - - PWAITQ open_wait; // Pointer for OS sleep function. - PWAITQ close_wait; // Pointer for OS sleep function. - PWAITQ delta_msr_wait;// Pointer for OS sleep function. - PWAITQ dss_now_wait; // Pointer for OS sleep function. - - struct timer_list BookmarkTimer; // Used by i2DrainOutput - wait_queue_head_t pBookmarkWait; // Used by i2DrainOutput - - int BaudBase; - int BaudDivisor; - - USHORT ClosingDelay; - USHORT ClosingWaitTime; - - volatile - flowIn infl; // This structure is initialized as a completely - // formed flow-control command packet, and as such - // has the channel number, also the capacity and - // "as-of" data needed continuously. - - USHORT sinceLastFlow; // Counts the number of characters read from input - // buffers, since the last time flow control info - // was sent. - - USHORT whenSendFlow; // Determines when new flow control is to be sent to - // the board. Note unlike earlier manifestations of - // the driver, these packets can be sent from - // in-place. - - USHORT channelNeeds; // Bit map of important things which must be done - // for this channel. (See bits below ) - - volatile - flowStat outfl; // Same type of structure is used to hold current - // flow control information used to control our - // output. "asof" is kept updated as data is sent, - // and "room" never goes to zero. - - // The incoming ring buffer - // Unlike the outgoing buffers, this holds raw data, not packets. The two - // extra bytes are used to hold the byte-padding when there is room for an - // odd number of bytes before we must wrap. - // - UCHAR Ibuf[IBUF_SIZE + 2]; - volatile - USHORT Ibuf_stuff; // Stuffing index - volatile - USHORT Ibuf_strip; // Stripping index - - // The outgoing ring-buffer: Holds Data and command packets. N.B., even - // though these are in the channel structure, the channel is also written - // here, the easier to send it to the fifo when ready. HOWEVER, individual - // packets here are NOT padded to even length: the routines for writing - // blocks to the fifo will pad to even byte counts. - // - UCHAR Obuf[OBUF_SIZE+MAX_OBUF_BLOCK+4]; - volatile - USHORT Obuf_stuff; // Stuffing index - volatile - USHORT Obuf_strip; // Stripping index - int Obuf_char_count; - - // The outgoing bypass-command buffer. Unlike earlier manifestations, the - // flow control packets are sent directly from the structures. As above, the - // channel number is included in the packet, but they are NOT padded to even - // size. - // - UCHAR Cbuf[CBUF_SIZE+MAX_CBUF_BLOCK+2]; - volatile - USHORT Cbuf_stuff; // Stuffing index - volatile - USHORT Cbuf_strip; // Stripping index - - // The temporary buffer for the Linux tty driver PutChar entry. - // - UCHAR Pbuf[MAX_OBUF_BLOCK - sizeof (i2DataHeader)]; - volatile - USHORT Pbuf_stuff; // Stuffing index - - // The state of incoming data-set signals - // - USHORT dataSetIn; // Bit-mapped according to below. Also indicates - // whether a break has been detected since last - // inquiry. - - // The state of outcoming data-set signals (as far as we can tell!) - // - USHORT dataSetOut; // Bit-mapped according to below. - - // Most recent hot-key identifier detected - // - USHORT hotKeyIn; // Hot key as sent by the board, HOT_CLEAR indicates - // no hot key detected since last examined. - - // Counter of outstanding requests for bookmarks - // - short bookMarks; // Number of outstanding bookmark requests, (+ive - // whenever a bookmark request if queued up, -ive - // whenever a bookmark is received). - - // Misc options - // - USHORT channelOptions; // See below - - // To store various incoming special packets - // - debugStat channelStatus; - cntStat channelRcount; - cntStat channelTcount; - failStat channelFail; - - // To store the last values for line characteristics we sent to the board. - // - int speed; - - int flush_flags; - - void (*trace)(unsigned short,unsigned char,unsigned char,unsigned long,...); - - /* - * Kernel counters for the 4 input interrupts - */ - struct async_icount icount; - - /* - * Task queues for processing input packets from the board. - */ - struct work_struct tqueue_input; - struct work_struct tqueue_status; - struct work_struct tqueue_hangup; - - rwlock_t Ibuf_spinlock; - rwlock_t Obuf_spinlock; - rwlock_t Cbuf_spinlock; - rwlock_t Pbuf_spinlock; - -} i2ChanStr, *i2ChanStrPtr; - -//--------------------------------------------------- -// Manifests and bit-maps for elements in i2ChanStr -//--------------------------------------------------- -// -// flush flags -// -#define STARTFL_FLAG 1 -#define STOPFL_FLAG 2 - -// validity -// -#define CHANNEL_MAGIC_BITS 0xff00 -#define CHANNEL_MAGIC 0x5300 // (validity & CHANNEL_MAGIC_BITS) == - // CHANNEL_MAGIC --> structure good - -#define CHANNEL_SUPPORT 0x0001 // Indicates channel is supported, exists, - // and passed P.O.S.T. - -// channelNeeds -// -#define NEED_FLOW 1 // Indicates flow control has been queued -#define NEED_INLINE 2 // Indicates inline commands or data queued -#define NEED_BYPASS 4 // Indicates bypass commands queued -#define NEED_CREDIT 8 // Indicates would be sending except has not sufficient - // credit. The data is still in the channel structure, - // but the channel is not enqueued in the board - // structure again until there is a credit received from - // the board. - -// dataSetIn (Also the bits for i2GetStatus return value) -// -#define I2_DCD 1 -#define I2_CTS 2 -#define I2_DSR 4 -#define I2_RI 8 - -// dataSetOut (Also the bits for i2GetStatus return value) -// -#define I2_DTR 1 -#define I2_RTS 2 - -// i2GetStatus() can optionally clear these bits -// -#define I2_BRK 0x10 // A break was detected -#define I2_PAR 0x20 // A parity error was received -#define I2_FRA 0x40 // A framing error was received -#define I2_OVR 0x80 // An overrun error was received - -// i2GetStatus() automatically clears these bits */ -// -#define I2_DDCD 0x100 // DCD changed from its former value -#define I2_DCTS 0x200 // CTS changed from its former value -#define I2_DDSR 0x400 // DSR changed from its former value -#define I2_DRI 0x800 // RI changed from its former value - -// hotKeyIn -// -#define HOT_CLEAR 0x1322 // Indicates that no hot-key has been detected - -// channelOptions -// -#define CO_NBLOCK_WRITE 1 // Writes don't block waiting for buffer. (Default - // is, they do wait.) - -// fcmodes -// -#define I2_OUTFLOW_CTS 0x0001 -#define I2_INFLOW_RTS 0x0002 -#define I2_INFLOW_DSR 0x0004 -#define I2_INFLOW_DTR 0x0008 -#define I2_OUTFLOW_DSR 0x0010 -#define I2_OUTFLOW_DTR 0x0020 -#define I2_OUTFLOW_XON 0x0040 -#define I2_OUTFLOW_XANY 0x0080 -#define I2_INFLOW_XON 0x0100 - -#define I2_CRTSCTS (I2_OUTFLOW_CTS|I2_INFLOW_RTS) -#define I2_IXANY_MODE (I2_OUTFLOW_XON|I2_OUTFLOW_XANY) - -//------------------------------------------- -// Macros used from user level like functions -//------------------------------------------- - -// Macros to set and clear channel options -// -#define i2SetOption(pCh, option) pCh->channelOptions |= option -#define i2ClrOption(pCh, option) pCh->channelOptions &= ~option - -// Macro to set fatal-error trap -// -#define i2SetFatalTrap(pB, routine) pB->i2eFatalTrap = routine - -//-------------------------------------------- -// Declarations and prototypes for i2lib.c -//-------------------------------------------- -// -static int i2InitChannels(i2eBordStrPtr, int, i2ChanStrPtr); -static int i2QueueCommands(int, i2ChanStrPtr, int, int, cmdSyntaxPtr,...); -static int i2GetStatus(i2ChanStrPtr, int); -static int i2Input(i2ChanStrPtr); -static int i2InputFlush(i2ChanStrPtr); -static int i2Output(i2ChanStrPtr, const char *, int); -static int i2OutputFree(i2ChanStrPtr); -static int i2ServiceBoard(i2eBordStrPtr); -static void i2DrainOutput(i2ChanStrPtr, int); - -#ifdef IP2DEBUG_TRACE -void ip2trace(unsigned short,unsigned char,unsigned char,unsigned long,...); -#else -#define ip2trace(a,b,c,d...) do {} while (0) -#endif - -// Argument to i2QueueCommands -// -#define C_IN_LINE 1 -#define C_BYPASS 0 - -#endif // I2LIB_H diff --git a/drivers/staging/tty/ip2/i2pack.h b/drivers/staging/tty/ip2/i2pack.h deleted file mode 100644 index 00342a677c90..000000000000 --- a/drivers/staging/tty/ip2/i2pack.h +++ /dev/null @@ -1,364 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Definitions of the packets used to transfer data and commands -* Host <--> Board. Information provided here is only applicable -* when the standard loadware is active. -* -*******************************************************************************/ -#ifndef I2PACK_H -#define I2PACK_H 1 - -//----------------------------------------------- -// Revision History: -// -// 10 October 1991 MAG First draft -// 24 February 1992 MAG Additions for 1.4.x loadware -// 11 March 1992 MAG New status packets -// -//----------------------------------------------- - -//------------------------------------------------------------------------------ -// Packet Formats: -// -// Information passes between the host and board through the FIFO in packets. -// These have headers which indicate the type of packet. Because the fifo data -// path may be 16-bits wide, the protocol is constrained such that each packet -// is always padded to an even byte count. (The lower-level interface routines -// -- i2ellis.c -- are designed to do this). -// -// The sender (be it host or board) must place some number of complete packets -// in the fifo, then place a message in the mailbox that packets are available. -// Placing such a message interrupts the "receiver" (be it board or host), who -// reads the mailbox message and determines that there are incoming packets -// ready. Since there are no partial packets, and the length of a packet is -// given in the header, the remainder of the packet can be read without checking -// for FIFO empty condition. The process is repeated, packet by packet, until -// the incoming FIFO is empty. Then the receiver uses the outbound mailbox to -// signal the board that it has read the data. Only then can the sender place -// additional data in the fifo. -//------------------------------------------------------------------------------ -// -//------------------------------------------------ -// Definition of Packet Header Area -//------------------------------------------------ -// -// Caution: these only define header areas. In actual use the data runs off -// beyond the end of these structures. -// -// Since these structures are based on sequences of bytes which go to the board, -// there cannot be ANY padding between the elements. -#pragma pack(1) - -//---------------------------- -// DATA PACKETS -//---------------------------- - -typedef struct _i2DataHeader -{ - unsigned char i2sChannel; /* The channel number: 0-255 */ - - // -- Bitfields are allocated LSB first -- - - // For incoming data, indicates whether this is an ordinary packet or a - // special one (e.g., hot key hit). - unsigned i2sId : 2 __attribute__ ((__packed__)); - - // For tagging data packets. There are flush commands which flush only data - // packets bearing a particular tag. (used in implementing IntelliView and - // IntelliPrint). THE TAG VALUE 0xf is RESERVED and must not be used (it has - // meaning internally to the loadware). - unsigned i2sTag : 4; - - // These two bits determine the type of packet sent/received. - unsigned i2sType : 2; - - // The count of data to follow: does not include the possible additional - // padding byte. MAXIMUM COUNT: 4094. The top four bits must be 0. - unsigned short i2sCount; - -} i2DataHeader, *i2DataHeaderPtr; - -// Structure is immediately followed by the data, proper. - -//---------------------------- -// NON-DATA PACKETS -//---------------------------- - -typedef struct _i2CmdHeader -{ - unsigned char i2sChannel; // The channel number: 0-255 (Except where noted - // - see below - - // Number of bytes of commands, status or whatever to follow - unsigned i2sCount : 6; - - // These two bits determine the type of packet sent/received. - unsigned i2sType : 2; - -} i2CmdHeader, *i2CmdHeaderPtr; - -// Structure is immediately followed by the applicable data. - -//--------------------------------------- -// Flow Control Packets (Outbound) -//--------------------------------------- - -// One type of outbound command packet is so important that the entire structure -// is explicitly defined here. That is the flow-control packet. This is never -// sent by user-level code (as would be the commands to raise/lower DTR, for -// example). These are only sent by the library routines in response to reading -// incoming data into the buffers. -// -// The parameters inside the command block are maintained in place, then the -// block is sent at the appropriate time. - -typedef struct _flowIn -{ - i2CmdHeader hd; // Channel #, count, type (see above) - unsigned char fcmd; // The flow control command (37) - unsigned short asof; // As of byte number "asof" (LSB first!) I have room - // for "room" bytes - unsigned short room; -} flowIn, *flowInPtr; - -//---------------------------------------- -// (Incoming) Status Packets -//---------------------------------------- - -// Incoming packets which are non-data packets are status packets. In this case, -// the channel number in the header is unimportant. What follows are one or more -// sub-packets, the first word of which consists of the channel (first or low -// byte) and the status indicator (second or high byte), followed by possibly -// more data. - -#define STAT_CTS_UP 0 /* CTS raised (no other bytes) */ -#define STAT_CTS_DN 1 /* CTS dropped (no other bytes) */ -#define STAT_DCD_UP 2 /* DCD raised (no other bytes) */ -#define STAT_DCD_DN 3 /* DCD dropped (no other bytes) */ -#define STAT_DSR_UP 4 /* DSR raised (no other bytes) */ -#define STAT_DSR_DN 5 /* DSR dropped (no other bytes) */ -#define STAT_RI_UP 6 /* RI raised (no other bytes) */ -#define STAT_RI_DN 7 /* RI dropped (no other bytes) */ -#define STAT_BRK_DET 8 /* BRK detect (no other bytes) */ -#define STAT_FLOW 9 /* Flow control(-- more: see below */ -#define STAT_BMARK 10 /* Bookmark (no other bytes) - * Bookmark is sent as a response to - * a command 60: request for bookmark - */ -#define STAT_STATUS 11 /* Special packet: see below */ -#define STAT_TXCNT 12 /* Special packet: see below */ -#define STAT_RXCNT 13 /* Special packet: see below */ -#define STAT_BOXIDS 14 /* Special packet: see below */ -#define STAT_HWFAIL 15 /* Special packet: see below */ - -#define STAT_MOD_ERROR 0xc0 -#define STAT_MODEM 0xc0/* If status & STAT_MOD_ERROR: - * == STAT_MODEM, then this is a modem - * status packet, given in response to a - * CMD_DSS_NOW command. - * The low nibble has each data signal: - */ -#define STAT_MOD_DCD 0x8 -#define STAT_MOD_RI 0x4 -#define STAT_MOD_DSR 0x2 -#define STAT_MOD_CTS 0x1 - -#define STAT_ERROR 0x80/* If status & STAT_MOD_ERROR - * == STAT_ERROR, then - * sort of error on the channel. - * The remaining seven bits indicate - * what sort of error it is. - */ -/* The low three bits indicate parity, framing, or overrun errors */ - -#define STAT_E_PARITY 4 /* Parity error */ -#define STAT_E_FRAMING 2 /* Framing error */ -#define STAT_E_OVERRUN 1 /* (uxart) overrun error */ - -//--------------------------------------- -// STAT_FLOW packets -//--------------------------------------- - -typedef struct _flowStat -{ - unsigned short asof; - unsigned short room; -}flowStat, *flowStatPtr; - -// flowStat packets are received from the board to regulate the flow of outgoing -// data. A local copy of this structure is also kept to track the amount of -// credits used and credits remaining. "room" is the amount of space in the -// board's buffers, "as of" having received a certain byte number. When sending -// data to the fifo, you must calculate how much buffer space your packet will -// use. Add this to the current "asof" and subtract it from the current "room". -// -// The calculation for the board's buffer is given by CREDIT_USAGE, where size -// is the un-rounded count of either data characters or command characters. -// (Which is to say, the count rounded up, plus two). - -#define CREDIT_USAGE(size) (((size) + 3) & ~1) - -//--------------------------------------- -// STAT_STATUS packets -//--------------------------------------- - -typedef struct _debugStat -{ - unsigned char d_ccsr; - unsigned char d_txinh; - unsigned char d_stat1; - unsigned char d_stat2; -} debugStat, *debugStatPtr; - -// debugStat packets are sent to the host in response to a CMD_GET_STATUS -// command. Each byte is bit-mapped as described below: - -#define D_CCSR_XON 2 /* Has received XON, ready to transmit */ -#define D_CCSR_XOFF 4 /* Has received XOFF, not transmitting */ -#define D_CCSR_TXENAB 8 /* Transmitter is enabled */ -#define D_CCSR_RXENAB 0x80 /* Receiver is enabled */ - -#define D_TXINH_BREAK 1 /* We are sending a break */ -#define D_TXINH_EMPTY 2 /* No data to send */ -#define D_TXINH_SUSP 4 /* Output suspended via command 57 */ -#define D_TXINH_CMD 8 /* We are processing an in-line command */ -#define D_TXINH_LCD 0x10 /* LCD diagnostics are running */ -#define D_TXINH_PAUSE 0x20 /* We are processing a PAUSE command */ -#define D_TXINH_DCD 0x40 /* DCD is low, preventing transmission */ -#define D_TXINH_DSR 0x80 /* DSR is low, preventing transmission */ - -#define D_STAT1_TXEN 1 /* Transmit INTERRUPTS enabled */ -#define D_STAT1_RXEN 2 /* Receiver INTERRUPTS enabled */ -#define D_STAT1_MDEN 4 /* Modem (data set sigs) interrupts enabled */ -#define D_STAT1_RLM 8 /* Remote loopback mode selected */ -#define D_STAT1_LLM 0x10 /* Local internal loopback mode selected */ -#define D_STAT1_CTS 0x20 /* CTS is low, preventing transmission */ -#define D_STAT1_DTR 0x40 /* DTR is low, to stop remote transmission */ -#define D_STAT1_RTS 0x80 /* RTS is low, to stop remote transmission */ - -#define D_STAT2_TXMT 1 /* Transmit buffers are all empty */ -#define D_STAT2_RXMT 2 /* Receive buffers are all empty */ -#define D_STAT2_RXINH 4 /* Loadware has tried to inhibit remote - * transmission: dropped DTR, sent XOFF, - * whatever... - */ -#define D_STAT2_RXFLO 8 /* Loadware can send no more data to host - * until it receives a flow-control packet - */ -//----------------------------------------- -// STAT_TXCNT and STAT_RXCNT packets -//---------------------------------------- - -typedef struct _cntStat -{ - unsigned short cs_time; // (Assumes host is little-endian!) - unsigned short cs_count; -} cntStat, *cntStatPtr; - -// These packets are sent in response to a CMD_GET_RXCNT or a CMD_GET_TXCNT -// bypass command. cs_time is a running 1 Millisecond counter which acts as a -// time stamp. cs_count is a running counter of data sent or received from the -// uxarts. (Not including data added by the chip itself, as with CRLF -// processing). -//------------------------------------------ -// STAT_HWFAIL packets -//------------------------------------------ - -typedef struct _failStat -{ - unsigned char fs_written; - unsigned char fs_read; - unsigned short fs_address; -} failStat, *failStatPtr; - -// This packet is sent whenever the on-board diagnostic process detects an -// error. At startup, this process is dormant. The host can wake it up by -// issuing the bypass command CMD_HW_TEST. The process runs at low priority and -// performs continuous hardware verification; writing data to certain on-board -// registers, reading it back, and comparing. If it detects an error, this -// packet is sent to the host, and the process goes dormant again until the host -// sends another CMD_HW_TEST. It then continues with the next register to be -// tested. - -//------------------------------------------------------------------------------ -// Macros to deal with the headers more easily! Note that these are defined so -// they may be used as "left" as well as "right" expressions. -//------------------------------------------------------------------------------ - -// Given a pointer to the packet, reference the channel number -// -#define CHANNEL_OF(pP) ((i2DataHeaderPtr)(pP))->i2sChannel - -// Given a pointer to the packet, reference the Packet type -// -#define PTYPE_OF(pP) ((i2DataHeaderPtr)(pP))->i2sType - -// The possible types of packets -// -#define PTYPE_DATA 0 /* Host <--> Board */ -#define PTYPE_BYPASS 1 /* Host ---> Board */ -#define PTYPE_INLINE 2 /* Host ---> Board */ -#define PTYPE_STATUS 2 /* Host <--- Board */ - -// Given a pointer to a Data packet, reference the Tag -// -#define TAG_OF(pP) ((i2DataHeaderPtr)(pP))->i2sTag - -// Given a pointer to a Data packet, reference the data i.d. -// -#define ID_OF(pP) ((i2DataHeaderPtr)(pP))->i2sId - -// The possible types of ID's -// -#define ID_ORDINARY_DATA 0 -#define ID_HOT_KEY 1 - -// Given a pointer to a Data packet, reference the count -// -#define DATA_COUNT_OF(pP) ((i2DataHeaderPtr)(pP))->i2sCount - -// Given a pointer to a Data packet, reference the beginning of data -// -#define DATA_OF(pP) &((unsigned char *)(pP))[4] // 4 = size of header - -// Given a pointer to a Non-Data packet, reference the count -// -#define CMD_COUNT_OF(pP) ((i2CmdHeaderPtr)(pP))->i2sCount - -#define MAX_CMD_PACK_SIZE 62 // Maximum size of such a count - -// Given a pointer to a Non-Data packet, reference the beginning of data -// -#define CMD_OF(pP) &((unsigned char *)(pP))[2] // 2 = size of header - -//-------------------------------- -// MailBox Bits: -//-------------------------------- - -//-------------------------- -// Outgoing (host to board) -//-------------------------- -// -#define MB_OUT_STUFFED 0x80 // Host has placed output in fifo -#define MB_IN_STRIPPED 0x40 // Host has read in all input from fifo - -//-------------------------- -// Incoming (board to host) -//-------------------------- -// -#define MB_IN_STUFFED 0x80 // Board has placed input in fifo -#define MB_OUT_STRIPPED 0x40 // Board has read all output from fifo -#define MB_FATAL_ERROR 0x20 // Board has encountered a fatal error - -#pragma pack() // Reset padding to command-line default - -#endif // I2PACK_H - diff --git a/drivers/staging/tty/ip2/ip2.h b/drivers/staging/tty/ip2/ip2.h deleted file mode 100644 index 936ccc533949..000000000000 --- a/drivers/staging/tty/ip2/ip2.h +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Driver constants for configuration and tuning -* -* NOTES: -* -*******************************************************************************/ -#ifndef IP2_H -#define IP2_H - -#include "ip2types.h" -#include "i2cmd.h" - -/*************/ -/* Constants */ -/*************/ - -/* Device major numbers - since version 2.0.26. */ -#define IP2_TTY_MAJOR 71 -#define IP2_CALLOUT_MAJOR 72 -#define IP2_IPL_MAJOR 73 - -/* Board configuration array. - * This array defines the hardware irq and address for up to IP2_MAX_BOARDS - * (4 supported per ip2_types.h) ISA board addresses and irqs MUST be specified, - * PCI and EISA boards are probed for and automagicly configed - * iff the addresses are set to 1 and 2 respectivily. - * 0x0100 - 0x03f0 == ISA - * 1 == PCI - * 2 == EISA - * 0 == (skip this board) - * This array defines the hardware addresses for them. Special - * addresses are EISA and PCI which go sniffing for boards. - - * In a multiboard system the position in the array determines which port - * devices are assigned to each board: - * board 0 is assigned ttyF0.. to ttyF63, - * board 1 is assigned ttyF64 to ttyF127, - * board 2 is assigned ttyF128 to ttyF191, - * board 3 is assigned ttyF192 to ttyF255. - * - * In PCI and EISA bus systems each range is mapped to card in - * monotonically increasing slot number order, ISA position is as specified - * here. - - * If the irqs are ALL set to 0,0,0,0 all boards operate in - * polled mode. For interrupt operation ISA boards require that the IRQ be - * specified, while PCI and EISA boards any nonzero entry - * will enable interrupts using the BIOS configured irq for the board. - * An invalid irq entry will default to polled mode for that card and print - * console warning. - - * When the driver is loaded as a module these setting can be overridden on the - * modprobe command line or on an option line in /etc/modprobe.conf. - * If the driver is built-in the configuration must be - * set here for ISA cards and address set to 1 and 2 for PCI and EISA. - * - * Here is an example that shows most if not all possibe combinations: - - *static ip2config_t ip2config = - *{ - * {11,1,0,0}, // irqs - * { // Addresses - * 0x0308, // Board 0, ttyF0 - ttyF63// ISA card at io=0x308, irq=11 - * 0x0001, // Board 1, ttyF64 - ttyF127//PCI card configured by BIOS - * 0x0000, // Board 2, ttyF128 - ttyF191// Slot skipped - * 0x0002 // Board 3, ttyF192 - ttyF255//EISA card configured by BIOS - * // but polled not irq driven - * } - *}; - */ - - /* this structure is zeroed out because the suggested method is to configure - * the driver as a module, set up the parameters with an options line in - * /etc/modprobe.conf and load with modprobe or kmod, the kernel - * module loader - */ - - /* This structure is NOW always initialized when the driver is initialized. - * Compiled in defaults MUST be added to the io and irq arrays in - * ip2.c. Those values are configurable from insmod parameters in the - * case of modules or from command line parameters (ip2=io,irq) when - * compiled in. - */ - -static ip2config_t ip2config = -{ - {0,0,0,0}, // irqs - { // Addresses - /* Do NOT set compile time defaults HERE! Use the arrays in - ip2.c! These WILL be overwritten! =mhw= */ - 0x0000, // Board 0, ttyF0 - ttyF63 - 0x0000, // Board 1, ttyF64 - ttyF127 - 0x0000, // Board 2, ttyF128 - ttyF191 - 0x0000 // Board 3, ttyF192 - ttyF255 - } -}; - -#endif diff --git a/drivers/staging/tty/ip2/ip2ioctl.h b/drivers/staging/tty/ip2/ip2ioctl.h deleted file mode 100644 index aa0a9da85e05..000000000000 --- a/drivers/staging/tty/ip2/ip2ioctl.h +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Driver constants for configuration and tuning -* -* NOTES: -* -*******************************************************************************/ - -#ifndef IP2IOCTL_H -#define IP2IOCTL_H - -//************* -//* Constants * -//************* - -// High baud rates (if not defined elsewhere. -#ifndef B153600 -# define B153600 0010005 -#endif -#ifndef B307200 -# define B307200 0010006 -#endif -#ifndef B921600 -# define B921600 0010007 -#endif - -#endif diff --git a/drivers/staging/tty/ip2/ip2main.c b/drivers/staging/tty/ip2/ip2main.c deleted file mode 100644 index ba074fbb4ce2..000000000000 --- a/drivers/staging/tty/ip2/ip2main.c +++ /dev/null @@ -1,3234 +0,0 @@ -/* -* -* (c) 1999 by Computone Corporation -* -******************************************************************************** -* -* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Mainline code for the device driver -* -*******************************************************************************/ -// ToDo: -// -// Fix the immediate DSS_NOW problem. -// Work over the channel stats return logic in ip2_ipl_ioctl so they -// make sense for all 256 possible channels and so the user space -// utilities will compile and work properly. -// -// Done: -// -// 1.2.14 /\/\|=mhw=|\/\/ -// Added bounds checking to ip2_ipl_ioctl to avoid potential terroristic acts. -// Changed the definition of ip2trace to be more consistent with kernel style -// Thanks to Andreas Dilger for these updates -// -// 1.2.13 /\/\|=mhw=|\/\/ -// DEVFS: Renamed ttf/{n} to tts/F{n} and cuf/{n} to cua/F{n} to conform -// to agreed devfs serial device naming convention. -// -// 1.2.12 /\/\|=mhw=|\/\/ -// Cleaned up some remove queue cut and paste errors -// -// 1.2.11 /\/\|=mhw=|\/\/ -// Clean up potential NULL pointer dereferences -// Clean up devfs registration -// Add kernel command line parsing for io and irq -// Compile defaults for io and irq are now set in ip2.c not ip2.h! -// Reworked poll_only hack for explicit parameter setting -// You must now EXPLICITLY set poll_only = 1 or set all irqs to 0 -// Merged ip2_loadmain and old_ip2_init -// Converted all instances of interruptible_sleep_on into queue calls -// Most of these had no race conditions but better to clean up now -// -// 1.2.10 /\/\|=mhw=|\/\/ -// Fixed the bottom half interrupt handler and enabled USE_IQI -// to split the interrupt handler into a formal top-half / bottom-half -// Fixed timing window on high speed processors that queued messages to -// the outbound mail fifo faster than the board could handle. -// -// 1.2.9 -// Four box EX was barfing on >128k kmalloc, made structure smaller by -// reducing output buffer size -// -// 1.2.8 -// Device file system support (MHW) -// -// 1.2.7 -// Fixed -// Reload of ip2 without unloading ip2main hangs system on cat of /proc/modules -// -// 1.2.6 -//Fixes DCD problems -// DCD was not reported when CLOCAL was set on call to TIOCMGET -// -//Enhancements: -// TIOCMGET requests and waits for status return -// No DSS interrupts enabled except for DCD when needed -// -// For internal use only -// -//#define IP2DEBUG_INIT -//#define IP2DEBUG_OPEN -//#define IP2DEBUG_WRITE -//#define IP2DEBUG_READ -//#define IP2DEBUG_IOCTL -//#define IP2DEBUG_IPL - -//#define IP2DEBUG_TRACE -//#define DEBUG_FIFO - -/************/ -/* 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 - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include - -#include "ip2types.h" -#include "ip2trace.h" -#include "ip2ioctl.h" -#include "ip2.h" -#include "i2ellis.h" -#include "i2lib.h" - -/***************** - * /proc/ip2mem * - *****************/ - -#include -#include - -static DEFINE_MUTEX(ip2_mutex); -static const struct file_operations ip2mem_proc_fops; -static const struct file_operations ip2_proc_fops; - -/********************/ -/* Type Definitions */ -/********************/ - -/*************/ -/* Constants */ -/*************/ - -/* String constants to identify ourselves */ -static const char pcName[] = "Computone IntelliPort Plus multiport driver"; -static const char pcVersion[] = "1.2.14"; - -/* String constants for port names */ -static const char pcDriver_name[] = "ip2"; -static const char pcIpl[] = "ip2ipl"; - -/***********************/ -/* Function Prototypes */ -/***********************/ - -/* Global module entry functions */ - -/* Private (static) functions */ -static int ip2_open(PTTY, struct file *); -static void ip2_close(PTTY, struct file *); -static int ip2_write(PTTY, const unsigned char *, int); -static int ip2_putchar(PTTY, unsigned char); -static void ip2_flush_chars(PTTY); -static int ip2_write_room(PTTY); -static int ip2_chars_in_buf(PTTY); -static void ip2_flush_buffer(PTTY); -static int ip2_ioctl(PTTY, UINT, ULONG); -static void ip2_set_termios(PTTY, struct ktermios *); -static void ip2_set_line_discipline(PTTY); -static void ip2_throttle(PTTY); -static void ip2_unthrottle(PTTY); -static void ip2_stop(PTTY); -static void ip2_start(PTTY); -static void ip2_hangup(PTTY); -static int ip2_tiocmget(struct tty_struct *tty); -static int ip2_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static int ip2_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount); - -static void set_irq(int, int); -static void ip2_interrupt_bh(struct work_struct *work); -static irqreturn_t ip2_interrupt(int irq, void *dev_id); -static void ip2_poll(unsigned long arg); -static inline void service_all_boards(void); -static void do_input(struct work_struct *); -static void do_status(struct work_struct *); - -static void ip2_wait_until_sent(PTTY,int); - -static void set_params (i2ChanStrPtr, struct ktermios *); -static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *); -static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *); - -static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *); -static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *); -static long ip2_ipl_ioctl(struct file *, UINT, ULONG); -static int ip2_ipl_open(struct inode *, struct file *); - -static int DumpTraceBuffer(char __user *, int); -static int DumpFifoBuffer( char __user *, int); - -static void ip2_init_board(int, const struct firmware *); -static unsigned short find_eisa_board(int); -static int ip2_setup(char *str); - -/***************/ -/* Static Data */ -/***************/ - -static struct tty_driver *ip2_tty_driver; - -/* Here, then is a table of board pointers which the interrupt routine should - * scan through to determine who it must service. - */ -static unsigned short i2nBoards; // Number of boards here - -static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS]; - -static i2ChanStrPtr DevTable[IP2_MAX_PORTS]; -//DevTableMem just used to save addresses for kfree -static void *DevTableMem[IP2_MAX_BOARDS]; - -/* This is the driver descriptor for the ip2ipl device, which is used to - * download the loadware to the boards. - */ -static const struct file_operations ip2_ipl = { - .owner = THIS_MODULE, - .read = ip2_ipl_read, - .write = ip2_ipl_write, - .unlocked_ioctl = ip2_ipl_ioctl, - .open = ip2_ipl_open, - .llseek = noop_llseek, -}; - -static unsigned long irq_counter; -static unsigned long bh_counter; - -// Use immediate queue to service interrupts -#define USE_IQI -//#define USE_IQ // PCI&2.2 needs work - -/* The timer_list entry for our poll routine. If interrupt operation is not - * selected, the board is serviced periodically to see if anything needs doing. - */ -#define POLL_TIMEOUT (jiffies + 1) -static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0); - -#ifdef IP2DEBUG_TRACE -/* Trace (debug) buffer data */ -#define TRACEMAX 1000 -static unsigned long tracebuf[TRACEMAX]; -static int tracestuff; -static int tracestrip; -static int tracewrap; -#endif - -/**********/ -/* Macros */ -/**********/ - -#ifdef IP2DEBUG_OPEN -#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \ - tty->name,(pCh->flags), \ - tty->count,/*GET_USE_COUNT(module)*/0,s) -#else -#define DBG_CNT(s) -#endif - -/********/ -/* Code */ -/********/ - -#include "i2ellis.c" /* Extremely low-level interface services */ -#include "i2cmd.c" /* Standard loadware command definitions */ -#include "i2lib.c" /* High level interface services */ - -/* Configuration area for modprobe */ - -MODULE_AUTHOR("Doug McNash"); -MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); -MODULE_LICENSE("GPL"); - -#define MAX_CMD_STR 50 - -static int poll_only; -static char cmd[MAX_CMD_STR]; - -static int Eisa_irq; -static int Eisa_slot; - -static int iindx; -static char rirqs[IP2_MAX_BOARDS]; -static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0}; - -/* Note: Add compiled in defaults to these arrays, not to the structure - in ip2.h any longer. That structure WILL get overridden - by these values, or command line values, or insmod values!!! =mhw= -*/ -static int io[IP2_MAX_BOARDS]; -static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 }; - -MODULE_AUTHOR("Doug McNash"); -MODULE_DESCRIPTION("Computone IntelliPort Plus Driver"); -module_param_array(irq, int, NULL, 0); -MODULE_PARM_DESC(irq, "Interrupts for IntelliPort Cards"); -module_param_array(io, int, NULL, 0); -MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards"); -module_param(poll_only, bool, 0); -MODULE_PARM_DESC(poll_only, "Do not use card interrupts"); -module_param_string(ip2, cmd, MAX_CMD_STR, 0); -MODULE_PARM_DESC(ip2, "Contains module parameter passed with 'ip2='"); - -/* for sysfs class support */ -static struct class *ip2_class; - -/* Some functions to keep track of what irqs we have */ - -static int __init is_valid_irq(int irq) -{ - int *i = Valid_Irqs; - - while (*i != 0 && *i != irq) - i++; - - return *i; -} - -static void __init mark_requested_irq(char irq) -{ - rirqs[iindx++] = irq; -} - -static int __exit clear_requested_irq(char irq) -{ - int i; - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - if (rirqs[i] == irq) { - rirqs[i] = 0; - return 1; - } - } - return 0; -} - -static int have_requested_irq(char irq) -{ - /* array init to zeros so 0 irq will not be requested as a side - * effect */ - int i; - for (i = 0; i < IP2_MAX_BOARDS; ++i) - if (rirqs[i] == irq) - return 1; - return 0; -} - -/******************************************************************************/ -/* Function: cleanup_module() */ -/* Parameters: None */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* This is a required entry point for an installable module. It has to return */ -/* the device and the driver to a passive state. It should not be necessary */ -/* to reset the board fully, especially as the loadware is downloaded */ -/* externally rather than in the driver. We just want to disable the board */ -/* and clear the loadware to a reset state. To allow this there has to be a */ -/* way to detect whether the board has the loadware running at init time to */ -/* handle subsequent installations of the driver. All memory allocated by the */ -/* driver should be returned since it may be unloaded from memory. */ -/******************************************************************************/ -static void __exit ip2_cleanup_module(void) -{ - int err; - int i; - - del_timer_sync(&PollTimer); - - /* Reset the boards we have. */ - for (i = 0; i < IP2_MAX_BOARDS; i++) - if (i2BoardPtrTable[i]) - iiReset(i2BoardPtrTable[i]); - - /* The following is done at most once, if any boards were installed. */ - for (i = 0; i < IP2_MAX_BOARDS; i++) { - if (i2BoardPtrTable[i]) { - iiResetDelay(i2BoardPtrTable[i]); - /* free io addresses and Tibet */ - release_region(ip2config.addr[i], 8); - device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); - device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, - 4 * i + 1)); - } - /* Disable and remove interrupt handler. */ - if (ip2config.irq[i] > 0 && - have_requested_irq(ip2config.irq[i])) { - free_irq(ip2config.irq[i], (void *)&pcName); - clear_requested_irq(ip2config.irq[i]); - } - } - class_destroy(ip2_class); - err = tty_unregister_driver(ip2_tty_driver); - if (err) - printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", - err); - put_tty_driver(ip2_tty_driver); - unregister_chrdev(IP2_IPL_MAJOR, pcIpl); - remove_proc_entry("ip2mem", NULL); - - /* free memory */ - for (i = 0; i < IP2_MAX_BOARDS; i++) { - void *pB; -#ifdef CONFIG_PCI - if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) { - pci_disable_device(ip2config.pci_dev[i]); - pci_dev_put(ip2config.pci_dev[i]); - ip2config.pci_dev[i] = NULL; - } -#endif - pB = i2BoardPtrTable[i]; - if (pB != NULL) { - kfree(pB); - i2BoardPtrTable[i] = NULL; - } - if (DevTableMem[i] != NULL) { - kfree(DevTableMem[i]); - DevTableMem[i] = NULL; - } - } -} -module_exit(ip2_cleanup_module); - -static const struct tty_operations ip2_ops = { - .open = ip2_open, - .close = ip2_close, - .write = ip2_write, - .put_char = ip2_putchar, - .flush_chars = ip2_flush_chars, - .write_room = ip2_write_room, - .chars_in_buffer = ip2_chars_in_buf, - .flush_buffer = ip2_flush_buffer, - .ioctl = ip2_ioctl, - .throttle = ip2_throttle, - .unthrottle = ip2_unthrottle, - .set_termios = ip2_set_termios, - .set_ldisc = ip2_set_line_discipline, - .stop = ip2_stop, - .start = ip2_start, - .hangup = ip2_hangup, - .tiocmget = ip2_tiocmget, - .tiocmset = ip2_tiocmset, - .get_icount = ip2_get_icount, - .proc_fops = &ip2_proc_fops, -}; - -/******************************************************************************/ -/* Function: ip2_loadmain() */ -/* Parameters: irq, io from command line of insmod et. al. */ -/* pointer to fip firmware and firmware size for boards */ -/* Returns: Success (0) */ -/* */ -/* Description: */ -/* This was the required entry point for all drivers (now in ip2.c) */ -/* It performs all */ -/* initialisation of the devices and driver structures, and registers itself */ -/* with the relevant kernel modules. */ -/******************************************************************************/ -/* IRQF_DISABLED - if set blocks all interrupts else only this line */ -/* IRQF_SHARED - for shared irq PCI or maybe EISA only */ -/* SA_RANDOM - can be source for cert. random number generators */ -#define IP2_SA_FLAGS 0 - - -static const struct firmware *ip2_request_firmware(void) -{ - struct platform_device *pdev; - const struct firmware *fw; - - pdev = platform_device_register_simple("ip2", 0, NULL, 0); - if (IS_ERR(pdev)) { - printk(KERN_ERR "Failed to register platform device for ip2\n"); - return NULL; - } - if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) { - printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n"); - fw = NULL; - } - platform_device_unregister(pdev); - return fw; -} - -/****************************************************************************** - * ip2_setup: - * str: kernel command line string - * - * Can't autoprobe the boards so user must specify configuration on - * kernel command line. Sane people build it modular but the others - * come here. - * - * Alternating pairs of io,irq for up to 4 boards. - * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3 - * - * io=0 => No board - * io=1 => PCI - * io=2 => EISA - * else => ISA I/O address - * - * irq=0 or invalid for ISA will revert to polling mode - * - * Any value = -1, do not overwrite compiled in value. - * - ******************************************************************************/ -static int __init ip2_setup(char *str) -{ - int j, ints[10]; /* 4 boards, 2 parameters + 2 */ - unsigned int i; - - str = get_options(str, ARRAY_SIZE(ints), ints); - - for (i = 0, j = 1; i < 4; i++) { - if (j > ints[0]) - break; - if (ints[j] >= 0) - io[i] = ints[j]; - j++; - if (j > ints[0]) - break; - if (ints[j] >= 0) - irq[i] = ints[j]; - j++; - } - return 1; -} -__setup("ip2=", ip2_setup); - -static int __init ip2_loadmain(void) -{ - int i, j, box; - int err = 0; - i2eBordStrPtr pB = NULL; - int rc = -1; - const struct firmware *fw = NULL; - char *str; - - str = cmd; - - if (poll_only) { - /* Hard lock the interrupts to zero */ - irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0; - } - - /* Check module parameter with 'ip2=' has been passed or not */ - if (!poll_only && (!strncmp(str, "ip2=", 4))) - ip2_setup(str); - - ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0); - - /* process command line arguments to modprobe or - insmod i.e. iop & irqp */ - /* irqp and iop should ALWAYS be specified now... But we check - them individually just to be sure, anyways... */ - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - ip2config.addr[i] = io[i]; - if (irq[i] >= 0) - ip2config.irq[i] = irq[i]; - else - ip2config.irq[i] = 0; - /* This is a little bit of a hack. If poll_only=1 on command - line back in ip2.c OR all IRQs on all specified boards are - explicitly set to 0, then drop to poll only mode and override - PCI or EISA interrupts. This superceeds the old hack of - triggering if all interrupts were zero (like da default). - Still a hack but less prone to random acts of terrorism. - - What we really should do, now that the IRQ default is set - to -1, is to use 0 as a hard coded, do not probe. - - /\/\|=mhw=|\/\/ - */ - poll_only |= irq[i]; - } - poll_only = !poll_only; - - /* Announce our presence */ - printk(KERN_INFO "%s version %s\n", pcName, pcVersion); - - ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS); - if (!ip2_tty_driver) - return -ENOMEM; - - /* Initialise all the boards we can find (up to the maximum). */ - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - switch (ip2config.addr[i]) { - case 0: /* skip this slot even if card is present */ - break; - default: /* ISA */ - /* ISA address must be specified */ - if (ip2config.addr[i] < 0x100 || - ip2config.addr[i] > 0x3f8) { - printk(KERN_ERR "IP2: Bad ISA board %d " - "address %x\n", i, - ip2config.addr[i]); - ip2config.addr[i] = 0; - break; - } - ip2config.type[i] = ISA; - - /* Check for valid irq argument, set for polling if - * invalid */ - if (ip2config.irq[i] && - !is_valid_irq(ip2config.irq[i])) { - printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n", - ip2config.irq[i]); - /* 0 is polling and is valid in that sense */ - ip2config.irq[i] = 0; - } - break; - case PCI: -#ifdef CONFIG_PCI - { - struct pci_dev *pdev = NULL; - u32 addr; - int status; - - pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE, - PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev); - if (pdev == NULL) { - ip2config.addr[i] = 0; - printk(KERN_ERR "IP2: PCI board %d not " - "found\n", i); - break; - } - - if (pci_enable_device(pdev)) { - dev_err(&pdev->dev, "can't enable device\n"); - goto out; - } - ip2config.type[i] = PCI; - ip2config.pci_dev[i] = pci_dev_get(pdev); - status = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1, - &addr); - if (addr & 1) - ip2config.addr[i] = (USHORT)(addr & 0xfffe); - else - dev_err(&pdev->dev, "I/O address error\n"); - - ip2config.irq[i] = pdev->irq; -out: - pci_dev_put(pdev); - } -#else - printk(KERN_ERR "IP2: PCI card specified but PCI " - "support not enabled.\n"); - printk(KERN_ERR "IP2: Recompile kernel with CONFIG_PCI " - "defined!\n"); -#endif /* CONFIG_PCI */ - break; - case EISA: - ip2config.addr[i] = find_eisa_board(Eisa_slot + 1); - if (ip2config.addr[i] != 0) { - /* Eisa_irq set as side effect, boo */ - ip2config.type[i] = EISA; - } - ip2config.irq[i] = Eisa_irq; - break; - } /* switch */ - } /* for */ - - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - if (ip2config.addr[i]) { - pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL); - if (pB) { - i2BoardPtrTable[i] = pB; - iiSetAddress(pB, ip2config.addr[i], - ii2DelayTimer); - iiReset(pB); - } else - printk(KERN_ERR "IP2: board memory allocation " - "error\n"); - } - } - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - pB = i2BoardPtrTable[i]; - if (pB != NULL) { - iiResetDelay(pB); - break; - } - } - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - /* We don't want to request the firmware unless we have at - least one board */ - if (i2BoardPtrTable[i] != NULL) { - if (!fw) - fw = ip2_request_firmware(); - if (!fw) - break; - ip2_init_board(i, fw); - } - } - if (fw) - release_firmware(fw); - - ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0); - - ip2_tty_driver->owner = THIS_MODULE; - ip2_tty_driver->name = "ttyF"; - ip2_tty_driver->driver_name = pcDriver_name; - ip2_tty_driver->major = IP2_TTY_MAJOR; - ip2_tty_driver->minor_start = 0; - ip2_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; - ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; - ip2_tty_driver->init_termios = tty_std_termios; - ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; - ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(ip2_tty_driver, &ip2_ops); - - ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0); - - err = tty_register_driver(ip2_tty_driver); - if (err) { - printk(KERN_ERR "IP2: failed to register tty driver\n"); - put_tty_driver(ip2_tty_driver); - return err; /* leaking resources */ - } - - err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl); - if (err) { - printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", - err); - } else { - /* create the sysfs class */ - ip2_class = class_create(THIS_MODULE, "ip2"); - if (IS_ERR(ip2_class)) { - err = PTR_ERR(ip2_class); - goto out_chrdev; - } - } - /* Register the read_procmem thing */ - if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) { - printk(KERN_ERR "IP2: failed to register read_procmem\n"); - return -EIO; /* leaking resources */ - } - - ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0); - /* Register the interrupt handler or poll handler, depending upon the - * specified interrupt. - */ - - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - if (ip2config.addr[i] == 0) - continue; - - pB = i2BoardPtrTable[i]; - if (pB != NULL) { - device_create(ip2_class, NULL, - MKDEV(IP2_IPL_MAJOR, 4 * i), - NULL, "ipl%d", i); - device_create(ip2_class, NULL, - MKDEV(IP2_IPL_MAJOR, 4 * i + 1), - NULL, "stat%d", i); - - for (box = 0; box < ABS_MAX_BOXES; box++) - for (j = 0; j < ABS_BIGGEST_BOX; j++) - if (pB->i2eChannelMap[box] & (1 << j)) - tty_register_device( - ip2_tty_driver, - j + ABS_BIGGEST_BOX * - (box+i*ABS_MAX_BOXES), - NULL); - } - - if (poll_only) { - /* Poll only forces driver to only use polling and - to ignore the probed PCI or EISA interrupts. */ - ip2config.irq[i] = CIR_POLL; - } - if (ip2config.irq[i] == CIR_POLL) { -retry: - if (!timer_pending(&PollTimer)) { - mod_timer(&PollTimer, POLL_TIMEOUT); - printk(KERN_INFO "IP2: polling\n"); - } - } else { - if (have_requested_irq(ip2config.irq[i])) - continue; - rc = request_irq(ip2config.irq[i], ip2_interrupt, - IP2_SA_FLAGS | - (ip2config.type[i] == PCI ? IRQF_SHARED : 0), - pcName, i2BoardPtrTable[i]); - if (rc) { - printk(KERN_ERR "IP2: request_irq failed: " - "error %d\n", rc); - ip2config.irq[i] = CIR_POLL; - printk(KERN_INFO "IP2: Polling %ld/sec.\n", - (POLL_TIMEOUT - jiffies)); - goto retry; - } - mark_requested_irq(ip2config.irq[i]); - /* Initialise the interrupt handler bottom half - * (aka slih). */ - } - } - - for (i = 0; i < IP2_MAX_BOARDS; ++i) { - if (i2BoardPtrTable[i]) { - /* set and enable board interrupt */ - set_irq(i, ip2config.irq[i]); - } - } - - ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0); - - return 0; - -out_chrdev: - unregister_chrdev(IP2_IPL_MAJOR, "ip2"); - /* unregister and put tty here */ - return err; -} -module_init(ip2_loadmain); - -/******************************************************************************/ -/* Function: ip2_init_board() */ -/* Parameters: Index of board in configuration structure */ -/* Returns: Success (0) */ -/* */ -/* Description: */ -/* This function initializes the specified board. The loadware is copied to */ -/* the board, the channel structures are initialized, and the board details */ -/* are reported on the console. */ -/******************************************************************************/ -static void -ip2_init_board(int boardnum, const struct firmware *fw) -{ - int i; - int nports = 0, nboxes = 0; - i2ChanStrPtr pCh; - i2eBordStrPtr pB = i2BoardPtrTable[boardnum]; - - if ( !iiInitialize ( pB ) ) { - printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n", - pB->i2eBase, pB->i2eError ); - goto err_initialize; - } - printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1, - ip2config.addr[boardnum], ip2config.irq[boardnum] ); - - if (!request_region( ip2config.addr[boardnum], 8, pcName )) { - printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]); - goto err_initialize; - } - - if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size ) - != II_DOWN_GOOD ) { - printk ( KERN_ERR "IP2: failed to download loadware\n" ); - goto err_release_region; - } else { - printk ( KERN_INFO "IP2: fv=%d.%d.%d lv=%d.%d.%d\n", - pB->i2ePom.e.porVersion, - pB->i2ePom.e.porRevision, - pB->i2ePom.e.porSubRev, pB->i2eLVersion, - pB->i2eLRevision, pB->i2eLSub ); - } - - switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) { - - default: - printk( KERN_ERR "IP2: Unknown board type, ID = %x\n", - pB->i2ePom.e.porID ); - nports = 0; - goto err_release_region; - break; - - case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */ - printk ( KERN_INFO "IP2: ISA-4\n" ); - nports = 4; - break; - - case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */ - printk ( KERN_INFO "IP2: ISA-8 std\n" ); - nports = 8; - break; - - case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */ - printk ( KERN_INFO "IP2: ISA-8 RJ11\n" ); - nports = 8; - break; - - case POR_ID_FIIEX: /* IntelliPort IIEX */ - { - int portnum = IP2_PORTS_PER_BOARD * boardnum; - int box; - - for( box = 0; box < ABS_MAX_BOXES; ++box ) { - if ( pB->i2eChannelMap[box] != 0 ) { - ++nboxes; - } - for( i = 0; i < ABS_BIGGEST_BOX; ++i ) { - if ( pB->i2eChannelMap[box] & 1<< i ) { - ++nports; - } - } - } - DevTableMem[boardnum] = pCh = - kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL ); - if ( !pCh ) { - printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n"); - goto err_release_region; - } - if ( !i2InitChannels( pB, nports, pCh ) ) { - printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError); - kfree ( pCh ); - goto err_release_region; - } - pB->i2eChannelPtr = &DevTable[portnum]; - pB->i2eChannelCnt = ABS_MOST_PORTS; - - for( box = 0; box < ABS_MAX_BOXES; ++box, portnum += ABS_BIGGEST_BOX ) { - for( i = 0; i < ABS_BIGGEST_BOX; ++i ) { - if ( pB->i2eChannelMap[box] & (1 << i) ) { - DevTable[portnum + i] = pCh; - pCh->port_index = portnum + i; - pCh++; - } - } - } - printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n", - nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 ); - } - goto ex_exit; - } - DevTableMem[boardnum] = pCh = - kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL ); - if ( !pCh ) { - printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n"); - goto err_release_region; - } - pB->i2eChannelPtr = pCh; - pB->i2eChannelCnt = nports; - if ( !i2InitChannels( pB, nports, pCh ) ) { - printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError); - kfree ( pCh ); - goto err_release_region; - } - pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum]; - - for( i = 0; i < pB->i2eChannelCnt; ++i ) { - DevTable[IP2_PORTS_PER_BOARD * boardnum + i] = pCh; - pCh->port_index = (IP2_PORTS_PER_BOARD * boardnum) + i; - pCh++; - } -ex_exit: - INIT_WORK(&pB->tqueue_interrupt, ip2_interrupt_bh); - return; - -err_release_region: - release_region(ip2config.addr[boardnum], 8); -err_initialize: - kfree ( pB ); - i2BoardPtrTable[boardnum] = NULL; - return; -} - -/******************************************************************************/ -/* Function: find_eisa_board ( int start_slot ) */ -/* Parameters: First slot to check */ -/* Returns: Address of EISA IntelliPort II controller */ -/* */ -/* Description: */ -/* This function searches for an EISA IntelliPort controller, starting */ -/* from the specified slot number. If the motherboard is not identified as an */ -/* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */ -/* it returns the base address of the controller. */ -/******************************************************************************/ -static unsigned short -find_eisa_board( int start_slot ) -{ - int i, j; - unsigned int idm = 0; - unsigned int idp = 0; - unsigned int base = 0; - unsigned int value; - int setup_address; - int setup_irq; - int ismine = 0; - - /* - * First a check for an EISA motherboard, which we do by comparing the - * EISA ID registers for the system board and the first couple of slots. - * No slot ID should match the system board ID, but on an ISA or PCI - * machine the odds are that an empty bus will return similar values for - * each slot. - */ - i = 0x0c80; - value = (inb(i) << 24) + (inb(i+1) << 16) + (inb(i+2) << 8) + inb(i+3); - for( i = 0x1c80; i <= 0x4c80; i += 0x1000 ) { - j = (inb(i)<<24)+(inb(i+1)<<16)+(inb(i+2)<<8)+inb(i+3); - if ( value == j ) - return 0; - } - - /* - * OK, so we are inclined to believe that this is an EISA machine. Find - * an IntelliPort controller. - */ - for( i = start_slot; i < 16; i++ ) { - base = i << 12; - idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff); - idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff); - ismine = 0; - if ( idm == 0x0e8e ) { - if ( idp == 0x0281 || idp == 0x0218 ) { - ismine = 1; - } else if ( idp == 0x0282 || idp == 0x0283 ) { - ismine = 3; /* Can do edge-trigger */ - } - if ( ismine ) { - Eisa_slot = i; - break; - } - } - } - if ( !ismine ) - return 0; - - /* It's some sort of EISA card, but at what address is it configured? */ - - setup_address = base + 0xc88; - value = inb(base + 0xc86); - setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0; - - if ( (ismine & 2) && !(value & 0x10) ) { - ismine = 1; /* Could be edging, but not */ - } - - if ( Eisa_irq == 0 ) { - Eisa_irq = setup_irq; - } else if ( Eisa_irq != setup_irq ) { - printk ( KERN_ERR "IP2: EISA irq mismatch between EISA controllers\n" ); - } - -#ifdef IP2DEBUG_INIT -printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x", - base >> 12, idm, idp, setup_address); - if ( Eisa_irq ) { - printk(KERN_DEBUG ", Interrupt %d %s\n", - setup_irq, (ismine & 2) ? "(edge)" : "(level)"); - } else { - printk(KERN_DEBUG ", (polled)\n"); - } -#endif - return setup_address; -} - -/******************************************************************************/ -/* Function: set_irq() */ -/* Parameters: index to board in board table */ -/* IRQ to use */ -/* Returns: Success (0) */ -/* */ -/* Description: */ -/******************************************************************************/ -static void -set_irq( int boardnum, int boardIrq ) -{ - unsigned char tempCommand[16]; - i2eBordStrPtr pB = i2BoardPtrTable[boardnum]; - unsigned long flags; - - /* - * Notify the boards they may generate interrupts. This is done by - * sending an in-line command to channel 0 on each board. This is why - * the channels have to be defined already. For each board, if the - * interrupt has never been defined, we must do so NOW, directly, since - * board will not send flow control or even give an interrupt until this - * is done. If polling we must send 0 as the interrupt parameter. - */ - - // We will get an interrupt here at the end of this function - - iiDisableMailIrq(pB); - - /* We build up the entire packet header. */ - CHANNEL_OF(tempCommand) = 0; - PTYPE_OF(tempCommand) = PTYPE_INLINE; - CMD_COUNT_OF(tempCommand) = 2; - (CMD_OF(tempCommand))[0] = CMDVALUE_IRQ; - (CMD_OF(tempCommand))[1] = boardIrq; - /* - * Write to FIFO; don't bother to adjust fifo capacity for this, since - * board will respond almost immediately after SendMail hit. - */ - write_lock_irqsave(&pB->write_fifo_spinlock, flags); - iiWriteBuf(pB, tempCommand, 4); - write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); - pB->i2eUsingIrq = boardIrq; - pB->i2eOutMailWaiting |= MB_OUT_STUFFED; - - /* Need to update number of boards before you enable mailbox int */ - ++i2nBoards; - - CHANNEL_OF(tempCommand) = 0; - PTYPE_OF(tempCommand) = PTYPE_BYPASS; - CMD_COUNT_OF(tempCommand) = 6; - (CMD_OF(tempCommand))[0] = 88; // SILO - (CMD_OF(tempCommand))[1] = 64; // chars - (CMD_OF(tempCommand))[2] = 32; // ms - - (CMD_OF(tempCommand))[3] = 28; // MAX_BLOCK - (CMD_OF(tempCommand))[4] = 64; // chars - - (CMD_OF(tempCommand))[5] = 87; // HW_TEST - write_lock_irqsave(&pB->write_fifo_spinlock, flags); - iiWriteBuf(pB, tempCommand, 8); - write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); - - CHANNEL_OF(tempCommand) = 0; - PTYPE_OF(tempCommand) = PTYPE_BYPASS; - CMD_COUNT_OF(tempCommand) = 1; - (CMD_OF(tempCommand))[0] = 84; /* get BOX_IDS */ - iiWriteBuf(pB, tempCommand, 3); - -#ifdef XXX - // enable heartbeat for test porpoises - CHANNEL_OF(tempCommand) = 0; - PTYPE_OF(tempCommand) = PTYPE_BYPASS; - CMD_COUNT_OF(tempCommand) = 2; - (CMD_OF(tempCommand))[0] = 44; /* get ping */ - (CMD_OF(tempCommand))[1] = 200; /* 200 ms */ - write_lock_irqsave(&pB->write_fifo_spinlock, flags); - iiWriteBuf(pB, tempCommand, 4); - write_unlock_irqrestore(&pB->write_fifo_spinlock, flags); -#endif - - iiEnableMailIrq(pB); - iiSendPendingMail(pB); -} - -/******************************************************************************/ -/* Interrupt Handler Section */ -/******************************************************************************/ - -static inline void -service_all_boards(void) -{ - int i; - i2eBordStrPtr pB; - - /* Service every board on the list */ - for( i = 0; i < IP2_MAX_BOARDS; ++i ) { - pB = i2BoardPtrTable[i]; - if ( pB ) { - i2ServiceBoard( pB ); - } - } -} - - -/******************************************************************************/ -/* Function: ip2_interrupt_bh(work) */ -/* Parameters: work - pointer to the board structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* Service the board in a bottom half interrupt handler and then */ -/* reenable the board's interrupts if it has an IRQ number */ -/* */ -/******************************************************************************/ -static void -ip2_interrupt_bh(struct work_struct *work) -{ - i2eBordStrPtr pB = container_of(work, i2eBordStr, tqueue_interrupt); -// pB better well be set or we have a problem! We can only get -// here from the IMMEDIATE queue. Here, we process the boards. -// Checking pB doesn't cost much and it saves us from the sanity checkers. - - bh_counter++; - - if ( pB ) { - i2ServiceBoard( pB ); - if( pB->i2eUsingIrq ) { -// Re-enable his interrupts - iiEnableMailIrq(pB); - } - } -} - - -/******************************************************************************/ -/* Function: ip2_interrupt(int irq, void *dev_id) */ -/* Parameters: irq - interrupt number */ -/* pointer to optional device ID structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* Our task here is simply to identify each board which needs servicing. */ -/* If we are queuing then, queue it to be serviced, and disable its irq */ -/* mask otherwise process the board directly. */ -/* */ -/* We could queue by IRQ but that just complicates things on both ends */ -/* with very little gain in performance (how many instructions does */ -/* it take to iterate on the immediate queue). */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_irq_work(i2eBordStrPtr pB) -{ -#ifdef USE_IQI - if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) { -// Disable his interrupt (will be enabled when serviced) -// This is mostly to protect from reentrancy. - iiDisableMailIrq(pB); - -// Park the board on the immediate queue for processing. - schedule_work(&pB->tqueue_interrupt); - -// Make sure the immediate queue is flagged to fire. - } -#else - -// We are using immediate servicing here. This sucks and can -// cause all sorts of havoc with ppp and others. The failsafe -// check on iiSendPendingMail could also throw a hairball. - - i2ServiceBoard( pB ); - -#endif /* USE_IQI */ -} - -static void -ip2_polled_interrupt(void) -{ - int i; - i2eBordStrPtr pB; - - ip2trace(ITRC_NO_PORT, ITRC_INTR, 99, 1, 0); - - /* Service just the boards on the list using this irq */ - for( i = 0; i < i2nBoards; ++i ) { - pB = i2BoardPtrTable[i]; - -// Only process those boards which match our IRQ. -// IRQ = 0 for polled boards, we won't poll "IRQ" boards - - if (pB && pB->i2eUsingIrq == 0) - ip2_irq_work(pB); - } - - ++irq_counter; - - ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); -} - -static irqreturn_t -ip2_interrupt(int irq, void *dev_id) -{ - i2eBordStrPtr pB = dev_id; - - ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, pB->i2eUsingIrq ); - - ip2_irq_work(pB); - - ++irq_counter; - - ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); - return IRQ_HANDLED; -} - -/******************************************************************************/ -/* Function: ip2_poll(unsigned long arg) */ -/* Parameters: ? */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* This function calls the library routine i2ServiceBoard for each board in */ -/* the board table. This is used instead of the interrupt routine when polled */ -/* mode is specified. */ -/******************************************************************************/ -static void -ip2_poll(unsigned long arg) -{ - ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 ); - - // Just polled boards, IRQ = 0 will hit all non-interrupt boards. - // It will NOT poll boards handled by hard interrupts. - // The issue of queued BH interrupts is handled in ip2_interrupt(). - ip2_polled_interrupt(); - - mod_timer(&PollTimer, POLL_TIMEOUT); - - ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); -} - -static void do_input(struct work_struct *work) -{ - i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_input); - unsigned long flags; - - ip2trace(CHANN, ITRC_INPUT, 21, 0 ); - - // Data input - if ( pCh->pTTY != NULL ) { - read_lock_irqsave(&pCh->Ibuf_spinlock, flags); - if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) { - read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - i2Input( pCh ); - } else - read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); - } else { - ip2trace(CHANN, ITRC_INPUT, 22, 0 ); - - i2InputFlush( pCh ); - } -} - -// code duplicated from n_tty (ldisc) -static inline void isig(int sig, struct tty_struct *tty, int flush) -{ - /* FIXME: This is completely bogus */ - if (tty->pgrp) - kill_pgrp(tty->pgrp, sig, 1); - if (flush || !L_NOFLSH(tty)) { - if ( tty->ldisc->ops->flush_buffer ) - tty->ldisc->ops->flush_buffer(tty); - i2InputFlush( tty->driver_data ); - } -} - -static void do_status(struct work_struct *work) -{ - i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_status); - int status; - - status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) ); - - ip2trace (CHANN, ITRC_STATUS, 21, 1, status ); - - if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) { - if ( (status & I2_BRK) ) { - // code duplicated from n_tty (ldisc) - if (I_IGNBRK(pCh->pTTY)) - goto skip_this; - if (I_BRKINT(pCh->pTTY)) { - isig(SIGINT, pCh->pTTY, 1); - goto skip_this; - } - wake_up_interruptible(&pCh->pTTY->read_wait); - } -#ifdef NEVER_HAPPENS_AS_SETUP_XXX - // and can't work because we don't know the_char - // as the_char is reported on a separate path - // The intelligent board does this stuff as setup - { - char brkf = TTY_NORMAL; - unsigned char brkc = '\0'; - unsigned char tmp; - if ( (status & I2_BRK) ) { - brkf = TTY_BREAK; - brkc = '\0'; - } - else if (status & I2_PAR) { - brkf = TTY_PARITY; - brkc = the_char; - } else if (status & I2_FRA) { - brkf = TTY_FRAME; - brkc = the_char; - } else if (status & I2_OVR) { - brkf = TTY_OVERRUN; - brkc = the_char; - } - tmp = pCh->pTTY->real_raw; - pCh->pTTY->real_raw = 0; - pCh->pTTY->ldisc->ops.receive_buf( pCh->pTTY, &brkc, &brkf, 1 ); - pCh->pTTY->real_raw = tmp; - } -#endif /* NEVER_HAPPENS_AS_SETUP_XXX */ - } -skip_this: - - if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) { - wake_up_interruptible(&pCh->delta_msr_wait); - - if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) { - if ( status & I2_DCD ) { - if ( pCh->wopen ) { - wake_up_interruptible ( &pCh->open_wait ); - } - } else { - if (pCh->pTTY && (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) { - tty_hangup( pCh->pTTY ); - } - } - } - } - - ip2trace (CHANN, ITRC_STATUS, 26, 0 ); -} - -/******************************************************************************/ -/* Device Open/Close/Ioctl Entry Point Section */ -/******************************************************************************/ - -/******************************************************************************/ -/* Function: open_sanity_check() */ -/* Parameters: Pointer to tty structure */ -/* Pointer to file structure */ -/* Returns: Success or failure */ -/* */ -/* Description: */ -/* Verifies the structure magic numbers and cross links. */ -/******************************************************************************/ -#ifdef IP2DEBUG_OPEN -static void -open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd ) -{ - if ( pBrd->i2eValid != I2E_MAGIC ) { - printk(KERN_ERR "IP2: invalid board structure\n" ); - } else if ( pBrd != pCh->pMyBord ) { - printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n", - pCh->pMyBord ); - } else if ( pBrd->i2eChannelCnt < pCh->port_index ) { - printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index ); - } else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) { - } else { - printk(KERN_INFO "IP2: all pointers check out!\n" ); - } -} -#endif - - -/******************************************************************************/ -/* Function: ip2_open() */ -/* Parameters: Pointer to tty structure */ -/* Pointer to file structure */ -/* Returns: Success or failure */ -/* */ -/* Description: (MANDATORY) */ -/* A successful device open has to run a gauntlet of checks before it */ -/* completes. After some sanity checking and pointer setup, the function */ -/* blocks until all conditions are satisfied. It then initialises the port to */ -/* the default characteristics and returns. */ -/******************************************************************************/ -static int -ip2_open( PTTY tty, struct file *pFile ) -{ - wait_queue_t wait; - int rc = 0; - int do_clocal = 0; - i2ChanStrPtr pCh = DevTable[tty->index]; - - ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 ); - - if ( pCh == NULL ) { - return -ENODEV; - } - /* Setup pointer links in device and tty structures */ - pCh->pTTY = tty; - tty->driver_data = pCh; - -#ifdef IP2DEBUG_OPEN - printk(KERN_DEBUG \ - "IP2:open(tty=%p,pFile=%p):dev=%s,ch=%d,idx=%d\n", - tty, pFile, tty->name, pCh->infl.hd.i2sChannel, pCh->port_index); - open_sanity_check ( pCh, pCh->pMyBord ); -#endif - - i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP); - pCh->dataSetOut |= (I2_DTR | I2_RTS); - serviceOutgoingFifo( pCh->pMyBord ); - - /* Block here until the port is ready (per serial and istallion) */ - /* - * 1. If the port is in the middle of closing wait for the completion - * and then return the appropriate error. - */ - init_waitqueue_entry(&wait, current); - add_wait_queue(&pCh->close_wait, &wait); - set_current_state( TASK_INTERRUPTIBLE ); - - if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) { - if ( pCh->flags & ASYNC_CLOSING ) { - tty_unlock(); - schedule(); - tty_lock(); - } - if ( tty_hung_up_p(pFile) ) { - set_current_state( TASK_RUNNING ); - remove_wait_queue(&pCh->close_wait, &wait); - return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS; - } - } - set_current_state( TASK_RUNNING ); - remove_wait_queue(&pCh->close_wait, &wait); - - /* - * 3. Handle a non-blocking open of a normal port. - */ - if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<flags |= ASYNC_NORMAL_ACTIVE; - goto noblock; - } - /* - * 4. Now loop waiting for the port to be free and carrier present - * (if required). - */ - if ( tty->termios->c_cflag & CLOCAL ) - do_clocal = 1; - -#ifdef IP2DEBUG_OPEN - printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal); -#endif - - ++pCh->wopen; - - init_waitqueue_entry(&wait, current); - add_wait_queue(&pCh->open_wait, &wait); - - for(;;) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP); - pCh->dataSetOut |= (I2_DTR | I2_RTS); - set_current_state( TASK_INTERRUPTIBLE ); - serviceOutgoingFifo( pCh->pMyBord ); - if ( tty_hung_up_p(pFile) ) { - set_current_state( TASK_RUNNING ); - remove_wait_queue(&pCh->open_wait, &wait); - return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS; - } - if (!(pCh->flags & ASYNC_CLOSING) && - (do_clocal || (pCh->dataSetIn & I2_DCD) )) { - rc = 0; - break; - } - -#ifdef IP2DEBUG_OPEN - printk(KERN_DEBUG "ASYNC_CLOSING = %s\n", - (pCh->flags & ASYNC_CLOSING)?"True":"False"); - printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n"); -#endif - ip2trace (CHANN, ITRC_OPEN, 3, 2, 0, - (pCh->flags & ASYNC_CLOSING) ); - /* check for signal */ - if (signal_pending(current)) { - rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS); - break; - } - tty_unlock(); - schedule(); - tty_lock(); - } - set_current_state( TASK_RUNNING ); - remove_wait_queue(&pCh->open_wait, &wait); - - --pCh->wopen; //why count? - - ip2trace (CHANN, ITRC_OPEN, 4, 0 ); - - if (rc != 0 ) { - return rc; - } - pCh->flags |= ASYNC_NORMAL_ACTIVE; - -noblock: - - /* first open - Assign termios structure to port */ - if ( tty->count == 1 ) { - i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB); - /* Now we must send the termios settings to the loadware */ - set_params( pCh, NULL ); - } - - /* - * Now set any i2lib options. These may go away if the i2lib code ends - * up rolled into the mainline. - */ - pCh->channelOptions |= CO_NBLOCK_WRITE; - -#ifdef IP2DEBUG_OPEN - printk (KERN_DEBUG "IP2: open completed\n" ); -#endif - serviceOutgoingFifo( pCh->pMyBord ); - - ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 ); - - return 0; -} - -/******************************************************************************/ -/* Function: ip2_close() */ -/* Parameters: Pointer to tty structure */ -/* Pointer to file structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_close( PTTY tty, struct file *pFile ) -{ - i2ChanStrPtr pCh = tty->driver_data; - - if ( !pCh ) { - return; - } - - ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 ); - -#ifdef IP2DEBUG_OPEN - printk(KERN_DEBUG "IP2:close %s:\n",tty->name); -#endif - - if ( tty_hung_up_p ( pFile ) ) { - - ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 ); - - return; - } - if ( tty->count > 1 ) { /* not the last close */ - - ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 ); - - return; - } - pCh->flags |= ASYNC_CLOSING; // last close actually - - tty->closing = 1; - - if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) { - /* - * Before we drop DTR, make sure the transmitter has completely drained. - * This uses an timeout, after which the close - * completes. - */ - ip2_wait_until_sent(tty, pCh->ClosingWaitTime ); - } - /* - * At this point we stop accepting input. Here we flush the channel - * input buffer which will allow the board to send up more data. Any - * additional input is tossed at interrupt/poll time. - */ - i2InputFlush( pCh ); - - /* disable DSS reporting */ - i2QueueCommands(PTYPE_INLINE, pCh, 100, 4, - CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); - if (tty->termios->c_cflag & HUPCL) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); - pCh->dataSetOut &= ~(I2_DTR | I2_RTS); - i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); - } - - serviceOutgoingFifo ( pCh->pMyBord ); - - tty_ldisc_flush(tty); - tty_driver_flush_buffer(tty); - tty->closing = 0; - - pCh->pTTY = NULL; - - if (pCh->wopen) { - if (pCh->ClosingDelay) { - msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay)); - } - wake_up_interruptible(&pCh->open_wait); - } - - pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&pCh->close_wait); - -#ifdef IP2DEBUG_OPEN - DBG_CNT("ip2_close: after wakeups--"); -#endif - - - ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 ); - - return; -} - -/******************************************************************************/ -/* Function: ip2_hangup() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_hangup ( PTTY tty ) -{ - i2ChanStrPtr pCh = tty->driver_data; - - if( !pCh ) { - return; - } - - ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 ); - - ip2_flush_buffer(tty); - - /* disable DSS reporting */ - - i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP); - i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB); - if ( (tty->termios->c_cflag & HUPCL) ) { - i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN); - pCh->dataSetOut &= ~(I2_DTR | I2_RTS); - i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); - } - i2QueueCommands(PTYPE_INLINE, pCh, 1, 3, - CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); - serviceOutgoingFifo ( pCh->pMyBord ); - - wake_up_interruptible ( &pCh->delta_msr_wait ); - - pCh->flags &= ~ASYNC_NORMAL_ACTIVE; - pCh->pTTY = NULL; - wake_up_interruptible ( &pCh->open_wait ); - - ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 ); -} - -/******************************************************************************/ -/******************************************************************************/ -/* Device Output Section */ -/******************************************************************************/ -/******************************************************************************/ - -/******************************************************************************/ -/* Function: ip2_write() */ -/* Parameters: Pointer to tty structure */ -/* Flag denoting data is in user (1) or kernel (0) space */ -/* Pointer to data */ -/* Number of bytes to write */ -/* Returns: Number of bytes actually written */ -/* */ -/* Description: (MANDATORY) */ -/* */ -/* */ -/******************************************************************************/ -static int -ip2_write( PTTY tty, const unsigned char *pData, int count) -{ - i2ChanStrPtr pCh = tty->driver_data; - int bytesSent = 0; - unsigned long flags; - - ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 ); - - /* Flush out any buffered data left over from ip2_putchar() calls. */ - ip2_flush_chars( tty ); - - /* This is the actual move bit. Make sure it does what we need!!!!! */ - write_lock_irqsave(&pCh->Pbuf_spinlock, flags); - bytesSent = i2Output( pCh, pData, count); - write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); - - ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent ); - - return bytesSent > 0 ? bytesSent : 0; -} - -/******************************************************************************/ -/* Function: ip2_putchar() */ -/* Parameters: Pointer to tty structure */ -/* Character to write */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static int -ip2_putchar( PTTY tty, unsigned char ch ) -{ - i2ChanStrPtr pCh = tty->driver_data; - unsigned long flags; - -// ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch ); - - write_lock_irqsave(&pCh->Pbuf_spinlock, flags); - pCh->Pbuf[pCh->Pbuf_stuff++] = ch; - if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) { - write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); - ip2_flush_chars( tty ); - } else - write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); - return 1; - -// ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch ); -} - -/******************************************************************************/ -/* Function: ip2_flush_chars() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/******************************************************************************/ -static void -ip2_flush_chars( PTTY tty ) -{ - int strip; - i2ChanStrPtr pCh = tty->driver_data; - unsigned long flags; - - write_lock_irqsave(&pCh->Pbuf_spinlock, flags); - if ( pCh->Pbuf_stuff ) { - -// ip2trace (CHANN, ITRC_PUTC, 10, 1, strip ); - - // - // We may need to restart i2Output if it does not fulfill this request - // - strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff); - if ( strip != pCh->Pbuf_stuff ) { - memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip ); - } - pCh->Pbuf_stuff -= strip; - } - write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); -} - -/******************************************************************************/ -/* Function: ip2_write_room() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Number of bytes that the driver can accept */ -/* */ -/* Description: */ -/* */ -/******************************************************************************/ -static int -ip2_write_room ( PTTY tty ) -{ - int bytesFree; - i2ChanStrPtr pCh = tty->driver_data; - unsigned long flags; - - read_lock_irqsave(&pCh->Pbuf_spinlock, flags); - bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff; - read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); - - ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree ); - - return ((bytesFree > 0) ? bytesFree : 0); -} - -/******************************************************************************/ -/* Function: ip2_chars_in_buf() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Number of bytes queued for transmission */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static int -ip2_chars_in_buf ( PTTY tty ) -{ - i2ChanStrPtr pCh = tty->driver_data; - int rc; - unsigned long flags; - - ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff ); - -#ifdef IP2DEBUG_WRITE - printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n", - pCh->Obuf_char_count + pCh->Pbuf_stuff, - pCh->Obuf_char_count, pCh->Pbuf_stuff ); -#endif - read_lock_irqsave(&pCh->Obuf_spinlock, flags); - rc = pCh->Obuf_char_count; - read_unlock_irqrestore(&pCh->Obuf_spinlock, flags); - read_lock_irqsave(&pCh->Pbuf_spinlock, flags); - rc += pCh->Pbuf_stuff; - read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); - return rc; -} - -/******************************************************************************/ -/* Function: ip2_flush_buffer() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_flush_buffer( PTTY tty ) -{ - i2ChanStrPtr pCh = tty->driver_data; - unsigned long flags; - - ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 ); - -#ifdef IP2DEBUG_WRITE - printk (KERN_DEBUG "IP2: flush buffer\n" ); -#endif - write_lock_irqsave(&pCh->Pbuf_spinlock, flags); - pCh->Pbuf_stuff = 0; - write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags); - i2FlushOutput( pCh ); - ip2_owake(tty); - - ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 ); - -} - -/******************************************************************************/ -/* Function: ip2_wait_until_sent() */ -/* Parameters: Pointer to tty structure */ -/* Timeout for wait. */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* This function is used in place of the normal tty_wait_until_sent, which */ -/* only waits for the driver buffers to be empty (or rather, those buffers */ -/* reported by chars_in_buffer) which doesn't work for IP2 due to the */ -/* indeterminate number of bytes buffered on the board. */ -/******************************************************************************/ -static void -ip2_wait_until_sent ( PTTY tty, int timeout ) -{ - int i = jiffies; - i2ChanStrPtr pCh = tty->driver_data; - - tty_wait_until_sent(tty, timeout ); - if ( (i = timeout - (jiffies -i)) > 0) - i2DrainOutput( pCh, i ); -} - -/******************************************************************************/ -/******************************************************************************/ -/* Device Input Section */ -/******************************************************************************/ -/******************************************************************************/ - -/******************************************************************************/ -/* Function: ip2_throttle() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_throttle ( PTTY tty ) -{ - i2ChanStrPtr pCh = tty->driver_data; - -#ifdef IP2DEBUG_READ - printk (KERN_DEBUG "IP2: throttle\n" ); -#endif - /* - * Signal the poll/interrupt handlers not to forward incoming data to - * the line discipline. This will cause the buffers to fill up in the - * library and thus cause the library routines to send the flow control - * stuff. - */ - pCh->throttled = 1; -} - -/******************************************************************************/ -/* Function: ip2_unthrottle() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_unthrottle ( PTTY tty ) -{ - i2ChanStrPtr pCh = tty->driver_data; - unsigned long flags; - -#ifdef IP2DEBUG_READ - printk (KERN_DEBUG "IP2: unthrottle\n" ); -#endif - - /* Pass incoming data up to the line discipline again. */ - pCh->throttled = 0; - i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME); - serviceOutgoingFifo( pCh->pMyBord ); - read_lock_irqsave(&pCh->Ibuf_spinlock, flags); - if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) { - read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); -#ifdef IP2DEBUG_READ - printk (KERN_DEBUG "i2Input called from unthrottle\n" ); -#endif - i2Input( pCh ); - } else - read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags); -} - -static void -ip2_start ( PTTY tty ) -{ - i2ChanStrPtr pCh = DevTable[tty->index]; - - i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME); - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND); - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME); -#ifdef IP2DEBUG_WRITE - printk (KERN_DEBUG "IP2: start tx\n" ); -#endif -} - -static void -ip2_stop ( PTTY tty ) -{ - i2ChanStrPtr pCh = DevTable[tty->index]; - - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND); -#ifdef IP2DEBUG_WRITE - printk (KERN_DEBUG "IP2: stop tx\n" ); -#endif -} - -/******************************************************************************/ -/* Device Ioctl Section */ -/******************************************************************************/ - -static int ip2_tiocmget(struct tty_struct *tty) -{ - i2ChanStrPtr pCh = DevTable[tty->index]; -#ifdef ENABLE_DSSNOW - wait_queue_t wait; -#endif - - if (pCh == NULL) - return -ENODEV; - -/* - FIXME - the following code is causing a NULL pointer dereference in - 2.3.51 in an interrupt handler. It's suppose to prompt the board - to return the DSS signal status immediately. Why doesn't it do - the same thing in 2.2.14? -*/ - -/* This thing is still busted in the 1.2.12 driver on 2.4.x - and even hoses the serial console so the oops can be trapped. - /\/\|=mhw=|\/\/ */ - -#ifdef ENABLE_DSSNOW - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW); - - init_waitqueue_entry(&wait, current); - add_wait_queue(&pCh->dss_now_wait, &wait); - set_current_state( TASK_INTERRUPTIBLE ); - - serviceOutgoingFifo( pCh->pMyBord ); - - schedule(); - - set_current_state( TASK_RUNNING ); - remove_wait_queue(&pCh->dss_now_wait, &wait); - - if (signal_pending(current)) { - return -EINTR; - } -#endif - return ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0) - | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0) - | ((pCh->dataSetIn & I2_DCD) ? TIOCM_CAR : 0) - | ((pCh->dataSetIn & I2_RI) ? TIOCM_RNG : 0) - | ((pCh->dataSetIn & I2_DSR) ? TIOCM_DSR : 0) - | ((pCh->dataSetIn & I2_CTS) ? TIOCM_CTS : 0); -} - -static int ip2_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - i2ChanStrPtr pCh = DevTable[tty->index]; - - if (pCh == NULL) - return -ENODEV; - - if (set & TIOCM_RTS) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP); - pCh->dataSetOut |= I2_RTS; - } - if (set & TIOCM_DTR) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP); - pCh->dataSetOut |= I2_DTR; - } - - if (clear & TIOCM_RTS) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN); - pCh->dataSetOut &= ~I2_RTS; - } - if (clear & TIOCM_DTR) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN); - pCh->dataSetOut &= ~I2_DTR; - } - serviceOutgoingFifo( pCh->pMyBord ); - return 0; -} - -/******************************************************************************/ -/* Function: ip2_ioctl() */ -/* Parameters: Pointer to tty structure */ -/* Pointer to file structure */ -/* Command */ -/* Argument */ -/* Returns: Success or failure */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static int -ip2_ioctl ( PTTY tty, UINT cmd, ULONG arg ) -{ - wait_queue_t wait; - i2ChanStrPtr pCh = DevTable[tty->index]; - i2eBordStrPtr pB; - struct async_icount cprev, cnow; /* kernel counter temps */ - int rc = 0; - unsigned long flags; - void __user *argp = (void __user *)arg; - - if ( pCh == NULL ) - return -ENODEV; - - pB = pCh->pMyBord; - - ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg ); - -#ifdef IP2DEBUG_IOCTL - printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg ); -#endif - - switch(cmd) { - case TIOCGSERIAL: - - ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc ); - - rc = get_serial_info(pCh, argp); - if (rc) - return rc; - break; - - case TIOCSSERIAL: - - ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc ); - - rc = set_serial_info(pCh, argp); - if (rc) - return rc; - break; - - case TCXONC: - rc = tty_check_change(tty); - if (rc) - return rc; - switch (arg) { - case TCOOFF: - //return -ENOIOCTLCMD; - break; - case TCOON: - //return -ENOIOCTLCMD; - break; - case TCIOFF: - if (STOP_CHAR(tty) != __DISABLED_CHAR) { - i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1, - CMD_XMIT_NOW(STOP_CHAR(tty))); - } - break; - case TCION: - if (START_CHAR(tty) != __DISABLED_CHAR) { - i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1, - CMD_XMIT_NOW(START_CHAR(tty))); - } - break; - default: - return -EINVAL; - } - return 0; - - case TCSBRK: /* SVID version: non-zero arg --> no break */ - rc = tty_check_change(tty); - - ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc ); - - if (!rc) { - ip2_wait_until_sent(tty,0); - if (!arg) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250)); - serviceOutgoingFifo( pCh->pMyBord ); - } - } - break; - - case TCSBRKP: /* support for POSIX tcsendbreak() */ - rc = tty_check_change(tty); - - ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc ); - - if (!rc) { - ip2_wait_until_sent(tty,0); - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, - CMD_SEND_BRK(arg ? arg*100 : 250)); - serviceOutgoingFifo ( pCh->pMyBord ); - } - break; - - case TIOCGSOFTCAR: - - ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc ); - - rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp); - if (rc) - return rc; - break; - - case TIOCSSOFTCAR: - - ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc ); - - rc = get_user(arg,(unsigned long __user *) argp); - if (rc) - return rc; - tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) - | (arg ? CLOCAL : 0)); - - break; - - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask - * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS - * for masking). Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - write_lock_irqsave(&pB->read_fifo_spinlock, flags); - cprev = pCh->icount; /* note the counters on entry */ - write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4, - CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP); - init_waitqueue_entry(&wait, current); - add_wait_queue(&pCh->delta_msr_wait, &wait); - set_current_state( TASK_INTERRUPTIBLE ); - - serviceOutgoingFifo( pCh->pMyBord ); - for(;;) { - ip2trace (CHANN, ITRC_IOCTL, 10, 0 ); - - schedule(); - - ip2trace (CHANN, ITRC_IOCTL, 11, 0 ); - - /* see if a signal did it */ - if (signal_pending(current)) { - rc = -ERESTARTSYS; - break; - } - write_lock_irqsave(&pB->read_fifo_spinlock, flags); - cnow = pCh->icount; /* atomic copy */ - write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { - rc = -EIO; /* no change => rc */ - break; - } - if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { - rc = 0; - break; - } - cprev = cnow; - } - set_current_state( TASK_RUNNING ); - remove_wait_queue(&pCh->delta_msr_wait, &wait); - - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3, - CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); - if ( ! (pCh->flags & ASYNC_CHECK_CD)) { - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP); - } - serviceOutgoingFifo( pCh->pMyBord ); - return rc; - break; - - /* - * The rest are not supported by this driver. By returning -ENOIOCTLCMD they - * will be passed to the line discipline for it to handle. - */ - case TIOCSERCONFIG: - case TIOCSERGWILD: - case TIOCSERGETLSR: - case TIOCSERSWILD: - case TIOCSERGSTRUCT: - case TIOCSERGETMULTI: - case TIOCSERSETMULTI: - - default: - ip2trace (CHANN, ITRC_IOCTL, 12, 0 ); - - rc = -ENOIOCTLCMD; - break; - } - - ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 ); - - return rc; -} - -static int ip2_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - i2ChanStrPtr pCh = DevTable[tty->index]; - i2eBordStrPtr pB; - struct async_icount cnow; /* kernel counter temp */ - unsigned long flags; - - if ( pCh == NULL ) - return -ENODEV; - - pB = pCh->pMyBord; - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for RI where - * only 0->1 is counted. The controller is quite capable of counting - * both, but this done to preserve compatibility with the standard - * serial driver. - */ - - write_lock_irqsave(&pB->read_fifo_spinlock, flags); - cnow = pCh->icount; - write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); - - icount->cts = cnow.cts; - icount->dsr = cnow.dsr; - icount->rng = cnow.rng; - icount->dcd = cnow.dcd; - icount->rx = cnow.rx; - icount->tx = cnow.tx; - icount->frame = cnow.frame; - icount->overrun = cnow.overrun; - icount->parity = cnow.parity; - icount->brk = cnow.brk; - icount->buf_overrun = cnow.buf_overrun; - return 0; -} - -/******************************************************************************/ -/* Function: GetSerialInfo() */ -/* Parameters: Pointer to channel structure */ -/* Pointer to old termios structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* This is to support the setserial command, and requires processing of the */ -/* standard Linux serial structure. */ -/******************************************************************************/ -static int -get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo ) -{ - struct serial_struct tmp; - - memset ( &tmp, 0, sizeof(tmp) ); - tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16]; - if (BID_HAS_654(tmp.type)) { - tmp.type = PORT_16650; - } else { - tmp.type = PORT_CIRRUS; - } - tmp.line = pCh->port_index; - tmp.port = pCh->pMyBord->i2eBase; - tmp.irq = ip2config.irq[pCh->port_index/64]; - tmp.flags = pCh->flags; - tmp.baud_base = pCh->BaudBase; - tmp.close_delay = pCh->ClosingDelay; - tmp.closing_wait = pCh->ClosingWaitTime; - tmp.custom_divisor = pCh->BaudDivisor; - return copy_to_user(retinfo,&tmp,sizeof(*retinfo)); -} - -/******************************************************************************/ -/* Function: SetSerialInfo() */ -/* Parameters: Pointer to channel structure */ -/* Pointer to old termios structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* This function provides support for setserial, which uses the TIOCSSERIAL */ -/* ioctl. Not all setserial parameters are relevant. If the user attempts to */ -/* change the IRQ, address or type of the port the ioctl fails. */ -/******************************************************************************/ -static int -set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info ) -{ - struct serial_struct ns; - int old_flags, old_baud_divisor; - - if (copy_from_user(&ns, new_info, sizeof (ns))) - return -EFAULT; - - /* - * We don't allow setserial to change IRQ, board address, type or baud - * base. Also line nunber as such is meaningless but we use it for our - * array index so it is fixed also. - */ - if ( (ns.irq != ip2config.irq[pCh->port_index]) - || ((int) ns.port != ((int) (pCh->pMyBord->i2eBase))) - || (ns.baud_base != pCh->BaudBase) - || (ns.line != pCh->port_index) ) { - return -EINVAL; - } - - old_flags = pCh->flags; - old_baud_divisor = pCh->BaudDivisor; - - if ( !capable(CAP_SYS_ADMIN) ) { - if ( ( ns.close_delay != pCh->ClosingDelay ) || - ( (ns.flags & ~ASYNC_USR_MASK) != - (pCh->flags & ~ASYNC_USR_MASK) ) ) { - return -EPERM; - } - - pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) | - (ns.flags & ASYNC_USR_MASK); - pCh->BaudDivisor = ns.custom_divisor; - } else { - pCh->flags = (pCh->flags & ~ASYNC_FLAGS) | - (ns.flags & ASYNC_FLAGS); - pCh->BaudDivisor = ns.custom_divisor; - pCh->ClosingDelay = ns.close_delay * HZ/100; - pCh->ClosingWaitTime = ns.closing_wait * HZ/100; - } - - if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) ) - || (old_baud_divisor != pCh->BaudDivisor) ) { - // Invalidate speed and reset parameters - set_params( pCh, NULL ); - } - - return 0; -} - -/******************************************************************************/ -/* Function: ip2_set_termios() */ -/* Parameters: Pointer to tty structure */ -/* Pointer to old termios structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_set_termios( PTTY tty, struct ktermios *old_termios ) -{ - i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data; - -#ifdef IP2DEBUG_IOCTL - printk (KERN_DEBUG "IP2: set termios %p\n", old_termios ); -#endif - - set_params( pCh, old_termios ); -} - -/******************************************************************************/ -/* Function: ip2_set_line_discipline() */ -/* Parameters: Pointer to tty structure */ -/* Returns: Nothing */ -/* */ -/* Description: Does nothing */ -/* */ -/* */ -/******************************************************************************/ -static void -ip2_set_line_discipline ( PTTY tty ) -{ -#ifdef IP2DEBUG_IOCTL - printk (KERN_DEBUG "IP2: set line discipline\n" ); -#endif - - ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 ); - -} - -/******************************************************************************/ -/* Function: SetLine Characteristics() */ -/* Parameters: Pointer to channel structure */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* This routine is called to update the channel structure with the new line */ -/* characteristics, and send the appropriate commands to the board when they */ -/* change. */ -/******************************************************************************/ -static void -set_params( i2ChanStrPtr pCh, struct ktermios *o_tios ) -{ - tcflag_t cflag, iflag, lflag; - char stop_char, start_char; - struct ktermios dummy; - - lflag = pCh->pTTY->termios->c_lflag; - cflag = pCh->pTTY->termios->c_cflag; - iflag = pCh->pTTY->termios->c_iflag; - - if (o_tios == NULL) { - dummy.c_lflag = ~lflag; - dummy.c_cflag = ~cflag; - dummy.c_iflag = ~iflag; - o_tios = &dummy; - } - - { - switch ( cflag & CBAUD ) { - case B0: - i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); - pCh->dataSetOut &= ~(I2_DTR | I2_RTS); - i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); - pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag); - goto service_it; - break; - case B38400: - /* - * This is the speed that is overloaded with all the other high - * speeds, depending upon the flag settings. - */ - if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) { - pCh->speed = CBR_57600; - } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) { - pCh->speed = CBR_115200; - } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) { - pCh->speed = CBR_C1; - } else { - pCh->speed = CBR_38400; - } - break; - case B50: pCh->speed = CBR_50; break; - case B75: pCh->speed = CBR_75; break; - case B110: pCh->speed = CBR_110; break; - case B134: pCh->speed = CBR_134; break; - case B150: pCh->speed = CBR_150; break; - case B200: pCh->speed = CBR_200; break; - case B300: pCh->speed = CBR_300; break; - case B600: pCh->speed = CBR_600; break; - case B1200: pCh->speed = CBR_1200; break; - case B1800: pCh->speed = CBR_1800; break; - case B2400: pCh->speed = CBR_2400; break; - case B4800: pCh->speed = CBR_4800; break; - case B9600: pCh->speed = CBR_9600; break; - case B19200: pCh->speed = CBR_19200; break; - case B57600: pCh->speed = CBR_57600; break; - case B115200: pCh->speed = CBR_115200; break; - case B153600: pCh->speed = CBR_153600; break; - case B230400: pCh->speed = CBR_230400; break; - case B307200: pCh->speed = CBR_307200; break; - case B460800: pCh->speed = CBR_460800; break; - case B921600: pCh->speed = CBR_921600; break; - default: pCh->speed = CBR_9600; break; - } - if ( pCh->speed == CBR_C1 ) { - // Process the custom speed parameters. - int bps = pCh->BaudBase / pCh->BaudDivisor; - if ( bps == 921600 ) { - pCh->speed = CBR_921600; - } else { - bps = bps/10; - i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) ); - } - } - i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed)); - - i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP); - pCh->dataSetOut |= (I2_DTR | I2_RTS); - } - if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag)) - { - i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, - CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1)); - } - if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag)) - { - i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, - CMD_SETPAR( - (cflag & PARENB ? (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP) - ) - ); - } - /* byte size and parity */ - if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag)) - { - int datasize; - switch ( cflag & CSIZE ) { - case CS5: datasize = CSZ_5; break; - case CS6: datasize = CSZ_6; break; - case CS7: datasize = CSZ_7; break; - case CS8: datasize = CSZ_8; break; - default: datasize = CSZ_5; break; /* as per serial.c */ - } - i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) ); - } - /* Process CTS flow control flag setting */ - if ( (cflag & CRTSCTS) ) { - i2QueueCommands(PTYPE_INLINE, pCh, 100, - 2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB); - } else { - i2QueueCommands(PTYPE_INLINE, pCh, 100, - 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB); - } - // - // Process XON/XOFF flow control flags settings - // - stop_char = STOP_CHAR(pCh->pTTY); - start_char = START_CHAR(pCh->pTTY); - - //////////// can't be \000 - if (stop_char == __DISABLED_CHAR ) - { - stop_char = ~__DISABLED_CHAR; - } - if (start_char == __DISABLED_CHAR ) - { - start_char = ~__DISABLED_CHAR; - } - ///////////////////////////////// - - if ( o_tios->c_cc[VSTART] != start_char ) - { - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char)); - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char)); - } - if ( o_tios->c_cc[VSTOP] != stop_char ) - { - i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char)); - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char)); - } - if (stop_char == __DISABLED_CHAR ) - { - stop_char = ~__DISABLED_CHAR; //TEST123 - goto no_xoff; - } - if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF))) - { - if ( iflag & IXOFF ) { // Enable XOFF output flow control - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON)); - } else { // Disable XOFF output flow control -no_xoff: - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE)); - } - } - if (start_char == __DISABLED_CHAR ) - { - goto no_xon; - } - if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY))) - { - if ( iflag & IXON ) { - if ( iflag & IXANY ) { // Enable XON/XANY output flow control - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY)); - } else { // Enable XON output flow control - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON)); - } - } else { // Disable XON output flow control -no_xon: - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE)); - } - } - if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) ) - { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, - CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0))); - } - if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) ) - { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, - CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB)); - } - - if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) - ^ ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) ) - { - char brkrpt = 0; - char parrpt = 0; - - if ( iflag & IGNBRK ) { /* Ignore breaks altogether */ - /* Ignore breaks altogether */ - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP); - } else { - if ( iflag & BRKINT ) { - if ( iflag & PARMRK ) { - brkrpt = 0x0a; // exception an inline triple - } else { - brkrpt = 0x1a; // exception and NULL - } - brkrpt |= 0x04; // flush input - } else { - if ( iflag & PARMRK ) { - brkrpt = 0x0b; //POSIX triple \0377 \0 \0 - } else { - brkrpt = 0x01; // Null only - } - } - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt)); - } - - if (iflag & IGNPAR) { - parrpt = 0x20; - /* would be 2 for not cirrus bug */ - /* would be 0x20 cept for cirrus bug */ - } else { - if ( iflag & PARMRK ) { - /* - * Replace error characters with 3-byte sequence (\0377,\0,char) - */ - parrpt = 0x04 ; - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0)); - } else { - parrpt = 0x03; - } - } - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt)); - } - if (cflag & CLOCAL) { - // Status reporting fails for DCD if this is off - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP); - pCh->flags &= ~ASYNC_CHECK_CD; - } else { - i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP); - pCh->flags |= ASYNC_CHECK_CD; - } - -service_it: - i2DrainOutput( pCh, 100 ); -} - -/******************************************************************************/ -/* IPL Device Section */ -/******************************************************************************/ - -/******************************************************************************/ -/* Function: ip2_ipl_read() */ -/* Parameters: Pointer to device inode */ -/* Pointer to file structure */ -/* Pointer to data */ -/* Number of bytes to read */ -/* Returns: Success or failure */ -/* */ -/* Description: Ugly */ -/* */ -/* */ -/******************************************************************************/ - -static -ssize_t -ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off ) -{ - unsigned int minor = iminor(pFile->f_path.dentry->d_inode); - int rc = 0; - -#ifdef IP2DEBUG_IPL - printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count ); -#endif - - switch( minor ) { - case 0: // IPL device - rc = -EINVAL; - break; - case 1: // Status dump - rc = -EINVAL; - break; - case 2: // Ping device - rc = -EINVAL; - break; - case 3: // Trace device - rc = DumpTraceBuffer ( pData, count ); - break; - case 4: // Trace device - rc = DumpFifoBuffer ( pData, count ); - break; - default: - rc = -ENODEV; - break; - } - return rc; -} - -static int -DumpFifoBuffer ( char __user *pData, int count ) -{ -#ifdef DEBUG_FIFO - int rc; - rc = copy_to_user(pData, DBGBuf, count); - - printk(KERN_DEBUG "Last index %d\n", I ); - - return count; -#endif /* DEBUG_FIFO */ - return 0; -} - -static int -DumpTraceBuffer ( char __user *pData, int count ) -{ -#ifdef IP2DEBUG_TRACE - int rc; - int dumpcount; - int chunk; - int *pIndex = (int __user *)pData; - - if ( count < (sizeof(int) * 6) ) { - return -EIO; - } - rc = put_user(tracewrap, pIndex ); - rc = put_user(TRACEMAX, ++pIndex ); - rc = put_user(tracestrip, ++pIndex ); - rc = put_user(tracestuff, ++pIndex ); - pData += sizeof(int) * 6; - count -= sizeof(int) * 6; - - dumpcount = tracestuff - tracestrip; - if ( dumpcount < 0 ) { - dumpcount += TRACEMAX; - } - if ( dumpcount > count ) { - dumpcount = count; - } - chunk = TRACEMAX - tracestrip; - if ( dumpcount > chunk ) { - rc = copy_to_user(pData, &tracebuf[tracestrip], - chunk * sizeof(tracebuf[0]) ); - pData += chunk * sizeof(tracebuf[0]); - tracestrip = 0; - chunk = dumpcount - chunk; - } else { - chunk = dumpcount; - } - rc = copy_to_user(pData, &tracebuf[tracestrip], - chunk * sizeof(tracebuf[0]) ); - tracestrip += chunk; - tracewrap = 0; - - rc = put_user(tracestrip, ++pIndex ); - rc = put_user(tracestuff, ++pIndex ); - - return dumpcount; -#else - return 0; -#endif -} - -/******************************************************************************/ -/* Function: ip2_ipl_write() */ -/* Parameters: */ -/* Pointer to file structure */ -/* Pointer to data */ -/* Number of bytes to write */ -/* Returns: Success or failure */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static ssize_t -ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off) -{ -#ifdef IP2DEBUG_IPL - printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count ); -#endif - return 0; -} - -/******************************************************************************/ -/* Function: ip2_ipl_ioctl() */ -/* Parameters: Pointer to device inode */ -/* Pointer to file structure */ -/* Command */ -/* Argument */ -/* Returns: Success or failure */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static long -ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg ) -{ - unsigned int iplminor = iminor(pFile->f_path.dentry->d_inode); - int rc = 0; - void __user *argp = (void __user *)arg; - ULONG __user *pIndex = argp; - i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4]; - i2ChanStrPtr pCh; - -#ifdef IP2DEBUG_IPL - printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg ); -#endif - - mutex_lock(&ip2_mutex); - - switch ( iplminor ) { - case 0: // IPL device - rc = -EINVAL; - break; - case 1: // Status dump - case 5: - case 9: - case 13: - switch ( cmd ) { - case 64: /* Driver - ip2stat */ - rc = put_user(-1, pIndex++ ); - rc = put_user(irq_counter, pIndex++ ); - rc = put_user(bh_counter, pIndex++ ); - break; - - case 65: /* Board - ip2stat */ - if ( pB ) { - rc = copy_to_user(argp, pB, sizeof(i2eBordStr)); - rc = put_user(inb(pB->i2eStatus), - (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) ); - } else { - rc = -ENODEV; - } - break; - - default: - if (cmd < IP2_MAX_PORTS) { - pCh = DevTable[cmd]; - if ( pCh ) - { - rc = copy_to_user(argp, pCh, sizeof(i2ChanStr)); - if (rc) - rc = -EFAULT; - } else { - rc = -ENODEV; - } - } else { - rc = -EINVAL; - } - } - break; - - case 2: // Ping device - rc = -EINVAL; - break; - case 3: // Trace device - /* - * akpm: This used to write a whole bunch of function addresses - * to userspace, which generated lots of put_user() warnings. - * I killed it all. Just return "success" and don't do - * anything. - */ - if (cmd == 1) - rc = 0; - else - rc = -EINVAL; - break; - - default: - rc = -ENODEV; - break; - } - mutex_unlock(&ip2_mutex); - return rc; -} - -/******************************************************************************/ -/* Function: ip2_ipl_open() */ -/* Parameters: Pointer to device inode */ -/* Pointer to file structure */ -/* Returns: Success or failure */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -static int -ip2_ipl_open( struct inode *pInode, struct file *pFile ) -{ - -#ifdef IP2DEBUG_IPL - printk (KERN_DEBUG "IP2IPL: open\n" ); -#endif - return 0; -} - -static int -proc_ip2mem_show(struct seq_file *m, void *v) -{ - i2eBordStrPtr pB; - i2ChanStrPtr pCh; - PTTY tty; - int i; - -#define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n" -#define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n" -#define FMTLIN3 " 0x%04x 0x%04x rc flow\n" - - seq_printf(m,"\n"); - - for( i = 0; i < IP2_MAX_BOARDS; ++i ) { - pB = i2BoardPtrTable[i]; - if ( pB ) { - seq_printf(m,"board %d:\n",i); - seq_printf(m,"\tFifo rem: %d mty: %x outM %x\n", - pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting); - } - } - - seq_printf(m,"#: tty flags, port flags, cflags, iflags\n"); - for (i=0; i < IP2_MAX_PORTS; i++) { - pCh = DevTable[i]; - if (pCh) { - tty = pCh->pTTY; - if (tty && tty->count) { - seq_printf(m,FMTLINE,i,(int)tty->flags,pCh->flags, - tty->termios->c_cflag,tty->termios->c_iflag); - - seq_printf(m,FMTLIN2, - pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds); - seq_printf(m,FMTLIN3,pCh->infl.asof,pCh->infl.room); - } - } - } - return 0; -} - -static int proc_ip2mem_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_ip2mem_show, NULL); -} - -static const struct file_operations ip2mem_proc_fops = { - .owner = THIS_MODULE, - .open = proc_ip2mem_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/* - * This is the handler for /proc/tty/driver/ip2 - * - * This stretch of code has been largely plagerized from at least three - * different sources including ip2mkdev.c and a couple of other drivers. - * The bugs are all mine. :-) =mhw= - */ -static int ip2_proc_show(struct seq_file *m, void *v) -{ - int i, j, box; - int boxes = 0; - int ports = 0; - int tports = 0; - i2eBordStrPtr pB; - char *sep; - - seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion); - seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n", - IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR, - IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX); - - for( i = 0; i < IP2_MAX_BOARDS; ++i ) { - /* This need to be reset for a board by board count... */ - boxes = 0; - pB = i2BoardPtrTable[i]; - if( pB ) { - switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) - { - case POR_ID_FIIEX: - seq_printf(m, "Board %d: EX ports=", i); - sep = ""; - for( box = 0; box < ABS_MAX_BOXES; ++box ) - { - ports = 0; - - if( pB->i2eChannelMap[box] != 0 ) ++boxes; - for( j = 0; j < ABS_BIGGEST_BOX; ++j ) - { - if( pB->i2eChannelMap[box] & 1<< j ) { - ++ports; - } - } - seq_printf(m, "%s%d", sep, ports); - sep = ","; - tports += ports; - } - seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8); - break; - - case POR_ID_II_4: - seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i); - tports = ports = 4; - break; - - case POR_ID_II_8: - seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i); - tports = ports = 8; - break; - - case POR_ID_II_8R: - seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i); - tports = ports = 8; - break; - - default: - seq_printf(m, "Board %d: unknown", i); - /* Don't try and probe for minor numbers */ - tports = ports = 0; - } - - } else { - /* Don't try and probe for minor numbers */ - seq_printf(m, "Board %d: vacant", i); - tports = ports = 0; - } - - if( tports ) { - seq_puts(m, " minors="); - sep = ""; - for ( box = 0; box < ABS_MAX_BOXES; ++box ) - { - for ( j = 0; j < ABS_BIGGEST_BOX; ++j ) - { - if ( pB->i2eChannelMap[box] & (1 << j) ) - { - seq_printf(m, "%s%d", sep, - j + ABS_BIGGEST_BOX * - (box+i*ABS_MAX_BOXES)); - sep = ","; - } - } - } - } - seq_putc(m, '\n'); - } - return 0; - } - -static int ip2_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, ip2_proc_show, NULL); -} - -static const struct file_operations ip2_proc_fops = { - .owner = THIS_MODULE, - .open = ip2_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/******************************************************************************/ -/* Function: ip2trace() */ -/* Parameters: Value to add to trace buffer */ -/* Returns: Nothing */ -/* */ -/* Description: */ -/* */ -/* */ -/******************************************************************************/ -#ifdef IP2DEBUG_TRACE -void -ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...) -{ - long flags; - unsigned long *pCode = &codes; - union ip2breadcrumb bc; - i2ChanStrPtr pCh; - - - tracebuf[tracestuff++] = jiffies; - if ( tracestuff == TRACEMAX ) { - tracestuff = 0; - } - if ( tracestuff == tracestrip ) { - if ( ++tracestrip == TRACEMAX ) { - tracestrip = 0; - } - ++tracewrap; - } - - bc.hdr.port = 0xff & pn; - bc.hdr.cat = cat; - bc.hdr.codes = (unsigned char)( codes & 0xff ); - bc.hdr.label = label; - tracebuf[tracestuff++] = bc.value; - - for (;;) { - if ( tracestuff == TRACEMAX ) { - tracestuff = 0; - } - if ( tracestuff == tracestrip ) { - if ( ++tracestrip == TRACEMAX ) { - tracestrip = 0; - } - ++tracewrap; - } - - if ( !codes-- ) - break; - - tracebuf[tracestuff++] = *++pCode; - } -} -#endif - - -MODULE_LICENSE("GPL"); - -static struct pci_device_id ip2main_pci_tbl[] __devinitdata __used = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_IP2EX) }, - { } -}; - -MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl); - -MODULE_FIRMWARE("intelliport2.bin"); diff --git a/drivers/staging/tty/ip2/ip2trace.h b/drivers/staging/tty/ip2/ip2trace.h deleted file mode 100644 index da20435dc8a6..000000000000 --- a/drivers/staging/tty/ip2/ip2trace.h +++ /dev/null @@ -1,42 +0,0 @@ - -// -union ip2breadcrumb -{ - struct { - unsigned char port, cat, codes, label; - } __attribute__ ((packed)) hdr; - unsigned long value; -}; - -#define ITRC_NO_PORT 0xFF -#define CHANN (pCh->port_index) - -#define ITRC_ERROR '!' -#define ITRC_INIT 'A' -#define ITRC_OPEN 'B' -#define ITRC_CLOSE 'C' -#define ITRC_DRAIN 'D' -#define ITRC_IOCTL 'E' -#define ITRC_FLUSH 'F' -#define ITRC_STATUS 'G' -#define ITRC_HANGUP 'H' -#define ITRC_INTR 'I' -#define ITRC_SFLOW 'J' -#define ITRC_SBCMD 'K' -#define ITRC_SICMD 'L' -#define ITRC_MODEM 'M' -#define ITRC_INPUT 'N' -#define ITRC_OUTPUT 'O' -#define ITRC_PUTC 'P' -#define ITRC_QUEUE 'Q' -#define ITRC_STFLW 'R' -#define ITRC_SFIFO 'S' -#define ITRC_VERIFY 'V' -#define ITRC_WRITE 'W' - -#define ITRC_ENTER 0x00 -#define ITRC_RETURN 0xFF - -#define ITRC_QUEUE_ROOM 2 -#define ITRC_QUEUE_CMD 6 - diff --git a/drivers/staging/tty/ip2/ip2types.h b/drivers/staging/tty/ip2/ip2types.h deleted file mode 100644 index 9d67b260b2f6..000000000000 --- a/drivers/staging/tty/ip2/ip2types.h +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* -* -* (c) 1998 by Computone Corporation -* -******************************************************************************** -* -* -* PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport -* serial I/O controllers. -* -* DESCRIPTION: Driver constants and type definitions. -* -* NOTES: -* -*******************************************************************************/ -#ifndef IP2TYPES_H -#define IP2TYPES_H - -//************* -//* Constants * -//************* - -// Define some limits for this driver. Ports per board is a hardware limitation -// that will not change. Current hardware limits this to 64 ports per board. -// Boards per driver is a self-imposed limit. -// -#define IP2_MAX_BOARDS 4 -#define IP2_PORTS_PER_BOARD ABS_MOST_PORTS -#define IP2_MAX_PORTS (IP2_MAX_BOARDS*IP2_PORTS_PER_BOARD) - -#define ISA 0 -#define PCI 1 -#define EISA 2 - -//******************** -//* Type Definitions * -//******************** - -typedef struct tty_struct * PTTY; -typedef wait_queue_head_t PWAITQ; - -typedef unsigned char UCHAR; -typedef unsigned int UINT; -typedef unsigned short USHORT; -typedef unsigned long ULONG; - -typedef struct -{ - short irq[IP2_MAX_BOARDS]; - unsigned short addr[IP2_MAX_BOARDS]; - int type[IP2_MAX_BOARDS]; -#ifdef CONFIG_PCI - struct pci_dev *pci_dev[IP2_MAX_BOARDS]; -#endif -} ip2config_t; - -#endif diff --git a/drivers/staging/tty/istallion.c b/drivers/staging/tty/istallion.c deleted file mode 100644 index ca18cbf4e3c9..000000000000 --- a/drivers/staging/tty/istallion.c +++ /dev/null @@ -1,4507 +0,0 @@ -/*****************************************************************************/ - -/* - * istallion.c -- stallion intelligent multiport serial driver. - * - * Copyright (C) 1996-1999 Stallion Technologies - * Copyright (C) 1994-1996 Greg Ungerer. - * - * This code is loosely based on the Linux serial driver, written by - * Linus Torvalds, Theodore T'so and others. - * - * 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 -#include -#include -#include -#include - -#include -#include - -#include - -/*****************************************************************************/ - -/* - * Define different board types. Not all of the following board types - * are supported by this driver. But I will use the standard "assigned" - * board numbers. Currently supported boards are abbreviated as: - * ECP = EasyConnection 8/64, ONB = ONboard, BBY = Brumby and - * STAL = Stallion. - */ -#define BRD_UNKNOWN 0 -#define BRD_STALLION 1 -#define BRD_BRUMBY4 2 -#define BRD_ONBOARD2 3 -#define BRD_ONBOARD 4 -#define BRD_ONBOARDE 7 -#define BRD_ECP 23 -#define BRD_ECPE 24 -#define BRD_ECPMC 25 -#define BRD_ECPPCI 29 - -#define BRD_BRUMBY BRD_BRUMBY4 - -/* - * Define a configuration structure to hold the board configuration. - * Need to set this up in the code (for now) with the boards that are - * to be configured into the system. This is what needs to be modified - * when adding/removing/modifying boards. Each line entry in the - * stli_brdconf[] array is a board. Each line contains io/irq/memory - * ranges for that board (as well as what type of board it is). - * Some examples: - * { BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 }, - * This line will configure an EasyConnection 8/64 at io address 2a0, - * and shared memory address of cc000. Multiple EasyConnection 8/64 - * boards can share the same shared memory address space. No interrupt - * is required for this board type. - * Another example: - * { BRD_ECPE, 0x5000, 0, 0x80000000, 0, 0 }, - * This line will configure an EasyConnection 8/64 EISA in slot 5 and - * shared memory address of 0x80000000 (2 GByte). Multiple - * EasyConnection 8/64 EISA boards can share the same shared memory - * address space. No interrupt is required for this board type. - * Another example: - * { BRD_ONBOARD, 0x240, 0, 0xd0000, 0, 0 }, - * This line will configure an ONboard (ISA type) at io address 240, - * and shared memory address of d0000. Multiple ONboards can share - * the same shared memory address space. No interrupt required. - * Another example: - * { BRD_BRUMBY4, 0x360, 0, 0xc8000, 0, 0 }, - * This line will configure a Brumby board (any number of ports!) at - * io address 360 and shared memory address of c8000. All Brumby boards - * configured into a system must have their own separate io and memory - * addresses. No interrupt is required. - * Another example: - * { BRD_STALLION, 0x330, 0, 0xd0000, 0, 0 }, - * This line will configure an original Stallion board at io address 330 - * and shared memory address d0000 (this would only be valid for a "V4.0" - * or Rev.O Stallion board). All Stallion boards configured into the - * system must have their own separate io and memory addresses. No - * interrupt is required. - */ - -struct stlconf { - int brdtype; - int ioaddr1; - int ioaddr2; - unsigned long memaddr; - int irq; - int irqtype; -}; - -static unsigned int stli_nrbrds; - -/* stli_lock must NOT be taken holding brd_lock */ -static spinlock_t stli_lock; /* TTY logic lock */ -static spinlock_t brd_lock; /* Board logic lock */ - -/* - * There is some experimental EISA board detection code in this driver. - * By default it is disabled, but for those that want to try it out, - * then set the define below to be 1. - */ -#define STLI_EISAPROBE 0 - -/*****************************************************************************/ - -/* - * Define some important driver characteristics. Device major numbers - * allocated as per Linux Device Registry. - */ -#ifndef STL_SIOMEMMAJOR -#define STL_SIOMEMMAJOR 28 -#endif -#ifndef STL_SERIALMAJOR -#define STL_SERIALMAJOR 24 -#endif -#ifndef STL_CALLOUTMAJOR -#define STL_CALLOUTMAJOR 25 -#endif - -/*****************************************************************************/ - -/* - * Define our local driver identity first. Set up stuff to deal with - * all the local structures required by a serial tty driver. - */ -static char *stli_drvtitle = "Stallion Intelligent Multiport Serial Driver"; -static char *stli_drvname = "istallion"; -static char *stli_drvversion = "5.6.0"; -static char *stli_serialname = "ttyE"; - -static struct tty_driver *stli_serial; -static const struct tty_port_operations stli_port_ops; - -#define STLI_TXBUFSIZE 4096 - -/* - * Use a fast local buffer for cooked characters. Typically a whole - * bunch of cooked characters come in for a port, 1 at a time. So we - * save those up into a local buffer, then write out the whole lot - * with a large memcpy. Just use 1 buffer for all ports, since its - * use it is only need for short periods of time by each port. - */ -static char *stli_txcookbuf; -static int stli_txcooksize; -static int stli_txcookrealsize; -static struct tty_struct *stli_txcooktty; - -/* - * Define a local default termios struct. All ports will be created - * with this termios initially. Basically all it defines is a raw port - * at 9600 baud, 8 data bits, no parity, 1 stop bit. - */ -static struct ktermios stli_deftermios = { - .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), - .c_cc = INIT_C_CC, - .c_ispeed = 9600, - .c_ospeed = 9600, -}; - -/* - * Define global stats structures. Not used often, and can be - * re-used for each stats call. - */ -static comstats_t stli_comstats; -static struct asystats stli_cdkstats; - -/*****************************************************************************/ - -static DEFINE_MUTEX(stli_brdslock); -static struct stlibrd *stli_brds[STL_MAXBRDS]; - -static int stli_shared; - -/* - * Per board state flags. Used with the state field of the board struct. - * Not really much here... All we need to do is keep track of whether - * the board has been detected, and whether it is actually running a slave - * or not. - */ -#define BST_FOUND 0 -#define BST_STARTED 1 -#define BST_PROBED 2 - -/* - * Define the set of port state flags. These are marked for internal - * state purposes only, usually to do with the state of communications - * with the slave. Most of them need to be updated atomically, so always - * use the bit setting operations (unless protected by cli/sti). - */ -#define ST_OPENING 2 -#define ST_CLOSING 3 -#define ST_CMDING 4 -#define ST_TXBUSY 5 -#define ST_RXING 6 -#define ST_DOFLUSHRX 7 -#define ST_DOFLUSHTX 8 -#define ST_DOSIGS 9 -#define ST_RXSTOP 10 -#define ST_GETSIGS 11 - -/* - * Define an array of board names as printable strings. Handy for - * referencing boards when printing trace and stuff. - */ -static char *stli_brdnames[] = { - "Unknown", - "Stallion", - "Brumby", - "ONboard-MC", - "ONboard", - "Brumby", - "Brumby", - "ONboard-EI", - NULL, - "ONboard", - "ONboard-MC", - "ONboard-MC", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "EasyIO", - "EC8/32-AT", - "EC8/32-MC", - "EC8/64-AT", - "EC8/64-EI", - "EC8/64-MC", - "EC8/32-PCI", - "EC8/64-PCI", - "EasyIO-PCI", - "EC/RA-PCI", -}; - -/*****************************************************************************/ - -/* - * Define some string labels for arguments passed from the module - * load line. These allow for easy board definitions, and easy - * modification of the io, memory and irq resoucres. - */ - -static char *board0[8]; -static char *board1[8]; -static char *board2[8]; -static char *board3[8]; - -static char **stli_brdsp[] = { - (char **) &board0, - (char **) &board1, - (char **) &board2, - (char **) &board3 -}; - -/* - * Define a set of common board names, and types. This is used to - * parse any module arguments. - */ - -static struct stlibrdtype { - char *name; - int type; -} stli_brdstr[] = { - { "stallion", BRD_STALLION }, - { "1", BRD_STALLION }, - { "brumby", BRD_BRUMBY }, - { "brumby4", BRD_BRUMBY }, - { "brumby/4", BRD_BRUMBY }, - { "brumby-4", BRD_BRUMBY }, - { "brumby8", BRD_BRUMBY }, - { "brumby/8", BRD_BRUMBY }, - { "brumby-8", BRD_BRUMBY }, - { "brumby16", BRD_BRUMBY }, - { "brumby/16", BRD_BRUMBY }, - { "brumby-16", BRD_BRUMBY }, - { "2", BRD_BRUMBY }, - { "onboard2", BRD_ONBOARD2 }, - { "onboard-2", BRD_ONBOARD2 }, - { "onboard/2", BRD_ONBOARD2 }, - { "onboard-mc", BRD_ONBOARD2 }, - { "onboard/mc", BRD_ONBOARD2 }, - { "onboard-mca", BRD_ONBOARD2 }, - { "onboard/mca", BRD_ONBOARD2 }, - { "3", BRD_ONBOARD2 }, - { "onboard", BRD_ONBOARD }, - { "onboardat", BRD_ONBOARD }, - { "4", BRD_ONBOARD }, - { "onboarde", BRD_ONBOARDE }, - { "onboard-e", BRD_ONBOARDE }, - { "onboard/e", BRD_ONBOARDE }, - { "onboard-ei", BRD_ONBOARDE }, - { "onboard/ei", BRD_ONBOARDE }, - { "7", BRD_ONBOARDE }, - { "ecp", BRD_ECP }, - { "ecpat", BRD_ECP }, - { "ec8/64", BRD_ECP }, - { "ec8/64-at", BRD_ECP }, - { "ec8/64-isa", BRD_ECP }, - { "23", BRD_ECP }, - { "ecpe", BRD_ECPE }, - { "ecpei", BRD_ECPE }, - { "ec8/64-e", BRD_ECPE }, - { "ec8/64-ei", BRD_ECPE }, - { "24", BRD_ECPE }, - { "ecpmc", BRD_ECPMC }, - { "ec8/64-mc", BRD_ECPMC }, - { "ec8/64-mca", BRD_ECPMC }, - { "25", BRD_ECPMC }, - { "ecppci", BRD_ECPPCI }, - { "ec/ra", BRD_ECPPCI }, - { "ec/ra-pc", BRD_ECPPCI }, - { "ec/ra-pci", BRD_ECPPCI }, - { "29", BRD_ECPPCI }, -}; - -/* - * Define the module agruments. - */ -MODULE_AUTHOR("Greg Ungerer"); -MODULE_DESCRIPTION("Stallion Intelligent Multiport Serial Driver"); -MODULE_LICENSE("GPL"); - - -module_param_array(board0, charp, NULL, 0); -MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]"); -module_param_array(board1, charp, NULL, 0); -MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,memaddr]"); -module_param_array(board2, charp, NULL, 0); -MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,memaddr]"); -module_param_array(board3, charp, NULL, 0); -MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]"); - -#if STLI_EISAPROBE != 0 -/* - * Set up a default memory address table for EISA board probing. - * The default addresses are all bellow 1Mbyte, which has to be the - * case anyway. They should be safe, since we only read values from - * them, and interrupts are disabled while we do it. If the higher - * memory support is compiled in then we also try probing around - * the 1Gb, 2Gb and 3Gb areas as well... - */ -static unsigned long stli_eisamemprobeaddrs[] = { - 0xc0000, 0xd0000, 0xe0000, 0xf0000, - 0x80000000, 0x80010000, 0x80020000, 0x80030000, - 0x40000000, 0x40010000, 0x40020000, 0x40030000, - 0xc0000000, 0xc0010000, 0xc0020000, 0xc0030000, - 0xff000000, 0xff010000, 0xff020000, 0xff030000, -}; - -static int stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs); -#endif - -/* - * Define the Stallion PCI vendor and device IDs. - */ -#ifndef PCI_DEVICE_ID_ECRA -#define PCI_DEVICE_ID_ECRA 0x0004 -#endif - -static struct pci_device_id istallion_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA), }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); - -static struct pci_driver stli_pcidriver; - -/*****************************************************************************/ - -/* - * Hardware configuration info for ECP boards. These defines apply - * to the directly accessible io ports of the ECP. There is a set of - * defines for each ECP board type, ISA, EISA, MCA and PCI. - */ -#define ECP_IOSIZE 4 - -#define ECP_MEMSIZE (128 * 1024) -#define ECP_PCIMEMSIZE (256 * 1024) - -#define ECP_ATPAGESIZE (4 * 1024) -#define ECP_MCPAGESIZE (4 * 1024) -#define ECP_EIPAGESIZE (64 * 1024) -#define ECP_PCIPAGESIZE (64 * 1024) - -#define STL_EISAID 0x8c4e - -/* - * Important defines for the ISA class of ECP board. - */ -#define ECP_ATIREG 0 -#define ECP_ATCONFR 1 -#define ECP_ATMEMAR 2 -#define ECP_ATMEMPR 3 -#define ECP_ATSTOP 0x1 -#define ECP_ATINTENAB 0x10 -#define ECP_ATENABLE 0x20 -#define ECP_ATDISABLE 0x00 -#define ECP_ATADDRMASK 0x3f000 -#define ECP_ATADDRSHFT 12 - -/* - * Important defines for the EISA class of ECP board. - */ -#define ECP_EIIREG 0 -#define ECP_EIMEMARL 1 -#define ECP_EICONFR 2 -#define ECP_EIMEMARH 3 -#define ECP_EIENABLE 0x1 -#define ECP_EIDISABLE 0x0 -#define ECP_EISTOP 0x4 -#define ECP_EIEDGE 0x00 -#define ECP_EILEVEL 0x80 -#define ECP_EIADDRMASKL 0x00ff0000 -#define ECP_EIADDRSHFTL 16 -#define ECP_EIADDRMASKH 0xff000000 -#define ECP_EIADDRSHFTH 24 -#define ECP_EIBRDENAB 0xc84 - -#define ECP_EISAID 0x4 - -/* - * Important defines for the Micro-channel class of ECP board. - * (It has a lot in common with the ISA boards.) - */ -#define ECP_MCIREG 0 -#define ECP_MCCONFR 1 -#define ECP_MCSTOP 0x20 -#define ECP_MCENABLE 0x80 -#define ECP_MCDISABLE 0x00 - -/* - * Important defines for the PCI class of ECP board. - * (It has a lot in common with the other ECP boards.) - */ -#define ECP_PCIIREG 0 -#define ECP_PCICONFR 1 -#define ECP_PCISTOP 0x01 - -/* - * Hardware configuration info for ONboard and Brumby boards. These - * defines apply to the directly accessible io ports of these boards. - */ -#define ONB_IOSIZE 16 -#define ONB_MEMSIZE (64 * 1024) -#define ONB_ATPAGESIZE (64 * 1024) -#define ONB_MCPAGESIZE (64 * 1024) -#define ONB_EIMEMSIZE (128 * 1024) -#define ONB_EIPAGESIZE (64 * 1024) - -/* - * Important defines for the ISA class of ONboard board. - */ -#define ONB_ATIREG 0 -#define ONB_ATMEMAR 1 -#define ONB_ATCONFR 2 -#define ONB_ATSTOP 0x4 -#define ONB_ATENABLE 0x01 -#define ONB_ATDISABLE 0x00 -#define ONB_ATADDRMASK 0xff0000 -#define ONB_ATADDRSHFT 16 - -#define ONB_MEMENABLO 0 -#define ONB_MEMENABHI 0x02 - -/* - * Important defines for the EISA class of ONboard board. - */ -#define ONB_EIIREG 0 -#define ONB_EIMEMARL 1 -#define ONB_EICONFR 2 -#define ONB_EIMEMARH 3 -#define ONB_EIENABLE 0x1 -#define ONB_EIDISABLE 0x0 -#define ONB_EISTOP 0x4 -#define ONB_EIEDGE 0x00 -#define ONB_EILEVEL 0x80 -#define ONB_EIADDRMASKL 0x00ff0000 -#define ONB_EIADDRSHFTL 16 -#define ONB_EIADDRMASKH 0xff000000 -#define ONB_EIADDRSHFTH 24 -#define ONB_EIBRDENAB 0xc84 - -#define ONB_EISAID 0x1 - -/* - * Important defines for the Brumby boards. They are pretty simple, - * there is not much that is programmably configurable. - */ -#define BBY_IOSIZE 16 -#define BBY_MEMSIZE (64 * 1024) -#define BBY_PAGESIZE (16 * 1024) - -#define BBY_ATIREG 0 -#define BBY_ATCONFR 1 -#define BBY_ATSTOP 0x4 - -/* - * Important defines for the Stallion boards. They are pretty simple, - * there is not much that is programmably configurable. - */ -#define STAL_IOSIZE 16 -#define STAL_MEMSIZE (64 * 1024) -#define STAL_PAGESIZE (64 * 1024) - -/* - * Define the set of status register values for EasyConnection panels. - * The signature will return with the status value for each panel. From - * this we can determine what is attached to the board - before we have - * actually down loaded any code to it. - */ -#define ECH_PNLSTATUS 2 -#define ECH_PNL16PORT 0x20 -#define ECH_PNLIDMASK 0x07 -#define ECH_PNLXPID 0x40 -#define ECH_PNLINTRPEND 0x80 - -/* - * Define some macros to do things to the board. Even those these boards - * are somewhat related there is often significantly different ways of - * doing some operation on it (like enable, paging, reset, etc). So each - * board class has a set of functions which do the commonly required - * operations. The macros below basically just call these functions, - * generally checking for a NULL function - which means that the board - * needs nothing done to it to achieve this operation! - */ -#define EBRDINIT(brdp) \ - if (brdp->init != NULL) \ - (* brdp->init)(brdp) - -#define EBRDENABLE(brdp) \ - if (brdp->enable != NULL) \ - (* brdp->enable)(brdp); - -#define EBRDDISABLE(brdp) \ - if (brdp->disable != NULL) \ - (* brdp->disable)(brdp); - -#define EBRDINTR(brdp) \ - if (brdp->intr != NULL) \ - (* brdp->intr)(brdp); - -#define EBRDRESET(brdp) \ - if (brdp->reset != NULL) \ - (* brdp->reset)(brdp); - -#define EBRDGETMEMPTR(brdp,offset) \ - (* brdp->getmemptr)(brdp, offset, __LINE__) - -/* - * Define the maximal baud rate, and the default baud base for ports. - */ -#define STL_MAXBAUD 460800 -#define STL_BAUDBASE 115200 -#define STL_CLOSEDELAY (5 * HZ / 10) - -/*****************************************************************************/ - -/* - * Define macros to extract a brd or port number from a minor number. - */ -#define MINOR2BRD(min) (((min) & 0xc0) >> 6) -#define MINOR2PORT(min) ((min) & 0x3f) - -/*****************************************************************************/ - -/* - * Prototype all functions in this driver! - */ - -static int stli_parsebrd(struct stlconf *confp, char **argp); -static int stli_open(struct tty_struct *tty, struct file *filp); -static void stli_close(struct tty_struct *tty, struct file *filp); -static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count); -static int stli_putchar(struct tty_struct *tty, unsigned char ch); -static void stli_flushchars(struct tty_struct *tty); -static int stli_writeroom(struct tty_struct *tty); -static int stli_charsinbuffer(struct tty_struct *tty); -static int stli_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); -static void stli_settermios(struct tty_struct *tty, struct ktermios *old); -static void stli_throttle(struct tty_struct *tty); -static void stli_unthrottle(struct tty_struct *tty); -static void stli_stop(struct tty_struct *tty); -static void stli_start(struct tty_struct *tty); -static void stli_flushbuffer(struct tty_struct *tty); -static int stli_breakctl(struct tty_struct *tty, int state); -static void stli_waituntilsent(struct tty_struct *tty, int timeout); -static void stli_sendxchar(struct tty_struct *tty, char ch); -static void stli_hangup(struct tty_struct *tty); - -static int stli_brdinit(struct stlibrd *brdp); -static int stli_startbrd(struct stlibrd *brdp); -static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); -static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); -static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg); -static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); -static void stli_poll(unsigned long arg); -static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); -static int stli_initopen(struct tty_struct *tty, struct stlibrd *brdp, struct stliport *portp); -static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); -static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); -static int stli_setport(struct tty_struct *tty); -static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); -static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); -static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); -static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp); -static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, asyport_t *pp, struct ktermios *tiosp); -static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); -static long stli_mktiocm(unsigned long sigvalue); -static void stli_read(struct stlibrd *brdp, struct stliport *portp); -static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp); -static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp); -static int stli_getbrdstats(combrd_t __user *bp); -static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, comstats_t __user *cp); -static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp); -static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp); -static int stli_getportstruct(struct stliport __user *arg); -static int stli_getbrdstruct(struct stlibrd __user *arg); -static struct stlibrd *stli_allocbrd(void); - -static void stli_ecpinit(struct stlibrd *brdp); -static void stli_ecpenable(struct stlibrd *brdp); -static void stli_ecpdisable(struct stlibrd *brdp); -static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_ecpreset(struct stlibrd *brdp); -static void stli_ecpintr(struct stlibrd *brdp); -static void stli_ecpeiinit(struct stlibrd *brdp); -static void stli_ecpeienable(struct stlibrd *brdp); -static void stli_ecpeidisable(struct stlibrd *brdp); -static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_ecpeireset(struct stlibrd *brdp); -static void stli_ecpmcenable(struct stlibrd *brdp); -static void stli_ecpmcdisable(struct stlibrd *brdp); -static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_ecpmcreset(struct stlibrd *brdp); -static void stli_ecppciinit(struct stlibrd *brdp); -static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_ecppcireset(struct stlibrd *brdp); - -static void stli_onbinit(struct stlibrd *brdp); -static void stli_onbenable(struct stlibrd *brdp); -static void stli_onbdisable(struct stlibrd *brdp); -static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_onbreset(struct stlibrd *brdp); -static void stli_onbeinit(struct stlibrd *brdp); -static void stli_onbeenable(struct stlibrd *brdp); -static void stli_onbedisable(struct stlibrd *brdp); -static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_onbereset(struct stlibrd *brdp); -static void stli_bbyinit(struct stlibrd *brdp); -static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_bbyreset(struct stlibrd *brdp); -static void stli_stalinit(struct stlibrd *brdp); -static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); -static void stli_stalreset(struct stlibrd *brdp); - -static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, unsigned int portnr); - -static int stli_initecp(struct stlibrd *brdp); -static int stli_initonb(struct stlibrd *brdp); -#if STLI_EISAPROBE != 0 -static int stli_eisamemprobe(struct stlibrd *brdp); -#endif -static int stli_initports(struct stlibrd *brdp); - -/*****************************************************************************/ - -/* - * Define the driver info for a user level shared memory device. This - * device will work sort of like the /dev/kmem device - except that it - * will give access to the shared memory on the Stallion intelligent - * board. This is also a very useful debugging tool. - */ -static const struct file_operations stli_fsiomem = { - .owner = THIS_MODULE, - .read = stli_memread, - .write = stli_memwrite, - .unlocked_ioctl = stli_memioctl, - .llseek = default_llseek, -}; - -/*****************************************************************************/ - -/* - * Define a timer_list entry for our poll routine. The slave board - * is polled every so often to see if anything needs doing. This is - * much cheaper on host cpu than using interrupts. It turns out to - * not increase character latency by much either... - */ -static DEFINE_TIMER(stli_timerlist, stli_poll, 0, 0); - -static int stli_timeron; - -/* - * Define the calculation for the timeout routine. - */ -#define STLI_TIMEOUT (jiffies + 1) - -/*****************************************************************************/ - -static struct class *istallion_class; - -static void stli_cleanup_ports(struct stlibrd *brdp) -{ - struct stliport *portp; - unsigned int j; - struct tty_struct *tty; - - for (j = 0; j < STL_MAXPORTS; j++) { - portp = brdp->ports[j]; - if (portp != NULL) { - tty = tty_port_tty_get(&portp->port); - if (tty != NULL) { - tty_hangup(tty); - tty_kref_put(tty); - } - kfree(portp); - } - } -} - -/*****************************************************************************/ - -/* - * Parse the supplied argument string, into the board conf struct. - */ - -static int stli_parsebrd(struct stlconf *confp, char **argp) -{ - unsigned int i; - char *sp; - - if (argp[0] == NULL || *argp[0] == 0) - return 0; - - for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) - *sp = tolower(*sp); - - for (i = 0; i < ARRAY_SIZE(stli_brdstr); i++) { - if (strcmp(stli_brdstr[i].name, argp[0]) == 0) - break; - } - if (i == ARRAY_SIZE(stli_brdstr)) { - printk(KERN_WARNING "istallion: unknown board name, %s?\n", argp[0]); - return 0; - } - - confp->brdtype = stli_brdstr[i].type; - if (argp[1] != NULL && *argp[1] != 0) - confp->ioaddr1 = simple_strtoul(argp[1], NULL, 0); - if (argp[2] != NULL && *argp[2] != 0) - confp->memaddr = simple_strtoul(argp[2], NULL, 0); - return(1); -} - -/*****************************************************************************/ - -/* - * On the first open of the device setup the port hardware, and - * initialize the per port data structure. Since initializing the port - * requires several commands to the board we will need to wait for any - * other open that is already initializing the port. - * - * Locking: protected by the port mutex. - */ - -static int stli_activate(struct tty_port *port, struct tty_struct *tty) -{ - struct stliport *portp = container_of(port, struct stliport, port); - struct stlibrd *brdp = stli_brds[portp->brdnr]; - int rc; - - if ((rc = stli_initopen(tty, brdp, portp)) >= 0) - clear_bit(TTY_IO_ERROR, &tty->flags); - wake_up_interruptible(&portp->raw_wait); - return rc; -} - -static int stli_open(struct tty_struct *tty, struct file *filp) -{ - struct stlibrd *brdp; - struct stliport *portp; - unsigned int minordev, brdnr, portnr; - - minordev = tty->index; - brdnr = MINOR2BRD(minordev); - if (brdnr >= stli_nrbrds) - return -ENODEV; - brdp = stli_brds[brdnr]; - if (brdp == NULL) - return -ENODEV; - if (!test_bit(BST_STARTED, &brdp->state)) - return -ENODEV; - portnr = MINOR2PORT(minordev); - if (portnr > brdp->nrports) - return -ENODEV; - - portp = brdp->ports[portnr]; - if (portp == NULL) - return -ENODEV; - if (portp->devnr < 1) - return -ENODEV; - - tty->driver_data = portp; - return tty_port_open(&portp->port, tty, filp); -} - - -/*****************************************************************************/ - -static void stli_shutdown(struct tty_port *port) -{ - struct stlibrd *brdp; - unsigned long ftype; - unsigned long flags; - struct stliport *portp = container_of(port, struct stliport, port); - - if (portp->brdnr >= stli_nrbrds) - return; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return; - - /* - * May want to wait for data to drain before closing. The BUSY - * flag keeps track of whether we are still transmitting or not. - * It is updated by messages from the slave - indicating when all - * chars really have drained. - */ - - if (!test_bit(ST_CLOSING, &portp->state)) - stli_rawclose(brdp, portp, 0, 0); - - spin_lock_irqsave(&stli_lock, flags); - clear_bit(ST_TXBUSY, &portp->state); - clear_bit(ST_RXSTOP, &portp->state); - spin_unlock_irqrestore(&stli_lock, flags); - - ftype = FLUSHTX | FLUSHRX; - stli_cmdwait(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0); -} - -static void stli_close(struct tty_struct *tty, struct file *filp) -{ - struct stliport *portp = tty->driver_data; - unsigned long flags; - if (portp == NULL) - return; - spin_lock_irqsave(&stli_lock, flags); - /* Flush any internal buffering out first */ - if (tty == stli_txcooktty) - stli_flushchars(tty); - spin_unlock_irqrestore(&stli_lock, flags); - tty_port_close(&portp->port, tty, filp); -} - -/*****************************************************************************/ - -/* - * Carry out first open operations on a port. This involves a number of - * commands to be sent to the slave. We need to open the port, set the - * notification events, set the initial port settings, get and set the - * initial signal values. We sleep and wait in between each one. But - * this still all happens pretty quickly. - */ - -static int stli_initopen(struct tty_struct *tty, - struct stlibrd *brdp, struct stliport *portp) -{ - asynotify_t nt; - asyport_t aport; - int rc; - - if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0) - return rc; - - memset(&nt, 0, sizeof(asynotify_t)); - nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK); - nt.signal = SG_DCD; - if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt, - sizeof(asynotify_t), 0)) < 0) - return rc; - - stli_mkasyport(tty, portp, &aport, tty->termios); - if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, - sizeof(asyport_t), 0)) < 0) - return rc; - - set_bit(ST_GETSIGS, &portp->state); - if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, - sizeof(asysigs_t), 1)) < 0) - return rc; - if (test_and_clear_bit(ST_GETSIGS, &portp->state)) - portp->sigs = stli_mktiocm(portp->asig.sigvalue); - stli_mkasysigs(&portp->asig, 1, 1); - if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, - sizeof(asysigs_t), 0)) < 0) - return rc; - - return 0; -} - -/*****************************************************************************/ - -/* - * Send an open message to the slave. This will sleep waiting for the - * acknowledgement, so must have user context. We need to co-ordinate - * with close events here, since we don't want open and close events - * to overlap. - */ - -static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait) -{ - cdkhdr_t __iomem *hdrp; - cdkctrl_t __iomem *cp; - unsigned char __iomem *bits; - unsigned long flags; - int rc; - -/* - * Send a message to the slave to open this port. - */ - -/* - * Slave is already closing this port. This can happen if a hangup - * occurs on this port. So we must wait until it is complete. The - * order of opens and closes may not be preserved across shared - * memory, so we must wait until it is complete. - */ - wait_event_interruptible_tty(portp->raw_wait, - !test_bit(ST_CLOSING, &portp->state)); - if (signal_pending(current)) { - return -ERESTARTSYS; - } - -/* - * Everything is ready now, so write the open message into shared - * memory. Once the message is in set the service bits to say that - * this port wants service. - */ - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; - writel(arg, &cp->openarg); - writeb(1, &cp->open); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + - portp->portidx; - writeb(readb(bits) | portp->portbit, bits); - EBRDDISABLE(brdp); - - if (wait == 0) { - spin_unlock_irqrestore(&brd_lock, flags); - return 0; - } - -/* - * Slave is in action, so now we must wait for the open acknowledgment - * to come back. - */ - rc = 0; - set_bit(ST_OPENING, &portp->state); - spin_unlock_irqrestore(&brd_lock, flags); - - wait_event_interruptible_tty(portp->raw_wait, - !test_bit(ST_OPENING, &portp->state)); - if (signal_pending(current)) - rc = -ERESTARTSYS; - - if ((rc == 0) && (portp->rc != 0)) - rc = -EIO; - return rc; -} - -/*****************************************************************************/ - -/* - * Send a close message to the slave. Normally this will sleep waiting - * for the acknowledgement, but if wait parameter is 0 it will not. If - * wait is true then must have user context (to sleep). - */ - -static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait) -{ - cdkhdr_t __iomem *hdrp; - cdkctrl_t __iomem *cp; - unsigned char __iomem *bits; - unsigned long flags; - int rc; - -/* - * Slave is already closing this port. This can happen if a hangup - * occurs on this port. - */ - if (wait) { - wait_event_interruptible_tty(portp->raw_wait, - !test_bit(ST_CLOSING, &portp->state)); - if (signal_pending(current)) { - return -ERESTARTSYS; - } - } - -/* - * Write the close command into shared memory. - */ - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; - writel(arg, &cp->closearg); - writeb(1, &cp->close); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + - portp->portidx; - writeb(readb(bits) |portp->portbit, bits); - EBRDDISABLE(brdp); - - set_bit(ST_CLOSING, &portp->state); - spin_unlock_irqrestore(&brd_lock, flags); - - if (wait == 0) - return 0; - -/* - * Slave is in action, so now we must wait for the open acknowledgment - * to come back. - */ - rc = 0; - wait_event_interruptible_tty(portp->raw_wait, - !test_bit(ST_CLOSING, &portp->state)); - if (signal_pending(current)) - rc = -ERESTARTSYS; - - if ((rc == 0) && (portp->rc != 0)) - rc = -EIO; - return rc; -} - -/*****************************************************************************/ - -/* - * Send a command to the slave and wait for the response. This must - * have user context (it sleeps). This routine is generic in that it - * can send any type of command. Its purpose is to wait for that command - * to complete (as opposed to initiating the command then returning). - */ - -static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) -{ - /* - * no need for wait_event_tty because clearing ST_CMDING cannot block - * on BTM - */ - wait_event_interruptible(portp->raw_wait, - !test_bit(ST_CMDING, &portp->state)); - if (signal_pending(current)) - return -ERESTARTSYS; - - stli_sendcmd(brdp, portp, cmd, arg, size, copyback); - - wait_event_interruptible(portp->raw_wait, - !test_bit(ST_CMDING, &portp->state)); - if (signal_pending(current)) - return -ERESTARTSYS; - - if (portp->rc != 0) - return -EIO; - return 0; -} - -/*****************************************************************************/ - -/* - * Send the termios settings for this port to the slave. This sleeps - * waiting for the command to complete - so must have user context. - */ - -static int stli_setport(struct tty_struct *tty) -{ - struct stliport *portp = tty->driver_data; - struct stlibrd *brdp; - asyport_t aport; - - if (portp == NULL) - return -ENODEV; - if (portp->brdnr >= stli_nrbrds) - return -ENODEV; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return -ENODEV; - - stli_mkasyport(tty, portp, &aport, tty->termios); - return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); -} - -/*****************************************************************************/ - -static int stli_carrier_raised(struct tty_port *port) -{ - struct stliport *portp = container_of(port, struct stliport, port); - return (portp->sigs & TIOCM_CD) ? 1 : 0; -} - -static void stli_dtr_rts(struct tty_port *port, int on) -{ - struct stliport *portp = container_of(port, struct stliport, port); - struct stlibrd *brdp = stli_brds[portp->brdnr]; - stli_mkasysigs(&portp->asig, on, on); - if (stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, - sizeof(asysigs_t), 0) < 0) - printk(KERN_WARNING "istallion: dtr set failed.\n"); -} - - -/*****************************************************************************/ - -/* - * Write routine. Take the data and put it in the shared memory ring - * queue. If port is not already sending chars then need to mark the - * service bits for this port. - */ - -static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - cdkasy_t __iomem *ap; - cdkhdr_t __iomem *hdrp; - unsigned char __iomem *bits; - unsigned char __iomem *shbuf; - unsigned char *chbuf; - struct stliport *portp; - struct stlibrd *brdp; - unsigned int len, stlen, head, tail, size; - unsigned long flags; - - if (tty == stli_txcooktty) - stli_flushchars(tty); - portp = tty->driver_data; - if (portp == NULL) - return 0; - if (portp->brdnr >= stli_nrbrds) - return 0; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; - chbuf = (unsigned char *) buf; - -/* - * All data is now local, shove as much as possible into shared memory. - */ - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - head = (unsigned int) readw(&ap->txq.head); - tail = (unsigned int) readw(&ap->txq.tail); - if (tail != ((unsigned int) readw(&ap->txq.tail))) - tail = (unsigned int) readw(&ap->txq.tail); - size = portp->txsize; - if (head >= tail) { - len = size - (head - tail) - 1; - stlen = size - head; - } else { - len = tail - head - 1; - stlen = len; - } - - len = min(len, (unsigned int)count); - count = 0; - shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset); - - while (len > 0) { - stlen = min(len, stlen); - memcpy_toio(shbuf + head, chbuf, stlen); - chbuf += stlen; - len -= stlen; - count += stlen; - head += stlen; - if (head >= size) { - head = 0; - stlen = tail; - } - } - - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - writew(head, &ap->txq.head); - if (test_bit(ST_TXBUSY, &portp->state)) { - if (readl(&ap->changed.data) & DT_TXEMPTY) - writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data); - } - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + - portp->portidx; - writeb(readb(bits) | portp->portbit, bits); - set_bit(ST_TXBUSY, &portp->state); - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - - return(count); -} - -/*****************************************************************************/ - -/* - * Output a single character. We put it into a temporary local buffer - * (for speed) then write out that buffer when the flushchars routine - * is called. There is a safety catch here so that if some other port - * writes chars before the current buffer has been, then we write them - * first them do the new ports. - */ - -static int stli_putchar(struct tty_struct *tty, unsigned char ch) -{ - if (tty != stli_txcooktty) { - if (stli_txcooktty != NULL) - stli_flushchars(stli_txcooktty); - stli_txcooktty = tty; - } - - stli_txcookbuf[stli_txcooksize++] = ch; - return 0; -} - -/*****************************************************************************/ - -/* - * Transfer characters from the local TX cooking buffer to the board. - * We sort of ignore the tty that gets passed in here. We rely on the - * info stored with the TX cook buffer to tell us which port to flush - * the data on. In any case we clean out the TX cook buffer, for re-use - * by someone else. - */ - -static void stli_flushchars(struct tty_struct *tty) -{ - cdkhdr_t __iomem *hdrp; - unsigned char __iomem *bits; - cdkasy_t __iomem *ap; - struct tty_struct *cooktty; - struct stliport *portp; - struct stlibrd *brdp; - unsigned int len, stlen, head, tail, size, count, cooksize; - unsigned char *buf; - unsigned char __iomem *shbuf; - unsigned long flags; - - cooksize = stli_txcooksize; - cooktty = stli_txcooktty; - stli_txcooksize = 0; - stli_txcookrealsize = 0; - stli_txcooktty = NULL; - - if (cooktty == NULL) - return; - if (tty != cooktty) - tty = cooktty; - if (cooksize == 0) - return; - - portp = tty->driver_data; - if (portp == NULL) - return; - if (portp->brdnr >= stli_nrbrds) - return; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - head = (unsigned int) readw(&ap->txq.head); - tail = (unsigned int) readw(&ap->txq.tail); - if (tail != ((unsigned int) readw(&ap->txq.tail))) - tail = (unsigned int) readw(&ap->txq.tail); - size = portp->txsize; - if (head >= tail) { - len = size - (head - tail) - 1; - stlen = size - head; - } else { - len = tail - head - 1; - stlen = len; - } - - len = min(len, cooksize); - count = 0; - shbuf = EBRDGETMEMPTR(brdp, portp->txoffset); - buf = stli_txcookbuf; - - while (len > 0) { - stlen = min(len, stlen); - memcpy_toio(shbuf + head, buf, stlen); - buf += stlen; - len -= stlen; - count += stlen; - head += stlen; - if (head >= size) { - head = 0; - stlen = tail; - } - } - - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - writew(head, &ap->txq.head); - - if (test_bit(ST_TXBUSY, &portp->state)) { - if (readl(&ap->changed.data) & DT_TXEMPTY) - writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data); - } - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + - portp->portidx; - writeb(readb(bits) | portp->portbit, bits); - set_bit(ST_TXBUSY, &portp->state); - - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -static int stli_writeroom(struct tty_struct *tty) -{ - cdkasyrq_t __iomem *rp; - struct stliport *portp; - struct stlibrd *brdp; - unsigned int head, tail, len; - unsigned long flags; - - if (tty == stli_txcooktty) { - if (stli_txcookrealsize != 0) { - len = stli_txcookrealsize - stli_txcooksize; - return len; - } - } - - portp = tty->driver_data; - if (portp == NULL) - return 0; - if (portp->brdnr >= stli_nrbrds) - return 0; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; - - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq; - head = (unsigned int) readw(&rp->head); - tail = (unsigned int) readw(&rp->tail); - if (tail != ((unsigned int) readw(&rp->tail))) - tail = (unsigned int) readw(&rp->tail); - len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head); - len--; - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - - if (tty == stli_txcooktty) { - stli_txcookrealsize = len; - len -= stli_txcooksize; - } - return len; -} - -/*****************************************************************************/ - -/* - * Return the number of characters in the transmit buffer. Normally we - * will return the number of chars in the shared memory ring queue. - * We need to kludge around the case where the shared memory buffer is - * empty but not all characters have drained yet, for this case just - * return that there is 1 character in the buffer! - */ - -static int stli_charsinbuffer(struct tty_struct *tty) -{ - cdkasyrq_t __iomem *rp; - struct stliport *portp; - struct stlibrd *brdp; - unsigned int head, tail, len; - unsigned long flags; - - if (tty == stli_txcooktty) - stli_flushchars(tty); - portp = tty->driver_data; - if (portp == NULL) - return 0; - if (portp->brdnr >= stli_nrbrds) - return 0; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; - - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq; - head = (unsigned int) readw(&rp->head); - tail = (unsigned int) readw(&rp->tail); - if (tail != ((unsigned int) readw(&rp->tail))) - tail = (unsigned int) readw(&rp->tail); - len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head)); - if ((len == 0) && test_bit(ST_TXBUSY, &portp->state)) - len = 1; - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - - return len; -} - -/*****************************************************************************/ - -/* - * Generate the serial struct info. - */ - -static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp) -{ - struct serial_struct sio; - struct stlibrd *brdp; - - memset(&sio, 0, sizeof(struct serial_struct)); - sio.type = PORT_UNKNOWN; - sio.line = portp->portnr; - sio.irq = 0; - sio.flags = portp->port.flags; - sio.baud_base = portp->baud_base; - sio.close_delay = portp->port.close_delay; - sio.closing_wait = portp->closing_wait; - sio.custom_divisor = portp->custom_divisor; - sio.xmit_fifo_size = 0; - sio.hub6 = 0; - - brdp = stli_brds[portp->brdnr]; - if (brdp != NULL) - sio.port = brdp->iobase; - - return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? - -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Set port according to the serial struct info. - * At this point we do not do any auto-configure stuff, so we will - * just quietly ignore any requests to change irq, etc. - */ - -static int stli_setserial(struct tty_struct *tty, struct serial_struct __user *sp) -{ - struct serial_struct sio; - int rc; - struct stliport *portp = tty->driver_data; - - if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) - return -EFAULT; - if (!capable(CAP_SYS_ADMIN)) { - if ((sio.baud_base != portp->baud_base) || - (sio.close_delay != portp->port.close_delay) || - ((sio.flags & ~ASYNC_USR_MASK) != - (portp->port.flags & ~ASYNC_USR_MASK))) - return -EPERM; - } - - portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) | - (sio.flags & ASYNC_USR_MASK); - portp->baud_base = sio.baud_base; - portp->port.close_delay = sio.close_delay; - portp->closing_wait = sio.closing_wait; - portp->custom_divisor = sio.custom_divisor; - - if ((rc = stli_setport(tty)) < 0) - return rc; - return 0; -} - -/*****************************************************************************/ - -static int stli_tiocmget(struct tty_struct *tty) -{ - struct stliport *portp = tty->driver_data; - struct stlibrd *brdp; - int rc; - - if (portp == NULL) - return -ENODEV; - if (portp->brdnr >= stli_nrbrds) - return 0; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, - &portp->asig, sizeof(asysigs_t), 1)) < 0) - return rc; - - return stli_mktiocm(portp->asig.sigvalue); -} - -static int stli_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct stliport *portp = tty->driver_data; - struct stlibrd *brdp; - int rts = -1, dtr = -1; - - if (portp == NULL) - return -ENODEV; - if (portp->brdnr >= stli_nrbrds) - return 0; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - if (set & TIOCM_RTS) - rts = 1; - if (set & TIOCM_DTR) - dtr = 1; - if (clear & TIOCM_RTS) - rts = 0; - if (clear & TIOCM_DTR) - dtr = 0; - - stli_mkasysigs(&portp->asig, dtr, rts); - - return stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, - sizeof(asysigs_t), 0); -} - -static int stli_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) -{ - struct stliport *portp; - struct stlibrd *brdp; - int rc; - void __user *argp = (void __user *)arg; - - portp = tty->driver_data; - if (portp == NULL) - return -ENODEV; - if (portp->brdnr >= stli_nrbrds) - return 0; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - rc = 0; - - switch (cmd) { - case TIOCGSERIAL: - rc = stli_getserial(portp, argp); - break; - case TIOCSSERIAL: - rc = stli_setserial(tty, argp); - break; - case STL_GETPFLAG: - rc = put_user(portp->pflag, (unsigned __user *)argp); - break; - case STL_SETPFLAG: - if ((rc = get_user(portp->pflag, (unsigned __user *)argp)) == 0) - stli_setport(tty); - break; - case COM_GETPORTSTATS: - rc = stli_getportstats(tty, portp, argp); - break; - case COM_CLRPORTSTATS: - rc = stli_clrportstats(portp, argp); - break; - case TIOCSERCONFIG: - case TIOCSERGWILD: - case TIOCSERSWILD: - case TIOCSERGETLSR: - case TIOCSERGSTRUCT: - case TIOCSERGETMULTI: - case TIOCSERSETMULTI: - default: - rc = -ENOIOCTLCMD; - break; - } - - return rc; -} - -/*****************************************************************************/ - -/* - * This routine assumes that we have user context and can sleep. - * Looks like it is true for the current ttys implementation..!! - */ - -static void stli_settermios(struct tty_struct *tty, struct ktermios *old) -{ - struct stliport *portp; - struct stlibrd *brdp; - struct ktermios *tiosp; - asyport_t aport; - - portp = tty->driver_data; - if (portp == NULL) - return; - if (portp->brdnr >= stli_nrbrds) - return; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return; - - tiosp = tty->termios; - - stli_mkasyport(tty, portp, &aport, tiosp); - stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0); - stli_mkasysigs(&portp->asig, ((tiosp->c_cflag & CBAUD) ? 1 : 0), -1); - stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, - sizeof(asysigs_t), 0); - if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0)) - tty->hw_stopped = 0; - if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL)) - wake_up_interruptible(&portp->port.open_wait); -} - -/*****************************************************************************/ - -/* - * Attempt to flow control who ever is sending us data. We won't really - * do any flow control action here. We can't directly, and even if we - * wanted to we would have to send a command to the slave. The slave - * knows how to flow control, and will do so when its buffers reach its - * internal high water marks. So what we will do is set a local state - * bit that will stop us sending any RX data up from the poll routine - * (which is the place where RX data from the slave is handled). - */ - -static void stli_throttle(struct tty_struct *tty) -{ - struct stliport *portp = tty->driver_data; - if (portp == NULL) - return; - set_bit(ST_RXSTOP, &portp->state); -} - -/*****************************************************************************/ - -/* - * Unflow control the device sending us data... That means that all - * we have to do is clear the RXSTOP state bit. The next poll call - * will then be able to pass the RX data back up. - */ - -static void stli_unthrottle(struct tty_struct *tty) -{ - struct stliport *portp = tty->driver_data; - if (portp == NULL) - return; - clear_bit(ST_RXSTOP, &portp->state); -} - -/*****************************************************************************/ - -/* - * Stop the transmitter. - */ - -static void stli_stop(struct tty_struct *tty) -{ -} - -/*****************************************************************************/ - -/* - * Start the transmitter again. - */ - -static void stli_start(struct tty_struct *tty) -{ -} - -/*****************************************************************************/ - - -/* - * Hangup this port. This is pretty much like closing the port, only - * a little more brutal. No waiting for data to drain. Shutdown the - * port and maybe drop signals. This is rather tricky really. We want - * to close the port as well. - */ - -static void stli_hangup(struct tty_struct *tty) -{ - struct stliport *portp = tty->driver_data; - tty_port_hangup(&portp->port); -} - -/*****************************************************************************/ - -/* - * Flush characters from the lower buffer. We may not have user context - * so we cannot sleep waiting for it to complete. Also we need to check - * if there is chars for this port in the TX cook buffer, and flush them - * as well. - */ - -static void stli_flushbuffer(struct tty_struct *tty) -{ - struct stliport *portp; - struct stlibrd *brdp; - unsigned long ftype, flags; - - portp = tty->driver_data; - if (portp == NULL) - return; - if (portp->brdnr >= stli_nrbrds) - return; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - if (tty == stli_txcooktty) { - stli_txcooktty = NULL; - stli_txcooksize = 0; - stli_txcookrealsize = 0; - } - if (test_bit(ST_CMDING, &portp->state)) { - set_bit(ST_DOFLUSHTX, &portp->state); - } else { - ftype = FLUSHTX; - if (test_bit(ST_DOFLUSHRX, &portp->state)) { - ftype |= FLUSHRX; - clear_bit(ST_DOFLUSHRX, &portp->state); - } - __stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0); - } - spin_unlock_irqrestore(&brd_lock, flags); - tty_wakeup(tty); -} - -/*****************************************************************************/ - -static int stli_breakctl(struct tty_struct *tty, int state) -{ - struct stlibrd *brdp; - struct stliport *portp; - long arg; - - portp = tty->driver_data; - if (portp == NULL) - return -EINVAL; - if (portp->brdnr >= stli_nrbrds) - return -EINVAL; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return -EINVAL; - - arg = (state == -1) ? BREAKON : BREAKOFF; - stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0); - return 0; -} - -/*****************************************************************************/ - -static void stli_waituntilsent(struct tty_struct *tty, int timeout) -{ - struct stliport *portp; - unsigned long tend; - - portp = tty->driver_data; - if (portp == NULL) - return; - - if (timeout == 0) - timeout = HZ; - tend = jiffies + timeout; - - while (test_bit(ST_TXBUSY, &portp->state)) { - if (signal_pending(current)) - break; - msleep_interruptible(20); - if (time_after_eq(jiffies, tend)) - break; - } -} - -/*****************************************************************************/ - -static void stli_sendxchar(struct tty_struct *tty, char ch) -{ - struct stlibrd *brdp; - struct stliport *portp; - asyctrl_t actrl; - - portp = tty->driver_data; - if (portp == NULL) - return; - if (portp->brdnr >= stli_nrbrds) - return; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return; - - memset(&actrl, 0, sizeof(asyctrl_t)); - if (ch == STOP_CHAR(tty)) { - actrl.rxctrl = CT_STOPFLOW; - } else if (ch == START_CHAR(tty)) { - actrl.rxctrl = CT_STARTFLOW; - } else { - actrl.txctrl = CT_SENDCHR; - actrl.tximdch = ch; - } - stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); -} - -static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stliport *portp, int portnr) -{ - char *uart; - int rc; - - rc = stli_portcmdstats(NULL, portp); - - uart = "UNKNOWN"; - if (test_bit(BST_STARTED, &brdp->state)) { - switch (stli_comstats.hwid) { - case 0: uart = "2681"; break; - case 1: uart = "SC26198"; break; - default:uart = "CD1400"; break; - } - } - seq_printf(m, "%d: uart:%s ", portnr, uart); - - if (test_bit(BST_STARTED, &brdp->state) && rc >= 0) { - char sep; - - seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal, - (int) stli_comstats.rxtotal); - - if (stli_comstats.rxframing) - seq_printf(m, " fe:%d", - (int) stli_comstats.rxframing); - if (stli_comstats.rxparity) - seq_printf(m, " pe:%d", - (int) stli_comstats.rxparity); - if (stli_comstats.rxbreaks) - seq_printf(m, " brk:%d", - (int) stli_comstats.rxbreaks); - if (stli_comstats.rxoverrun) - seq_printf(m, " oe:%d", - (int) stli_comstats.rxoverrun); - - sep = ' '; - if (stli_comstats.signals & TIOCM_RTS) { - seq_printf(m, "%c%s", sep, "RTS"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_CTS) { - seq_printf(m, "%c%s", sep, "CTS"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_DTR) { - seq_printf(m, "%c%s", sep, "DTR"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_CD) { - seq_printf(m, "%c%s", sep, "DCD"); - sep = '|'; - } - if (stli_comstats.signals & TIOCM_DSR) { - seq_printf(m, "%c%s", sep, "DSR"); - sep = '|'; - } - } - seq_putc(m, '\n'); -} - -/*****************************************************************************/ - -/* - * Port info, read from the /proc file system. - */ - -static int stli_proc_show(struct seq_file *m, void *v) -{ - struct stlibrd *brdp; - struct stliport *portp; - unsigned int brdnr, portnr, totalport; - - totalport = 0; - - seq_printf(m, "%s: version %s\n", stli_drvtitle, stli_drvversion); - -/* - * We scan through for each board, panel and port. The offset is - * calculated on the fly, and irrelevant ports are skipped. - */ - for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { - brdp = stli_brds[brdnr]; - if (brdp == NULL) - continue; - if (brdp->state == 0) - continue; - - totalport = brdnr * STL_MAXPORTS; - for (portnr = 0; (portnr < brdp->nrports); portnr++, - totalport++) { - portp = brdp->ports[portnr]; - if (portp == NULL) - continue; - stli_portinfo(m, brdp, portp, totalport); - } - } - return 0; -} - -static int stli_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, stli_proc_show, NULL); -} - -static const struct file_operations stli_proc_fops = { - .owner = THIS_MODULE, - .open = stli_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/*****************************************************************************/ - -/* - * Generic send command routine. This will send a message to the slave, - * of the specified type with the specified argument. Must be very - * careful of data that will be copied out from shared memory - - * containing command results. The command completion is all done from - * a poll routine that does not have user context. Therefore you cannot - * copy back directly into user space, or to the kernel stack of a - * process. This routine does not sleep, so can be called from anywhere. - * - * The caller must hold the brd_lock (see also stli_sendcmd the usual - * entry point) - */ - -static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) -{ - cdkhdr_t __iomem *hdrp; - cdkctrl_t __iomem *cp; - unsigned char __iomem *bits; - - if (test_bit(ST_CMDING, &portp->state)) { - printk(KERN_ERR "istallion: command already busy, cmd=%x!\n", - (int) cmd); - return; - } - - EBRDENABLE(brdp); - cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; - if (size > 0) { - memcpy_toio((void __iomem *) &(cp->args[0]), arg, size); - if (copyback) { - portp->argp = arg; - portp->argsize = size; - } - } - writel(0, &cp->status); - writel(cmd, &cp->cmd); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + - portp->portidx; - writeb(readb(bits) | portp->portbit, bits); - set_bit(ST_CMDING, &portp->state); - EBRDDISABLE(brdp); -} - -static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) -{ - unsigned long flags; - - spin_lock_irqsave(&brd_lock, flags); - __stli_sendcmd(brdp, portp, cmd, arg, size, copyback); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Read data from shared memory. This assumes that the shared memory - * is enabled and that interrupts are off. Basically we just empty out - * the shared memory buffer into the tty buffer. Must be careful to - * handle the case where we fill up the tty buffer, but still have - * more chars to unload. - */ - -static void stli_read(struct stlibrd *brdp, struct stliport *portp) -{ - cdkasyrq_t __iomem *rp; - char __iomem *shbuf; - struct tty_struct *tty; - unsigned int head, tail, size; - unsigned int len, stlen; - - if (test_bit(ST_RXSTOP, &portp->state)) - return; - tty = tty_port_tty_get(&portp->port); - if (tty == NULL) - return; - - rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; - head = (unsigned int) readw(&rp->head); - if (head != ((unsigned int) readw(&rp->head))) - head = (unsigned int) readw(&rp->head); - tail = (unsigned int) readw(&rp->tail); - size = portp->rxsize; - if (head >= tail) { - len = head - tail; - stlen = len; - } else { - len = size - (tail - head); - stlen = size - tail; - } - - len = tty_buffer_request_room(tty, len); - - shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->rxoffset); - - while (len > 0) { - unsigned char *cptr; - - stlen = min(len, stlen); - tty_prepare_flip_string(tty, &cptr, stlen); - memcpy_fromio(cptr, shbuf + tail, stlen); - len -= stlen; - tail += stlen; - if (tail >= size) { - tail = 0; - stlen = head; - } - } - rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; - writew(tail, &rp->tail); - - if (head != tail) - set_bit(ST_RXING, &portp->state); - - tty_schedule_flip(tty); - tty_kref_put(tty); -} - -/*****************************************************************************/ - -/* - * Set up and carry out any delayed commands. There is only a small set - * of slave commands that can be done "off-level". So it is not too - * difficult to deal with them here. - */ - -static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp) -{ - int cmd; - - if (test_bit(ST_DOSIGS, &portp->state)) { - if (test_bit(ST_DOFLUSHTX, &portp->state) && - test_bit(ST_DOFLUSHRX, &portp->state)) - cmd = A_SETSIGNALSF; - else if (test_bit(ST_DOFLUSHTX, &portp->state)) - cmd = A_SETSIGNALSFTX; - else if (test_bit(ST_DOFLUSHRX, &portp->state)) - cmd = A_SETSIGNALSFRX; - else - cmd = A_SETSIGNALS; - clear_bit(ST_DOFLUSHTX, &portp->state); - clear_bit(ST_DOFLUSHRX, &portp->state); - clear_bit(ST_DOSIGS, &portp->state); - memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &portp->asig, - sizeof(asysigs_t)); - writel(0, &cp->status); - writel(cmd, &cp->cmd); - set_bit(ST_CMDING, &portp->state); - } else if (test_bit(ST_DOFLUSHTX, &portp->state) || - test_bit(ST_DOFLUSHRX, &portp->state)) { - cmd = ((test_bit(ST_DOFLUSHTX, &portp->state)) ? FLUSHTX : 0); - cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0); - clear_bit(ST_DOFLUSHTX, &portp->state); - clear_bit(ST_DOFLUSHRX, &portp->state); - memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &cmd, sizeof(int)); - writel(0, &cp->status); - writel(A_FLUSH, &cp->cmd); - set_bit(ST_CMDING, &portp->state); - } -} - -/*****************************************************************************/ - -/* - * Host command service checking. This handles commands or messages - * coming from the slave to the host. Must have board shared memory - * enabled and interrupts off when called. Notice that by servicing the - * read data last we don't need to change the shared memory pointer - * during processing (which is a slow IO operation). - * Return value indicates if this port is still awaiting actions from - * the slave (like open, command, or even TX data being sent). If 0 - * then port is still busy, otherwise no longer busy. - */ - -static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) -{ - cdkasy_t __iomem *ap; - cdkctrl_t __iomem *cp; - struct tty_struct *tty; - asynotify_t nt; - unsigned long oldsigs; - int rc, donerx; - - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - cp = &ap->ctrl; - -/* - * Check if we are waiting for an open completion message. - */ - if (test_bit(ST_OPENING, &portp->state)) { - rc = readl(&cp->openarg); - if (readb(&cp->open) == 0 && rc != 0) { - if (rc > 0) - rc--; - writel(0, &cp->openarg); - portp->rc = rc; - clear_bit(ST_OPENING, &portp->state); - wake_up_interruptible(&portp->raw_wait); - } - } - -/* - * Check if we are waiting for a close completion message. - */ - if (test_bit(ST_CLOSING, &portp->state)) { - rc = (int) readl(&cp->closearg); - if (readb(&cp->close) == 0 && rc != 0) { - if (rc > 0) - rc--; - writel(0, &cp->closearg); - portp->rc = rc; - clear_bit(ST_CLOSING, &portp->state); - wake_up_interruptible(&portp->raw_wait); - } - } - -/* - * Check if we are waiting for a command completion message. We may - * need to copy out the command results associated with this command. - */ - if (test_bit(ST_CMDING, &portp->state)) { - rc = readl(&cp->status); - if (readl(&cp->cmd) == 0 && rc != 0) { - if (rc > 0) - rc--; - if (portp->argp != NULL) { - memcpy_fromio(portp->argp, (void __iomem *) &(cp->args[0]), - portp->argsize); - portp->argp = NULL; - } - writel(0, &cp->status); - portp->rc = rc; - clear_bit(ST_CMDING, &portp->state); - stli_dodelaycmd(portp, cp); - wake_up_interruptible(&portp->raw_wait); - } - } - -/* - * Check for any notification messages ready. This includes lots of - * different types of events - RX chars ready, RX break received, - * TX data low or empty in the slave, modem signals changed state. - */ - donerx = 0; - - if (ap->notify) { - nt = ap->changed; - ap->notify = 0; - tty = tty_port_tty_get(&portp->port); - - if (nt.signal & SG_DCD) { - oldsigs = portp->sigs; - portp->sigs = stli_mktiocm(nt.sigvalue); - clear_bit(ST_GETSIGS, &portp->state); - if ((portp->sigs & TIOCM_CD) && - ((oldsigs & TIOCM_CD) == 0)) - wake_up_interruptible(&portp->port.open_wait); - if ((oldsigs & TIOCM_CD) && - ((portp->sigs & TIOCM_CD) == 0)) { - if (portp->port.flags & ASYNC_CHECK_CD) { - if (tty) - tty_hangup(tty); - } - } - } - - if (nt.data & DT_TXEMPTY) - clear_bit(ST_TXBUSY, &portp->state); - if (nt.data & (DT_TXEMPTY | DT_TXLOW)) { - if (tty != NULL) { - tty_wakeup(tty); - EBRDENABLE(brdp); - } - } - - if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { - if (tty != NULL) { - tty_insert_flip_char(tty, 0, TTY_BREAK); - if (portp->port.flags & ASYNC_SAK) { - do_SAK(tty); - EBRDENABLE(brdp); - } - tty_schedule_flip(tty); - } - } - tty_kref_put(tty); - - if (nt.data & DT_RXBUSY) { - donerx++; - stli_read(brdp, portp); - } - } - -/* - * It might seem odd that we are checking for more RX chars here. - * But, we need to handle the case where the tty buffer was previously - * filled, but we had more characters to pass up. The slave will not - * send any more RX notify messages until the RX buffer has been emptied. - * But it will leave the service bits on (since the buffer is not empty). - * So from here we can try to process more RX chars. - */ - if ((!donerx) && test_bit(ST_RXING, &portp->state)) { - clear_bit(ST_RXING, &portp->state); - stli_read(brdp, portp); - } - - return((test_bit(ST_OPENING, &portp->state) || - test_bit(ST_CLOSING, &portp->state) || - test_bit(ST_CMDING, &portp->state) || - test_bit(ST_TXBUSY, &portp->state) || - test_bit(ST_RXING, &portp->state)) ? 0 : 1); -} - -/*****************************************************************************/ - -/* - * Service all ports on a particular board. Assumes that the boards - * shared memory is enabled, and that the page pointer is pointed - * at the cdk header structure. - */ - -static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp) -{ - struct stliport *portp; - unsigned char hostbits[(STL_MAXCHANS / 8) + 1]; - unsigned char slavebits[(STL_MAXCHANS / 8) + 1]; - unsigned char __iomem *slavep; - int bitpos, bitat, bitsize; - int channr, nrdevs, slavebitchange; - - bitsize = brdp->bitsize; - nrdevs = brdp->nrdevs; - -/* - * Check if slave wants any service. Basically we try to do as - * little work as possible here. There are 2 levels of service - * bits. So if there is nothing to do we bail early. We check - * 8 service bits at a time in the inner loop, so we can bypass - * the lot if none of them want service. - */ - memcpy_fromio(&hostbits[0], (((unsigned char __iomem *) hdrp) + brdp->hostoffset), - bitsize); - - memset(&slavebits[0], 0, bitsize); - slavebitchange = 0; - - for (bitpos = 0; (bitpos < bitsize); bitpos++) { - if (hostbits[bitpos] == 0) - continue; - channr = bitpos * 8; - for (bitat = 0x1; (channr < nrdevs); channr++, bitat <<= 1) { - if (hostbits[bitpos] & bitat) { - portp = brdp->ports[(channr - 1)]; - if (stli_hostcmd(brdp, portp)) { - slavebitchange++; - slavebits[bitpos] |= bitat; - } - } - } - } - -/* - * If any of the ports are no longer busy then update them in the - * slave request bits. We need to do this after, since a host port - * service may initiate more slave requests. - */ - if (slavebitchange) { - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - slavep = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset; - for (bitpos = 0; (bitpos < bitsize); bitpos++) { - if (readb(slavebits + bitpos)) - writeb(readb(slavep + bitpos) & ~slavebits[bitpos], slavebits + bitpos); - } - } -} - -/*****************************************************************************/ - -/* - * Driver poll routine. This routine polls the boards in use and passes - * messages back up to host when necessary. This is actually very - * CPU efficient, since we will always have the kernel poll clock, it - * adds only a few cycles when idle (since board service can be - * determined very easily), but when loaded generates no interrupts - * (with their expensive associated context change). - */ - -static void stli_poll(unsigned long arg) -{ - cdkhdr_t __iomem *hdrp; - struct stlibrd *brdp; - unsigned int brdnr; - - mod_timer(&stli_timerlist, STLI_TIMEOUT); - -/* - * Check each board and do any servicing required. - */ - for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { - brdp = stli_brds[brdnr]; - if (brdp == NULL) - continue; - if (!test_bit(BST_STARTED, &brdp->state)) - continue; - - spin_lock(&brd_lock); - EBRDENABLE(brdp); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - if (readb(&hdrp->hostreq)) - stli_brdpoll(brdp, hdrp); - EBRDDISABLE(brdp); - spin_unlock(&brd_lock); - } -} - -/*****************************************************************************/ - -/* - * Translate the termios settings into the port setting structure of - * the slave. - */ - -static void stli_mkasyport(struct tty_struct *tty, struct stliport *portp, - asyport_t *pp, struct ktermios *tiosp) -{ - memset(pp, 0, sizeof(asyport_t)); - -/* - * Start of by setting the baud, char size, parity and stop bit info. - */ - pp->baudout = tty_get_baud_rate(tty); - if ((tiosp->c_cflag & CBAUD) == B38400) { - if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - pp->baudout = 57600; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - pp->baudout = 115200; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - pp->baudout = 230400; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - pp->baudout = 460800; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) - pp->baudout = (portp->baud_base / portp->custom_divisor); - } - if (pp->baudout > STL_MAXBAUD) - pp->baudout = STL_MAXBAUD; - pp->baudin = pp->baudout; - - switch (tiosp->c_cflag & CSIZE) { - case CS5: - pp->csize = 5; - break; - case CS6: - pp->csize = 6; - break; - case CS7: - pp->csize = 7; - break; - default: - pp->csize = 8; - break; - } - - if (tiosp->c_cflag & CSTOPB) - pp->stopbs = PT_STOP2; - else - pp->stopbs = PT_STOP1; - - if (tiosp->c_cflag & PARENB) { - if (tiosp->c_cflag & PARODD) - pp->parity = PT_ODDPARITY; - else - pp->parity = PT_EVENPARITY; - } else { - pp->parity = PT_NOPARITY; - } - -/* - * Set up any flow control options enabled. - */ - if (tiosp->c_iflag & IXON) { - pp->flow |= F_IXON; - if (tiosp->c_iflag & IXANY) - pp->flow |= F_IXANY; - } - if (tiosp->c_cflag & CRTSCTS) - pp->flow |= (F_RTSFLOW | F_CTSFLOW); - - pp->startin = tiosp->c_cc[VSTART]; - pp->stopin = tiosp->c_cc[VSTOP]; - pp->startout = tiosp->c_cc[VSTART]; - pp->stopout = tiosp->c_cc[VSTOP]; - -/* - * Set up the RX char marking mask with those RX error types we must - * catch. We can get the slave to help us out a little here, it will - * ignore parity errors and breaks for us, and mark parity errors in - * the data stream. - */ - if (tiosp->c_iflag & IGNPAR) - pp->iflag |= FI_IGNRXERRS; - if (tiosp->c_iflag & IGNBRK) - pp->iflag |= FI_IGNBREAK; - - portp->rxmarkmsk = 0; - if (tiosp->c_iflag & (INPCK | PARMRK)) - pp->iflag |= FI_1MARKRXERRS; - if (tiosp->c_iflag & BRKINT) - portp->rxmarkmsk |= BRKINT; - -/* - * Set up clocal processing as required. - */ - if (tiosp->c_cflag & CLOCAL) - portp->port.flags &= ~ASYNC_CHECK_CD; - else - portp->port.flags |= ASYNC_CHECK_CD; - -/* - * Transfer any persistent flags into the asyport structure. - */ - pp->pflag = (portp->pflag & 0xffff); - pp->vmin = (portp->pflag & P_RXIMIN) ? 1 : 0; - pp->vtime = (portp->pflag & P_RXITIME) ? 1 : 0; - pp->cc[1] = (portp->pflag & P_RXTHOLD) ? 1 : 0; -} - -/*****************************************************************************/ - -/* - * Construct a slave signals structure for setting the DTR and RTS - * signals as specified. - */ - -static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts) -{ - memset(sp, 0, sizeof(asysigs_t)); - if (dtr >= 0) { - sp->signal |= SG_DTR; - sp->sigvalue |= ((dtr > 0) ? SG_DTR : 0); - } - if (rts >= 0) { - sp->signal |= SG_RTS; - sp->sigvalue |= ((rts > 0) ? SG_RTS : 0); - } -} - -/*****************************************************************************/ - -/* - * Convert the signals returned from the slave into a local TIOCM type - * signals value. We keep them locally in TIOCM format. - */ - -static long stli_mktiocm(unsigned long sigvalue) -{ - long tiocm = 0; - tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0); - tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0); - tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0); - tiocm |= ((sigvalue & SG_DSR) ? TIOCM_DSR : 0); - tiocm |= ((sigvalue & SG_DTR) ? TIOCM_DTR : 0); - tiocm |= ((sigvalue & SG_RTS) ? TIOCM_RTS : 0); - return(tiocm); -} - -/*****************************************************************************/ - -/* - * All panels and ports actually attached have been worked out. All - * we need to do here is set up the appropriate per port data structures. - */ - -static int stli_initports(struct stlibrd *brdp) -{ - struct stliport *portp; - unsigned int i, panelnr, panelport; - - for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { - portp = kzalloc(sizeof(struct stliport), GFP_KERNEL); - if (!portp) { - printk(KERN_WARNING "istallion: failed to allocate port structure\n"); - continue; - } - tty_port_init(&portp->port); - portp->port.ops = &stli_port_ops; - portp->magic = STLI_PORTMAGIC; - portp->portnr = i; - portp->brdnr = brdp->brdnr; - portp->panelnr = panelnr; - portp->baud_base = STL_BAUDBASE; - portp->port.close_delay = STL_CLOSEDELAY; - portp->closing_wait = 30 * HZ; - init_waitqueue_head(&portp->port.open_wait); - init_waitqueue_head(&portp->port.close_wait); - init_waitqueue_head(&portp->raw_wait); - panelport++; - if (panelport >= brdp->panels[panelnr]) { - panelport = 0; - panelnr++; - } - brdp->ports[i] = portp; - } - - return 0; -} - -/*****************************************************************************/ - -/* - * All the following routines are board specific hardware operations. - */ - -static void stli_ecpinit(struct stlibrd *brdp) -{ - unsigned long memconf; - - outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); - udelay(10); - outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); - udelay(100); - - memconf = (brdp->memaddr & ECP_ATADDRMASK) >> ECP_ATADDRSHFT; - outb(memconf, (brdp->iobase + ECP_ATMEMAR)); -} - -/*****************************************************************************/ - -static void stli_ecpenable(struct stlibrd *brdp) -{ - outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR)); -} - -/*****************************************************************************/ - -static void stli_ecpdisable(struct stlibrd *brdp) -{ - outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); -} - -/*****************************************************************************/ - -static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - unsigned char val; - - if (offset > brdp->memsize) { - printk(KERN_ERR "istallion: shared memory pointer=%x out of " - "range at line=%d(%d), brd=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - val = 0; - } else { - ptr = brdp->membase + (offset % ECP_ATPAGESIZE); - val = (unsigned char) (offset / ECP_ATPAGESIZE); - } - outb(val, (brdp->iobase + ECP_ATMEMPR)); - return(ptr); -} - -/*****************************************************************************/ - -static void stli_ecpreset(struct stlibrd *brdp) -{ - outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); - udelay(10); - outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); - udelay(500); -} - -/*****************************************************************************/ - -static void stli_ecpintr(struct stlibrd *brdp) -{ - outb(0x1, brdp->iobase); -} - -/*****************************************************************************/ - -/* - * The following set of functions act on ECP EISA boards. - */ - -static void stli_ecpeiinit(struct stlibrd *brdp) -{ - unsigned long memconf; - - outb(0x1, (brdp->iobase + ECP_EIBRDENAB)); - outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); - udelay(10); - outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); - udelay(500); - - memconf = (brdp->memaddr & ECP_EIADDRMASKL) >> ECP_EIADDRSHFTL; - outb(memconf, (brdp->iobase + ECP_EIMEMARL)); - memconf = (brdp->memaddr & ECP_EIADDRMASKH) >> ECP_EIADDRSHFTH; - outb(memconf, (brdp->iobase + ECP_EIMEMARH)); -} - -/*****************************************************************************/ - -static void stli_ecpeienable(struct stlibrd *brdp) -{ - outb(ECP_EIENABLE, (brdp->iobase + ECP_EICONFR)); -} - -/*****************************************************************************/ - -static void stli_ecpeidisable(struct stlibrd *brdp) -{ - outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); -} - -/*****************************************************************************/ - -static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - unsigned char val; - - if (offset > brdp->memsize) { - printk(KERN_ERR "istallion: shared memory pointer=%x out of " - "range at line=%d(%d), brd=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - val = 0; - } else { - ptr = brdp->membase + (offset % ECP_EIPAGESIZE); - if (offset < ECP_EIPAGESIZE) - val = ECP_EIENABLE; - else - val = ECP_EIENABLE | 0x40; - } - outb(val, (brdp->iobase + ECP_EICONFR)); - return(ptr); -} - -/*****************************************************************************/ - -static void stli_ecpeireset(struct stlibrd *brdp) -{ - outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); - udelay(10); - outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); - udelay(500); -} - -/*****************************************************************************/ - -/* - * The following set of functions act on ECP MCA boards. - */ - -static void stli_ecpmcenable(struct stlibrd *brdp) -{ - outb(ECP_MCENABLE, (brdp->iobase + ECP_MCCONFR)); -} - -/*****************************************************************************/ - -static void stli_ecpmcdisable(struct stlibrd *brdp) -{ - outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR)); -} - -/*****************************************************************************/ - -static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - unsigned char val; - - if (offset > brdp->memsize) { - printk(KERN_ERR "istallion: shared memory pointer=%x out of " - "range at line=%d(%d), brd=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - val = 0; - } else { - ptr = brdp->membase + (offset % ECP_MCPAGESIZE); - val = ((unsigned char) (offset / ECP_MCPAGESIZE)) | ECP_MCENABLE; - } - outb(val, (brdp->iobase + ECP_MCCONFR)); - return(ptr); -} - -/*****************************************************************************/ - -static void stli_ecpmcreset(struct stlibrd *brdp) -{ - outb(ECP_MCSTOP, (brdp->iobase + ECP_MCCONFR)); - udelay(10); - outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR)); - udelay(500); -} - -/*****************************************************************************/ - -/* - * The following set of functions act on ECP PCI boards. - */ - -static void stli_ecppciinit(struct stlibrd *brdp) -{ - outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); - udelay(10); - outb(0, (brdp->iobase + ECP_PCICONFR)); - udelay(500); -} - -/*****************************************************************************/ - -static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - unsigned char val; - - if (offset > brdp->memsize) { - printk(KERN_ERR "istallion: shared memory pointer=%x out of " - "range at line=%d(%d), board=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - val = 0; - } else { - ptr = brdp->membase + (offset % ECP_PCIPAGESIZE); - val = (offset / ECP_PCIPAGESIZE) << 1; - } - outb(val, (brdp->iobase + ECP_PCICONFR)); - return(ptr); -} - -/*****************************************************************************/ - -static void stli_ecppcireset(struct stlibrd *brdp) -{ - outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); - udelay(10); - outb(0, (brdp->iobase + ECP_PCICONFR)); - udelay(500); -} - -/*****************************************************************************/ - -/* - * The following routines act on ONboards. - */ - -static void stli_onbinit(struct stlibrd *brdp) -{ - unsigned long memconf; - - outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); - udelay(10); - outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); - mdelay(1000); - - memconf = (brdp->memaddr & ONB_ATADDRMASK) >> ONB_ATADDRSHFT; - outb(memconf, (brdp->iobase + ONB_ATMEMAR)); - outb(0x1, brdp->iobase); - mdelay(1); -} - -/*****************************************************************************/ - -static void stli_onbenable(struct stlibrd *brdp) -{ - outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR)); -} - -/*****************************************************************************/ - -static void stli_onbdisable(struct stlibrd *brdp) -{ - outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR)); -} - -/*****************************************************************************/ - -static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - - if (offset > brdp->memsize) { - printk(KERN_ERR "istallion: shared memory pointer=%x out of " - "range at line=%d(%d), brd=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - } else { - ptr = brdp->membase + (offset % ONB_ATPAGESIZE); - } - return(ptr); -} - -/*****************************************************************************/ - -static void stli_onbreset(struct stlibrd *brdp) -{ - outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); - udelay(10); - outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); - mdelay(1000); -} - -/*****************************************************************************/ - -/* - * The following routines act on ONboard EISA. - */ - -static void stli_onbeinit(struct stlibrd *brdp) -{ - unsigned long memconf; - - outb(0x1, (brdp->iobase + ONB_EIBRDENAB)); - outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); - udelay(10); - outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); - mdelay(1000); - - memconf = (brdp->memaddr & ONB_EIADDRMASKL) >> ONB_EIADDRSHFTL; - outb(memconf, (brdp->iobase + ONB_EIMEMARL)); - memconf = (brdp->memaddr & ONB_EIADDRMASKH) >> ONB_EIADDRSHFTH; - outb(memconf, (brdp->iobase + ONB_EIMEMARH)); - outb(0x1, brdp->iobase); - mdelay(1); -} - -/*****************************************************************************/ - -static void stli_onbeenable(struct stlibrd *brdp) -{ - outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR)); -} - -/*****************************************************************************/ - -static void stli_onbedisable(struct stlibrd *brdp) -{ - outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); -} - -/*****************************************************************************/ - -static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - unsigned char val; - - if (offset > brdp->memsize) { - printk(KERN_ERR "istallion: shared memory pointer=%x out of " - "range at line=%d(%d), brd=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - val = 0; - } else { - ptr = brdp->membase + (offset % ONB_EIPAGESIZE); - if (offset < ONB_EIPAGESIZE) - val = ONB_EIENABLE; - else - val = ONB_EIENABLE | 0x40; - } - outb(val, (brdp->iobase + ONB_EICONFR)); - return(ptr); -} - -/*****************************************************************************/ - -static void stli_onbereset(struct stlibrd *brdp) -{ - outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); - udelay(10); - outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); - mdelay(1000); -} - -/*****************************************************************************/ - -/* - * The following routines act on Brumby boards. - */ - -static void stli_bbyinit(struct stlibrd *brdp) -{ - outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); - udelay(10); - outb(0, (brdp->iobase + BBY_ATCONFR)); - mdelay(1000); - outb(0x1, brdp->iobase); - mdelay(1); -} - -/*****************************************************************************/ - -static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - void __iomem *ptr; - unsigned char val; - - BUG_ON(offset > brdp->memsize); - - ptr = brdp->membase + (offset % BBY_PAGESIZE); - val = (unsigned char) (offset / BBY_PAGESIZE); - outb(val, (brdp->iobase + BBY_ATCONFR)); - return(ptr); -} - -/*****************************************************************************/ - -static void stli_bbyreset(struct stlibrd *brdp) -{ - outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); - udelay(10); - outb(0, (brdp->iobase + BBY_ATCONFR)); - mdelay(1000); -} - -/*****************************************************************************/ - -/* - * The following routines act on original old Stallion boards. - */ - -static void stli_stalinit(struct stlibrd *brdp) -{ - outb(0x1, brdp->iobase); - mdelay(1000); -} - -/*****************************************************************************/ - -static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) -{ - BUG_ON(offset > brdp->memsize); - return brdp->membase + (offset % STAL_PAGESIZE); -} - -/*****************************************************************************/ - -static void stli_stalreset(struct stlibrd *brdp) -{ - u32 __iomem *vecp; - - vecp = (u32 __iomem *) (brdp->membase + 0x30); - writel(0xffff0000, vecp); - outb(0, brdp->iobase); - mdelay(1000); -} - -/*****************************************************************************/ - -/* - * Try to find an ECP board and initialize it. This handles only ECP - * board types. - */ - -static int stli_initecp(struct stlibrd *brdp) -{ - cdkecpsig_t sig; - cdkecpsig_t __iomem *sigsp; - unsigned int status, nxtid; - char *name; - int retval, panelnr, nrports; - - if ((brdp->iobase == 0) || (brdp->memaddr == 0)) { - retval = -ENODEV; - goto err; - } - - brdp->iosize = ECP_IOSIZE; - - if (!request_region(brdp->iobase, brdp->iosize, "istallion")) { - retval = -EIO; - goto err; - } - -/* - * Based on the specific board type setup the common vars to access - * and enable shared memory. Set all board specific information now - * as well. - */ - switch (brdp->brdtype) { - case BRD_ECP: - brdp->memsize = ECP_MEMSIZE; - brdp->pagesize = ECP_ATPAGESIZE; - brdp->init = stli_ecpinit; - brdp->enable = stli_ecpenable; - brdp->reenable = stli_ecpenable; - brdp->disable = stli_ecpdisable; - brdp->getmemptr = stli_ecpgetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_ecpreset; - name = "serial(EC8/64)"; - break; - - case BRD_ECPE: - brdp->memsize = ECP_MEMSIZE; - brdp->pagesize = ECP_EIPAGESIZE; - brdp->init = stli_ecpeiinit; - brdp->enable = stli_ecpeienable; - brdp->reenable = stli_ecpeienable; - brdp->disable = stli_ecpeidisable; - brdp->getmemptr = stli_ecpeigetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_ecpeireset; - name = "serial(EC8/64-EI)"; - break; - - case BRD_ECPMC: - brdp->memsize = ECP_MEMSIZE; - brdp->pagesize = ECP_MCPAGESIZE; - brdp->init = NULL; - brdp->enable = stli_ecpmcenable; - brdp->reenable = stli_ecpmcenable; - brdp->disable = stli_ecpmcdisable; - brdp->getmemptr = stli_ecpmcgetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_ecpmcreset; - name = "serial(EC8/64-MCA)"; - break; - - case BRD_ECPPCI: - brdp->memsize = ECP_PCIMEMSIZE; - brdp->pagesize = ECP_PCIPAGESIZE; - brdp->init = stli_ecppciinit; - brdp->enable = NULL; - brdp->reenable = NULL; - brdp->disable = NULL; - brdp->getmemptr = stli_ecppcigetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_ecppcireset; - name = "serial(EC/RA-PCI)"; - break; - - default: - retval = -EINVAL; - goto err_reg; - } - -/* - * The per-board operations structure is all set up, so now let's go - * and get the board operational. Firstly initialize board configuration - * registers. Set the memory mapping info so we can get at the boards - * shared memory. - */ - EBRDINIT(brdp); - - brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize); - if (brdp->membase == NULL) { - retval = -ENOMEM; - goto err_reg; - } - -/* - * Now that all specific code is set up, enable the shared memory and - * look for the a signature area that will tell us exactly what board - * this is, and what it is connected to it. - */ - EBRDENABLE(brdp); - sigsp = (cdkecpsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); - memcpy_fromio(&sig, sigsp, sizeof(cdkecpsig_t)); - EBRDDISABLE(brdp); - - if (sig.magic != cpu_to_le32(ECP_MAGIC)) { - retval = -ENODEV; - goto err_unmap; - } - -/* - * Scan through the signature looking at the panels connected to the - * board. Calculate the total number of ports as we go. - */ - for (panelnr = 0, nxtid = 0; (panelnr < STL_MAXPANELS); panelnr++) { - status = sig.panelid[nxtid]; - if ((status & ECH_PNLIDMASK) != nxtid) - break; - - brdp->panelids[panelnr] = status; - nrports = (status & ECH_PNL16PORT) ? 16 : 8; - if ((nrports == 16) && ((status & ECH_PNLXPID) == 0)) - nxtid++; - brdp->panels[panelnr] = nrports; - brdp->nrports += nrports; - nxtid++; - brdp->nrpanels++; - } - - - set_bit(BST_FOUND, &brdp->state); - return 0; -err_unmap: - iounmap(brdp->membase); - brdp->membase = NULL; -err_reg: - release_region(brdp->iobase, brdp->iosize); -err: - return retval; -} - -/*****************************************************************************/ - -/* - * Try to find an ONboard, Brumby or Stallion board and initialize it. - * This handles only these board types. - */ - -static int stli_initonb(struct stlibrd *brdp) -{ - cdkonbsig_t sig; - cdkonbsig_t __iomem *sigsp; - char *name; - int i, retval; - -/* - * Do a basic sanity check on the IO and memory addresses. - */ - if (brdp->iobase == 0 || brdp->memaddr == 0) { - retval = -ENODEV; - goto err; - } - - brdp->iosize = ONB_IOSIZE; - - if (!request_region(brdp->iobase, brdp->iosize, "istallion")) { - retval = -EIO; - goto err; - } - -/* - * Based on the specific board type setup the common vars to access - * and enable shared memory. Set all board specific information now - * as well. - */ - switch (brdp->brdtype) { - case BRD_ONBOARD: - case BRD_ONBOARD2: - brdp->memsize = ONB_MEMSIZE; - brdp->pagesize = ONB_ATPAGESIZE; - brdp->init = stli_onbinit; - brdp->enable = stli_onbenable; - brdp->reenable = stli_onbenable; - brdp->disable = stli_onbdisable; - brdp->getmemptr = stli_onbgetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_onbreset; - if (brdp->memaddr > 0x100000) - brdp->enabval = ONB_MEMENABHI; - else - brdp->enabval = ONB_MEMENABLO; - name = "serial(ONBoard)"; - break; - - case BRD_ONBOARDE: - brdp->memsize = ONB_EIMEMSIZE; - brdp->pagesize = ONB_EIPAGESIZE; - brdp->init = stli_onbeinit; - brdp->enable = stli_onbeenable; - brdp->reenable = stli_onbeenable; - brdp->disable = stli_onbedisable; - brdp->getmemptr = stli_onbegetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_onbereset; - name = "serial(ONBoard/E)"; - break; - - case BRD_BRUMBY4: - brdp->memsize = BBY_MEMSIZE; - brdp->pagesize = BBY_PAGESIZE; - brdp->init = stli_bbyinit; - brdp->enable = NULL; - brdp->reenable = NULL; - brdp->disable = NULL; - brdp->getmemptr = stli_bbygetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_bbyreset; - name = "serial(Brumby)"; - break; - - case BRD_STALLION: - brdp->memsize = STAL_MEMSIZE; - brdp->pagesize = STAL_PAGESIZE; - brdp->init = stli_stalinit; - brdp->enable = NULL; - brdp->reenable = NULL; - brdp->disable = NULL; - brdp->getmemptr = stli_stalgetmemptr; - brdp->intr = stli_ecpintr; - brdp->reset = stli_stalreset; - name = "serial(Stallion)"; - break; - - default: - retval = -EINVAL; - goto err_reg; - } - -/* - * The per-board operations structure is all set up, so now let's go - * and get the board operational. Firstly initialize board configuration - * registers. Set the memory mapping info so we can get at the boards - * shared memory. - */ - EBRDINIT(brdp); - - brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize); - if (brdp->membase == NULL) { - retval = -ENOMEM; - goto err_reg; - } - -/* - * Now that all specific code is set up, enable the shared memory and - * look for the a signature area that will tell us exactly what board - * this is, and how many ports. - */ - EBRDENABLE(brdp); - sigsp = (cdkonbsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); - memcpy_fromio(&sig, sigsp, sizeof(cdkonbsig_t)); - EBRDDISABLE(brdp); - - if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) || - sig.magic1 != cpu_to_le16(ONB_MAGIC1) || - sig.magic2 != cpu_to_le16(ONB_MAGIC2) || - sig.magic3 != cpu_to_le16(ONB_MAGIC3)) { - retval = -ENODEV; - goto err_unmap; - } - -/* - * Scan through the signature alive mask and calculate how many ports - * there are on this board. - */ - brdp->nrpanels = 1; - if (sig.amask1) { - brdp->nrports = 32; - } else { - for (i = 0; (i < 16); i++) { - if (((sig.amask0 << i) & 0x8000) == 0) - break; - } - brdp->nrports = i; - } - brdp->panels[0] = brdp->nrports; - - - set_bit(BST_FOUND, &brdp->state); - return 0; -err_unmap: - iounmap(brdp->membase); - brdp->membase = NULL; -err_reg: - release_region(brdp->iobase, brdp->iosize); -err: - return retval; -} - -/*****************************************************************************/ - -/* - * Start up a running board. This routine is only called after the - * code has been down loaded to the board and is operational. It will - * read in the memory map, and get the show on the road... - */ - -static int stli_startbrd(struct stlibrd *brdp) -{ - cdkhdr_t __iomem *hdrp; - cdkmem_t __iomem *memp; - cdkasy_t __iomem *ap; - unsigned long flags; - unsigned int portnr, nrdevs, i; - struct stliport *portp; - int rc = 0; - u32 memoff; - - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - nrdevs = hdrp->nrdevs; - -#if 0 - printk("%s(%d): CDK version %d.%d.%d --> " - "nrdevs=%d memp=%x hostp=%x slavep=%x\n", - __FILE__, __LINE__, readb(&hdrp->ver_release), readb(&hdrp->ver_modification), - readb(&hdrp->ver_fix), nrdevs, (int) readl(&hdrp->memp), readl(&hdrp->hostp), - readl(&hdrp->slavep)); -#endif - - if (nrdevs < (brdp->nrports + 1)) { - printk(KERN_ERR "istallion: slave failed to allocate memory for " - "all devices, devices=%d\n", nrdevs); - brdp->nrports = nrdevs - 1; - } - brdp->nrdevs = nrdevs; - brdp->hostoffset = hdrp->hostp - CDK_CDKADDR; - brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR; - brdp->bitsize = (nrdevs + 7) / 8; - memoff = readl(&hdrp->memp); - if (memoff > brdp->memsize) { - printk(KERN_ERR "istallion: corrupted shared memory region?\n"); - rc = -EIO; - goto stli_donestartup; - } - memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff); - if (readw(&memp->dtype) != TYP_ASYNCTRL) { - printk(KERN_ERR "istallion: no slave control device found\n"); - goto stli_donestartup; - } - memp++; - -/* - * Cycle through memory allocation of each port. We are guaranteed to - * have all ports inside the first page of slave window, so no need to - * change pages while reading memory map. - */ - for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) { - if (readw(&memp->dtype) != TYP_ASYNC) - break; - portp = brdp->ports[portnr]; - if (portp == NULL) - break; - portp->devnr = i; - portp->addr = readl(&memp->offset); - portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs)); - portp->portidx = (unsigned char) (i / 8); - portp->portbit = (unsigned char) (0x1 << (i % 8)); - } - - writeb(0xff, &hdrp->slavereq); - -/* - * For each port setup a local copy of the RX and TX buffer offsets - * and sizes. We do this separate from the above, because we need to - * move the shared memory page... - */ - for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) { - portp = brdp->ports[portnr]; - if (portp == NULL) - break; - if (portp->addr == 0) - break; - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - if (ap != NULL) { - portp->rxsize = readw(&ap->rxq.size); - portp->txsize = readw(&ap->txq.size); - portp->rxoffset = readl(&ap->rxq.offset); - portp->txoffset = readl(&ap->txq.offset); - } - } - -stli_donestartup: - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - - if (rc == 0) - set_bit(BST_STARTED, &brdp->state); - - if (! stli_timeron) { - stli_timeron++; - mod_timer(&stli_timerlist, STLI_TIMEOUT); - } - - return rc; -} - -/*****************************************************************************/ - -/* - * Probe and initialize the specified board. - */ - -static int __devinit stli_brdinit(struct stlibrd *brdp) -{ - int retval; - - switch (brdp->brdtype) { - case BRD_ECP: - case BRD_ECPE: - case BRD_ECPMC: - case BRD_ECPPCI: - retval = stli_initecp(brdp); - break; - case BRD_ONBOARD: - case BRD_ONBOARDE: - case BRD_ONBOARD2: - case BRD_BRUMBY4: - case BRD_STALLION: - retval = stli_initonb(brdp); - break; - default: - printk(KERN_ERR "istallion: board=%d is unknown board " - "type=%d\n", brdp->brdnr, brdp->brdtype); - retval = -ENODEV; - } - - if (retval) - return retval; - - stli_initports(brdp); - printk(KERN_INFO "istallion: %s found, board=%d io=%x mem=%x " - "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype], - brdp->brdnr, brdp->iobase, (int) brdp->memaddr, - brdp->nrpanels, brdp->nrports); - return 0; -} - -#if STLI_EISAPROBE != 0 -/*****************************************************************************/ - -/* - * Probe around trying to find where the EISA boards shared memory - * might be. This is a bit if hack, but it is the best we can do. - */ - -static int stli_eisamemprobe(struct stlibrd *brdp) -{ - cdkecpsig_t ecpsig, __iomem *ecpsigp; - cdkonbsig_t onbsig, __iomem *onbsigp; - int i, foundit; - -/* - * First up we reset the board, to get it into a known state. There - * is only 2 board types here we need to worry about. Don;t use the - * standard board init routine here, it programs up the shared - * memory address, and we don't know it yet... - */ - if (brdp->brdtype == BRD_ECPE) { - outb(0x1, (brdp->iobase + ECP_EIBRDENAB)); - outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); - udelay(10); - outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); - udelay(500); - stli_ecpeienable(brdp); - } else if (brdp->brdtype == BRD_ONBOARDE) { - outb(0x1, (brdp->iobase + ONB_EIBRDENAB)); - outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); - udelay(10); - outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); - mdelay(100); - outb(0x1, brdp->iobase); - mdelay(1); - stli_onbeenable(brdp); - } else { - return -ENODEV; - } - - foundit = 0; - brdp->memsize = ECP_MEMSIZE; - -/* - * Board shared memory is enabled, so now we have a poke around and - * see if we can find it. - */ - for (i = 0; (i < stli_eisamempsize); i++) { - brdp->memaddr = stli_eisamemprobeaddrs[i]; - brdp->membase = ioremap_nocache(brdp->memaddr, brdp->memsize); - if (brdp->membase == NULL) - continue; - - if (brdp->brdtype == BRD_ECPE) { - ecpsigp = stli_ecpeigetmemptr(brdp, - CDK_SIGADDR, __LINE__); - memcpy_fromio(&ecpsig, ecpsigp, sizeof(cdkecpsig_t)); - if (ecpsig.magic == cpu_to_le32(ECP_MAGIC)) - foundit = 1; - } else { - onbsigp = (cdkonbsig_t __iomem *) stli_onbegetmemptr(brdp, - CDK_SIGADDR, __LINE__); - memcpy_fromio(&onbsig, onbsigp, sizeof(cdkonbsig_t)); - if ((onbsig.magic0 == cpu_to_le16(ONB_MAGIC0)) && - (onbsig.magic1 == cpu_to_le16(ONB_MAGIC1)) && - (onbsig.magic2 == cpu_to_le16(ONB_MAGIC2)) && - (onbsig.magic3 == cpu_to_le16(ONB_MAGIC3))) - foundit = 1; - } - - iounmap(brdp->membase); - if (foundit) - break; - } - -/* - * Regardless of whether we found the shared memory or not we must - * disable the region. After that return success or failure. - */ - if (brdp->brdtype == BRD_ECPE) - stli_ecpeidisable(brdp); - else - stli_onbedisable(brdp); - - if (! foundit) { - brdp->memaddr = 0; - brdp->membase = NULL; - printk(KERN_ERR "istallion: failed to probe shared memory " - "region for %s in EISA slot=%d\n", - stli_brdnames[brdp->brdtype], (brdp->iobase >> 12)); - return -ENODEV; - } - return 0; -} -#endif - -static int stli_getbrdnr(void) -{ - unsigned int i; - - for (i = 0; i < STL_MAXBRDS; i++) { - if (!stli_brds[i]) { - if (i >= stli_nrbrds) - stli_nrbrds = i + 1; - return i; - } - } - return -1; -} - -#if STLI_EISAPROBE != 0 -/*****************************************************************************/ - -/* - * Probe around and try to find any EISA boards in system. The biggest - * problem here is finding out what memory address is associated with - * an EISA board after it is found. The registers of the ECPE and - * ONboardE are not readable - so we can't read them from there. We - * don't have access to the EISA CMOS (or EISA BIOS) so we don't - * actually have any way to find out the real value. The best we can - * do is go probing around in the usual places hoping we can find it. - */ - -static int __init stli_findeisabrds(void) -{ - struct stlibrd *brdp; - unsigned int iobase, eid, i; - int brdnr, found = 0; - -/* - * Firstly check if this is an EISA system. If this is not an EISA system then - * don't bother going any further! - */ - if (EISA_bus) - return 0; - -/* - * Looks like an EISA system, so go searching for EISA boards. - */ - for (iobase = 0x1000; (iobase <= 0xc000); iobase += 0x1000) { - outb(0xff, (iobase + 0xc80)); - eid = inb(iobase + 0xc80); - eid |= inb(iobase + 0xc81) << 8; - if (eid != STL_EISAID) - continue; - -/* - * We have found a board. Need to check if this board was - * statically configured already (just in case!). - */ - for (i = 0; (i < STL_MAXBRDS); i++) { - brdp = stli_brds[i]; - if (brdp == NULL) - continue; - if (brdp->iobase == iobase) - break; - } - if (i < STL_MAXBRDS) - continue; - -/* - * We have found a Stallion board and it is not configured already. - * Allocate a board structure and initialize it. - */ - if ((brdp = stli_allocbrd()) == NULL) - return found ? : -ENOMEM; - brdnr = stli_getbrdnr(); - if (brdnr < 0) - return found ? : -ENOMEM; - brdp->brdnr = (unsigned int)brdnr; - eid = inb(iobase + 0xc82); - if (eid == ECP_EISAID) - brdp->brdtype = BRD_ECPE; - else if (eid == ONB_EISAID) - brdp->brdtype = BRD_ONBOARDE; - else - brdp->brdtype = BRD_UNKNOWN; - brdp->iobase = iobase; - outb(0x1, (iobase + 0xc84)); - if (stli_eisamemprobe(brdp)) - outb(0, (iobase + 0xc84)); - if (stli_brdinit(brdp) < 0) { - kfree(brdp); - continue; - } - - stli_brds[brdp->brdnr] = brdp; - found++; - - for (i = 0; i < brdp->nrports; i++) - tty_register_device(stli_serial, - brdp->brdnr * STL_MAXPORTS + i, NULL); - } - - return found; -} -#else -static inline int stli_findeisabrds(void) { return 0; } -#endif - -/*****************************************************************************/ - -/* - * Find the next available board number that is free. - */ - -/*****************************************************************************/ - -/* - * We have a Stallion board. Allocate a board structure and - * initialize it. Read its IO and MEMORY resources from PCI - * configuration space. - */ - -static int __devinit stli_pciprobe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct stlibrd *brdp; - unsigned int i; - int brdnr, retval = -EIO; - - retval = pci_enable_device(pdev); - if (retval) - goto err; - brdp = stli_allocbrd(); - if (brdp == NULL) { - retval = -ENOMEM; - goto err; - } - mutex_lock(&stli_brdslock); - brdnr = stli_getbrdnr(); - if (brdnr < 0) { - printk(KERN_INFO "istallion: too many boards found, " - "maximum supported %d\n", STL_MAXBRDS); - mutex_unlock(&stli_brdslock); - retval = -EIO; - goto err_fr; - } - brdp->brdnr = (unsigned int)brdnr; - stli_brds[brdp->brdnr] = brdp; - mutex_unlock(&stli_brdslock); - brdp->brdtype = BRD_ECPPCI; -/* - * We have all resources from the board, so lets setup the actual - * board structure now. - */ - brdp->iobase = pci_resource_start(pdev, 3); - brdp->memaddr = pci_resource_start(pdev, 2); - retval = stli_brdinit(brdp); - if (retval) - goto err_null; - - set_bit(BST_PROBED, &brdp->state); - pci_set_drvdata(pdev, brdp); - - EBRDENABLE(brdp); - brdp->enable = NULL; - brdp->disable = NULL; - - for (i = 0; i < brdp->nrports; i++) - tty_register_device(stli_serial, brdp->brdnr * STL_MAXPORTS + i, - &pdev->dev); - - return 0; -err_null: - stli_brds[brdp->brdnr] = NULL; -err_fr: - kfree(brdp); -err: - return retval; -} - -static void __devexit stli_pciremove(struct pci_dev *pdev) -{ - struct stlibrd *brdp = pci_get_drvdata(pdev); - - stli_cleanup_ports(brdp); - - iounmap(brdp->membase); - if (brdp->iosize > 0) - release_region(brdp->iobase, brdp->iosize); - - stli_brds[brdp->brdnr] = NULL; - kfree(brdp); -} - -static struct pci_driver stli_pcidriver = { - .name = "istallion", - .id_table = istallion_pci_tbl, - .probe = stli_pciprobe, - .remove = __devexit_p(stli_pciremove) -}; -/*****************************************************************************/ - -/* - * Allocate a new board structure. Fill out the basic info in it. - */ - -static struct stlibrd *stli_allocbrd(void) -{ - struct stlibrd *brdp; - - brdp = kzalloc(sizeof(struct stlibrd), GFP_KERNEL); - if (!brdp) { - printk(KERN_ERR "istallion: failed to allocate memory " - "(size=%Zd)\n", sizeof(struct stlibrd)); - return NULL; - } - brdp->magic = STLI_BOARDMAGIC; - return brdp; -} - -/*****************************************************************************/ - -/* - * Scan through all the boards in the configuration and see what we - * can find. - */ - -static int __init stli_initbrds(void) -{ - struct stlibrd *brdp, *nxtbrdp; - struct stlconf conf; - unsigned int i, j, found = 0; - int retval; - - for (stli_nrbrds = 0; stli_nrbrds < ARRAY_SIZE(stli_brdsp); - stli_nrbrds++) { - memset(&conf, 0, sizeof(conf)); - if (stli_parsebrd(&conf, stli_brdsp[stli_nrbrds]) == 0) - continue; - if ((brdp = stli_allocbrd()) == NULL) - continue; - brdp->brdnr = stli_nrbrds; - brdp->brdtype = conf.brdtype; - brdp->iobase = conf.ioaddr1; - brdp->memaddr = conf.memaddr; - if (stli_brdinit(brdp) < 0) { - kfree(brdp); - continue; - } - stli_brds[brdp->brdnr] = brdp; - found++; - - for (i = 0; i < brdp->nrports; i++) - tty_register_device(stli_serial, - brdp->brdnr * STL_MAXPORTS + i, NULL); - } - - retval = stli_findeisabrds(); - if (retval > 0) - found += retval; - -/* - * All found boards are initialized. Now for a little optimization, if - * no boards are sharing the "shared memory" regions then we can just - * leave them all enabled. This is in fact the usual case. - */ - stli_shared = 0; - if (stli_nrbrds > 1) { - for (i = 0; (i < stli_nrbrds); i++) { - brdp = stli_brds[i]; - if (brdp == NULL) - continue; - for (j = i + 1; (j < stli_nrbrds); j++) { - nxtbrdp = stli_brds[j]; - if (nxtbrdp == NULL) - continue; - if ((brdp->membase >= nxtbrdp->membase) && - (brdp->membase <= (nxtbrdp->membase + - nxtbrdp->memsize - 1))) { - stli_shared++; - break; - } - } - } - } - - if (stli_shared == 0) { - for (i = 0; (i < stli_nrbrds); i++) { - brdp = stli_brds[i]; - if (brdp == NULL) - continue; - if (test_bit(BST_FOUND, &brdp->state)) { - EBRDENABLE(brdp); - brdp->enable = NULL; - brdp->disable = NULL; - } - } - } - - retval = pci_register_driver(&stli_pcidriver); - if (retval && found == 0) { - printk(KERN_ERR "Neither isa nor eisa cards found nor pci " - "driver can be registered!\n"); - goto err; - } - - return 0; -err: - return retval; -} - -/*****************************************************************************/ - -/* - * Code to handle an "staliomem" read operation. This device is the - * contents of the board shared memory. It is used for down loading - * the slave image (and debugging :-) - */ - -static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp) -{ - unsigned long flags; - void __iomem *memptr; - struct stlibrd *brdp; - unsigned int brdnr; - int size, n; - void *p; - loff_t off = *offp; - - brdnr = iminor(fp->f_path.dentry->d_inode); - if (brdnr >= stli_nrbrds) - return -ENODEV; - brdp = stli_brds[brdnr]; - if (brdp == NULL) - return -ENODEV; - if (brdp->state == 0) - return -ENODEV; - if (off >= brdp->memsize || off + count < off) - return 0; - - size = min(count, (size_t)(brdp->memsize - off)); - - /* - * Copy the data a page at a time - */ - - p = (void *)__get_free_page(GFP_KERNEL); - if(p == NULL) - return -ENOMEM; - - while (size > 0) { - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - memptr = EBRDGETMEMPTR(brdp, off); - n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); - n = min(n, (int)PAGE_SIZE); - memcpy_fromio(p, memptr, n); - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - if (copy_to_user(buf, p, n)) { - count = -EFAULT; - goto out; - } - off += n; - buf += n; - size -= n; - } -out: - *offp = off; - free_page((unsigned long)p); - return count; -} - -/*****************************************************************************/ - -/* - * Code to handle an "staliomem" write operation. This device is the - * contents of the board shared memory. It is used for down loading - * the slave image (and debugging :-) - * - * FIXME: copy under lock - */ - -static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp) -{ - unsigned long flags; - void __iomem *memptr; - struct stlibrd *brdp; - char __user *chbuf; - unsigned int brdnr; - int size, n; - void *p; - loff_t off = *offp; - - brdnr = iminor(fp->f_path.dentry->d_inode); - - if (brdnr >= stli_nrbrds) - return -ENODEV; - brdp = stli_brds[brdnr]; - if (brdp == NULL) - return -ENODEV; - if (brdp->state == 0) - return -ENODEV; - if (off >= brdp->memsize || off + count < off) - return 0; - - chbuf = (char __user *) buf; - size = min(count, (size_t)(brdp->memsize - off)); - - /* - * Copy the data a page at a time - */ - - p = (void *)__get_free_page(GFP_KERNEL); - if(p == NULL) - return -ENOMEM; - - while (size > 0) { - n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); - n = min(n, (int)PAGE_SIZE); - if (copy_from_user(p, chbuf, n)) { - if (count == 0) - count = -EFAULT; - goto out; - } - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - memptr = EBRDGETMEMPTR(brdp, off); - memcpy_toio(memptr, p, n); - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - off += n; - chbuf += n; - size -= n; - } -out: - free_page((unsigned long) p); - *offp = off; - return count; -} - -/*****************************************************************************/ - -/* - * Return the board stats structure to user app. - */ - -static int stli_getbrdstats(combrd_t __user *bp) -{ - struct stlibrd *brdp; - unsigned int i; - combrd_t stli_brdstats; - - if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t))) - return -EFAULT; - if (stli_brdstats.brd >= STL_MAXBRDS) - return -ENODEV; - brdp = stli_brds[stli_brdstats.brd]; - if (brdp == NULL) - return -ENODEV; - - memset(&stli_brdstats, 0, sizeof(combrd_t)); - - stli_brdstats.brd = brdp->brdnr; - stli_brdstats.type = brdp->brdtype; - stli_brdstats.hwid = 0; - stli_brdstats.state = brdp->state; - stli_brdstats.ioaddr = brdp->iobase; - stli_brdstats.memaddr = brdp->memaddr; - stli_brdstats.nrpanels = brdp->nrpanels; - stli_brdstats.nrports = brdp->nrports; - for (i = 0; (i < brdp->nrpanels); i++) { - stli_brdstats.panels[i].panel = i; - stli_brdstats.panels[i].hwid = brdp->panelids[i]; - stli_brdstats.panels[i].nrports = brdp->panels[i]; - } - - if (copy_to_user(bp, &stli_brdstats, sizeof(combrd_t))) - return -EFAULT; - return 0; -} - -/*****************************************************************************/ - -/* - * Resolve the referenced port number into a port struct pointer. - */ - -static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, - unsigned int portnr) -{ - struct stlibrd *brdp; - unsigned int i; - - if (brdnr >= STL_MAXBRDS) - return NULL; - brdp = stli_brds[brdnr]; - if (brdp == NULL) - return NULL; - for (i = 0; (i < panelnr); i++) - portnr += brdp->panels[i]; - if (portnr >= brdp->nrports) - return NULL; - return brdp->ports[portnr]; -} - -/*****************************************************************************/ - -/* - * Return the port stats structure to user app. A NULL port struct - * pointer passed in means that we need to find out from the app - * what port to get stats for (used through board control device). - */ - -static int stli_portcmdstats(struct tty_struct *tty, struct stliport *portp) -{ - unsigned long flags; - struct stlibrd *brdp; - int rc; - - memset(&stli_comstats, 0, sizeof(comstats_t)); - - if (portp == NULL) - return -ENODEV; - brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return -ENODEV; - - mutex_lock(&portp->port.mutex); - if (test_bit(BST_STARTED, &brdp->state)) { - if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, - &stli_cdkstats, sizeof(asystats_t), 1)) < 0) { - mutex_unlock(&portp->port.mutex); - return rc; - } - } else { - memset(&stli_cdkstats, 0, sizeof(asystats_t)); - } - - stli_comstats.brd = portp->brdnr; - stli_comstats.panel = portp->panelnr; - stli_comstats.port = portp->portnr; - stli_comstats.state = portp->state; - stli_comstats.flags = portp->port.flags; - - spin_lock_irqsave(&brd_lock, flags); - if (tty != NULL) { - if (portp->port.tty == tty) { - stli_comstats.ttystate = tty->flags; - stli_comstats.rxbuffered = -1; - if (tty->termios != NULL) { - stli_comstats.cflags = tty->termios->c_cflag; - stli_comstats.iflags = tty->termios->c_iflag; - stli_comstats.oflags = tty->termios->c_oflag; - stli_comstats.lflags = tty->termios->c_lflag; - } - } - } - spin_unlock_irqrestore(&brd_lock, flags); - - stli_comstats.txtotal = stli_cdkstats.txchars; - stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover; - stli_comstats.txbuffered = stli_cdkstats.txringq; - stli_comstats.rxbuffered += stli_cdkstats.rxringq; - stli_comstats.rxoverrun = stli_cdkstats.overruns; - stli_comstats.rxparity = stli_cdkstats.parity; - stli_comstats.rxframing = stli_cdkstats.framing; - stli_comstats.rxlost = stli_cdkstats.ringover; - stli_comstats.rxbreaks = stli_cdkstats.rxbreaks; - stli_comstats.txbreaks = stli_cdkstats.txbreaks; - stli_comstats.txxon = stli_cdkstats.txstart; - stli_comstats.txxoff = stli_cdkstats.txstop; - stli_comstats.rxxon = stli_cdkstats.rxstart; - stli_comstats.rxxoff = stli_cdkstats.rxstop; - stli_comstats.rxrtsoff = stli_cdkstats.rtscnt / 2; - stli_comstats.rxrtson = stli_cdkstats.rtscnt - stli_comstats.rxrtsoff; - stli_comstats.modem = stli_cdkstats.dcdcnt; - stli_comstats.hwid = stli_cdkstats.hwid; - stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals); - mutex_unlock(&portp->port.mutex); - - return 0; -} - -/*****************************************************************************/ - -/* - * Return the port stats structure to user app. A NULL port struct - * pointer passed in means that we need to find out from the app - * what port to get stats for (used through board control device). - */ - -static int stli_getportstats(struct tty_struct *tty, struct stliport *portp, - comstats_t __user *cp) -{ - struct stlibrd *brdp; - int rc; - - if (!portp) { - if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) - return -EFAULT; - portp = stli_getport(stli_comstats.brd, stli_comstats.panel, - stli_comstats.port); - if (!portp) - return -ENODEV; - } - - brdp = stli_brds[portp->brdnr]; - if (!brdp) - return -ENODEV; - - if ((rc = stli_portcmdstats(tty, portp)) < 0) - return rc; - - return copy_to_user(cp, &stli_comstats, sizeof(comstats_t)) ? - -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Clear the port stats structure. We also return it zeroed out... - */ - -static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp) -{ - struct stlibrd *brdp; - int rc; - - if (!portp) { - if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) - return -EFAULT; - portp = stli_getport(stli_comstats.brd, stli_comstats.panel, - stli_comstats.port); - if (!portp) - return -ENODEV; - } - - brdp = stli_brds[portp->brdnr]; - if (!brdp) - return -ENODEV; - - mutex_lock(&portp->port.mutex); - - if (test_bit(BST_STARTED, &brdp->state)) { - if ((rc = stli_cmdwait(brdp, portp, A_CLEARSTATS, NULL, 0, 0)) < 0) { - mutex_unlock(&portp->port.mutex); - return rc; - } - } - - memset(&stli_comstats, 0, sizeof(comstats_t)); - stli_comstats.brd = portp->brdnr; - stli_comstats.panel = portp->panelnr; - stli_comstats.port = portp->portnr; - mutex_unlock(&portp->port.mutex); - - if (copy_to_user(cp, &stli_comstats, sizeof(comstats_t))) - return -EFAULT; - return 0; -} - -/*****************************************************************************/ - -/* - * Return the entire driver ports structure to a user app. - */ - -static int stli_getportstruct(struct stliport __user *arg) -{ - struct stliport stli_dummyport; - struct stliport *portp; - - if (copy_from_user(&stli_dummyport, arg, sizeof(struct stliport))) - return -EFAULT; - portp = stli_getport(stli_dummyport.brdnr, stli_dummyport.panelnr, - stli_dummyport.portnr); - if (!portp) - return -ENODEV; - if (copy_to_user(arg, portp, sizeof(struct stliport))) - return -EFAULT; - return 0; -} - -/*****************************************************************************/ - -/* - * Return the entire driver board structure to a user app. - */ - -static int stli_getbrdstruct(struct stlibrd __user *arg) -{ - struct stlibrd stli_dummybrd; - struct stlibrd *brdp; - - if (copy_from_user(&stli_dummybrd, arg, sizeof(struct stlibrd))) - return -EFAULT; - if (stli_dummybrd.brdnr >= STL_MAXBRDS) - return -ENODEV; - brdp = stli_brds[stli_dummybrd.brdnr]; - if (!brdp) - return -ENODEV; - if (copy_to_user(arg, brdp, sizeof(struct stlibrd))) - return -EFAULT; - return 0; -} - -/*****************************************************************************/ - -/* - * The "staliomem" device is also required to do some special operations on - * the board. We need to be able to send an interrupt to the board, - * reset it, and start/stop it. - */ - -static long stli_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) -{ - struct stlibrd *brdp; - int brdnr, rc, done; - void __user *argp = (void __user *)arg; - -/* - * First up handle the board independent ioctls. - */ - done = 0; - rc = 0; - - switch (cmd) { - case COM_GETPORTSTATS: - rc = stli_getportstats(NULL, NULL, argp); - done++; - break; - case COM_CLRPORTSTATS: - rc = stli_clrportstats(NULL, argp); - done++; - break; - case COM_GETBRDSTATS: - rc = stli_getbrdstats(argp); - done++; - break; - case COM_READPORT: - rc = stli_getportstruct(argp); - done++; - break; - case COM_READBOARD: - rc = stli_getbrdstruct(argp); - done++; - break; - } - if (done) - return rc; - -/* - * Now handle the board specific ioctls. These all depend on the - * minor number of the device they were called from. - */ - brdnr = iminor(fp->f_dentry->d_inode); - if (brdnr >= STL_MAXBRDS) - return -ENODEV; - brdp = stli_brds[brdnr]; - if (!brdp) - return -ENODEV; - if (brdp->state == 0) - return -ENODEV; - - switch (cmd) { - case STL_BINTR: - EBRDINTR(brdp); - break; - case STL_BSTART: - rc = stli_startbrd(brdp); - break; - case STL_BSTOP: - clear_bit(BST_STARTED, &brdp->state); - break; - case STL_BRESET: - clear_bit(BST_STARTED, &brdp->state); - EBRDRESET(brdp); - if (stli_shared == 0) { - if (brdp->reenable != NULL) - (* brdp->reenable)(brdp); - } - break; - default: - rc = -ENOIOCTLCMD; - break; - } - return rc; -} - -static const struct tty_operations stli_ops = { - .open = stli_open, - .close = stli_close, - .write = stli_write, - .put_char = stli_putchar, - .flush_chars = stli_flushchars, - .write_room = stli_writeroom, - .chars_in_buffer = stli_charsinbuffer, - .ioctl = stli_ioctl, - .set_termios = stli_settermios, - .throttle = stli_throttle, - .unthrottle = stli_unthrottle, - .stop = stli_stop, - .start = stli_start, - .hangup = stli_hangup, - .flush_buffer = stli_flushbuffer, - .break_ctl = stli_breakctl, - .wait_until_sent = stli_waituntilsent, - .send_xchar = stli_sendxchar, - .tiocmget = stli_tiocmget, - .tiocmset = stli_tiocmset, - .proc_fops = &stli_proc_fops, -}; - -static const struct tty_port_operations stli_port_ops = { - .carrier_raised = stli_carrier_raised, - .dtr_rts = stli_dtr_rts, - .activate = stli_activate, - .shutdown = stli_shutdown, -}; - -/*****************************************************************************/ -/* - * Loadable module initialization stuff. - */ - -static void istallion_cleanup_isa(void) -{ - struct stlibrd *brdp; - unsigned int j; - - for (j = 0; (j < stli_nrbrds); j++) { - if ((brdp = stli_brds[j]) == NULL || - test_bit(BST_PROBED, &brdp->state)) - continue; - - stli_cleanup_ports(brdp); - - iounmap(brdp->membase); - if (brdp->iosize > 0) - release_region(brdp->iobase, brdp->iosize); - kfree(brdp); - stli_brds[j] = NULL; - } -} - -static int __init istallion_module_init(void) -{ - unsigned int i; - int retval; - - printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion); - - spin_lock_init(&stli_lock); - spin_lock_init(&brd_lock); - - stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); - if (!stli_txcookbuf) { - printk(KERN_ERR "istallion: failed to allocate memory " - "(size=%d)\n", STLI_TXBUFSIZE); - retval = -ENOMEM; - goto err; - } - - stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); - if (!stli_serial) { - retval = -ENOMEM; - goto err_free; - } - - stli_serial->owner = THIS_MODULE; - stli_serial->driver_name = stli_drvname; - stli_serial->name = stli_serialname; - stli_serial->major = STL_SERIALMAJOR; - stli_serial->minor_start = 0; - stli_serial->type = TTY_DRIVER_TYPE_SERIAL; - stli_serial->subtype = SERIAL_TYPE_NORMAL; - stli_serial->init_termios = stli_deftermios; - stli_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(stli_serial, &stli_ops); - - retval = tty_register_driver(stli_serial); - if (retval) { - printk(KERN_ERR "istallion: failed to register serial driver\n"); - goto err_ttyput; - } - - retval = stli_initbrds(); - if (retval) - goto err_ttyunr; - -/* - * Set up a character driver for the shared memory region. We need this - * to down load the slave code image. Also it is a useful debugging tool. - */ - retval = register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem); - if (retval) { - printk(KERN_ERR "istallion: failed to register serial memory " - "device\n"); - goto err_deinit; - } - - istallion_class = class_create(THIS_MODULE, "staliomem"); - for (i = 0; i < 4; i++) - device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), - NULL, "staliomem%d", i); - - return 0; -err_deinit: - pci_unregister_driver(&stli_pcidriver); - istallion_cleanup_isa(); -err_ttyunr: - tty_unregister_driver(stli_serial); -err_ttyput: - put_tty_driver(stli_serial); -err_free: - kfree(stli_txcookbuf); -err: - return retval; -} - -/*****************************************************************************/ - -static void __exit istallion_module_exit(void) -{ - unsigned int j; - - printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, - stli_drvversion); - - if (stli_timeron) { - stli_timeron = 0; - del_timer_sync(&stli_timerlist); - } - - unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); - - for (j = 0; j < 4; j++) - device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j)); - class_destroy(istallion_class); - - pci_unregister_driver(&stli_pcidriver); - istallion_cleanup_isa(); - - tty_unregister_driver(stli_serial); - put_tty_driver(stli_serial); - - kfree(stli_txcookbuf); -} - -module_init(istallion_module_init); -module_exit(istallion_module_exit); diff --git a/drivers/staging/tty/riscom8.c b/drivers/staging/tty/riscom8.c deleted file mode 100644 index 602643a40b4b..000000000000 --- a/drivers/staging/tty/riscom8.c +++ /dev/null @@ -1,1560 +0,0 @@ -/* - * linux/drivers/char/riscom.c -- RISCom/8 multiport serial driver. - * - * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) - * - * This code is loosely based on the Linux serial driver, written by - * Linus Torvalds, Theodore T'so and others. The RISCom/8 card - * programming info was obtained from various drivers for other OSes - * (FreeBSD, ISC, etc), but no source code from those drivers were - * directly included in this 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. - * - * 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. - * - * Revision 1.1 - * - * ChangeLog: - * Arnaldo Carvalho de Melo - 27-Jun-2001 - * - get rid of check_region and several cleanups - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "riscom8.h" -#include "riscom8_reg.h" - -/* Am I paranoid or not ? ;-) */ -#define RISCOM_PARANOIA_CHECK - -/* - * Crazy InteliCom/8 boards sometimes have swapped CTS & DSR signals. - * You can slightly speed up things by #undefing the following option, - * if you are REALLY sure that your board is correct one. - */ - -#define RISCOM_BRAIN_DAMAGED_CTS - -/* - * The following defines are mostly for testing purposes. But if you need - * some nice reporting in your syslog, you can define them also. - */ -#undef RC_REPORT_FIFO -#undef RC_REPORT_OVERRUN - - -#define RISCOM_LEGAL_FLAGS \ - (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \ - ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \ - ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP) - -static struct tty_driver *riscom_driver; - -static DEFINE_SPINLOCK(riscom_lock); - -static struct riscom_board rc_board[RC_NBOARD] = { - { - .base = RC_IOBASE1, - }, - { - .base = RC_IOBASE2, - }, - { - .base = RC_IOBASE3, - }, - { - .base = RC_IOBASE4, - }, -}; - -static struct riscom_port rc_port[RC_NBOARD * RC_NPORT]; - -/* RISCom/8 I/O ports addresses (without address translation) */ -static unsigned short rc_ioport[] = { -#if 1 - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, -#else - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x10, - 0x11, 0x12, 0x18, 0x28, 0x31, 0x32, 0x39, 0x3a, 0x40, 0x41, 0x61, 0x62, - 0x63, 0x64, 0x6b, 0x70, 0x71, 0x78, 0x7a, 0x7b, 0x7f, 0x100, 0x101 -#endif -}; -#define RC_NIOPORT ARRAY_SIZE(rc_ioport) - - -static int rc_paranoia_check(struct riscom_port const *port, - char *name, const char *routine) -{ -#ifdef RISCOM_PARANOIA_CHECK - static const char badmagic[] = KERN_INFO - "rc: Warning: bad riscom port magic number for device %s in %s\n"; - static const char badinfo[] = KERN_INFO - "rc: Warning: null riscom port for device %s in %s\n"; - - if (!port) { - printk(badinfo, name, routine); - return 1; - } - if (port->magic != RISCOM8_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#endif - return 0; -} - -/* - * - * Service functions for RISCom/8 driver. - * - */ - -/* Get board number from pointer */ -static inline int board_No(struct riscom_board const *bp) -{ - return bp - rc_board; -} - -/* Get port number from pointer */ -static inline int port_No(struct riscom_port const *port) -{ - return RC_PORT(port - rc_port); -} - -/* Get pointer to board from pointer to port */ -static inline struct riscom_board *port_Board(struct riscom_port const *port) -{ - return &rc_board[RC_BOARD(port - rc_port)]; -} - -/* Input Byte from CL CD180 register */ -static inline unsigned char rc_in(struct riscom_board const *bp, - unsigned short reg) -{ - return inb(bp->base + RC_TO_ISA(reg)); -} - -/* Output Byte to CL CD180 register */ -static inline void rc_out(struct riscom_board const *bp, unsigned short reg, - unsigned char val) -{ - outb(val, bp->base + RC_TO_ISA(reg)); -} - -/* Wait for Channel Command Register ready */ -static void rc_wait_CCR(struct riscom_board const *bp) -{ - unsigned long delay; - - /* FIXME: need something more descriptive then 100000 :) */ - for (delay = 100000; delay; delay--) - if (!rc_in(bp, CD180_CCR)) - return; - - printk(KERN_INFO "rc%d: Timeout waiting for CCR.\n", board_No(bp)); -} - -/* - * RISCom/8 probe functions. - */ - -static int rc_request_io_range(struct riscom_board * const bp) -{ - int i; - - for (i = 0; i < RC_NIOPORT; i++) - if (!request_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1, - "RISCom/8")) { - goto out_release; - } - return 0; -out_release: - printk(KERN_INFO "rc%d: Skipping probe at 0x%03x. IO address in use.\n", - board_No(bp), bp->base); - while (--i >= 0) - release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); - return 1; -} - -static void rc_release_io_range(struct riscom_board * const bp) -{ - int i; - - for (i = 0; i < RC_NIOPORT; i++) - release_region(RC_TO_ISA(rc_ioport[i]) + bp->base, 1); -} - -/* Reset and setup CD180 chip */ -static void __init rc_init_CD180(struct riscom_board const *bp) -{ - unsigned long flags; - - spin_lock_irqsave(&riscom_lock, flags); - - rc_out(bp, RC_CTOUT, 0); /* Clear timeout */ - rc_wait_CCR(bp); /* Wait for CCR ready */ - rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */ - spin_unlock_irqrestore(&riscom_lock, flags); - msleep(50); /* Delay 0.05 sec */ - spin_lock_irqsave(&riscom_lock, flags); - rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */ - rc_out(bp, CD180_GICR, 0); /* Clear all bits */ - rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */ - rc_out(bp, CD180_PILR2, RC_ACK_TINT); /* Prio for tx intr */ - rc_out(bp, CD180_PILR3, RC_ACK_RINT); /* Prio for rx intr */ - - /* Setting up prescaler. We need 4 ticks per 1 ms */ - rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8); - rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff); - - spin_unlock_irqrestore(&riscom_lock, flags); -} - -/* Main probing routine, also sets irq. */ -static int __init rc_probe(struct riscom_board *bp) -{ - unsigned char val1, val2; - int irqs = 0; - int retries; - - bp->irq = 0; - - if (rc_request_io_range(bp)) - return 1; - - /* Are the I/O ports here ? */ - rc_out(bp, CD180_PPRL, 0x5a); - outb(0xff, 0x80); - val1 = rc_in(bp, CD180_PPRL); - rc_out(bp, CD180_PPRL, 0xa5); - outb(0x00, 0x80); - val2 = rc_in(bp, CD180_PPRL); - - if ((val1 != 0x5a) || (val2 != 0xa5)) { - printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not found.\n", - board_No(bp), bp->base); - goto out_release; - } - - /* It's time to find IRQ for this board */ - for (retries = 0; retries < 5 && irqs <= 0; retries++) { - irqs = probe_irq_on(); - rc_init_CD180(bp); /* Reset CD180 chip */ - rc_out(bp, CD180_CAR, 2); /* Select port 2 */ - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_TXEN); /* Enable transmitter */ - rc_out(bp, CD180_IER, IER_TXRDY);/* Enable tx empty intr */ - msleep(50); - irqs = probe_irq_off(irqs); - val1 = rc_in(bp, RC_BSR); /* Get Board Status reg */ - val2 = rc_in(bp, RC_ACK_TINT); /* ACK interrupt */ - rc_init_CD180(bp); /* Reset CD180 again */ - - if ((val1 & RC_BSR_TINT) || (val2 != (RC_ID | GIVR_IT_TX))) { - printk(KERN_ERR "rc%d: RISCom/8 Board at 0x%03x not " - "found.\n", board_No(bp), bp->base); - goto out_release; - } - } - - if (irqs <= 0) { - printk(KERN_ERR "rc%d: Can't find IRQ for RISCom/8 board " - "at 0x%03x.\n", board_No(bp), bp->base); - goto out_release; - } - bp->irq = irqs; - bp->flags |= RC_BOARD_PRESENT; - - printk(KERN_INFO "rc%d: RISCom/8 Rev. %c board detected at " - "0x%03x, IRQ %d.\n", - board_No(bp), - (rc_in(bp, CD180_GFRCR) & 0x0f) + 'A', /* Board revision */ - bp->base, bp->irq); - - return 0; -out_release: - rc_release_io_range(bp); - return 1; -} - -/* - * - * Interrupt processing routines. - * - */ - -static struct riscom_port *rc_get_port(struct riscom_board const *bp, - unsigned char const *what) -{ - unsigned char channel; - struct riscom_port *port; - - channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF; - if (channel < CD180_NCH) { - port = &rc_port[board_No(bp) * RC_NPORT + channel]; - if (port->port.flags & ASYNC_INITIALIZED) - return port; - } - printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n", - board_No(bp), what, channel); - return NULL; -} - -static void rc_receive_exc(struct riscom_board const *bp) -{ - struct riscom_port *port; - struct tty_struct *tty; - unsigned char status; - unsigned char ch, flag; - - port = rc_get_port(bp, "Receive"); - if (port == NULL) - return; - - tty = tty_port_tty_get(&port->port); - -#ifdef RC_REPORT_OVERRUN - status = rc_in(bp, CD180_RCSR); - if (status & RCSR_OE) - port->overrun++; - status &= port->mark_mask; -#else - status = rc_in(bp, CD180_RCSR) & port->mark_mask; -#endif - ch = rc_in(bp, CD180_RDR); - if (!status) - goto out; - if (status & RCSR_TOUT) { - printk(KERN_WARNING "rc%d: port %d: Receiver timeout. " - "Hardware problems ?\n", - board_No(bp), port_No(port)); - goto out; - - } else if (status & RCSR_BREAK) { - printk(KERN_INFO "rc%d: port %d: Handling break...\n", - board_No(bp), port_No(port)); - flag = TTY_BREAK; - if (tty && (port->port.flags & ASYNC_SAK)) - do_SAK(tty); - - } else if (status & RCSR_PE) - flag = TTY_PARITY; - - else if (status & RCSR_FE) - flag = TTY_FRAME; - - else if (status & RCSR_OE) - flag = TTY_OVERRUN; - else - flag = TTY_NORMAL; - - if (tty) { - tty_insert_flip_char(tty, ch, flag); - tty_flip_buffer_push(tty); - } -out: - tty_kref_put(tty); -} - -static void rc_receive(struct riscom_board const *bp) -{ - struct riscom_port *port; - struct tty_struct *tty; - unsigned char count; - - port = rc_get_port(bp, "Receive"); - if (port == NULL) - return; - - tty = tty_port_tty_get(&port->port); - - count = rc_in(bp, CD180_RDCR); - -#ifdef RC_REPORT_FIFO - port->hits[count > 8 ? 9 : count]++; -#endif - - while (count--) { - u8 ch = rc_in(bp, CD180_RDR); - if (tty) - tty_insert_flip_char(tty, ch, TTY_NORMAL); - } - if (tty) { - tty_flip_buffer_push(tty); - tty_kref_put(tty); - } -} - -static void rc_transmit(struct riscom_board const *bp) -{ - struct riscom_port *port; - struct tty_struct *tty; - unsigned char count; - - port = rc_get_port(bp, "Transmit"); - if (port == NULL) - return; - - tty = tty_port_tty_get(&port->port); - - if (port->IER & IER_TXEMPTY) { - /* FIFO drained */ - rc_out(bp, CD180_CAR, port_No(port)); - port->IER &= ~IER_TXEMPTY; - rc_out(bp, CD180_IER, port->IER); - goto out; - } - - if ((port->xmit_cnt <= 0 && !port->break_length) - || (tty && (tty->stopped || tty->hw_stopped))) { - rc_out(bp, CD180_CAR, port_No(port)); - port->IER &= ~IER_TXRDY; - rc_out(bp, CD180_IER, port->IER); - goto out; - } - - if (port->break_length) { - if (port->break_length > 0) { - if (port->COR2 & COR2_ETC) { - rc_out(bp, CD180_TDR, CD180_C_ESC); - rc_out(bp, CD180_TDR, CD180_C_SBRK); - port->COR2 &= ~COR2_ETC; - } - count = min_t(int, port->break_length, 0xff); - rc_out(bp, CD180_TDR, CD180_C_ESC); - rc_out(bp, CD180_TDR, CD180_C_DELAY); - rc_out(bp, CD180_TDR, count); - port->break_length -= count; - if (port->break_length == 0) - port->break_length--; - } else { - rc_out(bp, CD180_TDR, CD180_C_ESC); - rc_out(bp, CD180_TDR, CD180_C_EBRK); - rc_out(bp, CD180_COR2, port->COR2); - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_CORCHG2); - port->break_length = 0; - } - goto out; - } - - count = CD180_NFIFO; - do { - rc_out(bp, CD180_TDR, port->port.xmit_buf[port->xmit_tail++]); - port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1); - if (--port->xmit_cnt <= 0) - break; - } while (--count > 0); - - if (port->xmit_cnt <= 0) { - rc_out(bp, CD180_CAR, port_No(port)); - port->IER &= ~IER_TXRDY; - rc_out(bp, CD180_IER, port->IER); - } - if (tty && port->xmit_cnt <= port->wakeup_chars) - tty_wakeup(tty); -out: - tty_kref_put(tty); -} - -static void rc_check_modem(struct riscom_board const *bp) -{ - struct riscom_port *port; - struct tty_struct *tty; - unsigned char mcr; - - port = rc_get_port(bp, "Modem"); - if (port == NULL) - return; - - tty = tty_port_tty_get(&port->port); - - mcr = rc_in(bp, CD180_MCR); - if (mcr & MCR_CDCHG) { - if (rc_in(bp, CD180_MSVR) & MSVR_CD) - wake_up_interruptible(&port->port.open_wait); - else if (tty) - tty_hangup(tty); - } - -#ifdef RISCOM_BRAIN_DAMAGED_CTS - if (mcr & MCR_CTSCHG) { - if (rc_in(bp, CD180_MSVR) & MSVR_CTS) { - port->IER |= IER_TXRDY; - if (tty) { - tty->hw_stopped = 0; - if (port->xmit_cnt <= port->wakeup_chars) - tty_wakeup(tty); - } - } else { - if (tty) - tty->hw_stopped = 1; - port->IER &= ~IER_TXRDY; - } - rc_out(bp, CD180_IER, port->IER); - } - if (mcr & MCR_DSRCHG) { - if (rc_in(bp, CD180_MSVR) & MSVR_DSR) { - port->IER |= IER_TXRDY; - if (tty) { - tty->hw_stopped = 0; - if (port->xmit_cnt <= port->wakeup_chars) - tty_wakeup(tty); - } - } else { - if (tty) - tty->hw_stopped = 1; - port->IER &= ~IER_TXRDY; - } - rc_out(bp, CD180_IER, port->IER); - } -#endif /* RISCOM_BRAIN_DAMAGED_CTS */ - - /* Clear change bits */ - rc_out(bp, CD180_MCR, 0); - tty_kref_put(tty); -} - -/* The main interrupt processing routine */ -static irqreturn_t rc_interrupt(int dummy, void *dev_id) -{ - unsigned char status; - unsigned char ack; - struct riscom_board *bp = dev_id; - unsigned long loop = 0; - int handled = 0; - - if (!(bp->flags & RC_BOARD_ACTIVE)) - return IRQ_NONE; - - while ((++loop < 16) && ((status = ~(rc_in(bp, RC_BSR))) & - (RC_BSR_TOUT | RC_BSR_TINT | - RC_BSR_MINT | RC_BSR_RINT))) { - handled = 1; - if (status & RC_BSR_TOUT) - printk(KERN_WARNING "rc%d: Got timeout. Hardware " - "error?\n", board_No(bp)); - else if (status & RC_BSR_RINT) { - ack = rc_in(bp, RC_ACK_RINT); - if (ack == (RC_ID | GIVR_IT_RCV)) - rc_receive(bp); - else if (ack == (RC_ID | GIVR_IT_REXC)) - rc_receive_exc(bp); - else - printk(KERN_WARNING "rc%d: Bad receive ack " - "0x%02x.\n", - board_No(bp), ack); - } else if (status & RC_BSR_TINT) { - ack = rc_in(bp, RC_ACK_TINT); - if (ack == (RC_ID | GIVR_IT_TX)) - rc_transmit(bp); - else - printk(KERN_WARNING "rc%d: Bad transmit ack " - "0x%02x.\n", - board_No(bp), ack); - } else /* if (status & RC_BSR_MINT) */ { - ack = rc_in(bp, RC_ACK_MINT); - if (ack == (RC_ID | GIVR_IT_MODEM)) - rc_check_modem(bp); - else - printk(KERN_WARNING "rc%d: Bad modem ack " - "0x%02x.\n", - board_No(bp), ack); - } - rc_out(bp, CD180_EOIR, 0); /* Mark end of interrupt */ - rc_out(bp, RC_CTOUT, 0); /* Clear timeout flag */ - } - return IRQ_RETVAL(handled); -} - -/* - * Routines for open & close processing. - */ - -/* Called with disabled interrupts */ -static int rc_setup_board(struct riscom_board *bp) -{ - int error; - - if (bp->flags & RC_BOARD_ACTIVE) - return 0; - - error = request_irq(bp->irq, rc_interrupt, IRQF_DISABLED, - "RISCom/8", bp); - if (error) - return error; - - rc_out(bp, RC_CTOUT, 0); /* Just in case */ - bp->DTR = ~0; - rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ - - bp->flags |= RC_BOARD_ACTIVE; - - return 0; -} - -/* Called with disabled interrupts */ -static void rc_shutdown_board(struct riscom_board *bp) -{ - if (!(bp->flags & RC_BOARD_ACTIVE)) - return; - - bp->flags &= ~RC_BOARD_ACTIVE; - - free_irq(bp->irq, NULL); - - bp->DTR = ~0; - rc_out(bp, RC_DTR, bp->DTR); /* Drop DTR on all ports */ - -} - -/* - * Setting up port characteristics. - * Must be called with disabled interrupts - */ -static void rc_change_speed(struct tty_struct *tty, struct riscom_board *bp, - struct riscom_port *port) -{ - unsigned long baud; - long tmp; - unsigned char cor1 = 0, cor3 = 0; - unsigned char mcor1 = 0, mcor2 = 0; - - port->IER = 0; - port->COR2 = 0; - port->MSVR = MSVR_RTS; - - baud = tty_get_baud_rate(tty); - - /* Select port on the board */ - rc_out(bp, CD180_CAR, port_No(port)); - - if (!baud) { - /* Drop DTR & exit */ - bp->DTR |= (1u << port_No(port)); - rc_out(bp, RC_DTR, bp->DTR); - return; - } else { - /* Set DTR on */ - bp->DTR &= ~(1u << port_No(port)); - rc_out(bp, RC_DTR, bp->DTR); - } - - /* - * Now we must calculate some speed depended things - */ - - /* Set baud rate for port */ - tmp = (((RC_OSCFREQ + baud/2) / baud + - CD180_TPC/2) / CD180_TPC); - - rc_out(bp, CD180_RBPRH, (tmp >> 8) & 0xff); - rc_out(bp, CD180_TBPRH, (tmp >> 8) & 0xff); - rc_out(bp, CD180_RBPRL, tmp & 0xff); - rc_out(bp, CD180_TBPRL, tmp & 0xff); - - baud = (baud + 5) / 10; /* Estimated CPS */ - - /* Two timer ticks seems enough to wakeup something like SLIP driver */ - tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO; - port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? - SERIAL_XMIT_SIZE - 1 : tmp); - - /* Receiver timeout will be transmission time for 1.5 chars */ - tmp = (RISCOM_TPS + RISCOM_TPS/2 + baud/2) / baud; - tmp = (tmp > 0xff) ? 0xff : tmp; - rc_out(bp, CD180_RTPR, tmp); - - switch (C_CSIZE(tty)) { - case CS5: - cor1 |= COR1_5BITS; - break; - case CS6: - cor1 |= COR1_6BITS; - break; - case CS7: - cor1 |= COR1_7BITS; - break; - case CS8: - cor1 |= COR1_8BITS; - break; - } - if (C_CSTOPB(tty)) - cor1 |= COR1_2SB; - - cor1 |= COR1_IGNORE; - if (C_PARENB(tty)) { - cor1 |= COR1_NORMPAR; - if (C_PARODD(tty)) - cor1 |= COR1_ODDP; - if (I_INPCK(tty)) - cor1 &= ~COR1_IGNORE; - } - /* Set marking of some errors */ - port->mark_mask = RCSR_OE | RCSR_TOUT; - if (I_INPCK(tty)) - port->mark_mask |= RCSR_FE | RCSR_PE; - if (I_BRKINT(tty) || I_PARMRK(tty)) - port->mark_mask |= RCSR_BREAK; - if (I_IGNPAR(tty)) - port->mark_mask &= ~(RCSR_FE | RCSR_PE); - if (I_IGNBRK(tty)) { - port->mark_mask &= ~RCSR_BREAK; - if (I_IGNPAR(tty)) - /* Real raw mode. Ignore all */ - port->mark_mask &= ~RCSR_OE; - } - /* Enable Hardware Flow Control */ - if (C_CRTSCTS(tty)) { -#ifdef RISCOM_BRAIN_DAMAGED_CTS - port->IER |= IER_DSR | IER_CTS; - mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; - mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; - tty->hw_stopped = !(rc_in(bp, CD180_MSVR) & - (MSVR_CTS|MSVR_DSR)); -#else - port->COR2 |= COR2_CTSAE; -#endif - } - /* Enable Software Flow Control. FIXME: I'm not sure about this */ - /* Some people reported that it works, but I still doubt */ - if (I_IXON(tty)) { - port->COR2 |= COR2_TXIBE; - cor3 |= (COR3_FCT | COR3_SCDE); - if (I_IXANY(tty)) - port->COR2 |= COR2_IXM; - rc_out(bp, CD180_SCHR1, START_CHAR(tty)); - rc_out(bp, CD180_SCHR2, STOP_CHAR(tty)); - rc_out(bp, CD180_SCHR3, START_CHAR(tty)); - rc_out(bp, CD180_SCHR4, STOP_CHAR(tty)); - } - if (!C_CLOCAL(tty)) { - /* Enable CD check */ - port->IER |= IER_CD; - mcor1 |= MCOR1_CDZD; - mcor2 |= MCOR2_CDOD; - } - - if (C_CREAD(tty)) - /* Enable receiver */ - port->IER |= IER_RXD; - - /* Set input FIFO size (1-8 bytes) */ - cor3 |= RISCOM_RXFIFO; - /* Setting up CD180 channel registers */ - rc_out(bp, CD180_COR1, cor1); - rc_out(bp, CD180_COR2, port->COR2); - rc_out(bp, CD180_COR3, cor3); - /* Make CD180 know about registers change */ - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3); - /* Setting up modem option registers */ - rc_out(bp, CD180_MCOR1, mcor1); - rc_out(bp, CD180_MCOR2, mcor2); - /* Enable CD180 transmitter & receiver */ - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_TXEN | CCR_RXEN); - /* Enable interrupts */ - rc_out(bp, CD180_IER, port->IER); - /* And finally set RTS on */ - rc_out(bp, CD180_MSVR, port->MSVR); -} - -/* Must be called with interrupts enabled */ -static int rc_activate_port(struct tty_port *port, struct tty_struct *tty) -{ - struct riscom_port *rp = container_of(port, struct riscom_port, port); - struct riscom_board *bp = port_Board(rp); - unsigned long flags; - - if (tty_port_alloc_xmit_buf(port) < 0) - return -ENOMEM; - - spin_lock_irqsave(&riscom_lock, flags); - - clear_bit(TTY_IO_ERROR, &tty->flags); - bp->count++; - rp->xmit_cnt = rp->xmit_head = rp->xmit_tail = 0; - rc_change_speed(tty, bp, rp); - spin_unlock_irqrestore(&riscom_lock, flags); - return 0; -} - -/* Must be called with interrupts disabled */ -static void rc_shutdown_port(struct tty_struct *tty, - struct riscom_board *bp, struct riscom_port *port) -{ -#ifdef RC_REPORT_OVERRUN - printk(KERN_INFO "rc%d: port %d: Total %ld overruns were detected.\n", - board_No(bp), port_No(port), port->overrun); -#endif -#ifdef RC_REPORT_FIFO - { - int i; - - printk(KERN_INFO "rc%d: port %d: FIFO hits [ ", - board_No(bp), port_No(port)); - for (i = 0; i < 10; i++) - printk("%ld ", port->hits[i]); - printk("].\n"); - } -#endif - tty_port_free_xmit_buf(&port->port); - - /* Select port */ - rc_out(bp, CD180_CAR, port_No(port)); - /* Reset port */ - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_SOFTRESET); - /* Disable all interrupts from this port */ - port->IER = 0; - rc_out(bp, CD180_IER, port->IER); - - set_bit(TTY_IO_ERROR, &tty->flags); - - if (--bp->count < 0) { - printk(KERN_INFO "rc%d: rc_shutdown_port: " - "bad board count: %d\n", - board_No(bp), bp->count); - bp->count = 0; - } - /* - * If this is the last opened port on the board - * shutdown whole board - */ - if (!bp->count) - rc_shutdown_board(bp); -} - -static int carrier_raised(struct tty_port *port) -{ - struct riscom_port *p = container_of(port, struct riscom_port, port); - struct riscom_board *bp = port_Board(p); - unsigned long flags; - int CD; - - spin_lock_irqsave(&riscom_lock, flags); - rc_out(bp, CD180_CAR, port_No(p)); - CD = rc_in(bp, CD180_MSVR) & MSVR_CD; - rc_out(bp, CD180_MSVR, MSVR_RTS); - bp->DTR &= ~(1u << port_No(p)); - rc_out(bp, RC_DTR, bp->DTR); - spin_unlock_irqrestore(&riscom_lock, flags); - return CD; -} - -static void dtr_rts(struct tty_port *port, int onoff) -{ - struct riscom_port *p = container_of(port, struct riscom_port, port); - struct riscom_board *bp = port_Board(p); - unsigned long flags; - - spin_lock_irqsave(&riscom_lock, flags); - bp->DTR &= ~(1u << port_No(p)); - if (onoff == 0) - bp->DTR |= (1u << port_No(p)); - rc_out(bp, RC_DTR, bp->DTR); - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static int rc_open(struct tty_struct *tty, struct file *filp) -{ - int board; - int error; - struct riscom_port *port; - struct riscom_board *bp; - - board = RC_BOARD(tty->index); - if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT)) - return -ENODEV; - - bp = &rc_board[board]; - port = rc_port + board * RC_NPORT + RC_PORT(tty->index); - if (rc_paranoia_check(port, tty->name, "rc_open")) - return -ENODEV; - - error = rc_setup_board(bp); - if (error) - return error; - - tty->driver_data = port; - return tty_port_open(&port->port, tty, filp); -} - -static void rc_flush_buffer(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) - return; - - spin_lock_irqsave(&riscom_lock, flags); - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - spin_unlock_irqrestore(&riscom_lock, flags); - - tty_wakeup(tty); -} - -static void rc_close_port(struct tty_port *port) -{ - unsigned long flags; - struct riscom_port *rp = container_of(port, struct riscom_port, port); - struct riscom_board *bp = port_Board(rp); - unsigned long timeout; - - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - - spin_lock_irqsave(&riscom_lock, flags); - rp->IER &= ~IER_RXD; - - rp->IER &= ~IER_TXRDY; - rp->IER |= IER_TXEMPTY; - rc_out(bp, CD180_CAR, port_No(rp)); - rc_out(bp, CD180_IER, rp->IER); - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - timeout = jiffies + HZ; - while (rp->IER & IER_TXEMPTY) { - spin_unlock_irqrestore(&riscom_lock, flags); - msleep_interruptible(jiffies_to_msecs(rp->timeout)); - spin_lock_irqsave(&riscom_lock, flags); - if (time_after(jiffies, timeout)) - break; - } - rc_shutdown_port(port->tty, bp, rp); - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static void rc_close(struct tty_struct *tty, struct file *filp) -{ - struct riscom_port *port = tty->driver_data; - - if (!port || rc_paranoia_check(port, tty->name, "close")) - return; - tty_port_close(&port->port, tty, filp); -} - -static int rc_write(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp; - int c, total = 0; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_write")) - return 0; - - bp = port_Board(port); - - while (1) { - spin_lock_irqsave(&riscom_lock, flags); - - c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, - SERIAL_XMIT_SIZE - port->xmit_head)); - if (c <= 0) - break; /* lock continues to be held */ - - memcpy(port->port.xmit_buf + port->xmit_head, buf, c); - port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - port->xmit_cnt += c; - - spin_unlock_irqrestore(&riscom_lock, flags); - - buf += c; - count -= c; - total += c; - } - - if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && - !(port->IER & IER_TXRDY)) { - port->IER |= IER_TXRDY; - rc_out(bp, CD180_CAR, port_No(port)); - rc_out(bp, CD180_IER, port->IER); - } - - spin_unlock_irqrestore(&riscom_lock, flags); - - return total; -} - -static int rc_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct riscom_port *port = tty->driver_data; - unsigned long flags; - int ret = 0; - - if (rc_paranoia_check(port, tty->name, "rc_put_char")) - return 0; - - spin_lock_irqsave(&riscom_lock, flags); - - if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) - goto out; - - port->port.xmit_buf[port->xmit_head++] = ch; - port->xmit_head &= SERIAL_XMIT_SIZE - 1; - port->xmit_cnt++; - ret = 1; - -out: - spin_unlock_irqrestore(&riscom_lock, flags); - return ret; -} - -static void rc_flush_chars(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_flush_chars")) - return; - - if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped) - return; - - spin_lock_irqsave(&riscom_lock, flags); - - port->IER |= IER_TXRDY; - rc_out(port_Board(port), CD180_CAR, port_No(port)); - rc_out(port_Board(port), CD180_IER, port->IER); - - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static int rc_write_room(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - int ret; - - if (rc_paranoia_check(port, tty->name, "rc_write_room")) - return 0; - - ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; - if (ret < 0) - ret = 0; - return ret; -} - -static int rc_chars_in_buffer(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - - if (rc_paranoia_check(port, tty->name, "rc_chars_in_buffer")) - return 0; - - return port->xmit_cnt; -} - -static int rc_tiocmget(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp; - unsigned char status; - unsigned int result; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, __func__)) - return -ENODEV; - - bp = port_Board(port); - - spin_lock_irqsave(&riscom_lock, flags); - - rc_out(bp, CD180_CAR, port_No(port)); - status = rc_in(bp, CD180_MSVR); - result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG; - - spin_unlock_irqrestore(&riscom_lock, flags); - - result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0) - | ((status & MSVR_DTR) ? TIOCM_DTR : 0) - | ((status & MSVR_CD) ? TIOCM_CAR : 0) - | ((status & MSVR_DSR) ? TIOCM_DSR : 0) - | ((status & MSVR_CTS) ? TIOCM_CTS : 0); - return result; -} - -static int rc_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct riscom_port *port = tty->driver_data; - unsigned long flags; - struct riscom_board *bp; - - if (rc_paranoia_check(port, tty->name, __func__)) - return -ENODEV; - - bp = port_Board(port); - - spin_lock_irqsave(&riscom_lock, flags); - - if (set & TIOCM_RTS) - port->MSVR |= MSVR_RTS; - if (set & TIOCM_DTR) - bp->DTR &= ~(1u << port_No(port)); - - if (clear & TIOCM_RTS) - port->MSVR &= ~MSVR_RTS; - if (clear & TIOCM_DTR) - bp->DTR |= (1u << port_No(port)); - - rc_out(bp, CD180_CAR, port_No(port)); - rc_out(bp, CD180_MSVR, port->MSVR); - rc_out(bp, RC_DTR, bp->DTR); - - spin_unlock_irqrestore(&riscom_lock, flags); - - return 0; -} - -static int rc_send_break(struct tty_struct *tty, int length) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp = port_Board(port); - unsigned long flags; - - if (length == 0 || length == -1) - return -EOPNOTSUPP; - - spin_lock_irqsave(&riscom_lock, flags); - - port->break_length = RISCOM_TPS / HZ * length; - port->COR2 |= COR2_ETC; - port->IER |= IER_TXRDY; - rc_out(bp, CD180_CAR, port_No(port)); - rc_out(bp, CD180_COR2, port->COR2); - rc_out(bp, CD180_IER, port->IER); - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_CORCHG2); - rc_wait_CCR(bp); - - spin_unlock_irqrestore(&riscom_lock, flags); - return 0; -} - -static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port, - struct serial_struct __user *newinfo) -{ - struct serial_struct tmp; - struct riscom_board *bp = port_Board(port); - int change_speed; - - if (copy_from_user(&tmp, newinfo, sizeof(tmp))) - return -EFAULT; - - mutex_lock(&port->port.mutex); - change_speed = ((port->port.flags & ASYNC_SPD_MASK) != - (tmp.flags & ASYNC_SPD_MASK)); - - if (!capable(CAP_SYS_ADMIN)) { - if ((tmp.close_delay != port->port.close_delay) || - (tmp.closing_wait != port->port.closing_wait) || - ((tmp.flags & ~ASYNC_USR_MASK) != - (port->port.flags & ~ASYNC_USR_MASK))) { - mutex_unlock(&port->port.mutex); - return -EPERM; - } - port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | - (tmp.flags & ASYNC_USR_MASK)); - } else { - port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | - (tmp.flags & ASYNC_FLAGS)); - port->port.close_delay = tmp.close_delay; - port->port.closing_wait = tmp.closing_wait; - } - if (change_speed) { - unsigned long flags; - - spin_lock_irqsave(&riscom_lock, flags); - rc_change_speed(tty, bp, port); - spin_unlock_irqrestore(&riscom_lock, flags); - } - mutex_unlock(&port->port.mutex); - return 0; -} - -static int rc_get_serial_info(struct riscom_port *port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - struct riscom_board *bp = port_Board(port); - - memset(&tmp, 0, sizeof(tmp)); - tmp.type = PORT_CIRRUS; - tmp.line = port - rc_port; - - mutex_lock(&port->port.mutex); - tmp.port = bp->base; - tmp.irq = bp->irq; - tmp.flags = port->port.flags; - tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC; - tmp.close_delay = port->port.close_delay * HZ/100; - tmp.closing_wait = port->port.closing_wait * HZ/100; - mutex_unlock(&port->port.mutex); - tmp.xmit_fifo_size = CD180_NFIFO; - return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0; -} - -static int rc_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct riscom_port *port = tty->driver_data; - void __user *argp = (void __user *)arg; - int retval; - - if (rc_paranoia_check(port, tty->name, "rc_ioctl")) - return -ENODEV; - - switch (cmd) { - case TIOCGSERIAL: - retval = rc_get_serial_info(port, argp); - break; - case TIOCSSERIAL: - retval = rc_set_serial_info(tty, port, argp); - break; - default: - retval = -ENOIOCTLCMD; - } - return retval; -} - -static void rc_throttle(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_throttle")) - return; - bp = port_Board(port); - - spin_lock_irqsave(&riscom_lock, flags); - port->MSVR &= ~MSVR_RTS; - rc_out(bp, CD180_CAR, port_No(port)); - if (I_IXOFF(tty)) { - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_SSCH2); - rc_wait_CCR(bp); - } - rc_out(bp, CD180_MSVR, port->MSVR); - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static void rc_unthrottle(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_unthrottle")) - return; - bp = port_Board(port); - - spin_lock_irqsave(&riscom_lock, flags); - port->MSVR |= MSVR_RTS; - rc_out(bp, CD180_CAR, port_No(port)); - if (I_IXOFF(tty)) { - rc_wait_CCR(bp); - rc_out(bp, CD180_CCR, CCR_SSCH1); - rc_wait_CCR(bp); - } - rc_out(bp, CD180_MSVR, port->MSVR); - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static void rc_stop(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_stop")) - return; - - bp = port_Board(port); - - spin_lock_irqsave(&riscom_lock, flags); - port->IER &= ~IER_TXRDY; - rc_out(bp, CD180_CAR, port_No(port)); - rc_out(bp, CD180_IER, port->IER); - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static void rc_start(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - struct riscom_board *bp; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_start")) - return; - - bp = port_Board(port); - - spin_lock_irqsave(&riscom_lock, flags); - - if (port->xmit_cnt && port->port.xmit_buf && !(port->IER & IER_TXRDY)) { - port->IER |= IER_TXRDY; - rc_out(bp, CD180_CAR, port_No(port)); - rc_out(bp, CD180_IER, port->IER); - } - spin_unlock_irqrestore(&riscom_lock, flags); -} - -static void rc_hangup(struct tty_struct *tty) -{ - struct riscom_port *port = tty->driver_data; - - if (rc_paranoia_check(port, tty->name, "rc_hangup")) - return; - - tty_port_hangup(&port->port); -} - -static void rc_set_termios(struct tty_struct *tty, - struct ktermios *old_termios) -{ - struct riscom_port *port = tty->driver_data; - unsigned long flags; - - if (rc_paranoia_check(port, tty->name, "rc_set_termios")) - return; - - spin_lock_irqsave(&riscom_lock, flags); - rc_change_speed(tty, port_Board(port), port); - spin_unlock_irqrestore(&riscom_lock, flags); - - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rc_start(tty); - } -} - -static const struct tty_operations riscom_ops = { - .open = rc_open, - .close = rc_close, - .write = rc_write, - .put_char = rc_put_char, - .flush_chars = rc_flush_chars, - .write_room = rc_write_room, - .chars_in_buffer = rc_chars_in_buffer, - .flush_buffer = rc_flush_buffer, - .ioctl = rc_ioctl, - .throttle = rc_throttle, - .unthrottle = rc_unthrottle, - .set_termios = rc_set_termios, - .stop = rc_stop, - .start = rc_start, - .hangup = rc_hangup, - .tiocmget = rc_tiocmget, - .tiocmset = rc_tiocmset, - .break_ctl = rc_send_break, -}; - -static const struct tty_port_operations riscom_port_ops = { - .carrier_raised = carrier_raised, - .dtr_rts = dtr_rts, - .shutdown = rc_close_port, - .activate = rc_activate_port, -}; - - -static int __init rc_init_drivers(void) -{ - int error; - int i; - - riscom_driver = alloc_tty_driver(RC_NBOARD * RC_NPORT); - if (!riscom_driver) - return -ENOMEM; - - riscom_driver->owner = THIS_MODULE; - riscom_driver->name = "ttyL"; - riscom_driver->major = RISCOM8_NORMAL_MAJOR; - riscom_driver->type = TTY_DRIVER_TYPE_SERIAL; - riscom_driver->subtype = SERIAL_TYPE_NORMAL; - riscom_driver->init_termios = tty_std_termios; - riscom_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - riscom_driver->init_termios.c_ispeed = 9600; - riscom_driver->init_termios.c_ospeed = 9600; - riscom_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_HARDWARE_BREAK; - tty_set_operations(riscom_driver, &riscom_ops); - error = tty_register_driver(riscom_driver); - if (error != 0) { - put_tty_driver(riscom_driver); - printk(KERN_ERR "rc: Couldn't register RISCom/8 driver, " - "error = %d\n", error); - return 1; - } - memset(rc_port, 0, sizeof(rc_port)); - for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { - tty_port_init(&rc_port[i].port); - rc_port[i].port.ops = &riscom_port_ops; - rc_port[i].magic = RISCOM8_MAGIC; - } - return 0; -} - -static void rc_release_drivers(void) -{ - tty_unregister_driver(riscom_driver); - put_tty_driver(riscom_driver); -} - -#ifndef MODULE -/* - * Called at boot time. - * - * You can specify IO base for up to RC_NBOARD cards, - * using line "riscom8=0xiobase1,0xiobase2,.." at LILO prompt. - * Note that there will be no probing at default - * addresses in this case. - * - */ -static int __init riscom8_setup(char *str) -{ - int ints[RC_NBOARD]; - int i; - - str = get_options(str, ARRAY_SIZE(ints), ints); - - for (i = 0; i < RC_NBOARD; i++) { - if (i < ints[0]) - rc_board[i].base = ints[i+1]; - else - rc_board[i].base = 0; - } - return 1; -} - -__setup("riscom8=", riscom8_setup); -#endif - -static char banner[] __initdata = - KERN_INFO "rc: SDL RISCom/8 card driver v1.1, (c) D.Gorodchanin " - "1994-1996.\n"; -static char no_boards_msg[] __initdata = - KERN_INFO "rc: No RISCom/8 boards detected.\n"; - -/* - * This routine must be called by kernel at boot time - */ -static int __init riscom8_init(void) -{ - int i; - int found = 0; - - printk(banner); - - if (rc_init_drivers()) - return -EIO; - - for (i = 0; i < RC_NBOARD; i++) - if (rc_board[i].base && !rc_probe(&rc_board[i])) - found++; - if (!found) { - rc_release_drivers(); - printk(no_boards_msg); - return -EIO; - } - return 0; -} - -#ifdef MODULE -static int iobase; -static int iobase1; -static int iobase2; -static int iobase3; -module_param(iobase, int, 0); -module_param(iobase1, int, 0); -module_param(iobase2, int, 0); -module_param(iobase3, int, 0); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_CHARDEV_MAJOR(RISCOM8_NORMAL_MAJOR); -#endif /* MODULE */ - -/* - * You can setup up to 4 boards (current value of RC_NBOARD) - * by specifying "iobase=0xXXX iobase1=0xXXX ..." as insmod parameter. - * - */ -static int __init riscom8_init_module(void) -{ -#ifdef MODULE - int i; - - if (iobase || iobase1 || iobase2 || iobase3) { - for (i = 0; i < RC_NBOARD; i++) - rc_board[i].base = 0; - } - - if (iobase) - rc_board[0].base = iobase; - if (iobase1) - rc_board[1].base = iobase1; - if (iobase2) - rc_board[2].base = iobase2; - if (iobase3) - rc_board[3].base = iobase3; -#endif /* MODULE */ - - return riscom8_init(); -} - -static void __exit riscom8_exit_module(void) -{ - int i; - - rc_release_drivers(); - for (i = 0; i < RC_NBOARD; i++) - if (rc_board[i].flags & RC_BOARD_PRESENT) - rc_release_io_range(&rc_board[i]); - -} - -module_init(riscom8_init_module); -module_exit(riscom8_exit_module); diff --git a/drivers/staging/tty/riscom8.h b/drivers/staging/tty/riscom8.h deleted file mode 100644 index c9876b3f9714..000000000000 --- a/drivers/staging/tty/riscom8.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * linux/drivers/char/riscom8.h -- RISCom/8 multiport serial driver. - * - * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) - * - * This code is loosely based on the Linux serial driver, written by - * Linus Torvalds, Theodore T'so and others. The RISCom/8 card - * programming info was obtained from various drivers for other OSes - * (FreeBSD, ISC, etc), but no source code from those drivers were - * directly included in this 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. - * - * 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 __LINUX_RISCOM8_H -#define __LINUX_RISCOM8_H - -#include - -#ifdef __KERNEL__ - -#define RC_NBOARD 4 -/* NOTE: RISCom decoder recognizes 16 addresses... */ -#define RC_NPORT 8 -#define RC_BOARD(line) (((line) >> 3) & 0x07) -#define RC_PORT(line) ((line) & (RC_NPORT - 1)) - -/* Ticks per sec. Used for setting receiver timeout and break length */ -#define RISCOM_TPS 4000 - -/* Yeah, after heavy testing I decided it must be 6. - * Sure, You can change it if needed. - */ -#define RISCOM_RXFIFO 6 /* Max. receiver FIFO size (1-8) */ - -#define RISCOM8_MAGIC 0x0907 - -#define RC_IOBASE1 0x220 -#define RC_IOBASE2 0x240 -#define RC_IOBASE3 0x250 -#define RC_IOBASE4 0x260 - -struct riscom_board { - unsigned long flags; - unsigned short base; - unsigned char irq; - signed char count; - unsigned char DTR; -}; - -#define RC_BOARD_PRESENT 0x00000001 -#define RC_BOARD_ACTIVE 0x00000002 - -struct riscom_port { - int magic; - struct tty_port port; - int baud_base; - int timeout; - int custom_divisor; - int xmit_head; - int xmit_tail; - int xmit_cnt; - short wakeup_chars; - short break_length; - unsigned char mark_mask; - unsigned char IER; - unsigned char MSVR; - unsigned char COR2; -#ifdef RC_REPORT_OVERRUN - unsigned long overrun; -#endif -#ifdef RC_REPORT_FIFO - unsigned long hits[10]; -#endif -}; - -#endif /* __KERNEL__ */ -#endif /* __LINUX_RISCOM8_H */ diff --git a/drivers/staging/tty/riscom8_reg.h b/drivers/staging/tty/riscom8_reg.h deleted file mode 100644 index a32475ed0d18..000000000000 --- a/drivers/staging/tty/riscom8_reg.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - * linux/drivers/char/riscom8_reg.h -- RISCom/8 multiport serial driver. - */ - -/* - * Definitions for RISCom/8 Async Mux card by SDL Communications, Inc. - */ - -/* - * Address mapping between Cirrus Logic CD180 chip internal registers - * and ISA port addresses: - * - * CL-CD180 A6 A5 A4 A3 A2 A1 A0 - * ISA A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 - */ -#define RC_TO_ISA(r) ((((r)&0x07)<<1) | (((r)&~0x07)<<7)) - - -/* RISCom/8 On-Board Registers (assuming address translation) */ - -#define RC_RI 0x100 /* Ring Indicator Register (R/O) */ -#define RC_DTR 0x100 /* DTR Register (W/O) */ -#define RC_BSR 0x101 /* Board Status Register (R/O) */ -#define RC_CTOUT 0x101 /* Clear Timeout (W/O) */ - - -/* Board Status Register */ - -#define RC_BSR_TOUT 0x08 /* Hardware Timeout */ -#define RC_BSR_RINT 0x04 /* Receiver Interrupt */ -#define RC_BSR_TINT 0x02 /* Transmitter Interrupt */ -#define RC_BSR_MINT 0x01 /* Modem Ctl Interrupt */ - - -/* On-board oscillator frequency (in Hz) */ -#define RC_OSCFREQ 9830400 - -/* Values of choice for Interrupt ACKs */ -#define RC_ACK_MINT 0x81 /* goes to PILR1 */ -#define RC_ACK_RINT 0x82 /* goes to PILR3 */ -#define RC_ACK_TINT 0x84 /* goes to PILR2 */ - -/* Chip ID (sorry, only one chip now) */ -#define RC_ID 0x10 - -/* Definitions for Cirrus Logic CL-CD180 8-port async mux chip */ - -#define CD180_NCH 8 /* Total number of channels */ -#define CD180_TPC 16 /* Ticks per character */ -#define CD180_NFIFO 8 /* TX FIFO size */ - - -/* Global registers */ - -#define CD180_GIVR 0x40 /* Global Interrupt Vector Register */ -#define CD180_GICR 0x41 /* Global Interrupting Channel Register */ -#define CD180_PILR1 0x61 /* Priority Interrupt Level Register 1 */ -#define CD180_PILR2 0x62 /* Priority Interrupt Level Register 2 */ -#define CD180_PILR3 0x63 /* Priority Interrupt Level Register 3 */ -#define CD180_CAR 0x64 /* Channel Access Register */ -#define CD180_GFRCR 0x6b /* Global Firmware Revision Code Register */ -#define CD180_PPRH 0x70 /* Prescaler Period Register High */ -#define CD180_PPRL 0x71 /* Prescaler Period Register Low */ -#define CD180_RDR 0x78 /* Receiver Data Register */ -#define CD180_RCSR 0x7a /* Receiver Character Status Register */ -#define CD180_TDR 0x7b /* Transmit Data Register */ -#define CD180_EOIR 0x7f /* End of Interrupt Register */ - - -/* Channel Registers */ - -#define CD180_CCR 0x01 /* Channel Command Register */ -#define CD180_IER 0x02 /* Interrupt Enable Register */ -#define CD180_COR1 0x03 /* Channel Option Register 1 */ -#define CD180_COR2 0x04 /* Channel Option Register 2 */ -#define CD180_COR3 0x05 /* Channel Option Register 3 */ -#define CD180_CCSR 0x06 /* Channel Control Status Register */ -#define CD180_RDCR 0x07 /* Receive Data Count Register */ -#define CD180_SCHR1 0x09 /* Special Character Register 1 */ -#define CD180_SCHR2 0x0a /* Special Character Register 2 */ -#define CD180_SCHR3 0x0b /* Special Character Register 3 */ -#define CD180_SCHR4 0x0c /* Special Character Register 4 */ -#define CD180_MCOR1 0x10 /* Modem Change Option 1 Register */ -#define CD180_MCOR2 0x11 /* Modem Change Option 2 Register */ -#define CD180_MCR 0x12 /* Modem Change Register */ -#define CD180_RTPR 0x18 /* Receive Timeout Period Register */ -#define CD180_MSVR 0x28 /* Modem Signal Value Register */ -#define CD180_RBPRH 0x31 /* Receive Baud Rate Period Register High */ -#define CD180_RBPRL 0x32 /* Receive Baud Rate Period Register Low */ -#define CD180_TBPRH 0x39 /* Transmit Baud Rate Period Register High */ -#define CD180_TBPRL 0x3a /* Transmit Baud Rate Period Register Low */ - - -/* Global Interrupt Vector Register (R/W) */ - -#define GIVR_ITMASK 0x07 /* Interrupt type mask */ -#define GIVR_IT_MODEM 0x01 /* Modem Signal Change Interrupt */ -#define GIVR_IT_TX 0x02 /* Transmit Data Interrupt */ -#define GIVR_IT_RCV 0x03 /* Receive Good Data Interrupt */ -#define GIVR_IT_REXC 0x07 /* Receive Exception Interrupt */ - - -/* Global Interrupt Channel Register (R/W) */ - -#define GICR_CHAN 0x1c /* Channel Number Mask */ -#define GICR_CHAN_OFF 2 /* Channel Number Offset */ - - -/* Channel Address Register (R/W) */ - -#define CAR_CHAN 0x07 /* Channel Number Mask */ -#define CAR_A7 0x08 /* A7 Address Extension (unused) */ - - -/* Receive Character Status Register (R/O) */ - -#define RCSR_TOUT 0x80 /* Rx Timeout */ -#define RCSR_SCDET 0x70 /* Special Character Detected Mask */ -#define RCSR_NO_SC 0x00 /* No Special Characters Detected */ -#define RCSR_SC_1 0x10 /* Special Char 1 (or 1 & 3) Detected */ -#define RCSR_SC_2 0x20 /* Special Char 2 (or 2 & 4) Detected */ -#define RCSR_SC_3 0x30 /* Special Char 3 Detected */ -#define RCSR_SC_4 0x40 /* Special Char 4 Detected */ -#define RCSR_BREAK 0x08 /* Break has been detected */ -#define RCSR_PE 0x04 /* Parity Error */ -#define RCSR_FE 0x02 /* Frame Error */ -#define RCSR_OE 0x01 /* Overrun Error */ - - -/* Channel Command Register (R/W) (commands in groups can be OR-ed) */ - -#define CCR_HARDRESET 0x81 /* Reset the chip */ - -#define CCR_SOFTRESET 0x80 /* Soft Channel Reset */ - -#define CCR_CORCHG1 0x42 /* Channel Option Register 1 Changed */ -#define CCR_CORCHG2 0x44 /* Channel Option Register 2 Changed */ -#define CCR_CORCHG3 0x48 /* Channel Option Register 3 Changed */ - -#define CCR_SSCH1 0x21 /* Send Special Character 1 */ - -#define CCR_SSCH2 0x22 /* Send Special Character 2 */ - -#define CCR_SSCH3 0x23 /* Send Special Character 3 */ - -#define CCR_SSCH4 0x24 /* Send Special Character 4 */ - -#define CCR_TXEN 0x18 /* Enable Transmitter */ -#define CCR_RXEN 0x12 /* Enable Receiver */ - -#define CCR_TXDIS 0x14 /* Disable Transmitter */ -#define CCR_RXDIS 0x11 /* Disable Receiver */ - - -/* Interrupt Enable Register (R/W) */ - -#define IER_DSR 0x80 /* Enable interrupt on DSR change */ -#define IER_CD 0x40 /* Enable interrupt on CD change */ -#define IER_CTS 0x20 /* Enable interrupt on CTS change */ -#define IER_RXD 0x10 /* Enable interrupt on Receive Data */ -#define IER_RXSC 0x08 /* Enable interrupt on Receive Spec. Char */ -#define IER_TXRDY 0x04 /* Enable interrupt on TX FIFO empty */ -#define IER_TXEMPTY 0x02 /* Enable interrupt on TX completely empty */ -#define IER_RET 0x01 /* Enable interrupt on RX Exc. Timeout */ - - -/* Channel Option Register 1 (R/W) */ - -#define COR1_ODDP 0x80 /* Odd Parity */ -#define COR1_PARMODE 0x60 /* Parity Mode mask */ -#define COR1_NOPAR 0x00 /* No Parity */ -#define COR1_FORCEPAR 0x20 /* Force Parity */ -#define COR1_NORMPAR 0x40 /* Normal Parity */ -#define COR1_IGNORE 0x10 /* Ignore Parity on RX */ -#define COR1_STOPBITS 0x0c /* Number of Stop Bits */ -#define COR1_1SB 0x00 /* 1 Stop Bit */ -#define COR1_15SB 0x04 /* 1.5 Stop Bits */ -#define COR1_2SB 0x08 /* 2 Stop Bits */ -#define COR1_CHARLEN 0x03 /* Character Length */ -#define COR1_5BITS 0x00 /* 5 bits */ -#define COR1_6BITS 0x01 /* 6 bits */ -#define COR1_7BITS 0x02 /* 7 bits */ -#define COR1_8BITS 0x03 /* 8 bits */ - - -/* Channel Option Register 2 (R/W) */ - -#define COR2_IXM 0x80 /* Implied XON mode */ -#define COR2_TXIBE 0x40 /* Enable In-Band (XON/XOFF) Flow Control */ -#define COR2_ETC 0x20 /* Embedded Tx Commands Enable */ -#define COR2_LLM 0x10 /* Local Loopback Mode */ -#define COR2_RLM 0x08 /* Remote Loopback Mode */ -#define COR2_RTSAO 0x04 /* RTS Automatic Output Enable */ -#define COR2_CTSAE 0x02 /* CTS Automatic Enable */ -#define COR2_DSRAE 0x01 /* DSR Automatic Enable */ - - -/* Channel Option Register 3 (R/W) */ - -#define COR3_XONCH 0x80 /* XON is a pair of characters (1 & 3) */ -#define COR3_XOFFCH 0x40 /* XOFF is a pair of characters (2 & 4) */ -#define COR3_FCT 0x20 /* Flow-Control Transparency Mode */ -#define COR3_SCDE 0x10 /* Special Character Detection Enable */ -#define COR3_RXTH 0x0f /* RX FIFO Threshold value (1-8) */ - - -/* Channel Control Status Register (R/O) */ - -#define CCSR_RXEN 0x80 /* Receiver Enabled */ -#define CCSR_RXFLOFF 0x40 /* Receive Flow Off (XOFF was sent) */ -#define CCSR_RXFLON 0x20 /* Receive Flow On (XON was sent) */ -#define CCSR_TXEN 0x08 /* Transmitter Enabled */ -#define CCSR_TXFLOFF 0x04 /* Transmit Flow Off (got XOFF) */ -#define CCSR_TXFLON 0x02 /* Transmit Flow On (got XON) */ - - -/* Modem Change Option Register 1 (R/W) */ - -#define MCOR1_DSRZD 0x80 /* Detect 0->1 transition of DSR */ -#define MCOR1_CDZD 0x40 /* Detect 0->1 transition of CD */ -#define MCOR1_CTSZD 0x20 /* Detect 0->1 transition of CTS */ -#define MCOR1_DTRTH 0x0f /* Auto DTR flow control Threshold (1-8) */ -#define MCOR1_NODTRFC 0x0 /* Automatic DTR flow control disabled */ - - -/* Modem Change Option Register 2 (R/W) */ - -#define MCOR2_DSROD 0x80 /* Detect 1->0 transition of DSR */ -#define MCOR2_CDOD 0x40 /* Detect 1->0 transition of CD */ -#define MCOR2_CTSOD 0x20 /* Detect 1->0 transition of CTS */ - - -/* Modem Change Register (R/W) */ - -#define MCR_DSRCHG 0x80 /* DSR Changed */ -#define MCR_CDCHG 0x40 /* CD Changed */ -#define MCR_CTSCHG 0x20 /* CTS Changed */ - - -/* Modem Signal Value Register (R/W) */ - -#define MSVR_DSR 0x80 /* Current state of DSR input */ -#define MSVR_CD 0x40 /* Current state of CD input */ -#define MSVR_CTS 0x20 /* Current state of CTS input */ -#define MSVR_DTR 0x02 /* Current state of DTR output */ -#define MSVR_RTS 0x01 /* Current state of RTS output */ - - -/* Escape characters */ - -#define CD180_C_ESC 0x00 /* Escape character */ -#define CD180_C_SBRK 0x81 /* Start sending BREAK */ -#define CD180_C_DELAY 0x82 /* Delay output */ -#define CD180_C_EBRK 0x83 /* Stop sending BREAK */ diff --git a/drivers/staging/tty/serial167.c b/drivers/staging/tty/serial167.c deleted file mode 100644 index 674af6933978..000000000000 --- a/drivers/staging/tty/serial167.c +++ /dev/null @@ -1,2489 +0,0 @@ -/* - * linux/drivers/char/serial167.c - * - * Driver for MVME166/7 board serial ports, which are via a CD2401. - * Based very much on cyclades.c. - * - * MVME166/7 work by Richard Hirst [richard@sleepie.demon.co.uk] - * - * ============================================================== - * - * static char rcsid[] = - * "$Revision: 1.36.1.4 $$Date: 1995/03/29 06:14:14 $"; - * - * linux/kernel/cyclades.c - * - * Maintained by Marcio Saito (cyclades@netcom.com) and - * Randolph Bentson (bentson@grieg.seaslug.org) - * - * Much of the design and some of the code came from serial.c - * which was copyright (C) 1991, 1992 Linus Torvalds. It was - * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92, - * and then fixed as suggested by Michael K. Johnson 12/12/92. - * - * This version does not support shared irq's. - * - * $Log: cyclades.c,v $ - * Revision 1.36.1.4 1995/03/29 06:14:14 bentson - * disambiguate between Cyclom-16Y and Cyclom-32Ye; - * - * Changes: - * - * 200 lines of changes record removed - RGH 11-10-95, starting work on - * converting this to drive serial ports on mvme166 (cd2401). - * - * Arnaldo Carvalho de Melo - 2000/08/25 - * - get rid of verify_area - * - use get_user to access memory from userspace in set_threshold, - * set_default_threshold and set_timeout - * - don't use the panic function in serial167_init - * - do resource release on failure on serial167_init - * - include missing restore_flags in mvme167_serial_console_setup - * - * Kars de Jong - 2004/09/06 - * - replace bottom half handler with task queue handler - */ - -#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 - -#define SERIAL_PARANOIA_CHECK -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_THROTTLE -#undef SERIAL_DEBUG_OTHER -#undef SERIAL_DEBUG_IO -#undef SERIAL_DEBUG_COUNT -#undef SERIAL_DEBUG_DTR -#undef CYCLOM_16Y_HACK -#define CYCLOM_ENABLE_MONITORING - -#define WAKEUP_CHARS 256 - -#define STD_COM_FLAGS (0) - -static struct tty_driver *cy_serial_driver; -extern int serial_console; -static struct cyclades_port *serial_console_info = NULL; -static unsigned int serial_console_cflag = 0; -u_char initial_console_speed; - -/* Base address of cd2401 chip on mvme166/7 */ - -#define BASE_ADDR (0xfff45000) -#define pcc2chip ((volatile u_char *)0xfff42000) -#define PccSCCMICR 0x1d -#define PccSCCTICR 0x1e -#define PccSCCRICR 0x1f -#define PccTPIACKR 0x25 -#define PccRPIACKR 0x27 -#define PccIMLR 0x3f - -/* This is the per-port data structure */ -struct cyclades_port cy_port[] = { - /* CARD# */ - {-1}, /* ttyS0 */ - {-1}, /* ttyS1 */ - {-1}, /* ttyS2 */ - {-1}, /* ttyS3 */ -}; - -#define NR_PORTS ARRAY_SIZE(cy_port) - -/* - * This is used to look up the divisor speeds and the timeouts - * We're normally limited to 15 distinct baud rates. The extra - * are accessed via settings in info->flags. - * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - * HI VHI - */ -static int baud_table[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, - 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000, - 0 -}; - -#if 0 -static char baud_co[] = { /* 25 MHz clock option table */ - /* value => 00 01 02 03 04 */ - /* divide by 8 32 128 512 2048 */ - 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, - 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -static char baud_bpr[] = { /* 25 MHz baud rate period table */ - 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3, - 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15 -}; -#endif - -/* I think 166 brd clocks 2401 at 20MHz.... */ - -/* These values are written directly to tcor, and >> 5 for writing to rcor */ -static u_char baud_co[] = { /* 20 MHz clock option table */ - 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x60, 0x60, 0x40, - 0x40, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* These values written directly to tbpr/rbpr */ -static u_char baud_bpr[] = { /* 20 MHz baud rate period table */ - 0x00, 0xc0, 0x80, 0x58, 0x6c, 0x40, 0xc0, 0x81, 0x40, 0x81, - 0x57, 0x40, 0x81, 0x40, 0x81, 0x40, 0x2b, 0x20, 0x15, 0x10 -}; - -static u_char baud_cor4[] = { /* receive threshold */ - 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07 -}; - -static void shutdown(struct cyclades_port *); -static int startup(struct cyclades_port *); -static void cy_throttle(struct tty_struct *); -static void cy_unthrottle(struct tty_struct *); -static void config_setup(struct cyclades_port *); -#ifdef CYCLOM_SHOW_STATUS -static void show_status(int); -#endif - -/* - * I have my own version of udelay(), as it is needed when initialising - * the chip, before the delay loop has been calibrated. Should probably - * reference one of the vmechip2 or pccchip2 counter for an accurate - * delay, but this wild guess will do for now. - */ - -void my_udelay(long us) -{ - u_char x; - volatile u_char *p = &x; - int i; - - while (us--) - for (i = 100; i; i--) - x |= *p; -} - -static inline int serial_paranoia_check(struct cyclades_port *info, char *name, - const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - if (!info) { - printk("Warning: null cyclades_port for (%s) in %s\n", name, - routine); - return 1; - } - - if (info < &cy_port[0] || info >= &cy_port[NR_PORTS]) { - printk("Warning: cyclades_port out of range for (%s) in %s\n", - name, routine); - return 1; - } - - if (info->magic != CYCLADES_MAGIC) { - printk("Warning: bad magic number for serial struct (%s) in " - "%s\n", name, routine); - return 1; - } -#endif - return 0; -} /* serial_paranoia_check */ - -#if 0 -/* The following diagnostic routines allow the driver to spew - information on the screen, even (especially!) during interrupts. - */ -void SP(char *data) -{ - unsigned long flags; - local_irq_save(flags); - printk(KERN_EMERG "%s", data); - local_irq_restore(flags); -} - -char scrn[2]; -void CP(char data) -{ - unsigned long flags; - local_irq_save(flags); - scrn[0] = data; - printk(KERN_EMERG "%c", scrn); - local_irq_restore(flags); -} /* CP */ - -void CP1(int data) -{ - (data < 10) ? CP(data + '0') : CP(data + 'A' - 10); -} /* CP1 */ -void CP2(int data) -{ - CP1((data >> 4) & 0x0f); - CP1(data & 0x0f); -} /* CP2 */ -void CP4(int data) -{ - CP2((data >> 8) & 0xff); - CP2(data & 0xff); -} /* CP4 */ -void CP8(long data) -{ - CP4((data >> 16) & 0xffff); - CP4(data & 0xffff); -} /* CP8 */ -#endif - -/* This routine waits up to 1000 micro-seconds for the previous - command to the Cirrus chip to complete and then issues the - new command. An error is returned if the previous command - didn't finish within the time limit. - */ -u_short write_cy_cmd(volatile u_char * base_addr, u_char cmd) -{ - unsigned long flags; - volatile int i; - - local_irq_save(flags); - /* Check to see that the previous command has completed */ - for (i = 0; i < 100; i++) { - if (base_addr[CyCCR] == 0) { - break; - } - my_udelay(10L); - } - /* if the CCR never cleared, the previous command - didn't finish within the "reasonable time" */ - if (i == 10) { - local_irq_restore(flags); - return (-1); - } - - /* Issue the new command */ - base_addr[CyCCR] = cmd; - local_irq_restore(flags); - return (0); -} /* write_cy_cmd */ - -/* cy_start and cy_stop provide software output flow control as a - function of XON/XOFF, software CTS, and other such stuff. */ - -static void cy_stop(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - unsigned long flags; - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_stop %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_stop")) - return; - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) (channel); /* index channel */ - base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); - local_irq_restore(flags); -} /* cy_stop */ - -static void cy_start(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - unsigned long flags; - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_start %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_start")) - return; - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) (channel); - base_addr[CyIER] |= CyTxMpty; - local_irq_restore(flags); -} /* cy_start */ - -/* The real interrupt service routines are called - whenever the card wants its hand held--chars - received, out buffer empty, modem change, etc. - */ -static irqreturn_t cd2401_rxerr_interrupt(int irq, void *dev_id) -{ - struct tty_struct *tty; - struct cyclades_port *info; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - unsigned char err, rfoc; - int channel; - char data; - - /* determine the channel and change to that context */ - channel = (u_short) (base_addr[CyLICR] >> 2); - info = &cy_port[channel]; - info->last_active = jiffies; - - if ((err = base_addr[CyRISR]) & CyTIMEOUT) { - /* This is a receive timeout interrupt, ignore it */ - base_addr[CyREOIR] = CyNOTRANS; - return IRQ_HANDLED; - } - - /* Read a byte of data if there is any - assume the error - * is associated with this character */ - - if ((rfoc = base_addr[CyRFOC]) != 0) - data = base_addr[CyRDR]; - else - data = 0; - - /* if there is nowhere to put the data, discard it */ - if (info->tty == 0) { - base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; - return IRQ_HANDLED; - } else { /* there is an open port for this data */ - tty = info->tty; - if (err & info->ignore_status_mask) { - base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; - return IRQ_HANDLED; - } - if (tty_buffer_request_room(tty, 1) != 0) { - if (err & info->read_status_mask) { - if (err & CyBREAK) { - tty_insert_flip_char(tty, data, - TTY_BREAK); - if (info->flags & ASYNC_SAK) { - do_SAK(tty); - } - } else if (err & CyFRAME) { - tty_insert_flip_char(tty, data, - TTY_FRAME); - } else if (err & CyPARITY) { - tty_insert_flip_char(tty, data, - TTY_PARITY); - } else if (err & CyOVERRUN) { - tty_insert_flip_char(tty, 0, - TTY_OVERRUN); - /* - If the flip buffer itself is - overflowing, we still lose - the next incoming character. - */ - if (tty_buffer_request_room(tty, 1) != - 0) { - tty_insert_flip_char(tty, data, - TTY_FRAME); - } - /* These two conditions may imply */ - /* a normal read should be done. */ - /* else if(data & CyTIMEOUT) */ - /* else if(data & CySPECHAR) */ - } else { - tty_insert_flip_char(tty, 0, - TTY_NORMAL); - } - } else { - tty_insert_flip_char(tty, data, TTY_NORMAL); - } - } else { - /* there was a software buffer overrun - and nothing could be done about it!!! */ - } - } - tty_schedule_flip(tty); - /* end of service */ - base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS; - return IRQ_HANDLED; -} /* cy_rxerr_interrupt */ - -static irqreturn_t cd2401_modem_interrupt(int irq, void *dev_id) -{ - struct cyclades_port *info; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - int mdm_change; - int mdm_status; - - /* determine the channel and change to that context */ - channel = (u_short) (base_addr[CyLICR] >> 2); - info = &cy_port[channel]; - info->last_active = jiffies; - - mdm_change = base_addr[CyMISR]; - mdm_status = base_addr[CyMSVR1]; - - if (info->tty == 0) { /* nowhere to put the data, ignore it */ - ; - } else { - if ((mdm_change & CyDCD) - && (info->flags & ASYNC_CHECK_CD)) { - if (mdm_status & CyDCD) { -/* CP('!'); */ - wake_up_interruptible(&info->open_wait); - } else { -/* CP('@'); */ - tty_hangup(info->tty); - wake_up_interruptible(&info->open_wait); - info->flags &= ~ASYNC_NORMAL_ACTIVE; - } - } - if ((mdm_change & CyCTS) - && (info->flags & ASYNC_CTS_FLOW)) { - if (info->tty->stopped) { - if (mdm_status & CyCTS) { - /* !!! cy_start isn't used because... */ - info->tty->stopped = 0; - base_addr[CyIER] |= CyTxMpty; - tty_wakeup(info->tty); - } - } else { - if (!(mdm_status & CyCTS)) { - /* !!! cy_stop isn't used because... */ - info->tty->stopped = 1; - base_addr[CyIER] &= - ~(CyTxMpty | CyTxRdy); - } - } - } - if (mdm_status & CyDSR) { - } - } - base_addr[CyMEOIR] = 0; - return IRQ_HANDLED; -} /* cy_modem_interrupt */ - -static irqreturn_t cd2401_tx_interrupt(int irq, void *dev_id) -{ - struct cyclades_port *info; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - int char_count, saved_cnt; - int outch; - - /* determine the channel and change to that context */ - channel = (u_short) (base_addr[CyLICR] >> 2); - - /* validate the port number (as configured and open) */ - if ((channel < 0) || (NR_PORTS <= channel)) { - base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); - base_addr[CyTEOIR] = CyNOTRANS; - return IRQ_HANDLED; - } - info = &cy_port[channel]; - info->last_active = jiffies; - if (info->tty == 0) { - base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); - base_addr[CyTEOIR] = CyNOTRANS; - return IRQ_HANDLED; - } - - /* load the on-chip space available for outbound data */ - saved_cnt = char_count = base_addr[CyTFTC]; - - if (info->x_char) { /* send special char */ - outch = info->x_char; - base_addr[CyTDR] = outch; - char_count--; - info->x_char = 0; - } - - if (info->x_break) { - /* The Cirrus chip requires the "Embedded Transmit - Commands" of start break, delay, and end break - sequences to be sent. The duration of the - break is given in TICs, which runs at HZ - (typically 100) and the PPR runs at 200 Hz, - so the delay is duration * 200/HZ, and thus a - break can run from 1/100 sec to about 5/4 sec. - Need to check these values - RGH 141095. - */ - base_addr[CyTDR] = 0; /* start break */ - base_addr[CyTDR] = 0x81; - base_addr[CyTDR] = 0; /* delay a bit */ - base_addr[CyTDR] = 0x82; - base_addr[CyTDR] = info->x_break * 200 / HZ; - base_addr[CyTDR] = 0; /* terminate break */ - base_addr[CyTDR] = 0x83; - char_count -= 7; - info->x_break = 0; - } - - while (char_count > 0) { - if (!info->xmit_cnt) { - base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); - break; - } - if (info->xmit_buf == 0) { - base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); - break; - } - if (info->tty->stopped || info->tty->hw_stopped) { - base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); - break; - } - /* Because the Embedded Transmit Commands have been - enabled, we must check to see if the escape - character, NULL, is being sent. If it is, we - must ensure that there is room for it to be - doubled in the output stream. Therefore we - no longer advance the pointer when the character - is fetched, but rather wait until after the check - for a NULL output character. (This is necessary - because there may not be room for the two chars - needed to send a NULL. - */ - outch = info->xmit_buf[info->xmit_tail]; - if (outch) { - info->xmit_cnt--; - info->xmit_tail = (info->xmit_tail + 1) - & (PAGE_SIZE - 1); - base_addr[CyTDR] = outch; - char_count--; - } else { - if (char_count > 1) { - info->xmit_cnt--; - info->xmit_tail = (info->xmit_tail + 1) - & (PAGE_SIZE - 1); - base_addr[CyTDR] = outch; - base_addr[CyTDR] = 0; - char_count--; - char_count--; - } else { - break; - } - } - } - - if (info->xmit_cnt < WAKEUP_CHARS) - tty_wakeup(info->tty); - - base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS; - return IRQ_HANDLED; -} /* cy_tx_interrupt */ - -static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id) -{ - struct tty_struct *tty; - struct cyclades_port *info; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - char data; - int char_count; - int save_cnt; - - /* determine the channel and change to that context */ - channel = (u_short) (base_addr[CyLICR] >> 2); - info = &cy_port[channel]; - info->last_active = jiffies; - save_cnt = char_count = base_addr[CyRFOC]; - - /* if there is nowhere to put the data, discard it */ - if (info->tty == 0) { - while (char_count--) { - data = base_addr[CyRDR]; - } - } else { /* there is an open port for this data */ - tty = info->tty; - /* load # characters available from the chip */ - -#ifdef CYCLOM_ENABLE_MONITORING - ++info->mon.int_count; - info->mon.char_count += char_count; - if (char_count > info->mon.char_max) - info->mon.char_max = char_count; - info->mon.char_last = char_count; -#endif - while (char_count--) { - data = base_addr[CyRDR]; - tty_insert_flip_char(tty, data, TTY_NORMAL); -#ifdef CYCLOM_16Y_HACK - udelay(10L); -#endif - } - tty_schedule_flip(tty); - } - /* end of service */ - base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS; - return IRQ_HANDLED; -} /* cy_rx_interrupt */ - -/* This is called whenever a port becomes active; - interrupts are enabled and DTR & RTS are turned on. - */ -static int startup(struct cyclades_port *info) -{ - unsigned long flags; - volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR; - int channel; - - if (info->flags & ASYNC_INITIALIZED) { - return 0; - } - - if (!info->type) { - if (info->tty) { - set_bit(TTY_IO_ERROR, &info->tty->flags); - } - return 0; - } - if (!info->xmit_buf) { - info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); - if (!info->xmit_buf) { - return -ENOMEM; - } - } - - config_setup(info); - - channel = info->line; - -#ifdef SERIAL_DEBUG_OPEN - printk("startup channel %d\n", channel); -#endif - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR); - - base_addr[CyCAR] = (u_char) channel; /* !!! Is this needed? */ - base_addr[CyMSVR1] = CyRTS; -/* CP('S');CP('1'); */ - base_addr[CyMSVR2] = CyDTR; - -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: raising DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - - base_addr[CyIER] |= CyRxData; - info->flags |= ASYNC_INITIALIZED; - - if (info->tty) { - clear_bit(TTY_IO_ERROR, &info->tty->flags); - } - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - - local_irq_restore(flags); - -#ifdef SERIAL_DEBUG_OPEN - printk(" done\n"); -#endif - return 0; -} /* startup */ - -void start_xmit(struct cyclades_port *info) -{ - unsigned long flags; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - - channel = info->line; - local_irq_save(flags); - base_addr[CyCAR] = channel; - base_addr[CyIER] |= CyTxMpty; - local_irq_restore(flags); -} /* start_xmit */ - -/* - * This routine shuts down a serial port; interrupts are disabled, - * and DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(struct cyclades_port *info) -{ - unsigned long flags; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - - if (!(info->flags & ASYNC_INITIALIZED)) { -/* CP('$'); */ - return; - } - - channel = info->line; - -#ifdef SERIAL_DEBUG_OPEN - printk("shutdown channel %d\n", channel); -#endif - - /* !!! REALLY MUST WAIT FOR LAST CHARACTER TO BE - SENT BEFORE DROPPING THE LINE !!! (Perhaps - set some flag that is read when XMTY happens.) - Other choices are to delay some fixed interval - or schedule some later processing. - */ - local_irq_save(flags); - if (info->xmit_buf) { - free_page((unsigned long)info->xmit_buf); - info->xmit_buf = NULL; - } - - base_addr[CyCAR] = (u_char) channel; - if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { - base_addr[CyMSVR1] = 0; -/* CP('C');CP('1'); */ - base_addr[CyMSVR2] = 0; -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: dropping DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - } - write_cy_cmd(base_addr, CyDIS_RCVR); - /* it may be appropriate to clear _XMIT at - some later date (after testing)!!! */ - - if (info->tty) { - set_bit(TTY_IO_ERROR, &info->tty->flags); - } - info->flags &= ~ASYNC_INITIALIZED; - local_irq_restore(flags); - -#ifdef SERIAL_DEBUG_OPEN - printk(" done\n"); -#endif -} /* shutdown */ - -/* - * This routine finds or computes the various line characteristics. - */ -static void config_setup(struct cyclades_port *info) -{ - unsigned long flags; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - unsigned cflag; - int i; - unsigned char ti, need_init_chan = 0; - - if (!info->tty || !info->tty->termios) { - return; - } - if (info->line == -1) { - return; - } - cflag = info->tty->termios->c_cflag; - - /* baud rate */ - i = cflag & CBAUD; -#ifdef CBAUDEX -/* Starting with kernel 1.1.65, there is direct support for - higher baud rates. The following code supports those - changes. The conditional aspect allows this driver to be - used for earlier as well as later kernel versions. (The - mapping is slightly different from serial.c because there - is still the possibility of supporting 75 kbit/sec with - the Cyclades board.) - */ - if (i & CBAUDEX) { - if (i == B57600) - i = 16; - else if (i == B115200) - i = 18; -#ifdef B78600 - else if (i == B78600) - i = 17; -#endif - else - info->tty->termios->c_cflag &= ~CBAUDEX; - } -#endif - if (i == 15) { - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - i += 1; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - i += 3; - } - /* Don't ever change the speed of the console port. It will - * run at the speed specified in bootinfo, or at 19.2K */ - /* Actually, it should run at whatever speed 166Bug was using */ - /* Note info->timeout isn't used at present */ - if (info != serial_console_info) { - info->tbpr = baud_bpr[i]; /* Tx BPR */ - info->tco = baud_co[i]; /* Tx CO */ - info->rbpr = baud_bpr[i]; /* Rx BPR */ - info->rco = baud_co[i] >> 5; /* Rx CO */ - if (baud_table[i] == 134) { - info->timeout = - (info->xmit_fifo_size * HZ * 30 / 269) + 2; - /* get it right for 134.5 baud */ - } else if (baud_table[i]) { - info->timeout = - (info->xmit_fifo_size * HZ * 15 / baud_table[i]) + - 2; - /* this needs to be propagated into the card info */ - } else { - info->timeout = 0; - } - } - /* By tradition (is it a standard?) a baud rate of zero - implies the line should be/has been closed. A bit - later in this routine such a test is performed. */ - - /* byte size and parity */ - info->cor7 = 0; - info->cor6 = 0; - info->cor5 = 0; - info->cor4 = (info->default_threshold ? info->default_threshold : baud_cor4[i]); /* receive threshold */ - /* Following two lines added 101295, RGH. */ - /* It is obviously wrong to access CyCORx, and not info->corx here, - * try and remember to fix it later! */ - channel = info->line; - base_addr[CyCAR] = (u_char) channel; - if (C_CLOCAL(info->tty)) { - if (base_addr[CyIER] & CyMdmCh) - base_addr[CyIER] &= ~CyMdmCh; /* without modem intr */ - /* ignore 1->0 modem transitions */ - if (base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD)) - base_addr[CyCOR4] &= ~(CyDSR | CyCTS | CyDCD); - /* ignore 0->1 modem transitions */ - if (base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD)) - base_addr[CyCOR5] &= ~(CyDSR | CyCTS | CyDCD); - } else { - if ((base_addr[CyIER] & CyMdmCh) != CyMdmCh) - base_addr[CyIER] |= CyMdmCh; /* with modem intr */ - /* act on 1->0 modem transitions */ - if ((base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD)) != - (CyDSR | CyCTS | CyDCD)) - base_addr[CyCOR4] |= CyDSR | CyCTS | CyDCD; - /* act on 0->1 modem transitions */ - if ((base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD)) != - (CyDSR | CyCTS | CyDCD)) - base_addr[CyCOR5] |= CyDSR | CyCTS | CyDCD; - } - info->cor3 = (cflag & CSTOPB) ? Cy_2_STOP : Cy_1_STOP; - info->cor2 = CyETC; - switch (cflag & CSIZE) { - case CS5: - info->cor1 = Cy_5_BITS; - break; - case CS6: - info->cor1 = Cy_6_BITS; - break; - case CS7: - info->cor1 = Cy_7_BITS; - break; - case CS8: - info->cor1 = Cy_8_BITS; - break; - } - if (cflag & PARENB) { - if (cflag & PARODD) { - info->cor1 |= CyPARITY_O; - } else { - info->cor1 |= CyPARITY_E; - } - } else { - info->cor1 |= CyPARITY_NONE; - } - - /* CTS flow control flag */ -#if 0 - /* Don't complcate matters for now! RGH 141095 */ - if (cflag & CRTSCTS) { - info->flags |= ASYNC_CTS_FLOW; - info->cor2 |= CyCtsAE; - } else { - info->flags &= ~ASYNC_CTS_FLOW; - info->cor2 &= ~CyCtsAE; - } -#endif - if (cflag & CLOCAL) - info->flags &= ~ASYNC_CHECK_CD; - else - info->flags |= ASYNC_CHECK_CD; - - /*********************************************** - The hardware option, CyRtsAO, presents RTS when - the chip has characters to send. Since most modems - use RTS as reverse (inbound) flow control, this - option is not used. If inbound flow control is - necessary, DTR can be programmed to provide the - appropriate signals for use with a non-standard - cable. Contact Marcio Saito for details. - ***********************************************/ - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - - /* CyCMR set once only in mvme167_init_serial() */ - if (base_addr[CyLICR] != channel << 2) - base_addr[CyLICR] = channel << 2; - if (base_addr[CyLIVR] != 0x5c) - base_addr[CyLIVR] = 0x5c; - - /* tx and rx baud rate */ - - if (base_addr[CyCOR1] != info->cor1) - need_init_chan = 1; - if (base_addr[CyTCOR] != info->tco) - base_addr[CyTCOR] = info->tco; - if (base_addr[CyTBPR] != info->tbpr) - base_addr[CyTBPR] = info->tbpr; - if (base_addr[CyRCOR] != info->rco) - base_addr[CyRCOR] = info->rco; - if (base_addr[CyRBPR] != info->rbpr) - base_addr[CyRBPR] = info->rbpr; - - /* set line characteristics according configuration */ - - if (base_addr[CySCHR1] != START_CHAR(info->tty)) - base_addr[CySCHR1] = START_CHAR(info->tty); - if (base_addr[CySCHR2] != STOP_CHAR(info->tty)) - base_addr[CySCHR2] = STOP_CHAR(info->tty); - if (base_addr[CySCRL] != START_CHAR(info->tty)) - base_addr[CySCRL] = START_CHAR(info->tty); - if (base_addr[CySCRH] != START_CHAR(info->tty)) - base_addr[CySCRH] = START_CHAR(info->tty); - if (base_addr[CyCOR1] != info->cor1) - base_addr[CyCOR1] = info->cor1; - if (base_addr[CyCOR2] != info->cor2) - base_addr[CyCOR2] = info->cor2; - if (base_addr[CyCOR3] != info->cor3) - base_addr[CyCOR3] = info->cor3; - if (base_addr[CyCOR4] != info->cor4) - base_addr[CyCOR4] = info->cor4; - if (base_addr[CyCOR5] != info->cor5) - base_addr[CyCOR5] = info->cor5; - if (base_addr[CyCOR6] != info->cor6) - base_addr[CyCOR6] = info->cor6; - if (base_addr[CyCOR7] != info->cor7) - base_addr[CyCOR7] = info->cor7; - - if (need_init_chan) - write_cy_cmd(base_addr, CyINIT_CHAN); - - base_addr[CyCAR] = (u_char) channel; /* !!! Is this needed? */ - - /* 2ms default rx timeout */ - ti = info->default_timeout ? info->default_timeout : 0x02; - if (base_addr[CyRTPRL] != ti) - base_addr[CyRTPRL] = ti; - if (base_addr[CyRTPRH] != 0) - base_addr[CyRTPRH] = 0; - - /* Set up RTS here also ????? RGH 141095 */ - if (i == 0) { /* baud rate is zero, turn off line */ - if ((base_addr[CyMSVR2] & CyDTR) == CyDTR) - base_addr[CyMSVR2] = 0; -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: dropping DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - } else { - if ((base_addr[CyMSVR2] & CyDTR) != CyDTR) - base_addr[CyMSVR2] = CyDTR; -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: raising DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - } - - if (info->tty) { - clear_bit(TTY_IO_ERROR, &info->tty->flags); - } - - local_irq_restore(flags); - -} /* config_setup */ - -static int cy_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - -#ifdef SERIAL_DEBUG_IO - printk("cy_put_char %s(0x%02x)\n", tty->name, ch); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_put_char")) - return 0; - - if (!info->xmit_buf) - return 0; - - local_irq_save(flags); - if (info->xmit_cnt >= PAGE_SIZE - 1) { - local_irq_restore(flags); - return 0; - } - - info->xmit_buf[info->xmit_head++] = ch; - info->xmit_head &= PAGE_SIZE - 1; - info->xmit_cnt++; - local_irq_restore(flags); - return 1; -} /* cy_put_char */ - -static void cy_flush_chars(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - -#ifdef SERIAL_DEBUG_IO - printk("cy_flush_chars %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) - return; - - if (info->xmit_cnt <= 0 || tty->stopped - || tty->hw_stopped || !info->xmit_buf) - return; - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = channel; - base_addr[CyIER] |= CyTxMpty; - local_irq_restore(flags); -} /* cy_flush_chars */ - -/* This routine gets called when tty_write has put something into - the write_queue. If the port is not already transmitting stuff, - start it off by enabling interrupts. The interrupt service - routine will then ensure that the characters are sent. If the - port is already active, there is no need to kick it. - */ -static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - int c, total = 0; - -#ifdef SERIAL_DEBUG_IO - printk("cy_write %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_write")) { - return 0; - } - - if (!info->xmit_buf) { - return 0; - } - - while (1) { - local_irq_save(flags); - c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) { - local_irq_restore(flags); - break; - } - - memcpy(info->xmit_buf + info->xmit_head, buf, c); - info->xmit_head = - (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1); - info->xmit_cnt += c; - local_irq_restore(flags); - - buf += c; - count -= c; - total += c; - } - - if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { - start_xmit(info); - } - return total; -} /* cy_write */ - -static int cy_write_room(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - int ret; - -#ifdef SERIAL_DEBUG_IO - printk("cy_write_room %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_write_room")) - return 0; - ret = PAGE_SIZE - info->xmit_cnt - 1; - if (ret < 0) - ret = 0; - return ret; -} /* cy_write_room */ - -static int cy_chars_in_buffer(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - -#ifdef SERIAL_DEBUG_IO - printk("cy_chars_in_buffer %s %d\n", tty->name, info->xmit_cnt); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) - return 0; - - return info->xmit_cnt; -} /* cy_chars_in_buffer */ - -static void cy_flush_buffer(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - -#ifdef SERIAL_DEBUG_IO - printk("cy_flush_buffer %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) - return; - local_irq_save(flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - local_irq_restore(flags); - tty_wakeup(tty); -} /* cy_flush_buffer */ - -/* This routine is called by the upper-layer tty layer to signal - that incoming characters should be throttled or that the - throttle should be released. - */ -static void cy_throttle(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); - printk("cy_throttle %s\n", tty->name); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) { - return; - } - - if (I_IXOFF(tty)) { - info->x_char = STOP_CHAR(tty); - /* Should use the "Send Special Character" feature!!! */ - } - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - base_addr[CyMSVR1] = 0; - local_irq_restore(flags); -} /* cy_throttle */ - -static void cy_unthrottle(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - unsigned long flags; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); - printk("cy_unthrottle %s\n", tty->name); -#endif - - if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) { - return; - } - - if (I_IXOFF(tty)) { - info->x_char = START_CHAR(tty); - /* Should use the "Send Special Character" feature!!! */ - } - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - base_addr[CyMSVR1] = CyRTS; - local_irq_restore(flags); -} /* cy_unthrottle */ - -static int -get_serial_info(struct cyclades_port *info, - struct serial_struct __user * retinfo) -{ - struct serial_struct tmp; - -/* CP('g'); */ - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof(tmp)); - tmp.type = info->type; - tmp.line = info->line; - tmp.port = info->line; - tmp.irq = 0; - tmp.flags = info->flags; - tmp.baud_base = 0; /*!!! */ - tmp.close_delay = info->close_delay; - tmp.custom_divisor = 0; /*!!! */ - tmp.hub6 = 0; /*!!! */ - return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; -} /* get_serial_info */ - -static int -set_serial_info(struct cyclades_port *info, - struct serial_struct __user * new_info) -{ - struct serial_struct new_serial; - struct cyclades_port old_info; - -/* CP('s'); */ - if (!new_info) - return -EFAULT; - if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) - return -EFAULT; - old_info = *info; - - if (!capable(CAP_SYS_ADMIN)) { - if ((new_serial.close_delay != info->close_delay) || - ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) != - (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))) - return -EPERM; - info->flags = ((info->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - goto check_and_exit; - } - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - - info->flags = ((info->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - info->close_delay = new_serial.close_delay; - -check_and_exit: - if (info->flags & ASYNC_INITIALIZED) { - config_setup(info); - return 0; - } - return startup(info); -} /* set_serial_info */ - -static int cy_tiocmget(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - int channel; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - unsigned long flags; - unsigned char status; - - channel = info->line; - - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - status = base_addr[CyMSVR1] | base_addr[CyMSVR2]; - local_irq_restore(flags); - - return ((status & CyRTS) ? TIOCM_RTS : 0) - | ((status & CyDTR) ? TIOCM_DTR : 0) - | ((status & CyDCD) ? TIOCM_CAR : 0) - | ((status & CyDSR) ? TIOCM_DSR : 0) - | ((status & CyCTS) ? TIOCM_CTS : 0); -} /* cy_tiocmget */ - -static int -cy_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) -{ - struct cyclades_port *info = tty->driver_data; - int channel; - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - unsigned long flags; - - channel = info->line; - - if (set & TIOCM_RTS) { - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - base_addr[CyMSVR1] = CyRTS; - local_irq_restore(flags); - } - if (set & TIOCM_DTR) { - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; -/* CP('S');CP('2'); */ - base_addr[CyMSVR2] = CyDTR; -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: raising DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - local_irq_restore(flags); - } - - if (clear & TIOCM_RTS) { - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - base_addr[CyMSVR1] = 0; - local_irq_restore(flags); - } - if (clear & TIOCM_DTR) { - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; -/* CP('C');CP('2'); */ - base_addr[CyMSVR2] = 0; -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: dropping DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - local_irq_restore(flags); - } - - return 0; -} /* set_modem_info */ - -static void send_break(struct cyclades_port *info, int duration) -{ /* Let the transmit ISR take care of this (since it - requires stuffing characters into the output stream). - */ - info->x_break = duration; - if (!info->xmit_cnt) { - start_xmit(info); - } -} /* send_break */ - -static int -get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon) -{ - - if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) - return -EFAULT; - info->mon.int_count = 0; - info->mon.char_count = 0; - info->mon.char_max = 0; - info->mon.char_last = 0; - return 0; -} - -static int set_threshold(struct cyclades_port *info, unsigned long __user * arg) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - unsigned long value; - int channel; - - if (get_user(value, arg)) - return -EFAULT; - - channel = info->line; - info->cor4 &= ~CyREC_FIFO; - info->cor4 |= value & CyREC_FIFO; - base_addr[CyCOR4] = info->cor4; - return 0; -} - -static int -get_threshold(struct cyclades_port *info, unsigned long __user * value) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - unsigned long tmp; - - channel = info->line; - - tmp = base_addr[CyCOR4] & CyREC_FIFO; - return put_user(tmp, value); -} - -static int -set_default_threshold(struct cyclades_port *info, unsigned long __user * arg) -{ - unsigned long value; - - if (get_user(value, arg)) - return -EFAULT; - - info->default_threshold = value & 0x0f; - return 0; -} - -static int -get_default_threshold(struct cyclades_port *info, unsigned long __user * value) -{ - return put_user(info->default_threshold, value); -} - -static int set_timeout(struct cyclades_port *info, unsigned long __user * arg) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - unsigned long value; - - if (get_user(value, arg)) - return -EFAULT; - - channel = info->line; - - base_addr[CyRTPRL] = value & 0xff; - base_addr[CyRTPRH] = (value >> 8) & 0xff; - return 0; -} - -static int get_timeout(struct cyclades_port *info, unsigned long __user * value) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - unsigned long tmp; - - channel = info->line; - - tmp = base_addr[CyRTPRL]; - return put_user(tmp, value); -} - -static int set_default_timeout(struct cyclades_port *info, unsigned long value) -{ - info->default_timeout = value & 0xff; - return 0; -} - -static int -get_default_timeout(struct cyclades_port *info, unsigned long __user * value) -{ - return put_user(info->default_timeout, value); -} - -static int -cy_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct cyclades_port *info = tty->driver_data; - int ret_val = 0; - void __user *argp = (void __user *)arg; - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */ -#endif - - tty_lock(); - - switch (cmd) { - case CYGETMON: - ret_val = get_mon_info(info, argp); - break; - case CYGETTHRESH: - ret_val = get_threshold(info, argp); - break; - case CYSETTHRESH: - ret_val = set_threshold(info, argp); - break; - case CYGETDEFTHRESH: - ret_val = get_default_threshold(info, argp); - break; - case CYSETDEFTHRESH: - ret_val = set_default_threshold(info, argp); - break; - case CYGETTIMEOUT: - ret_val = get_timeout(info, argp); - break; - case CYSETTIMEOUT: - ret_val = set_timeout(info, argp); - break; - case CYGETDEFTIMEOUT: - ret_val = get_default_timeout(info, argp); - break; - case CYSETDEFTIMEOUT: - ret_val = set_default_timeout(info, (unsigned long)arg); - break; - case TCSBRK: /* SVID version: non-zero arg --> no break */ - ret_val = tty_check_change(tty); - if (ret_val) - break; - tty_wait_until_sent(tty, 0); - if (!arg) - send_break(info, HZ / 4); /* 1/4 second */ - break; - case TCSBRKP: /* support for POSIX tcsendbreak() */ - ret_val = tty_check_change(tty); - if (ret_val) - break; - tty_wait_until_sent(tty, 0); - send_break(info, arg ? arg * (HZ / 10) : HZ / 4); - break; - -/* The following commands are incompletely implemented!!! */ - case TIOCGSERIAL: - ret_val = get_serial_info(info, argp); - break; - case TIOCSSERIAL: - ret_val = set_serial_info(info, argp); - break; - default: - ret_val = -ENOIOCTLCMD; - } - tty_unlock(); - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_ioctl done\n"); -#endif - - return ret_val; -} /* cy_ioctl */ - -static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) -{ - struct cyclades_port *info = tty->driver_data; - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_set_termios %s\n", tty->name); -#endif - - if (tty->termios->c_cflag == old_termios->c_cflag) - return; - config_setup(info); - - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->stopped = 0; - cy_start(tty); - } -#ifdef tytso_patch_94Nov25_1726 - if (!(old_termios->c_cflag & CLOCAL) && - (tty->termios->c_cflag & CLOCAL)) - wake_up_interruptible(&info->open_wait); -#endif -} /* cy_set_termios */ - -static void cy_close(struct tty_struct *tty, struct file *filp) -{ - struct cyclades_port *info = tty->driver_data; - -/* CP('C'); */ -#ifdef SERIAL_DEBUG_OTHER - printk("cy_close %s\n", tty->name); -#endif - - if (!info || serial_paranoia_check(info, tty->name, "cy_close")) { - return; - } -#ifdef SERIAL_DEBUG_OPEN - printk("cy_close %s, count = %d\n", tty->name, info->count); -#endif - - if ((tty->count == 1) && (info->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. Info->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk("cy_close: bad serial port count; tty->count is 1, " - "info->count is %d\n", info->count); - info->count = 1; - } -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: decrementing count to %d\n", __LINE__, - info->count - 1); -#endif - if (--info->count < 0) { - printk("cy_close: bad serial port count for ttys%d: %d\n", - info->line, info->count); -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: setting count to 0\n", __LINE__); -#endif - info->count = 0; - } - if (info->count) - return; - info->flags |= ASYNC_CLOSING; - if (info->flags & ASYNC_INITIALIZED) - tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */ - shutdown(info); - cy_flush_buffer(tty); - tty_ldisc_flush(tty); - info->tty = NULL; - if (info->blocked_open) { - if (info->close_delay) { - msleep_interruptible(jiffies_to_msecs - (info->close_delay)); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_close done\n"); -#endif -} /* cy_close */ - -/* - * cy_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -void cy_hangup(struct tty_struct *tty) -{ - struct cyclades_port *info = tty->driver_data; - -#ifdef SERIAL_DEBUG_OTHER - printk("cy_hangup %s\n", tty->name); /* */ -#endif - - if (serial_paranoia_check(info, tty->name, "cy_hangup")) - return; - - shutdown(info); -#if 0 - info->event = 0; - info->count = 0; -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: setting count to 0\n", __LINE__); -#endif - info->tty = 0; -#endif - info->flags &= ~ASYNC_NORMAL_ACTIVE; - wake_up_interruptible(&info->open_wait); -} /* cy_hangup */ - -/* - * ------------------------------------------------------------ - * cy_open() and friends - * ------------------------------------------------------------ - */ - -static int -block_til_ready(struct tty_struct *tty, struct file *filp, - struct cyclades_port *info) -{ - DECLARE_WAITQUEUE(wait, current); - unsigned long flags; - int channel; - int retval; - volatile u_char *base_addr = (u_char *) BASE_ADDR; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (info->flags & ASYNC_CLOSING) { - interruptible_sleep_on(&info->close_wait); - if (info->flags & ASYNC_HUP_NOTIFY) { - return -EAGAIN; - } else { - return -ERESTARTSYS; - } - } - - /* - * If non-blocking mode is set, then make the check up front - * and then exit. - */ - if (filp->f_flags & O_NONBLOCK) { - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, info->count is dropped by one, so that - * cy_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready before block: %s, count = %d\n", - tty->name, info->count); - /**/ -#endif - info->count--; -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count); -#endif - info->blocked_open++; - - channel = info->line; - - while (1) { - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; - base_addr[CyMSVR1] = CyRTS; -/* CP('S');CP('4'); */ - base_addr[CyMSVR2] = CyDTR; -#ifdef SERIAL_DEBUG_DTR - printk("cyc: %d: raising DTR\n", __LINE__); - printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], - base_addr[CyMSVR2]); -#endif - local_irq_restore(flags); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) - || !(info->flags & ASYNC_INITIALIZED)) { - if (info->flags & ASYNC_HUP_NOTIFY) { - retval = -EAGAIN; - } else { - retval = -ERESTARTSYS; - } - break; - } - local_irq_save(flags); - base_addr[CyCAR] = (u_char) channel; -/* CP('L');CP1(1 && C_CLOCAL(tty)); CP1(1 && (base_addr[CyMSVR1] & CyDCD) ); */ - if (!(info->flags & ASYNC_CLOSING) - && (C_CLOCAL(tty) - || (base_addr[CyMSVR1] & CyDCD))) { - local_irq_restore(flags); - break; - } - local_irq_restore(flags); - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready blocking: %s, count = %d\n", - tty->name, info->count); - /**/ -#endif - tty_unlock(); - schedule(); - tty_lock(); - } - __set_current_state(TASK_RUNNING); - remove_wait_queue(&info->open_wait, &wait); - if (!tty_hung_up_p(filp)) { - info->count++; -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: incrementing count to %d\n", __LINE__, - info->count); -#endif - } - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready after blocking: %s, count = %d\n", - tty->name, info->count); - /**/ -#endif - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} /* block_til_ready */ - -/* - * This routine is called whenever a serial port is opened. It - * performs the serial-specific initialization for the tty structure. - */ -int cy_open(struct tty_struct *tty, struct file *filp) -{ - struct cyclades_port *info; - int retval, line; - -/* CP('O'); */ - line = tty->index; - if ((line < 0) || (NR_PORTS <= line)) { - return -ENODEV; - } - info = &cy_port[line]; - if (info->line < 0) { - return -ENODEV; - } -#ifdef SERIAL_DEBUG_OTHER - printk("cy_open %s\n", tty->name); /* */ -#endif - if (serial_paranoia_check(info, tty->name, "cy_open")) { - return -ENODEV; - } -#ifdef SERIAL_DEBUG_OPEN - printk("cy_open %s, count = %d\n", tty->name, info->count); - /**/ -#endif - info->count++; -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count); -#endif - tty->driver_data = info; - info->tty = tty; - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) { - return retval; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { -#ifdef SERIAL_DEBUG_OPEN - printk("cy_open returning after block_til_ready with %d\n", - retval); -#endif - return retval; - } -#ifdef SERIAL_DEBUG_OPEN - printk("cy_open done\n"); - /**/ -#endif - return 0; -} /* cy_open */ - -/* - * --------------------------------------------------------------------- - * serial167_init() and friends - * - * serial167_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static void show_version(void) -{ - printk("MVME166/167 cd2401 driver\n"); -} /* show_version */ - -/* initialize chips on card -- return number of valid - chips (which is number of ports/4) */ - -/* - * This initialises the hardware to a reasonable state. It should - * probe the chip first so as to copy 166-Bug setup as a default for - * port 0. It initialises CMR to CyASYNC; that is never done again, so - * as to limit the number of CyINIT_CHAN commands in normal running. - * - * ... I wonder what I should do if this fails ... - */ - -void mvme167_serial_console_setup(int cflag) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int ch; - u_char spd; - u_char rcor, rbpr, badspeed = 0; - unsigned long flags; - - local_irq_save(flags); - - /* - * First probe channel zero of the chip, to see what speed has - * been selected. - */ - - base_addr[CyCAR] = 0; - - rcor = base_addr[CyRCOR] << 5; - rbpr = base_addr[CyRBPR]; - - for (spd = 0; spd < sizeof(baud_bpr); spd++) - if (rbpr == baud_bpr[spd] && rcor == baud_co[spd]) - break; - if (spd >= sizeof(baud_bpr)) { - spd = 14; /* 19200 */ - badspeed = 1; /* Failed to identify speed */ - } - initial_console_speed = spd; - - /* OK, we have chosen a speed, now reset and reinitialise */ - - my_udelay(20000L); /* Allow time for any active o/p to complete */ - if (base_addr[CyCCR] != 0x00) { - local_irq_restore(flags); - /* printk(" chip is never idle (CCR != 0)\n"); */ - return; - } - - base_addr[CyCCR] = CyCHIP_RESET; /* Reset the chip */ - my_udelay(1000L); - - if (base_addr[CyGFRCR] == 0x00) { - local_irq_restore(flags); - /* printk(" chip is not responding (GFRCR stayed 0)\n"); */ - return; - } - - /* - * System clock is 20Mhz, divided by 2048, so divide by 10 for a 1.0ms - * tick - */ - - base_addr[CyTPR] = 10; - - base_addr[CyPILR1] = 0x01; /* Interrupt level for modem change */ - base_addr[CyPILR2] = 0x02; /* Interrupt level for tx ints */ - base_addr[CyPILR3] = 0x03; /* Interrupt level for rx ints */ - - /* - * Attempt to set up all channels to something reasonable, and - * bang out a INIT_CHAN command. We should then be able to limit - * the amount of fiddling we have to do in normal running. - */ - - for (ch = 3; ch >= 0; ch--) { - base_addr[CyCAR] = (u_char) ch; - base_addr[CyIER] = 0; - base_addr[CyCMR] = CyASYNC; - base_addr[CyLICR] = (u_char) ch << 2; - base_addr[CyLIVR] = 0x5c; - base_addr[CyTCOR] = baud_co[spd]; - base_addr[CyTBPR] = baud_bpr[spd]; - base_addr[CyRCOR] = baud_co[spd] >> 5; - base_addr[CyRBPR] = baud_bpr[spd]; - base_addr[CySCHR1] = 'Q' & 0x1f; - base_addr[CySCHR2] = 'X' & 0x1f; - base_addr[CySCRL] = 0; - base_addr[CySCRH] = 0; - base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE; - base_addr[CyCOR2] = 0; - base_addr[CyCOR3] = Cy_1_STOP; - base_addr[CyCOR4] = baud_cor4[spd]; - base_addr[CyCOR5] = 0; - base_addr[CyCOR6] = 0; - base_addr[CyCOR7] = 0; - base_addr[CyRTPRL] = 2; - base_addr[CyRTPRH] = 0; - base_addr[CyMSVR1] = 0; - base_addr[CyMSVR2] = 0; - write_cy_cmd(base_addr, CyINIT_CHAN | CyDIS_RCVR | CyDIS_XMTR); - } - - /* - * Now do specials for channel zero.... - */ - - base_addr[CyMSVR1] = CyRTS; - base_addr[CyMSVR2] = CyDTR; - base_addr[CyIER] = CyRxData; - write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR); - - local_irq_restore(flags); - - my_udelay(20000L); /* Let it all settle down */ - - printk("CD2401 initialised, chip is rev 0x%02x\n", base_addr[CyGFRCR]); - if (badspeed) - printk - (" WARNING: Failed to identify line speed, rcor=%02x,rbpr=%02x\n", - rcor >> 5, rbpr); -} /* serial_console_init */ - -static const struct tty_operations cy_ops = { - .open = cy_open, - .close = cy_close, - .write = cy_write, - .put_char = cy_put_char, - .flush_chars = cy_flush_chars, - .write_room = cy_write_room, - .chars_in_buffer = cy_chars_in_buffer, - .flush_buffer = cy_flush_buffer, - .ioctl = cy_ioctl, - .throttle = cy_throttle, - .unthrottle = cy_unthrottle, - .set_termios = cy_set_termios, - .stop = cy_stop, - .start = cy_start, - .hangup = cy_hangup, - .tiocmget = cy_tiocmget, - .tiocmset = cy_tiocmset, -}; - -/* The serial driver boot-time initialization code! - Hardware I/O ports are mapped to character special devices on a - first found, first allocated manner. That is, this code searches - for Cyclom cards in the system. As each is found, it is probed - to discover how many chips (and thus how many ports) are present. - These ports are mapped to the tty ports 64 and upward in monotonic - fashion. If an 8-port card is replaced with a 16-port card, the - port mapping on a following card will shift. - - This approach is different from what is used in the other serial - device driver because the Cyclom is more properly a multiplexer, - not just an aggregation of serial ports on one card. - - If there are more cards with more ports than have been statically - allocated above, a warning is printed and the extra ports are ignored. - */ -static int __init serial167_init(void) -{ - struct cyclades_port *info; - int ret = 0; - int good_ports = 0; - int port_num = 0; - int index; - int DefSpeed; -#ifdef notyet - struct sigaction sa; -#endif - - if (!(mvme16x_config & MVME16x_CONFIG_GOT_CD2401)) - return 0; - - cy_serial_driver = alloc_tty_driver(NR_PORTS); - if (!cy_serial_driver) - return -ENOMEM; - -#if 0 - scrn[1] = '\0'; -#endif - - show_version(); - - /* Has "console=0,9600n8" been used in bootinfo to change speed? */ - if (serial_console_cflag) - DefSpeed = serial_console_cflag & 0017; - else { - DefSpeed = initial_console_speed; - serial_console_info = &cy_port[0]; - serial_console_cflag = DefSpeed | CS8; -#if 0 - serial_console = 64; /*callout_driver.minor_start */ -#endif - } - - /* Initialize the tty_driver structure */ - - cy_serial_driver->owner = THIS_MODULE; - cy_serial_driver->name = "ttyS"; - cy_serial_driver->major = TTY_MAJOR; - cy_serial_driver->minor_start = 64; - cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - cy_serial_driver->subtype = SERIAL_TYPE_NORMAL; - cy_serial_driver->init_termios = tty_std_termios; - cy_serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - cy_serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(cy_serial_driver, &cy_ops); - - ret = tty_register_driver(cy_serial_driver); - if (ret) { - printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n"); - put_tty_driver(cy_serial_driver); - return ret; - } - - port_num = 0; - info = cy_port; - for (index = 0; index < 1; index++) { - - good_ports = 4; - - if (port_num < NR_PORTS) { - while (good_ports-- && port_num < NR_PORTS) { - /*** initialize port ***/ - info->magic = CYCLADES_MAGIC; - info->type = PORT_CIRRUS; - info->card = index; - info->line = port_num; - info->flags = STD_COM_FLAGS; - info->tty = NULL; - info->xmit_fifo_size = 12; - info->cor1 = CyPARITY_NONE | Cy_8_BITS; - info->cor2 = CyETC; - info->cor3 = Cy_1_STOP; - info->cor4 = 0x08; /* _very_ small receive threshold */ - info->cor5 = 0; - info->cor6 = 0; - info->cor7 = 0; - info->tbpr = baud_bpr[DefSpeed]; /* Tx BPR */ - info->tco = baud_co[DefSpeed]; /* Tx CO */ - info->rbpr = baud_bpr[DefSpeed]; /* Rx BPR */ - info->rco = baud_co[DefSpeed] >> 5; /* Rx CO */ - info->close_delay = 0; - info->x_char = 0; - info->count = 0; -#ifdef SERIAL_DEBUG_COUNT - printk("cyc: %d: setting count to 0\n", - __LINE__); -#endif - info->blocked_open = 0; - info->default_threshold = 0; - info->default_timeout = 0; - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - /* info->session */ - /* info->pgrp */ -/*** !!!!!!!! this may expose new bugs !!!!!!!!! *********/ - info->read_status_mask = - CyTIMEOUT | CySPECHAR | CyBREAK | CyPARITY | - CyFRAME | CyOVERRUN; - /* info->timeout */ - - printk("ttyS%d ", info->line); - port_num++; - info++; - if (!(port_num & 7)) { - printk("\n "); - } - } - } - printk("\n"); - } - while (port_num < NR_PORTS) { - info->line = -1; - port_num++; - info++; - } - - ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0, - "cd2401_errors", cd2401_rxerr_interrupt); - if (ret) { - printk(KERN_ERR "Could't get cd2401_errors IRQ"); - goto cleanup_serial_driver; - } - - ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0, - "cd2401_modem", cd2401_modem_interrupt); - if (ret) { - printk(KERN_ERR "Could't get cd2401_modem IRQ"); - goto cleanup_irq_cd2401_errors; - } - - ret = request_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0, - "cd2401_txints", cd2401_tx_interrupt); - if (ret) { - printk(KERN_ERR "Could't get cd2401_txints IRQ"); - goto cleanup_irq_cd2401_modem; - } - - ret = request_irq(MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0, - "cd2401_rxints", cd2401_rx_interrupt); - if (ret) { - printk(KERN_ERR "Could't get cd2401_rxints IRQ"); - goto cleanup_irq_cd2401_txints; - } - - /* Now we have registered the interrupt handlers, allow the interrupts */ - - pcc2chip[PccSCCMICR] = 0x15; /* Serial ints are level 5 */ - pcc2chip[PccSCCTICR] = 0x15; - pcc2chip[PccSCCRICR] = 0x15; - - pcc2chip[PccIMLR] = 3; /* Allow PCC2 ints above 3!? */ - - return 0; -cleanup_irq_cd2401_txints: - free_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt); -cleanup_irq_cd2401_modem: - free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt); -cleanup_irq_cd2401_errors: - free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt); -cleanup_serial_driver: - if (tty_unregister_driver(cy_serial_driver)) - printk(KERN_ERR - "Couldn't unregister MVME166/7 serial driver\n"); - put_tty_driver(cy_serial_driver); - return ret; -} /* serial167_init */ - -module_init(serial167_init); - -#ifdef CYCLOM_SHOW_STATUS -static void show_status(int line_num) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - int channel; - struct cyclades_port *info; - unsigned long flags; - - info = &cy_port[line_num]; - channel = info->line; - printk(" channel %d\n", channel); - /**/ printk(" cy_port\n"); - printk(" card line flags = %d %d %x\n", - info->card, info->line, info->flags); - printk - (" *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n", - (long)info->tty, info->read_status_mask, info->timeout, - info->xmit_fifo_size); - printk(" cor1,cor2,cor3,cor4,cor5,cor6,cor7 = %x %x %x %x %x %x %x\n", - info->cor1, info->cor2, info->cor3, info->cor4, info->cor5, - info->cor6, info->cor7); - printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n", info->tbpr, info->tco, - info->rbpr, info->rco); - printk(" close_delay event count = %d %d %d\n", info->close_delay, - info->event, info->count); - printk(" x_char blocked_open = %x %x\n", info->x_char, - info->blocked_open); - printk(" open_wait = %lx %lx %lx\n", (long)info->open_wait); - - local_irq_save(flags); - -/* Global Registers */ - - printk(" CyGFRCR %x\n", base_addr[CyGFRCR]); - printk(" CyCAR %x\n", base_addr[CyCAR]); - printk(" CyRISR %x\n", base_addr[CyRISR]); - printk(" CyTISR %x\n", base_addr[CyTISR]); - printk(" CyMISR %x\n", base_addr[CyMISR]); - printk(" CyRIR %x\n", base_addr[CyRIR]); - printk(" CyTIR %x\n", base_addr[CyTIR]); - printk(" CyMIR %x\n", base_addr[CyMIR]); - printk(" CyTPR %x\n", base_addr[CyTPR]); - - base_addr[CyCAR] = (u_char) channel; - -/* Virtual Registers */ - -#if 0 - printk(" CyRIVR %x\n", base_addr[CyRIVR]); - printk(" CyTIVR %x\n", base_addr[CyTIVR]); - printk(" CyMIVR %x\n", base_addr[CyMIVR]); - printk(" CyMISR %x\n", base_addr[CyMISR]); -#endif - -/* Channel Registers */ - - printk(" CyCCR %x\n", base_addr[CyCCR]); - printk(" CyIER %x\n", base_addr[CyIER]); - printk(" CyCOR1 %x\n", base_addr[CyCOR1]); - printk(" CyCOR2 %x\n", base_addr[CyCOR2]); - printk(" CyCOR3 %x\n", base_addr[CyCOR3]); - printk(" CyCOR4 %x\n", base_addr[CyCOR4]); - printk(" CyCOR5 %x\n", base_addr[CyCOR5]); -#if 0 - printk(" CyCCSR %x\n", base_addr[CyCCSR]); - printk(" CyRDCR %x\n", base_addr[CyRDCR]); -#endif - printk(" CySCHR1 %x\n", base_addr[CySCHR1]); - printk(" CySCHR2 %x\n", base_addr[CySCHR2]); -#if 0 - printk(" CySCHR3 %x\n", base_addr[CySCHR3]); - printk(" CySCHR4 %x\n", base_addr[CySCHR4]); - printk(" CySCRL %x\n", base_addr[CySCRL]); - printk(" CySCRH %x\n", base_addr[CySCRH]); - printk(" CyLNC %x\n", base_addr[CyLNC]); - printk(" CyMCOR1 %x\n", base_addr[CyMCOR1]); - printk(" CyMCOR2 %x\n", base_addr[CyMCOR2]); -#endif - printk(" CyRTPRL %x\n", base_addr[CyRTPRL]); - printk(" CyRTPRH %x\n", base_addr[CyRTPRH]); - printk(" CyMSVR1 %x\n", base_addr[CyMSVR1]); - printk(" CyMSVR2 %x\n", base_addr[CyMSVR2]); - printk(" CyRBPR %x\n", base_addr[CyRBPR]); - printk(" CyRCOR %x\n", base_addr[CyRCOR]); - printk(" CyTBPR %x\n", base_addr[CyTBPR]); - printk(" CyTCOR %x\n", base_addr[CyTCOR]); - - local_irq_restore(flags); -} /* show_status */ -#endif - -#if 0 -/* Dummy routine in mvme16x/config.c for now */ - -/* Serial console setup. Called from linux/init/main.c */ - -void console_setup(char *str, int *ints) -{ - char *s; - int baud, bits, parity; - int cflag = 0; - - /* Sanity check. */ - if (ints[0] > 3 || ints[1] > 3) - return; - - /* Get baud, bits and parity */ - baud = 2400; - bits = 8; - parity = 'n'; - if (ints[2]) - baud = ints[2]; - if ((s = strchr(str, ','))) { - do { - s++; - } while (*s >= '0' && *s <= '9'); - if (*s) - parity = *s++; - if (*s) - bits = *s - '0'; - } - - /* Now construct a cflag setting. */ - switch (baud) { - case 1200: - cflag |= B1200; - break; - case 9600: - cflag |= B9600; - break; - case 19200: - cflag |= B19200; - break; - case 38400: - cflag |= B38400; - break; - case 2400: - default: - cflag |= B2400; - break; - } - switch (bits) { - case 7: - cflag |= CS7; - break; - default: - case 8: - cflag |= CS8; - break; - } - switch (parity) { - case 'o': - case 'O': - cflag |= PARODD; - break; - case 'e': - case 'E': - cflag |= PARENB; - break; - } - - serial_console_info = &cy_port[ints[1]]; - serial_console_cflag = cflag; - serial_console = ints[1] + 64; /*callout_driver.minor_start */ -} -#endif - -/* - * The following is probably out of date for 2.1.x serial console stuff. - * - * The console is registered early on from arch/m68k/kernel/setup.c, and - * it therefore relies on the chip being setup correctly by 166-Bug. This - * seems reasonable, as the serial port has been used to invoke the system - * boot. It also means that this function must not rely on any data - * initialisation performed by serial167_init() etc. - * - * Of course, once the console has been registered, we had better ensure - * that serial167_init() doesn't leave the chip non-functional. - * - * The console must be locked when we get here. - */ - -void serial167_console_write(struct console *co, const char *str, - unsigned count) -{ - volatile unsigned char *base_addr = (u_char *) BASE_ADDR; - unsigned long flags; - volatile u_char sink; - u_char ier; - int port; - u_char do_lf = 0; - int i = 0; - - local_irq_save(flags); - - /* Ensure transmitter is enabled! */ - - port = 0; - base_addr[CyCAR] = (u_char) port; - while (base_addr[CyCCR]) - ; - base_addr[CyCCR] = CyENB_XMTR; - - ier = base_addr[CyIER]; - base_addr[CyIER] = CyTxMpty; - - while (1) { - if (pcc2chip[PccSCCTICR] & 0x20) { - /* We have a Tx int. Acknowledge it */ - sink = pcc2chip[PccTPIACKR]; - if ((base_addr[CyLICR] >> 2) == port) { - if (i == count) { - /* Last char of string is now output */ - base_addr[CyTEOIR] = CyNOTRANS; - break; - } - if (do_lf) { - base_addr[CyTDR] = '\n'; - str++; - i++; - do_lf = 0; - } else if (*str == '\n') { - base_addr[CyTDR] = '\r'; - do_lf = 1; - } else { - base_addr[CyTDR] = *str++; - i++; - } - base_addr[CyTEOIR] = 0; - } else - base_addr[CyTEOIR] = CyNOTRANS; - } - } - - base_addr[CyIER] = ier; - - local_irq_restore(flags); -} - -static struct tty_driver *serial167_console_device(struct console *c, - int *index) -{ - *index = c->index; - return cy_serial_driver; -} - -static struct console sercons = { - .name = "ttyS", - .write = serial167_console_write, - .device = serial167_console_device, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -static int __init serial167_console_init(void) -{ - if (vme_brdtype == VME_TYPE_MVME166 || - vme_brdtype == VME_TYPE_MVME167 || - vme_brdtype == VME_TYPE_MVME177) { - mvme167_serial_console_setup(0); - register_console(&sercons); - } - return 0; -} - -console_initcall(serial167_console_init); - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/tty/specialix.c b/drivers/staging/tty/specialix.c deleted file mode 100644 index 5c3598ec7456..000000000000 --- a/drivers/staging/tty/specialix.c +++ /dev/null @@ -1,2368 +0,0 @@ -/* - * specialix.c -- specialix IO8+ multiport serial driver. - * - * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) - * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) - * - * Specialix pays for the development and support of this driver. - * Please DO contact io8-linux@specialix.co.uk if you require - * support. But please read the documentation (specialix.txt) - * first. - * - * This driver was developed in the BitWizard linux device - * driver service. If you require a linux device driver for your - * product, please contact devices@BitWizard.nl for a quote. - * - * This code is firmly based on the riscom/8 serial driver, - * written by Dmitry Gorodchanin. The specialix IO8+ card - * programming information was obtained from the CL-CD1865 Data - * Book, and Specialix document number 6200059: IO8+ Hardware - * Functional Specification. - * - * 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. - * - * Revision history: - * - * Revision 1.0: April 1st 1997. - * Initial release for alpha testing. - * Revision 1.1: April 14th 1997. - * Incorporated Richard Hudsons suggestions, - * removed some debugging printk's. - * Revision 1.2: April 15th 1997. - * Ported to 2.1.x kernels. - * Revision 1.3: April 17th 1997 - * Backported to 2.0. (Compatibility macros). - * Revision 1.4: April 18th 1997 - * Fixed DTR/RTS bug that caused the card to indicate - * "don't send data" to a modem after the password prompt. - * Fixed bug for premature (fake) interrupts. - * Revision 1.5: April 19th 1997 - * fixed a minor typo in the header file, cleanup a little. - * performance warnings are now MAXed at once per minute. - * Revision 1.6: May 23 1997 - * Changed the specialix=... format to include interrupt. - * Revision 1.7: May 27 1997 - * Made many more debug printk's a compile time option. - * Revision 1.8: Jul 1 1997 - * port to linux-2.1.43 kernel. - * Revision 1.9: Oct 9 1998 - * Added stuff for the IO8+/PCI version. - * Revision 1.10: Oct 22 1999 / Jan 21 2000. - * Added stuff for setserial. - * Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr) - * - */ - -#define VERSION "1.11" - - -/* - * There is a bunch of documentation about the card, jumpers, config - * settings, restrictions, cables, device names and numbers in - * Documentation/serial/specialix.txt - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "specialix_io8.h" -#include "cd1865.h" - - -/* - This driver can spew a whole lot of debugging output at you. If you - need maximum performance, you should disable the DEBUG define. To - aid in debugging in the field, I'm leaving the compile-time debug - features enabled, and disable them "runtime". That allows me to - instruct people with problems to enable debugging without requiring - them to recompile... -*/ -#define DEBUG - -static int sx_debug; -static int sx_rxfifo = SPECIALIX_RXFIFO; -static int sx_rtscts; - -#ifdef DEBUG -#define dprintk(f, str...) if (sx_debug & f) printk(str) -#else -#define dprintk(f, str...) /* nothing */ -#endif - -#define SX_DEBUG_FLOW 0x0001 -#define SX_DEBUG_DATA 0x0002 -#define SX_DEBUG_PROBE 0x0004 -#define SX_DEBUG_CHAN 0x0008 -#define SX_DEBUG_INIT 0x0010 -#define SX_DEBUG_RX 0x0020 -#define SX_DEBUG_TX 0x0040 -#define SX_DEBUG_IRQ 0x0080 -#define SX_DEBUG_OPEN 0x0100 -#define SX_DEBUG_TERMIOS 0x0200 -#define SX_DEBUG_SIGNALS 0x0400 -#define SX_DEBUG_FIFO 0x0800 - - -#define func_enter() dprintk(SX_DEBUG_FLOW, "io8: enter %s\n", __func__) -#define func_exit() dprintk(SX_DEBUG_FLOW, "io8: exit %s\n", __func__) - - -/* Configurable options: */ - -/* Am I paranoid or not ? ;-) */ -#define SPECIALIX_PARANOIA_CHECK - -/* - * The following defines are mostly for testing purposes. But if you need - * some nice reporting in your syslog, you can define them also. - */ -#undef SX_REPORT_FIFO -#undef SX_REPORT_OVERRUN - - - - -#define SPECIALIX_LEGAL_FLAGS \ - (ASYNC_HUP_NOTIFY | ASYNC_SAK | ASYNC_SPLIT_TERMIOS | \ - ASYNC_SPD_HI | ASYNC_SPEED_VHI | ASYNC_SESSION_LOCKOUT | \ - ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP) - -static struct tty_driver *specialix_driver; - -static struct specialix_board sx_board[SX_NBOARD] = { - { 0, SX_IOBASE1, 9, }, - { 0, SX_IOBASE2, 11, }, - { 0, SX_IOBASE3, 12, }, - { 0, SX_IOBASE4, 15, }, -}; - -static struct specialix_port sx_port[SX_NBOARD * SX_NPORT]; - - -static int sx_paranoia_check(struct specialix_port const *port, - char *name, const char *routine) -{ -#ifdef SPECIALIX_PARANOIA_CHECK - static const char *badmagic = KERN_ERR - "sx: Warning: bad specialix port magic number for device %s in %s\n"; - static const char *badinfo = KERN_ERR - "sx: Warning: null specialix port for device %s in %s\n"; - - if (!port) { - printk(badinfo, name, routine); - return 1; - } - if (port->magic != SPECIALIX_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#endif - return 0; -} - - -/* - * - * Service functions for specialix IO8+ driver. - * - */ - -/* Get board number from pointer */ -static inline int board_No(struct specialix_board *bp) -{ - return bp - sx_board; -} - - -/* Get port number from pointer */ -static inline int port_No(struct specialix_port const *port) -{ - return SX_PORT(port - sx_port); -} - - -/* Get pointer to board from pointer to port */ -static inline struct specialix_board *port_Board( - struct specialix_port const *port) -{ - return &sx_board[SX_BOARD(port - sx_port)]; -} - - -/* Input Byte from CL CD186x register */ -static inline unsigned char sx_in(struct specialix_board *bp, - unsigned short reg) -{ - bp->reg = reg | 0x80; - outb(reg | 0x80, bp->base + SX_ADDR_REG); - return inb(bp->base + SX_DATA_REG); -} - - -/* Output Byte to CL CD186x register */ -static inline void sx_out(struct specialix_board *bp, unsigned short reg, - unsigned char val) -{ - bp->reg = reg | 0x80; - outb(reg | 0x80, bp->base + SX_ADDR_REG); - outb(val, bp->base + SX_DATA_REG); -} - - -/* Input Byte from CL CD186x register */ -static inline unsigned char sx_in_off(struct specialix_board *bp, - unsigned short reg) -{ - bp->reg = reg; - outb(reg, bp->base + SX_ADDR_REG); - return inb(bp->base + SX_DATA_REG); -} - - -/* Output Byte to CL CD186x register */ -static inline void sx_out_off(struct specialix_board *bp, - unsigned short reg, unsigned char val) -{ - bp->reg = reg; - outb(reg, bp->base + SX_ADDR_REG); - outb(val, bp->base + SX_DATA_REG); -} - - -/* Wait for Channel Command Register ready */ -static void sx_wait_CCR(struct specialix_board *bp) -{ - unsigned long delay, flags; - unsigned char ccr; - - for (delay = SX_CCR_TIMEOUT; delay; delay--) { - spin_lock_irqsave(&bp->lock, flags); - ccr = sx_in(bp, CD186x_CCR); - spin_unlock_irqrestore(&bp->lock, flags); - if (!ccr) - return; - udelay(1); - } - - printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); -} - - -/* Wait for Channel Command Register ready */ -static void sx_wait_CCR_off(struct specialix_board *bp) -{ - unsigned long delay; - unsigned char crr; - unsigned long flags; - - for (delay = SX_CCR_TIMEOUT; delay; delay--) { - spin_lock_irqsave(&bp->lock, flags); - crr = sx_in_off(bp, CD186x_CCR); - spin_unlock_irqrestore(&bp->lock, flags); - if (!crr) - return; - udelay(1); - } - - printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp)); -} - - -/* - * specialix IO8+ IO range functions. - */ - -static int sx_request_io_range(struct specialix_board *bp) -{ - return request_region(bp->base, - bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE, - "specialix IO8+") == NULL; -} - - -static void sx_release_io_range(struct specialix_board *bp) -{ - release_region(bp->base, bp->flags & SX_BOARD_IS_PCI ? - SX_PCI_IO_SPACE : SX_IO_SPACE); -} - - -/* Set the IRQ using the RTS lines that run to the PAL on the board.... */ -static int sx_set_irq(struct specialix_board *bp) -{ - int virq; - int i; - unsigned long flags; - - if (bp->flags & SX_BOARD_IS_PCI) - return 1; - switch (bp->irq) { - /* In the same order as in the docs... */ - case 15: - virq = 0; - break; - case 12: - virq = 1; - break; - case 11: - virq = 2; - break; - case 9: - virq = 3; - break; - default:printk(KERN_ERR - "Speclialix: cannot set irq to %d.\n", bp->irq); - return 0; - } - spin_lock_irqsave(&bp->lock, flags); - for (i = 0; i < 2; i++) { - sx_out(bp, CD186x_CAR, i); - sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0); - } - spin_unlock_irqrestore(&bp->lock, flags); - return 1; -} - - -/* Reset and setup CD186x chip */ -static int sx_init_CD186x(struct specialix_board *bp) -{ - unsigned long flags; - int scaler; - int rv = 1; - - func_enter(); - sx_wait_CCR_off(bp); /* Wait for CCR ready */ - spin_lock_irqsave(&bp->lock, flags); - sx_out_off(bp, CD186x_CCR, CCR_HARDRESET); /* Reset CD186x chip */ - spin_unlock_irqrestore(&bp->lock, flags); - msleep(50); /* Delay 0.05 sec */ - spin_lock_irqsave(&bp->lock, flags); - sx_out_off(bp, CD186x_GIVR, SX_ID); /* Set ID for this chip */ - sx_out_off(bp, CD186x_GICR, 0); /* Clear all bits */ - sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT); /* Prio for modem intr */ - sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT); /* Prio for transmitter intr */ - sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT); /* Prio for receiver intr */ - /* Set RegAckEn */ - sx_out_off(bp, CD186x_SRCR, sx_in(bp, CD186x_SRCR) | SRCR_REGACKEN); - - /* Setting up prescaler. We need 4 ticks per 1 ms */ - scaler = SX_OSCFREQ/SPECIALIX_TPS; - - sx_out_off(bp, CD186x_PPRH, scaler >> 8); - sx_out_off(bp, CD186x_PPRL, scaler & 0xff); - spin_unlock_irqrestore(&bp->lock, flags); - - if (!sx_set_irq(bp)) { - /* Figure out how to pass this along... */ - printk(KERN_ERR "Cannot set irq to %d.\n", bp->irq); - rv = 0; - } - - func_exit(); - return rv; -} - - -static int read_cross_byte(struct specialix_board *bp, int reg, int bit) -{ - int i; - int t; - unsigned long flags; - - spin_lock_irqsave(&bp->lock, flags); - for (i = 0, t = 0; i < 8; i++) { - sx_out_off(bp, CD186x_CAR, i); - if (sx_in_off(bp, reg) & bit) - t |= 1 << i; - } - spin_unlock_irqrestore(&bp->lock, flags); - - return t; -} - - -/* Main probing routine, also sets irq. */ -static int sx_probe(struct specialix_board *bp) -{ - unsigned char val1, val2; - int rev; - int chip; - - func_enter(); - - if (sx_request_io_range(bp)) { - func_exit(); - return 1; - } - - /* Are the I/O ports here ? */ - sx_out_off(bp, CD186x_PPRL, 0x5a); - udelay(1); - val1 = sx_in_off(bp, CD186x_PPRL); - - sx_out_off(bp, CD186x_PPRL, 0xa5); - udelay(1); - val2 = sx_in_off(bp, CD186x_PPRL); - - - if (val1 != 0x5a || val2 != 0xa5) { - printk(KERN_INFO - "sx%d: specialix IO8+ Board at 0x%03x not found.\n", - board_No(bp), bp->base); - sx_release_io_range(bp); - func_exit(); - return 1; - } - - /* Check the DSR lines that Specialix uses as board - identification */ - val1 = read_cross_byte(bp, CD186x_MSVR, MSVR_DSR); - val2 = read_cross_byte(bp, CD186x_MSVR, MSVR_RTS); - dprintk(SX_DEBUG_INIT, - "sx%d: DSR lines are: %02x, rts lines are: %02x\n", - board_No(bp), val1, val2); - - /* They managed to switch the bit order between the docs and - the IO8+ card. The new PCI card now conforms to old docs. - They changed the PCI docs to reflect the situation on the - old card. */ - val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2; - if (val1 != val2) { - printk(KERN_INFO - "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n", - board_No(bp), val2, bp->base, val1); - sx_release_io_range(bp); - func_exit(); - return 1; - } - - - /* Reset CD186x again */ - if (!sx_init_CD186x(bp)) { - sx_release_io_range(bp); - func_exit(); - return 1; - } - - sx_request_io_range(bp); - bp->flags |= SX_BOARD_PRESENT; - - /* Chip revcode pkgtype - GFRCR SRCR bit 7 - CD180 rev B 0x81 0 - CD180 rev C 0x82 0 - CD1864 rev A 0x82 1 - CD1865 rev A 0x83 1 -- Do not use!!! Does not work. - CD1865 rev B 0x84 1 - -- Thanks to Gwen Wang, Cirrus Logic. - */ - - switch (sx_in_off(bp, CD186x_GFRCR)) { - case 0x82: - chip = 1864; - rev = 'A'; - break; - case 0x83: - chip = 1865; - rev = 'A'; - break; - case 0x84: - chip = 1865; - rev = 'B'; - break; - case 0x85: - chip = 1865; - rev = 'C'; - break; /* Does not exist at this time */ - default: - chip = -1; - rev = 'x'; - } - - dprintk(SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR)); - - printk(KERN_INFO - "sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n", - board_No(bp), bp->base, bp->irq, chip, rev); - - func_exit(); - return 0; -} - -/* - * - * Interrupt processing routines. - * */ - -static struct specialix_port *sx_get_port(struct specialix_board *bp, - unsigned char const *what) -{ - unsigned char channel; - struct specialix_port *port = NULL; - - channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF; - dprintk(SX_DEBUG_CHAN, "channel: %d\n", channel); - if (channel < CD186x_NCH) { - port = &sx_port[board_No(bp) * SX_NPORT + channel]; - dprintk(SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n", - board_No(bp) * SX_NPORT + channel, port, - port->port.flags & ASYNC_INITIALIZED); - - if (port->port.flags & ASYNC_INITIALIZED) { - dprintk(SX_DEBUG_CHAN, "port: %d %p\n", channel, port); - func_exit(); - return port; - } - } - printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n", - board_No(bp), what, channel); - return NULL; -} - - -static void sx_receive_exc(struct specialix_board *bp) -{ - struct specialix_port *port; - struct tty_struct *tty; - unsigned char status; - unsigned char ch, flag; - - func_enter(); - - port = sx_get_port(bp, "Receive"); - if (!port) { - dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n"); - func_exit(); - return; - } - tty = port->port.tty; - - status = sx_in(bp, CD186x_RCSR); - - dprintk(SX_DEBUG_RX, "status: 0x%x\n", status); - if (status & RCSR_OE) { - port->overrun++; - dprintk(SX_DEBUG_FIFO, - "sx%d: port %d: Overrun. Total %ld overruns.\n", - board_No(bp), port_No(port), port->overrun); - } - status &= port->mark_mask; - - /* This flip buffer check needs to be below the reading of the - status register to reset the chip's IRQ.... */ - if (tty_buffer_request_room(tty, 1) == 0) { - dprintk(SX_DEBUG_FIFO, - "sx%d: port %d: Working around flip buffer overflow.\n", - board_No(bp), port_No(port)); - func_exit(); - return; - } - - ch = sx_in(bp, CD186x_RDR); - if (!status) { - func_exit(); - return; - } - if (status & RCSR_TOUT) { - printk(KERN_INFO - "sx%d: port %d: Receiver timeout. Hardware problems ?\n", - board_No(bp), port_No(port)); - func_exit(); - return; - - } else if (status & RCSR_BREAK) { - dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n", - board_No(bp), port_No(port)); - flag = TTY_BREAK; - if (port->port.flags & ASYNC_SAK) - do_SAK(tty); - - } else if (status & RCSR_PE) - flag = TTY_PARITY; - - else if (status & RCSR_FE) - flag = TTY_FRAME; - - else if (status & RCSR_OE) - flag = TTY_OVERRUN; - - else - flag = TTY_NORMAL; - - if (tty_insert_flip_char(tty, ch, flag)) - tty_flip_buffer_push(tty); - func_exit(); -} - - -static void sx_receive(struct specialix_board *bp) -{ - struct specialix_port *port; - struct tty_struct *tty; - unsigned char count; - - func_enter(); - - port = sx_get_port(bp, "Receive"); - if (port == NULL) { - dprintk(SX_DEBUG_RX, "Hmm, couldn't find port.\n"); - func_exit(); - return; - } - tty = port->port.tty; - - count = sx_in(bp, CD186x_RDCR); - dprintk(SX_DEBUG_RX, "port: %p: count: %d\n", port, count); - port->hits[count > 8 ? 9 : count]++; - - while (count--) - tty_insert_flip_char(tty, sx_in(bp, CD186x_RDR), TTY_NORMAL); - tty_flip_buffer_push(tty); - func_exit(); -} - - -static void sx_transmit(struct specialix_board *bp) -{ - struct specialix_port *port; - struct tty_struct *tty; - unsigned char count; - - func_enter(); - port = sx_get_port(bp, "Transmit"); - if (port == NULL) { - func_exit(); - return; - } - dprintk(SX_DEBUG_TX, "port: %p\n", port); - tty = port->port.tty; - - if (port->IER & IER_TXEMPTY) { - /* FIFO drained */ - sx_out(bp, CD186x_CAR, port_No(port)); - port->IER &= ~IER_TXEMPTY; - sx_out(bp, CD186x_IER, port->IER); - func_exit(); - return; - } - - if ((port->xmit_cnt <= 0 && !port->break_length) - || tty->stopped || tty->hw_stopped) { - sx_out(bp, CD186x_CAR, port_No(port)); - port->IER &= ~IER_TXRDY; - sx_out(bp, CD186x_IER, port->IER); - func_exit(); - return; - } - - if (port->break_length) { - if (port->break_length > 0) { - if (port->COR2 & COR2_ETC) { - sx_out(bp, CD186x_TDR, CD186x_C_ESC); - sx_out(bp, CD186x_TDR, CD186x_C_SBRK); - port->COR2 &= ~COR2_ETC; - } - count = min_t(int, port->break_length, 0xff); - sx_out(bp, CD186x_TDR, CD186x_C_ESC); - sx_out(bp, CD186x_TDR, CD186x_C_DELAY); - sx_out(bp, CD186x_TDR, count); - port->break_length -= count; - if (port->break_length == 0) - port->break_length--; - } else { - sx_out(bp, CD186x_TDR, CD186x_C_ESC); - sx_out(bp, CD186x_TDR, CD186x_C_EBRK); - sx_out(bp, CD186x_COR2, port->COR2); - sx_wait_CCR(bp); - sx_out(bp, CD186x_CCR, CCR_CORCHG2); - port->break_length = 0; - } - - func_exit(); - return; - } - - count = CD186x_NFIFO; - do { - sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]); - port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1); - if (--port->xmit_cnt <= 0) - break; - } while (--count > 0); - - if (port->xmit_cnt <= 0) { - sx_out(bp, CD186x_CAR, port_No(port)); - port->IER &= ~IER_TXRDY; - sx_out(bp, CD186x_IER, port->IER); - } - if (port->xmit_cnt <= port->wakeup_chars) - tty_wakeup(tty); - - func_exit(); -} - - -static void sx_check_modem(struct specialix_board *bp) -{ - struct specialix_port *port; - struct tty_struct *tty; - unsigned char mcr; - int msvr_cd; - - dprintk(SX_DEBUG_SIGNALS, "Modem intr. "); - port = sx_get_port(bp, "Modem"); - if (port == NULL) - return; - - tty = port->port.tty; - - mcr = sx_in(bp, CD186x_MCR); - - if ((mcr & MCR_CDCHG)) { - dprintk(SX_DEBUG_SIGNALS, "CD just changed... "); - msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD; - if (msvr_cd) { - dprintk(SX_DEBUG_SIGNALS, "Waking up guys in open.\n"); - wake_up_interruptible(&port->port.open_wait); - } else { - dprintk(SX_DEBUG_SIGNALS, "Sending HUP.\n"); - tty_hangup(tty); - } - } - -#ifdef SPECIALIX_BRAIN_DAMAGED_CTS - if (mcr & MCR_CTSCHG) { - if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) { - tty->hw_stopped = 0; - port->IER |= IER_TXRDY; - if (port->xmit_cnt <= port->wakeup_chars) - tty_wakeup(tty); - } else { - tty->hw_stopped = 1; - port->IER &= ~IER_TXRDY; - } - sx_out(bp, CD186x_IER, port->IER); - } - if (mcr & MCR_DSSXHG) { - if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) { - tty->hw_stopped = 0; - port->IER |= IER_TXRDY; - if (port->xmit_cnt <= port->wakeup_chars) - tty_wakeup(tty); - } else { - tty->hw_stopped = 1; - port->IER &= ~IER_TXRDY; - } - sx_out(bp, CD186x_IER, port->IER); - } -#endif /* SPECIALIX_BRAIN_DAMAGED_CTS */ - - /* Clear change bits */ - sx_out(bp, CD186x_MCR, 0); -} - - -/* The main interrupt processing routine */ -static irqreturn_t sx_interrupt(int dummy, void *dev_id) -{ - unsigned char status; - unsigned char ack; - struct specialix_board *bp = dev_id; - unsigned long loop = 0; - int saved_reg; - unsigned long flags; - - func_enter(); - - spin_lock_irqsave(&bp->lock, flags); - - dprintk(SX_DEBUG_FLOW, "enter %s port %d room: %ld\n", __func__, - port_No(sx_get_port(bp, "INT")), - SERIAL_XMIT_SIZE - sx_get_port(bp, "ITN")->xmit_cnt - 1); - if (!(bp->flags & SX_BOARD_ACTIVE)) { - dprintk(SX_DEBUG_IRQ, "sx: False interrupt. irq %d.\n", - bp->irq); - spin_unlock_irqrestore(&bp->lock, flags); - func_exit(); - return IRQ_NONE; - } - - saved_reg = bp->reg; - - while (++loop < 16) { - status = sx_in(bp, CD186x_SRSR) & - (SRSR_RREQint | SRSR_TREQint | SRSR_MREQint); - if (status == 0) - break; - if (status & SRSR_RREQint) { - ack = sx_in(bp, CD186x_RRAR); - - if (ack == (SX_ID | GIVR_IT_RCV)) - sx_receive(bp); - else if (ack == (SX_ID | GIVR_IT_REXC)) - sx_receive_exc(bp); - else - printk(KERN_ERR - "sx%d: status: 0x%x Bad receive ack 0x%02x.\n", - board_No(bp), status, ack); - - } else if (status & SRSR_TREQint) { - ack = sx_in(bp, CD186x_TRAR); - - if (ack == (SX_ID | GIVR_IT_TX)) - sx_transmit(bp); - else - printk(KERN_ERR "sx%d: status: 0x%x Bad transmit ack 0x%02x. port: %d\n", - board_No(bp), status, ack, - port_No(sx_get_port(bp, "Int"))); - } else if (status & SRSR_MREQint) { - ack = sx_in(bp, CD186x_MRAR); - - if (ack == (SX_ID | GIVR_IT_MODEM)) - sx_check_modem(bp); - else - printk(KERN_ERR - "sx%d: status: 0x%x Bad modem ack 0x%02x.\n", - board_No(bp), status, ack); - - } - - sx_out(bp, CD186x_EOIR, 0); /* Mark end of interrupt */ - } - bp->reg = saved_reg; - outb(bp->reg, bp->base + SX_ADDR_REG); - spin_unlock_irqrestore(&bp->lock, flags); - func_exit(); - return IRQ_HANDLED; -} - - -/* - * Routines for open & close processing. - */ - -static void turn_ints_off(struct specialix_board *bp) -{ - unsigned long flags; - - func_enter(); - spin_lock_irqsave(&bp->lock, flags); - (void) sx_in_off(bp, 0); /* Turn off interrupts. */ - spin_unlock_irqrestore(&bp->lock, flags); - - func_exit(); -} - -static void turn_ints_on(struct specialix_board *bp) -{ - unsigned long flags; - - func_enter(); - - spin_lock_irqsave(&bp->lock, flags); - (void) sx_in(bp, 0); /* Turn ON interrupts. */ - spin_unlock_irqrestore(&bp->lock, flags); - - func_exit(); -} - - -/* Called with disabled interrupts */ -static int sx_setup_board(struct specialix_board *bp) -{ - int error; - - if (bp->flags & SX_BOARD_ACTIVE) - return 0; - - if (bp->flags & SX_BOARD_IS_PCI) - error = request_irq(bp->irq, sx_interrupt, - IRQF_DISABLED | IRQF_SHARED, "specialix IO8+", bp); - else - error = request_irq(bp->irq, sx_interrupt, - IRQF_DISABLED, "specialix IO8+", bp); - - if (error) - return error; - - turn_ints_on(bp); - bp->flags |= SX_BOARD_ACTIVE; - - return 0; -} - - -/* Called with disabled interrupts */ -static void sx_shutdown_board(struct specialix_board *bp) -{ - func_enter(); - - if (!(bp->flags & SX_BOARD_ACTIVE)) { - func_exit(); - return; - } - - bp->flags &= ~SX_BOARD_ACTIVE; - - dprintk(SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n", - bp->irq, board_No(bp)); - free_irq(bp->irq, bp); - turn_ints_off(bp); - func_exit(); -} - -static unsigned int sx_crtscts(struct tty_struct *tty) -{ - if (sx_rtscts) - return C_CRTSCTS(tty); - return 1; -} - -/* - * Setting up port characteristics. - * Must be called with disabled interrupts - */ -static void sx_change_speed(struct specialix_board *bp, - struct specialix_port *port) -{ - struct tty_struct *tty; - unsigned long baud; - long tmp; - unsigned char cor1 = 0, cor3 = 0; - unsigned char mcor1 = 0, mcor2 = 0; - static unsigned long again; - unsigned long flags; - - func_enter(); - - tty = port->port.tty; - if (!tty || !tty->termios) { - func_exit(); - return; - } - - port->IER = 0; - port->COR2 = 0; - /* Select port on the board */ - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CAR, port_No(port)); - - /* The Specialix board doesn't implement the RTS lines. - They are used to set the IRQ level. Don't touch them. */ - if (sx_crtscts(tty)) - port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS); - else - port->MSVR = (sx_in(bp, CD186x_MSVR) & MSVR_RTS); - spin_unlock_irqrestore(&bp->lock, flags); - dprintk(SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR); - baud = tty_get_baud_rate(tty); - - if (baud == 38400) { - if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - baud = 57600; - if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - baud = 115200; - } - - if (!baud) { - /* Drop DTR & exit */ - dprintk(SX_DEBUG_TERMIOS, "Dropping DTR... Hmm....\n"); - if (!sx_crtscts(tty)) { - port->MSVR &= ~MSVR_DTR; - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_MSVR, port->MSVR); - spin_unlock_irqrestore(&bp->lock, flags); - } else - dprintk(SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n"); - return; - } else { - /* Set DTR on */ - if (!sx_crtscts(tty)) - port->MSVR |= MSVR_DTR; - } - - /* - * Now we must calculate some speed depended things - */ - - /* Set baud rate for port */ - tmp = port->custom_divisor ; - if (tmp) - printk(KERN_INFO - "sx%d: Using custom baud rate divisor %ld. \n" - "This is an untested option, please be careful.\n", - port_No(port), tmp); - else - tmp = (((SX_OSCFREQ + baud/2) / baud + CD186x_TPC/2) / - CD186x_TPC); - - if (tmp < 0x10 && time_before(again, jiffies)) { - again = jiffies + HZ * 60; - /* Page 48 of version 2.0 of the CL-CD1865 databook */ - if (tmp >= 12) { - printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n" - "Performance degradation is possible.\n" - "Read specialix.txt for more info.\n", - port_No(port), tmp); - } else { - printk(KERN_INFO "sx%d: Baud rate divisor is %ld. \n" - "Warning: overstressing Cirrus chip. This might not work.\n" - "Read specialix.txt for more info.\n", port_No(port), tmp); - } - } - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff); - sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); - sx_out(bp, CD186x_RBPRL, tmp & 0xff); - sx_out(bp, CD186x_TBPRL, tmp & 0xff); - spin_unlock_irqrestore(&bp->lock, flags); - if (port->custom_divisor) - baud = (SX_OSCFREQ + port->custom_divisor/2) / - port->custom_divisor; - baud = (baud + 5) / 10; /* Estimated CPS */ - - /* Two timer ticks seems enough to wakeup something like SLIP driver */ - tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO; - port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? - SERIAL_XMIT_SIZE - 1 : tmp); - - /* Receiver timeout will be transmission time for 1.5 chars */ - tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud; - tmp = (tmp > 0xff) ? 0xff : tmp; - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_RTPR, tmp); - spin_unlock_irqrestore(&bp->lock, flags); - switch (C_CSIZE(tty)) { - case CS5: - cor1 |= COR1_5BITS; - break; - case CS6: - cor1 |= COR1_6BITS; - break; - case CS7: - cor1 |= COR1_7BITS; - break; - case CS8: - cor1 |= COR1_8BITS; - break; - } - - if (C_CSTOPB(tty)) - cor1 |= COR1_2SB; - - cor1 |= COR1_IGNORE; - if (C_PARENB(tty)) { - cor1 |= COR1_NORMPAR; - if (C_PARODD(tty)) - cor1 |= COR1_ODDP; - if (I_INPCK(tty)) - cor1 &= ~COR1_IGNORE; - } - /* Set marking of some errors */ - port->mark_mask = RCSR_OE | RCSR_TOUT; - if (I_INPCK(tty)) - port->mark_mask |= RCSR_FE | RCSR_PE; - if (I_BRKINT(tty) || I_PARMRK(tty)) - port->mark_mask |= RCSR_BREAK; - if (I_IGNPAR(tty)) - port->mark_mask &= ~(RCSR_FE | RCSR_PE); - if (I_IGNBRK(tty)) { - port->mark_mask &= ~RCSR_BREAK; - if (I_IGNPAR(tty)) - /* Real raw mode. Ignore all */ - port->mark_mask &= ~RCSR_OE; - } - /* Enable Hardware Flow Control */ - if (C_CRTSCTS(tty)) { -#ifdef SPECIALIX_BRAIN_DAMAGED_CTS - port->IER |= IER_DSR | IER_CTS; - mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD; - mcor2 |= MCOR2_DSROD | MCOR2_CTSOD; - spin_lock_irqsave(&bp->lock, flags); - tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & - (MSVR_CTS|MSVR_DSR)); - spin_unlock_irqrestore(&bp->lock, flags); -#else - port->COR2 |= COR2_CTSAE; -#endif - } - /* Enable Software Flow Control. FIXME: I'm not sure about this */ - /* Some people reported that it works, but I still doubt it */ - if (I_IXON(tty)) { - port->COR2 |= COR2_TXIBE; - cor3 |= (COR3_FCT | COR3_SCDE); - if (I_IXANY(tty)) - port->COR2 |= COR2_IXM; - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_SCHR1, START_CHAR(tty)); - sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty)); - sx_out(bp, CD186x_SCHR3, START_CHAR(tty)); - sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty)); - spin_unlock_irqrestore(&bp->lock, flags); - } - if (!C_CLOCAL(tty)) { - /* Enable CD check */ - port->IER |= IER_CD; - mcor1 |= MCOR1_CDZD; - mcor2 |= MCOR2_CDOD; - } - - if (C_CREAD(tty)) - /* Enable receiver */ - port->IER |= IER_RXD; - - /* Set input FIFO size (1-8 bytes) */ - cor3 |= sx_rxfifo; - /* Setting up CD186x channel registers */ - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_COR1, cor1); - sx_out(bp, CD186x_COR2, port->COR2); - sx_out(bp, CD186x_COR3, cor3); - spin_unlock_irqrestore(&bp->lock, flags); - /* Make CD186x know about registers change */ - sx_wait_CCR(bp); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3); - /* Setting up modem option registers */ - dprintk(SX_DEBUG_TERMIOS, "Mcor1 = %02x, mcor2 = %02x.\n", - mcor1, mcor2); - sx_out(bp, CD186x_MCOR1, mcor1); - sx_out(bp, CD186x_MCOR2, mcor2); - spin_unlock_irqrestore(&bp->lock, flags); - /* Enable CD186x transmitter & receiver */ - sx_wait_CCR(bp); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN); - /* Enable interrupts */ - sx_out(bp, CD186x_IER, port->IER); - /* And finally set the modem lines... */ - sx_out(bp, CD186x_MSVR, port->MSVR); - spin_unlock_irqrestore(&bp->lock, flags); - - func_exit(); -} - - -/* Must be called with interrupts enabled */ -static int sx_setup_port(struct specialix_board *bp, - struct specialix_port *port) -{ - unsigned long flags; - - func_enter(); - - if (port->port.flags & ASYNC_INITIALIZED) { - func_exit(); - return 0; - } - - if (!port->xmit_buf) { - /* We may sleep in get_zeroed_page() */ - unsigned long tmp; - - tmp = get_zeroed_page(GFP_KERNEL); - if (tmp == 0L) { - func_exit(); - return -ENOMEM; - } - - if (port->xmit_buf) { - free_page(tmp); - func_exit(); - return -ERESTARTSYS; - } - port->xmit_buf = (unsigned char *) tmp; - } - - spin_lock_irqsave(&port->lock, flags); - - if (port->port.tty) - clear_bit(TTY_IO_ERROR, &port->port.tty->flags); - - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - sx_change_speed(bp, port); - port->port.flags |= ASYNC_INITIALIZED; - - spin_unlock_irqrestore(&port->lock, flags); - - - func_exit(); - return 0; -} - - -/* Must be called with interrupts disabled */ -static void sx_shutdown_port(struct specialix_board *bp, - struct specialix_port *port) -{ - struct tty_struct *tty; - int i; - unsigned long flags; - - func_enter(); - - if (!(port->port.flags & ASYNC_INITIALIZED)) { - func_exit(); - return; - } - - if (sx_debug & SX_DEBUG_FIFO) { - dprintk(SX_DEBUG_FIFO, - "sx%d: port %d: %ld overruns, FIFO hits [ ", - board_No(bp), port_No(port), port->overrun); - for (i = 0; i < 10; i++) - dprintk(SX_DEBUG_FIFO, "%ld ", port->hits[i]); - dprintk(SX_DEBUG_FIFO, "].\n"); - } - - if (port->xmit_buf) { - free_page((unsigned long) port->xmit_buf); - port->xmit_buf = NULL; - } - - /* Select port */ - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CAR, port_No(port)); - - tty = port->port.tty; - if (tty == NULL || C_HUPCL(tty)) { - /* Drop DTR */ - sx_out(bp, CD186x_MSVDTR, 0); - } - spin_unlock_irqrestore(&bp->lock, flags); - /* Reset port */ - sx_wait_CCR(bp); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CCR, CCR_SOFTRESET); - /* Disable all interrupts from this port */ - port->IER = 0; - sx_out(bp, CD186x_IER, port->IER); - spin_unlock_irqrestore(&bp->lock, flags); - if (tty) - set_bit(TTY_IO_ERROR, &tty->flags); - port->port.flags &= ~ASYNC_INITIALIZED; - - if (!bp->count) - sx_shutdown_board(bp); - func_exit(); -} - - -static int block_til_ready(struct tty_struct *tty, struct file *filp, - struct specialix_port *port) -{ - DECLARE_WAITQUEUE(wait, current); - struct specialix_board *bp = port_Board(port); - int retval; - int do_clocal = 0; - int CD; - unsigned long flags; - - func_enter(); - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) { - interruptible_sleep_on(&port->port.close_wait); - if (port->port.flags & ASYNC_HUP_NOTIFY) { - func_exit(); - return -EAGAIN; - } else { - func_exit(); - return -ERESTARTSYS; - } - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - port->port.flags |= ASYNC_NORMAL_ACTIVE; - func_exit(); - return 0; - } - - if (C_CLOCAL(tty)) - do_clocal = 1; - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, info->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&port->port.open_wait, &wait); - spin_lock_irqsave(&port->lock, flags); - if (!tty_hung_up_p(filp)) - port->port.count--; - spin_unlock_irqrestore(&port->lock, flags); - port->port.blocked_open++; - while (1) { - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CAR, port_No(port)); - CD = sx_in(bp, CD186x_MSVR) & MSVR_CD; - if (sx_crtscts(tty)) { - /* Activate RTS */ - port->MSVR |= MSVR_DTR; /* WTF? */ - sx_out(bp, CD186x_MSVR, port->MSVR); - } else { - /* Activate DTR */ - port->MSVR |= MSVR_DTR; - sx_out(bp, CD186x_MSVR, port->MSVR); - } - spin_unlock_irqrestore(&bp->lock, flags); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(port->port.flags & ASYNC_INITIALIZED)) { - if (port->port.flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; - break; - } - if (!(port->port.flags & ASYNC_CLOSING) && - (do_clocal || CD)) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } - tty_unlock(); - schedule(); - tty_lock(); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&port->port.open_wait, &wait); - spin_lock_irqsave(&port->lock, flags); - if (!tty_hung_up_p(filp)) - port->port.count++; - port->port.blocked_open--; - spin_unlock_irqrestore(&port->lock, flags); - if (retval) { - func_exit(); - return retval; - } - - port->port.flags |= ASYNC_NORMAL_ACTIVE; - func_exit(); - return 0; -} - - -static int sx_open(struct tty_struct *tty, struct file *filp) -{ - int board; - int error; - struct specialix_port *port; - struct specialix_board *bp; - int i; - unsigned long flags; - - func_enter(); - - board = SX_BOARD(tty->index); - - if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT)) { - func_exit(); - return -ENODEV; - } - - bp = &sx_board[board]; - port = sx_port + board * SX_NPORT + SX_PORT(tty->index); - port->overrun = 0; - for (i = 0; i < 10; i++) - port->hits[i] = 0; - - dprintk(SX_DEBUG_OPEN, - "Board = %d, bp = %p, port = %p, portno = %d.\n", - board, bp, port, SX_PORT(tty->index)); - - if (sx_paranoia_check(port, tty->name, "sx_open")) { - func_exit(); - return -ENODEV; - } - - error = sx_setup_board(bp); - if (error) { - func_exit(); - return error; - } - - spin_lock_irqsave(&bp->lock, flags); - port->port.count++; - bp->count++; - tty->driver_data = port; - port->port.tty = tty; - spin_unlock_irqrestore(&bp->lock, flags); - - error = sx_setup_port(bp, port); - if (error) { - func_exit(); - return error; - } - - error = block_til_ready(tty, filp, port); - if (error) { - func_exit(); - return error; - } - - func_exit(); - return 0; -} - -static void sx_flush_buffer(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - unsigned long flags; - struct specialix_board *bp; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_flush_buffer")) { - func_exit(); - return; - } - - bp = port_Board(port); - spin_lock_irqsave(&port->lock, flags); - port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; - spin_unlock_irqrestore(&port->lock, flags); - tty_wakeup(tty); - - func_exit(); -} - -static void sx_close(struct tty_struct *tty, struct file *filp) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned long flags; - unsigned long timeout; - - func_enter(); - if (!port || sx_paranoia_check(port, tty->name, "close")) { - func_exit(); - return; - } - spin_lock_irqsave(&port->lock, flags); - - if (tty_hung_up_p(filp)) { - spin_unlock_irqrestore(&port->lock, flags); - func_exit(); - return; - } - - bp = port_Board(port); - if (tty->count == 1 && port->port.count != 1) { - printk(KERN_ERR "sx%d: sx_close: bad port count;" - " tty->count is 1, port count is %d\n", - board_No(bp), port->port.count); - port->port.count = 1; - } - - if (port->port.count > 1) { - port->port.count--; - bp->count--; - - spin_unlock_irqrestore(&port->lock, flags); - - func_exit(); - return; - } - port->port.flags |= ASYNC_CLOSING; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - spin_unlock_irqrestore(&port->lock, flags); - dprintk(SX_DEBUG_OPEN, "Closing\n"); - if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, port->port.closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - dprintk(SX_DEBUG_OPEN, "Closed\n"); - port->IER &= ~IER_RXD; - if (port->port.flags & ASYNC_INITIALIZED) { - port->IER &= ~IER_TXRDY; - port->IER |= IER_TXEMPTY; - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CAR, port_No(port)); - sx_out(bp, CD186x_IER, port->IER); - spin_unlock_irqrestore(&bp->lock, flags); - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - timeout = jiffies+HZ; - while (port->IER & IER_TXEMPTY) { - set_current_state(TASK_INTERRUPTIBLE); - msleep_interruptible(jiffies_to_msecs(port->timeout)); - if (time_after(jiffies, timeout)) { - printk(KERN_INFO "Timeout waiting for close\n"); - break; - } - } - - } - - if (--bp->count < 0) { - printk(KERN_ERR - "sx%d: sx_shutdown_port: bad board count: %d port: %d\n", - board_No(bp), bp->count, tty->index); - bp->count = 0; - } - if (--port->port.count < 0) { - printk(KERN_ERR - "sx%d: sx_close: bad port count for tty%d: %d\n", - board_No(bp), port_No(port), port->port.count); - port->port.count = 0; - } - - sx_shutdown_port(bp, port); - sx_flush_buffer(tty); - tty_ldisc_flush(tty); - spin_lock_irqsave(&port->lock, flags); - tty->closing = 0; - port->port.tty = NULL; - spin_unlock_irqrestore(&port->lock, flags); - if (port->port.blocked_open) { - if (port->port.close_delay) - msleep_interruptible( - jiffies_to_msecs(port->port.close_delay)); - wake_up_interruptible(&port->port.open_wait); - } - port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&port->port.close_wait); - - func_exit(); -} - - -static int sx_write(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - int c, total = 0; - unsigned long flags; - - func_enter(); - if (sx_paranoia_check(port, tty->name, "sx_write")) { - func_exit(); - return 0; - } - - bp = port_Board(port); - - if (!port->xmit_buf) { - func_exit(); - return 0; - } - - while (1) { - spin_lock_irqsave(&port->lock, flags); - c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, - SERIAL_XMIT_SIZE - port->xmit_head)); - if (c <= 0) { - spin_unlock_irqrestore(&port->lock, flags); - break; - } - memcpy(port->xmit_buf + port->xmit_head, buf, c); - port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - port->xmit_cnt += c; - spin_unlock_irqrestore(&port->lock, flags); - - buf += c; - count -= c; - total += c; - } - - spin_lock_irqsave(&bp->lock, flags); - if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && - !(port->IER & IER_TXRDY)) { - port->IER |= IER_TXRDY; - sx_out(bp, CD186x_CAR, port_No(port)); - sx_out(bp, CD186x_IER, port->IER); - } - spin_unlock_irqrestore(&bp->lock, flags); - func_exit(); - - return total; -} - - -static int sx_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct specialix_port *port = tty->driver_data; - unsigned long flags; - struct specialix_board *bp; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_put_char")) { - func_exit(); - return 0; - } - dprintk(SX_DEBUG_TX, "check tty: %p %p\n", tty, port->xmit_buf); - if (!port->xmit_buf) { - func_exit(); - return 0; - } - bp = port_Board(port); - spin_lock_irqsave(&port->lock, flags); - - dprintk(SX_DEBUG_TX, "xmit_cnt: %d xmit_buf: %p\n", - port->xmit_cnt, port->xmit_buf); - if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1 || !port->xmit_buf) { - spin_unlock_irqrestore(&port->lock, flags); - dprintk(SX_DEBUG_TX, "Exit size\n"); - func_exit(); - return 0; - } - dprintk(SX_DEBUG_TX, "Handle xmit: %p %p\n", port, port->xmit_buf); - port->xmit_buf[port->xmit_head++] = ch; - port->xmit_head &= SERIAL_XMIT_SIZE - 1; - port->xmit_cnt++; - spin_unlock_irqrestore(&port->lock, flags); - - func_exit(); - return 1; -} - - -static void sx_flush_chars(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - unsigned long flags; - struct specialix_board *bp = port_Board(port); - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_flush_chars")) { - func_exit(); - return; - } - if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || - !port->xmit_buf) { - func_exit(); - return; - } - spin_lock_irqsave(&bp->lock, flags); - port->IER |= IER_TXRDY; - sx_out(port_Board(port), CD186x_CAR, port_No(port)); - sx_out(port_Board(port), CD186x_IER, port->IER); - spin_unlock_irqrestore(&bp->lock, flags); - - func_exit(); -} - - -static int sx_write_room(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - int ret; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_write_room")) { - func_exit(); - return 0; - } - - ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1; - if (ret < 0) - ret = 0; - - func_exit(); - return ret; -} - - -static int sx_chars_in_buffer(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) { - func_exit(); - return 0; - } - func_exit(); - return port->xmit_cnt; -} - -static int sx_tiocmget(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned char status; - unsigned int result; - unsigned long flags; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, __func__)) { - func_exit(); - return -ENODEV; - } - - bp = port_Board(port); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CAR, port_No(port)); - status = sx_in(bp, CD186x_MSVR); - spin_unlock_irqrestore(&bp->lock, flags); - dprintk(SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n", - port_No(port), status, sx_in(bp, CD186x_CAR)); - dprintk(SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port); - if (sx_crtscts(port->port.tty)) { - result = TIOCM_DTR | TIOCM_DSR - | ((status & MSVR_DTR) ? TIOCM_RTS : 0) - | ((status & MSVR_CD) ? TIOCM_CAR : 0) - | ((status & MSVR_CTS) ? TIOCM_CTS : 0); - } else { - result = TIOCM_RTS | TIOCM_DSR - | ((status & MSVR_DTR) ? TIOCM_DTR : 0) - | ((status & MSVR_CD) ? TIOCM_CAR : 0) - | ((status & MSVR_CTS) ? TIOCM_CTS : 0); - } - - func_exit(); - - return result; -} - - -static int sx_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct specialix_port *port = tty->driver_data; - unsigned long flags; - struct specialix_board *bp; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, __func__)) { - func_exit(); - return -ENODEV; - } - - bp = port_Board(port); - - spin_lock_irqsave(&port->lock, flags); - if (sx_crtscts(port->port.tty)) { - if (set & TIOCM_RTS) - port->MSVR |= MSVR_DTR; - } else { - if (set & TIOCM_DTR) - port->MSVR |= MSVR_DTR; - } - if (sx_crtscts(port->port.tty)) { - if (clear & TIOCM_RTS) - port->MSVR &= ~MSVR_DTR; - } else { - if (clear & TIOCM_DTR) - port->MSVR &= ~MSVR_DTR; - } - spin_lock(&bp->lock); - sx_out(bp, CD186x_CAR, port_No(port)); - sx_out(bp, CD186x_MSVR, port->MSVR); - spin_unlock(&bp->lock); - spin_unlock_irqrestore(&port->lock, flags); - func_exit(); - return 0; -} - - -static int sx_send_break(struct tty_struct *tty, int length) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp = port_Board(port); - unsigned long flags; - - func_enter(); - if (length == 0 || length == -1) - return -EOPNOTSUPP; - - spin_lock_irqsave(&port->lock, flags); - port->break_length = SPECIALIX_TPS / HZ * length; - port->COR2 |= COR2_ETC; - port->IER |= IER_TXRDY; - spin_lock(&bp->lock); - sx_out(bp, CD186x_CAR, port_No(port)); - sx_out(bp, CD186x_COR2, port->COR2); - sx_out(bp, CD186x_IER, port->IER); - spin_unlock(&bp->lock); - spin_unlock_irqrestore(&port->lock, flags); - sx_wait_CCR(bp); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CCR, CCR_CORCHG2); - spin_unlock_irqrestore(&bp->lock, flags); - sx_wait_CCR(bp); - - func_exit(); - return 0; -} - - -static int sx_set_serial_info(struct specialix_port *port, - struct serial_struct __user *newinfo) -{ - struct serial_struct tmp; - struct specialix_board *bp = port_Board(port); - int change_speed; - - func_enter(); - - if (copy_from_user(&tmp, newinfo, sizeof(tmp))) { - func_exit(); - return -EFAULT; - } - - mutex_lock(&port->port.mutex); - change_speed = ((port->port.flags & ASYNC_SPD_MASK) != - (tmp.flags & ASYNC_SPD_MASK)); - change_speed |= (tmp.custom_divisor != port->custom_divisor); - - if (!capable(CAP_SYS_ADMIN)) { - if ((tmp.close_delay != port->port.close_delay) || - (tmp.closing_wait != port->port.closing_wait) || - ((tmp.flags & ~ASYNC_USR_MASK) != - (port->port.flags & ~ASYNC_USR_MASK))) { - func_exit(); - mutex_unlock(&port->port.mutex); - return -EPERM; - } - port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) | - (tmp.flags & ASYNC_USR_MASK)); - port->custom_divisor = tmp.custom_divisor; - } else { - port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) | - (tmp.flags & ASYNC_FLAGS)); - port->port.close_delay = tmp.close_delay; - port->port.closing_wait = tmp.closing_wait; - port->custom_divisor = tmp.custom_divisor; - } - if (change_speed) - sx_change_speed(bp, port); - - func_exit(); - mutex_unlock(&port->port.mutex); - return 0; -} - - -static int sx_get_serial_info(struct specialix_port *port, - struct serial_struct __user *retinfo) -{ - struct serial_struct tmp; - struct specialix_board *bp = port_Board(port); - - func_enter(); - - memset(&tmp, 0, sizeof(tmp)); - mutex_lock(&port->port.mutex); - tmp.type = PORT_CIRRUS; - tmp.line = port - sx_port; - tmp.port = bp->base; - tmp.irq = bp->irq; - tmp.flags = port->port.flags; - tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC; - tmp.close_delay = port->port.close_delay * HZ/100; - tmp.closing_wait = port->port.closing_wait * HZ/100; - tmp.custom_divisor = port->custom_divisor; - tmp.xmit_fifo_size = CD186x_NFIFO; - mutex_unlock(&port->port.mutex); - if (copy_to_user(retinfo, &tmp, sizeof(tmp))) { - func_exit(); - return -EFAULT; - } - - func_exit(); - return 0; -} - - -static int sx_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg) -{ - struct specialix_port *port = tty->driver_data; - void __user *argp = (void __user *)arg; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_ioctl")) { - func_exit(); - return -ENODEV; - } - - switch (cmd) { - case TIOCGSERIAL: - func_exit(); - return sx_get_serial_info(port, argp); - case TIOCSSERIAL: - func_exit(); - return sx_set_serial_info(port, argp); - default: - func_exit(); - return -ENOIOCTLCMD; - } - func_exit(); - return 0; -} - - -static void sx_throttle(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned long flags; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_throttle")) { - func_exit(); - return; - } - - bp = port_Board(port); - - /* Use DTR instead of RTS ! */ - if (sx_crtscts(tty)) - port->MSVR &= ~MSVR_DTR; - else { - /* Auch!!! I think the system shouldn't call this then. */ - /* Or maybe we're supposed (allowed?) to do our side of hw - handshake anyway, even when hardware handshake is off. - When you see this in your logs, please report.... */ - printk(KERN_ERR - "sx%d: Need to throttle, but can't (hardware hs is off)\n", - port_No(port)); - } - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CAR, port_No(port)); - spin_unlock_irqrestore(&bp->lock, flags); - if (I_IXOFF(tty)) { - sx_wait_CCR(bp); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CCR, CCR_SSCH2); - spin_unlock_irqrestore(&bp->lock, flags); - sx_wait_CCR(bp); - } - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_MSVR, port->MSVR); - spin_unlock_irqrestore(&bp->lock, flags); - - func_exit(); -} - - -static void sx_unthrottle(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned long flags; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) { - func_exit(); - return; - } - - bp = port_Board(port); - - spin_lock_irqsave(&port->lock, flags); - /* XXXX Use DTR INSTEAD???? */ - if (sx_crtscts(tty)) - port->MSVR |= MSVR_DTR; - /* Else clause: see remark in "sx_throttle"... */ - spin_lock(&bp->lock); - sx_out(bp, CD186x_CAR, port_No(port)); - spin_unlock(&bp->lock); - if (I_IXOFF(tty)) { - spin_unlock_irqrestore(&port->lock, flags); - sx_wait_CCR(bp); - spin_lock_irqsave(&bp->lock, flags); - sx_out(bp, CD186x_CCR, CCR_SSCH1); - spin_unlock_irqrestore(&bp->lock, flags); - sx_wait_CCR(bp); - spin_lock_irqsave(&port->lock, flags); - } - spin_lock(&bp->lock); - sx_out(bp, CD186x_MSVR, port->MSVR); - spin_unlock(&bp->lock); - spin_unlock_irqrestore(&port->lock, flags); - - func_exit(); -} - - -static void sx_stop(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned long flags; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_stop")) { - func_exit(); - return; - } - - bp = port_Board(port); - - spin_lock_irqsave(&port->lock, flags); - port->IER &= ~IER_TXRDY; - spin_lock(&bp->lock); - sx_out(bp, CD186x_CAR, port_No(port)); - sx_out(bp, CD186x_IER, port->IER); - spin_unlock(&bp->lock); - spin_unlock_irqrestore(&port->lock, flags); - - func_exit(); -} - - -static void sx_start(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned long flags; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_start")) { - func_exit(); - return; - } - - bp = port_Board(port); - - spin_lock_irqsave(&port->lock, flags); - if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { - port->IER |= IER_TXRDY; - spin_lock(&bp->lock); - sx_out(bp, CD186x_CAR, port_No(port)); - sx_out(bp, CD186x_IER, port->IER); - spin_unlock(&bp->lock); - } - spin_unlock_irqrestore(&port->lock, flags); - - func_exit(); -} - -static void sx_hangup(struct tty_struct *tty) -{ - struct specialix_port *port = tty->driver_data; - struct specialix_board *bp; - unsigned long flags; - - func_enter(); - - if (sx_paranoia_check(port, tty->name, "sx_hangup")) { - func_exit(); - return; - } - - bp = port_Board(port); - - sx_shutdown_port(bp, port); - spin_lock_irqsave(&port->lock, flags); - bp->count -= port->port.count; - if (bp->count < 0) { - printk(KERN_ERR - "sx%d: sx_hangup: bad board count: %d port: %d\n", - board_No(bp), bp->count, tty->index); - bp->count = 0; - } - port->port.count = 0; - port->port.flags &= ~ASYNC_NORMAL_ACTIVE; - port->port.tty = NULL; - spin_unlock_irqrestore(&port->lock, flags); - wake_up_interruptible(&port->port.open_wait); - - func_exit(); -} - - -static void sx_set_termios(struct tty_struct *tty, - struct ktermios *old_termios) -{ - struct specialix_port *port = tty->driver_data; - unsigned long flags; - struct specialix_board *bp; - - if (sx_paranoia_check(port, tty->name, "sx_set_termios")) - return; - - bp = port_Board(port); - spin_lock_irqsave(&port->lock, flags); - sx_change_speed(port_Board(port), port); - spin_unlock_irqrestore(&port->lock, flags); - - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - sx_start(tty); - } -} - -static const struct tty_operations sx_ops = { - .open = sx_open, - .close = sx_close, - .write = sx_write, - .put_char = sx_put_char, - .flush_chars = sx_flush_chars, - .write_room = sx_write_room, - .chars_in_buffer = sx_chars_in_buffer, - .flush_buffer = sx_flush_buffer, - .ioctl = sx_ioctl, - .throttle = sx_throttle, - .unthrottle = sx_unthrottle, - .set_termios = sx_set_termios, - .stop = sx_stop, - .start = sx_start, - .hangup = sx_hangup, - .tiocmget = sx_tiocmget, - .tiocmset = sx_tiocmset, - .break_ctl = sx_send_break, -}; - -static int sx_init_drivers(void) -{ - int error; - int i; - - func_enter(); - - specialix_driver = alloc_tty_driver(SX_NBOARD * SX_NPORT); - if (!specialix_driver) { - printk(KERN_ERR "sx: Couldn't allocate tty_driver.\n"); - func_exit(); - return 1; - } - - specialix_driver->owner = THIS_MODULE; - specialix_driver->name = "ttyW"; - specialix_driver->major = SPECIALIX_NORMAL_MAJOR; - specialix_driver->type = TTY_DRIVER_TYPE_SERIAL; - specialix_driver->subtype = SERIAL_TYPE_NORMAL; - specialix_driver->init_termios = tty_std_termios; - specialix_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - specialix_driver->init_termios.c_ispeed = 9600; - specialix_driver->init_termios.c_ospeed = 9600; - specialix_driver->flags = TTY_DRIVER_REAL_RAW | - TTY_DRIVER_HARDWARE_BREAK; - tty_set_operations(specialix_driver, &sx_ops); - - error = tty_register_driver(specialix_driver); - if (error) { - put_tty_driver(specialix_driver); - printk(KERN_ERR - "sx: Couldn't register specialix IO8+ driver, error = %d\n", - error); - func_exit(); - return 1; - } - memset(sx_port, 0, sizeof(sx_port)); - for (i = 0; i < SX_NPORT * SX_NBOARD; i++) { - sx_port[i].magic = SPECIALIX_MAGIC; - tty_port_init(&sx_port[i].port); - spin_lock_init(&sx_port[i].lock); - } - - func_exit(); - return 0; -} - -static void sx_release_drivers(void) -{ - func_enter(); - - tty_unregister_driver(specialix_driver); - put_tty_driver(specialix_driver); - func_exit(); -} - -/* - * This routine must be called by kernel at boot time - */ -static int __init specialix_init(void) -{ - int i; - int found = 0; - - func_enter(); - - printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.\n"); - printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.\n"); - if (sx_rtscts) - printk(KERN_INFO - "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n"); - else - printk(KERN_INFO "sx: DTR/RTS pin is always RTS.\n"); - - for (i = 0; i < SX_NBOARD; i++) - spin_lock_init(&sx_board[i].lock); - - if (sx_init_drivers()) { - func_exit(); - return -EIO; - } - - for (i = 0; i < SX_NBOARD; i++) - if (sx_board[i].base && !sx_probe(&sx_board[i])) - found++; - -#ifdef CONFIG_PCI - { - struct pci_dev *pdev = NULL; - - i = 0; - while (i < SX_NBOARD) { - if (sx_board[i].flags & SX_BOARD_PRESENT) { - i++; - continue; - } - pdev = pci_get_device(PCI_VENDOR_ID_SPECIALIX, - PCI_DEVICE_ID_SPECIALIX_IO8, pdev); - if (!pdev) - break; - - if (pci_enable_device(pdev)) - continue; - - sx_board[i].irq = pdev->irq; - - sx_board[i].base = pci_resource_start(pdev, 2); - - sx_board[i].flags |= SX_BOARD_IS_PCI; - if (!sx_probe(&sx_board[i])) - found++; - } - /* May exit pci_get sequence early with lots of boards */ - if (pdev != NULL) - pci_dev_put(pdev); - } -#endif - - if (!found) { - sx_release_drivers(); - printk(KERN_INFO "sx: No specialix IO8+ boards detected.\n"); - func_exit(); - return -EIO; - } - - func_exit(); - return 0; -} - -static int iobase[SX_NBOARD] = {0,}; -static int irq[SX_NBOARD] = {0,}; - -module_param_array(iobase, int, NULL, 0); -module_param_array(irq, int, NULL, 0); -module_param(sx_debug, int, 0); -module_param(sx_rtscts, int, 0); -module_param(sx_rxfifo, int, 0); - -/* - * You can setup up to 4 boards. - * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter. - * You should specify the IRQs too in that case "irq=....,...". - * - * More than 4 boards in one computer is not possible, as the card can - * only use 4 different interrupts. - * - */ -static int __init specialix_init_module(void) -{ - int i; - - func_enter(); - - if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) { - for (i = 0; i < SX_NBOARD; i++) { - sx_board[i].base = iobase[i]; - sx_board[i].irq = irq[i]; - sx_board[i].count = 0; - } - } - - func_exit(); - - return specialix_init(); -} - -static void __exit specialix_exit_module(void) -{ - int i; - - func_enter(); - - sx_release_drivers(); - for (i = 0; i < SX_NBOARD; i++) - if (sx_board[i].flags & SX_BOARD_PRESENT) - sx_release_io_range(&sx_board[i]); - func_exit(); -} - -static struct pci_device_id specialx_pci_tbl[] __devinitdata __used = { - { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) }, - { } -}; -MODULE_DEVICE_TABLE(pci, specialx_pci_tbl); - -module_init(specialix_init_module); -module_exit(specialix_exit_module); - -MODULE_LICENSE("GPL"); -MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR); diff --git a/drivers/staging/tty/specialix_io8.h b/drivers/staging/tty/specialix_io8.h deleted file mode 100644 index 1215d7e2cb37..000000000000 --- a/drivers/staging/tty/specialix_io8.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * linux/drivers/char/specialix_io8.h -- - * Specialix IO8+ multiport serial driver. - * - * Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) - * Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com) - * - * - * Specialix pays for the development and support of this driver. - * Please DO contact io8-linux@specialix.co.uk if you require - * support. - * - * This driver was developed in the BitWizard linux device - * driver service. If you require a linux device driver for your - * product, please contact devices@BitWizard.nl for a quote. - * - * This code is firmly based on the riscom/8 serial driver, - * written by Dmitry Gorodchanin. The specialix IO8+ card - * programming information was obtained from the CL-CD1865 Data - * Book, and Specialix document number 6200059: IO8+ Hardware - * Functional Specification. - * - * 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 __LINUX_SPECIALIX_H -#define __LINUX_SPECIALIX_H - -#include - -#ifdef __KERNEL__ - -/* You can have max 4 ISA cards in one PC, and I recommend not much -more than a few PCI versions of the card. */ - -#define SX_NBOARD 8 - -/* NOTE: Specialix decoder recognizes 4 addresses, but only two are used.... */ -#define SX_IO_SPACE 4 -/* The PCI version decodes 8 addresses, but still only 2 are used. */ -#define SX_PCI_IO_SPACE 8 - -/* eight ports per board. */ -#define SX_NPORT 8 -#define SX_BOARD(line) ((line) / SX_NPORT) -#define SX_PORT(line) ((line) & (SX_NPORT - 1)) - - -#define SX_DATA_REG 0 /* Base+0 : Data register */ -#define SX_ADDR_REG 1 /* base+1 : Address register. */ - -#define MHz *1000000 /* I'm ashamed of myself. */ - -/* On-board oscillator frequency */ -#define SX_OSCFREQ (25 MHz/2) -/* There is a 25MHz crystal on the board, but the chip is in /2 mode */ - - -/* Ticks per sec. Used for setting receiver timeout and break length */ -#define SPECIALIX_TPS 4000 - -/* Yeah, after heavy testing I decided it must be 6. - * Sure, You can change it if needed. - */ -#define SPECIALIX_RXFIFO 6 /* Max. receiver FIFO size (1-8) */ - -#define SPECIALIX_MAGIC 0x0907 - -#define SX_CCR_TIMEOUT 10000 /* CCR timeout. You may need to wait up to - 10 milliseconds before the internal - processor is available again after - you give it a command */ - -#define SX_IOBASE1 0x100 -#define SX_IOBASE2 0x180 -#define SX_IOBASE3 0x250 -#define SX_IOBASE4 0x260 - -struct specialix_board { - unsigned long flags; - unsigned short base; - unsigned char irq; - //signed char count; - int count; - unsigned char DTR; - int reg; - spinlock_t lock; -}; - -#define SX_BOARD_PRESENT 0x00000001 -#define SX_BOARD_ACTIVE 0x00000002 -#define SX_BOARD_IS_PCI 0x00000004 - - -struct specialix_port { - int magic; - struct tty_port port; - int baud_base; - int flags; - int timeout; - unsigned char * xmit_buf; - int custom_divisor; - int xmit_head; - int xmit_tail; - int xmit_cnt; - short wakeup_chars; - short break_length; - unsigned char mark_mask; - unsigned char IER; - unsigned char MSVR; - unsigned char COR2; - unsigned long overrun; - unsigned long hits[10]; - spinlock_t lock; -}; - -#endif /* __KERNEL__ */ -#endif /* __LINUX_SPECIALIX_H */ - - - - - - - - - diff --git a/drivers/staging/tty/stallion.c b/drivers/staging/tty/stallion.c deleted file mode 100644 index 4fff5cd3b163..000000000000 --- a/drivers/staging/tty/stallion.c +++ /dev/null @@ -1,4651 +0,0 @@ -/*****************************************************************************/ - -/* - * stallion.c -- stallion multiport serial driver. - * - * Copyright (C) 1996-1999 Stallion Technologies - * Copyright (C) 1994-1996 Greg Ungerer. - * - * This code is loosely based on the Linux serial driver, written by - * Linus Torvalds, Theodore T'so and others. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -/*****************************************************************************/ - -/* - * Define different board types. Use the standard Stallion "assigned" - * board numbers. Boards supported in this driver are abbreviated as - * EIO = EasyIO and ECH = EasyConnection 8/32. - */ -#define BRD_EASYIO 20 -#define BRD_ECH 21 -#define BRD_ECHMC 22 -#define BRD_ECHPCI 26 -#define BRD_ECH64PCI 27 -#define BRD_EASYIOPCI 28 - -struct stlconf { - unsigned int brdtype; - int ioaddr1; - int ioaddr2; - unsigned long memaddr; - int irq; - int irqtype; -}; - -static unsigned int stl_nrbrds; - -/*****************************************************************************/ - -/* - * Define some important driver characteristics. Device major numbers - * allocated as per Linux Device Registry. - */ -#ifndef STL_SIOMEMMAJOR -#define STL_SIOMEMMAJOR 28 -#endif -#ifndef STL_SERIALMAJOR -#define STL_SERIALMAJOR 24 -#endif -#ifndef STL_CALLOUTMAJOR -#define STL_CALLOUTMAJOR 25 -#endif - -/* - * Set the TX buffer size. Bigger is better, but we don't want - * to chew too much memory with buffers! - */ -#define STL_TXBUFLOW 512 -#define STL_TXBUFSIZE 4096 - -/*****************************************************************************/ - -/* - * Define our local driver identity first. Set up stuff to deal with - * all the local structures required by a serial tty driver. - */ -static char *stl_drvtitle = "Stallion Multiport Serial Driver"; -static char *stl_drvname = "stallion"; -static char *stl_drvversion = "5.6.0"; - -static struct tty_driver *stl_serial; - -/* - * Define a local default termios struct. All ports will be created - * with this termios initially. Basically all it defines is a raw port - * at 9600, 8 data bits, 1 stop bit. - */ -static struct ktermios stl_deftermios = { - .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), - .c_cc = INIT_C_CC, - .c_ispeed = 9600, - .c_ospeed = 9600, -}; - -/* - * Define global place to put buffer overflow characters. - */ -static char stl_unwanted[SC26198_RXFIFOSIZE]; - -/*****************************************************************************/ - -static DEFINE_MUTEX(stl_brdslock); -static struct stlbrd *stl_brds[STL_MAXBRDS]; - -static const struct tty_port_operations stl_port_ops; - -/* - * Per board state flags. Used with the state field of the board struct. - * Not really much here! - */ -#define BRD_FOUND 0x1 -#define STL_PROBED 0x2 - - -/* - * Define the port structure istate flags. These set of flags are - * modified at interrupt time - so setting and reseting them needs - * to be atomic. Use the bit clear/setting routines for this. - */ -#define ASYI_TXBUSY 1 -#define ASYI_TXLOW 2 -#define ASYI_TXFLOWED 3 - -/* - * Define an array of board names as printable strings. Handy for - * referencing boards when printing trace and stuff. - */ -static char *stl_brdnames[] = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "EasyIO", - "EC8/32-AT", - "EC8/32-MC", - NULL, - NULL, - NULL, - "EC8/32-PCI", - "EC8/64-PCI", - "EasyIO-PCI", -}; - -/*****************************************************************************/ - -/* - * Define some string labels for arguments passed from the module - * load line. These allow for easy board definitions, and easy - * modification of the io, memory and irq resoucres. - */ -static unsigned int stl_nargs; -static char *board0[4]; -static char *board1[4]; -static char *board2[4]; -static char *board3[4]; - -static char **stl_brdsp[] = { - (char **) &board0, - (char **) &board1, - (char **) &board2, - (char **) &board3 -}; - -/* - * Define a set of common board names, and types. This is used to - * parse any module arguments. - */ - -static struct { - char *name; - int type; -} stl_brdstr[] = { - { "easyio", BRD_EASYIO }, - { "eio", BRD_EASYIO }, - { "20", BRD_EASYIO }, - { "ec8/32", BRD_ECH }, - { "ec8/32-at", BRD_ECH }, - { "ec8/32-isa", BRD_ECH }, - { "ech", BRD_ECH }, - { "echat", BRD_ECH }, - { "21", BRD_ECH }, - { "ec8/32-mc", BRD_ECHMC }, - { "ec8/32-mca", BRD_ECHMC }, - { "echmc", BRD_ECHMC }, - { "echmca", BRD_ECHMC }, - { "22", BRD_ECHMC }, - { "ec8/32-pc", BRD_ECHPCI }, - { "ec8/32-pci", BRD_ECHPCI }, - { "26", BRD_ECHPCI }, - { "ec8/64-pc", BRD_ECH64PCI }, - { "ec8/64-pci", BRD_ECH64PCI }, - { "ech-pci", BRD_ECH64PCI }, - { "echpci", BRD_ECH64PCI }, - { "echpc", BRD_ECH64PCI }, - { "27", BRD_ECH64PCI }, - { "easyio-pc", BRD_EASYIOPCI }, - { "easyio-pci", BRD_EASYIOPCI }, - { "eio-pci", BRD_EASYIOPCI }, - { "eiopci", BRD_EASYIOPCI }, - { "28", BRD_EASYIOPCI }, -}; - -/* - * Define the module agruments. - */ - -module_param_array(board0, charp, &stl_nargs, 0); -MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,ioaddr2][,irq]]"); -module_param_array(board1, charp, &stl_nargs, 0); -MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,ioaddr2][,irq]]"); -module_param_array(board2, charp, &stl_nargs, 0); -MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,ioaddr2][,irq]]"); -module_param_array(board3, charp, &stl_nargs, 0); -MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,ioaddr2][,irq]]"); - -/*****************************************************************************/ - -/* - * Hardware ID bits for the EasyIO and ECH boards. These defines apply - * to the directly accessible io ports of these boards (not the uarts - - * they are in cd1400.h and sc26198.h). - */ -#define EIO_8PORTRS 0x04 -#define EIO_4PORTRS 0x05 -#define EIO_8PORTDI 0x00 -#define EIO_8PORTM 0x06 -#define EIO_MK3 0x03 -#define EIO_IDBITMASK 0x07 - -#define EIO_BRDMASK 0xf0 -#define ID_BRD4 0x10 -#define ID_BRD8 0x20 -#define ID_BRD16 0x30 - -#define EIO_INTRPEND 0x08 -#define EIO_INTEDGE 0x00 -#define EIO_INTLEVEL 0x08 -#define EIO_0WS 0x10 - -#define ECH_ID 0xa0 -#define ECH_IDBITMASK 0xe0 -#define ECH_BRDENABLE 0x08 -#define ECH_BRDDISABLE 0x00 -#define ECH_INTENABLE 0x01 -#define ECH_INTDISABLE 0x00 -#define ECH_INTLEVEL 0x02 -#define ECH_INTEDGE 0x00 -#define ECH_INTRPEND 0x01 -#define ECH_BRDRESET 0x01 - -#define ECHMC_INTENABLE 0x01 -#define ECHMC_BRDRESET 0x02 - -#define ECH_PNLSTATUS 2 -#define ECH_PNL16PORT 0x20 -#define ECH_PNLIDMASK 0x07 -#define ECH_PNLXPID 0x40 -#define ECH_PNLINTRPEND 0x80 - -#define ECH_ADDR2MASK 0x1e0 - -/* - * Define the vector mapping bits for the programmable interrupt board - * hardware. These bits encode the interrupt for the board to use - it - * is software selectable (except the EIO-8M). - */ -static unsigned char stl_vecmap[] = { - 0xff, 0xff, 0xff, 0x04, 0x06, 0x05, 0xff, 0x07, - 0xff, 0xff, 0x00, 0x02, 0x01, 0xff, 0xff, 0x03 -}; - -/* - * Lock ordering is that you may not take stallion_lock holding - * brd_lock. - */ - -static spinlock_t brd_lock; /* Guard the board mapping */ -static spinlock_t stallion_lock; /* Guard the tty driver */ - -/* - * Set up enable and disable macros for the ECH boards. They require - * the secondary io address space to be activated and deactivated. - * This way all ECH boards can share their secondary io region. - * If this is an ECH-PCI board then also need to set the page pointer - * to point to the correct page. - */ -#define BRDENABLE(brdnr,pagenr) \ - if (stl_brds[(brdnr)]->brdtype == BRD_ECH) \ - outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDENABLE), \ - stl_brds[(brdnr)]->ioctrl); \ - else if (stl_brds[(brdnr)]->brdtype == BRD_ECHPCI) \ - outb((pagenr), stl_brds[(brdnr)]->ioctrl); - -#define BRDDISABLE(brdnr) \ - if (stl_brds[(brdnr)]->brdtype == BRD_ECH) \ - outb((stl_brds[(brdnr)]->ioctrlval | ECH_BRDDISABLE), \ - stl_brds[(brdnr)]->ioctrl); - -#define STL_CD1400MAXBAUD 230400 -#define STL_SC26198MAXBAUD 460800 - -#define STL_BAUDBASE 115200 -#define STL_CLOSEDELAY (5 * HZ / 10) - -/*****************************************************************************/ - -/* - * Define the Stallion PCI vendor and device IDs. - */ -#ifndef PCI_VENDOR_ID_STALLION -#define PCI_VENDOR_ID_STALLION 0x124d -#endif -#ifndef PCI_DEVICE_ID_ECHPCI832 -#define PCI_DEVICE_ID_ECHPCI832 0x0000 -#endif -#ifndef PCI_DEVICE_ID_ECHPCI864 -#define PCI_DEVICE_ID_ECHPCI864 0x0002 -#endif -#ifndef PCI_DEVICE_ID_EIOPCI -#define PCI_DEVICE_ID_EIOPCI 0x0003 -#endif - -/* - * Define structure to hold all Stallion PCI boards. - */ - -static struct pci_device_id stl_pcibrds[] = { - { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI864), - .driver_data = BRD_ECH64PCI }, - { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_EIOPCI), - .driver_data = BRD_EASYIOPCI }, - { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI832), - .driver_data = BRD_ECHPCI }, - { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410), - .driver_data = BRD_ECHPCI }, - { } -}; -MODULE_DEVICE_TABLE(pci, stl_pcibrds); - -/*****************************************************************************/ - -/* - * Define macros to extract a brd/port number from a minor number. - */ -#define MINOR2BRD(min) (((min) & 0xc0) >> 6) -#define MINOR2PORT(min) ((min) & 0x3f) - -/* - * Define a baud rate table that converts termios baud rate selector - * into the actual baud rate value. All baud rate calculations are - * based on the actual baud rate required. - */ -static unsigned int stl_baudrates[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, - 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 -}; - -/*****************************************************************************/ - -/* - * Declare all those functions in this driver! - */ - -static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg); -static int stl_brdinit(struct stlbrd *brdp); -static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp); -static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); - -/* - * CD1400 uart specific handling functions. - */ -static void stl_cd1400setreg(struct stlport *portp, int regnr, int value); -static int stl_cd1400getreg(struct stlport *portp, int regnr); -static int stl_cd1400updatereg(struct stlport *portp, int regnr, int value); -static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *panelp); -static void stl_cd1400portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp); -static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp); -static int stl_cd1400getsignals(struct stlport *portp); -static void stl_cd1400setsignals(struct stlport *portp, int dtr, int rts); -static void stl_cd1400ccrwait(struct stlport *portp); -static void stl_cd1400enablerxtx(struct stlport *portp, int rx, int tx); -static void stl_cd1400startrxtx(struct stlport *portp, int rx, int tx); -static void stl_cd1400disableintrs(struct stlport *portp); -static void stl_cd1400sendbreak(struct stlport *portp, int len); -static void stl_cd1400flowctrl(struct stlport *portp, int state); -static void stl_cd1400sendflow(struct stlport *portp, int state); -static void stl_cd1400flush(struct stlport *portp); -static int stl_cd1400datastate(struct stlport *portp); -static void stl_cd1400eiointr(struct stlpanel *panelp, unsigned int iobase); -static void stl_cd1400echintr(struct stlpanel *panelp, unsigned int iobase); -static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr); -static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr); -static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr); - -static inline int stl_cd1400breakisr(struct stlport *portp, int ioaddr); - -/* - * SC26198 uart specific handling functions. - */ -static void stl_sc26198setreg(struct stlport *portp, int regnr, int value); -static int stl_sc26198getreg(struct stlport *portp, int regnr); -static int stl_sc26198updatereg(struct stlport *portp, int regnr, int value); -static int stl_sc26198getglobreg(struct stlport *portp, int regnr); -static int stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *panelp); -static void stl_sc26198portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp); -static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp); -static int stl_sc26198getsignals(struct stlport *portp); -static void stl_sc26198setsignals(struct stlport *portp, int dtr, int rts); -static void stl_sc26198enablerxtx(struct stlport *portp, int rx, int tx); -static void stl_sc26198startrxtx(struct stlport *portp, int rx, int tx); -static void stl_sc26198disableintrs(struct stlport *portp); -static void stl_sc26198sendbreak(struct stlport *portp, int len); -static void stl_sc26198flowctrl(struct stlport *portp, int state); -static void stl_sc26198sendflow(struct stlport *portp, int state); -static void stl_sc26198flush(struct stlport *portp); -static int stl_sc26198datastate(struct stlport *portp); -static void stl_sc26198wait(struct stlport *portp); -static void stl_sc26198txunflow(struct stlport *portp, struct tty_struct *tty); -static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase); -static void stl_sc26198txisr(struct stlport *port); -static void stl_sc26198rxisr(struct stlport *port, unsigned int iack); -static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char ch); -static void stl_sc26198rxbadchars(struct stlport *portp); -static void stl_sc26198otherisr(struct stlport *port, unsigned int iack); - -/*****************************************************************************/ - -/* - * Generic UART support structure. - */ -typedef struct uart { - int (*panelinit)(struct stlbrd *brdp, struct stlpanel *panelp); - void (*portinit)(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp); - void (*setport)(struct stlport *portp, struct ktermios *tiosp); - int (*getsignals)(struct stlport *portp); - void (*setsignals)(struct stlport *portp, int dtr, int rts); - void (*enablerxtx)(struct stlport *portp, int rx, int tx); - void (*startrxtx)(struct stlport *portp, int rx, int tx); - void (*disableintrs)(struct stlport *portp); - void (*sendbreak)(struct stlport *portp, int len); - void (*flowctrl)(struct stlport *portp, int state); - void (*sendflow)(struct stlport *portp, int state); - void (*flush)(struct stlport *portp); - int (*datastate)(struct stlport *portp); - void (*intr)(struct stlpanel *panelp, unsigned int iobase); -} uart_t; - -/* - * Define some macros to make calling these functions nice and clean. - */ -#define stl_panelinit (* ((uart_t *) panelp->uartp)->panelinit) -#define stl_portinit (* ((uart_t *) portp->uartp)->portinit) -#define stl_setport (* ((uart_t *) portp->uartp)->setport) -#define stl_getsignals (* ((uart_t *) portp->uartp)->getsignals) -#define stl_setsignals (* ((uart_t *) portp->uartp)->setsignals) -#define stl_enablerxtx (* ((uart_t *) portp->uartp)->enablerxtx) -#define stl_startrxtx (* ((uart_t *) portp->uartp)->startrxtx) -#define stl_disableintrs (* ((uart_t *) portp->uartp)->disableintrs) -#define stl_sendbreak (* ((uart_t *) portp->uartp)->sendbreak) -#define stl_flowctrl (* ((uart_t *) portp->uartp)->flowctrl) -#define stl_sendflow (* ((uart_t *) portp->uartp)->sendflow) -#define stl_flush (* ((uart_t *) portp->uartp)->flush) -#define stl_datastate (* ((uart_t *) portp->uartp)->datastate) - -/*****************************************************************************/ - -/* - * CD1400 UART specific data initialization. - */ -static uart_t stl_cd1400uart = { - stl_cd1400panelinit, - stl_cd1400portinit, - stl_cd1400setport, - stl_cd1400getsignals, - stl_cd1400setsignals, - stl_cd1400enablerxtx, - stl_cd1400startrxtx, - stl_cd1400disableintrs, - stl_cd1400sendbreak, - stl_cd1400flowctrl, - stl_cd1400sendflow, - stl_cd1400flush, - stl_cd1400datastate, - stl_cd1400eiointr -}; - -/* - * Define the offsets within the register bank of a cd1400 based panel. - * These io address offsets are common to the EasyIO board as well. - */ -#define EREG_ADDR 0 -#define EREG_DATA 4 -#define EREG_RXACK 5 -#define EREG_TXACK 6 -#define EREG_MDACK 7 - -#define EREG_BANKSIZE 8 - -#define CD1400_CLK 25000000 -#define CD1400_CLK8M 20000000 - -/* - * Define the cd1400 baud rate clocks. These are used when calculating - * what clock and divisor to use for the required baud rate. Also - * define the maximum baud rate allowed, and the default base baud. - */ -static int stl_cd1400clkdivs[] = { - CD1400_CLK0, CD1400_CLK1, CD1400_CLK2, CD1400_CLK3, CD1400_CLK4 -}; - -/*****************************************************************************/ - -/* - * SC26198 UART specific data initization. - */ -static uart_t stl_sc26198uart = { - stl_sc26198panelinit, - stl_sc26198portinit, - stl_sc26198setport, - stl_sc26198getsignals, - stl_sc26198setsignals, - stl_sc26198enablerxtx, - stl_sc26198startrxtx, - stl_sc26198disableintrs, - stl_sc26198sendbreak, - stl_sc26198flowctrl, - stl_sc26198sendflow, - stl_sc26198flush, - stl_sc26198datastate, - stl_sc26198intr -}; - -/* - * Define the offsets within the register bank of a sc26198 based panel. - */ -#define XP_DATA 0 -#define XP_ADDR 1 -#define XP_MODID 2 -#define XP_STATUS 2 -#define XP_IACK 3 - -#define XP_BANKSIZE 4 - -/* - * Define the sc26198 baud rate table. Offsets within the table - * represent the actual baud rate selector of sc26198 registers. - */ -static unsigned int sc26198_baudtable[] = { - 50, 75, 150, 200, 300, 450, 600, 900, 1200, 1800, 2400, 3600, - 4800, 7200, 9600, 14400, 19200, 28800, 38400, 57600, 115200, - 230400, 460800, 921600 -}; - -#define SC26198_NRBAUDS ARRAY_SIZE(sc26198_baudtable) - -/*****************************************************************************/ - -/* - * Define the driver info for a user level control device. Used mainly - * to get at port stats - only not using the port device itself. - */ -static const struct file_operations stl_fsiomem = { - .owner = THIS_MODULE, - .unlocked_ioctl = stl_memioctl, - .llseek = noop_llseek, -}; - -static struct class *stallion_class; - -static void stl_cd_change(struct stlport *portp) -{ - unsigned int oldsigs = portp->sigs; - struct tty_struct *tty = tty_port_tty_get(&portp->port); - - if (!tty) - return; - - portp->sigs = stl_getsignals(portp); - - if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0)) - wake_up_interruptible(&portp->port.open_wait); - - if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) - if (portp->port.flags & ASYNC_CHECK_CD) - tty_hangup(tty); - tty_kref_put(tty); -} - -/* - * Check for any arguments passed in on the module load command line. - */ - -/*****************************************************************************/ - -/* - * Parse the supplied argument string, into the board conf struct. - */ - -static int __init stl_parsebrd(struct stlconf *confp, char **argp) -{ - char *sp; - unsigned int i; - - pr_debug("stl_parsebrd(confp=%p,argp=%p)\n", confp, argp); - - if ((argp[0] == NULL) || (*argp[0] == 0)) - return 0; - - for (sp = argp[0], i = 0; (*sp != 0) && (i < 25); sp++, i++) - *sp = tolower(*sp); - - for (i = 0; i < ARRAY_SIZE(stl_brdstr); i++) - if (strcmp(stl_brdstr[i].name, argp[0]) == 0) - break; - - if (i == ARRAY_SIZE(stl_brdstr)) { - printk("STALLION: unknown board name, %s?\n", argp[0]); - return 0; - } - - confp->brdtype = stl_brdstr[i].type; - - i = 1; - if ((argp[i] != NULL) && (*argp[i] != 0)) - confp->ioaddr1 = simple_strtoul(argp[i], NULL, 0); - i++; - if (confp->brdtype == BRD_ECH) { - if ((argp[i] != NULL) && (*argp[i] != 0)) - confp->ioaddr2 = simple_strtoul(argp[i], NULL, 0); - i++; - } - if ((argp[i] != NULL) && (*argp[i] != 0)) - confp->irq = simple_strtoul(argp[i], NULL, 0); - return 1; -} - -/*****************************************************************************/ - -/* - * Allocate a new board structure. Fill out the basic info in it. - */ - -static struct stlbrd *stl_allocbrd(void) -{ - struct stlbrd *brdp; - - brdp = kzalloc(sizeof(struct stlbrd), GFP_KERNEL); - if (!brdp) { - printk("STALLION: failed to allocate memory (size=%Zd)\n", - sizeof(struct stlbrd)); - return NULL; - } - - brdp->magic = STL_BOARDMAGIC; - return brdp; -} - -/*****************************************************************************/ - -static int stl_activate(struct tty_port *port, struct tty_struct *tty) -{ - struct stlport *portp = container_of(port, struct stlport, port); - if (!portp->tx.buf) { - portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); - if (!portp->tx.buf) - return -ENOMEM; - portp->tx.head = portp->tx.buf; - portp->tx.tail = portp->tx.buf; - } - stl_setport(portp, tty->termios); - portp->sigs = stl_getsignals(portp); - stl_setsignals(portp, 1, 1); - stl_enablerxtx(portp, 1, 1); - stl_startrxtx(portp, 1, 0); - return 0; -} - -static int stl_open(struct tty_struct *tty, struct file *filp) -{ - struct stlport *portp; - struct stlbrd *brdp; - unsigned int minordev, brdnr, panelnr; - int portnr; - - pr_debug("stl_open(tty=%p,filp=%p): device=%s\n", tty, filp, tty->name); - - minordev = tty->index; - brdnr = MINOR2BRD(minordev); - if (brdnr >= stl_nrbrds) - return -ENODEV; - brdp = stl_brds[brdnr]; - if (brdp == NULL) - return -ENODEV; - - minordev = MINOR2PORT(minordev); - for (portnr = -1, panelnr = 0; panelnr < STL_MAXPANELS; panelnr++) { - if (brdp->panels[panelnr] == NULL) - break; - if (minordev < brdp->panels[panelnr]->nrports) { - portnr = minordev; - break; - } - minordev -= brdp->panels[panelnr]->nrports; - } - if (portnr < 0) - return -ENODEV; - - portp = brdp->panels[panelnr]->ports[portnr]; - if (portp == NULL) - return -ENODEV; - - tty->driver_data = portp; - return tty_port_open(&portp->port, tty, filp); - -} - -/*****************************************************************************/ - -static int stl_carrier_raised(struct tty_port *port) -{ - struct stlport *portp = container_of(port, struct stlport, port); - return (portp->sigs & TIOCM_CD) ? 1 : 0; -} - -static void stl_dtr_rts(struct tty_port *port, int on) -{ - struct stlport *portp = container_of(port, struct stlport, port); - /* Takes brd_lock internally */ - stl_setsignals(portp, on, on); -} - -/*****************************************************************************/ - -static void stl_flushbuffer(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_flushbuffer(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return; - - stl_flush(portp); - tty_wakeup(tty); -} - -/*****************************************************************************/ - -static void stl_waituntilsent(struct tty_struct *tty, int timeout) -{ - struct stlport *portp; - unsigned long tend; - - pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout); - - portp = tty->driver_data; - if (portp == NULL) - return; - - if (timeout == 0) - timeout = HZ; - tend = jiffies + timeout; - - while (stl_datastate(portp)) { - if (signal_pending(current)) - break; - msleep_interruptible(20); - if (time_after_eq(jiffies, tend)) - break; - } -} - -/*****************************************************************************/ - -static void stl_shutdown(struct tty_port *port) -{ - struct stlport *portp = container_of(port, struct stlport, port); - stl_disableintrs(portp); - stl_enablerxtx(portp, 0, 0); - stl_flush(portp); - portp->istate = 0; - if (portp->tx.buf != NULL) { - kfree(portp->tx.buf); - portp->tx.buf = NULL; - portp->tx.head = NULL; - portp->tx.tail = NULL; - } -} - -static void stl_close(struct tty_struct *tty, struct file *filp) -{ - struct stlport*portp; - pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); - - portp = tty->driver_data; - if(portp == NULL) - return; - tty_port_close(&portp->port, tty, filp); -} - -/*****************************************************************************/ - -/* - * Write routine. Take data and stuff it in to the TX ring queue. - * If transmit interrupts are not running then start them. - */ - -static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count) -{ - struct stlport *portp; - unsigned int len, stlen; - unsigned char *chbuf; - char *head, *tail; - - pr_debug("stl_write(tty=%p,buf=%p,count=%d)\n", tty, buf, count); - - portp = tty->driver_data; - if (portp == NULL) - return 0; - if (portp->tx.buf == NULL) - return 0; - -/* - * If copying direct from user space we must cater for page faults, - * causing us to "sleep" here for a while. To handle this copy in all - * the data we need now, into a local buffer. Then when we got it all - * copy it into the TX buffer. - */ - chbuf = (unsigned char *) buf; - - head = portp->tx.head; - tail = portp->tx.tail; - if (head >= tail) { - len = STL_TXBUFSIZE - (head - tail) - 1; - stlen = STL_TXBUFSIZE - (head - portp->tx.buf); - } else { - len = tail - head - 1; - stlen = len; - } - - len = min(len, (unsigned int)count); - count = 0; - while (len > 0) { - stlen = min(len, stlen); - memcpy(head, chbuf, stlen); - len -= stlen; - chbuf += stlen; - count += stlen; - head += stlen; - if (head >= (portp->tx.buf + STL_TXBUFSIZE)) { - head = portp->tx.buf; - stlen = tail - head; - } - } - portp->tx.head = head; - - clear_bit(ASYI_TXLOW, &portp->istate); - stl_startrxtx(portp, -1, 1); - - return count; -} - -/*****************************************************************************/ - -static int stl_putchar(struct tty_struct *tty, unsigned char ch) -{ - struct stlport *portp; - unsigned int len; - char *head, *tail; - - pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch); - - portp = tty->driver_data; - if (portp == NULL) - return -EINVAL; - if (portp->tx.buf == NULL) - return -EINVAL; - - head = portp->tx.head; - tail = portp->tx.tail; - - len = (head >= tail) ? (STL_TXBUFSIZE - (head - tail)) : (tail - head); - len--; - - if (len > 0) { - *head++ = ch; - if (head >= (portp->tx.buf + STL_TXBUFSIZE)) - head = portp->tx.buf; - } - portp->tx.head = head; - return 0; -} - -/*****************************************************************************/ - -/* - * If there are any characters in the buffer then make sure that TX - * interrupts are on and get'em out. Normally used after the putchar - * routine has been called. - */ - -static void stl_flushchars(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_flushchars(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return; - if (portp->tx.buf == NULL) - return; - - stl_startrxtx(portp, -1, 1); -} - -/*****************************************************************************/ - -static int stl_writeroom(struct tty_struct *tty) -{ - struct stlport *portp; - char *head, *tail; - - pr_debug("stl_writeroom(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return 0; - if (portp->tx.buf == NULL) - return 0; - - head = portp->tx.head; - tail = portp->tx.tail; - return (head >= tail) ? (STL_TXBUFSIZE - (head - tail) - 1) : (tail - head - 1); -} - -/*****************************************************************************/ - -/* - * Return number of chars in the TX buffer. Normally we would just - * calculate the number of chars in the buffer and return that, but if - * the buffer is empty and TX interrupts are still on then we return - * that the buffer still has 1 char in it. This way whoever called us - * will not think that ALL chars have drained - since the UART still - * must have some chars in it (we are busy after all). - */ - -static int stl_charsinbuffer(struct tty_struct *tty) -{ - struct stlport *portp; - unsigned int size; - char *head, *tail; - - pr_debug("stl_charsinbuffer(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return 0; - if (portp->tx.buf == NULL) - return 0; - - head = portp->tx.head; - tail = portp->tx.tail; - size = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head)); - if ((size == 0) && test_bit(ASYI_TXBUSY, &portp->istate)) - size = 1; - return size; -} - -/*****************************************************************************/ - -/* - * Generate the serial struct info. - */ - -static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) -{ - struct serial_struct sio; - struct stlbrd *brdp; - - pr_debug("stl_getserial(portp=%p,sp=%p)\n", portp, sp); - - memset(&sio, 0, sizeof(struct serial_struct)); - - mutex_lock(&portp->port.mutex); - sio.line = portp->portnr; - sio.port = portp->ioaddr; - sio.flags = portp->port.flags; - sio.baud_base = portp->baud_base; - sio.close_delay = portp->close_delay; - sio.closing_wait = portp->closing_wait; - sio.custom_divisor = portp->custom_divisor; - sio.hub6 = 0; - if (portp->uartp == &stl_cd1400uart) { - sio.type = PORT_CIRRUS; - sio.xmit_fifo_size = CD1400_TXFIFOSIZE; - } else { - sio.type = PORT_UNKNOWN; - sio.xmit_fifo_size = SC26198_TXFIFOSIZE; - } - - brdp = stl_brds[portp->brdnr]; - if (brdp != NULL) - sio.irq = brdp->irq; - mutex_unlock(&portp->port.mutex); - - return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Set port according to the serial struct info. - * At this point we do not do any auto-configure stuff, so we will - * just quietly ignore any requests to change irq, etc. - */ - -static int stl_setserial(struct tty_struct *tty, struct serial_struct __user *sp) -{ - struct stlport * portp = tty->driver_data; - struct serial_struct sio; - - pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp); - - if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) - return -EFAULT; - mutex_lock(&portp->port.mutex); - if (!capable(CAP_SYS_ADMIN)) { - if ((sio.baud_base != portp->baud_base) || - (sio.close_delay != portp->close_delay) || - ((sio.flags & ~ASYNC_USR_MASK) != - (portp->port.flags & ~ASYNC_USR_MASK))) { - mutex_unlock(&portp->port.mutex); - return -EPERM; - } - } - - portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) | - (sio.flags & ASYNC_USR_MASK); - portp->baud_base = sio.baud_base; - portp->close_delay = sio.close_delay; - portp->closing_wait = sio.closing_wait; - portp->custom_divisor = sio.custom_divisor; - mutex_unlock(&portp->port.mutex); - stl_setport(portp, tty->termios); - return 0; -} - -/*****************************************************************************/ - -static int stl_tiocmget(struct tty_struct *tty) -{ - struct stlport *portp; - - portp = tty->driver_data; - if (portp == NULL) - return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - return stl_getsignals(portp); -} - -static int stl_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear) -{ - struct stlport *portp; - int rts = -1, dtr = -1; - - portp = tty->driver_data; - if (portp == NULL) - return -ENODEV; - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - if (set & TIOCM_RTS) - rts = 1; - if (set & TIOCM_DTR) - dtr = 1; - if (clear & TIOCM_RTS) - rts = 0; - if (clear & TIOCM_DTR) - dtr = 0; - - stl_setsignals(portp, dtr, rts); - return 0; -} - -static int stl_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) -{ - struct stlport *portp; - int rc; - void __user *argp = (void __user *)arg; - - pr_debug("stl_ioctl(tty=%p,cmd=%x,arg=%lx)\n", tty, cmd, arg); - - portp = tty->driver_data; - if (portp == NULL) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - - rc = 0; - - switch (cmd) { - case TIOCGSERIAL: - rc = stl_getserial(portp, argp); - break; - case TIOCSSERIAL: - rc = stl_setserial(tty, argp); - break; - case COM_GETPORTSTATS: - rc = stl_getportstats(tty, portp, argp); - break; - case COM_CLRPORTSTATS: - rc = stl_clrportstats(portp, argp); - break; - case TIOCSERCONFIG: - case TIOCSERGWILD: - case TIOCSERSWILD: - case TIOCSERGETLSR: - case TIOCSERGSTRUCT: - case TIOCSERGETMULTI: - case TIOCSERSETMULTI: - default: - rc = -ENOIOCTLCMD; - break; - } - return rc; -} - -/*****************************************************************************/ - -/* - * Start the transmitter again. Just turn TX interrupts back on. - */ - -static void stl_start(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_start(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return; - stl_startrxtx(portp, -1, 1); -} - -/*****************************************************************************/ - -static void stl_settermios(struct tty_struct *tty, struct ktermios *old) -{ - struct stlport *portp; - struct ktermios *tiosp; - - pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old); - - portp = tty->driver_data; - if (portp == NULL) - return; - - tiosp = tty->termios; - if ((tiosp->c_cflag == old->c_cflag) && - (tiosp->c_iflag == old->c_iflag)) - return; - - stl_setport(portp, tiosp); - stl_setsignals(portp, ((tiosp->c_cflag & (CBAUD & ~CBAUDEX)) ? 1 : 0), - -1); - if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0)) { - tty->hw_stopped = 0; - stl_start(tty); - } - if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL)) - wake_up_interruptible(&portp->port.open_wait); -} - -/*****************************************************************************/ - -/* - * Attempt to flow control who ever is sending us data. Based on termios - * settings use software or/and hardware flow control. - */ - -static void stl_throttle(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_throttle(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return; - stl_flowctrl(portp, 0); -} - -/*****************************************************************************/ - -/* - * Unflow control the device sending us data... - */ - -static void stl_unthrottle(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_unthrottle(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return; - stl_flowctrl(portp, 1); -} - -/*****************************************************************************/ - -/* - * Stop the transmitter. Basically to do this we will just turn TX - * interrupts off. - */ - -static void stl_stop(struct tty_struct *tty) -{ - struct stlport *portp; - - pr_debug("stl_stop(tty=%p)\n", tty); - - portp = tty->driver_data; - if (portp == NULL) - return; - stl_startrxtx(portp, -1, 0); -} - -/*****************************************************************************/ - -/* - * Hangup this port. This is pretty much like closing the port, only - * a little more brutal. No waiting for data to drain. Shutdown the - * port and maybe drop signals. - */ - -static void stl_hangup(struct tty_struct *tty) -{ - struct stlport *portp = tty->driver_data; - pr_debug("stl_hangup(tty=%p)\n", tty); - - if (portp == NULL) - return; - tty_port_hangup(&portp->port); -} - -/*****************************************************************************/ - -static int stl_breakctl(struct tty_struct *tty, int state) -{ - struct stlport *portp; - - pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state); - - portp = tty->driver_data; - if (portp == NULL) - return -EINVAL; - - stl_sendbreak(portp, ((state == -1) ? 1 : 2)); - return 0; -} - -/*****************************************************************************/ - -static void stl_sendxchar(struct tty_struct *tty, char ch) -{ - struct stlport *portp; - - pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch); - - portp = tty->driver_data; - if (portp == NULL) - return; - - if (ch == STOP_CHAR(tty)) - stl_sendflow(portp, 0); - else if (ch == START_CHAR(tty)) - stl_sendflow(portp, 1); - else - stl_putchar(tty, ch); -} - -static void stl_portinfo(struct seq_file *m, struct stlport *portp, int portnr) -{ - int sigs; - char sep; - - seq_printf(m, "%d: uart:%s tx:%d rx:%d", - portnr, (portp->hwid == 1) ? "SC26198" : "CD1400", - (int) portp->stats.txtotal, (int) portp->stats.rxtotal); - - if (portp->stats.rxframing) - seq_printf(m, " fe:%d", (int) portp->stats.rxframing); - if (portp->stats.rxparity) - seq_printf(m, " pe:%d", (int) portp->stats.rxparity); - if (portp->stats.rxbreaks) - seq_printf(m, " brk:%d", (int) portp->stats.rxbreaks); - if (portp->stats.rxoverrun) - seq_printf(m, " oe:%d", (int) portp->stats.rxoverrun); - - sigs = stl_getsignals(portp); - sep = ' '; - if (sigs & TIOCM_RTS) { - seq_printf(m, "%c%s", sep, "RTS"); - sep = '|'; - } - if (sigs & TIOCM_CTS) { - seq_printf(m, "%c%s", sep, "CTS"); - sep = '|'; - } - if (sigs & TIOCM_DTR) { - seq_printf(m, "%c%s", sep, "DTR"); - sep = '|'; - } - if (sigs & TIOCM_CD) { - seq_printf(m, "%c%s", sep, "DCD"); - sep = '|'; - } - if (sigs & TIOCM_DSR) { - seq_printf(m, "%c%s", sep, "DSR"); - sep = '|'; - } - seq_putc(m, '\n'); -} - -/*****************************************************************************/ - -/* - * Port info, read from the /proc file system. - */ - -static int stl_proc_show(struct seq_file *m, void *v) -{ - struct stlbrd *brdp; - struct stlpanel *panelp; - struct stlport *portp; - unsigned int brdnr, panelnr, portnr; - int totalport; - - totalport = 0; - - seq_printf(m, "%s: version %s\n", stl_drvtitle, stl_drvversion); - -/* - * We scan through for each board, panel and port. The offset is - * calculated on the fly, and irrelevant ports are skipped. - */ - for (brdnr = 0; brdnr < stl_nrbrds; brdnr++) { - brdp = stl_brds[brdnr]; - if (brdp == NULL) - continue; - if (brdp->state == 0) - continue; - - totalport = brdnr * STL_MAXPORTS; - for (panelnr = 0; panelnr < brdp->nrpanels; panelnr++) { - panelp = brdp->panels[panelnr]; - if (panelp == NULL) - continue; - - for (portnr = 0; portnr < panelp->nrports; portnr++, - totalport++) { - portp = panelp->ports[portnr]; - if (portp == NULL) - continue; - stl_portinfo(m, portp, totalport); - } - } - } - return 0; -} - -static int stl_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, stl_proc_show, NULL); -} - -static const struct file_operations stl_proc_fops = { - .owner = THIS_MODULE, - .open = stl_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/*****************************************************************************/ - -/* - * All board interrupts are vectored through here first. This code then - * calls off to the approrpriate board interrupt handlers. - */ - -static irqreturn_t stl_intr(int irq, void *dev_id) -{ - struct stlbrd *brdp = dev_id; - - pr_debug("stl_intr(brdp=%p,irq=%d)\n", brdp, brdp->irq); - - return IRQ_RETVAL((* brdp->isr)(brdp)); -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for EasyIO board types. - */ - -static int stl_eiointr(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int iobase; - int handled = 0; - - spin_lock(&brd_lock); - panelp = brdp->panels[0]; - iobase = panelp->iobase; - while (inb(brdp->iostatus) & EIO_INTRPEND) { - handled = 1; - (* panelp->isr)(panelp, iobase); - } - spin_unlock(&brd_lock); - return handled; -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for ECH-AT board types. - */ - -static int stl_echatintr(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int ioaddr, bnknr; - int handled = 0; - - outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl); - - while (inb(brdp->iostatus) & ECH_INTRPEND) { - handled = 1; - for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { - ioaddr = brdp->bnkstataddr[bnknr]; - if (inb(ioaddr) & ECH_PNLINTRPEND) { - panelp = brdp->bnk2panel[bnknr]; - (* panelp->isr)(panelp, (ioaddr & 0xfffc)); - } - } - } - - outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl); - - return handled; -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for ECH-MCA board types. - */ - -static int stl_echmcaintr(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int ioaddr, bnknr; - int handled = 0; - - while (inb(brdp->iostatus) & ECH_INTRPEND) { - handled = 1; - for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { - ioaddr = brdp->bnkstataddr[bnknr]; - if (inb(ioaddr) & ECH_PNLINTRPEND) { - panelp = brdp->bnk2panel[bnknr]; - (* panelp->isr)(panelp, (ioaddr & 0xfffc)); - } - } - } - return handled; -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for ECH-PCI board types. - */ - -static int stl_echpciintr(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int ioaddr, bnknr, recheck; - int handled = 0; - - while (1) { - recheck = 0; - for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { - outb(brdp->bnkpageaddr[bnknr], brdp->ioctrl); - ioaddr = brdp->bnkstataddr[bnknr]; - if (inb(ioaddr) & ECH_PNLINTRPEND) { - panelp = brdp->bnk2panel[bnknr]; - (* panelp->isr)(panelp, (ioaddr & 0xfffc)); - recheck++; - handled = 1; - } - } - if (! recheck) - break; - } - return handled; -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for ECH-8/64-PCI board types. - */ - -static int stl_echpci64intr(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int ioaddr, bnknr; - int handled = 0; - - while (inb(brdp->ioctrl) & 0x1) { - handled = 1; - for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { - ioaddr = brdp->bnkstataddr[bnknr]; - if (inb(ioaddr) & ECH_PNLINTRPEND) { - panelp = brdp->bnk2panel[bnknr]; - (* panelp->isr)(panelp, (ioaddr & 0xfffc)); - } - } - } - - return handled; -} - -/*****************************************************************************/ - -/* - * Initialize all the ports on a panel. - */ - -static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp) -{ - struct stlport *portp; - unsigned int i; - int chipmask; - - pr_debug("stl_initports(brdp=%p,panelp=%p)\n", brdp, panelp); - - chipmask = stl_panelinit(brdp, panelp); - -/* - * All UART's are initialized (if found!). Now go through and setup - * each ports data structures. - */ - for (i = 0; i < panelp->nrports; i++) { - portp = kzalloc(sizeof(struct stlport), GFP_KERNEL); - if (!portp) { - printk("STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(struct stlport)); - break; - } - tty_port_init(&portp->port); - portp->port.ops = &stl_port_ops; - portp->magic = STL_PORTMAGIC; - portp->portnr = i; - portp->brdnr = panelp->brdnr; - portp->panelnr = panelp->panelnr; - portp->uartp = panelp->uartp; - portp->clk = brdp->clk; - portp->baud_base = STL_BAUDBASE; - portp->close_delay = STL_CLOSEDELAY; - portp->closing_wait = 30 * HZ; - init_waitqueue_head(&portp->port.open_wait); - init_waitqueue_head(&portp->port.close_wait); - portp->stats.brd = portp->brdnr; - portp->stats.panel = portp->panelnr; - portp->stats.port = portp->portnr; - panelp->ports[i] = portp; - stl_portinit(brdp, panelp, portp); - } - - return 0; -} - -static void stl_cleanup_panels(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - struct stlport *portp; - unsigned int j, k; - struct tty_struct *tty; - - for (j = 0; j < STL_MAXPANELS; j++) { - panelp = brdp->panels[j]; - if (panelp == NULL) - continue; - for (k = 0; k < STL_PORTSPERPANEL; k++) { - portp = panelp->ports[k]; - if (portp == NULL) - continue; - tty = tty_port_tty_get(&portp->port); - if (tty != NULL) { - stl_hangup(tty); - tty_kref_put(tty); - } - kfree(portp->tx.buf); - kfree(portp); - } - kfree(panelp); - } -} - -/*****************************************************************************/ - -/* - * Try to find and initialize an EasyIO board. - */ - -static int __devinit stl_initeio(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int status; - char *name; - int retval; - - pr_debug("stl_initeio(brdp=%p)\n", brdp); - - brdp->ioctrl = brdp->ioaddr1 + 1; - brdp->iostatus = brdp->ioaddr1 + 2; - - status = inb(brdp->iostatus); - if ((status & EIO_IDBITMASK) == EIO_MK3) - brdp->ioctrl++; - -/* - * Handle board specific stuff now. The real difference is PCI - * or not PCI. - */ - if (brdp->brdtype == BRD_EASYIOPCI) { - brdp->iosize1 = 0x80; - brdp->iosize2 = 0x80; - name = "serial(EIO-PCI)"; - outb(0x41, (brdp->ioaddr2 + 0x4c)); - } else { - brdp->iosize1 = 8; - name = "serial(EIO)"; - if ((brdp->irq < 0) || (brdp->irq > 15) || - (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { - printk("STALLION: invalid irq=%d for brd=%d\n", - brdp->irq, brdp->brdnr); - retval = -EINVAL; - goto err; - } - outb((stl_vecmap[brdp->irq] | EIO_0WS | - ((brdp->irqtype) ? EIO_INTLEVEL : EIO_INTEDGE)), - brdp->ioctrl); - } - - retval = -EBUSY; - if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) { - printk(KERN_WARNING "STALLION: Warning, board %d I/O address " - "%x conflicts with another device\n", brdp->brdnr, - brdp->ioaddr1); - goto err; - } - - if (brdp->iosize2 > 0) - if (!request_region(brdp->ioaddr2, brdp->iosize2, name)) { - printk(KERN_WARNING "STALLION: Warning, board %d I/O " - "address %x conflicts with another device\n", - brdp->brdnr, brdp->ioaddr2); - printk(KERN_WARNING "STALLION: Warning, also " - "releasing board %d I/O address %x \n", - brdp->brdnr, brdp->ioaddr1); - goto err_rel1; - } - -/* - * Everything looks OK, so let's go ahead and probe for the hardware. - */ - brdp->clk = CD1400_CLK; - brdp->isr = stl_eiointr; - - retval = -ENODEV; - switch (status & EIO_IDBITMASK) { - case EIO_8PORTM: - brdp->clk = CD1400_CLK8M; - /* fall thru */ - case EIO_8PORTRS: - case EIO_8PORTDI: - brdp->nrports = 8; - break; - case EIO_4PORTRS: - brdp->nrports = 4; - break; - case EIO_MK3: - switch (status & EIO_BRDMASK) { - case ID_BRD4: - brdp->nrports = 4; - break; - case ID_BRD8: - brdp->nrports = 8; - break; - case ID_BRD16: - brdp->nrports = 16; - break; - default: - goto err_rel2; - } - break; - default: - goto err_rel2; - } - -/* - * We have verified that the board is actually present, so now we - * can complete the setup. - */ - - panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL); - if (!panelp) { - printk(KERN_WARNING "STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(struct stlpanel)); - retval = -ENOMEM; - goto err_rel2; - } - - panelp->magic = STL_PANELMAGIC; - panelp->brdnr = brdp->brdnr; - panelp->panelnr = 0; - panelp->nrports = brdp->nrports; - panelp->iobase = brdp->ioaddr1; - panelp->hwid = status; - if ((status & EIO_IDBITMASK) == EIO_MK3) { - panelp->uartp = &stl_sc26198uart; - panelp->isr = stl_sc26198intr; - } else { - panelp->uartp = &stl_cd1400uart; - panelp->isr = stl_cd1400eiointr; - } - - brdp->panels[0] = panelp; - brdp->nrpanels = 1; - brdp->state |= BRD_FOUND; - brdp->hwid = status; - if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) { - printk("STALLION: failed to register interrupt " - "routine for %s irq=%d\n", name, brdp->irq); - retval = -ENODEV; - goto err_fr; - } - - return 0; -err_fr: - stl_cleanup_panels(brdp); -err_rel2: - if (brdp->iosize2 > 0) - release_region(brdp->ioaddr2, brdp->iosize2); -err_rel1: - release_region(brdp->ioaddr1, brdp->iosize1); -err: - return retval; -} - -/*****************************************************************************/ - -/* - * Try to find an ECH board and initialize it. This code is capable of - * dealing with all types of ECH board. - */ - -static int __devinit stl_initech(struct stlbrd *brdp) -{ - struct stlpanel *panelp; - unsigned int status, nxtid, ioaddr, conflict, panelnr, banknr, i; - int retval; - char *name; - - pr_debug("stl_initech(brdp=%p)\n", brdp); - - status = 0; - conflict = 0; - -/* - * Set up the initial board register contents for boards. This varies a - * bit between the different board types. So we need to handle each - * separately. Also do a check that the supplied IRQ is good. - */ - switch (brdp->brdtype) { - - case BRD_ECH: - brdp->isr = stl_echatintr; - brdp->ioctrl = brdp->ioaddr1 + 1; - brdp->iostatus = brdp->ioaddr1 + 1; - status = inb(brdp->iostatus); - if ((status & ECH_IDBITMASK) != ECH_ID) { - retval = -ENODEV; - goto err; - } - if ((brdp->irq < 0) || (brdp->irq > 15) || - (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { - printk("STALLION: invalid irq=%d for brd=%d\n", - brdp->irq, brdp->brdnr); - retval = -EINVAL; - goto err; - } - status = ((brdp->ioaddr2 & ECH_ADDR2MASK) >> 1); - status |= (stl_vecmap[brdp->irq] << 1); - outb((status | ECH_BRDRESET), brdp->ioaddr1); - brdp->ioctrlval = ECH_INTENABLE | - ((brdp->irqtype) ? ECH_INTLEVEL : ECH_INTEDGE); - for (i = 0; i < 10; i++) - outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl); - brdp->iosize1 = 2; - brdp->iosize2 = 32; - name = "serial(EC8/32)"; - outb(status, brdp->ioaddr1); - break; - - case BRD_ECHMC: - brdp->isr = stl_echmcaintr; - brdp->ioctrl = brdp->ioaddr1 + 0x20; - brdp->iostatus = brdp->ioctrl; - status = inb(brdp->iostatus); - if ((status & ECH_IDBITMASK) != ECH_ID) { - retval = -ENODEV; - goto err; - } - if ((brdp->irq < 0) || (brdp->irq > 15) || - (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { - printk("STALLION: invalid irq=%d for brd=%d\n", - brdp->irq, brdp->brdnr); - retval = -EINVAL; - goto err; - } - outb(ECHMC_BRDRESET, brdp->ioctrl); - outb(ECHMC_INTENABLE, brdp->ioctrl); - brdp->iosize1 = 64; - name = "serial(EC8/32-MC)"; - break; - - case BRD_ECHPCI: - brdp->isr = stl_echpciintr; - brdp->ioctrl = brdp->ioaddr1 + 2; - brdp->iosize1 = 4; - brdp->iosize2 = 8; - name = "serial(EC8/32-PCI)"; - break; - - case BRD_ECH64PCI: - brdp->isr = stl_echpci64intr; - brdp->ioctrl = brdp->ioaddr2 + 0x40; - outb(0x43, (brdp->ioaddr1 + 0x4c)); - brdp->iosize1 = 0x80; - brdp->iosize2 = 0x80; - name = "serial(EC8/64-PCI)"; - break; - - default: - printk("STALLION: unknown board type=%d\n", brdp->brdtype); - retval = -EINVAL; - goto err; - } - -/* - * Check boards for possible IO address conflicts and return fail status - * if an IO conflict found. - */ - retval = -EBUSY; - if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) { - printk(KERN_WARNING "STALLION: Warning, board %d I/O address " - "%x conflicts with another device\n", brdp->brdnr, - brdp->ioaddr1); - goto err; - } - - if (brdp->iosize2 > 0) - if (!request_region(brdp->ioaddr2, brdp->iosize2, name)) { - printk(KERN_WARNING "STALLION: Warning, board %d I/O " - "address %x conflicts with another device\n", - brdp->brdnr, brdp->ioaddr2); - printk(KERN_WARNING "STALLION: Warning, also " - "releasing board %d I/O address %x \n", - brdp->brdnr, brdp->ioaddr1); - goto err_rel1; - } - -/* - * Scan through the secondary io address space looking for panels. - * As we find'em allocate and initialize panel structures for each. - */ - brdp->clk = CD1400_CLK; - brdp->hwid = status; - - ioaddr = brdp->ioaddr2; - banknr = 0; - panelnr = 0; - nxtid = 0; - - for (i = 0; i < STL_MAXPANELS; i++) { - if (brdp->brdtype == BRD_ECHPCI) { - outb(nxtid, brdp->ioctrl); - ioaddr = brdp->ioaddr2; - } - status = inb(ioaddr + ECH_PNLSTATUS); - if ((status & ECH_PNLIDMASK) != nxtid) - break; - panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL); - if (!panelp) { - printk("STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(struct stlpanel)); - retval = -ENOMEM; - goto err_fr; - } - panelp->magic = STL_PANELMAGIC; - panelp->brdnr = brdp->brdnr; - panelp->panelnr = panelnr; - panelp->iobase = ioaddr; - panelp->pagenr = nxtid; - panelp->hwid = status; - brdp->bnk2panel[banknr] = panelp; - brdp->bnkpageaddr[banknr] = nxtid; - brdp->bnkstataddr[banknr++] = ioaddr + ECH_PNLSTATUS; - - if (status & ECH_PNLXPID) { - panelp->uartp = &stl_sc26198uart; - panelp->isr = stl_sc26198intr; - if (status & ECH_PNL16PORT) { - panelp->nrports = 16; - brdp->bnk2panel[banknr] = panelp; - brdp->bnkpageaddr[banknr] = nxtid; - brdp->bnkstataddr[banknr++] = ioaddr + 4 + - ECH_PNLSTATUS; - } else - panelp->nrports = 8; - } else { - panelp->uartp = &stl_cd1400uart; - panelp->isr = stl_cd1400echintr; - if (status & ECH_PNL16PORT) { - panelp->nrports = 16; - panelp->ackmask = 0x80; - if (brdp->brdtype != BRD_ECHPCI) - ioaddr += EREG_BANKSIZE; - brdp->bnk2panel[banknr] = panelp; - brdp->bnkpageaddr[banknr] = ++nxtid; - brdp->bnkstataddr[banknr++] = ioaddr + - ECH_PNLSTATUS; - } else { - panelp->nrports = 8; - panelp->ackmask = 0xc0; - } - } - - nxtid++; - ioaddr += EREG_BANKSIZE; - brdp->nrports += panelp->nrports; - brdp->panels[panelnr++] = panelp; - if ((brdp->brdtype != BRD_ECHPCI) && - (ioaddr >= (brdp->ioaddr2 + brdp->iosize2))) { - retval = -EINVAL; - goto err_fr; - } - } - - brdp->nrpanels = panelnr; - brdp->nrbnks = banknr; - if (brdp->brdtype == BRD_ECH) - outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl); - - brdp->state |= BRD_FOUND; - if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) { - printk("STALLION: failed to register interrupt " - "routine for %s irq=%d\n", name, brdp->irq); - retval = -ENODEV; - goto err_fr; - } - - return 0; -err_fr: - stl_cleanup_panels(brdp); - if (brdp->iosize2 > 0) - release_region(brdp->ioaddr2, brdp->iosize2); -err_rel1: - release_region(brdp->ioaddr1, brdp->iosize1); -err: - return retval; -} - -/*****************************************************************************/ - -/* - * Initialize and configure the specified board. - * Scan through all the boards in the configuration and see what we - * can find. Handle EIO and the ECH boards a little differently here - * since the initial search and setup is very different. - */ - -static int __devinit stl_brdinit(struct stlbrd *brdp) -{ - int i, retval; - - pr_debug("stl_brdinit(brdp=%p)\n", brdp); - - switch (brdp->brdtype) { - case BRD_EASYIO: - case BRD_EASYIOPCI: - retval = stl_initeio(brdp); - if (retval) - goto err; - break; - case BRD_ECH: - case BRD_ECHMC: - case BRD_ECHPCI: - case BRD_ECH64PCI: - retval = stl_initech(brdp); - if (retval) - goto err; - break; - default: - printk("STALLION: board=%d is unknown board type=%d\n", - brdp->brdnr, brdp->brdtype); - retval = -ENODEV; - goto err; - } - - if ((brdp->state & BRD_FOUND) == 0) { - printk("STALLION: %s board not found, board=%d io=%x irq=%d\n", - stl_brdnames[brdp->brdtype], brdp->brdnr, - brdp->ioaddr1, brdp->irq); - goto err_free; - } - - for (i = 0; i < STL_MAXPANELS; i++) - if (brdp->panels[i] != NULL) - stl_initports(brdp, brdp->panels[i]); - - printk("STALLION: %s found, board=%d io=%x irq=%d " - "nrpanels=%d nrports=%d\n", stl_brdnames[brdp->brdtype], - brdp->brdnr, brdp->ioaddr1, brdp->irq, brdp->nrpanels, - brdp->nrports); - - return 0; -err_free: - free_irq(brdp->irq, brdp); - - stl_cleanup_panels(brdp); - - release_region(brdp->ioaddr1, brdp->iosize1); - if (brdp->iosize2 > 0) - release_region(brdp->ioaddr2, brdp->iosize2); -err: - return retval; -} - -/*****************************************************************************/ - -/* - * Find the next available board number that is free. - */ - -static int __devinit stl_getbrdnr(void) -{ - unsigned int i; - - for (i = 0; i < STL_MAXBRDS; i++) - if (stl_brds[i] == NULL) { - if (i >= stl_nrbrds) - stl_nrbrds = i + 1; - return i; - } - - return -1; -} - -/*****************************************************************************/ -/* - * We have a Stallion board. Allocate a board structure and - * initialize it. Read its IO and IRQ resources from PCI - * configuration space. - */ - -static int __devinit stl_pciprobe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct stlbrd *brdp; - unsigned int i, brdtype = ent->driver_data; - int brdnr, retval = -ENODEV; - - if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) - goto err; - - retval = pci_enable_device(pdev); - if (retval) - goto err; - brdp = stl_allocbrd(); - if (brdp == NULL) { - retval = -ENOMEM; - goto err; - } - mutex_lock(&stl_brdslock); - brdnr = stl_getbrdnr(); - if (brdnr < 0) { - dev_err(&pdev->dev, "too many boards found, " - "maximum supported %d\n", STL_MAXBRDS); - mutex_unlock(&stl_brdslock); - retval = -ENODEV; - goto err_fr; - } - brdp->brdnr = (unsigned int)brdnr; - stl_brds[brdp->brdnr] = brdp; - mutex_unlock(&stl_brdslock); - - brdp->brdtype = brdtype; - brdp->state |= STL_PROBED; - -/* - * We have all resources from the board, so let's setup the actual - * board structure now. - */ - switch (brdtype) { - case BRD_ECHPCI: - brdp->ioaddr2 = pci_resource_start(pdev, 0); - brdp->ioaddr1 = pci_resource_start(pdev, 1); - break; - case BRD_ECH64PCI: - brdp->ioaddr2 = pci_resource_start(pdev, 2); - brdp->ioaddr1 = pci_resource_start(pdev, 1); - break; - case BRD_EASYIOPCI: - brdp->ioaddr1 = pci_resource_start(pdev, 2); - brdp->ioaddr2 = pci_resource_start(pdev, 1); - break; - default: - dev_err(&pdev->dev, "unknown PCI board type=%u\n", brdtype); - break; - } - - brdp->irq = pdev->irq; - retval = stl_brdinit(brdp); - if (retval) - goto err_null; - - pci_set_drvdata(pdev, brdp); - - for (i = 0; i < brdp->nrports; i++) - tty_register_device(stl_serial, - brdp->brdnr * STL_MAXPORTS + i, &pdev->dev); - - return 0; -err_null: - stl_brds[brdp->brdnr] = NULL; -err_fr: - kfree(brdp); -err: - return retval; -} - -static void __devexit stl_pciremove(struct pci_dev *pdev) -{ - struct stlbrd *brdp = pci_get_drvdata(pdev); - unsigned int i; - - free_irq(brdp->irq, brdp); - - stl_cleanup_panels(brdp); - - release_region(brdp->ioaddr1, brdp->iosize1); - if (brdp->iosize2 > 0) - release_region(brdp->ioaddr2, brdp->iosize2); - - for (i = 0; i < brdp->nrports; i++) - tty_unregister_device(stl_serial, - brdp->brdnr * STL_MAXPORTS + i); - - stl_brds[brdp->brdnr] = NULL; - kfree(brdp); -} - -static struct pci_driver stl_pcidriver = { - .name = "stallion", - .id_table = stl_pcibrds, - .probe = stl_pciprobe, - .remove = __devexit_p(stl_pciremove) -}; - -/*****************************************************************************/ - -/* - * Return the board stats structure to user app. - */ - -static int stl_getbrdstats(combrd_t __user *bp) -{ - combrd_t stl_brdstats; - struct stlbrd *brdp; - struct stlpanel *panelp; - unsigned int i; - - if (copy_from_user(&stl_brdstats, bp, sizeof(combrd_t))) - return -EFAULT; - if (stl_brdstats.brd >= STL_MAXBRDS) - return -ENODEV; - brdp = stl_brds[stl_brdstats.brd]; - if (brdp == NULL) - return -ENODEV; - - memset(&stl_brdstats, 0, sizeof(combrd_t)); - stl_brdstats.brd = brdp->brdnr; - stl_brdstats.type = brdp->brdtype; - stl_brdstats.hwid = brdp->hwid; - stl_brdstats.state = brdp->state; - stl_brdstats.ioaddr = brdp->ioaddr1; - stl_brdstats.ioaddr2 = brdp->ioaddr2; - stl_brdstats.irq = brdp->irq; - stl_brdstats.nrpanels = brdp->nrpanels; - stl_brdstats.nrports = brdp->nrports; - for (i = 0; i < brdp->nrpanels; i++) { - panelp = brdp->panels[i]; - stl_brdstats.panels[i].panel = i; - stl_brdstats.panels[i].hwid = panelp->hwid; - stl_brdstats.panels[i].nrports = panelp->nrports; - } - - return copy_to_user(bp, &stl_brdstats, sizeof(combrd_t)) ? -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Resolve the referenced port number into a port struct pointer. - */ - -static struct stlport *stl_getport(int brdnr, int panelnr, int portnr) -{ - struct stlbrd *brdp; - struct stlpanel *panelp; - - if (brdnr < 0 || brdnr >= STL_MAXBRDS) - return NULL; - brdp = stl_brds[brdnr]; - if (brdp == NULL) - return NULL; - if (panelnr < 0 || (unsigned int)panelnr >= brdp->nrpanels) - return NULL; - panelp = brdp->panels[panelnr]; - if (panelp == NULL) - return NULL; - if (portnr < 0 || (unsigned int)portnr >= panelp->nrports) - return NULL; - return panelp->ports[portnr]; -} - -/*****************************************************************************/ - -/* - * Return the port stats structure to user app. A NULL port struct - * pointer passed in means that we need to find out from the app - * what port to get stats for (used through board control device). - */ - -static int stl_getportstats(struct tty_struct *tty, struct stlport *portp, comstats_t __user *cp) -{ - comstats_t stl_comstats; - unsigned char *head, *tail; - unsigned long flags; - - if (!portp) { - if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t))) - return -EFAULT; - portp = stl_getport(stl_comstats.brd, stl_comstats.panel, - stl_comstats.port); - if (portp == NULL) - return -ENODEV; - } - - mutex_lock(&portp->port.mutex); - portp->stats.state = portp->istate; - portp->stats.flags = portp->port.flags; - portp->stats.hwid = portp->hwid; - - portp->stats.ttystate = 0; - portp->stats.cflags = 0; - portp->stats.iflags = 0; - portp->stats.oflags = 0; - portp->stats.lflags = 0; - portp->stats.rxbuffered = 0; - - spin_lock_irqsave(&stallion_lock, flags); - if (tty != NULL && portp->port.tty == tty) { - portp->stats.ttystate = tty->flags; - /* No longer available as a statistic */ - portp->stats.rxbuffered = 1; /*tty->flip.count; */ - if (tty->termios != NULL) { - portp->stats.cflags = tty->termios->c_cflag; - portp->stats.iflags = tty->termios->c_iflag; - portp->stats.oflags = tty->termios->c_oflag; - portp->stats.lflags = tty->termios->c_lflag; - } - } - spin_unlock_irqrestore(&stallion_lock, flags); - - head = portp->tx.head; - tail = portp->tx.tail; - portp->stats.txbuffered = (head >= tail) ? (head - tail) : - (STL_TXBUFSIZE - (tail - head)); - - portp->stats.signals = (unsigned long) stl_getsignals(portp); - mutex_unlock(&portp->port.mutex); - - return copy_to_user(cp, &portp->stats, - sizeof(comstats_t)) ? -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Clear the port stats structure. We also return it zeroed out... - */ - -static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp) -{ - comstats_t stl_comstats; - - if (!portp) { - if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t))) - return -EFAULT; - portp = stl_getport(stl_comstats.brd, stl_comstats.panel, - stl_comstats.port); - if (portp == NULL) - return -ENODEV; - } - - mutex_lock(&portp->port.mutex); - memset(&portp->stats, 0, sizeof(comstats_t)); - portp->stats.brd = portp->brdnr; - portp->stats.panel = portp->panelnr; - portp->stats.port = portp->portnr; - mutex_unlock(&portp->port.mutex); - return copy_to_user(cp, &portp->stats, - sizeof(comstats_t)) ? -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Return the entire driver ports structure to a user app. - */ - -static int stl_getportstruct(struct stlport __user *arg) -{ - struct stlport stl_dummyport; - struct stlport *portp; - - if (copy_from_user(&stl_dummyport, arg, sizeof(struct stlport))) - return -EFAULT; - portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr, - stl_dummyport.portnr); - if (!portp) - return -ENODEV; - return copy_to_user(arg, portp, sizeof(struct stlport)) ? -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * Return the entire driver board structure to a user app. - */ - -static int stl_getbrdstruct(struct stlbrd __user *arg) -{ - struct stlbrd stl_dummybrd; - struct stlbrd *brdp; - - if (copy_from_user(&stl_dummybrd, arg, sizeof(struct stlbrd))) - return -EFAULT; - if (stl_dummybrd.brdnr >= STL_MAXBRDS) - return -ENODEV; - brdp = stl_brds[stl_dummybrd.brdnr]; - if (!brdp) - return -ENODEV; - return copy_to_user(arg, brdp, sizeof(struct stlbrd)) ? -EFAULT : 0; -} - -/*****************************************************************************/ - -/* - * The "staliomem" device is also required to do some special operations - * on the board and/or ports. In this driver it is mostly used for stats - * collection. - */ - -static long stl_memioctl(struct file *fp, unsigned int cmd, unsigned long arg) -{ - int brdnr, rc; - void __user *argp = (void __user *)arg; - - pr_debug("stl_memioctl(fp=%p,cmd=%x,arg=%lx)\n", fp, cmd,arg); - - brdnr = iminor(fp->f_dentry->d_inode); - if (brdnr >= STL_MAXBRDS) - return -ENODEV; - rc = 0; - - switch (cmd) { - case COM_GETPORTSTATS: - rc = stl_getportstats(NULL, NULL, argp); - break; - case COM_CLRPORTSTATS: - rc = stl_clrportstats(NULL, argp); - break; - case COM_GETBRDSTATS: - rc = stl_getbrdstats(argp); - break; - case COM_READPORT: - rc = stl_getportstruct(argp); - break; - case COM_READBOARD: - rc = stl_getbrdstruct(argp); - break; - default: - rc = -ENOIOCTLCMD; - break; - } - return rc; -} - -static const struct tty_operations stl_ops = { - .open = stl_open, - .close = stl_close, - .write = stl_write, - .put_char = stl_putchar, - .flush_chars = stl_flushchars, - .write_room = stl_writeroom, - .chars_in_buffer = stl_charsinbuffer, - .ioctl = stl_ioctl, - .set_termios = stl_settermios, - .throttle = stl_throttle, - .unthrottle = stl_unthrottle, - .stop = stl_stop, - .start = stl_start, - .hangup = stl_hangup, - .flush_buffer = stl_flushbuffer, - .break_ctl = stl_breakctl, - .wait_until_sent = stl_waituntilsent, - .send_xchar = stl_sendxchar, - .tiocmget = stl_tiocmget, - .tiocmset = stl_tiocmset, - .proc_fops = &stl_proc_fops, -}; - -static const struct tty_port_operations stl_port_ops = { - .carrier_raised = stl_carrier_raised, - .dtr_rts = stl_dtr_rts, - .activate = stl_activate, - .shutdown = stl_shutdown, -}; - -/*****************************************************************************/ -/* CD1400 HARDWARE FUNCTIONS */ -/*****************************************************************************/ - -/* - * These functions get/set/update the registers of the cd1400 UARTs. - * Access to the cd1400 registers is via an address/data io port pair. - * (Maybe should make this inline...) - */ - -static int stl_cd1400getreg(struct stlport *portp, int regnr) -{ - outb((regnr + portp->uartaddr), portp->ioaddr); - return inb(portp->ioaddr + EREG_DATA); -} - -static void stl_cd1400setreg(struct stlport *portp, int regnr, int value) -{ - outb(regnr + portp->uartaddr, portp->ioaddr); - outb(value, portp->ioaddr + EREG_DATA); -} - -static int stl_cd1400updatereg(struct stlport *portp, int regnr, int value) -{ - outb(regnr + portp->uartaddr, portp->ioaddr); - if (inb(portp->ioaddr + EREG_DATA) != value) { - outb(value, portp->ioaddr + EREG_DATA); - return 1; - } - return 0; -} - -/*****************************************************************************/ - -/* - * Inbitialize the UARTs in a panel. We don't care what sort of board - * these ports are on - since the port io registers are almost - * identical when dealing with ports. - */ - -static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *panelp) -{ - unsigned int gfrcr; - int chipmask, i, j; - int nrchips, uartaddr, ioaddr; - unsigned long flags; - - pr_debug("stl_panelinit(brdp=%p,panelp=%p)\n", brdp, panelp); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(panelp->brdnr, panelp->pagenr); - -/* - * Check that each chip is present and started up OK. - */ - chipmask = 0; - nrchips = panelp->nrports / CD1400_PORTS; - for (i = 0; i < nrchips; i++) { - if (brdp->brdtype == BRD_ECHPCI) { - outb((panelp->pagenr + (i >> 1)), brdp->ioctrl); - ioaddr = panelp->iobase; - } else - ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 1)); - uartaddr = (i & 0x01) ? 0x080 : 0; - outb((GFRCR + uartaddr), ioaddr); - outb(0, (ioaddr + EREG_DATA)); - outb((CCR + uartaddr), ioaddr); - outb(CCR_RESETFULL, (ioaddr + EREG_DATA)); - outb(CCR_RESETFULL, (ioaddr + EREG_DATA)); - outb((GFRCR + uartaddr), ioaddr); - for (j = 0; j < CCR_MAXWAIT; j++) - if ((gfrcr = inb(ioaddr + EREG_DATA)) != 0) - break; - - if ((j >= CCR_MAXWAIT) || (gfrcr < 0x40) || (gfrcr > 0x60)) { - printk("STALLION: cd1400 not responding, " - "brd=%d panel=%d chip=%d\n", - panelp->brdnr, panelp->panelnr, i); - continue; - } - chipmask |= (0x1 << i); - outb((PPR + uartaddr), ioaddr); - outb(PPR_SCALAR, (ioaddr + EREG_DATA)); - } - - BRDDISABLE(panelp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - return chipmask; -} - -/*****************************************************************************/ - -/* - * Initialize hardware specific port registers. - */ - -static void stl_cd1400portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp) -{ - unsigned long flags; - pr_debug("stl_cd1400portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp, - panelp, portp); - - if ((brdp == NULL) || (panelp == NULL) || - (portp == NULL)) - return; - - spin_lock_irqsave(&brd_lock, flags); - portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || - (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); - portp->uartaddr = (portp->portnr & 0x04) << 5; - portp->pagenr = panelp->pagenr + (portp->portnr >> 3); - - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); - portp->hwid = stl_cd1400getreg(portp, GFRCR); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Wait for the command register to be ready. We will poll this, - * since it won't usually take too long to be ready. - */ - -static void stl_cd1400ccrwait(struct stlport *portp) -{ - int i; - - for (i = 0; i < CCR_MAXWAIT; i++) - if (stl_cd1400getreg(portp, CCR) == 0) - return; - - printk("STALLION: cd1400 not responding, port=%d panel=%d brd=%d\n", - portp->portnr, portp->panelnr, portp->brdnr); -} - -/*****************************************************************************/ - -/* - * Set up the cd1400 registers for a port based on the termios port - * settings. - */ - -static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp) -{ - struct stlbrd *brdp; - unsigned long flags; - unsigned int clkdiv, baudrate; - unsigned char cor1, cor2, cor3; - unsigned char cor4, cor5, ccr; - unsigned char srer, sreron, sreroff; - unsigned char mcor1, mcor2, rtpr; - unsigned char clk, div; - - cor1 = 0; - cor2 = 0; - cor3 = 0; - cor4 = 0; - cor5 = 0; - ccr = 0; - rtpr = 0; - clk = 0; - div = 0; - mcor1 = 0; - mcor2 = 0; - sreron = 0; - sreroff = 0; - - brdp = stl_brds[portp->brdnr]; - if (brdp == NULL) - return; - -/* - * Set up the RX char ignore mask with those RX error types we - * can ignore. We can get the cd1400 to help us out a little here, - * it will ignore parity errors and breaks for us. - */ - portp->rxignoremsk = 0; - if (tiosp->c_iflag & IGNPAR) { - portp->rxignoremsk |= (ST_PARITY | ST_FRAMING | ST_OVERRUN); - cor1 |= COR1_PARIGNORE; - } - if (tiosp->c_iflag & IGNBRK) { - portp->rxignoremsk |= ST_BREAK; - cor4 |= COR4_IGNBRK; - } - - portp->rxmarkmsk = ST_OVERRUN; - if (tiosp->c_iflag & (INPCK | PARMRK)) - portp->rxmarkmsk |= (ST_PARITY | ST_FRAMING); - if (tiosp->c_iflag & BRKINT) - portp->rxmarkmsk |= ST_BREAK; - -/* - * Go through the char size, parity and stop bits and set all the - * option register appropriately. - */ - switch (tiosp->c_cflag & CSIZE) { - case CS5: - cor1 |= COR1_CHL5; - break; - case CS6: - cor1 |= COR1_CHL6; - break; - case CS7: - cor1 |= COR1_CHL7; - break; - default: - cor1 |= COR1_CHL8; - break; - } - - if (tiosp->c_cflag & CSTOPB) - cor1 |= COR1_STOP2; - else - cor1 |= COR1_STOP1; - - if (tiosp->c_cflag & PARENB) { - if (tiosp->c_cflag & PARODD) - cor1 |= (COR1_PARENB | COR1_PARODD); - else - cor1 |= (COR1_PARENB | COR1_PAREVEN); - } else { - cor1 |= COR1_PARNONE; - } - -/* - * Set the RX FIFO threshold at 6 chars. This gives a bit of breathing - * space for hardware flow control and the like. This should be set to - * VMIN. Also here we will set the RX data timeout to 10ms - this should - * really be based on VTIME. - */ - cor3 |= FIFO_RXTHRESHOLD; - rtpr = 2; - -/* - * Calculate the baud rate timers. For now we will just assume that - * the input and output baud are the same. Could have used a baud - * table here, but this way we can generate virtually any baud rate - * we like! - */ - baudrate = tiosp->c_cflag & CBAUD; - if (baudrate & CBAUDEX) { - baudrate &= ~CBAUDEX; - if ((baudrate < 1) || (baudrate > 4)) - tiosp->c_cflag &= ~CBAUDEX; - else - baudrate += 15; - } - baudrate = stl_baudrates[baudrate]; - if ((tiosp->c_cflag & CBAUD) == B38400) { - if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - baudrate = 57600; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - baudrate = 115200; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - baudrate = 230400; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - baudrate = 460800; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) - baudrate = (portp->baud_base / portp->custom_divisor); - } - if (baudrate > STL_CD1400MAXBAUD) - baudrate = STL_CD1400MAXBAUD; - - if (baudrate > 0) { - for (clk = 0; clk < CD1400_NUMCLKS; clk++) { - clkdiv = (portp->clk / stl_cd1400clkdivs[clk]) / baudrate; - if (clkdiv < 0x100) - break; - } - div = (unsigned char) clkdiv; - } - -/* - * Check what form of modem signaling is required and set it up. - */ - if ((tiosp->c_cflag & CLOCAL) == 0) { - mcor1 |= MCOR1_DCD; - mcor2 |= MCOR2_DCD; - sreron |= SRER_MODEM; - portp->port.flags |= ASYNC_CHECK_CD; - } else - portp->port.flags &= ~ASYNC_CHECK_CD; - -/* - * Setup cd1400 enhanced modes if we can. In particular we want to - * handle as much of the flow control as possible automatically. As - * well as saving a few CPU cycles it will also greatly improve flow - * control reliability. - */ - if (tiosp->c_iflag & IXON) { - cor2 |= COR2_TXIBE; - cor3 |= COR3_SCD12; - if (tiosp->c_iflag & IXANY) - cor2 |= COR2_IXM; - } - - if (tiosp->c_cflag & CRTSCTS) { - cor2 |= COR2_CTSAE; - mcor1 |= FIFO_RTSTHRESHOLD; - } - -/* - * All cd1400 register values calculated so go through and set - * them all up. - */ - - pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", - portp->portnr, portp->panelnr, portp->brdnr); - pr_debug(" cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n", - cor1, cor2, cor3, cor4, cor5); - pr_debug(" mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n", - mcor1, mcor2, rtpr, sreron, sreroff); - pr_debug(" tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div); - pr_debug(" schr1=%x schr2=%x schr3=%x schr4=%x\n", - tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP], - tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); - srer = stl_cd1400getreg(portp, SRER); - stl_cd1400setreg(portp, SRER, 0); - if (stl_cd1400updatereg(portp, COR1, cor1)) - ccr = 1; - if (stl_cd1400updatereg(portp, COR2, cor2)) - ccr = 1; - if (stl_cd1400updatereg(portp, COR3, cor3)) - ccr = 1; - if (ccr) { - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, CCR_CORCHANGE); - } - stl_cd1400setreg(portp, COR4, cor4); - stl_cd1400setreg(portp, COR5, cor5); - stl_cd1400setreg(portp, MCOR1, mcor1); - stl_cd1400setreg(portp, MCOR2, mcor2); - if (baudrate > 0) { - stl_cd1400setreg(portp, TCOR, clk); - stl_cd1400setreg(portp, TBPR, div); - stl_cd1400setreg(portp, RCOR, clk); - stl_cd1400setreg(portp, RBPR, div); - } - stl_cd1400setreg(portp, SCHR1, tiosp->c_cc[VSTART]); - stl_cd1400setreg(portp, SCHR2, tiosp->c_cc[VSTOP]); - stl_cd1400setreg(portp, SCHR3, tiosp->c_cc[VSTART]); - stl_cd1400setreg(portp, SCHR4, tiosp->c_cc[VSTOP]); - stl_cd1400setreg(portp, RTPR, rtpr); - mcor1 = stl_cd1400getreg(portp, MSVR1); - if (mcor1 & MSVR1_DCD) - portp->sigs |= TIOCM_CD; - else - portp->sigs &= ~TIOCM_CD; - stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Set the state of the DTR and RTS signals. - */ - -static void stl_cd1400setsignals(struct stlport *portp, int dtr, int rts) -{ - unsigned char msvr1, msvr2; - unsigned long flags; - - pr_debug("stl_cd1400setsignals(portp=%p,dtr=%d,rts=%d)\n", - portp, dtr, rts); - - msvr1 = 0; - msvr2 = 0; - if (dtr > 0) - msvr1 = MSVR1_DTR; - if (rts > 0) - msvr2 = MSVR2_RTS; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - if (rts >= 0) - stl_cd1400setreg(portp, MSVR2, msvr2); - if (dtr >= 0) - stl_cd1400setreg(portp, MSVR1, msvr1); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Return the state of the signals. - */ - -static int stl_cd1400getsignals(struct stlport *portp) -{ - unsigned char msvr1, msvr2; - unsigned long flags; - int sigs; - - pr_debug("stl_cd1400getsignals(portp=%p)\n", portp); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - msvr1 = stl_cd1400getreg(portp, MSVR1); - msvr2 = stl_cd1400getreg(portp, MSVR2); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - - sigs = 0; - sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; - sigs |= (msvr1 & MSVR1_CTS) ? TIOCM_CTS : 0; - sigs |= (msvr1 & MSVR1_DTR) ? TIOCM_DTR : 0; - sigs |= (msvr2 & MSVR2_RTS) ? TIOCM_RTS : 0; -#if 0 - sigs |= (msvr1 & MSVR1_RI) ? TIOCM_RI : 0; - sigs |= (msvr1 & MSVR1_DSR) ? TIOCM_DSR : 0; -#else - sigs |= TIOCM_DSR; -#endif - return sigs; -} - -/*****************************************************************************/ - -/* - * Enable/Disable the Transmitter and/or Receiver. - */ - -static void stl_cd1400enablerxtx(struct stlport *portp, int rx, int tx) -{ - unsigned char ccr; - unsigned long flags; - - pr_debug("stl_cd1400enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); - - ccr = 0; - - if (tx == 0) - ccr |= CCR_TXDISABLE; - else if (tx > 0) - ccr |= CCR_TXENABLE; - if (rx == 0) - ccr |= CCR_RXDISABLE; - else if (rx > 0) - ccr |= CCR_RXENABLE; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, ccr); - stl_cd1400ccrwait(portp); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Start/stop the Transmitter and/or Receiver. - */ - -static void stl_cd1400startrxtx(struct stlport *portp, int rx, int tx) -{ - unsigned char sreron, sreroff; - unsigned long flags; - - pr_debug("stl_cd1400startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); - - sreron = 0; - sreroff = 0; - if (tx == 0) - sreroff |= (SRER_TXDATA | SRER_TXEMPTY); - else if (tx == 1) - sreron |= SRER_TXDATA; - else if (tx >= 2) - sreron |= SRER_TXEMPTY; - if (rx == 0) - sreroff |= SRER_RXDATA; - else if (rx > 0) - sreron |= SRER_RXDATA; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - stl_cd1400setreg(portp, SRER, - ((stl_cd1400getreg(portp, SRER) & ~sreroff) | sreron)); - BRDDISABLE(portp->brdnr); - if (tx > 0) - set_bit(ASYI_TXBUSY, &portp->istate); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Disable all interrupts from this port. - */ - -static void stl_cd1400disableintrs(struct stlport *portp) -{ - unsigned long flags; - - pr_debug("stl_cd1400disableintrs(portp=%p)\n", portp); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - stl_cd1400setreg(portp, SRER, 0); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -static void stl_cd1400sendbreak(struct stlport *portp, int len) -{ - unsigned long flags; - - pr_debug("stl_cd1400sendbreak(portp=%p,len=%d)\n", portp, len); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - stl_cd1400setreg(portp, SRER, - ((stl_cd1400getreg(portp, SRER) & ~SRER_TXDATA) | - SRER_TXEMPTY)); - BRDDISABLE(portp->brdnr); - portp->brklen = len; - if (len == 1) - portp->stats.txbreaks++; - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Take flow control actions... - */ - -static void stl_cd1400flowctrl(struct stlport *portp, int state) -{ - struct tty_struct *tty; - unsigned long flags; - - pr_debug("stl_cd1400flowctrl(portp=%p,state=%x)\n", portp, state); - - if (portp == NULL) - return; - tty = tty_port_tty_get(&portp->port); - if (tty == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - - if (state) { - if (tty->termios->c_iflag & IXOFF) { - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1); - portp->stats.rxxon++; - stl_cd1400ccrwait(portp); - } -/* - * Question: should we return RTS to what it was before? It may - * have been set by an ioctl... Suppose not, since if you have - * hardware flow control set then it is pretty silly to go and - * set the RTS line by hand. - */ - if (tty->termios->c_cflag & CRTSCTS) { - stl_cd1400setreg(portp, MCOR1, - (stl_cd1400getreg(portp, MCOR1) | - FIFO_RTSTHRESHOLD)); - stl_cd1400setreg(portp, MSVR2, MSVR2_RTS); - portp->stats.rxrtson++; - } - } else { - if (tty->termios->c_iflag & IXOFF) { - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2); - portp->stats.rxxoff++; - stl_cd1400ccrwait(portp); - } - if (tty->termios->c_cflag & CRTSCTS) { - stl_cd1400setreg(portp, MCOR1, - (stl_cd1400getreg(portp, MCOR1) & 0xf0)); - stl_cd1400setreg(portp, MSVR2, 0); - portp->stats.rxrtsoff++; - } - } - - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - tty_kref_put(tty); -} - -/*****************************************************************************/ - -/* - * Send a flow control character... - */ - -static void stl_cd1400sendflow(struct stlport *portp, int state) -{ - struct tty_struct *tty; - unsigned long flags; - - pr_debug("stl_cd1400sendflow(portp=%p,state=%x)\n", portp, state); - - if (portp == NULL) - return; - tty = tty_port_tty_get(&portp->port); - if (tty == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - if (state) { - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, CCR_SENDSCHR1); - portp->stats.rxxon++; - stl_cd1400ccrwait(portp); - } else { - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, CCR_SENDSCHR2); - portp->stats.rxxoff++; - stl_cd1400ccrwait(portp); - } - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - tty_kref_put(tty); -} - -/*****************************************************************************/ - -static void stl_cd1400flush(struct stlport *portp) -{ - unsigned long flags; - - pr_debug("stl_cd1400flush(portp=%p)\n", portp); - - if (portp == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); - stl_cd1400ccrwait(portp); - stl_cd1400setreg(portp, CCR, CCR_TXFLUSHFIFO); - stl_cd1400ccrwait(portp); - portp->tx.tail = portp->tx.head; - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Return the current state of data flow on this port. This is only - * really interesting when determining if data has fully completed - * transmission or not... This is easy for the cd1400, it accurately - * maintains the busy port flag. - */ - -static int stl_cd1400datastate(struct stlport *portp) -{ - pr_debug("stl_cd1400datastate(portp=%p)\n", portp); - - if (portp == NULL) - return 0; - - return test_bit(ASYI_TXBUSY, &portp->istate) ? 1 : 0; -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for cd1400 EasyIO boards. - */ - -static void stl_cd1400eiointr(struct stlpanel *panelp, unsigned int iobase) -{ - unsigned char svrtype; - - pr_debug("stl_cd1400eiointr(panelp=%p,iobase=%x)\n", panelp, iobase); - - spin_lock(&brd_lock); - outb(SVRR, iobase); - svrtype = inb(iobase + EREG_DATA); - if (panelp->nrports > 4) { - outb((SVRR + 0x80), iobase); - svrtype |= inb(iobase + EREG_DATA); - } - - if (svrtype & SVRR_RX) - stl_cd1400rxisr(panelp, iobase); - else if (svrtype & SVRR_TX) - stl_cd1400txisr(panelp, iobase); - else if (svrtype & SVRR_MDM) - stl_cd1400mdmisr(panelp, iobase); - - spin_unlock(&brd_lock); -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for cd1400 panels. - */ - -static void stl_cd1400echintr(struct stlpanel *panelp, unsigned int iobase) -{ - unsigned char svrtype; - - pr_debug("stl_cd1400echintr(panelp=%p,iobase=%x)\n", panelp, iobase); - - outb(SVRR, iobase); - svrtype = inb(iobase + EREG_DATA); - outb((SVRR + 0x80), iobase); - svrtype |= inb(iobase + EREG_DATA); - if (svrtype & SVRR_RX) - stl_cd1400rxisr(panelp, iobase); - else if (svrtype & SVRR_TX) - stl_cd1400txisr(panelp, iobase); - else if (svrtype & SVRR_MDM) - stl_cd1400mdmisr(panelp, iobase); -} - - -/*****************************************************************************/ - -/* - * Unfortunately we need to handle breaks in the TX data stream, since - * this is the only way to generate them on the cd1400. - */ - -static int stl_cd1400breakisr(struct stlport *portp, int ioaddr) -{ - if (portp->brklen == 1) { - outb((COR2 + portp->uartaddr), ioaddr); - outb((inb(ioaddr + EREG_DATA) | COR2_ETC), - (ioaddr + EREG_DATA)); - outb((TDR + portp->uartaddr), ioaddr); - outb(ETC_CMD, (ioaddr + EREG_DATA)); - outb(ETC_STARTBREAK, (ioaddr + EREG_DATA)); - outb((SRER + portp->uartaddr), ioaddr); - outb((inb(ioaddr + EREG_DATA) & ~(SRER_TXDATA | SRER_TXEMPTY)), - (ioaddr + EREG_DATA)); - return 1; - } else if (portp->brklen > 1) { - outb((TDR + portp->uartaddr), ioaddr); - outb(ETC_CMD, (ioaddr + EREG_DATA)); - outb(ETC_STOPBREAK, (ioaddr + EREG_DATA)); - portp->brklen = -1; - return 1; - } else { - outb((COR2 + portp->uartaddr), ioaddr); - outb((inb(ioaddr + EREG_DATA) & ~COR2_ETC), - (ioaddr + EREG_DATA)); - portp->brklen = 0; - } - return 0; -} - -/*****************************************************************************/ - -/* - * Transmit interrupt handler. This has gotta be fast! Handling TX - * chars is pretty simple, stuff as many as possible from the TX buffer - * into the cd1400 FIFO. Must also handle TX breaks here, since they - * are embedded as commands in the data stream. Oh no, had to use a goto! - * This could be optimized more, will do when I get time... - * In practice it is possible that interrupts are enabled but that the - * port has been hung up. Need to handle not having any TX buffer here, - * this is done by using the side effect that head and tail will also - * be NULL if the buffer has been freed. - */ - -static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) -{ - struct stlport *portp; - int len, stlen; - char *head, *tail; - unsigned char ioack, srer; - struct tty_struct *tty; - - pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); - - ioack = inb(ioaddr + EREG_TXACK); - if (((ioack & panelp->ackmask) != 0) || - ((ioack & ACK_TYPMASK) != ACK_TYPTX)) { - printk("STALLION: bad TX interrupt ack value=%x\n", ioack); - return; - } - portp = panelp->ports[(ioack >> 3)]; - -/* - * Unfortunately we need to handle breaks in the data stream, since - * this is the only way to generate them on the cd1400. Do it now if - * a break is to be sent. - */ - if (portp->brklen != 0) - if (stl_cd1400breakisr(portp, ioaddr)) - goto stl_txalldone; - - head = portp->tx.head; - tail = portp->tx.tail; - len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head)); - if ((len == 0) || ((len < STL_TXBUFLOW) && - (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { - set_bit(ASYI_TXLOW, &portp->istate); - tty = tty_port_tty_get(&portp->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } - } - - if (len == 0) { - outb((SRER + portp->uartaddr), ioaddr); - srer = inb(ioaddr + EREG_DATA); - if (srer & SRER_TXDATA) { - srer = (srer & ~SRER_TXDATA) | SRER_TXEMPTY; - } else { - srer &= ~(SRER_TXDATA | SRER_TXEMPTY); - clear_bit(ASYI_TXBUSY, &portp->istate); - } - outb(srer, (ioaddr + EREG_DATA)); - } else { - len = min(len, CD1400_TXFIFOSIZE); - portp->stats.txtotal += len; - stlen = min_t(unsigned int, len, - (portp->tx.buf + STL_TXBUFSIZE) - tail); - outb((TDR + portp->uartaddr), ioaddr); - outsb((ioaddr + EREG_DATA), tail, stlen); - len -= stlen; - tail += stlen; - if (tail >= (portp->tx.buf + STL_TXBUFSIZE)) - tail = portp->tx.buf; - if (len > 0) { - outsb((ioaddr + EREG_DATA), tail, len); - tail += len; - } - portp->tx.tail = tail; - } - -stl_txalldone: - outb((EOSRR + portp->uartaddr), ioaddr); - outb(0, (ioaddr + EREG_DATA)); -} - -/*****************************************************************************/ - -/* - * Receive character interrupt handler. Determine if we have good chars - * or bad chars and then process appropriately. Good chars are easy - * just shove the lot into the RX buffer and set all status byte to 0. - * If a bad RX char then process as required. This routine needs to be - * fast! In practice it is possible that we get an interrupt on a port - * that is closed. This can happen on hangups - since they completely - * shutdown a port not in user context. Need to handle this case. - */ - -static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr) -{ - struct stlport *portp; - struct tty_struct *tty; - unsigned int ioack, len, buflen; - unsigned char status; - char ch; - - pr_debug("stl_cd1400rxisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); - - ioack = inb(ioaddr + EREG_RXACK); - if ((ioack & panelp->ackmask) != 0) { - printk("STALLION: bad RX interrupt ack value=%x\n", ioack); - return; - } - portp = panelp->ports[(ioack >> 3)]; - tty = tty_port_tty_get(&portp->port); - - if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { - outb((RDCR + portp->uartaddr), ioaddr); - len = inb(ioaddr + EREG_DATA); - if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { - len = min_t(unsigned int, len, sizeof(stl_unwanted)); - outb((RDSR + portp->uartaddr), ioaddr); - insb((ioaddr + EREG_DATA), &stl_unwanted[0], len); - portp->stats.rxlost += len; - portp->stats.rxtotal += len; - } else { - len = min(len, buflen); - if (len > 0) { - unsigned char *ptr; - outb((RDSR + portp->uartaddr), ioaddr); - tty_prepare_flip_string(tty, &ptr, len); - insb((ioaddr + EREG_DATA), ptr, len); - tty_schedule_flip(tty); - portp->stats.rxtotal += len; - } - } - } else if ((ioack & ACK_TYPMASK) == ACK_TYPRXBAD) { - outb((RDSR + portp->uartaddr), ioaddr); - status = inb(ioaddr + EREG_DATA); - ch = inb(ioaddr + EREG_DATA); - if (status & ST_PARITY) - portp->stats.rxparity++; - if (status & ST_FRAMING) - portp->stats.rxframing++; - if (status & ST_OVERRUN) - portp->stats.rxoverrun++; - if (status & ST_BREAK) - portp->stats.rxbreaks++; - if (status & ST_SCHARMASK) { - if ((status & ST_SCHARMASK) == ST_SCHAR1) - portp->stats.txxon++; - if ((status & ST_SCHARMASK) == ST_SCHAR2) - portp->stats.txxoff++; - goto stl_rxalldone; - } - if (tty != NULL && (portp->rxignoremsk & status) == 0) { - if (portp->rxmarkmsk & status) { - if (status & ST_BREAK) { - status = TTY_BREAK; - if (portp->port.flags & ASYNC_SAK) { - do_SAK(tty); - BRDENABLE(portp->brdnr, portp->pagenr); - } - } else if (status & ST_PARITY) - status = TTY_PARITY; - else if (status & ST_FRAMING) - status = TTY_FRAME; - else if(status & ST_OVERRUN) - status = TTY_OVERRUN; - else - status = 0; - } else - status = 0; - tty_insert_flip_char(tty, ch, status); - tty_schedule_flip(tty); - } - } else { - printk("STALLION: bad RX interrupt ack value=%x\n", ioack); - tty_kref_put(tty); - return; - } - -stl_rxalldone: - tty_kref_put(tty); - outb((EOSRR + portp->uartaddr), ioaddr); - outb(0, (ioaddr + EREG_DATA)); -} - -/*****************************************************************************/ - -/* - * Modem interrupt handler. The is called when the modem signal line - * (DCD) has changed state. Leave most of the work to the off-level - * processing routine. - */ - -static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr) -{ - struct stlport *portp; - unsigned int ioack; - unsigned char misr; - - pr_debug("stl_cd1400mdmisr(panelp=%p)\n", panelp); - - ioack = inb(ioaddr + EREG_MDACK); - if (((ioack & panelp->ackmask) != 0) || - ((ioack & ACK_TYPMASK) != ACK_TYPMDM)) { - printk("STALLION: bad MODEM interrupt ack value=%x\n", ioack); - return; - } - portp = panelp->ports[(ioack >> 3)]; - - outb((MISR + portp->uartaddr), ioaddr); - misr = inb(ioaddr + EREG_DATA); - if (misr & MISR_DCD) { - stl_cd_change(portp); - portp->stats.modem++; - } - - outb((EOSRR + portp->uartaddr), ioaddr); - outb(0, (ioaddr + EREG_DATA)); -} - -/*****************************************************************************/ -/* SC26198 HARDWARE FUNCTIONS */ -/*****************************************************************************/ - -/* - * These functions get/set/update the registers of the sc26198 UARTs. - * Access to the sc26198 registers is via an address/data io port pair. - * (Maybe should make this inline...) - */ - -static int stl_sc26198getreg(struct stlport *portp, int regnr) -{ - outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); - return inb(portp->ioaddr + XP_DATA); -} - -static void stl_sc26198setreg(struct stlport *portp, int regnr, int value) -{ - outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); - outb(value, (portp->ioaddr + XP_DATA)); -} - -static int stl_sc26198updatereg(struct stlport *portp, int regnr, int value) -{ - outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); - if (inb(portp->ioaddr + XP_DATA) != value) { - outb(value, (portp->ioaddr + XP_DATA)); - return 1; - } - return 0; -} - -/*****************************************************************************/ - -/* - * Functions to get and set the sc26198 global registers. - */ - -static int stl_sc26198getglobreg(struct stlport *portp, int regnr) -{ - outb(regnr, (portp->ioaddr + XP_ADDR)); - return inb(portp->ioaddr + XP_DATA); -} - -#if 0 -static void stl_sc26198setglobreg(struct stlport *portp, int regnr, int value) -{ - outb(regnr, (portp->ioaddr + XP_ADDR)); - outb(value, (portp->ioaddr + XP_DATA)); -} -#endif - -/*****************************************************************************/ - -/* - * Inbitialize the UARTs in a panel. We don't care what sort of board - * these ports are on - since the port io registers are almost - * identical when dealing with ports. - */ - -static int stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *panelp) -{ - int chipmask, i; - int nrchips, ioaddr; - - pr_debug("stl_sc26198panelinit(brdp=%p,panelp=%p)\n", brdp, panelp); - - BRDENABLE(panelp->brdnr, panelp->pagenr); - -/* - * Check that each chip is present and started up OK. - */ - chipmask = 0; - nrchips = (panelp->nrports + 4) / SC26198_PORTS; - if (brdp->brdtype == BRD_ECHPCI) - outb(panelp->pagenr, brdp->ioctrl); - - for (i = 0; i < nrchips; i++) { - ioaddr = panelp->iobase + (i * 4); - outb(SCCR, (ioaddr + XP_ADDR)); - outb(CR_RESETALL, (ioaddr + XP_DATA)); - outb(TSTR, (ioaddr + XP_ADDR)); - if (inb(ioaddr + XP_DATA) != 0) { - printk("STALLION: sc26198 not responding, " - "brd=%d panel=%d chip=%d\n", - panelp->brdnr, panelp->panelnr, i); - continue; - } - chipmask |= (0x1 << i); - outb(GCCR, (ioaddr + XP_ADDR)); - outb(GCCR_IVRTYPCHANACK, (ioaddr + XP_DATA)); - outb(WDTRCR, (ioaddr + XP_ADDR)); - outb(0xff, (ioaddr + XP_DATA)); - } - - BRDDISABLE(panelp->brdnr); - return chipmask; -} - -/*****************************************************************************/ - -/* - * Initialize hardware specific port registers. - */ - -static void stl_sc26198portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp) -{ - pr_debug("stl_sc26198portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp, - panelp, portp); - - if ((brdp == NULL) || (panelp == NULL) || - (portp == NULL)) - return; - - portp->ioaddr = panelp->iobase + ((portp->portnr < 8) ? 0 : 4); - portp->uartaddr = (portp->portnr & 0x07) << 4; - portp->pagenr = panelp->pagenr; - portp->hwid = 0x1; - - BRDENABLE(portp->brdnr, portp->pagenr); - stl_sc26198setreg(portp, IOPCR, IOPCR_SETSIGS); - BRDDISABLE(portp->brdnr); -} - -/*****************************************************************************/ - -/* - * Set up the sc26198 registers for a port based on the termios port - * settings. - */ - -static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp) -{ - struct stlbrd *brdp; - unsigned long flags; - unsigned int baudrate; - unsigned char mr0, mr1, mr2, clk; - unsigned char imron, imroff, iopr, ipr; - - mr0 = 0; - mr1 = 0; - mr2 = 0; - clk = 0; - iopr = 0; - imron = 0; - imroff = 0; - - brdp = stl_brds[portp->brdnr]; - if (brdp == NULL) - return; - -/* - * Set up the RX char ignore mask with those RX error types we - * can ignore. - */ - portp->rxignoremsk = 0; - if (tiosp->c_iflag & IGNPAR) - portp->rxignoremsk |= (SR_RXPARITY | SR_RXFRAMING | - SR_RXOVERRUN); - if (tiosp->c_iflag & IGNBRK) - portp->rxignoremsk |= SR_RXBREAK; - - portp->rxmarkmsk = SR_RXOVERRUN; - if (tiosp->c_iflag & (INPCK | PARMRK)) - portp->rxmarkmsk |= (SR_RXPARITY | SR_RXFRAMING); - if (tiosp->c_iflag & BRKINT) - portp->rxmarkmsk |= SR_RXBREAK; - -/* - * Go through the char size, parity and stop bits and set all the - * option register appropriately. - */ - switch (tiosp->c_cflag & CSIZE) { - case CS5: - mr1 |= MR1_CS5; - break; - case CS6: - mr1 |= MR1_CS6; - break; - case CS7: - mr1 |= MR1_CS7; - break; - default: - mr1 |= MR1_CS8; - break; - } - - if (tiosp->c_cflag & CSTOPB) - mr2 |= MR2_STOP2; - else - mr2 |= MR2_STOP1; - - if (tiosp->c_cflag & PARENB) { - if (tiosp->c_cflag & PARODD) - mr1 |= (MR1_PARENB | MR1_PARODD); - else - mr1 |= (MR1_PARENB | MR1_PAREVEN); - } else - mr1 |= MR1_PARNONE; - - mr1 |= MR1_ERRBLOCK; - -/* - * Set the RX FIFO threshold at 8 chars. This gives a bit of breathing - * space for hardware flow control and the like. This should be set to - * VMIN. - */ - mr2 |= MR2_RXFIFOHALF; - -/* - * Calculate the baud rate timers. For now we will just assume that - * the input and output baud are the same. The sc26198 has a fixed - * baud rate table, so only discrete baud rates possible. - */ - baudrate = tiosp->c_cflag & CBAUD; - if (baudrate & CBAUDEX) { - baudrate &= ~CBAUDEX; - if ((baudrate < 1) || (baudrate > 4)) - tiosp->c_cflag &= ~CBAUDEX; - else - baudrate += 15; - } - baudrate = stl_baudrates[baudrate]; - if ((tiosp->c_cflag & CBAUD) == B38400) { - if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - baudrate = 57600; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - baudrate = 115200; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - baudrate = 230400; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - baudrate = 460800; - else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) - baudrate = (portp->baud_base / portp->custom_divisor); - } - if (baudrate > STL_SC26198MAXBAUD) - baudrate = STL_SC26198MAXBAUD; - - if (baudrate > 0) - for (clk = 0; clk < SC26198_NRBAUDS; clk++) - if (baudrate <= sc26198_baudtable[clk]) - break; - -/* - * Check what form of modem signaling is required and set it up. - */ - if (tiosp->c_cflag & CLOCAL) { - portp->port.flags &= ~ASYNC_CHECK_CD; - } else { - iopr |= IOPR_DCDCOS; - imron |= IR_IOPORT; - portp->port.flags |= ASYNC_CHECK_CD; - } - -/* - * Setup sc26198 enhanced modes if we can. In particular we want to - * handle as much of the flow control as possible automatically. As - * well as saving a few CPU cycles it will also greatly improve flow - * control reliability. - */ - if (tiosp->c_iflag & IXON) { - mr0 |= MR0_SWFTX | MR0_SWFT; - imron |= IR_XONXOFF; - } else - imroff |= IR_XONXOFF; - - if (tiosp->c_iflag & IXOFF) - mr0 |= MR0_SWFRX; - - if (tiosp->c_cflag & CRTSCTS) { - mr2 |= MR2_AUTOCTS; - mr1 |= MR1_AUTORTS; - } - -/* - * All sc26198 register values calculated so go through and set - * them all up. - */ - - pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", - portp->portnr, portp->panelnr, portp->brdnr); - pr_debug(" mr0=%x mr1=%x mr2=%x clk=%x\n", mr0, mr1, mr2, clk); - pr_debug(" iopr=%x imron=%x imroff=%x\n", iopr, imron, imroff); - pr_debug(" schr1=%x schr2=%x schr3=%x schr4=%x\n", - tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP], - tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_sc26198setreg(portp, IMR, 0); - stl_sc26198updatereg(portp, MR0, mr0); - stl_sc26198updatereg(portp, MR1, mr1); - stl_sc26198setreg(portp, SCCR, CR_RXERRBLOCK); - stl_sc26198updatereg(portp, MR2, mr2); - stl_sc26198updatereg(portp, IOPIOR, - ((stl_sc26198getreg(portp, IOPIOR) & ~IPR_CHANGEMASK) | iopr)); - - if (baudrate > 0) { - stl_sc26198setreg(portp, TXCSR, clk); - stl_sc26198setreg(portp, RXCSR, clk); - } - - stl_sc26198setreg(portp, XONCR, tiosp->c_cc[VSTART]); - stl_sc26198setreg(portp, XOFFCR, tiosp->c_cc[VSTOP]); - - ipr = stl_sc26198getreg(portp, IPR); - if (ipr & IPR_DCD) - portp->sigs &= ~TIOCM_CD; - else - portp->sigs |= TIOCM_CD; - - portp->imr = (portp->imr & ~imroff) | imron; - stl_sc26198setreg(portp, IMR, portp->imr); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Set the state of the DTR and RTS signals. - */ - -static void stl_sc26198setsignals(struct stlport *portp, int dtr, int rts) -{ - unsigned char iopioron, iopioroff; - unsigned long flags; - - pr_debug("stl_sc26198setsignals(portp=%p,dtr=%d,rts=%d)\n", portp, - dtr, rts); - - iopioron = 0; - iopioroff = 0; - if (dtr == 0) - iopioroff |= IPR_DTR; - else if (dtr > 0) - iopioron |= IPR_DTR; - if (rts == 0) - iopioroff |= IPR_RTS; - else if (rts > 0) - iopioron |= IPR_RTS; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_sc26198setreg(portp, IOPIOR, - ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Return the state of the signals. - */ - -static int stl_sc26198getsignals(struct stlport *portp) -{ - unsigned char ipr; - unsigned long flags; - int sigs; - - pr_debug("stl_sc26198getsignals(portp=%p)\n", portp); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - ipr = stl_sc26198getreg(portp, IPR); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - - sigs = 0; - sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; - sigs |= (ipr & IPR_CTS) ? 0 : TIOCM_CTS; - sigs |= (ipr & IPR_DTR) ? 0: TIOCM_DTR; - sigs |= (ipr & IPR_RTS) ? 0: TIOCM_RTS; - sigs |= TIOCM_DSR; - return sigs; -} - -/*****************************************************************************/ - -/* - * Enable/Disable the Transmitter and/or Receiver. - */ - -static void stl_sc26198enablerxtx(struct stlport *portp, int rx, int tx) -{ - unsigned char ccr; - unsigned long flags; - - pr_debug("stl_sc26198enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx,tx); - - ccr = portp->crenable; - if (tx == 0) - ccr &= ~CR_TXENABLE; - else if (tx > 0) - ccr |= CR_TXENABLE; - if (rx == 0) - ccr &= ~CR_RXENABLE; - else if (rx > 0) - ccr |= CR_RXENABLE; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_sc26198setreg(portp, SCCR, ccr); - BRDDISABLE(portp->brdnr); - portp->crenable = ccr; - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Start/stop the Transmitter and/or Receiver. - */ - -static void stl_sc26198startrxtx(struct stlport *portp, int rx, int tx) -{ - unsigned char imr; - unsigned long flags; - - pr_debug("stl_sc26198startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); - - imr = portp->imr; - if (tx == 0) - imr &= ~IR_TXRDY; - else if (tx == 1) - imr |= IR_TXRDY; - if (rx == 0) - imr &= ~(IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG); - else if (rx > 0) - imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_sc26198setreg(portp, IMR, imr); - BRDDISABLE(portp->brdnr); - portp->imr = imr; - if (tx > 0) - set_bit(ASYI_TXBUSY, &portp->istate); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Disable all interrupts from this port. - */ - -static void stl_sc26198disableintrs(struct stlport *portp) -{ - unsigned long flags; - - pr_debug("stl_sc26198disableintrs(portp=%p)\n", portp); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - portp->imr = 0; - stl_sc26198setreg(portp, IMR, 0); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -static void stl_sc26198sendbreak(struct stlport *portp, int len) -{ - unsigned long flags; - - pr_debug("stl_sc26198sendbreak(portp=%p,len=%d)\n", portp, len); - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - if (len == 1) { - stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); - portp->stats.txbreaks++; - } else - stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); - - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Take flow control actions... - */ - -static void stl_sc26198flowctrl(struct stlport *portp, int state) -{ - struct tty_struct *tty; - unsigned long flags; - unsigned char mr0; - - pr_debug("stl_sc26198flowctrl(portp=%p,state=%x)\n", portp, state); - - if (portp == NULL) - return; - tty = tty_port_tty_get(&portp->port); - if (tty == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - - if (state) { - if (tty->termios->c_iflag & IXOFF) { - mr0 = stl_sc26198getreg(portp, MR0); - stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); - stl_sc26198setreg(portp, SCCR, CR_TXSENDXON); - mr0 |= MR0_SWFRX; - portp->stats.rxxon++; - stl_sc26198wait(portp); - stl_sc26198setreg(portp, MR0, mr0); - } -/* - * Question: should we return RTS to what it was before? It may - * have been set by an ioctl... Suppose not, since if you have - * hardware flow control set then it is pretty silly to go and - * set the RTS line by hand. - */ - if (tty->termios->c_cflag & CRTSCTS) { - stl_sc26198setreg(portp, MR1, - (stl_sc26198getreg(portp, MR1) | MR1_AUTORTS)); - stl_sc26198setreg(portp, IOPIOR, - (stl_sc26198getreg(portp, IOPIOR) | IOPR_RTS)); - portp->stats.rxrtson++; - } - } else { - if (tty->termios->c_iflag & IXOFF) { - mr0 = stl_sc26198getreg(portp, MR0); - stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); - stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF); - mr0 &= ~MR0_SWFRX; - portp->stats.rxxoff++; - stl_sc26198wait(portp); - stl_sc26198setreg(portp, MR0, mr0); - } - if (tty->termios->c_cflag & CRTSCTS) { - stl_sc26198setreg(portp, MR1, - (stl_sc26198getreg(portp, MR1) & ~MR1_AUTORTS)); - stl_sc26198setreg(portp, IOPIOR, - (stl_sc26198getreg(portp, IOPIOR) & ~IOPR_RTS)); - portp->stats.rxrtsoff++; - } - } - - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - tty_kref_put(tty); -} - -/*****************************************************************************/ - -/* - * Send a flow control character. - */ - -static void stl_sc26198sendflow(struct stlport *portp, int state) -{ - struct tty_struct *tty; - unsigned long flags; - unsigned char mr0; - - pr_debug("stl_sc26198sendflow(portp=%p,state=%x)\n", portp, state); - - if (portp == NULL) - return; - tty = tty_port_tty_get(&portp->port); - if (tty == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - if (state) { - mr0 = stl_sc26198getreg(portp, MR0); - stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); - stl_sc26198setreg(portp, SCCR, CR_TXSENDXON); - mr0 |= MR0_SWFRX; - portp->stats.rxxon++; - stl_sc26198wait(portp); - stl_sc26198setreg(portp, MR0, mr0); - } else { - mr0 = stl_sc26198getreg(portp, MR0); - stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); - stl_sc26198setreg(portp, SCCR, CR_TXSENDXOFF); - mr0 &= ~MR0_SWFRX; - portp->stats.rxxoff++; - stl_sc26198wait(portp); - stl_sc26198setreg(portp, MR0, mr0); - } - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - tty_kref_put(tty); -} - -/*****************************************************************************/ - -static void stl_sc26198flush(struct stlport *portp) -{ - unsigned long flags; - - pr_debug("stl_sc26198flush(portp=%p)\n", portp); - - if (portp == NULL) - return; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - stl_sc26198setreg(portp, SCCR, CR_TXRESET); - stl_sc26198setreg(portp, SCCR, portp->crenable); - BRDDISABLE(portp->brdnr); - portp->tx.tail = portp->tx.head; - spin_unlock_irqrestore(&brd_lock, flags); -} - -/*****************************************************************************/ - -/* - * Return the current state of data flow on this port. This is only - * really interesting when determining if data has fully completed - * transmission or not... The sc26198 interrupt scheme cannot - * determine when all data has actually drained, so we need to - * check the port statusy register to be sure. - */ - -static int stl_sc26198datastate(struct stlport *portp) -{ - unsigned long flags; - unsigned char sr; - - pr_debug("stl_sc26198datastate(portp=%p)\n", portp); - - if (portp == NULL) - return 0; - if (test_bit(ASYI_TXBUSY, &portp->istate)) - return 1; - - spin_lock_irqsave(&brd_lock, flags); - BRDENABLE(portp->brdnr, portp->pagenr); - sr = stl_sc26198getreg(portp, SR); - BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); - - return (sr & SR_TXEMPTY) ? 0 : 1; -} - -/*****************************************************************************/ - -/* - * Delay for a small amount of time, to give the sc26198 a chance - * to process a command... - */ - -static void stl_sc26198wait(struct stlport *portp) -{ - int i; - - pr_debug("stl_sc26198wait(portp=%p)\n", portp); - - if (portp == NULL) - return; - - for (i = 0; i < 20; i++) - stl_sc26198getglobreg(portp, TSTR); -} - -/*****************************************************************************/ - -/* - * If we are TX flow controlled and in IXANY mode then we may - * need to unflow control here. We gotta do this because of the - * automatic flow control modes of the sc26198. - */ - -static void stl_sc26198txunflow(struct stlport *portp, struct tty_struct *tty) -{ - unsigned char mr0; - - mr0 = stl_sc26198getreg(portp, MR0); - stl_sc26198setreg(portp, MR0, (mr0 & ~MR0_SWFRXTX)); - stl_sc26198setreg(portp, SCCR, CR_HOSTXON); - stl_sc26198wait(portp); - stl_sc26198setreg(portp, MR0, mr0); - clear_bit(ASYI_TXFLOWED, &portp->istate); -} - -/*****************************************************************************/ - -/* - * Interrupt service routine for sc26198 panels. - */ - -static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase) -{ - struct stlport *portp; - unsigned int iack; - - spin_lock(&brd_lock); - -/* - * Work around bug in sc26198 chip... Cannot have A6 address - * line of UART high, else iack will be returned as 0. - */ - outb(0, (iobase + 1)); - - iack = inb(iobase + XP_IACK); - portp = panelp->ports[(iack & IVR_CHANMASK) + ((iobase & 0x4) << 1)]; - - if (iack & IVR_RXDATA) - stl_sc26198rxisr(portp, iack); - else if (iack & IVR_TXDATA) - stl_sc26198txisr(portp); - else - stl_sc26198otherisr(portp, iack); - - spin_unlock(&brd_lock); -} - -/*****************************************************************************/ - -/* - * Transmit interrupt handler. This has gotta be fast! Handling TX - * chars is pretty simple, stuff as many as possible from the TX buffer - * into the sc26198 FIFO. - * In practice it is possible that interrupts are enabled but that the - * port has been hung up. Need to handle not having any TX buffer here, - * this is done by using the side effect that head and tail will also - * be NULL if the buffer has been freed. - */ - -static void stl_sc26198txisr(struct stlport *portp) -{ - struct tty_struct *tty; - unsigned int ioaddr; - unsigned char mr0; - int len, stlen; - char *head, *tail; - - pr_debug("stl_sc26198txisr(portp=%p)\n", portp); - - ioaddr = portp->ioaddr; - head = portp->tx.head; - tail = portp->tx.tail; - len = (head >= tail) ? (head - tail) : (STL_TXBUFSIZE - (tail - head)); - if ((len == 0) || ((len < STL_TXBUFLOW) && - (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { - set_bit(ASYI_TXLOW, &portp->istate); - tty = tty_port_tty_get(&portp->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } - } - - if (len == 0) { - outb((MR0 | portp->uartaddr), (ioaddr + XP_ADDR)); - mr0 = inb(ioaddr + XP_DATA); - if ((mr0 & MR0_TXMASK) == MR0_TXEMPTY) { - portp->imr &= ~IR_TXRDY; - outb((IMR | portp->uartaddr), (ioaddr + XP_ADDR)); - outb(portp->imr, (ioaddr + XP_DATA)); - clear_bit(ASYI_TXBUSY, &portp->istate); - } else { - mr0 |= ((mr0 & ~MR0_TXMASK) | MR0_TXEMPTY); - outb(mr0, (ioaddr + XP_DATA)); - } - } else { - len = min(len, SC26198_TXFIFOSIZE); - portp->stats.txtotal += len; - stlen = min_t(unsigned int, len, - (portp->tx.buf + STL_TXBUFSIZE) - tail); - outb(GTXFIFO, (ioaddr + XP_ADDR)); - outsb((ioaddr + XP_DATA), tail, stlen); - len -= stlen; - tail += stlen; - if (tail >= (portp->tx.buf + STL_TXBUFSIZE)) - tail = portp->tx.buf; - if (len > 0) { - outsb((ioaddr + XP_DATA), tail, len); - tail += len; - } - portp->tx.tail = tail; - } -} - -/*****************************************************************************/ - -/* - * Receive character interrupt handler. Determine if we have good chars - * or bad chars and then process appropriately. Good chars are easy - * just shove the lot into the RX buffer and set all status byte to 0. - * If a bad RX char then process as required. This routine needs to be - * fast! In practice it is possible that we get an interrupt on a port - * that is closed. This can happen on hangups - since they completely - * shutdown a port not in user context. Need to handle this case. - */ - -static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) -{ - struct tty_struct *tty; - unsigned int len, buflen, ioaddr; - - pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); - - tty = tty_port_tty_get(&portp->port); - ioaddr = portp->ioaddr; - outb(GIBCR, (ioaddr + XP_ADDR)); - len = inb(ioaddr + XP_DATA) + 1; - - if ((iack & IVR_TYPEMASK) == IVR_RXDATA) { - if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { - len = min_t(unsigned int, len, sizeof(stl_unwanted)); - outb(GRXFIFO, (ioaddr + XP_ADDR)); - insb((ioaddr + XP_DATA), &stl_unwanted[0], len); - portp->stats.rxlost += len; - portp->stats.rxtotal += len; - } else { - len = min(len, buflen); - if (len > 0) { - unsigned char *ptr; - outb(GRXFIFO, (ioaddr + XP_ADDR)); - tty_prepare_flip_string(tty, &ptr, len); - insb((ioaddr + XP_DATA), ptr, len); - tty_schedule_flip(tty); - portp->stats.rxtotal += len; - } - } - } else { - stl_sc26198rxbadchars(portp); - } - -/* - * If we are TX flow controlled and in IXANY mode then we may need - * to unflow control here. We gotta do this because of the automatic - * flow control modes of the sc26198. - */ - if (test_bit(ASYI_TXFLOWED, &portp->istate)) { - if ((tty != NULL) && - (tty->termios != NULL) && - (tty->termios->c_iflag & IXANY)) { - stl_sc26198txunflow(portp, tty); - } - } - tty_kref_put(tty); -} - -/*****************************************************************************/ - -/* - * Process an RX bad character. - */ - -static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char ch) -{ - struct tty_struct *tty; - unsigned int ioaddr; - - tty = tty_port_tty_get(&portp->port); - ioaddr = portp->ioaddr; - - if (status & SR_RXPARITY) - portp->stats.rxparity++; - if (status & SR_RXFRAMING) - portp->stats.rxframing++; - if (status & SR_RXOVERRUN) - portp->stats.rxoverrun++; - if (status & SR_RXBREAK) - portp->stats.rxbreaks++; - - if ((tty != NULL) && - ((portp->rxignoremsk & status) == 0)) { - if (portp->rxmarkmsk & status) { - if (status & SR_RXBREAK) { - status = TTY_BREAK; - if (portp->port.flags & ASYNC_SAK) { - do_SAK(tty); - BRDENABLE(portp->brdnr, portp->pagenr); - } - } else if (status & SR_RXPARITY) - status = TTY_PARITY; - else if (status & SR_RXFRAMING) - status = TTY_FRAME; - else if(status & SR_RXOVERRUN) - status = TTY_OVERRUN; - else - status = 0; - } else - status = 0; - - tty_insert_flip_char(tty, ch, status); - tty_schedule_flip(tty); - - if (status == 0) - portp->stats.rxtotal++; - } - tty_kref_put(tty); -} - -/*****************************************************************************/ - -/* - * Process all characters in the RX FIFO of the UART. Check all char - * status bytes as well, and process as required. We need to check - * all bytes in the FIFO, in case some more enter the FIFO while we - * are here. To get the exact character error type we need to switch - * into CHAR error mode (that is why we need to make sure we empty - * the FIFO). - */ - -static void stl_sc26198rxbadchars(struct stlport *portp) -{ - unsigned char status, mr1; - char ch; - -/* - * To get the precise error type for each character we must switch - * back into CHAR error mode. - */ - mr1 = stl_sc26198getreg(portp, MR1); - stl_sc26198setreg(portp, MR1, (mr1 & ~MR1_ERRBLOCK)); - - while ((status = stl_sc26198getreg(portp, SR)) & SR_RXRDY) { - stl_sc26198setreg(portp, SCCR, CR_CLEARRXERR); - ch = stl_sc26198getreg(portp, RXFIFO); - stl_sc26198rxbadch(portp, status, ch); - } - -/* - * To get correct interrupt class we must switch back into BLOCK - * error mode. - */ - stl_sc26198setreg(portp, MR1, mr1); -} - -/*****************************************************************************/ - -/* - * Other interrupt handler. This includes modem signals, flow - * control actions, etc. Most stuff is left to off-level interrupt - * processing time. - */ - -static void stl_sc26198otherisr(struct stlport *portp, unsigned int iack) -{ - unsigned char cir, ipr, xisr; - - pr_debug("stl_sc26198otherisr(portp=%p,iack=%x)\n", portp, iack); - - cir = stl_sc26198getglobreg(portp, CIR); - - switch (cir & CIR_SUBTYPEMASK) { - case CIR_SUBCOS: - ipr = stl_sc26198getreg(portp, IPR); - if (ipr & IPR_DCDCHANGE) { - stl_cd_change(portp); - portp->stats.modem++; - } - break; - case CIR_SUBXONXOFF: - xisr = stl_sc26198getreg(portp, XISR); - if (xisr & XISR_RXXONGOT) { - set_bit(ASYI_TXFLOWED, &portp->istate); - portp->stats.txxoff++; - } - if (xisr & XISR_RXXOFFGOT) { - clear_bit(ASYI_TXFLOWED, &portp->istate); - portp->stats.txxon++; - } - break; - case CIR_SUBBREAK: - stl_sc26198setreg(portp, SCCR, CR_BREAKRESET); - stl_sc26198rxbadchars(portp); - break; - default: - break; - } -} - -static void stl_free_isabrds(void) -{ - struct stlbrd *brdp; - unsigned int i; - - for (i = 0; i < stl_nrbrds; i++) { - if ((brdp = stl_brds[i]) == NULL || (brdp->state & STL_PROBED)) - continue; - - free_irq(brdp->irq, brdp); - - stl_cleanup_panels(brdp); - - release_region(brdp->ioaddr1, brdp->iosize1); - if (brdp->iosize2 > 0) - release_region(brdp->ioaddr2, brdp->iosize2); - - kfree(brdp); - stl_brds[i] = NULL; - } -} - -/* - * Loadable module initialization stuff. - */ -static int __init stallion_module_init(void) -{ - struct stlbrd *brdp; - struct stlconf conf; - unsigned int i, j; - int retval; - - printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); - - spin_lock_init(&stallion_lock); - spin_lock_init(&brd_lock); - - stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); - if (!stl_serial) { - retval = -ENOMEM; - goto err; - } - - stl_serial->owner = THIS_MODULE; - stl_serial->driver_name = stl_drvname; - stl_serial->name = "ttyE"; - stl_serial->major = STL_SERIALMAJOR; - stl_serial->minor_start = 0; - stl_serial->type = TTY_DRIVER_TYPE_SERIAL; - stl_serial->subtype = SERIAL_TYPE_NORMAL; - stl_serial->init_termios = stl_deftermios; - stl_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - tty_set_operations(stl_serial, &stl_ops); - - retval = tty_register_driver(stl_serial); - if (retval) { - printk("STALLION: failed to register serial driver\n"); - goto err_frtty; - } - -/* - * Find any dynamically supported boards. That is via module load - * line options. - */ - for (i = stl_nrbrds; i < stl_nargs; i++) { - memset(&conf, 0, sizeof(conf)); - if (stl_parsebrd(&conf, stl_brdsp[i]) == 0) - continue; - if ((brdp = stl_allocbrd()) == NULL) - continue; - brdp->brdnr = i; - brdp->brdtype = conf.brdtype; - brdp->ioaddr1 = conf.ioaddr1; - brdp->ioaddr2 = conf.ioaddr2; - brdp->irq = conf.irq; - brdp->irqtype = conf.irqtype; - stl_brds[brdp->brdnr] = brdp; - if (stl_brdinit(brdp)) { - stl_brds[brdp->brdnr] = NULL; - kfree(brdp); - } else { - for (j = 0; j < brdp->nrports; j++) - tty_register_device(stl_serial, - brdp->brdnr * STL_MAXPORTS + j, NULL); - stl_nrbrds = i + 1; - } - } - - /* this has to be _after_ isa finding because of locking */ - retval = pci_register_driver(&stl_pcidriver); - if (retval && stl_nrbrds == 0) { - printk(KERN_ERR "STALLION: can't register pci driver\n"); - goto err_unrtty; - } - -/* - * Set up a character driver for per board stuff. This is mainly used - * to do stats ioctls on the ports. - */ - if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem)) - printk("STALLION: failed to register serial board device\n"); - - stallion_class = class_create(THIS_MODULE, "staliomem"); - if (IS_ERR(stallion_class)) - printk("STALLION: failed to create class\n"); - for (i = 0; i < 4; i++) - device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i), - NULL, "staliomem%d", i); - - return 0; -err_unrtty: - tty_unregister_driver(stl_serial); -err_frtty: - put_tty_driver(stl_serial); -err: - return retval; -} - -static void __exit stallion_module_exit(void) -{ - struct stlbrd *brdp; - unsigned int i, j; - - pr_debug("cleanup_module()\n"); - - printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, - stl_drvversion); - -/* - * Free up all allocated resources used by the ports. This includes - * memory and interrupts. As part of this process we will also do - * a hangup on every open port - to try to flush out any processes - * hanging onto ports. - */ - for (i = 0; i < stl_nrbrds; i++) { - if ((brdp = stl_brds[i]) == NULL || (brdp->state & STL_PROBED)) - continue; - for (j = 0; j < brdp->nrports; j++) - tty_unregister_device(stl_serial, - brdp->brdnr * STL_MAXPORTS + j); - } - - for (i = 0; i < 4; i++) - device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); - unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); - class_destroy(stallion_class); - - pci_unregister_driver(&stl_pcidriver); - - stl_free_isabrds(); - - tty_unregister_driver(stl_serial); - put_tty_driver(stl_serial); -} - -module_init(stallion_module_init); -module_exit(stallion_module_exit); - -MODULE_AUTHOR("Greg Ungerer"); -MODULE_DESCRIPTION("Stallion Multiport Serial Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/usbip/README b/drivers/staging/usbip/README index c11be5735485..41a2cf2e77a6 100644 --- a/drivers/staging/usbip/README +++ b/drivers/staging/usbip/README @@ -2,5 +2,6 @@ TODO: - more discussion about the protocol - testing - review of the userspace interface + - document the protocol Please send patches for this code to Greg Kroah-Hartman diff --git a/drivers/staging/usbip/stub.h b/drivers/staging/usbip/stub.h index 6592aa2ad15c..132adc57ebc1 100644 --- a/drivers/staging/usbip/stub.h +++ b/drivers/staging/usbip/stub.h @@ -76,7 +76,9 @@ struct stub_unlink { __u32 status; }; -#define BUSID_SIZE 20 +/* same as SYSFS_BUS_ID_SIZE */ +#define BUSID_SIZE 32 + struct bus_id_priv { char name[BUSID_SIZE]; char status; diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c index 8cbea42b69bc..fce22f2bd8bf 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@ -23,16 +23,10 @@ #include "usbip_common.h" #include "stub.h" -static int stub_probe(struct usb_interface *interface, - const struct usb_device_id *id); -static void stub_disconnect(struct usb_interface *interface); -static int stub_pre_reset(struct usb_interface *interface); -static int stub_post_reset(struct usb_interface *interface); - /* * Define device IDs here if you want to explicitly limit exportable devices. - * In the most cases, wild card matching will be ok because driver binding can - * be changed dynamically by a userland program. + * In most cases, wildcard matching will be okay because driver binding can be + * changed dynamically by a userland program. */ static struct usb_device_id stub_table[] = { #if 0 @@ -56,18 +50,9 @@ static struct usb_device_id stub_table[] = { }; MODULE_DEVICE_TABLE(usb, stub_table); -struct usb_driver stub_driver = { - .name = "usbip", - .probe = stub_probe, - .disconnect = stub_disconnect, - .id_table = stub_table, - .pre_reset = stub_pre_reset, - .post_reset = stub_post_reset, -}; - /* - * usbip_status shows status of usbip as long as this driver is bound to the - * target device. + * usbip_status shows the status of usbip-host as long as this driver is bound + * to the target device. */ static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf) @@ -211,10 +196,11 @@ static void stub_shutdown_connection(struct usbip_device *ud) if (ud->tcp_tx && !task_is_dead(ud->tcp_tx)) kthread_stop(ud->tcp_tx); - /* 2. close the socket */ /* - * tcp_socket is freed after threads are killed. - * So usbip_xmit do not touch NULL socket. + * 2. close the socket + * + * tcp_socket is freed after threads are killed so that usbip_xmit does + * not touch NULL socket. */ if (ud->tcp_socket) { sock_release(ud->tcp_socket); @@ -234,8 +220,8 @@ static void stub_shutdown_connection(struct usbip_device *ud) list_del(&unlink->list); kfree(unlink); } - list_for_each_entry_safe(unlink, tmp, - &sdev->unlink_free, list) { + list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, + list) { list_del(&unlink->list); kfree(unlink); } @@ -262,22 +248,17 @@ static void stub_device_reset(struct usbip_device *ud) /* try to reset the device */ ret = usb_reset_device(udev); - usb_unlock_device(udev); spin_lock(&ud->lock); if (ret) { dev_err(&udev->dev, "device reset\n"); ud->status = SDEV_ST_ERROR; - } else { dev_info(&udev->dev, "device reset\n"); ud->status = SDEV_ST_AVAILABLE; - } spin_unlock(&ud->lock); - - return; } static void stub_device_unusable(struct usbip_device *ud) @@ -379,7 +360,7 @@ static int stub_probe(struct usb_interface *interface, /* check we should claim or not by busid_table */ busid_priv = get_busid_priv(udev_busid); - if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) || + if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) || (busid_priv->status == STUB_BUSID_OTHER)) { dev_info(&interface->dev, "%s is not in match_busid table... " "skip!\n", udev_busid); @@ -424,7 +405,6 @@ static int stub_probe(struct usb_interface *interface, udev_busid); usb_set_intfdata(interface, NULL); busid_priv->interf_count--; - return err; } @@ -432,7 +412,7 @@ static int stub_probe(struct usb_interface *interface, return 0; } - /* ok. this is my device. */ + /* ok, this is my device */ sdev = stub_device_alloc(udev, interface); if (!sdev) return -ENOMEM; @@ -447,7 +427,6 @@ static int stub_probe(struct usb_interface *interface, /* set private data to usb_interface */ usb_set_intfdata(interface, sdev); busid_priv->interf_count++; - busid_priv->sdev = sdev; err = stub_add_files(&interface->dev); @@ -457,7 +436,6 @@ static int stub_probe(struct usb_interface *interface, usb_put_intf(interface); busid_priv->interf_count = 0; - busid_priv->sdev = NULL; stub_device_free(sdev); return err; @@ -562,3 +540,12 @@ int stub_post_reset(struct usb_interface *interface) dev_dbg(&interface->dev, "post_reset\n"); return 0; } + +struct usb_driver stub_driver = { + .name = "usbip-host", + .probe = stub_probe, + .disconnect = stub_disconnect, + .id_table = stub_table, + .pre_reset = stub_pre_reset, + .post_reset = stub_post_reset, + }; diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c index e9085d663945..a34249a9cb6e 100644 --- a/drivers/staging/usbip/stub_main.c +++ b/drivers/staging/usbip/stub_main.c @@ -25,9 +25,7 @@ #define DRIVER_AUTHOR "Takahiro Hirofuchi" #define DRIVER_DESC "USB/IP Host Driver" -/* stub_priv is allocated from stub_priv_cache */ struct kmem_cache *stub_priv_cache; - /* * busid_tables defines matching busids that usbip can grab. A user can change * dynamically what device is locally used and what device is exported to a @@ -37,42 +35,101 @@ struct kmem_cache *stub_priv_cache; static struct bus_id_priv busid_table[MAX_BUSID]; static spinlock_t busid_table_lock; -int match_busid(const char *busid) +static void init_busid_table(void) { int i; - spin_lock(&busid_table_lock); + memset(busid_table, 0, sizeof(busid_table)); + for (i = 0; i < MAX_BUSID; i++) + busid_table[i].status = STUB_BUSID_OTHER; + + spin_lock_init(&busid_table_lock); +} + +/* + * Find the index of the busid by name. + * Must be called with busid_table_lock held. + */ +static int get_busid_idx(const char *busid) +{ + int i; + int idx = -1; for (i = 0; i < MAX_BUSID; i++) if (busid_table[i].name[0]) if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { - /* already registerd */ - spin_unlock(&busid_table_lock); - return 0; + idx = i; + break; } - - spin_unlock(&busid_table_lock); - - return 1; + return idx; } struct bus_id_priv *get_busid_priv(const char *busid) { - int i; + int idx; + struct bus_id_priv *bid = NULL; spin_lock(&busid_table_lock); - - for (i = 0; i < MAX_BUSID; i++) - if (busid_table[i].name[0]) - if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { - /* already registerd */ - spin_unlock(&busid_table_lock); - return &(busid_table[i]); - } - + idx = get_busid_idx(busid); + if (idx >= 0) + bid = &(busid_table[idx]); spin_unlock(&busid_table_lock); - return NULL; + return bid; +} + +static int add_match_busid(char *busid) +{ + int i; + int ret = -1; + + spin_lock(&busid_table_lock); + /* already registered? */ + if (get_busid_idx(busid) >= 0) { + ret = 0; + goto out; + } + + for (i = 0; i < MAX_BUSID; i++) + if (!busid_table[i].name[0]) { + strncpy(busid_table[i].name, busid, BUSID_SIZE); + if ((busid_table[i].status != STUB_BUSID_ALLOC) && + (busid_table[i].status != STUB_BUSID_REMOV)) + busid_table[i].status = STUB_BUSID_ADDED; + ret = 0; + break; + } + +out: + spin_unlock(&busid_table_lock); + + return ret; +} + +int del_match_busid(char *busid) +{ + int idx; + int ret = -1; + + spin_lock(&busid_table_lock); + idx = get_busid_idx(busid); + if (idx < 0) + goto out; + + /* found */ + ret = 0; + + if (busid_table[idx].status == STUB_BUSID_OTHER) + memset(busid_table[idx].name, 0, BUSID_SIZE); + + if ((busid_table[idx].status != STUB_BUSID_OTHER) && + (busid_table[idx].status != STUB_BUSID_ADDED)) + busid_table[idx].status = STUB_BUSID_REMOV; + +out: + spin_unlock(&busid_table_lock); + + return ret; } static ssize_t show_match_busid(struct device_driver *drv, char *buf) @@ -81,81 +138,15 @@ static ssize_t show_match_busid(struct device_driver *drv, char *buf) char *out = buf; spin_lock(&busid_table_lock); - for (i = 0; i < MAX_BUSID; i++) if (busid_table[i].name[0]) out += sprintf(out, "%s ", busid_table[i].name); - spin_unlock(&busid_table_lock); - out += sprintf(out, "\n"); return out - buf; } -static int add_match_busid(char *busid) -{ - int i; - - if (!match_busid(busid)) - return 0; - - spin_lock(&busid_table_lock); - - for (i = 0; i < MAX_BUSID; i++) - if (!busid_table[i].name[0]) { - strncpy(busid_table[i].name, busid, BUSID_SIZE); - if ((busid_table[i].status != STUB_BUSID_ALLOC) && - (busid_table[i].status != STUB_BUSID_REMOV)) - busid_table[i].status = STUB_BUSID_ADDED; - spin_unlock(&busid_table_lock); - return 0; - } - - spin_unlock(&busid_table_lock); - - return -1; -} - -int del_match_busid(char *busid) -{ - int i; - - spin_lock(&busid_table_lock); - - for (i = 0; i < MAX_BUSID; i++) - if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { - /* found */ - if (busid_table[i].status == STUB_BUSID_OTHER) - memset(busid_table[i].name, 0, BUSID_SIZE); - if ((busid_table[i].status != STUB_BUSID_OTHER) && - (busid_table[i].status != STUB_BUSID_ADDED)) { - busid_table[i].status = STUB_BUSID_REMOV; - } - spin_unlock(&busid_table_lock); - return 0; - } - - spin_unlock(&busid_table_lock); - - return -1; -} - -static void init_busid_table(void) -{ - int i; - - for (i = 0; i < MAX_BUSID; i++) { - memset(busid_table[i].name, 0, BUSID_SIZE); - busid_table[i].status = STUB_BUSID_OTHER; - busid_table[i].interf_count = 0; - busid_table[i].sdev = NULL; - busid_table[i].shutdown_busid = 0; - } - - spin_lock_init(&busid_table_lock); -} - static ssize_t store_match_busid(struct device_driver *dev, const char *buf, size_t count) { @@ -175,23 +166,24 @@ static ssize_t store_match_busid(struct device_driver *dev, const char *buf, strncpy(busid, buf + 4, BUSID_SIZE); if (!strncmp(buf, "add ", 4)) { - if (add_match_busid(busid) < 0) + if (add_match_busid(busid) < 0) { return -ENOMEM; - else { + } else { pr_debug("add busid %s\n", busid); return count; } } else if (!strncmp(buf, "del ", 4)) { - if (del_match_busid(busid) < 0) + if (del_match_busid(busid) < 0) { return -ENODEV; - else { + } else { pr_debug("del busid %s\n", busid); return count; } - } else + } else { return -EINVAL; + } } -static DRIVER_ATTR(match_busid, S_IRUSR|S_IWUSR, show_match_busid, +static DRIVER_ATTR(match_busid, S_IRUSR | S_IWUSR, show_match_busid, store_match_busid); static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead) @@ -214,36 +206,30 @@ static struct stub_priv *stub_priv_pop(struct stub_device *sdev) spin_lock_irqsave(&sdev->priv_lock, flags); priv = stub_priv_pop_from_listhead(&sdev->priv_init); - if (priv) { - spin_unlock_irqrestore(&sdev->priv_lock, flags); - return priv; - } + if (priv) + goto done; priv = stub_priv_pop_from_listhead(&sdev->priv_tx); - if (priv) { - spin_unlock_irqrestore(&sdev->priv_lock, flags); - return priv; - } + if (priv) + goto done; priv = stub_priv_pop_from_listhead(&sdev->priv_free); - if (priv) { - spin_unlock_irqrestore(&sdev->priv_lock, flags); - return priv; - } +done: spin_unlock_irqrestore(&sdev->priv_lock, flags); - return NULL; + + return priv; } void stub_device_cleanup_urbs(struct stub_device *sdev) { struct stub_priv *priv; + struct urb *urb; dev_dbg(&sdev->udev->dev, "free sdev %p\n", sdev); while ((priv = stub_priv_pop(sdev))) { - struct urb *urb = priv->urb; - + urb = priv->urb; dev_dbg(&sdev->udev->dev, "free urb %p\n", urb); usb_kill_urb(urb); @@ -251,51 +237,46 @@ void stub_device_cleanup_urbs(struct stub_device *sdev) kfree(urb->transfer_buffer); kfree(urb->setup_packet); - usb_free_urb(urb); } } -static int __init usb_stub_init(void) +static int __init usbip_host_init(void) { int ret; - stub_priv_cache = kmem_cache_create("stub_priv", - sizeof(struct stub_priv), 0, - SLAB_HWCACHE_ALIGN, NULL); + stub_priv_cache = KMEM_CACHE(stub_priv, SLAB_HWCACHE_ALIGN); if (!stub_priv_cache) { - pr_err("create stub_priv_cache error\n"); + pr_err("kmem_cache_create failed\n"); return -ENOMEM; } ret = usb_register(&stub_driver); - if (ret) { + if (ret < 0) { pr_err("usb_register failed %d\n", ret); - goto error_usb_register; + goto err_usb_register; } - pr_info(DRIVER_DESC " " USBIP_VERSION "\n"); - - init_busid_table(); - ret = driver_create_file(&stub_driver.drvwrap.driver, &driver_attr_match_busid); - - if (ret) { - pr_err("create driver sysfs\n"); - goto error_create_file; + if (ret < 0) { + pr_err("driver_create_file failed\n"); + goto err_create_file; } + init_busid_table(); + pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); return ret; -error_create_file: + +err_create_file: usb_deregister(&stub_driver); -error_usb_register: +err_usb_register: kmem_cache_destroy(stub_priv_cache); return ret; } -static void __exit usb_stub_exit(void) +static void __exit usbip_host_exit(void) { driver_remove_file(&stub_driver.drvwrap.driver, &driver_attr_match_busid); @@ -309,8 +290,8 @@ static void __exit usb_stub_exit(void) kmem_cache_destroy(stub_priv_cache); } -module_init(usb_stub_init); -module_exit(usb_stub_exit); +module_init(usbip_host_init); +module_exit(usbip_host_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c index bc57844600b9..538fb9ee341a 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -306,18 +306,18 @@ static int stub_recv_cmd_unlink(struct stub_device *sdev, static int valid_request(struct stub_device *sdev, struct usbip_header *pdu) { struct usbip_device *ud = &sdev->ud; + int valid = 0; if (pdu->base.devid == sdev->devid) { spin_lock(&ud->lock); if (ud->status == SDEV_ST_USED) { /* A request is valid. */ - spin_unlock(&ud->lock); - return 1; + valid = 1; } spin_unlock(&ud->lock); } - return 0; + return valid; } static struct stub_priv *stub_priv_alloc(struct stub_device *sdev, diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c index fda2bc95e859..023fda305be2 100644 --- a/drivers/staging/usbip/stub_tx.c +++ b/drivers/staging/usbip/stub_tx.c @@ -97,13 +97,12 @@ void stub_complete(struct urb *urb) /* link a urb to the queue of tx. */ spin_lock_irqsave(&sdev->priv_lock, flags); - if (priv->unlinking) { stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status); stub_free_priv_and_urb(priv); - } else + } else { list_move_tail(&priv->list, &sdev->priv_tx); - + } spin_unlock_irqrestore(&sdev->priv_lock, flags); /* wake up tx_thread */ @@ -113,10 +112,10 @@ void stub_complete(struct urb *urb) static inline void setup_base_pdu(struct usbip_header_basic *base, __u32 command, __u32 seqnum) { - base->command = command; - base->seqnum = seqnum; - base->devid = 0; - base->ep = 0; + base->command = command; + base->seqnum = seqnum; + base->devid = 0; + base->ep = 0; base->direction = 0; } @@ -232,7 +231,7 @@ static int stub_send_ret_submit(struct stub_device *sdev) if (txsize != sizeof(pdu_header) + urb->actual_length) { dev_err(&sdev->interface->dev, "actual length of urb %d does not " - "match iso packet sizes %lu\n", + "match iso packet sizes %zu\n", urb->actual_length, txsize-sizeof(pdu_header)); kfree(iov); diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index 433a3b6207d6..f4b53d103c54 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -63,9 +63,9 @@ static void usbip_dump_buffer(char *buff, int bufflen) static void usbip_dump_pipe(unsigned int p) { unsigned char type = usb_pipetype(p); - unsigned char ep = usb_pipeendpoint(p); - unsigned char dev = usb_pipedevice(p); - unsigned char dir = usb_pipein(p); + unsigned char ep = usb_pipeendpoint(p); + unsigned char dev = usb_pipedevice(p); + unsigned char dir = usb_pipein(p); pr_debug("dev(%d) ep(%d) [%s] ", dev, ep, dir ? "IN" : "OUT"); @@ -204,7 +204,7 @@ static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd) pr_debug("CLEAR_FEAT\n"); break; case USB_REQ_SET_FEATURE: - pr_debug("SET_FEAT \n"); + pr_debug("SET_FEAT\n"); break; case USB_REQ_SET_ADDRESS: pr_debug("SET_ADDRRS\n"); @@ -231,14 +231,14 @@ static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd) pr_debug("SYNC_FRAME\n"); break; default: - pr_debug("REQ(%02X) \n", cmd->bRequest); + pr_debug("REQ(%02X)\n", cmd->bRequest); break; } usbip_dump_request_type(cmd->bRequestType); } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) { - pr_debug("CLASS \n"); + pr_debug("CLASS\n"); } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) { - pr_debug("VENDOR \n"); + pr_debug("VENDOR\n"); } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED) { pr_debug("RESERVED\n"); } @@ -334,8 +334,8 @@ void usbip_dump_header(struct usbip_header *pdu) EXPORT_SYMBOL_GPL(usbip_dump_header); /* Send/receive messages over TCP/IP. I refer drivers/block/nbd.c */ -int usbip_xmit(int send, struct socket *sock, char *buf, - int size, int msg_flags) +int usbip_xmit(int send, struct socket *sock, char *buf, int size, + int msg_flags) { int result; struct msghdr msg; @@ -627,9 +627,8 @@ void usbip_header_correct_endian(struct usbip_header *pdu, int send) } EXPORT_SYMBOL_GPL(usbip_header_correct_endian); -static void usbip_iso_pakcet_correct_endian( - struct usbip_iso_packet_descriptor *iso, - int send) +static void usbip_iso_packet_correct_endian( + struct usbip_iso_packet_descriptor *iso, int send) { /* does not need all members. but copy all simply. */ if (send) { @@ -678,7 +677,7 @@ void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen) iso = buff + (i * sizeof(*iso)); usbip_pack_iso(iso, &urb->iso_frame_desc[i], 1); - usbip_iso_pakcet_correct_endian(iso, 1); + usbip_iso_packet_correct_endian(iso, 1); } *bufflen = size; @@ -729,7 +728,7 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) for (i = 0; i < np; i++) { iso = buff + (i * sizeof(*iso)); - usbip_iso_pakcet_correct_endian(iso, 0); + usbip_iso_packet_correct_endian(iso, 0); usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0); total_length += urb->iso_frame_desc[i].actual_length; } @@ -839,19 +838,19 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb) } EXPORT_SYMBOL_GPL(usbip_recv_xbuff); -static int __init usbip_common_init(void) +static int __init usbip_core_init(void) { pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); return 0; } -static void __exit usbip_common_exit(void) +static void __exit usbip_core_exit(void) { return; } -module_init(usbip_common_init); -module_exit(usbip_common_exit); +module_init(usbip_core_init); +module_exit(usbip_core_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h index 4a641c552b78..074ac4267d3b 100644 --- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/staging/usbip/usbip_common.h @@ -65,7 +65,7 @@ enum { #define usbip_dbg_flag_vhci_tx (usbip_debug_flag & usbip_debug_vhci_tx) #define usbip_dbg_flag_stub_rx (usbip_debug_flag & usbip_debug_stub_rx) #define usbip_dbg_flag_stub_tx (usbip_debug_flag & usbip_debug_stub_tx) -#define usbip_dbg_flag_vhci_sysfs (usbip_debug_flag & usbip_debug_vhci_sysfs) +#define usbip_dbg_flag_vhci_sysfs (usbip_debug_flag & usbip_debug_vhci_sysfs) extern unsigned long usbip_debug_flag; extern struct device_attribute dev_attr_usbip_debug; @@ -104,111 +104,110 @@ extern struct device_attribute dev_attr_usbip_debug; usbip_dbg_with_flag(usbip_debug_stub_tx, fmt , ##args) /* - * USB/IP request headers. - * Currently, we define 4 request types: + * USB/IP request headers * - * - CMD_SUBMIT transfers a USB request, corresponding to usb_submit_urb(). + * Each request is transferred across the network to its counterpart, which + * facilitates the normal USB communication. The values contained in the headers + * are basically the same as in a URB. Currently, four request types are + * defined: + * + * - USBIP_CMD_SUBMIT: a USB request block, corresponds to usb_submit_urb() * (client to server) - * - RET_RETURN transfers the result of CMD_SUBMIT. - * (server to client) - * - CMD_UNLINK transfers an unlink request of a pending USB request. - * (client to server) - * - RET_UNLINK transfers the result of CMD_UNLINK. + * + * - USBIP_RET_SUBMIT: the result of USBIP_CMD_SUBMIT * (server to client) * - * Note: The below request formats are based on the USB subsystem of Linux. Its - * details will be defined when other implementations come. + * - USBIP_CMD_UNLINK: an unlink request of a pending USBIP_CMD_SUBMIT, + * corresponds to usb_unlink_urb() + * (client to server) * + * - USBIP_RET_UNLINK: the result of USBIP_CMD_UNLINK + * (server to client) * */ +#define USBIP_CMD_SUBMIT 0x0001 +#define USBIP_RET_SUBMIT 0x0002 +#define USBIP_CMD_UNLINK 0x0003 +#define USBIP_RET_UNLINK 0x0004 -/* - * A basic header followed by other additional headers. +#define USBIP_DIR_IN 0x00 +#define USBIP_DIR_OUT 0x01 + +/** + * struct usbip_header_basic - data pertinent to every request + * @command: the usbip request type + * @seqnum: sequential number that identifies requests; incremented per + * connection + * @devid: specifies a remote USB device uniquely instead of busnum and devnum; + * in the stub driver, this value is ((busnum << 16) | devnum) + * @direction: direction of the transfer + * @ep: endpoint number */ struct usbip_header_basic { -#define USBIP_CMD_SUBMIT 0x0001 -#define USBIP_CMD_UNLINK 0x0002 -#define USBIP_RET_SUBMIT 0x0003 -#define USBIP_RET_UNLINK 0x0004 __u32 command; - - /* sequential number which identifies requests. - * incremented per connections */ __u32 seqnum; - - /* devid is used to specify a remote USB device uniquely instead - * of busnum and devnum in Linux. In the case of Linux stub_driver, - * this value is ((busnum << 16) | devnum) */ __u32 devid; - -#define USBIP_DIR_OUT 0 -#define USBIP_DIR_IN 1 __u32 direction; - __u32 ep; /* endpoint number */ + __u32 ep; } __packed; -/* - * An additional header for a CMD_SUBMIT packet. +/** + * struct usbip_header_cmd_submit - USBIP_CMD_SUBMIT packet header + * @transfer_flags: URB flags + * @transfer_buffer_length: the data size for (in) or (out) transfer + * @start_frame: initial frame for isochronous or interrupt transfers + * @number_of_packets: number of isochronous packets + * @interval: maximum time for the request on the server-side host controller + * @setup: setup data for a control request */ struct usbip_header_cmd_submit { - /* these values are basically the same as in a URB. */ - - /* the same in a URB. */ __u32 transfer_flags; - - /* set the following data size (out), - * or expected reading data size (in) */ __s32 transfer_buffer_length; /* it is difficult for usbip to sync frames (reserved only?) */ __s32 start_frame; - - /* the number of iso descriptors that follows this header */ __s32 number_of_packets; - - /* the maximum time within which this request works in a host - * controller of a server side */ __s32 interval; - /* set setup packet data for a CTRL request */ unsigned char setup[8]; } __packed; -/* - * An additional header for a RET_SUBMIT packet. +/** + * struct usbip_header_ret_submit - USBIP_RET_SUBMIT packet header + * @status: return status of a non-iso request + * @actual_length: number of bytes transferred + * @start_frame: initial frame for isochronous or interrupt transfers + * @number_of_packets: number of isochronous packets + * @error_count: number of errors for isochronous transfers */ struct usbip_header_ret_submit { __s32 status; - __s32 actual_length; /* returned data length */ - __s32 start_frame; /* ISO and INT */ - __s32 number_of_packets; /* ISO only */ - __s32 error_count; /* ISO only */ + __s32 actual_length; + __s32 start_frame; + __s32 number_of_packets; + __s32 error_count; } __packed; -/* - * An additional header for a CMD_UNLINK packet. +/** + * struct usbip_header_cmd_unlink - USBIP_CMD_UNLINK packet header + * @seqnum: the URB seqnum to unlink */ struct usbip_header_cmd_unlink { - __u32 seqnum; /* URB's seqnum that will be unlinked */ + __u32 seqnum; } __packed; -/* - * An additional header for a RET_UNLINK packet. +/** + * struct usbip_header_ret_unlink - USBIP_RET_UNLINK packet header + * @status: return status of the request */ struct usbip_header_ret_unlink { __s32 status; } __packed; -/* the same as usb_iso_packet_descriptor but packed for pdu */ -struct usbip_iso_packet_descriptor { - __u32 offset; - __u32 length; /* expected length */ - __u32 actual_length; - __u32 status; -} __packed; - -/* - * All usbip packets use a common header to keep code simple. +/** + * struct usbip_header - common header for all usbip packets + * @base: the basic header + * @u: packet type dependent header */ struct usbip_header { struct usbip_header_basic base; @@ -221,40 +220,15 @@ struct usbip_header { } u; } __packed; -int usbip_xmit(int, struct socket *, char *, int, int); -int usbip_sendmsg(struct socket *, struct msghdr *, int); - -static inline int interface_to_busnum(struct usb_interface *interface) -{ - struct usb_device *udev = interface_to_usbdev(interface); - return udev->bus->busnum; -} - -static inline int interface_to_devnum(struct usb_interface *interface) -{ - struct usb_device *udev = interface_to_usbdev(interface); - return udev->devnum; -} - -static inline int interface_to_infnum(struct usb_interface *interface) -{ - return interface->cur_altsetting->desc.bInterfaceNumber; -} - -#if 0 -int setnodelay(struct socket *); -int setquickack(struct socket *); -int setkeepalive(struct socket *socket); -void setreuse(struct socket *); -#endif - -struct socket *sockfd_to_socket(unsigned int); -int set_sockaddr(struct socket *socket, struct sockaddr_storage *ss); - -void usbip_dump_urb(struct urb *purb); -void usbip_dump_header(struct usbip_header *pdu); - -struct usbip_device; +/* + * This is the same as usb_iso_packet_descriptor but packed for pdu. + */ +struct usbip_iso_packet_descriptor { + __u32 offset; + __u32 length; /* expected length */ + __u32 actual_length; + __u32 status; +} __packed; enum usbip_side { USBIP_VHCI, @@ -277,20 +251,7 @@ enum usbip_status { VDEV_ST_ERROR }; -/* a common structure for stub_device and vhci_device */ -struct usbip_device { - enum usbip_side side; - enum usbip_status status; - - /* lock for status */ - spinlock_t lock; - - struct socket *tcp_socket; - - struct task_struct *tcp_rx; - struct task_struct *tcp_tx; - - /* event handler */ +/* event handler */ #define USBIP_EH_SHUTDOWN (1 << 0) #define USBIP_EH_BYE (1 << 1) #define USBIP_EH_RESET (1 << 2) @@ -307,6 +268,19 @@ struct usbip_device { #define VDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) #define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) +/* a common structure for stub_device and vhci_device */ +struct usbip_device { + enum usbip_side side; + enum usbip_status status; + + /* lock for status */ + spinlock_t lock; + + struct socket *tcp_socket; + + struct task_struct *tcp_rx; + struct task_struct *tcp_tx; + unsigned long event; struct task_struct *eh; wait_queue_head_t eh_waitq; @@ -318,17 +292,32 @@ struct usbip_device { } eh_ops; }; +#if 0 +int usbip_sendmsg(struct socket *, struct msghdr *, int); +int set_sockaddr(struct socket *socket, struct sockaddr_storage *ss); +int setnodelay(struct socket *); +int setquickack(struct socket *); +int setkeepalive(struct socket *socket); +void setreuse(struct socket *); +#endif + +/* usbip_common.c */ +void usbip_dump_urb(struct urb *purb); +void usbip_dump_header(struct usbip_header *pdu); + +int usbip_xmit(int send, struct socket *sock, char *buf, int size, + int msg_flags); +struct socket *sockfd_to_socket(unsigned int sockfd); + void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, int pack); - void usbip_header_correct_endian(struct usbip_header *pdu, int send); -/* some members of urb must be substituted before. */ -int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb); + +void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen); /* some members of urb must be substituted before. */ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb); -/* some members of urb must be substituted before. */ int usbip_pad_iso(struct usbip_device *ud, struct urb *urb); -void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen); +int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb); /* usbip_event.c */ int usbip_start_eh(struct usbip_device *ud); @@ -336,4 +325,21 @@ void usbip_stop_eh(struct usbip_device *ud); void usbip_event_add(struct usbip_device *ud, unsigned long event); int usbip_event_happened(struct usbip_device *ud); +static inline int interface_to_busnum(struct usb_interface *interface) +{ + struct usb_device *udev = interface_to_usbdev(interface); + return udev->bus->busnum; +} + +static inline int interface_to_devnum(struct usb_interface *interface) +{ + struct usb_device *udev = interface_to_usbdev(interface); + return udev->devnum; +} + +static inline int interface_to_infnum(struct usb_interface *interface) +{ + return interface->cur_altsetting->desc.bInterfaceNumber; +} + #endif /* __USBIP_COMMON_H */ diff --git a/drivers/staging/usbip/userspace/AUTHORS b/drivers/staging/usbip/userspace/AUTHORS index 2f73e65d5092..a27ea8d03aec 100644 --- a/drivers/staging/usbip/userspace/AUTHORS +++ b/drivers/staging/usbip/userspace/AUTHORS @@ -1,2 +1,3 @@ Takahiro Hirofuchi Robert Leibl +matt mooney diff --git a/drivers/staging/usbip/userspace/Makefile.am b/drivers/staging/usbip/userspace/Makefile.am index 83f51b8df89f..9ab19499fe00 100644 --- a/drivers/staging/usbip/userspace/Makefile.am +++ b/drivers/staging/usbip/userspace/Makefile.am @@ -1,11 +1,6 @@ SUBDIRS := libsrc src -includedir := @includedir@/usbip +includedir = @includedir@/usbip include_HEADERS := $(addprefix libsrc/, \ - usbip.h usbip_common.h vhci_driver.h stub_driver.h) + usbip_common.h vhci_driver.h usbip_host_driver.h) dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8 usbip_bind_driver.8) - -if INSTALL_USBIDS -pkgdata_DATA := usb.ids -EXTRA_DIST := $(pkgdata_DATA) -endif diff --git a/drivers/staging/usbip/userspace/README b/drivers/staging/usbip/userspace/README index 2ee84b9e7e09..63cd10719059 100644 --- a/drivers/staging/usbip/userspace/README +++ b/drivers/staging/usbip/userspace/README @@ -1,19 +1,19 @@ -# vim:tw=78:ts=4:expandtab:ai:sw=4 # # README for usbip-utils # -# Copyright (C) 2005-2008 Takahiro Hirofuchi +# Copyright (C) 2011 matt mooney +# 2005-2008 Takahiro Hirofuchi [Requirements] - USB/IP device drivers - Its source code is included under $(top)/drivers/. + Found in the staging directory of the Linux kernel. - sysfsutils >= 2.0.0 - sysfsutils library + sysfsutils library - libwrap0-dev - tcp wrapper library + tcp wrapper library - gcc >= 4.0 @@ -21,195 +21,181 @@ - libtool, automake >= 1.9, autoconf >= 2.5.0, pkg-config + [Install] - 0. Skip here if you see a configure script. - $ ./autogen.sh + 0. Generate configuration scripts. + $ ./autogen.sh - 1. Compile & install. - $ ./configure - $ make install + 1. Compile & install the userspace utilities. + $ ./configure [--with-tcp-wrappers=no] [--with-usbids-dir=] + $ make install + + 2. Compile & install USB/IP drivers. - 2. Compile & install USB/IP drivers if not yet. [Usage] - server:# (Attach your USB device physically.) + server:# (Physically attach your USB device.) server:# insmod usbip-core.ko server:# insmod usbip-host.ko - - It was formerly named as stub.ko. server:# usbipd -D - - Start usbip daemon. + - Start usbip daemon. - server:# usbip_bind_driver --list - - List driver assignments for usb devices. - - server:# usbip_bind_driver --usbip 1-2 - - Bind usbip-host.ko to the device of busid 1-2. - - A usb device 1-2 is now exportable to other hosts! - - Use 'usbip_bind_driver --other 1-2' when you want to shutdown exporting - and use the device locally. + server:# usbip list -l + - List driver assignments for USB devices. + server:# usbip bind --busid 1-2 + - Bind usbip-host.ko to the device with busid 1-2. + - The USB device 1-2 is now exportable to other hosts! + - Use `usbip unbind --busid 1-2' to stop exporting the device. client:# insmod usbip-core.ko client:# insmod vhci-hcd.ko - - It was formerly named as vhci.ko. - client:# usbip --list server - - List exportable usb devices on the server. + client:# usbip list --remote + - List exported USB devices on the . - client:# usbip --attach server 1-2 - - Connect the remote USB device. + client:# usbip attach --host --busid 1-2 + - Connect the remote USB device. - client:# usbip --port - - Show virtual port status. + client:# usbip port + - Show virtual port status. - client:# usbip --detach 0 - - Detach the usb device. + client:# usbip detach --port + - Detach the USB device. -[Output Example] --------------------------------------------------------------------------------------------------------- -- SERVER SIDE (physically attach your USB devices to this host) ---------------------------------------- --------------------------------------------------------------------------------------------------------- -trois:# insmod (somewhere)/usbip-core.ko -trois:# insmod (somewhere)/usbip-host.ko -trois:# usbipd -D +[Example] +--------------------------- + SERVER SIDE +--------------------------- +Physically attach your USB devices to this host. --------------------------------------------------------------------------------------------------------- -In another terminal, let's look up what usb devices are physically attached to -this host. We can see a usb storage device of busid 3-3.2 is now bound to -usb-storage driver. To export this device, we first mark the device as -"exportable"; the device is bound to usbip driver. Please remember you can not -export a usb hub. + trois:# insmod path/to/usbip-core.ko + trois:# insmod path/to/usbip-host.ko + trois:# usbipd -D - trois:# usbip_bind_driver --list - List USB devices - - busid 3-3.2 (04bb:0206) - 3-3.2:1.0 -> usb-storage +In another terminal, let's look up what USB devices are physically +attached to this host. - - busid 3-3.1 (08bb:2702) - 3-3.1:1.0 -> snd-usb-audio - 3-3.1:1.1 -> snd-usb-audio + trois:# usbip list -l + Local USB devices + ================= + - busid 1-1 (05a9:a511) + 1-1:1.0 -> ov511 - - busid 3-3 (0409:0058) - 3-3:1.0 -> hub + - busid 3-2 (0711:0902) + 3-2:1.0 -> none - - busid 3-2 (0711:0902) - 3-2:1.0 -> none + - busid 3-3.1 (08bb:2702) + 3-3.1:1.0 -> snd-usb-audio + 3-3.1:1.1 -> snd-usb-audio - - busid 1-1 (05a9:a511) - 1-1:1.0 -> ov511 + - busid 3-3.2 (04bb:0206) + 3-3.2:1.0 -> usb-storage - - busid 4-1 (046d:08b2) - 4-1:1.0 -> none - 4-1:1.1 -> none - 4-1:1.2 -> none + - busid 3-3 (0409:0058) + 3-3:1.0 -> hub - - busid 5-2 (058f:9254) - 5-2:1.0 -> hub + - busid 4-1 (046d:08b2) + 4-1:1.0 -> none + 4-1:1.1 -> none + 4-1:1.2 -> none --------------------------------------------------------------------------------------------------------- -Mark the device of busid 3-3.2 as exportable. + - busid 5-2 (058f:9254) + 5-2:1.0 -> hub - trois:# usbip_bind_driver --usbip 3-3.2 - ** (process:24621): DEBUG: 3-3.2:1.0 -> none - ** (process:24621): DEBUG: write "add 3-3.2" to /sys/bus/usb/drivers/usbip/match_busid - ** Message: bind 3-3.2 to usbip, complete! +A USB storage device of busid 3-3.2 is now bound to the usb-storage +driver. To export this device, we first mark the device as +"exportable"; the device is bound to the usbip-host driver. Please +remember you can not export a USB hub. - trois:# usbip_bind_driver --list - List USB devices - - busid 3-3.2 (04bb:0206) - 3-3.2:1.0 -> usbip - (snip) +Mark the device of busid 3-3.2 as exportable: -Iterate the above operation for other devices if you like. + trois:# usbip --debug bind --busid 3-3.2 + ... + usbip debug: usbip_bind.c:162:[unbind_other] 3-3.2:1.0 -> usb-storage + ... + bind device on busid 3-3.2: complete + + trois:# usbip list -l + Local USB devices + ================= + ... + + - busid 3-3.2 (04bb:0206) + 3-3.2:1.0 -> usbip-host + ... + +--------------------------- + CLIENT SIDE +--------------------------- +First, let's list available remote devices that are marked as +exportable on the host. + + deux:# insmod path/to/usbip-core.ko + deux:# insmod path/to/vhci-hcd.ko + + deux:# usbip list --remote 10.0.0.3 + Exportable USB devices + ====================== + - 10.0.0.3 + 1-1: Prolific Technology, Inc. : unknown product (067b:3507) + : /sys/devices/pci0000:00/0000:00:1f.2/usb1/1-1 + : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) + : 0 - Mass Storage / SCSI / Bulk (Zip) (08/06/50) + + 1-2.2.1: Apple Computer, Inc. : unknown product (05ac:0203) + : /sys/devices/pci0000:00/0000:00:1f.2/usb1/1-2/1-2.2/1-2.2.1 + : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) + : 0 - Human Interface Devices / Boot Interface Subclass / Keyboard (03/01/01) + + 1-2.2.3: OmniVision Technologies, Inc. : OV511+ WebCam (05a9:a511) + : /sys/devices/pci0000:00/0000:00:1f.2/usb1/1-2/1-2.2/1-2.2.3 + : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) + : 0 - Vendor Specific Class / unknown subclass / unknown protocol (ff/00/00) + + 3-1: Logitech, Inc. : QuickCam Pro 4000 (046d:08b2) + : /sys/devices/pci0000:00/0000:00:1e.0/0000:02:0a.0/usb3/3-1 + : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) + : 0 - Data / unknown subclass / unknown protocol (0a/ff/00) + : 1 - Audio / Control Device / unknown protocol (01/01/00) + : 2 - Audio / Streaming / unknown protocol (01/02/00) + +Attach a remote USB device: + + deux:# usbip attach --host 10.0.0.3 --busid 1-1 + port 0 attached + +Show the devices attached to this client: + + deux:# usbip port + Port 00: at Full Speed(12Mbps) + Prolific Technology, Inc. : unknown product (067b:3507) + 6-1 -> usbip://10.0.0.3:3240/1-1 (remote bus/dev 001/004) + 6-1:1.0 used by usb-storage + /sys/class/scsi_device/0:0:0:0/device + /sys/class/scsi_host/host0/device + /sys/block/sda/device + +Detach the imported device: + + deux:# usbip detach --port 0 + port 0 detached --------------------------------------------------------------------------------------------------------- -- CLIENT SIDE ------------------------------------------------------------------------------------------ --------------------------------------------------------------------------------------------------------- -First, let's list available remote devices which are marked as exportable in -the server host. - - deux:# insmod (somewhere)/usbip-core.ko - deux:# insmod (somewhere)/vhci_hcd.ko - - deux:# usbip --list 10.0.0.3 - - 10.0.0.3 - 1-1: Prolific Technology, Inc. : unknown product (067b:3507) - : /sys/devices/pci0000:00/0000:00:1f.2/usb1/1-1 - : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) - : 0 - Mass Storage / SCSI / Bulk (Zip) (08/06/50) - - 1-2.2.1: Apple Computer, Inc. : unknown product (05ac:0203) - : /sys/devices/pci0000:00/0000:00:1f.2/usb1/1-2/1-2.2/1-2.2.1 - : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) - : 0 - Human Interface Devices / Boot Interface Subclass / Keyboard (03/01/01) - - 1-2.2.3: OmniVision Technologies, Inc. : OV511+ WebCam (05a9:a511) - : /sys/devices/pci0000:00/0000:00:1f.2/usb1/1-2/1-2.2/1-2.2.3 - : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) - : 0 - Vendor Specific Class / unknown subclass / unknown protocol (ff/00/00) - - 3-1: Logitech, Inc. : QuickCam Pro 4000 (046d:08b2) - : /sys/devices/pci0000:00/0000:00:1e.0/0000:02:0a.0/usb3/3-1 - : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) - : 0 - Data / unknown subclass / unknown protocol (0a/ff/00) - : 1 - Audio / Control Device / unknown protocol (01/01/00) - : 2 - Audio / Streaming / unknown protocol (01/02/00) - - 4-1: Logitech, Inc. : QuickCam Express (046d:0870) - : /sys/devices/pci0000:00/0000:00:1e.0/0000:02:0a.1/usb4/4-1 - : Vendor Specific Class / Vendor Specific Subclass / Vendor Specific Protocol (ff/ff/ff) - : 0 - Vendor Specific Class / Vendor Specific Subclass / Vendor Specific Protocol (ff/ff/ff) - - 4-2: Texas Instruments Japan : unknown product (08bb:2702) - : /sys/devices/pci0000:00/0000:00:1e.0/0000:02:0a.1/usb4/4-2 - : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00) - : 0 - Audio / Control Device / unknown protocol (01/01/00) - : 1 - Audio / Streaming / unknown protocol (01/02/00) - --------------------------------------------------------------------------------------------------------- -Attach a remote usb device! - - deux:# usbip --attach 10.0.0.3 1-1 - port 0 attached - --------------------------------------------------------------------------------------------------------- -Show what devices are attached to this client. - - deux:# usbip --port - Port 00: at Full Speed(12Mbps) - Prolific Technology, Inc. : unknown product (067b:3507) - 6-1 -> usbip://10.0.0.3:3240/1-1 (remote bus/dev 001/004) - 6-1:1.0 used by usb-storage - /sys/class/scsi_device/0:0:0:0/device - /sys/class/scsi_host/host0/device - /sys/block/sda/device - --------------------------------------------------------------------------------------------------------- -Detach the imported device. - - deux:# usbip --detach 0 - port 0 detached - --------------------------------------------------------------------------------------------------------- - - -[Check List] - - See Debug Tips in the project wiki. - - http://usbip.wiki.sourceforge.net/how-to-debug-usbip +[Checklist] + - See 'Debug Tips' on the project wiki. + - http://usbip.wiki.sourceforge.net/how-to-debug-usbip - usbip-host.ko must be bound to the target device. - - See /proc/bus/usb/devices and find "Driver=..." lines of the device. + - See /proc/bus/usb/devices and find "Driver=..." lines of the device. - Shutdown firewall. - - usbip now uses TCP port 3240. + - usbip now uses TCP port 3240. - Disable SELinux. - - If possible, compile your kernel with CONFIG_USB_DEBUG flag and try - again. - - Check your kernel and daemon messages. - ex. /var/log/{messages, kern.log, daemon.log, syslog} + - If possible, compile your kernel with CONFIG_USB_DEBUG flag and try again. + - Check the kernel and daemon messages. [Contact] - Mailing List: usbip-devel _at_ lists.sourceforge.net + Mailing List: linux-usb@vger.kernel.org diff --git a/drivers/staging/usbip/userspace/cleanup.sh b/drivers/staging/usbip/userspace/cleanup.sh index da2f89bd17c6..955c3ccb729a 100755 --- a/drivers/staging/usbip/userspace/cleanup.sh +++ b/drivers/staging/usbip/userspace/cleanup.sh @@ -1,10 +1,12 @@ -#!/bin/sh -x - +#!/bin/sh if [ -r Makefile ]; then make distclean fi -FILES="configure cscope.out Makefile.in depcomp compile config.guess config.sub config.h.in~ config.log config.status ltmain.sh libtool config.h.in autom4te.cache missing aclocal.m4 install-sh cmd/Makefile.in lib/Makefile.in Makefile lib/Makefile cmd/Makefile" +FILES="aclocal.m4 autom4te.cache compile config.guess config.h.in config.log \ + config.status config.sub configure cscope.out depcomp install-sh \ + libsrc/Makefile libsrc/Makefile.in libtool ltmain.sh Makefile \ + Makefile.in missing src/Makefile src/Makefile.in" -rm -Rf $FILES +rm -vRf $FILES diff --git a/drivers/staging/usbip/userspace/configure.ac b/drivers/staging/usbip/userspace/configure.ac index e3afa159116a..bf5cf49cb554 100644 --- a/drivers/staging/usbip/userspace/configure.ac +++ b/drivers/staging/usbip/userspace/configure.ac @@ -1,8 +1,8 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([usbip], [0.1.8], [usbip-devel@lists.sourceforge.net]) -AC_DEFINE([USBIP_VERSION], [0x000106], [numeric version number]) +AC_INIT([usbip-utils], [1.1.1], [linux-usb@vger.kernel.org]) +AC_DEFINE([USBIP_VERSION], [0x00000111], [binary-coded decimal version number]) CURRENT=0 REVISION=1 @@ -29,7 +29,7 @@ AC_PROG_MAKE_SET AC_HEADER_DIRENT AC_HEADER_STDC AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h stdlib.h dnl - string.h strings.h sys/socket.h syslog.h unistd.h]) + string.h sys/socket.h syslog.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_INT32_T @@ -41,7 +41,7 @@ AC_TYPE_UINT8_T # Checks for library functions. AC_FUNC_REALLOC -AC_CHECK_FUNCS([bzero memset mkdir regcomp socket strchr strerror strstr dnl +AC_CHECK_FUNCS([memset mkdir regcomp socket strchr strerror strstr dnl strtoul]) AC_CHECK_HEADER([sysfs/libsysfs.h], @@ -85,26 +85,12 @@ AC_ARG_WITH([tcp-wrappers], [AC_MSG_RESULT([no]); LIBS="$saved_LIBS"])]) # Sets directory containing usb.ids. -USBIDS_DIR='${datadir}/usbip' AC_ARG_WITH([usbids-dir], [AS_HELP_STRING([--with-usbids-dir=DIR], - [where usb.ids is found (default ${datadir}/usbip)])], - [USBIDS_DIR=$withval]) + [where usb.ids is found (default /usr/share/hwdata/)])], + [USBIDS_DIR=$withval], [USBIDS_DIR="/usr/share/hwdata/"]) AC_SUBST([USBIDS_DIR]) -dnl FIXME: when disabled, empty directry is created -usbids=install -AC_ARG_ENABLE([usbids-install], - [AS_HELP_STRING([--enable-usbids-install], - [install usb.ids (default)])], - [AS_CASE([$enableval], - [yes], [usbids=install], - [no], [usbids=notinstall], - [AC_MSG_ERROR( - [bad value ${enableval} for --enable-usbids-install])] - )]) -AM_CONDITIONAL([INSTALL_USBIDS], [test x$usbids = xinstall]) - GLIB2_REQUIRED=2.6.0 PKG_CHECK_MODULES([PACKAGE], [glib-2.0 >= $GLIB2_REQUIRED]) AC_SUBST([PACKAGE_CFLAGS]) diff --git a/drivers/staging/usbip/userspace/libsrc/Makefile.am b/drivers/staging/usbip/userspace/libsrc/Makefile.am index 77ecf6b844b7..4921189e0260 100644 --- a/drivers/staging/usbip/userspace/libsrc/Makefile.am +++ b/drivers/staging/usbip/userspace/libsrc/Makefile.am @@ -1,7 +1,7 @@ -libusbip_la_CPPFLAGS := -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"' -libusbip_la_CFLAGS := @EXTRA_CFLAGS@ -libusbip_la_LDFLAGS := -version-info @LIBUSBIP_VERSION@ +libusbip_la_CPPFLAGS = -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"' +libusbip_la_CFLAGS = @EXTRA_CFLAGS@ +libusbip_la_LDFLAGS = -version-info @LIBUSBIP_VERSION@ lib_LTLIBRARIES := libusbip.la -libusbip_la_SOURCES := names.c names.h stub_driver.c stub_driver.h usbip.h \ +libusbip_la_SOURCES := names.c names.h usbip_host_driver.c usbip_host_driver.h \ usbip_common.c usbip_common.h vhci_driver.c vhci_driver.h diff --git a/drivers/staging/usbip/userspace/libsrc/stub_driver.c b/drivers/staging/usbip/userspace/libsrc/stub_driver.c deleted file mode 100644 index cc3364345f5f..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/stub_driver.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (C) 2005-2007 Takahiro Hirofuchi - */ - -#include -#include -#include - -#include "usbip.h" - -/* kernel module name */ -static const char *usbip_stub_driver_name = "usbip-host"; - - -struct usbip_stub_driver *stub_driver; - -static struct sysfs_driver *open_sysfs_stub_driver(void) -{ - int ret; - - char sysfs_mntpath[SYSFS_PATH_MAX]; - char stub_driver_path[SYSFS_PATH_MAX]; - struct sysfs_driver *stub_driver; - - - ret = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX); - if (ret < 0) { - err("sysfs must be mounted"); - return NULL; - } - - snprintf(stub_driver_path, SYSFS_PATH_MAX, "%s/%s/usb/%s/%s", - sysfs_mntpath, SYSFS_BUS_NAME, SYSFS_DRIVERS_NAME, - usbip_stub_driver_name); - - stub_driver = sysfs_open_driver_path(stub_driver_path); - if (!stub_driver) { - err("usbip-core.ko and usbip-host.ko must be loaded"); - return NULL; - } - - return stub_driver; -} - - -#define SYSFS_OPEN_RETRIES 100 - -/* only the first interface value is true! */ -static int32_t read_attr_usbip_status(struct usb_device *udev) -{ - char attrpath[SYSFS_PATH_MAX]; - struct sysfs_attribute *attr; - int value = 0; - int ret; - struct stat s; - int retries = SYSFS_OPEN_RETRIES; - - /* This access is racy! - * - * Just after detach, our driver removes the sysfs - * files and recreates them. - * - * We may try and fail to open the usbip_status of - * an exported device in the (short) window where - * it has been removed and not yet recreated. - * - * This is a bug in the interface. Nothing we can do - * except work around it here by polling for the sysfs - * usbip_status to reappear. - */ - - snprintf(attrpath, SYSFS_PATH_MAX, "%s/%s:%d.%d/usbip_status", - udev->path, udev->busid, - udev->bConfigurationValue, - 0); - - while (retries > 0) { - if (stat(attrpath, &s) == 0) - break; - - if (errno != ENOENT) { - err("error stat'ing %s", attrpath); - return -1; - } - - usleep(10000); /* 10ms */ - retries--; - } - - if (retries == 0) - err("usbip_status not ready after %d retries", - SYSFS_OPEN_RETRIES); - else if (retries < SYSFS_OPEN_RETRIES) - info("warning: usbip_status ready after %d retries", - SYSFS_OPEN_RETRIES - retries); - - attr = sysfs_open_attribute(attrpath); - if (!attr) { - err("open %s", attrpath); - return -1; - } - - ret = sysfs_read_attribute(attr); - if (ret) { - err("read %s", attrpath); - sysfs_close_attribute(attr); - return -1; - } - - value = atoi(attr->value); - - sysfs_close_attribute(attr); - - return value; -} - - -static void usbip_exported_device_delete(void *dev) -{ - struct usbip_exported_device *edev = - (struct usbip_exported_device *) dev; - - sysfs_close_device(edev->sudev); - free(dev); -} - - -static struct usbip_exported_device *usbip_exported_device_new(char *sdevpath) -{ - struct usbip_exported_device *edev = NULL; - - edev = (struct usbip_exported_device *) calloc(1, sizeof(*edev)); - if (!edev) { - err("alloc device"); - return NULL; - } - - edev->sudev = sysfs_open_device_path(sdevpath); - if (!edev->sudev) { - err("open %s", sdevpath); - goto err; - } - - read_usb_device(edev->sudev, &edev->udev); - - edev->status = read_attr_usbip_status(&edev->udev); - if (edev->status < 0) - goto err; - - /* reallocate buffer to include usb interface data */ - size_t size = sizeof(*edev) + edev->udev.bNumInterfaces * sizeof(struct usb_interface); - edev = (struct usbip_exported_device *) realloc(edev, size); - if (!edev) { - err("alloc device"); - goto err; - } - - for (int i=0; i < edev->udev.bNumInterfaces; i++) - read_usb_interface(&edev->udev, i, &edev->uinf[i]); - - return edev; - -err: - if (edev && edev->sudev) - sysfs_close_device(edev->sudev); - if (edev) - free(edev); - return NULL; -} - - -static int check_new(struct dlist *dlist, struct sysfs_device *target) -{ - struct sysfs_device *dev; - - dlist_for_each_data(dlist, dev, struct sysfs_device) { - if (!strncmp(dev->bus_id, target->bus_id, SYSFS_BUS_ID_SIZE)) - /* found. not new */ - return 0; - } - - return 1; -} - -static void delete_nothing(void *dev __attribute__((unused))) -{ - /* do not delete anything. but, its container will be deleted. */ -} - -static int refresh_exported_devices(void) -{ - struct sysfs_device *suinf; /* sysfs_device of usb_interface */ - struct dlist *suinf_list; - - struct sysfs_device *sudev; /* sysfs_device of usb_device */ - struct dlist *sudev_list; - - - sudev_list = dlist_new_with_delete(sizeof(struct sysfs_device), delete_nothing); - - suinf_list = sysfs_get_driver_devices(stub_driver->sysfs_driver); - if (!suinf_list) { - printf("Bind usbip-host.ko to a usb device to be exportable!\n"); - goto bye; - } - - /* collect unique USB devices (not interfaces) */ - dlist_for_each_data(suinf_list, suinf, struct sysfs_device) { - - /* get usb device of this usb interface */ - sudev = sysfs_get_device_parent(suinf); - if (!sudev) { - err("get parent dev of %s", suinf->name); - continue; - } - - if (check_new(sudev_list, sudev)) { - dlist_unshift(sudev_list, sudev); - } - } - - dlist_for_each_data(sudev_list, sudev, struct sysfs_device) { - struct usbip_exported_device *edev; - - edev = usbip_exported_device_new(sudev->path); - if (!edev) { - err("usbip_exported_device new"); - continue; - } - - dlist_unshift(stub_driver->edev_list, (void *) edev); - stub_driver->ndevs++; - } - - - dlist_destroy(sudev_list); - -bye: - - return 0; -} - -int usbip_stub_refresh_device_list(void) -{ - int ret; - - if (stub_driver->edev_list) - dlist_destroy(stub_driver->edev_list); - - stub_driver->ndevs = 0; - - stub_driver->edev_list = dlist_new_with_delete(sizeof(struct usbip_exported_device), - usbip_exported_device_delete); - if (!stub_driver->edev_list) { - err("alloc dlist"); - return -1; - } - - ret = refresh_exported_devices(); - if (ret < 0) - return ret; - - return 0; -} - -int usbip_stub_driver_open(void) -{ - int ret; - - - stub_driver = (struct usbip_stub_driver *) calloc(1, sizeof(*stub_driver)); - if (!stub_driver) { - err("alloc stub_driver"); - return -1; - } - - stub_driver->ndevs = 0; - - stub_driver->edev_list = dlist_new_with_delete(sizeof(struct usbip_exported_device), - usbip_exported_device_delete); - if (!stub_driver->edev_list) { - err("alloc dlist"); - goto err; - } - - stub_driver->sysfs_driver = open_sysfs_stub_driver(); - if (!stub_driver->sysfs_driver) - goto err; - - ret = refresh_exported_devices(); - if (ret < 0) - goto err; - - return 0; - - -err: - if (stub_driver->sysfs_driver) - sysfs_close_driver(stub_driver->sysfs_driver); - if (stub_driver->edev_list) - dlist_destroy(stub_driver->edev_list); - free(stub_driver); - - stub_driver = NULL; - return -1; -} - - -void usbip_stub_driver_close(void) -{ - if (!stub_driver) - return; - - if (stub_driver->edev_list) - dlist_destroy(stub_driver->edev_list); - if (stub_driver->sysfs_driver) - sysfs_close_driver(stub_driver->sysfs_driver); - free(stub_driver); - - stub_driver = NULL; -} - -int usbip_stub_export_device(struct usbip_exported_device *edev, int sockfd) -{ - char attrpath[SYSFS_PATH_MAX]; - struct sysfs_attribute *attr; - char sockfd_buff[30]; - int ret; - - - if (edev->status != SDEV_ST_AVAILABLE) { - info("device not available, %s", edev->udev.busid); - switch( edev->status ) { - case SDEV_ST_ERROR: - info(" status SDEV_ST_ERROR"); - break; - case SDEV_ST_USED: - info(" status SDEV_ST_USED"); - break; - default: - info(" status unknown: 0x%x", edev->status); - } - return -1; - } - - /* only the first interface is true */ - snprintf(attrpath, sizeof(attrpath), "%s/%s:%d.%d/%s", - edev->udev.path, - edev->udev.busid, - edev->udev.bConfigurationValue, 0, - "usbip_sockfd"); - - attr = sysfs_open_attribute(attrpath); - if (!attr) { - err("open %s", attrpath); - return -1; - } - - snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd); - - dbg("write: %s", sockfd_buff); - - ret = sysfs_write_attribute(attr, sockfd_buff, strlen(sockfd_buff)); - if (ret < 0) { - err("write sockfd %s to %s", sockfd_buff, attrpath); - goto err_write_sockfd; - } - - info("connect %s", edev->udev.busid); - -err_write_sockfd: - sysfs_close_attribute(attr); - - return ret; -} - -struct usbip_exported_device *usbip_stub_get_device(int num) -{ - struct usbip_exported_device *edev; - struct dlist *dlist = stub_driver->edev_list; - int count = 0; - - dlist_for_each_data(dlist, edev, struct usbip_exported_device) { - if (num == count) - return edev; - else - count++ ; - } - - return NULL; -} diff --git a/drivers/staging/usbip/userspace/libsrc/stub_driver.h b/drivers/staging/usbip/userspace/libsrc/stub_driver.h deleted file mode 100644 index 3107d18de65a..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/stub_driver.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2005-2007 Takahiro Hirofuchi - */ - -#ifndef _USBIP_STUB_DRIVER_H -#define _USBIP_STUB_DRIVER_H - -#include "usbip.h" - - -struct usbip_stub_driver { - int ndevs; - struct sysfs_driver *sysfs_driver; - - struct dlist *edev_list; /* list of exported device */ -}; - -struct usbip_exported_device { - struct sysfs_device *sudev; - - int32_t status; - struct usb_device udev; - struct usb_interface uinf[]; -}; - - -extern struct usbip_stub_driver *stub_driver; - -int usbip_stub_driver_open(void); -void usbip_stub_driver_close(void); - -int usbip_stub_refresh_device_list(void); -int usbip_stub_export_device(struct usbip_exported_device *edev, int sockfd); - -struct usbip_exported_device *usbip_stub_get_device(int num); -#endif diff --git a/drivers/staging/usbip/userspace/libsrc/usbip.h b/drivers/staging/usbip/userspace/libsrc/usbip.h deleted file mode 100644 index 7cb8e6fef35d..000000000000 --- a/drivers/staging/usbip/userspace/libsrc/usbip.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2005-2007 Takahiro Hirofuchi - */ - -#ifndef _USBIP_H -#define _USBIP_H - -#ifdef HAVE_CONFIG_H -#include "../config.h" -#endif - -#include "usbip_common.h" -#include "stub_driver.h" -#include "vhci_driver.h" -#ifdef DMALLOC -#include -#endif - -#endif diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.c b/drivers/staging/usbip/userspace/libsrc/usbip_common.c index a128a924b27e..154b4b1103ec 100644 --- a/drivers/staging/usbip/userspace/libsrc/usbip_common.c +++ b/drivers/staging/usbip/userspace/libsrc/usbip_common.c @@ -2,9 +2,12 @@ * Copyright (C) 2005-2007 Takahiro Hirofuchi */ -#include "usbip.h" +#include "usbip_common.h" #include "names.h" +#undef PROGNAME +#define PROGNAME "libusbip" + int usbip_use_syslog = 0; int usbip_use_stderr = 0; int usbip_use_debug = 0; @@ -64,7 +67,7 @@ const char *usbip_speed_string(int num) #define DBG_UINF_INTEGER(name)\ dbg("%-20s = %x", to_string(name), (int) uinf->name) -void dump_usb_interface(struct usb_interface *uinf) +void dump_usb_interface(struct usbip_usb_interface *uinf) { char buff[100]; usbip_names_get_class(buff, sizeof(buff), @@ -74,7 +77,7 @@ void dump_usb_interface(struct usb_interface *uinf) dbg("%-20s = %s", "Interface(C/SC/P)", buff); } -void dump_usb_device(struct usb_device *udev) +void dump_usb_device(struct usbip_usb_device *udev) { char buff[100]; @@ -117,19 +120,19 @@ int read_attr_value(struct sysfs_device *dev, const char *name, const char *form attr = sysfs_open_attribute(attrpath); if (!attr) { - err("open attr %s", attrpath); + dbg("sysfs_open_attribute failed: %s", attrpath); return 0; } ret = sysfs_read_attribute(attr); if (ret < 0) { - err("read attr"); + dbg("sysfs_read_attribute failed"); goto err; } ret = sscanf(attr->value, format, &num); if (ret < 1) { - err("sscanf"); + dbg("sscanf failed"); goto err; } @@ -151,19 +154,19 @@ int read_attr_speed(struct sysfs_device *dev) attr = sysfs_open_attribute(attrpath); if (!attr) { - err("open attr"); + dbg("sysfs_open_attribute failed: %s", attrpath); return 0; } ret = sysfs_read_attribute(attr); if (ret < 0) { - err("read attr"); + dbg("sysfs_read_attribute failed"); goto err; } ret = sscanf(attr->value, "%s\n", speed); if (ret < 1) { - err("sscanf"); + dbg("sscanf failed"); goto err; } err: @@ -181,7 +184,7 @@ int read_attr_speed(struct sysfs_device *dev) do { (object)->name = (type) read_attr_value(dev, to_string(name), format); } while (0) -int read_usb_device(struct sysfs_device *sdev, struct usb_device *udev) +int read_usb_device(struct sysfs_device *sdev, struct usbip_usb_device *udev) { uint32_t busnum, devnum; @@ -209,7 +212,8 @@ int read_usb_device(struct sysfs_device *sdev, struct usb_device *udev) return 0; } -int read_usb_interface(struct usb_device *udev, int i, struct usb_interface *uinf) +int read_usb_interface(struct usbip_usb_device *udev, int i, + struct usbip_usb_interface *uinf) { char busid[SYSFS_BUS_ID_SIZE]; struct sysfs_device *sif; @@ -218,7 +222,7 @@ int read_usb_interface(struct usb_device *udev, int i, struct usb_interface *uin sif = sysfs_open_device("usb", busid); if (!sif) { - err("open sif of %s", busid); + dbg("sysfs_open_device(\"usb\", \"%s\") failed", busid); return -1; } diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.h b/drivers/staging/usbip/userspace/libsrc/usbip_common.h index c254b5481f7c..eedefbd12ea6 100644 --- a/drivers/staging/usbip/userspace/libsrc/usbip_common.h +++ b/drivers/staging/usbip/userspace/libsrc/usbip_common.h @@ -2,21 +2,18 @@ * Copyright (C) 2005-2007 Takahiro Hirofuchi */ -#ifndef _USBIP_COMMON_H -#define _USBIP_COMMON_H - -#include -#include -#include -#include -#include -#include -#include -#include +#ifndef __USBIP_COMMON_H +#define __USBIP_COMMON_H #include -#include -#include + +#include +#include +#include +#include + +#include +#include #ifndef USBIDS_FILE #define USBIDS_FILE "/usr/share/hwdata/usb.ids" @@ -26,7 +23,59 @@ #define VHCI_STATE_PATH "/var/run/vhci_hcd" #endif -//#include +/* kernel module names */ +#define USBIP_CORE_MOD_NAME "usbip-core" +#define USBIP_HOST_DRV_NAME "usbip-host" +#define USBIP_VHCI_DRV_NAME "vhci_hcd" + +extern int usbip_use_syslog; +extern int usbip_use_stderr; +extern int usbip_use_debug ; + +#define PROGNAME "usbip" + +#define pr_fmt(fmt) "%s: %s: " fmt "\n", PROGNAME +#define dbg_fmt(fmt) pr_fmt("%s:%d:[%s] " fmt), "debug", \ + __FILE__, __LINE__, __FUNCTION__ + +#define err(fmt, args...) \ + do { \ + if (usbip_use_syslog) { \ + syslog(LOG_ERR, pr_fmt(fmt), "error", ##args); \ + } \ + if (usbip_use_stderr) { \ + fprintf(stderr, pr_fmt(fmt), "error", ##args); \ + } \ + } while (0) + +#define info(fmt, args...) \ + do { \ + if (usbip_use_syslog) { \ + syslog(LOG_INFO, pr_fmt(fmt), "info", ##args); \ + } \ + if (usbip_use_stderr) { \ + fprintf(stderr, pr_fmt(fmt), "info", ##args); \ + } \ + } while (0) + +#define dbg(fmt, args...) \ + do { \ + if (usbip_use_debug) { \ + if (usbip_use_syslog) { \ + syslog(LOG_DEBUG, dbg_fmt(fmt), ##args); \ + } \ + if (usbip_use_stderr) { \ + fprintf(stderr, dbg_fmt(fmt), ##args); \ + } \ + } \ + } while (0) + +#define BUG() \ + do { \ + err("sorry, it's a bug!"); \ + abort(); \ + } while (0) + enum usb_device_speed { USB_SPEED_UNKNOWN = 0, /* enumerating */ USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */ @@ -51,66 +100,14 @@ enum usbip_device_status{ VDEV_ST_ERROR }; -extern int usbip_use_syslog; -extern int usbip_use_stderr; -extern int usbip_use_debug ; - -#define err(fmt, args...) do { \ - if (usbip_use_syslog) { \ - syslog(LOG_ERR, "usbip err: %13s:%4d (%-12s) " fmt "\n", \ - __FILE__, __LINE__, __FUNCTION__, ##args); \ - } \ - if (usbip_use_stderr) { \ - fprintf(stderr, "usbip err: %13s:%4d (%-12s) " fmt "\n", \ - __FILE__, __LINE__, __FUNCTION__, ##args); \ - } \ -} while (0) - -#define notice(fmt, args...) do { \ - if (usbip_use_syslog) { \ - syslog(LOG_DEBUG, "usbip: " fmt, ##args); \ - } \ - if (usbip_use_stderr) { \ - fprintf(stderr, "usbip: " fmt "\n", ##args); \ - } \ -} while (0) - -#define info(fmt, args...) do { \ - if (usbip_use_syslog) { \ - syslog(LOG_DEBUG, fmt, ##args); \ - } \ - if (usbip_use_stderr) { \ - fprintf(stderr, fmt "\n", ##args); \ - } \ -} while (0) - -#define dbg(fmt, args...) do { \ - if (usbip_use_debug) { \ - if (usbip_use_syslog) { \ - syslog(LOG_DEBUG, "usbip dbg: %13s:%4d (%-12s) " fmt, \ - __FILE__, __LINE__, __FUNCTION__, ##args); \ - } \ - if (usbip_use_stderr) { \ - fprintf(stderr, "usbip dbg: %13s:%4d (%-12s) " fmt "\n", \ - __FILE__, __LINE__, __FUNCTION__, ##args); \ - } \ - } \ -} while (0) - - -#define BUG() do { err("sorry, it's a bug"); abort(); } while (0) - - -struct usb_interface { +struct usbip_usb_interface { uint8_t bInterfaceClass; uint8_t bInterfaceSubClass; uint8_t bInterfaceProtocol; uint8_t padding; /* alignment */ } __attribute__((packed)); - - -struct usb_device { +struct usbip_usb_device { char path[SYSFS_PATH_MAX]; char busid[SYSFS_BUS_ID_SIZE]; @@ -132,11 +129,12 @@ struct usb_device { #define to_string(s) #s -void dump_usb_interface(struct usb_interface *); -void dump_usb_device(struct usb_device *); -int read_usb_device(struct sysfs_device *sdev, struct usb_device *udev); +void dump_usb_interface(struct usbip_usb_interface *); +void dump_usb_device(struct usbip_usb_device *); +int read_usb_device(struct sysfs_device *sdev, struct usbip_usb_device *udev); int read_attr_value(struct sysfs_device *dev, const char *name, const char *format); -int read_usb_interface(struct usb_device *udev, int i, struct usb_interface *uinf); +int read_usb_interface(struct usbip_usb_device *udev, int i, + struct usbip_usb_interface *uinf); const char *usbip_speed_string(int num); const char *usbip_status_string(int32_t status); @@ -146,4 +144,4 @@ void usbip_names_free(void); void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, uint16_t product); void usbip_names_get_class(char *buff, size_t size, uint8_t class, uint8_t subclass, uint8_t protocol); -#endif +#endif /* __USBIP_COMMON_H */ diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c new file mode 100644 index 000000000000..71a449cf50db --- /dev/null +++ b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c @@ -0,0 +1,401 @@ +/* + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi + * + * 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, see . + */ + +#include +#include + +#include +#include + +#include "usbip_common.h" +#include "usbip_host_driver.h" + +#undef PROGNAME +#define PROGNAME "libusbip" + +struct usbip_host_driver *host_driver; + +#define SYSFS_OPEN_RETRIES 100 + +/* only the first interface value is true! */ +static int32_t read_attr_usbip_status(struct usbip_usb_device *udev) +{ + char attrpath[SYSFS_PATH_MAX]; + struct sysfs_attribute *attr; + int value = 0; + int rc; + struct stat s; + int retries = SYSFS_OPEN_RETRIES; + + /* This access is racy! + * + * Just after detach, our driver removes the sysfs + * files and recreates them. + * + * We may try and fail to open the usbip_status of + * an exported device in the (short) window where + * it has been removed and not yet recreated. + * + * This is a bug in the interface. Nothing we can do + * except work around it here by polling for the sysfs + * usbip_status to reappear. + */ + + snprintf(attrpath, SYSFS_PATH_MAX, "%s/%s:%d.%d/usbip_status", + udev->path, udev->busid, udev->bConfigurationValue, 0); + + while (retries > 0) { + if (stat(attrpath, &s) == 0) + break; + + if (errno != ENOENT) { + dbg("stat failed: %s", attrpath); + return -1; + } + + usleep(10000); /* 10ms */ + retries--; + } + + if (retries == 0) + dbg("usbip_status not ready after %d retries", + SYSFS_OPEN_RETRIES); + else if (retries < SYSFS_OPEN_RETRIES) + dbg("warning: usbip_status ready after %d retries", + SYSFS_OPEN_RETRIES - retries); + + attr = sysfs_open_attribute(attrpath); + if (!attr) { + dbg("sysfs_open_attribute failed: %s", attrpath); + return -1; + } + + rc = sysfs_read_attribute(attr); + if (rc) { + dbg("sysfs_read_attribute failed: %s", attrpath); + sysfs_close_attribute(attr); + return -1; + } + + value = atoi(attr->value); + + sysfs_close_attribute(attr); + + return value; +} + +static struct usbip_exported_device *usbip_exported_device_new(char *sdevpath) +{ + struct usbip_exported_device *edev = NULL; + size_t size; + int i; + + edev = calloc(1, sizeof(*edev)); + if (!edev) { + dbg("calloc failed"); + return NULL; + } + + edev->sudev = sysfs_open_device_path(sdevpath); + if (!edev->sudev) { + dbg("sysfs_open_device_path failed: %s", sdevpath); + goto err; + } + + read_usb_device(edev->sudev, &edev->udev); + + edev->status = read_attr_usbip_status(&edev->udev); + if (edev->status < 0) + goto err; + + /* reallocate buffer to include usb interface data */ + size = sizeof(*edev) + edev->udev.bNumInterfaces * + sizeof(struct usbip_usb_interface); + + edev = realloc(edev, size); + if (!edev) { + dbg("realloc failed"); + goto err; + } + + for (i = 0; i < edev->udev.bNumInterfaces; i++) + read_usb_interface(&edev->udev, i, &edev->uinf[i]); + + return edev; +err: + if (edev && edev->sudev) + sysfs_close_device(edev->sudev); + if (edev) + free(edev); + + return NULL; +} + +static int check_new(struct dlist *dlist, struct sysfs_device *target) +{ + struct sysfs_device *dev; + + dlist_for_each_data(dlist, dev, struct sysfs_device) { + if (!strncmp(dev->bus_id, target->bus_id, SYSFS_BUS_ID_SIZE)) + /* device found and is not new */ + return 0; + } + return 1; +} + +static void delete_nothing(void *unused_data) +{ + /* + * NOTE: Do not delete anything, but the container will be deleted. + */ + (void) unused_data; +} + +static int refresh_exported_devices(void) +{ + /* sysfs_device of usb_interface */ + struct sysfs_device *suintf; + struct dlist *suintf_list; + /* sysfs_device of usb_device */ + struct sysfs_device *sudev; + struct dlist *sudev_list; + struct usbip_exported_device *edev; + + sudev_list = dlist_new_with_delete(sizeof(struct sysfs_device), + delete_nothing); + + suintf_list = sysfs_get_driver_devices(host_driver->sysfs_driver); + if (!suintf_list) { + /* + * Not an error condition. There are simply no devices bound to + * the driver yet. + */ + dbg("bind " USBIP_HOST_DRV_NAME ".ko to a usb device to be " + "exportable!"); + return 0; + } + + /* collect unique USB devices (not interfaces) */ + dlist_for_each_data(suintf_list, suintf, struct sysfs_device) { + /* get usb device of this usb interface */ + sudev = sysfs_get_device_parent(suintf); + if (!sudev) { + dbg("sysfs_get_device_parent failed: %s", suintf->name); + continue; + } + + if (check_new(sudev_list, sudev)) { + /* insert item at head of list */ + dlist_unshift(sudev_list, sudev); + } + } + + dlist_for_each_data(sudev_list, sudev, struct sysfs_device) { + edev = usbip_exported_device_new(sudev->path); + if (!edev) { + dbg("usbip_exported_device_new failed"); + continue; + } + + dlist_unshift(host_driver->edev_list, edev); + host_driver->ndevs++; + } + + dlist_destroy(sudev_list); + + return 0; +} + +static struct sysfs_driver *open_sysfs_host_driver(void) +{ + char bus_type[] = "usb"; + char sysfs_mntpath[SYSFS_PATH_MAX]; + char host_drv_path[SYSFS_PATH_MAX]; + struct sysfs_driver *host_drv; + int rc; + + rc = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX); + if (rc < 0) { + dbg("sysfs_get_mnt_path failed"); + return NULL; + } + + snprintf(host_drv_path, SYSFS_PATH_MAX, "%s/%s/%s/%s/%s", + sysfs_mntpath, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME, + USBIP_HOST_DRV_NAME); + + host_drv = sysfs_open_driver_path(host_drv_path); + if (!host_drv) { + dbg("sysfs_open_driver_path failed"); + return NULL; + } + + return host_drv; +} + +static void usbip_exported_device_delete(void *dev) +{ + struct usbip_exported_device *edev = dev; + sysfs_close_device(edev->sudev); + free(dev); +} + +int usbip_host_driver_open(void) +{ + int rc; + + host_driver = calloc(1, sizeof(*host_driver)); + if (!host_driver) { + dbg("calloc failed"); + return -1; + } + + host_driver->ndevs = 0; + host_driver->edev_list = + dlist_new_with_delete(sizeof(struct usbip_exported_device), + usbip_exported_device_delete); + if (!host_driver->edev_list) { + dbg("dlist_new_with_delete failed"); + goto err_free_host_driver; + } + + host_driver->sysfs_driver = open_sysfs_host_driver(); + if (!host_driver->sysfs_driver) + goto err_destroy_edev_list; + + rc = refresh_exported_devices(); + if (rc < 0) + goto err_close_sysfs_driver; + + return 0; + +err_close_sysfs_driver: + sysfs_close_driver(host_driver->sysfs_driver); +err_destroy_edev_list: + dlist_destroy(host_driver->edev_list); +err_free_host_driver: + free(host_driver); + host_driver = NULL; + + return -1; +} + +void usbip_host_driver_close(void) +{ + if (!host_driver) + return; + + if (host_driver->edev_list) + dlist_destroy(host_driver->edev_list); + if (host_driver->sysfs_driver) + sysfs_close_driver(host_driver->sysfs_driver); + + free(host_driver); + host_driver = NULL; +} + +int usbip_host_refresh_device_list(void) +{ + int rc; + + if (host_driver->edev_list) + dlist_destroy(host_driver->edev_list); + + host_driver->ndevs = 0; + host_driver->edev_list = + dlist_new_with_delete(sizeof(struct usbip_exported_device), + usbip_exported_device_delete); + if (!host_driver->edev_list) { + dbg("dlist_new_with_delete failed"); + return -1; + } + + rc = refresh_exported_devices(); + if (rc < 0) + return -1; + + return 0; +} + +int usbip_host_export_device(struct usbip_exported_device *edev, int sockfd) +{ + char attr_name[] = "usbip_sockfd"; + char attr_path[SYSFS_PATH_MAX]; + struct sysfs_attribute *attr; + char sockfd_buff[30]; + int ret; + + if (edev->status != SDEV_ST_AVAILABLE) { + dbg("device not available: %s", edev->udev.busid); + switch (edev->status) { + case SDEV_ST_ERROR: + dbg("status SDEV_ST_ERROR"); + break; + case SDEV_ST_USED: + dbg("status SDEV_ST_USED"); + break; + default: + dbg("status unknown: 0x%x", edev->status); + } + return -1; + } + + /* only the first interface is true */ + snprintf(attr_path, sizeof(attr_path), "%s/%s:%d.%d/%s", + edev->udev.path, edev->udev.busid, + edev->udev.bConfigurationValue, 0, attr_name); + + attr = sysfs_open_attribute(attr_path); + if (!attr) { + dbg("sysfs_open_attribute failed: %s", attr_path); + return -1; + } + + snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd); + dbg("write: %s", sockfd_buff); + + ret = sysfs_write_attribute(attr, sockfd_buff, strlen(sockfd_buff)); + if (ret < 0) { + dbg("sysfs_write_attribute failed: sockfd %s to %s", + sockfd_buff, attr_path); + goto err_write_sockfd; + } + + dbg("connect: %s", edev->udev.busid); + +err_write_sockfd: + sysfs_close_attribute(attr); + + return ret; +} + +struct usbip_exported_device *usbip_host_get_device(int num) +{ + struct usbip_exported_device *edev; + struct dlist *dlist = host_driver->edev_list; + int cnt = 0; + + dlist_for_each_data(dlist, edev, struct usbip_exported_device) { + if (num == cnt) + return edev; + else + cnt++; + } + + return NULL; +} diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h new file mode 100644 index 000000000000..34fd14cbfc49 --- /dev/null +++ b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi + * + * 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, see . + */ + +#ifndef __USBIP_HOST_DRIVER_H +#define __USBIP_HOST_DRIVER_H + +#include +#include "usbip_common.h" + +struct usbip_host_driver { + int ndevs; + struct sysfs_driver *sysfs_driver; + /* list of exported device */ + struct dlist *edev_list; +}; + +struct usbip_exported_device { + struct sysfs_device *sudev; + int32_t status; + struct usbip_usb_device udev; + struct usbip_usb_interface uinf[]; +}; + +extern struct usbip_host_driver *host_driver; + +int usbip_host_driver_open(void); +void usbip_host_driver_close(void); + +int usbip_host_refresh_device_list(void); +int usbip_host_export_device(struct usbip_exported_device *edev, int sockfd); +struct usbip_exported_device *usbip_host_get_device(int num); + +#endif /* __USBIP_HOST_DRIVER_H */ diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c index db43f8d2eb80..abbc285f4339 100644 --- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c +++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c @@ -2,11 +2,11 @@ * Copyright (C) 2005-2007 Takahiro Hirofuchi */ +#include "usbip_common.h" +#include "vhci_driver.h" -#include "usbip.h" - - -static const char vhci_driver_name[] = "vhci_hcd"; +#undef PROGNAME +#define PROGNAME "libusbip" struct usbip_vhci_driver *vhci_driver; @@ -16,17 +16,19 @@ static struct usbip_imported_device *imported_device_init(struct usbip_imported_ sudev = sysfs_open_device("usb", busid); if (!sudev) { - err("sysfs_open_device %s", busid); + dbg("sysfs_open_device failed: %s", busid); goto err; } read_usb_device(sudev, &idev->udev); sysfs_close_device(sudev); /* add class devices of this imported device */ - struct class_device *cdev; - dlist_for_each_data(vhci_driver->cdev_list, cdev, struct class_device) { - if (!strncmp(cdev->devpath, idev->udev.path, strlen(idev->udev.path))) { - struct class_device *new_cdev; + struct usbip_class_device *cdev; + dlist_for_each_data(vhci_driver->cdev_list, cdev, + struct usbip_class_device) { + if (!strncmp(cdev->dev_path, idev->udev.path, + strlen(idev->udev.path))) { + struct usbip_class_device *new_cdev; /* alloc and copy because dlist is linked from only one list */ new_cdev = calloc(1, sizeof(*new_cdev)); @@ -53,7 +55,7 @@ static int parse_status(char *value) for (int i = 0; i < vhci_driver->nports; i++) - bzero(&vhci_driver->idev[i], sizeof(struct usbip_imported_device)); + memset(&vhci_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); /* skip a header line */ @@ -69,7 +71,7 @@ static int parse_status(char *value) &devid, &socket, lbusid); if (ret < 5) { - err("scanf %d", ret); + dbg("sscanf failed: %d", ret); BUG(); } @@ -90,16 +92,16 @@ static int parse_status(char *value) idev->busnum = (devid >> 16); idev->devnum = (devid & 0x0000ffff); - idev->cdev_list = dlist_new(sizeof(struct class_device)); + idev->cdev_list = dlist_new(sizeof(struct usbip_class_device)); if (!idev->cdev_list) { - err("init new device"); + dbg("dlist_new failed"); return -1; } if (idev->status != VDEV_ST_NULL && idev->status != VDEV_ST_NOTASSIGNED) { idev = imported_device_init(idev, lbusid); if (!idev) { - err("init new device"); + dbg("imported_device_init failed"); return -1; } } @@ -118,29 +120,29 @@ static int parse_status(char *value) static int check_usbip_device(struct sysfs_class_device *cdev) { - char clspath[SYSFS_PATH_MAX]; /* /sys/class/video4linux/video0/device */ - char devpath[SYSFS_PATH_MAX]; /* /sys/devices/platform/vhci_hcd/usb6/6-1:1.1 */ - + char class_path[SYSFS_PATH_MAX]; /* /sys/class/video4linux/video0/device */ + char dev_path[SYSFS_PATH_MAX]; /* /sys/devices/platform/vhci_hcd/usb6/6-1:1.1 */ int ret; + struct usbip_class_device *usbip_cdev; - snprintf(clspath, sizeof(clspath), "%s/device", cdev->path); + snprintf(class_path, sizeof(class_path), "%s/device", cdev->path); - ret = sysfs_get_link(clspath, devpath, SYSFS_PATH_MAX); - if (!ret) { - if (!strncmp(devpath, vhci_driver->hc_device->path, - strlen(vhci_driver->hc_device->path))) { + ret = sysfs_get_link(class_path, dev_path, sizeof(dev_path)); + if (ret == 0) { + if (!strncmp(dev_path, vhci_driver->hc_device->path, + strlen(vhci_driver->hc_device->path))) { /* found usbip device */ - struct class_device *cdev; - - cdev = calloc(1, sizeof(*cdev)); + usbip_cdev = calloc(1, sizeof(*usbip_cdev)); if (!cdev) { - err("calloc cdev"); + dbg("calloc failed"); return -1; } - dlist_unshift(vhci_driver->cdev_list, (void*) cdev); - strncpy(cdev->clspath, clspath, sizeof(cdev->clspath)); - strncpy(cdev->devpath, devpath, sizeof(cdev->clspath)); - dbg(" found %s %s", clspath, devpath); + dlist_unshift(vhci_driver->cdev_list, usbip_cdev); + strncpy(usbip_cdev->class_path, class_path, + sizeof(usbip_cdev->class_path)); + strncpy(usbip_cdev->dev_path, dev_path, + sizeof(usbip_cdev->dev_path)); + dbg("found: %s %s", class_path, dev_path); } } @@ -157,11 +159,11 @@ static int search_class_for_usbip_device(char *cname) class = sysfs_open_class(cname); if (!class) { - err("open class"); + dbg("sysfs_open_class failed"); return -1; } - dbg("class %s", class->name); + dbg("class: %s", class->name); cdev_list = sysfs_get_class_devices(class); if (!cdev_list) @@ -169,7 +171,7 @@ static int search_class_for_usbip_device(char *cname) goto out; dlist_for_each_data(cdev_list, cdev, struct sysfs_class_device) { - dbg(" cdev %s", cdev->name); + dbg("cdev: %s", cdev->name); ret = check_usbip_device(cdev); if (ret < 0) goto out; @@ -187,11 +189,22 @@ static int refresh_class_device_list(void) int ret; struct dlist *cname_list; char *cname; + char sysfs_mntpath[SYSFS_PATH_MAX]; + char class_path[SYSFS_PATH_MAX]; + + ret = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX); + if (ret < 0) { + dbg("sysfs_get_mnt_path failed"); + return -1; + } + + snprintf(class_path, sizeof(class_path), "%s/%s", sysfs_mntpath, + SYSFS_CLASS_NAME); /* search under /sys/class */ - cname_list = sysfs_open_directory_list("/sys/class"); + cname_list = sysfs_open_directory_list(class_path); if (!cname_list) { - err("open class directory"); + dbg("sysfs_open_directory failed"); return -1; } @@ -221,45 +234,42 @@ static int refresh_imported_device_list(void) attr_status = sysfs_get_device_attr(vhci_driver->hc_device, "status"); if (!attr_status) { - err("get attr %s of %s", "status", vhci_driver->hc_device->name); + dbg("sysfs_get_device_attr(\"status\") failed: %s", + vhci_driver->hc_device->name); return -1; } - dbg("name %s, path %s, len %d, method %d\n", attr_status->name, - attr_status->path, attr_status->len, attr_status->method); - - dbg("%s", attr_status->value); + dbg("name: %s path: %s len: %d method: %d value: %s", + attr_status->name, attr_status->path, attr_status->len, + attr_status->method, attr_status->value); return parse_status(attr_status->value); } static int get_nports(void) { + char *c; int nports = 0; struct sysfs_attribute *attr_status; attr_status = sysfs_get_device_attr(vhci_driver->hc_device, "status"); if (!attr_status) { - err("get attr %s of %s", "status", vhci_driver->hc_device->name); + dbg("sysfs_get_device_attr(\"status\") failed: %s", + vhci_driver->hc_device->name); return -1; } - dbg("name %s, path %s, len %d, method %d\n", attr_status->name, - attr_status->path, attr_status->len, attr_status->method); + dbg("name: %s path: %s len: %d method: %d value: %s", + attr_status->name, attr_status->path, attr_status->len, + attr_status->method, attr_status->value); - dbg("%s", attr_status->value); + /* skip a header line */ + c = strchr(attr_status->value, '\n') + 1; - { - char *c; - - /* skip a header line */ - c = strchr(attr_status->value, '\n') + 1; - - while (*c != '\0') { - /* go to the next line */ - c = strchr(c, '\n') + 1; - nports += 1; - } + while (*c != '\0') { + /* go to the next line */ + c = strchr(c, '\n') + 1; + nports += 1; } return nports; @@ -275,20 +285,21 @@ static int get_hc_busid(char *sysfs_mntpath, char *hc_busid) int found = 0; - snprintf(sdriver_path, SYSFS_PATH_MAX, "%s/%s/platform/%s/%s", - sysfs_mntpath, SYSFS_BUS_NAME, SYSFS_DRIVERS_NAME, - vhci_driver_name); + snprintf(sdriver_path, SYSFS_PATH_MAX, "%s/%s/%s/%s/%s", sysfs_mntpath, + SYSFS_BUS_NAME, USBIP_VHCI_BUS_TYPE, SYSFS_DRIVERS_NAME, + USBIP_VHCI_DRV_NAME); sdriver = sysfs_open_driver_path(sdriver_path); if (!sdriver) { - info("%s is not found", sdriver_path); - info("load usbip-core.ko and vhci-hcd.ko !"); + dbg("sysfs_open_driver_path failed: %s", sdriver_path); + dbg("make sure " USBIP_CORE_MOD_NAME ".ko and " + USBIP_VHCI_DRV_NAME ".ko are loaded!"); return -1; } hc_devs = sysfs_get_driver_devices(sdriver); if (!hc_devs) { - err("get hc list"); + dbg("sysfs_get_driver failed"); goto err; } @@ -304,7 +315,7 @@ static int get_hc_busid(char *sysfs_mntpath, char *hc_busid) if (found) return 0; - err("not found usbip hc"); + dbg("%s not found", hc_busid); return -1; } @@ -318,13 +329,13 @@ int usbip_vhci_driver_open(void) vhci_driver = (struct usbip_vhci_driver *) calloc(1, sizeof(*vhci_driver)); if (!vhci_driver) { - err("alloc vhci_driver"); + dbg("calloc failed"); return -1; } ret = sysfs_get_mnt_path(vhci_driver->sysfs_mntpath, SYSFS_PATH_MAX); if (ret < 0) { - err("sysfs must be mounted"); + dbg("sysfs_get_mnt_path failed"); goto err; } @@ -333,17 +344,18 @@ int usbip_vhci_driver_open(void) goto err; /* will be freed in usbip_driver_close() */ - vhci_driver->hc_device = sysfs_open_device("platform", hc_busid); + vhci_driver->hc_device = sysfs_open_device(USBIP_VHCI_BUS_TYPE, + hc_busid); if (!vhci_driver->hc_device) { - err("get sysfs vhci_driver"); + dbg("sysfs_open_device failed"); goto err; } vhci_driver->nports = get_nports(); - info("%d ports available\n", vhci_driver->nports); + dbg("available ports: %d", vhci_driver->nports); - vhci_driver->cdev_list = dlist_new(sizeof(struct class_device)); + vhci_driver->cdev_list = dlist_new(sizeof(struct usbip_class_device)); if (!vhci_driver->cdev_list) goto err; @@ -402,7 +414,7 @@ int usbip_vhci_refresh_device_list(void) dlist_destroy(vhci_driver->idev[i].cdev_list); } - vhci_driver->cdev_list = dlist_new(sizeof(struct class_device)); + vhci_driver->cdev_list = dlist_new(sizeof(struct usbip_class_device)); if (!vhci_driver->cdev_list) goto err; @@ -422,7 +434,7 @@ int usbip_vhci_refresh_device_list(void) dlist_destroy(vhci_driver->idev[i].cdev_list); } - err("refresh device list"); + dbg("failed to refresh device list"); return -1; } @@ -445,7 +457,8 @@ int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, attr_attach = sysfs_get_device_attr(vhci_driver->hc_device, "attach"); if (!attr_attach) { - err("get attach"); + dbg("sysfs_get_device_attr(\"attach\") failed: %s", + vhci_driver->hc_device->name); return -1; } @@ -455,11 +468,11 @@ int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, ret = sysfs_write_attribute(attr_attach, buff, strlen(buff)); if (ret < 0) { - err("write to attach failed"); + dbg("sysfs_write_attribute failed"); return -1; } - info("port %d attached", port); + dbg("attached port: %d", port); return 0; } @@ -486,21 +499,21 @@ int usbip_vhci_detach_device(uint8_t port) attr_detach = sysfs_get_device_attr(vhci_driver->hc_device, "detach"); if (!attr_detach) { - err("get detach"); + dbg("sysfs_get_device_attr(\"detach\") failed: %s", + vhci_driver->hc_device->name); return -1; } snprintf(buff, sizeof(buff), "%u", port); - dbg("writing to detach"); dbg("writing: %s", buff); ret = sysfs_write_attribute(attr_detach, buff, strlen(buff)); if (ret < 0) { - err("write to detach failed"); + dbg("sysfs_write_attribute failed"); return -1; } - info("port %d detached", port); + dbg("detached port: %d", port); return 0; } diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h b/drivers/staging/usbip/userspace/libsrc/vhci_driver.h index cad8ad7586d9..89949aa7c313 100644 --- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h +++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.h @@ -2,18 +2,20 @@ * Copyright (C) 2005-2007 Takahiro Hirofuchi */ -#ifndef _VHCI_DRIVER_H -#define _VHCI_DRIVER_H - -#include "usbip.h" +#ifndef __VHCI_DRIVER_H +#define __VHCI_DRIVER_H +#include +#include +#include "usbip_common.h" +#define USBIP_VHCI_BUS_TYPE "platform" #define MAXNPORT 128 -struct class_device { - char clspath[SYSFS_PATH_MAX]; - char devpath[SYSFS_PATH_MAX]; +struct usbip_class_device { + char class_path[SYSFS_PATH_MAX]; + char dev_path[SYSFS_PATH_MAX]; }; struct usbip_imported_device { @@ -25,16 +27,19 @@ struct usbip_imported_device { uint8_t busnum; uint8_t devnum; - - struct dlist *cdev_list; /* list of class device */ - struct usb_device udev; + /* usbip_class_device list */ + struct dlist *cdev_list; + struct usbip_usb_device udev; }; struct usbip_vhci_driver { char sysfs_mntpath[SYSFS_PATH_MAX]; - struct sysfs_device *hc_device; /* /sys/devices/platform/vhci_hcd */ - struct dlist *cdev_list; /* list of class device */ + /* /sys/devices/platform/vhci_hcd */ + struct sysfs_device *hc_device; + + /* usbip_class_device list */ + struct dlist *cdev_list; int nports; struct usbip_imported_device idev[MAXNPORT]; @@ -58,4 +63,5 @@ int usbip_vhci_attach_device(uint8_t port, int sockfd, uint8_t busnum, uint8_t devnum, uint32_t speed); int usbip_vhci_detach_device(uint8_t port); -#endif + +#endif /* __VHCI_DRIVER_H */ diff --git a/drivers/staging/usbip/userspace/src/Makefile.am b/drivers/staging/usbip/userspace/src/Makefile.am index 05a7aa50d42f..3f09f6ad39f7 100644 --- a/drivers/staging/usbip/userspace/src/Makefile.am +++ b/drivers/staging/usbip/userspace/src/Makefile.am @@ -1,10 +1,11 @@ -AM_CPPFLAGS := -I$(top_srcdir)/libsrc -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"' -AM_CFLAGS := @EXTRA_CFLAGS@ @PACKAGE_CFLAGS@ -LDADD := $(top_srcdir)/libsrc/libusbip.la @PACKAGE_LIBS@ +AM_CPPFLAGS = -I$(top_srcdir)/libsrc -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"' +AM_CFLAGS = @EXTRA_CFLAGS@ @PACKAGE_CFLAGS@ +LDADD = $(top_builddir)/libsrc/libusbip.la @PACKAGE_LIBS@ -sbin_PROGRAMS := usbip usbipd usbip_bind_driver +sbin_PROGRAMS := usbip usbipd -usbip_SOURCES := usbip.c usbip_network.c usbip_network.h -usbipd_SOURCES := usbipd.c usbip_network.c usbip_network.h -usbip_bind_driver_SOURCES := bind-driver.c utils.c utils.h \ - usbip_network.h usbip_network.c +usbip_SOURCES := usbip.c utils.c usbip_network.c \ + usbip_attach.c usbip_detach.c usbip_list.c \ + usbip_bind.c usbip_unbind.c + +usbipd_SOURCES := usbipd.c usbip_network.c diff --git a/drivers/staging/usbip/userspace/src/bind-driver.c b/drivers/staging/usbip/userspace/src/bind-driver.c deleted file mode 100644 index 201ffbbee547..000000000000 --- a/drivers/staging/usbip/userspace/src/bind-driver.c +++ /dev/null @@ -1,643 +0,0 @@ -/* - * - * Copyright (C) 2005-2007 Takahiro Hirofuchi - */ - -#include "utils.h" - -#define _GNU_SOURCE -#include -#include - - - -static const struct option longopts[] = { - {"usbip", required_argument, NULL, 'u'}, - {"other", required_argument, NULL, 'o'}, - {"list", no_argument, NULL, 'l'}, - {"list2", no_argument, NULL, 'L'}, - {"help", no_argument, NULL, 'h'}, -#if 0 - {"allusbip", no_argument, NULL, 'a'}, - {"export-to", required_argument, NULL, 'e'}, - {"unexport", required_argument, NULL, 'x'}, - {"busid", required_argument, NULL, 'b'}, -#endif - - {NULL, 0, NULL, 0} -}; - -static const char match_busid_path[] = "/sys/bus/usb/drivers/usbip/match_busid"; - - -static void show_help(void) -{ - printf("Usage: usbip_bind_driver [OPTION]\n"); - printf("Change driver binding for USB/IP.\n"); - printf(" --usbip busid make a device exportable\n"); - printf(" --other busid use a device by a local driver\n"); - printf(" --list print usb devices and their drivers\n"); - printf(" --list2 print usb devices and their drivers in parseable mode\n"); -#if 0 - printf(" --allusbip make all devices exportable\n"); - printf(" --export-to host export the device to 'host'\n"); - printf(" --unexport host unexport a device previously exported to 'host'\n"); - printf(" --busid busid the busid used for --export-to\n"); -#endif -} - -static int modify_match_busid(char *busid, int add) -{ - int fd; - int ret; - char buff[BUS_ID_SIZE + 4]; - - /* BUS_IS_SIZE includes NULL termination? */ - if (strnlen(busid, BUS_ID_SIZE) > BUS_ID_SIZE - 1) { - g_warning("too long busid"); - return -1; - } - - fd = open(match_busid_path, O_WRONLY); - if (fd < 0) - return -1; - - if (add) - snprintf(buff, BUS_ID_SIZE + 4, "add %s", busid); - else - snprintf(buff, BUS_ID_SIZE + 4, "del %s", busid); - - g_debug("write \"%s\" to %s", buff, match_busid_path); - - ret = write(fd, buff, sizeof(buff)); - if (ret < 0) { - close(fd); - return -1; - } - - close(fd); - - return 0; -} - -static const char unbind_path_format[] = "/sys/bus/usb/devices/%s/driver/unbind"; - -/* buggy driver may cause dead lock */ -static int unbind_interface_busid(char *busid) -{ - char unbind_path[PATH_MAX]; - int fd; - int ret; - - snprintf(unbind_path, sizeof(unbind_path), unbind_path_format, busid); - - fd = open(unbind_path, O_WRONLY); - if (fd < 0) { - g_warning("opening unbind_path failed: %d", fd); - return -1; - } - - ret = write(fd, busid, strnlen(busid, BUS_ID_SIZE)); - if (ret < 0) { - g_warning("write to unbind_path failed: %d", ret); - close(fd); - return -1; - } - - close(fd); - - return 0; -} - -static int unbind_interface(char *busid, int configvalue, int interface) -{ - char inf_busid[BUS_ID_SIZE]; - g_debug("unbinding interface"); - - snprintf(inf_busid, BUS_ID_SIZE, "%s:%d.%d", busid, configvalue, interface); - - return unbind_interface_busid(inf_busid); -} - - -static const char bind_path_format[] = "/sys/bus/usb/drivers/%s/bind"; - -static int bind_interface_busid(char *busid, char *driver) -{ - char bind_path[PATH_MAX]; - int fd; - int ret; - - snprintf(bind_path, sizeof(bind_path), bind_path_format, driver); - - fd = open(bind_path, O_WRONLY); - if (fd < 0) - return -1; - - ret = write(fd, busid, strnlen(busid, BUS_ID_SIZE)); - if (ret < 0) { - close(fd); - return -1; - } - - close(fd); - - return 0; -} - -static int bind_interface(char *busid, int configvalue, int interface, char *driver) -{ - char inf_busid[BUS_ID_SIZE]; - - snprintf(inf_busid, BUS_ID_SIZE, "%s:%d.%d", busid, configvalue, interface); - - return bind_interface_busid(inf_busid, driver); -} - -static int unbind(char *busid) -{ - int configvalue = 0; - int ninterface = 0; - int devclass = 0; - int i; - int failed = 0; - - configvalue = read_bConfigurationValue(busid); - ninterface = read_bNumInterfaces(busid); - devclass = read_bDeviceClass(busid); - - if (configvalue < 0 || ninterface < 0 || devclass < 0) { - g_warning("read config and ninf value, removed?"); - return -1; - } - - if (devclass == 0x09) { - g_message("skip unbinding of hub"); - return -1; - } - - for (i = 0; i < ninterface; i++) { - char driver[PATH_MAX]; - int ret; - - bzero(&driver, sizeof(driver)); - - getdriver(busid, configvalue, i, driver, PATH_MAX-1); - - g_debug(" %s:%d.%d -> %s ", busid, configvalue, i, driver); - - if (!strncmp("none", driver, PATH_MAX)) - continue; /* unbound interface */ - -#if 0 - if (!strncmp("usbip", driver, PATH_MAX)) - continue; /* already bound to usbip */ -#endif - - /* unbinding */ - ret = unbind_interface(busid, configvalue, i); - if (ret < 0) { - g_warning("unbind driver at %s:%d.%d failed", - busid, configvalue, i); - failed = 1; - } - } - - if (failed) - return -1; - else - return 0; -} - -/* call at unbound state */ -static int bind_to_usbip(char *busid) -{ - int configvalue = 0; - int ninterface = 0; - int i; - int failed = 0; - - configvalue = read_bConfigurationValue(busid); - ninterface = read_bNumInterfaces(busid); - - if (configvalue < 0 || ninterface < 0) { - g_warning("read config and ninf value, removed?"); - return -1; - } - - for (i = 0; i < ninterface; i++) { - int ret; - - ret = bind_interface(busid, configvalue, i, "usbip"); - if (ret < 0) { - g_warning("bind usbip at %s:%d.%d, failed", - busid, configvalue, i); - failed = 1; - /* need to contine binding at other interfaces */ - } - } - - if (failed) - return -1; - else - return 0; -} - - -static int use_device_by_usbip(char *busid) -{ - int ret; - - ret = unbind(busid); - if (ret < 0) { - g_warning("unbind drivers of %s, failed", busid); - return -1; - } - - ret = modify_match_busid(busid, 1); - if (ret < 0) { - g_warning("add %s to match_busid, failed", busid); - return -1; - } - - ret = bind_to_usbip(busid); - if (ret < 0) { - g_warning("bind usbip to %s, failed", busid); - modify_match_busid(busid, 0); - return -1; - } - - g_message("bind %s to usbip, complete!", busid); - - return 0; -} - - - -static int use_device_by_other(char *busid) -{ - int ret; - int config; - - /* read and write the same config value to kick probing */ - config = read_bConfigurationValue(busid); - if (config < 0) { - g_warning("read bConfigurationValue of %s, failed", busid); - return -1; - } - - ret = modify_match_busid(busid, 0); - if (ret < 0) { - g_warning("del %s to match_busid, failed", busid); - return -1; - } - - ret = write_bConfigurationValue(busid, config); - if (ret < 0) { - g_warning("read bConfigurationValue of %s, failed", busid); - return -1; - } - - g_message("bind %s to other drivers than usbip, complete!", busid); - - return 0; -} - - -#include -#include - -#include -#include -#include - - - -static int is_usb_device(char *busid) -{ - int ret; - - regex_t regex; - regmatch_t pmatch[1]; - - ret = regcomp(®ex, "^[0-9]+-[0-9]+(\\.[0-9]+)*$", REG_NOSUB|REG_EXTENDED); - if (ret < 0) - g_error("regcomp: %s\n", strerror(errno)); - - ret = regexec(®ex, busid, 0, pmatch, 0); - if (ret) - return 0; /* not matched */ - - return 1; -} - - -#include -static int show_devices(void) -{ - DIR *dir; - - dir = opendir("/sys/bus/usb/devices/"); - if (!dir) - g_error("opendir: %s", strerror(errno)); - - printf("List USB devices\n"); - for (;;) { - struct dirent *dirent; - char *busid; - - dirent = readdir(dir); - if (!dirent) - break; - - busid = dirent->d_name; - - if (is_usb_device(busid)) { - char name[100] = {'\0'}; - char driver[100] = {'\0'}; - int conf, ninf = 0; - int i; - - conf = read_bConfigurationValue(busid); - ninf = read_bNumInterfaces(busid); - - getdevicename(busid, name, sizeof(name)); - - printf(" - busid %s (%s)\n", busid, name); - - for (i = 0; i < ninf; i++) { - getdriver(busid, conf, i, driver, sizeof(driver)); - printf(" %s:%d.%d -> %s\n", busid, conf, i, driver); - } - printf("\n"); - } - } - - closedir(dir); - - return 0; -} - -static int show_devices2(void) -{ - DIR *dir; - - dir = opendir("/sys/bus/usb/devices/"); - if (!dir) - g_error("opendir: %s", strerror(errno)); - - for (;;) { - struct dirent *dirent; - char *busid; - - dirent = readdir(dir); - if (!dirent) - break; - - busid = dirent->d_name; - - if (is_usb_device(busid)) { - char name[100] = {'\0'}; - char driver[100] = {'\0'}; - int conf, ninf = 0; - int i; - - conf = read_bConfigurationValue(busid); - ninf = read_bNumInterfaces(busid); - - getdevicename(busid, name, sizeof(name)); - - printf("busid=%s#usbid=%s#", busid, name); - - for (i = 0; i < ninf; i++) { - getdriver(busid, conf, i, driver, sizeof(driver)); - printf("%s:%d.%d=%s#", busid, conf, i, driver); - } - printf("\n"); - } - } - - closedir(dir); - - return 0; -} - - -#if 0 -static int export_to(char *host, char *busid) { - - int ret; - - if( host == NULL ) { - printf( "no host given\n\n"); - show_help(); - return -1; - } - if( busid == NULL ) { - /* XXX print device list and ask for busnumber, if none is - * given */ - printf( "no busid given, use --busid switch\n\n"); - show_help(); - return -1; - } - - - ret = use_device_by_usbip(busid); - if( ret != 0 ) { - printf( "could not bind driver to usbip\n"); - return -1; - } - - printf( "DEBUG: exporting device '%s' to '%s'\n", busid, host ); - ret = export_busid_to_host(host, busid); /* usbip_export.[ch] */ - if( ret != 0 ) { - printf( "could not export device to host\n" ); - printf( " host: %s, device: %s\n", host, busid ); - use_device_by_other(busid); - return -1; - } - - return 0; -} - -static int unexport_from(char *host, char *busid) { - - int ret; - - if (!host || !busid) - g_error("no host or no busid\n"); - - g_message("unexport_from: host: '%s', busid: '%s'", host, busid); - - ret = unexport_busid_from_host(host, busid); /* usbip_export.[ch] */ - if( ret != 0 ) { - err( "could not unexport device from host\n" ); - err( " host: %s, device: %s\n", host, busid ); - } - - ret = use_device_by_other(busid); - if (ret < 0) - g_error("could not unbind device from usbip\n"); - - return 0; -} - - -static int allusbip(void) -{ - DIR *dir; - - dir = opendir("/sys/bus/usb/devices/"); - if (!dir) - g_error("opendir: %s", strerror(errno)); - - for (;;) { - struct dirent *dirent; - char *busid; - - dirent = readdir(dir); - if (!dirent) - break; - - busid = dirent->d_name; - - if (!is_usb_device(busid)) - continue; - - { - char name[PATH_MAX]; - int conf, ninf = 0; - int i; - int be_local = 0; - - conf = read_bConfigurationValue(busid); - ninf = read_bNumInterfaces(busid); - - getdevicename(busid, name, sizeof(name)); - - for (i = 0; i < ninf; i++) { - char driver[PATH_MAX]; - - getdriver(busid, conf, i, driver, sizeof(driver)); -#if 0 - if (strncmp(driver, "usbhid", 6) == 0 || strncmp(driver, "usb-storage", 11) == 0) { - be_local = 1; - break; - } -#endif - } - - if (be_local == 0) - use_device_by_usbip(busid); - } - } - - closedir(dir); - - return 0; -} -#endif - -int main(int argc, char **argv) -{ - char *busid = NULL; - char *remote_host __attribute__((unused)) = NULL; - - enum { - cmd_unknown = 0, - cmd_use_by_usbip, - cmd_use_by_other, - cmd_list, - cmd_list2, - cmd_allusbip, - cmd_export_to, - cmd_unexport, - cmd_help, - } cmd = cmd_unknown; - - if (geteuid() != 0) - g_warning("running non-root?"); - - for (;;) { - int c; - int index = 0; - - c = getopt_long(argc, argv, "u:o:hlLae:x:b:", longopts, &index); - if (c == -1) - break; - - switch (c) { - case 'u': - cmd = cmd_use_by_usbip; - busid = optarg; - break; - case 'o' : - cmd = cmd_use_by_other; - busid = optarg; - break; - case 'l' : - cmd = cmd_list; - break; - case 'L' : - cmd = cmd_list2; - break; - case 'a' : - cmd = cmd_allusbip; - break; - case 'b': - busid = optarg; - break; - case 'e': - cmd = cmd_export_to; - remote_host = optarg; - break; - case 'x': - cmd = cmd_unexport; - remote_host = optarg; - break; - case 'h': /* fallthrough */ - case '?': - cmd = cmd_help; - break; - default: - g_error("getopt"); - } - - //if (cmd) - // break; - } - - switch (cmd) { - case cmd_use_by_usbip: - use_device_by_usbip(busid); - break; - case cmd_use_by_other: - use_device_by_other(busid); - break; - case cmd_list: - show_devices(); - break; - case cmd_list2: - show_devices2(); - break; -#if 0 - case cmd_allusbip: - allusbip(); - break; - case cmd_export_to: - export_to(remote_host, busid); - break; - case cmd_unexport: - unexport_from(remote_host, busid); - break; -#endif - case cmd_help: /* fallthrough */ - case cmd_unknown: - show_help(); - break; - default: - g_error("NOT REACHED"); - } - - return 0; -} diff --git a/drivers/staging/usbip/userspace/src/usbip.c b/drivers/staging/usbip/userspace/src/usbip.c index 01a562866b5d..fff4b768e705 100644 --- a/drivers/staging/usbip/userspace/src/usbip.c +++ b/drivers/staging/usbip/userspace/src/usbip.c @@ -1,723 +1,190 @@ /* + * command structure borrowed from udev + * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git) * - * Copyright (C) 2005-2007 Takahiro Hirofuchi + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi + * + * 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, see . */ -#ifdef HAVE_CONFIG_H -#include "../config.h" -#endif - -#include "usbip.h" -#include "usbip_network.h" -#include -#include -#include +#include #include -#include -#include -static const char version[] = PACKAGE_STRING; - - -/* /sys/devices/platform/vhci_hcd/usb6/6-1/6-1:1.1 -> 1 */ -static int get_interface_number(char *path) -{ - char *c; - - c = strstr(path, vhci_driver->hc_device->bus_id); - if (!c) - return -1; /* hc exist? */ - c++; - /* -> usb6/6-1/6-1:1.1 */ - - c = strchr(c, '/'); - if (!c) - return -1; /* hc exist? */ - c++; - /* -> 6-1/6-1:1.1 */ - - c = strchr(c, '/'); - if (!c) - return -1; /* no interface path */ - c++; - /* -> 6-1:1.1 */ - - c = strchr(c, ':'); - if (!c) - return -1; /* no configuration? */ - c++; - /* -> 1.1 */ - - c = strchr(c, '.'); - if (!c) - return -1; /* no interface? */ - c++; - /* -> 1 */ - - - return atoi(c); -} - - -static struct sysfs_device *open_usb_interface(struct usb_device *udev, int i) -{ - struct sysfs_device *suinf; - char busid[SYSFS_BUS_ID_SIZE]; - - snprintf(busid, SYSFS_BUS_ID_SIZE, "%s:%d.%d", - udev->busid, udev->bConfigurationValue, i); - - suinf = sysfs_open_device("usb", busid); - if (!suinf) - err("sysfs_open_device %s", busid); - - return suinf; -} - - -#define MAX_BUFF 100 -static int record_connection(char *host, char *port, char *busid, int rhport) -{ - int fd; - char path[PATH_MAX+1]; - char buff[MAX_BUFF+1]; - int ret; - - mkdir(VHCI_STATE_PATH, 0700); - - snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); - - fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU); - if (fd < 0) - return -1; - - snprintf(buff, MAX_BUFF, "%s %s %s\n", - host, port, busid); - - ret = write(fd, buff, strlen(buff)); - if (ret != (ssize_t) strlen(buff)) { - close(fd); - return -1; - } - - close(fd); - - return 0; -} - -static int read_record(int rhport, char *host, char *port, char *busid) -{ - FILE *file; - char path[PATH_MAX+1]; - - snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); - - file = fopen(path, "r"); - if (!file) { - err("fopen"); - return -1; - } - - if (fscanf(file, "%s %s %s\n", host, port, busid) != 3) { - err("fscanf"); - fclose(file); - return -1; - } - - fclose(file); - - return 0; -} - - -int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev) -{ - char product_name[100]; - char host[NI_MAXHOST] = "unknown host"; - char serv[NI_MAXSERV] = "unknown port"; - char remote_busid[SYSFS_BUS_ID_SIZE]; - int ret; - - if (idev->status == VDEV_ST_NULL || idev->status == VDEV_ST_NOTASSIGNED) { - info("Port %02d: <%s>", idev->port, usbip_status_string(idev->status)); - return 0; - } - - ret = read_record(idev->port, host, serv, remote_busid); - if (ret) { - err("read_record"); - return -1; - } - - info("Port %02d: <%s> at %s", idev->port, - usbip_status_string(idev->status), usbip_speed_string(idev->udev.speed)); - - usbip_names_get_product(product_name, sizeof(product_name), - idev->udev.idVendor, idev->udev.idProduct); - - info(" %s", product_name); - - info("%10s -> usbip://%s:%s/%s (remote devid %08x (bus/dev %03d/%03d))", - idev->udev.busid, host, serv, remote_busid, - idev->devid, - idev->busnum, idev->devnum); - - for (int i=0; i < idev->udev.bNumInterfaces; i++) { - /* show interface information */ - struct sysfs_device *suinf; - - suinf = open_usb_interface(&idev->udev, i); - if (!suinf) - continue; - - info(" %6s used by %-17s", suinf->bus_id, suinf->driver_name); - sysfs_close_device(suinf); - - /* show class device information */ - struct class_device *cdev; - - dlist_for_each_data(idev->cdev_list, cdev, struct class_device) { - int ifnum = get_interface_number(cdev->devpath); - if (ifnum == i) { - info(" %s", cdev->clspath); - } - } - } - - return 0; -} - - - - -static int query_exported_devices(int sockfd) -{ - int ret; - struct op_devlist_reply rep; - uint16_t code = OP_REP_DEVLIST; - - bzero(&rep, sizeof(rep)); - - ret = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0); - if (ret < 0) { - err("send op_common"); - return -1; - } - - ret = usbip_recv_op_common(sockfd, &code); - if (ret < 0) { - err("recv op_common"); - return -1; - } - - ret = usbip_recv(sockfd, (void *) &rep, sizeof(rep)); - if (ret < 0) { - err("recv op_devlist"); - return -1; - } - - PACK_OP_DEVLIST_REPLY(0, &rep); - dbg("exportable %d devices", rep.ndev); - - for (unsigned int i=0; i < rep.ndev; i++) { - char product_name[100]; - char class_name[100]; - struct usb_device udev; - - bzero(&udev, sizeof(udev)); - - ret = usbip_recv(sockfd, (void *) &udev, sizeof(udev)); - if (ret < 0) { - err("recv usb_device[%d]", i); - return -1; - } - pack_usb_device(0, &udev); - - usbip_names_get_product(product_name, sizeof(product_name), - udev.idVendor, udev.idProduct); - usbip_names_get_class(class_name, sizeof(class_name), udev.bDeviceClass, - udev.bDeviceSubClass, udev.bDeviceProtocol); - - info("%8s: %s", udev.busid, product_name); - info("%8s: %s", " ", udev.path); - info("%8s: %s", " ", class_name); - - for (int j=0; j < udev.bNumInterfaces; j++) { - struct usb_interface uinf; - - ret = usbip_recv(sockfd, (void *) &uinf, sizeof(uinf)); - if (ret < 0) { - err("recv usb_interface[%d]", j); - return -1; - } - - pack_usb_interface(0, &uinf); - usbip_names_get_class(class_name, sizeof(class_name), uinf.bInterfaceClass, - uinf.bInterfaceSubClass, uinf.bInterfaceProtocol); - - info("%8s: %2d - %s", " ", j, class_name); - } - - info(" "); - } - - return rep.ndev; -} - -static int import_device(int sockfd, struct usb_device *udev) -{ - int ret; - int port; - - ret = usbip_vhci_driver_open(); - if (ret < 0) { - err("open vhci_driver"); - return -1; - } - - port = usbip_vhci_get_free_port(); - if (port < 0) { - err("no free port"); - usbip_vhci_driver_close(); - return -1; - } - - ret = usbip_vhci_attach_device(port, sockfd, udev->busnum, - udev->devnum, udev->speed); - if (ret < 0) { - err("import device"); - usbip_vhci_driver_close(); - return -1; - } - - usbip_vhci_driver_close(); - - return port; -} - - -static int query_import_device(int sockfd, char *busid) -{ - int ret; - struct op_import_request request; - struct op_import_reply reply; - uint16_t code = OP_REP_IMPORT; - - bzero(&request, sizeof(request)); - bzero(&reply, sizeof(reply)); - - - /* send a request */ - ret = usbip_send_op_common(sockfd, OP_REQ_IMPORT, 0); - if (ret < 0) { - err("send op_common"); - return -1; - } - - strncpy(request.busid, busid, SYSFS_BUS_ID_SIZE-1); - - PACK_OP_IMPORT_REQUEST(0, &request); - - ret = usbip_send(sockfd, (void *) &request, sizeof(request)); - if (ret < 0) { - err("send op_import_request"); - return -1; - } - - - /* recieve a reply */ - ret = usbip_recv_op_common(sockfd, &code); - if (ret < 0) { - err("recv op_common"); - return -1; - } - - ret = usbip_recv(sockfd, (void *) &reply, sizeof(reply)); - if (ret < 0) { - err("recv op_import_reply"); - return -1; - } - - PACK_OP_IMPORT_REPLY(0, &reply); - - - /* check the reply */ - if (strncmp(reply.udev.busid, busid, SYSFS_BUS_ID_SIZE)) { - err("recv different busid %s", reply.udev.busid); - return -1; - } - - - /* import a device */ - return import_device(sockfd, &reply.udev); -} - -static int attach_device(char *host, char *busid) -{ - int sockfd; - int ret; - int rhport; - - sockfd = tcp_connect(host, USBIP_PORT_STRING); - if (sockfd < 0) { - err("tcp connect"); - return -1; - } - - rhport = query_import_device(sockfd, busid); - if (rhport < 0) { - err("query"); - return -1; - } - - close(sockfd); - - ret = record_connection(host, USBIP_PORT_STRING, - busid, rhport); - if (ret < 0) { - err("record connection"); - return -1; - } - - return 0; -} - -static int detach_port(char *port) -{ - int ret; - uint8_t portnum; - - for (unsigned int i=0; i < strlen(port); i++) - if (!isdigit(port[i])) { - err("invalid port %s", port); - return -1; - } - - /* check max port */ - - portnum = atoi(port); - - ret = usbip_vhci_driver_open(); - if (ret < 0) { - err("open vhci_driver"); - return -1; - } - - ret = usbip_vhci_detach_device(portnum); - if (ret < 0) - return -1; - - usbip_vhci_driver_close(); - - return ret; -} - -static int show_exported_devices(char *host) -{ - int ret; - int sockfd; - - sockfd = tcp_connect(host, USBIP_PORT_STRING); - if (sockfd < 0) { - err("- %s failed", host); - return -1; - } - - info("- %s", host); - - ret = query_exported_devices(sockfd); - if (ret < 0) { - err("query"); - return -1; - } - - close(sockfd); - return 0; -} - -static int attach_exported_devices(char *host, int sockfd) -{ - int ret; - struct op_devlist_reply rep; - uint16_t code = OP_REP_DEVLIST; - - bzero(&rep, sizeof(rep)); - - ret = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0); - if(ret < 0) { - err("send op_common"); - return -1; - } - - ret = usbip_recv_op_common(sockfd, &code); - if(ret < 0) { - err("recv op_common"); - return -1; - } - - ret = usbip_recv(sockfd, (void *) &rep, sizeof(rep)); - if(ret < 0) { - err("recv op_devlist"); - return -1; - } - - PACK_OP_DEVLIST_REPLY(0, &rep); - dbg("exportable %d devices", rep.ndev); - - for(unsigned int i=0; i < rep.ndev; i++) { - char product_name[100]; - char class_name[100]; - struct usb_device udev; - - bzero(&udev, sizeof(udev)); - - ret = usbip_recv(sockfd, (void *) &udev, sizeof(udev)); - if(ret < 0) { - err("recv usb_device[%d]", i); - return -1; - } - pack_usb_device(0, &udev); - - usbip_names_get_product(product_name, sizeof(product_name), - udev.idVendor, udev.idProduct); - usbip_names_get_class(class_name, sizeof(class_name), udev.bDeviceClass, - udev.bDeviceSubClass, udev.bDeviceProtocol); - - dbg("Attaching usb port %s from host %s on usbip, with deviceid: %s", udev.busid, host, product_name); - - for (int j=0; j < udev.bNumInterfaces; j++) { - struct usb_interface uinf; - - ret = usbip_recv(sockfd, (void *) &uinf, sizeof(uinf)); - if (ret < 0) { - err("recv usb_interface[%d]", j); - return -1; - } - - pack_usb_interface(0, &uinf); - usbip_names_get_class(class_name, sizeof(class_name), uinf.bInterfaceClass, - uinf.bInterfaceSubClass, uinf.bInterfaceProtocol); - - dbg("interface %2d - %s", j, class_name); - } - - attach_device(host, udev.busid); - } - - return rep.ndev; -} - -static int attach_devices_all(char *host) -{ - int ret; - int sockfd; - - sockfd = tcp_connect(host, USBIP_PORT_STRING); - if(sockfd < 0) { - err("- %s failed", host); - return -1; - } - - info("- %s", host); - - ret = attach_exported_devices(host, sockfd); - if(ret < 0) { - err("query"); - return -1; - } - - close(sockfd); - return 0; -} - - -const char help_message[] = "\ -Usage: usbip [options] \n\ - -a, --attach [host] [bus_id] \n\ - Attach a remote USB device. \n\ - \n\ - -x, --attachall [host] \n\ - Attach all remote USB devices on the specific host. \n\ - \n\ - -d, --detach [ports] \n\ - Detach an imported USB device. \n\ - \n\ - -l, --list [hosts] \n\ - List exported USB devices. \n\ - \n\ - -p, --port \n\ - List virtual USB port status. \n\ - \n\ - -D, --debug \n\ - Print debugging information. \n\ - \n\ - -v, --version \n\ - Show version. \n\ - \n\ - -h, --help \n\ - Print this help. \n"; - -static void show_help(void) -{ - printf("%s", help_message); -} - -static int show_port_status(void) -{ - int ret; - struct usbip_imported_device *idev; - - ret = usbip_vhci_driver_open(); - if (ret < 0) - return ret; - - for (int i = 0; i < vhci_driver->nports; i++) { - idev = &vhci_driver->idev[i]; - - if (usbip_vhci_imported_device_dump(idev) < 0) - ret = -1; - } - - usbip_vhci_driver_close(); - - return ret; -} - -#define _GNU_SOURCE #include -static const struct option longopts[] = { - {"attach", no_argument, NULL, 'a'}, - {"attachall", no_argument, NULL, 'x'}, - {"detach", no_argument, NULL, 'd'}, - {"port", no_argument, NULL, 'p'}, - {"list", no_argument, NULL, 'l'}, - {"version", no_argument, NULL, 'v'}, - {"help", no_argument, NULL, 'h'}, - {"debug", no_argument, NULL, 'D'}, - {"syslog", no_argument, NULL, 'S'}, - {NULL, 0, NULL, 0} +#include + +#include "usbip_common.h" +#include "usbip.h" + +static int usbip_help(int argc, char *argv[]); +static int usbip_version(int argc, char *argv[]); + +static const char usbip_version_string[] = PACKAGE_STRING; + +static const char usbip_usage_string[] = + "usbip [--debug] [--log] [version]\n" + " [help] \n"; + +static void usbip_usage(void) +{ + printf("usage: %s", usbip_usage_string); +} + +struct command { + const char *name; + int (*fn)(int argc, char *argv[]); + const char *help; + void (*usage)(void); }; +static const struct command cmds[] = { + { + .name = "help", + .fn = usbip_help, + .help = NULL, + .usage = NULL + }, + { + .name = "version", + .fn = usbip_version, + .help = NULL, + .usage = NULL + }, + { + .name = "attach", + .fn = usbip_attach, + .help = "Attach a remote USB device", + .usage = usbip_attach_usage + }, + { + .name = "detach", + .fn = usbip_detach, + .help = "Detach a remote USB device", + .usage = usbip_detach_usage + }, + { + .name = "list", + .fn = usbip_list, + .help = "List exportable or local USB devices", + .usage = usbip_list_usage + }, + { + .name = "bind", + .fn = usbip_bind, + .help = "Bind device to " USBIP_HOST_DRV_NAME ".ko", + .usage = usbip_bind_usage + }, + { + .name = "unbind", + .fn = usbip_unbind, + .help = "Unbind device from " USBIP_HOST_DRV_NAME ".ko", + .usage = usbip_unbind_usage + }, + { NULL, NULL, NULL, NULL } +}; + +static int usbip_help(int argc, char *argv[]) +{ + const struct command *cmd; + int i; + int ret = 0; + + if (argc > 1 && argv++) { + for (i = 0; cmds[i].name != NULL; i++) + if (!strcmp(cmds[i].name, argv[0]) && cmds[i].usage) { + cmds[i].usage(); + goto done; + } + ret = -1; + } + + usbip_usage(); + printf("\n"); + for (cmd = cmds; cmd->name != NULL; cmd++) + if (cmd->help != NULL) + printf(" %-10s %s\n", cmd->name, cmd->help); + printf("\n"); +done: + return ret; +} + +static int usbip_version(int argc, char *argv[]) +{ + (void) argc; + (void) argv; + + printf(PROGNAME " (%s)\n", usbip_version_string); + return 0; +} + +static int run_command(const struct command *cmd, int argc, char *argv[]) +{ + dbg("running command: `%s'", cmd->name); + return cmd->fn(argc, argv); +} + int main(int argc, char *argv[]) { - int ret; + static const struct option opts[] = { + { "debug", no_argument, NULL, 'd' }, + { "log", no_argument, NULL, 'l' }, + { NULL, 0, NULL, 0 } + }; - enum { - cmd_attach = 1, - cmd_attachall, - cmd_detach, - cmd_port, - cmd_list, - cmd_help, - cmd_version - } cmd = 0; + char *cmd; + int opt; + int i, rc = -1; usbip_use_stderr = 1; - - if (geteuid() != 0) - g_warning("running non-root?"); - - ret = usbip_names_init(USBIDS_FILE); - if (ret) - notice("failed to open %s", USBIDS_FILE); - + opterr = 0; for (;;) { - int c; - int index = 0; + opt = getopt_long(argc, argv, "+d", opts, NULL); - c = getopt_long(argc, argv, "adplvhDSx", longopts, &index); - - if (c == -1) + if (opt == -1) break; - switch(c) { - case 'a': - if (!cmd) - cmd = cmd_attach; - else - cmd = cmd_help; - break; - case 'd': - if (!cmd) - cmd = cmd_detach; - else - cmd = cmd_help; - break; - case 'p': - if (!cmd) - cmd = cmd_port; - else cmd = cmd_help; - break; - case 'l': - if (!cmd) - cmd = cmd_list; - else - cmd = cmd_help; - break; - case 'v': - if (!cmd) - cmd = cmd_version; - else - cmd = cmd_help; - break; - case 'x': - if(!cmd) - cmd = cmd_attachall; - else - cmd = cmd_help; - break; - case 'h': - cmd = cmd_help; - break; - case 'D': - usbip_use_debug = 1; - break; - case 'S': - usbip_use_syslog = 1; - break; - case '?': - break; - - default: - err("getopt"); + switch (opt) { + case 'd': + usbip_use_debug = 1; + break; + case 'l': + usbip_use_syslog = 1; + openlog("", LOG_PID, LOG_USER); + break; + case '?': + printf("usbip: invalid option\n"); + default: + usbip_usage(); + goto out; } } - ret = 0; - switch(cmd) { - case cmd_attach: - if (optind == argc - 2) - ret = attach_device(argv[optind], argv[optind+1]); - else - show_help(); - break; - case cmd_detach: - while (optind < argc) - ret = detach_port(argv[optind++]); - break; - case cmd_port: - ret = show_port_status(); - break; - case cmd_list: - while (optind < argc) - ret = show_exported_devices(argv[optind++]); - break; - case cmd_attachall: - while(optind < argc) - ret = attach_devices_all(argv[optind++]); - break; - case cmd_version: - printf("%s\n", version); - break; - case cmd_help: - show_help(); - break; - default: - show_help(); + cmd = argv[optind]; + if (cmd) { + for (i = 0; cmds[i].name != NULL; i++) + if (!strcmp(cmds[i].name, cmd)) { + argc -= optind; + argv += optind; + optind = 0; + rc = run_command(&cmds[i], argc, argv); + goto out; + } } - - usbip_names_free(); - - exit((ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE); + /* invalid command */ + usbip_help(0, NULL); +out: + return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/drivers/staging/usbip/userspace/src/usbip.h b/drivers/staging/usbip/userspace/src/usbip.h new file mode 100644 index 000000000000..14d4a475b683 --- /dev/null +++ b/drivers/staging/usbip/userspace/src/usbip.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi + * + * 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, see . + */ + +#ifndef __USBIP_H +#define __USBIP_H + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +/* usbip commands */ +int usbip_attach(int argc, char *argv[]); +int usbip_detach(int argc, char *argv[]); +int usbip_list(int argc, char *argv[]); +int usbip_bind(int argc, char *argv[]); +int usbip_unbind(int argc, char *argv[]); + +void usbip_attach_usage(void); +void usbip_detach_usage(void); +void usbip_list_usage(void); +void usbip_bind_usage(void); +void usbip_unbind_usage(void); + +#endif /* __USBIP_H */ diff --git a/drivers/staging/usbip/userspace/src/usbip_attach.c b/drivers/staging/usbip/userspace/src/usbip_attach.c new file mode 100644 index 000000000000..b7885a202757 --- /dev/null +++ b/drivers/staging/usbip/userspace/src/usbip_attach.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi + * + * 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, see . + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "vhci_driver.h" +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static const char usbip_attach_usage_string[] = + "usbip attach \n" + " -h, --host= The machine with exported USB devices\n" + " -b, --busid= Busid of the device on \n"; + +void usbip_attach_usage(void) +{ + printf("usage: %s", usbip_attach_usage_string); +} + +#define MAX_BUFF 100 +static int record_connection(char *host, char *port, char *busid, int rhport) +{ + int fd; + char path[PATH_MAX+1]; + char buff[MAX_BUFF+1]; + int ret; + + mkdir(VHCI_STATE_PATH, 0700); + + snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); + + fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU); + if (fd < 0) + return -1; + + snprintf(buff, MAX_BUFF, "%s %s %s\n", + host, port, busid); + + ret = write(fd, buff, strlen(buff)); + if (ret != (ssize_t) strlen(buff)) { + close(fd); + return -1; + } + + close(fd); + + return 0; +} + +static int import_device(int sockfd, struct usbip_usb_device *udev) +{ + int rc; + int port; + + rc = usbip_vhci_driver_open(); + if (rc < 0) { + err("open vhci_driver"); + return -1; + } + + port = usbip_vhci_get_free_port(); + if (port < 0) { + err("no free port"); + usbip_vhci_driver_close(); + return -1; + } + + rc = usbip_vhci_attach_device(port, sockfd, udev->busnum, + udev->devnum, udev->speed); + if (rc < 0) { + err("import device"); + usbip_vhci_driver_close(); + return -1; + } + + usbip_vhci_driver_close(); + + return port; +} + +static int query_import_device(int sockfd, char *busid) +{ + int rc; + struct op_import_request request; + struct op_import_reply reply; + uint16_t code = OP_REP_IMPORT; + + memset(&request, 0, sizeof(request)); + memset(&reply, 0, sizeof(reply)); + + /* send a request */ + rc = usbip_net_send_op_common(sockfd, OP_REQ_IMPORT, 0); + if (rc < 0) { + err("send op_common"); + return -1; + } + + strncpy(request.busid, busid, SYSFS_BUS_ID_SIZE-1); + + PACK_OP_IMPORT_REQUEST(0, &request); + + rc = usbip_net_send(sockfd, (void *) &request, sizeof(request)); + if (rc < 0) { + err("send op_import_request"); + return -1; + } + + /* recieve a reply */ + rc = usbip_net_recv_op_common(sockfd, &code); + if (rc < 0) { + err("recv op_common"); + return -1; + } + + rc = usbip_net_recv(sockfd, (void *) &reply, sizeof(reply)); + if (rc < 0) { + err("recv op_import_reply"); + return -1; + } + + PACK_OP_IMPORT_REPLY(0, &reply); + + /* check the reply */ + if (strncmp(reply.udev.busid, busid, SYSFS_BUS_ID_SIZE)) { + err("recv different busid %s", reply.udev.busid); + return -1; + } + + /* import a device */ + return import_device(sockfd, &reply.udev); +} + +static int attach_device(char *host, char *busid) +{ + int sockfd; + int rc; + int rhport; + + sockfd = usbip_net_tcp_connect(host, USBIP_PORT_STRING); + if (sockfd < 0) { + err("tcp connect"); + return -1; + } + + rhport = query_import_device(sockfd, busid); + if (rhport < 0) { + err("query"); + return -1; + } + + close(sockfd); + + rc = record_connection(host, USBIP_PORT_STRING, busid, rhport); + if (rc < 0) { + err("record connection"); + return -1; + } + + return 0; +} + +int usbip_attach(int argc, char *argv[]) +{ + static const struct option opts[] = { + { "host", required_argument, NULL, 'h' }, + { "busid", required_argument, NULL, 'b' }, + { NULL, 0, NULL, 0 } + }; + char *host = NULL; + char *busid = NULL; + int opt; + int ret = -1; + + for (;;) { + opt = getopt_long(argc, argv, "h:b:", opts, NULL); + + if (opt == -1) + break; + + switch (opt) { + case 'h': + host = optarg; + break; + case 'b': + busid = optarg; + break; + default: + goto err_out; + } + } + + if (!host || !busid) + goto err_out; + + ret = attach_device(host, busid); + goto out; + +err_out: + usbip_attach_usage(); +out: + return ret; +} diff --git a/drivers/staging/usbip/userspace/src/usbip_bind.c b/drivers/staging/usbip/userspace/src/usbip_bind.c new file mode 100644 index 000000000000..9ecaf6e574df --- /dev/null +++ b/drivers/staging/usbip/userspace/src/usbip_bind.c @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi + * + * 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, see . + */ + +#include + +#include +#include +#include +#include + +#include + +#include "usbip_common.h" +#include "utils.h" +#include "usbip.h" + +enum unbind_status { + UNBIND_ST_OK, + UNBIND_ST_USBIP_HOST, + UNBIND_ST_FAILED +}; + +static const char usbip_bind_usage_string[] = + "usbip bind \n" + " -b, --busid= Bind " USBIP_HOST_DRV_NAME ".ko to device " + "on \n"; + +void usbip_bind_usage(void) +{ + printf("usage: %s", usbip_bind_usage_string); +} + +/* call at unbound state */ +static int bind_usbip(char *busid) +{ + char bus_type[] = "usb"; + char attr_name[] = "bind"; + char sysfs_mntpath[SYSFS_PATH_MAX]; + char bind_attr_path[SYSFS_PATH_MAX]; + char intf_busid[SYSFS_BUS_ID_SIZE]; + struct sysfs_device *busid_dev; + struct sysfs_attribute *bind_attr; + struct sysfs_attribute *bConfValue; + struct sysfs_attribute *bNumIntfs; + int i, failed = 0; + int rc, ret = -1; + + rc = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX); + if (rc < 0) { + err("sysfs must be mounted: %s", strerror(errno)); + return -1; + } + + snprintf(bind_attr_path, sizeof(bind_attr_path), "%s/%s/%s/%s/%s/%s", + sysfs_mntpath, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME, + USBIP_HOST_DRV_NAME, attr_name); + + bind_attr = sysfs_open_attribute(bind_attr_path); + if (!bind_attr) { + dbg("problem getting bind attribute: %s", strerror(errno)); + return -1; + } + + busid_dev = sysfs_open_device(bus_type, busid); + if (!busid_dev) { + dbg("sysfs_open_device %s failed: %s", busid, strerror(errno)); + goto err_close_bind_attr; + } + + bConfValue = sysfs_get_device_attr(busid_dev, "bConfigurationValue"); + bNumIntfs = sysfs_get_device_attr(busid_dev, "bNumInterfaces"); + + if (!bConfValue || !bNumIntfs) { + dbg("problem getting device attributes: %s", + strerror(errno)); + goto err_close_busid_dev; + } + + for (i = 0; i < atoi(bNumIntfs->value); i++) { + snprintf(intf_busid, SYSFS_BUS_ID_SIZE, "%s:%.1s.%d", busid, + bConfValue->value, i); + + rc = sysfs_write_attribute(bind_attr, intf_busid, + SYSFS_BUS_ID_SIZE); + if (rc < 0) { + dbg("bind driver at %s failed", intf_busid); + failed = 1; + } + } + + if (!failed) + ret = 0; + +err_close_busid_dev: + sysfs_close_device(busid_dev); +err_close_bind_attr: + sysfs_close_attribute(bind_attr); + + return ret; +} + +/* buggy driver may cause dead lock */ +static int unbind_other(char *busid) +{ + char bus_type[] = "usb"; + char intf_busid[SYSFS_BUS_ID_SIZE]; + struct sysfs_device *busid_dev; + struct sysfs_device *intf_dev; + struct sysfs_driver *intf_drv; + struct sysfs_attribute *unbind_attr; + struct sysfs_attribute *bConfValue; + struct sysfs_attribute *bDevClass; + struct sysfs_attribute *bNumIntfs; + int i, rc; + enum unbind_status status = UNBIND_ST_OK; + + busid_dev = sysfs_open_device(bus_type, busid); + if (!busid_dev) { + dbg("sysfs_open_device %s failed: %s", busid, strerror(errno)); + return -1; + } + + bConfValue = sysfs_get_device_attr(busid_dev, "bConfigurationValue"); + bDevClass = sysfs_get_device_attr(busid_dev, "bDeviceClass"); + bNumIntfs = sysfs_get_device_attr(busid_dev, "bNumInterfaces"); + if (!bConfValue || !bDevClass || !bNumIntfs) { + dbg("problem getting device attributes: %s", + strerror(errno)); + goto err_close_busid_dev; + } + + if (!strncmp(bDevClass->value, "09", bDevClass->len)) { + dbg("skip unbinding of hub"); + goto err_close_busid_dev; + } + + for (i = 0; i < atoi(bNumIntfs->value); i++) { + snprintf(intf_busid, SYSFS_BUS_ID_SIZE, "%s:%.1s.%d", busid, + bConfValue->value, i); + intf_dev = sysfs_open_device(bus_type, intf_busid); + if (!intf_dev) { + dbg("could not open interface device: %s", + strerror(errno)); + goto err_close_busid_dev; + } + + dbg("%s -> %s", intf_dev->name, intf_dev->driver_name); + + if (!strncmp("unknown", intf_dev->driver_name, SYSFS_NAME_LEN)) + /* unbound interface */ + continue; + + if (!strncmp(USBIP_HOST_DRV_NAME, intf_dev->driver_name, + SYSFS_NAME_LEN)) { + /* already bound to usbip-host */ + status = UNBIND_ST_USBIP_HOST; + continue; + } + + /* unbinding */ + intf_drv = sysfs_open_driver(bus_type, intf_dev->driver_name); + if (!intf_drv) { + dbg("could not open interface driver on %s: %s", + intf_dev->name, strerror(errno)); + goto err_close_intf_dev; + } + + unbind_attr = sysfs_get_driver_attr(intf_drv, "unbind"); + if (!unbind_attr) { + dbg("problem getting interface driver attribute: %s", + strerror(errno)); + goto err_close_intf_drv; + } + + rc = sysfs_write_attribute(unbind_attr, intf_dev->bus_id, + SYSFS_BUS_ID_SIZE); + if (rc < 0) { + /* NOTE: why keep unbinding other interfaces? */ + dbg("unbind driver at %s failed", intf_dev->bus_id); + status = UNBIND_ST_FAILED; + } + + sysfs_close_driver(intf_drv); + sysfs_close_device(intf_dev); + } + + goto out; + +err_close_intf_drv: + sysfs_close_driver(intf_drv); +err_close_intf_dev: + sysfs_close_device(intf_dev); +err_close_busid_dev: + status = UNBIND_ST_FAILED; +out: + sysfs_close_device(busid_dev); + + return status; +} + +static int bind_device(char *busid) +{ + int rc; + + rc = unbind_other(busid); + if (rc == UNBIND_ST_FAILED) { + err("could not unbind driver from device on busid %s", busid); + return -1; + } else if (rc == UNBIND_ST_USBIP_HOST) { + err("device on busid %s is already bound to %s", busid, + USBIP_HOST_DRV_NAME); + return -1; + } + + rc = modify_match_busid(busid, 1); + if (rc < 0) { + err("unable to bind device on %s", busid); + return -1; + } + + rc = bind_usbip(busid); + if (rc < 0) { + err("could not bind device to %s", USBIP_HOST_DRV_NAME); + modify_match_busid(busid, 0); + return -1; + } + + printf("bind device on busid %s: complete\n", busid); + + return 0; +} + +int usbip_bind(int argc, char *argv[]) +{ + static const struct option opts[] = { + { "busid", required_argument, NULL, 'b' }, + { NULL, 0, NULL, 0 } + }; + + int opt; + int ret = -1; + + for (;;) { + opt = getopt_long(argc, argv, "b:", opts, NULL); + + if (opt == -1) + break; + + switch (opt) { + case 'b': + ret = bind_device(optarg); + goto out; + default: + goto err_out; + } + } + +err_out: + usbip_bind_usage(); +out: + return ret; +} diff --git a/drivers/staging/usbip/userspace/src/usbip_detach.c b/drivers/staging/usbip/userspace/src/usbip_detach.c new file mode 100644 index 000000000000..89bf3c195c28 --- /dev/null +++ b/drivers/staging/usbip/userspace/src/usbip_detach.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi + * + * 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, see . + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "vhci_driver.h" +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static const char usbip_detach_usage_string[] = + "usbip detach \n" + " -p, --port= " USBIP_VHCI_DRV_NAME + " port the device is on\n"; + +void usbip_detach_usage(void) +{ + printf("usage: %s", usbip_detach_usage_string); +} + +static int detach_port(char *port) +{ + int ret; + uint8_t portnum; + + for (unsigned int i=0; i < strlen(port); i++) + if (!isdigit(port[i])) { + err("invalid port %s", port); + return -1; + } + + /* check max port */ + + portnum = atoi(port); + + ret = usbip_vhci_driver_open(); + if (ret < 0) { + err("open vhci_driver"); + return -1; + } + + ret = usbip_vhci_detach_device(portnum); + if (ret < 0) + return -1; + + usbip_vhci_driver_close(); + + return ret; +} + +int usbip_detach(int argc, char *argv[]) +{ + static const struct option opts[] = { + { "port", required_argument, NULL, 'p' }, + { NULL, 0, NULL, 0 } + }; + int opt; + int ret = -1; + + for (;;) { + opt = getopt_long(argc, argv, "p:", opts, NULL); + + if (opt == -1) + break; + + switch (opt) { + case 'p': + ret = detach_port(optarg); + goto out; + default: + goto err_out; + } + } + +err_out: + usbip_detach_usage(); +out: + return ret; +} diff --git a/drivers/staging/usbip/userspace/src/usbip_list.c b/drivers/staging/usbip/userspace/src/usbip_list.c new file mode 100644 index 000000000000..ed30d910e037 --- /dev/null +++ b/drivers/staging/usbip/userspace/src/usbip_list.c @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi + * + * 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, see . + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static const char usbip_list_usage_string[] = + "usbip list [-p|--parsable] \n" + " -p, --parsable Parsable list format\n" + " -r, --remote= List the exportable USB devices on \n" + " -l, --local List the local USB devices\n"; + +void usbip_list_usage(void) +{ + printf("usage: %s", usbip_list_usage_string); +} + +static int get_exported_devices(char *host, int sockfd) +{ + char product_name[100]; + char class_name[100]; + struct op_devlist_reply reply; + uint16_t code = OP_REP_DEVLIST; + struct usbip_usb_device udev; + struct usbip_usb_interface uintf; + unsigned int i; + int j, rc; + + rc = usbip_net_send_op_common(sockfd, OP_REQ_DEVLIST, 0); + if (rc < 0) { + dbg("usbip_net_send_op_common failed"); + return -1; + } + + rc = usbip_net_recv_op_common(sockfd, &code); + if (rc < 0) { + dbg("usbip_net_recv_op_common failed"); + return -1; + } + + memset(&reply, 0, sizeof(reply)); + rc = usbip_net_recv(sockfd, &reply, sizeof(reply)); + if (rc < 0) { + dbg("usbip_net_recv_op_devlist failed"); + return -1; + } + PACK_OP_DEVLIST_REPLY(0, &reply); + dbg("exportable devices: %d\n", reply.ndev); + + if (reply.ndev == 0) { + info("no exportable devices found on %s", host); + return 0; + } + + printf("Exportable USB devices\n"); + printf("======================\n"); + printf(" - %s\n", host); + + for (i = 0; i < reply.ndev; i++) { + memset(&udev, 0, sizeof(udev)); + rc = usbip_net_recv(sockfd, &udev, sizeof(udev)); + if (rc < 0) { + dbg("usbip_net_recv failed: usbip_usb_device[%d]", i); + return -1; + } + usbip_net_pack_usb_device(0, &udev); + + usbip_names_get_product(product_name, sizeof(product_name), + udev.idVendor, udev.idProduct); + usbip_names_get_class(class_name, sizeof(class_name), + udev.bDeviceClass, udev.bDeviceSubClass, + udev.bDeviceProtocol); + printf("%11s: %s\n", udev.busid, product_name); + printf("%11s: %s\n", "", udev.path); + printf("%11s: %s\n", "", class_name); + + for (j = 0; j < udev.bNumInterfaces; j++) { + rc = usbip_net_recv(sockfd, &uintf, sizeof(uintf)); + if (rc < 0) { + dbg("usbip_net_recv failed: usbip_usb_intf[%d]", + j); + + return -1; + } + usbip_net_pack_usb_interface(0, &uintf); + + usbip_names_get_class(class_name, sizeof(class_name), + uintf.bInterfaceClass, + uintf.bInterfaceSubClass, + uintf.bInterfaceProtocol); + printf("%11s: %2d - %s\n", "", j, class_name); + } + printf("\n"); + } + + return 0; +} + +static int list_exported_devices(char *host) +{ + int rc; + int sockfd; + + sockfd = usbip_net_tcp_connect(host, USBIP_PORT_STRING); + if (sockfd < 0) { + err("could not connect to %s:%s: %s", host, + USBIP_PORT_STRING, gai_strerror(sockfd)); + return -1; + } + dbg("connected to %s:%s", host, USBIP_PORT_STRING); + + rc = get_exported_devices(host, sockfd); + if (rc < 0) { + err("failed to get device list from %s", host); + return -1; + } + + close(sockfd); + + return 0; +} + +static void print_device(char *busid, char *vendor, char *product, + bool parsable) +{ + if (parsable) + printf("busid=%s#usbid=%.4s:%.4s#", busid, vendor, product); + else + printf(" - busid %s (%.4s:%.4s)\n", busid, vendor, product); +} + +static void print_interface(char *busid, char *driver, bool parsable) +{ + if (parsable) + printf("%s=%s#", busid, driver); + else + printf("%9s%s -> %s\n", "", busid, driver); +} + +static int is_device(void *x) +{ + struct sysfs_attribute *devpath; + struct sysfs_device *dev = x; + int ret = 0; + + devpath = sysfs_get_device_attr(dev, "devpath"); + if (devpath && *devpath->value != '0') + ret = 1; + + return ret; +} + +static int devcmp(void *a, void *b) +{ + return strcmp(a, b); +} + +static int list_devices(bool parsable) +{ + char bus_type[] = "usb"; + char busid[SYSFS_BUS_ID_SIZE]; + struct sysfs_bus *ubus; + struct sysfs_device *dev; + struct sysfs_device *intf; + struct sysfs_attribute *idVendor; + struct sysfs_attribute *idProduct; + struct sysfs_attribute *bConfValue; + struct sysfs_attribute *bNumIntfs; + struct dlist *devlist; + int i; + int ret = -1; + + ubus = sysfs_open_bus(bus_type); + if (!ubus) { + err("could not open %s bus: %s", bus_type, strerror(errno)); + return -1; + } + + devlist = sysfs_get_bus_devices(ubus); + if (!devlist) { + err("could not get %s bus devices: %s", bus_type, + strerror(errno)); + goto err_out; + } + + /* remove interfaces and root hubs from device list */ + dlist_filter_sort(devlist, is_device, devcmp); + + if (!parsable) { + printf("Local USB devices\n"); + printf("=================\n"); + } + dlist_for_each_data(devlist, dev, struct sysfs_device) { + idVendor = sysfs_get_device_attr(dev, "idVendor"); + idProduct = sysfs_get_device_attr(dev, "idProduct"); + bConfValue = sysfs_get_device_attr(dev, "bConfigurationValue"); + bNumIntfs = sysfs_get_device_attr(dev, "bNumInterfaces"); + if (!idVendor || !idProduct || !bConfValue || !bNumIntfs) { + err("problem getting device attributes: %s", + strerror(errno)); + goto err_out; + } + + print_device(dev->bus_id, idVendor->value, idProduct->value, + parsable); + + for (i = 0; i < atoi(bNumIntfs->value); i++) { + snprintf(busid, sizeof(busid), "%s:%.1s.%d", + dev->bus_id, bConfValue->value, i); + intf = sysfs_open_device(bus_type, busid); + if (!intf) { + err("could not open device interface: %s", + strerror(errno)); + goto err_out; + } + print_interface(busid, intf->driver_name, parsable); + sysfs_close_device(intf); + } + printf("\n"); + } + + ret = 0; + +err_out: + sysfs_close_bus(ubus); + + return ret; +} + +int usbip_list(int argc, char *argv[]) +{ + static const struct option opts[] = { + { "parsable", no_argument, NULL, 'p' }, + { "remote", required_argument, NULL, 'r' }, + { "local", no_argument, NULL, 'l' }, + { NULL, 0, NULL, 0 } + }; + + bool parsable = false; + int opt; + int ret = -1; + + if (usbip_names_init(USBIDS_FILE)) + err("failed to open %s", USBIDS_FILE); + + for (;;) { + opt = getopt_long(argc, argv, "pr:l", opts, NULL); + + if (opt == -1) + break; + + switch (opt) { + case 'p': + parsable = true; + break; + case 'r': + ret = list_exported_devices(optarg); + goto out; + case 'l': + ret = list_devices(parsable); + goto out; + default: + goto err_out; + } + } + +err_out: + usbip_list_usage(); +out: + usbip_names_free(); + + return ret; +} diff --git a/drivers/staging/usbip/userspace/src/usbip_network.c b/drivers/staging/usbip/userspace/src/usbip_network.c index 01be3c7211d5..1a84dd37e125 100644 --- a/drivers/staging/usbip/userspace/src/usbip_network.c +++ b/drivers/staging/usbip/userspace/src/usbip_network.c @@ -1,11 +1,34 @@ /* + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi * - * Copyright (C) 2005-2007 Takahiro Hirofuchi + * 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, see . */ +#include + +#include + +#include +#include +#include +#include + +#include "usbip_common.h" #include "usbip_network.h" -void pack_uint32_t(int pack, uint32_t *num) +void usbip_net_pack_uint32_t(int pack, uint32_t *num) { uint32_t i; @@ -17,7 +40,7 @@ void pack_uint32_t(int pack, uint32_t *num) *num = i; } -void pack_uint16_t(int pack, uint16_t *num) +void usbip_net_pack_uint16_t(int pack, uint16_t *num) { uint16_t i; @@ -29,34 +52,34 @@ void pack_uint16_t(int pack, uint16_t *num) *num = i; } -void pack_usb_device(int pack, struct usb_device *udev) +void usbip_net_pack_usb_device(int pack, struct usbip_usb_device *udev) { - pack_uint32_t(pack, &udev->busnum); - pack_uint32_t(pack, &udev->devnum); - pack_uint32_t(pack, &udev->speed ); + usbip_net_pack_uint32_t(pack, &udev->busnum); + usbip_net_pack_uint32_t(pack, &udev->devnum); + usbip_net_pack_uint32_t(pack, &udev->speed ); - pack_uint16_t(pack, &udev->idVendor ); - pack_uint16_t(pack, &udev->idProduct); - pack_uint16_t(pack, &udev->bcdDevice); + usbip_net_pack_uint16_t(pack, &udev->idVendor); + usbip_net_pack_uint16_t(pack, &udev->idProduct); + usbip_net_pack_uint16_t(pack, &udev->bcdDevice); } -void pack_usb_interface(int pack __attribute__((unused)), - struct usb_interface *udev __attribute__((unused))) +void usbip_net_pack_usb_interface(int pack __attribute__((unused)), + struct usbip_usb_interface *udev + __attribute__((unused))) { /* uint8_t members need nothing */ } - -static ssize_t usbip_xmit(int sockfd, void *buff, size_t bufflen, int sending) +static ssize_t usbip_net_xmit(int sockfd, void *buff, size_t bufflen, + int sending) { + ssize_t nbytes; ssize_t total = 0; if (!bufflen) return 0; do { - ssize_t nbytes; - if (sending) nbytes = send(sockfd, buff, bufflen, 0); else @@ -65,80 +88,81 @@ static ssize_t usbip_xmit(int sockfd, void *buff, size_t bufflen, int sending) if (nbytes <= 0) return -1; - buff = (void *) ((intptr_t) buff + nbytes); + buff = (void *)((intptr_t) buff + nbytes); bufflen -= nbytes; total += nbytes; } while (bufflen > 0); - return total; } -ssize_t usbip_recv(int sockfd, void *buff, size_t bufflen) +ssize_t usbip_net_recv(int sockfd, void *buff, size_t bufflen) { - return usbip_xmit(sockfd, buff, bufflen, 0); + return usbip_net_xmit(sockfd, buff, bufflen, 0); } -ssize_t usbip_send(int sockfd, void *buff, size_t bufflen) +ssize_t usbip_net_send(int sockfd, void *buff, size_t bufflen) { - return usbip_xmit(sockfd, buff, bufflen, 1); + return usbip_net_xmit(sockfd, buff, bufflen, 1); } -int usbip_send_op_common(int sockfd, uint32_t code, uint32_t status) +int usbip_net_send_op_common(int sockfd, uint32_t code, uint32_t status) { - int ret; struct op_common op_common; + int rc; - bzero(&op_common, sizeof(op_common)); + memset(&op_common, 0, sizeof(op_common)); - op_common.version = USBIP_VERSION; - op_common.code = code; - op_common.status = status; + op_common.version = USBIP_VERSION; + op_common.code = code; + op_common.status = status; PACK_OP_COMMON(1, &op_common); - ret = usbip_send(sockfd, (void *) &op_common, sizeof(op_common)); - if (ret < 0) { - err("send op_common"); + rc = usbip_net_send(sockfd, &op_common, sizeof(op_common)); + if (rc < 0) { + dbg("usbip_net_send failed: %d", rc); return -1; } return 0; } -int usbip_recv_op_common(int sockfd, uint16_t *code) +int usbip_net_recv_op_common(int sockfd, uint16_t *code) { - int ret; struct op_common op_common; + int rc; - bzero(&op_common, sizeof(op_common)); + memset(&op_common, 0, sizeof(op_common)); - ret = usbip_recv(sockfd, (void *) &op_common, sizeof(op_common)); - if (ret < 0) { - err("recv op_common, %d", ret); + rc = usbip_net_recv(sockfd, &op_common, sizeof(op_common)); + if (rc < 0) { + dbg("usbip_net_recv failed: %d", rc); goto err; } PACK_OP_COMMON(0, &op_common); if (op_common.version != USBIP_VERSION) { - err("version mismatch, %d %d", op_common.version, USBIP_VERSION); + dbg("version mismatch: %d %d", op_common.version, + USBIP_VERSION); goto err; } - switch(*code) { - case OP_UNSPEC: - break; - default: - if (op_common.code != *code) { - info("unexpected pdu %d for %d", op_common.code, *code); - goto err; - } + switch (*code) { + case OP_UNSPEC: + break; + default: + if (op_common.code != *code) { + dbg("unexpected pdu %#0x for %#0x", op_common.code, + *code); + goto err; + } } if (op_common.status != ST_OK) { - info("request failed at peer, %d", op_common.status); + dbg("request failed at peer: %d", op_common.status); goto err; } @@ -149,103 +173,85 @@ int usbip_recv_op_common(int sockfd, uint16_t *code) return -1; } - -int usbip_set_reuseaddr(int sockfd) +int usbip_net_set_reuseaddr(int sockfd) { const int val = 1; int ret; ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); if (ret < 0) - err("setsockopt SO_REUSEADDR"); + dbg("setsockopt: SO_REUSEADDR"); return ret; } -int usbip_set_nodelay(int sockfd) +int usbip_net_set_nodelay(int sockfd) { const int val = 1; int ret; ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); if (ret < 0) - err("setsockopt TCP_NODELAY"); + dbg("setsockopt: TCP_NODELAY"); return ret; } -int usbip_set_keepalive(int sockfd) +int usbip_net_set_keepalive(int sockfd) { const int val = 1; int ret; ret = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); if (ret < 0) - err("setsockopt SO_KEEPALIVE"); + dbg("setsockopt: SO_KEEPALIVE"); return ret; } -/* IPv6 Ready */ /* - * moved here from vhci_attach.c + * IPv6 Ready */ -int tcp_connect(char *hostname, char *service) +int usbip_net_tcp_connect(char *hostname, char *service) { - struct addrinfo hints, *res, *res0; + struct addrinfo hints, *res, *rp; int sockfd; - int err; - + int ret; memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; /* get all possible addresses */ - err = getaddrinfo(hostname, service, &hints, &res0); - if (err) { - err("%s %s: %s", hostname, service, gai_strerror(err)); - return -1; + ret = getaddrinfo(hostname, service, &hints, &res); + if (ret < 0) { + dbg("getaddrinfo: %s service %s: %s", hostname, service, + gai_strerror(ret)); + return ret; } - /* try all the addresses */ - for (res = res0; res; res = res->ai_next) { - char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; - - err = getnameinfo(res->ai_addr, res->ai_addrlen, - hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); - if (err) { - err("%s %s: %s", hostname, service, gai_strerror(err)); + /* try the addresses */ + for (rp = res; rp; rp = rp->ai_next) { + sockfd = socket(rp->ai_family, rp->ai_socktype, + rp->ai_protocol); + if (sockfd < 0) continue; - } - - dbg("trying %s port %s\n", hbuf, sbuf); - - sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (sockfd < 0) { - err("socket"); - continue; - } /* should set TCP_NODELAY for usbip */ - usbip_set_nodelay(sockfd); - /* TODO: write code for heatbeat */ - usbip_set_keepalive(sockfd); + usbip_net_set_nodelay(sockfd); + /* TODO: write code for heartbeat */ + usbip_net_set_keepalive(sockfd); - err = connect(sockfd, res->ai_addr, res->ai_addrlen); - if (err < 0) { - close(sockfd); - continue; - } + if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) == 0) + break; - /* connected */ - dbg("connected to %s:%s", hbuf, sbuf); - freeaddrinfo(res0); - return sockfd; + close(sockfd); } + if (!rp) + return EAI_SYSTEM; - dbg("%s:%s, %s", hostname, service, "no destination to connect to"); - freeaddrinfo(res0); + freeaddrinfo(res); - return -1; + return sockfd; } diff --git a/drivers/staging/usbip/userspace/src/usbip_network.h b/drivers/staging/usbip/userspace/src/usbip_network.h index 1225466e1c59..2d1e070fb7b8 100644 --- a/drivers/staging/usbip/userspace/src/usbip_network.h +++ b/drivers/staging/usbip/userspace/src/usbip_network.h @@ -2,19 +2,20 @@ * Copyright (C) 2005-2007 Takahiro Hirofuchi */ -#ifndef _USBIP_NETWORK_H -#define _USBIP_NETWORK_H +#ifndef __USBIP_NETWORK_H +#define __USBIP_NETWORK_H + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif -#include "usbip.h" #include -#include -#include +#include +#include -/* -------------------------------------------------- */ -/* Define Protocol Format */ -/* -------------------------------------------------- */ - +#define USBIP_PORT 3240 +#define USBIP_PORT_STRING "3240" /* ---------------------------------------------------------------------- */ /* Common header for all the kinds of PDUs. */ @@ -33,12 +34,11 @@ struct op_common { } __attribute__((packed)); #define PACK_OP_COMMON(pack, op_common) do {\ - pack_uint16_t(pack, &(op_common)->version);\ - pack_uint16_t(pack, &(op_common)->code );\ - pack_uint32_t(pack, &(op_common)->status );\ + usbip_net_pack_uint16_t(pack, &(op_common)->version);\ + usbip_net_pack_uint16_t(pack, &(op_common)->code );\ + usbip_net_pack_uint32_t(pack, &(op_common)->status );\ } while (0) - /* ---------------------------------------------------------------------- */ /* Dummy Code */ #define OP_UNSPEC 0x00 @@ -56,11 +56,10 @@ struct op_devinfo_request { } __attribute__((packed)); struct op_devinfo_reply { - struct usb_device udev; - struct usb_interface uinf[]; + struct usbip_usb_device udev; + struct usbip_usb_interface uinf[]; } __attribute__((packed)); - /* ---------------------------------------------------------------------- */ /* Import a remote USB device. */ #define OP_IMPORT 0x03 @@ -72,19 +71,17 @@ struct op_import_request { } __attribute__((packed)); struct op_import_reply { - struct usb_device udev; -// struct usb_interface uinf[]; + struct usbip_usb_device udev; +// struct usbip_usb_interface uinf[]; } __attribute__((packed)); #define PACK_OP_IMPORT_REQUEST(pack, request) do {\ } while (0) #define PACK_OP_IMPORT_REPLY(pack, reply) do {\ - pack_usb_device(pack, &(reply)->udev);\ + usbip_net_pack_usb_device(pack, &(reply)->udev);\ } while (0) - - /* ---------------------------------------------------------------------- */ /* Export a USB device to a remote host. */ #define OP_EXPORT 0x06 @@ -92,7 +89,7 @@ struct op_import_reply { #define OP_REP_EXPORT (OP_REPLY | OP_EXPORT) struct op_export_request { - struct usb_device udev; + struct usbip_usb_device udev; } __attribute__((packed)); struct op_export_reply { @@ -101,7 +98,7 @@ struct op_export_reply { #define PACK_OP_EXPORT_REQUEST(pack, request) do {\ - pack_usb_device(pack, &(request)->udev);\ + usbip_net_pack_usb_device(pack, &(request)->udev);\ } while (0) #define PACK_OP_EXPORT_REPLY(pack, reply) do {\ @@ -114,7 +111,7 @@ struct op_export_reply { #define OP_REP_UNEXPORT (OP_REPLY | OP_UNEXPORT) struct op_unexport_request { - struct usb_device udev; + struct usbip_usb_device udev; } __attribute__((packed)); struct op_unexport_reply { @@ -122,14 +119,12 @@ struct op_unexport_reply { } __attribute__((packed)); #define PACK_OP_UNEXPORT_REQUEST(pack, request) do {\ - pack_usb_device(pack, &(request)->udev);\ + usbip_net_pack_usb_device(pack, &(request)->udev);\ } while (0) #define PACK_OP_UNEXPORT_REPLY(pack, reply) do {\ } while (0) - - /* ---------------------------------------------------------------------- */ /* Negotiate IPSec encryption key. (still not used) */ #define OP_CRYPKEY 0x04 @@ -161,38 +156,29 @@ struct op_devlist_reply { } __attribute__((packed)); struct op_devlist_reply_extra { - struct usb_device udev; - struct usb_interface uinf[]; + struct usbip_usb_device udev; + struct usbip_usb_interface uinf[]; } __attribute__((packed)); #define PACK_OP_DEVLIST_REQUEST(pack, request) do {\ } while (0) #define PACK_OP_DEVLIST_REPLY(pack, reply) do {\ - pack_uint32_t(pack, &(reply)->ndev);\ + usbip_net_pack_uint32_t(pack, &(reply)->ndev);\ } while (0) +void usbip_net_pack_uint32_t(int pack, uint32_t *num); +void usbip_net_pack_uint16_t(int pack, uint16_t *num); +void usbip_net_pack_usb_device(int pack, struct usbip_usb_device *udev); +void usbip_net_pack_usb_interface(int pack, struct usbip_usb_interface *uinf); -/* -------------------------------------------------- */ -/* Declare Prototype Function */ -/* -------------------------------------------------- */ +ssize_t usbip_net_recv(int sockfd, void *buff, size_t bufflen); +ssize_t usbip_net_send(int sockfd, void *buff, size_t bufflen); +int usbip_net_send_op_common(int sockfd, uint32_t code, uint32_t status); +int usbip_net_recv_op_common(int sockfd, uint16_t *code); +int usbip_net_set_reuseaddr(int sockfd); +int usbip_net_set_nodelay(int sockfd); +int usbip_net_set_keepalive(int sockfd); +int usbip_net_tcp_connect(char *hostname, char *port); -void pack_uint32_t(int pack, uint32_t *num); -void pack_uint16_t(int pack, uint16_t *num); -void pack_usb_device(int pack, struct usb_device *udev); -void pack_usb_interface(int pack, struct usb_interface *uinf); - -ssize_t usbip_recv(int sockfd, void *buff, size_t bufflen); -ssize_t usbip_send(int sockfd, void *buff, size_t bufflen); -int usbip_send_op_common(int sockfd, uint32_t code, uint32_t status); -int usbip_recv_op_common(int sockfd, uint16_t *code); -int usbip_set_reuseaddr(int sockfd); -int usbip_set_nodelay(int sockfd); -int usbip_set_keepalive(int sockfd); - -int tcp_connect(char *hostname, char *service); - -#define USBIP_PORT 3240 -#define USBIP_PORT_STRING "3240" - -#endif +#endif /* __USBIP_NETWORK_H */ diff --git a/drivers/staging/usbip/userspace/src/usbip_unbind.c b/drivers/staging/usbip/userspace/src/usbip_unbind.c new file mode 100644 index 000000000000..d5a9ab6af2a6 --- /dev/null +++ b/drivers/staging/usbip/userspace/src/usbip_unbind.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi + * + * 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, see . + */ + +#include + +#include +#include +#include + +#include + +#include "usbip_common.h" +#include "utils.h" +#include "usbip.h" + +static const char usbip_unbind_usage_string[] = + "usbip unbind \n" + " -b, --busid= Unbind " USBIP_HOST_DRV_NAME ".ko from " + "device on \n"; + +void usbip_unbind_usage(void) +{ + printf("usage: %s", usbip_unbind_usage_string); +} + +static int unbind_device(char *busid) +{ + char bus_type[] = "usb"; + struct sysfs_driver *usbip_host_drv; + struct sysfs_device *dev; + struct dlist *devlist; + int verified = 0; + int rc, ret = -1; + + char attr_name[] = "bConfigurationValue"; + char sysfs_mntpath[SYSFS_PATH_MAX]; + char busid_attr_path[SYSFS_PATH_MAX]; + struct sysfs_attribute *busid_attr; + char *val = NULL; + int len; + + /* verify the busid device is using usbip-host */ + usbip_host_drv = sysfs_open_driver(bus_type, USBIP_HOST_DRV_NAME); + if (!usbip_host_drv) { + err("could not open %s driver: %s", USBIP_HOST_DRV_NAME, + strerror(errno)); + return -1; + } + + devlist = sysfs_get_driver_devices(usbip_host_drv); + if (!devlist) { + err("%s is not in use by any devices", USBIP_HOST_DRV_NAME); + goto err_close_usbip_host_drv; + } + + dlist_for_each_data(devlist, dev, struct sysfs_device) { + if (!strncmp(busid, dev->name, strlen(busid)) && + !strncmp(dev->driver_name, USBIP_HOST_DRV_NAME, + strlen(USBIP_HOST_DRV_NAME))) { + verified = 1; + break; + } + } + + if (!verified) { + err("device on busid %s is not using %s", busid, + USBIP_HOST_DRV_NAME); + goto err_close_usbip_host_drv; + } + + /* + * NOTE: A read and write of an attribute value of the device busid + * refers to must be done to start probing. That way a rebind of the + * default driver for the device occurs. + * + * This seems very hackish and adds a lot of pointless code. I think it + * should be done in the kernel by the driver after del_match_busid is + * finished! + */ + + rc = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX); + if (rc < 0) { + err("sysfs must be mounted: %s", strerror(errno)); + return -1; + } + + snprintf(busid_attr_path, sizeof(busid_attr_path), "%s/%s/%s/%s/%s/%s", + sysfs_mntpath, SYSFS_BUS_NAME, bus_type, SYSFS_DEVICES_NAME, + busid, attr_name); + + /* read a device attribute */ + busid_attr = sysfs_open_attribute(busid_attr_path); + if (!busid_attr) { + err("could not open %s/%s: %s", busid, attr_name, + strerror(errno)); + return -1; + } + + if (sysfs_read_attribute(busid_attr) < 0) { + err("problem reading attribute: %s", strerror(errno)); + goto err_out; + } + + len = busid_attr->len; + val = malloc(len); + *val = *busid_attr->value; + sysfs_close_attribute(busid_attr); + + /* notify driver of unbind */ + rc = modify_match_busid(busid, 0); + if (rc < 0) { + err("unable to unbind device on %s", busid); + goto err_out; + } + + /* write the device attribute */ + busid_attr = sysfs_open_attribute(busid_attr_path); + if (!busid_attr) { + err("could not open %s/%s: %s", busid, attr_name, + strerror(errno)); + return -1; + } + + rc = sysfs_write_attribute(busid_attr, val, len); + if (rc < 0) { + err("problem writing attribute: %s", strerror(errno)); + goto err_out; + } + sysfs_close_attribute(busid_attr); + + ret = 0; + printf("unbind device on busid %s: complete\n", busid); + +err_out: + free(val); +err_close_usbip_host_drv: + sysfs_close_driver(usbip_host_drv); + + return ret; +} + +int usbip_unbind(int argc, char *argv[]) +{ + static const struct option opts[] = { + { "busid", required_argument, NULL, 'b' }, + { NULL, 0, NULL, 0 } + }; + + int opt; + int ret = -1; + + for (;;) { + opt = getopt_long(argc, argv, "b:", opts, NULL); + + if (opt == -1) + break; + + switch (opt) { + case 'b': + ret = unbind_device(optarg); + goto out; + default: + goto err_out; + } + } + +err_out: + usbip_unbind_usage(); +out: + return ret; +} diff --git a/drivers/staging/usbip/userspace/src/usbipd.c b/drivers/staging/usbip/userspace/src/usbipd.c index ec9faac5ff8f..8668a8092d4d 100644 --- a/drivers/staging/usbip/userspace/src/usbipd.c +++ b/drivers/staging/usbip/userspace/src/usbipd.c @@ -1,15 +1,29 @@ /* + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi * - * Copyright (C) 2005-2007 Takahiro Hirofuchi + * 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, see . */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif +#include #include #include -#include +#include #include #include #include @@ -23,124 +37,64 @@ #define _GNU_SOURCE #include +#include #include -#include "usbip.h" +#include "usbip_host_driver.h" +#include "usbip_common.h" #include "usbip_network.h" -#include +#undef PROGNAME +#define PROGNAME "usbipd" +#define MAXSOCKFD 20 -static const char version[] = PACKAGE_STRING; +GMainLoop *main_loop; +static const char usbip_version_string[] = PACKAGE_STRING; -static int send_reply_devlist(int sockfd) +static const char usbipd_help_string[] = + "usage: usbipd [options] \n" + " -D, --daemon \n" + " Run as a daemon process. \n" + " \n" + " -d, --debug \n" + " Print debugging information. \n" + " \n" + " -h, --help \n" + " Print this help. \n" + " \n" + " -v, --version \n" + " Show version. \n"; + +static void usbipd_help(void) { - int ret; - struct usbip_exported_device *edev; - struct op_devlist_reply reply; - - - reply.ndev = 0; - - /* how many devices are exported ? */ - dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) { - reply.ndev += 1; - } - - dbg("%d devices are exported", reply.ndev); - - ret = usbip_send_op_common(sockfd, OP_REP_DEVLIST, ST_OK); - if (ret < 0) { - err("send op_common"); - return ret; - } - - PACK_OP_DEVLIST_REPLY(1, &reply); - - ret = usbip_send(sockfd, (void *) &reply, sizeof(reply)); - if (ret < 0) { - err("send op_devlist_reply"); - return ret; - } - - dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) { - struct usb_device pdu_udev; - - dump_usb_device(&edev->udev); - memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev)); - pack_usb_device(1, &pdu_udev); - - ret = usbip_send(sockfd, (void *) &pdu_udev, sizeof(pdu_udev)); - if (ret < 0) { - err("send pdu_udev"); - return ret; - } - - for (int i=0; i < edev->udev.bNumInterfaces; i++) { - struct usb_interface pdu_uinf; - - dump_usb_interface(&edev->uinf[i]); - memcpy(&pdu_uinf, &edev->uinf[i], sizeof(pdu_uinf)); - pack_usb_interface(1, &pdu_uinf); - - ret = usbip_send(sockfd, (void *) &pdu_uinf, sizeof(pdu_uinf)); - if (ret < 0) { - err("send pdu_uinf"); - return ret; - } - } - } - - return 0; + printf("%s\n", usbipd_help_string); } - -static int recv_request_devlist(int sockfd) -{ - int ret; - struct op_devlist_request req; - - bzero(&req, sizeof(req)); - - ret = usbip_recv(sockfd, (void *) &req, sizeof(req)); - if (ret < 0) { - err("recv devlist request"); - return -1; - } - - ret = send_reply_devlist(sockfd); - if (ret < 0) { - err("send devlist reply"); - return -1; - } - - return 0; -} - - static int recv_request_import(int sockfd) { - int ret; struct op_import_request req; struct op_common reply; struct usbip_exported_device *edev; + struct usbip_usb_device pdu_udev; int found = 0; int error = 0; + int rc; - bzero(&req, sizeof(req)); - bzero(&reply, sizeof(reply)); + memset(&req, 0, sizeof(req)); + memset(&reply, 0, sizeof(reply)); - ret = usbip_recv(sockfd, (void *) &req, sizeof(req)); - if (ret < 0) { - err("recv import request"); + rc = usbip_net_recv(sockfd, &req, sizeof(req)); + if (rc < 0) { + dbg("usbip_net_recv failed: import request"); return -1; } - PACK_OP_IMPORT_REQUEST(0, &req); - dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) { + dlist_for_each_data(host_driver->edev_list, edev, + struct usbip_exported_device) { if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) { - dbg("found requested device %s", req.busid); + info("found requested device: %s", req.busid); found = 1; break; } @@ -148,229 +102,323 @@ static int recv_request_import(int sockfd) if (found) { /* should set TCP_NODELAY for usbip */ - usbip_set_nodelay(sockfd); + usbip_net_set_nodelay(sockfd); - /* export_device needs a TCP/IP socket descriptor */ - ret = usbip_stub_export_device(edev, sockfd); - if (ret < 0) + /* export device needs a TCP/IP socket descriptor */ + rc = usbip_host_export_device(edev, sockfd); + if (rc < 0) error = 1; } else { - info("not found requested device %s", req.busid); + info("requested device not found: %s", req.busid); error = 1; } - - ret = usbip_send_op_common(sockfd, OP_REP_IMPORT, (!error ? ST_OK : ST_NA)); - if (ret < 0) { - err("send import reply"); + rc = usbip_net_send_op_common(sockfd, OP_REP_IMPORT, + (!error ? ST_OK : ST_NA)); + if (rc < 0) { + dbg("usbip_net_send_op_common failed: %#0x", OP_REP_IMPORT); return -1; } - if (!error) { - struct usb_device pdu_udev; + if (error) { + dbg("import request busid %s: failed", req.busid); + return -1; + } + memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev)); + usbip_net_pack_usb_device(1, &pdu_udev); + + rc = usbip_net_send(sockfd, &pdu_udev, sizeof(pdu_udev)); + if (rc < 0) { + dbg("usbip_net_send failed: devinfo"); + return -1; + } + + dbg("import request busid %s: complete", req.busid); + + return 0; +} + +static int send_reply_devlist(int connfd) +{ + struct usbip_exported_device *edev; + struct usbip_usb_device pdu_udev; + struct usbip_usb_interface pdu_uinf; + struct op_devlist_reply reply; + int i; + int rc; + + reply.ndev = 0; + /* number of exported devices */ + dlist_for_each_data(host_driver->edev_list, edev, + struct usbip_exported_device) { + reply.ndev += 1; + } + info("exportable devices: %d", reply.ndev); + + rc = usbip_net_send_op_common(connfd, OP_REP_DEVLIST, ST_OK); + if (rc < 0) { + dbg("usbip_net_send_op_common failed: %#0x", OP_REP_DEVLIST); + return -1; + } + PACK_OP_DEVLIST_REPLY(1, &reply); + + rc = usbip_net_send(connfd, &reply, sizeof(reply)); + if (rc < 0) { + dbg("usbip_net_send failed: %#0x", OP_REP_DEVLIST); + return -1; + } + + dlist_for_each_data(host_driver->edev_list, edev, + struct usbip_exported_device) { + dump_usb_device(&edev->udev); memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev)); - pack_usb_device(1, &pdu_udev); + usbip_net_pack_usb_device(1, &pdu_udev); - ret = usbip_send(sockfd, (void *) &pdu_udev, sizeof(pdu_udev)); - if (ret < 0) { - err("send devinfo"); + rc = usbip_net_send(connfd, &pdu_udev, sizeof(pdu_udev)); + if (rc < 0) { + dbg("usbip_net_send failed: pdu_udev"); return -1; } + + for (i = 0; i < edev->udev.bNumInterfaces; i++) { + dump_usb_interface(&edev->uinf[i]); + memcpy(&pdu_uinf, &edev->uinf[i], sizeof(pdu_uinf)); + usbip_net_pack_usb_interface(1, &pdu_uinf); + + rc = usbip_net_send(connfd, &pdu_uinf, + sizeof(pdu_uinf)); + if (rc < 0) { + dbg("usbip_net_send failed: pdu_uinf"); + return -1; + } + } } return 0; } - - -static int recv_pdu(int sockfd) +static int recv_request_devlist(int connfd) { - int ret; - uint16_t code = OP_UNSPEC; + struct op_devlist_request req; + int rc; + memset(&req, 0, sizeof(req)); - ret = usbip_recv_op_common(sockfd, &code); - if (ret < 0) { - err("recv op_common, %d", ret); - return ret; - } - - - ret = usbip_stub_refresh_device_list(); - if (ret < 0) + rc = usbip_net_recv(connfd, &req, sizeof(req)); + if (rc < 0) { + dbg("usbip_net_recv failed: devlist request"); return -1; - - switch(code) { - case OP_REQ_DEVLIST: - ret = recv_request_devlist(sockfd); - break; - - case OP_REQ_IMPORT: - ret = recv_request_import(sockfd); - break; - - case OP_REQ_DEVINFO: - case OP_REQ_CRYPKEY: - - default: - err("unknown op_code, %d", code); - ret = -1; } + rc = send_reply_devlist(connfd); + if (rc < 0) { + dbg("send_reply_devlist failed"); + return -1; + } + + return 0; +} + +static int recv_pdu(int connfd) +{ + uint16_t code = OP_UNSPEC; + int ret; + + ret = usbip_net_recv_op_common(connfd, &code); + if (ret < 0) { + dbg("could not receive opcode: %#0x", code); + return -1; + } + + ret = usbip_host_refresh_device_list(); + if (ret < 0) { + dbg("could not refresh device list: %d", ret); + return -1; + } + + info("received request: %#0x(%d)", code, connfd); + switch (code) { + case OP_REQ_DEVLIST: + ret = recv_request_devlist(connfd); + break; + case OP_REQ_IMPORT: + ret = recv_request_import(connfd); + break; + case OP_REQ_DEVINFO: + case OP_REQ_CRYPKEY: + default: + err("received an unknown opcode: %#0x", code); + ret = -1; + } + + if (ret == 0) + info("request %#0x(%d): complete", code, connfd); + else + info("request %#0x(%d): failed", code, connfd); return ret; } +#ifdef HAVE_LIBWRAP +static int tcpd_auth(int connfd) +{ + struct request_info request; + int rc; + request_init(&request, RQ_DAEMON, PROGNAME, RQ_FILE, connfd, 0); + fromhost(&request); + rc = hosts_access(&request); + if (rc == 0) + return -1; + return 0; +} +#endif + +static int do_accept(int listenfd) +{ + int connfd; + struct sockaddr_storage ss; + socklen_t len = sizeof(ss); + char host[NI_MAXHOST], port[NI_MAXSERV]; + int rc; + + memset(&ss, 0, sizeof(ss)); + + connfd = accept(listenfd, (struct sockaddr *) &ss, &len); + if (connfd < 0) { + err("failed to accept connection"); + return -1; + } + + rc = getnameinfo((struct sockaddr *) &ss, len, host, sizeof(host), + port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); + if (rc) + err("getnameinfo: %s", gai_strerror(rc)); + +#ifdef HAVE_LIBWRAP + rc = tcpd_auth(connfd); + if (rc < 0) { + info("denied access from %s", host); + close(connfd); + return -1; + } +#endif + info("connection from %s:%s", host, port); + + return connfd; +} + +gboolean process_request(GIOChannel *gio, GIOCondition condition, + gpointer unused_data) +{ + int listenfd; + int connfd; + + (void) unused_data; + + if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { + err("unknown condition"); + BUG(); + } + + if (condition & G_IO_IN) { + listenfd = g_io_channel_unix_get_fd(gio); + connfd = do_accept(listenfd); + if (connfd < 0) + return TRUE; + + recv_pdu(connfd); + close(connfd); + } + + return TRUE; +} static void log_addrinfo(struct addrinfo *ai) { - int ret; char hbuf[NI_MAXHOST]; char sbuf[NI_MAXSERV]; + int rc; - ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), - sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); - if (ret) - err("getnameinfo, %s", gai_strerror(ret)); + rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf), + sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); + if (rc) + err("getnameinfo: %s", gai_strerror(rc)); - info("listen at [%s]:%s", hbuf, sbuf); + info("listening on %s:%s", hbuf, sbuf); } -static struct addrinfo *my_getaddrinfo(char *host, int ai_family) +static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[]) +{ + struct addrinfo *ai; + int ret, nsockfd = 0; + + for (ai = ai_head; ai && nsockfd < MAXSOCKFD; ai = ai->ai_next) { + sockfdlist[nsockfd] = socket(ai->ai_family, ai->ai_socktype, + ai->ai_protocol); + if (sockfdlist[nsockfd] < 0) + continue; + + usbip_net_set_reuseaddr(sockfdlist[nsockfd]); + usbip_net_set_nodelay(sockfdlist[nsockfd]); + + if (sockfdlist[nsockfd] >= FD_SETSIZE) { + close(sockfdlist[nsockfd]); + sockfdlist[nsockfd] = -1; + continue; + } + + ret = bind(sockfdlist[nsockfd], ai->ai_addr, ai->ai_addrlen); + if (ret < 0) { + close(sockfdlist[nsockfd]); + sockfdlist[nsockfd] = -1; + continue; + } + + ret = listen(sockfdlist[nsockfd], SOMAXCONN); + if (ret < 0) { + close(sockfdlist[nsockfd]); + sockfdlist[nsockfd] = -1; + continue; + } + + log_addrinfo(ai); + nsockfd++; + } + + if (nsockfd == 0) + return -1; + + dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es"); + + return nsockfd; +} + +static struct addrinfo *do_getaddrinfo(char *host, int ai_family) { - int ret; struct addrinfo hints, *ai_head; + int rc; - bzero(&hints, sizeof(hints)); - + memset(&hints, 0, sizeof(hints)); hints.ai_family = ai_family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; - ret = getaddrinfo(host, USBIP_PORT_STRING, &hints, &ai_head); - if (ret) { - err("%s: %s", USBIP_PORT_STRING, gai_strerror(ret)); + rc = getaddrinfo(host, USBIP_PORT_STRING, &hints, &ai_head); + if (rc) { + err("failed to get a network address %s: %s", USBIP_PORT_STRING, + gai_strerror(rc)); return NULL; } return ai_head; } -#define MAXSOCK 20 -static int listen_all_addrinfo(struct addrinfo *ai_head, int lsock[]) -{ - struct addrinfo *ai; - int n = 0; /* number of sockets */ - - for (ai = ai_head; ai && n < MAXSOCK; ai = ai->ai_next) { - int ret; - - lsock[n] = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (lsock[n] < 0) - continue; - - usbip_set_reuseaddr(lsock[n]); - usbip_set_nodelay(lsock[n]); - - if (lsock[n] >= FD_SETSIZE) { - close(lsock[n]); - lsock[n] = -1; - continue; - } - - ret = bind(lsock[n], ai->ai_addr, ai->ai_addrlen); - if (ret < 0) { - close(lsock[n]); - lsock[n] = -1; - continue; - } - - ret = listen(lsock[n], SOMAXCONN); - if (ret < 0) { - close(lsock[n]); - lsock[n] = -1; - continue; - } - - log_addrinfo(ai); - - /* next if succeed */ - n++; - } - - if (n == 0) { - err("no socket to listen to"); - return -1; - } - - dbg("listen %d address%s", n, (n==1)?"":"es"); - - return n; -} - -#ifdef HAVE_LIBWRAP -static int tcpd_auth(int csock) -{ - int ret; - struct request_info request; - - request_init(&request, RQ_DAEMON, "usbipd", RQ_FILE, csock, 0); - - fromhost(&request); - - ret = hosts_access(&request); - if (!ret) - return -1; - - return 0; -} -#endif - -static int my_accept(int lsock) -{ - int csock; - struct sockaddr_storage ss; - socklen_t len = sizeof(ss); - char host[NI_MAXHOST], port[NI_MAXSERV]; - int ret; - - bzero(&ss, sizeof(ss)); - - csock = accept(lsock, (struct sockaddr *) &ss, &len); - if (csock < 0) { - err("accept"); - return -1; - } - - ret = getnameinfo((struct sockaddr *) &ss, len, - host, sizeof(host), port, sizeof(port), - (NI_NUMERICHOST | NI_NUMERICSERV)); - if (ret) - err("getnameinfo, %s", gai_strerror(ret)); - -#ifdef HAVE_LIBWRAP - ret = tcpd_auth(csock); - if (ret < 0) { - info("deny access from %s", host); - close(csock); - return -1; - } -#endif - - info("connected from %s:%s", host, port); - - return csock; -} - - -GMainLoop *main_loop; - static void signal_handler(int i) { - dbg("signal catched, code %d", i); + dbg("received signal: code %d", i); if (main_loop) g_main_loop_quit(main_loop); @@ -380,191 +428,140 @@ static void set_signal(void) { struct sigaction act; - bzero(&act, sizeof(act)); + memset(&act, 0, sizeof(act)); act.sa_handler = signal_handler; sigemptyset(&act.sa_mask); sigaction(SIGTERM, &act, NULL); sigaction(SIGINT, &act, NULL); } - -gboolean process_comming_request(GIOChannel *gio, GIOCondition condition, - gpointer data __attribute__((unused))) +static int do_standalone_mode(gboolean daemonize) { - int ret; + struct addrinfo *ai_head; + int sockfdlist[MAXSOCKFD]; + int nsockfd; + int i; - if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) - g_error("unknown condition"); + if (usbip_names_init(USBIDS_FILE)) + err("failed to open %s", USBIDS_FILE); - - if (condition & G_IO_IN) { - int lsock; - int csock; - - lsock = g_io_channel_unix_get_fd(gio); - - csock = my_accept(lsock); - if (csock < 0) - return TRUE; - - ret = recv_pdu(csock); - if (ret < 0) - err("process recieved pdu"); - - close(csock); + if (usbip_host_driver_open()) { + err("please load " USBIP_CORE_MOD_NAME ".ko and " + USBIP_HOST_DRV_NAME ".ko!"); + return -1; } - return TRUE; -} - - -static void do_standalone_mode(gboolean daemonize) -{ - int ret; - int lsock[MAXSOCK]; - struct addrinfo *ai_head; - int n; - - - - ret = usbip_names_init(USBIDS_FILE); - if (ret) - err("open usb.ids"); - - ret = usbip_stub_driver_open(); - if (ret < 0) - g_error("driver open failed"); - if (daemonize) { - if (daemon(0,0) < 0) - g_error("daemonizing failed: %s", g_strerror(errno)); + if (daemon(0,0) < 0) { + err("daemonizing failed: %s", strerror(errno)); + return -1; + } usbip_use_syslog = 1; } - set_signal(); - ai_head = my_getaddrinfo(NULL, PF_UNSPEC); + ai_head = do_getaddrinfo(NULL, PF_UNSPEC); if (!ai_head) - return; + return -1; - n = listen_all_addrinfo(ai_head, lsock); - if (n <= 0) - g_error("no socket to listen to"); + info("starting " PROGNAME " (%s)", usbip_version_string); - for (int i = 0; i < n; i++) { - GIOChannel *gio; - - gio = g_io_channel_unix_new(lsock[i]); - g_io_add_watch(gio, (G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL), - process_comming_request, NULL); + nsockfd = listen_all_addrinfo(ai_head, sockfdlist); + if (nsockfd <= 0) { + err("failed to open a listening socket"); + return -1; } + for (i = 0; i < nsockfd; i++) { + GIOChannel *gio; - info("usbipd start (%s)", version); - + gio = g_io_channel_unix_new(sockfdlist[i]); + g_io_add_watch(gio, (G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL), + process_request, NULL); + } main_loop = g_main_loop_new(FALSE, FALSE); g_main_loop_run(main_loop); - info("shutdown"); + info("shutting down " PROGNAME); freeaddrinfo(ai_head); + usbip_host_driver_close(); usbip_names_free(); - usbip_stub_driver_close(); - return; + return 0; } - -static const char help_message[] = "\ -Usage: usbipd [options] \n\ - -D, --daemon \n\ - Run as a daemon process. \n\ - \n\ - -d, --debug \n\ - Print debugging information. \n\ - \n\ - -v, --version \n\ - Show version. \n\ - \n\ - -h, --help \n\ - Print this help. \n"; - -static void show_help(void) -{ - printf("%s", help_message); -} - -static const struct option longopts[] = { - {"daemon", no_argument, NULL, 'D'}, - {"debug", no_argument, NULL, 'd'}, - {"version", no_argument, NULL, 'v'}, - {"help", no_argument, NULL, 'h'}, - {NULL, 0, NULL, 0} -}; - int main(int argc, char *argv[]) { - gboolean daemonize = FALSE; + static const struct option longopts[] = { + { "daemon", no_argument, NULL, 'D' }, + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'v' }, + { NULL, 0, NULL, 0 } + }; enum { cmd_standalone_mode = 1, cmd_help, cmd_version - } cmd = cmd_standalone_mode; + } cmd; + gboolean daemonize = FALSE; + int opt, rc = -1; usbip_use_stderr = 1; usbip_use_syslog = 0; if (geteuid() != 0) - g_warning("running non-root?"); + err("not running as root?"); + cmd = cmd_standalone_mode; for (;;) { - int c; - int index = 0; + opt = getopt_long(argc, argv, "Ddhv", longopts, NULL); - c = getopt_long(argc, argv, "vhdD", longopts, &index); - - if (c == -1) + if (opt == -1) break; - switch (c) { - case 'd': - usbip_use_debug = 1; - continue; - case 'v': - cmd = cmd_version; - break; - case 'h': - cmd = cmd_help; - break; - case 'D': - daemonize = TRUE; - break; - case '?': - show_help(); - exit(EXIT_FAILURE); - default: - err("getopt"); + switch (opt) { + case 'D': + daemonize = TRUE; + break; + case 'd': + usbip_use_debug = 1; + break; + case 'h': + cmd = cmd_help; + break; + case 'v': + cmd = cmd_version; + break; + case '?': + usbipd_help(); + default: + goto err_out; } } switch (cmd) { - case cmd_standalone_mode: - do_standalone_mode(daemonize); - break; - case cmd_version: - printf("%s\n", version); - break; - case cmd_help: - show_help(); - break; - default: - info("unknown cmd"); - show_help(); + case cmd_standalone_mode: + rc = do_standalone_mode(daemonize); + break; + case cmd_version: + printf(PROGNAME " (%s)\n", usbip_version_string); + rc = 0; + break; + case cmd_help: + usbipd_help(); + rc = 0; + break; + default: + usbipd_help(); + goto err_out; } - return 0; +err_out: + return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/drivers/staging/usbip/userspace/src/utils.c b/drivers/staging/usbip/userspace/src/utils.c index 8f441089b645..2d4966e6289c 100644 --- a/drivers/staging/usbip/userspace/src/utils.c +++ b/drivers/staging/usbip/userspace/src/utils.c @@ -1,255 +1,76 @@ /* + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi * - * Copyright (C) 2005-2007 Takahiro Hirofuchi + * 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, see . */ +#include + +#include +#include +#include + +#include "usbip_common.h" #include "utils.h" -int read_integer(char *path) +int modify_match_busid(char *busid, int add) { - char buff[100]; - int fd; - int ret = 0; + char bus_type[] = "usb"; + char attr_name[] = "match_busid"; + char buff[SYSFS_BUS_ID_SIZE + 4]; + char sysfs_mntpath[SYSFS_PATH_MAX]; + char match_busid_attr_path[SYSFS_PATH_MAX]; + struct sysfs_attribute *match_busid_attr; + int rc, ret = 0; - bzero(buff, sizeof(buff)); - - fd = open(path, O_RDONLY); - if (fd < 0) - return -1; - - ret = read(fd, buff, sizeof(buff)); - if (ret < 0) { - close(fd); + if (strnlen(busid, SYSFS_BUS_ID_SIZE) > SYSFS_BUS_ID_SIZE - 1) { + dbg("busid is too long"); return -1; } - sscanf(buff, "%d", &ret); + rc = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX); + if (rc < 0) { + err("sysfs must be mounted: %s", strerror(errno)); + return -1; + } - close(fd); + snprintf(match_busid_attr_path, sizeof(match_busid_attr_path), + "%s/%s/%s/%s/%s/%s", sysfs_mntpath, SYSFS_BUS_NAME, bus_type, + SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME, attr_name); + + match_busid_attr = sysfs_open_attribute(match_busid_attr_path); + if (!match_busid_attr) { + dbg("problem getting match_busid attribute: %s", + strerror(errno)); + return -1; + } + + if (add) + snprintf(buff, SYSFS_BUS_ID_SIZE + 4, "add %s", busid); + else + snprintf(buff, SYSFS_BUS_ID_SIZE + 4, "del %s", busid); + + dbg("write \"%s\" to %s", buff, match_busid_attr->path); + + rc = sysfs_write_attribute(match_busid_attr, buff, sizeof(buff)); + if (rc < 0) { + dbg("failed to write match_busid: %s", strerror(errno)); + ret = -1; + } + + sysfs_close_attribute(match_busid_attr); return ret; } - -int read_string(char *path, char *string, size_t len) -{ - int fd; - int ret = 0; - char *p; - - bzero(string, len); - - fd = open(path, O_RDONLY); - if (fd < 0) { - string = NULL; - return -1; - } - - ret = read(fd, string, len-1); - if (ret < 0) { - string = NULL; - close(fd); - return -1; - } - - p = strchr(string, '\n'); - *p = '\0'; - - close(fd); - - return 0; -} - -int write_integer(char *path, int value) -{ - int fd; - int ret; - char buff[100]; - - snprintf(buff, sizeof(buff), "%d", value); - - fd = open(path, O_WRONLY); - if (fd < 0) - return -1; - - ret = write(fd, buff, strlen(buff)); - if (ret < 0) { - close(fd); - return -1; - } - - close(fd); - - return 0; -} - -int read_bConfigurationValue(char *busid) -{ - char path[PATH_MAX]; - - snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s/bConfigurationValue", busid); - - return read_integer(path); -} - -int write_bConfigurationValue(char *busid, int config) -{ - char path[PATH_MAX]; - - snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s/bConfigurationValue", busid); - - return write_integer(path, config); -} - -int read_bNumInterfaces(char *busid) -{ - char path[PATH_MAX]; - - snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s/bNumInterfaces", busid); - - return read_integer(path); -} - -int read_bDeviceClass(char *busid) -{ - char path[PATH_MAX]; - - snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s/bDeviceClass", busid); - - return read_integer(path); -} - -int getdriver(char *busid, int conf, int infnum, char *driver, size_t len) -{ - char path[PATH_MAX]; - char linkto[PATH_MAX]; - int ret; - - snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s:%d.%d/driver", busid, conf, infnum); - - /* readlink does not add NULL */ - bzero(linkto, sizeof(linkto)); - ret = readlink(path, linkto, sizeof(linkto)-1); - if (ret < 0) { - strncpy(driver, "none", len); - return -1; - } else { - strncpy(driver, basename(linkto), len); - return 0; - } -} - -int getdevicename(char *busid, char *name, size_t len) -{ - char path[PATH_MAX]; - char idProduct[10], idVendor[10]; - - snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s/idVendor", busid); - read_string(path, idVendor, sizeof(idVendor)); - - snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s/idProduct", busid); - read_string(path, idProduct, sizeof(idProduct)); - - if (!idVendor[0] || !idProduct[0]) - return -1; - - snprintf(name, len, "%s:%s", idVendor, idProduct); - - return 0; -} - -#define MAXLINE 100 - -/* if this cannot read a whole line, return -1 */ -int readline(int sockfd, char *buff, int bufflen) -{ - int ret; - char c; - int index = 0; - - - while (index < bufflen) { - ret = read(sockfd, &c, sizeof(c)); - if (ret < 0 && errno == EINTR) - continue; - if (ret <= 0) { - return -1; - } - - buff[index] = c; - - if ( index > 0 && buff[index-1] == '\r' && buff[index] == '\n') { - /* end of line */ - buff[index-1] = '\0'; /* get rid of delimitor */ - return index; - } else - index++; - } - - return -1; -} - -#if 0 -int writeline(int sockfd, char *str, int strlen) -{ - int ret; - int index = 0; - int len; - char buff[MAXLINE]; - - if (strlen + 3 > MAXLINE) - return -1; - - strncpy(buff, str, strlen); - buff[strlen+1] = '\r'; - buff[strlen+2] = '\n'; - buff[strlen+3] = '\0'; - - len = strlen + 3; - - while (len > 0) { - ret = write(sockfd, buff+index, len); - if (ret <= 0) { - return -1; - } - - len -= ret; - index += ret; - } - - return index; -} -#endif - -int writeline(int sockfd, char *str, int strlen) -{ - int ret; - int index = 0; - int len; - char buff[MAXLINE]; - - len = strnlen(str, strlen); - - if (strlen + 2 > MAXLINE) - return -1; - - memcpy(buff, str, strlen); - buff[strlen] = '\r'; - buff[strlen+1] = '\n'; /* strlen+1 <= MAXLINE-1 */ - - len = strlen + 2; - - while (len > 0) { - ret = write(sockfd, buff+index, len); - if (ret < 0 && errno == EINTR) - continue; - if (ret <= 0) { - return -1; - } - - len -= ret; - index += ret; - } - - return index; -} - diff --git a/drivers/staging/usbip/userspace/src/utils.h b/drivers/staging/usbip/userspace/src/utils.h index 991f662720bb..fdcb14dc0fb8 100644 --- a/drivers/staging/usbip/userspace/src/utils.h +++ b/drivers/staging/usbip/userspace/src/utils.h @@ -1,37 +1,24 @@ +/* + * Copyright (C) 2011 matt mooney + * 2005-2007 Takahiro Hirofuchi + * + * 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, see . + */ -#ifdef HAVE_CONFIG_H -#include "../config.h" -#endif +#ifndef __UTILS_H +#define __UTILS_H -#define _GNU_SOURCE -#include -#include -#include -#include +int modify_match_busid(char *busid, int add); -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -/* Be sync to kernel header */ -#define BUS_ID_SIZE 20 - -int read_string(char *path, char *, size_t len); -int read_integer(char *path); -int getdevicename(char *busid, char *name, size_t len); -int getdriver(char *busid, int conf, int infnum, char *driver, size_t len); -int read_bNumInterfaces(char *busid); -int read_bConfigurationValue(char *busid); -int write_integer(char *path, int value); -int write_bConfigurationValue(char *busid, int config); -int read_bDeviceClass(char *busid); -int readline(int sockfd, char *str, int strlen); -int writeline(int sockfd, char *buff, int bufflen); +#endif /* __UTILS_H */ diff --git a/drivers/staging/usbip/userspace/usb.ids b/drivers/staging/usbip/userspace/usb.ids deleted file mode 100644 index b1f87449bdd3..000000000000 --- a/drivers/staging/usbip/userspace/usb.ids +++ /dev/null @@ -1,13209 +0,0 @@ -# -# List of USB ID's -# -# Maintained by Stephen J. Gowdy -# If you have any new entries, send them to the maintainer. -# Send entries as patches (diff -u old new). -# The latest version can be obtained from -# http://www.linux-usb.org/usb.ids -# -# $Id: usb.ids,v 1.346 2008/04/23 13:51:46 gowdy Exp $ -# - -# Vendors, devices and interfaces. Please keep sorted. - -# Syntax: -# vendor vendor_name -# device device_name <-- single tab -# interface interface_name <-- two tabs - -0001 Fry's Electronics -0002 Ingram -0003 Club Mac -0004 Nebraska Furniture Mart -0145 Unknown - 0112 Card Reader -0204 Chipsbank Microelectronics Co., Ltd - 6025 CBM2080 Flash drive controller - 6026 CBM1180 Flash drive controller -02ad HUMAX Co., Ltd. - 138c PVR Mass Storage -0386 LTS - 0001 PSX for USB Converter -03e8 EndPoints, Inc. - 0004 SE401 WebCam - 0008 101 Ethernet [klsi] - 0015 USB ATAPI Enclosure - 2123 SiPix StyleCam Deluxe - 8004 Aox 99001 -03e9 Thesys Microelectronics -03ea Data Broadcasting Corp. -03eb Atmel Corp. - 2002 Mass Storage Device - 2015 at90usbkey sample firmware (HID keyboard) - 2018 at90usbkey sample firmware (CDC ACM) - 2019 stk525 sample firmware (microphone) - 201c at90usbkey sample firmware (HID mouse) - 201d at90usbkey sample firmware (HID generic) - 2022 at90usbkey sample firmware (composite device) - 2103 JTAG ICE mkII - 2104 AVR ISP mkII - 2107 AVR Dragon - 2ffb at90usb AVR DFU bootloader - 2ffd at89c5130/c5131 DFU bootloader - 2fff at89c5132/c51snd1c DFU bootloader - 3301 at43301 4-port Hub - 3312 4-port Hub - 5601 at76c510 Prism-II 802.11b Access Point - 5603 Cisco 7920 WiFi IP Phone - 6124 at91sam SAMBA bootloader - 7603 at76c503a D-Link DWL-120 802.11b Adapter - 7604 FastVNET - 7605 at76c503a 802.11b Adapter - 7606 at76c505 802.11b Adapter - 7611 at76c510 rfmd2948 802.11b Access Point - 7613 WL-1130 USB - 7614 AT76c505a Wireless Adapter -03ec Iwatsu America, Inc. -03ed Mitel Corp. -03ee Mitsumi - 0000 CD-R/RW Drive - 2501 eHome Infrared Receiver - 2502 eHome Infrared Receiver - 5609 Japanese Keyboard - 641f WIF-0402C Bluetooth Adapter - 6438 Bluetooth Device - 6440 WML-C52APR Bluetooth Adapter - 6901 SmartDisk FDD - 6902 Floppy Disk Drive - 7500 CD-R/RW - ffff Dongle with BlueCore in DFU mode -03f0 Hewlett-Packard - 0004 DeskJet 895c - 0011 OfficeJet G55 - 0012 DeskJet 1125C Printer Port - 0024 KU-0316 Keyboard - 0101 ScanJet 4100c - 0102 PhotoSmart S20 - 0104 DeskJet 880c/970c - 0105 ScanJet 4200c - 0107 CD-Writer Plus - 010c Multimedia Keyboard Hub - 0111 G55xi Printer/Scanner/Copier - 0117 LaserJet 3200 - 011c hn210w 802.11b Adapter - 011d Integrated Bluetooth Module - 0121 HP49g+ Calculator - 0122 HID Internet Keyboard - 0201 ScanJet 6200c - 0202 PhotoSmart S20 - 0204 DeskJet 815c - 0205 ScanJet 3300c - 0207 CD-Writer Plus 8200e - 020c Multimedia Keyboard - 0211 OfficeJet G85 - 0212 DeskJet 1220C - 0217 LaserJet 2200 - 0218 APOLLO P2500/2600 - 2624 Pole Display (HP522 2 x 20 Line Display) - 0304 DeskJet 810c/812c - 0305 ScanJet 4300c - 0307 CD-Writer+ CD-4e - 0311 OfficeJet G85xi - 0312 Color Inkjet CP1700 - 0314 designjet 30/130 series - 0317 LaserJet 1200 - 0401 ScanJet 5200c - 0404 DeskJet 830c/832c - 0405 ScanJet 3400cse - 0411 OfficeJet G95 - 0412 Printing Support - 0417 LaserJet 1200 series - 0504 DeskJet 885c - 0505 ScanJet 2100c - 0507 DVD+RW - 050c 5219 Wireless Keyboard - 0511 OfficeJet K60 - 0512 DeckJet 450 - 0517 LaserJet 1000 - 051d integrated module with Bluetooth wireless technology. - 0601 ScanJet 6300c - 0604 DeskJet 840c - 0605 ScanJet 2200c - 0611 OfficeJet K60xi - 0612 business inkjet 3000 - 0624 Bluetooth Dongle - 0701 ScanJet 5300c/5370c - 0704 DeskJet 825c - 0705 ScanJet 4400c - 0711 OfficeJet K80 - 0712 DeskJet 1180c - 0714 Printing Support - 0801 ScanJet 7400c - 0804 DeskJet 816c - 0805 HP4470C - 0811 OfficeJet K80xi - 0817 LaserJet 3300 - 0901 ScanJet 2300c - 0904 DeskJet 845c - 0912 Printing Support - 0917 LaserJet 3330 - 0924 Modular Smartcard Keyboard - 0a01 ScanJet 2400c - 0a17 color LaserJet 3700 - 0b01 Scanjet 82x0C - 0b17 Laserjet 2300d - 0c17 LaserJet 1010 - 0c24 Bluetooth Dongle - 0d12 Officejet 9100 series - 0d17 LaserJet 1012 - 0e17 LaserJet 1015 - 0f11 OfficeJet V40 - 0f12 Printing Support - 0f17 LaserJet 1150 - 1001 Photo Scanner 1000 - 1002 photosmart 140 series - 1004 DeskJet 970c/970cse - 1005 ScanJet 5400c - 1011 OfficeJet V40xi - 1016 Jornada 548 / iPAQ HW6515 Pocket PC - 1017 LaserJet 1300 - 1024 Smart Card Keyboard - 1102 photosmart 240 series - 1104 DeskJet 959c - 1105 ScanJet 5470c - 1111 officejet v60 - 1116 Jornada 568 Pocket PC - 1117 LaserJet 1300n - 1151 PSC-750xi Printer/Scanner/Copier - 1202 Photosmart 320 Series - 1204 DeskJet 930c - 1205 ScanJet 4500C/5550C - 1211 officejet v60xi - 1217 LaserJet 2300L - 1302 Photosmart 370 Series - 1305 ScanJet 4570c - 1311 OfficeJet V30 - 1312 Deskjet 460 - 1317 LaserJet 1005 - 1405 Scanjet 3670 - 1411 PSC 750 - 1424 f2105 Monitor Hub - 1502 Photosmart 420 Series - 1504 DeskJet 920c - 1511 PSC 750xi - 1512 Printing Support - 1517 color LaserJet 3500 - 1524 Smart Card Keyboard - KR - 1602 Photosmart 330 Series - 1604 DeskJet 940c - 1605 ScanJet 5530C Photosmart - 1611 psc 780 - 1617 LaserJet 3015 - 161d Wireless Rechargeable Optical Mouse (HID) - 1624 Smart Card Keyboard - JP - 1702 Photosmart 380 Series - 1704 deskjet 948C - 1705 ScanJet 5590 - 1711 psc 780xi - 1712 Printing Support - 1717 LaserJet 3020 - 171d Wireless (Bluetooth + WLAN) Interface [Integrated Module] - 1801 Inkjet P-2000U - 1802 Photosmart 470 Series - 1804 deskjet 916C - 1805 ScanJet 7650 - 1811 PSC 720 - 1817 LaserJet 3030 - 181d integrated module with Bluetooth 2.0 wireless technology. - 1902 Photosmart A430 series - 1904 DeskJet 3820 - 1911 OfficeJet V45 - 1917 LaserJet 3380 - 1a02 Photosmart A510 series - 1a11 officejet 5100 series - 1a17 color LaserJet 4650 - 1b02 Photosmart A610 series - 1b04 deskjet 3810 - 1b05 ScanJet 4850C/4890C - 1c02 Photosmart A710 series - 1c17 Color LaserJet 2550l - 1d02 Photosmart A310 series - 1d17 LaserJet 1320 - 1e02 Photosmart A320 Printer series - 1e11 PSC-950 - 1e17 LaserJet 1160 series - 1f02 Photosmart A440 Printer series - 1f11 PSC 920 - 1f12 Officejet Pro K5300 - 1f17 color LaserJet 5550 - 2001 Floppy - 2002 Hub - 2004 DeskJet 640c - 2005 ScanJet 3570c - 2012 Officejet Pro K5400 - 2102 photosmart 7345 - 2104 DeskJet 630c - 2112 Officejet Pro L7500 - 2202 photosmart 7600 series - 2205 ScanJet 3500c - 2212 Officejet Pro L7600 - 2217 color LaserJet 9500 MFP - 2302 photosmart 7600 series - 2304 DeskJet 656c - 2305 ScanJet 3970c - 2311 officejet d series - 2312 Officejet Pro L7700 - 2317 LaserJet 4350 - 2402 photosmart 7700 series - 2405 ScanJet 4070 Photosmart - 2417 LaserJet 4250 - 2424 LP1965 19" Monitor Hub - 2502 photosmart 7700 series - 2505 ScanJet 3770 - 2512 Officejet Pro L7300 - 2517 LaserJet 2410 - 2524 LP3065 30" Monitor Hub - 2602 Photosmart A520 series - 2605 ScanJet 3800c - 2611 officejet 7100 series - 2617 Color LaserJet 2820 Series - 2702 Photosmart A620 series - 2704 Deskjet 915 - 2717 Color LaserJet 2830 - 2811 PSC-2100 - 2817 Color LaserJet 2840 - 2902 Photosmart A820 series - 2911 PSC 2200 - 2917 LaserJet 2420 - 2a11 PSC 2150 series - 2a17 LaserJet 2430 - 2b11 PSC 2170 series - 2b17 LaserJet 1020 - 2c17 Printing Support - 2d11 OfficeJet 6110 - 2d17 Printing Support - 2e11 PSC 1000 - 2e17 Printing Support - 2f11 PSC 1200 - 2f17 EWS 2605dn - 3002 photosmart P1000 - 3004 deskjet 980c - 3005 ScanJet 4670v - 3011 PSC 1100 series - 3017 Printing Support - 3102 PhotoSmart P1100 Printer w/ Card Reader - 3104 DeskJet 960c - 3111 officejet 4100 series - 3117 EWS 2605dtn - 3202 photosmart 1215 - 3211 officejet 4105 series - 3217 LaserJet 3050 - 3302 photosmart 1218 - 3304 DeskJet 990c - 3317 LaserJet 3052 - 3402 photosmart 1115 - 3404 DeskJet 6122 - 3417 LaserJet 3055 - 3502 photosmart 230 - 3504 DeskJet 6127c - 3511 PSC 2300 - 3517 LaserJet 3390 - 3602 photosmart 1315 - 3611 PSC 2410 Photosmart - 3617 EWS 2605 - 3711 PSC 2500 - 3717 EWS UPD - 3802 photosmart 100 - 3817 LaserJet P2015 Series - 3902 photosmart 130 - 3a02 photosmart 7150 - 3a11 OfficeJet 5500 series - 3a17 Printing Support - 3b02 photosmart 7150~ - 3b11 PSC 1300 series - 3b17 LaserJet M1005 MFP - 3c02 PhotoSmart 7350 - 3c11 PSC 1358 - 3c17 EWS UPD - 3d02 photosmart 7350~ - 3d11 OfficeJet 4215 - 3e02 photosmart 7550 - 3f02 photosmart 7550~ - 3f11 PSC-1315/PSC-1317 - 4002 PhotoSmart 720 / PhotoSmart 935 (storage) - 4004 cp1160 - 4102 PhotoSmart 618 - 4105 ScanJet 4370 - 4111 Officejet 7200 series - 4117 Printing Support - 4202 PhotoSmart 812 - 4205 Scanjet G3010 - 4211 Officejet 7300 series - 4217 EWS CM1015 - 4302 PhotoSmart 850 (ptp) - 4311 Officejet 7400 series - 4317 Color LaserJet CM1017 - 4402 PhotoSmart 935 (ptp) - 4417 EWS UPD - 4502 PhotoSmart 945 (PTP mode) - 4505 ScanJet G4010 - 4511 Photosmart 2600 - 4517 EWS UPD - 4605 ScanJet G4050 - 4611 Photosmart 2700 - 4811 PSC 1600 - 4911 PSC 2350 - 4b11 Officejet 6200 - 4c11 PSC 1500 series - 4c17 EWS UPD - 4d11 PSC 1400 - 4d17 EWS UPD - 4e11 Photosmart 2570 series - 4f11 Officejet 5600 (USBHUB) - 5004 DeskJet 995c - 5011 Photosmart 3100 Series - 5017 EWS UPD - 5111 Photosmart 3200 Series - 5211 Photosmart 3300 Series - 5311 Officejet 6300 - 5411 Officejet 4300 - 5511 Deskjet F300 series - 5611 PhotoSmart C3180 - 5617 LaserJet M1120 MFP - 5711 Photosmart C4100 series - 5717 LaserJet M1120n MFP - 5811 Photosmart C5100 series - 5817 LaserJet M1319f MFP - 5911 PhotoSmart C6180 - 5a11 Photosmart C7100 series - 5b11 Officejet J2100 Series - 5c11 Photosmart C4200 Printer series - 5d11 Photosmart C5200 series - 5e11 Photosmart D7400 series - 6004 DeskJet 5550 - 6102 Hewlett Packard Digital Camera - 6104 DeskJet 5650c - 6117 color LaserJet 3550 - 6202 PhotoSmart 215 - 6204 DeskJet 5150c - 6217 Color LaserJet 4700 - 6302 PhotoSmart 318/612 - 6317 Color LaserJet 4730mfp - 6402 PhotoSmart 715 (ptp) - 6411 Photosmart C8100 series - 6417 LaserJet 5200 - 6502 PhotoSmart 120 (ptp) - 6511 Photosmart C7200 series - 6602 PhotoSmart 320 - 6611 Photosmart C4380 series - 6617 LaserJet 5200L - 6702 PhotoSmart 720 (ptp) - 6717 Color LaserJet 3000 - 6802 PhotoSmart 620 (ptp) - 6811 Photosmart D5300 series - 6817 Color LaserJet 3800 - 6911 Photosmart D7200 series - 6917 Color LaserJet 3600 - 6a02 PhotoSmart 735 (ptp) - 6a11 Photosmart C6200 series - 6a17 LaserJet 4240 - 6b02 PhotoSmart R707 (PTP mode) - 6c17 Color LaserJet 4610 - 6f17 Color LaserJet CP6015 series - 7004 DeskJet 3320c - 7102 PhotoSmart 635 (PTP mode) - 7104 DeskJet 3420c - 7117 CM8060 Color MFP with Edgeline Technology - 7202 PhotoSmart 43x (ptp) - 7204 DeskJet 36xx - 7217 LaserJet M5035 MFP - 7302 PhotoSmart M307 (PTP mode) - 7304 DeskJet 35xx - 7317 LaserJet P3005 - 7404 Printing Support - 7417 LaserJet M4345 MFP - 7504 Printing Support - 7517 LaserJet M3035 MFP - 7604 Deskjet 3940 - 7617 LaserJet P3004 - 7702 PhotoSmart R817 (PTP mode) - 7704 Deskjet D4100 - 7717 CM8050 Color MFP with Edgeline Technology - 7804 Deskjet D1360 - 7817 Color LaserJet CP3505 - 7917 LaserJet M5025 MFP - 7a02 PhotoSmart M415 (PTP mode) - 7a17 LaserJet M3027 MFP - 7b02 PhotoSmart M23 (PTP mode) - 7b17 Color LaserJet CP4005 - 7c17 Color LaserJet CM6040 Series - 7d04 Deskjet F2100 Printer series - 7d17 Color LaserJet CM4730 MFP - 7e04 Deskjet F4100 Printer series - 8017 LaserJet P4515 - 8104 Printing Support - 8117 LaserJet P4015 - 811c Ethernet HN210E - 8204 Printing Support - 8217 LaserJet P4014 - 8317 LaserJet M9050 MFP - 8404 Deskjet 6800 Series - 8417 LaserJet M9040 MFP - 8504 Deskjet 6600 Series - 8604 Deskjet 5440 - 8704 deskjet 5900 series - 8804 Deskjet 6980 Series - 8904 Deskjet 6940 Series - 9002 Photosmart M437 - 9102 Photosmart M537 - 9302 Photosmart R930 series - 9402 Photosmart R837 - 9502 Photosmart R840 series - 9602 Photosmart M730 series - 9702 Photosmart R740 series - 9802 Photosmart Mz60 series - 9902 Photosmart M630 series - 9a02 Photosmart E330 series - 9b02 Photosmart M540 series - 9c02 Photosmart M440 series - a004 DeskJet 5850c - b002 photosmart 7200 series - b102 photosmart 7200 series - b202 photosmart 7600 series - b302 photosmart 7600 series - b402 photosmart 7700 series - b502 photosmart 7700 series - b602 photosmart 7900 series - b702 photosmart 7900 series - b802 Photosmart 7400 Series - b902 Photosmart 7800 Series - ba02 Photosmart 8100 Series - bb02 Photosmart 8400 Series - bc02 Photosmart 8700 Series - bd02 Photosmart Pro B9100 series - bef4 NEC Picty760 - c002 Photosmart 7800 Series - c102 Photosmart 8000 Series - c202 Photosmart 8200 Series - c302 Deskjet D2300 - c402 Photosmart D5100 series - c502 Photosmart D6100 series - c602 Photosmart D7100 series - c702 Photosmart D7300 series - c802 Photosmart D5060 Printer - d104 Bluetooth Dongle - efbe NEC Picty900 - f0be NEC Picty920 - f1be NEC Picty800 -03f1 Genoa Technology -03f2 Oak Technology, Inc. -03f3 Adaptec, Inc. - 0020 AWN-8020 WLAN - 0080 AVC-1100 Audio Capture - 0083 AVC-2200 Device - 0087 AVC-2210 Loader - 0088 AVC-2210 Device - 008b AVC-2310 Loader - 008c AVC-2310 Device - 0094 eHome Infrared Receiver - 009b AVC-1410 GameBridge TV NTSC - 2000 USBXchange - 2001 USBXchange Adapter - 2002 USB2-Xchange - 2003 USB2-Xchange Adapter - adcc Composite Device Support -03f4 Diebold, Inc. -03f5 Siemens Electromechanical -03f8 Epson Imaging Technology Center -03f9 KeyTronic Corp. - 0100 Keyboard - 0101 Keyboard - 0102 Keyboard Mouse -03fb OPTi, Inc. -03fc Elitegroup Computer Systems -03fd Xilinx, Inc. -03fe Farallon Comunications -0400 National Semiconductor Corp. - 0807 Bluetooth Dongle - 080a Bluetooth Device - 1000 Mustek BearPaw 1200 Scanner - 1001 Mustek BearPaw 2400 Scanner - 1237 Hub - a000 Smart Display Reference Device - c35b Printing Support -0401 National Registry, Inc. -0402 ALi Corp. - 5462 M5462 IDE Controller - 5602 Video Camera Controller - 5603 USB 2.0 Q-tec Webcam 300 - 5621 USB 2.0 Storage Device - 5623 VistaScan Astra 3600 - 5627 Welland ME-740PS USB2 3.5" Power Saving Enclosure - 5632 USB 2.0 Host-to-Host Link - 5635 USB 2.0 Flash Card Reader - 5636 USB 2.0 Storage Device - 5637 M5637 IDE Controller -0403 Future Technology Devices International, Ltd - 0000 H4SMK 7 Port Hub - 0232 Serial Converter - 6001 FT232 USB-Serial (UART) IC - 6007 Serial Converter - 6008 Serial Converter - 6009 Serial Converter - 6010 FT2232C Dual USB-UART/FIFO IC - 8040 4 Port Hub - 8070 7 Port Hub - 8370 7 Port Hub - 8371 PS/2 Keyboard And Mouse - 8372 FT8U100AX Serial Port - c630 lcd2usb interface - c7d0 RR-CirKits LocoBuffer-USB - cc48 product FTDI TACTRIX_OPENPORT_13M 0xcc48 OpenPort 1.3 Mitsubishi - cc49 product FTDI TACTRIX_OPENPORT_13S 0xcc49 OpenPort 1.3 Subaru - cc4a product FTDI TACTRIX_OPENPORT_13U 0xcc4a OpenPort 1.3 Universal - d010 SCS PTC-IIusb - d011 SCS Position-Tracker/TNC - d012 SCS DRAGON 1 - d013 SCS DRAGON 1 - d6f8 UNI Black BOX - e700 Elster Unicom III Optical Probe - e888 Expert ISDN Control USB - e889 USB-RS232 OptoBridge - e88a Expert mouseCLOCK USB II - e88b Precision Clock MSF USB - e88c Expert mouseCLOCK USB II HBG - ea90 Eclo 1-Wire Adapter - f208 Papenmeier Braille-Display - f680 Suunto Sports Instrument - f918 Ant8 Logic Probe - fa00 Matrix Orbital USB Serial - fa01 Matrix Orbital MX2 or MX3 - fa02 Matrix Orbital MX4 or MX5 - fa03 Matrix Orbital VK/LK202 Family - fa04 Matrix Orbital VK/LK204 Family - fc08 Crystalfontz CFA-632 USB LCD - fc09 Crystalfontz CFA-634 USB LCD - fc0b Crystalfontz CFA-633 USB LCD - fc0c Crystalfontz CFA-631 USB LCD - fc0d Crystalfontz CFA-635 USB LCD - fc82 SEMC DSS-20 SyncStation - fd48 ShipModul MiniPlex-4xUSB NMEA Multiplexer - ff08 ToolHouse LoopBack Adapter - ff18 Logbook Bus - ff19 Logbook Bus - ff1a Logbook Bus - ff1b Logbook Bus - ff1c Logbook Bus - ff1d Logbook Bus - ff1e Logbook Bus - ff1f Logbook Bus -0404 NCR Corp. - 0202 78XX Scanner - 0203 78XX Scanner - Embedded System - 0310 K590 Printer, Self-Service - 0311 7167 Printer, Receipt/Slip - 0312 7197 Printer Receipt - 0320 5932-USB Keyboard - 0321 5953-USB Dynakey - 0322 5932-USB Enhanced Keyboard - 0323 5932-USB Enhanced Keyboard, Flash-Recovery/Download - 0324 5953-USB Enhanced Dynakey - 0325 5953-USB Enhanced Dynakey Flash-Recovery/Download - 0328 K016: USB-MSR ISO 3-track MSR: POS Standard (See HID pages) - 0329 K018: USB-MSR JIS 2-Track MSR: POS Standard - 032a K016: USB-MSR ISO 3-Track MSR: HID Keyboard Mode - 032b K016/K018: USB-MSR Flash-Recovery/Download -0405 Synopsys, Inc. -0406 Fujitsu-ICL Computers -0407 Fujitsu Personal Systems, Inc. -0408 Quanta Computer, Inc. -0409 NEC Corp. - 0011 PC98 Series Layout Keyboard Mouse - 0012 ATerm IT75DSU ISDN TA - 0014 Japanese Keyboard - 0019 109 Japanese Keyboard with Bus-Powered Hub - 001a PC98 Series Layout Keyboard with Bus-Powered Hub - 0025 Mini Keyboard with Bus-Powered Hub - 0027 MultiSync Monitor - 002c Clik!-USB Drive - 0034 109 Japanese Keyboard with One-touch start buttons - 003f Wireless Keyboard with One-touch start buttons - 0040 Floppy - 004e SuperScript 1400 Series - 004f Wireless Keyboard with One-touch start buttons - 0058 HighSpeed Hub - 0059 HighSpeed Hub - 005a HighSpeed Hub - 006a Conceptronic USB Harddisk Box - 0081 SuperScript 1400 Series - 0082 SuperScript 1400 Series - 0094 Japanese Keyboard with One-touch start buttons - 0095 Japanese Keyboard - 00a9 AtermIT21L 128K Support Standard - 00aa AtermITX72 128K Support Standard - 00ab AtermITX62 128K Support Standard - 00ac AtermIT42 128K Support Standard - 00ae INSMATEV70G-MAX Standard - 00af AtermITX70 128K Support Standard - 00b0 AtermITX80 128K Support Standard - 00b2 AtermITX80D 128K Support Standard - 00c0 Wireless Remocon - 00f7 Smart Display PK-SD10 - 011d e228 Mobile Phone - 0203 HID Audio Controls - 55aa Hub - 55ab Hub [iMac/iTouch kbd] - 8010 Intellibase Hub - 8011 Intellibase Hub - efbe P!cty 900 [HP DJ] - f0be P!cty 920 [HP DJ 812c] -040a Kodak Co. - 0001 DVC-323 - 0002 DVC-325 - 0100 DC-220 - 0110 DC-260 - 0111 DC-265 - 0112 DC-290 - 0120 DC-240 - 0121 DC-240 (PTP firmware) - 0130 DC-280 - 0131 DC-5000 - 0132 DC-3400 - 0140 DC-4800 - 0160 DC4800 - 0170 DX3900 - 0200 Digital Camera - 0300 EZ-200 - 0400 MC3 - 0402 Digital Camera - 0403 Z7590 - 0500 DX3500 - 0510 DX3600 - 0525 DX3215 - 0530 DX3700 - 0535 EasyShare CX4230 Camera - 0540 LS420 - 0550 DX4900 - 0555 DX4330 - 0560 CX4200 - 0565 CX4210 - 0566 CX4300 - 0567 LS753 - 0568 LS443 - 0569 LS663 - 0570 DX6340 - 0571 CX6330 - 0572 DX6440 - 0573 CX6230 - 0574 CX6200 - 0575 DX6490 - 0576 DX4530 - 0577 DX7630 - 0578 CX7300/CX7310 - 0579 CX7220 - 057a CX7330 - 057b CX7430 - 057c CX7530 - 057d DX7440 - 057e C300 - 057f DX7590 - 0580 Z730 - 0581 Digital Camera - 0582 Digital Camera - 0583 Digital Camera - 0584 CX6445 - 0585 Digital Camera - 0586 CX7525 - 0587 Digital Camera - 0588 Digital Camera - 0589 EasyShare C360 - 058a C310 - 058b Digital Camera - 058c C330 - 058d C340 - 058e V530 - 058f V550 - 0590 Digital Camera - 0591 Digital Camera - 0592 Digital Camera - 0593 Digital Camera - 0594 Digital Camera - 0595 Digital Camera - 0596 Digital Camera - 0597 Digital Camera - 0598 Digital Camera - 0599 Digital Camera - 059a Digital Camera - 059b Digital Camera - 059c Digital Camera - 059d Digital Camera - 059e Digital Camera - 059f Digital Camera - 05a0 Digital Camera - 05a1 Digital Camera - 05a2 Digital Camera - 05a3 Digital Camera - 05a4 Digital Camera - 05a5 Digital Camera - 05a6 Digital Camera - 05a7 Digital Camera - 05a8 Digital Camera - 05a9 Digital Camera - 05aa Digital Camera - 05ab Digital Camera - 05ac Digital Camera - 05ad Digital Camera - 05ae Digital Camera - 05af Digital Camera - 05b0 Digital Camera - 05b1 Digital Camera - 05b2 Digital Camera - 05b3 EasyShare Z710 Camera - 05b4 Digital Camera - 05b5 Digital Camera - 05b6 Digital Camera - 05b7 Digital Camera - 05b8 Digital Camera - 05b9 Digital Camera - 05ba Digital Camera - 05bb Digital Camera - 05bc Digital Camera - 05bd Digital Camera - 05be Digital Camera - 05bf Digital Camera - 05c0 Digital Camera - 05c1 Digital Camera - 05c2 Digital Camera - 05c3 Digital Camera - 05c4 Digital Camera - 05c5 Digital Camera - 4000 InkJet Color Printer - 410d EasyShare G600 Printer Dock - 5010 Wireless Adapter - 5012 DBT-220 Bluetooth Adapter - 6001 i30 - 6002 i40 - 6003 i50 - 6004 i60 - 6005 i80 -040b Weltrend Semiconductor - 6510 Weltrend Bar Code Reader - 6520 XBOX Xploder -040c VTech Computers, Ltd -040d VIA Technologies, Inc. - 3184 VNT VT6656 USB-802.11 Wireless LAN Adapter - 6205 USB 2.0 Card Reader -040e MCCI -040f Echo Speech Corp. -0411 MelCo., Inc. - 0001 LUA-TX Ethernet [pegasus] - 0005 LUA-TX Ethernet - 0006 WLI-USB-L11 Wireless LAN Adapter - 0009 LUA2-TX Ethernet - 000b WLI-USB-L11G-WR Wireless LAN Adapter - 000d WLI-USB-L11G Wireless LAN Adapter - 0012 LUA-KTX Ethernet - 0013 USB2-IDE Adapter - 0016 WLI-USB-S11 802.11b Adapter - 0018 USB2-IDE Adapter - 001c USB-IDE Bridge: DUB-PxxG - 0027 WLI-USB-KS11G 802.11b Adapter - 003d LUA-U2-KTX Ethernet - 0044 WLI-USB-KB11 Wireless LAN Adapter - 004d WLI-USB-B11 Wireless LAN Adapter - 0050 WLI2-USB2-G54 Wireless LAN Adapter - 005e WLI-U2-KG54-YB WLAN - 0065 Python2 WDM Encoder - 0066 WLI-U2-KG54 WLAN - 0067 WLI-U2-KG54-AI WLAN - 008b Nintendo Wi-Fi - 0091 WLI-U2-KAMG54 Wireless LAN Adapter - 0092 WLI-U2-KAMG54 Bootloader - 0097 WLI-U2-KG54-BB - 00a9 WLI-U2-AMG54HP Wireless LAN Adapter - 00aa WLI-U2-AMG54HP Bootloader - 00b3 PC-OP-RS1 RemoteStation - 00ca 802.11n Network Adapter - 00cb WLI-U2-G300N 802.11n Adapter - 00d8 WLI-U2-SG54HP - 00d9 WLI-U2-G54HP - 00da WLI-U2-KG54L -0412 Award Software International -0413 Leadtek Research, Inc. - 1310 WinFast TV - NTSC + FM - 1311 WinFast TV - NTSC + MTS + FM - 1312 WinFast TV - PAL BG + FM - 1313 WinFast TV - PAL BG+TXT + FM - 1314 WinFast TV Audio - PHP PAL I - 1315 WinFast TV Audio - PHP PAL I+TXT - 1316 WinFast TV Audio - PHP PAL DK - 1317 WinFast TV Audio - PHP PAL DK+TXT - 1318 WinFast TV - PAL I/DK + FM - 1319 WinFast TV - PAL N + FM - 131a WinFast TV Audio - PHP SECAM LL - 131b WinFast TV Audio - PHP SECAM LL+TXT - 131c WinFast TV Audio - PHP SECAM DK - 131d WinFast TV - SECAM DK + TXT + FM - 131e WinFast TV - NTSC Japan + FM - 1320 WinFast TV - NTSC - 1321 WinFast TV - NTSC + MTS - 1322 WinFast TV - PAL BG - 1323 WinFast TV - PAL BG+TXT - 1324 WinFast TV Audio - PHP PAL I - 1325 WinFast TV Audio - PHP PAL I+TXT - 1326 WinFast TV Audio - PHP PAL DK - 1327 WinFast TV Audio - PHP PAL DK+TXT - 1328 WinFast TV - PAL I/DK - 1329 WinFast TV - PAL N - 132a WinFast TV Audio - PHP SECAM LL - 132b WinFast TV Audio - PHP SECAM LL+TXT - 132c WinFast TV Audio - PHP SECAM DK - 132d WinFast TV - SECAM DK + TXT - 132e WinFast TV - NTSC Japan - 6023 EMP Audio Device - 6024 WinFast PalmTop/Novo TV Video - 6025 WinFast DTV Dongle (cold state) - 6026 WinFast DTV Dongle (warm state) - 6125 WinFast DTV Dongle - 6126 WinFast DTV Dongle BDA Driver - 6f00 WinFast DTV Dongle (STK7700P based) -0414 Giga-Byte Technology Co., Ltd -0416 Winbond Electronics Corp. - 0035 W89C35 802.11bg WLAN Adapter - 0101 Hub - 0961 AVL Flash Card Reader - 3810 Smart Card Controller - 3811 Generic Controller - Single interface - 3812 Smart Card Controller_2Interface - 3813 Panel Display - 5518 4-Port Hub - 551a PC Sync Keypad - 551b PC Async Keypad - 551c Sync Tenkey - 551d Async Tenkey - 551e Keyboard - 551f Keyboard w/ Sys and Media - 5521 Keyboard - 6481 16-bit Scanner - 7721 Memory Stick Reader/Writer - 7722 Memory Stick Reader/Writer - 7723 SD Card Reader -0417 Symbios Logic -0418 AST Research -0419 Samsung Info. Systems America, Inc. - 0001 IrDA Remote Controller - 3001 Xerox P1202 Laser Printer - 3003 Olivetti PG L12L - 3201 Docuprint P8ex - 3404 SCX-5x12 Series - 3406 MFP 830 Series - 3407 ML-912 - 3601 InkJet Color Printer - 3602 InkJet Color Printer - 4602 Remote NDIS Network Device - 8001 Hub - 8002 SyncMaster 757DFX HID Device -041a Phoenix Technologies, Ltd -041b d'TV -041d S3, Inc. -041e Creative Technology, Ltd - 1002 Nomad II - 1003 Blaster GamePad Cobra - 1050 GamePad Cobra - 3000 SoundBlaster Extigy - 3002 SB External Composite Device - 3010 SoundBlaster MP3+ - 3014 SB External Composite Device - 3015 Sound Blaster Digital Music LX - 3020 SoundBlaster Audigy 2 NX - 3030 SB External Composite Device - 3040 SoundBlaster Live! 24-bit External SB0490 - 3060 Sound Blaster Audigy 2 ZS External - 3061 SoundBlaster Audigy 2 ZS Video Editor - 3090 Sound Blaster Digital Music SX - 3f02 E-Mu 0202 - 3f04 E-Mu 0404 - 4003 VideoBlaster WebCam Go Plus [W9967CF] - 4004 Nomad II MG - 4005 WebCam Blaster Go ES - 4007 Go Mini - 400a PC-Cam 300 - 400b PC-Cam 600 - 400c WebCam 5 [pwc] - 400d WebCam PD1001 - 400f PC-CAM 550 (Composite) - 4011 WebCam PRO eX - 4012 PC-CAM350 - 4013 PC-Cam 750 - 4015 CardCam Value - 4016 CardCam - 4017 WebCam Mobile - 4018 WebCam Vista - 4019 Audio Device - 401c WebCam NX [PD1110] - 401d WebCam NX Ultra - 401e WebCam NX Pro - 401f Webcam Notebook - 4020 WebCam NX - 4021 WebCam NX Ultra - 4022 WebCam NX Pro - 4028 Vista Plus cam [VF0090] - 402f DC-CAM 3000Z - 4034 WebCam Instant - 4035 WebCam Instant - 4036 Webcam Live!/Live! Pro - 4037 WebCam Live! - 4038 ORITE CCD Webcam(PC370R) - 4039 WebCam Live! Effects - 403a WebCam NX Pro 2 - 403c WebCam Live! Ultra - 403d WebCam Notebook Ultra - 403e WebCam Vista Plus - 4041 WebCam Live! Motion - 4045 Live! Cam Voice - 4049 Live! Cam Voice - 4051 Live! Cam Notebook Pro - 4052 Live! Cam Vista IM - 4053 Live! Cam Video IM - 4054 Live! Cam Video IM - 4055 Live! Cam Video IM Pro - 4056 Live! Cam Video IM Pro - 4057 Live! Cam Optia - 4058 Live! Cam Optia AF - 4068 WebCam Live! Notebook - 4100 Nomad Jukebox 2 - 4101 Nomad Jukebox 3 - 4102 NOMAD MuVo^2 - 4106 Nomad MuVo - 4107 NOMAD MuVo - 4108 Nomad Jukebox Zen - 4109 Nomad Jukebox Zen NX - 410b Nomad Jukebox Zen USB 2.0 - 410c Nomad MuVo NX - 410f NOMAD MuVo^2 (Flash) - 4110 Nomad Jukebox Zen Xtra - 4111 Dell Digital Jukebox - 4116 MuVo^2 - 4117 Nomad MuVo TX - 411b Zen Touch - 411c Nomad MuVo USB 2.0 - 411d Zen - 411e Zen Micro - 4123 Zen Portable Media Center - 4124 MuVo^2 FM (uHDD) - 4126 Dell DJ (2nd gen) - 4127 Dell DJ - 4128 NOMAD Jukebox Zen Xtra (mtp) - 412b MuVo N200 with FM radio - 4130 Zen Micro (mtp) - 4131 Zen Touch (mtp) - 4133 Mass Storage Device - 4134 Zen Neeon - 4136 Zen Sleek - 4137 Zen Sleek (mtp) - 4139 Zen Nano Plus - 413c Zen MicroPhoto - 4151 Zen Vision:M (mtp) - 4155 Zen Stone plus - 500f Broadband Blaster 8012U-V - 5015 TECOM Bluetooth Device - ffff WebCam Live! Ultra -041f LCS Telegraphics -0420 Chips and Technologies - 1307 Celly SIM Card Reader -0421 Nokia Mobile Phones - 0018 6288 GSM Smartphone - 0019 6288 GSM Smartphone (imaging mode) - 001a 6288 GSM Smartphone (file transfer mode) - 0024 5610 XpressMusic (Storage mode) - 0025 5610 XpressMusic (PC-Suite mode) - 0028 5610 XpressMusic (Imaging mode) - 0096 N810 Internet Tablet - 0103 ADL Flashing Engine AVALON Parent - 0104 ADL Re-Flashing Engine Parent - 0105 E-61 (Firmware update mode) - 0106 ROM Parent - 0400 7600 Phone Parent - 0401 6650 GSM Phone - 0402 6255 Phone Parent - 0404 5510 - 0405 9500 GSM Communicator - 0407 Music Player HDR-1(tm) - 040b N-Gage GSM Phone - 040d 6620 Phone Parent - 040e 6651 Phone Parent - 040f 6230 GSM Phone - 0410 6630 Imaging Smartphone - 0411 7610 Phone Parent - 0413 6260 Phone Parent - 0414 7370 - 0415 9300 GSM Smartphone - 0416 6170 Phone Parent - 0417 7270 Phone Parent - 0418 E-70 (PC-Suite mode) - 0419 E-60 (PC-Suite mode) - 041a 9500 GSM Communicator (RNDIS) - 041b 9300 GSM Smartphone (RNDIS) - 041c 7710 Phone Parent - 041d 6670 Phone Parent - 041e 6680 - 041f 6235 Phone Parent - 0421 3230 Phone Parent - 0422 6681 Phone Parent - 0423 6682 Phone Parent - 0428 6230i Modem - 0429 6230i MultiMedia Card - 0431 770 Internet Tablet - 0432 N90 Phone Parent - 0435 E-70 (IP Passthrough/RNDIS mode) - 0436 E-60 (IP Passthrough/RNDIS mode) - 0437 6265 Phone Parent - 043a N70 USB Phone Parent - 043b 3155 Phone Parent - 043c 6155 Phone Parent - 043d 6270 Phone Parent - 0443 N70 Phone Parent - 044c NM850iG Phone Parent - 044d E-61 (PC Suite mode) - 044e E-61 (Data Exchange mode) - 044f E-61 (IP Passthrough/RNDIS mode) - 0453 9300 Phone Parent - 0456 6111 Phone Parent - 045a 6280 Phone Parent - 045d 6282 Phone Parent - 046e 6110 Navigator - 0485 MTP Device - 04c3 N800 Internet Tablet - 04ce E90 Communicator (PC-Suite mode) - 04cf E90 Communicator (Storage mode) - 04f9 6300 (PC-Suite mode) - 0600 Digital Pen SU-1B - 0800 Connectivity Cable DKU-5 - 0801 Data Cable DKU-6 - 0802 CA-42 Phone Parent -0422 ADI Systems, Inc. -0423 Computer Access Technology Corp. - 000a NetMate Ethernet - 000c NetMate2 Ethernet - 000d USB Chief Analyzer - 0100 Generic Universal Protocol Analyzer - 0101 UPA USBTracer - 0200 Generic 10K Universal Protocol Analyzer - 020a PETracer ML - 0300 Generic Universal Protocol Analyzer - 0301 2500H Tracer Trainer - 030a PETracer x1 - 1237 Andromeda Hub -0424 Standard Microsystems Corp. - 0001 Integrated Hub - 0acd Sitecom Internal Multi Memory reader/writer MD-005 - 0fdc Floppy - 10cd Sitecom Internal Multi Memory reader/writer MD-005 - 2020 USB Hub - 20cd Sitecom Internal Multi Memory reader/writer MD-005 - 20fc 6-in-1 Card Reader - 2228 9-in-2 Card Reader - 223a 8-in-1 Card Reader - 2503 USB 2.0 Hub - 2504 USB 2.0 Hub - 2524 USB MultiSwitch Hub -0425 Motorola Semiconductors HK, Ltd - 0101 G-Tech Wireless Mouse & Keyboard -0426 Integrated Device Technology, Inc. - 0426 WDM Driver -0427 Motorola Electronics Taiwan, Ltd -0428 Advanced Gravis Computer Tech, Ltd - 4001 GamePad Pro -0429 Cirrus Logic -042a Ericsson Austrian, AG -042b Intel Corp. - 9316 8x931Hx Customer Hub -042c Innovative Semiconductors, Inc. -042d Micronics -042e Acer, Inc. - 0380 MP3 Player -042f Molex, Inc. -0430 Sun Microsystems, Inc. - 0002 109 Keyboard - 0005 Type 6 Keyboard - 000a 109 Japanese Keyboard - 000b 109 Japanese Keyboard - 0082 109 Japanese Keyboard - 0083 109 Japanese Keyboard - 0100 3-button Mouse - 36ba Bus Powered Hub -0431 Itac Systems, Inc. - 0100 Mouse-Trak 3-button Track Ball -0432 Unisys Corp. -0433 Alps Electric, Inc. - 1101 IBM Game Controller - abab Keyboard -0434 Samsung Info. Systems America, Inc. -0435 Hyundai Electronics America -0436 Taugagreining HF - 0005 CameraMate (DPCM_USB) -0437 Framatome Connectors USA -0438 Advanced Micro Devices, Inc. -0439 Voice Technologies Group -043d Lexmark International, Inc. - 0001 Laser Printer - 0002 Optra E310 Printer - 0003 Laser Printer - 0004 Laser Printer - 0005 Laser Printer - 0006 Laser Printer - 0007 Laser Printer - 0008 Inkjet Color Printer - 0009 Optra S2450 Printer - 000a Laser Printer - 000b Inkjet Color Printer - 000c Optra E312 Printer - 000d Laser Printer - 000e Laser Printer - 000f Laser Printer - 0010 Laser Printer - 0011 Laser Printer - 0012 Inkjet Color Printer - 0013 Inkjet Color Printer - 0014 InkJet Color Printer - 0015 InkJet Color Printer - 0016 Z12 Color Jetprinter - 0017 Z32 printer - 0018 Z52 Printer - 0019 Forms Printer - 001a Z65 Printer - 001b InkJet Photo Printer - 001c Kodak Personal Picture Maker 200 Printer - 001d InkJet Color Printer - 001e InkJet Photo Printer - 001f Kodak Personal Picture Maker 200 Card Reader - 0020 Z51 Printer - 0021 Z33 Printer - 0022 InkJet Color Printer - 0023 Laser Printer - 0024 Laser Printer - 0025 InkJet Color Printer - 0026 InkJet Color Printer - 0027 InkJet Color Printer - 0028 InkJet Color Printer - 0029 Scan Print Copy - 002a Scan Print Copy - 002b Scan Print Copy - 002c Scan Print Copy - 002d X70/X73 Scan/Print/Copy - 002e Scan Print Copy - 002f Scan Print Copy - 0030 Scan Print Copy - 0031 Scan Print Copy - 0032 Scan Print Copy - 0033 Scan Print Copy - 0034 Scan Print Copy - 0035 Scan Print Copy - 0036 Scan Print Copy - 0037 Scan Print Copy - 0038 Scan Print Copy - 0039 Scan Print Copy - 003a Scan Print Copy - 003b Scan Print Copy - 003c Scan Print Copy - 003d X83 Scan/Print/Copy - 003e Scan Print Copy - 003f Scan Print Copy - 0040 Scan Print Copy - 0041 Scan Print Copy - 0042 Scan Print Copy - 0043 Scan Print Copy - 0044 Scan Print Copy - 0045 Scan Print Copy - 0046 Scan Print Copy - 0047 Scan Print Copy - 0048 Scan Print Copy - 0049 Scan Print Copy - 004a Scan Print Copy - 004b Scan Print Copy - 004c Scan Print Copy - 004d Laser Printer - 004e Laser Printer - 004f InkJet Color Printer - 0050 InkJet Color Printer - 0051 Laser Printer - 0052 Laser Printer - 0053 InkJet Color Printer - 0054 InkJet Color Printer - 0057 Z35 Printer - 0058 Laser Printer - 005a X63 - 005c InkJet Color Printer - 0060 X74/X75 Scanner - 0061 X74 Hub - 0065 X5130 - 0069 X74/X75 Printer - 006d X125 - 0072 X6170 Printer - 0073 InkJet Color Printer - 0078 InkJet Color Printer - 0079 InkJet Color Printer - 007a Generic Hub - 007b InkJet Color Printer - 007c Lexmark X1110/X1130/X1140/X1150/X1170/X1180/X1185 - 007d Photo 3150 - 008a 4200 Series - 008b InkJet Color Printer - 008c to CF/SM/SD/MS Card Reader - 008e InkJet Color Printer - 008f X422 - 0093 X5250 - 0095 E220 Printer - 0096 2200 Series - 0097 P6250 - 0098 7100 Series - 009e P910 Series Human Interface Device - 009f InkJet Color Printer - 00a9 IBM Infoprint 1410 MFP - 00ab InkJet Color Printer - 00b2 3300 Series - 00b8 7300 Series - 00b9 8300 Series - 00ba InkJet Color Printer - 00bb 2300 Series - 00bd Printing Support - 00be Printing Support - 00bf Printing Support - 00c0 6300 Series - 00c1 4300 Series - 00c7 Printing Support - 00c8 Printing Support - 00c9 Printing Support - 00cb Printing Support - 00d0 9300 Series - 00d3 X340 Scanner - 00d4 X342n Scanner - 00d5 Printing Support - 00d6 X340 Scanner - 00e8 X642e - 00e9 2400 Series - 00f6 3400 Series - 00f7 InkJet Color Printer - 00ff InkJet Color Printer - 010b 2500 Series - 010d 3500-4500 Series - 010f 6500 Series - 4303 Xerox WorkCentre Pro 412 -043e LG Electronics USA, Inc. - 42bd Flatron 795FT Plus Monitor - 4a4d Flatron 915FT Plus Monitor - 7001 MF-PD100 Soul Digital MP3 Player - 7013 MP3 Player - 8484 LPC-U30 Webcam II - 8585 LPC-UC35 Webcam - 8888 Electronics VCS Camera II(LPC-U20) - 9800 Remote Control Receiver_iMON - 9803 eHome Infrared Receiver - 9804 DMB Receiver Control - 9c01 LGE Sync -043f RadiSys Corp. -0440 Eizo Nanao Corp. -0441 Winbond Systems Lab. - 1456 Hub -0442 Ericsson, Inc. - abba Bluetooth Device -0443 Gateway, Inc. - 000e Multimedia Keyboard - 002e Millennium Keyboard -0445 Lucent Technologies, Inc. -0446 NMB Technologies Corp. - 6781 Keyboard with PS/2 Mouse Port - 6782 Keyboard -0447 Momentum Microsystems -044a Shamrock Tech. Co., Ltd -044b WSI -044c CCL/ITRI -044d Siemens Nixdorf AG -044e Alps Electric Co., Ltd - 1104 Japanese Keyboard - 2002 MD-5500 Printer - 2014 Bluetooth Device - 3001 UGTZ4 Bluetooth - 3002 Bluetooth Device - 3003 Bluetooth Device - 3004 Bluetooth Adapter - 3005 Integrated Bluetooth Device - 3006 Bluetooth Adapter - 3007 GlidePoint PS/2 TouchPad - 300c Bluetooth Controller (ALPS/UGPZ6) - 300d Bluetooth Controller (ALPS/UGPZ6) - ffff Compaq Bluetooth Multiport Module -044f ThrustMaster, Inc. - 0400 HOTAS Cougar - a003 Rage 3D Game Pad - a01b PK-GP301 Driving Wheel - a0a0 Top Gun Joystick - a0a1 Top Gun Joystick (rev2) - a0a3 Fusion Digital GamePad - a201 PK-GP201 PlayStick - b203 360 Modena Pro Wheel - b300 Firestorm Dual Power - b304 Firestorm Dual Power - b307 vibrating Upad - b603 force feedback Wheel - b605 force feedback Racing Wheel - b700 Tacticalboard -0450 DFI, Inc. -0451 Texas Instruments, Inc. - 1234 Bluetooth Device - 1428 Hub - 1446 TUSB2040/2070 Hub - 2036 TUSB2036 Hub - 2046 TUSB2046 Hub - 2077 TUSB2077 Hub - 3410 TUSB3410 Microcontroller - 3f02 SMC WSKP100 Wi-Fi Phone - 5409 Frontier Labs NEX IA+ Digital Audio Player - 6000 AU5 ADSL Modem (pre-reenum) - 6001 AU5 ADSL Modem - 6060 RNDIS/BeWAN ADSL2+ - 6070 RNDIS/BeWAN ADSL2+ - 625f Trekstor USB-Stick 12 CS-D 12 GB - dbc0 Device Bay Controller - e001 GraphLink - e004 TI-89 Titanium Calculator - e008 TI-84 Plus Silver Calculator - f430 MSP-FET430UIF JTAG Tool - ffff Bluetooth Device -0452 Mitsubishi Electronics America, Inc. - 0021 HID Monitor Controls - 0050 Diamond Pro 900u CRT Monitor - 0051 Integrated Hub -0453 CMD Technology - 6781 NMB Keyboard - 6783 Chicony Composite Keyboard -0454 Vobis Microcomputer AG -0455 Telematics International, Inc. -0456 Analog Devices, Inc. -0457 Silicon Integrated Systems Corp. - 0150 Super Talent 1GB Flash Drive - 0151 Super Flash 1GB / GXT 64MB Flash Drive - 0162 SiS162 usb Wireless LAN Adapter - 0163 802.11 Wireless LAN Adapter - 5401 Wireless Adapter RO80211GS-USB -0458 KYE Systems Corp. (Mouse Systems) - 0001 Mouse - 0002 Genius NetMouse Pro - 0003 Genius NetScroll+ - 0006 Easy Mouse+ USB(USB\Vid_0458&Pid;_0006) Mouse - 000b NetMouse Wheel(P+U) - 000c TACOMA Fingerprint V1.06.01 - 000e VideoCAM Web - 0013 TACOMA Fingerprint Mouse V1.06.01 - 001a Genius WebScroll+ - 0036 Pocket Mouse LE - 004c Slimstar Pro Keyboard - 0056 Ergo 300 Mouse - 0057 Enhanced Gaming Device - 0059 Enhanced Laser Device - 005a Enhanced Device - 005b Enhanced Device - 005c Enhanced Laser Gaming Device - 005d Enhanced Device - 0061 Bluetooth Dongle - 0083 Bluetooth Dongle - 0100 EasyPen Tablet - 0101 CueCat - 1001 Joystick - 1002 Game Pad - 1003 Genius VideoCam - 1004 Flight2000 F-23 Joystick - 100a Aashima Technology Trust Sight Fighter Vibration Feedback Joystick - 2001 ColorPage-Vivid Pro Scanner - 2004 ColorPage-HR6 V1 Scanner - 2005 ColorPage-HR6/Vivid3 - 2007 ColorPage-HR6 V2 Scanner - 2008 ColorPage-HR6 V2 Scanner - 2009 ColorPage-HR6A Scanner - 2011 ColorPage-Vivid3x Scanner - 2012 Plustek Scanner - 2013 ColorPage-HR7 Scanner - 2014 ColorPage-Vivid4 - 2015 ColorPage-HR7LE Scanner - 2016 ColorPage-HR6X Scanner - 2017 ColorPage-Vivid3xe - 2018 ColorPage-HR7X - 2019 ColorPage-HR6X Slim - 201a ColorPage-Vivid4xe - 201b ColorPage-Vivid4x - 201c ColorPage-HR8 - 201d ColorPage-Vivid 1200 X - 201e ColorPage-Slim 1200 - 201f ColorPage-Vivid 1200 XE - 2020 ColorPage-Slim 1200 USB2 - 2021 ColorPage-SF600 - 301d Genius MaxFire MiniPad - 6001 GF3000F Ethernet Adapter - 7004 VideoCAM Express - 7007 VideoCAM Web - 7009 G-Shot G312 Still Camera Device - 700c VideoCAM Web V3 - 700d G-Shot G511 Composite Device - 700f VideoCAM Web V4 - 7012 WebCAM USB2.0 - 7014 VideoCAM Live V3 - 701c G-Shot G512 Still Camera - 7020 Sim 321C -0459 Adobe Systems, Inc. -045a SONICblue, Inc. - 07da Supra Express 56K modem - 0b4a SupraMax 2890 56K Modem [Lucent Atlas] - 0b68 SupraMax 56K Modem - 5001 Rio 600 MP3 Player - 5002 Rio 800 MP3 Player - 5003 Nike Psa/Play MP3 Player - 5005 Rio S10 MP3 Player - 5006 Rio S50 MP3 Player - 5007 Rio S35 MP3 Player - 5008 Rio 900 MP3 Player - 5009 Rio S30 MP3 Player - 500d Fuse MP3 Player - 500e Chiba MP3 Player - 500f Cali MP3 Player - 5010 Rio S11 MP3 Player - 501c Virgin MPF-1000 - 501d Rio Fuse - 501e Rio Chiba - 501f Rio Cali - 503f Cali256 MP3 Player - 5202 Rio Riot MP3 Player - 5210 Rio Karma Music Player - 5220 Rio Nitrus MP3 Player - 5221 Rio Eigen -045b Hitachi, Ltd -045d Nortel Networks, Ltd -045e Microsoft Corp. - 0007 SideWinder Game Pad - 0008 SideWinder Precision Pro - 0009 IntelliMouse - 000b Natural Keyboard Elite - 000e SideWinder® Freestyle Pro - 0014 Digital Sound System 80 - 001a SideWinder Precision Racing Wheel - 001b SideWinder Force Feedback 2 Joystick - 001c Internet Keyboard Pro - 001d Natural Keyboard Pro - 001e IntelliMouse Explorer - 0023 Trackball Optical - 0024 Trackball Explorer - 0025 IntelliEye Mouse - 0026 SideWinder GamePad Pro - 0027 SideWinder PnP GamePad - 0028 SideWinder Dual Strike - 0029 IntelliMouse Optical - 002b Internet Keyboard Pro - 002d Internet Keyboard - 002f Integrated Hub - 0033 Sidewinder Strategic Commander - 0034 SideWinder Force Feedback Wheel - 0038 SideWinder Precision 2 - 0039 IntelliMouse Optical - 003b SideWinder Game Voice - 003c SideWinder Joystick - 0040 Wheel Mouse Optical - 0047 IntelliMouse Explorer 3.0 - 0048 Office Keyboard 1.0A - 0053 Optical Mouse - 0059 Wireless IntelliMouse Explorer - 005c Office Keyboard (106/109) - 005f Wireless MultiMedia Keyboard - 0061 Wireless MultiMedia Keyboard (106/109) - 0063 Wireless Natural MultiMedia Keyboard - 0065 Wireless Natural MultiMedia Keyboard (106/109) - 006a Wireless Optical Mouse (IntelliPoint) - 006d eHome Remote Control Keyboard keys - 006e MN510 802.11b Adapter - 006f Smart Display Reference Device - 0070 Wireless MultiMedia Keyboard - 0071 Wireless MultiMedia Keyboard (106/109) - 0072 Wireless Natural MultiMedia Keyboard - 0073 Wireless Natural MultiMedia Keyboard (106/109) - 007a 10/100 USB NIC - 007d Notebook Optical Mouse - 007e Wireless Transceiver for Bluetooth - 0080 Digital Media Pro Keyboard - 0083 Basic Optical Mouse - 0084 Basic Optical Mouse - 008a Wireless Keyboard and Mouse - 008b Dual Receiver Wireless Mouse (IntelliPoint) - 008c Wireless Intellimouse Explorer 2.0 - 0095 IntelliMouse Explorer 4.0 (IntelliPoint) - 009c Wireless Transceiver for Bluetooth 2.0 - 00a0 eHome Infrared Receiver - 00b0 Digital Media Pro Keyboard - 00b9 Wireless Optical Mouse 3.0 - 00bb Fingerprint Reader - 00bc Fingerprint Reader - 00bd Fingerprint Reader - 00c2 Wireless Adapter MN-710 - 00c9 MTP Device - 00ce Generic PPC Flash device - 00d1 Optical Mouse with Tilt Wheel - 00da eHome Infrared Receiver - 00db Natural Ergonomic Keyboard 4000 V1.0 - 00e1 Wireless Laser Mouse 6000 Reciever - 00f4 LifeCam VX-6000. - 00f5 LifeCam VX-3000. - 00f7 LifeCam VX-1000. - 00f8 LifeCam NX-6000. - 0202 Xbox Controller - 0280 XBox Device - 0284 Xbox DVD Playback Kit - 0285 Xbox Controller S - 0288 Xbox Controller S Hub - 0289 Xbox Controller S - 028b Xbox360 DVD Emulator - 028d Xbox360 Memory Unit 64MB - 028e Xbox360 Controller - 028f Xbox360 Wireless Controller - 0290 Xbox360 Performance Pipe (PIX) - 0292 Xbox360 Wireless Networking Adapter - 029c Xbox360 HD-DVD Drive - 029d Xbox360 HD-DVD Drive - 029e Xbox360 HD-DVD Memory Unit - 0400 Windows Powered Pocket PC 2002 - 0401 Windows Powered Pocket PC 2002 - 0402 Windows Powered Pocket PC 2002 - 0403 Windows Powered Pocket PC 2002 - 0404 Windows Powered Pocket PC 2002 - 0405 Windows Powered Pocket PC 2002 - 0406 Windows Powered Pocket PC 2002 - 0407 Windows Powered Pocket PC 2002 - 0408 Windows Powered Pocket PC 2002 - 0409 Windows Powered Pocket PC 2002 - 040a Windows Powered Pocket PC 2002 - 040b Windows Powered Pocket PC 2002 - 040c Windows Powered Pocket PC 2002 - 040d Windows Powered Pocket PC 2002 - 040e Windows Powered Pocket PC 2002 - 040f Windows Powered Pocket PC 2002 - 0410 Windows Powered Pocket PC 2002 - 0411 Windows Powered Pocket PC 2002 - 0412 Windows Powered Pocket PC 2002 - 0413 Windows Powered Pocket PC 2002 - 0414 Windows Powered Pocket PC 2002 - 0415 Windows Powered Pocket PC 2002 - 0416 Windows Powered Pocket PC 2002 - 0417 Windows Powered Pocket PC 2002 - 0432 Windows Powered Pocket PC 2003 - 0433 Windows Powered Pocket PC 2003 - 0434 Windows Powered Pocket PC 2003 - 0435 Windows Powered Pocket PC 2003 - 0436 Windows Powered Pocket PC 2003 - 0437 Windows Powered Pocket PC 2003 - 0438 Windows Powered Pocket PC 2003 - 0439 Windows Powered Pocket PC 2003 - 043a Windows Powered Pocket PC 2003 - 043b Windows Powered Pocket PC 2003 - 043c Windows Powered Pocket PC 2003 - 043d Becker Traffic Assist Highspeed 7934 - 043e Windows Powered Pocket PC 2003 - 043f Windows Powered Pocket PC 2003 - 0440 Windows Powered Pocket PC 2003 - 0441 Windows Powered Pocket PC 2003 - 0442 Windows Powered Pocket PC 2003 - 0443 Windows Powered Pocket PC 2003 - 0444 Windows Powered Pocket PC 2003 - 0445 Windows Powered Pocket PC 2003 - 0446 Windows Powered Pocket PC 2003 - 0447 Windows Powered Pocket PC 2003 - 0448 Windows Powered Pocket PC 2003 - 0449 Windows Powered Pocket PC 2003 - 044a Windows Powered Pocket PC 2003 - 044b Windows Powered Pocket PC 2003 - 044c Windows Powered Pocket PC 2003 - 044d Windows Powered Pocket PC 2003 - 044e Windows Powered Pocket PC 2003 - 044f Windows Powered Pocket PC 2003 - 0450 Windows Powered Pocket PC 2003 - 0451 Windows Powered Pocket PC 2003 - 0452 Windows Powered Pocket PC 2003 - 0453 Windows Powered Pocket PC 2003 - 0454 Windows Powered Pocket PC 2003 - 0455 Windows Powered Pocket PC 2003 - 0456 Windows Powered Pocket PC 2003 - 0457 Windows Powered Pocket PC 2003 - 0458 Windows Powered Pocket PC 2003 - 0459 Windows Powered Pocket PC 2003 - 045a Windows Powered Pocket PC 2003 - 045b Windows Powered Pocket PC 2003 - 045c Windows Powered Pocket PC 2003 - 045d Windows Powered Pocket PC 2003 - 045e Windows Powered Pocket PC 2003 - 045f Windows Powered Pocket PC 2003 - 0460 Windows Powered Pocket PC 2003 - 0461 Windows Powered Pocket PC 2003 - 0462 Windows Powered Pocket PC 2003 - 0463 Windows Powered Pocket PC 2003 - 0464 Windows Powered Pocket PC 2003 - 0465 Windows Powered Pocket PC 2003 - 0466 Windows Powered Pocket PC 2003 - 0467 Windows Powered Pocket PC 2003 - 0468 Windows Powered Pocket PC 2003 - 0469 Windows Powered Pocket PC 2003 - 046a Windows Powered Pocket PC 2003 - 046b Windows Powered Pocket PC 2003 - 046c Windows Powered Pocket PC 2003 - 046d Windows Powered Pocket PC 2003 - 046e Windows Powered Pocket PC 2003 - 046f Windows Powered Pocket PC 2003 - 0470 Windows Powered Pocket PC 2003 - 0471 Windows Powered Pocket PC 2003 - 0472 Windows Powered Pocket PC 2003 - 0473 Windows Powered Pocket PC 2003 - 0474 Windows Powered Pocket PC 2003 - 0475 Windows Powered Pocket PC 2003 - 0476 Windows Powered Pocket PC 2003 - 0477 Windows Powered Pocket PC 2003 - 0478 Windows Powered Pocket PC 2003 - 0479 Windows Powered Pocket PC 2003 - 047a Windows Powered Pocket PC 2003 - 047b Windows Powered Pocket PC 2003 - 04c8 Windows Powered Smartphone 2002 - 04c9 Windows Powered Smartphone 2002 - 04ca Windows Powered Smartphone 2002 - 04cb Windows Powered Smartphone 2002 - 04cc Windows Powered Smartphone 2002 - 04cd Windows Powered Smartphone 2002 - 04ce Windows Powered Smartphone 2002 - 04d7 Windows Powered Smartphone 2003 - 04d8 Windows Powered Smartphone 2003 - 04d9 Windows Powered Smartphone 2003 - 04da Windows Powered Smartphone 2003 - 04db Windows Powered Smartphone 2003 - 04dc Windows Powered Smartphone 2003 - 04dd Windows Powered Smartphone 2003 - 04de Windows Powered Smartphone 2003 - 04df Windows Powered Smartphone 2003 - 04e0 Windows Powered Smartphone 2003 - 04e1 Windows Powered Smartphone 2003 - 04e2 Windows Powered Smartphone 2003 - 04e3 Windows Powered Smartphone 2003 - 04e4 Windows Powered Smartphone 2003 - 04e5 Windows Powered Smartphone 2003 - 04e6 Windows Powered Smartphone 2003 - 04e7 Windows Powered Smartphone 2003 - 04e8 Windows Powered Smartphone 2003 - 04e9 Windows Powered Smartphone 2003 - 04ea Windows Powered Smartphone 2003 - 0708 Transceiver v 3.0 for Bluetooth - 070a Charon Bluetooth Dongle (DFU) - 930a ISOUSB.SYS Intel 82930 Isochronous IO Test Board - fff8 Keyboard -0460 Ace Cad Enterprise Co., Ltd -0461 Primax Electronics, Ltd - 0300 G2-300 Scanner - 0301 G2E-300 Scanner - 0302 G2-300 #2 Scanner - 0303 G2E-300 #2 Scanner - 0340 Colorado 9600 Scanner - 0341 Colorado 600u Scanner - 0345 Visioneer 6200 Scanner - 0346 Memorex Maxx 6136u Scanner - 0347 Primascan Colorado 2600u/Visioneer 4400 Scanner - 0360 Colorado 19200 Scanner - 0361 Colorado 1200u Scanner - 0363 VistaScan Astra 3600(ENG) - 0364 LG Electronics Scanworks 600U Scanner - 0365 VistaScan Astra 3600(ENG) - 0366 6400 - 0367 VistaScan Astra 3600(ENG) - 0371 Visioneer Onetouch 8920 Scanner - 0374 UMAX Astra 2500 - 0375 VistaScan Astra 3600(ENG) - 0377 Medion MD 5345 Scanner - 0378 VistaScan Astra 3600(ENG) - 037b Medion MD 6190 Scanner - 037c VistaScan Astra 3600(ENG) - 0380 G2-600 Scanner - 0381 ReadyScan 636i Scanner - 0382 G2-600 #2 Scanner - 0383 G2E-600 Scanner - 038a UMAX Astra 3000/3600 - 038b Xerox 2400 Onetouch - 038c UMAX Astra 4100 - 0392 Medion/Lifetec/Tevion/Cytron MD 6190 - 03a8 9420M - 0813 IBM UltraPort Camera - 0815 Micro Innovations WebCam - 0819 Fujifilm IX-30 Camera [webcam mode] - 081a Fujifilm IX-30 Camera [storage mode] - 081c Elitegroup ECS-C11 Camera - 081d Elitegroup ECS-C11 Storage - 0a00 Web Cam 320 - 4d01 Comfort Keyboard - 4d02 Mouse-in-a-Box - 4d03 Kensington Mouse-in-a-box - 4d04 Mouse - 4d06 Balless Mouse (HID) - 4d2a PoPo Elixir Mouse (HID) - 4d2b Wireless Laser Mini Mouse (HID) - 4d2c PoPo Mini Pointer Mouse (HID) - 4d2e Optical Mobile Mouse (HID) -0463 MGE UPS Systems - 0001 UPS - ffff UPS -0464 AMP/Tycoelectronics Corp. -0467 AT&T Paradyne -0468 Wieson Technologies Co., Ltd -046a Cherry GmbH - 0001 My3000 Keyboard - 0003 My3000 Hub - 0004 CyBoard Keyboard - 0005 XX33 SmartCard Reader Keyboard - 0010 SmartBoard XX44 - 0023 Cymotion Master Linux Keyboard - 002d SmartTerminal XX44 - 003e SmartTerminal ST-2xxx -046b American Megatrends, Inc. - 0001 Keyboard - 0101 PS/2 Keyboard, Mouse & Joystick Ports - 0301 USB 1.0 Hub - 0500 Serial & Parallel Ports -046c Toshiba Corp., Digital Media Equipment -046d Logitech, Inc. - 0082 Acer Aspire 5672 Webcam - 0200 WingMan Extreme Joystick - 0203 M2452 Keyboard - 0301 M4848 Mouse - 0401 HP PageScan - 0402 NEC PageScan - 040f Logitech/Storm PageScan - 0430 Mic (Cordless) - 0801 QuickCam Home - 0810 QuickCam Pro - 0820 QuickCam VC - 0830 QuickClip - 0840 QuickCam Express - 0850 QuickCam Web - 0870 QuickCam Express - 0890 QuickCam Traveler - 0892 OrbiCam - 0894 CrystalCam - 0895 QuickCam for Dell Notebooks - 0896 OrbiCam - 0897 QuickCam for Dell Notebooks - 0899 QuickCam for Dell Notebooks - 08a0 QuickCam IM - 08a1 QuickCam IM with sound - 08a2 Labtec WebCam Pro - 08a3 QuickCam QuickCam Chat - 08a6 QuickCam IM - 08a7 QuickCam Image - 08a9 Notebook Deluxe - 08aa Labtec Notebooks - 08ac QuickCam Cool - 08ad QuickCam Communicate STX - 08ae Quickcam for Notebooks - 08af QuickCam Easy/Cool - 08b0 QuickCam 3000 Pro [pwc] - 08b1 QuickCam Notebook Pro - 08b2 QuickCam Pro 4000 - 08b3 QuickCam Zoom - 08b4 QuickCam Zoom - 08b5 QuickCam Sphere - 08b9 QuickCam IM - 08bd Microphone (Pro 4000) - 08c0 QuickCam Pro 3000 - 08c1 QuickCam Fusion - 08c2 QuickCam PTZ - 08c3 Camera (Notebooks Pro) - 08c5 QuickCam Pro 5000 - 08c6 QuickCam for DELL Notebooks - 08c9 QuickCam Ultra Vision - 08ca Mic (Fusion) - 08cb Mic (Notebooks Pro) - 08cc Mic (PTZ) - 08ce QuickCam Pro 5000 - 08cf QuickCam UpdateMe - 08d0 QuickCam Express - 08d7 QuickCam Communicate STX - 08d8 QuickCam for Notebook Deluxe - 08d9 QuickCam IM/Connect - 08da QuickCam Messanger - 08dd QuickCam for Notebooks - 08e0 QuickCam Express - 08e1 Labtec WebCam - 08f0 QuickCam Messenger - 08f1 QuickCam Express - 08f2 Microphone (Messenger) - 08f3 QuickCam Express - 08f4 Labtec WebCam - 08f5 QuickCam Messenger Communicate - 08f6 Quickcam Messenger Plus - 0900 ClickSmart 310 - 0901 ClickSmart 510 - 0903 ClickSmart 820 - 0905 ClickSmart 820 - 0910 QuickCam Cordless - 0920 QuickCam Express - 0921 Labtec WebCam - 0922 QuickCam Live - 0928 Quickcam Express - 0929 Labtec WebCam Pro - 092a QuickCam for Notebooks - 092b Labtec WebCam Plus - 092c QuickCam Chat - 092d QuickCam Express / Go - 092e QuickCam Chat - 092f QuickCam Express Plus - 0950 Pocket Camera - 0960 ClickSmart 420 - 0970 Pocket750 - 0990 QuickCam Pro 9000 - 0991 QuickCam Pro for Notebooks - 0992 QuickCam Communicate Deluxe - 0994 QuickCam Orbit/Sphere AF - 09b0 OrbiCam - 09c0 QuickCam for Dell Notebooks Mic - 09c1 QuickCam Deluxe for Notebooks - 0a01 USB Headset - 0a02 Premium Stereo USB Headset 350 - 0a03 Logitech USB Microphone - 0a04 V20 portable speakers (USB powered) - 0b02 BT Mini-Receiver (HID proxy mode) - 8801 Video Camera - b305 BT Mini-Receiver - bfe4 Premium Optical Wheel Mouse - c000 N43 [Pilot Mouse] - c001 N48/M-BB48 [FirstMouse Plus] - c002 M-BA47 [MouseMan Plus] - c003 MouseMan - c004 WingMan Gaming Mouse - c005 WingMan Gaming Wheel Mouse - c00b MouseMan Wheel - c00c Optical Wheel Mouse - c00d MouseMan Wheel+ - c00e M-BJ58/M-BJ69 Optical Wheel Mouse - c00f MouseMan Traveler/Mobile - c011 Optical MouseMan - c012 Mouseman Dual Optical - c014 Corded Workstation Mouse - c015 Corded Workstation Mouse - c016 M-UV69a/HP M-UV96 Optical Wheel Mouse - c018 Optical Wheel Mouse - c019 Optical Tilt Wheel Mouse - c01a M-BQ85 Optical Wheel Mouse - c01b MX310 Optical Mouse - c01c Optical Mouse - c01d MX510 Optical Mouse - c01e MX518 Optical Mouse - c024 MX300 Optical Mouse - c025 MX500 Optical Mouse - c030 iFeel Mouse - c031 iFeel Mouse+ - c032 MouseMan iFeel - c033 iFeel MouseMan+ - c034 MouseMan Optical - c035 Mouse - c036 Mouse - c037 Mouse - c038 Mouse - c03d M-BT69a Pilot Optical Mouse - c03e Premium Optical Wheel Mouse - c03f UltraX Optical Mouse - c040 Corded Tilt-Wheel Mouse - c043 MX320 Laser Mouse - c044 LX3 Optical Mouse - c045 Optical Mouse - c046 RX1000 Laser Mouse - c047 Laser Mouse - c049 G5 Laser Mouse - c050 RX 250 Optical Mouse - c051 G3 (MX518) Optical Mouse - c053 Laser Mouse - c101 UltraX Media Remote - c201 WingMan Extreme Joystick with Throttle - c202 WingMan Formula - c207 WingMan Extreme Digital 3D - c208 WingMan Gamepad Extreme - c209 WingMan Gamepad - c20a WingMan RumblePad - c20b WingMan Action Pad - c20c WingMan Precision - c20d WingMan Attack 2 - c20e WingMan Formula GP - c211 iTouch Cordless Reciever - c212 WingMan Extreme Digital 3D - c213 J-UH16 (Freedom 2.4 Cordless Joystick) - c214 ATK3 (Attack III Joystick) - c215 Extreme 3D Pro - c216 Dual Action Gamepad - c218 Logitech RumblePad 2 USB - c219 Cordless RumblePad 2 - c21a Precision Gamepad - c221 G15 Keyboard / Keyboard - c222 G15 Keyboard / LCD - c223 G15 Keyboard / USB Hub - c281 WingMan Force - c283 WingMan Force 3D - c285 WingMan Strike Force 3D - c286 Force 3D Pro - c291 WingMan Formula Force - c293 WingMan Formula Force GP - c294 Driving Force - c295 Momo Force Steering Wheel - c298 Driving Force Pro - c2a0 Wingman Force Feedback Mouse - c2a1 WingMan Force Feedback Mouse - c301 iTouch Keyboard - c302 iTouch Pro Keyboard - c303 iTouch Keyboard - c305 Internet Keyboard - c307 Internet Keyboard - c308 Internet Navigator Keyboard - c309 Internet Keyboard - c30a iTouch Composite - c30c Internet Keys (X) - c30d Internet Keys - c30e UltraX Keys (X) - c30f Logicool HID-Compliant Keyboard (106 key) - c315 Classic New Touch Keyboard - c316 HID-Compliant Keyboard - c401 TrackMan Marble Wheel - c402 Marble Mouse (2-button) - c403 Turbo TrackMan Marble FX - c404 TrackMan Wheel - c408 Marble Mouse (4-button) - c501 Cordless Mouse Receiver - c502 Cordless Mouse & iTouch Keys - c503 Cordless Mouse+Keyboard Receiver - c504 Cordless Mouse+Keyboard Receiver - c505 Cordless Mouse+Keyboard Receiver - c506 MX-700 Cordless Mouse Receiver - c508 Cordless Trackball - c509 Cordless Keyboard - c50a Cordless Mouse - c50b Cordless Desktop Optical - c50d Cordless Mouse - c50e MX-1000 Cordless Mouse Receiver - c510 Cordless Mouse - c512 LX-700 Cordless Desktop Receiver - c513 MX3000 Cordless Desktop Receiver - c514 Cordless Mouse - c517 LX710 Cordless Desktop Laser - c518 MX610 Laser Cordless Mouse - c51a MX Revolution/G7 Cordless Mouse - c521 MX620 Laser Cordless Mouse - c625 3Dconnexion Space Pilot 3D Mouse - c626 3DConnexion Space Navigator 3D Mouse - c627 3DConnexion Space Explorer 3D Mouse - c702 Cordless Presenter - c703 Elite Keyboard Y-RP20 + Mouse MX900 (Bluetooth) - c707 Bluetooth wireless hub - c708 Bluetooth wireless hub - c709 BT Mini-Receiver (HCI mode) - c70a MX5000 Cordless Desktop - c70b BT Mini-Receiver (HID proxy mode) - c70c BT Mini-Receiver (HID proxy mode) - c70d Bluetooth wireless hub - c70e MX1000 Bluetooth Laser Mouse - c70f Bluetooth wireless hub - c712 Bluetooth wireless hub - c715 Bluetooth wireless hub - c71a Bluetooth wireless hub - c71d Bluetooth wireless hub - c720 Bluetooth wireless hub - ca03 MOMO Racing - ca04 Formula Vibration Feedback Wheel - d001 QuickCam Pro -046e Behavior Tech. Computer Corp. - 0100 Keyboard - 3001 Mass Storage Device - 3002 Mass Storage Device - 3003 Mass Storage Device - 3005 Mass Storage Device - 3008 Mass Storage Device - 5250 KeyMaestro Multimedia Keyboard - 5273 KeyMaestro Multimedia Keyboard - 5308 KeyMaestro Keyboard - 5408 KeyMaestro Multimedia Keyboard/Hub - 5720 Smart Card Reader - 6782 BTC 7932 mouse+keyboard -046f Crystal Semiconductor -0471 Philips - 0101 DSS350 Digital Speaker System - 0104 DSS330 Digital Speaker System [uda1321] - 0105 UDA1321 - 0160 MP3 Player - 0161 MP3 Player - 0201 Hub - 0222 Creative Nomad Jukebox - 0302 PCA645VC WebCam [pwc] - 0303 PCA646VC WebCam [pwc] - 0304 Askey VC010 WebCam [pwc] - 0307 PCVC675K WebCam [pwc] - 0308 PCVC680K WebCam [pwc] - 030b PC VGA Camera (Vesta Fun) - 030c PCVC690K WebCam [pwc] - 0310 PCVC730K WebCam [pwc] - 0311 PCVC740K ToUcam Pro [pwc] - 0312 PCVC750K WebCam [pwc] - 0314 DMVC 1000K - 0316 DMVC 2000K Video Capture - 0321 FunCam - 0325 SPC 200NC PC Camera - 0326 SPC 300NC PC Camera - 0327 WebCam SPC 6000 NC (WebCam w/ mic) - 0329 ORITE CCD Webcam(PC370R) - 0401 Semiconductors CICT Keyboard - 0402 PS/2 Mouse on Semiconductors CICT Keyboard - 0406 15 inch Detachable Monitor - 0407 10 inch Mobile Monitor - 0471 Digital Speaker System - 0601 OVU1020 IR Dongle (Kbd+Mouse) - 0602 ATI Remote Wonder II Input Device - 0603 ATI Remote Wonder II Controller - 0608 eHome Infrared Receiver - 060a TSU9600 Remote Control - 060e RF Dongle - 0619 TSU9400 Remote Control - 0700 Semiconductors CICT Hub - 0701 150P1 TFT Display - 0809 AVNET Bluetooth Device - 0811 JR24 CDRW - 0815 eHome Infrared Receiver - 1120 Creative Rhomba MP3 player - 1125 Nike psa[128max Player - 1137 HDD065 MP3 player - 1201 Arima Bluetooth Device - 1230 Wireless Adapter 11g - 1232 SNU6500 Wireless Adapter - 1233 Wireless Adapter Bootloader Download - 1236 SNU5600 - 1237 TalkTalk SNU5630NS/05 Wireless Adapter - 1552 ISP 1581 Hi-Speed USB MPEG2 Encoder Reference Kit - 1801 Diva MP3 player - 200a Wireless Network Adapter - 200f 802.11n Wireless Adapter - 485d Senselock SenseIV v2.x -0472 Chicony Electronics Co., Ltd - 0065 PFU-65 Keyboard -0473 Sanyo Information Business Co., Ltd -0474 Sanyo Electric Co., Ltd - 0110 Digital Voice Recorder R200 - 0217 Xacti J2 - 022f C5 Digital Media Camera (mass storage mode) - 0230 C5 Digital Media Camera (PictBridge mode) - 0231 C5 Digital Media Camera (PC control mode) - 0401 Optical Drive - 0701 SCP-4900 Cellphone - 071f Usb Com Port Enumerator -0475 Relisys/Teco Information System - 0100 NEC Petiscan - 0103 Eclipse 1200U/Episode - 0210 Scorpio Ultra 3 -0476 AESP -0477 Seagate Technology, Inc. -0478 Connectix Corp. - 0001 QuickCam - 0002 QuickClip - 0003 QuickCam Pro -0479 Advanced Peripheral Laboratories -047a Semtech Corp. - 0004 ScreenCoder UR7HCTS2-USB -047b Silitek Corp. - 0001 Keyboard - 0002 Keyboard and Mouse - 00f9 SK-1789u Keyboard - 0101 BlueTooth Keyboard and Mouse - 020b SK-3105 SmartCard Reader - 050e Internet Compact Keyboard - 1000 Trust Office Scan USB 19200 - 1002 HP ScanJet 4300c Parallel Port -047c Dell Computer Corp. -047d Kensington - 1001 Mouse*in*a*Box - 1002 Expert Mouse Pro - 1003 Orbit TrackBall - 1004 MouseWorks - 1005 TurboBall - 1006 TurboRing - 1009 Orbit TrackBall for Mac - 1012 PocketMouse - 1013 Mouse*in*a*Box Optical Pro - 1014 Expert Mouse Pro Wireless - 1015 Expert Mouse - 1016 ADB/USB Orbit - 1018 Studio Mouse - 101d Mouse*in*a*Box Optical Pro - 101e Studio Mouse Wireless - 101f PocketMouse Pro - 1020 Expert Mouse Trackball - 1021 Expert Mouse Wireless - 1022 Orbit Optical - 1023 Pocket Mouse Pro Wireless - 1024 PocketMouse - 1025 Mouse*in*a*Box Optical Elite Wireless - 1026 Pocket Mouse Pro - 1027 StudioMouse - 1028 StudioMouse Wireless - 1029 Mouse*in*a*Box Optical Elite - 102a Mouse*in*a*Box Optical - 102b PocketMouse - 102c Iridio - 102d Pilot Optical - 102e Pilot Optical Pro - 102f Pilot Optical Pro Wireless - 104a PilotMouse Mini Retractable - 105d PocketMouse Bluetooth - 105e Bluetooth EDR Dongle - 1061 PocketMouse Grip - 1062 PocketMouse Max - 1063 PocketMouse Max Wireless - 1064 PocketMouse 2.0 Wireless - 1065 PocketMouse 2.0 - 1066 PocketMouse Max Glow - 1067 ValueMouse - 1068 ValueOpt White - 1069 ValueOpt Black - 106a PilotMouse Laser Wireless Mini - 106b PilotMouse Laser - 3 Button - 106c PilotMouse Laser - Gaming - 106d PilotMouse Laser - Wired - 106e PilotMouse Micro Laser - 1070 ValueOpt Travel - 1071 ValueOpt RF TX - 1072 PocketMouse Colour - 1073 PilotMouse Laser - 6 Button - 1074 PilotMouse Laser Wireless Mini - 1075 SlimBlade Presenter Media Mouse - 1076 SlimBlade Media Mouse - 1077 SlimBlade Presenter Mouse - 1152 Bluetooth EDR Dongle - 2002 Optical Elite Wireless - 2010 Wireless Presentation Remote - 2021 PilotBoard Wireless - 2030 PilotBoard Wireless - 2034 SlimBlade Media Notebook Set - 4003 Gravis Xterminator Digital Gamepad - 4005 Gravis Eliminator GamePad Pro - 4006 Gravis Eliminator AfterShock - 4007 Gravis Xterminator Force - 4008 Gravis Destroyer TiltPad - 5001 Cabo I Camera - 5002 VideoCam CABO II - 5003 VideoCam -047e Agere Systems, Inc. (Lucent) - 0300 ORiNOCO Card - 1001 USS720 Parallel Port - 2892 Systems Soft Modem - bad1 Lucent 56k Modem - f101 Atlas Modem -047f Plantronics, Inc. - 0101 Bulk Driver - 0301 Bulk Driver - 0ca1 USB DSP v4 Audio Interface -0480 Toshiba America Info. Systems, Inc. - 0001 InTouch Module - 0004 InTouch Module - 0011 InTouch Module - 0014 InTouch Module -0481 Zenith Data Systems -0482 Kyocera Corp. - 000e FS-1020D Printer - 0100 Finecam S3x - 0101 Finecam S4 - 0103 Finecam S5 - 0105 Finecam L3 - 0106 Finecam - 0107 Digital Camera Device - 0108 Digital Camera Device - 0203 AH-K3001V - 0204 iBurst Terminal -0483 SGS Thomson Microelectronics - 0137 BeWAN ADSL USB ST (blue or green) - 1307 Cytronix 6in1 card reader - 163d Cool Icam Digi-MP3 - 2015 TouchChip® Fingerprint Reader - 2016 Fingerprint Reader - 2017 Biometric Smart Card Reader - 2018 BioSimKey - 2302 Portable Flash Device (PFD) - 4810 ISDN adapter - 481d BT Digital Access adapter - 5000 ST Micro Bluetooth Device - 5001 ST Micro Bluetooth Device - 7270 ST Micro Serial Bridge - 7554 56k SoftModem - ff10 Swann ST56 Modem -0484 Specialix -0485 Nokia Monitors -0486 ASUS Computers, Inc. -0487 Stewart Connector -0488 Cirque Corp. -0489 Foxconn / Hon Hai - 0502 SmartMedia Card Reader Firmware Loader - 0503 SmartMedia Card Reader -048a S-MOS Systems, Inc. -048c Alps Electric Ireland, Ltd -048d Integrated Technology Express, Inc. -048f Eicon Tech. -0490 United Microelectronics Corp. -0491 Capetronic - 0003 Taxan Monitor Control -0492 Samsung SemiConductor, Inc. -0493 MAG Technology Co., Ltd -0495 ESS Technology, Inc. -0496 Micron Electronics -0497 Smile International -0498 Capetronic (Kaohsiung) Corp. -0499 Yamaha Corp. - 1000 UX256 MIDI I/F - 1001 MU1000 - 1002 MU2000 - 1003 MU500 - 1004 UW500 - 1005 MOTIF6 - 1006 MOTIF7 - 1007 MOTIF8 - 1008 UX96 MIDI I/F - 1009 UX16 MIDI I/F - 100a EOS BX - 100c UC-MX - 100d UC-KX - 100e S08 - 100f CLP-150 - 1010 CLP-170 - 1011 P-250 - 1012 TYROS - 1013 PF-500 - 1014 S90 - 1015 MOTIF-R - 1016 MDP-5 - 1017 CVP-204 - 1018 CVP-206 - 1019 CVP-208 - 101a CVP-210 - 101b PSR-1100 - 101c PSR-2100 - 101d CLP-175 - 101e PSR-K1 - 101f EZ-J24 - 1020 EZ-250i - 1021 MOTIF ES 6 - 1022 MOTIF ES 7 - 1023 MOTIF ES 8 - 1024 CVP-301 - 1025 CVP-303 - 1026 CVP-305 - 1027 CVP-307 - 1028 CVP-309 - 1029 CVP-309GP - 102a PSR-1500 - 102b PSR-3000 - 102e ELS-01/01C - 1030 PSR-295/293 - 1031 DGX-205/203 - 1032 DGX-305 - 1033 DGX-505 - 2000 DGP-7 - 2001 DGP-5 - 3001 YST-MS55D USB Speaker - 4000 NetVolante RTA54i Broadband&ISDN Router - 4001 NetVolante RTW65b Broadband Wireless Router - 4002 NetVolante RTW65i Broadband&ISDN Wireless Router - 4004 NetVolante RTA55i Broadband VoIP Router - 5000 CS1D - 5001 DSP1D - 5002 DME32 - 5003 DM2000 - 5004 02R96 - 5005 ACU16-C - 5006 NHB32-C - 5007 DM1000 - 5008 01V96 - 5009 SPX2000 - 500a PM5D - 500b DME64N - 500c DME24N - 6001 CRW2200UX Lightspeed 2 External CD-RW Drive - 7000 DTX - 7010 UB99 -049a Gandalf Technologies, Ltd -049b Curtis Computer Products -049c Acer Advanced Labs, Inc. - 0002 Keyboard (???) -049d VLSI Technology -049f Compaq Computer Corp. - 0002 InkJet Color Printer - 0003 iPAQ PocketPC - 000e Internet Keyboard - 0012 InkJet Color Printer - 0018 PA-1/PA-2 MP3 Player - 0019 InkJet Color Printer - 001a S4 100 Scanner - 001e IJ650 Inkjet Printer - 001f WL215 Adapter - 0021 S200 Scanner - 0027 Bluetooth Multiport Module by Compaq - 002a 1400P Inkjet Printer - 002b A3000 - 002c Lexmark X125 - 0032 802.11b Adapter [ipaq h5400] - 0033 802.11b Adapter [orinoco] - 0036 Bluetooth Multiport Module - 0051 KU-0133 Easy Access Interner Keyboard - 0076 Wireless LAN MultiPort W200 - 0080 GPRS Multiport - 0086 Bluetooth Device - 504a Personal Jukebox PJB100 - 505a Linux-USB "CDC Subset" Device, or Itsy (experimental) - 8511 iPAQ Networking 10/100 Ethernet [pegasus2] -04a0 Digital Equipment Corp. -04a1 SystemSoft Corp. - fff0 Telex Composite Device -04a2 FirePower Systems -04a3 Trident Microsystems, Inc. -04a4 Hitachi, Ltd - 0004 DVD-CAM DZ-MV100A Camcorder - 001e DVDCAM USB HS Interface -04a5 Acer Peripherals Inc. (now BenQ Corp.) - 0001 Keyboard - 0002 API Ergo K/B - 0003 API Generic K/B Mouse - 12a6 AcerScan C310U - 1a20 Prisa 310U - 1a2a Prisa 620U - 2022 Prisa 320U/340U - 2040 Prisa 620UT - 205e ScanPrisa 640BU - 2060 Prisa 620U+/640U - 207e Prisa 640BU - 209e ScanPrisa 640BT - 20ae S2W 3000U - 20b0 S2W 3300U/4300U - 20be Prisa 640BT - 20c0 Prisa 1240UT - 20de S2W 4300U+ - 20f8 Benq 5000 - 20fc Benq 5000 - 20fe SW2 5300U - 2137 Benq 5150/5250 - 2202 Benq 7400UT - 3003 Benq WebCam - 3008 Benq 1500 - 300a Benq 3410 - 300c Benq 1016 - 3019 Benq DC C40 - 4000 P30 Composite Device - 6001 Mass Storage Device - 6002 Mass Storage Device - 6003 ATA/ATAPI Adapter - 6004 Mass Storage Device - 6005 Mass Storage Device - 6006 Mass Storage Device - 6007 Mass Storage Device - 6008 Mass Storage Device - 6009 Mass Storage Device - 600a Mass Storage Device - 600b Mass Storage Device - 600c Mass Storage Device - 600d Mass Storage Device - 600e Mass Storage Device - 600f Mass Storage Device - 6010 Mass Storage Device - 6011 Mass Storage Device - 6012 Mass Storage Device - 6013 Mass Storage Device - 6014 Mass Storage Device - 6015 Mass Storage Device - 6125 MP3 Player - 6180 MP3 Player - 6200 MP3 Player - 7500 Hi-Speed Mass Storage Device - 9000 AWL300 Wireless Adapter - 9001 AWL400 Wireless Adapter - 9213 Kbd Hub -04a6 Nokia Display Products - 00b9 Audio - 0180 Hub Type P - 0181 HID Monitor Controls -04a7 Visioneer - 0100 StrobePro - 0101 Strobe Pro Scanner (1.01) - 0102 StrobePro Scanner - 0211 OneTouch 7600 Scanner - 0221 OneTouch 5300 Scanner - 0223 OneTouch 8200 - 0224 OneTouch 4800 USB/Microtek Scanport 3000 - 0225 VistaScan Astra 3600(ENG) - 0226 OneTouch 5300 USB - 0229 OneTouch 7100 - 022a OneTouch 6600 - 022c OneTouch 9000/9020 - 0231 6100 Scanner - 0311 6200 EPP/USB Scanner - 0321 OneTouch 8100 EPP/USB Scanner - 0331 OneTouch 8600 EPP/USB Scanner - 0341 6400 - 0361 VistaScan Astra 3600(ENG) - 0362 OneTouch 9320 - 0371 OneTouch 8700/8920 - 0380 OneTouch 7700 - 0382 Photo Port 7700 - 0390 9650 - 03a0 Xerox 4800 One Touch - 0410 OneTouch Pro 8800/8820 - 0421 9450 USB - 0423 9750 Scanner - 0424 Strobe XP 450 - 0425 Strobe XP 100 - 0426 Strobe XP 200 - 0427 Strobe XP 100 - 0444 OneTouch 7300 - 0445 CardReader 100 - 0446 Xerox DocuMate 510 - 0447 XEROX DocuMate 520 - 0448 XEROX DocuMate 250 - 0449 Xerox DocuMate 252 - 044a Xerox 6400 - 044c Xerox DocuMate 262 - 0474 Strobe XP 300 - 0475 Xerox DocuMate 272 - 0478 Strobe XP 220 - 0479 Strobe XP 470 - 047a 9450 - 047b 9650 - 047d 9420 - 0480 9520 - 048f Strobe XP 470 - 0491 Strobe XP 450 - 0493 9750 - 0494 Strobe XP 120 - 0497 Patriot 430 - 0498 Patriot 680 - 0499 Patriot 780 - 049b Strobe XP 100 - 04a0 7400 -04a8 Multivideo Labs, Inc. - 0101 Hub - 0303 Peripheral Switch - 0404 Peripheral Switch -04a9 Canon, Inc. - 1005 BJ Printer Hub - 1035 PD Printer Storage - 1050 BJC-8200 - 1051 BJC-3000 Color Printer - 1052 BJC-6100 - 1053 BJC-6200 - 1054 BJC-6500 - 1055 BJC-85 - 1056 BJC-2110 Color Printer - 1057 LR1 - 105a BJC-55 - 105b S600 Printer - 105c S400 - 105d S450 Printer - 105e S800 - 1062 S500 Printer - 1063 S4500 - 1064 S300 Printer - 1065 S100 - 1066 S630 - 1067 S900 - 1068 S9000 - 1069 S820 - 106a S200 Printer - 106b S520 Printer - 106d S750 Printer - 106e S820D - 1070 S530D - 1072 I850 Printer - 1073 I550 Printer - 1074 S330 Printer - 1076 i70 - 1077 i950 - 107a S830D - 107b i320 - 107c i470D - 107d i9100 - 107e i450 - 107f i860 - 1082 i350 - 1084 i250 - 1085 i255 - 1086 i560 - 1088 i965 - 108a i455 - 108b i900D - 108c i475D - 108d PIXMA iP2000 - 108f i80 - 1090 i9900 Photo Printer - 1091 PIXMA iP1500 - 1093 PIXMA iP4000 - 1094 PIXMA iP3000x Printer - 1095 PIXMA iP6000D - 1097 PIXMA iP5000 - 1098 PIXMA iP1000 - 1099 PIXMA iP8500 - 109c PIXMA iP4000R - 109d iP90 - 10a0 PIXMA iP1600 Printer - 10a2 iP4200 - 10a4 iP5200R - 10a5 iP5200 - 10a7 iP6210D - 10a8 iP6220D - 10a9 iP6600D - 10b6 PIXMA iP4300 Printer - 1404 W6400PG - 1405 W8400PG - 150f BIJ2350 PCL - 1510 BIJ1350 PCL - 1512 BIJ1350D PCL - 1601 DR-2080C Scanner - 1607 DR-6080 Scanner - 1700 PIXMA MP110 Scanner - 1701 PIXMA MP130 Scanner - 1702 MP410 Composite - 1703 MP430 Composite - 1704 MP330 Composite - 1706 PIXMA MP750 Scanner - 1707 PIXMA MP780 Scanner - 1708 PIXMA MP760 Scanner - 1709 PIXMA MP150 Scanner - 170a PIXMA MP170 Scanner - 170b PIXMA MP450 Scanner - 170c PIXMA MP500 Scanner - 170d PIXMA MP800 Scanner - 170e MP800R - 1710 MP950 - 1712 MP530 - 1713 PIXMA MP830 Scanner - 1714 MP160 - 1715 MP180 Storage - 1716 MP460 Composite - 1717 MP510 - 1718 MP600 Storage - 171a MP810 Storage - 171b MP960 - 1721 MP210 ser - 1723 MP470 ser - 1725 MP610 ser - 1726 MP970 ser - 1727 MX300 ser - 1728 MX310 ser - 1729 MX700 ser - 172b MP140 ser - 2200 CanoScan LiDE 25 - 2201 CanoScan FB320U - 2202 CanoScan FB620U - 2204 CanoScan FB630U - 2205 CanoScan FB1210U - 2206 CanoScan N650U/N656U - 2207 CanoScan 1220U - 2208 CanoScan D660U - 220a CanoScan D2400UF - 220b CanoScan D646U - 220c CanoScan D1250U2 - 220d CanoScan N670U/N676U/LiDE 20 - 220e CanoScan N1240U/LiDE 30 - 220f CanoScan 8000F - 2210 CanoScan 9900F - 2212 CanoScan 5000F - 2213 CanoScan LiDE 50/LiDE 35/LiDE 40 - 2214 CanoScan LiDE 80 - 2215 CanoScan 3000/3000F/3000ex - 2216 CanoScan 3200F - 2217 CanoScan 5200F - 2219 CanoScan 9950F - 221b CanoScan 4200F - 221c CanoScan LiDE 60 - 221e CanoScan 8400F - 221f CanoScan LiDE 500F - 2220 CanoScan LIDE 25 - 2225 CanoScan LiDE 70 - 2228 CanoScan 4400F - 2602 MultiPASS C555 - 2603 MultiPASS C755 - 260a CAPT Printer - 260e LBP-2000 - 2610 MPC600F - 2611 SmartBase MPC400 - 2612 MultiPASS C855 - 2617 CAPT Printer - 261a iR1600 - 261b iR1610 - 261c iC2300 - 261f MPC200 Printer - 2621 iR2000 - 2622 iR2010 - 2623 FAX-B180C - 2629 FAXPHONE L75 - 262b LaserShot LBP-1120 Printer - 262d iR C3200 - 262f MultiPASS MP730 - 2630 MultiPASS MP700 - 2631 LASER CLASS 700 - 2632 FAX-L2000 - 2635 MPC190 - 2637 iR C6800 - 2638 iR C3100 - 263c Smartbase MP360 - 263d MP370 - 263e MP390 FAX - 263f MP375 - 2646 MF5530 Scanner Device V1.9.1 - 2647 MF5550 Composite - 264e MF5630 - 264f MF5650 (FAX) - 2650 iR 6800C EUR - 2651 iR 3100C EUR - 2655 FP-L170/MF350/L380/L398 - 2659 MF8100 - 265b CAPT Printer - 265c iR C3220 - 265d MF5730 - 265e MF5750 - 265f MF5770 - 2660 MF3110 - 2663 iR3570/iR4570 - 2664 iR2270/iR2870 - 2665 iR C2620 - 2666 iR C5800 - 2667 iR85PLUS - 2669 iR105PLUS - 266a CAPT Device - 266b iR8070 - 266c iR9070 - 266d iR 5800C EUR - 266e CAPT Device - 266f iR2230 - 2670 iR3530 - 2671 iR5570/iR6570 - 2672 iR C3170 - 2673 iR 3170C EUR - 2674 L120 - 2675 iR2830 - 2676 CAPT Device - 2677 iR C2570 - 2678 iR 2570C EUR - 2679 CAPT Device - 267a iR2016 - 267b iR2020 - 267d MF7100 Series - 2684 MF3200 Series - 2687 iR4530 - 2688 LBP3460 - 268c iR C6870 - 268d iR 6870C EUR - 268e iR C5870 - 268f iR 5870C EUR - 2691 iR7105 - 26a3 MF4100 Series - 26b5 MF4200 Series - 3041 PowerShot S10 - 3042 CanoScan FS4000US Film Scanner - 3043 PowerShot S20 - 3044 EOS D30 - 3045 PowerShot S100 - 3046 IXY Digital - 3047 Digital IXUS - 3048 PowerShot G1 - 3049 PowerShot Pro90 IS - 304a CP-10 - 304b IXY Digital 300 - 304c PowerShot S300 - 304d Digital IXUS 300 - 304e PowerShot A20 - 304f PowerShot A10 - 3050 PowerShot unknown 1 - 3051 PowerShot S110 - 3052 Digital IXUS V - 3055 PowerShot G2 - 3056 PowerShot S40 - 3057 PowerShot S30 - 3058 PowerShot A40 - 3059 PowerShot A30 - 305b ZR45MC Digital Camcorder - 305c PowerShot unknown 2 - 3060 EOS D60 - 3061 PowerShot A100 - 3062 PowerShot A200 - 3063 CP-100 - 3065 PowerShot S200 - 3066 Digital IXUS 330 - 3067 MV550i Digital Video Camera - 3069 PowerShot G3 - 306a Digital unknown 3 - 306b MVX2i Digital Video Camera - 306c PowerShot S45 - 306d PowerShot S45 PtP Mode - 306e PowerShot G3 (normal mode) - 306f PowerShot G3 (ptp) - 3070 PowerShot S230 - 3071 PowerShot S230 (ptp) - 3072 PowerShot SD100 / Digital IXUS II (ptp) - 3073 PowerShot A70 (ptp) - 3074 PowerShot A60 (ptp) - 3075 IXUS 400 Camera - 3076 PowerShot A300 - 3077 PowerShot S50 - 3078 ZR70MC Digital Camcorder - 307a MV650i (normal mode) - 307b MV630i Digital Video Camera - 307c MV630i (normal mode) - 307d CP-300 - 307f Optura 20 - 3080 MVX150i (normal mode) / Optura 20 (normal mode) - 3081 Optura 10 - 3082 MVX100i / Optura 10 - 3083 EOS 10D - 3084 EOS 300D / EOS Digital Rebel - 3085 PowerShot G5 - 3087 Elura 50 (PTP mode) - 3088 Elura 50 (normal mode) - 308d MVX3i - 308e FV M1 (normal mode) / MVX 3i (normal mode) / Optura Xi (normal mode) - 3093 Optura 300 - 3096 IXY DV M2 (normal mode) / MVX 10i (normal mode) - 3099 EOS 300D (ptp) - 309a PowerShot A80 - 309b Digital IXUS (ptp) - 309c PowerShot S1 IS - 309d Camera - 309f Camera - 30a0 Camera - 30a1 Camera - 30a2 Camera - 30a8 Elura 60E/Optura 40 (ptp) - 30a9 MVX25i (normal mode) / Optura 40 (normal mode) - 30b1 PowerShot S70 (normal mode) / PowerShot S70 (PTP mode) - 30b2 PowerShot S60 (normal mode) / PowerShot S60 (PTP mode) - 30b3 PowerShot G6 (normal mode) / PowerShot G6 (PTP mode) - 30b4 PowerShot S500 - 30b5 PowerShot A75 - 30b6 Digital IXUS II2 / Digital IXUS II2 (PTP mode) / PowerShot SD110 (PTP mode) / PowerShot SD110 Digital ELPH - 30b7 PowerShot A400 / PowerShot A400 (PTP mode) - 30b8 PowerShot A310 / PowerShot A310 (PTP mode) - 30b9 Powershot A85 - 30ba PowerShot S410 Digital Elph - 30bb PowerShot A95 - 30bd CP-220 - 30be CP-330 - 30bf Digital IXUS 40 - 30c0 Digital IXUS 30 (PTP mode) / PowerShot SD200 (PTP mode) - 30c1 Digital IXUS 50 (normal mode) / IXY Digital 55 (normal mode) / PowerShot A520 (PTP mode) / PowerShot SD400 (normal mode) - 30c2 PowerShot A510 (normal mode) / PowerShot A510 (PTP mode) - 30c4 Digital IXUS i5 (normal mode) / IXY Digital L2 (normal mode) / PowerShot SD20 (normal mode) - 30ea EOS 1D Mark II (PTP mode) - 30eb EOS 20D - 30ec EOS 20D (ptp) - 30ee EOS 350D - 30ef EOS 350D (ptp) - 30f0 PowerShot S2 IS (PTP mode) - 30f2 Digital IXUS 700 (normal mode) / Digital IXUS 700 (PTP mode) / IXY Digital 600 (normal mode) / PowerShot SD500 (normal mode) / PowerShot SD500 (PTP mode) - 30f6 SELPHY CP400 - 30f8 Powershot A430 - 30f9 PowerShot A410 (PTP mode) - 30fc PowerShot A620 (PTP mode) - 30fd PowerShot A610 (normal mode)/PowerShot A610 (PTP mode) - 30ff Digital IXUS 55 (PTP mode)/PowerShot SD450 (PTP mode) - 310b SELPHY CP600 - 310e Digital IXUS 50 (PTP mode) - 3116 Digital IXUS 750 (PTP mode) - 3117 PowerShot A700 - 3138 PowerShot A710 IS - 315a PowerShot G9 - 3176 PowerShot A590 - 31ff Digital IXUS 55 -04aa DaeWoo Telecom, Ltd -04ab Chromatic Research -04ac Micro Audiometrics Corp. -04ad Dooin Electronics - 2501 Bluetooth Device -04af Winnov L.P. -04b0 Nikon Corp. - 0102 Coolpix 990 - 0103 Coolpix 880 - 0104 Coolpix 995 - 0106 Coolpix 775 - 0107 Coolpix 5000 - 0108 Coolpix 2500 - 0109 Coolpix 2500 (ptp) - 010a Coolpix 4500 - 010b Coolpix 4500 (ptp) - 010d Coolpix 5700 (ptp) - 010e Coolpix 4300 (storage) - 010f Coolpix 4300 (ptp) - 0110 Coolpix 3500 (Sierra Mode) - 0111 Coolpix 3500 (ptp) - 0112 Coolpix 885 (ptp) - 0113 Coolpix 5000 (ptp) - 0114 Coolpix 3100 (storage) - 0115 Coolpix 3100 (ptp) - 0117 Coolpix 2100 (ptp) - 0119 Coolpix 5400 (ptp) - 011d Coolpix 3700 (ptp) - 0121 Coolpix 3200 (ptp) - 0122 Coolpix 2200 (ptp) - 0126 Coolpix 8800 - 0129 Coolpix 4800 (ptp) - 012c Coolpix 4100 (storage) - 012d Coolpix 4100 (ptp) - 012e Coolpix 5600 (ptp) - 0130 Coolpix 4600 (ptp) - 0135 Coolpix 5900 (ptp) - 0136 Coolpix 7900 (storage) - 0137 Coolpix 7900 (ptp) - 0141 Coolpix P2 (storage) - 0142 Coolpix P2 (ptp) - 0163 Coolpix P5100 (ptp) - 0169 Coolpix P50 (ptp) - 0202 Coolpix SQ (ptp) - 0203 Coolpix 4200 (mass storage mode) - 0204 Coolpix 4200 (ptp) - 0205 Coolpix 5200 (storage) - 0206 Coolpix 5200 (ptp) - 0301 Coolpix 2000 (storage) - 0302 Coolpix 2000 (ptp) - 0402 DSC D100 (ptp) - 0403 D2H (mass storage mode) - 0404 D2H SLR (ptp) - 0405 D70 (mass storage mode) - 0406 DSC D70 (ptp) - 0408 D2X SLR (ptp) - 0409 D50 digital camera - 040a D50 (ptp) - 040c D2Hs - 040e DSC D70s (ptp) - 0413 D40 (mass storage mode) - 4000 Coolscan LS 40 ED - 4001 LS 50 ED/Coolscan V ED - 4002 Super Coolscan LS-5000 ED -04b1 Pan International -04b3 IBM Corp. - 3003 Rapid Access III Keyboard - 3004 Media Access Pro Keyboard - 300a Rapid Access IIIe Keyboard - 3016 UltraNav Keyboard Hub - 3018 UltraNav Keyboard - 301b SK-8815 Keyboard - 301c Enhanced Performance Keyboard - 3020 Enhanced Performance Keyboard - 3100 NetVista Mouse - 3103 ScrollPoint Pro Mouse - 3104 ScrollPoint Wireless Mouse - 3105 ScrollPoint Optical (HID) - 3107 ThinkPad 800dpi Optical Travel Mouse - 3108 800dpi Optical Mouse w/ Scroll Point - 3109 Optical ScrollPoint Pro Mouse - 310b Red Wheel Mouse - 4427 Portable CD ROM - 4482 Serial Converter - 4525 Double sided CRT - 4550 NVRAM (128 KB) - 4554 Cash Drawer - 4580 Hub w/ NVRAM - 4581 4800-2xx Hub w/ Cash Drawer - 4604 Keyboard w/ Card Reader - 4671 4820 LCD w/ MSR/KB -04b4 Cypress Semiconductor Corp. - 0000 Dacal DC-101 CD Library - 0001 Mouse - 0002 CY7C63x0x Thermometer - 0101 Keyboard/Hub - 0102 Keyboard with APM - 0130 MyIRC Remote Receiver - 0bad MetaGeek Wi-Spy - 1002 CY7C63001 R100 FM Radio - 1006 Human Interface Device - 4381 SCAPS USC-1 Scanner Controller - 4611 Storage Adapter FX2 (CY) - 4616 Flash Disk (TPP) - 5500 HID->COM RS232 Adapter - 6370 ViewMate Desktop Mouse CC2201 - 6560 CY7C65640 USB-2.0 "TetraHub" - 6830 CY7C68300A EZ-USB AT2 USB 2.0 to ATA/ATAPI - 6831 Storage Adapter ISD-300LP (CY) - 7417 Wireless PC Lock - 8613 CY7C68013 EZ-USB FX2 USB 2.0 Development Kit - 8614 DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) - cc04 Centor USB RACIA-ALVAR USB PORT - cc06 Centor-P RACIA-ALVAR USB PORT - d5d5 CY7C63x0x Zoltrix Z-Boxer GamePad - f000 CY30700 Licorice evaluation board -04b5 ROHM LSI Systems USA, LLC -04b6 Hint Corp. -04b7 Compal Electronics, Inc. -04b8 Seiko Epson Corp. - 0001 Stylus Color 740 / Photo 750 - 0002 ISD Smart Cable for Mac - 0003 ISD Smart Cable - 0004 Printer - 0005 Stylus D88+ - 0006 Printer - 0007 Printer - 0101 Perfection 636 - 0102 GT-2200 - 0103 Perfection 610 - 0104 Perfection 1200 - 0105 StylusScan 2000 - 0106 Stylus Scan 2500 - 0107 Expression 1600U - 0109 Expression 1640 XL - 010a Perfection 1640SU - 010b Perfection 1240 - 010c Perfection 640 - 010e Perfection 1680 - 010f Perfection 1250 - 0110 Perfection 1650 - 0112 Perfection 2450 - 0114 Perfection 660 - 0116 Perfection 3170 (GT-9400) - 0118 Perfection 4180 (GF-F600) - 0119 Perfection 4490 Photo - 011a 1000 ICS - 011b Perfection 2400 Photo - 011c Perfection 3200 - 011d Perfection 1260 Photo - 011e Perfection 1660 Photo - 011f Perfection 1670 - 0120 Perfection 1270 scanner - 0121 Perfection 2480 Photo - 0122 Perfection 3590 scanner - 0126 GT-15000 (ES-7000) - 0128 Perfection 4870 (GT-X700) - 0129 Expression 10000XL (ES-10000G) - 012a Perfection 4990 Photo scanner - 012b GT-2500 (ES-H300) - 012c Perfection V350 (GT-F700) - 012d Perfection V10/V100 (GT-S600/F650) - 012f Perfection V350 (GT-F700) - 0202 Receipt Printer M129C - 0401 CP 800 Digital Camera - 0402 PhotoPC 850z - 0403 PhotoPC 3000z - 0509 JVC PIX-MC10 - 0601 Stylus Photo 875DC Card Reader - 0602 Stylus Photo 895 Card Reader - 0801 Stylus CX5200/CX5400/CX6600 - 0802 Stylus CX3200 - 0803 Printer (Composite Device) - 0804 Storage Device - 0805 Stylus CX6400 - 0806 Stylus Photo RX600/610 - 0807 Stylus Photo RX500/510 - 0808 Stylus CX5200 - 0809 Storage Device - 080a Storage Device - 080c ME100 - 080d Stylus CX4500/4600 - 080e CX-3500/3600/3650 MFP - 080f Stylus Photo RX425 scanner - 0810 Stylus Photo RX700 (PM-A900) - 0811 Stylus Photo RX620 all-in-one - 0812 MFP Composite Device - 0813 Stylus CX6500/6600 - 0814 (PM-A700) - 0815 AcuLaser CX11 (LP-A500) - 0816 Printer (Composite Device) - 0817 (LP-M5500) - 0818 Stylus CX3700/CX3800/DX3800 - 0819 Stylus CX4700/CX4800/DX4800 (PX-A750) - 081a Stylus Photo RX520/RX530 (PM-A750) - 081b MFP Composite Device - 081c Stylus Photo RX640/RX650 (PM-A890) - 081d (PM-A950) - 081e MFP Composite Device - 081f Stylus CX7700/7800 - 0820 CX4200 MP scanner - 0821 MFP Composite Device - 0822 Storage Device - 0823 MFP Composite Device - 0824 Storage Device - 0825 MFP Composite Device - 0826 Storage Device - 0827 Stylus Photo RX560/580/590 (PM-A820) - 0828 (PM-A970) - 0829 (PM-T990) - 082a (PM-A920) - 082b Stylus DX5050 - 082c Storage Device - 082d Storage Device - 082e 0x082e DX-60x0 MFP scanner - 082f Stylus DX4050 - 0830 Stylus CX2800/CX2900/ME200 - 0831 MFP Composite Device - 0832 MFP Composite Device - 0833 (LP-M5600) - 0834 MFP Composite Device - 0835 AcuLaser CX21 - 0836 MFP Composite Device - 0837 MFP Composite Device - 0838 CX7300/CX7400/DX7400 - 0839 CX8300/CX8400/DX8400 - 083a CX9300F/CX9400Fax/DX9400F - 083b MFP Composite Device - 083c MFP Composite Device - 083d MFP Composite Device - 083e MFP Composite Device - 083f Stylus DX4450 -04b9 Rainbow Technologies, Inc. - 0300 SafeNet USB SuperPro/UltraPro - 1000 iKey 1000 Token - 1001 iKey 1200 Token - 1002 iKey Token - 1003 iKey Token - 1004 iKey Token - 1005 iKey Token - 1006 iKey Token - 1200 iKey 2000 Token - 1201 iKey Token - 1202 iKey 2032 Token - 1203 iKey Token - 1204 iKey Token - 1205 iKey Token - 1206 iKey Token - 1300 iKey 3000 Token - 1301 iKey 3000 - 1302 iKey Token - 1303 iKey Token - 1304 iKey Token - 1305 iKey Token - 1306 iKey Token -04ba Toucan Systems, Ltd -04bb I-O Data Device, Inc. - 0101 USB2-IDE/ATAPI Bridge Adapter - 0201 USB2-IDE/ATAPI Bridge Adapter - 0204 DVD Multi-plus unit iU-CD2 - 0206 DVD Multi-plus unit DVR-UEH8 - 0301 Storage Device - 0314 USB-SSMRW SD-card - 0319 USB2-IDE/ATAPI Bridge Adapter - 031a USB2-IDE/ATAPI Bridge Adapter - 031b USB2-IDE/ATAPI Bridge Adapter - 031e USB-SDRW SD-card - 0502 Nogatech Live! (BT) - 0901 USB ETT - 0904 ET/TX Ethernet [pegasus] - 0913 ET/TX-S Ethernet [pegasus2] - 0919 USB WN-B11 - 0922 IOData AirPort WN-B11/USBS 802.11b - 0930 ETG-US2 - 0937 WN-WAG/USL Wireless LAN Adapter - 0938 WN-G54/USL Wireless LAN Adapter - 0a03 Serial USB-RSAQ1 - 0a07 USB2-iCN Adapter - 0a08 USB2-iCN Adapter - 0c01 FM-10 Pro Disk -04bd Toshiba Electronics Taiwan Corp. -04be Telia Research AB -04bf TDK Corp. - 0100 MediaReader CF - 0115 USB-PDC Adapter UPA9664 - 0116 USB-cdmaOne Adapter UCA1464 - 0117 USB-PHS Adapter UHA6400 - 0118 USB-PHS Adapter UPA6400 - 0135 MediaReader Dual - 0202 73S1121F Smart Card Reader- - 0309 Bluetooth USB dongle - 030a IBM Bluetooth Ultraport Module - 030b Bluetooth Device - 030c Ultraport Bluetooth Device - 0310 Integrated Bluetooth - 0311 Integrated Bluetooth Device - 0317 Bluetooth UltraPort Module from IBM - 0318 IBM Integrated Bluetooth - 0319 Bluetooth Adapter - 0320 Bluetooth Adapter - 0321 Bluetooth Device - 0a28 INDI AV-IN Device -04c1 U.S. Robotics (3Com) - 0020 56K Voice Pro - 0022 56K Voice Pro - 007e ISDN TA - 0082 OfficeConnect Analog Modem - 008f Pro ISDN TA - 0097 OfficeConnect Analog - 009d HomeConnect WebCam [vicam] - 00a9 ISDN Pro TA-U - 00b9 HomeConnect IDSL Modem - 3021 56k Voice FaxModem Pro -04c2 Methode Electronics Far East PTE, Ltd -04c3 Maxi Switch, Inc. - 1102 Mouse - 2102 Mouse -04c4 Lockheed Martin Energy Research -04c5 Fujitsu, Ltd - 1029 fi-4010c Scanner - 1033 fi-4110CU - 1041 fi-4120c Scanner - 1042 fi-4220c Scanner - 105b AH-F401U Air H device - 1096 fi-5110EOX - 1097 fi-5110C - 10ae fi-4120C2 - 10af fi-4220C2 - 10e0 fi-5120c Scanner - 10e1 fi-5220C - 10e7 fi-5900C - 10fe S500 -04c6 Toshiba America Electronic Components -04c7 Micro Macro Technologies -04c8 Konica Corp. - 0720 Digital Color Camera - 0721 e-miniD Camera - 0722 e-mini - 0723 KD-200Z Camera - 0726 KD-310Z Camera - 0728 Revio C2 Mass Storage Device - 0729 Revio C2 Digital Camera - 072c Revio KD20M - 072d Revio KD410Z -04ca Lite-On Technology Corp. - 1766 HID Monitor Controls - 9304 Hub -04cb Fuji Photo Film Co., Ltd - 0100 FinePix 30i/40i/50i, A101/201, 1300/2200, 1400/2400/2600/2800/4500/4700/4800/4900/6800/6900 Zoom - 0103 FinePix NX-500/NX-700 printer - 0104 FinePix A101, 2600/2800/4800/6800 Zoom (PC CAM) - 0108 FinePix F601 Zoom (DSC) - 0109 FinePix F601 Zoom (PC CAM) - 010a FinePix S602 (Pro) Zoom (DSC) - 010b FinePix S602 (Pro) Zoom (PC CAM) - 010d FinePix Digital Camera 020531 - 010e FinePix F402 Zoom (DSC) - 010f FinePix F402 Zoom (PC CAM) - 0110 FinePix M603 Zoom (DSC) - 0111 FinePix M603 Zoom (PC CAM) - 0112 FinePix A202, A200 Zoom (DSC) - 0113 FinePix A202, A200 Zoom (PC CAM) - 0114 FinePix F401 Zoom (DSC) - 0115 FinePix F401 Zoom (PC CAM) - 0116 FinePix A203 Zoom (DSC) - 0117 FinePix A203 Zoom (PC CAM) - 0118 FinePix A303 Zoom (DSC) - 0119 FinePix A303 Zoom (PC CAM) - 011a FinePix S304/3800 Zoom (DSC) - 011b FinePix S304/3800 Zoom (PC CAM) - 011c FinePix A204/2650 Zoom (DSC) - 011d FinePix A204/2650 Zoom (PC CAM) - 0120 FinePix F700 Zoom (DSC) - 0121 FinePix F700 Zoom (PC CAM) - 0122 FinePix F410 Zoom (DSC) - 0123 FinePix F410 Zoom (PC CAM) - 0124 FinePix A310 Zoom (DSC) - 0125 FinePix A310 Zoom (PC CAM) - 0126 FinePix A210 Zoom (DSC) - 0127 FinePix A210 Zoom (PC CAM) - 0128 FinePix A205(S) Zoom (DSC) - 0129 FinePix A205(S) Zoom (PC CAM) - 012a FinePix F610 Zoom (DSC) - 012b FinePix Digital Camera 030513 - 012c FinePix S7000 Zoom (DSC) - 012d FinePix S7000 Zoom (PC CAM) - 012f FinePix Digital Camera 030731 - 0130 FinePix S5000 Zoom (DSC) - 0131 FinePix S5000 Zoom (PC CAM) - 013b FinePix Digital Camera 030722 - 013c FinePix S3000 Zoom (DSC) - 013d FinePix S3000 Zoom (PC CAM) - 013e FinePix F420 Zoom (DSC) - 013f FinePix F420 Zoom (PC CAM) - 0142 FinePix S7000 Zoom (PTP) - 0148 FinePix A330 Zoom (DSC) - 0149 FinePix A330 Zoom (UVC) - 014a FinePix A330 Zoom (PTP) - 014b FinePix A340 Zoom (DSC) - 0159 FinePix F710 Zoom (DSC) - 0165 FinePix S3500 Zoom (DSC) - 0168 FinePix E500 Zoom (DSC) - 0169 FinePix E500 Zoom (UVC) - 016b FinePix E510 Zoom (DSC) - 016c FinePix E510 Zoom (PC CAM) - 016e FinePix S5500 Zoom (DSC) - 016f FinePix S5500 Zoom (UVC) - 0171 FinePix E550 Zoom (DSC) - 0172 FinePix E550 Zoom (PTP) - 0177 FinePix F10 (DSC) - 0179 Finepix F10 (PTP) - 0186 FinePix S5200/S5600 Zoom (DSC) - 0188 FinePix S5200/S5600 Zoom (PTP) - 018e FinePix S9500 Zoom (DSC) - 018f FinePix S9500 Zoom (PTP) - 0192 FinePix E900 Zoom (DSC) - 0193 FinePix E900 Zoom (PTP) - 019b FinePix F30 (PTP) - 01bf FinePix F6000fd/S6500fd Zoom (PTP) - 01c0 FinePix F20 (PTP) - 01c1 FinePix F31fd (PTP) - 01c4 FinePix S5700 Zoom (PTP) - 01c5 FinePix F40fd (PTP) - 01c6 FinePix A820 Zoom (PTP) - 01d2 FinePix A800 Zoom (PTP) - 01d5 FinePix F47 (PTP) -04cc Philips Semiconductors - 1122 Hub - 1521 USB 2.0 Hub - 8116 Camera -04cd Tatung Co. Of America -04ce ScanLogic Corp. - 0002 SL11R-IDE IDE Bridge - 0100 USB2PRN Printer Class - 0300 Phantom 336CX - C3 scanner - 04ce SL11DEMO, VID: 0x4ce, PID: 0x4ce - 07d1 SL11R, VID: 0x4ce, PID: 0x07D1 -04cf Myson Century, Inc. - 0800 MTP800 Mass Storage Device - 8810 CS8810 Mass Storage Device - 8811 CS8811 Mass Storage Device - 8813 CS8813 Mass Storage Device - 8818 USB2.0 to ATAPI Bridge Controller -04d0 Digi International -04d1 ITT Canon -04d2 Altec Lansing Technologies - 0070 ADA70 Speakers - 0305 Non-Compliant Audio Device - 0311 ADA-310 Speakers - 2060 Claritel-i750 - vp - ff05 ADA-305 Speakers - ff47 Lansing HID Audio Controls - ff49 Lansing HID Audio Controls -04d3 VidUS, Inc. -04d4 LSI Logic, Inc. -04d5 Forte Technologies, Inc. -04d6 Mentor Graphics -04d7 Oki Semiconductor - 1be4 Bluetooth Device -04d8 Microchip Technology, Inc. - 0002 USB-LCD 2x20 - 8000 In-Circuit Debugger - 8001 ICD2 in-circuit debugger -04d9 Holtek Semiconductor, Inc. - 1203 MC Industries Keyboard -04da Panasonic (Matsushita) - 0901 LS-120 Camera - 0b01 CD-R/RW Drive - 0b03 SuperDisk 240MB - 0d01 CD-R Drive KXL-840AN - 0d09 CD-R Drive KXL-RW32AN - 0d0a CD-R Drive KXL-CB20AN - 0d0d CDRCB03 - 0d0e DVD-ROM & CD-R/RW - 0f40 Printer - 1500 MFSUSB Driver - 1b00 MultiMediaCard - 2121 EB-VS6 - 2317 DVC USB-SERIAL Driver for WinXP - 2319 NV-GS15 (webcam mode) - 231d DVC Web Camera Device - 231e DVC DV Stream Device - 2372 Lumix DMC-FZ10 Camera - 2374 DMC-FZ20 -04db Hypertec Pty, Ltd -04dc Huan Hsin Holdings, Ltd -04dd Sharp Corp. - 13a6 MFC2000 - 6006 AL-1216 - 6007 AL-1045 - 6008 AL-1255 - 6009 AL-1530CS - 600a AL-1540CS - 600b AL-1456 - 600c AL-1555 - 600d AL-1225 - 600e AL-1551CS - 600f AR-122E - 6010 AR-152E - 6011 AR-157E - 6012 SN-1045 - 6013 SN-1255 - 6014 SN-1456 - 6015 SN-1555 - 6016 AR-153E - 6017 AR-122E N - 6018 AR-153E N - 6019 AR-152E N - 601a AR-157E N - 601b AL-1217 - 601c AL-1226 - 601d AR-123E - 7002 DVC Ver.1.0 - 7004 VE-CG40U Digital Still Camera - 7005 VE-CG30 Digital Still Camera - 7007 VL-Z7S Digital Camcorder - 8004 Zaurus SL-5000D/SL-5500 PDA - 8005 Zaurus A-300 - 8006 Zaurus SL-B500/SL-5600 PDA - 8007 Zaurus C-700 PDA - 9014 IM-DR80 Portable NetMD Player - 9031 Zaurus C-750/C-760/C-860/SL-C3000 PDA - 9032 Zaurus SL-6000 - 903a GSM GPRS - 9050 Zaurus C-860 PDA - 9056 Viewcam Z - 9073 AM-900 - 9074 GSM GPRS - 90a9 Sharp Composite - 90d0 USB-to-Serial Comm. Port - 90f2 Sharp 3G GSM USB Control - 9120 WS004SH - 9122 WS007SH - 9123 W-ZERO3 ES Smartphone - 91a3 922SH Internet Machine -04de MindShare, Inc. -04df Interlink Electronics -04e1 Iiyama North America, Inc. - 0201 Monitor Hub -04e2 Exar Corp. -04e3 Zilog, Inc. -04e4 ACC Microelectronics -04e5 Promise Technology -04e6 SCM Microsystems, Inc. - 0001 E-USB ATA Bridge - 0002 eUSCSI SCSI Bridge - 0003 eUSB SmartMedia Card Reader - 0005 eUSB SmartMedia/CompactFlash Card Reader - 0006 eUSB SmartMedia Card Reader - 0007 Hifd - 0009 eUSB ATA/ATAPI Adapter - 000a eUSB CompactFlash Adapter - 000b eUSCSI Bridge - 000c eUSCSI Bridge - 000d Dazzle MS - 0012 Dazzle SD/MMC - 0101 eUSB ATA Bridge - 0311 Dazzle DM-CF - 0312 Dazzle DM-SD/MMC - 0313 Dazzle SM - 0314 Dazzle MS - 0322 e-Film Reader-5 - 0325 eUSB ORCA Quad Reader - 0327 Digital Media Reader - 03fe DMHS2 DFU Adapter - 0406 eUSB SmartDM Reader - 04e6 eUSB DFU Adapter - 04e7 STCII DFU Adapter - 04e8 eUSBDM DFU Adapter - 04e9 DM-E DFU Adapter - 0500 Veridicom 5thSense Fingerprint Sensor and eUSB SmartCard - 0701 DCS200 Loader Device - 0702 DVD Creation Station 200 - 0703 DVC100 Loader Device - 0704 Digital Video Creator 100 - 1001 SCR300 Smart Card Reader - 1010 USBAT-2 CompactFlash Card Reader - 1014 e-Film Reader-3 - 1020 USBAT ATA/ATAPI Adapter - 2007 RSA SecurID ComboReader - 2009 Citibank Smart Card Reader - 200a Reflex v.2 Smart Card Reader - 200d STR391 Reader - 5111 SCR331-DI SmartCard Reader - 5113 SCR333 SmartCard Reader - 5114 SCR331-DI SmartCard Reader - 5115 SCR335 SmartCard Reader - 5116 SCR331-LC1 SmartCard Reader - 5117 SCR3320 - Smart Card Reader - 5118 Expresscard SIM Card Reader - 5119 SCR3340 - ExpressCard54 Smart Card Reader - 511b SmartCard Reader - 511d SCR3311 Smart Card Reader - 5120 SCR331-DI SmartCard Reader - 5121 SDI010 Smart Card Reader - 5151 SCR338 Keyboard Smart Card Reader - 5410 SCR35xx Smart Card Reader - e000 SCRx31 Reader - e001 SCR331 SmartCard Reader - e003 SPR532 PinPad SmartCard Reader -04e7 Elo TouchSystems - 0001 TouchScreen - 0002 Touchmonitor Interface 2600 Rev 2 - 0004 4000U CarrollTouch® Touchmonitor Interface - 0007 2500U IntelliTouch® Touchmonitor Interface - 0008 3000U AccuTouch® Touchmonitor Interface - 0009 4000U CarrollTouch® Touchmonitor Interface - 0020 Touchscreen Interface (2700) - 0021 Touchmonitor Interface - 0030 4500U CarrollTouch® Touchmonitor Interface - 0032 Touchmonitor Interface - 0033 Touchmonitor Interface - 0041 5010 Surface Capacitive Touchmonitor Interface - 0042 Touchmonitor Interface - 0050 2216 AccuTouch® Touchmonitor Interface - 0071 Touchmonitor Interface - 0072 Touchmonitor Interface - 0081 Touchmonitor Interface - 0082 Touchmonitor Interface - 00ff Touchmonitor Interface -04e8 Samsung Electronics Co., Ltd - 0110 Connect3D Flash Drive - 0111 Connect3D Flash Drive - 1003 MP3 Player and Recorder - 1006 SDC-200Z - 3004 ML-4600 - 3005 Docuprint P1210 - 3008 ML-6060 laser printer - 300c ML-1210 Printer - 300e Laser Printer - 3104 ML-3550N - 3226 Laser Printer - 3228 Laser Printer - 322a Laser Printer - 322c Laser Printer - 3230 ML-1440 - 3232 Laser Printer - 3236 ML-1450 - 3238 ML-1430 - 323a ML-1710 Printer - 323b Phaser 3130 - 323c Laser Printer - 323d Phaser 3120 - 323e Laser Printer - 3240 Laser Printer - 3242 Laser Printer - 3248 Color Laser Printer - 324a Laser Printer - 324c ML-1740 Printer - 324d Phaser 3121 - 325f Phaser 3425 Laser Printer - 3260 CLP-510 Color Laser Printer - 3268 ML-1610 Mono Laser Printer - 326c ML-2010P Mono Laser Printer - 3409 SCX-4216F Scanner - 340c SCX-5x15 Series - 340d SCX-6x20 Series - 340e MFP 560 Series - 340f Printing Support - 3412 SCX-4x20 Series - 3413 SCX-4100 Scanner - 3415 Composite Device - 3419 Composite Device - 341a Printing Support - 341b SCX-4200 Series - 341c Composite Device - 341d Composite Device - 341f Composite Device - 3420 Composite Device - 3605 InkJet Color Printer - 3606 InkJet Color Printer - 3609 InkJet Color Printer - 3902 InkJet Color Printer - 3903 Xerox WorkCentre XK50cx - 390f InkJet Color Printer - 3911 SCX-1020 Series - 5000 YP-MF Series - 5001 YP-100 - 5002 YP-30 - 5003 YP-700 - 5004 YP-30 - 5005 YP-300 - 5006 YP-750 - 500d MP3 Player - 5010 MP3 Player - 5011 YP-780 - 5013 YP-60 - 5015 yepp upgrade - 501b MP3 Player - 503b YP-U1 MP3 Player - 5050 YP-U2 MP3 Player - 507d YP-U3 MP3 Player - 508b YP-S5 MP3 Player - 5a00 YP-NEU - 5a01 YP-NDU - 5a03 Yepp MP3 Player - 5a04 YP-800 - 5a08 YP-90 - 5a0f MTP Device - 5b01 Memory Stick Reader/Writer - 5b02 Memory Stick Reader/Writer - 5b03 Memory Stick Reader/Writer - 5b04 Memory Stick Reader/Writer - 5b05 Memory Stick Reader/Writer - 5b11 SEW-2001u Card - 5f00 NEXiO Sync - 5f01 NEXiO Sync - 5f02 NEXiO Sync - 5f03 NEXiO Sync - 5f04 NEXiO Sync - 6601 Z100 Mobile Phone - 6611 MITs Sync - 6613 MITs Sync - 6615 MITs Sync - 6617 MITs Sync - 6619 MITs Sync - 661b MITs Sync - 661e Handheld - 6620 Handheld - 6622 Handheld - 6624 Handheld - 662e MITs Sync - 6630 MITs Sync - 6632 MITs Sync - 663f SGH-E720/SGH-E840 - 6640 Usb Modem Enumerator - 7011 SEW-2003U Card - 7021 Bluetooth Device - 7061 eHome Infrared Receiver - 7081 Human Interface Device - 8001 Handheld - e020 SERI E02 SCOM 6200 UMTS Phone - e021 SERI E02 SCOM 6200 Virtual UARTs - e022 SERI E02 SCOM 6200 Flash Load Disk - ff30 SG_iMON -04e9 PC-Tel, Inc. -04ea Brooktree Corp. -04eb Northstar Systems, Inc. -04ec Tokyo Electron Device, Ltd -04ed Annabooks -04ef Pacific Electronic International, Inc. -04f0 Daewoo Electronics Co., Ltd -04f1 Victor Company of Japan, Ltd - 0001 GC-QX3 Digital Still Camera - 0004 GR-DVL815U Digital Video Camera - 0006 DV Camera Storage - 0008 GZ-MG30AA/MC500E Digital Video Camera - 0009 GR-DX25EK Digital Video Camera - 000a GR-D72 Digital Video Camera - 3008 MP-PRX1 Ethernet -04f2 Chicony Electronics Co., Ltd - 0001 KU-8933 Keyboard - 0002 NT68P81 Keyboard - 0110 KU-2971 Keyboard - 0111 KU-9908 Keyboard - 0112 KU-8933 Keyboard with PS/2 Mouse port - 0116 KU-2971 German Keyboard - 0403 KU-0420 keyboard - a001 E-Video DC-100 Camera - a120 ORITE CCD Webcam(PC370R) - a121 ORITE CCD Webcam(PC370R) - a122 ORITE CCD Webcam(PC370R) - a123 ORITE CCD Webcam(PC370R) - a124 ORITE CCD Webcam(PC370R) - a133 Gateway Webcam - a204 DSC WIA Device (1300) - a208 DSC WIA Device (2320) - a209 Labtec DC-2320 - a20a DSC WIA Device (3310) - a20c DSC WIA Device (3320) - a210 Audio Device - b009 Integrated Camera - b010 Integrated Camera - b012 1.3 MPixel UVC webcam - b018 Video Device - b022 Camera - b025 Camera - b027 Gateway Webcam - b028 VGA UVC WebCam -04f3 Elan Microelectronics Corp. - 0210 AM-400 Hama Optical Mouse -04f4 Harting Elektronik, Inc. -04f5 Fujitsu-ICL Systems, Inc. -04f6 Norand Corp. -04f7 Newnex Technology Corp. -04f8 FuturePlus Systems -04f9 Brother Industries, Ltd - 0002 HL-1050 Laser Printer - 0005 Printer - 0006 HL-1240 Laser Printer - 0007 HL-1250 Laser Printer - 0008 HL-1270 Laser Printer - 0009 Printer - 000a P2500 Series - 000b Printer - 000c Printer - 000d HL-1440 Laser Printer - 000e HL-1450 series - 000f HL-1470N series - 0010 Printer - 0011 Printer - 0012 Printer - 0013 Printer - 0014 Printer - 0015 Printer - 0016 Printer - 0017 Printer - 0018 Printer - 001c Printer - 001e Printer - 0020 HL-5130 series - 0021 HL-5140 series - 0022 HL-5150D series - 0023 HL-5170DN series - 0024 Printer - 0025 Printer - 0027 HL-2030 Laser Printer - 0028 Printer - 0029 Printer - 002a Printer - 002b Printer - 002c Printer - 002d Printer - 0100 MFC8600/9650 Series - 0101 MFC9600/9870 Series - 0102 MFC9750/1200 Series - 0104 MFC-8300J - 0105 MFC-9600J - 0106 MFC-7300C - 0107 MFC-7400C - 0108 MFC-9200C - 0109 MFC-830 - 010a MFC-840 - 010b MFC-860 - 010c MFC-7400J - 010d MFC-9200J - 010e MFC3100C Scanner - 010f MFC 5100C - 0110 MFC4800 Scanner - 0111 MFC 6800 - 0112 DCP1000 Port(FaxModem) - 0113 MFC-8500 - 0114 MFC9700 Port(FaxModem) - 0115 MFC9800 Scanner - 0116 DCP1400 Scanner - 0119 MFC-9660 - 011b MFC-9880 - 011c MFC-9760 - 011d MFC-9070 - 011e MFC-9180 - 011f MFC-9160 - 0120 MFC580 Port(FaxModem) - 0121 MFC-590 - 0122 MFC-5100J - 0129 Imagistics 2500 (MFC-8640D clone) - 012f FAX-4750e - 0132 MFC-5200C RemovableDisk - 0135 MFC-100 Scanner - 0136 MFC-150CL Scanner - 013c MFC-890 Port - 013d MFC-5200J Printer - 013e MFC-4420C RemovableDisk - 013f MFC-4820C RemovableDisk - 0140 DCP-8020 - 0141 DCP-8025D - 0142 MFC-8420 - 0143 MFC-8820D - 0144 DCP-4020C RemovableDisk - 0146 MFC-3220C - 0147 FAX-1820C Printer - 0148 MFC-3320CN Printer - 0149 FAX-1920CN Printer - 014a MFC-3420C - 014b MFC-3820CN - 014d FAX-1815C Printer - 014e MFC-8820J - 0150 MFC-8220 Port(FaxModem) - 0151 MFC-8210J - 0157 MFC-3420J Printer - 0158 MFC-3820JN Port(FaxModem) - 015d MFC Composite Device - 015e DCP-8045D - 015f MFC-8440 - 0160 MFC-8840D - 0161 MFC-210C - 0162 MFC-420CN Remote Setup Port - 0163 MFC-410CN RemovableDisk - 0165 MFC-620CN - 0166 MFC-610CLN RemovableDisk - 0168 MFC-620CLN - 0169 DCP-110C RemovableDisk - 016b DCP-310CN RemovableDisk - 016c FAX-2440C Printer - 016d MFC-5440CN - 016e MFC-5840CN Remote Setup Port - 0170 FAX-1840C Printer - 0171 FAX-1835C Printer - 0172 FAX-1940CN Printer - 0173 MFC-3240C Remote Setup Port - 0174 MFC-3340CN RemovableDisk - 017b Imagistics sx2100 - 0180 MFC-7420 - 0181 MFC-7820N Port(FaxModem) - 0182 Composite Device - 0183 DCP-7020 - 0184 DCP-7025 Printer - 0185 MFC-7220 Printer - 0186 Composite Device - 0187 FAX-2820 Printer - 0188 FAX-2920 Printer - 018a MFC-9420CN - 018c DCP-115C - 018d DCP-116C - 018e DCP-117C - 018f DCP-118C - 0190 DCP-120C - 0191 DCP-315CN - 0192 DCP-340CW - 0193 MFC-215C - 0194 MFC-425CN - 0195 MFC-820CW Remote Setup Port - 0196 MFC-820CN Remote Setup Port - 0197 MFC-640CW - 019a MFC-840CLN Remote Setup Port - 01a2 MFC-8640D - 01a3 Composite Device - 01a4 DCP-8065DN Printer - 01a5 MFC-8460N Port(FaxModem) - 01a6 MFC-8860DN Port(FaxModem) - 01a7 MFC-8870DW Printer - 01a8 DCP-130C - 01a9 DCP-330C - 01aa DCP-540CN - 01ab MFC-240C - 01ae DCP-750CW RemovableDisk - 01af MFC-440CN - 01b0 MFC-660CN - 01b1 MFC-665CW Remote Setup Port - 01b2 MFC-845CW Remote Setup Port - 01b4 MFC-460CN Remote Setup Port - 01b5 MFC-630CD - 01b6 MFC-850CDN - 01b7 MFC-5460CN Remote Setup Port - 01b8 MFC-5860CN - 01ba MFC-3360C - 01bd MFC-8660DN - 01be DCP-750CN RemovableDisk - 01bf MFC-860CDN Remote Setup Port - 01c0 DCP-128C - 01c1 DCP-129C - 01c2 DCP-131C - 01c3 DCP-329C - 01c4 DCP-331C - 01c5 MFC-239C - 01ca MFC-9440CN Remote Setup Port - 01ce DCP-135C - 01cf DCP-150C - 01d0 DCP-350C - 01d1 DCP-560CN - 01d4 MFC-230C - 01d5 MFC-235C - 01d6 MFC-260C - 01df DCP-155C - 01e0 MFC-265C - 01e1 DCP-153C - 01e2 DCP-157C - 01e3 DCP-353C - 01e4 DCP-357C - 1000 Printer - 1002 Printer - 2002 PTUSB Printing - 2004 PT-2300/2310 p-Touch Laber Printer - 2015 QL-500 P-touch label printer - 2100 Card Reader Writer -04fa Dallas Semiconductor - 2490 DS1490F 2-in-1 Fob, 1-Wire adapter - 4201 DS4201 Audio DAC -04fb Biostar Microtech International Corp. -04fc Sunplus Technology Co., Ltd - 0003 CM1092 Optical Scroller Mouse - 0013 ViewMate Desktop Mouse CC2201 - 0015 ViewMate Desktop Mouse CC2201 - 0232 Fingerprint - 0561 Flexcam 100 - 1533 Mass Storage - 504a SPCA504a Digital Camera - 504b Aiptek, 1.3 mega PockerCam - 5330 Digitrex 2110 - 5331 Vivitar Vivicam 10 - 5720 Card Reader Driver - 7333 Finet Technology Palmpix DC-85 - 757a Aiptek, MP315 MP3 Player - ffff PureDigital Ritz Disposable -04fd Soliton Systems, K.K. - 0003 Smart Card Reader II -04fe PFU, Ltd -04ff E-CMOS Corp. -0500 Siam United Hi-Tech - 0001 DART Keyboard Mouse - 0002 DART-2 Keyboard -0501 Fujikura DDK, Ltd -0502 Acer, Inc. - 0001 Handheld - 0736 Handheld - 15b1 PDA n311 - 1631 c10 Series - 1632 c20 Series - 16e1 n10 Handheld Sync - 16e2 n20 Pocket PC Sync - 16e3 n30 Handheld Sync - d001 Divio NW801/DVC-V6+ Digital Camera -0503 Hitachi America, Ltd -0504 Hayes Microcomputer Products -0506 3Com Corp. - 009d HomeConnect Camera - 00a0 3CREB96 Bluetooth Adapter - 00a1 Bluetooth Device - 00a2 Bluetooth Device - 00df 3Com Home Connect lite - 0100 HomeConnect ADSL Modem Driver - 03e8 3C19250 Ethernet [klsi] - 0a01 3CRSHEW696 Wireless Adapter - 0a11 3CRWE254G72 802.11g Adapter - 11f8 HomeConnect 3C460 - 2922 HomeConnect Cable Modem External with - 3021 U.S.Robotics 56000 Voice FaxModem Pro - 4601 3C460B 10/100 Ethernet Adapter - f002 3CP4218 ADSL Modem (pre-init) - f003 3CP4218 ADSL Modem - f100 3CP4218 ADSL Modem (pre-init) -0507 Hosiden Corp. - 0011 Konami ParaParaParadise Controller -0508 Clarion Co., Ltd -0509 Aztech Systems, Ltd - 0801 ADSL Modem - 0802 ADSL Modem (RFC1483) - 0806 DSL Modem - 080f Binatone ADSL500 Modem Network Interface - 0812 Pirelli ADSL Modem Network Interface -050a Cinch Connectors -050b Cable System International -050c InnoMedia, Inc. -050d Belkin Components - 0004 Direct Connect - 0012 F8T012 Bluetooth Adapter - 0013 F8T013 Bluetooth Adapter - 0050 F5D6050 802.11b Wireless Adapter - 0081 F8T001v2 Bluetooth - 0083 Bluetooth Device - 0084 F8T003v2 Bluetooth - 0102 Flip KVM - 0103 F5U103 Serial Adapter [etek] - 0106 VideoBus II Adapter, Video - 0108 F1DE108B KVM - 0109 F5U109/F5U409 PDA Adapter - 0115 SCSI Adapter - 0119 F5U120-PC Dual PS/2 Ports - 0121 F5D5050 100Mbps Ethernet - 0122 Ethernet Adapter - 0131 Bluetooth Device with trace filter - 0201 Peripheral Switch - 0208 USBView II Video Adapter [nt1004] - 0210 F5U228 Hi-Speed USB 2.0 DVD Creator - 0211 F5U211 USB 2.0 15-in-1 Media Reader & Writer - 0224 F5U224 USB 2.0 4-Port Hub - 0234 F5U234 USB 2.0 4-Port Hub - 0237 F5U237 USB 2.0 7-Port Hub - 0240 F5U240 USB 2.0 CF Card Reader - 0257 F5U257 Serial - 0409 F5U409 Serial - 0551 F6C550-AVR UPS - 0802 Nostromo n40 Gamepad - 0803 Nostromo 1745 GamePad - 0805 Nostromo N50 GamePad - 0815 Nostromo n52 HID SpeedPad Mouse Wheel - 0826 ErgoFit Wireless Optical Mouse (HID) - 0980 HID UPS Battery - 1202 F5U120-PC Parallel Printer Port - 1203 F5U120-PC Serial Port - 258a F5U258 Host to Host cable - 3101 F1DF102U/F1DG102U Flip Hub - 3201 F1DF102U/F1DG102U Flip KVM - 4050 ZD1211B - 5055 F5D5055 - 6051 11Mbps Wireless Network Adapter - 7050 F5D7050 ver 1000 WiFi - 7051 F5D7051 54g USB Network Adapter - 705a F5D7050A Wireless Adapter - 705b Wireless G Adapter - 705c F5D7050 v4000 Wireless Adapter - 905b F5D9050 ver 3 Wireless Adapter - 905c Wireless G Plus MIMO Network Adapter -050e Neon Technology, Inc. -050f KC Technology, Inc. - 0001 Hub - 0003 KC82C160S Hub - 0180 KC-180 IrDA Dongle - 0190 KC2190 USB Host-to-Host cable -0510 Sejin Electron, Inc. - 0001 Keyboard - 1000 Keyboard with PS/2 Mouse Port - e001 Mouse -0511 N'Able (DataBook) Technologies, Inc. -0512 Hualon Microelectronics Corp. -0513 digital-X, Inc. -0514 FCI Electronics -0515 ACTC -0516 Longwell Electronics -0517 Butterfly Communications -0518 EzKEY Corp. - 0001 USB to PS2 Adaptor v1.09 - 0002 EZ-9900C Keyboard -0519 Star Micronics Co., Ltd - c002 Xlive Bluetooth XBM-100S MP3 Player -051a WYSE Technology - a005 Smart Display Version 9973 -051b Silicon Graphics -051c Shuttle, Inc. - c001 eHome Infrared Receiver - c002 eHome Infrared Receiver -051d American Power Conversion - 0001 UPS - 0002 Uninterruptible Power Supply - 0003 UPS -051e Scientific Atlanta, Inc. -051f IO Systems (Elite Electronics), Inc. -0520 Taiwan Semiconductor Manufacturing Co. -0521 Airborn Connectors -0522 Advanced Connectek, Inc. -0523 ATEN GmbH -0524 Sola Electronics -0525 Netchip Technology, Inc. - 100d RFMD Bluetooth Device - 1080 NET1080 USB-USB Bridge - a140 USB Clik! 40 - a141 (OME) PocketZip 40 MP3 Player Driver - a220 GVC Bluetooth Wireless Adapter - a4a0 Linux-USB "Gadget Zero" - a4a1 Linux-USB Ethernet Gadget - a4a2 Linux-USB Ethernet/RNDIS Gadget - a4a3 Linux-USB user-mode isochronous source/sink - a4a4 Linux-USB user-mode bulk source/sink - a4a5 Linux-USB File Storage Gadget - a4a6 Linux-USB Serial Gadget - a4a7 Linux-USB Serial Gadget (CDC ACM mode) - a4a8 Linux-USB Printer Gadget -0526 Temic MHS S.A. -0527 ALTRA -0528 ATI Technologies, Inc. - 7561 TV Wonder - 7562 TV Wonder, Edition (FN5) - 7563 TV Wonder, Edition (FI) - 7564 TV Wonder, Edition (FQ) - 7565 TV Wonder, Edition (NTSC+) - 7566 TV Wonder, Edition (FN5) - 7567 TV Wonder, Edition (FI) - 7568 TV Wonder, Edition (FQ) - 7569 Live! Pro (A) - 756a Live! Pro Audio (O) -0529 Aladdin Knowledge Systems - 0001 HASP v0.06 - 030b eToken R1 v3.1.3.x - 0313 eToken R1 v3.2.3.x - 031b eToken R1 v3.3.3.x - 0323 eToken R1 v3.4.3.x - 0412 eToken R2 v2.2.4.x - 041a eToken R2 v2.2.4.x - 0422 eToken R2 v2.4.4.x - 042a eToken R2 v2.5.4.x - 050c eToken Pro v4.1.5.x - 0514 eToken Pro v4.2.5.4 - 0600 eToken Pro 64k (4.2) -052a Crescent Heart Software -052b Tekom Technologies, Inc. - 0102 Ca508A HP1020 Camera v.1.3.1.6 - 0801 Yakumo MegaImage 37 - 1512 Yakumo MegaImage IV - 1513 Aosta CX100 WebCam - 1514 Aosta CX100 WebCam Storage - 1905 Yakumo MegaImage 47 - 1911 Yakumo MegaImage 47 SL - 2202 WDM Still Image Capture - 2203 Sound Vision Stream Driver - 3a06 DigiLife DDV-5120A - d001 P35U Camera Capture -052c Canon Information Systems, Inc. -052d Avid Electronics Corp. -052e Standard Microsystems Corp. -052f Unicore Software, Inc. -0530 American Microsystems, Inc. -0531 Wacom Technology Corp. -0532 Systech Corp. -0533 Alcatel Mobile Phones -0534 Motorola, Inc. -0535 LIH TZU Electric Co., Ltd -0536 Hand Held Products (Welch Allyn, Inc.) - 01a0 PDT -0537 Inventec Corp. -0538 Caldera International, Inc. (SCO) -0539 Shyh Shiun Terminals Co., Ltd -053a Preh Werke GmbH & Co. KG -053b Global Village Communication -053c Institut of Microelectronic & Mechatronic Systems -053d Silicon Architect -053e Mobility Electronics -053f Synopsys, Inc. -0540 UniAccess AB - 0101 Panache Surf ISDN TA -0541 Sirf Technology, Inc. -0543 ViewSonic Corp. - 00fe G773 Monitor Hub - 00ff P815 Monitor Hub - 0bf2 airpanel V150 Wireless Smart Display - 0bf3 airpanel V110 Wireless Smart Display - 0ed9 Color Pocket PC V35 - 0f01 airsync Wi-Fi Wireless Adapter - 1527 Color Pocket PC V36 - 1529 Color Pocket PC V37 - 152b Color Pocket PC V38 - 152e Pocket PC - 1921 Communicator Pocket PC - 1922 Smartphone - 1923 Pocket PC V30 - 1a11 Wireless 802.11g Adapter - 1e60 TA310 - ATSC/NTSC/PAL Driver(PCM4) - 4153 ViewSonic G773 Control (?) -0544 Cristie Electronics, Ltd -0545 Xirlink, Inc. - 7333 Trution Web Camera - 8002 IBM NetCamera - 8009 Veo PC Camera - 800c Veo StingRay - 800d Veo PC Camera - 8080 IBM C-It WebCam - 808a Veo PC Camera - 808b Veo PC Camera - 808d Veo PC Camera - 810a Veo Advanced Connect WebCam - 810b Veo PC Camera - 810c Veo PC Camera - 8135 Veo Mobile/Advanced Web Camera - 813a Veo PC Camera - 813b Veo PC Camera - 813c Veo Mobile/Advanced Web Camera - 8333 Veo Stingray/Connect Web Camera - 888c eVision 123 digital camera - 888d eVision 123 digital camera -0546 Polaroid Corp. - 0daf PDC 2300Z - 1bed PDC 1320 Camera - 3097 PDC 310 - 3187 Digital Cam - dccf Sound Vision Stream Driver -0547 Anchor Chips, Inc. - 0001 ICSI Bluetooth Device - 1002 Python2 WDM Encoder - 2131 AN2131 EZUSB Microcontroller - 2235 AN2235 EZUSB-FX Microcontroller - 2710 EZ-Link Loader (EZLNKLDR.SYS) - 2720 AN2720 USB-USB Bridge - 2727 Xircom PGUNET USB-USB Bridge - 2750 EZ-Link (EZLNKUSB.SYS) - 2810 Cypress USB ATAPI Bridge - 7777 Bluetooth Device - 9999 AN2131 uninitialized (?) -0548 Tyan Computer Corp. - 1005 EZ Cart II GameBoy Flash Programmer -0549 Pixera Corp. -054a Fujitsu Microelectronics, Inc. -054b New Media Corp. -054c Sony Corp. - 0001 HUB - 0002 Standard HUB - 0010 DSC-S30/S70/S75/F505V/F505/FD92/W1 Cybershot/Mavica Digital Camera - 0014 Nogatech USBVision (SY) - 0022 Storage Adapter V2 (TPP) - 0023 CD Writer - 0024 Mavica CD-1000 Camera - 0025 NW-MS7 Walkman MemoryStick Reader - 002b Portable USB Harddrive V2 - 002c USB Floppy Disk Drive - 002d MSAC-US1 MemoryStick Reader - 002e Sony HandyCam MemoryStick Reader - 0030 Storage Adapter V2 (TPP) - 0032 MemoryStick MSC-U01 Reader - 0035 Network Walkman (E) - 0036 Net MD - 0037 MG Memory Stick Reader/Writer - 0038 Clie PEG-S300/D PalmOS PDA - 0039 Network Walkman (MS) - 003c VAIO-MX LCD Control - 0045 Digital Imaging Video - 0046 Network Walkman - 004a Memory Stick Hi-Fi System - 004b Memory Stick Reader/Writer - 004e DSC-xxx (ptp) - 0056 MG Memory Stick Reader/Writer - 0058 Clie PEG-N7x0C PalmOS PDA Mass Storage - 0066 Clie PEG-N7x0C/PEG-T425 PalmOS PDA Serial - 0069 Memorystick MSC-U03 Reader - 006d Clie PEG-T425 PDA Mass Storage - 006f Network Walkman (EV) - 0073 Storage CRX1750U - 0075 Net MD - 0076 Storage Adapter ACR-U20 - 007c Net MD - 007f IC Recorder (MS) - 0080 Net MD - 0081 Net MD - 0084 Net MD - 0085 Net MD - 0086 Net MD - 008b Micro Vault 64M Mass Storage - 0095 Sony Clie s360 - 0099 Clie NR70 PDA Mass Storage - 009a Clie NR70 PDA Serial - 00ab Visual Communication Camera (PCGA-UVC10) - 00af DPP-EX Series Digital Photo Printer - 00bf IC Recorder (S) - 00c0 Handycam DCR-30 - 00c6 Net MD - 00c7 Net MD - 00c8 MZ-N710 Minidisc Walkman - 00c9 Net MD - 00ca MZ-DN430 Minidisc Walkman - 00cb MSAC-US20 Memory Stick Reader - 00da Sony Clie nx60 - 00e8 Network Walkman (MS) - 00e9 Handheld - 00eb Net MD - 0101 Net MD - 0103 IC Recorder (ST) - 0105 Micro Vault Hub - 0107 VCC-U01 Visual Communication Camera - 0110 Digital Imaging Video - 0113 Net MD - 0116 IC Recorder (P) - 0144 Clie PEG-TH55 PDA - 0147 Visual Communication Camera (PCGA-UVC11) - 014c Aiwa AM-NX9 Net MD Music Recorder MDLP - 014d Memory Stick Reader/Writer - 0154 Eyetoy Audio Device - 015f IC Recorder (BM) - 0169 Clie PEG-TJ35 PDA Serial - 016a Clie PEG-TJ35 PDA Mass Storage - 016b Mobile HDD - 016d IC Recorder (SX) - 016e DPP-EX50 Digital Photo Printer - 0171 Fingerprint Sensor 3500 - 017e Net MD - 017f Hi-MD WALKMAN - 0180 Net MD - 0181 Hi-MD WALKMAN - 0182 Net MD - 0183 Hi-MD WALKMAN - 0184 Net MD - 0185 Hi-MD WALKMAN - 0186 Net MD - 0187 Hi-MD WALKMAN - 0188 Net MD - 018a Net MD - 018b Hi-MD SOUND GATE - 019e Micro Vault 1.0G Mass Storage - 01ad ATRAC HDD PA - 01bd MRW62E Multi-Card Reader/Writer - 01c3 NW-E55 Network Walkman - 01c6 MEMORY P-AUDIO - 01c7 Printing Support - 01d0 DVD+RW External Drive DRU-700A - 01d5 IC RECORDER - 01de VRD-VC10 [Video Capture] - 01e9 Net MD - 01ea Hi-MD WALKMAN - 01ee IC RECORDER - 01fa Sony IC Recorder (P) - 01fb NW-E405 Network Walkman - 020f Device - 0210 ATRAC HDD PA - 0219 Net MD - 021a Hi-MD WALKMAN - 021b Net MD - 021c Hi-MD WALKMAN - 021d Net MD - 0227 Printing Support - 022c Net MD - 022d Hi-MD AUDIO - 0233 ATRAC HDD PA - 0236 Mobile HDD - 023b DVD+RW External Drive DRU-800UL - 023c Net MD - 023d Hi-MD WALKMAN - 0243 MicroVault Flash Drive - 0257 IFU-WLM2 USB Wireless LAN Module (Wireless Mode) - 0258 IFU-WLM2 USB Wireless LAN Module (Memory Mode) - 0259 IC RECORDER - 0267 Tachikoma Device - 0268 Batoh Device - 0269 HDD WALKMAN - 026a HDD WALKMAN - 0271 IC Recorder (P) - 027c NETWORK WALKMAN - 027e SONY Communicator - 027f IC RECORDER - 0286 Net MD - 0287 Hi-MD WALKMAN - 029b PRS-500 eBook reader - 02ae PlayStation 3 Memory Card Adaptor - 02af Handycam DCR-DVD306E - 02c4 Device - 02d2 PSP -054d Try Corp. -054e Proside Corp. -054f WYSE Technology Taiwan -0550 Fuji Xerox Co., Ltd - 0002 InkJet Color Printer - 0004 InkJet Color Printer - 0005 InkJet Color Printer -0551 CompuTrend Systems, Inc. -0552 Philips Monitors -0553 STMicroelectronics Imaging Division (VLSI Vision) - 0001 TerraCAM - 0002 CPiA WebCam - 0100 STV0672 Camera - 0140 Video Camera - 0150 CDE CAM 100 - 0151 Digital Blue QX5 Microscope - 0200 Dual-mode Camera0 - 0201 Dual-mode Camera1 - 0202 Aiptek PenCam 1 - 0674 Multi-mode Camera - 0679 NMS Video Camera (Webcam) - 1002 Che-ez! Splash -0554 Dictaphone Corp. -0555 ANAM S&T Co., Ltd -0556 Asahi Kasei Microsystems Co., Ltd - 0001 AK5370 I/F A/D Converter -0557 ATEN International Co., Ltd - 2001 UC-1284 Printer Port - 2002 10Mbps Ethernet [klsi] - 2004 UC-100KM PS/2 Mouse and Keyboard adapter - 2006 UC-1284B Printer Port - 2007 UC-110T 100Mbps Ethernet [pegasus] - 2008 UC-232A Serial Port [pl2303] - 2009 UC-210T Ethernet - 2202 CS124U Miniview II KVM Switch - 2600 IDE Bridge - 4000 DSB-650 10Mbps Ethernet [klsi] - 7000 Hub -0558 Truevision, Inc. -0559 Cadence Design Systems, Inc. -055a Kenwood USA -055b KnowledgeTek, Inc. -055c Proton Electronic Ind. -055d Samsung Electro-Mechanics Co. - 0001 Keyboard - 0bb1 Bluetooth Device - 1030 Optical Wheel Mouse (OMS3CB/OMGB30) - 1031 Optical Wheel Mouse (OMA3CB/OMGI30) - 1040 Mouse HID Device - 1050 E-Mail Optical Wheel Mouse (OMS3CE) - 1080 Optical Wheel Mouse (OMS3CH) - 2020 Floppy Disk Drive - 6780 Keyboard V1 - 6781 Keyboard Mouse - 8001 E.M. Hub - 9000 AnyCam [pwc] - 9001 MPC-C30 AnyCam Premium for Notebooks [pwc] - a010 WLAN Adapter(SWL-2300) - a011 Boot Device - a012 WLAN Adapter(SWL-2300) - a013 WLAN Adapter(SWL-2350) - a230 Boot Device - b000 11Mbps WLAN Mini Adapter - b230 Netopia 802.11b WLAN Adapter - b231 LG Wireless LAN 11b Adapter -055e CTX Opto-Electronics Corp. -055f Mustek Systems, Inc. - 0001 ScanExpress 1200 CU - 0002 ScanExpress 600 CU - 0003 ScanExpress 1200 USB - 0006 ScanExpress 1200 UB - 0007 ScanExpress 1200 USB Plus - 0008 ScanExpress 1200 CU Plus - 0010 BearPaw 1200F - 0210 ScanExpress A3 USB - 0218 BearPaw 2400 TA - 0219 BearPaw 2400 TA Plus - 021a BearPaw 2448 TA Plus - 021c BearPaw 1200 CU Plus - 021d BearPaw 2400 CU Plus - 021e BearPaw 1200 TA/CS - 021f SNAPSCAN e22 - 0400 BearPaw 2400 TA Pro - 0401 P 3600 A3 Pro - 0408 BearPaw 2448 CU Pro - 0873 ScanExpress 600 USB - 1000 BearPaw 4800 TA Pro - a350 gSmart 350 - a800 MDC 800 Camera - b500 MDC 3000 Camera - c005 PC CAM 300A - c200 gSmart 300 - c220 gSmart mini - c360 Mustek DV 4000 - c420 gSmart mini 2 - c440 Mustek DV 3000 - c520 gSmart mini 3 - c530 Mustek Gsmart LCD 2 - c631 MDC-4000 - c650 Mustek MDC5500Z - d001 WCam 300 - d003 PC CAM 300A - d004 PC CAM 300A -0560 Interface Corp. -0561 Oasis Design, Inc. -0562 Telex Communications, Inc. - 0001 Enhanced Microphone - 0002 Telex Microphone -0563 Immersion Corp. -0564 Chinon Industries, Inc. -0565 Peracom Networks, Inc. - 0001 Serial Port [etek] - 0002 Enet Ethernet [klsi] - 0003 @Home Networks Ethernet [klsi] - 0005 Enet2 Ethernet [klsi] - 0041 Peracom Remote NDIS Ethernet Adapter -0566 Monterey International Corp. - 0110 ViewMate Desktop Mouse CC2201 - 1001 ViewMate Desktop Mouse CC2201 - 1002 ViewMate Desktop Mouse CC2201 - 1003 ViewMate Desktop Mouse CC2201 - 1004 ViewMate Desktop Mouse CC2201 - 1005 ViewMate Desktop Mouse CC2201 - 1006 ViewMate Desktop Mouse CC2201 - 1007 ViewMate Desktop Mouse CC2201 - 2800 MIC K/B - 2801 MIC K/B Mouse - 2802 Kbd Hub -0567 Xyratex International, Ltd -0568 Quartz Ingenierie -0569 SegaSoft -056a Wacom Co., Ltd - 0000 PenPartner - 0001 PenPartner 4x5 - 0002 PenPartner 6x8 - 0010 Graphire - 0011 Graphire 2 - 0013 Graphire 3 4x5 - 0020 Intuos 4x5 - 0021 Intuos 6x8 - 0022 Intuos 9x12 - 0023 Intuos 12x12 - 0024 Intuos 12x18 - 0030 PL400 - 0031 PL500 - 0032 PL600 - 0034 PL550 - 0035 PL800 - 0041 Intuos2 4x5 - 0042 Intuos 2 6x8 - 0043 Intuos 2 - 0044 Intuos2 12x12 - 0045 Intuos2 12x18 - 0400 PenPartner 4x5 - 4850 PenPartner 6x8 -056b Decicon, Inc. -056c eTEK Labs - 0006 KwikLink Host-Host Connector - 8007 Kwik232 Serial Port - 8100 KwikLink Host-Host Connector - 8101 KwikLink USB-USB Bridge -056d EIZO Corp. - 0000 Hub - 0001 Monitor - 0002 HID Monitor Controls - 0003 Device Bay Controller -056e Elecom Co., Ltd - 0002 29UO Mouse - 200c LD-USB/TX - 4002 Laneed 100Mbps Ethernet LD-USB/TX [pegasus] - 4005 LD-USBL/TX - 400b LD-USB/TX - 4010 LD-USB20 - 5003 UC-SGT - 5004 UC-SGT - abc1 LD-USB/TX -056f Korea Data Systems Co., Ltd - cd00 CDM-751 CD organizer -0570 Epson America -0571 Interex, Inc. - 0002 echoFX InterView Lite -0572 Conexant Systems (Rockwell), Inc. - 0001 Ezcam II WebCam - 0002 Ezcam II WebCam - 0040 Wondereye CP-115 WebCam - 0041 WebCam Notebook - 0042 WebCam Notebook - 1232 V.90 modem - 1234 Typhoon Redfun Modem V90 56k - 1252 HCF V90 Data Fax Voice Modem - 1253 Zoom V.92 Faxmodem - 1300 SoftK56 Data Fax Voice CARP - 1301 Modem Enumerator - 2000 SoftGate 802.11 Adapter - 2002 SoftGate 802.11 Adapter - 8390 WinFast PalmTop/Novo TV Video - 8392 WinFast PalmTop/Novo TV Video - cafe AccessRunner ADSL Modem - cb00 E-Tech ADSL Modem v2 - cb01 GeekADSL Promax Q31 ADSL Modem - cb06 StarModem Network Interface -0573 Zoran Co. Personal Media Division (Nogatech) - 0003 USBGear USBG-V1 - 0400 D-Link V100 - 0600 Dazzle USBVision (1006) - 1300 leadtek USBVision (1006) - 2000 X10 va10a Wireless Camera - 2001 Dazzle EmMe (2001) - 2101 Zoran Co. PMD (Nogatech) AV-grabber Manhattan - 2d00 Osprey 50 - 2d01 Hauppauge USB-Live Model 600 - 3000 Dazzle MicroCam (NTSC) - 3001 Dazzle MicroCam (PAL) - 4000 Nogatech TV! (NTSC) - 4001 Nogatech TV! (PAL) - 4002 Nogatech TV! (PAL-I-) - 4003 Nogatech TV! (MF-) - 4008 Nogatech TV! (NTSC) (T) - 4009 Nogatech TV! (PAL) (T) - 4010 Nogatech TV! (NTSC) (A) - 4100 USB-TV FM (NTSC) - 4110 PNY USB-TV (NTSC) FM - 4400 Nogatech TV! Pro (NTSC) - 4401 Nogatech TV! Pro (PAL) - 4450 PixelView PlayTv-USB PRO (PAL) FM - 4451 Nogatech TV! Pro (PAL+) - 4452 Nogatech TV! Pro (PAL-I+) - 4500 Nogatech TV! Pro (NTSC) - 4501 Nogatech TV! Pro (PAL) - 4550 ZTV ZT-721 2.4GHz USB A/V Receiver - 4551 Dazzle TV! Pro Audio (P+) - 4d00 Hauppauge WinTV-USB USA - 4d01 Hauppauge WinTV-USB - 4d02 Hauppauge WinTV-USB UK - 4d03 Hauppauge WinTV-USB France - 4d04 Hauppauge WinTV (PAL D/K) - 4d10 Hauppauge WinTV-USB with FM USA radio - 4d11 Hauppauge WinTV-USB (PAL) with FM radio - 4d12 Hauppauge WinTV-USB UK with FM Radio - 4d14 Hauppauge WinTV (PAL D/K FM) - 4d20 Hauppauge WinTV-USB II (PAL) with FM radio - 4d21 Hauppauge WinTV-USB II (PAL) - 4d22 Hauppauge WinTV-USB II (PAL) Model 566 - 4d23 Hauppauge WinTV-USB France 4D23 - 4d24 Hauppauge WinTV Pro (PAL D/K) - 4d25 Hauppauge WinTV-USB Model 40209 rev B234 - 4d26 Hauppauge WinTV-USB Model 40209 rev B243 - 4d27 Hauppauge WinTV-USB Model 40204 Rev B281 - 4d28 Hauppauge WinTV-USB Model 40204 rev B283 - 4d29 Hauppauge WinTV-USB Model 40205 rev B298 - 4d2a Hauppague WinTV-USB Model 602 Rev B285 - 4d2b Hauppague WinTV-USB Model 602 Rev B282 - 4d2c Hauppauge WinTV Pro (PAL/SECAM) - 4d30 Hauppauge WinTV-USB FM Model 40211 Rev B123 - 4d31 Hauppauge WinTV-USB III (PAL) with FM radio Model 568 - 4d32 Hauppauge WinTV-USB III (PAL) FM Model 573 - 4d34 Hauppauge WinTV Pro (PAL D/K FM) - 4d35 Hauppauge WinTV-USB III (PAL) FM Model 597 - 4d36 Hauppauge WinTV Pro (PAL B/G FM) - 4d37 Hauppauge WinTV-USB Model 40219 rev E189 - 4d38 Hauppauge WinTV Pro (NTSC FM) -0574 City University of Hong Kong -0575 Philips Creative Display Solutions -0576 BAFO/Quality Computer Accessories -0577 ELSA -0578 Intrinsix Corp. -0579 GVC Corp. -057a Samsung Electronics America -057b Y-E Data, Inc. - 0000 FlashBuster-U Floppy - 0001 Tri-Media Reader Floppy - 0006 Tri-Media Reader Card Reader - 0010 Memory Stick Reader Writer - 0020 HEXA Media Drive 6-in-1 Card Reader Writer - 0030 Memory Card Viewer (TV) -057c AVM GmbH - 0b00 ISDN-Controller B1 Family - 0c00 ISDN-Controller FRITZ!Card - 1000 ISDN-Controller FRITZ!Card v2.0 - 1900 ISDN-Controller FRITZ!Card v2.1 - 2000 ISDN-Connector FRITZ!X - 2200 BlueFRITZ! - 2300 Teledat X130 DSL - 2800 ISDN-Connector TA - 3200 Teledat X130 DSL - 3500 FRITZ!Card DSL SL - 3701 FRITZ!Box SL - 3702 FRITZ!Box - 3800 BlueFRITZ! Bluetooth Stick - 3a00 FRITZ!Box Fon - 3c00 FRITZ!Box WLAN - 3d00 Fritz!Box - 3e01 FRITZ!Box (Annex A) - 4001 FRITZ!Box Fon (Annex A) - 4101 FRITZ!Box WLAN (Annex A) - 4201 FRITZ!Box Fon WLAN (Annex A) - 4601 Eumex 5520PC (WinXP/2000) - 4602 Eumex 400 (WinXP/2000) - 4701 AVM FRITZ!Box Fon ata - 5401 Eumex 300 IP - 5601 AVM FRITZ!WLAN Stick - 6201 WLAN USB v1.1 - 62ff WLAN USB v1.1 [no firmware] -057d Shark Multimedia, Inc. -057e Nintendo Co., Ltd - 0306 Wii Remote Controller RVL-003 -057f QuickShot, Ltd - 6238 USB StrikePad -0580 Denron, Inc. -0581 Racal Data Group -0582 Roland Corp. - 0000 UA-100 - 0002 UM-4/MPU-64 MIDI Interface - 0003 SoundCanvas SC-8850 - 0004 U-8 - 0005 Edirol UM-2 MIDI Adapter - 0007 SoundCanvas SC-8820 - 0008 PC-300 - 0009 Edirol UM-1SX MIDI Adapter - 000b SK-500 - 000c SC-D70 - 0010 EDIROL UA-5 - 0011 Edirol UA-5 Sound Capture - 0012 XV-5050 - 0013 XV-5050 - 0014 EDIROL UM-880 MIDI I/F (native) - 0015 EDIROL UM-880 MIDI I/F (generic) - 0016 EDIROL SD-90 - 0017 EDIROL SD-90 - 001b MMP-2 - 001c MMP-2 - 001d V-SYNTH - 001e V-SYNTH - 0023 EDIROL UM-550 - 0024 EDIROL UM-550 - 0025 EDIROL UA-20 - 0026 EDIROL UA-20 - 0027 EDIROL SD-20 - 0028 EDIROL SD-20 - 0029 EDIROL SD-80 - 002a EDIROL SD-80 - 002b EDIROL UA-700 - 002c EDIROL UA-700 - 002d XV-2020 Synthesizer - 002e XV-2020 Synthesizer - 002f VariOS - 0030 VariOS - 0033 EDIROL PCR - 0034 EDIROL PCR - 0037 Digital Piano - 0038 Digital Piano - 003b BOSS GS-10 - 003c BOSS GS-10 - 0040 GI-20 - 0041 GI-20 - 0042 RS-70 - 0043 RS-70 - 0044 EDIROL UA-1000 - 0047 EDIROL UR-80 WAVE - 0048 EDIROL UR-80 MIDI - 0049 EDIROL UR-80 WAVE - 004a EDIROL UR-80 MIDI - 004b EDIROL M-100FX - 004c EDIROL PCR-A WAVE - 004d EDIROL PCR-A MIDI - 004e EDIROL PCR-A WAVE - 004f EDIROL PCR-A MIDI - 0050 EDIROL UA-3FX - 0052 EDIROL UM-1SX - 0054 Digital Piano - 0060 EXR Series - 0064 EDIROL PCR-1 WAVE - 0065 EDIROL PCR-1 MIDI - 0066 EDIROL PCR-1 WAVE - 0067 EDIROL PCR-1 MIDI - 006a SP-606 - 006b SP-606 - 006d FANTOM-X - 006e FANTOM-X - 0073 EDIROL UA-25 - 0074 EDIROL UA-25 - 0075 BOSS DR-880 - 0076 BOSS DR-880 - 007a RD - 007b RD - 007d EDIROL UA-101 - 0080 G-70 - 0081 G-70 - 008b EDIROL PC-50 - 008c EDIROL PC-50 - 008d EDIROL UA-101 USB1 - 0092 EDIROL PC-80 WAVE - 0093 EDIROL PC-80 MIDI - 0096 EDIROL UA-1EX - 009a EDIROL UM-3EX - 009d EDIROL UM-1 - 00a2 Digital Piano - 00a3 EDIROL UA-4FX - 00a6 Juno-G - 00ad SH-201 - 00c4 EDIROL M-16DX -0583 Padix Co., Ltd (Rockfire) - 2030 RM-203 USB Nest [mode 1] - 2031 RM-203 USB Nest [mode 2] - 2032 RM-203 USB Nest [mode 3] - 2033 RM-203 USB Nest [mode 4] - 2050 PX-205 PSX Bridge - 3050 QF-305u Gamepad - 688f QF-688uv Windstorm Pro Joystick - 7070 QF-707u Bazooka Joystick -0584 RATOC System, Inc. - 0008 Fujifilm MemoryCard ReaderWriter - b000 REX-USB60 -0585 FlashPoint Technology, Inc. - 0001 Digital Camera - 0002 Digital Camera - 0003 Digital Camera - 0004 Digital Camera - 0005 Digital Camera - 0006 Digital Camera - 0007 Digital Camera - 0008 Digital Camera - 0009 Digital Camera - 000a Digital Camera - 000b Digital Camera - 000c Digital Camera - 000d Digital Camera - 000e Digital Camera - 000f Digital Camera -0586 ZyXEL Communications Corp. - 1000 Omni NET Modem / ISDN TA - 1500 Omni 56K Plus - 2011 Scorpion-980N keyboard - 3304 LAN Modem - 330a ADSL Modem Interface - 330e USB Broadband ADSL Modem Rev 1.10 - 3400 ZyAIR B-220 IEEE 802.11b Adapter - 3401 ZyAIR G-220 - 3402 (ZD1211)IEEE 802.11b+g Adapter - 3407 G-200 v2 - 3409 AG-225H - 340a M-202 - 340f G-220 v2 - 3410 Wi-Fi Wireless LAN Adapter - 3412 Wi-Fi Wireless LAN Adapter - 3413 AG-225H v2 802.11a/g Wi-Fi Finder & Adapter - 3415 G-210H 802.11g Wireless Adapter -0587 America Kotobuki Electronics Industries, Inc. -0588 Sapien Design -0589 Victron -058a Nohau Corp. -058b Infineon Technologies -058c In Focus Systems - 0007 Flash - 0008 LP130 - 000a LP530 - 0010 Projector - 0011 Projector - 0012 Projector - 0013 Projector - 0014 Projector - 0015 Projector - 0016 Projector - 0017 Projector - 0018 Projector - 0019 Projector - 001a Projector - 001b Projector - 001c Projector - 001d Projector - 001e Projector - 001f Projector -058d Micrel Semiconductor -058e Tripath Technology, Inc. -058f Alcor Micro Corp. - 2412 SCard R/W CSR-145 - 2802 Monterey Keyboard - 5492 Hub - 6232 Hi-Speed 16-in-1 Flash Card Reader/Writer - 6360 Multimedia Card Reader - 6361 Multimedia Card Reader - 6362 Hi-Speed 21-in-1 Flash Card Reader/Writer (Internal/External) - 6377 Multimedia Card Reader - 6386 Memory Card - 6387 Transcend JetFlash Flash Drive - 6390 USB 2.0-IDE bridge - 9213 MacAlly Kbd Hub - 9215 AU9814 Hub - 9254 Hub - 9310 Mass Storage (UID4/5A & UID7A) - 9320 Micro Storage Driver for Win98 - 9321 Micro Storage Driver for Win98 - 9330 SD Reader - 9331 Micro Storage Driver for Win98 - 9340 Delkin eFilm Reader-32 - 9350 Delkin eFilm Reader-32 - 9360 8-in-1 Media Card Reader - 9361 Multimedia Card Reader - 9368 Multimedia Card Reader - 9380 Flash drive - 9382 Acer/Sweex Flash drive - 9410 Keyboard - 9472 Keyboard Hub - 9510 ChunghwaTL USB02 Smartcard Reader - 9520 EMV Certified Smart Card Reader - 9720 USB-Serial Adapter -0590 Omron Corp. - 0004 Cable Modem - 000b MR56SVS - 0028 HJ-720IT Pedometer -0591 Questra Consulting -0592 Powerware Corp. - 0002 UPS (X-Slot) -0593 Incite -0594 Princeton Graphic Systems -0595 Zoran Microelectronics, Ltd - 1001 Digitrex DSC-1300/DSC-2100 (mass storage mode) - 4343 Digital Camera EX-20 DSC -0596 MicroTouch Systems, Inc. - 0001 Touchscreen - 0002 Touch Screen Controller -0597 Trisignal Communications -0598 Niigata Canotec Co., Inc. -0599 Brilliance Semiconductor, Inc. -059a Spectrum Signal Processing, Inc. -059b Iomega Corp. - 0001 Zip 100 (Type 1) - 000b Zip 100 (Type 2) - 0021 Win98 Disk Controller - 0030 Zip 250 (Ver 1) - 0031 Zip 100 (Type 3) - 0032 Zip 250 (Ver 2) - 0034 Zip 100 Driver - 0037 Zip 750 MB - 0040 SCSI Bridge - 0042 Rev 70 GB - 0050 Zip CD 650 Writer - 0053 CDRW55292EXT CD-RW External Drive - 0057 Mass Storage Device - 005d Mass Storage Device - 005f Mass Storage Device - 0060 PCMCIA PocketZip Dock - 0061 Varo PocketZip 40 MP3 Player - 006d HipZip MP3 Player - 007c Ultra Max USB/1394 - 00db FotoShow Zip 250 Driver - 0150 Mass Storage Device - 015d Super DVD Writer - 0173 Hi-Speed USB-to-IDE Bridge Controller - 0174 Hi-Speed USB-to-IDE Bridge Controller - 0176 Hi-Speed USB-to-IDE Bridge Controller - 0177 Hi-Speed USB-to-IDE Bridge Controller - 0178 Hi-Speed USB-to-IDE Bridge Controller - 0179 Hi-Speed USB-to-IDE Bridge Controller - 017a HDD - 017b HDD/1394A - 017c HDD/1394B - 0251 Optical - 0252 Optical - 1052 DVD+RW External Drive -059c A-Trend Technology Co., Ltd -059d Advanced Input Devices -059e Intelligent Instrumentation -059f LaCie, Ltd - 0201 StudioDrive USB2 - 0202 StudioDrive USB2 - 0203 StudioDrive USB2 - 0211 PocketDrive - 0212 PocketDrive - 0213 PocketDrive USB2 - 0323 LaCie d2 Drive USB2 - 0641 Mobile Hard Drive - 1010 Desktop Hard Drive - a601 HardDrive - a602 CD R/W -05a0 Vetronix Corp. -05a1 USC Corp. -05a2 Fuji Film Microdevices Co., Ltd -05a3 ARC International -05a4 Ortek Technology, Inc. - 9720 Keyboard Mouse - 9722 Keyboard - 9731 MCK-600W/MCK-800USB Keyboard -05a5 Sampo Technology Corp. -05a6 Cisco Systems, Inc. - 0001 CVA124 Cable Voice Adapter (WDM) - 0002 CVA122 Cable Voice Adapter (WDM) - 0003 CVA124E Cable Voice Adapter (WDM) - 0004 CVA122E Cable Voice Adapter (WDM) -05a7 Bose Corp. -05a8 Spacetec IMC Corp. -05a9 OmniVision Technologies, Inc. - 0511 OV511 WebCam - 0518 OV518 WebCam - 0519 OV519 Microphone - 1550 VEHO Filmscanner - 2800 SuperCAM - 4519 Webcam Classic - 8519 OV519 WebCam - a511 OV511+ WebCam - a518 D-Link DSB-C310 WebCam -05aa Utilux South China, Ltd -05ab In-System Design - 0002 Parallel Port - 0030 Storage Adapter V2 (TPP) - 0031 ATA Bridge - 0060 USB 2.0 ATA Bridge - 0061 Storage Adapter V3 (TPP-I) - 0101 Storage Adapter (TPP) - 0130 Compact Flash and Microdrive Reader (TPP) - 0200 USS725 ATA Bridge - 0201 Storage Adapter (TPP) - 0202 ATA Bridge - 0300 Portable Hard Drive (TPP) - 0301 Portable Hard Drive V2 - 0350 Portable Hard Drive (TPP) - 0351 Portable Hard Drive V2 - 081a ATA Bridge - 0cda ATA Bridge for CD-R/RW - 1001 BAYI Printer Class Support - 5700 Storage Adapter V2 (TPP) - 5701 USB Storage Adapter V2 - 5901 Smart Board (TPP) - 5a01 ATI Storage Adapter (TPP) - 5d01 DataBook Adapter (TPP) -05ac Apple, Inc. - 0201 USB Keyboard [Alps or Logitech, M2452] - 0202 Keyboard [ALPS] - 0205 Extended Keyboard [Mitsumi] - 0206 Extended Keyboard [Mitsumi] - 020b Pro Keyboard [Mitsumi, A1048/US layout] - 020c Extended Keyboard [Mitsumi] - 020d Pro Keyboard [Mitsumi, A1048/JIS layout] - 020e Internal Keyboard/Trackpad - 020f Internal Keyboard/Trackpad - 021b Internal Keyboard/Trackpad - 0220 Aluminum Keyboard - 0221 Keyboard (Aluminium) (ISO) - 0229 Internal Keyboard/Trackpad (MacBook Pro) (ANSI) - 022a Internal Keyboard/Trackpad (MacBook Pro) (ISO) - 022b Internal Keyboard/Trackpad (MacBook Pro) (JIS) - 0301 USB Mouse [Mitsumi, M4848] - 0302 Optical Mouse [Fujitsu] - 0304 Optical USB Mouse [Mitsumi] - 0306 Optical USB Mouse [Fujitsu] - 1000 Bluetooth HCI MacBookPro (HID mode) - 1001 Keyboard Hub [ALPS] - 1002 Extended Keyboard Hub [Mitsumi] - 1003 Hub in Pro Keyboard [Mitsumi, A1048] - 1006 Hub in Aluminum Keyboard - 1101 Speakers - 1201 3G iPod - 1202 iPod 2G - 1203 iPod 4.Gen Grayscale 40G - 1204 iPod [Photo] - 1205 iPod Mini 1.Gen/2.Gen - 1206 iPod '06' - 1207 iPod '07' - 1208 iPod '08' - 1209 iPod Video - 120a iPod Nano - 1260 iPod Nano 2.Gen - 1261 iPod Classic - 1300 iPod Shuffle - 1301 iPod Shuffle 2.Gen - 8202 HCF V.90 Data/Fax Modem - 8203 Bluetooth HCI - 8204 Bluetooth HCI [Bluetooth 2.0 + EDR, build-in] - 8205 Bluetooth HCI MacBookPro - 8206 Bluetooth USB Host Controller - 8240 IR Receiver [build-in] - 8300 Built-in iSight (no firmware loaded) - 8501 Built-in iSight [Micron] - 912f Hub in 30" Cinema Display - 9221 30" Cinema Display - ffff Bluetooth in DFU mode - Driver -05ad Y.C. Cable U.S.A., Inc. -05ae Synopsys, Inc. -05af Jing-Mold Enterprise Co., Ltd - 0821 IDE to - 9167 KB 9151B - 678 - 9267 KB 9251B - 678 Mouse -05b0 Fountain Technologies, Inc. -05b1 First International Computer, Inc. - 1389 Bluetooth Wireless Adapter -05b4 LG Semicon Co., Ltd - 4857 M-Any DAH-210 - 6001 Digisette DUO-MP3 AR-100 -05b5 Dialogic Corp. -05b6 Proxima Corp. -05b7 Medianix Semiconductor, Inc. -05b8 Agiler, Inc. - 3002 Scroll Mouse -05b9 Philips Research Laboratories -05ba DigitalPersona, Inc. -05bb Grey Cell Systems -05bc 3G Green Green Globe Co., Ltd - 0004 Trackball -05bd RAFI GmbH & Co. KG -05be Tyco Electronics (Raychem) -05bf S & S Research -05c0 Keil Software -05c1 Kawasaki Microelectronics, Inc. -05c2 Media Phonics (Suisse) S.A. -05c5 Digi International, Inc. - 0002 AccelePort USB 2 - 0004 AccelePort USB 4 - 0008 AccelePort USB 8 -05c6 Qualcomm, Inc. - 3100 CDMA Wireless Modem/Phone - 3196 CDMA Wireless Modem - 3197 CDMA Wireless Modem/Phone -05c7 Qtronix Corp. - 0113 PC Line Mouse - 1001 Lynx Mouse - 2001 Keyboard - 2011 SCorpius Keyboard - 6001 Ten-Keypad -05c8 Cheng Uei Precision Industry Co., Ltd (Foxlink) -05c9 Semtech Corp. -05ca Ricoh Co., Ltd - 0101 RDC-5300 Camera - 0325 Caplio GX (ptp) - 032d Caplio GX 8 (ptp) - 032f Caplio R3 (ptp) - 03a1 IS200e - 0403 Printing Support - 0405 Type 101 - 0406 Type 102 - 1830 Visual Communication Camera VGP-VCC2 - 1835 Visual Communication Camera VGP-VCC5 - 1870 Webcam 1000 - 2201 RDC-7 Camera - 2202 Caplio RR30 - 2203 Caplio 300G - 2204 Caplio G3 - 2205 Caplio RR30 / Medion MD 6126 Camera - 2206 Konica DG-3Z - 2207 Caplio Pro G3 - 2208 Caplio G4 - 2209 Caplio 400G wide - 220a KONICA MINOLTA DG-4Wide - 220b Caplio RX - 220c Caplio GX - 220d Caplio R1/RZ1 - 220e Sea & Sea 5000G - 220f Rollei dr5 / Rollei dr5 (PTP mode) - 2211 Caplio R1S - 2212 Caplio R1v Camera - 2213 Caplio R2 - 2214 Caplio GX 8 - 2215 DSC 725 - 2216 Caplio R3 - 2222 RDC-i500 -05cb PowerVision Technologies, Inc. - 1483 PV8630 interface (scanners, webcams) -05cc ELSA AG - 2100 MicroLink ISDN Office - 2219 MicroLink ISDN - 2265 MicroLink 56k - 2267 MicroLink 56k (V.250) - 2280 MicroLink 56k Fun - 3000 Micolink USB2Ethernet [pegasus] - 3100 AirLancer USB-11 - 3363 MicroLink ADSL Fun -05cd Silicom, Ltd -05ce sci-worx GmbH -05cf Sung Forn Co., Ltd -05d0 GE Medical Systems Lunar -05d1 Brainboxes, Ltd - 0003 Bluetooth Adapter BL-554 -05d2 Wave Systems Corp. -05d3 Tohoku Ricoh Co., Ltd -05d5 Super Gate Technology Co., Ltd -05d6 Philips Semiconductors, CICT -05d7 Thomas & Betts Corp. - 0099 10Mbps Ethernet [klsi] -05d8 Ultima Electronics Corp. - 4001 Artec Ultima 2000 - 4002 Artec Ultima 2000 (GT6801 based)/Lifetec LT9385/ScanMagic 1200 UB Plus Scanner - 4003 Artec E+ 48U - 4004 Artec E+ Pro - 4005 MEM48U - 4006 TRUST EASY WEBSCAN 19200 - 4007 TRUST 240H EASY WEBSCAN GOLD - 4008 Trust Easy Webscan 19200 - 4009 Umax Astraslim - 4013 IT Scan 1200 - 8105 Artec T1 USB TVBOX (cold) - 8106 Artec T1 USB TVBOX (warm) - 8107 Artec T1 USB TVBOX with AN2235 (cold) - 8108 Artec T1 USB TVBOX with AN2235 (warm) - 8109 Artec T1 USB2.0 TVBOX (cold -05d9 Axiohm Transaction Solutions - a225 A225 Printer - a758 A758 Printer - a794 A794 Printer -05da Microtek International, Inc. - 0091 ScanMaker X6u - 0093 ScanMaker V6USL - 0094 Phantom 336CX/C3 - 0099 ScanMaker X6/X6U - 009a Phantom C6 - 00a0 Phantom 336CX/C3 (#2) - 00a3 ScanMaker V6USL - 00ac ScanMaker V6UL - 00b6 ScanMaker V6UPL - 00ef ScanMaker V6UPL - 1006 Jenoptik JD350 entrance - 1011 NHJ Che-ez! Kiss Digital Camera - 1018 Digital Dream Enigma 1.3 - 1020 Digital Dream l'espion xtra - 1025 Take-it Still Camera Device - 1026 Take-it - 1043 Take-It 1300 DSC Bulk Driver - 1045 Take-it D1 - 1047 Take-it Camera Composite Device - 1048 Take-it Q3 - 1049 3M Still Camera Device - 1051 Camcorder Series - 1052 Mass Storage Device - 1053 Take-it DV Composite Device - 1054 Mass Storage Device - 1055 Digital Camera Series(536) - 1056 Mass Storage Device - 1057 Take-it DSC Camera Device(536) - 1058 Mass Storage Device - 1059 Camcorder DSC Series - 1060 Microtek Take-it MV500 - 2007 ArtixScan DI 1210 - 200c 1394_USB2 Scanner - 200e ArtixScan DI 810 - 2017 UF ICE Scanner - 201c 4800 Scanner - 201d ArtixScan DI 1610 - 201f 4800 Scanner-ICE - 202e ArtixScan DI 2020 - 208b ScanMaker 6800 - 208f ArtixScan DI 2010 - 209e ScanMaker 4700LP - 20a7 ScanMaker 5600 - 20b0 ScanMaker X12USL - 20b1 ScanMaker 8700 - 20b4 ScanMaker 4700 - 20bd ScanMaker 5700 - 20c9 ScanMaker 6700 - 20d2 Microtek ArtixScan 1800f - 20d6 PS4000 - 20de ScanMaker 9800XL - 20e0 ScanMaker 9700XL - 20ed ScanMaker 4700 - 20ee Micortek ScanMaker X12USL - 3008 Scanner - 300a 4800 ICE Scanner - 300b 4800 Scanner - 300f MiniScan C5 - 3020 4800dpi Scanner - 3021 1200dpi Scanner - 3022 Scanner 4800dpi - 3023 USB1200II Scanner - 30c1 USB600 Scanner - 30ce ScanMaker 3800 - 30cf ScanMaker 4800 - 30d4 USB1200 Scanner - 30d8 Scanner - 30d9 USB2400 Scanner - 30e4 ScanMaker 4100 - 30e5 USB3200 Scanner - 30e6 ScanMaker i320 - 40b3 ScanMaker 3600 - 40b8 ScanMaker 3700 - 40c7 ScanMaker 4600 - 40ca ScanMaker 3600 - 40cb ScanMaker 3700 - 40dd ScanMaker 3750i - 40ff ScanMaker 3600 - 5003 Goya - 5013 3200 Scanner - 80a3 ScanMaker V6USL (#2) - 80ac ScanMaker V6UL/SpicyU -05db Sun Corp. (Suntac?) - 0003 SUNTAC U-Cable type D2 - 0005 SUNTAC U-Cable type P1 - 0009 SUNTAC Slipper U - 000a SUNTAC Ir-Trinity - 000b SUNTAC U-Cable type A3 - 0011 SUNTAC U-Cable type A4 -05dc Lexar Media, Inc. - 0001 jumpSHOT CompactFlash Reader - 0002 JumpShot - 0003 JumpShot - 0080 Jumpdrive Secure 64MB - 0081 RBC Compact Flash Drive - 00a7 JumpDrive Impact - 0100 JumpDrive PRO - 0200 JumpDrive 2.0 Pro - 0300 Jumpdrive Geysr - 0301 JumpDrive Classic - 0302 JD Micro - 0303 JD Micro Pro - 0304 JD Secure II - 0310 JumpDrive - 0311 JumpDrive Classic - 0312 JD Micro - 0313 JD Micro Pro - 0320 JumpDrive - 0321 JD Micro - 0322 JD Micro Pro - 0323 UFC - 0330 JumpDrive Expression - 0340 JumpDrive TAD - 0350 Express Card - 0400 UFDC - 0401 UFDC - 0403 Locked B Device - 0405 Locked C Device - 0407 Locked D Device - 0409 Locked E Device - 040b Locked F Device - 040d Locked G Device - 040f Locked H Device - 0410 JumpDrive - 0411 JumpDrive - 0413 Locked J Device - 0415 Locked K Device - 0417 Locked L Device - 0419 Locked M Device - 041b Locked N Device - 041d Locked O Device - 041f Locked P Device - 0420 JumpDrive - 0421 JumpDrive - 0423 Locked R Device - 0425 Locked S Device - 0427 Locked T Device - 0429 Locked U Device - 042b Locked V Device - 042d Locked W Device - 042f Locked X Device - 0431 Locked Y Device - 0433 Locked Z Device - 4d02 MP3 Player - 4d12 MP3 Player - a300 JumpDrive2 - a400 JumpDrive trade; Pro 40-501 - a410 JumpDrive 128MB/256MB - a411 JumpDrive Traveler - a420 JumpDrive Pro - a421 JumpDrive Pro II - a422 JumpDrive Micro Pro - a430 JumpDrive Secure - a431 JumpDrive Secure II - a432 JumpDrive Classic - a440 JumpDrive Lightning - a450 JumpDrive TouchGuard - a460 JD Mercury - a501 JumpDrive Classic - a510 JumpDrive Sport - a530 JumpDrive Expression - a531 JumpDrive Secure II - a560 JumpDrive FireFly - a701 JumpDrive FireFly - b002 USB CF Reader - b018 Multi-Card Reader -05dd Delta Electronics, Inc. - ff31 AWU-120 - ff32 FriendlyNET AeroLAN AL2011 - ff35 PCW 100 - Wireless 802.11b Adapter - ff91 2Wire PC Port Phoneline 10Mbps Adapter -05df Silicon Vision, Inc. -05e0 Symbol Technologies - 0700 Bar Code Scanner (CS1504) - 0800 Spectrum24 Wireless LAN Adapter - 1200 DS6608 Bar Code Scanner - 1900 SNAPI Imaging Device - 2000 MC3090 Rugged Mobile Computer - 200d MC70 Rugged Mobile Computer -05e1 Syntek Semiconductor Co., Ltd - 0500 DC-112X - 0501 WebCam, Chipset DC-1125 similar to 174f:a311 - Asus F2F, F2J, F3J, F3T, G1, Z53JA - 0890 STK011 Camera - 0892 STK013 Camera - 0895 STK016 Camera - 0896 STK017 Camera -05e2 ElecVision, Inc. -05e3 Genesys Logic, Inc. - 000a Keyboard with PS/2 Port - 000b Mouse - 0100 Nintendo Game Boy Advance SP - 0120 Pacific Image Electronics PrimeFilm 1800u slide/negative scanner - 0131 CF/SM Reader/Writer - 0142 Multiple Slides Scanner-3600 - 0143 Multiple Frames Film Scanner-36series - 0180 Plustek Scanner - 0182 Wize Media 1000 - 0189 ScanJet 4600 series - 018a Xerox 6400 - 0300 GLUSB98PT Parallel Port - 0301 USB2LPT Cable Release2 - 0406 Hub - 0501 GL620USB Host-Host interface - 0502 GL620USB GeneLink USB-USB Bridge - 0504 HID Keyboard Filter - 0604 USB 1.1 Hub - 0605 USB 2.0 Hub [ednet] - 0606 USB 2.0 Hub / D-Link DUB-H4 USB 2.0 Hub - 0608 USB-2.0 4-Port HUB - 0660 USB 2.0 Hub - 0700 SIIG US2256 CompactFlash Card Reader - 0701 USB 2.0 IDE Adapter - 0702 USB 2.0 IDE Adapter - 0703 Card Reader - 0704 Card Reader - 0705 Card Reader - 0706 Card Reader - 0707 Card Reader - 0708 Card Reader - 0709 Card Reader - 070a Pen Flash - 070b DMHS1B Rev 3 DFU Adapter - 070e X-PRO CR20xA USB 2.0 Internal Card Reader - 070f Pen Flash - 0710 USB 2.0 33-in-1 Card Reader - 0711 Card Reader - 0712 Delkin Mass Storage Device - 0715 USB 2.0 microSD Reader - 0760 USB 2.0 Card Reader/Writer - 0761 Genesys Mass Storage Device - 0780 USBFS DFU Adapter - 07a0 Pen Flash - 0927 Card Reader - 1205 Afilias Optical Mouse H3003 - a700 Pen Flash - f102 VX7012 TV Box - f103 VX7012 TV Box - f104 VX7012 TV Box - fd21 3M TL20 Temperature Logger - fe00 Razer Mouse -05e4 Red Wing Corp. -05e5 Fuji Electric Co., Ltd -05e6 Keithley Instruments -05e8 ICC, Inc. -05e9 Kawasaki LSI - 0008 KL5KUSB101B Ethernet [klsi] - 0009 Sony 10Mbps Ethernet [pegasus] - 000c USB-to-RS-232 - 000d USB-to-RS-232 - 0014 RS-232 J104 - 0040 Ethernet Adapter - 2008 Ethernet Adapter -05eb FFC, Ltd -05ec COM21, Inc. -05ee Cytechinfo Inc. -05ef AVB, Inc. [anko?] - 020a Top Shot Pegasus Joystick - 8884 Mag Turbo Force Wheel - 8888 Top Shot Force Feedback Racing Wheel -05f0 Canopus Co., Ltd - 0101 DA-Port DAC -05f1 Compass Communications -05f2 Dexin Corp., Ltd - 0010 AQ Mouse -05f3 PI Engineering, Inc. - 0007 Kinesis Advantage PRO MPC/USB Keyboard - 0081 Kinesis Integrated Hub - 020b PS2 Adapter - 0232 X-Keys Switch Interface, Programming Mode - 0261 X-Keys Switch Interface, SPLAT Mode - 0264 X-Keys Switch Interface, Composite Mode -05f5 Unixtar Technology, Inc. -05f6 AOC International -05f7 RFC Distribution(s) PTE, Ltd -05f9 PSC Scanning, Inc. -05fa Siemens Telecommunications Systems, Ltd - 3301 Keyboard with PS/2 Mouse Port - 3302 Keyboard - 3303 Keyboard with PS/2 Mouse Port -05fc Harman Multimedia - 7849 Harman/Kardon SoundSticks -05fd InterAct, Inc. - 0239 SV-239 HammerHead Digital - 0251 Raider Pro - 0253 ProPad 8 Digital - 0286 SV-286 Cyclone Digital - 262a 3dfx HammerHead FX - 262f HammerHead Fx - daae Game Shark -05fe Chic Technology Corp. - 0001 Mouse - 0003 Cypress USB Mouse - 0005 Viewmaster 4D Browser Mouse - 0007 Twinhead Mouse - 0009 Inland Pro 4500/5000 Mouse - 0011 Browser Mouse - 1010 Optical Wireless -05ff LeCroy Corp. -0600 Barco Display Systems -0601 Jazz Hipster Corp. - 0003 Internet Security Co., Ltd. SecureKey -0602 Vista Imaging, Inc. - 1001 ViCam WebCam -0603 Novatek Microelectronics Corp. - 00f1 Keyboard - 6871 Mouse -0604 Jean Co., Ltd -0605 Anchor C&C Co., Ltd -0606 Royal Information Electronics Co., Ltd -0607 Bridge Information Co., Ltd -0608 Genrad Ads -0609 SMK Manufacturing, Inc. - 031d eHome Infrared Receiver - 0322 eHome Infrared Receiver - ff12 SMK Bluetooth Device -060a Worthington Data Solutions, Inc. -060b Solid Year - 0001 MacAlly Keyboard - 1006 Japanese Keyboard - 260U - 2101 Keyboard - 5811 ACK-571U Wireless Keyboard - 5903 Japanese Keyboard - 595U - 6001 SolidTek USB 2p HUB - 6002 SolidTek USB Keyboard - 6003 Japanese Keyboard - 600HM - a001 Maxwell Compact Pc PM3 -060c EEH Datalink GmbH -060d Auctor Corp. -060e Transmonde Technologies, Inc. -060f Joinsoon Electronics Mfg. Co., Ltd -0610 Costar Electronics, Inc. -0611 Totoku Electric Co., Ltd -0613 TransAct Technologies, Inc. -0614 Bio-Rad Laboratories -0615 Quabbin Wire & Cable Co., Inc. -0616 Future Techno Designs PVT, Ltd -0617 Swiss Federal Insitute of Technology -0618 MacAlly - 0101 Mouse -0619 Seiko Instruments, Inc. - 0101 SLP-100 Driver - 0102 SLP-200 Driver - 0103 SLP-100N Driver - 0104 SLP-200N Driver - 0105 SLP-240 Driver -061a Veridicom International, Inc. - 0110 5thSense Fingerprint Sensor - 0200 FPS200 Fingerprint Sensor - 8200 VKI-A Fingerprint Sensor/Flash Storage (dumb) - 9200 VKI-B Fingerprint Sensor/Flash Storage (smart) -061b Promptus Communications, Inc. -061c Act Labs, Ltd -061d Quatech, Inc. -061e Nissei Electric Co. - 0001 nissei 128DE-USB - - 0010 nissei 128DE-PNA - -0620 Alaris, Inc. - 0004 QuickVideo weeCam - 0007 QuickVideo weeCam - 000a QuickVideo weeCam - 000b QuickVideo weeCam -0621 ODU-Steckverbindungssysteme GmbH & Co. KG -0622 Iotech, Inc. -0623 Littelfuse, Inc. -0624 Avocent Corp. -0625 TiMedia Technology Co., Ltd -0626 Nippon Systems Development Co., Ltd -0627 Adomax Technology Co., Ltd -0628 Tasking Software, Inc. -0629 Zida Technologies, Ltd -062a Creative Labs - 0000 Optical mouse - 0001 Notebook Optical Mouse - 0201 Defender Office Keyboard (K7310) S Zodiak KM-9010 - 9003 VoIP Conference Hub (A16GH) - 9004 USR9602 USB Internet Mini Phone -062b Greatlink Electronics Taiwan, Ltd -062c Institute for Information Industry -062d Taiwan Tai-Hao Enterprises Co., Ltd -062e Mainsuper Enterprises Co., Ltd -062f Sin Sheng Terminal & Machine, Inc. -0631 JUJO Electronics Corp. -0633 Cyrix Corp. -0634 Micron Technology, Inc. -0635 Methode Electronics, Inc. -0636 Sierra Imaging, Inc. - 0003 Vivicam 35Xx -0638 Avision, Inc. - 0268 iVina 1200U Scanner - 026a Minolta Dimage Scan Dual II - 0a10 iVina FB1600/UMAX Astra 4500 - 0a13 AV600U - 0a16 SC-215 - 0a30 UMAX Astra 6700 Scanner - 0a41 Avision AM3000/MF3000 Series - 0f01 fi-4010CU - 4004 Minolta Dimage Scan Elite II -0639 Chrontel, Inc. -063a Techwin Corp. -063b Taugagreining HF -063c Yamaichi Electronics Co., Ltd (Sakura) -063d Fong Kai Industrial Co., Ltd -063e RealMedia Technology, Inc. -063f New Technology Cable, Ltd -0640 Hitex Development Tools -0641 Woods Industries, Inc. -0642 VIA Medical Corp. -0644 TEAC Corp. - 0000 Floppy - 1000 CD-ROM Drive - 800d TASCAM Portastudio DP-01FX - d001 CD-R/RW Unit - d002 CD-R/RW Unit - d010 CD-RW/DVD Unit -0645 Who? Vision Systems, Inc. -0646 UMAX -0647 Acton Research Corp. - 0100 ARC SpectraPro UV/VIS/IR Monochromator/Spectrograph - 0101 ARC AM-VM Mono Airpath/Vacuum Monochromator/Spectrograph - 0102 ARC Inspectrum Mono - 0103 ARC Filterwheel - 03e9 Inspectrum 128x1024 F VIS Spectrograph - 03ea Inspectrum 256x1024 F VIS Spectrograph - 03eb Inspectrum 128x1024 B VIS Spectrograph - 03ec Inspectrum 256x1024 B VIS Spectrograph -0648 Inside Out Networks -0649 Weli Science Co., Ltd -064b White Mountain DSP, Inc. -064c Ji-Haw Industrial Co., Ltd -064d TriTech Microelectronics, Ltd -064e Suyin Corp. -064f WIBU-Systems AG - 0bd7 BOX/U - 0bd8 BOX/RU -0650 Dynapro Systems -0651 Likom Technology Sdn. Bhd. -0652 Stargate Solutions, Inc. -0653 CNF, Inc. -0654 Granite Microsystems, Inc. - 0005 Device Bay Controller - 0006 Hub - 0007 Device Bay Controller - 0016 Hub -0655 Space Shuttle Hi-Tech Co., Ltd -0656 Glory Mark Electronic, Ltd -0657 Tekcon Electronics Corp. -0658 Sigma Designs, Inc. -0659 Aethra -065a Optoelectronics Co., Ltd - 0001 Barcode scanner -065b Tracewell Systems -065e Silicon Graphics -065f Good Way Technology Co., Ltd & GWC technology Inc. -0660 TSAY-E (BVI) International, Inc. -0661 Hamamatsu Photonics K.K. -0662 Kansai Electric Co., Ltd -0663 Topmax Electronic Co., Ltd - 0103 CobraPad -0667 Aiwa Co., Ltd - 0fa1 TD-U8000 Tape Drive -0668 WordWand -0669 Oce' Printing Systems GmbH -066a Total Technologies, Ltd -066b Linksys, Inc. - 0105 SCM eUSB SmartMedia Card Reader - 010a Melco MCR-U2 SmartMedia / CompactFlash Reader - 200c USB10TX - 2202 USB10TX Ethernet [pegasus] - 2203 USB100TX Ethernet [pegasus] - 2204 USB100TX HomePNA Ethernet [pegasus] - 2206 USB Ethernet [pegasus] - 2207 HomeLink Phoneline 10M Network Adapter - 2211 WUSB11 802.11b Adapter - 2212 WUSB11v2.5 802.11b Adapter - 2213 WUSB12v1.1 802.11b Adapter - 2219 Instant Wireless Network Adapter - 400b USB10TX -066d Entrega, Inc. -066e Acer Semiconductor America, Inc. -066f SigmaTel, Inc. - 003b MP3 Player - 003e MP3 Player - 003f MP3 Player - 0040 MP3 Player - 0041 MP3 Player - 0042 MP3 Player - 0043 MP3 Player - 004b A-Max PA11 MP3 Player - 3400 STMP3400 D-Major MP3 Player - 3410 STMP3410 D-Major MP3 Player - 3500 Player Recovery Device - 4200 STIr4200 IrDA Bridge - 4210 STIr4210 IrDA Bridge - 8000 MSCN MP3 Player - 8001 SigmaTel MSCN Audio Player - 8004 MSCNMMC MP3 Player - 8008 i-Bead 100 MP3 Player - 8020 MP3 Player - 8034 MP3 Player - 8036 MP3 Player - 8038 MP3 Player - 8056 MP3 Player - 8060 MP3 Player - 8066 MP3 Player - 807e MP3 Player - 8092 MP3 Player - 8096 MP3 Player - 809a MP3 Player - 80aa MP3 Player - 80ac MP3 Player - 80b8 MP3 Player - 80ba MP3 Player - 80bc MP3 Player - 80bf MP3 Player - 80c5 MP3 Player - 80c8 MP3 Player - 80ca MP3 Player - 80cc MP3 Player - 8104 MP3 Player - 8106 MP3 Player - 8108 MP3 Player - 810a MP3 Player - 810c MP3 Player - 8122 MP3 Player - 8124 MP3 Player - 8126 MP3 Player - 8128 MP3 Player - 8134 MP3 Player - 8136 MP3 Player - 8138 MP3 Player - 813a MP3 Player - 813e MP3 Player - 8140 MP3 Player - 8142 MP3 Player - 8144 MP3 Player - 8146 MP3 Player - 8148 MP3 Player - 814c MP3 Player - 8201 MP3 Player - 8202 Jens of Sweden / I-BEAD 150M/150H MP3 player - 8203 MP3 Player - 8204 MP3 Player - 8205 MP3 Player - 8206 Digital MP3 Music Player - 8207 MP3 Player - 8208 MP3 Player - 8209 MP3 Player - 820a MP3 Player - 820b MP3 Player - 820c MP3 Player - 820d MP3 Player - 820e MP3 Player - 820f MP3 Player - 8210 MP3 Player - 8211 MP3 Player - 8212 MP3 Player - 8213 MP3 Player - 8214 MP3 Player - 8215 MP3 Player - 8216 MP3 Player - 8217 MP3 Player - 8218 MP3 Player - 8219 MP3 Player - 821a MP3 Player - 821b MP3 Player - 821c MP3 Player - 821d MP3 Player - 821e MP3 Player - 821f MP3 Player - 8220 MP3 Player - 8221 MP3 Player - 8222 MP3 Player - 8223 MP3 Player - 8224 MP3 Player - 8225 MP3 Player - 8226 MP3 Player - 8227 MP3 Player - 8228 MP3 Player - 8229 MP3 Player - 8230 MP3 Player - 9000 MP3 Player - 9001 MP3 Player - 9002 MP3 Player -0672 Labtec, Inc. - 1041 LCS1040 Speaker System - 5000 SpaceBall 4000 FLX -0673 HCL - 5000 Keyboard -0674 Key Mouse Electronic Enterprise Co., Ltd -0675 Draytech - 0110 Vigor 128 ISDN TA - 0550 Vigor550 -0676 Teles AG -0677 Aiwa Co., Ltd - 07d5 TM-ED1285(USB) - 0fa1 TD-U8000 Tape Drive -0678 ACard Technology Corp. -067b Prolific Technology, Inc. - 0000 PL2301 USB-USB Bridge - 0001 PL2302 USB-USB Bridge - 04bb PL2303 Serial (IODATA USB-RSAQ2) - 0610 Onext EG210U MODEM - 0611 AlDiga AL-11U Quad-band GSM/GPRS/EDGE modem - 2303 PL2303 Serial Port - 2305 PL2305 Parallel Port - 2307 PL2307 USB-ATAPI4 Bridge - 2313 FITEL PHS U Cable Adaptor - 2315 Flash Disk Embedded Hub - 2316 Flash Disk Security Device - 2317 Mass Storage Device - 2501 PL2501 USB-USB Bridge (USB 2.0) - 2507 PL2507 Hi-speed USB to IDE bridge controller - 2515 Flash Disk Embedded Hub - 2517 Flash Disk Mass Storage Device - 25a1 PL25A1 Host-Host Bridge - 3400 Hi-Speed Flash Disk with TruePrint AES3400 - 3500 Hi-Speed Flash Disk with TruePrint AES3500 - 3507 PL3507 ATAPI6 Bridge - aaa0 Prolific Pharos - aaa2 PL2303 Serial Adapter (IODATA USB-RSAQ3) -067c Efficient Networks, Inc. - 1001 Siemens SpeedStream 100MBps Ethernet - 1022 Siemens SpeedStream 1022 802.11b Adapter - 1023 SpeedStream Wireless - 4020 SpeedStream 4020 ATM/ADSL Installer - 4031 Efficient ADSL Modem - 4032 SpeedStream 4031 ATM/ADSL Installer - 4033 SpeedStream 4031 ATM/ADSL Installer - 4060 Alcatel Speedstream 4060 ADSL Modem - 4062 Efficient Networks 4060 Loader - 5667 Efficient Networks Virtual Bus for ADSL Modem - c031 SpeedStream 4031 ATM/ADSL Installer - c032 SpeedStream 4031 ATM/ADSL Installer - c033 SpeedStream 4031 ATM/ADSL Installer - c060 SpeedStream 4060 Miniport ATM/ADSL Adapter - d667 Efficient Networks Virtual Bus for ADSL Modem - e240 Speedstream Ethernet Adapter E240 - e540 Speedstream Ethernet Adapter E240 -067d Hohner Corp. -067e Intermec - 1001 Mobile Computer -067f Virata, Ltd - 4552 DSL-200 ADSL Modem - 6542 DSL Modem - 6549 DSL Modem - 7541 DSL Modem -0680 Realtek Semiconductor Corp., CPP Div. (Avance Logic) - 0002 Arowana Optical Wheel Mouse MSOP-01 -0681 Siemens Information and Communication Products - 0001 Dect Base - 0002 Gigaset 3075 Passive ISDN - 0005 ID-Mouse with Fingerprint Reader - 0012 I-Gate 802.11b Adapter - 001b WLL013 - 0022 Gigaset SX353 ISDN - 002b A-100-I ADSL Modem - 002e ADSL Router_S-141 - 0034 GSM module MC35/ES75 USB Modem - 3c06 54g USB Network Adapter -0682 Victor Company of Japan, Ltd -0684 Actiontec Electronics, Inc. -0686 Minolta Co., Ltd - 2001 PagePro 4110W - 3001 PagePro 4100 - 3006 PagePro 1250W - 302e Develop D 1650iD PCL - 3034 Develop D 2050iD PCL - 4001 Dimage 2300 - 4003 Dimage 2330 Zoom Camera - 4004 Scan Elite II - 4005 Minolta DiMAGE E201 Mass Storage Device - 4006 Dimage 7 Camera - 4007 Dimage S304 Camera - 4008 Dimage 5 Camera - 4009 Dimage X Camera - 400a Dimage S404 Camera - 400b Dimage 7i Camera - 400c Dimage F100 Camera - 400d Scan Dual III - 400e Dimage 5400 - 400f Dimage 7Hi Camera - 4010 Dimage Xi Camera - 4011 Dimage F300 Camera - 4012 Dimage F200 Camera - 4014 Dimage S414 Camera - 4015 Dimage XT Camera [storage] - 4016 Dimage XT Camera [remote mode] - 4017 Dimage E223 - 4018 Dimage Z1 Camera - 401a Dimage A1 Camera - 401c Dimage X20 Camera - 401e Dimage E323 Camera -068a Pertech, Inc. -068b Potrans International, Inc. -068e CH Products, Inc. - 00e2 HFX OEM Joystick - 00f1 Pro Throttle - 00f2 Flight Sim Pedals - 00f3 Fighterstick - 00ff Flight Sim Yoke - 0500 GameStick 3D - 0501 CH Pro Pedals - 0504 F-16 Combat Stick -0690 Golden Bridge Electech, Inc. -0693 Hagiwara Sys-Com Co., Ltd - 0002 FlashGate SmartMedia Card Reader - 0003 FlashGate CompactFlash Card Reader - 0005 FlashGate - 0006 SM PCCard R/W and SPD - 0007 FlashGate ME (Authenticated) - 000a SDCard/MMC Reader/Writer -0694 Lego Group - 0001 Mindstorms Tower -0698 Chuntex (CTX) - 1786 1300ex Monitor - 9999 VLxxxx Monitor+Hub -0699 Tektronix, Inc. -069a Askey Computer Corp. - 0001 VC010 WebCam [pwc] - 0303 Cable Modem - 0311 ADSL Router Remote NDIS Device - 0318 Remote NDIS Device - 0319 220V Remote NDIS Device - 0320 IEEE 802.11b Wireless LAN Card - 0321 Dynalink WLL013 / Compex WLU11A 802.11b Adapter - 0402 Scientific Atlanta WebSTAR 100 & 200 series Cable Modem - 0811 BT Virtual Bus for Helium - 0821 BT Voyager 1010 802.11b Adapter - 4402 Scientific Atlanta WebSTAR 2000 series Cable Modem - 4403 Scientific Atlanta WebSTAR 300 series Cable Modem - 4501 Scientific-Atlanta WebSTAR 2000 series Cable Modem -069b Thomson, Inc. - 0704 DCM245 Cable Modem - 070c MP3 Player - 070d MP3 Player - 070e MP3 Player - 070f RCA Lyra RD1071 MP3 Player - 2220 RCA Kazoo RD1000 MP3 Player - 300a RCA Lyra MP3 Player - 3012 MP3 Player - 3013 MP3 Player - 5557 RCA CDS6300 -069d Hughes Network Systems (HNS) - 0001 Satellite Receiver Device - 0002 Satellite Device -069e Marx - 0005 CryptoBox v1.2 -069f Allied Data Technologies BV - 0010 Tornado Speakerphone FaxModem 56.0 - 0011 Tornado Speakerphone FaxModem 56.0 - 1000 ADT VvBus for CopperJet -06a2 Topro Technology, Inc. -06a3 Saitek PLC - 0006 Cyborg Gold Joystick - 0109 P880 Pad - 0160 ST290 Pro - 0200 Xbox Adrenalin Hub - 0241 Xbox Adrenalin Gamepad - 0255 X52 Flight Controller - 040b P990 Dual Analog Pad - 040c P2900 Wireless Pad - 0422 ST90 Joystick - 0460 ST290 Pro Flight Stick - 0463 ST290 - 0464 Cyborg Evo - 0471 Cyborg Graphite Stick - 0501 R100 Sports Wheel - 0502 ST200 Stick - 0506 R220 Digital Wheel - 051e Cyborg Digital II Stick - 052d P750 Gamepad - 053c X45 Flight Controller - 053f X36F Flightstick - 056c P2000 Tilt Pad - 056f P2000 Tilt Pad - 05d2 PC Dash 2 - 075c X52 Flight Controller - 0805 R440 Force Wheel - 1003 GM2 Action Pad - 1009 Action Pad - 100a SP550 Pad and Joystick Combo - 100b SP550 Pad - 1509 P3000 Wireless Pad - 1589 P3000 Wireless Pad - 2541 X45 Flight Controller - 3509 P3000 RF GamePad - 353e Cyborg Evo Wireless - 3589 P3000 Wireless Pad - 35be Cyborg Evo - 5509 P3000 Wireless Pad - 8000 Gamers' Keyboard - 801e Cyborg 3D Digital Stick II - 8021 Eclipse II Keyboard - 802d P750 Pad - 803f X36 Flight Controller - 806f P2000 Tilt Pad - 80c0 Pro Gamer Command Unit - a502 Gaming Mouse - ff04 R440 Force Wheel - ff0c Cyborg Force Rumble Pad - ff0d P2600 Rumble Force Pad - ff12 Cyborg 3D Force Stick - ff17 ST 330 Rumble Force Stick - ff52 Cyborg 3D Rumble Force Joystick - ffb5 Cyborg Evo Force Joystick -06a4 Xiamen Doowell Electron Co., Ltd -06a5 Divio - 0000 Typhoon Webcam 100k [nw8000] - d001 ProLink DS3303u WebCam - d800 Chicony TwinkleCam - d820 Wize Media 1000 -06a7 MicroStore, Inc. -06a8 Topaz Systems, Inc. - 0042 SignatureGem 1X5 Pad - 0043 SignatureGem 1X5-HID Pad -06a9 Westell - 0005 WireSpeed Dual Connect Modem - 0006 WireSpeed Dual Connect Modem - 000a WireSpeed Dual Connect Modem - 000b WireSpeed Dual Connect Modem - 000e 802.11g Adapter -06aa Sysgration, Ltd -06ac Fujitsu Laboratories of America, Inc. -06ad Greatland Electronics Taiwan, Ltd -06ae Professional Multimedia Testing Centre -06af Harting, Inc. of North America -06b8 Pixela Corp. -06b9 Alcatel Telecom - 0121 SpeedTouch 121g Wireless Dongle - 2001 SPEED TOUCH Card - 4061 SpeedTouch ISDN or ADSL Modem - a5a5 DynaMiTe Modem -06ba Smooth Cord & Connector Co., Ltd -06bb EDA, Inc. -06bc Oki Data Corp. -06bd AGFA-Gevaert NV - 0001 SnapScan 1212U - 0002 SnapScan 1236U - 0100 SnapScan Touch - 0101 SNAPSCAN ELITE - 0200 ScanMaker 8700 - 02bf DUOSCAN f40 - 0400 CL30 - 0401 Mass Storage - 0403 ePhoto CL18 Camera - 0404 ePhoto CL20 Camera - 2061 SnapScan 1212U (?) - 208d Snapscan e40 - 208f SnapScan e50 - 2091 SnapScan e20 - 2093 SnapScan e10 - 2095 SnapScan e25 - 2097 SnapScan e26 - 20fd SnapScan e52 - 20ff SnapScan e42 -06be AME Optimedia Technology Co., Ltd - 1005 Dazzle DPVM! (1005) - d001 P35U Camera Capture -06bf Leoco Corp. -06c2 Phidgets Inc. (formerly GLAB) - 0030 PhidgetRFID - 0038 4-Motor PhidgetServo v3.0 - 0039 1-Motor PhidgetServo v3.0 - 003a 8-Motor PhidgetAvancedServo - 0040 PhidgetInterface Kit 0-0-4 - 0044 PhidgetInterface Kit 0-16-16 - 0045 PhidgetInterface Kit 8-8-8 - 0048 PhidgetStepper (Under Development) - 0049 PhidgetTextLED Ver 1.0 - 004a PhidgetLED Ver 1.0 - 004b PhidgetEncoder Ver 1.0 - 0051 PhidgetInterface Kit 0-5-7 (Custom) - 0052 PhidgetTextLCD - 0053 PhidgetInterfaceKit 0-8-8 - 0058 PhidgetMotorControl Ver 1.0 - 0070 PhidgetTemperatureSensor Ver 1.0 - 0071 PhidgetAccelerometer Ver 1.0 - 0072 PhidgetWeightSensor Ver 1.0 - 0073 PhidgetHumiditySensor - 0074 PhidgetPHSensor - 0075 PhidgetGyroscope -06c4 Bizlink International Corp. -06c5 Hagenuk, GmbH -06c6 Infowave Software, Inc. -06c8 SIIG, Inc. -06c9 Taxan (Europe), Ltd - 0005 Monitor Control - 0007 Monitor Control - 0009 Monitor Control -06ca Newer Technology, Inc. -06cb Synaptics, Inc. - 0001 HID Device - 0002 HID Device - 0003 HID Device - 0005 Touchpad/FPS - 0006 HID Device - 0007 HID Device - 0008 HID Device - 0009 Composite TouchPad and TrackPoint - 000e HID Device - 0010 Composite Human Interface Device - 0013 Human Interface Device -06cc Terayon Communication Systems - 0101 Cable Modem - 0102 Cable Modem - 0103 Cable Modem - 0104 Cable Modem - 0304 Cable Modem -06cd Keyspan - 0101 USA-28 PDA [no firmware] - 0102 USA-28X PDA [no firmware] - 0103 USA-19 PDA [no firmware] - 0104 PDA [prerenum] - 0105 USA-18X PDA [no firmware] - 0106 USA-19W PDA [no firmware] - 0107 USA-19 PDA - 0108 USA-19W PDA - 0109 USA-49W serial adapter [no firmware] - 010a USA-49W serial adapter - 010b USA-19Qi serial adapter [no firmware] - 010c USA-19Qi serial adapter - 010d USA-19Q serial Adapter (no firmware) - 010e USA-19Q serial Adapter - 010f USA-28 PDA - 0110 USA-28Xb PDA - 0111 USA-18 serial Adapter - 0112 USA-18X PDA - 0113 USA-28Xb PDA [no firmware] - 0114 USA-28Xa PDA [no firmware] - 0115 USA-28Xa PDA - 0116 USA-18XA serial Adapter (no firmware) - 0117 USA-18XA serial Adapter - 0118 USA-19QW PDA [no firmware] - 0119 USA-19QW PDA - 011a USA-49Wlc serial adapter [no firmware] - 011b MPR Serial Preloader (MPRQI) - 011c MPR Serial (MPRQI) - 011d MPR Serial Preloader (MPRQ) - 011e MPR Serial (MPRQ) - 0121 USA-19hs serial adapter - 012a USA-49Wlc serial adapter - 0201 Digital Media Remote - 0202 UIA-11 remote control -06cf SpheronVR AG - 1010 PanoCam 10 - 1012 PanoCam 12/12X -06d0 LapLink, Inc. - 0622 LapLink Gold USB-USB Bridge [net1080] -06d1 Daewoo Electronics Co., Ltd -06d3 Mitsubishi Electric Corp. - 0380 CP8000D Port - 0381 CP770D Port - 0385 CP900D Port - 0387 CP980D Port - 038b CP3020D Port - 038c CP900DW(ID) Port - 0393 CP9500D/DW Port - 0394 CP9000D/DW Port - 03a1 CP9550D/DW Port -06d4 Cisco Systems -06d5 Toshiba - 4000 Japanese Keyboard -06d6 Aashima Technology B.V. - 002d Trust PowerC@m 350FT - 002e Trust PowerC@m 350FS - 0030 Trust 710 LCD POWERC@M ZOOM - MSD - 0031 Trust 710 LCD POWERC@M ZOOM - 003a Trust PowerC@m 770Z - 003c Trust 910z PowerC@m - 003f Trust 735S POWERC@M ZOOM, WDM DSC Bulk Driver - 0050 Trust 738AV LCD PV Digital Camera - 0062 TRUST 782AV LCD P. V. Video Capture - 0066 TRUST Digital PCTV and Movie Editor - 006b TRUST AUDIO VIDEO EDITOR -06d7 Network Computing Devices (NCD) -06d8 Technical Marketing Research, Inc. -06da Phoenixtec Power Co., Ltd - 0002 UPS -06db Paradyne -06dc Foxlink Image Technology Co., Ltd - 0012 Scan 1200c Scanner - 0014 Prolink Winscan Pro 2448U -06de Heisei Electronics Co., Ltd -06e0 Multi-Tech Systems, Inc. - f101 MT5634ZBA-USB MultiModemUSB (old firmware) - f103 MT5634MU MultiMobileUSB - f104 MT5634ZBA-USB MultiModemUSB (new firmware) - f107 MT5634ZBA-USB-V92 MultiModemUSB -06e1 ADS Technologies, Inc. - 0008 UBS-10BT Ethernet [klsi] - 0009 UBS-10BT Ethernet - 0833 Mass Storage Device - a160 Instant Video-To-Go RDX-160 (no firmware) - a161 Instant Video-To-Go RDX-160 - a190 Instand VCD Capture - a191 Instant VideoXpress - a337 Mini DigitalTV - a701 DVD Xpress - b337 Mini DigitalTV - b701 DVD Xpress B -06e4 Alcatel Microelectronics -06e6 Tiger Jet Network, Inc. - 0200 Internet Phone - 0201 Internet Phone - 0202 Composite Device - 0203 Internet Phone - 0210 Composite Device - 0211 Internet Phone - 0212 Internet Phone - 031c Internet Phone - 031d Internet Phone - 031e Internet Phone - 3200 Composite Device - 3201 Internet Phone - 3202 Composite Device - 3203 Composite Device - 7200 Composite Device - 7210 Composite Device - 7250 Composite Device - 825c Internet Phone - 831c Internet Phone - 831d Composite Device - 831e Composite Device - b200 Composite Device - b201 Composite Device - b202 Internet Phone - b210 Internet Phone - b211 Composite Device - b212 Composite Device - b250 Composite Device - b251 Internet Phone - b252 Internet Phone - c200 Internet Phone - c201 Internet Phone - c202 Composite Device - c203 Internet Phone - c210 Personal PhoneGateway - c211 Personal PhoneGateway - c212 Personal PhoneGateway - c213 PPG Device - c25c Composite Device - c290 PPG Device - c291 PPG Device - c292 PPG Device - c293 Personal PhoneGateway - c31c Composite Device - c39c Personal PhoneGateway - c39d PPG Device - c39e PPG Device - c39f PPG Device - c700 Internet Phone - c701 Internet Phone - c702 Composite Device - c703 Internet Phone - c710 VoIP Combo Device - c711 VoIP Combo - c712 VoIP Combo Device - c713 VoIP Combo Device - cf00 Composite Device - cf01 Internet Phone - cf02 Internet Phone - cf03 Composite Device - d210 Personal PhoneGateway - d211 PPG Device - d212 PPG Device - d213 Personal PhoneGateway - d700 Composite Device - d701 Composite Device - d702 Internet Phone - d703 Composite Device - d710 VoIP Combo - d711 VoIP Combo Device - d712 VoIP Combo - d713 VoIP Combo - df00 Composite Device - df01 Composite Device - df02 Internet Phone - df03 Internet Phone - f200 Internet Phone - f201 Internet Phone - f202 Composite Device - f203 Composite Device - f210 Internet Phone - f250 Composite Device - f252 Internet Phone - f310 Internet Phone - f350 Composite Device -06ea Sirius Technologies - 0001 NetCom Roadster II 56k - 0002 Roadster II 56k -06eb PC Expert Tech. Co., Ltd -06ef I.A.C. Geometrische Ingenieurs B.V. -06f0 T.N.C Industrial Co., Ltd - de01 DualCam Video Camera - de02 DualCam Still Camera -06f1 Opcode Systems, Inc. - a011 SonicPort - a021 SonicPort Optical -06f2 Emine Technology Co. - 0011 KVM Switch Keyboard -06f6 Wintrend Technology Co., Ltd -06f7 Wailly Technology Ltd - 0003 USB->Din 4 Adaptor -06f8 Guillemot Corp. - a300 Dual Analog Leader GamePad - b000 Hercules DJ Console - c000 Hercules Muse Pocket - d002 Hercules DJ Console - e000 HWGUSB2-54 WLAN - e010 HWGUSB2-54-LB - e020 HWGUSB2-54V2-AP -06fa HSD S.r.L -06fc Motorola Semiconductor Products Sector -06fd Boston Acoustics - 0101 Audio Device - 0102 Audio Device - 0201 2-piece Audio Device -06fe Gallant Computer, Inc. -0701 Supercomal Wire & Cable SDN. BHD. -0703 Bvtech Industry, Inc. -0705 NKK Corp. -0706 Ariel Corp. -0707 Standard Microsystems Corp. - 0100 2202 Ethernet [klsi] - 0200 2202 Ethernet [pegasus] - 0201 EZ Connect USB Ethernet - ee04 SMCWUSB32 802.11b Wireless LAN Card - ee06 EZ-Connect 802.11g Adapter - ee13 EZ-Connect 802.11g Adapter -0708 Putercom Co., Ltd - 047e USB-1284 BRIDGE -0709 Silicon Systems, Ltd (SSL) -070a Oki Electric Industry Co., Ltd - 4002 Bluetooth Device - 4003 Bluetooth Device -070d Comoss Electronic Co., Ltd -070e Excel Cell Electronic Co., Ltd -0710 Connect Tech, Inc. - 0001 WhiteHeat (fake ID) - 8001 WhiteHeat -0711 Magic Control Technology Corp. - 0100 Hub - 0180 IRXpress Infrared Device - 0181 IRXpress Infrared Device - 0200 BAY-3U1S1P Serial Port - 0210 MCT1S Serial Port - 0230 MCT-232 Serial Port - 0231 PS/2 Mouse Port - 0232 Serial On Port - 0240 PS/2 to USB Converter - 0300 BAY-3U1S1P Parallel Port - 0302 Parallel Port - 0900 SVGA Adapter -0713 Interval Research Corp. -0714 NewMotion, Inc. - 0003 ADB to USB convertor -0717 ZNK Corp. -0718 Imation Corp. - 0002 SuperDisk 120MB - 0003 SuperDisk 120MB (Authenticated) - 0060 Flash Drive - 0061 Flash Drive - 0062 Flash Drive - 0063 Swivel Flash Drive - 0064 Flash Drive - 0065 Flash Drive - 0066 Flash Drive - 0067 Flash Drive - 0068 Flash Drive - 0084 USB Flash Drive Mini -0719 Tremon Enterprises Co., Ltd -071b Domain Technologies, Inc. - 0002 DTI-56362-USB Digital Interface Unit - 0101 Audio4-USB DSP Data Acquisition Unit - 0201 Audio4-5410 DSP Data Acquisition Unit - 0301 SB-USB JTAG Emulator -071c Xionics Document Technologies, Inc. -071d Eicon Networks Corp. - 1000 Diva ISDN TA - 1003 Diva - 2000 Teledat Surf -071e Ariston Technologies -0723 Centillium Communications Corp. - 0002 Palladia 300/400 Adsl Modem -0726 Vanguard International Semiconductor-America -0729 Amitm - 1000 USC-1000 Serial Port -072e Sunix Co., Ltd -072f Advanced Card Systems, Ltd - 0001 AC1030-based SmartCard Reader - 0008 ACR 80 Smart Card Reader - 1000 PLDT Drive - 1001 PLDT Drive - 8002 AET63 BioTRUSTKey - 8003 ACR120 - 8103 ACR120 - 9000 ACR38 AC1038-based Smart Card Reader - 90cc ACR38 SmartCard Reader - 90cf ACR38 SAM Smart Card Reader - 90d0 PertoSmart EMV - Card Reader -0731 Susteen, Inc. - 0528 SonyEricsson DCU-11 Cable -0732 Goldfull Electronics & Telecommunications Corp. -0733 ViewQuest Technologies, Inc. - 0101 Digital Video Camera - 0110 VQ110 - 0401 CS330 WebCam - 0402 M-318B WebCam - 0430 Intel Pro Share WebCam - 0630 VQ630 Dual Mode Digital Camera(Bulk) - 0631 Hercules Dualpix - 0780 Smart Cam Deluxe(composite) - 1310 Epsilon 1.3/Jenoptik JD C1.3/UMAX AstraPix 470 - 1311 Digital Dream Epsilon 1.3 - 2211 Jenoptik -0734 Lasat Communications A/S - 0001 560V Modem - 0002 Lasat 560V Modem - 043a DVS Audio -0735 Asuscom Network - 2100 ISDN Adapter - 2101 ISDN Adapter - 6694 ISDN Adapter - c541 ISDN TA 280 -0736 Lorom Industrial Co., Ltd -0738 Mad Catz, Inc. - 4507 XBox Device - 4516 XBox Device - 4520 XBox Device - 4526 XBox Device - 4536 XBox Device - 4540 XBox Device - 4556 XBox Device - 4566 XBox Device - 4576 XBox Device - 4586 XBox Device - 4588 XBox Device -073a Chaplet Systems, Inc. -073b Suncom Technologies -073d Eutron S.p.a. - 0005 Crypto Token - 0007 CryptoIdentity CCID - 0025 SmartKey 3 - 0c00 Pocket Reader - 0d00 StarSign Bio Token 3.0 EU -073c Industrial Electronic Engineers, Inc. - 0305 Pole Display (PC305-3415 2 x 20 Line Display) - 0322 Pole Display (PC322-3415 2 x 20 Line Display) - 0324 Pole Display (LB324-USB 4 x 20 Line Display) - 0330 Pole Display (P330-3415 2 x 20 Line Display) - 0450 Pole Display (L450-USB Graphic Line Display) - 0505 Pole Display (SPC505-3415 2 x 20 Line Display) - 0522 Pole Display (SPC522-3415 2 x 20 Line Display) - 0624 Pole Display (SP324-3415 2 x 20 Line Display) -073e NEC, Inc. - 0301 Game Pad -0745 Syntech Information Co., Ltd -0746 Onkyo Corp. - 5500 SE-U55 Audio Device -0747 Labway Corp. -0748 Strong Man Enterprise Co., Ltd -0749 EVer Electronics Corp. -074a Ming Fortune Industry Co., Ltd -074b Polestar Tech. Corp. -074c C-C-C Group PLC -074d Micronas GmbH - 3553 Composite USB-Device - 3554 Composite USB-Device - 3556 Composite USB-Device -074e Digital Stream Corp. - 0001 PS/2 Adapter - 0002 PS/2 Adapter -0755 Aureal Semiconductor -0757 Network Technologies, Inc. -075b Sophisticated Circuits, Inc. - 0001 Kick-off! Watchdog -0763 Midiman - 0115 KeyRig 25 - 0117 Trigger Finger - 0119 MidAir - 0150 M-Audio Uno - 0160 M-Audio 1x1 - 0192 M-Audio Keystation 88es - 0193 ProKeys 88 - 0194 ProKeys 88sx - 0195 Oxygen 8 v2 - 0196 Oxygen 49 - 0197 Oxygen 61 - 0198 Axiom 25 - 0199 Axiom 49 - 019a Axiom 61 - 019b KeyRig 49 - 019c KeyStudio - 1001 MidiSport 2x2 - 1002 MidiSport 2x2 - 1003 MidiSport 2x2 - 1010 MidiSport 1x1 - 1011 MidiSport 1x1 - 1014 M-Audio Keystation Loader - 1015 M-Audio Keystation - 1020 Midisport 4x4 - 1021 MidiSport 4x4 - 1030 Midisport 8x8 - 1031 MidiSport 8x8/s Loader - 1033 MidiSport 8x8/s - 1040 M-Audio MidiSport 2x4 Loader - 1041 M-Audio MidiSport 2x4 - 2001 M Audio Quattro - 2002 M Audio Duo - 2003 M Audio AudioPhile - 2004 M-Audio MobilePre - 2006 M-Audio Transit - 2007 M-Audio Sonica Theater - 2008 M-Audio Ozone - 200d M-Audio OmniStudio - 200f M-Audio MobilePre - 2010 M-Audio Fast Track - 2013 M-Audio JamLab - 2015 M-Audio RunTime DFU - 2016 M-Audio RunTime DFU - 2019 M-Audio Ozone Academic - 201a M-Audio Micro - 201b M-Audio RunTime DFU - 201d M-Audio Producer - 2080 M-Audio RunTime DFU - 2081 M-Audio RunTime DFU - 2803 M-Audio Audiophile DFU - 2804 M-Audio MobilePre DFU - 2806 M-Audio Transit DFU - 2815 M-Audio DFU - 2816 M-Audio DFU - 281b M-Audio DFU - 2880 M-Audio DFU - 2881 M-Audio DFU -0764 Cyber Power System, Inc. - 0005 Cyber Power UPS - 0501 CP1500 AVR UPS -0765 X-Rite, Inc. -0766 Jess-Link Products Co., Ltd -0767 Tokheim Corp. -0768 Camtel Technology Corp. - 0006 Camtel Technology USB TV Genie Pro FM Model TVB330 - 0023 eHome Infrared Receiver -0769 Surecom Technology Corp. - 11f2 EP-9001-g 802.11g 54M WLAN Adapter - 11f3 RT2570 - 11f7 802.11g 54M WLAN Adapter - 31f3 RT2573 -076a Smart Technology Enablers, Inc. -076b OmniKey AG - 0596 CardMan 2020 - 1021 CardMan 1021 - 1221 CardMan 1221 - 1784 CardMan 6020 - 3021 CardMan 3121 - 3610 CardMan 3620 - 3621 CardMan 3621 - 3821 CardMan 3821 - 4321 CardMan 4321 - 5121 CardMan 5121 - 5125 CardMan 5125 - 6622 CardMan 6121 - a011 CCID Smart Card Reader Keyboard - a021 CCID Smart Card Reader - a022 CardMan Smart@Link - c000 CardMan 3x21 CS - c001 CardMan 5121 CS -076c Partner Tech -076d Denso Corp. -076e Kuan Tech Enterprise Co., Ltd -076f Jhen Vei Electronic Co., Ltd -0770 Welch Allyn, Inc - Medical Division -0774 AmTRAN Technology Co., Ltd -0775 Longshine Electronics Corp. -0776 Inalways Corp. -0777 Comda Enterprise Corp. -0778 Volex, Inc. -0779 Fairchild Semiconductor -077a Sankyo Seiki Mfg. Co., Ltd -077b Linksys - 08be BEFCMU10 v4 Cable Modem - 2219 WUSB11 V2.6 802.11b Adapter - 2226 USB200M 100baseTX Adapter -077c Forward Electronics Co., Ltd - 0005 NEC Keyboard -077d Griffin Technology - 0223 IMic Audio In/Out - 0405 iMate, ADB Adapter - 0410 PowerMate - 041a PowerWave - 07af iMic - 627a Radio SHARK -077f Well Excellent & Most Corp. -0781 SanDisk Corp. - 0001 SDDR-05a ImageMate CompactFlash Reader - 0002 SDDR-31 ImageMate II CompactFlash Reader - 0005 SDDR-05b (CF II) ImageMate CompactFlash Reader - 0100 ImageMate SDDR-12 - 0200 SDDR-09 (SSFDC) ImageMate SmartMedia Reader [eusb] - 0400 SecureMate SD/MMC Reader - 0621 SDDR-86 Imagemate 6-in-1 Reader - 0720 Sansa C200 series in recovery mode - 0729 Sansa E200 series in recovery mode - 0810 SDDR-75 ImageMate CF-SM Reader - 0830 ImageMate CF/MMC/SD Reader - 1234 Cruzer Mini Flash Drive - 5150 SDCZ2 Cruzer Mini Flash Drive (thin) - 5151 Cruzer Micro 256/512MB Flash Drive - 5153 Cruzer USB-Flash-Drive - 5406 Cruzer Micro 1/4GB Flash Drive - 5408 Cruzer Titanium U3 - 6100 Ultra II SD Plus 2GB - 7100 Cruzer Mini - 7101 Pen Flash - 7102 Cruzer Mini - 7103 Cruzer Mini - 7104 Cruzer Micro Mini 256MB Flash Drive - 7105 Cruzer Mini - 7106 Cruzer Mini - 7112 Cruzer Micro 128MB Flash Drive - 7113 Cruzer Micro 256MB Flash Drive - 7114 Cruzer Mini - 7115 Cruzer Mini - 7420 Sansa E200 series (mtp) - 7421 Sansa E200 series - 7432 Sansa Clip (mtp) - 7433 Sansa Clip (msc) - 7450 Sansa C250 - 7451 Sansa C240 - 7480 Sansa Connect - 7481 Sansa Connect (in recovery mode) - 8181 Pen Flash - 8183 Hi-Speed Mass Storage Device - 8185 SDCZ2 Cruzer Mini Flash Drive (older, thick) - 8888 Card Reader - 8889 SDDR-88 Imagemate 8-in-1 Reader - 8919 Card Reader - 8989 ImageMate 12-in-1 Reader - 9191 ImageMate CF - 9219 Card Reader - 9292 ImageMate CF Reader/Writer - 9393 ImageMate SD-MMC - 9595 ImageMate xD-SM - 9797 ImageMate MS-PRO - 9919 Card Reader - 9999 SDDR-99 5-in-1 Reader - a7e8 SDDR-113 MicroMate SDHC Reader - b2b3 SDDR-103 MobileMate SD+ Reader -0782 Trackerball -0783 C3PO - 0003 LTC31 SmartCard Reader -0784 Vivitar, Inc. - 0100 Vivicam 2655 - 1310 Vivicam 3305 - 1688 Vivicam 3665 - 1689 Gateway DC-M42/Labtec DC-505/Vivitar Vivicam 3705 - 2620 AOL Photocam Plus - 2888 Polaroid DC700 - 3330 Nytec ND-3200 Camera - 4300 Traveler D1 - 5260 Werlisa Sport PX 100 / JVC GC-A33 Camera - 5300 Pretec dc530 -0785 NTT-ME - 0001 MN128mini-V ISDN TA - 0003 MN128mini-J ISDN TA -0789 Logitec Corp. - 0026 LHD Device - 0033 DVD Multi-plus unit LDR-H443SU2 - 0063 LDR Device - 0064 LDR-R Device - 00b3 DVD Multi-plus unit LDR-H443U2 - 010c Realtek RTL8187 Wireless 802.11g 54Mbps Network Adapter -078b Happ Controls, Inc. - 0010 Driving UGCI - 0020 Flying UGCI - 0030 Fighting UGCI -078c GTCO/CalComp - 0400 Digitizer (Whiteboard) -078e Brincom, Inc. -0790 Pro-Image Manufacturing Co., Ltd -0791 Copartner Wire and Cable Mfg. Corp. -0792 Axis Communications AB -0793 Wha Yu Industrial Co., Ltd -0794 ABL Electronics Corp. -0795 RealChip, Inc. -0796 Certicom Corp. -0797 Grandtech Semiconductor Corp. - 6801 Flatbed Scanner - 6802 InkJet Color Printer - 8001 SmartCam - 801a Typhoon StyloCam - 801c Meade Binoculars/Camera - 8901 ScanHex SX-35a - 8909 ScanHex SX-35b - 8911 ScanHex SX-35c -0798 Optelec - 0001 Braille Voyager -079b Sagem - 0027 USB-Serial Controller - 004a XG-760A - 004b Wi-Fi 11g adapter - 0056 Agfa AP1100 Photo Printer - 0062 XG-76NA -079d Alfadata Computer Corp. - 0201 GamePort Adapter -07a1 Digicom S.p.A. - d952 Palladio USB V.92 Modem -07a2 National Technical Systems -07a3 Onnto Corp. -07a4 Be, Inc. -07a6 ADMtek, Inc. - 07c2 AN986A Ethernet - 0986 AN986 Pegasus Ethernet - 8266 Infineon WildCard-USB Wireless LAN Adapter - 8511 ADM8511 Pegasus II Ethernet - 8513 AN8513 Ethernet - 8515 AN8515 Ethernet -07aa Corega K.K. - 0001 Ether USB-T Ethernet [klsi] - 0004 FEther USB-TX Ethernet [pegasus] - 000c WirelessLAN USB-11 - 000d FEther USB-TXS - 0012 Stick-11 802.11b Adapter - 0017 FEther USB2-TX - 001a ULUSB-11 Key - 002f CG-WLUSB2GNL - 7613 Stick-11 V2 802.11b Adapter - 9601 FEther USB-TXC -07ab Freecom Technologies - fc01 IDE bridge - fc02 Cable II USB-2 - fc03 USB2-IDE IDE bridge - fcf8 Freecom Classic SL Network Drive -07af Microtech - 0004 SCSI-DB25 SCSI Bridge [shuttle] - 0005 SCSI-HD50 SCSI Bridge [shuttle] - 0006 CameraMate SmartMedia and CompactFlash Card Reader [eusb/shuttle] - fc01 Freecom USB-IDE -07b0 Trust Technologies - 0001 ISDN TA - 0002 ISDN TA128 Plus - 0003 ISDN TA128 Deluxe - 0005 ISDN TA128 SE - 0006 ISDN TA128 CE - 0007 ISDN TA - 0008 ISDN TA -07b1 IMP, Inc. -07b2 Motorola BCS, Inc. - 0100 SURFboard Voice over IP Cable Modem - 0900 SURFboard Gateway - 0950 SURFboard SBG950 Gateway - 1000 SURFboard SBG1000 Gateway - 4100 SurfBoard SB4100 Cable Modem - 4200 SurfBoard SB4200 Cable Modem - 4210 SurfBoard 4210 Cable Modem - 4220 SURFboard SB4220 Cable Modem - 4500 CG4500 Communications Gateway - 450b CG4501 Communications Gateway - 450e CG4500E Communications Gateway - 5100 SurfBoard SB5100 Cable Modem - 5101 SurfBoard SB5101 Cable Modem - 5120 SurfBoard SB5120 Cable Modem (RNDIS) - 7030 Wireless Adapter WU830G -07b3 Plustek, Inc. - 0001 OpticPro 1212U Scanner - 0003 Scanner - 0010 OpticPro U12 Scanner - 0011 OpticPro U24 Scanner - 0013 OpticPro UT12 Scanner - 0014 Scanner - 0015 OpticPro U24 Scanner - 0017 OpticPro UT12/16/24 Scanner - 0204 Scanner - 0400 OpticPro 1248U Scanner - 0401 OpticPro 1248U Scanner #2 - 0403 OpticPro U16B Scanner - 0404 Scanner - 0405 A8 Namecard-s Controller - 0406 A8 Namecard-D Controller - 0410 Scanner - 0412 Scanner - 0800 OpticPro ST48 Scanner - 0c03 OpticPro ST64+ Scanner -07b4 Olympus Optical Co., Ltd - 0100 Camedia C-2100/C-3000 Ultra Zoom Camera - 0102 Camedia E-10/C-220/C-50 Camera - 0105 Camedia C-310Z/C-700/C-750UZ/C-755/C-765UZ/C-3040/C-4000/C-5050Z/D-560/C-3020Z Zoom Camera - 0109 C-370Z/D-535Z/X-450 - 0112 MAUSB-100 xD Card Reader - 0113 Mju 500 - 0114 C-350Z Camera - 0118 Mju Mini Digital/Mju Digital 500 Camera - 0184 P-S100 port - 0203 Digital Voice Recorder DW-90 - 0206 Digital Voice Recorder DS-330 - 0207 Digital Voice Recorder & Camera W-10 - 0209 Digital Voice Recorder DM-20 - 020d Digital Voice Recorder VN-240PC -07b5 Mega World International, Ltd - 0017 Joystick - 0213 Thrustmaster Firestorm Digital 3 Gamepad - 9902 GamePad -07b6 Marubun Corp. -07b7 TIME Interconnect, Ltd -07b8 D-Link Corp. - 110c XX1 - 1201 IEEE 802.11b Adapter - 200c XX2 - 2573 Wireless LAN Card - 4000 DU-E10 Ethernet [klsi] - 4002 DU-E100 Ethernet [pegasus] - 4003 1/10/100 Ethernet Adapter - 4004 XX4 - 4007 XX5 - 400b XX6 - 400c XX7 - 401a RTL8151 - 4102 USB 1.1 10/100M Fast Ethernet Adapter - 4104 XX9 - 420a UF200 Ethernet - 6001 WL54 - a001 Wireless Network Adapter - abc1 DU-E10 Ethernet [pegasus] - b000 BWU613 - b02a AboCom Bluetooth Device - b02b Bluetooth dongle - b02c BCM92045DG-Flash with trace filter - b02d BCM92045DG-Flash with trace filter - b02e BCM92045DG-Flash with trace filter - b030 BCM92045DG-Flash with trace filter - b031 BCM92045DG-Flash with trace filter - b032 BCM92045DG-Flash with trace filter - b033 BCM92045DG-Flash with trace filter - b21a 802.11g Wireless Adapter - b21b HWU54DM - b21c RT2573 - b21d RT2573 - b21e RT2573 - b21f WUG2700 - d011 MP3 Player - e001 Mass Storage Device - e002 Mass Storage Device - e003 Mass Storage Device - e004 Mass Storage Device - e005 Mass Storage Device - e006 Mass Storage Device - e007 Mass Storage Device - e008 Mass Storage Device - e009 Mass Storage Device - e00a Mass Storage Device - e4f0 Card Reader Driver - f101 DSB-560 Modem [atlas] -07bc Canon Computer Systems, Inc. -07bd Webgear, Inc. -07be Veridicom -07c0 Code Mercenaries Hard- und Software GmbH - 1121 The Claw - 1500 IO-Warrior 40 - 1501 IO-Warrior 24 - 1502 IO-Warrior 48 - 1503 IO-Warrior 28 -07c1 Keisokugiken - 0068 HKS-0200 USBDAQ -07c4 Datafab Systems, Inc. - 0102 USB to LS120 - 0103 USB to IDE - 1234 USB to ATAPI - a000 CompactFlash Card Reader - a001 CompactFlash & SmartMedia Card Reader [eusb] - a002 Disk Drive - a003 Datafab-based Reader - a004 USB to MMC Class Drive - a005 CompactFlash & SmartMedia Card Reader - a006 SmartMedia Card Reader - a007 Memory Stick Class Drive - a103 MDSM-B reader - a107 USB to Memory Stick (LC1) Drive - a109 LC1 CompactFlash & SmartMedia Card Reader - a10b USB to CF+MS(LC1) - a200 DF-UT-06 Hama MMC/SD Reader - a400 CompactFlash & Microdrive Reader - a600 Card Reader - ad01 Mass Storage Device - ae01 Mass Storage Device - af01 Mass Storage Device - b000 USB to CF(LC1) - b001 USB to CF+PCMCIA - b004 MMC/SD Reader - b006 USB to PCMCIA - b00a USB to CF+SD Drive(LC1) - b00b USB to Memory Stick(LC1) -07c5 APG Cash Drawer -07c6 ShareWave, Inc. -07c7 Powertech Industrial Co., Ltd -07c8 B.U.G., Inc. - 0202 MN128-SOHO PAL -07c9 Allied Telesyn International - b100 AT-USB100 -07ca AVerMedia Technologies, Inc. - 0002 AVerTV PVR USB/EZMaker Pro Device - 0026 AVerTV - 1228 MPEG-2 Capture Device (M038) - e880 MPEG-2 Capture Device (E880) - e882 MPEG-2 Capture Device (E882) -07cb Kingmax Technology, Inc. -07cc Carry Computer Eng., Co., Ltd - 0000 CF Card Reader - 0001 Reader (UICSE) - 0002 Reader (UIS) - 0003 SM Card Reader - 0004 SM/CF/PCMCIA Card Reader - 0005 Reader (UISA2SE) - 0006 SM/CF/PCMCIA Card Reader - 0007 Reader (UISA6SE) - 000c SM/CF Card Reader - 000d SM/CF Card Reader - 000e Reader (UISDA) - 000f Reader (UICLIK) - 0010 Reader (UISMA) - 0012 Reader (UISC6SE-FLASH) - 0014 Litronic Fortezza Reader - 0030 Mass Storage (UISDMC12S) - 0040 Mass Storage (UISDMC13S) - 0100 Reader (UID) - 0101 Reader (UIM) - 0102 Reader (UISDMA) - 0103 Reader (UISDMC) - 0104 Reader (UISDM) - 0200 6-in-1 Card Reader - 0201 Mass Storage (UISDMC1S & UISDMC3S) - 0202 Mass Storage (UISDMC5S) - 0203 Mass Storage (UISMC5S) - 0204 Mass Storage (UIM4/5S & UIM7S) - 0205 Mass Storage (UIS4/5S & UIS7S) - 0206 Mass Storage (UISDMC10S & UISDMC11S) - 0207 Mass Storage (UPIDMA) - 0208 Mass Storage (UCFC II) - 0210 Mass Storage (UPIXXA) - 0213 Mass Storage (UPIDA) - 0214 Mass Storage (UPIMA) - 0215 Mass Storage (UPISA) - 0217 Mass Storage (UPISDMA) - 0223 Mass Storage (UCIDA) - 0224 Mass Storage (UCIMA) - 0225 Mass Storage (UIS7S) - 0227 Mass Storage (UCIDMA) - 0234 Mass Storage (UIM7S) - 0235 Mass Storage (UIS4S-S) - 0237 Velper (UISDMC4S) - 0300 6-in-1 Card Reader - 0301 6-in-1 Card Reader - 0303 Mass Storage (UID10W) - 0304 Mass Storage (UIM10W) - 0305 Mass Storage (UIS10W) - 0308 Mass Storage (UIC10W) - 0309 Mass Storage (UISC3W) - 0310 Mass Storage (UISDMA2W) - 0311 Mass Storage (UISDMC14W) - 0320 Mass Storage (UISDMC4W) - 0321 Mass Storage (UISDMC37W) - 0330 WINTERREADER Reader - 0350 9-in-1 Card Reader - 0500 Mass Storage - 0501 Mass Storage -07cd Elektor - 0001 USBuart Serial Port -07cf Casio Computer Co., Ltd - 1001 QV-8000SX/5700/3000EX Digicam; Exilim EX-M20 - 1003 Exilim EX-S500 - 1004 Exilim EX-Z120 - 1011 USB-CASIO PC CAMERA - 2002 E-125 Cassiopeia Pocket PC - 3801 WMP-1 MP3-Watch - 4001 Label Printer KL-P1000 - 4007 CW50 Device - 4104 Cw75 Device - 4107 CW-L300 Device - 4500 LV-20 Digital Camera - 6801 PL-40R - 6802 MIDI Keyboard -07d0 Dazzle - 0001 Digital Video Creator I - 0002 Global Village VideoFX Grabber - 0003 Fusion Model DVC-50 Rev 1 (NTSC) - 0004 DVC-800 (PAL) Grabber - 0005 Fusion Video and Audio Ports - 0006 DVC 150 Loader Device - 0007 DVC 150 - 0327 Fusion Digital Media Reader - 1001 DM-FLEX DFU Adapter - 1002 DMHS2 DFU Adapter - 1102 CF Reader/Writer - 1103 SD Reader/Writer - 1104 SM Reader/Writer - 1105 MS Reader/Writer - 1106 xD/SM Reader/Writer - 1202 MultiSlot Reader/Writer - 2000 FX2 DFU Adapter - 2001 eUSB CompactFlash Reader - 4100 Kingsun SF-620 Infrared Adapter - 4959 Kingsun KS-959 Infrared Adapter -07d1 D-Link System - 13ec VvBus for Helium 2xx - 13ed VvBus for Helium 2xx - 13f1 DSL-302G Modem - 13f2 DSL-502G Router - 3a07 WUA-2340 Adapter - 3a08 predator Bootloader Download - 3a0d DWA-120 Wireless 108G Adapter - 3b01 AirPlus G DWL-G122 Wireless Adapter - 3b10 RangeBooster N Adapter - 3b11 Wireless N Adapter DWA-130 - 3c03 DWL-G122 802.11g Adapter [ralink rt73] - 3c04 WUA-1340 - 3c05 EH103 Wireless G Adapter - 3c07 Wireless G DWA-110 Adapter - 3c09 DWA-140 802.11n Adapter [ralink rt2870] - 5100 Remote NDIS Device - f101 DBT-122 Bluetooth - fc01 DBT-120 Bluetooth Adapter -07d2 Aptio Products, Inc. -07d3 Cyberdata Corp. -07d7 GCC Technologies, Inc. -07da Arasan Chip Systems -07de Diamond Multimedia - 2820 VC500 Video Capture Dongle -07df David Electronics Co., Ltd -07e1 Ambient Technologies, Inc. - 5201 V.90 Modem -07e2 Elmeg GmbH & Co., Ltd -07e3 Planex Communications, Inc. -07e4 Movado Enterprise Co., Ltd - 0967 SCard R/W CSR-145 - 0968 SCard R/W CSR-145 -07e5 QPS, Inc. - 05c2 IDE-to-USB2.0 PCA - 5c01 Que! CDRW -07e6 Allied Cable Corp. -07e7 Mirvo Toys, Inc. -07e8 Labsystems -07ea Iwatsu Electric Co., Ltd -07eb Double-H Technology Co., Ltd -07ec Taiyo Electric Wire & Cable Co., Ltd -07ee Torex Retail (formerly Logware) - 0002 Cash Drawer I/F -07ef STSN - 0001 Internet Access Device -07f6 Circuit Assembly Corp. -07f7 Century Corp. - 0005 ScanLogic/Century Corporation uATA - 011e Century USB Disk Enclosure -07f9 Dotop Technology, Inc. -07fa Draytek - 0778 miniVigor 128 ISDN TA - 1012 BeWAN ADSL USB ST (grey) - a904 BeWAN ADSL - a905 BeWAN ADSL ST -07fd Mark of the Unicorn - 0000 FastLane MIDI Interface - 0001 FastLane Quad MIDI Interface - 0002 MOTU Audio for 64 bit -0801 Mag-Tek - 0002 Mini Swipe Reader -0802 Mako Technologies, LLC -0803 Zoom Telephonics, Inc. - 1300 V92 Faxmodem - 4310 Wireless-G - 5241 Cable Modem - 5551 DSL Modem - 9700 2986L FaxModem - 9800 Cable Modem - a312 Wireless-G -0809 Genicom Technology, Inc. -080a Evermuch Technology Co., Ltd -080c Datalogic S.p.A. - 0300 Gryphon D120 Barcode Scanner - 0400 Gryphon D120 Barcode Scanner - 0500 Gryphon D120 Barcode Scanner - 0600 Gryphon M100 Barcode Scanner -080d Teco Image Systems Co., Ltd - 0102 Hercules Scan@home 48 - 0104 3.2Slim - 0110 UMAX AstraSlim 1200 Scanner -0810 Personal Communication Systems, Inc. -0813 Mattel, Inc. - 0001 Intel Play QX3 Microscope - 0002 Dual Mode Camera Plus -081a MG Logic - 1000 Duo Pen Tablet -081b Indigita Corp. - 0600 Storage Adapter - 0601 Storage Adapter -081c Mipsys -081e AlphaSmart, Inc. - df00 Handheld -0822 Reudo Corp. - 2001 IRXpress Infrared Device -0825 GC Protronics -0826 Data Transit -0827 BroadLogic, Inc. -0828 Sato Corp. -0829 DirecTV Broadband, Inc. (Telocity) -082d Handspring - 0100 Visor - 0200 Treo - 0300 Treo 600 - 0400 Handheld - 0500 Handheld - 0600 Handheld -0830 Palm, Inc. - 0001 m500 - 0002 m505 - 0003 m515 - 0004 Handheld - 0005 Handheld - 0006 Handheld - 0010 Handheld - 0011 Handheld - 0012 Handheld - 0013 Handheld - 0014 Handheld - 0020 i705 - 0021 Handheld - 0022 Handheld - 0023 Handheld - 0024 Handheld - 0030 Handheld - 0031 Tungsten W - 0032 Handheld - 0033 Handheld - 0034 Handheld - 0040 m125 - 0041 Handheld - 0042 Handheld - 0043 Handheld - 0044 Handheld - 0050 m130 - 0051 Handheld - 0052 Handheld - 0053 Handheld - 0054 Handheld - 0060 Tungsten C/E/T/T2/T3 / Zire 71 - 0061 Lifedrive / Treo 650/680 / Tunsten E2/T5/TX / Zire 21/31/72 / Z22 - 0062 Handheld - 0063 Handheld - 0064 Handheld - 0070 Zire - 0071 Handheld - 0072 Handheld - 0080 Serial Adapter [for Palm III] - 0081 Handheld - 0082 Handheld -0832 Kouwell Electronics Corp. - 5850 Cable -0833 Sourcenext Corp. - 012e KeikaiDenwa 8 with charger - 039f KeikaiDenwa 8 -0835 Action Star Enterprise Co., Ltd -0839 Samsung Techwin Co., Ltd - 0005 Digimax Camera - 0008 Digimax 230 Camera - 0009 Digimax 340 - 000a Digimax 410 - 000e Digimax 360 - 0010 Digimax 300 - 1003 Digimax 210SE - 1005 Digimax 220 - 1009 Digimax V4 - 1012 6500 Document Camera - 1058 S730 Camera - 1542 Digimax 50 Duo - 3000 Digimax 35 MP3 -083a Accton Technology Corp. - 1046 10/100 Ethernet [pegasus] - 1060 HomeLine Adapter - 1f4d SMC8013WG Broadband Remote NDIS Device - 3046 10/100 Series Adapter - 3060 1/10/100 Adapter - 3501 2664W - 3502 WN3501D Wireless Adapter - 3503 T-Sinus 111 Wireless Adapter - 4501 T-Sinus 154data - 4505 SMCWUSB-G - 5046 SpeedStream 10/100 Ethernet [pegasus] - 5501 Wireless Adapter 11g - 6500 Cable Modem - 6618 802.11n Wireless Adapter - 7522 802.11N Wireless Adapter - a618 SMC EZ Connect N Draft 11n Wireless Adapter - b004 CPWUE001 USB/Ethernet Adapter - b522 EZ Connect N Draft 11n Wireless USB2.0 Adapter - bb01 BlueExpert Bluetooth Device - c003 802.11b Wireless Adapter - c501 Zoom Wireless-G - c561 802.11a/g Wireless Adapter - e501 ZD1211B - f501 802.11g Wireless Adapter - f502 802.11g Wireless Adapter -083f Global Village - b100 TelePort V.90 Fax/Modem -0840 Argosy Research, Inc. - 0060 Storage Adapter Bridge Module -0841 Rioport.com, Inc. - 0001 Rio 500 -0844 Welland Industrial Co., Ltd -0846 NetGear, Inc. - 1001 EA101 Ethernet [klsi] - 1002 Ethernet - 1020 Ethernet 10/100, USB1.1 - 1040 USB 2.0 Ethernet - 4110 MA111 WiFi (v1) - 4200 WG121 WiFi (v1) - 4210 WG121 WiFi (v2) - 4220 WG111 WiFi (v1) - 4230 MA111 WiFi (v2) - 4240 WG111 WiFi (v2) - 4260 WG111v3 802.11g Adapter [realtek RTL8187B] - 4300 WG111U - 4301 WG111U (no firmware) - 6a00 WG111 WiFi (v2) - 7100 WN121T Wireless Adapter - 9000 RangeMax NEXT Wireless-N Adapter WN111 - a001 PA101 Phoneline10X Adapter -084d Minton Optic Industry Co., Inc. - 0001 Jenoptik JD800i - 0003 S-Cam F5 Digital Camera - 0011 Argus DC3500 Digital Camera - 0014 Praktica DC 32 - 0019 Praktica DPix3000 - 0025 Praktica DC 60 - 1001 ScanHex SX-35d -084e KB Gear - 0001 KBGear JamCam - 1002 Pablo Tablet -084f Empeg - 0001 Empeg-Car Mark I/II Player -0850 Fast Point Technologies, Inc. -0851 Macronix International Co., Ltd - 1542 SiPix Blink - 1543 Maxell WS30 Slim Digital Camera - a168 MXIC -0852 CSEM -0853 Topre Corporation - 0100 HHKB Professional -0854 ActiveWire, Inc. - 0100 I/O Board - 0101 I/O Board, rev1 -0856 B&B Electronics - ac01 uLinks USOTL4 RS422/485 Adapter -0858 Hitachi Maxell, Ltd - 3102 Bluetooth Device - ffff Maxell module with BlueCore in DFU mode -0859 Minolta Systems Laboratory, Inc. -085a Xircom - 0001 Portstation Dual Serial Port - 0003 Portstation Paraller Port - 0008 Ethernet - 0009 Ethernet - 000b Portstation Dual PS/2 Port - 0021 1 port to Serial Converter - 0022 Parallel Port - 0023 2 port to Serial Converter - 0024 Parallel Port - 0027 1 port to Serial Converter - 0028 PortGear to SCSI Converter - 0032 PortStation SCSI Module - 003c Bluetooth Adapter - 0299 Colorvision, Inc. Monitor Spyder - 8021 1 port to Serial - 8023 2 port to Serial - 8027 PGSDB9 Serial Port -085c ColorVision, Inc. - 0200 Monitor Spyder -0862 Teletrol Systems, Inc. -0863 Filanet Corp. -0864 NetGear, Inc. - 4100 MA101 802.11b Adapter - 4102 MA101 802.11b Adapter -0867 Data Translation, Inc. - 9812 ECON Data acquisition unit - 9816 DT9816 ECON data acquisition module - 9836 DT9836 data acquisition card -086a Emagic Soft- und Hardware GmbH - 0001 Unitor8 - 0002 AMT8 - 0003 MT4 -086c DeTeWe - Deutsche Telephonwerke AG & Co. - 1001 Eumex 504PC ISDN TA - 1002 Eumex 504PC (FlashLoad) - 1003 TA33 ISDN TA - 1004 TA33 (FlashLoad) - 1005 Eumex 604PC HomeNet - 1006 Eumex 604PC HomeNet (FlashLoad) - 1007 Eumex 704PC DSL - 1008 Eumex 704PC DSL (FlashLoad) - 1009 Eumex 724PC DSL - 100a Eumex 724PC DSL (FlashLoad) - 100b OpenCom 30 - 100c OpenCom 30 (FlashLoad) - 100d BeeTel Home 100 - 100e BeeTel Home 100 (FlashLoad) - 1011 USB2DECT - 1012 USB2DECT (FlashLoad) - 1013 Eumex 704PC LAN - 1014 Eumex 704PC LAN (FlashLoad) - 1021 OpenCom 40 - 1022 OpenCom 40 (FlashLoad) - 1023 OpenCom 45 - 1024 OpenCom 45 (FlashLoad) - 1025 Sinus 61 data - 1029 dect BOX - 102c Eumex 604PC HomeNet [FlashLoad] - 1030 Eumex 704PC DSL [FlashLoad] - 1032 OpenCom 40 [FlashLoad] - 1033 OpenCom 30 plus - 1034 OpenCom 30 plus (FlashLoad) - 1055 Eumex 220 ISDN TA - 2000 OpenCom 1000 -086e System TALKS, Inc. - 1920 SGC-X2UL -086f MEC IMEX, Inc. -0870 Metricom - 0001 Ricochet GS -0871 SanDisk, Inc. - 0001 SDDR-01 Compact Flash Reader - 0002 SDDR-31 Compact Flash Reader - 0005 SDDR-05 Compact Flash Reader -0873 Xpeed, Inc. -0874 A-Tec Subsystem, Inc. -0879 Comtrol Corp. -087c Adesso/Kbtek America, Inc. -087d Jaton Corp. - 5704 Ethernet -087e Fujitsu Computer Products of America -087f Virtual IP Group, Inc. -0880 APT Technologies, Inc. -0883 Recording Industry Association of America (RIAA) -0885 Boca Research, Inc. -0886 XAC Automation Corp. - 0630 Intel PC Camera CS630 -0887 Hannstar Electronics Corp. -088b MassWorks, Inc. - 4944 MassWorks ID-75 TouchScreen -0892 DioGraphy, Inc. - 0101 Smartdio Reader/Writer -089c United Technologies Research Cntr. -089d Icron Technologies Corp. -089e NST Co., Ltd -089f Primex Aerospace Co. -08a5 e9, Inc. -08a8 Andrea Electronics -08ae Macally (Mace Group, Inc.) -08b4 Sorenson Vision, Inc. -08b8 J. Gordon Electronic Design, Inc. - 01f4 USBSIMM1 -08b9 RadioShack Corp. (Tandy) -08bb Texas Instruments Japan - 2702 Speakers - 2900 PCM2900 Audio Codec - 2904 PCM2904 Audio Codec -08bd Citizen Watch Co., Ltd - 1100 X1-USB Floppy -08c3 Precise Biometrics - 0001 100 SC - 0002 100 A - 0003 100 SC BioKeyboard - 0006 100 A BioKeyboard - 0100 100 MC ISP - 0101 100 MC FingerPrint and SmartCard Reader - 0300 100 AX - 0400 100 SC - 0401 150 MC - 0402 200 MC FingerPrint and SmartCard Reader - 0404 100 SC Upgrade - 0405 150 MC Upgrade - 0406 100 MC Upgrade -08c4 Proxim, Inc. - 02f2 Farallon Home Phoneline Adapter -08c7 Key Nice Enterprise Co., Ltd -08c8 2Wire, Inc. -08c9 Nippon Telegraph and Telephone Corp. -08ca Aiptek International, Inc. - 0010 Tablet - 0020 APT-6000U Tablet - 0021 APT-2 Tablet - 0022 Tablet - 0023 Tablet - 0024 Tablet - 0100 Pen Drive - 0102 DualCam - 0103 Pocket DV Digital Camera - 0104 Pocket DVII - 0105 Mega DV(Disk) - 0106 Pocket DV3100+ - 0107 Pocket DV 3100 - 0109 Nisis DV4 Digital Camera - 010a Trust 738AV LCD PV Mass Storage - 0111 PenCam VGA Plus - 2008 Mini PenCam 2 - 2010 Pocket CAM 3 Mega (webcam) - 2011 Pocket CAM 3 Mega (storage) - 2018 Pencam SD 2 - 2024 Pocket DV3500 - 2042 DV 5100M Composite Device - 2043 DV 5100M(Disk) -08cd Jue Hsun Ind. Corp. -08ce Long Well Electronics Corp. -08cf Productivity Enhancement Products -08d1 smartBridges, Inc. - 0001 smartNIC Ethernet [catc] - 0003 smartNIC 2 PnP Ethernet -08d3 Virtual Ink -08d4 Fujitsu Siemens Computers - 0009 SCR SmartCard Reader -08d9 Increment P Corp. -08dd Billionton Systems, Inc. - 0112 Wireless LAN Adapter - 0113 Wireless LAN Adapter - 0986 USB-100N Ethernet [pegasus] - 0987 USBLP-100 HomePNA Ethernet [pegasus] - 0988 USBEL-100 Ethernet [pegasus] - 1986 10/100 LAN Adapter - 2103 DVB-T TV-Tuner Card-R - 8511 USBE-100 Ethernet [pegasus2] - 90ff USB2AR Ethernet -08de ??? - 7a01 802.11b Adapter -08df Spyrus, Inc. - 0001 Rosetta Token V1 - 0002 Rosetta Token V2 - 0003 Rosetta Token V3 - 0a00 Lynks Interface -08e3 Olitec, Inc. - 0002 USB-RS232 Bridge - 0100 Interface ADSL - 0101 Interface ADSL - 0102 ADSL - 0301 RNIS -08e4 Pioneer Corp. -08e5 Litronic -08e6 Gemplus - 0001 GemPC-Touch 430 - 0430 GemPC430 SmartCard Reader - 0432 GemPC432 SmartCard Reader - 0435 GemPC435 SmartCard Reader - 0437 GemPC433 SL SmartCard Reader - 1359 UA SECURE STORAGE TOKEN - 2202 Gem e-Seal Pro Token - 3437 GemPC Twin SmartCard Reader - 3438 GemPC Key SmartCard Reader - 3478 PinPad Smart Card Reader - 4433 GemPC433-Swap - 5501 GemProx-PU Contactless Smart Card Reader - ace0 UA HYBRID TOKEN -08e7 Pan-International Wire & Cable -08e8 Integrated Memory Logic -08e9 Extended Systems, Inc. - 0100 XTNDAccess IrDA Dongle -08ea Ericsson, Inc., Blue Ridge Labs - 00c9 ADSL Modem HM120dp Loader - 00ca ADSL WAN Modem HM120dp - 00ce HM230d Virtual Bus for Helium - abba USB Driver for Bluetooth Wireless Technology - abbb Bluetooth Device in DFU State -08ec M-Systems Flash Disk Pioneers - 0001 TravelDrive 2C - 0002 TravelDrive 2C - 0005 TravelDrive 2C - 0008 TravelDrive 2C - 0010 DiskOnKey - 0011 DiskOnKey - 0012 TravelDrive 2C - 0014 TravelDrive 2C - 0015 Kingston DataTraveler ELITE - 0016 Kingston DataTraveler U3 - 0020 TravelDrive - 0021 TravelDrive - 0022 TravelDrive - 0023 TravelDrive - 0024 TravelDrive - 0025 TravelDrive - 0026 TravelDrive - 0027 TravelDrive - 0028 TravelDrive - 0029 TravelDrive - 0030 TravelDrive - 0822 TravelDrive 2C - 0832 Hi-Speed Mass Storage Device - 0998 Kingston Data Traveler2.0 Disk Driver - 0999 Kingston Data Traveler2.0 Disk Driver - 1000 TravelDrive 2C - 2000 TravelDrive 2C - 2038 TravelDrive - 2039 TravelDrive - 204a TravelDrive - 204b TravelDrive -08ee CCSI/Hesso -08f0 Corex Technologies -08f1 CTI Electronics Corp. -08f5 SysTec Co., Ltd -08f6 Logic 3 International, Ltd -08f7 Vernier - 0001 LabPro - 0002 EasyTemp -08f8 Keen Top International Enterprise Co., Ltd -08f9 Wipro Technologies -08fa Caere -08fb Socket Communications -08fc Sicon Cable Technology Co., Ltd -08fd Digianswer A/S - 0001 Bluetooth Device -08ff AuthenTec, Inc. - 1600 AES1600 - 1610 AES1600 - 2500 AES2501 - 2501 AES2501 - 2502 AES2501 - 2503 AES2501 - 2504 AES2501 - 2505 AES2501 - 2506 AES2501 - 2507 AES2501 - 2508 AES2501 - 2509 AES2501 - 250a AES2501 - 250b AES2501 - 250c AES2501 - 250d AES2501 - 250e AES2501 - 250f AES2501 - 2510 AES2510 - 2580 AES2501 Fingerprint Sensor - 2588 AES2501 - 2589 AES2501 - 258a AES2501 - 258b AES2501 - 258c AES2501 - 258d AES2501 - 258e AES2501 - 258f AES2501 - 3400 AES3400 TruePrint Sensor - 3401 AES3400 Sensor - 3402 AES3400 Sensor - 3403 AES3400 Sensor - 3404 AES3400 TruePrint Sensor - 3405 AES3400 TruePrint Sensor - 3406 AES3400 TruePrint Sensor - 3407 AES3400 TruePrint Sensor - 4902 BioMV with TruePrint AES3500 - 4903 BioMV with TruePrint AES3400 - 5500 AES4000 - 5501 AES4000 TruePrint Sensor - 5503 AES4000 TruePrint Sensor - 5505 AES4000 TruePrint Sensor - 5507 AES4000 TruePrint Sensor - 55ff AES4000 TruePrint Sensor. - 5700 AES3500 Fingerprint Reader - 5701 AES3500 TruePrint Sensor - 5702 AES3500 TruePrint Sensor - 5703 AES3500 TruePrint Sensor - 5704 AES3500-BZ TruePrint Sensor - 5705 AES3500-BZ TruePrint Sensor - 5706 AES3500-BZ TruePrint Sensor - 5707 AES3500-BZ TruePrint Sensor - 5710 AES3500 TruePrint Sensor - 5711 AES3500 TruePrint Sensor - 5712 AES3500 TruePrint Sensor - 5713 AES3500 TruePrint Sensor - 5714 AES3500-BZ TruePrint Sensor - 5715 AES3500-BZ TruePrint Sensor - 5716 AES3500-BZ TruePrint Sensor - 5717 AES3500-BZ TruePrint Sensor - 5730 AES3500 TruePrint Sensor - 5731 AES3500 TruePrint Sensor - 5732 AES3500 TruePrint Sensor - 5733 AES3500 TruePrint Sensor - 5734 AES3500-BZ TruePrint Sensor - 5735 AES3500-BZ TruePrint Sensor - 5736 AES3500-BZ TruePrint Sensor - 5737 AES3500-BZ TruePrint Sensor - afe3 FingerLoc Sensor Module (Anchor) - afe4 FingerLoc Sensor Module (Anchor) - afe5 FingerLoc Sensor Module (Anchor) - afe6 FingerLoc Sensor Module (Anchor) - fffd AES2510 Sensor (USB Emulator) - ffff Sensor (Emulator) -0900 Pinnacle Systems, Inc. -0901 VST Technologies - 0001 Hard Drive Adapter (TPP) - 0002 SigmaDrive Adapter (TPP) -0906 Faraday Technology Corp. -0909 Audio-Technica Corp. -090a Trumpion Microelectronics, Inc. - 1001 T33520 USB Flash Card Controller - 1100 Comotron C3310 MP3 player - 1200 MP3 player - 1540 Digitex Container Flash Disk -090b Neurosmith -090c Feiya Technology Corp. - 1000 Memory Bar - 1132 5-in-1 Card Reader -090d Multiport Computer Vertriebs GmbH -090e Shining Technology, Inc. -090f Fujitsu Devices, Inc. -0910 Alation Systems, Inc. -0911 Philips Speech Processing - 2512 SpeechMike Pro -0912 Voquette, Inc. -0915 GlobeSpan, Inc. - 0001 DSL Modem - 0002 ADSL ATM Modem - 0005 LAN Modem - 2000 802.11 Adapter - 2002 802.11 Adapter - 8000 ADSL LAN Modem - 8005 DSL-302G Modem - 8101 ADSL WAN Modem - 8102 DSL-200 ADSL Modem - 8103 DSL-200 ADSL Modem - 8104 DSL-200 Modem - 8400 DSL Modem - 8401 DSL Modem - 8402 DSL Modem - 8500 DSL Modem - 8501 DSL Modem -0917 SmartDisk Corp. - 0001 eFilm Reader-11 SM/CF - 0002 eFilm Reader-11 SM - 0003 eFilm Reader-11 CF - 0200 FireFly - 0201 FireLite - 0202 STORAGE ADAPTER (FirePower) - 0204 FlashTrax Storage - 0205 STORAGE ADAPTER (CrossFire) - 0206 FireFly 20G HDD - 0207 FireLite - 020f STORAGE ADAPTER (FireLite) - da01 eFilm Reader-11 Test - ffff eFilm Reader-11 (Class/PDR) -0919 Tiger Electronics - 0100 Fast Flicks Digital Camera -091e Garmin International - 0003 GPSmap (various models) - 0004 Garmin iQue 3600 - 0200 Data Card Programmer (install) - 1200 Data Card Programmer -0920 Echelon Co. - 7500 Network Interface -0921 GoHubs, Inc. - 1001 GoCOM232 Serial -0922 Dymo-CoStar Corp. - 0007 LabelWriter 330 - 0009 LabelWriter 310 -0923 IC Media Corp. - 010f SIIG MobileCam -0924 Xerox - 23dd DocuPrint M760 (X760_USB) - 3d5b Phaser 6115MFP TWAIN Scanner - 420f WorkCentre PE220 Series - 421f M20 Scanner - 423b Printing Support - ffef WorkCenter M15 - fffb DocuPrint M750 (X750_USB) -0925 Lakeview Research - 8101 Phidgets, Inc., 1-Motor PhidgetServo v2.0 - 8104 Phidgets, Inc., 4-Motor PhidgetServo v2.0 - 8800 WiseGroup Ltd, MP-8800 Quad Joypad - 8866 WiseGroup Ltd, MP-8866 Dual Joypad -0927 Summus, Ltd -0928 Oxford Semiconductor, Ltd -0929 American Biometric Co. -092a Toshiba Information & Industrial Sys. And Services -092b Sena Technologies, Inc. -092f Northern Embedded Science/CAVNEX - 0004 JTAG-4 - 0005 JTAG-5 -0930 Toshiba Corp. - 0009 Gigabeat F/X (HDD audio player) - 000c Gigabeat F (mtp) - 0010 Gigabeat S (mtp) - 0301 PCX1100U Cable Modem (WDM) - 0302 PCX2000 Cable Modem (WDM) - 0305 Cable Modem PCX3000 - 0307 Cable Modem PCX2500 - 0308 PCX2200 Cable Modem (WDM) - 0309 PCX5000 Cable Modem (WDM) - 030b Cable Modem PCX2600 - 0501 Bluetooth Controller - 0502 Integrated Bluetooth - 0503 Bluetooth Controller - 0505 Integrated Bluetooth - 0506 Integrated Bluetooth - 0507 Bluetooth Adapter - 0508 Integrated Bluetooth HCI - 0509 BT EDR Dongle - 0706 PocketPC e740 - 0707 Pocket PC e330 Series - 0708 Pocket PC e350 Series - 0709 Pocket PC e750 Series - 070a Pocket PC e400 Series - 070b Pocket PC e800 Series - 1300 Wireless Broadband (CDMA EV-DO) SM-Bus Minicard Status Port - 1301 Wireless Broadband (CDMA EV-DO) Minicard Status Port - 1302 Wireless Broadband (3G HSDPA) SM-Bus Minicard Status Port - 1303 Wireless Broadband (3G HSDPA) Minicard Status Port - 1308 Broadband (3G HSDPA) SM-Bus Minicard Diagnostics Port - 642f TravelDrive - 6506 TravelDrive 2C - 6507 TravelDrive 2C - 6508 TravelDrive 2C - 6509 TravelDrive 2C - 6510 TravelDrive 2C - 6517 TravelDrive 2C - 6518 TravelDrive 2C - 6519 Kingston DataTraveler 2.0 USB Stick - 651a TravelDrive 2C - 651b TravelDrive 2C - 651c TravelDrive 2C - 651d TravelDrive 2C - 651e TravelDrive 2C - 651f TravelDrive 2C - 6520 TravelDrive 2C - 6521 TravelDrive 2C - 6522 TravelDrive 2C - 6523 TravelDrive - 6524 TravelDrive - 6525 TravelDrive - 6526 TravelDrive - 6527 TravelDrive - 6528 TravelDrive - 6529 TravelDrive - 652a TravelDrive - 652b TravelDrive - 652c TravelDrive - 652d TravelDrive - 652f TravelDrive - 6530 TravelDrive - 6531 TravelDrive - 6532 256M USB Stick - 6533 512M USB Stick - 6534 TravelDrive - 653c Kingston DataTraveler 2.0 USB Stick (512M) - 653d Kingston DataTraveler 2.0 USB Stick (1GB) - 653e USB Flash Memory - 6540 TransMemory USB Flash Memory -0931 Harmonic Data Systems, Ltd -0932 Crescentec Corp. - 0300 VideoAdvantage - 0302 Syntek DC-112X - 0320 VideoAdvantage - 1100 Video Enhamcement Device - 1112 Veo Web Camera - a311 Video Enhancement Device -0933 Quantum Corp. -0934 Netcom Systems -0939 Lumberg, Inc. -093a Pixart Imaging, Inc. - 0007 CMOS 100K-R Rev. 1.90 - 010e Digital camera, CD302N/Elta Medi@ digi-cam/HE-501A - 010f Argus DC-1610/DC-1620/Emprex PCD3600/Philips P44417B keychain camera/Precision Mini,Model HA513A/Vivitar Vivicam 55 - 2460 Q-TEC WEBCAM 100 - 2468 Cammaestro 2.5DU/X-EYE/Orite SC-120/ICGear TravelCam/Easy Snap Snake Eye WebCam - 2470 SoC PC-Camera - 2471 SoC PC-Camera - 2500 USB Optical Mouse - 2600 Typhoon Easycam USB 330K (newer)/Typhoon Easycam USB 2.0 VGA 1.3M/Sansun SN-508 - 2601 SPC 610NC Laptop Camera -093b Plextor Corp. - 0010 Storage Adapter - 0011 PlexWriter 40/12/40U - 0042 PX-712UF DVD RW - a002 ConvertX M402U XLOADER - a003 ConvertX AV100U A/V Capture Audio - a004 ConvertX TV402U XLOADER - a005 KWorld EMP Audio Device - a102 ConvertX M402U A/V Capture - a104 ConvertX PX-TV402U/NA -093c Intrepid Control Systems, Inc. - 0601 ValueCAN - 0701 NeoVI Blue vehicle bus interface -093d InnoSync, Inc. -093e J.S.T. Mfg. Co., Ltd -093f Olympia Telecom Vertriebs GmbH -0940 Japan Storage Battery Co., Ltd -0941 Photobit Corp. -0942 i2Go.com, LLC -0943 HCL Technologies India Private, Ltd -0944 KORG, Inc. -0945 Pasco Scientific -0948 Kronauer music in digital - 0301 USB Pro (24/48) - 0302 USB Pro (24/96 playback) - 0303 USB Pro (24/96 record) - 0304 USB Pro (16/48) - 1105 USB One -094b Linkup Systems Corp. -094d Cable Television Laboratories -094f Yano - 0101 U640MO-03 - 05fc METALWEAR-HDD -0951 Kingston Technology - 0008 Ethernet - 000a KNU101TX 100baseTX Ethernet - 1600 Data Traveler II Pen Drive - 1601 Data Traveler II+ Pen Drive - 1602 Data Traveler Mini - 1603 Data Traveler 1GB/2GB Pen Drive -0954 RPM Systems Corp. -0955 NVidia Corp. -0956 BSquare Corp. -0957 Agilent Technologies, Inc. - 0200 E-Video DC-350 Camera - 0202 E-Video DC-350 Camera -0958 CompuLink Research, Inc. -0959 Cologne Chip AG - 2bd0 Intelligent ISDN (Ver. 3.60.04) -095a Portsmith - 3003 Express Ethernet -095b Medialogic Corp. -095c K-Tec Electronics -095d Polycom, Inc. - 0001 Polycom ViaVideo -0967 Acer (??) - 0204 WarpLink 802.11b Adapter -0968 Catalyst Enterprises, Inc. -096e Feitian Technologies, Inc. - 0802 ePass2000 (G&D STARCOS SPK 2.4) -0971 Gretag-Macbeth AG -0973 Schlumberger - 0001 e-gate Smart Card -0974 Datagraphix, a business unit of Anacomp -0975 OL'E Communications, Inc. -0976 Adirondack Wire & Cable -0977 Lightsurf Technologies -0978 Beckhoff GmbH -0979 Jeilin Technology Corp., Ltd - 0224 JL2005A Toy Camera - 0226 JL2005A Toy Camera -097a Minds At Work LLC - 0001 Digital Wallet -097b Knudsen Engineering, Ltd -097c Marunix Co., Ltd -097d Rosun Technologies, Inc. -097f Barun Electronics Co., Ltd -0981 Oak Technology, Ltd -0984 Apricorn - 0200 Hard Drive Storage (TPP) -0985 cab Produkttechnik GmbH & Co KG - 00a3 A3/200 or A3/300 Label Printer -0986 Matsushita Electric Works, Ltd. -098c Vitana Corp. -098d INDesign -098e Integrated Intellectual Property, Inc. -098f Kenwood TMI Corp. -0993 Gemstar eBook Group, Ltd - 0001 REB1100 eBook Reader - 0002 eBook -0996 Integrated Telecom Express, Inc. -099a Zippy Technology Corp. - 610c EL-610 Super Mini Electron luminescent Keyboard -09a3 PairGain Technologies -09a4 Contech Research, Inc. -09a5 VCON Telecommunications -09a6 Poinchips - 8001 Mass Storage Device -09a7 Data Transmission Network Corp. -09a8 Lin Shiung Enterprise Co., Ltd -09a9 Smart Card Technologies Co., Ltd -09aa Intersil Corp. - 1000 Prism GT 802.11b/g Adapter - 3642 Prism 2.x 802.11b Adapter -09ab Japan Cash Machine Co., Ltd. -09ae Tripp Lite -09b2 Franklin Electronic Publishers, Inc. - 0001 eBookman Palm Computer -09b3 Altius Solutions, Inc. -09b4 MDS Telephone Systems -09b5 Celltrix Technology Co., Ltd -09bc Grundig - 0002 MPaxx MP150 MP3 Player -09be MySmart.Com - 0001 MySmartPad -09bf Auerswald GmbH & Co. KG - 00c0 COMpact 2104 ISDN PBX - 00db COMpact 4410/2206 ISDN ISDN - 00f1 COMfort System Telephones -09c1 Arris Interactive LLC - 1337 TOUCHSTONE DEVICE -09c2 Nisca Corp. -09c3 ActivCard, Inc. - 0007 Reader V2 - 0008 SmartCard Reader -09c4 ACTiSYS Corp. - 0011 ACT-IR2000U IrDA Dongle -09c5 Memory Corp. -09cc Workbit Corp. - 0404 BAFO USB-ATA/ATAPI Bridge Controller -09cd Psion Dacom Home Networks, Ltd -09ce City Electronics, Ltd -09cf Electronics Testing Center, Taiwan -09d1 NeoMagic, Inc. -09d2 Vreelin Engineering, Inc. -09d3 Com One - 0001 ISDN TA -09d7 Novatel Wireless - 0100 NovAtel FlexPack GPS receiver -09d9 KRF Tech, Ltd -09da A4 Tech Co., Ltd - 0006 Optical Mouse WOP-35 / Trust 450L Optical Mouse - 000a Port Mouse - 0018 Trust Human Interface Device - 001a Wireless Mouse & RXM-15 Receiver - 002a Wireless Optical Mouse NB-30 -09db Measurement Computing Corp. - 0075 MiniLab 1008 - 0076 PMD-1024 - 007a PMD-1208LS - 0081 USB-1616FS - 0088 USB-1616FS internal hub -09dc Aimex Corp. -09dd Fellowes, Inc. -09df Addonics Technologies Corp. -09e1 Intellon Corp. - 5121 MicroLink dLAN -09e5 Jo-Dan International, Inc. -09e6 Silutia, Inc. -09e7 Real 3D, Inc. -09e8 AKAI Professional M.I. Corp. -09e9 Chen-Source, Inc. -09eb IM Networks, Inc. - 4331 iRhythm Tuner Remote -09ef Xitel - 0101 MD-Port DG2 MiniDisc Interface -09f5 AresCom - 0168 Network Adapter - 0188 LAN Adapter - 0850 Adapter -09f6 RocketChips, Inc. -09f7 Edu-Science (H.K.), Ltd -09f8 SoftConnex Technologies, Inc. -09f9 Bay Associates -09fa Mtek Vision -09fb Altera -09ff Gain Technology Corp. -0a00 Liquid Audio -0a01 ViA, Inc. -0a07 Ontrak Control Systems Inc. - 0064 ADU100 Data Acquisition Interface - 00c8 ADU200 Relay I/O Interface - 00d0 ADU208 Data Acquisition Interface -0a0b Cybex Computer Products Co. -0a11 Xentec, Inc. -0a12 Cambridge Silicon Radio, Ltd - 0001 Bluetooth Dongle (HCI mode) - 0002 Frontline Test Equipment Bluetooth Device - 0003 Nanosira - 0004 Nanosira WHQL Reference Radio - 0005 Nanosira-Multimedia - 0006 Nanosira-Multimedia WHQL Reference Radio - 0007 Nanosira3-ROM - 0008 Nanosira3-ROM - 0009 Nanosira4-EDR WHQL Reference Radio - 000a Nanosira4-EDR-ROM - 000b Nanosira5-ROM - 0043 Bluetooth Device - 0100 Casira with BlueCore2-External Module - 0101 Casira with BlueCore2-Flash Module - 0102 Casira with BlueCore3-Multimedia Module - 0103 Casira with BlueCore3-Flash Module - 0104 Casira with BlueCore4-External Module - 0105 Casira with BlueCore4-Multimedia Module - 1000 Bluetooth Dongle (HID proxy mode) - 1010 Bluetooth Device - 1011 Bluetooth Device - 1012 Bluetooth Device - ffff USB Bluetooth Device in DFU State -0a13 Telebyte, Inc. -0a14 Spacelabs Medical, Inc. -0a15 Scalar Corp. -0a16 Trek Technology (S) PTE, Ltd - 1111 ThumbDrive - 8888 IBM USB Memory Key - 9988 Trek2000 TD-G2 -0a17 Pentax Corp. - 0004 Pentax Optio 330 - 0006 Pentax Optio S - 0007 Pentax Optio 550 - 0009 Pentax Optio 33WR - 000a Pentax Optio 555 - 000c Pentax Optio 43WR (mass storage mode) - 000d Pentax Optio 43WR - 0015 Pentax Optio S40/S5i - 003b Pentax Optio 50 (mass storage mode) - 003d Pentax Optio S55 - 0043 Pentax *ist DL - 0047 Pentax Optio S60 - 0052 Optio 60 Digital Camera - 006e Pentax K10D - 0070 Pentax K100D - 1001 EI2000 Camera powered by Digita! -0a18 Heidelberger Druckmaschinen AG -0a19 Hua Geng Technologies, Inc. -0a21 Medtronic Physio Control Corp. -0a22 Century Semiconductor USA, Inc. -0a2c AK-Modul-Bus Computer GmbH - 0008 GPIO Ports -0a34 TG3 Electronics, Inc. - 0110 Deck 82-key backlit keyboard -0a39 Gilat Satellite Networks, Ltd -0a3a PentaMedia Co., Ltd - 0163 KN-W510U 1.0 Wireless LAN Adapter -0a3c NTT DoCoMo, Inc. -0a3d Varo Vision -0a3f Swissonic AG -0a43 Boca Systems, Inc. -0a46 Davicom Semiconductor, Inc. - 0268 ST268 - 9601 DM9601 To Fast Ethernet Adapter -0a47 Hirose Electric -0a48 I/O Interconnect - 3233 Multimedia Card Reader - 3239 Multimedia Card Reader - 3258 Dane Elec zMate SD Reader - 3259 Dane Elec zMate CF Reader - 5000 MediaGear xD-SM - 500a Mass Storage Device - 500f Mass Storage Device - 5010 Mass Storage Device - 5011 Mass Storage Device - 5014 Mass Storage Device - 5020 Mass Storage Device - 5021 Mass Storage Device - 5022 Mass Storage Device - 5023 Mass Storage Device - 5024 Mass Storage Device - 5025 Mass Storage Device -0a4b Fujitsu Media Devices, Ltd -0a4c Computex Co., Ltd -0a4d Evolution Electronics, Ltd - 0064 MK-225 Driver - 0065 MK-225C Driver - 0066 MK-225C Driver - 0067 MK-425C Driver - 0078 MK-37 Driver - 0079 MK-37C Driver - 007a MK-37C Driver - 008c TerraTec MIDI MASTER - 008d MK-249C Driver - 008e MK-249C MIDI Keyboard - 008f MK-449C Driver - 0090 Keystation 49e Driver - 0091 Keystation 61es Driver - 00a0 MK-361 Driver - 00a1 MK-361C Driver - 00a2 MK-361C Driver - 00a3 MK-461C MIDI Keyboard - 00b5 Keystation Pro 88 Driver - 00d2 E-Keys Driver - 00f0 UC-16 Driver - 00f1 X-Session Driver - 00f5 UC-33e MIDI Controller -0a4e Steinberg Soft-und Hardware GmbH -0a4f Litton Systems, Inc. -0a50 Mimaki Engineering Co., Ltd -0a51 Sony Electronics, Inc. -0a52 Jebsee Electronics Co., Ltd -0a53 Portable Peripheral Co., Ltd - 1000 Scanner - 2000 Q-Scan A6 Scanner - 2001 Q-Scan A6 Scanner - 2013 Media Drive A6 Scanner - 2014 Media Drive A6 Scanner - 2015 BizCardReader 600C - 2016 BizCardReader 600C - 202a Scanshell-CSSN - 3000 Q-Scan A8 Scanner - 3002 Q-Scan A8 Reader - 3015 BizCardReader 300G - 5001 BizCardReader 900C -0a5a Electronics For Imaging, Inc. -0a5b EAsics NV -0a5c Broadcom Corp. - 0201 iLine10(tm) Network Adapter - 2000 Bluetooth Device - 2009 Bluetooth Controller - 200a Bluetooth dongle - 200f Bluetooth Controller - 201d Bluetooth Device - 201e IBM Integrated Bluetooth IV - 2020 Bluetooth Dongle - 2033 BCM2033 Bluetooth - 2035 BCM2035 Bluetooth - 2038 Blutonium Device - 2039 Bluetooth Device - 2045 Bluetooth Controller - 2046 Bluetooth Device - 2047 Bluetooth Device - 205e Bluetooth Device - 2100 Bluetooth 2.0+eDR dongle - 2101 A-Link BlueUsbA2 Bluetooth - 2102 ANYCOM Blue USB-200/250 - 2110 Bluetooth Controller - 2111 ANYCOM Blue USB-UHE 200/250 - 2120 2045 Bluetooth 2.0 USB-UHE Device with trace filter - 2121 BCM2210 Bluetooth - 2122 Bluetooth 2.0+EDR dongle - 2130 2045 Bluetooth 2.0 USB-UHE Device with trace filter - 2131 2045 Bluetooth 2.0 Device with trace filter - 6300 Pirelli Remote NDIS Device -0a5d Diatrend Corp. -0a5f Zebra - 0009 LP2844 Printer - 930a Printer -0a62 MPMan - 0010 MPMan MP-F40 MP3 Player -0a66 ClearCube Technology -0a67 Medeli Electronics Co., Ltd -0a68 Comaide Corp. -0a69 Chroma ate, Inc. -0a6b Green House Co., Ltd - 0001 Compact Flash R/W with MP3 player -0a6c Integrated Circuit Systems, Inc. -0a6d UPS Manufacturing -0a6e Benwin -0a6f Core Technology, Inc. - 0400 Xanboo -0a70 International Game Technology -0a72 Sanwa Denshi -0a7d NSTL, Inc. -0a7e Octagon Systems Corp. -0a80 Rexon Technology Corp., Ltd -0a81 Chesen Electronics Corp. - 0101 Keyboard - 0103 Keyboard - 0203 Mouse - 0205 PS/2 Keyboard+Mouse Adapter -0a82 Syscan - 4600 TravelScan 460/464 -0a83 NextComm, Inc. -0a84 Maui Innovative Peripherals -0a85 Idexx Labs -0a86 NITGen Co., Ltd -0a8d Picturetel -0a8e Japan Aviation Electronics Industry, Ltd - 2011 Filter Driver For JAE XMC R/W -0a90 Candy Technology Co., Ltd -0a91 Globlink Technology, Inc. - 3801 Targus PAKP003 Mouse -0a92 EGO SYStems, Inc. - 0011 SYS WaveTerminal U2A - 0021 GIGAPort - 0031 GIGAPortAG - 0053 AudioTrak Optoplay - 0061 Waveterminal U24 - 0071 MAYA EX7 - 0091 Maya 44 - 00b1 MAYA EX5 - 1000 MIDI Mate - 1010 RoMI/O - 1020 M4U - 1030 M8U - 1090 KeyControl49 - 10a0 KeyControl25 -0a93 C Technologies AB - 0002 C-Pen 10 - 0005 MyPen Light - 000d Input Pen - 0010 C-Pen 20 -0a94 Intersense -0aa3 Lava Computer Mfg., Inc. -0aa4 Develco Elektronik -0aa5 First International Digital - 0002 irock! 500 Series - 0801 MP3 Player -0aa6 Perception Digital, Ltd - 0101 Hercules Jukebox - 1501 Store 'n' Go HD Drive -0aa7 Wincor Nixdorf International GmbH - 0100 POS Keyboard, TA58P-USB - 0101 POS Keyboard, TA85P-USB - 0102 POS Keyboard, TA59-USB - 0103 POS Keyboard, TA60-USB - 0104 SNIkey Keyboard, SNIKey-KB-USB - 0200 Operator Display, BA63-USB - 0201 Operator Display, BA66-USB - 0202 Operator Display & Scanner, XiCheck-BA63 - 0203 Operator Display & Scanner, XiCheck-BA66 - 0204 Graphics Operator Display, BA63GV - 0300 POS Printer (printer class mode), TH210 - 0301 POS Printer (native mode), TH210 - 0302 POS Printer (printer class mode), TH220 - 0303 POS Printer (native mode), TH220 - 0304 POS Printer, TH230 - 0305 Lottery Printer, XiPrintPlus - 0306 POS Printer (printer class mode), TH320 - 0307 POS Printer (native mode), TH320 - 0308 POS Printer (printer class mode), TH420 - 0309 POS Printer (native mode), TH420 - 030a POS Printer, TH200B - 0400 Lottery Scanner, Xiscan S - 0401 Lottery Scanner, Xiscan 3 - 4304 Banking Printer TP07 -0aa8 TriGem Computer, Inc. - 0060 TG 11Mbps WLAN Mini Adapter - 1001 DreamComboM4100 - 3002 InkJet Color Printer - 8001 TG_iMON - 8002 TG_KLOSS - a001 TG_X2 - a002 TGVFD_KLOSS - ffda iMON_VFD -0aa9 Baromtec Co. - f01b Medion MD 6242 MP3 Player -0aaa Japan CBM Corp. -0aab Vision Shape Europe SA -0aac iCompression, Inc. -0aad Rohde & Schwarz GmbH & Co. KG -0aae NEC infrontia Corp. (Nitsuko) -0aaf Digitalway Co., Ltd -0ab0 Arrow Strong Electronics Co., Ltd -0aba Ellisys - 8001 USB Tracker 110 Protocol Analyzer -0abe Stereo-Link - 0101 SL1200 DAC -0ac3 Sanyo Semiconductor Company Micro -0ac4 Leco Corp. -0ac5 I & C Corp. -0ac6 Singing Electrons, Inc. -0ac7 Panwest Corp. -0ac8 Z-Star Microelectronics Corp. - 0301 Web Camera - 0302 ZC0302 WebCam - 0321 USB 2.0 Webcam - 0323 Luxya WC-1200 USB 2.0 Webcam - 301b ZC0301 WebCam - 303b ZC0303 WebCam - 305b ZC0305 WebCam - 307b USB 1.1 WebCam - c002 Visual Communication Camera VGP-VCC1 -0ac9 Micro Solutions, Inc. - 0000 Backpack CD-ReWriter - 0001 BACKPACK 2 Cable - 0010 BACKPACK - 0011 Backpack 40GB Hard Drive - 0110 BACKPACK - 0111 BackPack - 1234 BACKPACK -0aca OPEN Networks Ltd - 1060 OPEN NT1 Plus II -0acc Koga Electronics Co. -0acd ID Tech - 0401 ID TECH Spectrum III Hybrid Smartcard Reader -0ace ZyDAS - 1201 802.11b WiFi - 1211 802.11b/g USB2 WiFi - 1215 WLA-54L WiFi - 1608 ONMI FAXMODEM 56K UNO (ZyXEL) -0acf Intoto, Inc. -0ad0 Intellix Corp. -0ad1 Remotec Technology, Ltd -0ad2 Service & Quality Technology Co., Ltd -0ae3 Allion Computer, Inc. -0ae4 Taito Corp. -0ae7 Neodym Systems, Inc. -0ae8 System Support Co., Ltd -0ae9 North Shore Circuit Design L.L.P. -0aea SciEssence, LLC -0aeb TTP Communications, Ltd -0aec Neodio Technologies Corp. - 2101 SmartMedia Card Reader - 2102 CompactFlash Card Reader - 2103 MMC/SD Card Reader - 2104 MemoryStick Card Reader - 2201 SmartMedia+CompactFlash Card Reader - 2202 SmartMedia+MMC/SD Card Reader - 2203 SmartMedia+MemoryStick Card Reader - 2204 CompactFlash+MMC/SD Card Reader - 2205 CompactFlash+MemoryStick Card Reader - 2206 MMC/SD+MemoryStick Card Reader - 2301 SmartMedia+CompactFlash+MMC/SD Card Reader - 2302 SmartMedia+CompactFlash+MemoryStick Card Reader - 2303 SmartMedia+MMC/SD+MemoryStick Card Reader - 2304 CompactFlash+MMC/SD+MemoryStick Card Reader - 3016 MMC/SD+Memory Stick Card Reader - 3050 ND3050 8-in-1 Card Reader - 3060 1.1 FS Card Reader - 3101 MMC/SD Card Reader - 3102 MemoryStick Card Reader - 3201 MMC/SD+MemoryStick Card Reader - 3216 HS Card Reader - 3260 7-in-1 Card Reader - 5010 ND5010 Card Reader -0af0 Option - 5000 UMTS Card - 6000 GlobeTrotter 3G datacard - 6300 GT 3G Quad UMTS/GPRS Card - 6600 GlobeTrotter 3G+ datacard -0af6 Silver I Co., Ltd -0af7 B2C2, Inc. - 0101 Digital TV USB Receiver (DVB-S/T/C / ATSC) -0af9 Hama, Inc. - 0010 USB SightCam 100 - 0011 Micro Innovations IC50C WebCam -0afc Zaptronix Ltd -0afd Tateno Dennou, Inc. -0afe Cummins Engine Co. -0aff Jump Zone Network Products, Inc. -0b00 INGENICO -0b05 ASUSTek Computer, Inc. - 1101 Mass Storage (UISDMC4S) - 1706 WL-167G 802.11g Adapter [ralink] - 1707 WL-167g Wireless Adapter - 1708 Mass Storage Device - 170b Mass Storage Device - 170c WL-159g - 170d 802.11b/g Wireless Network Adapter - 1712 BT-183 Bluetooth 2.0+EDR adapter - 1715 2045 Bluetooth 2.0 Device with trace filter - 1716 Bluetooth Device - 171b A9T wireless - 171c 802.11b/g Wireless Network Adapter - 1723 WL-167G v2 802.11g Adapter [ralink] - 1724 RT2573 - 1726 Laptop OLED Display - 172a ASUS 802.11n Network Adapter - 172b 802.11n Network Adapter - 1731 ASUS 802.11n Network Adapter - 1732 802.11n Network Adapter - 173c BT-183 Bluetooth 2.0 - 1742 802.11n Network Adapter - 6101 Cable Modem - 620a Remote NDIS Device -0b0c Todos Data System AB - 0009 Todos Argos Mini II Smart Card Reader -0b0e GN Netcom -0b0f AVID Technology -0b10 Pcally -0b11 I Tech Solutions Co., Ltd -0b1e Electronic Warfare Assoc., Inc. (EWA) -0b1f Insyde Software Corp. -0b20 TransDimension, Inc. -0b21 Yokogawa Electric Corp. -0b22 Japan System Development Co., Ltd -0b23 Pan-Asia Electronics Co., Ltd -0b24 Link Evolution Corp. -0b27 Ritek Corp. -0b28 Kenwood Corp. -0b2c Village Center, Inc. -0b30 PNY Technologies, Inc. - 0006 SM Media-Shuttle Card Reader -0b33 Contour Design, Inc. - 0020 ShuttleXpress -0b37 Hitachi ULSI Systems Co., Ltd -0b39 Omnidirectional Control Technology, Inc. - 0109 USB TO Ethernet - 0421 Serial - 0801 USB-Parallel Bridge - 0901 OCT To Fast Ethernet Converter - 0c03 LAN DOCK Serial Converter -0b3a IPaxess -0b3b Tekram Technology Co., Ltd - 0163 TL-WN320G 1.0 WLAN Adapter - 1601 Allnet 0193 802.11b Adapter - 1602 ZyXEL ZyAIR B200 802.11b Adapter - 1612 AIR.Mate 2@net 802.11b Adapter - 1613 802.11b Wireless LAN Adapter - 1620 Allnet USB 2.0 Wireless Network Adapter - 1630 QuickWLAN - 5630 ZD1211 - 6630 ZD1211 -0b3c Olivetti Techcenter - a010 Simple_Way Printer/Scanner/Copier -0b3e Kikusui Electronics Corp. -0b41 Hal Corp. - 0011 Crossam2+USB IR commander -0b43 Play.com, Inc. - 0003 PS2 Controller Converter -0b47 Sportbug.com, Inc. -0b48 TechnoTrend AG - 1003 Technotrend/Hauppauge USB-Nova - 1004 TT-PCline - 1005 Technotrend/Hauppauge USB-Nova - 1006 Technotrend/Hauppauge DEC3000-s - 1007 TT-micro plus Device - 1008 Technotrend/Hauppauge DEC2000-t - 1009 Technotrend/Hauppauge DEC2540-t -0b49 ASCII Corp. - 064f Trance Vibrator -0b4b Pine Corp. Ltd. - 0100 D'music MP3 Player -0b4d Graphtec America, Inc. - 110a Graphtec CC200-20 -0b4e Musical Electronics, Ltd - 6500 MP3 Player - 8028 MP3 Player - 8920 MP3 Player -0b50 Dumpries Co., Ltd -0b51 Comfort Keyboard Co. - 0020 Comfort Keyboard -0b52 Colorado MicroDisplay, Inc. -0b54 Sinbon Electronics Co., Ltd -0b56 TYI Systems, Ltd -0b57 Beijing HanwangTechnology Co., Ltd -0b59 Lake Communications, Ltd -0b5a Corel Corp. -0b5f Green Electronics Co., Ltd -0b60 Nsine, Ltd -0b61 NEC Viewtechnology, Ltd -0b62 Orange Micro, Inc. - 000b Bluetooth Device - 0059 iBOT2 WebCam -0b63 ADLink Technology, Inc. -0b64 Wonderful Wire Cable Co., Ltd -0b65 Expert Magnetics Corp. -0b69 CacheVision -0b6a Maxim Integrated Products -0b6f Nagano Japan Radio Co., Ltd -0b70 PortalPlayer, Inc. - 00ba iRiver H10 20GB -0b71 SHIN-EI Sangyo Co., Ltd -0b72 Embedded Wireless Technology Co., Ltd -0b73 Computone Corp. -0b75 Roland DG Corp. -0b79 Sunrise Telecom, Inc. -0b7a Zeevo, Inc. - 07d0 Bluetooth Dongle -0b7b Taiko Denki Co., Ltd -0b7c ITRAN Communications, Ltd -0b7d Astrodesign, Inc. -0b84 Rextron Technology, Inc. -0b85 Elkat Electronics, Sdn., Bhd. -0b86 Exputer Systems, Inc. - 5100 XMC5100 Zippy Drive - 5110 XMC5110 Flash Drive - 5200 XMC5200 Zippy Drive - 5201 XMC5200 Zippy Drive - 5202 XMC5200 Zippy Drive - 5280 XMC5280 Storage Drive - fff0 ISP5200 Debugger -0b87 Plus-One I & T, Inc. -0b88 Sigma Koki Co., Ltd, Technology Center -0b89 Advanced Digital Broadcast, Ltd -0b95 ASIX Electronics Corp. - 1720 10/100 Ethernet - 1780 AX88178 - 7720 AX88772 -0b96 Sewon Telecom -0b97 O2 Micro, Inc. - 7732 Smart Card Reader - 7761 Oz776 1.1 Hub - 7762 Oz776 SmartCard Reader - 7772 OZ776 CCID Smartcard Reader -0b98 Playmates Toys, Inc. -0b99 Audio International, Inc. -0b9b Dipl.-Ing. Stefan Kunde - 4012 Reflex RC-controller Interface -0b9d Softprotec Co. -0b9f Chippo Technologies -0baf U.S. Robotics - 00e5 USR6000 - 00eb USR1120 802.11b Adapter - 00ec 56K Faxmodem - 00f1 SureConnect ADSL ATM Adapter - 00f2 SureConnect ADSL Loader - 00f5 SureConnect ADSL ATM Adapter - 00f6 SureConnect ADSL Loader - 00f7 SureConnect ADSL ATM Adapter - 00f8 SureConnect ADSL Loader - 00f9 SureConnect ADSL ATM Adapter - 00fa SureConnect ADSL Loader - 00fb SureConnect ADSL Ethernet/USB Router - 0118 U5 802.11g Adapter - 011b Wireless MAXg Adapter - 0121 USR5423 WLAN - 6112 FaxModem Model 5633 -0bb0 Concord Camera Corp. - 0100 Sound Vision Stream - 5007 3340z/Rollei DC3100 -0bb1 Infinilink Corp. -0bb2 Ambit Microsystems Corp. - 0302 WLAN - 6098 USB Cable Modem -0bb3 Ofuji Technology -0bb4 High Tech Computer Corp. - 00ce mmO2 XDA GSM/GPRS Pocket PC - 00cf SPV C500 Smart Phone - 0a01 PocketPC Sync - 0a02 Himalaya GSM/GPRS Pocket PC - 0a03 PocketPC Sync - 0a04 PocketPC Sync - 0a05 PocketPC Sync - 0a06 PocketPC Sync - 0a07 Magician PocketPC SmartPhone / O2 XDA - 0a08 PocketPC Sync - 0a09 PocketPC Sync - 0a0a PocketPC Sync - 0a0b PocketPC Sync - 0a0c PocketPC Sync - 0a0d PocketPC Sync - 0a0e PocketPC Sync - 0a0f PocketPC Sync - 0a10 PocketPC Sync - 0a11 PocketPC Sync - 0a12 PocketPC Sync - 0a13 PocketPC Sync - 0a14 PocketPC Sync - 0a15 PocketPC Sync - 0a16 PocketPC Sync - 0a17 PocketPC Sync - 0a18 PocketPC Sync - 0a19 PocketPC Sync - 0a1a PocketPC Sync - 0a1b PocketPC Sync - 0a1c PocketPC Sync - 0a1d PocketPC Sync - 0a1e PocketPC Sync - 0a1f PocketPC Sync - 0a20 PocketPC Sync - 0a21 PocketPC Sync - 0a22 PocketPC Sync - 0a23 PocketPC Sync - 0a24 PocketPC Sync - 0a25 PocketPC Sync - 0a26 PocketPC Sync - 0a27 PocketPC Sync - 0a28 PocketPC Sync - 0a29 PocketPC Sync - 0a2a PocketPC Sync - 0a2b PocketPC Sync - 0a2c PocketPC Sync - 0a2d PocketPC Sync - 0a2e PocketPC Sync - 0a2f PocketPC Sync - 0a30 PocketPC Sync - 0a31 PocketPC Sync - 0a32 PocketPC Sync - 0a33 PocketPC Sync - 0a34 PocketPC Sync - 0a35 PocketPC Sync - 0a36 PocketPC Sync - 0a37 PocketPC Sync - 0a38 PocketPC Sync - 0a39 PocketPC Sync - 0a3a PocketPC Sync - 0a3b PocketPC Sync - 0a3c PocketPC Sync - 0a3d PocketPC Sync - 0a3e PocketPC Sync - 0a3f PocketPC Sync - 0a40 PocketPC Sync - 0a41 PocketPC Sync - 0a42 PocketPC Sync - 0a43 PocketPC Sync - 0a44 PocketPC Sync - 0a45 PocketPC Sync - 0a46 PocketPC Sync - 0a47 PocketPC Sync - 0a48 PocketPC Sync - 0a49 PocketPC Sync - 0a4a PocketPC Sync - 0a4b PocketPC Sync - 0a4c PocketPC Sync - 0a4d PocketPC Sync - 0a4e PocketPC Sync - 0a4f PocketPC Sync - 0a50 HTC SmartPhone Sync - 0a51 SPV C400 / T-Mobile SDA GSM/GPRS Pocket PC - 0a52 SmartPhone Sync - 0a53 SmartPhone Sync - 0a54 SmartPhone Sync - 0a55 SmartPhone Sync - 0a56 SmartPhone Sync - 0a57 SmartPhone Sync - 0a58 SmartPhone Sync - 0a59 SmartPhone Sync - 0a5a SmartPhone Sync - 0a5b SmartPhone Sync - 0a5c SmartPhone Sync - 0a5d SmartPhone Sync - 0a5e SmartPhone Sync - 0a5f SmartPhone Sync - 0a60 SmartPhone Sync - 0a61 SmartPhone Sync - 0a62 SmartPhone Sync - 0a63 SmartPhone Sync - 0a64 SmartPhone Sync - 0a65 SmartPhone Sync - 0a66 SmartPhone Sync - 0a67 SmartPhone Sync - 0a68 SmartPhone Sync - 0a69 SmartPhone Sync - 0a6a SmartPhone Sync - 0a6b SmartPhone Sync - 0a6c SmartPhone Sync - 0a6d SmartPhone Sync - 0a6e SmartPhone Sync - 0a6f SmartPhone Sync - 0a70 SmartPhone Sync - 0a71 SmartPhone Sync - 0a72 SmartPhone Sync - 0a73 SmartPhone Sync - 0a74 SmartPhone Sync - 0a75 SmartPhone Sync - 0a76 SmartPhone Sync - 0a77 SmartPhone Sync - 0a78 SmartPhone Sync - 0a79 SmartPhone Sync - 0a7a SmartPhone Sync - 0a7b SmartPhone Sync - 0a7c SmartPhone Sync - 0a7d SmartPhone Sync - 0a7e SmartPhone Sync - 0a7f SmartPhone Sync - 0a80 SmartPhone Sync - 0a81 SmartPhone Sync - 0a82 SmartPhone Sync - 0a83 SmartPhone Sync - 0a84 SmartPhone Sync - 0a85 SmartPhone Sync - 0a86 SmartPhone Sync - 0a87 SmartPhone Sync - 0a88 SmartPhone Sync - 0a89 SmartPhone Sync - 0a8a SmartPhone Sync - 0a8b SmartPhone Sync - 0a8c SmartPhone Sync - 0a8d SmartPhone Sync - 0a8e SmartPhone Sync - 0a8f SmartPhone Sync - 0a90 SmartPhone Sync - 0a91 SmartPhone Sync - 0a92 SmartPhone Sync - 0a93 SmartPhone Sync - 0a94 SmartPhone Sync - 0a95 SmartPhone Sync - 0a96 SmartPhone Sync - 0a97 SmartPhone Sync - 0a98 SmartPhone Sync - 0a99 SmartPhone Sync - 0a9a SmartPhone Sync - 0a9b SmartPhone Sync - 0a9c SmartPhone Sync - 0a9d SmartPhone Sync - 0a9e SmartPhone Sync - 0a9f SmartPhone Sync - 0b04 Hermes / TyTN / T-Mobile MDA Vario II / O2 Xda Trion - 0b06 Athena / Advantage x7500 / Dopod U1000 / T-Mobile AMEO - 0b0c Elf / Touch / P3450 / T-Mobile MDA Touch / O2 Xda Nova / Dopod S1 - 0bce Vario MDA -0bb5 Murata Manufacturing Co., Ltd -0bb6 Network Alchemy -0bb7 Joytech Computer Co., Ltd -0bb8 Hitachi Semiconductor and Devices Sales Co., Ltd -0bb9 Eiger M&C Co., Ltd -0bba ZAccess Systems -0bbb General Meters Corp. -0bbc Assistive Technology, Inc. -0bbd System Connection, Inc. -0bc0 Knilink Technology, Inc. -0bc1 Fuw Yng Electronics Co., Ltd -0bc2 Seagate RSS LLC - 2000 Storage Adapter V3 (TPP) -0bc3 IPWireless, Inc. -0bc4 Microcube Corp. -0bc5 JCN Co., Ltd -0bc6 ExWAY, Inc. -0bc7 X10 Wireless Technology, Inc. - 0001 ActiveHome (ACPI-compliant) - 0002 Firecracker Interface (ACPI-compliant) - 0003 VGA Video Sender (ACPI-compliant) - 0004 X10 Receiver - 0005 Wireless Transceiver (ACPI-compliant) - 0006 Wireless Transceiver (ACPI-compliant) - 0007 Wireless Transceiver (ACPI-compliant) - 0008 Wireless Transceiver (ACPI-compliant) - 0009 Wireless Transceiver (ACPI-compliant) - 000a Wireless Transceiver (ACPI-compliant) - 000b Transceiver (ACPI-compliant) - 000c Transceiver (ACPI-compliant) - 000d Transceiver (ACPI-compliant) - 000e Transceiver (ACPI-compliant) - 000f Transceiver (ACPI-compliant) -0bc8 Telmax Communications -0bc9 ECI Telecom, Ltd -0bca Startek Engineering, Inc. -0bcb Perfect Technic Enterprise Co., Ltd -0bd7 Andrew Pargeter & Associates - a021 Amptek DP4 multichannel signal analyzer -0bda Realtek Semiconductor Corp. - 0103 USB 2.0 Card Reader - 0104 Mass Storage Device - 0106 Mass Storage Device - 0107 Mass Storage Device - 0108 Mass Storage Device - 0111 Card Reader - 0113 Mass Storage Device - 0115 Mass Storage Device - 0116 Mass Storage Device - 0117 Mass Storage Device - 0118 Mass Storage Device - 0151 Mass Stroage Device - 0152 Mass Stroage Device - 0153 Mass Stroage Device - 0156 Mass Stroage Device - 0157 Mass Stroage Device - 0158 Mass Stroage Device - 0161 Mass Stroage Device - 0168 Mass Stroage Device - 0169 Mass Stroage Device - 0171 Mass Stroage Device - 0176 Mass Stroage Device - 0178 Mass Stroage Device - 2831 2831U Device - 8150 RTL8150 Fast Ethernet Adapter - 8151 RTL8151 Adapteon Business Mobile Networks BV - 8187 RTL8187 Wireless Adapter - 8189 RTL8187B Wireless 802.11g 54Mbps Network Adapter - 8197 RTL8187B Wireless Adapter -0bdb Ericsson Business Mobile Networks BV - 1000 BV Bluetooth Device - 1002 Bluetooth Device 1.2 -0bdc Y Media Corp. -0bdd Orange PCS -0be2 Kanda Tsushin Kogyo Co., Ltd -0be3 TOYO Corp. -0be4 Elka International, Ltd -0be5 DOME imaging systems, Inc. -0be6 Dong Guan Humen Wonderful Wire Cable Factory -0bee LTK Industries, Ltd -0bef Way2Call Communications -0bf0 Pace Micro Technology PLC -0bf1 Intracom S.A. - 0001 netMod Driver Ver 2.4.17 (CAPI) - 0002 netMod Driver Ver 2.4 (CAPI) - 0003 netMod Driver Ver 2.4 (CAPI) -0bf2 Konexx -0bf6 Addonics Technologies, Inc. - 0103 Storage Device - 1234 Storage Device - a000 Cable 205 (TPP) - a001 Cable 205 - a002 IDE Bridge -0bf7 Sunny Giken, Inc. -0bf8 Fujitsu Siemens Computers - 1001 Fujitsu Pocket Loox 600 PDA -0c04 MOTO Development Group, Inc. -0c05 Appian Graphics -0c06 Hasbro Games, Inc. -0c07 Infinite Data Storage, Ltd -0c08 Agate - 0378 Q 16MB Storage Device -0c09 Comjet Information System - a5a5 Litto Version USB2.0 -0c0a Highpoint Technologies, Inc. -0c0b Dura Micro, Inc. (Acomdata) - 27cb 6-in-1 Flash Reader and Writer - 27d7 Multi Memory reader/writer MD-005 - 27da Multi Memory reader/writer MD-005 - 27dc Multi Memory reader/writer MD-005 - 27e7 3,5'' HDD case MD-231 - 27ee 3,5'' HDD case MD-231 - 2814 3,5'' HDD case MD-231 - 2815 3,5'' HDD case MD-231 - 281d 3,5'' HDD case MD-231 - a109 CF/SM Reader and Writer - a10c SD/MS Reader and Writer - b001 USB 2.0 Mass Storage IDE adapter - b004 MMC/SD Reader and Writer -0c12 Zeroplus - 0005 PSX Vibration Feedback Converter - 8809 Red Octane Ignition Xbox DDR Pad -0c15 Iris Graphics -0c16 Gyration, Inc. - 0080 eHome Infrared Receiver - 0081 eHome Infrared Receiver -0c17 Cyberboard A/S -0c18 SynerTek Korea, Inc. -0c19 cyberPIXIE, Inc. -0c1a Silicon Motion, Inc. -0c1b MIPS Technologies -0c1c Hang Zhou Silan Electronics Co., Ltd -0c22 Tally Printer Corp. -0c23 Lernout + Hauspie -0c24 Taiyo Yuden - 0001 Bluetooth Adaptor - 0002 Bluetooth Device2 - 0005 Bluetooth Device(BC04-External) - 000b Bluetooth Device(BC04-External) - 000c Bluetooth Adaptor - 000e Bluetooth Device(BC04-External) - 000f Bluetooth Driver (V2.0+EDR) - 0010 Bluetooth Device(BC04-External) - 0012 Bluetooth Device(BC04-External) - 0018 Bluetooth Device(BC04-External) - 0019 Bluetooth Device - 0c24 Bluetooth Device(SAMPLE) - ffff Bluetooth module with BlueCore in DFU mode -0c25 Sampo Corp. - 0310 Scream Cam -0c27 RFIDeas, Inc - 3bfa pcProx Card Reader -0c2e Metro - 0200 Metrologic Scanner -0c35 Eagletron, Inc. -0c36 E Ink Corp. -0c37 e.Digital -0c38 Der An Electric Wire & Cable Co., Ltd -0c39 IFR -0c3a Furui Precise Component (Kunshan) Co., Ltd -0c3b Komatsu, Ltd -0c3c Radius Co., Ltd -0c3d Innocom, Inc. -0c3e Nextcell, Inc. -0c44 Motorola iDEN - 0021 iDEN P2k0 Device - 0022 iDEN P2k1 Device - 03a2 iDEN Smartphone -0c45 Microdia - 1020 Mass Storage Reader - 1028 Mass Storage Reader - 1030 Mass Storage Reader - 1031 Sonix Mass Storage Device - 1032 Mass Storage Reader - 1033 Sonix Mass Storage Device - 1034 Mass Storage Reader - 1035 Mass Storage Reader - 1036 Mass Storage Reader - 1037 Sonix Mass Storage Device - 1050 CF Card Reader - 1058 HDD Reader - 1060 iFlash SM-Direct Card Reader - 1061 Mass Storage Reader - 1062 Mass Storage Reader - 1063 Sonix Mass Storage Device - 1064 Mass Storage Reader - 1065 Mass Storage Reader - 1066 Mass Storage Reader - 1067 Mass Storage Reader - 1158 A56AK - 184c VoIP Phone - 6001 Genius VideoCAM NB - 6005 Sweex Mini WebCam - 6007 VideoCAM Eye - 6009 VideoCAM ExpressII - 600d TwinkleCam USB camera - 6011 PC Camera (SN9C102) - 6019 PC Camera (SN9C102) - 6024 VideoCAM ExpressII - 6025 VideoCAM ExpressII - 6028 Typhoon Easycam USB 330K (older) - 6029 Triplex i-mini PC Camera - 602a Meade ETX-105EC Camera - 602b VideoCAM NB 300 - 602c Clas Ohlson TWC-30XOP WebCam - 602d VideoCAM ExpressII - 602e VideoCAM Messenger - 6030 VideoCAM ExpressII - 603f VideoCAM ExpressII - 6040 CCD PC Camera (PC390A) - 606a CCD PC Camera (PC390A) - 607a CCD PC Camera (PC390A) - 607b Win2 PC Camera - 607c CCD PC Camera (PC390A) - 607e CCD PC Camera (PC390A) - 6080 Audio (Microphone) - 6082 VideoCAM Look - 6083 VideoCAM Look - 608c VideoCAM Look - 608e VideoCAM Look - 608f VideoCAM Look - 60a8 VideoCAM Look - 60aa VideoCAM Look - 60ab PC Camera - 60af VideoCAM Look - 60b0 Genius VideoCam Look - 60c0 PC Camera with Mic (SN9C105) - 60c8 Win2 PC Camera - 60cc Composite Device - 60ec Composite Device - 60ef Win2 PC Camera - 60fa PC Camera with Mic (SN9C105) - 60fb Composite Device - 60fc PC Camera with Mic (SN9C105) - 60fe Audio (Microphone) - 6108 Win2 PC Camera - 6122 PC Camera (SN9C110) - 6123 PC Camera (SN9C110) - 612a PC Camera (SN9C110) - 612c PC Camera (SN9C110) - 612e PC Camera (SN9C110) - 612f PC Camera (SN9C110) - 6130 PC Camera (SN9C120) - 6138 Win2 PC Camera - 613a PC Camera (SN9C120) - 613b Win2 PC Camera - 613c PC Camera (SN9C120) - 613e PC Camera (SN9C120) - 6240 PC Camera (SN9C201) - 6242 PC Camera (SN9C201) - 6243 PC Camera (SN9C201) - 6248 PC Camera (SN9C201) - 624b PC Camera (SN9C201) - 624c PC Camera (SN9C201) - 624e PC Camera (SN9C201) - 624f PC Camera (SN9C201) - 6260 PC Camera (SN9C201) - 6270 U-CAM PC Camera NE878 - 627a PC Camera (SN9C201) - 627b PC Camera (SN9C201) - 627c PC Camera (SN9C201) - 627f PC Camera (SN9C201) - 6280 Composite Device - 6282 Audio (Microphone) - 6283 Audio (Microphone) - 6288 Audio (Microphone) - 628a Composite Device - 628b PC Camera (SN9C202) - 628c PC Camera (SN9C202) - 628e Composite Device - 628f Composite Device - 62a0 Audio (Microphone) - 62b0 Audio (Microphone) - 62ba PC Camera (SN9C202) - 62bb PC Camera (SN9C202) - 62bc Composite Device - 62c0 Pavilion Webcam - 8000 DC31VC - 8006 Dual Mode Camera (8006 VGA) - 800a Vivitar Vivicam3350B -0c46 WaveRider Communications, Inc. -0c4b Reiner SCT Kartensysteme GmbH - 0100 cyberJack e-com/pinpad - 0300 cyberJack pinpad(a) -0c52 Sealevel Systems, Inc. - 2101 Serial Converter -0c53 ViewPLUS, Inc. -0c54 Glory, Ltd -0c55 Spectrum Digital, Inc. - 0510 Spectrum Digital XDS510 JTAG Debugger - 0540 SPI540 - 5416 TMS320C5416 DSK - 6416 TMS320C6416 DDB -0c56 Billion Bright, Ltd -0c57 Imaginative Design Operation Co., Ltd -0c58 Vidar Systems Corp. -0c59 Dong Guan Shinko Wire Co., Ltd -0c5a TRS International Mfg., Inc. -0c5e Xytronix Research & Design -0c62 Chant Sincere Co., Ltd -0c63 Toko, Inc. -0c64 Signality System Engineering Co., Ltd -0c65 Eminence Enterprise Co., Ltd -0c66 Rexon Electronics Corp. -0c67 Concept Telecom, Ltd -0c70 MCT Elektronikladen - 0000 USB08 Development board -0c74 Optronic Laboratories Inc. - 0002 OL 700-30 Goniometer -0c76 JMTek, LLC. - 0001 Mass Storage Controller - 0002 Mass Storage Controller - 0003 USBdisk - 0004 Mass Storage Controller - 0005 Transcend USB Flash disk - 0006 Transcend JetFlash - 0007 Mass Storage Device -0c77 Sipix Group, Ltd - 1001 SiPix Web2 - 1002 SiPix SC2100 - 1010 SiPix Snap - 1011 SiPix Blink 2 - 1015 SiPix CAMeleon -0c78 Detto Corp. -0c79 NuConnex Technologies Pte., Ltd -0c7a Wing-Span Enterprise Co., Ltd -0c86 NDA Technologies, Inc. -0c88 Kyocera Wireless Corp. - 0021 Handheld - 17da Qualcomm Kyocera CDMA Technologies MSM -0c89 Honda Tsushin Kogyo Co., Ltd -0c8a Pathway Connectivity, Inc. -0c8b Wavefly Corp. -0c8c Coactive Networks -0c8d Tempo -0c8e Cesscom Co., Ltd - 6000 Luxian Series -0c8f Applied Microsystems -0c98 Berkshire Products, Inc. - 1140 USB PC Watchdog -0c99 Innochips Co., Ltd -0c9a Hanwool Robotics Corp. -0c9b Jobin Yvon, Inc. -0c9d SemTek - 0170 3873 Manual Insert card reader -0ca2 Zyfer -0ca3 Sega Corp. -0ca4 ST&T Instrument Corp. -0ca5 BAE Systems Canada, Inc. -0ca6 Castles Technology Co., Ltd - 0010 EZUSB PC/SC Smart Card Reader - 0050 EZ220PU Reader Controller - 1077 Bludrive Family Smart Card Reader - 107e Reader Controller - 2010 myPad110 PC/SC Smart Card Reader -0ca7 Information Systems Laboratories -0cad Motorola CGISS - 9001 PowerPad Pocket PC Device -0cae Ascom Business Systems, Ltd -0caf Buslink - 2507 Hi-Speed USB-to-IDE Bridge Controller - 2515 Flash Disk Embedded Hub - 2516 Flash Disk Security Device - 2517 Flash Disk Mass Storage Device - 25c7 Hi-Speed USB-to-IDE Bridge Controller - 3a00 Hard Drive - 3a20 Mass Storage Device - 3acd Mass Storage Device -0cb0 Flying Pig Systems -0cb1 Innovonics, Inc. -0cb6 Celestix Networks, Pte., Ltd -0cb7 Singatron Enterprise Co., Ltd -0cb8 Opticis Co., Ltd -0cba Trust Electronic (Shanghai) Co., Ltd -0cbb Shanghai Darong Electronics Co., Ltd -0cbc Palmax Technology Co., Ltd - 0101 Pocket PC P6C - 0201 Personal Digital Assistant - 0301 Personal Digital Assistant P6M+ - 0401 Pocket PC -0cbd Pentel Co., Ltd (Electronics Equipment Div.) -0cbe Keryx Technologies, Inc. -0cbf Union Genius Computer Co., Ltd -0cc0 Kuon Yi Industrial Corp. -0cc1 Given Imaging, Ltd -0cc2 Timex Corp. -0cc3 Rimage Corp. -0cc4 emsys GmbH -0cc5 Sendo -0cc6 Intermagic Corp. -0cc7 Kontron Medical AG -0cc8 Technotools Corp. -0cc9 BroadMAX Technologies, Inc. -0cca Amphenol -0ccb SKNet Co., Ltd -0ccc Domex Technology Corp. -0ccd TerraTec Electronic GmbH - 0012 PHASE 26 - 0013 PHASE 26 - 0014 PHASE 26 - 0015 Flash Update for TerraTec PHASE 26 - 0021 Cameo Grabster 200 - 0023 Mystify Claw - 0028 Aureon 5.1 MkII - 0032 MIDI HUBBLE - 0035 Miditech Play'n Roll - 0036 Cinergy 250 Audio - 0037 Cinergy 250 Audio - 0038 Cinergy T^2 DVB-T Receiver - 0039 Grabster AV 400 - 003b Cinergy 400 - 003c Grabster AV 250 - 0042 Cinergy Hybrid T XS - 0043 Cinergy T XS - 004e Cinergy T XS - 004f Cinergy Analog XS - 005c Cinergy T² - 0069 Cinergy T XE DVB-T Receiver -0cd4 Bang Olufsen - 0101 BeolinkPC2 -0cd7 NewChip S.r.l. -0cd8 JS Digitech, Inc. - 2007 Smart Card Reader/JSTU-9700 -0cd9 Hitachi Shin Din Cable, Ltd -0cde Z-Com - 0001 M4Y-750 - 0002 XI-725/726 Prism2.5 802.11b Adapter - 0003 Sagem 802.11b Dongle - 0004 Sagem 802.11b Dongle - 0005 XI-735 Prism3 802.11b Adapter - 0006 Medion 40900 802.11b Adapter - 0008 Sitecom Wireless Network Adapter 100G+ WL-125 - 0009 (ZD1211)IEEE 802.11b+g Adapter - 0011 ZD1211 - 0012 AR5523 - 0013 AR5523 driver (no firmware) - 0014 NB 802.11g Wireless LAN Adapter(3887A) - 0015 Zoom Wireless-G - 0016 NB 802.11g Wireless LAN Adapter(3887A) - 0018 NB 802.11a/b/g Wireless LAN Adapter(3887A) - 001a ZD1211B - 001c 802.11b/g Wireless Network Adapter - 0020 Wi-Fi Wireless LAN Adapter - 0022 802.11b/g/n Wireless Network Adapter -0ce9 pico Technology - 1001 PicoScope3204 -0cf1 e-Conn Electronic Co., Ltd -0cf2 ENE Technology, Inc. -0cf3 Atheros Communications, Inc. - 0001 AR5523 - 0002 AR5523 (no firmware) - 0003 AR5523 - 0004 AR5523 (no firmware) - 0005 AR5523 - 0006 AR5523 (no firmware) -0cf4 Fomtex Corp. -0cf5 Cellink Co., Ltd -0cf6 Compucable Corp. -0cf7 ishoni Networks -0cf8 Clarisys, Inc. - 0750 Claritel-i750 - vp -0cf9 Central System Research Co., Ltd -0cfa Inviso, Inc. -0cfc Minolta-QMS, Inc. -0cff SAFA MEDIA Co., Ltd. - 0320 SR-380N -0d06 telos EDV Systementwicklung GmbH -0d08 UTStarcom - 0602 DV007 [serial] - 0603 DV007 [storage] -0d0b Contemporary Controls -0d0c Astron Electronics Co., Ltd -0d0d MKNet Corp. -0d0e Hybrid Networks, Inc. -0d0f Feng Shin Cable Co., Ltd -0d10 Elastic Networks - 0001 StormPort (WDM) -0d11 Maspro Denkoh Corp. -0d12 Hansol Electronics, Inc. -0d13 BMF Corp. -0d14 Array Comm, Inc. -0d15 OnStream b.v. -0d16 Hi-Touch Imaging Technologies Co., Ltd - 0001 PhotoShuttle - 0002 Photo Printer 730 series - 0004 Photo Printer 63xPL/PS - 0100 Photo Printer 63xPL/PS - 0102 Photo Printer 64xPS - 0103 Photo Printer 730 series - 0104 Photo Printer 63xPL/PS - 0105 Photo Printer 64xPS - 0200 Photo Printer 64xDL -0d17 NALTEC, Inc. -0d18 coaXmedia -0d19 Hank Connection Industrial Co., Ltd -0d32 Leo Hui Electric Wire & Cable Co., Ltd -0d33 AirSpeak, Inc. -0d34 Rearden Steel Technologies -0d35 Dah Kun Co., Ltd -0d3a Posiflex Technologies, Inc. -0d3c Sri Cable Technology, Ltd -0d3d Tangtop Technology Co., Ltd - 0001 HID Keyboard -0d3e Fitcom, inc. -0d3f MTS Systems Corp. -0d40 Ascor, Inc. -0d41 Ta Yun Terminals Industrial Co., Ltd -0d42 Full Der Co., Ltd -0d46 Kobil Systems GmbH - 2012 KAAN Standard Plus (Smartcard reader) - 3003 mIDentity Light / KAAN SIM III - 4000 mIDentity (mass storage) - 4001 mIDentity Basic/Classic (composite device) - 4081 mIDentity Basic/Classic (installationless) -0d49 Maxtor - 3000 Drive - 3010 3000LE Drive - 3100 Hi-Speed USB-IDE Bridge Controller - 5000 5000XT Drive - 5010 5000LE Drive - 5020 Mobile Hard Disk Drive - 7000 OneTouch - 7010 OneTouch -0d4a NF Corp. -0d4b Grape Systems, Inc. -0d4c Tedas AG -0d4d Coherent, Inc. -0d4e Agere Systems Netherland BV - 047a WLAN Card - 1000 Wireless Card Model 0801 - 1001 Wireless Card Model 0802 -0d4f EADS Airbus France -0d50 Cleware GmbH - 0011 USB-Temp2 Thermometer -0d51 Volex (Asia) Pte., Ltd -0d53 HMI Co., Ltd -0d54 Holon Corp. -0d55 ASKA Technologies, Inc. -0d56 AVLAB Technology, Inc. -0d57 Solomon Microtech, Ltd -0d5c Belkin - a002 F5D6050 802.11b Adapter -0d5e Myacom, Ltd - 2346 BT Digital Access adapter -0d5f CSI, Inc. -0d60 IVL Technologies, Ltd -0d61 Meilu Electronics (Shenzhen) Co., Ltd -0d62 Darfon Electronics Corp. - 0003 Smartcard Reader - 0004 Filter Driver - 0306 M530 Mouse - 0800 Magic Wheel - 2021 AM805 Keyboard - 2026 TECOM Bluetooth Device - a100 Benq Mouse -0d63 Fritz Gegauf AG -0d64 DXG Technology Corp. - 0105 Dual Mode Digital Camera 1.3M - 0107 Horus MT-409 Camera - 0108 Dual Mode Digital Camera - 0202 Dual Mode Video Camera Device - 0303 DXG-305V Camera - 1001 SiPix Stylecam/UMAX AstraPix 320s - 1002 Fashion Cam 01 Dual-Mode DSC (Video Camera) - 1003 Fashion Cam Dual-Mode DSC (Controller) - 1021 D-Link DSC 350F - 1208 Dual Mode Still Camera Device - 2208 Mass Storage - 3105 Dual Mode Digital Camera Disk - 3108 Digicam Mass Storage Device -0d65 KMJP Co., Ltd -0d66 TMT -0d67 Advanet, Inc. -0d68 Super Link Electronics Co., Ltd -0d69 NSI -0d6a Megapower International Corp. -0d6b And-Or Logic -0d70 Try Computer Co., Ltd -0d71 Hirakawa Hewtech Corp. -0d72 Winmate Communication, Inc. -0d73 Hit's Communications, Inc. -0d76 MFP Korea, Inc. -0d77 Power Sentry/Newpoint -0d78 Japan Distributor Corp. -0d7a MARX Datentechnik GmbH -0d7b Wellco Technology Co., Ltd -0d7c Taiwan Line Tek Electronic Co., Ltd -0d7d Phison Electronics Corp. - 0100 PS1001/1011/1006/1026 Flash Disk - 0110 Gigabyte FlexDrive - 0120 Disk Pro 64MB - 0124 GIGABYTE Disk - 0240 I/O-Magic/Transcend 6-in-1 Card Reader - 110e NEC uPD720121/130 USB-ATA/ATAPI Bridge - 1240 Apacer 6-in-1 Card Reader 2.0 - 1270 Wolverine SixPac 6000 - 1300 Flash Disk - 1320 PS2031 Flash Disk - 1400 Attache 256MB USB 2.0 Flash Drive - 1420 PS2044 Pen Drive - 1470 Vosonic X's-Drive II+ VP2160 - 1900 USB Thumb Drive -0d7e American Computer & Digital Components - 2507 Hi-Speed USB-to-IDE Bridge Controller - 2517 Hi-Speed Mass Storage Device - 25c7 Hi-Speed USB-to-IDE Bridge Controller -0d7f Essential Reality LLC -0d80 H.R. Silvine Electronics, Inc. -0d81 TechnoVision -0d83 Think Outside, Inc. -0d89 Oz Software -0d8a King Jim Co., Ltd - 0101 TEPRA PRO -0d8b Ascom Telecommunications, Ltd -0d8c C-Media Electronics, Inc. - 0001 Audio Device - 0002 Composite Device - 0003 Sound Device - 0006 Storm HP-USB500 5.1 Headset - 000c Audio Adapter - 000d Composite Device - 000e Audio Adapter (Planet UP-100, Genius G-Talk) - 0102 CM106 Like Sound Device - 0103 Turtle Beach Audio Advantage Micro - 0201 CM6501 - 5000 Mass Storage Controller - 5200 Mass Storage Controller(0D8C,5200) - b213 USB Phone CM109 (aka CT2000,VPT1000) -0d8d Promotion & Display Technology, Ltd - 0234 V-234 Composite Device - 0550 V-550 Composite Device - 0551 V-551 Composite Device - 0552 V-552 Composite Device - 0651 V-651 Composite Device - 0652 V-652 Composite Device - 0653 V-653 Composite Device - 0654 V-654 Composite Device - 0655 V-655 Composite Device - 0656 V-656 Composite Device - 0657 V-657 Composite Device - 0658 V-658 Composite Device - 0659 V-659 Composite Device - 0660 V-660 Composite Device - 0661 V-661 Composite Device - 0662 V-662 Composite Device - 0850 V-850 Composite Device - 0851 V-851 Composite Device - 0852 V-852 Composite Device - 0901 V-901 Composite Device - 0902 V-902 Composite Device - 0903 V-903 Composite Device - 4754 Voyager DMP Composite Device - bb00 Bloomberg Composite Device - bb01 Bloomberg Composite Device - bb02 Bloomberg Composite Device - bb03 Bloomberg Composite Device - bb04 Bloomberg Composite Device - bb05 Bloomberg Composite Device - fffe Global Tuner Composite Device - ffff Voyager DMP Composite Device -0d8e Global Sun Technology, Inc. - 0163 802.11g 54 Mbps Wireless Dongle - 1621 802.11b Wireless Adapter - 3762 802.11g Wireless Mini adapter - 3763 802.11g Wireless dongle - 7100 802.11b Adapter - 7110 WL-210 - 7801 AR5523 - 7802 AR5523 (no firmware) - 7811 AR5523 - 7812 AR5523 (no firmware) - 7a01 PRISM25 802.11b Adapter -0d8f Pitney Bowes -0d90 Sure-Fire Electrical Corp. -0d96 Skanhex Technology, Inc. - 0000 Jenoptik JD350 video - 3300 SX330z Camera - 4100 SX410z Camera - 4102 MD 9700 Camera - 4104 Jenoptik JD-4100z3s - 410a Medion 9801/Novatech SX-410z - 5200 SX-520z Camera -0d97 Santa Barbara Instrument Group - 0001 SBIG Astronomy Camera (without firmware) - 0101 SBIG Astronomy Camera (with firmware) -0d98 Mars Semiconductor Corp. - 0300 Avaya Wireless Card -0d99 Trazer Technologies, Inc. -0d9a RTX Telecom AS - 0001 Bluetooth Device -0d9b Tat Shing Electrical Co. -0d9c Chee Chen Hi-Technology Co., Ltd -0d9d Sanwa Supply, Inc. -0d9e Avaya - 0300 Wireless Card -0d9f Powercom Co., Ltd -0da0 Danger Research -0da1 Suzhou Peter's Precise Industrial Co., Ltd -0da2 Land Instruments International, Ltd -0da3 Nippon Electro-Sensory Devices Corp. -0da4 Polar Electro OY - 0001 Interface -0da7 IOGear, Inc. -0da8 softDSP Co., Ltd - 0001 SDS 200A Oscilloscope -0dab Cubig Group - 0100 DVR/CVR-M140 MP3 Player -0dad Westover Scientific -0db0 Micro Star International - 1020 PC2PC WLAN Card - 1967 Bluetooth Dongle - 4011 Medion Flash XL V2.0 Card Reader - 4600 802.11b/g Turbo Wireless Adapter - 5501 Mass Storage Device - 5502 Mass Storage Device - 5513 MP3 Player - 5515 MP3 Player - 5516 MP3 Player - 6823 UB11B/MS-6823 802.11b Wi-Fi adapter - 6826 IEEE 802.11g Wireless Network Adapter - 6855 Bluetooth Device - 6861 MSI-6861 802.11g WiFi adapter - 6865 RT2570 - 6869 RT2570 - 6874 RT2573 - 6877 RT2573 - 6881 Bluetooth Class I EDR Device - 688a Bluetooth Class I EDR Device - 6970 Bluetooth adapter - 697a Bluetooth Dongle - 6982 Medion Flash XL Card Reader - a861 RT2573 - a874 RT2573 - a970 Bluetooth dongle - a97a Bluetooth EDR Device - b970 Bluetooth EDR Device - b97a Bluetooth EDR Device -0db1 Wen Te Electronics Co., Ltd -0db2 Shian Hwi Plug Parts, Plastic Factory -0db3 Tekram Technology Co., Ltd -0db4 Chung Fu Chen Yeh Enterprise Corp. -0db7 ELCON Systemtechnik - 0002 Goldpfeil P-LAN -0dbe Jiuh Shiuh Precision Industry Co., Ltd -0dbf Quik Tech Solutions - 0002 SmartDongle Security Key - 0200 HDD Storage Solution - 021b USB-2.0 IDE Adapter - 0300 Storage Adapter - 0333 Storage Adapter - 0707 ZIV Drive -0dc0 Great Notions -0dc1 Tamagawa Seiki Co., Ltd -0dc3 Athena Smartcard Solutions, Inc. - 0801 ASEDrive III - 0802 ASEDrive IIIe - 1104 ASEDrive IIIe KB - 1701 ASEKey - 1702 ASEKey -0dc4 Macpower Peripherals, Ltd - 0040 Mass Storage Device - 0041 Mass Storage Device - 0042 Mass Storage Device - 0101 Hi-Speed Mass Storage Device -0dc5 SDK Co., Ltd -0dc6 Precision Squared Technology Corp. -0dc7 First Cable Line, Inc. -0dcd NetworkFab Corp. - 0001 Remote Interface Adapter - 0002 High Bandwidth Codec -0dd0 Access Solutions - 1002 Triple Talk Speech Synthesizer -0dd1 Contek Electronics Co., Ltd -0dd2 Power Quotient International Co., Ltd - 0003 Mass Storage (P) -0dd3 MediaQ -0dd4 Custom Engineering SPA -0dd5 California Micro Devices -0dd7 Kocom Co., Ltd -0dd8 Netac Technology Co., Ltd - 1060 USB-CF-Card - e007 OnlyDisk U222 Pendrive -0dd9 HighSpeed Surfing -0dda Integrated Circuit Solution, Inc. - 0001 Multi-Card Reader 6in1 - 0002 Multi-Card Reader 7in1 - 0003 Flash Disk - 0005 Internal Multi-Card Reader 6in1 - 0008 SD single card reader - 0009 MS single card reader - 000a MS+SD Dual Card Reader - 000b SM single card reader - 0101 All-In-One Card Reader - 0102 All-In-One Card Reader - 0301 MP3 Player - 0302 Multi-Card MP3 Player - 1001 Multi-Flash Disk - 2001 Multi-Card Reader - 2002 Q018 default PID - 2003 Multi-Card Reader - 2005 Datalux DLX-1611 16in1 Card Reader - 2006 All-In-One Card Reader - 2007 USB to ATAPI bridge - 2008 All-In-One Card Reader - 2013 SD/MS Combo Card Reader - 2014 SD/MS Single Card Reader - 2023 card reader SD/MS DEMO board with ICSI brand name (MaskROM version) - 2024 card reader SD/MS DEMO board with Generic brand name (MaskROM version) - 2026 USB2.0 Card Reader - 2027 USB 2.0 Card Reader - 2315 UFD MP3 player (model 2) - 2318 UFD MP3 player (model 1) - 2321 UFD MP3 player -0ddb Tamarack, Inc. -0ddd Datelink Technology Co., Ltd -0dde Ubicom, Inc. -0de0 BD Consumer Healthcare -0dea UTECH Electronic (D.G.) Co., Ltd. -0ded Novasonics -0dee Lifetime Memory Products - 4010 Storage Adapter -0def Full Rise Electronic Co., Ltd -0df6 Sitecom Europe B.V. - 0001 C-Media VOIP Device - 0004 Bluetooth 2.0 Adapter 100m - 0007 Bluetooth 2.0 Adapter 10m - 000b Bluetooth 2.0.USB Adapter DFU - 000d WL-168 Wireless Network Adapter 54g - 0017 WL-182 - 0019 Bluetooth 2.0 adapter 10m CN-512v2 001 - 001a Bluetooth 2.0 adapter 100m CN-521v2 001 - 061c LN-028 - 21f4 44 St Bluetooth Device - 2200 Sitecom bluetooth2.0 class 2 dongle CN-512 - 2208 Sitecom bluetooth2.0 class 2 dongle CN-520 - 2209 Sitecom bluetooth2.0 class 1 dongle CN-521 - 9071 zd1211 802.11g Adapter - 9075 ZD1211B - 90ac WL-172 - 9712 WL-113 rev 2 -0df7 Mobile Action Technology, Inc. - 0620 MA-620 Infrared Adapter - 0700 MA-700 Bluetooth Adapter - 0720 MA-720 Bluetooth Adapter - 0722 Bluetooth Dongle - 0800 Data Cable - 0820 Data Cable - 1800 Generic Card Reader - 1802 Card Reader -0dfa Toyo Communication Equipment Co., Ltd -0dfc GeneralTouch Technology Co., Ltd - 0001 Touchscreen -0e03 Nippon Systemware Co., Ltd -0e08 Winbest Technology Co., Ltd -0e0c Gesytec - 0101 LonUSB LonTalk Network Adapter -0e16 JMTek, LLC -0e17 Walex Electronic, Ltd -0e1b Crewave -0e21 Cowon Systems, Inc. - 0300 iAudio CW200 - 0400 MP3 Player - 0510 iAudio X5 - 0513 iAudio X5, side USB port - 0520 iAudio M5 - 0700 iAudio U3 -0e22 Symbian Ltd. -0e23 Liou Yuane Enterprise Co., Ltd -0e25 VinChip Systems, Inc. -0e26 J-Phone East Co., Ltd -0e30 HeartMath LLC -0e34 Micro Computer Control Corp. -0e35 3Pea Technologies, Inc. -0e36 TiePie engineering - 0008 Handyscope HS3 - 0009 Handyscope HS3 (br) - 000a Handyscope HS4 - 000b Handyscope HS4 (br) - 000e Handyscope HS4 Diff - 000f Handyscope HS4 Diff (br) - 0010 Handyscope HS2 - 0018 Handyprobe HP2 - 0042 TiePieSCOPE HS801 - 00fd USB To Parallel adapter - 00fe USB To Parallel adapter -0e38 Stratitec, Inc. -0e39 Smart Modular Technologies, Inc. - 0137 Bluetooth Device -0e3a Neostar Technology Co., Ltd - 1100 CW-1100 Wireless Network Adapter -0e3b Mansella, Ltd -0e41 Line6, Inc. - 4250 BassPODxt - 4252 BassPODxt Pro - 4642 BassPODxt Live - 4650 PODxt Live - 4750 GuitarPort - 5044 PODxt - 5050 PODxt Pro - 534d SeaMonkey -0e44 Sun-Riseful Technology Co., Ltd. -0e48 Julia Corp., Ltd - 0100 CardPro SmartCard Reader -0e4a Shenzhen Bao Hing Electric Wire & Cable Mfr. Co. -0e4c Radica Games, Ltd -0e55 Speed Dragon Multimedia, Ltd - 110b MS3303H USB-to-Serial Bridge -0e56 Kingston Technology Company, Inc. - 6021 K-PEX 100 -0e5a Active Co., Ltd -0e5b Union Power Information Industrial Co., Ltd -0e5c Bitland Information Technology Co., Ltd - 6118 LCD Device - 6119 remote receive and control device - 6441 C-Media Sound Device -0e5d Neltron Industrial Co., Ltd -0e66 Hawking - 400b UF100 10/100 Network Adapter - 400c UF100 Ethernet [pegasus2] -0e67 Fossil, Inc. - 0002 Wrist PDA -0e6a Megawin Technology Co., Ltd -0e70 Tokyo Electronic Industry Co., Ltd -0e72 Hsi-Chin Electronics Co., Ltd -0e75 TVS Electronics, Ltd -0e79 Archos, Inc. - 1106 Pocket Medai Assistant - PMA400 -0e7b On-Tech Industry Co., Ltd -0e7e Gmate, Inc. - 0001 Yopy 3000 PDA - 1001 YP3X00 PDA -0e82 Ching Tai Electric Wire & Cable Co., Ltd -0e83 Shin An Wire & Cable Co. -0e8c Well Force Electronic Co., Ltd -0e8d MediaTek Inc. -0e8f GreenAsia Inc. - 0012 Joystick -0e90 WiebeTech, LLC - 0100 Storage Adapter V1 -0e91 VTech Engineering Canada, Ltd -0e92 C's Glory Enterprise Co., Ltd -0e93 eM Technics Co., Ltd -0e95 Future Technology Co., Ltd -0e96 Aplux Communications, Ltd - c001 TRUST 380 USB2 SPACEC@M -0e97 Fingerworks, Inc. -0e98 Advanced Analogic Technologies, Inc. -0e99 Parallel Dice Co., Ltd -0e9a TA HSING Industries, Ltd -0e9b ADTEC Corp. -0e9c Streamzap, Inc. - 0000 Streamzap Remote Control -0e9f Tamura Corp. -0ea0 Ours Technology, Inc. - 2126 7-in-1 Card Reader - 2168 Transcend JetFlash 2.0 / Astone USB Drive - 6803 OTI-6803 Flash Disk - 6808 OTI-6808 Flash Disk - 6828 OTI-6828 Flash Disk -0ea6 Nihon Computer Co., Ltd -0ea7 MSL Enterprises Corp. -0ea8 CenDyne, Inc. -0ead Humax Co., Ltd -0eb0 NovaTech - 9020 NovaTech NV-902W - 9021 RT2573 -0eb1 WIS Technologies, Inc. - 6666 WinFast WalkieTV TV Loader - 6668 WinFast WalkieTV TV Loader - 7007 WinFast WalkieTV WDM Capture -0eb2 Y-S Electronic Co., Ltd -0eb3 Saint Technology Corp. -0eb7 Endor AG -0ebe VWeb Corp. -0ebf Omega Technology of Taiwan, Inc. -0ec0 LHI Technology (China) Co., Ltd -0ec1 Abit Computer Corp. -0ec2 Sweetray Industrial, Ltd -0ec3 Axell Co., Ltd -0ec4 Ballracing Developments, Ltd -0ec5 GT Information System Co., Ltd -0ec6 InnoVISION Multimedia, Ltd -0ec7 Theta Link Corp. - 1008 So., Show 301 Digital Camera -0ecd Lite-On IT Corp. - 1400 CD\RW 40X -0ece TaiSol Electronics Co., Ltd -0ecf Phogenix Imaging, LLC -0ed1 WinMaxGroup - 6660 USB Flash Disk 64M-C - 6680 USB Flash Disk 64M-B - 7634 MP3 Player -0ed2 Kyoto Micro Computer Co., Ltd -0ed3 Wing-Tech Enterprise Co., Ltd -0ed5 Fiberbyte - e000 USB-inSync Device - f000 Fiberbyte USB-inSync Device - f201 Fiberbyte USB-inSync DAQ-2500X -0eda Noriake Itron Corp. -0edf e-MDT Co., Ltd - 2060 FID irock! 100 Series -0ee0 Shima Seiki Mfg., Ltd -0ee1 Sarotech Co., Ltd -0ee2 AMI Semiconductor, Inc. -0ee3 ComTrue Technology Corp. - 1000 Image Tank 1.5 -0ee4 Sunrich Technology, Ltd -0eee Digital Stream Technology, Inc. - 8810 Mass Storage Drive -0eef D-WAV Scientific Co., Ltd - 0001 eGalax TouchScreen - 0002 Touchscreen Controller(Professional) -0ef0 Hitachi Cable, Ltd -0ef1 Aichi Micro Intelligent Corp. -0ef2 I/O Magic Corp. -0ef3 Lynn Products, Inc. -0ef4 DSI Datotech -0ef5 PointChips - 2202 Flash Disk - 2366 Flash Disk -0ef6 Yield Microelectronics Corp. -0ef7 SM Tech Co., Ltd (Tulip) -0efd Oasis Semiconductor -0efe Wem Technology, Inc. -0f06 Visual Frontier Enterprise Co., Ltd -0f08 CSL Wire & Plug (Shen Zhen) Co. -0f0c CAS Corp. -0f0d Hori Co., Ltd -0f0e Energy Full Corp. -0f12 Mars Engineering Corp. -0f13 Acetek Technology Co., Ltd -0f19 Oracom Co., Ltd -0f1b Onset Computer Corp. -0f1c Funai Electric Co., Ltd -0f1d Iwill Corp. -0f21 IOI Technology Corp. -0f22 Senior Industries, Inc. -0f23 Leader Tech Manufacturer Co., Ltd -0f24 Flex-P Industries, Snd., Bhd. -0f2d ViPower, Inc. -0f2e Geniality Maple Technology Co., Ltd -0f2f Priva Design Services -0f30 Jess Technology Co., Ltd - 001c PS3 Guitar Controller Dongle - 0110 10-Button Joypad -0f31 Chrysalis Development -0f32 YFC-BonEagle Electric Co., Ltd -0f37 Kokuyo Co., Ltd -0f38 Nien-Yi Industrial Corp. -0f3d Airprime, Incorporated - 0112 CDMA 1xEVDO PC Card, PC 5220 -0f41 RDC Semiconductor Co., Ltd -0f42 Nital Consulting Services, Inc. -0f44 Polhemus - ef11 Patriot (firmware not loaded) - ef12 Patriot - ff11 Liberty (firmware not loaded) - ff12 Liberty -0f4b St. John Technology Co., Ltd -0f4c WorldWide Cable Opto Corp. -0f4d Microtune, Inc. - 1000 Bluetooth Dongle -0f4e Freedom Scientific -0f52 Wing Key Electrical Co., Ltd -0f53 Dongguan White Horse Cable Factory, Ltd -0f54 Kawai Musical Instruments Mfg. Co., Ltd -0f55 AmbiCom, Inc. -0f5c Prairiecomm, Inc. -0f5d NewAge International, LLC - 9455 Compact Drive -0f5f Key Technology Corp. -0f60 NTK, Ltd -0f61 Varian, Inc. -0f62 Acrox Technologies Co., Ltd - 1001 Targus Mini Trackball Optical Mouse -0f68 Kobe Steel, Ltd -0f69 Dionex Corp. -0f6a Vibren Technologies, Inc. -0f6e INTELLIGENT SYSTEMS - 0100 GameBoy Color Emulator - 0201 GameBoy Advance Flash Gang Writer - 0202 GameBoy Advance Capture - 0300 Gamecube DOL Viewer - 0400 NDS Emulator - 0401 NDS UIC - 0402 NDS Writer - 0403 NDS Capture - 0404 NDS Emulator (Lite) -0f73 DFI -0f7c DQ Technology, Inc. -0f7d NetBotz, Inc. -0f7e Fluke Corp. -0f88 VTech Holdings, Ltd - 3012 RT2570 - 3014 ZD1211B -0f8b Yazaki Corp. -0f8c Young Generation International Corp. -0f8d Uniwill Computer Corp. -0f8e Kingnet Technology Co., Ltd -0f8f Soma Networks -0f97 CviLux Corp. -0f98 CyberBank Corp. -0f9c Hyun Won, Inc. - 0301 M-Any Premium DAH-610 MP3/WMA Player - 0332 mobiBLU DAH-1200 MP3/Ogg Player -0f9e Lucent Technologies -0fa3 Starconn Electronic Co., Ltd -0fa4 ATL Technology -0fa5 Sotec Co., Ltd -0fa7 Epox Computer Co., Ltd -0fa8 Logic Controls, Inc. -0faf Winpoint Electronic Corp. -0fb0 Haurtian Wire & Cable Co., Ltd -0fb1 Inclose Design, Inc. -0fb2 Juan-Chern Industrial Co., Ltd -0fb8 Wistron Corp. - 0002 eHome Infrared Receiver -0fb9 AACom Corp. -0fba San Shing Electronics Co., Ltd -0fbb Bitwise Systems, Inc. -0fc1 Mitac Internatinal Corp. -0fc2 Plug and Jack Industrial, Inc. -0fc5 Delcom Engineering - 1222 I/O Development Board -0fc6 Dataplus Supplies, Inc. -0fca Research In Motion, Ltd. - 0001 Blackberry Handheld -0fce Sony Ericsson Mobile Communications AB - 1010 WMC Modem - d008 V800-Vodafone 802SE WMC Modem - d016 K750i Phone - d017 K608i Phone - d019 VDC EGPRS Modem - d025 520 WMC Data Modem - d038 W850i Phone - d041 K510i Phone - d042 W810i Phone - d046 K610i Phone -0fcf Dynastream Innovations, Inc. -0fd0 Tulip Computers B.V. -0fd1 Giant Electronics Ltd. -0fd4 Tenovis GmbH & Co., KG -0fd5 Direct Access Technology, Inc. -0fdc Micro Plus -0fe4 IN-Tech Electronics, Ltd -0fe5 Greenconn (U.S.A.), Inc. -0fe9 DVICO - db00 FusionHDTV DVB-T (MT352+LgZ201) (uninitialized) - db01 FusionHDTV DVB-T (MT352+LgZ201) (initialized) - db10 FusionHDTV DVB-T (MT352+Thomson7579) (uninitialized) - db11 FusionHDTV DVB-T (MT352+Thomson7579) (initialized) -0fea United Computer Accessories -0feb CRS Electronic Co., Ltd -0fec UMC Electronics Co., Ltd -0fed Access Co., Ltd -0fee Xsido Corp. -0fef MJ Research, Inc. -0ff6 Core Valley Co., Ltd -0ff7 CHI SHING Computer Accessories Co., Ltd -0fff Aopen, Inc. -1000 Speed Tech Corp. -1001 Ritronics Components (S) Pte., Ltd -1003 Sigma Corp. - 0100 Sigma SD10 -1004 LG Electronics, Inc. - 1fae U8120 3G Cellphone - 6000 VX4400/VX6000 Cellphone - 6005 T5100 - 6800 CDMA Modem - 7000 LG LDP-7024D(LD)USB -1005 Apacer Technology, Inc. - 1001 MP3 Player - 1004 MP3 Player - 1006 MP3 Player - b113 Handy Steno 2.0/HT203 - b223 CD-RW + 6 in 1 Card Reader Digital Storage / Converter -1006 iRiver, Ltd. - 3001 iHP-100 - 3002 iHP-120/140 MP3 Player - 3003 H320/H340 - 3004 H340 (mtp) -1009 Emuzed, Inc. - 000e eHome Infrared Receiver - 0013 Angel MPEG Device - 0015 Lumanate Wave PAL SECAM DVBT Device - 0016 Lumanate Wave NTSC/ATSC Combo Device -100a AV Chaseway, Ltd - 2402 MP3 Player - 2404 MP3 Player - 2405 MP3 Player - 2406 MP3 Player - a0c0 MP3 Player -100b Chou Chin Industrial Co., Ltd -100d Netopia, Inc. - 3342 Cayman 3352 DSL Modem - 3382 3380 Series Network Interface - cb01 Cayman 3341 Ethernet DSL Router -1010 Fukuda Denshi Co., Ltd -1011 Mobile Media Tech. - 0001 AccFast Mp3 -1012 SDKM Fibres, Wires & Cables Berhad -1013 TST-Touchless Sensor Technology AG -1014 Densitron Technologies PLC -1015 Softronics Pty., Ltd -1016 Xiamen Hung's Enterprise Co., Ltd -1017 Speedy Industrial Supplies, Pte., Ltd -1019 Elitegroup Computer Systems (ECS) - 0c55 USB Flash Reader, Desknote UCR-61S2B -1020 Labtec - 000a Wireless Optical Mouse -1022 Shinko Shoji Co., Ltd -1025 Hyper-Paltek - 005e USB DVB-T device - 005f USB DVB-T device - 0300 MP3 Player - 0350 MP3 Player -1026 Newly Corp. -1027 Time Domain -1028 Inovys Corp. -1029 Atlantic Coast Telesys -102a Ramos Technology Co., Ltd -102b Infotronic America, Inc. -102c Etoms Electronics Corp. - 6251 Q-Cam -102d Winic Corp. -1031 Comax Technology, Inc. -1032 C-One Technology Corp. -1033 Nucam Corp. - 0068 3,5'' HDD case MD-231 -1038 Ideazon, Inc. - 0100 Zboard -1039 devolo AG - 2140 dsl+ 1100 duo -103d Stanton - 0100 ScratchAmp - 0101 ScratchAmp -1043 iCreate Technologies Corp. - 160f Wireless Network Adapter - 4901 AV-836 Video Capture Device - 8006 Flash Disk 32-256 MB -1044 Chu Yuen Enterprise Co., Ltd - 7001 U7000 TV tuner device - 8001 GN-54G - 8002 GN-BR402W - 8003 GN-WLBM101 - 8004 GN-WLBZ101 802.11b Adapter - 8005 GN-WLBZ201 802.11b Adapter - 8006 GN-WBZB-M 802.11b Adapter - 8007 GN-WBKG - 8008 GN-WB01GS - 800a GN-WI05GS - 800b GN-WB30N 802.11n WLAN Card -1046 Winbond Electronics Corp. [hex] - 8901 Bluetooth Device - 9967 W9967CF/W9968CF WebCam IC -1048 Targus Group International -104c AMCO TEC International, Inc. -1053 Immanuel Electronics Co., Ltd -1054 BMS International Beheer N.V. - 5004 DSL 7420 Loader - 5005 DSL 7420 LAN Modem -1055 Complex Micro Interconnection Co., Ltd -1056 Hsin Chen Ent Co., Ltd -1057 ON Semiconductor -1058 Western Digital Technologies, Inc. - 0200 Firewire USB Combo - 0400 External HDD - 0500 hub - 0702 Passport External HDD - 0901 MyBook External HDD - 1001 External Hard Disk -1059 Giesecke & Devrient GmbH - 000b StarSign Bio Token 3.0 -105c Hong Ji Electric Wire & Cable (Dongguan) Co., Ltd -105d Delkin Devices, Inc. -105e Valence Semiconductor Design, Ltd -105f Chin Shong Enterprise Co., Ltd -1060 Easthome Industrial Co., Ltd -1063 Motorola Electronics Taiwan, Ltd [hex] - 1555 MC141555 Hub - 4100 SB4100 USB Cable Modem -1065 CCYU Technology - 0020 USB-DVR2 Dev Board - 2136 EasyDisk ED1064 -106a Loyal Legend, Ltd -106c Curitel Communications, Inc. - 1101 CDMA 2000 1xRTT USB modem (HX-550C) - 1102 Packet Service - 1103 Packet Service Diagnostic Serial Port (WDM) - 1104 Packet Service Diagnostic Serial Port (WDM) - 1105 Composite Device - 1106 Packet Service Diagnostic Serial Port (WDM) - 1301 Composite Device - 1302 Packet Service Diagnostic Serial Port (WDM) - 1303 Packet Service - 1304 Packet Service - 1401 Composite Device - 1402 Packet Service - 1403 Packet Service Diagnostic Serial Port (WDM) - 1501 Packet Service - 1502 Packet Service Diagnostic Serial Port (WDM) - 1503 Packet Service - 1601 Packet Service - 1602 Packet Service Diagnostic Serial Port (WDM) - 1603 Packet Service - 2101 AudioVox 8900 Cell Phone - 2102 Packet Service - 2103 Packet Service Diagnostic Serial Port (WDM) - 2301 Packet Service - 2302 Packet Service Diagnostic Serial Port (WDM) - 2303 Packet Service - 2401 Packet Service Diagnostic Serial Port (WDM) - 2402 Packet Service - 2403 Packet Service Diagnostic Serial Port (WDM) - 2501 Packet Service - 2502 Packet Service Diagnostic Serial Port (WDM) - 2503 Packet Service - 2601 Packet Service - 2602 Packet Service Diagnostic Serial Port (WDM) - 2603 Packet Service - 3701 Broadband Wireless modem - 3702 Pantech PX-500 - 3eb4 Packet Service Diagnostic Serial Port (WDM) - 4101 Packet Service Diagnostic Serial Port (WDM) - 4102 Packet Service - 4301 Composite Device - 4302 Packet Service Diagnostic Serial Port (WDM) - 4401 Composite Device - 4402 Packet Service - 4501 Packet Service - 4502 Packet Service Diagnostic Serial Port (WDM) - 4601 Composite Device - 4602 Packet Service Diagnostic Serial Port (WDM) - 5101 Packet Service - 5102 Packet Service Diagnostic Serial Port (WDM) - 5301 Packet Service Diagnostic Serial Port (WDM) - 5302 Packet Service - 5401 Packet Service - 5402 Packet Service Diagnostic Serial Port (WDM) - 5501 Packet Service Diagnostic Serial Port (WDM) - 5502 Packet Service - 5601 Packet Service Diagnostic Serial Port (WDM) - 5602 Packet Service - 7101 Composite Device - 7102 Packet Service - a000 Packet Service - a001 Packet Service Diagnostic Serial Port (WDM) - c100 Packet Service - c200 Packet Service - c500 Packet Service Diagnostic Serial Port (WDM) - e200 Packet Service -106d San Chieh Manufacturing, Ltd -106e ConectL -106f Money Controls -1076 GCT Semiconductor, Inc. - 0031 Bluetooth Device - 0032 Bluetooth Device -107d Arlec Australia, Ltd -107e Midoriya Electric Co., Ltd -107f KidzMouse, Inc. -1082 Shin-Etsukaken Co., Ltd -1083 Canon Electronics, Inc. -1084 Pantech Co., Ltd -108a Chloride Power Protection -108b Grand-tek Technology Co., Ltd -108c Robert Bosch GmbH -108e Lotes Co., Ltd. -1099 Surface Optics Corp. -109a DATASOFT Systems GmbH -109f eSOL Co., Ltd - 3163 Trigem Mobile SmartDisplay84 - 3164 Trigem Mobile SmartDisplay121 -10a0 Hirotech, Inc. -10a3 Mitsubishi Materials Corp. -10a9 SK Teletech Co., Ltd -10aa Cables To Go -10ab USI Co., Ltd - 1002 Bluetooth Device - 1003 BC02-EXT in DFU - 1005 Bluetooth Adptr - 1006 BC04-EXT in DFU - 10c5 Sony-Ericsson / Samsung DataCable -10ac Honeywell, Inc. -10ae Princeton Technology Corp. -10af Liebert Corp. - 0000 UPS - 0001 PowerSure PSA UPS - 0002 PowerSure PST UPS - 0003 PowerSure PSP UPS - 0004 PowerSure PSI UPS - 0005 UPStation GXT 2U UPS - 0006 UPStation GXT UPS - 0007 Nfinity Power Systems UPS - 0008 PowerSure Interactive UPS -10b5 Comodo (PLX?) - 9060 Test Board -10b8 DiBcom - 0bb8 DiBcom USB DVB-T reference design (MOD300) (cold) - 0bb9 DiBcom USB DVB-T reference design (MOD300) (warm) - 0bc6 DiBcom USB2.0 DVB-T reference design (MOD3000P) (cold) - 0bc7 DiBcom USB2.0 DVB-T reference design (MOD3000P) (warm) -10bb TM Technology, Inc. -10bc Dinging Technology Co., Ltd -10bd TMT Technology, Inc. - 1427 Ethernet -10bf SmartHome - 0001 SmartHome PowerLinc -10c4 Cygnal Integrated Products, Inc. - 0002 F32x USBXpress Device - 80a9 CP210x to UART Bridge Controller - 80ca ATM2400 Sensor Device - ea60 CP210x Composite Device -10c5 Sanei Electric, Inc. -10c6 Intec, Inc. -10cb Eratech -10cc GBM Connector Co., Ltd - 1101 MP3 Player -10cd Kycon, Inc. -10ce Silicon Labs - ea6a MobiData EDGE USB Modem -10cf Velleman Components, Inc. - 5500 8055 Experiment Interface Board (address=0) - 5501 8055 Experiment Interface Board (address=1) - 5502 8055 Experiment Interface Board (address=2) - 5503 8055 Experiment Interface Board (address=3) -10d1 Hottinger Baldwin Measurement - 0101 USB-Module for Spider8, CP32 - 0202 CP22 - Communication Processor - 0301 CP42 - Communication Processor -10d4 Man Boon Manufactory, Ltd -10d5 Uni Class Technology Co., Ltd -10d6 Actions Semiconductor Co., Ltd - 1000 MP3 Player - 1100 MPMan MP-Ki 128 MP3 Player/Recorder - 1101 D-Wave 2GB MP4 Player - 8888 ADFU Device - ff51 ADFU Device -10de Authenex, Inc. -10df In-Win Development, Inc. -10e0 Post-Op Video, Inc. -10e1 CablePlus, Ltd -10e2 Nada Electronics, Ltd -10ec Vast Technologies, Inc. -10f5 Turtle Beach - 0200 Audio Advantage Roadie -10fb Pictos Technologies, Inc. -10fd Anubis Electronics, Ltd - 804d Typhoon Webshot II Webcam [zc0301] - 8050 FlyCAM-USB 300 XP2 - de00 WinFast WalkieTV WDM Capture Driver. -1100 VirTouch, Ltd - 0001 VTPlayer VTP-1 Braille Mouse -1101 EasyPass Industrial Co., Ltd - 0001 FSK Electronics Super GSM Reader -1108 Brightcom Technologies, Ltd -1110 Analog Devices Canada, Ltd (Allied Telesyn) - 5c01 Huawei MT-882 Remote NDIS Network Device - 6489 ADSL ETH/USB RTR - 9000 ADSL LAN Adapter - 9001 ADSL Loader - 900f AT-AR215 DSL Modem - 9010 AT-AR215 DSL Modem - 9021 ADSL WAN Adapter - 9022 ADSL Loader - 9023 ADSL WAN Adapter - 9024 ADSL Loader - 9031 ADSL LAN Adapter - 9032 ADSL Loader -1111 Pandora International Ltd. - 8888 Evolution Device -1112 YM ELECTRIC CO., Ltd -1113 Medion AG -111e VSO Electric Co., Ltd -112e Master Hill Electric Wire and Cable Co., Ltd -112f Cellon International, Inc. -1130 Tenx Technology, Inc. - f211 USB audio headset -1131 Integrated System Solution Corp. - 1001 KY-BT100 Bluetooth Adapter - 1002 Bluetooth Device - 1003 Bluetooth Device - 1004 Bluetooth Device -1132 Toshiba Corp., Digital Media Equipment [hex] - 4331 PDR-M4/M5/M70 Digital Camera - 4332 PDR-M60 Digital Camera - 4333 PDR-M2300/PDR-M700 - 4334 PDR-M65 - 4335 PDR-M61 - 4337 PDR-M11 - 4338 PDR-M25 -113c Arin Tech Co., Ltd -113d Mapower Electronics Co., Ltd -1141 V One Multimedia, Pte., Ltd -1142 CyberScan Technologies, Inc. -1145 Japan Radio Company - 0001 AirH PHONE AH-J3001V/J3002V -1146 Shimane SANYO Electric Co., Ltd. -1147 Ever Great Electric Wire and Cable Co., Ltd -114b Sphairon Access Systems GmbH - 0110 Turbolink UB801R WLAN USB Adapter -114c Tinius Olsen Testing Machine Co., Inc. -114d Alpha Imaging Technology Corp. -115b Salix Technology Co., Ltd. -1162 Secugen Corp. -1163 DeLorme Publishing, Inc. - 0100 Earthmate GPS -1164 YUAN High-Tech Development Co., Ltd - 0300 ELSAVISION 460D - 0601 Analog TV Tuner - 0900 TigerBird BMP837 USB2.0 WDM Encoder - 0bc7 Digital TV Tuner -1165 Telson Electronics Co., Ltd -1166 Bantam Interactive Technologies -1167 Salient Systems Corp. -1168 BizConn International Corp. -116e Gigastorage Corp. -116f Silicon 10 Technology Corp. -1175 Shengyih Steel Mold Co., Ltd -117d Santa Electronic, Inc. -117e JNC, Inc. -1182 Venture Corp., Ltd -1183 Compaq Computer Corp. [hex] (Digital Dream ??) - 0001 DigitalDream l'espion XS - 19c7 ISDN TA - 4008 56k FaxModem - 504a PJB-100 Personal Jukebox -1184 Kyocera Elco Corp. -1188 Bloomberg L.P. -1189 Acer Communications & Multimedia - 0893 EP-1427X-2 Ethernet Adapter -118f You Yang Technology Co., Ltd -1190 Tripace -1191 Loyalty Founder Enterprise Co., Ltd -1196 Yankee Robotics, LLC - 0010 Trifid Camera without code - 0011 Trifid Camera -1197 Technoimagia Co., Ltd -1198 StarShine Technology Corp. -1199 Sierra Wireless, Inc. - 0019 AC595U - 0021 AC597E - 0110 Composite Device - 0112 CDMA 1xEVDO PC Card, AirCard 580 - 0120 AC595U - 0218 MC5720 Wireless Modem - 6467 MP Series Network Adapter - 6468 MP Series Network Adapter - 6469 MP Series Network Adapter - 6802 MC8755 Device - 6803 MC8765 Device - 6804 MC8755 Device - 6805 MC8765 Device - 6812 MC8775 Device - 6820 AC875 Device - 6832 MC8780 Device - 6833 MC8781 Device - 683a MC8785 Device - 6850 AirCard 880 Device - 6851 AirCard 881 Device - 6852 AirCard 880E Device - 6853 AirCard 881E Device - 6854 AirCard 885 Device - 6870 MC8780 Device - 6871 MC8781 Device -119a ZHAN QI Technology Co., Ltd -119b ruwido austria GmbH - 0400 Infrared Keyboard V2.01 -11a0 Chipcon AS - eb11 CC2400EB 2.0 ZigBee Sniffer -11a3 Technovas Co., Ltd - 8031 MP3 Player - 8032 MP3 Player -11aa GlobalMedia Group, LLC - 1518 iREZ K2 -11ab Exito Electronics Co., Ltd -11b0 ATECH FLASH TECHNOLOGY -11db Topfield Co., Ltd. - 1000 PVR - 1100 PVR -11e6 K.I. Technology Co. Ltd. -11f5 Siemens AG (?) - 0001 SX1 - 0003 Mobile phone USB cable - 0004 X75 -11f6 Prolific - 2001 Willcom WSIM -11f7 Alcatel (?) - 02df TD10 Mobile phone USB cable -1209 InterBiometrics - 1001 USB Hub - 1002 USB Relais - 1003 IBSecureCam-P - 1004 IBSecureCam-O - 1005 IBSecureCam-N -120e Hudson Soft Co., Ltd -121e Jungsoft Co., Ltd - 3403 Muzio JM250 Audio Player -1223 SKYCABLE ENTERPRISE. CO., LTD. -1230 Chipidea-Microelectronica, S.A. -1235 Novation EMS - 0001 ReMOTE Audio/XStation - 0002 Speedio - 4661 ReMOTE25 -1241 Belkin - 1111 Mouse - 1122 Typhoon Stream Optical Mouse USB+PS/2 - 1155 PS2/USB Browser Combo Mouse - 1166 MI-2150 Trust Mouse - 1177 F8E842-DL Mouse - 1503 Keyboard -124a AirVast - 4017 PC-Chips 802.11b Adapter -124b Nyko (Honey Bee) - 4d01 Airflo EX Joystick -125f A-DATA Technology Co., Ltd. -1264 Covidien Energy-based Devices -1267 Logic3 / SpectraVideo plc - 0103 G-720 Keyboard - 0201 A4Tech SWOP-3 Mouse - a001 JP260 PC Game Pad - c002 Wireless Optical Mouse -126c Aristocrat Technologies -126d Bel Stewart -126e Strobe Data, Inc. -126f TwinMOS - 1325 Mobile Disk - 2168 Mobile Disk III - a006 G240 -1275 Xaxero Marine Software Engineering, Ltd. - 0002 WeatherFax 2000 Demodulator - 0080 SkyEye Weather Satellite Receiver -1286 Marvell Semiconductor, Inc. - 8001 BLOB boot loader firmware -1292 Innomedia - 0258 Creative Labs VoIP Blaster -1293 Belkin Components [hex] - 0002 F5U002 Parallel Port [uss720] - 2101 104-key keyboard -1294 RISO KAGAKU CORP. -129b CyberTAN Technology - 1666 TG54USB -12a7 Trendchip Technologies Corp. -12ab Honey Bee Electronic International Ltd. -12ba Licensed by Sony Computer Entertainment America - 0200 Harmonix Guitar for PlayStation(R)3 - 0210 Harmonix Drum Kit for PlayStation(R)3 -12d1 Huawei Technologies Co., Ltd. - 1001 E620 USB Modem - 1003 E220 HSDPA Modem / E270 HSDPA/HSUPA Modem -12d2 LINE TECH INDUSTRIAL CO., LTD. -12d7 BETTER WIRE FACTORY CO., LTD. -12ef Tapwave, Inc. - 0100 Tapwave Handheld [Tapwave Zodiac] -12f5 Dynamic System Electronics Corp. -12f7 Memorex Products, Inc. - 1a00 TD Classic 003B - 1e23 TravelDrive 2007 Flash Drive -12fd AIN Comm. Technology Co., Ltd - 1001 AWU2000b 802.11b Stick -1307 Transcend Information, Inc. - 0163 512MB USB Flash Drive - 1169 TS2GJF210 JetFlash 210 2GB -1310 Roper - 0001 Class 1 Bluetooth Dongle -1312 ICS Electronics -131d Natural Point - 0155 TrackIR 3 Pro Head Tracker -132b Konica Minolta - 0000 Dimage A2 Camera - 0001 Minolta DiMAGE A2 (ptp) - 0003 Dimage Xg Camera - 0006 Dimage Z2 Camera - 0007 Minolta DiMAGE Z2 (PictBridge mode) - 0008 Dimage X21 Camera - 000a Dimage Scan Dual IV - 000b Dimage Z10 Camera - 000d Dimage X50 Camera [storage?] - 000f Dimage X50 Camera [p2p?] - 0010 Dimage G600 Camera - 0012 Dimage Scan Elite5400 2 - 0013 Dimage X31 Camera - 0015 Dimage G530 Camera - 0017 Dimage Z3 Camera - 0018 Minolta DiMAGE Z3 (PictBridge mode) - 0019 Dimage A200 Camera - 0021 Dimage Z5 Camera - 0022 Minolta DiMAGE Z5 (PictBridge mode) -1342 Mobility - 0200 EasiDock 200 Hub - 0201 EasiDock 200 Keyboard and Mouse Port - 0202 EasiDock 200 Serial Port - 0203 EasiDock 200 Printer Port - 0204 Ethernet - 0304 EasiDock Ethernet -1348 Katsuragawa Electric Co., Ltd. -134e Digby's Bitpile, Inc. DBA D Bit -136b STEC -1370 Swissbit - 6828 Victorinox Flash Drive -1371 Dick Smith Electronics - 9022 RT2573 - 9032 C-Net CWD-854 rev F -1376 Vimtron Electronics Co., Ltd. -1385 Netgear, Inc - 4250 WG111T - 4251 WG111T (no firmware) - 5f00 WPN111 RangeMax(TM) Wireless USB 2.0 Adapter - 5f01 WPN111 (no firmware) -138e Jungo LTD - 9000 Raisonance S.A. STM32 ARM evaluation board -1390 TOMTOM B.V. -1395 Sennheiser Communications - 3556 USB Headset -1398 Q-tec - 2103 USB 2.0 Storage Device -13ad Baltech - 9999 Card reader -13b0 PerkinElmer Optoelectronics - 000a Alesis Photon X25 MIDI Controller -13b1 Linksys - 000b WUSB11 v4.0 802.11b Adapter - 000d WUSB54G Wireless Adapter - 0011 WUSB54GP v4.0 802.11g Adapter - 0018 USB200M 10/100 Ethernet Adapter - 001a HU200TS Wireless Adapter - 0020 WUSB54GC 802.11g Adapter [ralink rt73] - 0023 WUSB54GR - 0024 WUSBF54G v1.1 802.11g Adapter w/ Wi-Fi Finder -13b3 Nippon Dics Co., Ltd. -13be Ricoh Printing Systems, Ltd. -13ca JyeTai Precision Industrial Co., Ltd. -13cf Wisair Ltd. -13d1 A-Max Technology Macao Commercial Offshore Co. Ltd. -13d2 Shark Multimedia - 0400 Pocket Ethernet [klsi] -13d3 IMC Networks - 3201 VisionDTV USB-Ter/HAMA USB DVB-T device cold - 3202 VisionDTV USB-Ter/HAMA USB DVB-T device warm - 3203 DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) - 3204 DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) - 3205 DNTV Live! Tiny USB2 BDA (No Remote) - 3206 DNTV Live! Tiny USB2 BDA (No Remote) - 3207 DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) - 3208 DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) - 3209 DTV-DVB UDST7022BDA DVB-S Box(Without HID) - 3211 DTV-DVB Hybrid Analog/Capture / Pinnacle PCTV 310e - 3212 DTV-DVB UDTT704C - DVBT/NTSC/PAL Driver(PCM4) - 3213 DTV-DVB UDTT704D - DVBT/NTSC/PAL Driver (PCM4) - 3214 DTV-DVB UDTT704F -(MiniCard) DVBT/NTSC/PAL Driver(Without HID) - 3215 DTV-DVB UDAT7240 - ATSC/NTSC/PAL Driver(PCM4) - 3216 DTV-DVB UDTT 7047-USB 2.0 DVB-T Driver - 3217 Digital-TV Receiver. - 3219 DTV-DVB UDTT7049 - DVB-T Driver(Without HID) - 3220 DTV-DVB UDTT 7047M-USB 2.0 DVB-T Driver - 3223 DNTV Live! Tiny USB2 BDA (No Remote) - 3224 DNTV Live! Tiny USB2 BDA (No Remote) - 3226 DigitalNow TinyTwin DVB-T Receiver - 3236 DTV-DVB UDTT 7047A-USB 2.0 DVB-T Driver - 3237 DTV-DVB UDTT 704J - dual DVB-T Driver - 3239 DTV-DVB UDTT704D - DVBT/NTSC/PAL Driver(Without HID) - 3240 DTV-DVB UDXTTM6010 - A/D Driver(Without HID) - 3241 DTV-DVB UDXTTM6010 - A/D Driver(Without HID) - 3242 DTV-DVB UDAT7240LP - ATSC/NTSC/PAL Driver(Without HID) - 3243 DTV-DVB UDXTTM6010 - A/D Driver(Without HID) - 3244 DTV-DVB UDTT 7047Z-USB 2.0 DVB-T Driver - 3247 802.11 n/g/b Wireless LAN Adapter - 7020 DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005) - 7022 DTV-DVB UDST7022BDA DVB-S Box(Without HID) -13dc ALEREON, INC. -13dd i.Tech Dynamic Limited -13e1 Kaibo Wire & Cable (Shenzhen) Co., Ltd. -13e5 Rane - 0001 SL-1 -13e6 TechnoScope Co., Ltd. -13fd Initio Corporation -13fe Kingston Technology Company Inc. - 1a00 512MB/1GB Flash Drive - 1a23 512MB Flash Drive - 1d00 DataTraveler 2.0 1GB/4GB Flash Drive / Patriot Xporter 4GB Flash Drive - 1f00 DataTraveler 2.0 4GB Flash Drive -1400 Axxion Group Corp. -1402 Bowe Bell & Howell -1403 Sitronix - 0001 Digital Photo Frame -140e Telechips, Inc. -1410 Novatel Wireless - 1110 Merlin S620 - 1120 Merlin EX720 - 1130 Merlin S720 - 1400 Merlin U740 - 2110 Ovation U720/MCD3000 - 4100 U727 -1415 Nam Tai E&E Products Ltd. or OmniVision Technologies, Inc. - 0000 Sony SingStar USBMIC - 2000 Sony Playstation Eye -1419 ABILITY ENTERPRISE CO., LTD. -1429 Vega Technologies Industrial (Austria) Co. -1430 RedOctane -1431 Pertech Resources, Inc. -1435 Wistron NeWeb - 0711 UR055G - 0826 AR5523 - 0827 AR5523 (no firmware) - 0828 AR5523 - 0829 AR5523 (no firmware) -1436 Denali Software, Inc. -143c Altek Corporation -1453 Radio Shack - 4026 26-183 Serial Cable -1456 Extending Wire & Cable Co., Ltd. -1457 First International Computer, Inc. - 5117 OpenMoko Neo1973 kernel usbnet (g_ether, CDC Ethernet) mode - 5118 OpenMoko Neo1973 Debug board (V2+) - 5119 OpenMoko Neo1973 u-boot cdc_acm serial port - 5120 OpenMoko Neo1973 u-boot usbtty generic serial - 5121 OpenMoko Neo1973 kernel mass storage (g_storage) mode - 5122 OpenMoko Neo1973 kernel cdc_ether USB network - 5123 OpenMoko Neo1973 internal USB CSR4 module - 5124 OpenMoko Neo1973 Bluetooth Device ID service -1461 Staccato Communications -1462 Micro Star International - 5512 MegaStick-1 Flash Stick -1472 Huawei-3Com - 0009 Aolynk WUB320g -147a Formosa Industrial Computing, Inc. - e015 eHome Infrared Receiver - e016 eHome Infrared Receiver -147f Hama GmbH & Co., KG -1484 Elsa AG [hex] - 1746 Ecomo 19H99 Monitor - 7616 Elsa Hub -1485 Silicom - 0001 U2E - 0002 Psion Gold Port Ethernet -1487 DSP Group, Ltd. -148e EVATRONIX SA -148f Ralink Technology, Corp. - 1706 RT2500USB Wireless Adapter - 2570 802.11g WiFi - 2573 RT2501USB Wireless Adapter - 2671 RT2601USB Wireless Adapter - 9020 RT2500USB Wireless Adapter - 9021 RT2501USB Wireless Adapter -1497 Panstrong Company Ltd. -149a Imagination Technologies - 2107 DBX1 DSP core -14aa AVerMedia (again) or C&E - 0001 Avermedia AverTV DVBT USB1.1 (cold) - 0002 Avermedia AverTV DVBT USB1.1 (warm) - 0201 AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0 (cold) - 0221 AVermedia DVBT Tuner Dongle - 0301 AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0 (warm) -14ad CTK Corporation -14ae Printronix Inc. -14af ATP Electronics Inc. -14b0 StarTech.com Ltd. -14b2 Atheros Communications Inc - 3a93 USB WLAN Device - 3c02 C54RU WLAN - 3c22 C54RU -14c0 Rockwell Automation, Inc. -14c2 Gemlight Computer, Ltd - 0250 Storage Adapter V2 - 0350 Storage Adapter V2 -14cd Super Top - 6600 USB 2.0 IDE DEVICE -14d8 JAMER INDUSTRIES CO., LTD. -14dd Raritan Computer, Inc. -14e5 SAIN Information & Communications Co., Ltd. -14ea Planex Communications - ab10 GW-US54GZ - ab11 GU-1000T - ab13 GW-US54Mini -14ed Shure Inc. -1500 Ellisys -1501 Pine-Tum Enterprise Co., Ltd. -1513 Hypercom -1516 CompUSA - 8628 128M Pen Drive -1518 Cheshire Engineering Corp. - 0001 HDReye High Dynamic Range Camera - 0002 HDReye (before firmware loads) -1520 Bitwire Corp. -1524 ENE Technology Inc - 6680 UTS 6680 -1527 Silicon Portals - 0200 YAP Phone (no firmware) - 0201 YAP Phone -1529 UBIQUAM Co., Ltd. - 3100 CDMA 1xRTT USB Modem (U-100/105/200/300/520) -152d JMicron Technology Corp. / JMicron USA Technology Corp. - 2338 JM20337 Hi-Speed USB to SATA & PATA Combo Bridge -152e LG (HLDS) - e001 GSA-5120D DVD-RW -1532 Razer USA, Ltd - 0001 RZ01-020300 Optical Mouse [Diamondback] - 0003 Krait Mouse - 0007 DeathAdder Mouse - 0102 Tarantula Keyboard -1546 U-Blox AG -154b PNY - 0010 USB 2.0 Flash Drive -154d ConnectCounty Holdings Berhad -154e D&M Holdings, Inc. (Denon/Marantz) - 3000 Marantz RC9001 Remote Control -1554 Prolink Microsystems Corp. -1557 OQO - 0002 model 01 WiFi interface - 0003 model 01 Bluetooth interface - 7720 model 01+ Ethernet - 8150 model 01 Ethernet interface -1568 Sunf Pu Technology Co., Ltd -156f Quantum Corporation -1570 ALLTOP TECHNOLOGY CO., LTD. -157b Ketron SRL -157e TRENDnet - 3006 TEW-444UB EU - 3007 TEW-444UB EU (no firmware) - 300a TEW-429UB 802.11g Adapter with HotSpot Detector - 300b TEW-429UB - 300d TEW-429UB C1 - 3204 ALL0298 v2 - 3205 AR5523 - 3206 AR5523 (no firmware) -1582 Fiberline - 6003 WL-430U -1587 SMA Technologie AG -158d Oakley Inc. -1598 Kunshan Guoji Electronics Co., Ltd. -15a2 Freescale Semiconductor, Inc. -15a8 Teams Power Limited -15aa Gearway Electronics (Dong Guan) Co., Ltd. -15ba Olimex Ltd. - 0003 OpenOCD JTAG - 0004 OpenOCD JTAG TINY -15c2 SoundGraph Inc. - ffdc iMON PAD Remote Controller -15c6 Laboratoires MXM - 1000 DigistimSP (cold) - 1001 DigistimSP (warm) - 1002 DigimapSP USB (cold) - 1003 DigimapSP USB (warm) -15c9 D-Box Technologies -15ca Textech International Ltd. - 00c3 Mini Optical Mouse -15d5 Coulomb Electronics Ltd. -15dc Hynix Semiconductor Inc. -15e0 Seong Ji Industrial Co., Ltd. -15e1 RSA - 2007 RSA SecurID (R) Authenticator -15e8 SohoWare - 9100 NUB100 Ethernet [pegasus] - 9110 10/100 USB Ethernet -15e9 Pacific Digital Corp. - 04ce MemoryFrame MF-570 - 1968 MemoryFrame MF-570 - 1969 Digital Frame -15ec Belcarra Technologies Corp. -15f4 HanfTek - 0001 HanfTek UMT-010 USB2.0 DVB-T (cold) - 0025 HanfTek UMT-010 USB2.0 DVB-T (warm) -1604 Tascam - 8000 US-428 Audio/Midi Controller (without fw) - 8001 US-428 Audio/Midi Controller - 8004 US-224 Audio/Midi Controller (without fw) - 8005 US-224 Audio/Midi Controller - 8006 US-122 Audio/Midi Interface (without fw) - 8007 US-122 Audio/Midi Interface -1606 Umax [hex] - 0002 Astra 1236U Scanner - 0010 Astra 1220U - 0030 Astra 2000U - 0050 Scanner - 0060 Astra 3400U - 0130 Astra 2100U - 0160 Astra 5400U - 0230 Astra 2200/2200SU - 0350 Astra 4800/4850 Scanner - 1030 Astra 4000U - 1220 Genesys Logic Scanner Controller NT5.0 - 2010 AstraCam Digital Camera - 2020 AstraCam 1000 - 2030 AstraCam 1800 Digital Camera -1608 Inside Out Networks [hex] - 0001 EdgePort/4 Serial Port - 0002 Edgeport/8 - 0003 Rapidport/4 - 0004 Edgeport/4 - 0005 Edgeport/2 - 0006 Edgeport/4i - 0007 Edgeport/2i - 0008 Edgeport/8 - 000c Edgeport/421 - 000d Edgeport/21 - 000e Edgeport/4 - 000f Edgeport/8 - 0010 Edgeport/2 - 0011 Edgeport/4 - 0012 Edgeport/416 - 0014 Edgeport/8i - 0018 Edgeport/412 - 0019 Edgeport/412 - 001a Edgeport/2+2i - 0101 Edgeport/4 - 0105 Edgeport/2 - 0106 Edgeport/4i - 0107 Edgeport/2i - 010c Edgeport/421 - 010d Edgeport/21 - 0110 Edgeport/2 - 0111 Edgeport/4 - 0112 Edgeport/416 - 0114 Edgeport/8i - 0201 Edgeport/4 - 0203 Rapidport/4 - 0204 Edgeport/4 - 0205 Edgeport/2 - 0206 Edgeport/4i - 0207 Edgeport/2i - 020c Edgeport/421 - 020d Edgeport/21 - 020e Edgeport/4 - 020f Edgeport/8 - 0210 Edgeport/2 - 0211 Edgeport/4 - 0212 Edgeport/416 - 0214 Edgeport/8i - 0215 Edgeport/1 - 0216 EPOS/44 - 0217 Edgeport/42 - 021a Edgeport/2+2i - 021b Edgeport/2c - 021c Edgeport/221c - 021d Edgeport/22c - 021e Edgeport/21c - 021f Edgeport/62 - 0240 Edgeport/1 - 0241 Edgeport/1i - 0242 Edgeport/4s - 0243 Edgeport/8s - 0244 Edgeport/8 - 0245 Edgeport/22c - 0301 Watchport/P - 0302 Watchport/M - 0303 Watchport/W - 0304 Watchport/T - 0305 Watchport/H - 0306 Watchport/E - 0307 Watchport/L - 0308 Watchport/R - 0309 Watchport/A - 030a Watchport/D - 030b Watchport/D - 030c Power Management Port - 030e Power Management Port - 030f Watchport/G - 0310 Watchport/Tc - 0311 Watchport/Hc - 1403 MultiTech Systems MT4X56 Modem - 1a17 Agilent Technologies (E6473) -1619 L & K Precision Technology Co., Ltd. -1621 Wionics Research -1628 Stonestreet One, Inc. -162a Airgo Networks Inc. -162f WiQuest Communications, Inc. -1631 Good Way Technology - 6200 GWUSB2E - c019 RT2573 -1645 Entrega [hex] - 0001 1S Serial Port - 0002 2S Serial Port - 0003 1S25 Serial Port - 0004 4S Serial Port - 0005 E45 Ethernet [klsi] - 0006 Parallel Port - 0007 U1-SC25 SCSI - 0008 Ethernet - 0016 Bi-directional to Parallel Printer Converter - 0080 1 port to Serial Converter - 0081 1 port to Serial Converter - 0093 1S9 Serial Port - 8000 EZ-USB - 8001 1 port to Serial - 8002 2x Serial Port - 8003 1 port to Serial - 8004 2U4S serial/usb hub - 8005 Ethernet - 8080 1 port to Serial - 8081 1 port to Serial - 8093 PortGear Serial Port -164a ChipX -1657 Struck Innovative Systeme GmbH - 3150 SIS3150 USB2.0 to VME interface -1660 Creatix Polymedia GmbH -1668 Actiontec Electronics, Inc. [hex] - 0009 Gateway - 0333 Modem - 0358 InternetPhoneWizard - 0405 Gateway - 0408 Prism2.5 802.11b Adapter - 0413 Gateway - 0421 Prism2.5 802.11b Adapter - 0441 IBM Integrated Bluetooth II - 0500 BTM200B BlueTooth Adapter - 1050 802.11g Wireless Mini adapter - 1441 IBM Integrated Bluetooth II - 2441 BMDC-2 IBM Bluetooth III w.56k - 3441 IBM Integrated Bluetooth III - 6010 Gateway - 6097 802.11b Wireless Adapter - 6106 ROPEX FreeLan 802.11b - 7605 UAT1 Wireless Ethernet Adapter -1669 PiKRON Ltd. [hex] - 1001 uLan2USB Converter - PS1 protocol -1679 Total Phase - 2001 Beagle USB 12 Protocol Analyzer -1682 Maxwise Production Enterprise Ltd. -1684 Godspeed Computer Corp. -1686 ZOOM Corporation - 0045 H4 Digital Recorder -1687 Kingmax Digital Inc. -168c Atheros Communications - 0001 AR5523 - 0002 AR5523 (no firmware) -1690 Askey Computer Corp. [hex] - 0101 Creative Modem Blaster DE5670 - 0102 CDC Modem Board - 0103 Askey 1456 VQE-R3 Modem [conexant] - 0104 HCF V90 Data Fax RTAD Modem - 0107 HCF V.90 Data,Fax,RTAD Modem - 0109 Askey MagicXpress V.90 Pocket Modem [conexant] - 0203 Voyager ADSL Modem Loader - 0204 Voyager ADSL Modem - 0205 DSL Modem - 0206 GlobeSpan ADSL WAN Modem - 0208 DSL Modem - 0209 Voyager 100 ADSL Modem - 0211 Globespan Virata ADSL LAN Modem - 0212 DSL Modem - 0213 HM121d DSL Modem - 0214 HM121d DSL Modem - 0215 Voyager 105 ADSL Modem - 0701 WLAN - 0710 SMCWUSBT-G - 0711 SMCWUSBT-G (no firmware) - 0712 AR5523 - 0713 AR5523 (no firmware) - 0715 Voyager 1055 Laptop Adapter - 0722 RT2573 - 0726 Wi-Fi Wireless LAN Adapter - 0901 Voyager 205 ADSL Router -1696 Hitachi Video and Information System, Inc. -1697 VTec Test, Inc. -16a5 Shenzhen Zhengerya Cable Co., Ltd. -16ab Global Sun Technology - 7801 AR5523 - 7802 AR5523 (no firmware) - 7811 AR5523 - 7812 AR5523 (no firmware) -16ac Dongguan ChingLung Wire & Cable Co., Ltd. -16c0 VOTI - 03e8 free for internal lab use 1000 - 03e9 free for internal lab use 1001 - 03ea free for internal lab use 1002 - 03eb free for internal lab use 1003 - 03ec free for internal lab use 1004 - 03ed free for internal lab use 1005 - 03ee free for internal lab use 1006 - 03ef free for internal lab use 1007 - 03f0 free for internal lab use 1008 - 03f1 free for internal lab use 1009 - 076b OpenPCD 13.56MHz RFID Reader - 076c OpenPICC 13.56MHz RFID Simulator (native) - 08ac OpenBeacon USB stick -16cc silex technology, Inc. -16d3 Frontline Test Equipment, Inc. -16d5 AnyDATA Corporation - 6501 CDMA 2000 1xRTT/EV-DO USB Modem -16d8 CMOTECH Co., Ltd. - 5141 CMOTECH CDMA Technologies USB modem - 5543 CDMA 2000 1xRTT/1xEVDO USB modem - 6280 CMOTECH CDMA Technologies USB modem -16df King Billion Electronics Co., Ltd. -16f5 Futurelogic Inc. -1706 BlueView Technologies, Inc. -1707 ARTIMI -170b Swissonic - 0011 MIDI-USB 1x1 -170d Avnera -1733 Cellink Technology Co., Ltd - 0101 RF Wireless Optical Mouse OP-701 -1736 CANON IMAGING SYSTEM TECHNOLOGIES INC. -1737 Linksys - 0039 USB1000 -1740 Senao - 2000 NUB-8301 -1743 General Atomics -174c ASMedia Technology Inc. -174f Syntek - 5a35 1.3MPixel Web Cam - Asus G1s - 6a31 Web Cam - Asus A8J, F3S, F5R, VX2S, V1S - 6a33 Web Cam - Asus F3SA, F9J, F9S - 6a51 2.0MPixel Web Cam - Asus Z96J, Z96S, S96S - 6a54 Web Cam - 6d51 2.0Mpixel Web Cam - Eurocom D900C - 8a12 0.3MPixel Web Cam - Packard Bell MX37-T-003 - a311 1.3MPixel Web Cam - Asus A3A, A6J, A6K, A6M, A6R, A6T, A6V, A7T, A7sv, A7U - a312 1.3MPixel Web Cam - a821 Web Cam - Packard Bell BU45, PB Easynote MX66-208W - aa11 Web Cam -1759 LucidPort Technology, Inc. -1772 System Level Solutions, Inc. -1781 Multiple Vendors - 083e MetaGeek Wi-Spy - 0938 Iguanaworks USB IR Transceiver -1782 Spreadtrum Communications Inc. -1784 TopSeed Technology Corp. -1788 ShenZhen Litkconn Technology Co., Ltd. -1796 Printrex, Inc. -1797 JALCO CO., LTD. -17a5 Advanced Connection Technology Inc. -17a7 MICOMSOFT CO., LTD. -17b3 Grey Innovation - 0004 Linux-USB Midi Gadget -17c3 Singim International Corp. -17cc Native Instruments - 0815 Audio Kontrol 1 - 1940 RigKontrol3 - 1969 RigKontrol2 - 1978 Audio 8 DJ - 4711 Kore Controller - 4712 Kore Controller 2 -17cf Hip Hing Cable & Plug Mfy. Ltd. -17d0 Sanford L.P. -17d3 Korea Techtron Co., Ltd. -17e9 Newnham Research - 0051 USB VGA Adaptor -17eb Cornice, Inc. -17ef Lenovo - 3815 ChipsBnk 2GB USB Stick -17f5 K.K. Rocky -17f6 Unicomp, Inc -1822 Twinhan - 3201 VisionDTV USB-Ter/HAMA USB DVB-T device cold - 3202 VisionDTV USB-Ter/HAMA USB DVB-T device warm -1831 Gwo Jinn Industries Co., Ltd. -1832 Huizhou Shenghua Industrial Co., Ltd. -1854 Memory Devices Ltd. -185b Compro - d000 Compro Videomate DVB-U2000 - DVB-T USB cold - d001 Compro Videomate DVB-U2000 - DVB-T USB warm -1861 Tech Technology Industrial Company -1862 Teridian Semiconductor Corp. -1871 Aveo Technology Corp. -1894 Topseed - 5632 Atek Tote Remote - 5641 TSAM-004 Presentation Remote -1897 Evertop Wire Cable Co. -18b6 Mikkon Technology Limited -18b7 Zotek Electronic Co., Ltd. -18c5 AMIT - 0002 CG-WLUSB2GO -18d5 Starline International Group Limited -18d9 Kaba - 01xy LEGIC advant desktop reader -18e3 Fitipower Integrated Technology Inc -18e8 Qcom - 6196 RT2573 - 6229 RT2573 -18ea Matrox Graphics, Inc. - 0002 DualHead2Go [Analog Edition] - 0004 TripleHead2Go [Digital Edition] -18fd FineArch Inc. -190d Motorola GSG -1914 Alco Digital Devices Limited -1915 Linksys - 2233 WUSB11 v2.8 802.11b Adapter - 2234 WUSB54G 802.11g Adapter -192f Avago Technologies, Pte. -1930 Shenzhen Xianhe Technology Co., Ltd. -1931 Ningbo Broad Telecommunication Co., Ltd. -1949 Lab126 -1951 Hyperstone AG -1953 Ironkey Inc. -1954 Radiient Technologies -195d Itron Technology iONE - 7002 Libra-Q11 IR remote - 7006 Libra-Q26 / 1.0 Remote - 7777 Scorpius wireless keyboard -1967 CASIO HITACHI Mobile Communications Co., Ltd. -196b Wispro Technology Inc. -1970 Dane-Elec Corp. USA -1975 Dongguan Guneetal Wire & Cable Co., Ltd. -1976 Chipsbrand Microelectronics (HK) Co., Ltd. -1977 T-Logic - 0111 TL203 MP3 Player and Voice Recorder -1989 Nuconn Technology Corp. -198f Beceem Communications Inc. -1990 Acron Precision Industrial Co., Ltd. -1995 Trillium Technology Pty. Ltd. - 3202 REC-ADPT-USB (recorder) - 3203 REC-A-ADPT-USB (recorder) -199e The Imaging Source Europe GmbH -199f Benica Corporation -19a8 Biforst Technology Inc. -19af S Life - 6611 Celestia VoIP Phone -19b5 B & W Group -19b6 Infotech Logistic, LLC -19ca Mindtribe - 0001 Sandio 3D HID Mouse -19cf Parrot SA -19e1 WeiDuan Electronic Accessory (S.Z.) Co., Ltd. -19e8 Industrial Technology Research Institute -19ef Pak Heng Technology (Shenzhen) Co., Ltd. -19ff Best Buy - 0201 Rocketfish Wireless 2.4G Laser Mouse -1a08 Bellwood International, Inc. -1a0a USB-IF non-workshop - badd USB OTG Compliance test device -1a12 KES Co., Ltd. -1a25 Amphenol East Asia Ltd. -1a2a Seagate Branded Solutions -1a36 Biwin Technology Ltd. -1a40 TERMINUS TECHNOLOGY INC. -1a41 Action Electronics Co., Ltd. -1a4a Silicon Image -1a4b SafeBoot International B.V. -1a61 Abbott Diabetes Care -1a6a Spansion Inc. -1a6d SamYoung Electronics Co., Ltd -1a6e Global Unichip Corp. -1a6f Sagem Orga GmbH -1a79 Bayer Health Care LLC -1a7b Lumberg Connect GmbH & Co. KG -1a89 Dynalith Systems Co., Ltd. -1a8b SGS Taiwan Ltd. -1a98 Leica Camera AG -1aa4 Data Drive Thru, Inc. -1aa5 UBeacon Technologies, Inc. -1aa6 eFortune Technology Corp. -1acb Salcomp Plc -1ad1 Desay Wire Co., Ltd. -1ae4 ic-design Reinhard Gottinger GmbH -1aed High Top Precision Electronic Co., Ltd. -1aef Conntech Electronic (Suzhou) Corporation -1b04 Meilhaus Electronic GmBH - 0630 ME-630 - 0940 ME-94 - 0950 ME-95 - 0960 ME-96 - 1000 ME-1000 - 100a ME-1000 - 100b ME-1000 - 1400 ME-1400 - 140a ME-1400A - 140b ME-1400B - 140c ME-1400C - 140d ME-1400D - 140e ME-1400E - 14ea ME-1400EA - 14eb ME-1400EB - 1604 ME-1600/4U - 1608 ME-1600/8U - 160c ME-1600/12U - 160f ME-1600/16U - 168f ME-1600/16U8I - 4610 ME-4610 - 4650 ME-4650 - 4660 ME-4660 - 4661 ME-4660I - 4662 ME-4660 - 4663 ME-4660I - 4670 ME-4670 - 4671 ME-4670I - 4672 ME-4670S - 4673 ME-4670IS - 4680 ME-4680 - 4681 ME-4680I - 4682 ME-4680S - 4683 ME-4680IS - 6004 ME-6000/4 - 6008 ME-6000/8 - 600f ME-6000/16 - 6014 ME-6000I/4 - 6018 ME-6000I/8 - 601f ME-6000I/16 - 6034 ME-6000ISLE/4 - 6038 ME-6000ISLE/8 - 603f ME-6000ISLE/16 - 6044 ME-6000/4/DIO - 6048 ME-6000/8/DIO - 604f ME-6000/16/DIO - 6054 ME-6000I/4/DIO - 6058 ME-6000I/8/DIO - 605f ME-6000I/16/DIO - 6074 ME-6000ISLE/4/DIO - 6078 ME-6000ISLE/8/DIO - 607f ME-6000ISLE/16/DIO - 6104 ME-6100/4 - 6108 ME-6100/8 - 610f ME-6100/16 - 6114 ME-6100I/4 - 6118 ME-6100I/8 - 611f ME-6100I/16 - 6134 ME-6100ISLE/4 - 6138 ME-6100ISLE/8 - 613f ME-6100ISLE/16 - 6144 ME-6100/4/DIO - 6148 ME-6100/8/DIO - 614f ME-6100/16/DIO - 6154 ME-6100I/4/DIO - 6158 ME-6100I/8/DIO - 615f ME-6100I/16/DIO - 6174 ME-6100ISLE/4/DIO - 6178 ME-6100ISLE/8/DIO - 617f ME-6100ISLE/16/DIO - 6259 ME-6200I/9/DIO - 6359 ME-6300I/9/DIO - 810a ME-8100A - 810b ME-8100B - 820a ME-8200A - 820b ME-8200B -1b20 MStar Semiconductor, Inc. -1b22 WiLinx Corp. -1b26 Cellex Power Products, Inc. -1b27 Current Electronics Inc. -1b28 NAVIsis Inc. -1b32 Ugobe Life Forms, Inc. -1b36 ViXS Systems, Inc. -1b3f Generalplus Technology Inc. -1b47 Energizer Holdings, Inc. - 0001 CHUSB Duo Charger (NiMH AA/AAA USB smart charger) -1b48 Plastron Precision Co., Ltd. -1b59 K.S. Terminals Inc. -1b5a Chao Zhou Kai Yuan Electric Co., Ltd. -1b65 The Hong Kong Standards and Testing Centre Ltd. -1b72 ATERGI TECHNOLOGY CO., LTD. -1b76 Legend Silicon Corp. -1b86 Dongguan Guanshang Electronics Co., Ltd. -1b88 ShenMing Electron (Dong Guan) Co., Ltd. -1b8c Altium Limited -1b8d e-MOVE Technology Co., Ltd. -1b8e Amlogic, Inc. -1b8f MA LABS, Inc. -1b98 YMax Communications Corp. -1b99 Shenzhen Yuanchuan Electronic -1ba1 JINQ CHERN ENTERPRISE CO., LTD. -1ba2 Lite Metals & Plastic (Shenzhen) Co., Ltd. -1ba4 Ember Corporation - 0001 InSight USB Link -1ba8 China Telecommunication Technology Labs -1bad Harmonix Music - 0002 Harmonix Guitar for Xbox 360 - 0003 Harmonix Drum Kit for Xbox 360 -1bbb T & A Mobile Phones -1bc4 Ford Motor Co. -1bc5 AVIXE Technology (China) Ltd. -1bce Contac Cable Industrial Limited -1bcf Sunplus Innovation Technology Inc. -1bd0 Hangzhou Riyue Electronic Co., Ltd. -1bde P-TWO INDUSTRIES, INC. -1bef Shenzhen Tongyuan Network-Communication Cables Co., Ltd -1bf0 RealVision Inc. -1bf5 Extranet Systems Inc. -1bf6 Orient Semiconductor Electronics, Ltd. -1bfd TouchPack - 1688 Resistive Touch Screen -1c02 Kreton Corporation -1c04 QNAP System Inc. -1c0d Relm Wireless -1c10 Lanterra Industrial Co., Ltd. -1c13 ALECTRONIC LIMITED -1c1a Datel Electronics Ltd. -1c1b Volkswagen of America, Inc. -1c1f Goldvish S.A. -1c20 Fuji Electric Device Technology Co., Ltd. -1c21 ADDMM LLC -1c22 ZHONGSHAN CHIANG YU ELECTRIC CO., LTD. -1c26 Shanghai Haiying Electronics Co., Ltd. -1c27 HuiYang D & S Cable Co., Ltd. -1c31 LS Cable Ltd. -1c37 Authorizer Technologies, Inc. -1c3d NONIN MEDICAL INC. -1c3e Wep Peripherals -1c49 Cherng Weei Technology Corp. -1c6b Philips & Lite-ON Digital Solutions Corporation -1c6c Skydigital Inc. -1c77 Kaetat Industrial Co., Ltd. -1c78 Datascope Corp. -1c79 Unigen Corporation -1c7a LighTuning Technology Inc. -1c7b LUXSHARE PRECISION INDUSTRY (SHENZHEN) CO., LTD. -1c87 2N TELEKOMUNIKACE a.s. -1c88 Somagic, Inc. -1c89 HONGKONG WEIDIDA ELECTRON LIMITED -1c8e ASTRON INTERNATIONAL CORP. -1c98 ALPINE ELECTRONICS, INC. -1ca0 ACCARIO Inc. -1cb3 Aces Electronic Co., Ltd. -1cb4 OPEX CORPORATION -1cbe Luminary Micro Inc. -1cbf FORTAT SKYMARK INDUSTRIAL COMPANY -1cc0 PlantSense -1cca NextWave Broadband Inc. -1ccd Bodatong Technology (Shenzhen) Co., Ltd. -1cd4 adp corporation -1cd5 Firecomms Ltd. -1cd6 Antonio Precise Products Manufactory Ltd. -1cde Telecommunications Technology Association (TTA) -1cdf WonTen Technology Co., Ltd. -1ce0 EDIMAX TECHNOLOGY CO., LTD. -1ce1 Amphenol KAE -1cfc ANDES TECHNOLOGY CORPORATION -1cfd Flextronics Digital Design Japan, LTD. -1d08 NINGBO HENTEK DRAGON ELECTRONICS CO., LTD. -1d09 TechFaith Wireless Technology Limited -1d0a Johnson Controls, Inc. The Automotive Business Unit -1d0b HAN HUA CABLE & WIRE TECHNOLOGY (J.X.) CO., LTD. -1d14 ALPHA-SAT TECHNOLOGY LIMITED -1d1f Diostech Co., Ltd. -1d20 SAMTACK INC. -1d50 OpenMoko, Inc. -1d5b Smartronix, Inc. -1d6b Linux Foundation - 0001 1.1 root hub - 0002 2.0 root hub - 0003 3.0 root hub -1ebb NuCORE Technology, Inc. -2001 D-Link Corp. [hex] - 0001 DWL-120 WIRELESS ADAPTER - 0201 DHN-120 10Mb Home Phoneline Adapter - 1a00 10/100 Ethernet - 200c 10/100 Ethernet - 3200 DWL-120 802.11b (Atmel RFMD503A) [usbvnetr] - 3500 Elitegroup Computer Systems WLAN card WL-162 - 3700 DWL-122 802.11b - 3701 DWL-G120 Spinnaker 802.11b - 3702 DWL-120 rev F - 3703 DWL-122 802.11b - 3704 DWL-G122 802.11g rev. A2 - 3705 AirPlus G DWL-G120 Wireless Adapter(rev.C) - 3761 IEEE 802.11g USB2.0 Wireless Network Adapter-PN - 3a00 DWL-AG132 - 3a01 DWL-AG132 (no firmware) - 3a02 DWL-G132 - 3a03 DWL-G132 (no firmware) - 3a04 DWL-AG122 - 3a05 DWL-AG122 (no firmware) - 3a80 AirPlus Xtreme G DWL-G132 Wireless Adapter - 3a81 predator Bootloader Download - 3a82 AirPremier AG DWL-AG132 Wireless Adapter - 3a83 predator Bootloader Download - 3b00 AirPlus DWL-120+ Wireless Adapter - 3b01 WLAN Boot Device - 3c00 DWL-G122 802.11g rev. B1 [ralink] - 3c01 AirPlus AG DWL-AG122 Wireless Adapter - 3c02 AirPlus G DWL-G122 Wireless Adapter - 3c05 DUB-E100 Fast Ethernet [asix] - 4000 DSB-650C Ethernet [klsi] - 4001 DSB-650TX Ethernet [pegasus] - 4002 DSB-650TX Ethernet [pegasus] - 4003 DSB-650TX-PNA Ethernet [pegasus] - 400b 10/100 Ethernet - 4102 10/100 Ethernet - 5100 DSL-200 ADSL ATM Modem - 5102 DSL-200 ADSL Loader - 5b00 Remote NDIS Network Device - 9414 Cable Modem - 9b00 Broadband Cable Modem Remote NDIS Device - abc1 DSB-650 Ethernet [pegasus] - f013 DLink 7 port USB2.0 Hub - f10d Accent Communications Modem - f110 DUB-AV300 A/V Capture - f111 DBT-122 Bluetooth adapter - f112 DUB-T210 Audio Device - f116 Formosa 2 - f117 Formosa 3 - f118 Formosa 4 -2019 PLANEX - 3220 GW-US11S WLAN - 5303 GW-US54GXS - ab01 GW-US54HP - ab50 GW-US54Mini2 - c002 GW-US54SG - c007 GW-US54GZL - ed02 GW-USMM -2040 Hauppauge - 6502 WinTV HVR-900 - 6503 WinTV HVR-930 - 7050 Nova-T Stick - 9300 WinTV NOVA-T USB2 (cold) - 9301 WinTV NOVA-T USB2 (warm) -2101 ActionStar - 0201 SIIG 4-to-2 Printer Switch -2162 Creative (?) - 2031 Network Blaster Wireless Adapter - 500c DE5771 Modem Blaster - 8001 Broadxent BritePort DSL Bridge 8010U -2222 MacAlly - 0004 iWebKey Keyboard - 4050 AirStick joystick -2233 RadioShack Corporation - 6323 USB Electronic Scale -22b8 Motorola PCS - 0001 Wally 2.2 chipset - 0002 Wally 2.4 chipset - 0005 V.60c/V.60i GSM Phone - 0850 Bluetooth Device - 1001 Patriot 1.0 (GSM) chipset - 1002 Patriot 2.0 chipset - 1005 T280e GSM/GPRS Phone - 1101 Patriot 1.0 (TDMA) chipset - 1801 Rainbow chipset flash - 2035 Bluetooth Device - 2805 GSM Modem - 2821 T720 GSM Phone - 2822 V.120e GSM Phone - 2823 Flash Interface - 2a01 MSM6050 chipset - 2a02 CDMA modem - 2a03 MSM6050 chipset flash - 2a21 V710 GSM Phone (P2K) - 2a22 V710 GSM Phone (AT) - 2a23 MSM6100 chipset flash - 2a41 MSM6300 chipset - 2a42 Usb Modem - 2a43 MSM6300 chipset flash - 2a61 E815 GSM Phone (P2K) - 2a62 E815 GSM Phone (AT) - 2a63 MSM6500 chipset flash - 2a81 MSM6025 chipset - 2a83 MSM6025 chipset flash - 2ac1 MSM6100 chipset - 2ac3 MSM6100 chipset flash - 3001 A835/E1000 GSM Phone (P2K) - 3002 A835/E1000 GSM Phone (AT) - 3801 C350L/C450 (P2K) - 3802 C330/C350L/C450/EZX GSM Phone (AT) - 3803 Neptune LT chipset flash - 4001 OMAP 1.0 chipset - 4002 A920/A925 UMTS Phone - 4003 OMAP 1.0 chipset flash - 4008 OMAP 1.0 chipset RDL - 4204 MPx200 Smartphone - 4214 MPc GSM - 4224 MPx220 Smartphone - 4234 MPc CDMA - 4244 MPx100 Smartphone - 4801 Neptune LTS chipset - 4803 Neptune LTS chipset flash - 4810 Triplet GSM Phone (storage) - 4901 Triplet GSM Phone (P2K) - 4902 Triplet GSM Phone (AT) - 4903 Neptune LTE chipset flash - 4a01 Neptune LTX chipset - 4a03 Neptune LTX chipset flash - 4a32 L6-imode Phone - 5801 Neptune ULS chipset - 5803 Neptune ULS chipset flash - 5901 Neptune VLT chipset - 5903 Neptune VLT chipset flash - 6001 Dalhart EZX - 6003 Dalhart flash - 6004 EZX GSM Phone (CDC Net) - 6008 Dalhart RDL - 6009 EZX GSM Phone (P2K) - 600a Dalhart EZX config 17 - 600b Dalhart EZX config 18 - 600c EZX GSM Phone (USBLAN) - 6021 JUIX chipset - 6023 JUIX chipset flash - 6026 Flash RAM Downloader/miniOS - 6027 USBLAN - 604c EZX GSM Phone (Storage) - 6101 Talon integrated chipset - 6401 Argon chipset - 6403 Argon chipset flash - 6415 ROKR Z6 (MTP mode) - 6604 Washington CDMA Phone - 6631 CDC Modem -22b9 eTurboTouch Technology, Inc. -22ba Technology Innovation Holdings, Ltd -2304 Pinnacle Systems, Inc. [hex] - 0109 Studio PCTV USB (SECAM) - 0110 Studio PCTV USB (PAL) - 0111 Miro PCTV USB - 0112 Studio PCTV USB (NTSC) with FM radio - 0201 Systems MovieBox Device - 0204 MovieBox USB_B - 0205 DVC 150B - 0206 Systems MovieBox Deluxe Device - 0207 Dazzle DVC90 Video Device - 0208 Studio PCTV USB2 - 020e PCTV 200e - 020f PCTV 400e BDA Device - 0210 Studio PCTV USB (PAL) with FM radio - 0212 Studio PCTV USB (NTSC) - 0213 500-USB Device - 0214 Studio PCTV USB (PAL) with FM radio - 0216 PCTV 60e - 0219 PCTV 260e - 021a Dazzle DVC100 Audio Device - 021b Dazzle DVC130/DVC170 - 021d Dazzle DVC130 - 021e Dazzle DVC170 - 021f PCTV Sat HDTV Pro BDA Device - 0222 PCTV Sat Pro BDA Device - 0223 DazzleTV Sat BDA Device - 0226 PCTV 330e - 0227 PCTV for Mac, HD Stick - 0228 PCTV DVB-T Flash Stick - 022a PCTV 160e - 022b PCTV 71e - 0232 PCTV 170e - 0300 Studio Linx Video input cable (NTSC) - 0301 Studio Linx Video input cable (PAL) - 0302 Dazzle DVC120 - 0419 PCTV Bungee USB (PAL) with FM radio - 061d PCTV Deluxe (NTSC) Device - 061e PCTV Deluxe (PAL) Device -2318 Shining Technologies, Inc. [hex] - 0011 CitiDISK Jr. IDE Enclosure -2375 Digit@lway, Inc. - 0001 Digital Audio Player -2406 SANHO Digital Electronics Co., Ltd. - 6688 PD7X Portable Storage -2478 Tripp-Lite - 2008 U209-000-R Serial Port -2632 TwinMOS - 3209 7-in-1 Card Reader -2650 Electronics For Imaging, Inc. [hex] -2730 Citizen - 200f CT-S310 Label printer -2735 DigitalWay - 0003 MPIO 1.5GB Hard Disc Drive -2770 NHJ, Ltd - 0a01 ScanJet 4600 series - 905c Che-Ez Snap SNAP-U/Digigr8/Soundstar TDC-35 - 9060 A130 - 9120 Che-ez! Snap / iClick Tiny VGA Digital Camera - 9130 TCG 501 - 913c Argus DC-1730 - 9150 Mini Cam - 9153 iClick 5X - 915d Cyberpix S-210S / Little Tikes My Real Digital Camera - 930b CCD Webcam(PC370R) - 930c CCD Webcam(PC370R) -2899 Toptronic Industrial Co., Ltd -2c02 Planex Communications - 14ea GW-US11H WLAN -2fb2 Fujitsu, Ltd -3125 Eagletron - 0001 TrackerPod Camera Stand -3176 Whanam Electronics Co., Ltd -3275 VidzMedia Pte Ltd - 4fb1 MonsterTV P2H -3334 AEI - 1701 Fast Ethernet -3340 Yakumo - 043a Mio A701 DigiWalker PPCPhone - 0e3a Pocket PC 300 GPS SL / Typhoon MyGuide 3500 - a0a3 deltaX 5 BT (D) PDA -3504 Micro Star - f110 Security Key -3538 Power Quotient International Co., Ltd - 0001 Travel Flash - 0015 Mass Storge Device - 0022 Hi-Speed Mass Storage Device - 0042 Cool Drive U339 Flash Disk -3579 DIVA - 6901 Media Reader -3636 InVibro -3838 WEM - 0001 5-in-1 Card Reader -3923 National Instruments Corp. - 12c0 DAQPad-6020E - 12d0 DAQPad-6507 - 12e0 NI 4350 - 12f0 NI 5102 - 1750 DAQPad-6508 - 17b0 USB-ISA-Bridge - 1820 DAQPad-6020E (68 pin I/O) - 1830 DAQPad-6020E (BNC) - 1f00 DAQPad-6024E - 1f10 DAQPad-6024E - 1f20 DAQPad-6025E - 1f30 DAQPad-6025E - 1f40 DAQPad-6036E - 1f50 DAQPad-6036E - 2f80 DAQPad-6052E - 2f90 DAQPad-6052E - 703c USB-485 RS485 Cable - 7254 NI MIO (data acquisition card) firmware updater - 729e USB-6251 (OEM) data acquisition card -40bb I-O Data - 0a09 USB2.0-SCSI Bridge USB2-SC -4101 i-rocks - 1301 IR-2510 usb phone -4102 iRiver, Ltd. - 1001 iFP-100 series mp3 player - 1003 iFP-300 series mp3 player - 1005 iFP-500 series mp3 player - 1007 iFP-700 series mp3/ogg vorbis player - 1008 iFP-800 series mp3/ogg vorbis player - 100a iFP-1000 series mp3/ogg vorbis player - 1014 T20 series mp3/ogg vorbis player (ums firmware) - 1101 iFP-100 series mp3 player (ums firmware) - 1103 iFP-300 series mp3 player (ums firmware) - 1105 iFP-500 series mp3 player (ums firmware) - 1113 T10 (alternate) - 1117 T10 - 1119 T30 series mp3/ogg/wma player - 2002 H10 6GB - 2101 H10 20GB (mtp) - 2102 H10 5GB (mtp) - 2105 H10 5/6GB (mtp) -413c Dell Computer Corp. - 0058 Port Replicator - 1001 Keyboard Hub - 1002 Keyboard Hub - 2001 Keyboard HID Support - 2002 SK-8125 Keyboard - 2003 Keyboard - 2005 RT7D50 Keyboard - 2100 SK-3106 Keyboard - 2101 SmartCard Reader Keyboard - 2500 DRAC4 Remote Access Card - 3010 Optical Wheel Mouse - 3200 Mouse - 4001 Axim X5 - 4002 Axim X3 - 4003 Axim X30 - 4004 Axim Sync - 4005 Axim Sync - 4006 Axim Sync - 4007 Axim Sync - 4008 Axim Sync - 4009 Axim Sync - 4011 Axim X51v - 5103 AIO Printer A940 - 5105 AIO Printer A920 - 5107 AIO Printer A960 - 5109 Photo AIO Printer 922 - 5110 Photo AIO Printer 962 - 5111 Photo AIO Printer 942 - 5112 Photo AIO Printer 924 - 5113 Photo AIO Printer 944 - 5114 Photo AIO Printer 964 - 5115 Photo AIO Printer 926 - 5116 AIO Printer 946 - 5117 Photo AIO Printer 966 - 5118 AIO 810 - 5124 Laser MFP 1815 - 5128 Photo AIO 928 - 5200 Laser Printer - 5202 Printing Support - 5203 Printing Support - 5210 Printing Support - 5211 Printing Support - 5220 Laser MFP 1600n - 5225 Printing Support - 5226 Printing Support - 5300 Laser Printer - 5400 Laser Printer - 5401 Laser Printer - 5601 Laser Printer 3100cn - 5602 Laser Printer 3000cn - 5631 Laser Printer 5100cn - 5905 Printing Support - 8000 BC02 Bluetooth USB Adapter - 8010 TrueMobile Bluetooth Module in - 8100 TrueMobile 1180 802.11b Adapter - 8102 TrueMobile 1300 USB2.0 WLAN Card - 8103 Wireless 350 Bluetooth - 8104 Wireless 1450 Dual-band (802.11a/b/g) USB2.0 Adapter - 8105 U2 in HID - Driver - 8106 Wireless 350 Bluetooth Internal Card in - 8110 Wireless 3xx Bluetooth Internal Card - 8111 Wireless 3xx Bluetooth Internal Card in - 8114 Wireless 5700 Mobile Broadband (CDMA EV-DO) Minicard Modem - 8115 Wireless 5500 Mobile Broadband (3G HSDPA) Minicard Modem - 8116 Wireless 5505 Mobile Broadband (3G HSDPA) Minicard Modem - 8117 Wireless 5700 Mobile Broadband (CDMA EV-DO) Expresscard Modem - 8118 Wireless 5510 Mobile Broadband (3G HSDPA) Expresscard Status Port - 8120 Bluetooth adapter - 8121 Eastfold in HID - 8122 Eastfold in DFU - 8123 eHome Infrared Receiver - 8124 eHome Infrared Receiver - 8126 Wireless 355 Bluetooth - 8127 Wireless 355 Module with Bluetooth 2.0 + EDR Technology. - 8128 Wireless 5700-Sprint Mobile Broadband (CDMA EV-DO) Mini-Card Status Port - 8129 Wireless 5700-Telus Mobile Broadband (CDMA EV-DO) Mini-Card Status Port - 8131 Wireless 360 Bluetooth 2.0 + EDR module. - 8133 Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port - 8134 Wireless 5720 Sprint Mobile Broadband (EVDO Rev-A) Minicard Status Port - 8135 Wireless 5720 TELUS Mobile Broadband (EVDO Rev-A) Minicard Diagnostics Port - 8136 Wireless 5520 Cingular Mobile Broadband (3G HSDPA) Minicard Diagnostics Port - 8137 Wireless 5520 Voda L Mobile Broadband (3G HSDPA) Minicard Status Port - 8138 Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard EAP-SIM Port - 8140 Wireless 360 Bluetooth - 8142 Mobile 360 in DFU - 8501 Bluetooth Adapter - a001 Hub - a005 Internal 2.0 Hub - a700 Hub (in 1905FP LCD Monitor) -4146 USBest Technology - 9281 Iomega Micro Mini 128MB Flash Drive - ba01 Intuix Flash Drive -4242 USB Design by Example - 4201 Buttons and Lights HID device - 4220 Echo 1 Camera -4348 WinChipHead - 5523 USB->RS 232 adapter with Prolifec PL 2303 chipset - 5537 13.56Mhz RFID Card Reader and Writer - 5584 CH34x printer adapter cable -4572 Shuttle, Inc. - 4572 Shuttle PN31 Remote -4586 Panram - 1026 Crystal Bar Flash Drive -4670 EMS Production - 9394 Game Cube USB Memory Adaptor 64M -4752 Miditech - 0011 Midistart-2 -4766 Aceeca - 0001 MEZ1000 RDA -4855 Memorex - 7288 Ultra Traveldrive 160G 2.5" HDD -5032 Grandtec - 0bb8 Grandtec USB1.1 DVB-T (cold) - 0bb9 Grandtec USB1.1 DVB-T (warm) - 0fa0 Grandtec USB1.1 DVB-T (cold) - 0fa1 Grandtec USB1.1 DVB-T (warm) -5041 Linksys (?) - 2234 WUSB54G 802.11g Adapter -5173 Sweex - 1809 ZD1211 -5345 Owon - 1234 PDS6062T Oscilloscope -544d Transmeta Corp. -5543 UC-Logic Technology Corp. - 0002 SuperPen WP3325U Tablet - 0003 Genius MousePen 4x3 Tablet/Aquila L1 Tablet - 0004 Genius MousePen 5x4 Tablet - 0005 Genius MousePen 8x6 Tablet - 0041 Genius PenSketch 6x8 Tablet - 0042 Genius PenSketch 12x9 Tablet -55aa OnSpec Electronic, Inc. - 0015 Hard Drive - 0102 SuperDisk - 0103 IDE Hard Drive - 0201 DDI to Reader-19 - 1234 ATAPI Bridge - a103 Sandisk SDDR-55 SmartMedia Card Reader - b000 USB to CompactFlash Card Reader - b004 OnSpec MMC/SD Reader/Writer - b00b USB to Memory Stick Card Reader - b00c USB to SmartMedia Card Reader - b012 Mitsumi FA402M 8-in-2 Card Reader - b200 Compact Flash Reader - b204 MMC/ SD Reader - b207 Memory Stick Reader -5986 Acer, Inc - 0102 Crystal Eye webcam -5a57 Zinwell - 0260 RT2570 -6189 Sitecom - 182d USB 2.0 Ethernet - 2068 USB to serial cable (v2) -6253 TwinHan Technology Co., Ltd - 0100 Ir reciver f. remote control -636c CoreLogic, Inc. -6547 Arkmicro Technologies Inc. - 0232 ARK3116 Serial -6666 Prototype product Vendor ID - 0667 WiseGroup Smart Joy PSX, PS-PC Smart JoyPad - 2667 JCOP BlueZ Smartcard reader - 8804 WiseGroup SuperJoy Box 5 -6891 3Com - a727 3CRUSB10075 -6993 Freshtel - b001 FT-102 VoIP USB Phone -6a75 Shanghai Jujo Electronics Co., Ltd -7104 CME (Central Music Co.) - 2202 UF5/UF6/UF7/UF8 MIDI Master Keyboard -8086 Intel Corp. - 0001 AnyPoint (TM) Home Network 1.6 Mbps Wireless Adapter - 0100 Personal Audio Player 3000 - 0101 Personal Audio Player 3000 - 0110 Easy PC Camera - 0120 PC Camera CS120 - 0200 AnyPoint(TM) Wireless II Network 11Mbps Adapter - 0431 Intel Pro Video PC Camera - 0510 Digital Movie Creator - 0630 Pocket PC Camera - 0780 CS780 Microphone Input - 07d3 BLOB boot loader firmware - 0dad Cherry MiniatureCard Keyboard - 1010 AnyPoint(TM) Home Network 10 Mbps Phoneline Adapter - 110a Bluetooth Controller from (Ericsson P4A) - 110b Bluetooth Controller from (Intel/CSR) - 1110 PRO/Wireless LAN Module - 1111 PRO/Wireless 2011B 802.11b Adapter - 1134 Hollister Mobile Monitor - 1234 Prototype Reader/Writer - 3100 PRO/DSL 3220 Modem - WAN - 3101 PRO/DSL 3220 Modem - 3240 AnyPoint® 3240 Modem - WAN - 3241 AnyPoint® 3240 Modem - 8602 Miniature Card Slot - 9303 Intel 8x930Hx Hub - 9890 82930 Test Board - beef SCM Miniature Card Reader/Writer - c013 Wireless HID Station - f001 XScale PXA27x Bulverde flash -8341 EGO Systems, Inc. - 2000 Flashdisk -9016 Sitecom - 182d WL-022 -9710 MosChip Semiconductor - 7703 MCS7703 Serial Port Adapter - 7705 Printer cable - 7715 Printer cable - 7780 MS7780 4Mbps Fast IRDA Adapter - 7830 MCS7830 Ethernet -a727 3Com - 6893 AR5523 - 6895 AR5523 - 6897 AR5523 -c251 Keil Software, Inc. - 2710 ULink -eb1a eMPIA Technology, Inc. - 17de KWorld V-Stream XPERT DTV - DVB-T USB cold - 17df KWorld V-Stream XPERT DTV - DVB-T USB warm - 2710 SilverCrest WebCam - 2750 ECS Elitegroup G220 integrated webcam - 2800 Terratec Cinergy 200 - 2801 GrabBeeX+ Video Encoder -f003 Hewlett Packard - 6002 PhotoSmart C500 - -# List of known device classes, subclasses and protocols - -# Syntax: -# C class class_name -# subclass subclass_name <-- single tab -# protocol protocol_name <-- two tabs - -C 00 (Defined at Interface level) -C 01 Audio - 01 Control Device - 02 Streaming - 03 MIDI Streaming -C 02 Communications - 01 Direct Line - 02 Abstract (modem) - 00 None - 01 AT-commands (v.25ter) - 02 AT-commands (PCCA101) - 03 AT-commands (PCCA101 + wakeup) - 04 AT-commands (GSM) - 05 AT-commands (3G) - 06 AT-commands (CDMA) - fe Defined by command set descriptor - ff Vendor Specific (MSFT RNDIS?) - 03 Telephone - 04 Multi-Channel - 05 CAPI Control - 06 Ethernet Networking - 07 ATM Networking - 08 Wireless Handset Control - 09 Device Management - 0a Mobile Direct Line - 0b OBEX - 0c Ethernet Emulation - 07 Ethernet Emulation (EEM) -C 03 Human Interface Device - 00 No Subclass - 00 None - 01 Keyboard - 02 Mouse - 01 Boot Interface Subclass - 00 None - 01 Keyboard - 02 Mouse -C 05 Physical Interface Device -C 06 Imaging - 01 Still Image Capture - 01 Picture Transfer Protocol (PIMA 15470) -C 07 Printer - 01 Printer - 00 Reserved/Undefined - 01 Unidirectional - 02 Bidirectional - 03 IEEE 1284.4 compatible bidirectional - ff Vendor Specific -C 08 Mass Storage - 01 RBC (typically Flash) - 00 Control/Bulk/Interrupt - 01 Control/Bulk - 50 Bulk (Zip) - 02 SFF-8020i, MMC-2 (ATAPI) - 03 QIC-157 - 04 Floppy (UFI) - 00 Control/Bulk/Interrupt - 01 Control/Bulk - 50 Bulk (Zip) - 05 SFF-8070i - 06 SCSI - 00 Control/Bulk/Interrupt - 01 Control/Bulk - 50 Bulk (Zip) -C 09 Hub - 00 Unused - 00 Full speed (or root) hub - 01 Single TT - 02 TT per port -C 0a CDC Data - 00 Unused - 30 I.430 ISDN BRI - 31 HDLC - 32 Transparent - 50 Q.921M - 51 Q.921 - 52 Q.921TM - 90 V.42bis - 91 Q.932 EuroISDN - 92 V.120 V.24 rate ISDN - 93 CAPI 2.0 - fd Host Based Driver - fe CDC PUF - ff Vendor specific -C 0b Chip/SmartCard -C 0d Content Security -C 0e Video - 00 Undefined - 01 Video Control - 02 Video Streaming - 03 Video Interface Collection -C dc Diagnostic - 01 Reprogrammable Diagnostics - 01 USB2 Compliance -C e0 Wireless - 01 Radio Frequency - 01 Bluetooth - 02 Ultra WideBand Radio Control - 03 RNDIS - 02 Wireless USB Wire Adapter - 01 Host Wire Adapter Control/Data Streaming - 02 Device Wire Adapter Control/Data Streaming - 03 Device Wire Adapter Isochronous Streaming -C ef Miscellaneous Device - 01 ? - 01 Microsoft ActiveSync - 02 Palm Sync - 02 ? - 01 Interface Association - 02 Wire Adapter Multifunction Peripheral - 03 ? - 01 Cable Based Association -C fe Application Specific Interface - 01 Device Firmware Update - 02 IRDA Bridge - 03 Test and Measurement - 01 TMC - 02 USB488 -C ff Vendor Specific Class - ff Vendor Specific Subclass - ff Vendor Specific Protocol - -# List of Audio Class Terminal Types - -# Syntax: -# AT terminal_type terminal_type_name - -AT 0100 USB Undefined -AT 0101 USB Streaming -AT 01ff USB Vendor Specific -AT 0200 Input Undefined -AT 0201 Microphone -AT 0202 Desktop Microphone -AT 0203 Personal Microphone -AT 0204 Omni-directional Microphone -AT 0205 Microphone Array -AT 0206 Processing Microphone Array -AT 0300 Output Undefined -AT 0301 Speaker -AT 0302 Headphones -AT 0303 Head Mounted Display Audio -AT 0304 Desktop Speaker -AT 0305 Room Speaker -AT 0306 Communication Speaker -AT 0307 Low Frequency Effects Speaker -AT 0400 Bidirectional Undefined -AT 0401 Handset -AT 0402 Headset -AT 0403 Speakerphone, no echo reduction -AT 0404 Echo-suppressing speakerphone -AT 0405 Echo-canceling speakerphone -AT 0500 Telephony Undefined -AT 0501 Phone line -AT 0502 Telephone -AT 0503 Down Line Phone -AT 0600 External Undefined -AT 0601 Analog Connector -AT 0602 Digital Audio Interface -AT 0603 Line Connector -AT 0604 Legacy Audio Connector -AT 0605 SPDIF interface -AT 0606 1394 DA stream -AT 0607 1394 DV stream soundtrack -AT 0700 Embedded Undefined -AT 0701 Level Calibration Noise Source -AT 0702 Equalization Noise -AT 0703 CD Player -AT 0704 DAT -AT 0705 DCC -AT 0706 MiniDisc -AT 0707 Analog Tape -AT 0708 Phonograph -AT 0709 VCR Audio -AT 070a Video Disc Audio -AT 070b DVD Audio -AT 070c TV Tuner Audio -AT 070d Satellite Receiver Audio -AT 070e Cable Tuner Audio -AT 070f DSS Audio -AT 0710 Radio Receiver -AT 0711 Radio Transmitter -AT 0712 Multitrack Recorder -AT 0713 Synthesizer - -# List of HID Descriptor Types - -# Syntax: -# HID descriptor_type descriptor_type_name - -HID 21 HID -HID 22 Report -HID 23 Physical - -# List of HID Descriptor Item Types -# Note: 2 bits LSB encode data length following - -# Syntax: -# R item_type item_type_name - -# Main Items -R 80 Input -R 90 Output -R b0 Feature -R a0 Collection -R c0 End Collection - -# Global Items -R 04 Usage Page -R 14 Logical Minimum -R 24 Logical Maximum -R 34 Physical Minimum -R 44 Physical Maximum -R 54 Unit Exponent -R 64 Unit -R 74 Report Size -R 84 Report ID -R 94 Report Count -R a4 Push -R b4 Pop - -# Local Items -R 08 Usage -R 18 Usage Minimum -R 28 Usage Maximum -R 38 Designator Index -R 48 Designator Minimum -R 58 Designator Maximum -R 78 String Index -R 88 String Minimum -R 98 String Maximum -R a8 Delimiter - -# List of Physical Descriptor Bias Types - -# Syntax: -# BIAS item_type item_type_name - -BIAS 0 Not Applicable -BIAS 1 Right Hand -BIAS 2 Left Hand -BIAS 3 Both Hands -BIAS 4 Either Hand - -# List of Physical Descriptor Item Types - -# Syntax: -# PHY item_type item_type_name - -PHY 00 None -PHY 01 Hand -PHY 02 Eyeball -PHY 03 Eyebrow -PHY 04 Eyelid -PHY 05 Ear -PHY 06 Nose -PHY 07 Mouth -PHY 08 Upper Lip -PHY 09 Lower Lip -PHY 0a Jaw -PHY 0b Neck -PHY 0c Upper Arm -PHY 0d Elbow -PHY 0e Forearm -PHY 0f Wrist -PHY 10 Palm -PHY 11 Thumb -PHY 12 Index Finger -PHY 13 Middle Finger -PHY 14 Ring Finger -PHY 15 Little Finger -PHY 16 Head -PHY 17 Shoulder -PHY 18 Hip -PHY 19 Waist -PHY 1a Thigh -PHY 1b Knee -PHY 1c calf -PHY 1d Ankle -PHY 1e Foot -PHY 1f Heel -PHY 20 Ball of Foot -PHY 21 Big Toe -PHY 22 Second Toe -PHY 23 Third Toe -PHY 24 Fourth Toe -PHY 25 Fifth Toe -PHY 26 Brow -PHY 27 Cheek - -# List of HID Usages - -# Syntax: -# HUT hi _usage_page hid_usage_page_name -# hid_usage hid_usage_name - -HUT 00 Undefined -HUT 01 Generic Desktop Controls - 000 Undefined - 001 Pointer - 002 Mouse - 004 Joystick - 005 Gamepad - 006 Keyboard - 007 Keypad - 008 Multi-Axis Controller - 030 Direction-X - 031 Direction-Y - 032 Direction-Z - 033 Rotate-X - 034 Rotate-Y - 035 Rotate-Z - 036 Slider - 037 Dial - 038 Wheel - 039 Hat Switch - 03a Counted Buffer - 03b Byte Count - 03c Motion Wakeup - 03d Start - 03e Select - 040 Vector-X - 041 Vector-Y - 042 Vector-Z - 043 Vector-X relative Body - 044 Vector-Y relative Body - 045 Vector-Z relative Body - 046 Vector - 080 System Control - 081 System Power Down - 082 System Sleep - 083 System Wake Up - 084 System Context Menu - 085 System Main Menu - 086 System App Menu - 087 System Menu Help - 088 System Menu Exit - 089 System Menu Select - 08a System Menu Right - 08b System Menu Left - 08c System Menu Up - 08d System Menu Down - 090 Direction Pad Up - 091 Direction Pad Down - 092 Direction Pad Right - 093 Direction Pad Left -HUT 02 Simulation Controls - 000 Undefined - 001 Flight Simulation Device - 002 Automobile Simulation Device - 003 Tank Simulation Device - 004 Spaceship Simulation Device - 005 Submarine Simulation Device - 006 Sailing Simulation Device - 007 Motorcycle Simulation Device - 008 Sports Simulation Device - 009 Airplane Simualtion Device - 00a Helicopter Simulation Device - 00b Magic Carpet Simulation Device - 00c Bicycle Simulation Device - 020 Flight Control Stick - 021 Flight Stick - 022 Cyclic Control - 023 Cyclic Trim - 024 Flight Yoke - 025 Track Control - 0b0 Aileron - 0b1 Aileron Trim - 0b2 Anti-Torque Control - 0b3 Autopilot Enable - 0b4 Chaff Release - 0b5 Collective Control - 0b6 Dive Break - 0b7 Electronic Countermeasures - 0b8 Elevator - 0b9 Elevator Trim - 0ba Rudder - 0bb Throttle - 0bc Flight COmmunications - 0bd Flare Release - 0be Landing Gear - 0bf Toe Break - 0c0 Trigger - 0c1 Weapon Arm - 0c2 Weapons Select - 0c3 Wing Flaps - 0c4 Accelerator - 0c5 Brake - 0c6 Clutch - 0c7 Shifter - 0c8 Steering - 0c9 Turret Direction - 0ca Barrel Elevation - 0cb Drive Plane - 0cc Ballast - 0cd Bicylce Crank - 0ce Handle Bars - 0cf Front Brake - 0d0 Rear Brake -HUT 03 VR Controls - 000 Unidentified - 001 Belt - 002 Body Suit - 003 Flexor - 004 Glove - 005 Head Tracker - 006 Head Mounted Display - 007 Hand Tracker - 008 Oculometer - 009 Vest - 00a Animatronic Device - 020 Stereo Enable - 021 Display Enable -HUT 04 Sport Controls - 000 Unidentified - 001 Baseball Bat - 002 Golf Club - 003 Rowing Machine - 004 Treadmill - 030 Oar - 031 Slope - 032 Rate - 033 Stick Speed - 034 Stick Face Angle - 035 Stick Heel/Toe - 036 Stick Follow Through - 047 Stick Temp - 038 Stick Type - 039 Stick Height - 050 Putter - 051 1 Iron - 052 2 Iron - 053 3 Iron - 054 4 Iron - 055 5 Iron - 056 6 Iron - 057 7 Iron - 058 8 Iron - 059 9 Iron - 05a 10 Iron - 05b 11 Iron - 05c Sand Wedge - 05d Loft Wedge - 05e Power Wedge - 05f 1 Wood - 060 3 Wood - 061 5 Wood - 062 7 Wood - 063 9 Wood -HUT 05 Game Controls - 000 Undefined - 001 3D Game Controller - 002 Pinball Device - 003 Gun Device - 020 Point Of View - 021 Turn Right/Left - 022 Pitch Right/Left - 023 Roll Forward/Backward - 024 Move Right/Left - 025 Move Forward/Backward - 026 Move Up/Down - 027 Lean Right/Left - 028 Lean Forward/Backward - 029 Height of POV - 02a Flipper - 02b Secondary Flipper - 02c Bump - 02d New Game - 02e Shoot Ball - 02f Player - 030 Gun Bolt - 031 Gun Clip - 032 Gun Selector - 033 Gun Single Shot - 034 Gun Burst - 035 Gun Automatic - 036 Gun Safety - 037 Gamepad Fire/Jump - 038 Gamepad Fun - 039 Gamepad Trigger -HUT 07 Keyboard - 000 No Event - 001 Keyboard ErrorRollOver - 002 Keyboard POSTfail - 003 Keyboard Error Undefined - 004 A - 005 B - 006 C - 007 D - 008 E - 009 F - 00a G - 00b H - 00c I - 00d J - 00e K - 00f L - 010 M - 011 N - 012 O - 013 P - 014 Q - 015 R - 016 S - 017 T - 018 U - 019 V - 01a W - 01b X - 01c Y - 01d Z - 01e 1 and ! (One and Exclamation) - 01f 2 and @ (2 and at) - 020 3 and # (3 and Hash) - 021 4 and $ (4 and Dollar Sign) - 022 5 and % (5 and Percent Sign) - 023 6 and ^ (6 and circumflex) - 024 7 and & (Seven and Ampersand) - 025 8 and * (Eight and asterisk) - 026 9 and ( (Nine and Parenthesis Left) - 027 0 and ) (Zero and Parenthesis Right) - 028 Return (Enter) - 029 Escape - 02a Delete (Backspace) - 02b Tab - 02c Space Bar - 02d - and _ (Minus and underscore) - 02e = and + (Equal and Plus) - 02f [ and { (Bracket and Braces Left) - 030 ] and } (Bracket and Braces Right) - 031 \ and | (Backslash and Bar) - 032 # and ~ (Hash and Tilde, Non-US Keyboard near right shift) - 033 ; and : (Semicolon and Colon) - 034 ´ and " (Accent Acute and Double Quotes) - 035 ` and ~ (Accent Grace and Tilde) - 036 , and < (Comma and Less) - 037 . and > (Period and Greater) - 038 / and ? (Slash and Question Mark) - 039 Caps Lock - 03a F1 - 03b F2 - 03c F3 - 03d F4 - 03e F5 - 03f F6 - 040 F7 - 041 F8 - 042 F9 - 043 F10 - 044 F11 - 045 F12 - 046 Print Screen - 047 Scroll Lock - 048 Pause - 049 Insert - 04a Home - 04b Page Up - 04c Delete Forward (without Changing Position) - 04d End - 04e Page Down - 04f Right Arrow - 050 Left Arrow - 051 Down Arrow - 052 Up Arrow - 053 Num Lock and Clear - 054 Keypad / (Division Sign) - 055 Keypad * (Multiplication Sign) - 056 Keypad - (Subtraction Sign) - 057 Keypad + (Addition Sign) - 058 Keypad Enter - 059 Keypad 1 and END - 05a Keypad 2 and Down Arrow - 05b Keypad 3 and Page Down - 05c Keypad 4 and Left Arrow - 05d Keypad 5 (Tactilei Raised) - 05f Keypad 6 and Right Arrow - 060 Keypad 7 and Home - 061 Keypad 8 and Up Arrow - 062 Keypad 8 and Page Up - 063 Keypad . (decimal delimiter) and Delete - 064 \ and | (Backslash and Bar, UK and Non-US Keyboard near left shift) - 065 Keyboard Application (Windows Key for Win95 or Compose) - 066 Power (not a key) - 067 Keypad = (Equal Sign) - 068 F13 - 069 F14 - 06a F15 - 06b F16 - 06c F17 - 06d F18 - 06e F19 - 06f F20 - 070 F21 - 071 F22 - 072 F23 - 073 F24 - 074 Execute - 075 Help - 076 Menu - 077 Select - 078 Stop - 079 Again - 07a Undo - 07b Cut - 07c Copy - 07d Paste - 07e Find - 07f Mute - 080 Volume Up - 081 Volume Down - 082 Locking Caps Lock - 083 Locking Num Lock - 084 Locking Scroll Lock - 085 Keypad Comma - 086 Keypad Equal Sign (AS/400) - 087 International 1 (PC98) - 088 International 2 (PC98) - 089 International 3 (PC98) - 08a International 4 (PC98) - 08b International 5 (PC98) - 08c International 6 (PC98) - 08d International 7 (Toggle Single/Double Byte Mode) - 08e International 8 - 08f International 9 - 090 LANG 1 (Hangul/English Toggle, Korea) - 091 LANG 2 (Hanja Conversion, Korea) - 092 LANG 3 (Katakana, Japan) - 093 LANG 4 (Hiragana, Japan) - 094 LANG 5 (Zenkaku/Hankaku, Japan) - 095 LANG 6 - 096 LANG 7 - 097 LANG 8 - 098 LANG 9 - 099 Alternate Erase - 09a SysReq/Attention - 09b Cancel - 09c Clear - 09d Prior - 09e Return - 09f Separator - 0a0 Out - 0a1 Open - 0a2 Clear/Again - 0a3 CrSel/Props - 0a4 ExSel - 0e0 Control Left - 0e1 Shift Left - 0e2 Alt Left - 0e3 GUI Left - 0e4 Control Right - 0e5 Shift Right - 0e6 Alt Rigth - 0e7 GUI Right -HUT 08 LEDs - 000 Undefined - 001 NumLock - 002 CapsLock - 003 Scroll Lock - 004 Compose - 005 Kana - 006 Power - 007 Shift - 008 Do not disturb - 009 Mute - 00a Tone Enabke - 00b High Cut Filter - 00c Low Cut Filter - 00d Equalizer Enable - 00e Sound Field ON - 00f Surround On - 010 Repeat - 011 Stereo - 012 Sampling Rate Detect - 013 Spinning - 014 CAV - 015 CLV - 016 Recording Format Detect - 017 Off-Hook - 018 Ring - 019 Message Waiting - 01a Data Mode - 01b Battery Operation - 01c Battery OK - 01d Battery Low - 01e Speaker - 01f Head Set - 020 Hold - 021 Microphone - 022 Coverage - 023 Night Mode - 024 Send Calls - 025 Call Pickup - 026 Conference - 027 Stand-by - 028 Camera On - 029 Camera Off - 02a On-Line - 02b Off-Line - 02c Busy - 02d Ready - 02e Paper-Out - 02f Paper-Jam - 030 Remote - 031 Forward - 032 Reverse - 033 Stop - 034 Rewind - 035 Fast Forward - 036 Play - 037 Pause - 038 Record - 039 Error - 03a Usage Selected Indicator - 03b Usage In Use Indicator - 03c Usage Multi Indicator - 03d Indicator On - 03e Indicator Flash - 03f Indicator Slow Blink - 040 Indicator Fast Blink - 041 Indicator Off - 042 Flash On Time - 043 Slow Blink On Time - 044 Slow Blink Off Time - 045 Fast Blink On Time - 046 Fast Blink Off Time - 047 Usage Color Indicator - 048 Indicator Red - 049 Indicator Green - 04a Indicator Amber - 04b Generic Indicator - 04c System Suspend - 04d External Power Connected -HUT 09 Buttons - 000 No Button Pressed - 001 Button 1 (Primary) - 002 Button 2 (Secondary) - 003 Button 3 (Tertiary) - 004 Button 4 - 005 Button 5 -HUT 0a Ordinal - 001 Instance 1 - 002 Instance 2 - 003 Instance 3 -HUT 0b Telephony - 000 Unassigned - 001 Phone - 002 Answering Machine - 003 Message Controls - 004 Handset - 005 Headset - 006 Telephony Key Pad - 007 Programmable Button - 020 Hook Switch - 021 Flash - 022 Feature - 023 Hold - 024 Redial - 025 Transfer - 026 Drop - 027 Park - 028 Forward Calls - 029 Alternate Function - 02a Line - 02b Speaker Phone - 02c Conference - 02d Ring Enable - 02e Ring Select - 02f Phone Mute - 030 Caller ID - 050 Speed Dial - 051 Store Number - 052 Recall Number - 053 Phone Directory - 070 Voice Mail - 071 Screen Calls - 072 Do Not Disturb - 073 Message - 074 Answer On/Offf - 090 Inside Dial Tone - 091 Outside Dial Tone - 092 Inside Ring Tone - 093 Outside Ring Tone - 094 Priority Ring Tone - 095 Inside Ringback - 096 Priority Ringback - 097 Line Busy Tone - 098 Recorder Tone - 099 Call Waiting Tone - 09a Confirmation Tone 1 - 09b Confirmation Tone 2 - 09c Tones Off - 09d Outside Ringback - 0b0 Key 1 - 0b1 Key 2 - 0b3 Key 3 - 0b4 Key 4 - 0b5 Key 5 - 0b6 Key 6 - 0b7 Key 7 - 0b8 Key 8 - 0b9 Key 9 - 0ba Key Star - 0bb Key Pound - 0bc Key A - 0bd Key B - 0be Key C - 0bf Key D -HUT 0c Consumer - 000 Unassigned - 001 Consumer Control - 002 Numeric Key Pad - 003 Programmable Buttons - 020 +10 - 021 +100 - 022 AM/PM - 030 Power - 031 Reset - 032 Sleep - 033 Sleep After - 034 Sleep Mode - 035 Illumination - 036 Function Buttons - 040 Menu - 041 Menu Pick - 042 Menu Up - 043 Menu Down - 044 Menu Left - 045 Menu Right - 046 Menu Escape - 047 Menu Value Increase - 048 Menu Value Decrease - 060 Data on Screen - 061 Closed Caption - 062 Closed Caption Select - 063 VCR/TV - 064 Broadcast Mode - 065 Snapshot - 066 Still - 080 Selection - 081 Assign Selection - 082 Mode Step - 083 Recall Last - 084 Enter Channel - 085 Order Movie - 086 Channel - 087 Media Selection - 088 Media Select Computer - 089 Media Select TV - 08a Media Select WWW - 08b Media Select DVD - 08c Media Select Telephone - 08d Media Select Program Guide - 08e Media Select Video Phone - 08f Media Select Games - 090 Media Select Messages - 091 Media Select CD - 092 Media Select VCR - 093 Media Select Tuner - 094 Quit - 095 Help - 096 Media Select Tape - 097 Media Select Cable - 098 Media Select Satellite - 099 Media Select Security - 09a Media Select Home - 09b Media Select Call - 09c Channel Increment - 09d Channel Decrement - 09e Media Select SAP - 0a0 VCR Plus - 0a1 Once - 0a2 Daily - 0a3 Weekly - 0a4 Monthly - 0b0 Play - 0b1 Pause - 0b2 Record - 0b3 Fast Forward - 0b4 Rewind - 0b5 Scan Next Track - 0b6 Scan Previous Track - 0b7 Stop - 0b8 Eject - 0b9 Random Play - 0ba Select Disc - 0bb Enter Disc - 0bc Repeat - 0bd Tracking - 0be Track Normal - 0bf Slow Tracking - 0c0 Frame Forward - 0c1 Frame Back - 0c2 Mark - 0c3 Clear Mark - 0c4 Repeat from Mark - 0c5 Return to Mark - 0c6 Search Mark Forward - 0c7 Search Mark Backward - 0c8 Counter Reset - 0c9 Show Counter - 0ca Tracking Increment - 0cb Tracking Decrement - 0cc Stop/Eject - 0cd Play/Pause - 0ce Play/Skip - 0e0 Volume - 0e1 Balance - 0e2 Mute - 0e3 Bass - 0e4 Treble - 0e5 Bass Boost - 0e6 Surround Mode - 0e7 Loudness - 0e8 MPX - 0e9 Volume Increment - 0ea Volume Decrement - 0f0 Speed Select - 0f1 Playback Speed - 0f2 Standard Play - 0f3 Long Play - 0f4 Extended Play - 0f5 Slow - 100 Fan Enable - 101 Fan Speed - 102 Light Enable - 103 Light Illumination Level - 104 Climate Control Enable - 105 Room Temperature - 106 Security Enable - 107 Fire Alarm - 108 Police Alarm - 150 Balance Right - 151 Balance Left - 152 Bass Increment - 153 Bass Decrement - 154 Treble Increment - 155 Treble Decrement - 160 Speaker System - 161 Channel Left - 162 Channel Right - 163 Channel Center - 164 Channel Front - 165 Channel Center Front - 166 Channel Side - 167 Channel Surround - 168 Channel Low Frequency Enhancement - 169 Channel Top - 16a Channel Unknown - 170 Sub-Channel - 171 Sub-Channel Increment - 172 Sub-Channel Decrement - 173 Alternative Audio Increment - 174 Alternative Audio Decrement - 180 Application Launch Buttons - 181 AL Launch Button Configuration Tool - 182 AL Launch Button Configuration - 183 AL Consumer Control Configuration - 184 AL Word Processor - 185 AL Text Editor - 186 AL Spreadsheet - 187 AL Graphics Editor - 188 AL Presentation App - 189 AL Database App - 18a AL Email Reader - 18b AL Newsreader - 18c AL Voicemail - 18d AL Contacts/Address Book - 18e AL Calendar/Schedule - 18f AL Task/Project Manager - 190 AL Log/Jounal/Timecard - 191 AL Checkbook/Finance - 192 AL Calculator - 193 AL A/V Capture/Playback - 194 AL Local Machine Browser - 195 AL LAN/Wan Browser - 196 AL Internet Browser - 197 AL Remote Networking/ISP Connect - 198 AL Network Conference - 199 AL Network Chat - 19a AL Telephony/Dialer - 19b AL Logon - 19c AL Logoff - 19d AL Logon/Logoff - 19e AL Terminal Local/Screensaver - 19f AL Control Panel - 1a0 AL Command Line Processor/Run - 1a1 AL Process/Task Manager - 1a2 AL Select Task/Application - 1a3 AL Next Task/Application - 1a4 AL Previous Task/Application - 1a5 AL Preemptive Halt Task/Application - 200 Generic GUI Application Controls - 201 AC New - 202 AC Open - 203 AC CLose - 204 AC Exit - 205 AC Maximize - 206 AC Minimize - 207 AC Save - 208 AC Print - 209 AC Properties - 21a AC Undo - 21b AC Copy - 21c AC Cut - 21d AC Paste - 21e AC Select All - 21f AC Find - 220 AC Find and Replace - 221 AC Search - 222 AC Go To - 223 AC Home - 224 AC Back - 225 AC Forward - 226 AC Stop - 227 AC Refresh - 228 AC Previous Link - 229 AC Next Link - 22b AC History - 22c AC Subscriptions - 22d AC Zoom In - 22e AC Zoom Out - 22f AC Zoom - 230 AC Full Screen View - 231 AC Normal View - 232 AC View Toggle - 233 AC Scroll Up - 234 AC Scroll Down - 235 AC Scroll - 236 AC Pan Left - 237 AC Pan Right - 238 AC Pan - 239 AC New Window - 23a AC Tile Horizontally - 23b AC Tile Vertically - 23c AC Format -HUT 0d Digitizer - 000 Undefined - 001 Digitizer - 002 Pen - 003 Light Pen - 004 Touch Screen - 005 Touch Pad - 006 White Board - 007 Coordinate Measuring Machine - 008 3D Digitizer - 009 Stereo Plotter - 00a Articulated Arm - 00b Armature - 00c Multiple Point Digitizer - 00d Free Space Wand - 020 Stylus - 021 Puck - 022 Finger - 030 Tip Pressure - 031 Barrel Pressure - 032 In Range - 033 Touch - 034 Untouch - 035 Tap - 036 Quality - 037 Data Valid - 038 Transducer Index - 039 Tablet Function Keys - 03a Program Change Keys - 03b Battery Strength - 03c Invert - 03d X Tilt - 03e Y Tilt - 03f Azimuth - 040 Altitude - 041 Twist - 042 Tip Switch - 043 Secondary Tip Switch - 044 Barrel Switch - 045 Eraser - 046 Tablet Pick -HUT 0f PID Page - 000 Undefined - 001 Physical Interface Device - 020 Normal - 021 Set Effect Report - 022 Effect Block Index - 023 Parameter Block Offset - 024 ROM Flag - 025 Effect Type - 026 ET Constant Force - 027 ET Ramp - 028 ET Custom Force Data - 030 ET Square - 031 ET Sine - 032 ET Triangle - 033 ET Sawtooth Up - 034 ET Sawtooth Down - 040 ET Spring - 041 ET Damper - 042 ET Inertia - 043 ET Friction - 050 Duration - 051 Sample Period - 052 Gain - 053 Trigger Button - 054 Trigger Repeat Interval - 055 Axes Enable - 056 Direction Enable - 057 Direction - 058 Type Specific Block Offset - 059 Block Type - 05A Set Envelope Report - 05B Attack Level - 05C Attack Time - 05D Fade Level - 05E Fade Time - 05F Set Condition Report - 060 CP Offset - 061 Positive Coefficient - 062 Negative Coefficient - 063 Positive Saturation - 064 Negative Saturation - 065 Dead Band - 066 Download Force Sample - 067 Isoch Custom Force Enable - 068 Custom Force Data Report - 069 Custom Force Data - 06A Custom Force Vendor Defined Data - 06B Set Custom Force Report - 06C Custom Force Data Offset - 06D Sample Count - 06E Set Periodic Report - 06F Offset - 070 Magnitude - 071 Phase - 072 Period - 073 Set Constant Force Report - 074 Set Ramp Force Report - 075 Ramp Start - 076 Ramp End - 077 Effect Operation Report - 078 Effect Operation - 079 Op Effect Start - 07A Op Effect Start Solo - 07B Op Effect Stop - 07C Loop Count - 07D Device Gain Report - 07E Device Gain - 07F PID Pool Report - 080 RAM Pool Size - 081 ROM Pool Size - 082 ROM Effect Block Count - 083 Simultaneous Effects Max - 084 Pool Alignment - 085 PID Pool Move Report - 086 Move Source - 087 Move Destination - 088 Move Length - 089 PID Block Load Report - 08B Block Load Status - 08C Block Load Success - 08D Block Load Full - 08E Block Load Error - 08F Block Handle - 090 PID Block Free Report - 091 Type Specific Block Handle - 092 PID State Report - 094 Effect Playing - 095 PID Device Control Report - 096 PID Device Control - 097 DC Enable Actuators - 098 DC Disable Actuators - 099 DC Stop All Effects - 09A DC Device Reset - 09B DC Device Pause - 09C DC Device Continue - 09F Device Paused - 0A0 Actuators Enabled - 0A4 Safety Switch - 0A5 Actuator Override Switch - 0A6 Actuator Power - 0A7 Start Delay - 0A8 Parameter Block Size - 0A9 Device Managed Pool - 0AA Shared Parameter Blocks - 0AB Create New Effect Report - 0AC RAM Pool Available -HUT 10 Unicode -HUT 14 Alphanumeric Display - 000 Undefined - 001 Alphanumeric Display - 020 Display Attributes Report - 021 ASCII Character Set - 022 Data Read Back - 023 Font Read Back - 024 Display Control Report - 025 Clear Display - 026 Display Enable - 027 Screen Saver Delay - 028 Screen Saver Enable - 029 Vertical Scroll - 02a Horizontal Scroll - 02b Character Report - 02c Display Data - 02d Display Status - 02e Stat Not Ready - 02f Stat Ready - 030 Err Not a loadable Character - 031 Err Font Data Cannot Be Read - 032 Cursur Position Report - 033 Row - 034 Column - 035 Rows - 036 Columns - 037 Cursor Pixel Positioning - 038 Cursor Mode - 039 Cursor Enable - 03a Cursor Blink - 03b Font Report - 03c Font Data - 03d Character Width - 03e Character Height - 03f Character Spacing Horizontal - 040 Character Spacing Vertical - 041 Unicode Character Set -HUT 80 USB Monitor - 001 Monitor Control - 002 EDID Information - 003 VDIF Information - 004 VESA Version -HUT 81 USB Monitor Enumerated Values -HUT 82 Monitor VESA Virtual Controls - 001 Degauss - 010 Brightness - 012 Contrast - 016 Red Video Gain - 018 Green Video Gain - 01a Blue Video Gain - 01c Focus - 020 Horizontal Position - 022 Horizontal Size - 024 Horizontal Pincushion - 026 Horizontal Pincushion Balance - 028 Horizontal Misconvergence - 02a Horizontal Linearity - 02c Horizontal Linearity Balance - 030 Vertical Position - 032 Vertical Size - 034 Vertical Pincushion - 036 Vertical Pincushion Balance - 038 Vertical Misconvergence - 03a Vertical Linearity - 03c Vertical Linearity Balance - 040 Parallelogram Balance (Key Distortion) - 042 Trapezoidal Distortion (Key) - 044 Tilt (Rotation) - 046 Top Corner Distortion Control - 048 Top Corner Distortion Balance - 04a Bottom Corner Distortion Control - 04c Bottom Corner Distortion Balance - 056 Horizontal Moire - 058 Vertical Moire - 05e Input Level Select - 060 Input Source Select - 06c Red Video Black Level - 06e Green Video Black Level - 070 Blue Video Black Level - 0a2 Auto Size Center - 0a4 Polarity Horizontal Sychronization - 0a6 Polarity Vertical Synchronization - 0aa Screen Orientation - 0ac Horizontal Frequency in Hz - 0ae Vertical Frequency in 0.1 Hz - 0b0 Settings - 0ca On Screen Display (OSD) - 0d4 Stereo Mode -HUT 84 Power Device Page - 000 Undefined - 001 iName - 002 Present Status - 003 Changed Status - 004 UPS - 005 Power Supply - 010 Battery System - 011 Battery System ID - 012 Battery - 013 Battery ID - 014 Charger - 015 Charger ID - 016 Power Converter - 017 Power Converter ID - 018 Outlet System - 019 Outlet System ID - 01a Input - 01b Input ID - 01c Output - 01d Output ID - 01e Flow - 01f Flow ID - 020 Outlet - 021 Outlet ID - 022 Gang - 023 Gang ID - 024 Power Summary - 025 Power Summary ID - 030 Voltage - 031 Current - 032 Frequency - 033 Apparent Power - 034 Active Power - 035 Percent Load - 036 Temperature - 037 Humidity - 038 Bad Count - 040 Config Voltage - 041 Config Current - 042 Config Frequency - 043 Config Apparent Power - 044 Config Active Power - 045 Config Percent Load - 046 Config Temperature - 047 Config Humidity - 050 Switch On Control - 051 Switch Off Control - 052 Toggle Control - 053 Low Voltage Transfer - 054 High Voltage Transfer - 055 Delay Before Reboot - 056 Delay Before Startup - 057 Delay Before Shutdown - 058 Test - 059 Module Reset - 05a Audible Alarm Control - 060 Present - 061 Good - 062 Internal Failure - 063 Voltage out of range - 064 Frequency out of range - 065 Overload - 066 Over Charged - 067 Over Temperature - 068 Shutdown Requested - 069 Shutdown Imminent - 06a Reserved - 06b Switch On/Off - 06c Switchable - 06d Used - 06e Boost - 06f Buck - 070 Initialized - 071 Tested - 072 Awaiting Power - 073 Communication Lost - 0fd iManufacturer - 0fe iProduct - 0ff iSerialNumber -HUT 85 Battery System Page - 000 Undefined - 001 SMB Battery Mode - 002 SMB Battery Status - 003 SMB Alarm Warning - 004 SMB Charger Mode - 005 SMB Charger Status - 006 SMB Charger Spec Info - 007 SMB Selector State - 008 SMB Selector Presets - 009 SMB Selector Info - 010 Optional Mfg. Function 1 - 011 Optional Mfg. Function 2 - 012 Optional Mfg. Function 3 - 013 Optional Mfg. Function 4 - 014 Optional Mfg. Function 5 - 015 Connection to SMBus - 016 Output Connection - 017 Charger Connection - 018 Battery Insertion - 019 Use Next - 01a OK to use - 01b Battery Supported - 01c SelectorRevision - 01d Charging Indicator - 028 Manufacturer Access - 029 Remaining Capacity Limit - 02a Remaining Time Limit - 02b At Rate - 02c Capacity Mode - 02d Broadcast To Charger - 02e Primary Battery - 02f Charge Controller - 040 Terminate Charge - 041 Terminate Discharge - 042 Below Remaining Capacity Limit - 043 Remaining Time Limit Expired - 044 Charging - 045 Discharging - 046 Fully Charged - 047 Fully Discharged - 048 Conditioning Flag - 049 At Rate OK - 04a SMB Error Code - 04b Need Replacement - 060 At Rate Time To Full - 061 At Rate Time To Empty - 062 Average Current - 063 Max Error - 064 Relative State Of Charge - 065 Absolute State Of Charge - 066 Remaining Capacity - 067 Full Charge Capacity - 068 Run Time To Empty - 069 Average Time To Empty - 06a Average Time To Full - 06b Cycle Count - 080 Batt. Pack Model Level - 081 Internal Charge Controller - 082 Primary Battery Support - 083 Design Capacity - 084 Specification Info - 085 Manufacturer Date - 086 Serial Number - 087 iManufacturerName - 088 iDeviceName - 089 iDeviceChemistry - 08a Manufacturer Data - 08b Rechargeable - 08c Warning Capacity Limit - 08d Capacity Granularity 1 - 08e Capacity Granularity 2 - 08f iOEMInformation - 0c0 Inhibit Charge - 0c1 Enable Polling - 0c2 Reset To Zero - 0d0 AC Present - 0d1 Battery Present - 0d2 Power Fail - 0d3 Alarm Inhibited - 0d4 Thermistor Under Range - 0d5 Thermistor Hot - 0d6 Thermistor Cold - 0d7 Thermistor Over Range - 0d8 Voltage Out Of Range - 0d9 Current Out Of Range - 0da Current Not Regulated - 0db Voltage Not Regulated - 0dc Master Mode - 0f0 Charger Selector Support - 0f1 Charger Spec - 0f2 Level 2 - 0f3 Level 3 -HUT 86 Power Pages -HUT 87 Power Pages -HUT 8c Bar Code Scanner Page (POS) -HUT 8d Scale Page (POS) -HUT 90 Camera Control Page -HUT 91 Arcade Control Page -HUT f0 Cash Device - 0f1 Cash Drawer - 0f2 Cash Drawer Number - 0f3 Cash Drawer Set - 0f4 Cash Drawer Status -HUT ff Vendor Specific - -# List of Languages - -# Syntax: -# L language_id language_name -# dialect_id dialect_name - -L 0001 Arabic - 01 Saudi Arabia - 02 Iraq - 03 Egypt - 04 Libya - 05 Algeria - 06 Morocco - 07 Tunesia - 08 Oman - 09 Yemen - 0a Syria - 0b Jordan - 0c Lebanon - 0d Kuwait - 0e U.A.E - 0f Bahrain - 10 Qatar -L 0002 Bulgarian -L 0003 Catalan -L 0004 Chinese - 01 Traditional - 02 Simplified - 03 Hongkong SAR, PRC - 04 Singapore - 05 Macau SAR -L 0005 Czech -L 0006 Danish -L 0007 German - 01 German - 02 Swiss - 03 Austrian - 04 Luxembourg - 05 Liechtenstein -L 0008 Greek -L 0009 English - 01 US - 02 UK - 03 Australian - 04 Canadian - 05 New Zealand - 06 Ireland - 07 South Africa - 08 Jamaica - 09 Carribean - 0a Belize - 0b Trinidad - 0c Zimbabwe - 0d Philippines -L 000a Spanish - 01 Castilian - 02 Mexican - 03 Modern - 04 Guatemala - 05 Costa Rica - 06 Panama - 07 Dominican Republic - 08 Venzuela - 09 Colombia - 0a Peru - 0b Argentina - 0c Ecuador - 0d Chile - 0e Uruguay - 0f Paraguay - 10 Bolivia - 11 El Salvador - 12 Honduras - 13 Nicaragua - 14 Puerto Rico -L 000b Finnish -L 000c French - 01 French - 02 Belgian - 03 Canadian - 04 Swiss - 05 Luxembourg - 06 Monaco -L 000d Hebrew -L 000e Hungarian -L 000f Idelandic -L 0010 Italian - 01 Italian - 02 Swiss -L 0011 Japanese -L 0012 Korean - 01 Korean -L 0013 Dutch - 01 Dutch - 02 Belgian -L 0014 Norwegian - 01 Bokmal - 02 Nynorsk -L 0015 Polish -L 0016 Portuguese - 01 Portuguese - 02 Brazilian -L 0017 forgotten -L 0018 Romanian -L 0019 Russian -L 001a Serbian - 01 Croatian - 02 Latin - 03 Cyrillic -L 001b Slovak -L 001c Albanian -L 001d Swedish - 01 Swedish - 02 Finland -L 001e Thai -L 001f Turkish -L 0020 Urdu - 01 Pakistan - 02 India -L 0021 Indonesian -L 0022 Ukrainian -L 0023 Belarusian -L 0024 Slovenian -L 0025 Estonian -L 0026 Latvian -L 0027 Lithuanian - 01 Lithuanian -L 0028 forgotten -L 0029 Farsi -L 002a Vietnamese -L 002b Armenian -L 002c Azeri - 01 Cyrillic - 02 Latin -L 002d Basque -L 002e forgotten -L 002f Macedonian -L 0036 Afrikaans -L 0037 Georgian -L 0038 Faeroese -L 0039 Hindi -L 003e Malay - 01 Malaysia - 02 Brunei Darassalam -L 003f Kazak -L 0041 Awahili -L 0043 Uzbek - 01 Latin - 02 Cyrillic -L 0044 Tatar -L 0045 Bengali -L 0046 Punjabi -L 0047 Gujarati -L 0048 Oriya -L 0049 Tamil -L 004a Telugu -L 004b Kannada -L 004c Malayalam -L 004d Assamese -L 004e Marathi -L 004f Sanskrit -L 0057 Konkani -L 0058 Manipuri -L 0059 Sindhi -L 0060 Kashmiri - 02 India -L 0061 Nepali - 02 India - -# HID Descriptor bCountryCode -# HID Specification 1.11 (2001-06-27) page 23 -# -# Syntax: -# HCC country_code keymap_type - -HCC 00 Not supported -HCC 01 Arabic -HCC 02 Belgian -HCC 03 Canadian-Bilingual -HCC 04 Canadian-French -HCC 05 Czech Republic -HCC 06 Danish -HCC 07 Finnish -HCC 08 French -HCC 09 German -HCC 10 Greek -HCC 11 Hebrew -HCC 12 Hungary -HCC 13 International (ISO) -HCC 14 Italian -HCC 15 Japan (Katakana) -HCC 16 Korean -HCC 17 Latin American -HCC 18 Netherlands/Dutch -HCC 19 Norwegian -HCC 20 Persian (Farsi) -HCC 21 Poland -HCC 22 Portuguese -HCC 23 Russia -HCC 24 Slovakia -HCC 25 Spanish -HCC 26 Swedish -HCC 27 Swiss/French -HCC 28 Swiss/German -HCC 29 Switzerland -HCC 30 Taiwan -HCC 31 Turkish-Q -HCC 32 UK -HCC 33 US -HCC 34 Yugoslavia -HCC 35 Turkish-F - -# List of Video Class Terminal Types - -# Syntax: -# VT terminal_type terminal_type_name - -VT 0100 USB Vendor Specific -VT 0101 USB Streaming -VT 0200 Input Vendor Specific -VT 0201 Camera Sensor -VT 0202 Sequential Media -VT 0300 Output Vendor Specific -VT 0301 Generic Display -VT 0302 Sequential Media -VT 0400 External Vendor Specific -VT 0401 Composite Video -VT 0402 S-Video -VT 0403 Component Video diff --git a/drivers/staging/usbip/vhci.h b/drivers/staging/usbip/vhci.h index d5bc8e7e3d79..71a586e00fd7 100644 --- a/drivers/staging/usbip/vhci.h +++ b/drivers/staging/usbip/vhci.h @@ -6,15 +6,6 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * This 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 @@ -105,7 +96,7 @@ struct vhci_hcd { }; extern struct vhci_hcd *the_controller; -extern struct attribute_group dev_attr_group; +extern const struct attribute_group dev_attr_group; #define hardware (&the_controller->pdev.dev) /* vhci_hcd.c */ diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index a76e8fa69b6e..2ee97e2095b0 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -92,14 +92,28 @@ static const char * const bit_desc[] = { "R31", /*31*/ }; -static void dump_port_status(u32 status) +static void dump_port_status_diff(u32 prev_status, u32 new_status) { int i = 0; + u32 bit = 1; - pr_debug("status %08x:", status); - for (i = 0; i < 32; i++) { - if (status & (1 << i)) - pr_debug(" %s", bit_desc[i]); + pr_debug("status prev -> new: %08x -> %08x\n", prev_status, new_status); + while (bit) { + u32 prev = prev_status & bit; + u32 new = new_status & bit; + char change; + + if (!prev && new) + change = '+'; + else if (prev && !new) + change = '-'; + else + change = ' '; + + if (prev || new) + pr_debug(" %c%s\n", change, bit_desc[i]); + bit <<= 1; + i++; } pr_debug("\n"); } @@ -273,9 +287,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, /* store old status and compare now and old later */ if (usbip_dbg_flag_vhci_rh) { - int i = 0; - for (i = 0; i < VHCI_NPORTS; i++) - prev_port_status[i] = dum->port_status[i]; + memcpy(prev_port_status, dum->port_status, + sizeof(prev_port_status)); } switch (typeReq) { @@ -344,9 +357,9 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, * */ if (dum->resuming && time_after(jiffies, dum->re_timeout)) { dum->port_status[rhport] |= - (1 << USB_PORT_FEAT_C_SUSPEND); + (1 << USB_PORT_FEAT_C_SUSPEND); dum->port_status[rhport] &= - ~(1 << USB_PORT_FEAT_SUSPEND); + ~(1 << USB_PORT_FEAT_SUSPEND); dum->resuming = 0; dum->re_timeout = 0; /* if (dum->driver && dum->driver->resume) { @@ -464,8 +477,11 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, if (usbip_dbg_flag_vhci_rh) { pr_debug("port %d\n", rhport); - dump_port_status(prev_port_status[rhport]); - dump_port_status(dum->port_status[rhport]); + /* Only dump valid port status */ + if (rhport >= 0) { + dump_port_status_diff(prev_port_status[rhport], + dum->port_status[rhport]); + } } usbip_dbg_vhci_rh(" bye\n"); @@ -639,9 +655,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, usb_hcd_unlink_urb_from_ep(hcd, urb); no_need_unlink: spin_unlock_irqrestore(&the_controller->lock, flags); - usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); - return ret; } @@ -846,9 +860,9 @@ static void vhci_shutdown_connection(struct usbip_device *ud) } /* kill threads related to this sdev, if v.c. exists */ - if (vdev->ud.tcp_rx) + if (vdev->ud.tcp_rx && !task_is_dead(vdev->ud.tcp_rx)) kthread_stop(vdev->ud.tcp_rx); - if (vdev->ud.tcp_tx) + if (vdev->ud.tcp_tx && !task_is_dead(vdev->ud.tcp_tx)) kthread_stop(vdev->ud.tcp_tx); pr_info("stop threads\n"); @@ -1033,9 +1047,8 @@ static int vhci_bus_resume(struct usb_hcd *hcd) hcd->state = HC_STATE_RUNNING; } spin_unlock_irq(&vhci->lock); - return rc; - return 0; + return rc; } #else @@ -1212,7 +1225,7 @@ static struct platform_device the_pdev = { }, }; -static int __init vhci_init(void) +static int __init vhci_hcd_init(void) { int ret; @@ -1236,14 +1249,14 @@ static int __init vhci_init(void) return ret; } -static void __exit vhci_cleanup(void) +static void __exit vhci_hcd_exit(void) { platform_device_unregister(&the_pdev); platform_driver_unregister(&vhci_driver); } -module_init(vhci_init); -module_exit(vhci_cleanup); +module_init(vhci_hcd_init); +module_exit(vhci_hcd_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c index e42ce9dab7ac..09c44abb89e8 100644 --- a/drivers/staging/usbip/vhci_rx.c +++ b/drivers/staging/usbip/vhci_rx.c @@ -179,8 +179,6 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, } kfree(unlink); - - return; } static int vhci_priv_tx_empty(struct vhci_device *vdev) diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c index d9736f9c4028..0cd039bb5fd6 100644 --- a/drivers/staging/usbip/vhci_sysfs.c +++ b/drivers/staging/usbip/vhci_sysfs.c @@ -135,7 +135,7 @@ static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach); static int valid_args(__u32 rhport, enum usb_device_speed speed) { /* check rhport */ - if ((rhport < 0) || (rhport >= VHCI_NPORTS)) { + if (rhport >= VHCI_NPORTS) { pr_err("port %u\n", rhport); return -EINVAL; } @@ -192,7 +192,7 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, /* check sockfd */ socket = sockfd_to_socket(sockfd); if (!socket) - return -EINVAL; + return -EINVAL; /* now need lock until setting vdev status as used */ @@ -239,6 +239,6 @@ static struct attribute *dev_attrs[] = { NULL, }; -struct attribute_group dev_attr_group = { +const struct attribute_group dev_attr_group = { .attrs = dev_attrs, }; diff --git a/drivers/staging/vme/boards/vme_vmivme7805.c b/drivers/staging/vme/boards/vme_vmivme7805.c index 80eaa0c4fe1c..8e05bb4e135a 100644 --- a/drivers/staging/vme/boards/vme_vmivme7805.c +++ b/drivers/staging/vme/boards/vme_vmivme7805.c @@ -27,9 +27,9 @@ static void __exit vmic_exit(void); /** Base address to access FPGA register */ static void *vmic_base; -static char driver_name[] = "vmivme_7805"; +static const char driver_name[] = "vmivme_7805"; -static struct pci_device_id vmic_ids[] = { +static DEFINE_PCI_DEVICE_TABLE(vmic_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_VMIC, PCI_DEVICE_ID_VTIMR) }, { }, }; diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index a4007287ef47..5122c13a9563 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -42,7 +42,7 @@ static void __exit ca91cx42_exit(void); /* Module parameters */ static int geoid; -static char driver_name[] = "vme_ca91cx42"; +static const char driver_name[] = "vme_ca91cx42"; static DEFINE_PCI_DEVICE_TABLE(ca91cx42_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) }, @@ -190,7 +190,7 @@ static irqreturn_t ca91cx42_irqhandler(int irq, void *ptr) serviced |= ca91cx42_VIRQ_irqhandler(ca91cx42_bridge, stat); /* Clear serviced interrupts */ - iowrite32(stat, bridge->base + LINT_STAT); + iowrite32(serviced, bridge->base + LINT_STAT); return IRQ_HANDLED; } @@ -256,6 +256,18 @@ static void ca91cx42_irq_exit(struct ca91cx42_driver *bridge, free_irq(pdev->irq, pdev); } +static int ca91cx42_iack_received(struct ca91cx42_driver *bridge, int level) +{ + u32 tmp; + + tmp = ioread32(bridge->base + LINT_STAT); + + if (tmp & (1 << level)) + return 0; + else + return 1; +} + /* * Set up an VME interrupt */ @@ -311,7 +323,8 @@ static int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level, iowrite32(tmp, bridge->base + VINT_EN); /* Wait for IACK */ - wait_event_interruptible(bridge->iack_queue, 0); + wait_event_interruptible(bridge->iack_queue, + ca91cx42_iack_received(bridge, level)); /* Return interrupt to low state */ tmp = ioread32(bridge->base + VINT_EN); diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 106aa9daff48..9c539513c74b 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -44,7 +44,7 @@ static void __exit tsi148_exit(void); static int err_chk; static int geoid; -static char driver_name[] = "vme_tsi148"; +static const char driver_name[] = "vme_tsi148"; static DEFINE_PCI_DEVICE_TABLE(tsi148_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) }, diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index a571173249cf..91d2cc7bb4c3 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -41,7 +41,7 @@ #include "vme_user.h" static DEFINE_MUTEX(vme_user_mutex); -static char driver_name[] = "vme_user"; +static const char driver_name[] = "vme_user"; static int bus[USER_BUS_MAX]; static unsigned int bus_num; @@ -91,7 +91,7 @@ static unsigned int bus_num; /* * Structure to handle image related parameters. */ -typedef struct { +struct image_desc { void *kern_buf; /* Buffer address in kernel space */ dma_addr_t pci_buf; /* Buffer address in PCI address space */ unsigned long long size_buf; /* Buffer size */ @@ -99,10 +99,10 @@ typedef struct { struct device *device; /* Sysfs device */ struct vme_resource *resource; /* VME resource */ int users; /* Number of current users */ -} image_desc_t; -static image_desc_t image[VME_DEVS]; +}; +static struct image_desc image[VME_DEVS]; -typedef struct { +struct driver_stats { unsigned long reads; unsigned long writes; unsigned long ioctls; @@ -111,8 +111,8 @@ typedef struct { unsigned long dmaErrors; unsigned long timeouts; unsigned long external; -} driver_stats_t; -static driver_stats_t statistics; +}; +static struct driver_stats statistics; static struct cdev *vme_user_cdev; /* Character device */ static struct class *vme_user_sysfs_class; /* Sysfs class */ @@ -138,7 +138,7 @@ static long vme_user_unlocked_ioctl(struct file *, unsigned int, unsigned long); static int __devinit vme_user_probe(struct device *, int, int); static int __devexit vme_user_remove(struct device *, int, int); -static struct file_operations vme_user_fops = { +static const struct file_operations vme_user_fops = { .open = vme_user_open, .release = vme_user_release, .read = vme_user_read, @@ -168,8 +168,8 @@ static int vme_user_open(struct inode *inode, struct file *file) unsigned int minor = MINOR(inode->i_rdev); down(&image[minor].sem); - /* Only allow device to be opened if a resource is allocated */ - if (image[minor].resource == NULL) { + /* Allow device to be opened if a resource is needed and allocated. */ + if (minor < CONTROL_MINOR && image[minor].resource == NULL) { printk(KERN_ERR "No resources allocated for device\n"); err = -EINVAL; goto err_res; @@ -321,6 +321,9 @@ static ssize_t vme_user_read(struct file *file, char __user *buf, size_t count, size_t image_size; size_t okcount; + if (minor == CONTROL_MINOR) + return 0; + down(&image[minor].sem); /* XXX Do we *really* want this helper - we can use vme_*_get ? */ @@ -365,6 +368,9 @@ static ssize_t vme_user_write(struct file *file, const char __user *buf, size_t image_size; size_t okcount; + if (minor == CONTROL_MINOR) + return 0; + down(&image[minor].sem); image_size = vme_get_size(image[minor].resource); @@ -406,6 +412,9 @@ static loff_t vme_user_llseek(struct file *file, loff_t off, int whence) unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); size_t image_size; + if (minor == CONTROL_MINOR) + return -EINVAL; + down(&image[minor].sem); image_size = vme_get_size(image[minor].resource); @@ -452,6 +461,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, { struct vme_master master; struct vme_slave slave; + struct vme_irq_id irq_req; unsigned long copied; unsigned int minor = MINOR(inode->i_rdev); int retval; @@ -462,6 +472,21 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, switch (type[minor]) { case CONTROL_MINOR: + switch (cmd) { + case VME_IRQ_GEN: + copied = copy_from_user(&irq_req, (char *)arg, + sizeof(struct vme_irq_id)); + if (copied != 0) { + printk(KERN_WARNING "Partial copy from userspace\n"); + return -EFAULT; + } + + retval = vme_irq_generate(vme_user_bridge, + irq_req.level, + irq_req.statid); + + return retval; + } break; case MASTER_MINOR: switch (cmd) { @@ -773,6 +798,7 @@ static int __devinit vme_user_probe(struct device *dev, int cur_bus, /* Add sysfs Entries */ for (i = 0; i < VME_DEVS; i++) { + int num; switch (type[i]) { case MASTER_MINOR: sprintf(name, "bus/vme/m%%d"); @@ -789,10 +815,9 @@ static int __devinit vme_user_probe(struct device *dev, int cur_bus, break; } - image[i].device = - device_create(vme_user_sysfs_class, NULL, - MKDEV(VME_MAJOR, i), NULL, name, - (type[i] == SLAVE_MINOR) ? i - (MASTER_MAX + 1) : i); + num = (type[i] == SLAVE_MINOR) ? i - (MASTER_MAX + 1) : i; + image[i].device = device_create(vme_user_sysfs_class, NULL, + MKDEV(VME_MAJOR, i), NULL, name, num); if (IS_ERR(image[i].device)) { printk(KERN_INFO "%s: Error creating sysfs device\n", driver_name); diff --git a/drivers/staging/vme/devices/vme_user.h b/drivers/staging/vme/devices/vme_user.h index ede77d7e766b..24bf4e54013d 100644 --- a/drivers/staging/vme/devices/vme_user.h +++ b/drivers/staging/vme/devices/vme_user.h @@ -43,10 +43,16 @@ struct vme_slave { #endif }; +struct vme_irq_id { + __u8 level; + __u8 statid; +}; + #define VME_GET_SLAVE _IOR(VME_IOC_MAGIC, 1, struct vme_slave) #define VME_SET_SLAVE _IOW(VME_IOC_MAGIC, 2, struct vme_slave) #define VME_GET_MASTER _IOR(VME_IOC_MAGIC, 3, struct vme_master) #define VME_SET_MASTER _IOW(VME_IOC_MAGIC, 4, struct vme_master) +#define VME_IRQ_GEN _IOW(VME_IOC_MAGIC, 5, struct vme_irq_id) #endif /* _VME_USER_H_ */ diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h index 48768ca97e16..4155d8c2a531 100644 --- a/drivers/staging/vme/vme.h +++ b/drivers/staging/vme/vme.h @@ -98,7 +98,7 @@ struct vme_device_id { struct vme_driver { struct list_head node; - char *name; + const char *name; const struct vme_device_id *bind_table; int (*probe) (struct device *, int, int); int (*remove) (struct device *, int, int); diff --git a/drivers/staging/westbridge/Kconfig b/drivers/staging/westbridge/Kconfig deleted file mode 100644 index 2b1c2ae557b6..000000000000 --- a/drivers/staging/westbridge/Kconfig +++ /dev/null @@ -1,53 +0,0 @@ -# -# West Bridge configuration -# - -menuconfig WESTBRIDGE - tristate "West Bridge support" - depends on WESTBRIDGE_HAL_SELECTED - help - This selects West Bridge Peripheral controller support. - - If you want West Bridge support, you should say Y here. - -menuconfig WESTBRIDGE_ASTORIA - bool "West Bridge Astoria support" - depends on WESTBRIDGE != n && WESTBRIDGE_HAL_SELECTED - help - This option enables support for West Bridge Astoria - -if WESTBRIDGE_ASTORIA -source "drivers/staging/westbridge/astoria/Kconfig" -endif #WESTBRIDGE_ASTORIA - -config WESTBRIDGE_HAL_SELECTED - boolean - -choice - prompt "West Bridge HAL" - help - West Bridge HAL/processor interface to be used - -# -# HAL Layers -# - -config MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL - bool "WESTBRIDGE OMAP3430 Astoria PNAND HAL" - depends on ARCH_OMAP3 - select WESTBRIDGE_HAL_SELECTED - help - Include the OMAP3430 HAL for PNAND interface - -config MACH_NO_WESTBRIDGE - bool "no West Bridge HAL selected" - help - Do not include any HAL layer(de-activates West Bridge option) -endchoice - -config WESTBRIDGE_DEBUG - bool "West Bridge debugging" - depends on WESTBRIDGE != n - help - This is an option for use by developers; most people should - say N here. This enables WESTBRIDGE core and driver debugging. diff --git a/drivers/staging/westbridge/TODO b/drivers/staging/westbridge/TODO deleted file mode 100644 index 6ca80581bbe2..000000000000 --- a/drivers/staging/westbridge/TODO +++ /dev/null @@ -1,7 +0,0 @@ -TODO: -- checkpatch.pl fixes -- determine where to put the hal and common api code -- modify the driver directory structure in an intuitive way - -Please send any patches to Greg Kroah-Hartman -and David Cross . diff --git a/drivers/staging/westbridge/astoria/Kconfig b/drivers/staging/westbridge/astoria/Kconfig deleted file mode 100644 index 1ce388acbfeb..000000000000 --- a/drivers/staging/westbridge/astoria/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# -# West Bridge configuration -# -source "drivers/staging/westbridge/astoria/device/Kconfig" - -source "drivers/staging/westbridge/astoria/block/Kconfig" - -source "drivers/staging/westbridge/astoria/gadget/Kconfig" - diff --git a/drivers/staging/westbridge/astoria/Makefile b/drivers/staging/westbridge/astoria/Makefile deleted file mode 100644 index 907bdb25804b..000000000000 --- a/drivers/staging/westbridge/astoria/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for the kernel westbridge device drivers. -# - -ifneq ($(CONFIG_WESTBRIDGE_DEBUG),y) - EXTRA_CFLAGS += -WESTBRIDGE_NDEBUG -endif - -obj-$(CONFIG_WESTBRIDGE) += device/ -obj-$(CONFIG_WESTBRIDGE) += block/ -obj-$(CONFIG_WESTBRIDGE) += gadget/ \ No newline at end of file diff --git a/drivers/staging/westbridge/astoria/api/Makefile b/drivers/staging/westbridge/astoria/api/Makefile deleted file mode 100644 index 1c94bc7bb310..000000000000 --- a/drivers/staging/westbridge/astoria/api/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# Makefile for the kernel westbridge core. -# - -ifeq ($(CONFIG_WESTBRIDGE_DEBUG),n) - EXTRA_CFLAGS += -NDEBUG -endif - -obj-$(CONFIG_WESTBRIDGE_DEVICE_DRIVER) += cyasapi.o -cyasapi-y := src/cyasdma.o src/cyasintr.o src/cyaslep2pep.o \ - src/cyaslowlevel.o src/cyasmisc.o src/cyasmtp.o \ - src/cyasstorage.o src/cyasusb.o - - diff --git a/drivers/staging/westbridge/astoria/api/src/cyasdma.c b/drivers/staging/westbridge/astoria/api/src/cyasdma.c deleted file mode 100644 index c461d4f60bfb..000000000000 --- a/drivers/staging/westbridge/astoria/api/src/cyasdma.c +++ /dev/null @@ -1,1107 +0,0 @@ -/* Cypress West Bridge API source file (cyasdma.c) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#include "../../include/linux/westbridge/cyashal.h" -#include "../../include/linux/westbridge/cyasdma.h" -#include "../../include/linux/westbridge/cyaslowlevel.h" -#include "../../include/linux/westbridge/cyaserr.h" -#include "../../include/linux/westbridge/cyasregs.h" - -/* - * Add the DMA queue entry to the free list to be re-used later - */ -static void -cy_as_dma_add_request_to_free_queue(cy_as_device *dev_p, - cy_as_dma_queue_entry *req_p) -{ - uint32_t imask; - imask = cy_as_hal_disable_interrupts(); - - req_p->next_p = dev_p->dma_freelist_p; - dev_p->dma_freelist_p = req_p; - - cy_as_hal_enable_interrupts(imask); -} - -/* - * Get a DMA queue entry from the free list. - */ -static cy_as_dma_queue_entry * -cy_as_dma_get_dma_queue_entry(cy_as_device *dev_p) -{ - cy_as_dma_queue_entry *req_p; - uint32_t imask; - - cy_as_hal_assert(dev_p->dma_freelist_p != 0); - - imask = cy_as_hal_disable_interrupts(); - req_p = dev_p->dma_freelist_p; - dev_p->dma_freelist_p = req_p->next_p; - cy_as_hal_enable_interrupts(imask); - - return req_p; -} - -/* - * Set the maximum size that the West Bridge hardware - * can handle in a single DMA operation. This size - * may change for the P <-> U endpoints as a function - * of the endpoint type and whether we are running - * at full speed or high speed. - */ -cy_as_return_status_t -cy_as_dma_set_max_dma_size(cy_as_device *dev_p, - cy_as_end_point_number_t ep, uint32_t size) -{ - /* In MTP mode, EP2 is allowed to have all max sizes. */ - if ((!dev_p->is_mtp_firmware) || (ep != 0x02)) { - if (size < 64 || size > 1024) - return CY_AS_ERROR_INVALID_SIZE; - } - - CY_AS_NUM_EP(dev_p, ep)->maxhwdata = (uint16_t)size; - return CY_AS_ERROR_SUCCESS; -} - -/* - * The callback for requests sent to West Bridge - * to relay endpoint data. Endpoint data for EP0 - * and EP1 are sent using mailbox requests. This - * is the callback that is called when a response - * to a mailbox request to send data is received. - */ -static void -cy_as_dma_request_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *resp_p, - cy_as_return_status_t ret) -{ - uint16_t v; - uint16_t datacnt; - cy_as_end_point_number_t ep; - - (void)context; - - cy_as_log_debug_message(5, "cy_as_dma_request_callback called"); - - /* - * extract the return code from the firmware - */ - if (ret == CY_AS_ERROR_SUCCESS) { - if (cy_as_ll_request_response__get_code(resp_p) != - CY_RESP_SUCCESS_FAILURE) - ret = CY_AS_ERROR_INVALID_RESPONSE; - else - ret = cy_as_ll_request_response__get_word(resp_p, 0); - } - - /* - * extract the endpoint number and the transferred byte count - * from the request. - */ - v = cy_as_ll_request_response__get_word(req_p, 0); - ep = (cy_as_end_point_number_t)((v >> 13) & 0x01); - - if (ret == CY_AS_ERROR_SUCCESS) { - /* - * if the firmware returns success, - * all of the data requested was - * transferred. there are no partial - * transfers. - */ - datacnt = v & 0x3FF; - } else { - /* - * if the firmware returned an error, no data was transferred. - */ - datacnt = 0; - } - - /* - * queue the request and response data structures for use with the - * next EP0 or EP1 request. - */ - if (ep == 0) { - dev_p->usb_ep0_dma_req = req_p; - dev_p->usb_ep0_dma_resp = resp_p; - } else { - dev_p->usb_ep1_dma_req = req_p; - dev_p->usb_ep1_dma_resp = resp_p; - } - - /* - * call the DMA complete function so we can - * signal that this portion of the transfer - * has completed. if the low level request - * was canceled, we do not need to signal - * the completed function as the only way a - * cancel can happen is via the DMA cancel - * function. - */ - if (ret != CY_AS_ERROR_CANCELED) - cy_as_dma_completed_callback(dev_p->tag, ep, datacnt, ret); -} - -/* - * Set the DRQ mask register for the given endpoint number. If state is - * CyTrue, the DRQ interrupt for the given endpoint is enabled, otherwise - * it is disabled. - */ -static void -cy_as_dma_set_drq(cy_as_device *dev_p, - cy_as_end_point_number_t ep, cy_bool state) -{ - uint16_t mask; - uint16_t v; - uint32_t intval; - - /* - * there are not DRQ register bits for EP0 and EP1 - */ - if (ep == 0 || ep == 1) - return; - - /* - * disable interrupts while we do this to be sure the state of the - * DRQ mask register is always well defined. - */ - intval = cy_as_hal_disable_interrupts(); - - /* - * set the DRQ bit to the given state for the ep given - */ - mask = (1 << ep); - v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_DRQ_MASK); - - if (state) - v |= mask; - else - v &= ~mask; - - cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_DRQ_MASK, v); - cy_as_hal_enable_interrupts(intval); -} - -/* -* Send the next DMA request for the endpoint given -*/ -static void -cy_as_dma_send_next_dma_request(cy_as_device *dev_p, cy_as_dma_end_point *ep_p) -{ - uint32_t datacnt; - void *buf_p; - cy_as_dma_queue_entry *dma_p; - - cy_as_log_debug_message(6, "cy_as_dma_send_next_dma_request called"); - - /* If the queue is empty, nothing to do */ - dma_p = ep_p->queue_p; - if (dma_p == 0) { - /* - * there are no pending DMA requests - * for this endpoint. disable the DRQ - * mask bits to insure no interrupts - * will be triggered by this endpoint - * until someone is interested in the data. - */ - cy_as_dma_set_drq(dev_p, ep_p->ep, cy_false); - return; - } - - cy_as_dma_end_point_set_running(ep_p); - - /* - * get the number of words that still - * need to be xferred in this request. - */ - datacnt = dma_p->size - dma_p->offset; - cy_as_hal_assert(datacnt >= 0); - - /* - * the HAL layer should never limit the size - * of the transfer to something less than the - * maxhwdata otherwise, the data will be sent - * in packets that are not correct in size. - */ - cy_as_hal_assert(ep_p->maxhaldata == CY_AS_DMA_MAX_SIZE_HW_SIZE - || ep_p->maxhaldata >= ep_p->maxhwdata); - - /* - * update the number of words that need to be xferred yet - * based on the limits of the HAL layer. - */ - if (ep_p->maxhaldata == CY_AS_DMA_MAX_SIZE_HW_SIZE) { - if (datacnt > ep_p->maxhwdata) - datacnt = ep_p->maxhwdata; - } else { - if (datacnt > ep_p->maxhaldata) - datacnt = ep_p->maxhaldata; - } - - /* - * find a pointer to the data that needs to be transferred - */ - buf_p = (((char *)dma_p->buf_p) + dma_p->offset); - - /* - * mark a request in transit - */ - cy_as_dma_end_point_set_in_transit(ep_p); - - if (ep_p->ep == 0 || ep_p->ep == 1) { - /* - * if this is a WRITE request on EP0 and EP1 - * we write the data via an EP_DATA request - * to west bridge via the mailbox registers. - * if this is a READ request, we do nothing - * and the data will arrive via an EP_DATA - * request from west bridge. in the request - * handler for the USB context we will pass - * the data back into the DMA module. - */ - if (dma_p->readreq == cy_false) { - uint16_t v; - uint16_t len; - cy_as_ll_request_response *resp_p; - cy_as_ll_request_response *req_p; - cy_as_return_status_t ret; - - len = (uint16_t)(datacnt / 2); - if (datacnt % 2) - len++; - - len++; - - if (ep_p->ep == 0) { - req_p = dev_p->usb_ep0_dma_req; - resp_p = dev_p->usb_ep0_dma_resp; - dev_p->usb_ep0_dma_req = 0; - dev_p->usb_ep0_dma_resp = 0; - } else { - req_p = dev_p->usb_ep1_dma_req; - resp_p = dev_p->usb_ep1_dma_resp; - dev_p->usb_ep1_dma_req = 0; - dev_p->usb_ep1_dma_resp = 0; - } - - cy_as_hal_assert(req_p != 0); - cy_as_hal_assert(resp_p != 0); - cy_as_hal_assert(len <= 64); - - cy_as_ll_init_request(req_p, CY_RQT_USB_EP_DATA, - CY_RQT_USB_RQT_CONTEXT, len); - - v = (uint16_t)(datacnt | (ep_p->ep << 13) | (1 << 14)); - if (dma_p->offset == 0) - v |= (1 << 12);/* Set the first packet bit */ - if (dma_p->offset + datacnt == dma_p->size) - v |= (1 << 11);/* Set the last packet bit */ - - cy_as_ll_request_response__set_word(req_p, 0, v); - cy_as_ll_request_response__pack(req_p, - 1, datacnt, buf_p); - - cy_as_ll_init_response(resp_p, 1); - - ret = cy_as_ll_send_request(dev_p, req_p, resp_p, - cy_false, cy_as_dma_request_callback); - if (ret == CY_AS_ERROR_SUCCESS) - cy_as_log_debug_message(5, - "+++ send EP 0/1 data via mailbox registers"); - else - cy_as_log_debug_message(5, - "+++ error sending EP 0/1 data via mailbox " - "registers - CY_AS_ERROR_TIMEOUT"); - - if (ret != CY_AS_ERROR_SUCCESS) - cy_as_dma_completed_callback(dev_p->tag, - ep_p->ep, 0, ret); - } - } else { - /* - * this is a DMA request on an endpoint that is accessible - * via the P port. ask the HAL DMA capabilities to - * perform this. the amount of data sent is limited by the - * HAL max size as well as what we need to send. if the - * ep_p->maxhaldata is set to a value larger than the - * endpoint buffer size, then we will pass more than a - * single buffer worth of data to the HAL layer and expect - * the HAL layer to divide the data into packets. the last - * parameter here (ep_p->maxhwdata) gives the packet size for - * the data so the HAL layer knows what the packet size should - * be. - */ - if (cy_as_dma_end_point_is_direction_in(ep_p)) - cy_as_hal_dma_setup_write(dev_p->tag, - ep_p->ep, buf_p, datacnt, ep_p->maxhwdata); - else - cy_as_hal_dma_setup_read(dev_p->tag, - ep_p->ep, buf_p, datacnt, ep_p->maxhwdata); - - /* - * the DRQ interrupt for this endpoint should be enabled - * so that the data transfer progresses at interrupt time. - */ - cy_as_dma_set_drq(dev_p, ep_p->ep, cy_true); - } -} - -/* - * This function is called when the HAL layer has - * completed the last requested DMA operation. - * This function sends/receives the next batch of - * data associated with the current DMA request, - * or it is is complete, moves to the next DMA request. - */ -void -cy_as_dma_completed_callback(cy_as_hal_device_tag tag, - cy_as_end_point_number_t ep, uint32_t cnt, cy_as_return_status_t status) -{ - uint32_t mask; - cy_as_dma_queue_entry *req_p; - cy_as_dma_end_point *ep_p; - cy_as_device *dev_p = cy_as_device_find_from_tag(tag); - - /* Make sure the HAL layer gave us good parameters */ - cy_as_hal_assert(dev_p != 0); - cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE); - cy_as_hal_assert(ep < 16); - - - /* Get the endpoint ptr */ - ep_p = CY_AS_NUM_EP(dev_p, ep); - cy_as_hal_assert(ep_p->queue_p != 0); - - /* Get a pointer to the current entry in the queue */ - mask = cy_as_hal_disable_interrupts(); - req_p = ep_p->queue_p; - - /* Update the offset to reflect the data actually received or sent */ - req_p->offset += cnt; - - /* - * if we are still sending/receiving the current packet, - * send/receive the next chunk basically we keep going - * if we have not sent/received enough data, and we are - * not doing a packet operation, and the last packet - * sent or received was a full sized packet. in other - * words, when we are NOT doing a packet operation, a - * less than full size packet (a short packet) will - * terminate the operation. - * - * note: if this is EP1 request and the request has - * timed out, it means the buffer is not free. - * we have to resend the data. - * - * note: for the MTP data transfers, the DMA transfer - * for the next packet can only be started asynchronously, - * after a firmware event notifies that the device is ready. - */ - if (((req_p->offset != req_p->size) && (req_p->packet == cy_false) && - ((cnt == ep_p->maxhaldata) || ((cnt == ep_p->maxhwdata) && - ((ep != CY_AS_MTP_READ_ENDPOINT) || - (cnt == dev_p->usb_max_tx_size))))) - || ((ep == 1) && (status == CY_AS_ERROR_TIMEOUT))) { - cy_as_hal_enable_interrupts(mask); - - /* - * and send the request again to send the next block of - * data. special handling for MTP transfers on E_ps 2 - * and 6. the send_next_request will be processed based - * on the event sent by the firmware. - */ - if ((ep == CY_AS_MTP_WRITE_ENDPOINT) || ( - (ep == CY_AS_MTP_READ_ENDPOINT) && - (!cy_as_dma_end_point_is_direction_in(ep_p)))) - cy_as_dma_end_point_set_stopped(ep_p); - else - cy_as_dma_send_next_dma_request(dev_p, ep_p); - } else { - /* - * we get here if ... - * we have sent or received all of the data - * or - * we are doing a packet operation - * or - * we receive a short packet - */ - - /* - * remove this entry from the DMA queue for this endpoint. - */ - cy_as_dma_end_point_clear_in_transit(ep_p); - ep_p->queue_p = req_p->next_p; - if (ep_p->last_p == req_p) { - /* - * we have removed the last packet from the DMA queue, - * disable the interrupt associated with this interrupt. - */ - ep_p->last_p = 0; - cy_as_hal_enable_interrupts(mask); - cy_as_dma_set_drq(dev_p, ep, cy_false); - } else - cy_as_hal_enable_interrupts(mask); - - if (req_p->cb) { - /* - * if the request has a callback associated with it, - * call the callback to tell the interested party that - * this DMA request has completed. - * - * note, we set the in_callback bit to insure that we - * cannot recursively call an API function that is - * synchronous only from a callback. - */ - cy_as_device_set_in_callback(dev_p); - (*req_p->cb)(dev_p, ep, req_p->buf_p, - req_p->offset, status); - cy_as_device_clear_in_callback(dev_p); - } - - /* - * we are done with this request, put it on the freelist to be - * reused at a later time. - */ - cy_as_dma_add_request_to_free_queue(dev_p, req_p); - - if (ep_p->queue_p == 0) { - /* - * if the endpoint is out of DMA entries, set the - * endpoint as stopped. - */ - cy_as_dma_end_point_set_stopped(ep_p); - - /* - * the DMA queue is empty, wake any task waiting on - * the QUEUE to drain. - */ - if (cy_as_dma_end_point_is_sleeping(ep_p)) { - cy_as_dma_end_point_set_wake_state(ep_p); - cy_as_hal_wake(&ep_p->channel); - } - } else { - /* - * if the queued operation is a MTP transfer, - * wait until firmware event before sending - * down the next DMA request. - */ - if ((ep == CY_AS_MTP_WRITE_ENDPOINT) || - ((ep == CY_AS_MTP_READ_ENDPOINT) && - (!cy_as_dma_end_point_is_direction_in(ep_p))) || - ((ep == dev_p->storage_read_endpoint) && - (!cy_as_device_is_p2s_dma_start_recvd(dev_p))) - || ((ep == dev_p->storage_write_endpoint) && - (!cy_as_device_is_p2s_dma_start_recvd(dev_p)))) - cy_as_dma_end_point_set_stopped(ep_p); - else - cy_as_dma_send_next_dma_request(dev_p, ep_p); - } - } -} - -/* -* This function is used to kick start DMA on a given -* channel. If DMA is already running on the given -* endpoint, nothing happens. If DMA is not running, -* the first entry is pulled from the DMA queue and -* sent/recevied to/from the West Bridge device. -*/ -cy_as_return_status_t -cy_as_dma_kick_start(cy_as_device *dev_p, cy_as_end_point_number_t ep) -{ - cy_as_dma_end_point *ep_p; - cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE); - - ep_p = CY_AS_NUM_EP(dev_p, ep); - - /* We are already running */ - if (cy_as_dma_end_point_is_running(ep_p)) - return CY_AS_ERROR_SUCCESS; - - cy_as_dma_send_next_dma_request(dev_p, ep_p); - return CY_AS_ERROR_SUCCESS; -} - -/* - * This function stops the given endpoint. Stopping and endpoint cancels - * any pending DMA operations and frees all resources associated with the - * given endpoint. - */ -static cy_as_return_status_t -cy_as_dma_stop_end_point(cy_as_device *dev_p, cy_as_end_point_number_t ep) -{ - cy_as_return_status_t ret; - cy_as_dma_end_point *ep_p = CY_AS_NUM_EP(dev_p, ep); - - /* - * cancel any pending DMA requests associated with this endpoint. this - * cancels any DMA requests at the HAL layer as well as dequeues any - * request that is currently pending. - */ - ret = cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* - * destroy the sleep channel - */ - if (!cy_as_hal_destroy_sleep_channel(&ep_p->channel) - && ret == CY_AS_ERROR_SUCCESS) - ret = CY_AS_ERROR_DESTROY_SLEEP_CHANNEL_FAILED; - - /* - * free the memory associated with this endpoint - */ - cy_as_hal_free(ep_p); - - /* - * set the data structure ptr to something sane since the - * previous pointer is now free. - */ - dev_p->endp[ep] = 0; - - return ret; -} - -/* - * This method stops the USB stack. This is an internal function that does - * all of the work of destroying the USB stack without the protections that - * we provide to the API (i.e. stopping at stack that is not running). - */ -static cy_as_return_status_t -cy_as_dma_stop_internal(cy_as_device *dev_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_return_status_t lret; - cy_as_end_point_number_t i; - - /* - * stop all of the endpoints. this cancels all DMA requests, and - * frees all resources associated with each endpoint. - */ - for (i = 0; i < sizeof(dev_p->endp)/(sizeof(dev_p->endp[0])); i++) { - lret = cy_as_dma_stop_end_point(dev_p, i); - if (lret != CY_AS_ERROR_SUCCESS && ret == CY_AS_ERROR_SUCCESS) - ret = lret; - } - - /* - * now, free the list of DMA requests structures that we use to manage - * DMA requests. - */ - while (dev_p->dma_freelist_p) { - cy_as_dma_queue_entry *req_p; - uint32_t imask = cy_as_hal_disable_interrupts(); - - req_p = dev_p->dma_freelist_p; - dev_p->dma_freelist_p = req_p->next_p; - - cy_as_hal_enable_interrupts(imask); - - cy_as_hal_free(req_p); - } - - cy_as_ll_destroy_request(dev_p, dev_p->usb_ep0_dma_req); - cy_as_ll_destroy_request(dev_p, dev_p->usb_ep1_dma_req); - cy_as_ll_destroy_response(dev_p, dev_p->usb_ep0_dma_resp); - cy_as_ll_destroy_response(dev_p, dev_p->usb_ep1_dma_resp); - - return ret; -} - - -/* - * CyAsDmaStop() - * - * This function shuts down the DMA module. All resources - * associated with the DMA module will be freed. This - * routine is the API stop function. It insures that we - * are stopping a stack that is actually running and then - * calls the internal function to do the work. - */ -cy_as_return_status_t -cy_as_dma_stop(cy_as_device *dev_p) -{ - cy_as_return_status_t ret; - - ret = cy_as_dma_stop_internal(dev_p); - cy_as_device_set_dma_stopped(dev_p); - - return ret; -} - -/* - * CyAsDmaStart() - * - * This function initializes the DMA module to insure it is up and running. - */ -cy_as_return_status_t -cy_as_dma_start(cy_as_device *dev_p) -{ - cy_as_end_point_number_t i; - uint16_t cnt; - - if (cy_as_device_is_dma_running(dev_p)) - return CY_AS_ERROR_ALREADY_RUNNING; - - /* - * pre-allocate DMA queue structures to be used in the interrupt context - */ - for (cnt = 0; cnt < 32; cnt++) { - cy_as_dma_queue_entry *entry_p = (cy_as_dma_queue_entry *) - cy_as_hal_alloc(sizeof(cy_as_dma_queue_entry)); - if (entry_p == 0) { - cy_as_dma_stop_internal(dev_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - cy_as_dma_add_request_to_free_queue(dev_p, entry_p); - } - - /* - * pre-allocate the DMA requests for sending EP0 - * and EP1 data to west bridge - */ - dev_p->usb_ep0_dma_req = cy_as_ll_create_request(dev_p, - CY_RQT_USB_EP_DATA, CY_RQT_USB_RQT_CONTEXT, 64); - dev_p->usb_ep1_dma_req = cy_as_ll_create_request(dev_p, - CY_RQT_USB_EP_DATA, CY_RQT_USB_RQT_CONTEXT, 64); - - if (dev_p->usb_ep0_dma_req == 0 || dev_p->usb_ep1_dma_req == 0) { - cy_as_dma_stop_internal(dev_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - dev_p->usb_ep0_dma_req_save = dev_p->usb_ep0_dma_req; - - dev_p->usb_ep0_dma_resp = cy_as_ll_create_response(dev_p, 1); - dev_p->usb_ep1_dma_resp = cy_as_ll_create_response(dev_p, 1); - if (dev_p->usb_ep0_dma_resp == 0 || dev_p->usb_ep1_dma_resp == 0) { - cy_as_dma_stop_internal(dev_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - dev_p->usb_ep0_dma_resp_save = dev_p->usb_ep0_dma_resp; - - /* - * set the dev_p->endp to all zeros to insure cleanup is possible if - * an error occurs during initialization. - */ - cy_as_hal_mem_set(dev_p->endp, 0, sizeof(dev_p->endp)); - - /* - * now, iterate through each of the endpoints and initialize each - * one. - */ - for (i = 0; i < sizeof(dev_p->endp)/sizeof(dev_p->endp[0]); i++) { - dev_p->endp[i] = (cy_as_dma_end_point *) - cy_as_hal_alloc(sizeof(cy_as_dma_end_point)); - if (dev_p->endp[i] == 0) { - cy_as_dma_stop_internal(dev_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - cy_as_hal_mem_set(dev_p->endp[i], 0, - sizeof(cy_as_dma_end_point)); - - dev_p->endp[i]->ep = i; - dev_p->endp[i]->queue_p = 0; - dev_p->endp[i]->last_p = 0; - - cy_as_dma_set_drq(dev_p, i, cy_false); - - if (!cy_as_hal_create_sleep_channel(&dev_p->endp[i]->channel)) - return CY_AS_ERROR_CREATE_SLEEP_CHANNEL_FAILED; - } - - /* - * tell the HAL layer who to call when the - * HAL layer completes a DMA request - */ - cy_as_hal_dma_register_callback(dev_p->tag, - cy_as_dma_completed_callback); - - /* - * mark DMA as up and running on this device - */ - cy_as_device_set_dma_running(dev_p); - - return CY_AS_ERROR_SUCCESS; -} - -/* -* Wait for all entries in the DMA queue associated -* the given endpoint to be drained. This function -* will not return until all the DMA data has been -* transferred. -*/ -cy_as_return_status_t -cy_as_dma_drain_queue(cy_as_device *dev_p, - cy_as_end_point_number_t ep, cy_bool kickstart) -{ - cy_as_dma_end_point *ep_p; - int loopcount = 1000; - uint32_t mask; - - /* - * make sure the endpoint is valid - */ - if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0])) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* Get the endpoint pointer based on the endpoint number */ - ep_p = CY_AS_NUM_EP(dev_p, ep); - - /* - * if the endpoint is empty of traffic, we return - * with success immediately - */ - mask = cy_as_hal_disable_interrupts(); - if (ep_p->queue_p == 0) { - cy_as_hal_enable_interrupts(mask); - return CY_AS_ERROR_SUCCESS; - } else { - /* - * add 10 seconds to the time out value for each 64 KB segment - * of data to be transferred. - */ - if (ep_p->queue_p->size > 0x10000) - loopcount += ((ep_p->queue_p->size / 0x10000) * 1000); - } - cy_as_hal_enable_interrupts(mask); - - /* If we are already sleeping on this endpoint, it is an error */ - if (cy_as_dma_end_point_is_sleeping(ep_p)) - return CY_AS_ERROR_NESTED_SLEEP; - - /* - * we disable the endpoint while the queue drains to - * prevent any additional requests from being queued while we are waiting - */ - cy_as_dma_enable_end_point(dev_p, ep, - cy_false, cy_as_direction_dont_change); - - if (kickstart) { - /* - * now, kick start the DMA if necessary - */ - cy_as_dma_kick_start(dev_p, ep); - } - - /* - * check one last time before we begin sleeping to see if the - * queue is drained. - */ - if (ep_p->queue_p == 0) { - cy_as_dma_enable_end_point(dev_p, ep, cy_true, - cy_as_direction_dont_change); - return CY_AS_ERROR_SUCCESS; - } - - while (loopcount-- > 0) { - /* - * sleep for 10 ms maximum (per loop) while - * waiting for the transfer to complete. - */ - cy_as_dma_end_point_set_sleep_state(ep_p); - cy_as_hal_sleep_on(&ep_p->channel, 10); - - /* If we timed out, the sleep bit will still be set */ - cy_as_dma_end_point_set_wake_state(ep_p); - - /* Check the queue to see if is drained */ - if (ep_p->queue_p == 0) { - /* - * clear the endpoint running and in transit flags - * for the endpoint, now that its DMA queue is empty. - */ - cy_as_dma_end_point_clear_in_transit(ep_p); - cy_as_dma_end_point_set_stopped(ep_p); - - cy_as_dma_enable_end_point(dev_p, ep, - cy_true, cy_as_direction_dont_change); - return CY_AS_ERROR_SUCCESS; - } - } - - /* - * the DMA operation that has timed out can be cancelled, so that later - * operations on this queue can proceed. - */ - cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_TIMEOUT); - cy_as_dma_enable_end_point(dev_p, ep, - cy_true, cy_as_direction_dont_change); - return CY_AS_ERROR_TIMEOUT; -} - -/* -* This function queues a write request in the DMA queue -* for a given endpoint. The direction of the -* entry will be inferred from the endpoint direction. -*/ -cy_as_return_status_t -cy_as_dma_queue_request(cy_as_device *dev_p, - cy_as_end_point_number_t ep, void *mem_p, - uint32_t size, cy_bool pkt, cy_bool readreq, cy_as_dma_callback cb) -{ - uint32_t mask; - cy_as_dma_queue_entry *entry_p; - cy_as_dma_end_point *ep_p; - - /* - * make sure the endpoint is valid - */ - if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0])) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* Get the endpoint pointer based on the endpoint number */ - ep_p = CY_AS_NUM_EP(dev_p, ep); - - if (!cy_as_dma_end_point_is_enabled(ep_p)) - return CY_AS_ERROR_ENDPOINT_DISABLED; - - entry_p = cy_as_dma_get_dma_queue_entry(dev_p); - - entry_p->buf_p = mem_p; - entry_p->cb = cb; - entry_p->size = size; - entry_p->offset = 0; - entry_p->packet = pkt; - entry_p->readreq = readreq; - - mask = cy_as_hal_disable_interrupts(); - entry_p->next_p = 0; - if (ep_p->last_p) - ep_p->last_p->next_p = entry_p; - ep_p->last_p = entry_p; - if (ep_p->queue_p == 0) - ep_p->queue_p = entry_p; - cy_as_hal_enable_interrupts(mask); - - return CY_AS_ERROR_SUCCESS; -} - -/* -* This function enables or disables and endpoint for DMA -* queueing. If an endpoint is disabled, any queue requests -* continue to be processed, but no new requests can be queued. -*/ -cy_as_return_status_t -cy_as_dma_enable_end_point(cy_as_device *dev_p, - cy_as_end_point_number_t ep, cy_bool enable, cy_as_dma_direction dir) -{ - cy_as_dma_end_point *ep_p; - - /* - * make sure the endpoint is valid - */ - if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0])) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* Get the endpoint pointer based on the endpoint number */ - ep_p = CY_AS_NUM_EP(dev_p, ep); - - if (dir == cy_as_direction_out) - cy_as_dma_end_point_set_direction_out(ep_p); - else if (dir == cy_as_direction_in) - cy_as_dma_end_point_set_direction_in(ep_p); - - /* - * get the maximum size of data buffer the HAL - * layer can accept. this is used when the DMA - * module is sending DMA requests to the HAL. - * the DMA module will never send down a request - * that is greater than this value. - * - * for EP0 and EP1, we can send no more than 64 - * bytes of data at one time as this is the maximum - * size of a packet that can be sent via these - * endpoints. - */ - if (ep == 0 || ep == 1) - ep_p->maxhaldata = 64; - else - ep_p->maxhaldata = cy_as_hal_dma_max_request_size( - dev_p->tag, ep); - - if (enable) - cy_as_dma_end_point_enable(ep_p); - else - cy_as_dma_end_point_disable(ep_p); - - return CY_AS_ERROR_SUCCESS; -} - -/* - * This function cancels any DMA operations pending with the HAL layer as well - * as any DMA operation queued on the endpoint. - */ -cy_as_return_status_t -cy_as_dma_cancel( - cy_as_device *dev_p, - cy_as_end_point_number_t ep, - cy_as_return_status_t err) -{ - uint32_t mask; - cy_as_dma_end_point *ep_p; - cy_as_dma_queue_entry *entry_p; - cy_bool epstate; - - /* - * make sure the endpoint is valid - */ - if (ep >= sizeof(dev_p->endp)/sizeof(dev_p->endp[0])) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* Get the endpoint pointer based on the endpoint number */ - ep_p = CY_AS_NUM_EP(dev_p, ep); - - if (ep_p) { - /* Remember the state of the endpoint */ - epstate = cy_as_dma_end_point_is_enabled(ep_p); - - /* - * disable the endpoint so no more DMA packets can be - * queued. - */ - cy_as_dma_enable_end_point(dev_p, ep, - cy_false, cy_as_direction_dont_change); - - /* - * don't allow any interrupts from this endpoint - * while we get the most current request off of - * the queue. - */ - cy_as_dma_set_drq(dev_p, ep, cy_false); - - /* - * cancel any pending request queued in the HAL layer - */ - if (cy_as_dma_end_point_in_transit(ep_p)) - cy_as_hal_dma_cancel_request(dev_p->tag, ep_p->ep); - - /* - * shutdown the DMA for this endpoint so no - * more data is transferred - */ - cy_as_dma_end_point_set_stopped(ep_p); - - /* - * mark the endpoint as not in transit, because we are - * going to consume any queued requests - */ - cy_as_dma_end_point_clear_in_transit(ep_p); - - /* - * now, remove each entry in the queue and call the - * associated callback stating that the request was - * canceled. - */ - ep_p->last_p = 0; - while (ep_p->queue_p != 0) { - /* Disable interrupts to manipulate the queue */ - mask = cy_as_hal_disable_interrupts(); - - /* Remove an entry from the queue */ - entry_p = ep_p->queue_p; - ep_p->queue_p = entry_p->next_p; - - /* Ok, the queue has been updated, we can - * turn interrupts back on */ - cy_as_hal_enable_interrupts(mask); - - /* Call the callback indicating we have - * canceled the DMA */ - if (entry_p->cb) - entry_p->cb(dev_p, ep, - entry_p->buf_p, entry_p->size, err); - - cy_as_dma_add_request_to_free_queue(dev_p, entry_p); - } - - if (ep == 0 || ep == 1) { - /* - * if this endpoint is zero or one, we need to - * clear the queue of any pending CY_RQT_USB_EP_DATA - * requests as these are pending requests to send - * data to the west bridge device. - */ - cy_as_ll_remove_ep_data_requests(dev_p, ep); - } - - if (epstate) { - /* - * the endpoint started out enabled, so we - * re-enable the endpoint here. - */ - cy_as_dma_enable_end_point(dev_p, ep, - cy_true, cy_as_direction_dont_change); - } - } - - return CY_AS_ERROR_SUCCESS; -} - -cy_as_return_status_t -cy_as_dma_received_data(cy_as_device *dev_p, - cy_as_end_point_number_t ep, uint32_t dsize, void *data) -{ - cy_as_dma_queue_entry *dma_p; - uint8_t *src_p, *dest_p; - cy_as_dma_end_point *ep_p; - uint32_t xfersize; - - /* - * make sure the endpoint is valid - */ - if (ep != 0 && ep != 1) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* Get the endpoint pointer based on the endpoint number */ - ep_p = CY_AS_NUM_EP(dev_p, ep); - dma_p = ep_p->queue_p; - if (dma_p == 0) - return CY_AS_ERROR_SUCCESS; - - /* - * if the data received exceeds the size of the DMA buffer, - * clip the data to the size of the buffer. this can lead - * to losing some data, but is not different than doing - * non-packet reads on the other endpoints. - */ - if (dsize > dma_p->size - dma_p->offset) - dsize = dma_p->size - dma_p->offset; - - /* - * copy the data from the request packet to the DMA buffer - * for the endpoint - */ - src_p = (uint8_t *)data; - dest_p = ((uint8_t *)(dma_p->buf_p)) + dma_p->offset; - xfersize = dsize; - while (xfersize-- > 0) - *dest_p++ = *src_p++; - - /* Signal the DMA module that we have - * received data for this EP request */ - cy_as_dma_completed_callback(dev_p->tag, - ep, dsize, CY_AS_ERROR_SUCCESS); - - return CY_AS_ERROR_SUCCESS; -} diff --git a/drivers/staging/westbridge/astoria/api/src/cyasintr.c b/drivers/staging/westbridge/astoria/api/src/cyasintr.c deleted file mode 100644 index b60f69ce5985..000000000000 --- a/drivers/staging/westbridge/astoria/api/src/cyasintr.c +++ /dev/null @@ -1,143 +0,0 @@ -/* Cypress West Bridge API source file (cyasintr.c) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#include "../../include/linux/westbridge/cyashal.h" -#include "../../include/linux/westbridge/cyasdevice.h" -#include "../../include/linux/westbridge/cyasregs.h" -#include "../../include/linux/westbridge/cyaserr.h" - -extern void cy_as_mail_box_interrupt_handler(cy_as_device *); - -void -cy_as_mcu_interrupt_handler(cy_as_device *dev_p) -{ - /* Read and clear the interrupt. */ - uint16_t v; - - v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_MCU_STAT); - v = v; -} - -void -cy_as_power_management_interrupt_handler(cy_as_device *dev_p) -{ - uint16_t v; - - v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PWR_MAGT_STAT); - v = v; -} - -void -cy_as_pll_lock_loss_interrupt_handler(cy_as_device *dev_p) -{ - uint16_t v; - - v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PLL_LOCK_LOSS_STAT); - v = v; -} - -uint32_t cy_as_intr_start(cy_as_device *dev_p, cy_bool dmaintr) -{ - uint16_t v; - - cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE); - - if (cy_as_device_is_intr_running(dev_p) != 0) - return CY_AS_ERROR_ALREADY_RUNNING; - - v = CY_AS_MEM_P0_INT_MASK_REG_MMCUINT | - CY_AS_MEM_P0_INT_MASK_REG_MMBINT | - CY_AS_MEM_P0_INT_MASK_REG_MPMINT; - - if (dmaintr) - v |= CY_AS_MEM_P0_INT_MASK_REG_MDRQINT; - - /* Enable the interrupts of interest */ - cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_INT_MASK_REG, v); - - /* Mark the interrupt module as initialized */ - cy_as_device_set_intr_running(dev_p); - - return CY_AS_ERROR_SUCCESS; -} - -uint32_t cy_as_intr_stop(cy_as_device *dev_p) -{ - cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE); - - if (cy_as_device_is_intr_running(dev_p) == 0) - return CY_AS_ERROR_NOT_RUNNING; - - cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_INT_MASK_REG, 0); - cy_as_device_set_intr_stopped(dev_p); - - return CY_AS_ERROR_SUCCESS; -} - -void cy_as_intr_service_interrupt(cy_as_hal_device_tag tag) -{ - uint16_t v; - cy_as_device *dev_p; - - dev_p = cy_as_device_find_from_tag(tag); - - /* - * only power management interrupts can occur before the - * antioch API setup is complete. if this is a PM interrupt - * handle it here; otherwise output a warning message. - */ - if (dev_p == 0) { - v = cy_as_hal_read_register(tag, CY_AS_MEM_P0_INTR_REG); - if (v == CY_AS_MEM_P0_INTR_REG_PMINT) { - /* Read the PWR_MAGT_STAT register - * to clear this interrupt. */ - v = cy_as_hal_read_register(tag, - CY_AS_MEM_PWR_MAGT_STAT); - } else - cy_as_hal_print_message("stray antioch " - "interrupt detected" - ", tag not associated " - "with any created device."); - return; - } - - /* Make sure we got a valid object from CyAsDeviceFindFromTag */ - cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE); - - v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_INTR_REG); - - if (v & CY_AS_MEM_P0_INTR_REG_MCUINT) - cy_as_mcu_interrupt_handler(dev_p); - - if (v & CY_AS_MEM_P0_INTR_REG_PMINT) - cy_as_power_management_interrupt_handler(dev_p); - - if (v & CY_AS_MEM_P0_INTR_REG_PLLLOCKINT) - cy_as_pll_lock_loss_interrupt_handler(dev_p); - - /* If the interrupt module is not running, no mailbox - * interrupts are expected from the west bridge. */ - if (cy_as_device_is_intr_running(dev_p) == 0) - return; - - if (v & CY_AS_MEM_P0_INTR_REG_MBINT) - cy_as_mail_box_interrupt_handler(dev_p); -} diff --git a/drivers/staging/westbridge/astoria/api/src/cyaslep2pep.c b/drivers/staging/westbridge/astoria/api/src/cyaslep2pep.c deleted file mode 100644 index 76821e51b817..000000000000 --- a/drivers/staging/westbridge/astoria/api/src/cyaslep2pep.c +++ /dev/null @@ -1,358 +0,0 @@ -/* Cypress West Bridge API source file (cyaslep2pep.c) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#include "../../include/linux/westbridge/cyashal.h" -#include "../../include/linux/westbridge/cyasusb.h" -#include "../../include/linux/westbridge/cyaserr.h" -#include "../../include/linux/westbridge/cyaslowlevel.h" -#include "../../include/linux/westbridge/cyasdma.h" - -typedef enum cy_as_physical_endpoint_state { - cy_as_e_p_free, - cy_as_e_p_in, - cy_as_e_p_out, - cy_as_e_p_iso_in, - cy_as_e_p_iso_out -} cy_as_physical_endpoint_state; - - -/* -* This map is used to map an index between 1 and 10 -* to a logical endpoint number. This is used to map -* LEP register indexes into actual EP numbers. -*/ -static cy_as_end_point_number_t end_point_map[] = { - 3, 5, 7, 9, 10, 11, 12, 13, 14, 15 }; - -#define CY_AS_EPCFG_1024 (1 << 3) -#define CY_AS_EPCFG_DBL (0x02) -#define CY_AS_EPCFG_TRIPLE (0x03) -#define CY_AS_EPCFG_QUAD (0x00) - -/* - * NB: This table contains the register values for PEP1 - * and PEP3. PEP2 and PEP4 only have a bit to change the - * direction of the PEP and therefre are not represented - * in this table. - */ -static uint8_t pep_register_values[12][4] = { - /* Bit 1:0 buffering, 0 = quad, 2 = double, 3 = triple */ - /* Bit 3 size, 0 = 512, 1 = 1024 */ - { - CY_AS_EPCFG_DBL, - CY_AS_EPCFG_DBL, - },/* Config 1 - PEP1 (2 * 512), PEP2 (2 * 512), - * PEP3 (2 * 512), PEP4 (2 * 512) */ - { - CY_AS_EPCFG_DBL, - CY_AS_EPCFG_QUAD, - }, /* Config 2 - PEP1 (2 * 512), PEP2 (2 * 512), - * PEP3 (4 * 512), PEP4 (N/A) */ - { - CY_AS_EPCFG_DBL, - CY_AS_EPCFG_DBL | CY_AS_EPCFG_1024, - },/* Config 3 - PEP1 (2 * 512), PEP2 (2 * 512), - * PEP3 (2 * 1024), PEP4(N/A) */ - { - CY_AS_EPCFG_QUAD, - CY_AS_EPCFG_DBL, - },/* Config 4 - PEP1 (4 * 512), PEP2 (N/A), - * PEP3 (2 * 512), PEP4 (2 * 512) */ - { - CY_AS_EPCFG_QUAD, - CY_AS_EPCFG_QUAD, - },/* Config 5 - PEP1 (4 * 512), PEP2 (N/A), - * PEP3 (4 * 512), PEP4 (N/A) */ - { - CY_AS_EPCFG_QUAD, - CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL, - },/* Config 6 - PEP1 (4 * 512), PEP2 (N/A), - * PEP3 (2 * 1024), PEP4 (N/A) */ - { - CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL, - CY_AS_EPCFG_DBL, - },/* Config 7 - PEP1 (2 * 1024), PEP2 (N/A), - * PEP3 (2 * 512), PEP4 (2 * 512) */ - { - CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL, - CY_AS_EPCFG_QUAD, - },/* Config 8 - PEP1 (2 * 1024), PEP2 (N/A), - * PEP3 (4 * 512), PEP4 (N/A) */ - { - CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL, - CY_AS_EPCFG_1024 | CY_AS_EPCFG_DBL, - },/* Config 9 - PEP1 (2 * 1024), PEP2 (N/A), - * PEP3 (2 * 1024), PEP4 (N/A)*/ - { - CY_AS_EPCFG_TRIPLE, - CY_AS_EPCFG_TRIPLE, - },/* Config 10 - PEP1 (3 * 512), PEP2 (N/A), - * PEP3 (3 * 512), PEP4 (2 * 512)*/ - { - CY_AS_EPCFG_TRIPLE | CY_AS_EPCFG_1024, - CY_AS_EPCFG_DBL, - },/* Config 11 - PEP1 (3 * 1024), PEP2 (N/A), - * PEP3 (N/A), PEP4 (2 * 512) */ - { - CY_AS_EPCFG_QUAD | CY_AS_EPCFG_1024, - CY_AS_EPCFG_DBL, - },/* Config 12 - PEP1 (4 * 1024), PEP2 (N/A), - * PEP3 (N/A), PEP4 (N/A) */ -}; - -static cy_as_return_status_t -find_endpoint_directions(cy_as_device *dev_p, - cy_as_physical_endpoint_state epstate[4]) -{ - int i; - cy_as_physical_endpoint_state desired; - - /* - * note, there is no error checking here because - * ISO error checking happens when the API is called. - */ - for (i = 0; i < 10; i++) { - int epno = end_point_map[i]; - if (dev_p->usb_config[epno].enabled) { - int pep = dev_p->usb_config[epno].physical; - if (dev_p->usb_config[epno].type == cy_as_usb_iso) { - /* - * marking this as an ISO endpoint, removes the - * physical EP from consideration when - * mapping the remaining E_ps. - */ - if (dev_p->usb_config[epno].dir == cy_as_usb_in) - desired = cy_as_e_p_iso_in; - else - desired = cy_as_e_p_iso_out; - } else { - if (dev_p->usb_config[epno].dir == cy_as_usb_in) - desired = cy_as_e_p_in; - else - desired = cy_as_e_p_out; - } - - /* - * NB: Note the API calls insure that an ISO endpoint - * has a physical and logical EP number that are the - * same, therefore this condition is not enforced here. - */ - if (epstate[pep - 1] != - cy_as_e_p_free && epstate[pep - 1] != desired) - return CY_AS_ERROR_INVALID_CONFIGURATION; - - epstate[pep - 1] = desired; - } - } - - /* - * create the EP1 config values directly. - * both EP1OUT and EP1IN are invalid by default. - */ - dev_p->usb_ep1cfg[0] = 0; - dev_p->usb_ep1cfg[1] = 0; - if (dev_p->usb_config[1].enabled) { - if ((dev_p->usb_config[1].dir == cy_as_usb_out) || - (dev_p->usb_config[1].dir == cy_as_usb_in_out)) { - /* Set the valid bit and type field. */ - dev_p->usb_ep1cfg[0] = (1 << 7); - if (dev_p->usb_config[1].type == cy_as_usb_bulk) - dev_p->usb_ep1cfg[0] |= (2 << 4); - else - dev_p->usb_ep1cfg[0] |= (3 << 4); - } - - if ((dev_p->usb_config[1].dir == cy_as_usb_in) || - (dev_p->usb_config[1].dir == cy_as_usb_in_out)) { - /* Set the valid bit and type field. */ - dev_p->usb_ep1cfg[1] = (1 << 7); - if (dev_p->usb_config[1].type == cy_as_usb_bulk) - dev_p->usb_ep1cfg[1] |= (2 << 4); - else - dev_p->usb_ep1cfg[1] |= (3 << 4); - } - } - - return CY_AS_ERROR_SUCCESS; -} - -static void -create_register_settings(cy_as_device *dev_p, - cy_as_physical_endpoint_state epstate[4]) -{ - int i; - uint8_t v; - - for (i = 0; i < 4; i++) { - if (i == 0) { - /* Start with the values that specify size */ - dev_p->usb_pepcfg[i] = - pep_register_values - [dev_p->usb_phy_config - 1][0]; - } else if (i == 2) { - /* Start with the values that specify size */ - dev_p->usb_pepcfg[i] = - pep_register_values - [dev_p->usb_phy_config - 1][1]; - } else - dev_p->usb_pepcfg[i] = 0; - - /* Adjust direction if it is in */ - if (epstate[i] == cy_as_e_p_iso_in || - epstate[i] == cy_as_e_p_in) - dev_p->usb_pepcfg[i] |= (1 << 6); - } - - /* Configure the logical EP registers */ - for (i = 0; i < 10; i++) { - int val; - int epnum = end_point_map[i]; - - v = 0x10; /* PEP 1, Bulk Endpoint, EP not valid */ - if (dev_p->usb_config[epnum].enabled) { - v |= (1 << 7); /* Enabled */ - - val = dev_p->usb_config[epnum].physical - 1; - cy_as_hal_assert(val >= 0 && val <= 3); - v |= (val << 5); - - switch (dev_p->usb_config[epnum].type) { - case cy_as_usb_bulk: - val = 2; - break; - case cy_as_usb_int: - val = 3; - break; - case cy_as_usb_iso: - val = 1; - break; - default: - cy_as_hal_assert(cy_false); - break; - } - v |= (val << 3); - } - - dev_p->usb_lepcfg[i] = v; - } -} - - -cy_as_return_status_t -cy_as_usb_map_logical2_physical(cy_as_device *dev_p) -{ - cy_as_return_status_t ret; - - /* Physical EPs 3 5 7 9 respectively in the array */ - cy_as_physical_endpoint_state epstate[4] = { - cy_as_e_p_free, cy_as_e_p_free, - cy_as_e_p_free, cy_as_e_p_free }; - - /* Find the direction for the endpoints */ - ret = find_endpoint_directions(dev_p, epstate); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* - * now create the register settings based on the given - * assigned of logical E_ps to physical endpoints. - */ - create_register_settings(dev_p, epstate); - - return ret; -} - -static uint16_t -get_max_dma_size(cy_as_device *dev_p, cy_as_end_point_number_t ep) -{ - uint16_t size = dev_p->usb_config[ep].size; - - if (size == 0) { - switch (dev_p->usb_config[ep].type) { - case cy_as_usb_control: - size = 64; - break; - - case cy_as_usb_bulk: - size = cy_as_device_is_usb_high_speed(dev_p) ? - 512 : 64; - break; - - case cy_as_usb_int: - size = cy_as_device_is_usb_high_speed(dev_p) ? - 1024 : 64; - break; - - case cy_as_usb_iso: - size = cy_as_device_is_usb_high_speed(dev_p) ? - 1024 : 1023; - break; - } - } - - return size; -} - -cy_as_return_status_t -cy_as_usb_set_dma_sizes(cy_as_device *dev_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint32_t i; - - for (i = 0; i < 10; i++) { - cy_as_usb_end_point_config *config_p = - &dev_p->usb_config[end_point_map[i]]; - if (config_p->enabled) { - ret = cy_as_dma_set_max_dma_size(dev_p, - end_point_map[i], - get_max_dma_size(dev_p, end_point_map[i])); - if (ret != CY_AS_ERROR_SUCCESS) - break; - } - } - - return ret; -} - -cy_as_return_status_t -cy_as_usb_setup_dma(cy_as_device *dev_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint32_t i; - - for (i = 0; i < 10; i++) { - cy_as_usb_end_point_config *config_p = - &dev_p->usb_config[end_point_map[i]]; - if (config_p->enabled) { - /* Map the endpoint direction to the DMA direction */ - cy_as_dma_direction dir = cy_as_direction_out; - if (config_p->dir == cy_as_usb_in) - dir = cy_as_direction_in; - - ret = cy_as_dma_enable_end_point(dev_p, - end_point_map[i], cy_true, dir); - if (ret != CY_AS_ERROR_SUCCESS) - break; - } - } - - return ret; -} diff --git a/drivers/staging/westbridge/astoria/api/src/cyaslowlevel.c b/drivers/staging/westbridge/astoria/api/src/cyaslowlevel.c deleted file mode 100644 index 96a86d088305..000000000000 --- a/drivers/staging/westbridge/astoria/api/src/cyaslowlevel.c +++ /dev/null @@ -1,1264 +0,0 @@ -/* Cypress West Bridge API source file (cyaslowlevel.c) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#include "../../include/linux/westbridge/cyashal.h" -#include "../../include/linux/westbridge/cyascast.h" -#include "../../include/linux/westbridge/cyasdevice.h" -#include "../../include/linux/westbridge/cyaslowlevel.h" -#include "../../include/linux/westbridge/cyasintr.h" -#include "../../include/linux/westbridge/cyaserr.h" -#include "../../include/linux/westbridge/cyasregs.h" - -static const uint32_t cy_as_low_level_timeout_count = 65536 * 4; - -/* Forward declaration */ -static cy_as_return_status_t cy_as_send_one(cy_as_device *dev_p, - cy_as_ll_request_response *req_p); - -/* -* This array holds the size of the largest request we will ever recevie from -* the West Bridge device per context. The size is in 16 bit words. Note a -* size of 0xffff indicates that there will be no requests on this context -* from West Bridge. -*/ -static uint16_t max_request_length[CY_RQT_CONTEXT_COUNT] = { - 8, /* CY_RQT_GENERAL_RQT_CONTEXT - CY_RQT_INITIALIZATION_COMPLETE */ - 8, /* CY_RQT_RESOURCE_RQT_CONTEXT - none */ - 8, /* CY_RQT_STORAGE_RQT_CONTEXT - CY_RQT_MEDIA_CHANGED */ - 128, /* CY_RQT_USB_RQT_CONTEXT - CY_RQT_USB_EVENT */ - 8 /* CY_RQT_TUR_RQT_CONTEXT - CY_RQT_TURBO_CMD_FROM_HOST */ -}; - -/* -* For the given context, this function removes the request node at the head -* of the queue from the context. This is called after all processing has -* occurred on the given request and response and we are ready to remove this -* entry from the queue. -*/ -static void -cy_as_ll_remove_request_queue_head(cy_as_device *dev_p, cy_as_context *ctxt_p) -{ - uint32_t mask, state; - cy_as_ll_request_list_node *node_p; - - (void)dev_p; - cy_as_hal_assert(ctxt_p->request_queue_p != 0); - - mask = cy_as_hal_disable_interrupts(); - node_p = ctxt_p->request_queue_p; - ctxt_p->request_queue_p = node_p->next; - cy_as_hal_enable_interrupts(mask); - - node_p->callback = 0; - node_p->rqt = 0; - node_p->resp = 0; - - /* - * note that the caller allocates and destroys the request and - * response. generally the destroy happens in the callback for - * async requests and after the wait returns for sync. the - * request and response may not actually be destroyed but may be - * managed in other ways as well. it is the responsibilty of - * the caller to deal with these in any case. the caller can do - * this in the request/response callback function. - */ - state = cy_as_hal_disable_interrupts(); - cy_as_hal_c_b_free(node_p); - cy_as_hal_enable_interrupts(state); -} - -/* -* For the context given, this function sends the next request to -* West Bridge via the mailbox register, if the next request is -* ready to be sent and has not already been sent. -*/ -static void -cy_as_ll_send_next_request(cy_as_device *dev_p, cy_as_context *ctxt_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - /* - * ret == ret is equivalent to while (1) but eliminates compiler - * warnings for some compilers. - */ - while (ret == ret) { - cy_as_ll_request_list_node *node_p = ctxt_p->request_queue_p; - if (node_p == 0) - break; - - if (cy_as_request_get_node_state(node_p) != - CY_AS_REQUEST_LIST_STATE_QUEUED) - break; - - cy_as_request_set_node_state(node_p, - CY_AS_REQUEST_LIST_STATE_WAITING); - ret = cy_as_send_one(dev_p, node_p->rqt); - if (ret == CY_AS_ERROR_SUCCESS) - break; - - /* - * if an error occurs in sending the request, tell the requester - * about the error and remove the request from the queue. - */ - cy_as_request_set_node_state(node_p, - CY_AS_REQUEST_LIST_STATE_RECEIVED); - node_p->callback(dev_p, ctxt_p->number, - node_p->rqt, node_p->resp, ret); - cy_as_ll_remove_request_queue_head(dev_p, ctxt_p); - - /* - * this falls through to the while loop to send the next request - * since the previous request did not get sent. - */ - } -} - -/* -* This method removes an entry from the request queue of a given context. -* The entry is removed only if it is not in transit. -*/ -cy_as_remove_request_result_t -cy_as_ll_remove_request(cy_as_device *dev_p, cy_as_context *ctxt_p, - cy_as_ll_request_response *req_p, cy_bool force) -{ - uint32_t imask; - cy_as_ll_request_list_node *node_p; - cy_as_ll_request_list_node *tmp_p; - uint32_t state; - - imask = cy_as_hal_disable_interrupts(); - if (ctxt_p->request_queue_p != 0 && - ctxt_p->request_queue_p->rqt == req_p) { - node_p = ctxt_p->request_queue_p; - if ((cy_as_request_get_node_state(node_p) == - CY_AS_REQUEST_LIST_STATE_WAITING) && (!force)) { - cy_as_hal_enable_interrupts(imask); - return cy_as_remove_request_in_transit; - } - - ctxt_p->request_queue_p = node_p->next; - } else { - tmp_p = ctxt_p->request_queue_p; - while (tmp_p != 0 && tmp_p->next != 0 && - tmp_p->next->rqt != req_p) - tmp_p = tmp_p->next; - - if (tmp_p == 0 || tmp_p->next == 0) { - cy_as_hal_enable_interrupts(imask); - return cy_as_remove_request_not_found; - } - - node_p = tmp_p->next; - tmp_p->next = node_p->next; - } - - if (node_p->callback) - node_p->callback(dev_p, ctxt_p->number, node_p->rqt, - node_p->resp, CY_AS_ERROR_CANCELED); - - state = cy_as_hal_disable_interrupts(); - cy_as_hal_c_b_free(node_p); - cy_as_hal_enable_interrupts(state); - - cy_as_hal_enable_interrupts(imask); - return cy_as_remove_request_sucessful; -} - -void -cy_as_ll_remove_all_requests(cy_as_device *dev_p, cy_as_context *ctxt_p) -{ - cy_as_ll_request_list_node *node = ctxt_p->request_queue_p; - - while (node) { - if (cy_as_request_get_node_state(ctxt_p->request_queue_p) != - CY_AS_REQUEST_LIST_STATE_RECEIVED) - cy_as_ll_remove_request(dev_p, ctxt_p, - node->rqt, cy_true); - node = node->next; - } -} - -static cy_bool -cy_as_ll_is_in_queue(cy_as_context *ctxt_p, cy_as_ll_request_response *req_p) -{ - uint32_t mask; - cy_as_ll_request_list_node *node_p; - - mask = cy_as_hal_disable_interrupts(); - node_p = ctxt_p->request_queue_p; - while (node_p) { - if (node_p->rqt == req_p) { - cy_as_hal_enable_interrupts(mask); - return cy_true; - } - node_p = node_p->next; - } - cy_as_hal_enable_interrupts(mask); - return cy_false; -} - -/* -* This is the handler for mailbox data when we are trying to send data -* to the West Bridge firmware. The firmware may be trying to send us -* data and we need to queue this data to allow the firmware to move -* forward and be in a state to receive our request. Here we just queue -* the data and it is processed at a later time by the mailbox interrupt -* handler. -*/ -void -cy_as_ll_queue_mailbox_data(cy_as_device *dev_p) -{ - cy_as_context *ctxt_p; - uint8_t context; - uint16_t data[4]; - int32_t i; - - /* Read the data from mailbox 0 to determine what to do with the data */ - for (i = 3; i >= 0; i--) - data[i] = cy_as_hal_read_register(dev_p->tag, - cy_cast_int2U_int16(CY_AS_MEM_P0_MAILBOX0 + i)); - - context = cy_as_mbox_get_context(data[0]); - if (context >= CY_RQT_CONTEXT_COUNT) { - cy_as_hal_print_message("mailbox request/response received " - "with invalid context value (%d)\n", context); - return; - } - - ctxt_p = dev_p->context[context]; - - /* - * if we have queued too much data, drop future data. - */ - cy_as_hal_assert(ctxt_p->queue_index * sizeof(uint16_t) + - sizeof(data) <= sizeof(ctxt_p->data_queue)); - - for (i = 0; i < 4; i++) - ctxt_p->data_queue[ctxt_p->queue_index++] = data[i]; - - cy_as_hal_assert((ctxt_p->queue_index % 4) == 0); - dev_p->ll_queued_data = cy_true; -} - -void -cy_as_mail_box_process_data(cy_as_device *dev_p, uint16_t *data) -{ - cy_as_context *ctxt_p; - uint8_t context; - uint16_t *len_p; - cy_as_ll_request_response *rec_p; - uint8_t st; - uint16_t src, dest; - - context = cy_as_mbox_get_context(data[0]); - if (context >= CY_RQT_CONTEXT_COUNT) { - cy_as_hal_print_message("mailbox request/response received " - "with invalid context value (%d)\n", context); - return; - } - - ctxt_p = dev_p->context[context]; - - if (cy_as_mbox_is_request(data[0])) { - cy_as_hal_assert(ctxt_p->req_p != 0); - rec_p = ctxt_p->req_p; - len_p = &ctxt_p->request_length; - - } else { - if (ctxt_p->request_queue_p == 0 || - cy_as_request_get_node_state(ctxt_p->request_queue_p) - != CY_AS_REQUEST_LIST_STATE_WAITING) { - cy_as_hal_print_message("mailbox response received on " - "context that was not expecting a response\n"); - cy_as_hal_print_message(" context: %d\n", context); - cy_as_hal_print_message(" contents: 0x%04x 0x%04x " - "0x%04x 0x%04x\n", - data[0], data[1], data[2], data[3]); - if (ctxt_p->request_queue_p != 0) - cy_as_hal_print_message(" state: 0x%02x\n", - ctxt_p->request_queue_p->state); - return; - } - - /* Make sure the request has an associated response */ - cy_as_hal_assert(ctxt_p->request_queue_p->resp != 0); - - rec_p = ctxt_p->request_queue_p->resp; - len_p = &ctxt_p->request_queue_p->length; - } - - if (rec_p->stored == 0) { - /* - * this is the first cycle of the response - */ - cy_as_ll_request_response__set_code(rec_p, - cy_as_mbox_get_code(data[0])); - cy_as_ll_request_response__set_context(rec_p, context); - - if (cy_as_mbox_is_last(data[0])) { - /* This is a single cycle response */ - *len_p = rec_p->length; - st = 1; - } else { - /* Ensure that enough memory has been - * reserved for the response. */ - cy_as_hal_assert(rec_p->length >= data[1]); - *len_p = (data[1] < rec_p->length) ? - data[1] : rec_p->length; - st = 2; - } - } else - st = 1; - - /* Trasnfer the data from the mailboxes to the response */ - while (rec_p->stored < *len_p && st < 4) - rec_p->data[rec_p->stored++] = data[st++]; - - if (cy_as_mbox_is_last(data[0])) { - /* NB: The call-back that is made below can cause the - * addition of more data in this queue, thus causing - * a recursive overflow of the queue. this is prevented - * by removing the request entry that is currently - * being passed up from the data queue. if this is done, - * the queue only needs to be as long as two request - * entries from west bridge. - */ - if ((ctxt_p->rqt_index > 0) && - (ctxt_p->rqt_index <= ctxt_p->queue_index)) { - dest = 0; - src = ctxt_p->rqt_index; - - while (src < ctxt_p->queue_index) - ctxt_p->data_queue[dest++] = - ctxt_p->data_queue[src++]; - - ctxt_p->rqt_index = 0; - ctxt_p->queue_index = dest; - cy_as_hal_assert((ctxt_p->queue_index % 4) == 0); - } - - if (ctxt_p->request_queue_p != 0 && rec_p == - ctxt_p->request_queue_p->resp) { - /* - * if this is the last cycle of the response, call the - * callback and reset for the next response. - */ - cy_as_ll_request_response *resp_p = - ctxt_p->request_queue_p->resp; - resp_p->length = ctxt_p->request_queue_p->length; - cy_as_request_set_node_state(ctxt_p->request_queue_p, - CY_AS_REQUEST_LIST_STATE_RECEIVED); - - cy_as_device_set_in_callback(dev_p); - ctxt_p->request_queue_p->callback(dev_p, context, - ctxt_p->request_queue_p->rqt, - resp_p, CY_AS_ERROR_SUCCESS); - - cy_as_device_clear_in_callback(dev_p); - - cy_as_ll_remove_request_queue_head(dev_p, ctxt_p); - cy_as_ll_send_next_request(dev_p, ctxt_p); - } else { - /* Send the request to the appropriate - * module to handle */ - cy_as_ll_request_response *request_p = ctxt_p->req_p; - ctxt_p->req_p = 0; - if (ctxt_p->request_callback) { - cy_as_device_set_in_callback(dev_p); - ctxt_p->request_callback(dev_p, context, - request_p, 0, CY_AS_ERROR_SUCCESS); - cy_as_device_clear_in_callback(dev_p); - } - cy_as_ll_init_request(request_p, 0, - context, request_p->length); - ctxt_p->req_p = request_p; - } - } -} - -/* -* This is the handler for processing queued mailbox data -*/ -void -cy_as_mail_box_queued_data_handler(cy_as_device *dev_p) -{ - uint16_t i; - - /* - * if more data gets queued in between our entering this call - * and the end of the iteration on all contexts; we should - * continue processing the queued data. - */ - while (dev_p->ll_queued_data) { - dev_p->ll_queued_data = cy_false; - for (i = 0; i < CY_RQT_CONTEXT_COUNT; i++) { - uint16_t offset; - cy_as_context *ctxt_p = dev_p->context[i]; - cy_as_hal_assert((ctxt_p->queue_index % 4) == 0); - - offset = 0; - while (offset < ctxt_p->queue_index) { - ctxt_p->rqt_index = offset + 4; - cy_as_mail_box_process_data(dev_p, - ctxt_p->data_queue + offset); - offset = ctxt_p->rqt_index; - } - ctxt_p->queue_index = 0; - } - } -} - -/* -* This is the handler for the mailbox interrupt. This function reads -* data from the mailbox registers until a complete request or response -* is received. When a complete request is received, the callback -* associated with requests on that context is called. When a complete -* response is recevied, the callback associated with the request that -* generated the response is called. -*/ -void -cy_as_mail_box_interrupt_handler(cy_as_device *dev_p) -{ - cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE); - - /* - * queue the mailbox data to preserve - * order for later processing. - */ - cy_as_ll_queue_mailbox_data(dev_p); - - /* - * process what was queued and anything that may be pending - */ - cy_as_mail_box_queued_data_handler(dev_p); -} - -cy_as_return_status_t -cy_as_ll_start(cy_as_device *dev_p) -{ - uint16_t i; - - if (cy_as_device_is_low_level_running(dev_p)) - return CY_AS_ERROR_ALREADY_RUNNING; - - dev_p->ll_sending_rqt = cy_false; - dev_p->ll_abort_curr_rqt = cy_false; - - for (i = 0; i < CY_RQT_CONTEXT_COUNT; i++) { - dev_p->context[i] = (cy_as_context *) - cy_as_hal_alloc(sizeof(cy_as_context)); - if (dev_p->context[i] == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - dev_p->context[i]->number = (uint8_t)i; - dev_p->context[i]->request_callback = 0; - dev_p->context[i]->request_queue_p = 0; - dev_p->context[i]->last_node_p = 0; - dev_p->context[i]->req_p = cy_as_ll_create_request(dev_p, - 0, (uint8_t)i, max_request_length[i]); - dev_p->context[i]->queue_index = 0; - - if (!cy_as_hal_create_sleep_channel - (&dev_p->context[i]->channel)) - return CY_AS_ERROR_CREATE_SLEEP_CHANNEL_FAILED; - } - - cy_as_device_set_low_level_running(dev_p); - return CY_AS_ERROR_SUCCESS; -} - -/* -* Shutdown the low level communications module. This operation will -* also cancel any queued low level requests. -*/ -cy_as_return_status_t -cy_as_ll_stop(cy_as_device *dev_p) -{ - uint8_t i; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_context *ctxt_p; - uint32_t mask; - - for (i = 0; i < CY_RQT_CONTEXT_COUNT; i++) { - ctxt_p = dev_p->context[i]; - if (!cy_as_hal_destroy_sleep_channel(&ctxt_p->channel)) - return CY_AS_ERROR_DESTROY_SLEEP_CHANNEL_FAILED; - - /* - * now, free any queued requests and assocaited responses - */ - while (ctxt_p->request_queue_p) { - uint32_t state; - cy_as_ll_request_list_node *node_p = - ctxt_p->request_queue_p; - - /* Mark this pair as in a cancel operation */ - cy_as_request_set_node_state(node_p, - CY_AS_REQUEST_LIST_STATE_CANCELING); - - /* Tell the caller that we are canceling this request */ - /* NB: The callback is responsible for destroying the - * request and the response. we cannot count on the - * contents of these two after calling the callback. - */ - node_p->callback(dev_p, i, node_p->rqt, - node_p->resp, CY_AS_ERROR_CANCELED); - - /* Remove the pair from the queue */ - mask = cy_as_hal_disable_interrupts(); - ctxt_p->request_queue_p = node_p->next; - cy_as_hal_enable_interrupts(mask); - - /* Free the list node */ - state = cy_as_hal_disable_interrupts(); - cy_as_hal_c_b_free(node_p); - cy_as_hal_enable_interrupts(state); - } - - cy_as_ll_destroy_request(dev_p, dev_p->context[i]->req_p); - cy_as_hal_free(dev_p->context[i]); - dev_p->context[i] = 0; - - } - cy_as_device_set_low_level_stopped(dev_p); - - return ret; -} - -void -cy_as_ll_init_request(cy_as_ll_request_response *req_p, - uint16_t code, uint16_t context, uint16_t length) -{ - uint16_t totallen = sizeof(cy_as_ll_request_response) + - (length - 1) * sizeof(uint16_t); - - cy_as_hal_mem_set(req_p, 0, totallen); - req_p->length = length; - cy_as_ll_request_response__set_code(req_p, code); - cy_as_ll_request_response__set_context(req_p, context); - cy_as_ll_request_response__set_request(req_p); -} - -/* -* Create a new request. -*/ -cy_as_ll_request_response * -cy_as_ll_create_request(cy_as_device *dev_p, uint16_t code, - uint8_t context, uint16_t length) -{ - cy_as_ll_request_response *req_p; - uint32_t state; - uint16_t totallen = sizeof(cy_as_ll_request_response) + - (length - 1) * sizeof(uint16_t); - - (void)dev_p; - - state = cy_as_hal_disable_interrupts(); - req_p = cy_as_hal_c_b_alloc(totallen); - cy_as_hal_enable_interrupts(state); - if (req_p) - cy_as_ll_init_request(req_p, code, context, length); - - return req_p; -} - -/* -* Destroy a request. -*/ -void -cy_as_ll_destroy_request(cy_as_device *dev_p, cy_as_ll_request_response *req_p) -{ - uint32_t state; - (void)dev_p; - (void)req_p; - - state = cy_as_hal_disable_interrupts(); - cy_as_hal_c_b_free(req_p); - cy_as_hal_enable_interrupts(state); - -} - -void -cy_as_ll_init_response(cy_as_ll_request_response *req_p, uint16_t length) -{ - uint16_t totallen = sizeof(cy_as_ll_request_response) + - (length - 1) * sizeof(uint16_t); - - cy_as_hal_mem_set(req_p, 0, totallen); - req_p->length = length; - cy_as_ll_request_response__set_response(req_p); -} - -/* -* Create a new response -*/ -cy_as_ll_request_response * -cy_as_ll_create_response(cy_as_device *dev_p, uint16_t length) -{ - cy_as_ll_request_response *req_p; - uint32_t state; - uint16_t totallen = sizeof(cy_as_ll_request_response) + - (length - 1) * sizeof(uint16_t); - - (void)dev_p; - - state = cy_as_hal_disable_interrupts(); - req_p = cy_as_hal_c_b_alloc(totallen); - cy_as_hal_enable_interrupts(state); - if (req_p) - cy_as_ll_init_response(req_p, length); - - return req_p; -} - -/* -* Destroy the new response -*/ -void -cy_as_ll_destroy_response(cy_as_device *dev_p, cy_as_ll_request_response *req_p) -{ - uint32_t state; - (void)dev_p; - (void)req_p; - - state = cy_as_hal_disable_interrupts(); - cy_as_hal_c_b_free(req_p); - cy_as_hal_enable_interrupts(state); -} - -static uint16_t -cy_as_read_intr_status( - cy_as_device *dev_p) -{ - uint32_t mask; - cy_bool bloop = cy_true; - uint16_t v = 0, last = 0xffff; - - /* - * before determining if the mailboxes are ready for more data, - * we first check the mailbox interrupt to see if we need to - * receive data. this prevents a dead-lock condition that can - * occur when both sides are trying to receive data. - */ - while (last == last) { - /* - * disable interrupts to be sure we don't process the mailbox - * here and have the interrupt routine try to read this data - * as well. - */ - mask = cy_as_hal_disable_interrupts(); - - /* - * see if there is data to be read. - */ - v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_INTR_REG); - if ((v & CY_AS_MEM_P0_INTR_REG_MBINT) == 0) { - cy_as_hal_enable_interrupts(mask); - break; - } - - /* - * queue the mailbox data for later processing. - * this allows the firmware to move forward and - * service the requst from the P port. - */ - cy_as_ll_queue_mailbox_data(dev_p); - - /* - * enable interrupts again to service mailbox - * interrupts appropriately - */ - cy_as_hal_enable_interrupts(mask); - } - - /* - * now, all data is received - */ - last = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_MCU_MB_STAT) & CY_AS_MEM_P0_MCU_MBNOTRD; - while (bloop) { - v = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_MCU_MB_STAT) & CY_AS_MEM_P0_MCU_MBNOTRD; - if (v == last) - break; - - last = v; - } - - return v; -} - -/* -* Send a single request or response using the mail box register. -* This function does not deal with the internal queues at all, -* but only sends the request or response across to the firmware -*/ -static cy_as_return_status_t -cy_as_send_one( - cy_as_device *dev_p, - cy_as_ll_request_response *req_p) -{ - int i; - uint16_t mb0, v; - int32_t loopcount; - uint32_t int_stat; - -#ifdef _DEBUG - if (cy_as_ll_request_response__is_request(req_p)) { - switch (cy_as_ll_request_response__get_context(req_p)) { - case CY_RQT_GENERAL_RQT_CONTEXT: - cy_as_hal_assert(req_p->length * 2 + 2 < - CY_CTX_GEN_MAX_DATA_SIZE); - break; - - case CY_RQT_RESOURCE_RQT_CONTEXT: - cy_as_hal_assert(req_p->length * 2 + 2 < - CY_CTX_RES_MAX_DATA_SIZE); - break; - - case CY_RQT_STORAGE_RQT_CONTEXT: - cy_as_hal_assert(req_p->length * 2 + 2 < - CY_CTX_STR_MAX_DATA_SIZE); - break; - - case CY_RQT_USB_RQT_CONTEXT: - cy_as_hal_assert(req_p->length * 2 + 2 < - CY_CTX_USB_MAX_DATA_SIZE); - break; - } - } -#endif - - /* Write the request to the mail box registers */ - if (req_p->length > 3) { - uint16_t length = req_p->length; - int which = 0; - int st = 1; - - dev_p->ll_sending_rqt = cy_true; - while (which < length) { - loopcount = cy_as_low_level_timeout_count; - do { - v = cy_as_read_intr_status(dev_p); - - } while (v && loopcount-- > 0); - - if (v) { - cy_as_hal_print_message( - ">>>>>> LOW LEVEL TIMEOUT " - "%x %x %x %x\n", - cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_MCU_MAILBOX0), - cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_MCU_MAILBOX1), - cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_MCU_MAILBOX2), - cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_MCU_MAILBOX3)); - return CY_AS_ERROR_TIMEOUT; - } - - if (dev_p->ll_abort_curr_rqt) { - dev_p->ll_sending_rqt = cy_false; - dev_p->ll_abort_curr_rqt = cy_false; - return CY_AS_ERROR_CANCELED; - } - - int_stat = cy_as_hal_disable_interrupts(); - - /* - * check again whether the mailbox is free. - * it is possible that an ISR came in and - * wrote into the mailboxes since we last - * checked the status. - */ - v = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_MCU_MB_STAT) & - CY_AS_MEM_P0_MCU_MBNOTRD; - if (v) { - /* Go back to the original check since - * the mailbox is not free. */ - cy_as_hal_enable_interrupts(int_stat); - continue; - } - - if (which == 0) { - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_MCU_MAILBOX1, length); - st = 2; - } else { - st = 1; - } - - while ((which < length) && (st < 4)) { - cy_as_hal_write_register(dev_p->tag, - cy_cast_int2U_int16 - (CY_AS_MEM_MCU_MAILBOX0 + st), - req_p->data[which++]); - st++; - } - - mb0 = req_p->box0; - if (which == length) { - dev_p->ll_sending_rqt = cy_false; - mb0 |= CY_AS_REQUEST_RESPONSE_LAST_MASK; - } - - if (dev_p->ll_abort_curr_rqt) { - dev_p->ll_sending_rqt = cy_false; - dev_p->ll_abort_curr_rqt = cy_false; - cy_as_hal_enable_interrupts(int_stat); - return CY_AS_ERROR_CANCELED; - } - - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_MCU_MAILBOX0, mb0); - - /* Wait for the MBOX interrupt to be high */ - cy_as_hal_sleep150(); - cy_as_hal_enable_interrupts(int_stat); - } - } else { -check_mailbox_availability: - /* - * wait for the mailbox registers to become available. this - * should be a very quick wait as the firmware is designed - * to accept requests at interrupt time and queue them for - * future processing. - */ - loopcount = cy_as_low_level_timeout_count; - do { - v = cy_as_read_intr_status(dev_p); - - } while (v && loopcount-- > 0); - - if (v) { - cy_as_hal_print_message( - ">>>>>> LOW LEVEL TIMEOUT %x %x %x %x\n", - cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_MCU_MAILBOX0), - cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_MCU_MAILBOX1), - cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_MCU_MAILBOX2), - cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_MCU_MAILBOX3)); - return CY_AS_ERROR_TIMEOUT; - } - - int_stat = cy_as_hal_disable_interrupts(); - - /* - * check again whether the mailbox is free. it is - * possible that an ISR came in and wrote into the - * mailboxes since we last checked the status. - */ - v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_MCU_MB_STAT) & - CY_AS_MEM_P0_MCU_MBNOTRD; - if (v) { - /* Go back to the original check - * since the mailbox is not free. */ - cy_as_hal_enable_interrupts(int_stat); - goto check_mailbox_availability; - } - - /* Write the data associated with the request - * into the mbox registers 1 - 3 */ - v = 0; - for (i = req_p->length - 1; i >= 0; i--) - cy_as_hal_write_register(dev_p->tag, - cy_cast_int2U_int16(CY_AS_MEM_MCU_MAILBOX1 + i), - req_p->data[i]); - - /* Write the mbox register 0 to trigger the interrupt */ - cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_MCU_MAILBOX0, - req_p->box0 | CY_AS_REQUEST_RESPONSE_LAST_MASK); - - cy_as_hal_sleep150(); - cy_as_hal_enable_interrupts(int_stat); - } - - return CY_AS_ERROR_SUCCESS; -} - -/* -* This function queues a single request to be sent to the firmware. -*/ -extern cy_as_return_status_t -cy_as_ll_send_request( - cy_as_device *dev_p, - /* The request to send */ - cy_as_ll_request_response *req, - /* Storage for a reply, must be sure - * it is of sufficient size */ - cy_as_ll_request_response *resp, - /* If true, this is a synchronous request */ - cy_bool sync, - /* Callback to call when reply is received */ - cy_as_response_callback cb -) -{ - cy_as_context *ctxt_p; - uint16_t box0 = req->box0; - uint8_t context; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_ll_request_list_node *node_p; - uint32_t mask, state; - - cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE); - - context = cy_as_mbox_get_context(box0); - cy_as_hal_assert(context < CY_RQT_CONTEXT_COUNT); - ctxt_p = dev_p->context[context]; - - /* Allocate the list node */ - state = cy_as_hal_disable_interrupts(); - node_p = cy_as_hal_c_b_alloc(sizeof(cy_as_ll_request_list_node)); - cy_as_hal_enable_interrupts(state); - - if (node_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* Initialize the list node */ - node_p->callback = cb; - node_p->length = 0; - node_p->next = 0; - node_p->resp = resp; - node_p->rqt = req; - node_p->state = CY_AS_REQUEST_LIST_STATE_QUEUED; - if (sync) - cy_as_request_node_set_sync(node_p); - - /* Put the request into the queue */ - mask = cy_as_hal_disable_interrupts(); - if (ctxt_p->request_queue_p == 0) { - /* Empty queue */ - ctxt_p->request_queue_p = node_p; - ctxt_p->last_node_p = node_p; - } else { - ctxt_p->last_node_p->next = node_p; - ctxt_p->last_node_p = node_p; - } - cy_as_hal_enable_interrupts(mask); - cy_as_ll_send_next_request(dev_p, ctxt_p); - - if (!cy_as_device_is_in_callback(dev_p)) { - mask = cy_as_hal_disable_interrupts(); - cy_as_mail_box_queued_data_handler(dev_p); - cy_as_hal_enable_interrupts(mask); - } - - return ret; -} - -static void -cy_as_ll_send_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t ret) -{ - (void)rqt; - (void)resp; - (void)ret; - - - cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE); - - /* - * storage the state to return to the caller - */ - dev_p->ll_error = ret; - - /* - * now wake the caller - */ - cy_as_hal_wake(&dev_p->context[context]->channel); -} - -cy_as_return_status_t -cy_as_ll_send_request_wait_reply( - cy_as_device *dev_p, - /* The request to send */ - cy_as_ll_request_response *req, - /* Storage for a reply, must be - * sure it is of sufficient size */ - cy_as_ll_request_response *resp - ) -{ - cy_as_return_status_t ret; - uint8_t context; - /* Larger 8 sec time-out to handle the init - * delay for slower storage devices in USB FS. */ - uint32_t loopcount = 800; - cy_as_context *ctxt_p; - - /* Get the context for the request */ - context = cy_as_ll_request_response__get_context(req); - cy_as_hal_assert(context < CY_RQT_CONTEXT_COUNT); - ctxt_p = dev_p->context[context]; - - ret = cy_as_ll_send_request(dev_p, req, resp, - cy_true, cy_as_ll_send_callback); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - while (loopcount-- > 0) { - /* - * sleep while we wait on the response. receiving the reply will - * wake this thread. we will wait, at most 2 seconds (10 ms*200 - * tries) before we timeout. note if the reply arrives, we will - * not sleep the entire 10 ms, just til the reply arrives. - */ - cy_as_hal_sleep_on(&ctxt_p->channel, 10); - - /* - * if the request has left the queue, it means the request has - * been sent and the reply has been received. this means we can - * return to the caller and be sure the reply has been received. - */ - if (!cy_as_ll_is_in_queue(ctxt_p, req)) - return dev_p->ll_error; - } - - /* Remove the QueueListNode for this request. */ - cy_as_ll_remove_request(dev_p, ctxt_p, req, cy_true); - - return CY_AS_ERROR_TIMEOUT; -} - -cy_as_return_status_t -cy_as_ll_register_request_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_response_callback cb) -{ - cy_as_context *ctxt_p; - cy_as_hal_assert(context < CY_RQT_CONTEXT_COUNT); - ctxt_p = dev_p->context[context]; - - ctxt_p->request_callback = cb; - return CY_AS_ERROR_SUCCESS; -} - -void -cy_as_ll_request_response__pack( - cy_as_ll_request_response *req_p, - uint32_t offset, - uint32_t length, - void *data_p) -{ - uint16_t dt; - uint8_t *dp = (uint8_t *)data_p; - - while (length > 1) { - dt = ((*dp++) << 8); - dt |= (*dp++); - cy_as_ll_request_response__set_word(req_p, offset, dt); - offset++; - length -= 2; - } - - if (length == 1) { - dt = (*dp << 8); - cy_as_ll_request_response__set_word(req_p, offset, dt); - } -} - -void -cy_as_ll_request_response__unpack( - cy_as_ll_request_response *req_p, - uint32_t offset, - uint32_t length, - void *data_p) -{ - uint8_t *dp = (uint8_t *)data_p; - - while (length-- > 0) { - uint16_t val = cy_as_ll_request_response__get_word - (req_p, offset++); - *dp++ = (uint8_t)((val >> 8) & 0xff); - - if (length) { - length--; - *dp++ = (uint8_t)(val & 0xff); - } - } -} - -extern cy_as_return_status_t -cy_as_ll_send_status_response( - cy_as_device *dev_p, - uint8_t context, - uint16_t code, - uint8_t clear_storage) -{ - cy_as_return_status_t ret; - cy_as_ll_request_response resp; - cy_as_ll_request_response *resp_p = &resp; - - cy_as_hal_mem_set(resp_p, 0, sizeof(resp)); - resp_p->length = 1; - cy_as_ll_request_response__set_response(resp_p); - cy_as_ll_request_response__set_context(resp_p, context); - - if (clear_storage) - cy_as_ll_request_response__set_clear_storage_flag(resp_p); - - cy_as_ll_request_response__set_code(resp_p, CY_RESP_SUCCESS_FAILURE); - cy_as_ll_request_response__set_word(resp_p, 0, code); - - ret = cy_as_send_one(dev_p, resp_p); - - return ret; -} - -extern cy_as_return_status_t -cy_as_ll_send_data_response( - cy_as_device *dev_p, - uint8_t context, - uint16_t code, - uint16_t length, - void *data) -{ - cy_as_ll_request_response *resp_p; - uint16_t wlen; - uint8_t respbuf[256]; - - if (length > 192) - return CY_AS_ERROR_INVALID_SIZE; - - /* Word length for bytes */ - wlen = length / 2; - - /* If byte length odd, add one more */ - if (length % 2) - wlen++; - - /* One for the length of field */ - wlen++; - - resp_p = (cy_as_ll_request_response *)respbuf; - cy_as_hal_mem_set(resp_p, 0, sizeof(respbuf)); - resp_p->length = wlen; - cy_as_ll_request_response__set_context(resp_p, context); - cy_as_ll_request_response__set_code(resp_p, code); - - cy_as_ll_request_response__set_word(resp_p, 0, length); - cy_as_ll_request_response__pack(resp_p, 1, length, data); - - return cy_as_send_one(dev_p, resp_p); -} - -static cy_bool -cy_as_ll_is_e_p_transfer_related_request(cy_as_ll_request_response *rqt_p, - cy_as_end_point_number_t ep) -{ - uint16_t v; - uint8_t type = cy_as_ll_request_response__get_code(rqt_p); - - if (cy_as_ll_request_response__get_context(rqt_p) != - CY_RQT_USB_RQT_CONTEXT) - return cy_false; - - /* - * when cancelling outstanding EP0 data transfers, any pending - * setup ACK requests also need to be cancelled. - */ - if ((ep == 0) && (type == CY_RQT_ACK_SETUP_PACKET)) - return cy_true; - - if (type != CY_RQT_USB_EP_DATA) - return cy_false; - - v = cy_as_ll_request_response__get_word(rqt_p, 0); - if ((cy_as_end_point_number_t)((v >> 13) & 1) != ep) - return cy_false; - - return cy_true; -} - -cy_as_return_status_t -cy_as_ll_remove_ep_data_requests(cy_as_device *dev_p, - cy_as_end_point_number_t ep) -{ - cy_as_context *ctxt_p; - cy_as_ll_request_list_node *node_p; - uint32_t imask; - - /* - * first, remove any queued requests - */ - ctxt_p = dev_p->context[CY_RQT_USB_RQT_CONTEXT]; - if (ctxt_p) { - for (node_p = ctxt_p->request_queue_p; node_p; - node_p = node_p->next) { - if (cy_as_ll_is_e_p_transfer_related_request - (node_p->rqt, ep)) { - cy_as_ll_remove_request(dev_p, ctxt_p, - node_p->rqt, cy_false); - break; - } - } - - /* - * now, deal with any request that may be in transit - */ - imask = cy_as_hal_disable_interrupts(); - - if (ctxt_p->request_queue_p != 0 && - cy_as_ll_is_e_p_transfer_related_request - (ctxt_p->request_queue_p->rqt, ep) && - cy_as_request_get_node_state(ctxt_p->request_queue_p) == - CY_AS_REQUEST_LIST_STATE_WAITING) { - cy_as_hal_print_message("need to remove an in-transit " - "request to antioch\n"); - - /* - * if the request has not been fully sent to west bridge - * yet, abort sending. otherwise, terminate the request - * with a CANCELED status. firmware will already have - * terminated this transfer. - */ - if (dev_p->ll_sending_rqt) - dev_p->ll_abort_curr_rqt = cy_true; - else { - uint32_t state; - - node_p = ctxt_p->request_queue_p; - if (node_p->callback) - node_p->callback(dev_p, ctxt_p->number, - node_p->rqt, node_p->resp, - CY_AS_ERROR_CANCELED); - - ctxt_p->request_queue_p = node_p->next; - state = cy_as_hal_disable_interrupts(); - cy_as_hal_c_b_free(node_p); - cy_as_hal_enable_interrupts(state); - } - } - - cy_as_hal_enable_interrupts(imask); - } - - return CY_AS_ERROR_SUCCESS; -} diff --git a/drivers/staging/westbridge/astoria/api/src/cyasmisc.c b/drivers/staging/westbridge/astoria/api/src/cyasmisc.c deleted file mode 100644 index 4564fc11df22..000000000000 --- a/drivers/staging/westbridge/astoria/api/src/cyasmisc.c +++ /dev/null @@ -1,3488 +0,0 @@ -/* Cypress West Bridge API source file (cyasmisc.c) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#include "../../include/linux/westbridge/cyashal.h" -#include "../../include/linux/westbridge/cyasmisc.h" -#include "../../include/linux/westbridge/cyasdma.h" -#include "../../include/linux/westbridge/cyasintr.h" -#include "../../include/linux/westbridge/cyaserr.h" -#include "../../include/linux/westbridge/cyasregs.h" -#include "../../include/linux/westbridge/cyaslowlevel.h" -#include "../../include/linux/westbridge/cyasprotocol.h" - -/* -* The device list, the only global in the API -*/ -static cy_as_device *g_device_list; - -/* - * The current debug level - */ -static uint8_t debug_level; - -/* - * This function sets the debug level for the API - * - */ -void -cy_as_misc_set_log_level(uint8_t level) -{ - debug_level = level; -} - -#ifdef CY_AS_LOG_SUPPORT - -/* - * This function is a low level logger for the API. - */ -void -cy_as_log_debug_message(int level, const char *str) -{ - if (level <= debug_level) - cy_as_hal_print_message("log %d: %s\n", level, str); -} - -#endif - -#define cy_as_check_device_ready(dev_p) \ -{\ - if (!(dev_p) || ((dev_p)->sig != \ - CY_AS_DEVICE_HANDLE_SIGNATURE)) \ - return CY_AS_ERROR_INVALID_HANDLE; \ -\ - if (!cy_as_device_is_configured(dev_p)) \ - return CY_AS_ERROR_NOT_CONFIGURED; \ -\ - if (!cy_as_device_is_firmware_loaded(dev_p))\ - return CY_AS_ERROR_NO_FIRMWARE; \ -} - -/* Find an West Bridge device based on a TAG */ -cy_as_device * -cy_as_device_find_from_tag(cy_as_hal_device_tag tag) -{ - cy_as_device *dev_p; - - for (dev_p = g_device_list; dev_p != 0; dev_p = dev_p->next_p) { - if (dev_p->tag == tag) - return dev_p; - } - - return 0; -} - -/* Map a pre-V1.2 media type to the V1.2+ bus number */ -static void -cy_as_bus_from_media_type(cy_as_media_type type, - cy_as_bus_number_t *bus) -{ - if (type == cy_as_media_nand) - *bus = 0; - else - *bus = 1; -} - -static cy_as_return_status_t -my_handle_response_no_data(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) - ret = CY_AS_ERROR_INVALID_RESPONSE; - else - ret = cy_as_ll_request_response__get_word(reply_p, 0); - - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -/* -* Create a new West Bridge device -*/ -cy_as_return_status_t -cy_as_misc_create_device(cy_as_device_handle *handle_p, - cy_as_hal_device_tag tag) -{ - cy_as_device *dev_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_as_log_debug_message(6, "cy_as_misc_create_device called"); - - dev_p = (cy_as_device *)cy_as_hal_alloc(sizeof(cy_as_device)); - if (dev_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - cy_as_hal_mem_set(dev_p, 0, sizeof(cy_as_device)); - - /* - * dynamically allocating this buffer to ensure that it is - * word aligned. - */ - dev_p->usb_ep_data = (uint8_t *)cy_as_hal_alloc(64 * sizeof(uint8_t)); - if (dev_p->usb_ep_data == 0) { - cy_as_hal_free(dev_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - dev_p->sig = CY_AS_DEVICE_HANDLE_SIGNATURE; - dev_p->tag = tag; - dev_p->usb_max_tx_size = 0x40; - - dev_p->storage_write_endpoint = CY_AS_P2S_WRITE_ENDPOINT; - dev_p->storage_read_endpoint = CY_AS_P2S_READ_ENDPOINT; - - dev_p->func_cbs_misc = cy_as_create_c_b_queue(CYAS_FUNC_CB); - if (dev_p->func_cbs_misc == 0) - goto destroy; - - dev_p->func_cbs_res = cy_as_create_c_b_queue(CYAS_FUNC_CB); - if (dev_p->func_cbs_res == 0) - goto destroy; - - dev_p->func_cbs_stor = cy_as_create_c_b_queue(CYAS_FUNC_CB); - if (dev_p->func_cbs_stor == 0) - goto destroy; - - dev_p->func_cbs_usb = cy_as_create_c_b_queue(CYAS_FUNC_CB); - if (dev_p->func_cbs_usb == 0) - goto destroy; - - dev_p->func_cbs_mtp = cy_as_create_c_b_queue(CYAS_FUNC_CB); - if (dev_p->func_cbs_mtp == 0) - goto destroy; - - /* - * allocate memory for the DMA module here. it is then marked idle, and - * will be activated when cy_as_misc_configure_device is called. - */ - ret = cy_as_dma_start(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - cy_as_device_set_dma_stopped(dev_p); - - /* - * allocate memory for the low level module here. this module is also - * activated only when cy_as_misc_configure_device is called. - */ - ret = cy_as_ll_start(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - cy_as_device_set_low_level_stopped(dev_p); - - dev_p->next_p = g_device_list; - g_device_list = dev_p; - - *handle_p = dev_p; - cy_as_hal_init_dev_registers(tag, cy_false); - return CY_AS_ERROR_SUCCESS; - -destroy: - /* Free any queues that were successfully allocated. */ - if (dev_p->func_cbs_misc) - cy_as_destroy_c_b_queue(dev_p->func_cbs_misc); - - if (dev_p->func_cbs_res) - cy_as_destroy_c_b_queue(dev_p->func_cbs_res); - - if (dev_p->func_cbs_stor) - cy_as_destroy_c_b_queue(dev_p->func_cbs_stor); - - if (dev_p->func_cbs_usb) - cy_as_destroy_c_b_queue(dev_p->func_cbs_usb); - - if (dev_p->func_cbs_mtp) - cy_as_destroy_c_b_queue(dev_p->func_cbs_mtp); - - cy_as_hal_free(dev_p->usb_ep_data); - cy_as_hal_free(dev_p); - - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - else - return CY_AS_ERROR_OUT_OF_MEMORY; -} - -/* -* Destroy an existing West Bridge device -*/ -cy_as_return_status_t -cy_as_misc_destroy_device(cy_as_device_handle handle) -{ - cy_as_return_status_t ret; - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_misc_destroy_device called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - /* - * if the USB stack is still running, - * it must be stopped first - */ - if (dev_p->usb_count > 0) - return CY_AS_ERROR_STILL_RUNNING; - - /* - * if the STORAGE stack is still running, - * it must be stopped first - */ - if (dev_p->storage_count > 0) - return CY_AS_ERROR_STILL_RUNNING; - - if (cy_as_device_is_intr_running(dev_p)) - ret = cy_as_intr_stop(dev_p); - - ret = cy_as_ll_stop(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_intr_start(dev_p, dev_p->use_int_drq); - return ret; - } - - ret = cy_as_dma_stop(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_intr_start(dev_p, dev_p->use_int_drq); - return ret; - } - - /* Reset the West Bridge device. */ - cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_RST_CTRL_REG, - CY_AS_MEM_RST_CTRL_REG_HARD); - - /* - * remove the device from the device list - */ - if (g_device_list == dev_p) { - g_device_list = dev_p->next_p; - } else { - cy_as_device *tmp_p = g_device_list; - while (tmp_p && tmp_p->next_p != dev_p) - tmp_p = tmp_p->next_p; - - cy_as_hal_assert(tmp_p != 0); - tmp_p->next_p = dev_p->next_p; - } - - /* - * reset the signature so this will not be detected - * as a valid handle - */ - dev_p->sig = 0; - - cy_as_destroy_c_b_queue(dev_p->func_cbs_misc); - cy_as_destroy_c_b_queue(dev_p->func_cbs_res); - cy_as_destroy_c_b_queue(dev_p->func_cbs_stor); - cy_as_destroy_c_b_queue(dev_p->func_cbs_usb); - cy_as_destroy_c_b_queue(dev_p->func_cbs_mtp); - - /* - * free the memory associated with the device - */ - cy_as_hal_free(dev_p->usb_ep_data); - cy_as_hal_free(dev_p); - - return CY_AS_ERROR_SUCCESS; -} - -/* -* Determine the endian mode for the processor we are -* running on, then set the endian mode register -*/ -static void -cy_as_setup_endian_mode(cy_as_device *dev_p) -{ - /* - * In general, we always set west bridge intothe little - * endian mode. this causes the data on bit 0 internally - * to come out on data line 0 externally and it is generally - * what we want regardless of the endian mode of the - * processor. this capability in west bridge should be - * labeled as a "SWAP" capability and can be used to swap the - * bytes of data in and out of west bridge. this is - * useful if there is DMA hardware that requires this for some - * reason I cannot imagine at this time. basically if the - * wires are connected correctly, we should never need to - * change the endian-ness of west bridge. - */ - cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_ENDIAN, - CY_AS_LITTLE_ENDIAN); -} - -/* -* Query the West Bridge device and determine if we are an standby mode -*/ -cy_as_return_status_t -cy_as_misc_in_standby(cy_as_device_handle handle, cy_bool *standby) -{ - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_misc_in_standby called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (cy_as_device_is_pin_standby(dev_p) || - cy_as_device_is_register_standby(dev_p)) { - *standby = cy_true; - } else - *standby = cy_false; - - return CY_AS_ERROR_SUCCESS; -} - -static void -cy_as_misc_func_callback(cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t ret); - - -static void -my_misc_callback(cy_as_device *dev_p, uint8_t context, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *resp_p, - cy_as_return_status_t ret) -{ - (void)resp_p; - (void)context; - (void)ret; - - switch (cy_as_ll_request_response__get_code(req_p)) { - case CY_RQT_INITIALIZATION_COMPLETE: - { - uint16_t v; - - cy_as_ll_send_status_response(dev_p, - CY_RQT_GENERAL_RQT_CONTEXT, - CY_AS_ERROR_SUCCESS, 0); - cy_as_device_set_firmware_loaded(dev_p); - - if (cy_as_device_is_waking(dev_p)) { - /* - * this is a callback from a - * cy_as_misc_leave_standby() - * request. in this case we call - * the standby callback and clear - * the waking state. - */ - if (dev_p->misc_event_cb) - dev_p->misc_event_cb( - (cy_as_device_handle)dev_p, - cy_as_event_misc_awake, 0); - cy_as_device_clear_waking(dev_p); - } else { - v = cy_as_ll_request_response__get_word - (req_p, 3); - - /* - * store the media supported on - * each of the device buses. - */ - dev_p->media_supported[0] = - (uint8_t)(v & 0xFF); - dev_p->media_supported[1] = - (uint8_t)((v >> 8) & 0xFF); - - v = cy_as_ll_request_response__get_word - (req_p, 4); - - dev_p->is_mtp_firmware = - (cy_bool)((v >> 8) & 0xFF); - - if (dev_p->misc_event_cb) - dev_p->misc_event_cb( - (cy_as_device_handle)dev_p, - cy_as_event_misc_initialized, 0); - } - - v = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_P0_VM_SET); - - if (v & CY_AS_MEM_P0_VM_SET_CFGMODE) - cy_as_hal_print_message( - "initialization message " - "received, but config bit " - "still set\n"); - - v = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_RST_CTRL_REG); - if ((v & CY_AS_MEM_RST_RSTCMPT) == 0) - cy_as_hal_print_message( - "initialization message " - "received, but reset complete " - "bit still not set\n"); - } - break; - - case CY_RQT_OUT_OF_SUSPEND: - cy_as_ll_send_status_response(dev_p, CY_RQT_GENERAL_RQT_CONTEXT, - CY_AS_ERROR_SUCCESS, 0); - cy_as_device_clear_suspend_mode(dev_p); - - /* - * if the wakeup was caused by an async cy_as_misc_leave_suspend - * call, we have to call the corresponding callback. - */ - if (dev_p->func_cbs_misc->count > 0) { - cy_as_func_c_b_node *node = (cy_as_func_c_b_node *) - dev_p->func_cbs_misc->head_p; - cy_as_hal_assert(node); - - if (cy_as_funct_c_b_type_get_type(node->data_type) == - CY_FUNCT_CB_MISC_LEAVESUSPEND) { - cy_as_hal_assert(node->cb_p != 0); - - node->cb_p((cy_as_device_handle)dev_p, - CY_AS_ERROR_SUCCESS, node->client_data, - CY_FUNCT_CB_MISC_LEAVESUSPEND, 0); - cy_as_remove_c_b_node(dev_p->func_cbs_misc); - } - } - - if (dev_p->misc_event_cb) - dev_p->misc_event_cb((cy_as_device_handle)dev_p, - cy_as_event_misc_wakeup, 0); - break; - - case CY_RQT_DEBUG_MESSAGE: - if ((req_p->data[0] == 0) && (req_p->data[1] == 0) && - (req_p->data[2] == 0)) { - if (dev_p->misc_event_cb) - dev_p->misc_event_cb((cy_as_device_handle)dev_p, - cy_as_event_misc_heart_beat, 0); - } else { - cy_as_hal_print_message( - "**** debug message: %02x " - "%02x %02x %02x %02x %02x\n", - req_p->data[0] & 0xff, - (req_p->data[0] >> 8) & 0xff, - req_p->data[1] & 0xff, - (req_p->data[1] >> 8) & 0xff, - req_p->data[2] & 0xff, - (req_p->data[2] >> 8) & 0xff); - } - break; - - case CY_RQT_WB_DEVICE_MISMATCH: - { - if (dev_p->misc_event_cb) - dev_p->misc_event_cb((cy_as_device_handle)dev_p, - cy_as_event_misc_device_mismatch, 0); - } - break; - - case CY_RQT_BOOTLOAD_NO_FIRMWARE: - { - /* TODO Handle case when firmware is - * not found during bootloading. */ - cy_as_hal_print_message("no firmware image found " - "during bootload. device not started\n"); - } - break; - - default: - cy_as_hal_assert(0); - } -} - -static cy_bool -is_valid_silicon_id(uint16_t v) -{ - cy_bool idok = cy_false; - - /* - * remove the revision number from the ID value - */ - v = v & CY_AS_MEM_CM_WB_CFG_ID_HDID_MASK; - - /* - * if this is west bridge, then we are OK. - */ - if (v == CY_AS_MEM_CM_WB_CFG_ID_HDID_ANTIOCH_VALUE || - v == CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_FPGA_VALUE || - v == CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_VALUE) - idok = cy_true; - - return idok; -} - -/* -* Configure the West Bridge device hardware -*/ -cy_as_return_status_t -cy_as_misc_configure_device(cy_as_device_handle handle, - cy_as_device_config *config_p) -{ - cy_as_return_status_t ret; - cy_bool standby; - cy_as_device *dev_p; - uint16_t v; - uint16_t fw_present; - cy_as_log_debug_message(6, "cy_as_misc_configure_device called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - /* Setup big endian vs little endian */ - cy_as_setup_endian_mode(dev_p); - - /* Now, confirm that we can talk to the West Bridge device */ - dev_p->silicon_id = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_CM_WB_CFG_ID); - fw_present = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_RST_CTRL_REG); - if (!(fw_present & CY_AS_MEM_RST_RSTCMPT)) { - if (!is_valid_silicon_id(dev_p->silicon_id)) - return CY_AS_ERROR_NO_ANTIOCH; - } - /* Check for standby mode */ - ret = cy_as_misc_in_standby(handle, &standby); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - if (ret) - return CY_AS_ERROR_IN_STANDBY; - - /* Setup P-port interface mode (CRAM / SRAM). */ - if (cy_as_device_is_astoria_dev(dev_p)) { - if (config_p->srammode) - v = CY_AS_MEM_P0_VM_SET_VMTYPE_SRAM; - else - v = CY_AS_MEM_P0_VM_SET_VMTYPE_RAM; - } else - v = CY_AS_MEM_P0_VM_SET_VMTYPE_RAM; - - /* Setup synchronous versus asynchronous mode */ - if (config_p->sync) - v |= CY_AS_MEM_P0_VM_SET_IFMODE; - if (config_p->dackmode == cy_as_device_dack_ack) - v |= CY_AS_MEM_P0_VM_SET_DACKEOB; - if (config_p->drqpol) - v |= CY_AS_MEM_P0_VM_SET_DRQPOL; - if (config_p->dackpol) - v |= CY_AS_MEM_P0_VM_SET_DACKPOL; - cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_P0_VM_SET, v); - - if (config_p->crystal) - cy_as_device_set_crystal(dev_p); - else - cy_as_device_set_external_clock(dev_p); - - /* Register a callback to handle MISC requests from the firmware */ - cy_as_ll_register_request_callback(dev_p, - CY_RQT_GENERAL_RQT_CONTEXT, my_misc_callback); - - /* Now mark the DMA and low level modules as active. */ - cy_as_device_set_dma_running(dev_p); - cy_as_device_set_low_level_running(dev_p); - - /* Now, initialize the interrupt module */ - dev_p->use_int_drq = config_p->dmaintr; - ret = cy_as_intr_start(dev_p, config_p->dmaintr); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* Mark the interface as initialized */ - cy_as_device_set_configured(dev_p); - - return CY_AS_ERROR_SUCCESS; -} - -static void -my_dma_callback(cy_as_device *dev_p, - cy_as_end_point_number_t ep, - void *mem_p, - uint32_t size, - cy_as_return_status_t ret - ) -{ - cy_as_dma_end_point *ep_p; - - (void)size; - - /* Get the endpoint pointer based on the endpoint number */ - ep_p = CY_AS_NUM_EP(dev_p, ep); - - /* Check the queue to see if is drained */ - if (ep_p->queue_p == 0) { - cy_as_func_c_b_node *node = - (cy_as_func_c_b_node *)dev_p->func_cbs_misc->head_p; - - cy_as_hal_assert(node); - - if (ret == CY_AS_ERROR_SUCCESS) { - /* - * disable endpoint 2. the storage module - * will enable this EP if necessary. - */ - cy_as_dma_enable_end_point(dev_p, - CY_AS_FIRMWARE_ENDPOINT, - cy_false, cy_as_direction_in); - - /* - * clear the reset register. this releases the - * antioch micro-controller from reset and begins - * running the code at address zero. - */ - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_RST_CTRL_REG, 0x00); - } - - /* Call the user Callback */ - node->cb_p((cy_as_device_handle)dev_p, ret, node->client_data, - node->data_type, node->data); - cy_as_remove_c_b_node(dev_p->func_cbs_misc); - } else { - /* This is the header data that was allocated in the - * download firmware function, and can be safely freed - * here. */ - uint32_t state = cy_as_hal_disable_interrupts(); - cy_as_hal_c_b_free(mem_p); - cy_as_hal_enable_interrupts(state); - } -} - -cy_as_return_status_t -cy_as_misc_download_firmware(cy_as_device_handle handle, - const void *mem_p, - uint16_t size, - cy_as_function_callback cb, - uint32_t client) -{ - uint8_t *header; - cy_as_return_status_t ret; - cy_bool standby; - cy_as_device *dev_p; - cy_as_dma_callback dmacb = 0; - uint32_t state; - - cy_as_log_debug_message(6, "cy_as_misc_download_firmware called"); - - /* Make sure we have a valid device */ - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - /* - * if the device has not been initialized, we cannot download firmware - * to the device. - */ - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - /* - * make sure west bridge is not in standby - */ - ret = cy_as_misc_in_standby(dev_p, &standby); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (standby) - return CY_AS_ERROR_IN_STANDBY; - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - /* - * make sure we are in configuration mode - */ - if ((cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_VM_SET) & - CY_AS_MEM_P0_VM_SET_CFGMODE) == 0) - return CY_AS_ERROR_NOT_IN_CONFIG_MODE; - - /* Maximum firmware size is 24k */ - if (size > CY_AS_MAXIMUM_FIRMWARE_SIZE) - return CY_AS_ERROR_INVALID_SIZE; - - /* Make sure the size is an even number of bytes as well */ - if (size & 0x01) - return CY_AS_ERROR_ALIGNMENT_ERROR; - - /* - * write the two word header that gives the base address and - * size of the firmware image to download - */ - state = cy_as_hal_disable_interrupts(); - header = (uint8_t *)cy_as_hal_c_b_alloc(4); - cy_as_hal_enable_interrupts(state); - if (header == NULL) - return CY_AS_ERROR_OUT_OF_MEMORY; - - header[0] = 0x00; - header[1] = 0x00; - header[2] = (uint8_t)(size & 0xff); - header[3] = (uint8_t)((size >> 8) & 0xff); - - /* Enable the firmware endpoint */ - ret = cy_as_dma_enable_end_point(dev_p, CY_AS_FIRMWARE_ENDPOINT, - cy_true, cy_as_direction_in); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* - * setup DMA for 64 byte packets. this is the requirement for downloading - * firmware to west bridge. - */ - cy_as_dma_set_max_dma_size(dev_p, CY_AS_FIRMWARE_ENDPOINT, 64); - - if (cb) - dmacb = my_dma_callback; - - ret = cy_as_dma_queue_request(dev_p, CY_AS_FIRMWARE_ENDPOINT, header, - 4, cy_false, cy_false, dmacb); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* - * write the firmware image to the west bridge device - */ - ret = cy_as_dma_queue_request(dev_p, CY_AS_FIRMWARE_ENDPOINT, - (void *)mem_p, size, cy_false, cy_false, dmacb); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cb) { - cy_as_func_c_b_node *cbnode = cy_as_create_func_c_b_node_data( - cb, client, CY_FUNCT_CB_MISC_DOWNLOADFIRMWARE, 0); - - if (cbnode == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - else - cy_as_insert_c_b_node(dev_p->func_cbs_misc, cbnode); - - ret = cy_as_dma_kick_start(dev_p, CY_AS_FIRMWARE_ENDPOINT); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - } else { - ret = cy_as_dma_drain_queue(dev_p, - CY_AS_FIRMWARE_ENDPOINT, cy_true); - - /* Free the header memory that was allocated earlier. */ - cy_as_hal_c_b_free(header); - - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* - * disable EP 2. the storage module will - * enable this EP if necessary. - */ - cy_as_dma_enable_end_point(dev_p, CY_AS_FIRMWARE_ENDPOINT, - cy_false, cy_as_direction_in); - - /* - * clear the reset register. this releases the west bridge - * micro-controller from reset and begins running the code at - * address zero. - */ - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_RST_CTRL_REG, 0x00); - } - - /* - * the firmware is not marked as loaded until the firmware - * initializes west bridge and a request is sent from west bridge - * to the P port processor indicating that west bridge is ready. - */ - return CY_AS_ERROR_SUCCESS; -} - - -static cy_as_return_status_t -my_handle_response_get_firmware_version(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_get_firmware_version_data *data_p) -{ - - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint16_t val; - - if (cy_as_ll_request_response__get_code(reply_p) - != CY_RESP_FIRMWARE_VERSION) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - data_p->major = cy_as_ll_request_response__get_word(reply_p, 0); - data_p->minor = cy_as_ll_request_response__get_word(reply_p, 1); - data_p->build = cy_as_ll_request_response__get_word(reply_p, 2); - val = cy_as_ll_request_response__get_word(reply_p, 3); - data_p->media_type = (uint8_t)(((val >> 8) & 0xFF) | (val & 0xFF)); - val = cy_as_ll_request_response__get_word(reply_p, 4); - data_p->is_debug_mode = (cy_bool)(val & 0xFF); - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_misc_get_firmware_version(cy_as_device_handle handle, - cy_as_get_firmware_version_data *data, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_bool standby; - cy_as_ll_request_response *req_p, *reply_p; - - cy_as_device *dev_p; - - (void)client; - - cy_as_log_debug_message(6, "cy_as_misc_get_firmware_version called"); - - /* Make sure we have a valid device */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - /* - * make sure antioch is not in standby - */ - ret = cy_as_misc_in_standby(dev_p, &standby); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - if (standby) - return CY_AS_ERROR_IN_STANDBY; - - /* Make sure the Antioch is not in suspend mode. */ - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_GET_FIRMWARE_VERSION, - CY_RQT_GENERAL_RQT_CONTEXT, 0); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* - * Reserve space for the reply, the reply data - * will not exceed three words - */ - reply_p = cy_as_ll_create_response(dev_p, 5); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* Request and response are freed in - * MyHandleResponseGetFirmwareVersion. */ - ret = my_handle_response_get_firmware_version(dev_p, - req_p, reply_p, data); - return ret; - } else { - - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_GETFIRMWAREVERSION, data, - dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed - * as part of the MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_misc_get_firmware_version); - -static cy_as_return_status_t -my_handle_response_read_m_c_u_register(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - uint8_t *data_p) -{ - - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (cy_as_ll_request_response__get_code(reply_p) - != CY_RESP_MCU_REGISTER_DATA) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - *data_p = (uint8_t) - (cy_as_ll_request_response__get_word(reply_p, 0)); - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -static cy_as_return_status_t -my_handle_response_get_gpio_value(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - uint8_t *data_p) -{ - - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (cy_as_ll_request_response__get_code(reply_p) - != CY_RESP_GPIO_STATE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - } else - *data_p = (uint8_t) - (cy_as_ll_request_response__get_word(reply_p, 0)); - - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - - -cy_as_return_status_t cy_as_misc_set_sd_power_polarity( - cy_as_device_handle handle, - cy_as_misc_signal_polarity polarity, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p, *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_device *dev_p = (cy_as_device *)handle; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDPOLARITY, - CY_RQT_GENERAL_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, - (uint16_t)polarity); - - /* - * Reserve space for the reply, the reply data will - * not exceed one word - */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return (my_handle_response_no_data(dev_p, req_p, reply_p)); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_SETSDPOLARITY, 0, dev_p->func_cbs_misc, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed - * as part of the FuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - return ret; -} - - -cy_as_return_status_t -cy_as_misc_read_m_c_u_register(cy_as_device_handle handle, - uint16_t address, - uint8_t *value, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_ll_request_response *req_p, *reply_p; - - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_misc_read_m_c_u_register called"); - - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - /* Check whether the firmware supports this command. */ - if (cy_as_device_is_nand_storage_supported(dev_p)) - return CY_AS_ERROR_NOT_SUPPORTED; - - /* Make sure the Antioch is not in suspend mode. */ - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_READ_MCU_REGISTER, - CY_RQT_GENERAL_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)address); - - /* Reserve space for the reply, the reply - * data will not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_MCU_REGISTER_DATA) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - *value = (uint8_t)(cy_as_ll_request_response__get_word - (reply_p, 0)); - } else { - - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_READMCUREGISTER, value, - dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed - * as part of the MiscFuncCallback */ - return ret; - } -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_misc_read_m_c_u_register); - -cy_as_return_status_t -cy_as_misc_write_m_c_u_register(cy_as_device_handle handle, - uint16_t address, - uint8_t mask, - uint8_t value, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_ll_request_response *req_p, *reply_p; - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_misc_write_m_c_u_register called"); - - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - /* Check whether the firmware supports this command. */ - if (cy_as_device_is_nand_storage_supported(dev_p)) - return CY_AS_ERROR_NOT_SUPPORTED; - - /* Make sure the Antioch is not in suspend mode. */ - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_WRITE_MCU_REGISTER, - CY_RQT_GENERAL_RQT_CONTEXT, 2); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)address); - cy_as_ll_request_response__set_word(req_p, 1, - (uint16_t)((mask << 8) | value)); - - /* - * Reserve space for the reply, the reply data - * will not exceed one word - */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_WRITEMCUREGISTER, 0, - dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* - * The request and response are freed as part of the - * MiscFuncCallback - */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -my_handle_response_reset(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_reset_type type) -{ - uint16_t v; - - (void)req_p; - (void)reply_p; - - /* - * if the device is in suspend mode, it needs to be woken up - * so that the write to the reset control register succeeds. - * we need not however wait for the wake up procedure to be - * complete. - */ - if (cy_as_device_is_in_suspend_mode(dev_p)) { - v = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_CM_WB_CFG_ID); - cy_as_hal_sleep(1); - } - - if (type == cy_as_reset_hard) { - cy_as_misc_cancel_ex_requests(dev_p); - cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_RST_CTRL_REG, - CY_AS_MEM_RST_CTRL_REG_HARD); - cy_as_device_set_unconfigured(dev_p); - cy_as_device_set_firmware_not_loaded(dev_p); - cy_as_device_set_dma_stopped(dev_p); - cy_as_device_set_low_level_stopped(dev_p); - cy_as_device_set_intr_stopped(dev_p); - cy_as_device_clear_suspend_mode(dev_p); - cy_as_usb_cleanup(dev_p); - cy_as_storage_cleanup(dev_p); - - /* - * wait for a small amount of time to - * allow reset to be complete. - */ - cy_as_hal_sleep(100); - } - - cy_as_device_clear_reset_pending(dev_p); - - return CY_AS_ERROR_SUCCESS; -} - -cy_as_return_status_t -cy_as_misc_reset(cy_as_device_handle handle, - cy_as_reset_type type, - cy_bool flush, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p; - cy_as_end_point_number_t i; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - (void)client; - (void)cb; - - cy_as_log_debug_message(6, "cy_as_misc_reset_e_x called"); - - /* Make sure the device is ready for the command. */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - /* - * soft reset is not supported until we close on the issues - * in the firmware with what needs to happen. - */ - if (type == cy_as_reset_soft) - return CY_AS_ERROR_NOT_YET_SUPPORTED; - - cy_as_device_set_reset_pending(dev_p); - - if (flush) { - /* Unable to DrainQueues in polling mode */ - if ((dev_p->storage_cb || dev_p->storage_cb_ms) && - cy_as_hal_is_polling()) - return CY_AS_ERROR_ASYNC_PENDING; - - /* - * shutdown the endpoints so no more traffic can be queued - */ - for (i = 0; i < 15; i++) - cy_as_dma_enable_end_point(dev_p, i, cy_false, - cy_as_direction_dont_change); - - /* - * if we are in normal mode, drain all traffic across all - * endpoints to be sure all traffic is flushed. if the - * device is suspended, data will not be coming in on any - * endpoint and all outstanding DMA operations can be - * cancelled. - */ - if (cy_as_device_is_in_suspend_mode(dev_p)) { - for (i = 0; i < 15; i++) - cy_as_dma_cancel(dev_p, i, - CY_AS_ERROR_CANCELED); - } else { - for (i = 0; i < 15; i++) { - if ((i == CY_AS_P2S_WRITE_ENDPOINT) || - (i == CY_AS_P2S_READ_ENDPOINT)) - cy_as_dma_drain_queue(dev_p, i, - cy_false); - else - cy_as_dma_drain_queue(dev_p, i, - cy_true); - } - } - } else { - /* No flush was requested, so cancel any outstanding DMAs - * so the user callbacks are called as needed - */ - if (cy_as_device_is_storage_async_pending(dev_p)) { - for (i = 0; i < 15; i++) - cy_as_dma_cancel(dev_p, i, - CY_AS_ERROR_CANCELED); - } - } - - ret = my_handle_response_reset(dev_p, 0, 0, type); - - if (cb) - /* Even though no mailbox communication was needed, - * issue the callback so the user does not need to - * special case their code. */ - cb((cy_as_device_handle)dev_p, ret, client, - CY_FUNCT_CB_MISC_RESET, 0); - - /* - * initialize any registers that may have been - * changed when the device was reset. - */ - cy_as_hal_init_dev_registers(dev_p->tag, cy_false); - - return ret; -} -EXPORT_SYMBOL(cy_as_misc_reset); - -static cy_as_return_status_t -get_unallocated_resource(cy_as_device *dev_p, cy_as_resource_type resource) -{ - uint8_t shift = 0; - uint16_t v; - cy_as_return_status_t ret = CY_AS_ERROR_NOT_ACQUIRED; - - switch (resource) { - case cy_as_bus_u_s_b: - shift = 4; - break; - case cy_as_bus_1: - shift = 0; - break; - case cy_as_bus_0: - shift = 2; - break; - default: - cy_as_hal_assert(cy_false); - break; - } - - /* Get the semaphore value for this resource */ - v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_RSE_ALLOCATE); - v = (v >> shift) & 0x03; - - if (v == 0x03) { - ret = CY_AS_ERROR_RESOURCE_ALREADY_OWNED; - } else if ((v & 0x01) == 0) { - /* The resource is not owned by anyone, we can try to get it */ - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_P0_RSE_MASK, (0x03 << shift)); - v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_RSE_MASK); - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_P0_RSE_ALLOCATE, (0x01 << shift)); - v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_RSE_MASK); - - v = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_P0_RSE_ALLOCATE); - v = (v >> shift) & 0x03; - if (v == 0x03) - ret = CY_AS_ERROR_SUCCESS; - } - - return ret; -} - -static cy_as_return_status_t -my_handle_response_acquire_resource(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_resource_type *resource) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - if (ret == CY_AS_ERROR_SUCCESS) { - ret = get_unallocated_resource(dev_p, *resource); - if (ret != CY_AS_ERROR_NOT_ACQUIRED) - ret = CY_AS_ERROR_SUCCESS; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_misc_acquire_resource(cy_as_device_handle handle, - cy_as_resource_type *resource, - cy_bool force, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p, *reply_p; - cy_as_return_status_t ret; - - cy_as_device *dev_p; - - (void)client; - - cy_as_log_debug_message(6, "cy_as_misc_acquire_resource called"); - - if (*resource != cy_as_bus_u_s_b && *resource != - cy_as_bus_0 && *resource != cy_as_bus_1) - return CY_AS_ERROR_INVALID_RESOURCE; - - - /* Make sure the device is ready to accept the command. */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - - ret = get_unallocated_resource(dev_p, *resource); - - /* - * make sure that the callback is called if the resource is - * successfully acquired at this point. - */ - if ((ret == CY_AS_ERROR_SUCCESS) && (cb != 0)) - cb(handle, ret, client, - CY_FUNCT_CB_MISC_ACQUIRERESOURCE, resource); - - if (ret != CY_AS_ERROR_NOT_ACQUIRED) - return ret; - - if (!force) - return CY_AS_ERROR_NOT_ACQUIRED; - - /* Create the request to acquire the resource */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_ACQUIRE_RESOURCE, - CY_RQT_RESOURCE_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)(*resource)); - - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_ACQUIRERESOURCE, resource, - dev_p->func_cbs_res, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed - * as part of the MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - if (ret == CY_AS_ERROR_SUCCESS) { - ret = get_unallocated_resource(dev_p, *resource); - if (ret != CY_AS_ERROR_NOT_ACQUIRED) - ret = CY_AS_ERROR_SUCCESS; - } - - return ret; -} -EXPORT_SYMBOL(cy_as_misc_acquire_resource); - -cy_as_return_status_t -cy_as_misc_release_resource(cy_as_device_handle handle, - cy_as_resource_type resource) -{ - uint8_t shift = 0; - uint16_t v; - - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_misc_release_resource called"); - - /* Make sure the device is ready for the command. */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - if (resource != cy_as_bus_u_s_b && resource != - cy_as_bus_0 && resource != cy_as_bus_1) - return CY_AS_ERROR_INVALID_RESOURCE; - - switch (resource) { - case cy_as_bus_u_s_b: - shift = 4; - break; - case cy_as_bus_1: - shift = 0; - break; - case cy_as_bus_0: - shift = 2; - break; - default: - cy_as_hal_assert(cy_false); - break; - } - - /* Get the semaphore value for this resource */ - v = (cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_P0_RSE_ALLOCATE) >> shift) & 0x03; - if (v == 0 || v == 1 || v == 2) - return CY_AS_ERROR_RESOURCE_NOT_OWNED; - - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_P0_RSE_MASK, (0x03 << shift)); - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_P0_RSE_ALLOCATE, (0x02 << shift)); - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_P0_RSE_MASK, 0); - - return CY_AS_ERROR_SUCCESS; -} -EXPORT_SYMBOL(cy_as_misc_release_resource); - -cy_as_return_status_t -cy_as_misc_set_trace_level(cy_as_device_handle handle, - uint8_t level, - cy_as_bus_number_t bus, - uint32_t device, - uint32_t unit, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p, *reply_p; - cy_as_return_status_t ret; - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_misc_set_trace_level called"); - - /* Make sure the device is ready for the command. */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - if (bus < 0 || bus >= CY_AS_MAX_BUSES) - return CY_AS_ERROR_NO_SUCH_BUS; - - if (device >= CY_AS_MAX_STORAGE_DEVICES) - return CY_AS_ERROR_NO_SUCH_DEVICE; - - if (unit > 255) - return CY_AS_ERROR_NO_SUCH_UNIT; - - if (level >= CYAS_FW_TRACE_MAX_LEVEL) - return CY_AS_ERROR_INVALID_TRACE_LEVEL; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_SET_TRACE_LEVEL, - CY_RQT_GENERAL_RQT_CONTEXT, 2); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, - (uint16_t)level); - cy_as_ll_request_response__set_word(req_p, 1, - (uint16_t)((bus << 12) | (device << 8) | (unit))); - - /* - * Reserve space for the reply, the reply data will not - * exceed three words - */ - reply_p = cy_as_ll_create_response(dev_p, 2); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_NOT_SUPPORTED; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - } else { - - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_SETTRACELEVEL, 0, dev_p->func_cbs_misc, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of the - * MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_misc_heart_beat_control(cy_as_device_handle handle, - cy_bool enable, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p, *reply_p; - cy_as_return_status_t ret; - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_misc_heart_beat_control called"); - - /* Make sure the device is ready for the command. */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_CONTROL_ANTIOCH_HEARTBEAT, - CY_RQT_GENERAL_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)enable); - - /* Reserve space for the reply, the reply - * data will not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - } else { - - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_HEARTBEATCONTROL, 0, - dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of the - * MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_misc_heart_beat_control); - -static cy_as_return_status_t -my_set_sd_clock_freq( - cy_as_device *dev_p, - uint8_t card_type, - uint8_t setting, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_ll_request_response *req_p, *reply_p; - - if (cy_as_device_is_in_callback(dev_p) && (cb == 0)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - req_p = cy_as_ll_create_request(dev_p, CY_RQT_SET_SD_CLOCK_FREQ, - CY_RQT_GENERAL_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, - (uint16_t)((card_type << 8) | setting)); - - /* Reserve space for the reply, which will not exceed one word. */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_SETSDFREQ, 0, dev_p->func_cbs_misc, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of the - * MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_misc_set_low_speed_sd_freq( - cy_as_device_handle handle, - cy_as_low_speed_sd_freq setting, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_misc_set_low_speed_sd_freq called"); - - /* Make sure the device is ready for the command. */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - if ((setting != CY_AS_SD_DEFAULT_FREQ) && - (setting != CY_AS_SD_RATED_FREQ)) - return CY_AS_ERROR_INVALID_PARAMETER; - - return my_set_sd_clock_freq(dev_p, 0, (uint8_t)setting, cb, client); -} -EXPORT_SYMBOL(cy_as_misc_set_low_speed_sd_freq); - -cy_as_return_status_t -cy_as_misc_set_high_speed_sd_freq( - cy_as_device_handle handle, - cy_as_high_speed_sd_freq setting, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_misc_set_high_speed_sd_freq called"); - - /* Make sure the device is ready for the command. */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - if ((setting != CY_AS_HS_SD_FREQ_24) && - (setting != CY_AS_HS_SD_FREQ_48)) - return CY_AS_ERROR_INVALID_PARAMETER; - - return my_set_sd_clock_freq(dev_p, 1, (uint8_t)setting, cb, client); -} -EXPORT_SYMBOL(cy_as_misc_set_high_speed_sd_freq); - -cy_as_return_status_t -cy_as_misc_get_gpio_value(cy_as_device_handle handle, - cy_as_misc_gpio pin, - uint8_t *value, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_ll_request_response *req_p, *reply_p; - cy_as_device *dev_p; - uint16_t v; - - cy_as_log_debug_message(6, "cy_as_misc_get_gpio_value called"); - - /* Make sure the device is ready for the command. */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - /* If the pin specified is UVALID, there is no need - * for firmware to be loaded. */ - if (pin == cy_as_misc_gpio_U_valid) { - v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PMU_UPDATE); - *value = (uint8_t)(v & CY_AS_MEM_PMU_UPDATE_UVALID); - - if (cb != 0) - cb(dev_p, ret, client, - CY_FUNCT_CB_MISC_GETGPIOVALUE, value); - - return ret; - } - - /* Check whether the firmware supports this command. */ - if (cy_as_device_is_nand_storage_supported(dev_p)) - return CY_AS_ERROR_NOT_SUPPORTED; - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - /* Make sure the pin selected is valid */ - if ((pin != cy_as_misc_gpio_1) && (pin != cy_as_misc_gpio_0)) - return CY_AS_ERROR_INVALID_PARAMETER; - - req_p = cy_as_ll_create_request(dev_p, CY_RQT_GET_GPIO_STATE, - CY_RQT_GENERAL_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, ((uint8_t)pin << 8)); - - /* Reserve space for the reply, which will not exceed one word. */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_GPIO_STATE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - *value = (uint8_t) - cy_as_ll_request_response__get_word(reply_p, 0); - } else { - - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_GETGPIOVALUE, value, - dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of the - * MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_misc_get_gpio_value); - -cy_as_return_status_t -cy_as_misc_set_gpio_value(cy_as_device_handle handle, - cy_as_misc_gpio pin, - uint8_t value, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_ll_request_response *req_p, *reply_p; - cy_as_device *dev_p; - uint16_t v; - - cy_as_log_debug_message(6, "cy_as_misc_set_gpio_value called"); - - /* Make sure the device is ready for the command. */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - /* If the pin specified is UVALID, there is - * no need for firmware to be loaded. */ - if (pin == cy_as_misc_gpio_U_valid) { - v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_PMU_UPDATE); - if (value) - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_PMU_UPDATE, - (v | CY_AS_MEM_PMU_UPDATE_UVALID)); - else - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_PMU_UPDATE, - (v & ~CY_AS_MEM_PMU_UPDATE_UVALID)); - - if (cb != 0) - cb(dev_p, ret, client, - CY_FUNCT_CB_MISC_SETGPIOVALUE, 0); - return ret; - } - - /* Check whether the firmware supports this command. */ - if (cy_as_device_is_nand_storage_supported(dev_p)) - return CY_AS_ERROR_NOT_SUPPORTED; - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - /* Make sure the pin selected is valid */ - if ((pin < cy_as_misc_gpio_0) || (pin > cy_as_misc_gpio_U_valid)) - return CY_AS_ERROR_INVALID_PARAMETER; - - /* Create and initialize the low level request to the firmware. */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_SET_GPIO_STATE, - CY_RQT_GENERAL_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - v = (uint16_t)(((uint8_t)pin << 8) | (value > 0)); - cy_as_ll_request_response__set_word(req_p, 0, v); - - /* Reserve space for the reply, which will not exceed one word. */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - } else { - - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_SETGPIOVALUE, 0, - dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of the - * MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_misc_set_gpio_value); - -static cy_as_return_status_t -my_enter_standby(cy_as_device *dev_p, cy_bool pin) -{ - cy_as_misc_cancel_ex_requests(dev_p); - - /* Save the current values in the critical P-port - * registers, where necessary. */ - cy_as_hal_read_regs_before_standby(dev_p->tag); - - if (pin) { - if (cy_as_hal_set_wakeup_pin(dev_p->tag, cy_false)) - cy_as_device_set_pin_standby(dev_p); - else - return CY_AS_ERROR_SETTING_WAKEUP_PIN; - } else { - /* - * put antioch in the standby mode - */ - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_PWR_MAGT_STAT, 0x02); - cy_as_device_set_register_standby(dev_p); - } - - /* - * when the antioch comes out of standby, we have to wait until - * the firmware initialization completes before sending other - * requests down. - */ - cy_as_device_set_firmware_not_loaded(dev_p); - - /* - * keep west bridge interrupt disabled until the device is being woken - * up from standby. - */ - dev_p->stby_int_mask = cy_as_hal_disable_interrupts(); - - return CY_AS_ERROR_SUCCESS; -} - -static cy_as_return_status_t -my_handle_response_enter_standby(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_bool pin) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - ret = my_enter_standby(dev_p, pin); - - return ret; -} - -cy_as_return_status_t -cy_as_misc_enter_standby(cy_as_device_handle handle, - cy_bool pin, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_ll_request_response *req_p, *reply_p; - cy_bool standby; - - cy_as_log_debug_message(6, "cy_as_misc_enter_standby called"); - - /* Make sure we have a valid device */ - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - /* - * if we already are in standby, do not do it again and let the - * user know via the error return. - */ - ret = cy_as_misc_in_standby(handle, &standby); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (standby == cy_true) - return CY_AS_ERROR_ALREADY_STANDBY; - - /* - * if the user wants to transition from suspend mode to standby mode, - * the device needs to be woken up so that it can complete all pending - * operations. - */ - if (cy_as_device_is_in_suspend_mode(dev_p)) - cy_as_misc_leave_suspend(dev_p, 0, 0); - - if (dev_p->usb_count) { - /* - * we do not allow west bridge to go into standby mode when the - * USB stack is initialized. you must stop the USB stack in - * order to enter standby mode. - */ - return CY_AS_ERROR_USB_RUNNING; - } - - /* - * if the storage stack is not running, the device can directly be - * put into sleep mode. otherwise, the firmware needs to be signaled - * to prepare for going into sleep mode. - */ - if (dev_p->storage_count) { - /* - * if there are async storage operations pending, - * make one attempt to complete them. - */ - if (cy_as_device_is_storage_async_pending(dev_p)) { - /* DrainQueue will not work in polling mode */ - if (cy_as_hal_is_polling()) - return CY_AS_ERROR_ASYNC_PENDING; - - cy_as_dma_drain_queue(dev_p, - CY_AS_P2S_READ_ENDPOINT, cy_false); - cy_as_dma_drain_queue(dev_p, - CY_AS_P2S_WRITE_ENDPOINT, cy_false); - - /* - * if more storage operations were queued - * at this stage, return an error. - */ - if (cy_as_device_is_storage_async_pending(dev_p)) - return CY_AS_ERROR_ASYNC_PENDING; - } - - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_PREPARE_FOR_STANDBY, - CY_RQT_GENERAL_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (!cb) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed - * in the HandleResponse */ - return my_handle_response_enter_standby(dev_p, - req_p, reply_p, pin); - - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_ENTERSTANDBY, (void *)pin, - dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed - * as part of the MiscFuncCallback */ - return ret; - } -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - } else { - ret = my_enter_standby(dev_p, pin); - if (cb) - /* Even though no mailbox communication was - * needed, issue the callback so the user - * does not need to special case their code. */ - cb((cy_as_device_handle)dev_p, ret, client, - CY_FUNCT_CB_MISC_ENTERSTANDBY, 0); - } - - return ret; -} -EXPORT_SYMBOL(cy_as_misc_enter_standby); - -cy_as_return_status_t -cy_as_misc_enter_standby_e_x_u(cy_as_device_handle handle, - cy_bool pin, - cy_bool uvalid_special, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p; - - dev_p = (cy_as_device *)handle; - if (uvalid_special) - cy_as_hal_write_register(dev_p->tag, 0xc5, 0x4); - - return cy_as_misc_enter_standby(handle, pin, cb, client); -} - -cy_as_return_status_t -cy_as_misc_leave_standby(cy_as_device_handle handle, - cy_as_resource_type resource) -{ - cy_as_device *dev_p; - uint16_t v; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint32_t count = 8; - uint8_t retry = 1; - - cy_as_log_debug_message(6, "cy_as_misc_leave_standby called"); - (void)resource; - - /* Make sure we have a valid device */ - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (cy_as_device_is_register_standby(dev_p)) { - /* - * set a flag to indicate that the west bridge is waking - * up from standby. - */ - cy_as_device_set_waking(dev_p); - - /* - * the initial read will not succeed, but will just wake - * the west bridge device from standby. successive reads - * should succeed and in that way we know west bridge is awake. - */ - v = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_CM_WB_CFG_ID); - - do { - /* - * we have initiated the operation to leave standby, now - * we need to wait at least N ms before trying to access - * the west bridge device to insure the PLLs have locked - * and we can talk to the device. - */ - if (cy_as_device_is_crystal(dev_p)) - cy_as_hal_sleep( - CY_AS_LEAVE_STANDBY_DELAY_CRYSTAL); - else - cy_as_hal_sleep( - CY_AS_LEAVE_STANDBY_DELAY_CLOCK); - v = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_CM_WB_CFG_ID); - - /* - * if the P-SPI interface mode is in use, there may be a - * need to re-synchronise the serial clock used for - * astoria access. - */ - if (!is_valid_silicon_id(v)) { - if (cy_as_hal_sync_device_clocks(dev_p->tag) != - cy_true) { - cy_as_hal_enable_interrupts( - dev_p->stby_int_mask); - return CY_AS_ERROR_TIMEOUT; - } - } - } while (!is_valid_silicon_id(v) && count-- > 0); - - /* - * if we tried to read the register and could not, - * return a timeout - */ - if (count == 0) { - cy_as_hal_enable_interrupts( - dev_p->stby_int_mask); - return CY_AS_ERROR_TIMEOUT; - } - - /* - * the standby flag is cleared here, after the action to - * exit standby has been taken. the wait for firmware - * initialization, is ensured by marking the firmware as - * not loaded until the init event is received. - */ - cy_as_device_clear_register_standby(dev_p); - - /* - * initialize any registers that may have been changed - * while the device was in standby mode. - */ - cy_as_hal_init_dev_registers(dev_p->tag, cy_true); - } else if (cy_as_device_is_pin_standby(dev_p)) { - /* - * set a flag to indicate that the west bridge is waking - * up from standby. - */ - cy_as_device_set_waking(dev_p); - -try_wakeup_again: - /* - * try to set the wakeup pin, if this fails in the HAL - * layer, return this failure to the user. - */ - if (!cy_as_hal_set_wakeup_pin(dev_p->tag, cy_true)) { - cy_as_hal_enable_interrupts(dev_p->stby_int_mask); - return CY_AS_ERROR_SETTING_WAKEUP_PIN; - } - - /* - * we have initiated the operation to leave standby, now - * we need to wait at least N ms before trying to access - * the west bridge device to insure the PL_ls have locked - * and we can talk to the device. - */ - if (cy_as_device_is_crystal(dev_p)) - cy_as_hal_sleep(CY_AS_LEAVE_STANDBY_DELAY_CRYSTAL); - else - cy_as_hal_sleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK); - - /* - * initialize any registers that may have been changed - * while the device was in standby mode. - */ - cy_as_hal_init_dev_registers(dev_p->tag, cy_true); - - /* - * the standby flag is cleared here, after the action to - * exit standby has been taken. the wait for firmware - * initialization, is ensured by marking the firmware as - * not loaded until the init event is received. - */ - cy_as_device_clear_pin_standby(dev_p); - } else { - return CY_AS_ERROR_NOT_IN_STANDBY; - } - - /* - * the west bridge interrupt can be enabled now. - */ - cy_as_hal_enable_interrupts(dev_p->stby_int_mask); - - /* - * release the west bridge micro-_controller from reset, - * so that firmware initialization can complete. the attempt - * to release antioch reset is made up to 8 times. - */ - v = 0x03; - count = 0x08; - while ((v & 0x03) && (count)) { - cy_as_hal_write_register(dev_p->tag, - CY_AS_MEM_RST_CTRL_REG, 0x00); - v = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_RST_CTRL_REG); - count--; - } - - if (v & 0x03) { - cy_as_hal_print_message("failed to clear antioch reset\n"); - return CY_AS_ERROR_TIMEOUT; - } - - /* - * if the wake-up pin is being used, wait here to make - * sure that the wake-up event is received within a - * reasonable delay. otherwise, toggle the wake-up pin - * again in an attempt to start the firmware properly. - */ - if (retry) { - count = 10; - while (count) { - /* If the wake-up event has been received, - * we can return. */ - if (cy_as_device_is_firmware_loaded(dev_p)) - break; - /* If we are in polling mode, the interrupt may - * not have been serviced as yet. read the - * interrupt status register. if a pending mailbox - * interrupt is seen, we can assume that the - * wake-up event will be received soon. */ - v = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_P0_INTR_REG); - if (v & CY_AS_MEM_P0_INTR_REG_MBINT) - break; - - cy_as_hal_sleep(10); - count--; - } - - if (!count) { - retry = 0; - dev_p->stby_int_mask = cy_as_hal_disable_interrupts(); - cy_as_hal_set_wakeup_pin(dev_p->tag, cy_false); - cy_as_hal_sleep(10); - goto try_wakeup_again; - } - } - - return ret; -} -EXPORT_SYMBOL(cy_as_misc_leave_standby); - -cy_as_return_status_t -cy_as_misc_register_callback( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The function to call */ - cy_as_misc_event_callback callback - ) -{ - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_misc_register_callback called"); - - /* Make sure we have a valid device */ - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - dev_p->misc_event_cb = callback; - return CY_AS_ERROR_SUCCESS; -} - -cy_as_return_status_t -cy_as_misc_storage_changed(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_bool standby; - cy_as_ll_request_response *req_p, *reply_p; - - cy_as_log_debug_message(6, "cy_as_misc_storage_changed called"); - - /* Make sure the device is ready for the command. */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - /* - * make sure antioch is not in standby - */ - ret = cy_as_misc_in_standby(dev_p, &standby); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (standby) - return CY_AS_ERROR_IN_STANDBY; - - /* - * make sure westbridge is not in suspend mode. - */ - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_STORAGE_MEDIA_CHANGED, - CY_RQT_GENERAL_RQT_CONTEXT, 0); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* Reserve space for the reply, the reply data will - * not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - } else { - - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_STORAGECHANGED, 0, - dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of the - * MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_misc_storage_changed); - -cy_as_return_status_t -cy_as_misc_enter_suspend( - cy_as_device_handle handle, - cy_bool usb_wakeup_en, - cy_bool gpio_wakeup_en, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_bool standby; - cy_as_ll_request_response *req_p, *reply_p; - uint16_t value; - uint32_t int_state; - - cy_as_log_debug_message(6, "cy_as_misc_enter_suspend called"); - - /* - * basic sanity checks to ensure that the device is initialised. - */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - /* - * make sure west bridge is not already in standby - */ - cy_as_misc_in_standby(dev_p, &standby); - if (standby) - return CY_AS_ERROR_IN_STANDBY; - - /* - * make sure that the device is not already in suspend mode. - */ - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - /* - * make sure there is no active USB connection. - */ - if ((cy_as_device_is_usb_connected(dev_p)) && (dev_p->usb_last_event - != cy_as_event_usb_suspend)) - return CY_AS_ERROR_USB_CONNECTED; - - /* - * make sure that there are no async requests at this point in time. - */ - int_state = cy_as_hal_disable_interrupts(); - if ((dev_p->func_cbs_misc->count) || (dev_p->func_cbs_res->count) || - (dev_p->func_cbs_stor->count) || (dev_p->func_cbs_usb->count)) { - cy_as_hal_enable_interrupts(int_state); - return CY_AS_ERROR_ASYNC_PENDING; - } - cy_as_hal_enable_interrupts(int_state); - - /* Create the request to send to the Antioch device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_ENTER_SUSPEND_MODE, - CY_RQT_GENERAL_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* Reserve space for the reply, the reply data will not - * exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - /* Wakeup control flags. */ - value = 0x0001; - if (usb_wakeup_en) - value |= 0x04; - if (gpio_wakeup_en) - value |= 0x02; - cy_as_ll_request_response__set_word(req_p, 0, value); - - if (cb != 0) { - - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_ENTERSUSPEND, - 0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, - cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return CY_AS_ERROR_SUCCESS; - } else { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) - ret = CY_AS_ERROR_INVALID_RESPONSE; - else - ret = cy_as_ll_request_response__get_word(reply_p, 0); - } - -destroy: - if (ret == CY_AS_ERROR_SUCCESS) - cy_as_device_set_suspend_mode(dev_p); - - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_misc_enter_suspend); - -cy_as_return_status_t -cy_as_misc_leave_suspend( - cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p; - uint16_t v, count; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_as_log_debug_message(6, "cy_as_misc_leave_suspend called"); - - /* Make sure we have a valid device */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - /* Make sure we are in suspend mode. */ - if (cy_as_device_is_in_suspend_mode(dev_p)) { - if (cb) { - cy_as_func_c_b_node *cbnode = - cy_as_create_func_c_b_node_data(cb, client, - CY_FUNCT_CB_MISC_LEAVESUSPEND, 0); - if (cbnode == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_insert_c_b_node(dev_p->func_cbs_misc, cbnode); - } - - /* - * do a read from the ID register so that the CE assertion - * will wake west bridge. the read is repeated until the - * read comes back with valid data. - */ - count = 8; - - v = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_CM_WB_CFG_ID); - - while (!is_valid_silicon_id(v) && count-- > 0) { - cy_as_hal_sleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK); - v = cy_as_hal_read_register(dev_p->tag, - CY_AS_MEM_CM_WB_CFG_ID); - } - - /* - * if we tried to read the register and could not, - * return a timeout - */ - if (count == 0) - return CY_AS_ERROR_TIMEOUT; - } else - return CY_AS_ERROR_NOT_IN_SUSPEND; - - if (cb == 0) { - /* - * wait until the in suspend mode flag is cleared. - */ - count = 20; - while ((cy_as_device_is_in_suspend_mode(dev_p)) - && (count--)) { - cy_as_hal_sleep(CY_AS_LEAVE_STANDBY_DELAY_CLOCK); - } - - if (cy_as_device_is_in_suspend_mode(dev_p)) - ret = CY_AS_ERROR_TIMEOUT; - } - - return ret; -} -EXPORT_SYMBOL(cy_as_misc_leave_suspend); - -cy_as_return_status_t -cy_as_misc_reserve_l_n_a_boot_area(cy_as_device_handle handle, - uint8_t numzones, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_bool standby; - cy_as_ll_request_response *req_p, *reply_p; - - cy_as_device *dev_p; - - (void)client; - - cy_as_log_debug_message(6, "cy_as_misc_switch_pnand_mode called"); - - /* Make sure we have a valid device */ - dev_p = (cy_as_device *)handle; - cy_as_check_device_ready(dev_p); - - /* - * make sure antioch is not in standby - */ - ret = cy_as_misc_in_standby(dev_p, &standby); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - if (standby) - return CY_AS_ERROR_IN_STANDBY; - - /* Make sure the Antioch is not in suspend mode. */ - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_RESERVE_LNA_BOOT_AREA, - CY_RQT_GENERAL_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - cy_as_ll_request_response__set_word(req_p, - 0, (uint16_t)numzones); - - /* Reserve space for the reply, the reply data will not - * exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - } else { - - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MISC_RESERVELNABOOTAREA, - 0, dev_p->func_cbs_misc, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_misc_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of the - * MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_func_c_b_node* -cy_as_create_func_c_b_node_data(cy_as_function_callback cb, - uint32_t client, - cy_as_funct_c_b_type type, - void *data) -{ - uint32_t state = cy_as_hal_disable_interrupts(); - cy_as_func_c_b_node *node = cy_as_hal_c_b_alloc( - sizeof(cy_as_func_c_b_node)); - cy_as_hal_enable_interrupts(state); - if (node != 0) { - node->node_type = CYAS_FUNC_CB; - node->cb_p = cb; - node->client_data = client; - node->data_type = type; - if (data != 0) - node->data_type |= CY_FUNCT_CB_DATA; - else - node->data_type |= CY_FUNCT_CB_NODATA; - node->data = data; - node->next_p = 0; - } - return node; -} - -cy_as_func_c_b_node* -cy_as_create_func_c_b_node(cy_as_function_callback cb, - uint32_t client) -{ - return cy_as_create_func_c_b_node_data(cb, client, - CY_FUNCT_CB_NODATA, 0); -} - -void -cy_as_destroy_func_c_b_node(cy_as_func_c_b_node *node) -{ - uint32_t state; - - node->node_type = CYAS_INVALID; - state = cy_as_hal_disable_interrupts(); - cy_as_hal_c_b_free(node); - cy_as_hal_enable_interrupts(state); -} - -cy_as_usb_func_c_b_node* -cy_as_create_usb_func_c_b_node( - cy_as_usb_function_callback cb, uint32_t client) -{ - uint32_t state = cy_as_hal_disable_interrupts(); - cy_as_usb_func_c_b_node *node = cy_as_hal_c_b_alloc( - sizeof(cy_as_usb_func_c_b_node)); - cy_as_hal_enable_interrupts(state); - if (node != 0) { - node->type = CYAS_USB_FUNC_CB; - node->cb_p = cb; - node->client_data = client; - node->next_p = 0; - } - return node; -} - -void -cy_as_destroy_usb_func_c_b_node(cy_as_usb_func_c_b_node *node) -{ - uint32_t state; - - node->type = CYAS_INVALID; - state = cy_as_hal_disable_interrupts(); - cy_as_hal_c_b_free(node); - cy_as_hal_enable_interrupts(state); -} - -cy_as_usb_io_c_b_node* -cy_as_create_usb_io_c_b_node(cy_as_usb_io_callback cb) -{ - uint32_t state = cy_as_hal_disable_interrupts(); - cy_as_usb_io_c_b_node *node = cy_as_hal_c_b_alloc( - sizeof(cy_as_usb_io_c_b_node)); - cy_as_hal_enable_interrupts(state); - if (node != 0) { - node->type = CYAS_USB_IO_CB; - node->cb_p = cb; - node->next_p = 0; - } - return node; -} - -void -cy_as_destroy_usb_io_c_b_node(cy_as_usb_io_c_b_node *node) -{ - uint32_t state; - - node->type = CYAS_INVALID; - - state = cy_as_hal_disable_interrupts(); - cy_as_hal_c_b_free(node); - cy_as_hal_enable_interrupts(state); -} - -cy_as_storage_io_c_b_node* -cy_as_create_storage_io_c_b_node(cy_as_storage_callback cb, - cy_as_media_type media, uint32_t device_index, - uint32_t unit, uint32_t block_addr, cy_as_oper_type oper, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p) -{ - uint32_t state = cy_as_hal_disable_interrupts(); - cy_as_storage_io_c_b_node *node = cy_as_hal_c_b_alloc( - sizeof(cy_as_storage_io_c_b_node)); - cy_as_hal_enable_interrupts(state); - if (node != 0) { - node->type = CYAS_STORAGE_IO_CB; - node->cb_p = cb; - node->media = media; - node->device_index = device_index; - node->unit = unit; - node->block_addr = block_addr; - node->oper = oper; - node->req_p = req_p; - node->reply_p = reply_p; - node->next_p = 0; - } - return node; -} - -void -cy_as_destroy_storage_io_c_b_node(cy_as_storage_io_c_b_node *node) -{ - uint32_t state; - node->type = CYAS_INVALID; - state = cy_as_hal_disable_interrupts(); - cy_as_hal_c_b_free(node); - cy_as_hal_enable_interrupts(state); -} - -cy_as_c_b_queue * -cy_as_create_c_b_queue(cy_as_c_b_node_type type) -{ - uint32_t state = cy_as_hal_disable_interrupts(); - cy_as_c_b_queue *queue = cy_as_hal_c_b_alloc( - sizeof(cy_as_c_b_queue)); - cy_as_hal_enable_interrupts(state); - if (queue) { - queue->type = type; - queue->head_p = 0; - queue->tail_p = 0; - queue->count = 0; - } - - return queue; -} - -void -cy_as_destroy_c_b_queue(cy_as_c_b_queue *queue) -{ - uint32_t state; - queue->type = CYAS_INVALID; - queue->head_p = 0; - queue->tail_p = 0; - queue->count = 0; - state = cy_as_hal_disable_interrupts(); - cy_as_hal_c_b_free(queue); - cy_as_hal_enable_interrupts(state); -} - -/* Inserts a CyAsCBNode into the queue, the - * node type must match the queue type*/ -void -cy_as_insert_c_b_node(cy_as_c_b_queue *queue_p, void*cbnode) -{ - uint32_t int_state; - - int_state = cy_as_hal_disable_interrupts(); - - cy_as_hal_assert(queue_p != 0); - - switch (queue_p->type) { - case CYAS_USB_FUNC_CB: - { - cy_as_usb_func_c_b_node *node = - (cy_as_usb_func_c_b_node *)cbnode; - cy_as_usb_func_c_b_node *tail = - (cy_as_usb_func_c_b_node *)queue_p->tail_p; - - cy_as_hal_assert(node->type == CYAS_USB_FUNC_CB); - cy_as_hal_assert(tail == 0 || - tail->type == CYAS_USB_FUNC_CB); - if (queue_p->head_p == 0) - queue_p->head_p = node; - else - tail->next_p = node; - - queue_p->tail_p = node; - } - break; - - case CYAS_USB_IO_CB: - { - cy_as_usb_io_c_b_node *node = - (cy_as_usb_io_c_b_node *)cbnode; - cy_as_usb_io_c_b_node *tail = - (cy_as_usb_io_c_b_node *)queue_p->tail_p; - - cy_as_hal_assert(node->type == CYAS_USB_IO_CB); - cy_as_hal_assert(tail == 0 || - tail->type == CYAS_USB_IO_CB); - if (queue_p->head_p == 0) - queue_p->head_p = node; - else - tail->next_p = node; - - queue_p->tail_p = node; - } - break; - - case CYAS_STORAGE_IO_CB: - { - cy_as_storage_io_c_b_node *node = - (cy_as_storage_io_c_b_node *)cbnode; - cy_as_storage_io_c_b_node *tail = - (cy_as_storage_io_c_b_node *)queue_p->tail_p; - - cy_as_hal_assert(node->type == CYAS_STORAGE_IO_CB); - cy_as_hal_assert(tail == 0 || - tail->type == CYAS_STORAGE_IO_CB); - if (queue_p->head_p == 0) - queue_p->head_p = node; - else - tail->next_p = node; - - queue_p->tail_p = node; - } - break; - - case CYAS_FUNC_CB: - { - cy_as_func_c_b_node *node = - (cy_as_func_c_b_node *)cbnode; - cy_as_func_c_b_node *tail = - (cy_as_func_c_b_node *)queue_p->tail_p; - - cy_as_hal_assert(node->node_type == CYAS_FUNC_CB); - cy_as_hal_assert(tail == 0 || - tail->node_type == CYAS_FUNC_CB); - if (queue_p->head_p == 0) - queue_p->head_p = node; - else - tail->next_p = node; - - queue_p->tail_p = node; - } - break; - - default: - cy_as_hal_assert(cy_false); - break; - } - - queue_p->count++; - - cy_as_hal_enable_interrupts(int_state); -} - -/* Removes the tail node from the queue and frees it */ -void -cy_as_remove_c_b_tail_node(cy_as_c_b_queue *queue_p) -{ - uint32_t int_state; - - int_state = cy_as_hal_disable_interrupts(); - - if (queue_p->count > 0) { - /* - * the worst case length of the queue should be - * under 10 elements, and the average case should - * be just 1 element. so, we just employ a linear - * search to find the node to be freed. - */ - switch (queue_p->type) { - case CYAS_FUNC_CB: - { - cy_as_func_c_b_node *node = - (cy_as_func_c_b_node *) - queue_p->head_p; - cy_as_func_c_b_node *tail = - (cy_as_func_c_b_node *) - queue_p->tail_p; - if (node != tail) { - while (node->next_p != tail) - node = node->next_p; - node->next_p = 0; - queue_p->tail_p = node; - } - cy_as_destroy_func_c_b_node(tail); - } - break; - - case CYAS_USB_FUNC_CB: - { - cy_as_usb_func_c_b_node *node = - (cy_as_usb_func_c_b_node *) - queue_p->head_p; - cy_as_usb_func_c_b_node *tail = - (cy_as_usb_func_c_b_node *) - queue_p->tail_p; - if (node != tail) { - while (node->next_p != tail) - node = node->next_p; - node->next_p = 0; - queue_p->tail_p = node; - } - - cy_as_destroy_usb_func_c_b_node(tail); - } - break; - - case CYAS_USB_IO_CB: - { - cy_as_usb_io_c_b_node *node = - (cy_as_usb_io_c_b_node *) - queue_p->head_p; - cy_as_usb_io_c_b_node *tail = - (cy_as_usb_io_c_b_node *) - queue_p->tail_p; - if (node != tail) { - while (node->next_p != tail) - node = node->next_p; - node->next_p = 0; - queue_p->tail_p = node; - } - cy_as_destroy_usb_io_c_b_node(tail); - } - break; - - case CYAS_STORAGE_IO_CB: - { - cy_as_storage_io_c_b_node *node = - (cy_as_storage_io_c_b_node *) - queue_p->head_p; - cy_as_storage_io_c_b_node *tail = - (cy_as_storage_io_c_b_node *) - queue_p->tail_p; - if (node != tail) { - while (node->next_p != tail) - node = node->next_p; - node->next_p = 0; - queue_p->tail_p = node; - } - cy_as_destroy_storage_io_c_b_node(tail); - } - break; - - default: - cy_as_hal_assert(cy_false); - } - - queue_p->count--; - if (queue_p->count == 0) { - queue_p->head_p = 0; - queue_p->tail_p = 0; - } - } - - cy_as_hal_enable_interrupts(int_state); -} - -/* Removes the first CyAsCBNode from the queue and frees it */ -void -cy_as_remove_c_b_node(cy_as_c_b_queue *queue_p) -{ - uint32_t int_state; - - int_state = cy_as_hal_disable_interrupts(); - - cy_as_hal_assert(queue_p->count >= 0); - if (queue_p->count > 0) { - if (queue_p->type == CYAS_USB_FUNC_CB) { - cy_as_usb_func_c_b_node *node = - (cy_as_usb_func_c_b_node *) - queue_p->head_p; - queue_p->head_p = node->next_p; - cy_as_destroy_usb_func_c_b_node(node); - } else if (queue_p->type == CYAS_USB_IO_CB) { - cy_as_usb_io_c_b_node *node = - (cy_as_usb_io_c_b_node *) - queue_p->head_p; - queue_p->head_p = node->next_p; - cy_as_destroy_usb_io_c_b_node(node); - } else if (queue_p->type == CYAS_STORAGE_IO_CB) { - cy_as_storage_io_c_b_node *node = - (cy_as_storage_io_c_b_node *) - queue_p->head_p; - queue_p->head_p = node->next_p; - cy_as_destroy_storage_io_c_b_node(node); - } else if (queue_p->type == CYAS_FUNC_CB) { - cy_as_func_c_b_node *node = - (cy_as_func_c_b_node *) - queue_p->head_p; - queue_p->head_p = node->next_p; - cy_as_destroy_func_c_b_node(node); - } else { - cy_as_hal_assert(cy_false); - } - - queue_p->count--; - if (queue_p->count == 0) { - queue_p->head_p = 0; - queue_p->tail_p = 0; - } - } - - cy_as_hal_enable_interrupts(int_state); -} - -void my_print_func_c_b_node(cy_as_func_c_b_node *node) -{ - cy_as_funct_c_b_type type = - cy_as_funct_c_b_type_get_type(node->data_type); - cy_as_hal_print_message("[cd:%2u dt:%2u cb:0x%08x " - "d:0x%08x nt:%1i]", node->client_data, type, - (uint32_t)node->cb_p, (uint32_t)node->data, - node->node_type); -} - -void my_print_c_b_queue(cy_as_c_b_queue *queue_p) -{ - uint32_t i = 0; - - cy_as_hal_print_message("| count: %u type: ", queue_p->count); - - if (queue_p->type == CYAS_USB_FUNC_CB) { - cy_as_hal_print_message("USB_FUNC_CB\n"); - } else if (queue_p->type == CYAS_USB_IO_CB) { - cy_as_hal_print_message("USB_IO_CB\n"); - } else if (queue_p->type == CYAS_STORAGE_IO_CB) { - cy_as_hal_print_message("STORAGE_IO_CB\n"); - } else if (queue_p->type == CYAS_FUNC_CB) { - cy_as_func_c_b_node *node = queue_p->head_p; - cy_as_hal_print_message("FUNC_CB\n"); - if (queue_p->count > 0) { - cy_as_hal_print_message("| head->"); - - for (i = 0; i < queue_p->count; i++) { - if (node) { - cy_as_hal_print_message("->"); - my_print_func_c_b_node(node); - node = node->next_p; - } else - cy_as_hal_print_message("->[NULL]\n"); - } - - cy_as_hal_print_message("\n| tail->"); - my_print_func_c_b_node(queue_p->tail_p); - cy_as_hal_print_message("\n"); - } - } else { - cy_as_hal_print_message("INVALID\n"); - } - - cy_as_hal_print_message("|----------\n"); -} - - -/* Removes and frees all pending callbacks */ -void -cy_as_clear_c_b_queue(cy_as_c_b_queue *queue_p) -{ - uint32_t int_state = cy_as_hal_disable_interrupts(); - - while (queue_p->count != 0) - cy_as_remove_c_b_node(queue_p); - - cy_as_hal_enable_interrupts(int_state); -} - -cy_as_return_status_t -cy_as_misc_send_request(cy_as_device *dev_p, - cy_as_function_callback cb, - uint32_t client, - cy_as_funct_c_b_type type, - void *data, - cy_as_c_b_queue *queue, - uint16_t req_type, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_response_callback rcb) -{ - - cy_as_func_c_b_node *cbnode = cy_as_create_func_c_b_node_data(cb, - client, type, data); - cy_as_return_status_t ret; - - if (cbnode == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - else - cy_as_insert_c_b_node(queue, cbnode); - - req_p->flags |= req_type; - - ret = cy_as_ll_send_request(dev_p, req_p, reply_p, cy_false, rcb); - if (ret != CY_AS_ERROR_SUCCESS) - cy_as_remove_c_b_tail_node(queue); - - return ret; -} - -void -cy_as_misc_cancel_ex_requests(cy_as_device *dev_p) -{ - int i; - for (i = 0; i < CY_RQT_CONTEXT_COUNT; i++) - cy_as_ll_remove_all_requests(dev_p, dev_p->context[i]); -} - - -static void -cy_as_misc_func_callback(cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t stat) -{ - cy_as_func_c_b_node *node = NULL; - cy_as_return_status_t ret; - - cy_bool ex_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_EX) - == CY_AS_REQUEST_RESPONSE_EX; - cy_bool ms_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_MS) - == CY_AS_REQUEST_RESPONSE_MS; - uint8_t code; - uint32_t type; - uint8_t cntxt; - - cy_as_hal_assert(ex_request || ms_request); - (void) ex_request; - (void) ms_request; - (void)context; - - cntxt = cy_as_ll_request_response__get_context(rqt); - code = cy_as_ll_request_response__get_code(rqt); - - switch (cntxt) { - case CY_RQT_GENERAL_RQT_CONTEXT: - cy_as_hal_assert(dev_p->func_cbs_misc->count != 0); - cy_as_hal_assert(dev_p->func_cbs_misc->type == CYAS_FUNC_CB); - node = (cy_as_func_c_b_node *)dev_p->func_cbs_misc->head_p; - type = cy_as_funct_c_b_type_get_type(node->data_type); - - switch (code) { - case CY_RQT_GET_FIRMWARE_VERSION: - cy_as_hal_assert(node->data != 0); - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_GETFIRMWAREVERSION); - ret = my_handle_response_get_firmware_version(dev_p, - rqt, resp, - (cy_as_get_firmware_version_data *)node->data); - break; - case CY_RQT_READ_MCU_REGISTER: - cy_as_hal_assert(node->data != 0); - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_READMCUREGISTER); - ret = my_handle_response_read_m_c_u_register(dev_p, rqt, - resp, (uint8_t *)node->data); - break; - case CY_RQT_GET_GPIO_STATE: - cy_as_hal_assert(node->data != 0); - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_GETGPIOVALUE); - ret = my_handle_response_get_gpio_value(dev_p, rqt, - resp, (uint8_t *)node->data); - break; - case CY_RQT_SET_SD_CLOCK_FREQ: - cy_as_hal_assert(type == CY_FUNCT_CB_MISC_SETSDFREQ); - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_CONTROL_ANTIOCH_HEARTBEAT: - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_HEARTBEATCONTROL); - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_WRITE_MCU_REGISTER: - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_WRITEMCUREGISTER); - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_STORAGE_MEDIA_CHANGED: - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_STORAGECHANGED); - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_SET_GPIO_STATE: - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_SETGPIOVALUE); - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_SET_TRACE_LEVEL: - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_SETTRACELEVEL); - ret = my_handle_response_no_data(dev_p, rqt, resp); - if (ret == CY_AS_ERROR_INVALID_RESPONSE) - ret = CY_AS_ERROR_NOT_SUPPORTED; - break; - case CY_RQT_PREPARE_FOR_STANDBY: - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_ENTERSTANDBY); - ret = my_handle_response_enter_standby(dev_p, rqt, resp, - (cy_bool)node->data); - break; - case CY_RQT_ENTER_SUSPEND_MODE: - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_ENTERSUSPEND); - ret = my_handle_response_no_data(dev_p, rqt, resp); - if (ret == CY_AS_ERROR_SUCCESS) - cy_as_device_set_suspend_mode(dev_p); - - break; - case CY_RQT_RESERVE_LNA_BOOT_AREA: - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_RESERVELNABOOTAREA); - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_SDPOLARITY: - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_SETSDPOLARITY); - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - default: - ret = CY_AS_ERROR_INVALID_RESPONSE; - cy_as_hal_assert(cy_false); - break; - } - break; - - case CY_RQT_RESOURCE_RQT_CONTEXT: - cy_as_hal_assert(dev_p->func_cbs_res->count != 0); - cy_as_hal_assert(dev_p->func_cbs_res->type == CYAS_FUNC_CB); - node = (cy_as_func_c_b_node *)dev_p->func_cbs_res->head_p; - type = cy_as_funct_c_b_type_get_type(node->data_type); - - switch (code) { - case CY_RQT_ACQUIRE_RESOURCE: - /* The node->data field is actually an enum value - * which could be 0, thus no assert is done */ - cy_as_hal_assert(type == - CY_FUNCT_CB_MISC_ACQUIRERESOURCE); - ret = my_handle_response_acquire_resource(dev_p, rqt, - resp, (cy_as_resource_type *)node->data); - break; - default: - ret = CY_AS_ERROR_INVALID_RESPONSE; - cy_as_hal_assert(cy_false); - break; - } - break; - - default: - ret = CY_AS_ERROR_INVALID_RESPONSE; - cy_as_hal_assert(cy_false); - break; - } - - /* - * if the low level layer returns a direct error, use the - * corresponding error code. if not, use the error code - * based on the response from firmware. - */ - if (stat == CY_AS_ERROR_SUCCESS) - stat = ret; - - /* Call the user Callback */ - node->cb_p((cy_as_device_handle)dev_p, stat, node->client_data, - node->data_type, node->data); - if (cntxt == CY_RQT_GENERAL_RQT_CONTEXT) - cy_as_remove_c_b_node(dev_p->func_cbs_misc); - else - cy_as_remove_c_b_node(dev_p->func_cbs_res); - -} - - - -/*[]*/ diff --git a/drivers/staging/westbridge/astoria/api/src/cyasmtp.c b/drivers/staging/westbridge/astoria/api/src/cyasmtp.c deleted file mode 100644 index 8598364f7ab7..000000000000 --- a/drivers/staging/westbridge/astoria/api/src/cyasmtp.c +++ /dev/null @@ -1,1136 +0,0 @@ -/* Cypress West Bridge API header file (cyasmtp.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#include "../../include/linux/westbridge/cyashal.h" -#include "../../include/linux/westbridge/cyasmtp.h" -#include "../../include/linux/westbridge/cyaserr.h" -#include "../../include/linux/westbridge/cyasdma.h" -#include "../../include/linux/westbridge/cyaslowlevel.h" - -static void -cy_as_mtp_func_callback(cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t stat); - -static cy_as_return_status_t -is_mtp_active(cy_as_device *dev_p) -{ - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - if (dev_p->mtp_count == 0) - return CY_AS_ERROR_NOT_RUNNING; - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - return CY_AS_ERROR_SUCCESS; -} - -static void -my_mtp_request_callback(cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *resp_p, - cy_as_return_status_t ret) -{ - uint16_t val, ev, status; - uint16_t mtp_datalen = 0; - uint32_t bytecount_l, bytecount_h; - cy_as_mtp_send_object_complete_data send_obj_data; - cy_as_mtp_get_object_complete_data get_obj_data; - cy_as_dma_end_point *ep_p; - - uint8_t code = cy_as_ll_request_response__get_code(req_p); - - (void)resp_p; - (void)context; - (void)ret; - - switch (code) { - case CY_RQT_MTP_EVENT: - val = cy_as_ll_request_response__get_word(req_p, 0); - /* MSB indicates status of read/write */ - status = (val >> 8) & 0xFF; - /* event type */ - ev = val & 0xFF; - switch (ev) { - case 0: /* SendObject Complete */ - { - bytecount_l = - cy_as_ll_request_response__get_word - (req_p, 1); - bytecount_h = - cy_as_ll_request_response__get_word - (req_p, 2); - send_obj_data.byte_count = - (bytecount_h << 16) | bytecount_l; - - send_obj_data.status = status; - - /* use the byte count again */ - bytecount_l = - cy_as_ll_request_response__get_word - (req_p, 3); - bytecount_h = - cy_as_ll_request_response__get_word - (req_p, 4); - send_obj_data.transaction_id = - (bytecount_h << 16) | bytecount_l; - - dev_p->mtp_turbo_active = cy_false; - - if (dev_p->mtp_event_cb) - dev_p->mtp_event_cb( - (cy_as_device_handle) dev_p, - cy_as_mtp_send_object_complete, - &send_obj_data); - } - break; - - case 1: /* GetObject Complete */ - { - bytecount_l = - cy_as_ll_request_response__get_word - (req_p, 1); - bytecount_h = - cy_as_ll_request_response__get_word - (req_p, 2); - - get_obj_data.byte_count = - (bytecount_h << 16) | bytecount_l; - - get_obj_data.status = status; - - dev_p->mtp_turbo_active = cy_false; - - if (dev_p->mtp_event_cb) - dev_p->mtp_event_cb( - (cy_as_device_handle) dev_p, - cy_as_mtp_get_object_complete, - &get_obj_data); - } - break; - - case 2: /* BlockTable Needed */ - { - if (dev_p->mtp_event_cb) - dev_p->mtp_event_cb( - (cy_as_device_handle) dev_p, - cy_as_mtp_block_table_needed, 0); - } - break; - default: - cy_as_hal_print_message("invalid event type\n"); - cy_as_ll_send_data_response(dev_p, - CY_RQT_TUR_RQT_CONTEXT, - CY_RESP_MTP_INVALID_EVENT, - sizeof(ev), &ev); - break; - } - break; - - case CY_RQT_TURBO_CMD_FROM_HOST: - { - mtp_datalen = - cy_as_ll_request_response__get_word(req_p, 1); - - /* Get the endpoint pointer based on - * the endpoint number */ - ep_p = CY_AS_NUM_EP(dev_p, CY_AS_MTP_READ_ENDPOINT); - - /* The event should arrive only after the DMA operation - * has been queued. */ - cy_as_hal_assert(ep_p->queue_p != 0); - - /* Put the len in ep data information in - * dmaqueue and kick start the queue */ - cy_as_hal_assert(ep_p->queue_p->size >= mtp_datalen); - - if (mtp_datalen == 0) { - cy_as_dma_completed_callback(dev_p->tag, - CY_AS_MTP_READ_ENDPOINT, 0, - CY_AS_ERROR_SUCCESS); - } else { - ep_p->maxhwdata = mtp_datalen; - - /* - * make sure that the DMA status for this - * EP is not running, so that the call to - * cy_as_dma_kick_start gets this transfer - * going. note: in MTP mode, we never leave - * a DMA transfer of greater than one packet - * running. so, it is okay to override the - * status here and start the next packet - * transfer. - */ - cy_as_dma_end_point_set_stopped(ep_p); - - /* Kick start the queue if it is not running */ - cy_as_dma_kick_start(dev_p, - CY_AS_MTP_READ_ENDPOINT); - } - } - break; - - case CY_RQT_TURBO_START_WRITE_DMA: - { - /* - * now that the firmware is ready to receive the - * next packet of data, start the corresponding - * DMA transfer. first, ensure that a DMA - * operation is still pending in the queue for the - * write endpoint. - */ - cy_as_ll_send_status_response(dev_p, - CY_RQT_TUR_RQT_CONTEXT, - CY_AS_ERROR_SUCCESS, 0); - - ep_p = CY_AS_NUM_EP(dev_p, CY_AS_MTP_WRITE_ENDPOINT); - cy_as_hal_assert(ep_p->queue_p != 0); - - cy_as_dma_end_point_set_stopped(ep_p); - cy_as_dma_kick_start(dev_p, CY_AS_MTP_WRITE_ENDPOINT); - } - break; - - default: - cy_as_hal_print_message("invalid request received " - "on TUR context\n"); - val = req_p->box0; - cy_as_ll_send_data_response(dev_p, CY_RQT_TUR_RQT_CONTEXT, - CY_RESP_INVALID_REQUEST, sizeof(val), &val); - break; - } -} - -static cy_as_return_status_t -my_handle_response_no_data(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -static cy_as_return_status_t -my_handle_response_mtp_start(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_return_status_t ret) -{ - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - dev_p->mtp_count++; - - cy_as_dma_enable_end_point(dev_p, CY_AS_MTP_READ_ENDPOINT, - cy_true, cy_as_direction_out); - dev_p->usb_config[CY_AS_MTP_READ_ENDPOINT].enabled = cy_true; - dev_p->usb_config[CY_AS_MTP_READ_ENDPOINT].dir = cy_as_usb_out; - dev_p->usb_config[CY_AS_MTP_READ_ENDPOINT].type = cy_as_usb_bulk; - - cy_as_dma_enable_end_point(dev_p, CY_AS_MTP_WRITE_ENDPOINT, - cy_true, cy_as_direction_in); - dev_p->usb_config[CY_AS_MTP_WRITE_ENDPOINT].enabled = cy_true; - dev_p->usb_config[CY_AS_MTP_WRITE_ENDPOINT].dir = cy_as_usb_in; - dev_p->usb_config[CY_AS_MTP_WRITE_ENDPOINT].type = cy_as_usb_bulk; - - /* Packet size is 512 bytes */ - cy_as_dma_set_max_dma_size(dev_p, 0x02, 0x0200); - /* Packet size is 64 bytes until a switch to high speed happens.*/ - cy_as_dma_set_max_dma_size(dev_p, 0x06, 0x40); - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - if (ret != CY_AS_ERROR_SUCCESS) - cy_as_ll_register_request_callback(dev_p, - CY_RQT_TUR_RQT_CONTEXT, 0); - - cy_as_device_clear_m_s_s_pending(dev_p); - - return ret; -} - - -cy_as_return_status_t -cy_as_mtp_start(cy_as_device_handle handle, - cy_as_mtp_event_callback event_c_b, - cy_as_function_callback cb, - uint32_t client - ) -{ - cy_as_ll_request_response *req_p, *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_device *dev_p; - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - if (cy_as_device_is_m_s_s_pending(dev_p)) - return CY_AS_ERROR_STARTSTOP_PENDING; - - if (dev_p->storage_count == 0) - return CY_AS_ERROR_NOT_RUNNING; - - if (dev_p->usb_count == 0) - return CY_AS_ERROR_NOT_RUNNING; - - if (dev_p->is_mtp_firmware == 0) - return CY_AS_ERROR_NOT_SUPPORTED; - - cy_as_device_set_m_s_s_pending(dev_p); - - if (dev_p->mtp_count == 0) { - - dev_p->mtp_event_cb = event_c_b; - /* - * we register here because the start request may cause - * events to occur before the response to the start request. - */ - cy_as_ll_register_request_callback(dev_p, - CY_RQT_TUR_RQT_CONTEXT, my_mtp_request_callback); - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_START_MTP, CY_RQT_TUR_RQT_CONTEXT, 0); - if (req_p == 0) { - cy_as_device_clear_m_s_s_pending(dev_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - /* Reserve space for the reply, the reply data will - * not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_device_clear_m_s_s_pending(dev_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_mtp_start(dev_p, req_p, - reply_p, ret); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MTP_START, 0, dev_p->func_cbs_mtp, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_mtp_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - } else { - dev_p->mtp_count++; - if (cb) - cb(handle, ret, client, CY_FUNCT_CB_MTP_START, 0); - } - - cy_as_device_clear_m_s_s_pending(dev_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_mtp_start); - -static cy_as_return_status_t -my_handle_response_mtp_stop(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_return_status_t ret) -{ - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* - * we successfully shutdown the stack, so decrement - * to make the count zero. - */ - dev_p->mtp_count--; - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - if (ret != CY_AS_ERROR_SUCCESS) - cy_as_ll_register_request_callback(dev_p, - CY_RQT_TUR_RQT_CONTEXT, 0); - - cy_as_device_clear_m_s_s_pending(dev_p); - - return ret; -} - -cy_as_return_status_t -cy_as_mtp_stop(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client - ) -{ - cy_as_ll_request_response *req_p = 0, *reply_p = 0; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_mtp_stop called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_mtp_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - if (cy_as_device_is_m_s_s_pending(dev_p)) - return CY_AS_ERROR_STARTSTOP_PENDING; - - cy_as_device_set_m_s_s_pending(dev_p); - - if (dev_p->mtp_count == 1) { - /* Create the request to send to the West - * Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_STOP_MTP, - CY_RQT_TUR_RQT_CONTEXT, 0); - if (req_p == 0) { - ret = CY_AS_ERROR_OUT_OF_MEMORY; - goto destroy; - } - - /* Reserve space for the reply, the reply data will - * not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - ret = CY_AS_ERROR_OUT_OF_MEMORY; - goto destroy; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_mtp_stop(dev_p, req_p, - reply_p, ret); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MTP_STOP, 0, dev_p->func_cbs_mtp, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_mtp_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - } else if (dev_p->mtp_count > 1) { - - dev_p->mtp_count--; - - if (cb) - cb(handle, ret, client, CY_FUNCT_CB_MTP_STOP, 0); - } - - cy_as_device_clear_m_s_s_pending(dev_p); - - return ret; -} - -static void -mtp_write_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t ret) -{ - cy_as_hal_assert(context == CY_RQT_TUR_RQT_CONTEXT); - - if (ret == CY_AS_ERROR_SUCCESS) { - if (cy_as_ll_request_response__get_code(resp) != - CY_RESP_SUCCESS_FAILURE) - ret = CY_AS_ERROR_INVALID_RESPONSE; - else - ret = cy_as_ll_request_response__get_word(resp, 0); - } - - if (ret != CY_AS_ERROR_SUCCESS) { - /* Firmware failed the request. Cancel the DMA transfer. */ - cy_as_dma_cancel(dev_p, 0x04, CY_AS_ERROR_CANCELED); - cy_as_device_clear_storage_async_pending(dev_p); - } - - cy_as_ll_destroy_response(dev_p, resp); - cy_as_ll_destroy_request(dev_p, rqt); -} - -static void -async_write_request_callback(cy_as_device *dev_p, - cy_as_end_point_number_t ep, void *buf_p, uint32_t size, - cy_as_return_status_t err) -{ - cy_as_device_handle h; - cy_as_function_callback cb; - - (void)size; - (void)buf_p; - (void)ep; - - - cy_as_log_debug_message(6, "async_write_request_callback called"); - - h = (cy_as_device_handle)dev_p; - - cb = dev_p->mtp_cb; - dev_p->mtp_cb = 0; - - cy_as_device_clear_storage_async_pending(dev_p); - - if (cb) - cb(h, err, dev_p->mtp_client, dev_p->mtp_op, 0); - -} - -static void -sync_mtp_callback(cy_as_device *dev_p, cy_as_end_point_number_t ep, - void *buf_p, uint32_t size, cy_as_return_status_t err) -{ - (void)ep; - (void)buf_p; - (void)size; - - dev_p->mtp_error = err; -} - -static cy_as_return_status_t -cy_as_mtp_operation(cy_as_device *dev_p, - cy_as_mtp_block_table *blk_table, - uint32_t num_bytes, - uint32_t transaction_id, - cy_as_function_callback cb, - uint32_t client, - uint8_t rqttype - ) -{ - cy_as_ll_request_response *req_p = 0, *reply_p = 0; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint32_t mask = 0; - cy_as_funct_c_b_type mtp_cb_op = 0; - uint16_t size = 2; - - if (dev_p->mtp_count == 0) - return CY_AS_ERROR_NOT_RUNNING; - - if (rqttype == CY_RQT_INIT_SEND_OBJECT) { - mtp_cb_op = CY_FUNCT_CB_MTP_INIT_SEND_OBJECT; - dev_p->mtp_turbo_active = cy_true; - } else if (rqttype == CY_RQT_INIT_GET_OBJECT) { - mtp_cb_op = CY_FUNCT_CB_MTP_INIT_GET_OBJECT; - dev_p->mtp_turbo_active = cy_true; - } else - mtp_cb_op = CY_FUNCT_CB_MTP_SEND_BLOCK_TABLE; - - ret = is_mtp_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (CY_RQT_INIT_GET_OBJECT == rqttype) - size = 4; - - /* Create the request to send to the West - * Bridge device */ - req_p = cy_as_ll_create_request(dev_p, rqttype, - CY_RQT_TUR_RQT_CONTEXT, size); - if (req_p == 0) { - ret = CY_AS_ERROR_OUT_OF_MEMORY; - goto destroy; - } - - /* Reserve space for the reply, the reply data will - * not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - ret = CY_AS_ERROR_OUT_OF_MEMORY; - goto destroy; - } - - cy_as_ll_request_response__set_word(req_p, 0, - (uint16_t)(num_bytes & 0xFFFF)); - cy_as_ll_request_response__set_word(req_p, 1, - (uint16_t)((num_bytes >> 16) & 0xFFFF)); - - /* If it is GET_OBJECT, send transaction id as well*/ - if (CY_RQT_INIT_GET_OBJECT == rqttype) { - cy_as_ll_request_response__set_word(req_p, 2, - (uint16_t)(transaction_id & 0xFFFF)); - cy_as_ll_request_response__set_word(req_p, 3, - (uint16_t)((transaction_id >> 16) & 0xFFFF)); - } - - if (cb == 0) { - /* Queue the DMA request for block table write */ - ret = cy_as_dma_queue_request(dev_p, 4, blk_table, - sizeof(cy_as_mtp_block_table), cy_false, - cy_false, sync_mtp_callback); - - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_dma_cancel(dev_p, 4, CY_AS_ERROR_CANCELED); - cy_as_device_clear_storage_async_pending(dev_p); - - goto destroy; - } - - ret = cy_as_dma_drain_queue(dev_p, 4, cy_true); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - ret = dev_p->mtp_error; - goto destroy; - } else { -#if 0 - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MTP_INIT_SEND_OBJECT, - 0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_mtp_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; -#endif - - /* Protection from interrupt driven code */ - /* since we are using storage EP4 check if any - * storage activity is pending */ - mask = cy_as_hal_disable_interrupts(); - if ((cy_as_device_is_storage_async_pending(dev_p)) || - (dev_p->storage_wait)) { - cy_as_hal_enable_interrupts(mask); - return CY_AS_ERROR_ASYNC_PENDING; - } - cy_as_device_set_storage_async_pending(dev_p); - cy_as_hal_enable_interrupts(mask); - - dev_p->mtp_cb = cb; - dev_p->mtp_client = client; - dev_p->mtp_op = mtp_cb_op; - - ret = cy_as_ll_send_request(dev_p, req_p, reply_p, - cy_false, mtp_write_callback); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - ret = cy_as_dma_queue_request(dev_p, 4, blk_table, - sizeof(cy_as_mtp_block_table), cy_false, cy_false, - async_write_request_callback); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* Kick start the queue if it is not running */ - cy_as_dma_kick_start(dev_p, 4); - - return CY_AS_ERROR_SUCCESS; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_mtp_init_send_object(cy_as_device_handle handle, - cy_as_mtp_block_table *blk_table, - uint32_t num_bytes, - cy_as_function_callback cb, - uint32_t client - ) -{ - cy_as_device *dev_p; - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - return cy_as_mtp_operation(dev_p, blk_table, num_bytes, 0, cb, - client, CY_RQT_INIT_SEND_OBJECT); - -} -EXPORT_SYMBOL(cy_as_mtp_init_send_object); - -cy_as_return_status_t -cy_as_mtp_init_get_object(cy_as_device_handle handle, - cy_as_mtp_block_table *blk_table, - uint32_t num_bytes, - uint32_t transaction_id, - cy_as_function_callback cb, - uint32_t client - ) -{ - cy_as_device *dev_p; - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - return cy_as_mtp_operation(dev_p, blk_table, num_bytes, - transaction_id, cb, client, CY_RQT_INIT_GET_OBJECT); - -} -EXPORT_SYMBOL(cy_as_mtp_init_get_object); - -static cy_as_return_status_t -my_handle_response_cancel_send_object(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_return_status_t ret) -{ - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_mtp_cancel_send_object(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client - ) -{ - cy_as_ll_request_response *req_p = 0, *reply_p = 0; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_device *dev_p; - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (dev_p->mtp_count == 0) - return CY_AS_ERROR_NOT_RUNNING; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_CANCEL_SEND_OBJECT, CY_RQT_TUR_RQT_CONTEXT, 0); - if (req_p == 0) { - ret = CY_AS_ERROR_OUT_OF_MEMORY; - goto destroy; - } - - /* Reserve space for the reply, the reply data will - * not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - ret = CY_AS_ERROR_OUT_OF_MEMORY; - goto destroy; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_cancel_send_object(dev_p, - req_p, reply_p, ret); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MTP_CANCEL_SEND_OBJECT, 0, - dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_mtp_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_mtp_cancel_send_object); - -static cy_as_return_status_t -my_handle_response_cancel_get_object(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_return_status_t ret) -{ - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_mtp_cancel_get_object(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client - ) -{ - cy_as_ll_request_response *req_p = 0, *reply_p = 0; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_device *dev_p; - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (dev_p->mtp_count == 0) - return CY_AS_ERROR_NOT_RUNNING; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_CANCEL_GET_OBJECT, - CY_RQT_TUR_RQT_CONTEXT, 0); - if (req_p == 0) { - ret = CY_AS_ERROR_OUT_OF_MEMORY; - goto destroy; - } - - /* Reserve space for the reply, the reply data will - * not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - ret = CY_AS_ERROR_OUT_OF_MEMORY; - goto destroy; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_cancel_get_object(dev_p, - req_p, reply_p, ret); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MTP_CANCEL_GET_OBJECT, 0, - dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_mtp_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_mtp_cancel_get_object); - -cy_as_return_status_t -cy_as_mtp_send_block_table(cy_as_device_handle handle, - cy_as_mtp_block_table *blk_table, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p; - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - return cy_as_mtp_operation(dev_p, blk_table, 0, 0, cb, - client, CY_RQT_SEND_BLOCK_TABLE); -} - -static void -cy_as_mtp_func_callback(cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t stat) -{ - cy_as_func_c_b_node* node = (cy_as_func_c_b_node *) - dev_p->func_cbs_mtp->head_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint8_t code; - cy_bool delay_callback = cy_false; - - cy_as_hal_assert(dev_p->func_cbs_mtp->count != 0); - cy_as_hal_assert(dev_p->func_cbs_mtp->type == CYAS_FUNC_CB); - - (void)context; - - /* The Handlers are responsible for Deleting the - * rqt and resp when they are finished - */ - code = cy_as_ll_request_response__get_code(rqt); - switch (code) { - case CY_RQT_START_MTP: - ret = my_handle_response_mtp_start(dev_p, rqt, - resp, stat); - break; - case CY_RQT_STOP_MTP: - ret = my_handle_response_mtp_stop(dev_p, rqt, - resp, stat); - break; -#if 0 - case CY_RQT_INIT_SEND_OBJECT: - ret = my_handle_response_init_send_object(dev_p, - rqt, resp, stat, cy_true); - delay_callback = cy_true; - break; -#endif - case CY_RQT_CANCEL_SEND_OBJECT: - ret = my_handle_response_cancel_send_object(dev_p, - rqt, resp, stat); - break; -#if 0 - case CY_RQT_INIT_GET_OBJECT: - ret = my_handle_response_init_get_object(dev_p, - rqt, resp, stat, cy_true); - delay_callback = cy_true; - break; -#endif - case CY_RQT_CANCEL_GET_OBJECT: - ret = my_handle_response_cancel_get_object(dev_p, - rqt, resp, stat); - break; -#if 0 - case CY_RQT_SEND_BLOCK_TABLE: - ret = my_handle_response_send_block_table(dev_p, rqt, - resp, stat, cy_true); - delay_callback = cy_true; - break; -#endif - case CY_RQT_ENABLE_USB_PATH: - ret = my_handle_response_no_data(dev_p, rqt, resp); - if (ret == CY_AS_ERROR_SUCCESS) - dev_p->is_storage_only_mode = cy_false; - break; - default: - ret = CY_AS_ERROR_INVALID_RESPONSE; - cy_as_hal_assert(cy_false); - break; - } - - /* - * if the low level layer returns a direct error, use the - * corresponding error code. if not, use the error code - * based on the response from firmware. - */ - if (stat == CY_AS_ERROR_SUCCESS) - stat = ret; - - if (!delay_callback) { - node->cb_p((cy_as_device_handle)dev_p, stat, node->client_data, - node->data_type, node->data); - cy_as_remove_c_b_node(dev_p->func_cbs_mtp); - } -} - -cy_as_return_status_t -cy_as_mtp_storage_only_start(cy_as_device_handle handle) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - if (dev_p->storage_count == 0) - return CY_AS_ERROR_NOT_RUNNING; - - dev_p->is_storage_only_mode = cy_true; - return CY_AS_ERROR_SUCCESS; -} -EXPORT_SYMBOL(cy_as_mtp_storage_only_start); - -cy_as_return_status_t -cy_as_mtp_storage_only_stop(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - cy_as_ll_request_response *req_p, *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - if (dev_p->storage_count == 0) - return CY_AS_ERROR_NOT_RUNNING; - - if (dev_p->is_storage_only_mode == cy_false) - return CY_AS_ERROR_SUCCESS; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_ENABLE_USB_PATH, CY_RQT_TUR_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - ret = my_handle_response_no_data(dev_p, req_p, - reply_p); - if (ret == CY_AS_ERROR_SUCCESS) - dev_p->is_storage_only_mode = cy_false; - return ret; - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_MTP_STOP_STORAGE_ONLY, 0, - dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_mtp_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_mtp_storage_only_stop); - diff --git a/drivers/staging/westbridge/astoria/api/src/cyasstorage.c b/drivers/staging/westbridge/astoria/api/src/cyasstorage.c deleted file mode 100644 index 7abd6a35e828..000000000000 --- a/drivers/staging/westbridge/astoria/api/src/cyasstorage.c +++ /dev/null @@ -1,4125 +0,0 @@ -/* Cypress West Bridge API source file (cyasstorage.c) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -/* -* Storage Design -* -* The storage module is fairly straight forward once the -* DMA and LOWLEVEL modules have been designed. The -* storage module simple takes requests from the user, queues -* the associated DMA requests for action, and then sends -* the low level requests to the West Bridge firmware. -* -*/ - -#include "../../include/linux/westbridge/cyashal.h" -#include "../../include/linux/westbridge/cyasstorage.h" -#include "../../include/linux/westbridge/cyaserr.h" -#include "../../include/linux/westbridge/cyasdevice.h" -#include "../../include/linux/westbridge/cyaslowlevel.h" -#include "../../include/linux/westbridge/cyasdma.h" -#include "../../include/linux/westbridge/cyasregs.h" - -/* Map a pre-V1.2 media type to the V1.2+ bus number */ -cy_as_return_status_t -cy_an_map_bus_from_media_type(cy_as_device *dev_p, - cy_as_media_type type, cy_as_bus_number_t *bus) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint8_t code = (uint8_t)(1 << type); - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - - if (dev_p->media_supported[0] & code) { - if (dev_p->media_supported[1] & code) { - /* - * this media type could be supported on multiple - * buses. so, report an address resolution error. - */ - ret = CY_AS_ERROR_ADDRESS_RESOLUTION_ERROR; - } else - *bus = 0; - } else { - if (dev_p->media_supported[1] & code) - *bus = 1; - else - ret = CY_AS_ERROR_NO_SUCH_MEDIA; - } - - return ret; -} - -static uint16_t -create_address(cy_as_bus_number_t bus, uint32_t device, uint8_t unit) -{ - cy_as_hal_assert(bus >= 0 && bus < CY_AS_MAX_BUSES); - cy_as_hal_assert(device < 16); - - return (uint16_t)(((uint8_t)bus << 12) | (device << 8) | unit); -} - -cy_as_media_type -cy_as_storage_get_media_from_address(uint16_t v) -{ - cy_as_media_type media = cy_as_media_max_media_value; - - switch (v & 0xFF) { - case 0x00: - break; - case 0x01: - media = cy_as_media_nand; - break; - case 0x02: - media = cy_as_media_sd_flash; - break; - case 0x04: - media = cy_as_media_mmc_flash; - break; - case 0x08: - media = cy_as_media_ce_ata; - break; - case 0x10: - media = cy_as_media_sdio; - break; - default: - cy_as_hal_assert(0); - break; - } - - return media; -} - -cy_as_bus_number_t -cy_as_storage_get_bus_from_address(uint16_t v) -{ - cy_as_bus_number_t bus = (cy_as_bus_number_t)((v >> 12) & 0x0f); - cy_as_hal_assert(bus >= 0 && bus < CY_AS_MAX_BUSES); - return bus; -} - -uint32_t -cy_as_storage_get_device_from_address(uint16_t v) -{ - return (uint32_t)((v >> 8) & 0x0f); -} - -static uint8_t -get_unit_from_address(uint16_t v) -{ - return (uint8_t)(v & 0xff); -} - -static cy_as_return_status_t -cy_as_map_bad_addr(uint16_t val) -{ - cy_as_return_status_t ret = CY_AS_ERROR_INVALID_RESPONSE; - - switch (val) { - case 0: - ret = CY_AS_ERROR_NO_SUCH_BUS; - break; - case 1: - ret = CY_AS_ERROR_NO_SUCH_DEVICE; - break; - case 2: - ret = CY_AS_ERROR_NO_SUCH_UNIT; - break; - case 3: - ret = CY_AS_ERROR_INVALID_BLOCK; - break; - } - - return ret; -} - -static void -my_storage_request_callback(cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *resp_p, - cy_as_return_status_t ret) -{ - uint16_t val; - uint16_t addr; - cy_as_bus_number_t bus; - uint32_t device; - cy_as_device_handle h = (cy_as_device_handle)dev_p; - cy_as_dma_end_point *ep_p = NULL; - - (void)resp_p; - (void)context; - (void)ret; - - switch (cy_as_ll_request_response__get_code(req_p)) { - case CY_RQT_MEDIA_CHANGED: - cy_as_ll_send_status_response(dev_p, - CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); - - /* Media has either been inserted or removed */ - addr = cy_as_ll_request_response__get_word(req_p, 0); - - bus = cy_as_storage_get_bus_from_address(addr); - device = cy_as_storage_get_device_from_address(addr); - - /* Clear the entry for this device to force re-query later */ - cy_as_hal_mem_set(&(dev_p->storage_device_info[bus][device]), 0, - sizeof(dev_p->storage_device_info[bus][device])); - - val = cy_as_ll_request_response__get_word(req_p, 1); - if (dev_p->storage_event_cb_ms) { - if (val == 1) - dev_p->storage_event_cb_ms(h, bus, - device, cy_as_storage_removed, 0); - else - dev_p->storage_event_cb_ms(h, bus, - device, cy_as_storage_inserted, 0); - } else if (dev_p->storage_event_cb) { - if (val == 1) - dev_p->storage_event_cb(h, bus, - cy_as_storage_removed, 0); - else - dev_p->storage_event_cb(h, bus, - cy_as_storage_inserted, 0); - } - - break; - - case CY_RQT_ANTIOCH_CLAIM: - cy_as_ll_send_status_response(dev_p, - CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); - if (dev_p->storage_event_cb || dev_p->storage_event_cb_ms) { - val = cy_as_ll_request_response__get_word(req_p, 0); - if (dev_p->storage_event_cb_ms) { - if (val & 0x0100) - dev_p->storage_event_cb_ms(h, 0, 0, - cy_as_storage_antioch, 0); - if (val & 0x0200) - dev_p->storage_event_cb_ms(h, 1, 0, - cy_as_storage_antioch, 0); - } else { - if (val & 0x01) - dev_p->storage_event_cb(h, - cy_as_media_nand, - cy_as_storage_antioch, 0); - if (val & 0x02) - dev_p->storage_event_cb(h, - cy_as_media_sd_flash, - cy_as_storage_antioch, 0); - if (val & 0x04) - dev_p->storage_event_cb(h, - cy_as_media_mmc_flash, - cy_as_storage_antioch, 0); - if (val & 0x08) - dev_p->storage_event_cb(h, - cy_as_media_ce_ata, - cy_as_storage_antioch, 0); - } - } - break; - - case CY_RQT_ANTIOCH_RELEASE: - cy_as_ll_send_status_response(dev_p, - CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); - val = cy_as_ll_request_response__get_word(req_p, 0); - if (dev_p->storage_event_cb_ms) { - if (val & 0x0100) - dev_p->storage_event_cb_ms(h, 0, 0, - cy_as_storage_processor, 0); - if (val & 0x0200) - dev_p->storage_event_cb_ms(h, 1, 0, - cy_as_storage_processor, 0); - } else if (dev_p->storage_event_cb) { - if (val & 0x01) - dev_p->storage_event_cb(h, - cy_as_media_nand, - cy_as_storage_processor, 0); - if (val & 0x02) - dev_p->storage_event_cb(h, - cy_as_media_sd_flash, - cy_as_storage_processor, 0); - if (val & 0x04) - dev_p->storage_event_cb(h, - cy_as_media_mmc_flash, - cy_as_storage_processor, 0); - if (val & 0x08) - dev_p->storage_event_cb(h, - cy_as_media_ce_ata, - cy_as_storage_processor, 0); - } - break; - - - case CY_RQT_SDIO_INTR: - cy_as_ll_send_status_response(dev_p, - CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); - val = cy_as_ll_request_response__get_word(req_p, 0); - if (dev_p->storage_event_cb_ms) { - if (val & 0x0100) - dev_p->storage_event_cb_ms(h, 1, 0, - cy_as_sdio_interrupt, 0); - else - dev_p->storage_event_cb_ms(h, 0, 0, - cy_as_sdio_interrupt, 0); - - } else if (dev_p->storage_event_cb) { - dev_p->storage_event_cb(h, - cy_as_media_sdio, cy_as_sdio_interrupt, 0); - } - break; - - case CY_RQT_P2S_DMA_START: - /* Do the DMA setup for the waiting operation. */ - cy_as_ll_send_status_response(dev_p, - CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); - cy_as_device_set_p2s_dma_start_recvd(dev_p); - if (dev_p->storage_oper == cy_as_op_read) { - ep_p = CY_AS_NUM_EP(dev_p, CY_AS_P2S_READ_ENDPOINT); - cy_as_dma_end_point_set_stopped(ep_p); - cy_as_dma_kick_start(dev_p, CY_AS_P2S_READ_ENDPOINT); - } else { - ep_p = CY_AS_NUM_EP(dev_p, CY_AS_P2S_WRITE_ENDPOINT); - cy_as_dma_end_point_set_stopped(ep_p); - cy_as_dma_kick_start(dev_p, CY_AS_P2S_WRITE_ENDPOINT); - } - break; - - default: - cy_as_hal_print_message("invalid request received " - "on storage context\n"); - val = req_p->box0; - cy_as_ll_send_data_response(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, - CY_RESP_INVALID_REQUEST, sizeof(val), &val); - break; - } -} - -static cy_as_return_status_t -is_storage_active(cy_as_device *dev_p) -{ - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - if (dev_p->storage_count == 0) - return CY_AS_ERROR_NOT_RUNNING; - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - return CY_AS_ERROR_SUCCESS; -} - -static void -cy_as_storage_func_callback(cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t ret); - -static cy_as_return_status_t -my_handle_response_no_data(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -static cy_as_return_status_t -my_handle_response_storage_start(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_return_status_t ret) -{ - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - if (dev_p->storage_count > 0 && ret == - CY_AS_ERROR_ALREADY_RUNNING) - ret = CY_AS_ERROR_SUCCESS; - - ret = cy_as_dma_enable_end_point(dev_p, - CY_AS_P2S_WRITE_ENDPOINT, cy_true, cy_as_direction_in); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - ret = cy_as_dma_set_max_dma_size(dev_p, - CY_AS_P2S_WRITE_ENDPOINT, CY_AS_STORAGE_EP_SIZE); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - ret = cy_as_dma_enable_end_point(dev_p, - CY_AS_P2S_READ_ENDPOINT, cy_true, cy_as_direction_out); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - ret = cy_as_dma_set_max_dma_size(dev_p, - CY_AS_P2S_READ_ENDPOINT, CY_AS_STORAGE_EP_SIZE); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - cy_as_ll_register_request_callback(dev_p, - CY_RQT_STORAGE_RQT_CONTEXT, my_storage_request_callback); - - /* Create the request/response used for storage reads and writes. */ - dev_p->storage_rw_req_p = cy_as_ll_create_request(dev_p, - 0, CY_RQT_STORAGE_RQT_CONTEXT, 5); - if (dev_p->storage_rw_req_p == 0) { - ret = CY_AS_ERROR_OUT_OF_MEMORY; - goto destroy; - } - - dev_p->storage_rw_resp_p = cy_as_ll_create_response(dev_p, 5); - if (dev_p->storage_rw_resp_p == 0) { - cy_as_ll_destroy_request(dev_p, dev_p->storage_rw_req_p); - ret = CY_AS_ERROR_OUT_OF_MEMORY; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - /* Increment the storage count only if - * the above functionality succeeds.*/ - if (ret == CY_AS_ERROR_SUCCESS) { - if (dev_p->storage_count == 0) { - cy_as_hal_mem_set(dev_p->storage_device_info, - 0, sizeof(dev_p->storage_device_info)); - dev_p->is_storage_only_mode = cy_false; - } - - dev_p->storage_count++; - } - - cy_as_device_clear_s_s_s_pending(dev_p); - - return ret; -} - -cy_as_return_status_t -cy_as_storage_start(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p, *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_device *dev_p = (cy_as_device *)handle; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - if (cy_as_device_is_s_s_s_pending(dev_p)) - return CY_AS_ERROR_STARTSTOP_PENDING; - - cy_as_device_set_s_s_s_pending(dev_p); - - if (dev_p->storage_count == 0) { - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_START_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1); - if (req_p == 0) { - cy_as_device_clear_s_s_s_pending(dev_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - /* Reserve space for the reply, the reply data - * will not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_device_clear_s_s_s_pending(dev_p); - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_storage_start(dev_p, - req_p, reply_p, ret); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_STOR_START, 0, dev_p->func_cbs_stor, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as - * part of the FuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - } else { - dev_p->storage_count++; - if (cb) - cb(handle, ret, client, CY_FUNCT_CB_STOR_START, 0); - } - - cy_as_device_clear_s_s_s_pending(dev_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_storage_start); - -static cy_as_return_status_t -my_handle_response_storage_stop(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_return_status_t ret) -{ - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - if (ret == CY_AS_ERROR_SUCCESS) { - cy_as_ll_destroy_request(dev_p, dev_p->storage_rw_req_p); - cy_as_ll_destroy_response(dev_p, dev_p->storage_rw_resp_p); - dev_p->storage_count--; - } - - cy_as_device_clear_s_s_s_pending(dev_p); - - return ret; -} -cy_as_return_status_t -cy_as_storage_stop(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_as_device *dev_p = (cy_as_device *)handle; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_storage_async_pending(dev_p)) - return CY_AS_ERROR_ASYNC_PENDING; - - if (cy_as_device_is_s_s_s_pending(dev_p)) - return CY_AS_ERROR_STARTSTOP_PENDING; - - cy_as_device_set_s_s_s_pending(dev_p); - - if (dev_p->storage_count == 1) { - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_STOP_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 0); - if (req_p == 0) { - cy_as_device_clear_s_s_s_pending(dev_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - /* Reserve space for the reply, the reply data - * will not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_device_clear_s_s_s_pending(dev_p); - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_storage_stop(dev_p, - req_p, reply_p, ret); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_STOR_STOP, 0, dev_p->func_cbs_stor, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed - * as part of the MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - } else if (dev_p->storage_count > 1) { - dev_p->storage_count--; - if (cb) - cb(handle, ret, client, CY_FUNCT_CB_STOR_STOP, 0); - } - - cy_as_device_clear_s_s_s_pending(dev_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_storage_stop); - -cy_as_return_status_t -cy_as_storage_register_callback(cy_as_device_handle handle, - cy_as_storage_event_callback callback) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - if (dev_p->storage_count == 0) - return CY_AS_ERROR_NOT_RUNNING; - - dev_p->storage_event_cb = NULL; - dev_p->storage_event_cb_ms = callback; - - return CY_AS_ERROR_SUCCESS; -} -EXPORT_SYMBOL(cy_as_storage_register_callback); - - -static cy_as_return_status_t -my_handle_response_storage_claim(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (cy_as_ll_request_response__get_code(reply_p) == - CY_RESP_NO_SUCH_ADDRESS) { - ret = cy_as_map_bad_addr( - cy_as_ll_request_response__get_word(reply_p, 3)); - goto destroy; - } - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_MEDIA_CLAIMED_RELEASED) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - /* The response must be about the address I am - * trying to claim or the firmware is broken */ - if ((cy_as_storage_get_bus_from_address( - cy_as_ll_request_response__get_word(req_p, 0)) != - cy_as_storage_get_bus_from_address( - cy_as_ll_request_response__get_word(reply_p, 0))) || - (cy_as_storage_get_device_from_address( - cy_as_ll_request_response__get_word(req_p, 0)) != - cy_as_storage_get_device_from_address( - cy_as_ll_request_response__get_word(reply_p, 0)))) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - if (cy_as_ll_request_response__get_word(reply_p, 1) != 1) - ret = CY_AS_ERROR_NOT_ACQUIRED; - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -static cy_as_return_status_t -my_storage_claim(cy_as_device *dev_p, - void *data, - cy_as_bus_number_t bus, - uint32_t device, - uint16_t req_flags, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (dev_p->mtp_count > 0) - return CY_AS_ERROR_NOT_VALID_IN_MTP; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_CLAIM_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, - 0, create_address(bus, device, 0)); - - /* Reserve space for the reply, the reply data will - * not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 4); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_storage_claim(dev_p, req_p, reply_p); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_STOR_CLAIM, data, dev_p->func_cbs_stor, - req_flags, req_p, reply_p, - cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of - * the MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_storage_claim(cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - - if (bus < 0 || bus >= CY_AS_MAX_BUSES) - return CY_AS_ERROR_NO_SUCH_BUS; - - return my_storage_claim(dev_p, NULL, bus, device, - CY_AS_REQUEST_RESPONSE_MS, cb, client); -} -EXPORT_SYMBOL(cy_as_storage_claim); - -static cy_as_return_status_t -my_handle_response_storage_release(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (cy_as_ll_request_response__get_code(reply_p) == - CY_RESP_NO_SUCH_ADDRESS) { - ret = cy_as_map_bad_addr( - cy_as_ll_request_response__get_word(reply_p, 3)); - goto destroy; - } - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_MEDIA_CLAIMED_RELEASED) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - /* The response must be about the address I am - * trying to release or the firmware is broken */ - if ((cy_as_storage_get_bus_from_address( - cy_as_ll_request_response__get_word(req_p, 0)) != - cy_as_storage_get_bus_from_address( - cy_as_ll_request_response__get_word(reply_p, 0))) || - (cy_as_storage_get_device_from_address( - cy_as_ll_request_response__get_word(req_p, 0)) != - cy_as_storage_get_device_from_address( - cy_as_ll_request_response__get_word(reply_p, 0)))) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - - if (cy_as_ll_request_response__get_word(reply_p, 1) != 0) - ret = CY_AS_ERROR_NOT_RELEASED; - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -static cy_as_return_status_t -my_storage_release(cy_as_device *dev_p, - void *data, - cy_as_bus_number_t bus, - uint32_t device, - uint16_t req_flags, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (dev_p->mtp_count > 0) - return CY_AS_ERROR_NOT_VALID_IN_MTP; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_RELEASE_STORAGE, - CY_RQT_STORAGE_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word( - req_p, 0, create_address(bus, device, 0)); - - /* Reserve space for the reply, the reply - * data will not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 4); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_storage_release( - dev_p, req_p, reply_p); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_STOR_RELEASE, data, dev_p->func_cbs_stor, - req_flags, req_p, reply_p, - cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as - * part of the MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_storage_release(cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - - if (bus < 0 || bus >= CY_AS_MAX_BUSES) - return CY_AS_ERROR_NO_SUCH_BUS; - - return my_storage_release(dev_p, NULL, bus, device, - CY_AS_REQUEST_RESPONSE_MS, cb, client); -} -EXPORT_SYMBOL(cy_as_storage_release); - -static cy_as_return_status_t -my_handle_response_storage_query_bus(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - uint32_t *count) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint8_t code = cy_as_ll_request_response__get_code(reply_p); - uint16_t v; - - if (code == CY_RESP_NO_SUCH_ADDRESS) { - ret = CY_AS_ERROR_NO_SUCH_BUS; - goto destroy; - } - - if (code != CY_RESP_BUS_DESCRIPTOR) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - /* - * verify that the response corresponds to the bus that was queried. - */ - if (cy_as_storage_get_bus_from_address( - cy_as_ll_request_response__get_word(req_p, 0)) != - cy_as_storage_get_bus_from_address( - cy_as_ll_request_response__get_word(reply_p, 0))) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - v = cy_as_ll_request_response__get_word(reply_p, 1); - if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) { - /* - * this request is only for the count of devices - * on the bus. there is no need to check the media type. - */ - if (v) - *count = 1; - else - *count = 0; - } else { - /* - * this request is for the count of devices of a - * particular type. we need to check whether the media - * type found matches the queried type. - */ - cy_as_media_type queried = (cy_as_media_type) - cy_as_ll_request_response__get_word(req_p, 1); - cy_as_media_type found = - cy_as_storage_get_media_from_address(v); - - if (queried == found) - *count = 1; - else - *count = 0; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -my_storage_query_bus(cy_as_device *dev_p, - cy_as_bus_number_t bus, - cy_as_media_type type, - uint16_t req_flags, - uint32_t *count, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret; - cy_as_ll_request_response *req_p, *reply_p; - cy_as_funct_c_b_type cb_type = CY_FUNCT_CB_STOR_QUERYBUS; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* Create the request to send to the Antioch device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_QUERY_BUS, CY_RQT_STORAGE_RQT_CONTEXT, 2); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, - 0, create_address(bus, 0, 0)); - cy_as_ll_request_response__set_word(req_p, 1, (uint16_t)type); - - /* Reserve space for the reply, the reply data - * will not exceed two words. */ - reply_p = cy_as_ll_create_response(dev_p, 2); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - req_p->flags |= req_flags; - return my_handle_response_storage_query_bus(dev_p, - req_p, reply_p, count); - } else { - if (req_flags == CY_AS_REQUEST_RESPONSE_EX) - cb_type = CY_FUNCT_CB_STOR_QUERYMEDIA; - - ret = cy_as_misc_send_request(dev_p, cb, client, cb_type, - count, dev_p->func_cbs_stor, req_flags, - req_p, reply_p, cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of - * the MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_storage_query_bus(cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t *count, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - - return my_storage_query_bus(dev_p, bus, cy_as_media_max_media_value, - CY_AS_REQUEST_RESPONSE_MS, count, cb, client); -} -EXPORT_SYMBOL(cy_as_storage_query_bus); - -cy_as_return_status_t -cy_as_storage_query_media(cy_as_device_handle handle, - cy_as_media_type type, - uint32_t *count, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_bus_number_t bus; - - cy_as_device *dev_p = (cy_as_device *)handle; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - ret = cy_an_map_bus_from_media_type(dev_p, type, &bus); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - return my_storage_query_bus(dev_p, bus, type, CY_AS_REQUEST_RESPONSE_EX, - count, cb, client); -} -EXPORT_SYMBOL(cy_as_storage_query_media); - -static cy_as_return_status_t -my_handle_response_storage_query_device(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - void *data_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint16_t v; - cy_as_bus_number_t bus; - cy_as_media_type type; - uint32_t device; - cy_bool removable; - cy_bool writeable; - cy_bool locked; - uint16_t block_size; - uint32_t number_units; - uint32_t number_eus; - - if (cy_as_ll_request_response__get_code(reply_p) - == CY_RESP_NO_SUCH_ADDRESS) { - ret = cy_as_map_bad_addr( - cy_as_ll_request_response__get_word(reply_p, 3)); - goto destroy; - } - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_DEVICE_DESCRIPTOR) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - /* Unpack the response */ - v = cy_as_ll_request_response__get_word(reply_p, 0); - type = cy_as_storage_get_media_from_address(v); - bus = cy_as_storage_get_bus_from_address(v); - device = cy_as_storage_get_device_from_address(v); - - block_size = cy_as_ll_request_response__get_word(reply_p, 1); - - v = cy_as_ll_request_response__get_word(reply_p, 2); - removable = (v & 0x8000) ? cy_true : cy_false; - writeable = (v & 0x0100) ? cy_true : cy_false; - locked = (v & 0x0200) ? cy_true : cy_false; - number_units = (v & 0xff); - - number_eus = (cy_as_ll_request_response__get_word(reply_p, 3) << 16) - | cy_as_ll_request_response__get_word(reply_p, 4); - - /* Store the results based on the version of originating function */ - if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) { - cy_as_storage_query_device_data *store_p = - (cy_as_storage_query_device_data *)data_p; - - /* Make sure the response is about the address we asked - * about - if not, firmware error */ - if ((bus != store_p->bus) || (device != store_p->device)) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - store_p->desc_p.type = type; - store_p->desc_p.removable = removable; - store_p->desc_p.writeable = writeable; - store_p->desc_p.block_size = block_size; - store_p->desc_p.number_units = number_units; - store_p->desc_p.locked = locked; - store_p->desc_p.erase_unit_size = number_eus; - dev_p->storage_device_info[bus][device] = store_p->desc_p; - } else { - cy_as_storage_query_device_data_dep *store_p = - (cy_as_storage_query_device_data_dep *)data_p; - - /* Make sure the response is about the address we asked - * about - if not, firmware error */ - if ((type != store_p->type) || (device != store_p->device)) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - store_p->desc_p.type = type; - store_p->desc_p.removable = removable; - store_p->desc_p.writeable = writeable; - store_p->desc_p.block_size = block_size; - store_p->desc_p.number_units = number_units; - store_p->desc_p.locked = locked; - store_p->desc_p.erase_unit_size = number_eus; - dev_p->storage_device_info[bus][device] = store_p->desc_p; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -static cy_as_return_status_t -my_storage_query_device(cy_as_device *dev_p, - void *data_p, - uint16_t req_flags, - cy_as_bus_number_t bus, - uint32_t device, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* Create the request to send to the Antioch device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_QUERY_DEVICE, CY_RQT_STORAGE_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, device, 0)); - - /* Reserve space for the reply, the reply data - * will not exceed five words. */ - reply_p = cy_as_ll_create_response(dev_p, 5); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - req_p->flags |= req_flags; - return my_handle_response_storage_query_device(dev_p, - req_p, reply_p, data_p); - } else { - - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_STOR_QUERYDEVICE, data_p, - dev_p->func_cbs_stor, req_flags, req_p, - reply_p, cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of the - * MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_storage_query_device(cy_as_device_handle handle, - cy_as_storage_query_device_data *data_p, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - return my_storage_query_device(dev_p, data_p, - CY_AS_REQUEST_RESPONSE_MS, data_p->bus, - data_p->device, cb, client); -} -EXPORT_SYMBOL(cy_as_storage_query_device); - -static cy_as_return_status_t -my_handle_response_storage_query_unit(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - void *data_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_bus_number_t bus; - uint32_t device; - uint32_t unit; - cy_as_media_type type; - uint16_t block_size; - uint32_t start_block; - uint32_t unit_size; - uint16_t v; - - if (cy_as_ll_request_response__get_code(reply_p) == - CY_RESP_NO_SUCH_ADDRESS) { - ret = cy_as_map_bad_addr( - cy_as_ll_request_response__get_word(reply_p, 3)); - goto destroy; - } - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_UNIT_DESCRIPTOR) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - /* Unpack the response */ - v = cy_as_ll_request_response__get_word(reply_p, 0); - bus = cy_as_storage_get_bus_from_address(v); - device = cy_as_storage_get_device_from_address(v); - unit = get_unit_from_address(v); - - type = cy_as_storage_get_media_from_address( - cy_as_ll_request_response__get_word(reply_p, 1)); - - block_size = cy_as_ll_request_response__get_word(reply_p, 2); - start_block = cy_as_ll_request_response__get_word(reply_p, 3) - | (cy_as_ll_request_response__get_word(reply_p, 4) << 16); - unit_size = cy_as_ll_request_response__get_word(reply_p, 5) - | (cy_as_ll_request_response__get_word(reply_p, 6) << 16); - - /* Store the results based on the version of - * originating function */ - if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) { - cy_as_storage_query_unit_data *store_p = - (cy_as_storage_query_unit_data *)data_p; - - /* Make sure the response is about the address we - * asked about - if not, firmware error */ - if (bus != store_p->bus || device != store_p->device || - unit != store_p->unit) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - store_p->desc_p.type = type; - store_p->desc_p.block_size = block_size; - store_p->desc_p.start_block = start_block; - store_p->desc_p.unit_size = unit_size; - } else { - cy_as_storage_query_unit_data_dep *store_p = - (cy_as_storage_query_unit_data_dep *)data_p; - - /* Make sure the response is about the media type we asked - * about - if not, firmware error */ - if ((type != store_p->type) || (device != store_p->device) || - (unit != store_p->unit)) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - store_p->desc_p.type = type; - store_p->desc_p.block_size = block_size; - store_p->desc_p.start_block = start_block; - store_p->desc_p.unit_size = unit_size; - } - - dev_p->storage_device_info[bus][device].type = type; - dev_p->storage_device_info[bus][device].block_size = block_size; - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -static cy_as_return_status_t -my_storage_query_unit(cy_as_device *dev_p, - void *data_p, - uint16_t req_flags, - cy_as_bus_number_t bus, - uint32_t device, - uint32_t unit, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_QUERY_UNIT, CY_RQT_STORAGE_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - if (device > 255) - return CY_AS_ERROR_NO_SUCH_DEVICE; - - if (unit > 255) - return CY_AS_ERROR_NO_SUCH_UNIT; - - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, device, (uint8_t)unit)); - - /* Reserve space for the reply, the reply data - * will be of seven words. */ - reply_p = cy_as_ll_create_response(dev_p, 7); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - req_p->flags |= req_flags; - return my_handle_response_storage_query_unit(dev_p, - req_p, reply_p, data_p); - } else { - - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_STOR_QUERYUNIT, data_p, - dev_p->func_cbs_stor, req_flags, req_p, reply_p, - cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed - * as part of the MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_storage_query_unit(cy_as_device_handle handle, - cy_as_storage_query_unit_data *data_p, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - return my_storage_query_unit(dev_p, data_p, CY_AS_REQUEST_RESPONSE_MS, - data_p->bus, data_p->device, data_p->unit, cb, client); -} -EXPORT_SYMBOL(cy_as_storage_query_unit); - -static cy_as_return_status_t -cy_as_get_block_size(cy_as_device *dev_p, - cy_as_bus_number_t bus, - uint32_t device, - cy_as_function_callback cb) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_QUERY_DEVICE, - CY_RQT_STORAGE_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, device, 0)); - - reply_p = cy_as_ll_create_response(dev_p, 4); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) - == CY_RESP_NO_SUCH_ADDRESS) { - ret = CY_AS_ERROR_NO_SUCH_BUS; - goto destroy; - } - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_DEVICE_DESCRIPTOR) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - /* Make sure the response is about the media type we asked - * about - if not, firmware error */ - if ((cy_as_storage_get_bus_from_address - (cy_as_ll_request_response__get_word(reply_p, 0)) - != bus) || (cy_as_storage_get_device_from_address - (cy_as_ll_request_response__get_word(reply_p, 0)) - != device)) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - - dev_p->storage_device_info[bus][device].block_size = - cy_as_ll_request_response__get_word(reply_p, 1); - } else - ret = CY_AS_ERROR_INVALID_REQUEST; - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -my_storage_device_control( - cy_as_device *dev_p, - cy_as_bus_number_t bus, - uint32_t device, - cy_bool card_detect_en, - cy_bool write_prot_en, - cy_as_storage_card_detect config_detect, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret; - cy_bool use_gpio = cy_false; - - (void)device; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - if (bus < 0 || bus >= CY_AS_MAX_BUSES) - return CY_AS_ERROR_NO_SUCH_BUS; - - if (device >= CY_AS_MAX_STORAGE_DEVICES) - return CY_AS_ERROR_NO_SUCH_DEVICE; - - /* If SD is not supported on the specified bus, - * then return ERROR */ - if ((dev_p->media_supported[bus] == 0) || - (dev_p->media_supported[bus] & (1<func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of the - * MiscFuncCallback */ - return ret; - } -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_storage_device_control(cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - cy_bool card_detect_en, - cy_bool write_prot_en, - cy_as_storage_card_detect config_detect, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - - return my_storage_device_control(dev_p, bus, device, card_detect_en, - write_prot_en, config_detect, cb, client); -} -EXPORT_SYMBOL(cy_as_storage_device_control); - -static void -cy_as_async_storage_callback(cy_as_device *dev_p, - cy_as_end_point_number_t ep, void *buf_p, uint32_t size, - cy_as_return_status_t ret) -{ - cy_as_storage_callback_dep cb; - cy_as_storage_callback cb_ms; - - (void)size; - (void)buf_p; - (void)ep; - - cy_as_device_clear_storage_async_pending(dev_p); - - /* - * if the LL request callback has already been called, - * the user callback has to be called from here. - */ - if (!dev_p->storage_wait) { - cy_as_hal_assert(dev_p->storage_cb != NULL || - dev_p->storage_cb_ms != NULL); - cb = dev_p->storage_cb; - cb_ms = dev_p->storage_cb_ms; - - dev_p->storage_cb = 0; - dev_p->storage_cb_ms = 0; - - if (ret == CY_AS_ERROR_SUCCESS) - ret = dev_p->storage_error; - - if (cb_ms) { - cb_ms((cy_as_device_handle)dev_p, - dev_p->storage_bus_index, - dev_p->storage_device_index, - dev_p->storage_unit, - dev_p->storage_block_addr, - dev_p->storage_oper, ret); - } else { - cb((cy_as_device_handle)dev_p, - dev_p->storage_device_info - [dev_p->storage_bus_index] - [dev_p->storage_device_index].type, - dev_p->storage_device_index, - dev_p->storage_unit, - dev_p->storage_block_addr, - dev_p->storage_oper, ret); - } - } else - dev_p->storage_error = ret; -} - -static void -cy_as_async_storage_reply_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t ret) -{ - cy_as_storage_callback_dep cb; - cy_as_storage_callback cb_ms; - uint8_t reqtype; - (void)rqt; - (void)context; - - reqtype = cy_as_ll_request_response__get_code(rqt); - - if (ret == CY_AS_ERROR_SUCCESS) { - if (cy_as_ll_request_response__get_code(resp) == - CY_RESP_ANTIOCH_DEFERRED_ERROR) { - ret = cy_as_ll_request_response__get_word - (resp, 0) & 0x00FF; - } else if (cy_as_ll_request_response__get_code(resp) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - } - } - - if (ret != CY_AS_ERROR_SUCCESS) { - if (reqtype == CY_RQT_READ_BLOCK) - cy_as_dma_cancel(dev_p, - dev_p->storage_read_endpoint, ret); - else - cy_as_dma_cancel(dev_p, - dev_p->storage_write_endpoint, ret); - } - - dev_p->storage_wait = cy_false; - - /* - * if the DMA callback has already been called, the - * user callback has to be called from here. - */ - if (!cy_as_device_is_storage_async_pending(dev_p)) { - cy_as_hal_assert(dev_p->storage_cb != NULL || - dev_p->storage_cb_ms != NULL); - cb = dev_p->storage_cb; - cb_ms = dev_p->storage_cb_ms; - - dev_p->storage_cb = 0; - dev_p->storage_cb_ms = 0; - - if (ret == CY_AS_ERROR_SUCCESS) - ret = dev_p->storage_error; - - if (cb_ms) { - cb_ms((cy_as_device_handle)dev_p, - dev_p->storage_bus_index, - dev_p->storage_device_index, - dev_p->storage_unit, - dev_p->storage_block_addr, - dev_p->storage_oper, ret); - } else { - cb((cy_as_device_handle)dev_p, - dev_p->storage_device_info - [dev_p->storage_bus_index] - [dev_p->storage_device_index].type, - dev_p->storage_device_index, - dev_p->storage_unit, - dev_p->storage_block_addr, - dev_p->storage_oper, ret); - } - } else - dev_p->storage_error = ret; -} - -static cy_as_return_status_t -cy_as_storage_async_oper(cy_as_device *dev_p, cy_as_end_point_number_t ep, - uint8_t reqtype, uint16_t req_flags, cy_as_bus_number_t bus, - uint32_t device, uint32_t unit, uint32_t block, void *data_p, - uint16_t num_blocks, cy_as_storage_callback_dep callback, - cy_as_storage_callback callback_ms) -{ - uint32_t mask; - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (bus < 0 || bus >= CY_AS_MAX_BUSES) - return CY_AS_ERROR_NO_SUCH_BUS; - - if (device >= CY_AS_MAX_STORAGE_DEVICES) - return CY_AS_ERROR_NO_SUCH_DEVICE; - - if (unit > 255) - return CY_AS_ERROR_NO_SUCH_UNIT; - - /* We are supposed to return success if the number of - * blocks is zero - */ - if (num_blocks == 0) { - if (callback_ms) - callback_ms((cy_as_device_handle)dev_p, - bus, device, unit, block, - ((reqtype == CY_RQT_WRITE_BLOCK) - ? cy_as_op_write : cy_as_op_read), - CY_AS_ERROR_SUCCESS); - else - callback((cy_as_device_handle)dev_p, - dev_p->storage_device_info[bus][device].type, - device, unit, block, - ((reqtype == CY_RQT_WRITE_BLOCK) ? - cy_as_op_write : cy_as_op_read), - CY_AS_ERROR_SUCCESS); - - return CY_AS_ERROR_SUCCESS; - } - - if (dev_p->storage_device_info[bus][device].block_size == 0) - return CY_AS_ERROR_QUERY_DEVICE_NEEDED; - - /* - * since async operations can be triggered by interrupt - * code, we must insure that we do not get multiple - * async operations going at one time and protect this - * test and set operation from interrupts. also need to - * check for pending async MTP writes - */ - mask = cy_as_hal_disable_interrupts(); - if ((cy_as_device_is_storage_async_pending(dev_p)) || - (dev_p->storage_wait) || - (cy_as_device_is_usb_async_pending(dev_p, 6))) { - cy_as_hal_enable_interrupts(mask); - return CY_AS_ERROR_ASYNC_PENDING; - } - - cy_as_device_set_storage_async_pending(dev_p); - cy_as_device_clear_p2s_dma_start_recvd(dev_p); - cy_as_hal_enable_interrupts(mask); - - /* - * storage information about the currently outstanding request - */ - dev_p->storage_cb = callback; - dev_p->storage_cb_ms = callback_ms; - dev_p->storage_bus_index = bus; - dev_p->storage_device_index = device; - dev_p->storage_unit = unit; - dev_p->storage_block_addr = block; - - /* Initialise the request to send to the West Bridge. */ - req_p = dev_p->storage_rw_req_p; - cy_as_ll_init_request(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 5); - - /* Initialise the space for reply from the West Bridge. */ - reply_p = dev_p->storage_rw_resp_p; - cy_as_ll_init_response(reply_p, 5); - - /* Remember which version of the API originated the request */ - req_p->flags |= req_flags; - - /* Setup the DMA request and adjust the storage - * operation if we are reading */ - if (reqtype == CY_RQT_READ_BLOCK) { - ret = cy_as_dma_queue_request(dev_p, ep, data_p, - dev_p->storage_device_info[bus][device].block_size - * num_blocks, cy_false, cy_true, - cy_as_async_storage_callback); - dev_p->storage_oper = cy_as_op_read; - } else if (reqtype == CY_RQT_WRITE_BLOCK) { - ret = cy_as_dma_queue_request(dev_p, ep, data_p, - dev_p->storage_device_info[bus][device].block_size * - num_blocks, cy_false, cy_false, - cy_as_async_storage_callback); - dev_p->storage_oper = cy_as_op_write; - } - - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_device_clear_storage_async_pending(dev_p); - return ret; - } - - cy_as_ll_request_response__set_word(req_p, - 0, create_address(bus, (uint8_t)device, (uint8_t)unit)); - cy_as_ll_request_response__set_word(req_p, - 1, (uint16_t)((block >> 16) & 0xffff)); - cy_as_ll_request_response__set_word(req_p, - 2, (uint16_t)(block & 0xffff)); - cy_as_ll_request_response__set_word(req_p, - 3, (uint16_t)((num_blocks >> 8) & 0x00ff)); - cy_as_ll_request_response__set_word(req_p, - 4, (uint16_t)((num_blocks << 8) & 0xff00)); - - /* Set the burst mode flag. */ - if (dev_p->is_storage_only_mode) - req_p->data[4] |= 0x0001; - - /* Send the request and wait for completion - * of storage request */ - dev_p->storage_wait = cy_true; - ret = cy_as_ll_send_request(dev_p, req_p, reply_p, - cy_true, cy_as_async_storage_reply_callback); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED); - cy_as_device_clear_storage_async_pending(dev_p); - } - - return ret; -} - -static void -cy_as_sync_storage_callback(cy_as_device *dev_p, - cy_as_end_point_number_t ep, void *buf_p, - uint32_t size, cy_as_return_status_t err) -{ - (void)ep; - (void)buf_p; - (void)size; - - dev_p->storage_error = err; -} - -static void -cy_as_sync_storage_reply_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t ret) -{ - uint8_t reqtype; - (void)rqt; - - reqtype = cy_as_ll_request_response__get_code(rqt); - - if (cy_as_ll_request_response__get_code(resp) == - CY_RESP_ANTIOCH_DEFERRED_ERROR) { - ret = cy_as_ll_request_response__get_word(resp, 0) & 0x00FF; - - if (ret != CY_AS_ERROR_SUCCESS) { - if (reqtype == CY_RQT_READ_BLOCK) - cy_as_dma_cancel(dev_p, - dev_p->storage_read_endpoint, ret); - else - cy_as_dma_cancel(dev_p, - dev_p->storage_write_endpoint, ret); - } - } else if (cy_as_ll_request_response__get_code(resp) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - } - - dev_p->storage_wait = cy_false; - dev_p->storage_error = ret; - - /* Wake any threads/processes that are waiting on - * the read/write completion. */ - cy_as_hal_wake(&dev_p->context[context]->channel); -} - -static cy_as_return_status_t -cy_as_storage_sync_oper(cy_as_device *dev_p, - cy_as_end_point_number_t ep, uint8_t reqtype, - cy_as_bus_number_t bus, uint32_t device, - uint32_t unit, uint32_t block, void *data_p, - uint16_t num_blocks) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_context *ctxt_p; - uint32_t loopcount = 200; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (bus < 0 || bus >= CY_AS_MAX_BUSES) - return CY_AS_ERROR_NO_SUCH_BUS; - - if (device >= CY_AS_MAX_STORAGE_DEVICES) - return CY_AS_ERROR_NO_SUCH_DEVICE; - - if (unit > 255) - return CY_AS_ERROR_NO_SUCH_UNIT; - - if ((cy_as_device_is_storage_async_pending(dev_p)) || - (dev_p->storage_wait)) - return CY_AS_ERROR_ASYNC_PENDING; - - /* Also need to check for pending Async MTP writes */ - if (cy_as_device_is_usb_async_pending(dev_p, 6)) - return CY_AS_ERROR_ASYNC_PENDING; - - /* We are supposed to return success if the number of - * blocks is zero - */ - if (num_blocks == 0) - return CY_AS_ERROR_SUCCESS; - - if (dev_p->storage_device_info[bus][device].block_size == 0) { - /* - * normally, a given device has been queried via - * the query device call before a read request is issued. - * therefore, this normally will not be run. - */ - ret = cy_as_get_block_size(dev_p, bus, device, 0); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - } - - /* Initialise the request to send to the West Bridge. */ - req_p = dev_p->storage_rw_req_p; - cy_as_ll_init_request(req_p, reqtype, - CY_RQT_STORAGE_RQT_CONTEXT, 5); - - /* Initialise the space for reply from - * the West Bridge. */ - reply_p = dev_p->storage_rw_resp_p; - cy_as_ll_init_response(reply_p, 5); - cy_as_device_clear_p2s_dma_start_recvd(dev_p); - - /* Setup the DMA request */ - if (reqtype == CY_RQT_READ_BLOCK) { - ret = cy_as_dma_queue_request(dev_p, ep, data_p, - dev_p->storage_device_info[bus][device].block_size * - num_blocks, cy_false, - cy_true, cy_as_sync_storage_callback); - dev_p->storage_oper = cy_as_op_read; - } else if (reqtype == CY_RQT_WRITE_BLOCK) { - ret = cy_as_dma_queue_request(dev_p, ep, data_p, - dev_p->storage_device_info[bus][device].block_size * - num_blocks, cy_false, cy_false, - cy_as_sync_storage_callback); - dev_p->storage_oper = cy_as_op_write; - } - - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, (uint8_t)unit)); - cy_as_ll_request_response__set_word(req_p, 1, - (uint16_t)((block >> 16) & 0xffff)); - cy_as_ll_request_response__set_word(req_p, 2, - (uint16_t)(block & 0xffff)); - cy_as_ll_request_response__set_word(req_p, 3, - (uint16_t)((num_blocks >> 8) & 0x00ff)); - cy_as_ll_request_response__set_word(req_p, 4, - (uint16_t)((num_blocks << 8) & 0xff00)); - - /* Set the burst mode flag. */ - if (dev_p->is_storage_only_mode) - req_p->data[4] |= 0x0001; - - /* Send the request and wait for - * completion of storage request */ - dev_p->storage_wait = cy_true; - ret = cy_as_ll_send_request(dev_p, req_p, reply_p, cy_true, - cy_as_sync_storage_reply_callback); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED); - } else { - /* Setup the DMA request */ - ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT]; - ret = cy_as_dma_drain_queue(dev_p, ep, cy_false); - - while (loopcount-- > 0) { - if (dev_p->storage_wait == cy_false) - break; - cy_as_hal_sleep_on(&ctxt_p->channel, 10); - } - - if (dev_p->storage_wait == cy_true) { - dev_p->storage_wait = cy_false; - cy_as_ll_remove_request(dev_p, ctxt_p, req_p, cy_true); - ret = CY_AS_ERROR_TIMEOUT; - } - - if (ret == CY_AS_ERROR_SUCCESS) - ret = dev_p->storage_error; - } - - return ret; -} - -cy_as_return_status_t -cy_as_storage_read(cy_as_device_handle handle, - cy_as_bus_number_t bus, uint32_t device, - uint32_t unit, uint32_t block, - void *data_p, uint16_t num_blocks) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - return cy_as_storage_sync_oper(dev_p, dev_p->storage_read_endpoint, - CY_RQT_READ_BLOCK, bus, device, - unit, block, data_p, num_blocks); -} -EXPORT_SYMBOL(cy_as_storage_read); - -cy_as_return_status_t -cy_as_storage_write(cy_as_device_handle handle, - cy_as_bus_number_t bus, uint32_t device, - uint32_t unit, uint32_t block, void *data_p, - uint16_t num_blocks) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (dev_p->mtp_turbo_active) - return CY_AS_ERROR_NOT_VALID_DURING_MTP; - - return cy_as_storage_sync_oper(dev_p, - dev_p->storage_write_endpoint, - CY_RQT_WRITE_BLOCK, bus, device, - unit, block, data_p, num_blocks); -} -EXPORT_SYMBOL(cy_as_storage_write); - -cy_as_return_status_t -cy_as_storage_read_async(cy_as_device_handle handle, - cy_as_bus_number_t bus, uint32_t device, uint32_t unit, - uint32_t block, void *data_p, uint16_t num_blocks, - cy_as_storage_callback callback) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (callback == 0) - return CY_AS_ERROR_NULL_CALLBACK; - - return cy_as_storage_async_oper(dev_p, - dev_p->storage_read_endpoint, CY_RQT_READ_BLOCK, - CY_AS_REQUEST_RESPONSE_MS, bus, device, unit, - block, data_p, num_blocks, NULL, callback); -} -EXPORT_SYMBOL(cy_as_storage_read_async); - -cy_as_return_status_t -cy_as_storage_write_async(cy_as_device_handle handle, - cy_as_bus_number_t bus, uint32_t device, uint32_t unit, - uint32_t block, void *data_p, uint16_t num_blocks, - cy_as_storage_callback callback) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (callback == 0) - return CY_AS_ERROR_NULL_CALLBACK; - - if (dev_p->mtp_turbo_active) - return CY_AS_ERROR_NOT_VALID_DURING_MTP; - - return cy_as_storage_async_oper(dev_p, - dev_p->storage_write_endpoint, CY_RQT_WRITE_BLOCK, - CY_AS_REQUEST_RESPONSE_MS, bus, device, unit, block, - data_p, num_blocks, NULL, callback); -} -EXPORT_SYMBOL(cy_as_storage_write_async); - -static void -my_storage_cancel_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t stat) -{ - (void)context; - (void)stat; - - /* Nothing to do here, except free up the - * request and response structures. */ - cy_as_ll_destroy_response(dev_p, resp); - cy_as_ll_destroy_request(dev_p, rqt); -} - - -cy_as_return_status_t -cy_as_storage_cancel_async(cy_as_device_handle handle) -{ - cy_as_return_status_t ret; - cy_as_ll_request_response *req_p , *reply_p; - - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (!cy_as_device_is_storage_async_pending(dev_p)) - return CY_AS_ERROR_ASYNC_NOT_PENDING; - - /* - * create and send a mailbox request to firmware - * asking it to abort processing of the current - * P2S operation. the rest of the cancel processing will be - * driven through the callbacks for the read/write call. - */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_ABORT_P2S_XFER, - CY_RQT_GENERAL_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - ret = cy_as_ll_send_request(dev_p, req_p, - reply_p, cy_false, my_storage_cancel_callback); - if (ret) { - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - } - - return CY_AS_ERROR_SUCCESS; -} -EXPORT_SYMBOL(cy_as_storage_cancel_async); - -/* - * This function does all the API side clean-up associated with - * CyAsStorageStop, without any communication with the firmware. - */ -void cy_as_storage_cleanup(cy_as_device *dev_p) -{ - if (dev_p->storage_count) { - cy_as_ll_destroy_request(dev_p, dev_p->storage_rw_req_p); - cy_as_ll_destroy_response(dev_p, dev_p->storage_rw_resp_p); - dev_p->storage_count = 0; - cy_as_device_clear_scsi_messages(dev_p); - cy_as_hal_mem_set(dev_p->storage_device_info, - 0, sizeof(dev_p->storage_device_info)); - - cy_as_device_clear_storage_async_pending(dev_p); - dev_p->storage_cb = 0; - dev_p->storage_cb_ms = 0; - dev_p->storage_wait = cy_false; - } -} - -static cy_as_return_status_t -my_handle_response_sd_reg_read( - cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_storage_sd_reg_read_data *info) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint8_t resp_type, i; - uint16_t resp_len; - uint8_t length = info->length; - uint8_t *data_p = info->buf_p; - - resp_type = cy_as_ll_request_response__get_code(reply_p); - if (resp_type == CY_RESP_SD_REGISTER_DATA) { - uint16_t *resp_p = reply_p->data + 1; - uint16_t temp; - - resp_len = cy_as_ll_request_response__get_word(reply_p, 0); - cy_as_hal_assert(resp_len >= length); - - /* - * copy the values into the output buffer after doing the - * necessary bit shifting. the bit shifting is required because - * the data comes out of the west bridge with a 6 bit offset. - */ - i = 0; - while (length) { - temp = ((resp_p[i] << 6) | (resp_p[i + 1] >> 10)); - i++; - - *data_p++ = (uint8_t)(temp >> 8); - length--; - - if (length) { - *data_p++ = (uint8_t)(temp & 0xFF); - length--; - } - } - } else { - if (resp_type == CY_RESP_SUCCESS_FAILURE) - ret = cy_as_ll_request_response__get_word(reply_p, 0); - else - ret = CY_AS_ERROR_INVALID_RESPONSE; - } - - cy_as_ll_destroy_response(dev_p, reply_p); - cy_as_ll_destroy_request(dev_p, req_p); - - return ret; -} - -cy_as_return_status_t -cy_as_storage_sd_register_read( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint8_t device, - cy_as_sd_card_reg_type reg_type, - cy_as_storage_sd_reg_read_data *data_p, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint8_t length; - - /* - * sanity checks required before sending the request to the - * firmware. - */ - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (device >= CY_AS_MAX_STORAGE_DEVICES) - return CY_AS_ERROR_NO_SUCH_DEVICE; - - if (reg_type > cy_as_sd_reg_CSD) - return CY_AS_ERROR_INVALID_PARAMETER; - - /* If SD/MMC media is not supported on the - * addressed bus, return error. */ - if ((dev_p->media_supported[bus] & (1 << cy_as_media_sd_flash)) == 0) - return CY_AS_ERROR_INVALID_PARAMETER; - - /* - * find the amount of data to be returned. this will be the minimum of - * the actual data length, and the length requested. - */ - switch (reg_type) { - case cy_as_sd_reg_OCR: - length = CY_AS_SD_REG_OCR_LENGTH; - break; - case cy_as_sd_reg_CID: - length = CY_AS_SD_REG_CID_LENGTH; - break; - case cy_as_sd_reg_CSD: - length = CY_AS_SD_REG_CSD_LENGTH; - break; - - default: - length = 0; - cy_as_hal_assert(0); - } - - if (length < data_p->length) - data_p->length = length; - length = data_p->length; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_SD_REGISTER_READ, - CY_RQT_STORAGE_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, - (create_address(bus, device, 0) | (uint16_t)reg_type)); - - reply_p = cy_as_ll_create_response(dev_p, - CY_AS_SD_REG_MAX_RESP_LENGTH); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_sd_reg_read(dev_p, - req_p, reply_p, data_p); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_STOR_SDREGISTERREAD, data_p, - dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of the - * MiscFuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_storage_sd_register_read); - -cy_as_return_status_t -cy_as_storage_create_p_partition( - /* Handle to the device of interest */ - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - /* of P-port only partition in blocks */ - uint32_t size, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p, *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_device *dev_p = (cy_as_device *)handle; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* Partitions cannot be created or deleted while - * the USB stack is active. */ - if (dev_p->usb_count) - return CY_AS_ERROR_USB_RUNNING; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_PARTITION_STORAGE, - CY_RQT_STORAGE_RQT_CONTEXT, 3); - - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* Reserve space for the reply, the reply - * data will not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, 0x00)); - cy_as_ll_request_response__set_word(req_p, 1, - (uint16_t)((size >> 16) & 0xffff)); - cy_as_ll_request_response__set_word(req_p, 2, - (uint16_t)(size & 0xffff)); - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_no_data(dev_p, req_p, reply_p); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_STOR_PARTITION, 0, dev_p->func_cbs_stor, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of the - * FuncCallback */ - return ret; - - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_storage_create_p_partition); - -cy_as_return_status_t -cy_as_storage_remove_p_partition( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p, *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_device *dev_p = (cy_as_device *)handle; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* Partitions cannot be created or deleted while - * the USB stack is active. */ - if (dev_p->usb_count) - return CY_AS_ERROR_USB_RUNNING; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_PARTITION_ERASE, - CY_RQT_STORAGE_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* Reserve space for the reply, the reply - * data will not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - cy_as_ll_request_response__set_word(req_p, - 0, create_address(bus, (uint8_t)device, 0x00)); - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_no_data(dev_p, req_p, reply_p); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_NODATA, 0, dev_p->func_cbs_stor, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed - * as part of the FuncCallback */ - return ret; - - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_storage_remove_p_partition); - -static cy_as_return_status_t -my_handle_response_get_transfer_amount(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_m_s_c_progress_data *data) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint8_t code = cy_as_ll_request_response__get_code(reply_p); - uint16_t v1, v2; - - if (code != CY_RESP_TRANSFER_COUNT) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - v1 = cy_as_ll_request_response__get_word(reply_p, 0); - v2 = cy_as_ll_request_response__get_word(reply_p, 1); - data->wr_count = (uint32_t)((v1 << 16) | v2); - - v1 = cy_as_ll_request_response__get_word(reply_p, 2); - v2 = cy_as_ll_request_response__get_word(reply_p, 3); - data->rd_count = (uint32_t)((v1 << 16) | v2); - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_storage_get_transfer_amount( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - cy_as_m_s_c_progress_data *data_p, - cy_as_function_callback cb, - uint32_t client - ) -{ - cy_as_ll_request_response *req_p, *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_device *dev_p = (cy_as_device *)handle; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* Check if the firmware image supports this feature. */ - if ((dev_p->media_supported[0]) && (dev_p->media_supported[0] - == (1 << cy_as_media_nand))) - return CY_AS_ERROR_NOT_SUPPORTED; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_GET_TRANSFER_AMOUNT, - CY_RQT_STORAGE_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* Reserve space for the reply, the reply data - * will not exceed four words. */ - reply_p = cy_as_ll_create_response(dev_p, 4); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, 0x00)); - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_get_transfer_amount(dev_p, - req_p, reply_p, data_p); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_STOR_GETTRANSFERAMOUNT, (void *)data_p, - dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed as part of the - * FuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; - -} -EXPORT_SYMBOL(cy_as_storage_get_transfer_amount); - -cy_as_return_status_t -cy_as_storage_erase( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint32_t erase_unit, - uint16_t num_erase_units, - cy_as_function_callback cb, - uint32_t client - ) -{ - cy_as_ll_request_response *req_p, *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_device *dev_p = (cy_as_device *)handle; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_storage_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (bus < 0 || bus >= CY_AS_MAX_BUSES) - return CY_AS_ERROR_NO_SUCH_BUS; - - if (device >= CY_AS_MAX_STORAGE_DEVICES) - return CY_AS_ERROR_NO_SUCH_DEVICE; - - if (dev_p->storage_device_info[bus][device].block_size == 0) - return CY_AS_ERROR_QUERY_DEVICE_NEEDED; - - /* If SD is not supported on the specified bus, then return ERROR */ - if (dev_p->storage_device_info[bus][device].type != - cy_as_media_sd_flash) - return CY_AS_ERROR_NOT_SUPPORTED; - - if (num_erase_units == 0) - return CY_AS_ERROR_SUCCESS; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_ERASE, - CY_RQT_STORAGE_RQT_CONTEXT, 5); - - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* Reserve space for the reply, the reply - * data will not exceed four words. */ - reply_p = cy_as_ll_create_response(dev_p, 4); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, 0x00)); - cy_as_ll_request_response__set_word(req_p, 1, - (uint16_t)((erase_unit >> 16) & 0xffff)); - cy_as_ll_request_response__set_word(req_p, 2, - (uint16_t)(erase_unit & 0xffff)); - cy_as_ll_request_response__set_word(req_p, 3, - (uint16_t)((num_erase_units >> 8) & 0x00ff)); - cy_as_ll_request_response__set_word(req_p, 4, - (uint16_t)((num_erase_units << 8) & 0xff00)); - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - ret = my_handle_response_no_data(dev_p, req_p, reply_p); - - /* If error = "invalid response", this (very likely) means - * that we are not using the SD-only firmware module which - * is the only one supporting storage_erase. in this case - * force a "non supported" error code */ - if (ret == CY_AS_ERROR_INVALID_RESPONSE) - ret = CY_AS_ERROR_NOT_SUPPORTED; - - return ret; - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_STOR_ERASE, 0, dev_p->func_cbs_stor, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_storage_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* The request and response are freed - * as part of the FuncCallback */ - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_storage_erase); - -static void -cy_as_storage_func_callback(cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t stat) -{ - cy_as_func_c_b_node *node = (cy_as_func_c_b_node *) - dev_p->func_cbs_stor->head_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_bool ex_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_EX) - == CY_AS_REQUEST_RESPONSE_EX; - cy_bool ms_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_MS) - == CY_AS_REQUEST_RESPONSE_MS; - uint8_t code; - uint8_t cntxt; - - cy_as_hal_assert(ex_request || ms_request); - cy_as_hal_assert(dev_p->func_cbs_stor->count != 0); - cy_as_hal_assert(dev_p->func_cbs_stor->type == CYAS_FUNC_CB); - (void) ex_request; - (void) ms_request; - - (void)context; - - cntxt = cy_as_ll_request_response__get_context(rqt); - cy_as_hal_assert(cntxt == CY_RQT_STORAGE_RQT_CONTEXT); - - code = cy_as_ll_request_response__get_code(rqt); - switch (code) { - case CY_RQT_START_STORAGE: - ret = my_handle_response_storage_start(dev_p, rqt, resp, stat); - break; - case CY_RQT_STOP_STORAGE: - ret = my_handle_response_storage_stop(dev_p, rqt, resp, stat); - break; - case CY_RQT_CLAIM_STORAGE: - ret = my_handle_response_storage_claim(dev_p, rqt, resp); - break; - case CY_RQT_RELEASE_STORAGE: - ret = my_handle_response_storage_release(dev_p, rqt, resp); - break; - case CY_RQT_QUERY_MEDIA: - cy_as_hal_assert(cy_false);/* Not used any more. */ - break; - case CY_RQT_QUERY_BUS: - cy_as_hal_assert(node->data != 0); - ret = my_handle_response_storage_query_bus(dev_p, - rqt, resp, (uint32_t *)node->data); - break; - case CY_RQT_QUERY_DEVICE: - cy_as_hal_assert(node->data != 0); - ret = my_handle_response_storage_query_device(dev_p, - rqt, resp, node->data); - break; - case CY_RQT_QUERY_UNIT: - cy_as_hal_assert(node->data != 0); - ret = my_handle_response_storage_query_unit(dev_p, - rqt, resp, node->data); - break; - case CY_RQT_SD_INTERFACE_CONTROL: - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_SD_REGISTER_READ: - cy_as_hal_assert(node->data != 0); - ret = my_handle_response_sd_reg_read(dev_p, rqt, resp, - (cy_as_storage_sd_reg_read_data *)node->data); - break; - case CY_RQT_PARTITION_STORAGE: - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_PARTITION_ERASE: - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_GET_TRANSFER_AMOUNT: - cy_as_hal_assert(node->data != 0); - ret = my_handle_response_get_transfer_amount(dev_p, - rqt, resp, (cy_as_m_s_c_progress_data *)node->data); - break; - case CY_RQT_ERASE: - ret = my_handle_response_no_data(dev_p, rqt, resp); - - /* If error = "invalid response", this (very likely) - * means that we are not using the SD-only firmware - * module which is the only one supporting storage_erase. - * in this case force a "non supported" error code */ - if (ret == CY_AS_ERROR_INVALID_RESPONSE) - ret = CY_AS_ERROR_NOT_SUPPORTED; - - break; - - default: - ret = CY_AS_ERROR_INVALID_RESPONSE; - cy_as_hal_assert(cy_false); - break; - } - - /* - * if the low level layer returns a direct error, use the - * corresponding error code. if not, use the error code - * based on the response from firmware. - */ - if (stat == CY_AS_ERROR_SUCCESS) - stat = ret; - - /* Call the user callback, if there is one */ - if (node->cb_p) - node->cb_p((cy_as_device_handle)dev_p, stat, - node->client_data, node->data_type, node->data); - cy_as_remove_c_b_node(dev_p->func_cbs_stor); -} - - -static void -cy_as_sdio_sync_reply_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t ret) -{ - (void)rqt; - - if ((cy_as_ll_request_response__get_code(resp) == - CY_RESP_SDIO_GET_TUPLE) || - (cy_as_ll_request_response__get_code(resp) == - CY_RESP_SDIO_EXT)) { - ret = cy_as_ll_request_response__get_word(resp, 0); - if ((ret & 0x00FF) != CY_AS_ERROR_SUCCESS) { - if (cy_as_ll_request_response__get_code(rqt) == - CY_RQT_SDIO_READ_EXTENDED) - cy_as_dma_cancel(dev_p, - dev_p->storage_read_endpoint, ret); - else - cy_as_dma_cancel(dev_p, - dev_p->storage_write_endpoint, ret); - } - } else { - ret = CY_AS_ERROR_INVALID_RESPONSE; - } - - dev_p->storage_rw_resp_p = resp; - dev_p->storage_wait = cy_false; - if (((ret & 0x00FF) == CY_AS_ERROR_IO_ABORTED) || ((ret & 0x00FF) - == CY_AS_ERROR_IO_SUSPENDED)) - dev_p->storage_error = (ret & 0x00FF); - else - dev_p->storage_error = (ret & 0x00FF) ? - CY_AS_ERROR_INVALID_RESPONSE : CY_AS_ERROR_SUCCESS; - - /* Wake any threads/processes that are waiting on - * the read/write completion. */ - cy_as_hal_wake(&dev_p->context[context]->channel); -} - -cy_as_return_status_t -cy_as_sdio_device_check( - cy_as_device *dev_p, - cy_as_bus_number_t bus, - uint32_t device) -{ - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (bus < 0 || bus >= CY_AS_MAX_BUSES) - return CY_AS_ERROR_NO_SUCH_BUS; - - if (device >= CY_AS_MAX_STORAGE_DEVICES) - return CY_AS_ERROR_NO_SUCH_DEVICE; - - if (!cy_as_device_is_astoria_dev(dev_p)) - return CY_AS_ERROR_NOT_SUPPORTED; - - return (is_storage_active(dev_p)); -} - -cy_as_return_status_t -cy_as_sdio_direct_io( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no, - uint32_t address, - uint8_t misc_buf, - uint16_t argument, - uint8_t is_write, - uint8_t *data_p) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint16_t resp_data; - - /* - * sanity checks required before sending the request to the - * firmware. - */ - cy_as_device *dev_p = (cy_as_device *)handle; - ret = cy_as_sdio_device_check(dev_p, bus, device); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - - if (!(cy_as_sdio_check_function_initialized(handle, - bus, n_function_no))) - return CY_AS_ERROR_INVALID_FUNCTION; - if (cy_as_sdio_check_function_suspended(handle, bus, n_function_no)) - return CY_AS_ERROR_FUNCTION_SUSPENDED; - - req_p = cy_as_ll_create_request(dev_p, (is_write == cy_true) ? - CY_RQT_SDIO_WRITE_DIRECT : CY_RQT_SDIO_READ_DIRECT, - CY_RQT_STORAGE_RQT_CONTEXT, 3); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /*Setting up request*/ - - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, n_function_no)); - /* D1 */ - if (is_write == cy_true) { - cy_as_ll_request_response__set_word(req_p, 1, - ((argument<<8) | 0x0080 | (n_function_no<<4) | - ((misc_buf&CY_SDIO_RAW)<<3) | - ((misc_buf&CY_SDIO_REARM_INT)>>5) | - (uint16_t)(address>>15))); - } else { - cy_as_ll_request_response__set_word(req_p, 1, - (n_function_no<<4) | ((misc_buf&CY_SDIO_REARM_INT)>>5) | - (uint16_t)(address>>15)); - } - /* D2 */ - cy_as_ll_request_response__set_word(req_p, 2, - ((uint16_t)((address&0x00007fff)<<1))); - - /*Create response*/ - reply_p = cy_as_ll_create_response(dev_p, 2); - - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - /*Sending the request*/ - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /*Check reply type*/ - if (cy_as_ll_request_response__get_code(reply_p) == - CY_RESP_SDIO_DIRECT) { - resp_data = cy_as_ll_request_response__get_word(reply_p, 0); - if (resp_data >> 8) - ret = CY_AS_ERROR_INVALID_RESPONSE; - else if (data_p != 0) - *(uint8_t *)(data_p) = (uint8_t)(resp_data&0x00ff); - } else { - ret = CY_AS_ERROR_INVALID_RESPONSE; - } - -destroy: - if (req_p != 0) - cy_as_ll_destroy_request(dev_p, req_p); - if (reply_p != 0) - cy_as_ll_destroy_response(dev_p, reply_p); - return ret; -} - - -cy_as_return_status_t -cy_as_sdio_direct_read( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no, - uint32_t address, - uint8_t misc_buf, - uint8_t *data_p) -{ - return cy_as_sdio_direct_io(handle, bus, device, n_function_no, - address, misc_buf, 0x00, cy_false, data_p); -} -EXPORT_SYMBOL(cy_as_sdio_direct_read); - -cy_as_return_status_t -cy_as_sdio_direct_write( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no, - uint32_t address, - uint8_t misc_buf, - uint16_t argument, - uint8_t *data_p) -{ - return cy_as_sdio_direct_io(handle, bus, device, n_function_no, - address, misc_buf, argument, cy_true, data_p); -} -EXPORT_SYMBOL(cy_as_sdio_direct_write); - -/*Cmd53 IO*/ -cy_as_return_status_t -cy_as_sdio_extended_i_o( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no, - uint32_t address, - uint8_t misc_buf, - uint16_t argument, - uint8_t is_write, - uint8_t *data_p , - uint8_t is_resume) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint8_t resp_type; - uint8_t reqtype; - uint16_t resp_data; - cy_as_context *ctxt_p; - uint32_t dmasize, loopcount = 200; - cy_as_end_point_number_t ep; - - cy_as_device *dev_p = (cy_as_device *)handle; - ret = cy_as_sdio_device_check(dev_p, bus, device); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (!(cy_as_sdio_check_function_initialized(handle, - bus, n_function_no))) - return CY_AS_ERROR_INVALID_FUNCTION; - if (cy_as_sdio_check_function_suspended(handle, bus, n_function_no)) - return CY_AS_ERROR_FUNCTION_SUSPENDED; - - - if ((cy_as_device_is_storage_async_pending(dev_p)) || - (dev_p->storage_wait)) - return CY_AS_ERROR_ASYNC_PENDING; - - /* Request for 0 bytes of blocks is returned as a success*/ - if (argument == 0) - return CY_AS_ERROR_SUCCESS; - - /* Initialise the request to send to the West Bridge device. */ - if (is_write == cy_true) { - reqtype = CY_RQT_SDIO_WRITE_EXTENDED; - ep = dev_p->storage_write_endpoint; - } else { - reqtype = CY_RQT_SDIO_READ_EXTENDED; - ep = dev_p->storage_read_endpoint; - } - - req_p = dev_p->storage_rw_req_p; - cy_as_ll_init_request(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 3); - - /* Initialise the space for reply from the Antioch. */ - reply_p = dev_p->storage_rw_resp_p; - cy_as_ll_init_response(reply_p, 2); - - /* Setup the DMA request */ - if (!(misc_buf&CY_SDIO_BLOCKMODE)) { - if (argument > - dev_p->sdiocard[bus]. - function[n_function_no-1].blocksize) - return CY_AS_ERROR_INVALID_BLOCKSIZE; - - } else { - if (argument > 511) - return CY_AS_ERROR_INVALID_BLOCKSIZE; - } - - if (argument == 512) - argument = 0; - - dmasize = ((misc_buf&CY_SDIO_BLOCKMODE) != 0) ? - dev_p->sdiocard[bus].function[n_function_no-1].blocksize - * argument : argument; - - ret = cy_as_dma_queue_request(dev_p, ep, (void *)(data_p), - dmasize, cy_false, (is_write & cy_true) ? cy_false : - cy_true, cy_as_sync_storage_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, - n_function_no | ((is_resume) ? 0x80 : 0x00))); - cy_as_ll_request_response__set_word(req_p, 1, - ((uint16_t)n_function_no)<<12| - ((uint16_t)(misc_buf & (CY_SDIO_BLOCKMODE|CY_SDIO_OP_INCR))) - << 9 | (uint16_t)(address >> 7) | - ((is_write == cy_true) ? 0x8000 : 0x0000)); - cy_as_ll_request_response__set_word(req_p, 2, - ((uint16_t)(address&0x0000ffff) << 9) | argument); - - - /* Send the request and wait for completion of storage request */ - dev_p->storage_wait = cy_true; - ret = cy_as_ll_send_request(dev_p, req_p, reply_p, - cy_true, cy_as_sdio_sync_reply_callback); - - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED); - } else { - /* Setup the DMA request */ - ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT]; - ret = cy_as_dma_drain_queue(dev_p, ep, cy_true); - - while (loopcount-- > 0) { - if (dev_p->storage_wait == cy_false) - break; - cy_as_hal_sleep_on(&ctxt_p->channel, 10); - } - if (dev_p->storage_wait == cy_true) { - dev_p->storage_wait = cy_false; - cy_as_ll_remove_request(dev_p, ctxt_p, req_p, cy_true); - dev_p->storage_error = CY_AS_ERROR_TIMEOUT; - } - - ret = dev_p->storage_error; - - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - resp_type = cy_as_ll_request_response__get_code( - dev_p->storage_rw_resp_p); - if (resp_type == CY_RESP_SDIO_EXT) { - resp_data = cy_as_ll_request_response__get_word - (reply_p, 0)&0x00ff; - if (resp_data) - ret = CY_AS_ERROR_INVALID_REQUEST; - - } else { - ret = CY_AS_ERROR_INVALID_RESPONSE; - } - } - return ret; - -} - -static void -cy_as_sdio_async_reply_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t ret) -{ - cy_as_storage_callback cb_ms; - uint8_t reqtype; - uint32_t pendingblocks; - (void)rqt; - (void)context; - - pendingblocks = 0; - reqtype = cy_as_ll_request_response__get_code(rqt); - if (ret == CY_AS_ERROR_SUCCESS) { - if ((cy_as_ll_request_response__get_code(resp) == - CY_RESP_SUCCESS_FAILURE) || - (cy_as_ll_request_response__get_code(resp) == - CY_RESP_SDIO_EXT)) { - ret = cy_as_ll_request_response__get_word(resp, 0); - ret &= 0x00FF; - } else { - ret = CY_AS_ERROR_INVALID_RESPONSE; - } - } - - if (ret != CY_AS_ERROR_SUCCESS) { - if (reqtype == CY_RQT_SDIO_READ_EXTENDED) - cy_as_dma_cancel(dev_p, - dev_p->storage_read_endpoint, ret); - else - cy_as_dma_cancel(dev_p, - dev_p->storage_write_endpoint, ret); - - dev_p->storage_error = ret; - } - - dev_p->storage_wait = cy_false; - - /* - * if the DMA callback has already been called, - * the user callback has to be called from here. - */ - if (!cy_as_device_is_storage_async_pending(dev_p)) { - cy_as_hal_assert(dev_p->storage_cb_ms != NULL); - cb_ms = dev_p->storage_cb_ms; - - dev_p->storage_cb = 0; - dev_p->storage_cb_ms = 0; - - if ((ret == CY_AS_ERROR_SUCCESS) || - (ret == CY_AS_ERROR_IO_ABORTED) || - (ret == CY_AS_ERROR_IO_SUSPENDED)) { - ret = dev_p->storage_error; - pendingblocks = ((uint32_t) - cy_as_ll_request_response__get_word - (resp, 1)) << 16; - } else - ret = CY_AS_ERROR_INVALID_RESPONSE; - - cb_ms((cy_as_device_handle)dev_p, dev_p->storage_bus_index, - dev_p->storage_device_index, - (dev_p->storage_unit | pendingblocks), - dev_p->storage_block_addr, dev_p->storage_oper, ret); - } else - dev_p->storage_error = ret; -} - - -cy_as_return_status_t -cy_as_sdio_extended_i_o_async( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no, - uint32_t address, - uint8_t misc_buf, - uint16_t argument, - uint8_t is_write, - uint8_t *data_p, - cy_as_storage_callback callback) -{ - - uint32_t mask; - uint32_t dmasize; - cy_as_ll_request_response *req_p , *reply_p; - uint8_t reqtype; - cy_as_end_point_number_t ep; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_device *dev_p = (cy_as_device *)handle; - - ret = cy_as_sdio_device_check(dev_p, bus, device); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (!(cy_as_sdio_check_function_initialized(handle, - bus, n_function_no))) - return CY_AS_ERROR_INVALID_FUNCTION; - if (cy_as_sdio_check_function_suspended(handle, bus, n_function_no)) - return CY_AS_ERROR_FUNCTION_SUSPENDED; - - if (callback == 0) - return CY_AS_ERROR_NULL_CALLBACK; - - /* We are supposed to return success if the number of - * blocks is zero - */ - if (((misc_buf&CY_SDIO_BLOCKMODE) != 0) && (argument == 0)) { - callback(handle, bus, device, n_function_no, address, - ((is_write) ? cy_as_op_write : cy_as_op_read), - CY_AS_ERROR_SUCCESS); - return CY_AS_ERROR_SUCCESS; - } - - - /* - * since async operations can be triggered by interrupt - * code, we must insure that we do not get multiple async - * operations going at one time and protect this test and - * set operation from interrupts. - */ - mask = cy_as_hal_disable_interrupts(); - if ((cy_as_device_is_storage_async_pending(dev_p)) || - (dev_p->storage_wait)) { - cy_as_hal_enable_interrupts(mask); - return CY_AS_ERROR_ASYNC_PENDING; - } - cy_as_device_set_storage_async_pending(dev_p); - cy_as_hal_enable_interrupts(mask); - - - /* - * storage information about the currently - * outstanding request - */ - dev_p->storage_cb_ms = callback; - dev_p->storage_bus_index = bus; - dev_p->storage_device_index = device; - dev_p->storage_unit = n_function_no; - dev_p->storage_block_addr = address; - - if (is_write == cy_true) { - reqtype = CY_RQT_SDIO_WRITE_EXTENDED; - ep = dev_p->storage_write_endpoint; - } else { - reqtype = CY_RQT_SDIO_READ_EXTENDED; - ep = dev_p->storage_read_endpoint; - } - - /* Initialise the request to send to the West Bridge. */ - req_p = dev_p->storage_rw_req_p; - cy_as_ll_init_request(req_p, reqtype, - CY_RQT_STORAGE_RQT_CONTEXT, 3); - - /* Initialise the space for reply from the West Bridge. */ - reply_p = dev_p->storage_rw_resp_p; - cy_as_ll_init_response(reply_p, 2); - - if (!(misc_buf&CY_SDIO_BLOCKMODE)) { - if (argument > - dev_p->sdiocard[bus].function[n_function_no-1].blocksize) - return CY_AS_ERROR_INVALID_BLOCKSIZE; - - } else { - if (argument > 511) - return CY_AS_ERROR_INVALID_BLOCKSIZE; - } - - if (argument == 512) - argument = 0; - dmasize = ((misc_buf&CY_SDIO_BLOCKMODE) != 0) ? - dev_p->sdiocard[bus].function[n_function_no-1].blocksize * - argument : argument; - - /* Setup the DMA request and adjust the storage - * operation if we are reading */ - if (reqtype == CY_RQT_SDIO_READ_EXTENDED) { - ret = cy_as_dma_queue_request(dev_p, ep, - (void *)data_p, dmasize , cy_false, cy_true, - cy_as_async_storage_callback); - dev_p->storage_oper = cy_as_op_read; - } else if (reqtype == CY_RQT_SDIO_WRITE_EXTENDED) { - ret = cy_as_dma_queue_request(dev_p, ep, (void *)data_p, - dmasize, cy_false, cy_false, cy_as_async_storage_callback); - dev_p->storage_oper = cy_as_op_write; - } - - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_device_clear_storage_async_pending(dev_p); - return ret; - } - - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, n_function_no)); - cy_as_ll_request_response__set_word(req_p, 1, - ((uint16_t)n_function_no) << 12 | - ((uint16_t)(misc_buf & (CY_SDIO_BLOCKMODE | CY_SDIO_OP_INCR))) - << 9 | (uint16_t)(address>>7) | - ((is_write == cy_true) ? 0x8000 : 0x0000)); - cy_as_ll_request_response__set_word(req_p, 2, - ((uint16_t)(address&0x0000ffff) << 9) | argument); - - - /* Send the request and wait for completion of storage request */ - dev_p->storage_wait = cy_true; - ret = cy_as_ll_send_request(dev_p, req_p, reply_p, cy_true, - cy_as_sdio_async_reply_callback); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED); - cy_as_device_clear_storage_async_pending(dev_p); - } else { - cy_as_dma_kick_start(dev_p, ep); - } - - return ret; -} - -/* CMD53 Extended Read*/ -cy_as_return_status_t -cy_as_sdio_extended_read( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no, - uint32_t address, - uint8_t misc_buf, - uint16_t argument, - uint8_t *data_p, - cy_as_sdio_callback callback) -{ - if (callback == 0) - return cy_as_sdio_extended_i_o(handle, bus, device, - n_function_no, address, misc_buf, argument, - cy_false, data_p, 0); - - return cy_as_sdio_extended_i_o_async(handle, bus, device, - n_function_no, address, misc_buf, argument, cy_false, - data_p, callback); -} -EXPORT_SYMBOL(cy_as_sdio_extended_read); - -/* CMD53 Extended Write*/ -cy_as_return_status_t -cy_as_sdio_extended_write( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no, - uint32_t address, - uint8_t misc_buf, - uint16_t argument, - uint8_t *data_p, - cy_as_sdio_callback callback) -{ - if (callback == 0) - return cy_as_sdio_extended_i_o(handle, bus, device, - n_function_no, address, misc_buf, argument, cy_true, - data_p, 0); - - return cy_as_sdio_extended_i_o_async(handle, bus, device, - n_function_no, address, misc_buf, argument, cy_true, - data_p, callback); -} -EXPORT_SYMBOL(cy_as_sdio_extended_write); - -/* Read the CIS info tuples for the given function and Tuple ID*/ -cy_as_return_status_t -cy_as_sdio_get_c_i_s_info( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no, - uint16_t tuple_id, - uint8_t *data_p) -{ - - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint16_t resp_data; - cy_as_context *ctxt_p; - uint32_t loopcount = 200; - - cy_as_device *dev_p = (cy_as_device *)handle; - - ret = cy_as_sdio_device_check(dev_p, bus, device); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (!(cy_as_sdio_check_function_initialized(handle, bus, 0))) - return CY_AS_ERROR_INVALID_FUNCTION; - - if ((cy_as_device_is_storage_async_pending(dev_p)) || - (dev_p->storage_wait)) - return CY_AS_ERROR_ASYNC_PENDING; - - - /* Initialise the request to send to the Antioch. */ - req_p = dev_p->storage_rw_req_p; - cy_as_ll_init_request(req_p, CY_RQT_SDIO_GET_TUPLE, - CY_RQT_STORAGE_RQT_CONTEXT, 2); - - /* Initialise the space for reply from the Antioch. */ - reply_p = dev_p->storage_rw_resp_p; - cy_as_ll_init_response(reply_p, 3); - - /* Setup the DMA request */ - ret = cy_as_dma_queue_request(dev_p, dev_p->storage_read_endpoint, - data_p+1, 255, cy_false, cy_true, cy_as_sync_storage_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, n_function_no)); - - /* Set tuple id to fetch. */ - cy_as_ll_request_response__set_word(req_p, 1, tuple_id<<8); - - /* Send the request and wait for completion of storage request */ - dev_p->storage_wait = cy_true; - ret = cy_as_ll_send_request(dev_p, req_p, reply_p, cy_true, - cy_as_sdio_sync_reply_callback); - - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_dma_cancel(dev_p, - dev_p->storage_read_endpoint, CY_AS_ERROR_CANCELED); - } else { - /* Setup the DMA request */ - ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT]; - ret = cy_as_dma_drain_queue(dev_p, - dev_p->storage_read_endpoint, cy_true); - - while (loopcount-- > 0) { - if (dev_p->storage_wait == cy_false) - break; - cy_as_hal_sleep_on(&ctxt_p->channel, 10); - } - - if (dev_p->storage_wait == cy_true) { - dev_p->storage_wait = cy_false; - cy_as_ll_remove_request(dev_p, ctxt_p, req_p, cy_true); - return CY_AS_ERROR_TIMEOUT; - } - ret = dev_p->storage_error; - - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_ll_request_response__get_code - (dev_p->storage_rw_resp_p) == CY_RESP_SDIO_GET_TUPLE) { - resp_data = cy_as_ll_request_response__get_word - (reply_p, 0); - if (resp_data) { - ret = CY_AS_ERROR_INVALID_REQUEST; - } else if (data_p != 0) - *(uint8_t *)data_p = (uint8_t) - (cy_as_ll_request_response__get_word - (reply_p, 0)&0x00ff); - } else { - ret = CY_AS_ERROR_INVALID_RESPONSE; - } - } - return ret; -} - -/*Query Device*/ -cy_as_return_status_t -cy_as_sdio_query_card( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - cy_as_sdio_card *data_p) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - uint8_t resp_type; - cy_as_device *dev_p = (cy_as_device *)handle; - - ret = cy_as_sdio_device_check(dev_p, bus, device); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* Allocating memory to the SDIO device structure in dev_p */ - - cy_as_hal_mem_set(&dev_p->sdiocard[bus], 0, sizeof(cy_as_sdio_device)); - - req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDIO_QUERY_CARD, - CY_RQT_STORAGE_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, 0)); - - reply_p = cy_as_ll_create_response(dev_p, 5); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - resp_type = cy_as_ll_request_response__get_code(reply_p); - if (resp_type == CY_RESP_SDIO_QUERY_CARD) { - dev_p->sdiocard[bus].card.num_functions = - (uint8_t)((reply_p->data[0]&0xff00)>>8); - dev_p->sdiocard[bus].card.memory_present = - (uint8_t)reply_p->data[0]&0x0001; - dev_p->sdiocard[bus].card.manufacturer__id = - reply_p->data[1]; - dev_p->sdiocard[bus].card.manufacturer_info = - reply_p->data[2]; - dev_p->sdiocard[bus].card.blocksize = - reply_p->data[3]; - dev_p->sdiocard[bus].card.maxblocksize = - reply_p->data[3]; - dev_p->sdiocard[bus].card.card_capability = - (uint8_t)((reply_p->data[4]&0xff00)>>8); - dev_p->sdiocard[bus].card.sdio_version = - (uint8_t)(reply_p->data[4]&0x00ff); - dev_p->sdiocard[bus].function_init_map = 0x01; - data_p->num_functions = - dev_p->sdiocard[bus].card.num_functions; - data_p->memory_present = - dev_p->sdiocard[bus].card.memory_present; - data_p->manufacturer__id = - dev_p->sdiocard[bus].card.manufacturer__id; - data_p->manufacturer_info = - dev_p->sdiocard[bus].card.manufacturer_info; - data_p->blocksize = dev_p->sdiocard[bus].card.blocksize; - data_p->maxblocksize = - dev_p->sdiocard[bus].card.maxblocksize; - data_p->card_capability = - dev_p->sdiocard[bus].card.card_capability; - data_p->sdio_version = - dev_p->sdiocard[bus].card.sdio_version; - } else { - if (resp_type == CY_RESP_SUCCESS_FAILURE) - ret = cy_as_ll_request_response__get_word(reply_p, 0); - else - ret = CY_AS_ERROR_INVALID_RESPONSE; - } -destroy: - if (req_p != 0) - cy_as_ll_destroy_request(dev_p, req_p); - if (reply_p != 0) - cy_as_ll_destroy_response(dev_p, reply_p); - return ret; -} -EXPORT_SYMBOL(cy_as_sdio_query_card); - -/*Reset SDIO card. */ -cy_as_return_status_t -cy_as_sdio_reset_card( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device) -{ - - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint8_t resp_type; - cy_as_device *dev_p = (cy_as_device *)handle; - - ret = cy_as_sdio_device_check(dev_p, bus, device); - - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (dev_p->sdiocard != 0) { - dev_p->sdiocard[bus].function_init_map = 0; - dev_p->sdiocard[bus].function_suspended_map = 0; - } - - req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDIO_RESET_DEV, - CY_RQT_STORAGE_RQT_CONTEXT, 1); - - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /*Setup mailbox */ - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, 0)); - - reply_p = cy_as_ll_create_response(dev_p, 2); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - resp_type = cy_as_ll_request_response__get_code(reply_p); - - if (resp_type == CY_RESP_SUCCESS_FAILURE) { - ret = cy_as_ll_request_response__get_word(reply_p, 0); - if (ret == CY_AS_ERROR_SUCCESS) - ret = cy_as_sdio_query_card(handle, bus, device, 0); - } else - ret = CY_AS_ERROR_INVALID_RESPONSE; - -destroy: - if (req_p != 0) - cy_as_ll_destroy_request(dev_p, req_p); - if (reply_p != 0) - cy_as_ll_destroy_response(dev_p, reply_p); - return ret; -} - -/* Initialise an IO function*/ -cy_as_return_status_t -cy_as_sdio_init_function( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no, - uint8_t misc_buf) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint8_t resp_type; - cy_as_device *dev_p = (cy_as_device *)handle; - - ret = cy_as_sdio_device_check(dev_p, bus, device); - - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (!(cy_as_sdio_check_function_initialized - (handle, bus, 0))) - return CY_AS_ERROR_NOT_RUNNING; - - if ((cy_as_sdio_check_function_initialized - (handle, bus, n_function_no))) { - if (misc_buf&CY_SDIO_FORCE_INIT) - dev_p->sdiocard[bus].function_init_map &= - (~(1 << n_function_no)); - else - return CY_AS_ERROR_ALREADY_RUNNING; - } - - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_SDIO_INIT_FUNCTION, CY_RQT_STORAGE_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, n_function_no)); - - reply_p = cy_as_ll_create_response(dev_p, 5); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - resp_type = cy_as_ll_request_response__get_code(reply_p); - - if (resp_type == CY_RESP_SDIO_INIT_FUNCTION) { - dev_p->sdiocard[bus].function[n_function_no-1].function_code = - (uint8_t)((reply_p->data[0]&0xff00)>>8); - dev_p->sdiocard[bus].function[n_function_no-1]. - extended_func_code = (uint8_t)reply_p->data[0]&0x00ff; - dev_p->sdiocard[bus].function[n_function_no-1].blocksize = - reply_p->data[1]; - dev_p->sdiocard[bus].function[n_function_no-1]. - maxblocksize = reply_p->data[1]; - dev_p->sdiocard[bus].function[n_function_no-1].card_psn = - (uint32_t)(reply_p->data[2])<<16; - dev_p->sdiocard[bus].function[n_function_no-1].card_psn |= - (uint32_t)(reply_p->data[3]); - dev_p->sdiocard[bus].function[n_function_no-1].csa_bits = - (uint8_t)((reply_p->data[4]&0xff00)>>8); - dev_p->sdiocard[bus].function[n_function_no-1].wakeup_support = - (uint8_t)(reply_p->data[4]&0x0001); - dev_p->sdiocard[bus].function_init_map |= (1 << n_function_no); - cy_as_sdio_clear_function_suspended(handle, bus, n_function_no); - - } else { - if (resp_type == CY_RESP_SUCCESS_FAILURE) - ret = cy_as_ll_request_response__get_word(reply_p, 0); - else - ret = CY_AS_ERROR_INVALID_FUNCTION; - } - -destroy: - if (req_p != 0) - cy_as_ll_destroy_request(dev_p, req_p); - if (reply_p != 0) - cy_as_ll_destroy_response(dev_p, reply_p); - return ret; -} -EXPORT_SYMBOL(cy_as_sdio_init_function); - -/*Query individual functions. */ -cy_as_return_status_t -cy_as_sdio_query_function( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no, - cy_as_sdio_func *data_p) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - cy_as_return_status_t ret; - - ret = cy_as_sdio_device_check(dev_p, bus, device); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (!(cy_as_sdio_check_function_initialized(handle, - bus, n_function_no))) - return CY_AS_ERROR_INVALID_FUNCTION; - - data_p->blocksize = - dev_p->sdiocard[bus].function[n_function_no-1].blocksize; - data_p->card_psn = - dev_p->sdiocard[bus].function[n_function_no-1].card_psn; - data_p->csa_bits = - dev_p->sdiocard[bus].function[n_function_no-1].csa_bits; - data_p->extended_func_code = - dev_p->sdiocard[bus].function[n_function_no-1]. - extended_func_code; - data_p->function_code = - dev_p->sdiocard[bus].function[n_function_no-1].function_code; - data_p->maxblocksize = - dev_p->sdiocard[bus].function[n_function_no-1].maxblocksize; - data_p->wakeup_support = - dev_p->sdiocard[bus].function[n_function_no-1].wakeup_support; - - return CY_AS_ERROR_SUCCESS; -} - -/* Abort the Current Extended IO Operation*/ -cy_as_return_status_t -cy_as_sdio_abort_function( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint8_t resp_type; - cy_as_device *dev_p = (cy_as_device *)handle; - - ret = cy_as_sdio_device_check(dev_p, bus, device); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (!(cy_as_sdio_check_function_initialized(handle, - bus, n_function_no))) - return CY_AS_ERROR_INVALID_FUNCTION; - - if ((cy_as_device_is_storage_async_pending(dev_p)) || - (dev_p->storage_wait)) { - if (!(cy_as_sdio_get_card_capability(handle, bus) & - CY_SDIO_SDC)) - return CY_AS_ERROR_INVALID_COMMAND; - } - - req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDIO_ABORT_IO, - CY_RQT_GENERAL_RQT_CONTEXT, 1); - - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /*Setup mailbox */ - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, n_function_no)); - - reply_p = cy_as_ll_create_response(dev_p, 2); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - resp_type = cy_as_ll_request_response__get_code(reply_p); - - if (resp_type == CY_RESP_SUCCESS_FAILURE) - ret = cy_as_ll_request_response__get_word(reply_p, 0); - else - ret = CY_AS_ERROR_INVALID_RESPONSE; - - -destroy: - if (req_p != 0) - cy_as_ll_destroy_request(dev_p, req_p); - if (reply_p != 0) - cy_as_ll_destroy_response(dev_p, reply_p); - return ret; -} - -/* Suspend IO to current function*/ -cy_as_return_status_t -cy_as_sdio_suspend( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - cy_as_device *dev_p = (cy_as_device *)handle; - - ret = cy_as_sdio_device_check(dev_p, bus, device); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (!(cy_as_sdio_check_function_initialized(handle, bus, - n_function_no))) - return CY_AS_ERROR_INVALID_FUNCTION; - if (!(cy_as_sdio_check_support_bus_suspend(handle, bus))) - return CY_AS_ERROR_INVALID_FUNCTION; - if (!(cy_as_sdio_get_card_capability(handle, bus) & CY_SDIO_SDC)) - return CY_AS_ERROR_INVALID_FUNCTION; - if (cy_as_sdio_check_function_suspended(handle, bus, n_function_no)) - return CY_AS_ERROR_FUNCTION_SUSPENDED; - - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_SDIO_SUSPEND, CY_RQT_GENERAL_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /*Setup mailbox */ - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, n_function_no)); - - reply_p = cy_as_ll_create_response(dev_p, 2); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - - if (ret == CY_AS_ERROR_SUCCESS) { - ret = cy_as_ll_request_response__get_code(reply_p); - cy_as_sdio_set_function_suspended(handle, bus, n_function_no); - } - - if (req_p != 0) - cy_as_ll_destroy_request(dev_p, req_p); - if (reply_p != 0) - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -/*Resume suspended function*/ -cy_as_return_status_t -cy_as_sdio_resume( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no, - cy_as_oper_type op, - uint8_t misc_buf, - uint16_t pendingblockcount, - uint8_t *data_p - ) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t resp_data, ret = CY_AS_ERROR_SUCCESS; - cy_as_device *dev_p = (cy_as_device *)handle; - - ret = cy_as_sdio_device_check(dev_p, bus, device); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (!(cy_as_sdio_check_function_initialized - (handle, bus, n_function_no))) - return CY_AS_ERROR_INVALID_FUNCTION; - - /* If suspend resume is not supported return */ - if (!(cy_as_sdio_check_support_bus_suspend(handle, bus))) - return CY_AS_ERROR_INVALID_FUNCTION; - - /* if the function is not suspended return. */ - if (!(cy_as_sdio_check_function_suspended - (handle, bus, n_function_no))) - return CY_AS_ERROR_INVALID_FUNCTION; - - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_SDIO_RESUME, CY_RQT_STORAGE_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /*Setup mailbox */ - cy_as_ll_request_response__set_word(req_p, 0, - create_address(bus, (uint8_t)device, n_function_no)); - - reply_p = cy_as_ll_create_response(dev_p, 2); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) == - CY_RESP_SDIO_RESUME) { - resp_data = cy_as_ll_request_response__get_word(reply_p, 0); - if (resp_data & 0x00ff) { - /* Send extended read request to resume the read. */ - if (op == cy_as_op_read) { - ret = cy_as_sdio_extended_i_o(handle, bus, - device, n_function_no, 0, misc_buf, - pendingblockcount, cy_false, data_p, 1); - } else { - ret = cy_as_sdio_extended_i_o(handle, bus, - device, n_function_no, 0, misc_buf, - pendingblockcount, cy_true, data_p, 1); - } - } else { - ret = CY_AS_ERROR_SUCCESS; - } - } else { - ret = CY_AS_ERROR_INVALID_RESPONSE; - } - -destroy: - cy_as_sdio_clear_function_suspended(handle, bus, n_function_no); - if (req_p != 0) - cy_as_ll_destroy_request(dev_p, req_p); - if (reply_p != 0) - cy_as_ll_destroy_response(dev_p, reply_p); - return ret; - -} - -/*Set function blocksize. Size cannot exceed max - * block size for the function*/ -cy_as_return_status_t -cy_as_sdio_set_blocksize( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no, - uint16_t blocksize) -{ - cy_as_return_status_t ret; - cy_as_device *dev_p = (cy_as_device *)handle; - ret = cy_as_sdio_device_check(dev_p, bus, device); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (!(cy_as_sdio_check_function_initialized - (handle, bus, n_function_no))) - return CY_AS_ERROR_INVALID_FUNCTION; - if (n_function_no == 0) { - if (blocksize > cy_as_sdio_get_card_max_blocksize(handle, bus)) - return CY_AS_ERROR_INVALID_BLOCKSIZE; - else if (blocksize == cy_as_sdio_get_card_blocksize - (handle, bus)) - return CY_AS_ERROR_SUCCESS; - } else { - if (blocksize > - cy_as_sdio_get_function_max_blocksize(handle, - bus, n_function_no)) - return CY_AS_ERROR_INVALID_BLOCKSIZE; - else if (blocksize == - cy_as_sdio_get_function_blocksize(handle, - bus, n_function_no)) - return CY_AS_ERROR_SUCCESS; - } - - ret = cy_as_sdio_direct_write(handle, bus, device, 0, - (uint16_t)(n_function_no << 8) | - 0x10, 0, blocksize & 0x00ff, 0); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - ret = cy_as_sdio_direct_write(handle, bus, device, 0, - (uint16_t)(n_function_no << 8) | - 0x11, 0, (blocksize & 0xff00) >> 8, 0); - - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (n_function_no == 0) - cy_as_sdio_set_card_block_size(handle, bus, blocksize); - else - cy_as_sdio_set_function_block_size(handle, - bus, n_function_no, blocksize); - return ret; -} -EXPORT_SYMBOL(cy_as_sdio_set_blocksize); - -/* Deinitialize an SDIO function*/ -cy_as_return_status_t -cy_as_sdio_de_init_function( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - uint8_t n_function_no) -{ - cy_as_return_status_t ret; - uint8_t temp; - - if (n_function_no == 0) - return CY_AS_ERROR_INVALID_FUNCTION; - - ret = cy_as_sdio_device_check((cy_as_device *)handle, bus, device); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (!(cy_as_sdio_check_function_initialized - (handle, bus, n_function_no))) - return CY_AS_ERROR_SUCCESS; - - temp = (uint8_t)(((cy_as_device *)handle)->sdiocard[bus]. - function_init_map & (~(1 << n_function_no))); - - cy_as_sdio_direct_write(handle, bus, device, 0, 0x02, 0, temp, 0); - - ((cy_as_device *)handle)->sdiocard[bus].function_init_map &= - (~(1 << n_function_no)); - - return CY_AS_ERROR_SUCCESS; -} - - -/*[]*/ diff --git a/drivers/staging/westbridge/astoria/api/src/cyasusb.c b/drivers/staging/westbridge/astoria/api/src/cyasusb.c deleted file mode 100644 index 1b55e611191e..000000000000 --- a/drivers/staging/westbridge/astoria/api/src/cyasusb.c +++ /dev/null @@ -1,3740 +0,0 @@ -/* Cypress West Bridge API source file (cyasusb.c) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#include "../../include/linux/westbridge/cyashal.h" -#include "../../include/linux/westbridge/cyasusb.h" -#include "../../include/linux/westbridge/cyaserr.h" -#include "../../include/linux/westbridge/cyasdma.h" -#include "../../include/linux/westbridge/cyaslowlevel.h" -#include "../../include/linux/westbridge/cyaslep2pep.h" -#include "../../include/linux/westbridge/cyasregs.h" -#include "../../include/linux/westbridge/cyasstorage.h" - -static cy_as_return_status_t -cy_as_usb_ack_setup_packet( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -static void -cy_as_usb_func_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t ret); -/* -* Reset the USB EP0 state -*/ -static void -cy_as_usb_reset_e_p0_state(cy_as_device *dev_p) -{ - cy_as_log_debug_message(6, "cy_as_usb_reset_e_p0_state called"); - - cy_as_device_clear_ack_delayed(dev_p); - cy_as_device_clear_setup_packet(dev_p); - if (cy_as_device_is_usb_async_pending(dev_p, 0)) - cy_as_usb_cancel_async((cy_as_device_handle)dev_p, 0); - - dev_p->usb_pending_buffer = 0; -} - -/* -* External function to map logical endpoints to physical endpoints -*/ -static cy_as_return_status_t -is_usb_active(cy_as_device *dev_p) -{ - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - if (dev_p->usb_count == 0) - return CY_AS_ERROR_NOT_RUNNING; - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - return CY_AS_ERROR_SUCCESS; -} - -static void -usb_ack_callback(cy_as_device_handle h, - cy_as_return_status_t status, - uint32_t client, - cy_as_funct_c_b_type type, - void *data) -{ - cy_as_device *dev_p = (cy_as_device *)h; - - (void)client; - (void)status; - (void)data; - - cy_as_hal_assert(type == CY_FUNCT_CB_NODATA); - - if (dev_p->usb_pending_buffer) { - cy_as_usb_io_callback cb; - - cb = dev_p->usb_cb[0]; - dev_p->usb_cb[0] = 0; - cy_as_device_clear_usb_async_pending(dev_p, 0); - if (cb) - cb(h, 0, dev_p->usb_pending_size, - dev_p->usb_pending_buffer, dev_p->usb_error); - - dev_p->usb_pending_buffer = 0; - } - - cy_as_device_clear_setup_packet(dev_p); -} - -static void -my_usb_request_callback_usb_event(cy_as_device *dev_p, - cy_as_ll_request_response *req_p) -{ - uint16_t ev; - uint16_t val; - cy_as_device_handle h = (cy_as_device_handle)dev_p; - - ev = cy_as_ll_request_response__get_word(req_p, 0); - switch (ev) { - case 0: /* Reserved */ - cy_as_ll_send_status_response(dev_p, CY_RQT_USB_RQT_CONTEXT, - CY_AS_ERROR_INVALID_REQUEST, 0); - break; - - case 1: /* Reserved */ - cy_as_ll_send_status_response(dev_p, CY_RQT_USB_RQT_CONTEXT, - CY_AS_ERROR_INVALID_REQUEST, 0); - break; - - case 2: /* USB Suspend */ - dev_p->usb_last_event = cy_as_event_usb_suspend; - if (dev_p->usb_event_cb_ms) - dev_p->usb_event_cb_ms(h, cy_as_event_usb_suspend, 0); - else if (dev_p->usb_event_cb) - dev_p->usb_event_cb(h, cy_as_event_usb_suspend, 0); - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); - break; - - case 3: /* USB Resume */ - dev_p->usb_last_event = cy_as_event_usb_resume; - if (dev_p->usb_event_cb_ms) - dev_p->usb_event_cb_ms(h, cy_as_event_usb_resume, 0); - else if (dev_p->usb_event_cb) - dev_p->usb_event_cb(h, cy_as_event_usb_resume, 0); - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); - break; - - case 4: /* USB Reset */ - /* - * if we get a USB reset, the USB host did not understand - * our response or we timed out for some reason. reset - * our internal state to be ready for another set of - * enumeration based requests. - */ - if (cy_as_device_is_ack_delayed(dev_p)) - cy_as_usb_reset_e_p0_state(dev_p); - - dev_p->usb_last_event = cy_as_event_usb_reset; - if (dev_p->usb_event_cb_ms) - dev_p->usb_event_cb_ms(h, cy_as_event_usb_reset, 0); - else if (dev_p->usb_event_cb) - dev_p->usb_event_cb(h, cy_as_event_usb_reset, 0); - - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); - cy_as_device_clear_usb_high_speed(dev_p); - cy_as_usb_set_dma_sizes(dev_p); - dev_p->usb_max_tx_size = 0x40; - cy_as_dma_set_max_dma_size(dev_p, 0x06, 0x40); - break; - - case 5: /* USB Set Configuration */ - /* The configuration to set */ - val = cy_as_ll_request_response__get_word(req_p, 1); - dev_p->usb_last_event = cy_as_event_usb_set_config; - if (dev_p->usb_event_cb_ms) - dev_p->usb_event_cb_ms(h, - cy_as_event_usb_set_config, &val); - else if (dev_p->usb_event_cb) - dev_p->usb_event_cb(h, - cy_as_event_usb_set_config, &val); - - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); - break; - - case 6: /* USB Speed change */ - /* Connect speed */ - val = cy_as_ll_request_response__get_word(req_p, 1); - dev_p->usb_last_event = cy_as_event_usb_speed_change; - if (dev_p->usb_event_cb_ms) - dev_p->usb_event_cb_ms(h, - cy_as_event_usb_speed_change, &val); - else if (dev_p->usb_event_cb) - dev_p->usb_event_cb(h, - cy_as_event_usb_speed_change, &val); - - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); - cy_as_device_set_usb_high_speed(dev_p); - cy_as_usb_set_dma_sizes(dev_p); - dev_p->usb_max_tx_size = 0x200; - cy_as_dma_set_max_dma_size(dev_p, 0x06, 0x200); - break; - - case 7: /* USB Clear Feature */ - /* EP Number */ - val = cy_as_ll_request_response__get_word(req_p, 1); - if (dev_p->usb_event_cb_ms) - dev_p->usb_event_cb_ms(h, - cy_as_event_usb_clear_feature, &val); - if (dev_p->usb_event_cb) - dev_p->usb_event_cb(h, - cy_as_event_usb_clear_feature, &val); - - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); - break; - - default: - cy_as_hal_print_message("invalid event type\n"); - cy_as_ll_send_data_response(dev_p, CY_RQT_USB_RQT_CONTEXT, - CY_RESP_USB_INVALID_EVENT, sizeof(ev), &ev); - break; - } -} - -static void -my_usb_request_callback_usb_data(cy_as_device *dev_p, - cy_as_ll_request_response *req_p) -{ - cy_as_end_point_number_t ep; - uint8_t type; - uint16_t len; - uint16_t val; - cy_as_device_handle h = (cy_as_device_handle)dev_p; - - val = cy_as_ll_request_response__get_word(req_p, 0); - ep = (cy_as_end_point_number_t)((val >> 13) & 0x01); - len = (val & 0x1ff); - - cy_as_hal_assert(len <= 64); - cy_as_ll_request_response__unpack(req_p, - 1, len, dev_p->usb_ep_data); - - type = (uint8_t)((val >> 14) & 0x03); - if (type == 0) { - if (cy_as_device_is_ack_delayed(dev_p)) { - /* - * A setup packet has arrived while we are - * processing a previous setup packet. reset - * our state with respect to EP0 to be ready - * to process the new packet. - */ - cy_as_usb_reset_e_p0_state(dev_p); - } - - if (len != 8) - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, - CY_AS_ERROR_INVALID_REQUEST, 0); - else { - cy_as_device_clear_ep0_stalled(dev_p); - cy_as_device_set_setup_packet(dev_p); - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, - CY_AS_ERROR_SUCCESS, 0); - - if (dev_p->usb_event_cb_ms) - dev_p->usb_event_cb_ms(h, - cy_as_event_usb_setup_packet, - dev_p->usb_ep_data); - else - dev_p->usb_event_cb(h, - cy_as_event_usb_setup_packet, - dev_p->usb_ep_data); - - if ((!cy_as_device_is_ack_delayed(dev_p)) && - (!cy_as_device_is_ep0_stalled(dev_p))) - cy_as_usb_ack_setup_packet(h, - usb_ack_callback, 0); - } - } else if (type == 2) { - if (len != 0) - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, - CY_AS_ERROR_INVALID_REQUEST, 0); - else { - if (dev_p->usb_event_cb_ms) - dev_p->usb_event_cb_ms(h, - cy_as_event_usb_status_packet, 0); - else - dev_p->usb_event_cb(h, - cy_as_event_usb_status_packet, 0); - - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, - CY_AS_ERROR_SUCCESS, 0); - } - } else if (type == 1) { - /* - * we need to hand the data associated with these - * endpoints to the DMA module. - */ - cy_as_dma_received_data(dev_p, ep, len, dev_p->usb_ep_data); - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); - } -} - -static void -my_usb_request_callback_inquiry(cy_as_device *dev_p, - cy_as_ll_request_response *req_p) -{ - cy_as_usb_inquiry_data_dep cbdata; - cy_as_usb_inquiry_data cbdata_ms; - void *data; - uint16_t val; - cy_as_device_handle h = (cy_as_device_handle)dev_p; - uint8_t def_inq_data[64]; - uint8_t evpd; - uint8_t codepage; - cy_bool updated; - uint16_t length; - - cy_as_bus_number_t bus; - uint32_t device; - cy_as_media_type media; - - val = cy_as_ll_request_response__get_word(req_p, 0); - bus = cy_as_storage_get_bus_from_address(val); - device = cy_as_storage_get_device_from_address(val); - media = cy_as_storage_get_media_from_address(val); - - val = cy_as_ll_request_response__get_word(req_p, 1); - evpd = (uint8_t)((val >> 8) & 0x01); - codepage = (uint8_t)(val & 0xff); - - length = cy_as_ll_request_response__get_word(req_p, 2); - data = (void *)def_inq_data; - - updated = cy_false; - - if (dev_p->usb_event_cb_ms) { - cbdata_ms.bus = bus; - cbdata_ms.device = device; - cbdata_ms.updated = updated; - cbdata_ms.evpd = evpd; - cbdata_ms.codepage = codepage; - cbdata_ms.length = length; - cbdata_ms.data = data; - - cy_as_hal_assert(cbdata_ms.length <= sizeof(def_inq_data)); - cy_as_ll_request_response__unpack(req_p, - 3, cbdata_ms.length, cbdata_ms.data); - - dev_p->usb_event_cb_ms(h, - cy_as_event_usb_inquiry_before, &cbdata_ms); - - updated = cbdata_ms.updated; - data = cbdata_ms.data; - length = cbdata_ms.length; - } else if (dev_p->usb_event_cb) { - cbdata.media = media; - cbdata.updated = updated; - cbdata.evpd = evpd; - cbdata.codepage = codepage; - cbdata.length = length; - cbdata.data = data; - - cy_as_hal_assert(cbdata.length <= - sizeof(def_inq_data)); - cy_as_ll_request_response__unpack(req_p, 3, - cbdata.length, cbdata.data); - - dev_p->usb_event_cb(h, - cy_as_event_usb_inquiry_before, &cbdata); - - updated = cbdata.updated; - data = cbdata.data; - length = cbdata.length; - } - - if (updated && length > 192) - cy_as_hal_print_message("an inquiry result from a " - "cy_as_event_usb_inquiry_before event " - "was greater than 192 bytes."); - - /* Now send the reply with the data back - * to the West Bridge device */ - if (updated && length <= 192) { - /* - * the callback function modified the inquiry - * data, ship the data back to the west bridge firmware. - */ - cy_as_ll_send_data_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, - CY_RESP_INQUIRY_DATA, length, data); - } else { - /* - * the callback did not modify the data, just acknowledge - * that we processed the request - */ - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 1); - } - - if (dev_p->usb_event_cb_ms) - dev_p->usb_event_cb_ms(h, - cy_as_event_usb_inquiry_after, &cbdata_ms); - else if (dev_p->usb_event_cb) - dev_p->usb_event_cb(h, - cy_as_event_usb_inquiry_after, &cbdata); -} - -static void -my_usb_request_callback_start_stop(cy_as_device *dev_p, - cy_as_ll_request_response *req_p) -{ - cy_as_bus_number_t bus; - cy_as_media_type media; - uint32_t device; - uint16_t val; - - if (dev_p->usb_event_cb_ms || dev_p->usb_event_cb) { - cy_bool loej; - cy_bool start; - cy_as_device_handle h = (cy_as_device_handle)dev_p; - - val = cy_as_ll_request_response__get_word(req_p, 0); - bus = cy_as_storage_get_bus_from_address(val); - device = cy_as_storage_get_device_from_address(val); - media = cy_as_storage_get_media_from_address(val); - - val = cy_as_ll_request_response__get_word(req_p, 1); - loej = (val & 0x02) ? cy_true : cy_false; - start = (val & 0x01) ? cy_true : cy_false; - - if (dev_p->usb_event_cb_ms) { - cy_as_usb_start_stop_data cbdata_ms; - - cbdata_ms.bus = bus; - cbdata_ms.device = device; - cbdata_ms.loej = loej; - cbdata_ms.start = start; - dev_p->usb_event_cb_ms(h, - cy_as_event_usb_start_stop, &cbdata_ms); - - } else if (dev_p->usb_event_cb) { - cy_as_usb_start_stop_data_dep cbdata; - - cbdata.media = media; - cbdata.loej = loej; - cbdata.start = start; - dev_p->usb_event_cb(h, - cy_as_event_usb_start_stop, &cbdata); - } - } - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 1); -} - -static void -my_usb_request_callback_uknown_c_b_w(cy_as_device *dev_p, - cy_as_ll_request_response *req_p) -{ - uint16_t val; - cy_as_device_handle h = (cy_as_device_handle)dev_p; - uint8_t buf[16]; - - uint8_t response[4]; - uint16_t reqlen; - void *request; - uint8_t status; - uint8_t key; - uint8_t asc; - uint8_t ascq; - - val = cy_as_ll_request_response__get_word(req_p, 0); - /* Failed by default */ - status = 1; - /* Invalid command */ - key = 0x05; - /* Invalid command */ - asc = 0x20; - /* Invalid command */ - ascq = 0x00; - reqlen = cy_as_ll_request_response__get_word(req_p, 1); - request = buf; - - cy_as_hal_assert(reqlen <= sizeof(buf)); - cy_as_ll_request_response__unpack(req_p, 2, reqlen, request); - - if (dev_p->usb_event_cb_ms) { - cy_as_usb_unknown_command_data cbdata_ms; - cbdata_ms.bus = cy_as_storage_get_bus_from_address(val); - cbdata_ms.device = - cy_as_storage_get_device_from_address(val); - cbdata_ms.reqlen = reqlen; - cbdata_ms.request = request; - cbdata_ms.status = status; - cbdata_ms.key = key; - cbdata_ms.asc = asc; - cbdata_ms.ascq = ascq; - - dev_p->usb_event_cb_ms(h, - cy_as_event_usb_unknown_storage, &cbdata_ms); - status = cbdata_ms.status; - key = cbdata_ms.key; - asc = cbdata_ms.asc; - ascq = cbdata_ms.ascq; - } else if (dev_p->usb_event_cb) { - cy_as_usb_unknown_command_data_dep cbdata; - cbdata.media = - cy_as_storage_get_media_from_address(val); - cbdata.reqlen = reqlen; - cbdata.request = request; - cbdata.status = status; - cbdata.key = key; - cbdata.asc = asc; - cbdata.ascq = ascq; - - dev_p->usb_event_cb(h, - cy_as_event_usb_unknown_storage, &cbdata); - status = cbdata.status; - key = cbdata.key; - asc = cbdata.asc; - ascq = cbdata.ascq; - } - - response[0] = status; - response[1] = key; - response[2] = asc; - response[3] = ascq; - cy_as_ll_send_data_response(dev_p, CY_RQT_USB_RQT_CONTEXT, - CY_RESP_UNKNOWN_SCSI_COMMAND, sizeof(response), response); -} - -static void -my_usb_request_callback_m_s_c_progress(cy_as_device *dev_p, - cy_as_ll_request_response *req_p) -{ - uint16_t val1, val2; - cy_as_device_handle h = (cy_as_device_handle)dev_p; - - if ((dev_p->usb_event_cb) || (dev_p->usb_event_cb_ms)) { - cy_as_m_s_c_progress_data cbdata; - - val1 = cy_as_ll_request_response__get_word(req_p, 0); - val2 = cy_as_ll_request_response__get_word(req_p, 1); - cbdata.wr_count = (uint32_t)((val1 << 16) | val2); - - val1 = cy_as_ll_request_response__get_word(req_p, 2); - val2 = cy_as_ll_request_response__get_word(req_p, 3); - cbdata.rd_count = (uint32_t)((val1 << 16) | val2); - - if (dev_p->usb_event_cb) - dev_p->usb_event_cb(h, - cy_as_event_usb_m_s_c_progress, &cbdata); - else - dev_p->usb_event_cb_ms(h, - cy_as_event_usb_m_s_c_progress, &cbdata); - } - - cy_as_ll_send_status_response(dev_p, - CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0); -} - -/* -* This function processes the requests delivered from the -* firmware within the West Bridge device that are delivered -* in the USB context. These requests generally are EP0 and -* EP1 related requests or USB events. -*/ -static void -my_usb_request_callback(cy_as_device *dev_p, uint8_t context, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *resp_p, - cy_as_return_status_t ret) -{ - uint16_t val; - uint8_t code = cy_as_ll_request_response__get_code(req_p); - - (void)resp_p; - (void)context; - (void)ret; - - switch (code) { - case CY_RQT_USB_EVENT: - my_usb_request_callback_usb_event(dev_p, req_p); - break; - - case CY_RQT_USB_EP_DATA: - dev_p->usb_last_event = cy_as_event_usb_setup_packet; - my_usb_request_callback_usb_data(dev_p, req_p); - break; - - case CY_RQT_SCSI_INQUIRY_COMMAND: - dev_p->usb_last_event = cy_as_event_usb_inquiry_after; - my_usb_request_callback_inquiry(dev_p, req_p); - break; - - case CY_RQT_SCSI_START_STOP_COMMAND: - dev_p->usb_last_event = cy_as_event_usb_start_stop; - my_usb_request_callback_start_stop(dev_p, req_p); - break; - - case CY_RQT_SCSI_UNKNOWN_COMMAND: - dev_p->usb_last_event = cy_as_event_usb_unknown_storage; - my_usb_request_callback_uknown_c_b_w(dev_p, req_p); - break; - - case CY_RQT_USB_ACTIVITY_UPDATE: - dev_p->usb_last_event = cy_as_event_usb_m_s_c_progress; - my_usb_request_callback_m_s_c_progress(dev_p, req_p); - break; - - default: - cy_as_hal_print_message("invalid request " - "received on USB context\n"); - val = req_p->box0; - cy_as_ll_send_data_response(dev_p, CY_RQT_USB_RQT_CONTEXT, - CY_RESP_INVALID_REQUEST, sizeof(val), &val); - break; - } -} - -static cy_as_return_status_t -my_handle_response_usb_start(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_return_status_t ret) -{ - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* - * mark EP 0 and EP1 as 64 byte endpoints - */ - cy_as_dma_set_max_dma_size(dev_p, 0, 64); - cy_as_dma_set_max_dma_size(dev_p, 1, 64); - - dev_p->usb_count++; - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_destroy_c_b_queue(dev_p->usb_func_cbs); - cy_as_ll_register_request_callback(dev_p, - CY_RQT_USB_RQT_CONTEXT, 0); - } - - cy_as_device_clear_u_s_s_pending(dev_p); - - return ret; - -} - -/* -* This function starts the USB stack. The stack is reference -* counted so if the stack is already started, this function -* just increments the count. If the stack has not been started, -* a start request is sent to the West Bridge device. -* -* Note: Starting the USB stack does not cause the USB signals -* to be connected to the USB pins. To do this and therefore -* initiate enumeration, CyAsUsbConnect() must be called. -*/ -cy_as_return_status_t -cy_as_usb_start(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p, *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_start called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - if (cy_as_device_is_u_s_s_pending(dev_p)) - return CY_AS_ERROR_STARTSTOP_PENDING; - - cy_as_device_set_u_s_s_pending(dev_p); - - if (dev_p->usb_count == 0) { - /* - * since we are just starting the stack, - * mark USB as not connected to the remote host - */ - cy_as_device_clear_usb_connected(dev_p); - dev_p->usb_phy_config = 0; - - /* Queue for 1.0 Async Requests, kept for - * backwards compatibility */ - dev_p->usb_func_cbs = cy_as_create_c_b_queue(CYAS_USB_FUNC_CB); - if (dev_p->usb_func_cbs == 0) { - cy_as_device_clear_u_s_s_pending(dev_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - /* Reset the EP0 state */ - cy_as_usb_reset_e_p0_state(dev_p); - - /* - * we register here because the start request may cause - * events to occur before the response to the start request. - */ - cy_as_ll_register_request_callback(dev_p, - CY_RQT_USB_RQT_CONTEXT, my_usb_request_callback); - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_START_USB, CY_RQT_USB_RQT_CONTEXT, 0); - if (req_p == 0) { - cy_as_destroy_c_b_queue(dev_p->usb_func_cbs); - dev_p->usb_func_cbs = 0; - cy_as_device_clear_u_s_s_pending(dev_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - /* Reserve space for the reply, the reply data - * will not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_destroy_c_b_queue(dev_p->usb_func_cbs); - dev_p->usb_func_cbs = 0; - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_device_clear_u_s_s_pending(dev_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_usb_start(dev_p, - req_p, reply_p, ret); - } else { - ret = cy_as_misc_send_request(dev_p, cb, - client, CY_FUNCT_CB_USB_START, 0, - dev_p->func_cbs_usb, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - } else { - dev_p->usb_count++; - if (cb) - cb(handle, ret, client, CY_FUNCT_CB_USB_START, 0); - } - - cy_as_device_clear_u_s_s_pending(dev_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_usb_start); - -void -cy_as_usb_reset(cy_as_device *dev_p) -{ - int i; - - cy_as_device_clear_usb_connected(dev_p); - - for (i = 0; i < sizeof(dev_p->usb_config) / - sizeof(dev_p->usb_config[0]); i++) { - /* - * cancel all pending USB read/write operations, as it is - * possible that the USB stack comes up in a different - * configuration with a different set of endpoints. - */ - if (cy_as_device_is_usb_async_pending(dev_p, i)) - cy_as_usb_cancel_async(dev_p, - (cy_as_end_point_number_t)i); - - dev_p->usb_cb[i] = 0; - dev_p->usb_config[i].enabled = cy_false; - } - - dev_p->usb_phy_config = 0; -} - -/* - * This function does all the API side clean-up associated - * with CyAsUsbStop, without any communication with firmware. - * This needs to be done when the device is being reset while - * the USB stack is active. - */ -void -cy_as_usb_cleanup(cy_as_device *dev_p) -{ - if (dev_p->usb_count) { - cy_as_usb_reset_e_p0_state(dev_p); - cy_as_usb_reset(dev_p); - cy_as_hal_mem_set(dev_p->usb_config, 0, - sizeof(dev_p->usb_config)); - cy_as_destroy_c_b_queue(dev_p->usb_func_cbs); - - dev_p->usb_count = 0; - } -} - -static cy_as_return_status_t -my_handle_response_usb_stop(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_return_status_t ret) -{ - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* - * we successfully shutdown the stack, so - * decrement to make the count zero. - */ - cy_as_usb_cleanup(dev_p); - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - if (ret != CY_AS_ERROR_SUCCESS) - cy_as_ll_register_request_callback(dev_p, - CY_RQT_USB_RQT_CONTEXT, 0); - - cy_as_device_clear_u_s_s_pending(dev_p); - - return ret; -} - -/* -* This function stops the USB stack. The USB stack is reference -* counted so first is reference count is decremented. If the -* reference count is then zero, a request is sent to the West -* Bridge device to stop the USB stack on the West Bridge device. -*/ -cy_as_return_status_t -cy_as_usb_stop(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p = 0, *reply_p = 0; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_stop called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_usb_connected(dev_p)) - return CY_AS_ERROR_USB_CONNECTED; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - if (cy_as_device_is_u_s_s_pending(dev_p)) - return CY_AS_ERROR_STARTSTOP_PENDING; - - cy_as_device_set_u_s_s_pending(dev_p); - - if (dev_p->usb_count == 1) { - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_STOP_USB, - CY_RQT_USB_RQT_CONTEXT, 0); - if (req_p == 0) { - ret = CY_AS_ERROR_OUT_OF_MEMORY; - goto destroy; - } - - /* Reserve space for the reply, the reply data will not - * exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - ret = CY_AS_ERROR_OUT_OF_MEMORY; - goto destroy; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_usb_stop(dev_p, - req_p, reply_p, ret); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_USB_STOP, 0, dev_p->func_cbs_usb, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - } else if (dev_p->usb_count > 1) { - /* - * reset all LE_ps to inactive state, after cleaning - * up any pending async read/write calls. - */ - cy_as_usb_reset(dev_p); - dev_p->usb_count--; - - if (cb) - cb(handle, ret, client, CY_FUNCT_CB_USB_STOP, 0); - } - - cy_as_device_clear_u_s_s_pending(dev_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_usb_stop); - -/* -* This function registers a callback to be called when -* USB events are processed -*/ -cy_as_return_status_t -cy_as_usb_register_callback(cy_as_device_handle handle, - cy_as_usb_event_callback callback) -{ - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_register_callback called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (!cy_as_device_is_configured(dev_p)) - return CY_AS_ERROR_NOT_CONFIGURED; - - if (!cy_as_device_is_firmware_loaded(dev_p)) - return CY_AS_ERROR_NO_FIRMWARE; - - dev_p->usb_event_cb = NULL; - dev_p->usb_event_cb_ms = callback; - return CY_AS_ERROR_SUCCESS; -} -EXPORT_SYMBOL(cy_as_usb_register_callback); - -static cy_as_return_status_t -my_handle_response_no_data(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) - ret = CY_AS_ERROR_INVALID_RESPONSE; - else - ret = cy_as_ll_request_response__get_word(reply_p, 0); - - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -static cy_as_return_status_t -my_handle_response_connect(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_return_status_t ret) -{ - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - if (ret == CY_AS_ERROR_SUCCESS) - cy_as_device_set_usb_connected(dev_p); - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - - -/* -* This method asks the West Bridge device to connect the -* internal USB D+ and D- signals to the USB pins, thus -* starting the enumeration processes if the external pins -* are connected to a USB host. If the external pins are -* not connected to a USB host, enumeration will begin as soon -* as the USB pins are connected to a host. -*/ -cy_as_return_status_t -cy_as_usb_connect(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_connect called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_SET_CONNECT_STATE, CY_RQT_USB_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* 1 = Connect request */ - cy_as_ll_request_response__set_word(req_p, 0, 1); - - /* Reserve space for the reply, the reply - * data will not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_connect(dev_p, req_p, reply_p, ret); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_USB_CONNECT, 0, dev_p->func_cbs_usb, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_usb_connect); - -static cy_as_return_status_t -my_handle_response_disconnect(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_return_status_t ret) -{ - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - if (ret == CY_AS_ERROR_SUCCESS) - cy_as_device_clear_usb_connected(dev_p); - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -/* -* This method forces a disconnect of the D+ and D- pins -* external to the West Bridge device from the D+ and D- -* signals internally, effectively disconnecting the West -* Bridge device from any connected USB host. -*/ -cy_as_return_status_t -cy_as_usb_disconnect(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_disconnect called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - if (!cy_as_device_is_usb_connected(dev_p)) - return CY_AS_ERROR_USB_NOT_CONNECTED; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_SET_CONNECT_STATE, CY_RQT_USB_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, 0); - - /* Reserve space for the reply, the reply - * data will not exceed two bytes */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_disconnect(dev_p, - req_p, reply_p, ret); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_USB_DISCONNECT, 0, dev_p->func_cbs_usb, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_usb_disconnect); - -static cy_as_return_status_t -my_handle_response_set_enum_config(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - - if (ret == CY_AS_ERROR_SUCCESS) { - /* - * we configured the west bridge device and - * enumeration is going to happen on the P port - * processor. now we must enable endpoint zero - */ - cy_as_usb_end_point_config config; - - config.dir = cy_as_usb_in_out; - config.type = cy_as_usb_control; - config.enabled = cy_true; - - ret = cy_as_usb_set_end_point_config((cy_as_device_handle *) - dev_p, 0, &config); - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -/* -* This method sets how the USB is enumerated and should -* be called before the CyAsUsbConnect() is called. -*/ -static cy_as_return_status_t -my_usb_set_enum_config(cy_as_device *dev_p, - uint8_t bus_mask, - uint8_t media_mask, - cy_bool use_antioch_enumeration, - uint8_t mass_storage_interface, - uint8_t mtp_interface, - cy_bool mass_storage_callbacks, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_as_log_debug_message(6, "cy_as_usb_set_enum_config called"); - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_usb_connected(dev_p)) - return CY_AS_ERROR_USB_CONNECTED; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - /* if we are using MTP firmware: */ - if (dev_p->is_mtp_firmware == 1) { - /* we cannot enumerate MSC */ - if (mass_storage_interface != 0) - return CY_AS_ERROR_INVALID_CONFIGURATION; - - if (bus_mask == 0) { - if (mtp_interface != 0) - return CY_AS_ERROR_INVALID_CONFIGURATION; - } else if (bus_mask == 2) { - /* enable EP 1 as it will be used */ - cy_as_dma_enable_end_point(dev_p, 1, cy_true, - cy_as_direction_in); - dev_p->usb_config[1].enabled = cy_true; - dev_p->usb_config[1].dir = cy_as_usb_in; - dev_p->usb_config[1].type = cy_as_usb_int; - } else { - return CY_AS_ERROR_INVALID_CONFIGURATION; - } - /* if we are not using MTP firmware, we cannot enumerate MTP */ - } else if (mtp_interface != 0) - return CY_AS_ERROR_INVALID_CONFIGURATION; - - /* - * if we are not enumerating mass storage, we should - * not be providing an interface number. - */ - if (bus_mask == 0 && mass_storage_interface != 0) - return CY_AS_ERROR_INVALID_CONFIGURATION; - - /* - * if we are going to use mtp_interface, bus mask must be 2. - */ - if (mtp_interface != 0 && bus_mask != 2) - return CY_AS_ERROR_INVALID_CONFIGURATION; - - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_SET_USB_CONFIG, CY_RQT_USB_RQT_CONTEXT, 4); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* Marshal the structure */ - cy_as_ll_request_response__set_word(req_p, 0, - (uint16_t)((media_mask << 8) | bus_mask)); - cy_as_ll_request_response__set_word(req_p, 1, - (uint16_t)use_antioch_enumeration); - cy_as_ll_request_response__set_word(req_p, 2, - dev_p->is_mtp_firmware ? mtp_interface : - mass_storage_interface); - cy_as_ll_request_response__set_word(req_p, 3, - (uint16_t)mass_storage_callbacks); - - /* Reserve space for the reply, the reply - * data will not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_set_enum_config(dev_p, - req_p, reply_p); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_USB_SETENUMCONFIG, 0, dev_p->func_cbs_usb, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -/* - * This method sets how the USB is enumerated and should - * be called before the CyAsUsbConnect() is called. - */ -cy_as_return_status_t -cy_as_usb_set_enum_config(cy_as_device_handle handle, - cy_as_usb_enum_control *config_p, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - uint8_t bus_mask, media_mask; - uint32_t bus, device; - cy_as_return_status_t ret; - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if ((cy_as_device_is_in_callback(dev_p)) && (cb != 0)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - /* Since we are mapping the media types to bus with NAND to 0 - * and the rest to 1, and we are only allowing for enumerating - * all the devices on a bus we just scan the array for any - * positions where there a device is enabled and mark the bus - * to be enumerated. - */ - bus_mask = 0; - media_mask = 0; - for (bus = 0; bus < CY_AS_MAX_BUSES; bus++) { - for (device = 0; device < CY_AS_MAX_STORAGE_DEVICES; device++) { - if (config_p->devices_to_enumerate[bus][device] == - cy_true) { - bus_mask |= (0x01 << bus); - media_mask |= dev_p->media_supported[bus]; - media_mask |= dev_p->media_supported[bus]; - } - } - } - - return my_usb_set_enum_config(dev_p, bus_mask, media_mask, - config_p->antioch_enumeration, - config_p->mass_storage_interface, - config_p->mtp_interface, - config_p->mass_storage_callbacks, - cb, - client - ); -} -EXPORT_SYMBOL(cy_as_usb_set_enum_config); - -static cy_as_return_status_t -my_handle_response_get_enum_config(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - void *config_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint16_t val; - uint8_t bus_mask; - uint32_t bus; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_USB_CONFIG) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - /* Marshal the reply */ - if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) { - uint32_t device; - cy_bool state; - cy_as_usb_enum_control *ms_config_p = - (cy_as_usb_enum_control *)config_p; - - bus_mask = (uint8_t) - (cy_as_ll_request_response__get_word - (reply_p, 0) & 0xFF); - for (bus = 0; bus < CY_AS_MAX_BUSES; bus++) { - if (bus_mask & (1 << bus)) - state = cy_true; - else - state = cy_false; - - for (device = 0; device < CY_AS_MAX_STORAGE_DEVICES; - device++) - ms_config_p->devices_to_enumerate[bus][device] - = state; - } - - ms_config_p->antioch_enumeration = - (cy_bool)cy_as_ll_request_response__get_word - (reply_p, 1); - - val = cy_as_ll_request_response__get_word(reply_p, 2); - if (dev_p->is_mtp_firmware) { - ms_config_p->mass_storage_interface = 0; - ms_config_p->mtp_interface = (uint8_t)(val & 0xFF); - } else { - ms_config_p->mass_storage_interface = - (uint8_t)(val & 0xFF); - ms_config_p->mtp_interface = 0; - } - ms_config_p->mass_storage_callbacks = (cy_bool)(val >> 8); - - /* - * firmware returns an invalid interface number for mass storage, - * if mass storage is not enabled. this needs to be converted to - * zero to match the input configuration. - */ - if (bus_mask == 0) { - if (dev_p->is_mtp_firmware) - ms_config_p->mtp_interface = 0; - else - ms_config_p->mass_storage_interface = 0; - } - } else { - cy_as_usb_enum_control_dep *ex_config_p = - (cy_as_usb_enum_control_dep *)config_p; - - ex_config_p->enum_mass_storage = (uint8_t) - ((cy_as_ll_request_response__get_word - (reply_p, 0) >> 8) & 0xFF); - ex_config_p->antioch_enumeration = (cy_bool) - cy_as_ll_request_response__get_word(reply_p, 1); - - val = cy_as_ll_request_response__get_word(reply_p, 2); - ex_config_p->mass_storage_interface = (uint8_t)(val & 0xFF); - ex_config_p->mass_storage_callbacks = (cy_bool)(val >> 8); - - /* - * firmware returns an invalid interface number for mass - * storage, if mass storage is not enabled. this needs to - * be converted to zero to match the input configuration. - */ - if (ex_config_p->enum_mass_storage == 0) - ex_config_p->mass_storage_interface = 0; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -/* -* This sets up the request for the enumerateion configuration -* information, based on if the request is from the old pre-1.2 -* functions. -*/ -static cy_as_return_status_t -my_usb_get_enum_config(cy_as_device_handle handle, - uint16_t req_flags, - void *config_p, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_get_enum_config called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_GET_USB_CONFIG, CY_RQT_USB_RQT_CONTEXT, 0); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* Reserve space for the reply, the reply data - * will not exceed two bytes */ - reply_p = cy_as_ll_create_response(dev_p, 3); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - /* we need to know the type of request to - * know how to manage the data */ - req_p->flags |= req_flags; - return my_handle_response_get_enum_config(dev_p, - req_p, reply_p, config_p); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_USB_GETENUMCONFIG, config_p, - dev_p->func_cbs_usb, req_flags, req_p, reply_p, - cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -/* - * This method returns the enumerateion configuration information - * from the West Bridge device. Generally this is not used by - * client software but is provided mostly for debug information. - * We want a method to read all state information from the device. - */ -cy_as_return_status_t -cy_as_usb_get_enum_config(cy_as_device_handle handle, - cy_as_usb_enum_control *config_p, - cy_as_function_callback cb, - uint32_t client) -{ - return my_usb_get_enum_config(handle, - CY_AS_REQUEST_RESPONSE_MS, config_p, cb, client); -} -EXPORT_SYMBOL(cy_as_usb_get_enum_config); - -/* -* This method sets the USB descriptor for a given entity. -*/ -cy_as_return_status_t -cy_as_usb_set_descriptor(cy_as_device_handle handle, - cy_as_usb_desc_type type, - uint8_t index, - void *desc_p, - uint16_t length, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint16_t pktlen; - - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_set_descriptor called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - if (length > CY_AS_MAX_USB_DESCRIPTOR_SIZE) - return CY_AS_ERROR_INVALID_DESCRIPTOR; - - pktlen = (uint16_t)length / 2; - if (length % 2) - pktlen++; - pktlen += 2; /* 1 for type, 1 for length */ - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, CY_RQT_SET_DESCRIPTOR, - CY_RQT_USB_RQT_CONTEXT, (uint16_t)pktlen); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, - (uint16_t)((uint8_t)type | (index << 8))); - cy_as_ll_request_response__set_word(req_p, 1, - (uint16_t)length); - cy_as_ll_request_response__pack(req_p, 2, length, desc_p); - - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_no_data(dev_p, req_p, reply_p); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_USB_SETDESCRIPTOR, 0, dev_p->func_cbs_usb, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_usb_set_descriptor); - -/* - * This method clears all descriptors that were previously - * stored on the West Bridge through CyAsUsbSetDescriptor calls. - */ -cy_as_return_status_t -cy_as_usb_clear_descriptors(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_ll_request_response *req_p , *reply_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_clear_descriptors called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if ((cy_as_device_is_in_callback(dev_p)) && (cb == 0)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_CLEAR_DESCRIPTORS, CY_RQT_USB_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_no_data(dev_p, req_p, reply_p); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_USB_CLEARDESCRIPTORS, 0, - dev_p->func_cbs_usb, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_usb_clear_descriptors); - -static cy_as_return_status_t -my_handle_response_get_descriptor(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_get_descriptor_data *data) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint32_t retlen; - - if (cy_as_ll_request_response__get_code(reply_p) == - CY_RESP_SUCCESS_FAILURE) { - ret = cy_as_ll_request_response__get_word(reply_p, 0); - goto destroy; - } else if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_USB_DESCRIPTOR) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - retlen = cy_as_ll_request_response__get_word(reply_p, 0); - if (retlen > data->length) { - ret = CY_AS_ERROR_INVALID_SIZE; - goto destroy; - } - - ret = CY_AS_ERROR_SUCCESS; - cy_as_ll_request_response__unpack(reply_p, 1, - retlen, data->desc_p); - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -/* -* This method retreives the USB descriptor for a given type. -*/ -cy_as_return_status_t -cy_as_usb_get_descriptor(cy_as_device_handle handle, - cy_as_usb_desc_type type, - uint8_t index, - cy_as_get_descriptor_data *data, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret; - cy_as_ll_request_response *req_p , *reply_p; - - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_get_descriptor called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_GET_DESCRIPTOR, CY_RQT_USB_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, - (uint16_t)((uint8_t)type | (index << 8))); - - /* Add one for the length field */ - reply_p = cy_as_ll_create_response(dev_p, - CY_AS_MAX_USB_DESCRIPTOR_SIZE + 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply( - dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return my_handle_response_get_descriptor(dev_p, - req_p, reply_p, data); - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_USB_GETDESCRIPTOR, data, - dev_p->func_cbs_usb, - CY_AS_REQUEST_RESPONSE_EX, req_p, - reply_p, cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_usb_get_descriptor); - -cy_as_return_status_t -cy_as_usb_set_physical_configuration(cy_as_device_handle handle, - uint8_t config) -{ - cy_as_return_status_t ret; - cy_as_device *dev_p; - - cy_as_log_debug_message(6, - "cy_as_usb_set_physical_configuration called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_usb_connected(dev_p)) - return CY_AS_ERROR_USB_CONNECTED; - - if (config < 1 || config > 12) - return CY_AS_ERROR_INVALID_CONFIGURATION; - - dev_p->usb_phy_config = config; - - return CY_AS_ERROR_SUCCESS; -} -EXPORT_SYMBOL(cy_as_usb_set_physical_configuration); - -static cy_bool -is_physical_valid(uint8_t config, cy_as_end_point_number_t ep) -{ - static uint8_t validmask[12] = { - 0x0f, /* Config 1 - 1, 2, 3, 4 */ - 0x07, /* Config 2 - 1, 2, 3 */ - 0x07, /* Config 3 - 1, 2, 3 */ - 0x0d, /* Config 4 - 1, 3, 4 */ - 0x05, /* Config 5 - 1, 3 */ - 0x05, /* Config 6 - 1, 3 */ - 0x0d, /* Config 7 - 1, 3, 4 */ - 0x05, /* Config 8 - 1, 3 */ - 0x05, /* Config 9 - 1, 3 */ - 0x0d, /* Config 10 - 1, 3, 4 */ - 0x09, /* Config 11 - 1, 4 */ - 0x01 /* Config 12 - 1 */ - }; - - return (validmask[config - 1] & (1 << (ep - 1))) ? cy_true : cy_false; -} - -/* -* This method sets the configuration for an endpoint -*/ -cy_as_return_status_t -cy_as_usb_set_end_point_config(cy_as_device_handle handle, - cy_as_end_point_number_t ep, cy_as_usb_end_point_config *config_p) -{ - cy_as_return_status_t ret; - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_set_end_point_config called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_usb_connected(dev_p)) - return CY_AS_ERROR_USB_CONNECTED; - - if (ep >= 16 || ep == 2 || ep == 4 || ep == 6 || ep == 8) - return CY_AS_ERROR_INVALID_ENDPOINT; - - if (ep == 0) { - /* Endpoint 0 must be 64 byte, dir IN/OUT, - * and control type */ - if (config_p->dir != cy_as_usb_in_out || - config_p->type != cy_as_usb_control) - return CY_AS_ERROR_INVALID_CONFIGURATION; - } else if (ep == 1) { - if ((dev_p->is_mtp_firmware == 1) && - (dev_p->usb_config[1].enabled == cy_true)) { - return CY_AS_ERROR_INVALID_ENDPOINT; - } - - /* - * EP1 can only be used either as an OUT ep, or as an IN ep. - */ - if ((config_p->type == cy_as_usb_control) || - (config_p->type == cy_as_usb_iso) || - (config_p->dir == cy_as_usb_in_out)) - return CY_AS_ERROR_INVALID_CONFIGURATION; - } else { - if (config_p->dir == cy_as_usb_in_out || - config_p->type == cy_as_usb_control) - return CY_AS_ERROR_INVALID_CONFIGURATION; - - if (!is_physical_valid(dev_p->usb_phy_config, - config_p->physical)) - return CY_AS_ERROR_INVALID_PHYSICAL_ENDPOINT; - - /* - * ISO endpoints must be on E_ps 3, 5, 7 or 9 as - * they need to align directly with the underlying - * physical endpoint. - */ - if (config_p->type == cy_as_usb_iso) { - if (ep != 3 && ep != 5 && ep != 7 && ep != 9) - return CY_AS_ERROR_INVALID_CONFIGURATION; - - if (ep == 3 && config_p->physical != 1) - return CY_AS_ERROR_INVALID_CONFIGURATION; - - if (ep == 5 && config_p->physical != 2) - return CY_AS_ERROR_INVALID_CONFIGURATION; - - if (ep == 7 && config_p->physical != 3) - return CY_AS_ERROR_INVALID_CONFIGURATION; - - if (ep == 9 && config_p->physical != 4) - return CY_AS_ERROR_INVALID_CONFIGURATION; - } - } - - /* Store the configuration information until a - * CyAsUsbCommitConfig is done */ - dev_p->usb_config[ep] = *config_p; - - /* If the endpoint is enabled, enable DMA associated - * with the endpoint */ - /* - * we make some assumptions that we check here. we assume - * that the direction fields for the DMA module are the same - * values as the direction values for the USB module. - */ - cy_as_hal_assert((int)cy_as_usb_in == (int)cy_as_direction_in); - cy_as_hal_assert((int)cy_as_usb_out == (int)cy_as_direction_out); - cy_as_hal_assert((int)cy_as_usb_in_out == (int)cy_as_direction_in_out); - - return cy_as_dma_enable_end_point(dev_p, ep, - config_p->enabled, (cy_as_dma_direction)config_p->dir); -} -EXPORT_SYMBOL(cy_as_usb_set_end_point_config); - -cy_as_return_status_t -cy_as_usb_get_end_point_config(cy_as_device_handle handle, - cy_as_end_point_number_t ep, cy_as_usb_end_point_config *config_p) -{ - cy_as_return_status_t ret; - - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_get_end_point_config called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (ep >= 16 || ep == 2 || ep == 4 || ep == 6 || ep == 8) - return CY_AS_ERROR_INVALID_ENDPOINT; - - *config_p = dev_p->usb_config[ep]; - - return CY_AS_ERROR_SUCCESS; -} -EXPORT_SYMBOL(cy_as_usb_get_end_point_config); - -/* -* Commit the configuration of the various endpoints to the hardware. -*/ -cy_as_return_status_t -cy_as_usb_commit_config(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - uint32_t i; - cy_as_return_status_t ret; - cy_as_ll_request_response *req_p , *reply_p; - cy_as_device *dev_p; - uint16_t data; - - cy_as_log_debug_message(6, "cy_as_usb_commit_config called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_usb_connected(dev_p)) - return CY_AS_ERROR_USB_CONNECTED; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - /* - * this performs the mapping based on informatation that was - * previously stored on the device about the various endpoints - * and how they are configured. the output of this mapping is - * setting the the 14 register values contained in usb_lepcfg - * and usb_pepcfg - */ - ret = cy_as_usb_map_logical2_physical(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* - * now, package the information about the various logical and - * physical endpoint configuration registers and send it - * across to the west bridge device. - */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_SET_USB_CONFIG_REGISTERS, CY_RQT_USB_RQT_CONTEXT, 8); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_hal_print_message("USB configuration: %d\n", - dev_p->usb_phy_config); - cy_as_hal_print_message("EP1OUT: 0x%02x EP1IN: 0x%02x\n", - dev_p->usb_ep1cfg[0], dev_p->usb_ep1cfg[1]); - cy_as_hal_print_message("PEP registers: 0x%02x 0x%02x 0x%02x 0x%02x\n", - dev_p->usb_pepcfg[0], dev_p->usb_pepcfg[1], - dev_p->usb_pepcfg[2], dev_p->usb_pepcfg[3]); - - cy_as_hal_print_message("LEP registers: 0x%02x 0x%02x 0x%02x " - "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", - dev_p->usb_lepcfg[0], dev_p->usb_lepcfg[1], - dev_p->usb_lepcfg[2], dev_p->usb_lepcfg[3], - dev_p->usb_lepcfg[4], dev_p->usb_lepcfg[5], - dev_p->usb_lepcfg[6], dev_p->usb_lepcfg[7], - dev_p->usb_lepcfg[8], dev_p->usb_lepcfg[9]); - - /* Write the EP1OUTCFG and EP1INCFG data in the first word. */ - data = (uint16_t)((dev_p->usb_ep1cfg[0] << 8) | - dev_p->usb_ep1cfg[1]); - cy_as_ll_request_response__set_word(req_p, 0, data); - - /* Write the PEP CFG data in the next 2 words */ - for (i = 0; i < 4; i += 2) { - data = (uint16_t)((dev_p->usb_pepcfg[i] << 8) | - dev_p->usb_pepcfg[i + 1]); - cy_as_ll_request_response__set_word(req_p, - 1 + i / 2, data); - } - - /* Write the LEP CFG data in the next 5 words */ - for (i = 0; i < 10; i += 2) { - data = (uint16_t)((dev_p->usb_lepcfg[i] << 8) | - dev_p->usb_lepcfg[i + 1]); - cy_as_ll_request_response__set_word(req_p, - 3 + i / 2, data); - } - - /* A single status word response type */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - ret = my_handle_response_no_data(dev_p, - req_p, reply_p); - - if (ret == CY_AS_ERROR_SUCCESS) - ret = cy_as_usb_setup_dma(dev_p); - - return ret; - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_USB_COMMITCONFIG, 0, dev_p->func_cbs_usb, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_usb_commit_config); - -static void -sync_request_callback(cy_as_device *dev_p, - cy_as_end_point_number_t ep, void *buf_p, - uint32_t size, cy_as_return_status_t err) -{ - (void)ep; - (void)buf_p; - - dev_p->usb_error = err; - dev_p->usb_actual_cnt = size; -} - -static void -async_read_request_callback(cy_as_device *dev_p, - cy_as_end_point_number_t ep, void *buf_p, - uint32_t size, cy_as_return_status_t err) -{ - cy_as_device_handle h; - - cy_as_log_debug_message(6, - "async_read_request_callback called"); - - h = (cy_as_device_handle)dev_p; - - if (ep == 0 && cy_as_device_is_ack_delayed(dev_p)) { - dev_p->usb_pending_buffer = buf_p; - dev_p->usb_pending_size = size; - dev_p->usb_error = err; - cy_as_usb_ack_setup_packet(h, usb_ack_callback, 0); - } else { - cy_as_usb_io_callback cb; - - cb = dev_p->usb_cb[ep]; - dev_p->usb_cb[ep] = 0; - cy_as_device_clear_usb_async_pending(dev_p, ep); - if (cb) - cb(h, ep, size, buf_p, err); - } -} - -static void -async_write_request_callback(cy_as_device *dev_p, - cy_as_end_point_number_t ep, void *buf_p, - uint32_t size, cy_as_return_status_t err) -{ - cy_as_device_handle h; - - cy_as_log_debug_message(6, - "async_write_request_callback called"); - - h = (cy_as_device_handle)dev_p; - - if (ep == 0 && cy_as_device_is_ack_delayed(dev_p)) { - dev_p->usb_pending_buffer = buf_p; - dev_p->usb_pending_size = size; - dev_p->usb_error = err; - - /* The west bridge protocol generates ZLPs as required. */ - cy_as_usb_ack_setup_packet(h, usb_ack_callback, 0); - } else { - cy_as_usb_io_callback cb; - - cb = dev_p->usb_cb[ep]; - dev_p->usb_cb[ep] = 0; - - cy_as_device_clear_usb_async_pending(dev_p, ep); - if (cb) - cb(h, ep, size, buf_p, err); - } -} - -static void -my_turbo_rqt_callback(cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t stat) -{ - uint8_t code; - - (void)context; - (void)stat; - - /* The Handlers are responsible for Deleting the rqt and resp when - * they are finished - */ - code = cy_as_ll_request_response__get_code(rqt); - switch (code) { - case CY_RQT_TURBO_SWITCH_ENDPOINT: - cy_as_hal_assert(stat == CY_AS_ERROR_SUCCESS); - cy_as_ll_destroy_request(dev_p, rqt); - cy_as_ll_destroy_response(dev_p, resp); - break; - default: - cy_as_hal_assert(cy_false); - break; - } -} - -/* Send a mailbox request to prepare the endpoint for switching */ -static cy_as_return_status_t -my_send_turbo_switch(cy_as_device *dev_p, uint32_t size, cy_bool pktread) -{ - cy_as_return_status_t ret; - cy_as_ll_request_response *req_p , *reply_p; - - /* Create the request to send to the West Bridge device */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_TURBO_SWITCH_ENDPOINT, CY_RQT_TUR_RQT_CONTEXT, 3); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* Reserve space for the reply, the reply data will - * not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - cy_as_ll_request_response__set_word(req_p, 0, - (uint16_t)pktread); - cy_as_ll_request_response__set_word(req_p, 1, - (uint16_t)((size >> 16) & 0xFFFF)); - cy_as_ll_request_response__set_word(req_p, 2, - (uint16_t)(size & 0xFFFF)); - - ret = cy_as_ll_send_request(dev_p, req_p, - reply_p, cy_false, my_turbo_rqt_callback); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_request(dev_p, reply_p); - return ret; - } - - return CY_AS_ERROR_SUCCESS; -} - -cy_as_return_status_t -cy_as_usb_read_data(cy_as_device_handle handle, - cy_as_end_point_number_t ep, cy_bool pktread, - uint32_t dsize, uint32_t *dataread, void *data) -{ - cy_as_return_status_t ret; - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_read_data called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - if (ep >= 16 || ep == 4 || ep == 6 || ep == 8) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* EP2 is available for reading when MTP is active */ - if (dev_p->mtp_count == 0 && ep == CY_AS_MTP_READ_ENDPOINT) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* If the endpoint is disabled, we cannot - * write data to the endpoint */ - if (!dev_p->usb_config[ep].enabled) - return CY_AS_ERROR_ENDPOINT_DISABLED; - - if (dev_p->usb_config[ep].dir != cy_as_usb_out) - return CY_AS_ERROR_USB_BAD_DIRECTION; - - ret = cy_as_dma_queue_request(dev_p, ep, data, dsize, - pktread, cy_true, sync_request_callback); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (ep == CY_AS_MTP_READ_ENDPOINT) { - ret = my_send_turbo_switch(dev_p, dsize, pktread); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_dma_cancel(dev_p, ep, ret); - return ret; - } - - ret = cy_as_dma_drain_queue(dev_p, ep, cy_false); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - } else { - ret = cy_as_dma_drain_queue(dev_p, ep, cy_true); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - } - - ret = dev_p->usb_error; - *dataread = dev_p->usb_actual_cnt; - - return ret; -} -EXPORT_SYMBOL(cy_as_usb_read_data); - -cy_as_return_status_t -cy_as_usb_read_data_async(cy_as_device_handle handle, - cy_as_end_point_number_t ep, cy_bool pktread, - uint32_t dsize, void *data, cy_as_usb_io_callback cb) -{ - cy_as_return_status_t ret; - uint32_t mask; - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_read_data_async called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (ep >= 16 || ep == 4 || ep == 6 || ep == 8) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* EP2 is available for reading when MTP is active */ - if (dev_p->mtp_count == 0 && ep == CY_AS_MTP_READ_ENDPOINT) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* If the endpoint is disabled, we cannot - * write data to the endpoint */ - if (!dev_p->usb_config[ep].enabled) - return CY_AS_ERROR_ENDPOINT_DISABLED; - - if (dev_p->usb_config[ep].dir != cy_as_usb_out && - dev_p->usb_config[ep].dir != cy_as_usb_in_out) - return CY_AS_ERROR_USB_BAD_DIRECTION; - - /* - * since async operations can be triggered by interrupt - * code, we must insure that we do not get multiple async - * operations going at one time and protect this test and - * set operation from interrupts. - */ - mask = cy_as_hal_disable_interrupts(); - if (cy_as_device_is_usb_async_pending(dev_p, ep)) { - cy_as_hal_enable_interrupts(mask); - return CY_AS_ERROR_ASYNC_PENDING; - } - cy_as_device_set_usb_async_pending(dev_p, ep); - - /* - * if this is for EP0, we set this bit to delay the - * ACK response until after this read has completed. - */ - if (ep == 0) - cy_as_device_set_ack_delayed(dev_p); - - cy_as_hal_enable_interrupts(mask); - - cy_as_hal_assert(dev_p->usb_cb[ep] == 0); - dev_p->usb_cb[ep] = cb; - - ret = cy_as_dma_queue_request(dev_p, ep, data, dsize, - pktread, cy_true, async_read_request_callback); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (ep == CY_AS_MTP_READ_ENDPOINT) { - ret = my_send_turbo_switch(dev_p, dsize, pktread); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_dma_cancel(dev_p, ep, ret); - return ret; - } - } else { - /* Kick start the queue if it is not running */ - cy_as_dma_kick_start(dev_p, ep); - } - return ret; -} -EXPORT_SYMBOL(cy_as_usb_read_data_async); - -cy_as_return_status_t -cy_as_usb_write_data(cy_as_device_handle handle, - cy_as_end_point_number_t ep, uint32_t dsize, void *data) -{ - cy_as_return_status_t ret; - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_write_data called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - if (ep >= 16 || ep == 2 || ep == 4 || ep == 8) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* EP6 is available for writing when MTP is active */ - if (dev_p->mtp_count == 0 && ep == CY_AS_MTP_WRITE_ENDPOINT) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* If the endpoint is disabled, we cannot - * write data to the endpoint */ - if (!dev_p->usb_config[ep].enabled) - return CY_AS_ERROR_ENDPOINT_DISABLED; - - if (dev_p->usb_config[ep].dir != cy_as_usb_in && - dev_p->usb_config[ep].dir != cy_as_usb_in_out) - return CY_AS_ERROR_USB_BAD_DIRECTION; - - /* Write on Turbo endpoint */ - if (ep == CY_AS_MTP_WRITE_ENDPOINT) { - cy_as_ll_request_response *req_p, *reply_p; - - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_TURBO_SEND_RESP_DATA_TO_HOST, - CY_RQT_TUR_RQT_CONTEXT, 3); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, - 0, 0x0006); /* EP number to use. */ - cy_as_ll_request_response__set_word(req_p, - 1, (uint16_t)((dsize >> 16) & 0xFFFF)); - cy_as_ll_request_response__set_word(req_p, - 2, (uint16_t)(dsize & 0xFFFF)); - - /* Reserve space for the reply, the reply data - * will not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (dsize) { - ret = cy_as_dma_queue_request(dev_p, - ep, data, dsize, cy_false, - cy_false, sync_request_callback); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - } - - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret == CY_AS_ERROR_SUCCESS) { - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) - ret = CY_AS_ERROR_INVALID_RESPONSE; - else - ret = cy_as_ll_request_response__get_word - (reply_p, 0); - } - - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - if (ret != CY_AS_ERROR_SUCCESS) { - if (dsize) - cy_as_dma_cancel(dev_p, ep, ret); - return ret; - } - - /* If this is a zero-byte write, firmware will - * handle it. there is no need to do any work here. - */ - if (!dsize) - return CY_AS_ERROR_SUCCESS; - } else { - ret = cy_as_dma_queue_request(dev_p, ep, data, dsize, - cy_false, cy_false, sync_request_callback); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - } - - if (ep != CY_AS_MTP_WRITE_ENDPOINT) - ret = cy_as_dma_drain_queue(dev_p, ep, cy_true); - else - ret = cy_as_dma_drain_queue(dev_p, ep, cy_false); - - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - ret = dev_p->usb_error; - return ret; -} -EXPORT_SYMBOL(cy_as_usb_write_data); - -static void -mtp_write_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t ret) -{ - cy_as_usb_io_callback cb; - cy_as_device_handle h = (cy_as_device_handle)dev_p; - - cy_as_hal_assert(context == CY_RQT_TUR_RQT_CONTEXT); - - if (ret == CY_AS_ERROR_SUCCESS) { - if (cy_as_ll_request_response__get_code(resp) != - CY_RESP_SUCCESS_FAILURE) - ret = CY_AS_ERROR_INVALID_RESPONSE; - else - ret = cy_as_ll_request_response__get_word(resp, 0); - } - - /* If this was a zero byte transfer request, we can - * call the callback from here. */ - if ((cy_as_ll_request_response__get_word(rqt, 1) == 0) && - (cy_as_ll_request_response__get_word(rqt, 2) == 0)) { - cb = dev_p->usb_cb[CY_AS_MTP_WRITE_ENDPOINT]; - dev_p->usb_cb[CY_AS_MTP_WRITE_ENDPOINT] = 0; - cy_as_device_clear_usb_async_pending(dev_p, - CY_AS_MTP_WRITE_ENDPOINT); - if (cb) - cb(h, CY_AS_MTP_WRITE_ENDPOINT, 0, 0, ret); - - goto destroy; - } - - if (ret != CY_AS_ERROR_SUCCESS) { - /* Firmware failed the request. Cancel the DMA transfer. */ - cy_as_dma_cancel(dev_p, 0x06, CY_AS_ERROR_CANCELED); - dev_p->usb_cb[0x06] = 0; - cy_as_device_clear_usb_async_pending(dev_p, 0x06); - } - -destroy: - cy_as_ll_destroy_response(dev_p, resp); - cy_as_ll_destroy_request(dev_p, rqt); -} - -cy_as_return_status_t -cy_as_usb_write_data_async(cy_as_device_handle handle, - cy_as_end_point_number_t ep, uint32_t dsize, void *data, - cy_bool spacket, cy_as_usb_io_callback cb) -{ - uint32_t mask; - cy_as_return_status_t ret; - cy_as_device *dev_p; - - cy_as_log_debug_message(6, "cy_as_usb_write_data_async called"); - - dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (ep >= 16 || ep == 2 || ep == 4 || ep == 8) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* EP6 is available for writing when MTP is active */ - if (dev_p->mtp_count == 0 && ep == CY_AS_MTP_WRITE_ENDPOINT) - return CY_AS_ERROR_INVALID_ENDPOINT; - - /* If the endpoint is disabled, we cannot - * write data to the endpoint */ - if (!dev_p->usb_config[ep].enabled) - return CY_AS_ERROR_ENDPOINT_DISABLED; - - if (dev_p->usb_config[ep].dir != cy_as_usb_in && - dev_p->usb_config[ep].dir != cy_as_usb_in_out) - return CY_AS_ERROR_USB_BAD_DIRECTION; - - /* - * since async operations can be triggered by interrupt - * code, we must insure that we do not get multiple - * async operations going at one time and - * protect this test and set operation from interrupts. - */ - mask = cy_as_hal_disable_interrupts(); - if (cy_as_device_is_usb_async_pending(dev_p, ep)) { - cy_as_hal_enable_interrupts(mask); - return CY_AS_ERROR_ASYNC_PENDING; - } - - cy_as_device_set_usb_async_pending(dev_p, ep); - - if (ep == 0) - cy_as_device_set_ack_delayed(dev_p); - - cy_as_hal_enable_interrupts(mask); - - cy_as_hal_assert(dev_p->usb_cb[ep] == 0); - dev_p->usb_cb[ep] = cb; - dev_p->usb_spacket[ep] = spacket; - - /* Write on Turbo endpoint */ - if (ep == CY_AS_MTP_WRITE_ENDPOINT) { - cy_as_ll_request_response *req_p, *reply_p; - - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_TURBO_SEND_RESP_DATA_TO_HOST, - CY_RQT_TUR_RQT_CONTEXT, 3); - - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - cy_as_ll_request_response__set_word(req_p, 0, - 0x0006); /* EP number to use. */ - cy_as_ll_request_response__set_word(req_p, 1, - (uint16_t)((dsize >> 16) & 0xFFFF)); - cy_as_ll_request_response__set_word(req_p, 2, - (uint16_t)(dsize & 0xFFFF)); - - /* Reserve space for the reply, the reply data - * will not exceed one word */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (dsize) { - ret = cy_as_dma_queue_request(dev_p, ep, data, - dsize, cy_false, cy_false, - async_write_request_callback); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - } - - ret = cy_as_ll_send_request(dev_p, req_p, reply_p, - cy_false, mtp_write_callback); - if (ret != CY_AS_ERROR_SUCCESS) { - if (dsize) - cy_as_dma_cancel(dev_p, ep, ret); - return ret; - } - - /* Firmware will handle a zero byte transfer - * without any DMA transfers. */ - if (!dsize) - return CY_AS_ERROR_SUCCESS; - } else { - ret = cy_as_dma_queue_request(dev_p, ep, data, dsize, - cy_false, cy_false, async_write_request_callback); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - } - - /* Kick start the queue if it is not running */ - if (ep != CY_AS_MTP_WRITE_ENDPOINT) - cy_as_dma_kick_start(dev_p, ep); - - return CY_AS_ERROR_SUCCESS; -} -EXPORT_SYMBOL(cy_as_usb_write_data_async); - -static void -my_usb_cancel_async_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t ret) -{ - uint8_t ep; - (void)context; - - ep = (uint8_t)cy_as_ll_request_response__get_word(rqt, 0); - if (ret == CY_AS_ERROR_SUCCESS) { - if (cy_as_ll_request_response__get_code(resp) != - CY_RESP_SUCCESS_FAILURE) - ret = CY_AS_ERROR_INVALID_RESPONSE; - else - ret = cy_as_ll_request_response__get_word(resp, 0); - } - - cy_as_ll_destroy_request(dev_p, rqt); - cy_as_ll_destroy_response(dev_p, resp); - - if (ret == CY_AS_ERROR_SUCCESS) { - cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED); - dev_p->usb_cb[ep] = 0; - cy_as_device_clear_usb_async_pending(dev_p, ep); - } -} - -cy_as_return_status_t -cy_as_usb_cancel_async(cy_as_device_handle handle, - cy_as_end_point_number_t ep) -{ - cy_as_return_status_t ret; - cy_as_ll_request_response *req_p, *reply_p; - - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ep &= 0x7F; /* Remove the direction bit. */ - if (!cy_as_device_is_usb_async_pending(dev_p, ep)) - return CY_AS_ERROR_ASYNC_NOT_PENDING; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_suspend_mode(dev_p)) - return CY_AS_ERROR_IN_SUSPEND; - - if ((ep == CY_AS_MTP_WRITE_ENDPOINT) || - (ep == CY_AS_MTP_READ_ENDPOINT)) { - /* Need firmware support for the cancel operation. */ - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_CANCEL_ASYNC_TRANSFER, - CY_RQT_TUR_RQT_CONTEXT, 1); - - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - cy_as_ll_request_response__set_word(req_p, 0, - (uint16_t)ep); - - ret = cy_as_ll_send_request(dev_p, req_p, reply_p, - cy_false, my_usb_cancel_async_callback); - - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - return ret; - } - } else { - ret = cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - dev_p->usb_cb[ep] = 0; - cy_as_device_clear_usb_async_pending(dev_p, ep); - } - - return CY_AS_ERROR_SUCCESS; -} -EXPORT_SYMBOL(cy_as_usb_cancel_async); - -static void -cy_as_usb_ack_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t ret) -{ - cy_as_func_c_b_node *node = (cy_as_func_c_b_node *) - dev_p->func_cbs_usb->head_p; - - (void)context; - - if (ret == CY_AS_ERROR_SUCCESS) { - if (cy_as_ll_request_response__get_code(resp) != - CY_RESP_SUCCESS_FAILURE) - ret = CY_AS_ERROR_INVALID_RESPONSE; - else - ret = cy_as_ll_request_response__get_word(resp, 0); - } - - node->cb_p((cy_as_device_handle)dev_p, ret, - node->client_data, node->data_type, node->data); - cy_as_remove_c_b_node(dev_p->func_cbs_usb); - - cy_as_ll_destroy_request(dev_p, rqt); - cy_as_ll_destroy_response(dev_p, resp); - cy_as_device_clear_ack_delayed(dev_p); -} - -static cy_as_return_status_t -cy_as_usb_ack_setup_packet(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret; - cy_as_ll_request_response *req_p; - cy_as_ll_request_response *reply_p; - cy_as_func_c_b_node *cbnode; - - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_callback(dev_p) && cb == 0) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - cy_as_hal_assert(cb != 0); - - cbnode = cy_as_create_func_c_b_node(cb, client); - if (cbnode == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - req_p = cy_as_ll_create_request(dev_p, 0, - CY_RQT_USB_RQT_CONTEXT, 2); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - cy_as_ll_init_request(req_p, CY_RQT_ACK_SETUP_PACKET, - CY_RQT_USB_RQT_CONTEXT, 1); - cy_as_ll_init_response(reply_p, 1); - - req_p->flags |= CY_AS_REQUEST_RESPONSE_EX; - - cy_as_insert_c_b_node(dev_p->func_cbs_usb, cbnode); - - ret = cy_as_ll_send_request(dev_p, req_p, reply_p, - cy_false, cy_as_usb_ack_callback); - - return ret; -} - -/* - * Flush all data in logical EP that is being NAK-ed or - * Stall-ed, so that this does not continue to block data - * on other LEPs that use the same physical EP. - */ -static void -cy_as_usb_flush_logical_e_p( - cy_as_device *dev_p, - uint16_t ep) -{ - uint16_t addr, val, count; - - addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2; - val = cy_as_hal_read_register(dev_p->tag, addr); - - while (val) { - count = ((val & 0xFFF) + 1) / 2; - while (count--) - val = cy_as_hal_read_register(dev_p->tag, ep); - - cy_as_hal_write_register(dev_p->tag, addr, 0); - val = cy_as_hal_read_register(dev_p->tag, addr); - } -} - -static cy_as_return_status_t -cy_as_usb_nak_stall_request(cy_as_device_handle handle, - cy_as_end_point_number_t ep, - uint16_t request, - cy_bool state, - cy_as_usb_function_callback cb, - cy_as_function_callback fcb, - uint32_t client) -{ - cy_as_return_status_t ret; - cy_as_ll_request_response *req_p , *reply_p; - uint16_t data; - - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - if (cb) - cy_as_hal_assert(fcb == 0); - if (fcb) - cy_as_hal_assert(cb == 0); - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_callback(dev_p) && cb == 0 && fcb == 0) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - req_p = cy_as_ll_create_request(dev_p, - request, CY_RQT_USB_RQT_CONTEXT, 2); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* A single status word response type */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - /* Set the endpoint */ - data = (uint8_t)ep; - cy_as_ll_request_response__set_word(req_p, 0, data); - - /* Set stall state to stalled */ - cy_as_ll_request_response__set_word(req_p, 1, (uint8_t)state); - - if (cb || fcb) { - void *cbnode; - cy_as_c_b_queue *queue; - if (cb) { - cbnode = cy_as_create_usb_func_c_b_node(cb, client); - queue = dev_p->usb_func_cbs; - } else { - cbnode = cy_as_create_func_c_b_node(fcb, client); - queue = dev_p->func_cbs_usb; - req_p->flags |= CY_AS_REQUEST_RESPONSE_EX; - } - - if (cbnode == 0) { - ret = CY_AS_ERROR_OUT_OF_MEMORY; - goto destroy; - } else - cy_as_insert_c_b_node(queue, cbnode); - - - if (cy_as_device_is_setup_packet(dev_p)) { - /* No Ack is needed on a stall request on EP0 */ - if ((state == cy_true) && (ep == 0)) { - cy_as_device_set_ep0_stalled(dev_p); - } else { - cy_as_device_set_ack_delayed(dev_p); - req_p->flags |= - CY_AS_REQUEST_RESPONSE_DELAY_ACK; - } - } - - ret = cy_as_ll_send_request(dev_p, req_p, - reply_p, cy_false, cy_as_usb_func_callback); - if (ret != CY_AS_ERROR_SUCCESS) { - if (req_p->flags & CY_AS_REQUEST_RESPONSE_DELAY_ACK) - cy_as_device_rem_ack_delayed(dev_p); - cy_as_remove_c_b_tail_node(queue); - - goto destroy; - } - } else { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) != - CY_RESP_SUCCESS_FAILURE) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - ret = cy_as_ll_request_response__get_word(reply_p, 0); - - if ((ret == CY_AS_ERROR_SUCCESS) && - (request == CY_RQT_STALL_ENDPOINT)) { - if ((ep > 1) && (state != 0) && - (dev_p->usb_config[ep].dir == cy_as_usb_out)) - cy_as_usb_flush_logical_e_p(dev_p, ep); - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - } - - return ret; -} - -static cy_as_return_status_t -my_handle_response_get_stall(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_bool *state_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint8_t code = cy_as_ll_request_response__get_code(reply_p); - - if (code == CY_RESP_SUCCESS_FAILURE) { - ret = cy_as_ll_request_response__get_word(reply_p, 0); - goto destroy; - } else if (code != CY_RESP_ENDPOINT_STALL) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - *state_p = (cy_bool)cy_as_ll_request_response__get_word(reply_p, 0); - ret = CY_AS_ERROR_SUCCESS; - - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -static cy_as_return_status_t -my_handle_response_get_nak(cy_as_device *dev_p, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_bool *state_p) -{ - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - uint8_t code = cy_as_ll_request_response__get_code(reply_p); - - if (code == CY_RESP_SUCCESS_FAILURE) { - ret = cy_as_ll_request_response__get_word(reply_p, 0); - goto destroy; - } else if (code != CY_RESP_ENDPOINT_NAK) { - ret = CY_AS_ERROR_INVALID_RESPONSE; - goto destroy; - } - - *state_p = (cy_bool)cy_as_ll_request_response__get_word(reply_p, 0); - ret = CY_AS_ERROR_SUCCESS; - - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -static cy_as_return_status_t -cy_as_usb_get_nak_stall(cy_as_device_handle handle, - cy_as_end_point_number_t ep, - uint16_t request, - uint16_t response, - cy_bool *state_p, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret; - cy_as_ll_request_response *req_p , *reply_p; - uint16_t data; - - cy_as_device *dev_p = (cy_as_device *)handle; - - (void)response; - - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_callback(dev_p) && !cb) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - req_p = cy_as_ll_create_request(dev_p, request, - CY_RQT_USB_RQT_CONTEXT, 1); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* Set the endpoint */ - data = (uint8_t)ep; - cy_as_ll_request_response__set_word(req_p, 0, (uint16_t)ep); - - /* A single status word response type */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, - req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (request == CY_RQT_GET_STALL) - return my_handle_response_get_stall(dev_p, - req_p, reply_p, state_p); - else - return my_handle_response_get_nak(dev_p, - req_p, reply_p, state_p); - - } else { - cy_as_funct_c_b_type type; - - if (request == CY_RQT_GET_STALL) - type = CY_FUNCT_CB_USB_GETSTALL; - else - type = CY_FUNCT_CB_USB_GETNAK; - - ret = cy_as_misc_send_request(dev_p, cb, client, type, - state_p, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} - -cy_as_return_status_t -cy_as_usb_set_nak(cy_as_device_handle handle, - cy_as_end_point_number_t ep, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - /* - * we send the firmware the EP# with the appropriate direction - * bit, regardless of what the user gave us. - */ - ep &= 0x0f; - if (dev_p->usb_config[ep].dir == cy_as_usb_in) - ep |= 0x80; - - if (dev_p->mtp_count > 0) - return CY_AS_ERROR_NOT_VALID_IN_MTP; - - return cy_as_usb_nak_stall_request(handle, ep, - CY_RQT_ENDPOINT_SET_NAK, cy_true, 0, cb, client); -} -EXPORT_SYMBOL(cy_as_usb_set_nak); - -cy_as_return_status_t -cy_as_usb_clear_nak(cy_as_device_handle handle, - cy_as_end_point_number_t ep, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - /* - * we send the firmware the EP# with the appropriate - * direction bit, regardless of what the user gave us. - */ - ep &= 0x0f; - if (dev_p->usb_config[ep].dir == cy_as_usb_in) - ep |= 0x80; - - if (dev_p->mtp_count > 0) - return CY_AS_ERROR_NOT_VALID_IN_MTP; - - return cy_as_usb_nak_stall_request(handle, ep, - CY_RQT_ENDPOINT_SET_NAK, cy_false, 0, cb, client); -} -EXPORT_SYMBOL(cy_as_usb_clear_nak); - -cy_as_return_status_t -cy_as_usb_get_nak(cy_as_device_handle handle, - cy_as_end_point_number_t ep, - cy_bool *nak_p, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - /* - * we send the firmware the EP# with the appropriate - * direction bit, regardless of what the user gave us. - */ - ep &= 0x0f; - if (dev_p->usb_config[ep].dir == cy_as_usb_in) - ep |= 0x80; - - if (dev_p->mtp_count > 0) - return CY_AS_ERROR_NOT_VALID_IN_MTP; - - return cy_as_usb_get_nak_stall(handle, ep, - CY_RQT_GET_ENDPOINT_NAK, CY_RESP_ENDPOINT_NAK, - nak_p, cb, client); -} -EXPORT_SYMBOL(cy_as_usb_get_nak); - -cy_as_return_status_t -cy_as_usb_set_stall(cy_as_device_handle handle, - cy_as_end_point_number_t ep, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - /* - * we send the firmware the EP# with the appropriate - * direction bit, regardless of what the user gave us. - */ - ep &= 0x0f; - if (dev_p->usb_config[ep].dir == cy_as_usb_in) - ep |= 0x80; - - if (dev_p->mtp_turbo_active) - return CY_AS_ERROR_NOT_VALID_DURING_MTP; - - return cy_as_usb_nak_stall_request(handle, ep, - CY_RQT_STALL_ENDPOINT, cy_true, 0, cb, client); -} -EXPORT_SYMBOL(cy_as_usb_set_stall); - -cy_as_return_status_t -cy_as_usb_clear_stall(cy_as_device_handle handle, - cy_as_end_point_number_t ep, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - /* - * we send the firmware the EP# with the appropriate - * direction bit, regardless of what the user gave us. - */ - ep &= 0x0f; - if (dev_p->usb_config[ep].dir == cy_as_usb_in) - ep |= 0x80; - - if (dev_p->mtp_turbo_active) - return CY_AS_ERROR_NOT_VALID_DURING_MTP; - - return cy_as_usb_nak_stall_request(handle, ep, - CY_RQT_STALL_ENDPOINT, cy_false, 0, cb, client); -} -EXPORT_SYMBOL(cy_as_usb_clear_stall); - -cy_as_return_status_t -cy_as_usb_get_stall(cy_as_device_handle handle, - cy_as_end_point_number_t ep, - cy_bool *stall_p, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - /* - * we send the firmware the EP# with the appropriate - * direction bit, regardless of what the user gave us. - */ - ep &= 0x0f; - if (dev_p->usb_config[ep].dir == cy_as_usb_in) - ep |= 0x80; - - if (dev_p->mtp_turbo_active) - return CY_AS_ERROR_NOT_VALID_DURING_MTP; - - return cy_as_usb_get_nak_stall(handle, ep, - CY_RQT_GET_STALL, CY_RESP_ENDPOINT_STALL, stall_p, cb, client); -} -EXPORT_SYMBOL(cy_as_usb_get_stall); - -cy_as_return_status_t -cy_as_usb_signal_remote_wakeup(cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret; - cy_as_ll_request_response *req_p , *reply_p; - - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if (cy_as_device_is_in_callback(dev_p)) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - if (dev_p->usb_last_event != cy_as_event_usb_suspend) - return CY_AS_ERROR_NOT_IN_SUSPEND; - - req_p = cy_as_ll_create_request(dev_p, - CY_RQT_USB_REMOTE_WAKEUP, CY_RQT_USB_RQT_CONTEXT, 0); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* A single status word response type */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) == - CY_RESP_SUCCESS_FAILURE) - ret = cy_as_ll_request_response__get_word(reply_p, 0); - else - ret = CY_AS_ERROR_INVALID_RESPONSE; - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_USB_SIGNALREMOTEWAKEUP, 0, - dev_p->func_cbs_usb, - CY_AS_REQUEST_RESPONSE_EX, req_p, - reply_p, cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_usb_signal_remote_wakeup); - -cy_as_return_status_t -cy_as_usb_set_m_s_report_threshold(cy_as_device_handle handle, - uint32_t wr_sectors, - uint32_t rd_sectors, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret; - cy_as_ll_request_response *req_p , *reply_p; - - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - if ((cb == 0) && (cy_as_device_is_in_callback(dev_p))) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - /* Check if the firmware version supports this feature. */ - if ((dev_p->media_supported[0]) && (dev_p->media_supported[0] == - (1 << cy_as_media_nand))) - return CY_AS_ERROR_NOT_SUPPORTED; - - req_p = cy_as_ll_create_request(dev_p, CY_RQT_USB_STORAGE_MONITOR, - CY_RQT_USB_RQT_CONTEXT, 4); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* A single status word response type */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - /* Set the read and write count parameters into - * the request structure. */ - cy_as_ll_request_response__set_word(req_p, 0, - (uint16_t)((wr_sectors >> 16) & 0xFFFF)); - cy_as_ll_request_response__set_word(req_p, 1, - (uint16_t)(wr_sectors & 0xFFFF)); - cy_as_ll_request_response__set_word(req_p, 2, - (uint16_t)((rd_sectors >> 16) & 0xFFFF)); - cy_as_ll_request_response__set_word(req_p, 3, - (uint16_t)(rd_sectors & 0xFFFF)); - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) == - CY_RESP_SUCCESS_FAILURE) - ret = cy_as_ll_request_response__get_word(reply_p, 0); - else - ret = CY_AS_ERROR_INVALID_RESPONSE; - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_USB_SET_MSREPORT_THRESHOLD, 0, - dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, - req_p, reply_p, cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_usb_set_m_s_report_threshold); - -cy_as_return_status_t -cy_as_usb_select_m_s_partitions( - cy_as_device_handle handle, - cy_as_bus_number_t bus, - uint32_t device, - cy_as_usb_m_s_type_t type, - cy_as_function_callback cb, - uint32_t client) -{ - cy_as_return_status_t ret; - cy_as_ll_request_response *req_p , *reply_p; - uint16_t val; - - cy_as_device *dev_p = (cy_as_device *)handle; - if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE)) - return CY_AS_ERROR_INVALID_HANDLE; - - ret = is_usb_active(dev_p); - if (ret != CY_AS_ERROR_SUCCESS) - return ret; - - /* This API has to be made before SetEnumConfig is called. */ - if (dev_p->usb_config[0].enabled) - return CY_AS_ERROR_INVALID_CALL_SEQUENCE; - - if ((cb == 0) && (cy_as_device_is_in_callback(dev_p))) - return CY_AS_ERROR_INVALID_IN_CALLBACK; - - req_p = cy_as_ll_create_request(dev_p, CY_RQT_MS_PARTITION_SELECT, - CY_RQT_USB_RQT_CONTEXT, 2); - if (req_p == 0) - return CY_AS_ERROR_OUT_OF_MEMORY; - - /* A single status word response type */ - reply_p = cy_as_ll_create_response(dev_p, 1); - if (reply_p == 0) { - cy_as_ll_destroy_request(dev_p, req_p); - return CY_AS_ERROR_OUT_OF_MEMORY; - } - - /* Set the read and write count parameters into - * the request structure. */ - cy_as_ll_request_response__set_word(req_p, 0, - (uint16_t)((bus << 8) | device)); - - val = 0; - if ((type == cy_as_usb_m_s_unit0) || (type == cy_as_usb_m_s_both)) - val |= 1; - if ((type == cy_as_usb_m_s_unit1) || (type == cy_as_usb_m_s_both)) - val |= (1 << 8); - - cy_as_ll_request_response__set_word(req_p, 1, val); - - if (cb == 0) { - ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p); - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - - if (cy_as_ll_request_response__get_code(reply_p) == - CY_RESP_SUCCESS_FAILURE) - ret = cy_as_ll_request_response__get_word(reply_p, 0); - else - ret = CY_AS_ERROR_INVALID_RESPONSE; - } else { - ret = cy_as_misc_send_request(dev_p, cb, client, - CY_FUNCT_CB_NODATA, 0, dev_p->func_cbs_usb, - CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p, - cy_as_usb_func_callback); - - if (ret != CY_AS_ERROR_SUCCESS) - goto destroy; - return ret; - } - -destroy: - cy_as_ll_destroy_request(dev_p, req_p); - cy_as_ll_destroy_response(dev_p, reply_p); - - return ret; -} -EXPORT_SYMBOL(cy_as_usb_select_m_s_partitions); - -static void -cy_as_usb_func_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_ll_request_response *rqt, - cy_as_ll_request_response *resp, - cy_as_return_status_t stat) -{ - cy_as_usb_func_c_b_node* node = (cy_as_usb_func_c_b_node *) - dev_p->usb_func_cbs->head_p; - cy_as_func_c_b_node* fnode = (cy_as_func_c_b_node *) - dev_p->func_cbs_usb->head_p; - cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS; - - cy_as_device_handle h = (cy_as_device_handle)dev_p; - cy_bool delayed_ack = (rqt->flags & CY_AS_REQUEST_RESPONSE_DELAY_ACK) - == CY_AS_REQUEST_RESPONSE_DELAY_ACK; - cy_bool ex_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_EX) - == CY_AS_REQUEST_RESPONSE_EX; - cy_bool ms_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_MS) - == CY_AS_REQUEST_RESPONSE_MS; - uint8_t code; - uint8_t ep, state; - - if (!ex_request && !ms_request) { - cy_as_hal_assert(dev_p->usb_func_cbs->count != 0); - cy_as_hal_assert(dev_p->usb_func_cbs->type == - CYAS_USB_FUNC_CB); - } else { - cy_as_hal_assert(dev_p->func_cbs_usb->count != 0); - cy_as_hal_assert(dev_p->func_cbs_usb->type == CYAS_FUNC_CB); - } - - (void)context; - - /* The Handlers are responsible for Deleting the rqt and resp when - * they are finished - */ - code = cy_as_ll_request_response__get_code(rqt); - switch (code) { - case CY_RQT_START_USB: - ret = my_handle_response_usb_start(dev_p, rqt, resp, stat); - break; - case CY_RQT_STOP_USB: - ret = my_handle_response_usb_stop(dev_p, rqt, resp, stat); - break; - case CY_RQT_SET_CONNECT_STATE: - if (!cy_as_ll_request_response__get_word(rqt, 0)) - ret = my_handle_response_disconnect( - dev_p, rqt, resp, stat); - else - ret = my_handle_response_connect( - dev_p, rqt, resp, stat); - break; - case CY_RQT_GET_CONNECT_STATE: - break; - case CY_RQT_SET_USB_CONFIG: - ret = my_handle_response_set_enum_config(dev_p, rqt, resp); - break; - case CY_RQT_GET_USB_CONFIG: - cy_as_hal_assert(fnode->data != 0); - ret = my_handle_response_get_enum_config(dev_p, - rqt, resp, fnode->data); - break; - case CY_RQT_STALL_ENDPOINT: - ep = (uint8_t)cy_as_ll_request_response__get_word(rqt, 0); - state = (uint8_t)cy_as_ll_request_response__get_word(rqt, 1); - ret = my_handle_response_no_data(dev_p, rqt, resp); - if ((ret == CY_AS_ERROR_SUCCESS) && (ep > 1) && (state != 0) - && (dev_p->usb_config[ep].dir == cy_as_usb_out)) - cy_as_usb_flush_logical_e_p(dev_p, ep); - break; - case CY_RQT_GET_STALL: - cy_as_hal_assert(fnode->data != 0); - ret = my_handle_response_get_stall(dev_p, - rqt, resp, (cy_bool *)fnode->data); - break; - case CY_RQT_SET_DESCRIPTOR: - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_GET_DESCRIPTOR: - cy_as_hal_assert(fnode->data != 0); - ret = my_handle_response_get_descriptor(dev_p, - rqt, resp, (cy_as_get_descriptor_data *)fnode->data); - break; - case CY_RQT_SET_USB_CONFIG_REGISTERS: - ret = my_handle_response_no_data(dev_p, rqt, resp); - if (ret == CY_AS_ERROR_SUCCESS) - ret = cy_as_usb_setup_dma(dev_p); - break; - case CY_RQT_ENDPOINT_SET_NAK: - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_GET_ENDPOINT_NAK: - cy_as_hal_assert(fnode->data != 0); - ret = my_handle_response_get_nak(dev_p, - rqt, resp, (cy_bool *)fnode->data); - break; - case CY_RQT_ACK_SETUP_PACKET: - break; - case CY_RQT_USB_REMOTE_WAKEUP: - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_CLEAR_DESCRIPTORS: - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_USB_STORAGE_MONITOR: - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - case CY_RQT_MS_PARTITION_SELECT: - ret = my_handle_response_no_data(dev_p, rqt, resp); - break; - default: - ret = CY_AS_ERROR_INVALID_RESPONSE; - cy_as_hal_assert(cy_false); - break; - } - - /* - * if the low level layer returns a direct error, use - * the corresponding error code. if not, use the error - * code based on the response from firmware. - */ - if (stat == CY_AS_ERROR_SUCCESS) - stat = ret; - - if (ex_request || ms_request) { - fnode->cb_p((cy_as_device_handle)dev_p, stat, - fnode->client_data, fnode->data_type, fnode->data); - cy_as_remove_c_b_node(dev_p->func_cbs_usb); - } else { - node->cb_p((cy_as_device_handle)dev_p, stat, - node->client_data); - cy_as_remove_c_b_node(dev_p->usb_func_cbs); - } - - if (delayed_ack) { - cy_as_hal_assert(cy_as_device_is_ack_delayed(dev_p)); - cy_as_device_rem_ack_delayed(dev_p); - - /* - * send the ACK if required. - */ - if (!cy_as_device_is_ack_delayed(dev_p)) - cy_as_usb_ack_setup_packet(h, - usb_ack_callback, 0); - } -} - - -/*[]*/ diff --git a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c deleted file mode 100644 index dd4cd412aeb5..000000000000 --- a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c +++ /dev/null @@ -1,2441 +0,0 @@ -/* Cypress WestBridge OMAP3430 Kernel Hal source file (cyashalomap_kernel.c) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor, -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* include seems broken moving for patch submission - * #include - * #include - * #include - * #include - * #include - * #include - * #include - * #include - * #include - */ -#include -#include -#include "../plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h" -#include "../plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasomapdev_kernel.h" -#include "../plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h" -#include "../../../include/linux/westbridge/cyaserr.h" -#include "../../../include/linux/westbridge/cyasregs.h" -#include "../../../include/linux/westbridge/cyasdma.h" -#include "../../../include/linux/westbridge/cyasintr.h" - -#define HAL_REV "1.1.0" - -/* - * uncomment to enable 16bit pnand interface - */ -#define PNAND_16BIT_MODE - -/* - * selects one of 3 versions of pnand_lbd_read() - * PNAND_LBD_READ_NO_PFE - original 8/16 bit code - * reads through the gpmc CONTROLLER REGISTERS - * ENABLE_GPMC_PF_ENGINE - USES GPMC PFE FIFO reads, in 8 bit mode, - * same speed as the above - * PFE_LBD_READ_V2 - slightly diffrenet, performance same as above - */ -#define PNAND_LBD_READ_NO_PFE -/* #define ENABLE_GPMC_PF_ENGINE */ -/* #define PFE_LBD_READ_V2 */ - -/* - * westbrige astoria ISR options to limit number of - * back to back DMA transfers per ISR interrupt - */ -#define MAX_DRQ_LOOPS_IN_ISR 4 - -/* - * debug prints enabling - *#define DBGPRN_ENABLED - *#define DBGPRN_DMA_SETUP_RD - *#define DBGPRN_DMA_SETUP_WR - */ - - -/* - * For performance reasons, we handle storage endpoint transfers up to 4 KB - * within the HAL itself. - */ - #define CYASSTORAGE_WRITE_EP_NUM (4) - #define CYASSTORAGE_READ_EP_NUM (8) - -/* - * size of DMA packet HAL can accept from Storage API - * HAL will fragment it into smaller chunks that the P port can accept - */ -#define CYASSTORAGE_MAX_XFER_SIZE (2*32768) - -/* - * P port MAX DMA packet size according to interface/ep configurartion - */ -#define HAL_DMA_PKT_SZ 512 - -#define is_storage_e_p(ep) (((ep) == 2) || ((ep) == 4) || \ - ((ep) == 6) || ((ep) == 8)) - -/* - * persistent, stores current GPMC interface cfg mode - */ -static uint8_t pnand_16bit; - -/* - * keep processing new WB DRQ in ISR until all handled (performance feature) - */ -#define PROCESS_MULTIPLE_DRQ_IN_ISR (1) - - -/* - * ASTORIA PNAND IF COMMANDS, CASDO - READ, CASDI - WRITE - */ -#define CASDO 0x05 -#define CASDI 0x85 -#define RDPAGE_B1 0x00 -#define RDPAGE_B2 0x30 -#define PGMPAGE_B1 0x80 -#define PGMPAGE_B2 0x10 - -/* - * The type of DMA operation, per endpoint - */ -typedef enum cy_as_hal_dma_type { - cy_as_hal_read, - cy_as_hal_write, - cy_as_hal_none -} cy_as_hal_dma_type; - - -/* - * SG list halpers defined in scaterlist.h -#define sg_is_chain(sg) ((sg)->page_link & 0x01) -#define sg_is_last(sg) ((sg)->page_link & 0x02) -#define sg_chain_ptr(sg) \ - ((struct scatterlist *) ((sg)->page_link & ~0x03)) -*/ -typedef struct cy_as_hal_endpoint_dma { - cy_bool buffer_valid; - uint8_t *data_p; - uint32_t size; - /* - * sg_list_enabled - if true use, r/w DMA transfers use sg list, - * FALSE use pointer to a buffer - * sg_p - pointer to the owner's sg list, of there is such - * (like blockdriver) - * dma_xfer_sz - size of the next dma xfer on P port - * seg_xfer_cnt - counts xfered bytes for in current sg_list - * memory segment - * req_xfer_cnt - total number of bytes transferred so far in - * current request - * req_length - total request length - */ - bool sg_list_enabled; - struct scatterlist *sg_p; - uint16_t dma_xfer_sz; - uint32_t seg_xfer_cnt; - uint16_t req_xfer_cnt; - uint16_t req_length; - cy_as_hal_dma_type type; - cy_bool pending; -} cy_as_hal_endpoint_dma; - -/* - * The list of OMAP devices (should be one) - */ -static cy_as_omap_dev_kernel *m_omap_list_p; - -/* - * The callback to call after DMA operations are complete - */ -static cy_as_hal_dma_complete_callback callback; - -/* - * Pending data size for the endpoints - */ -static cy_as_hal_endpoint_dma end_points[16]; - -/* - * Forward declaration - */ -static void cy_handle_d_r_q_interrupt(cy_as_omap_dev_kernel *dev_p); - -static uint16_t intr_sequence_num; -static uint8_t intr__enable; -spinlock_t int_lock; - -static u32 iomux_vma; -static u32 csa_phy; - -/* - * gpmc I/O registers VMA - */ -static u32 gpmc_base; - -/* - * gpmc data VMA associated with CS4 (ASTORIA CS on GPMC) - */ -static u32 gpmc_data_vma; -static u32 ndata_reg_vma; -static u32 ncmd_reg_vma; -static u32 naddr_reg_vma; - -/* - * fwd declarations - */ -static void p_nand_lbd_read(u16 col_addr, u32 row_addr, u16 count, void *buff); -static void p_nand_lbd_write(u16 col_addr, u32 row_addr, u16 count, void *buff); -static inline u16 __attribute__((always_inline)) - ast_p_nand_casdo_read(u8 reg_addr8); -static inline void __attribute__((always_inline)) - ast_p_nand_casdi_write(u8 reg_addr8, u16 data); - -/* - * prints given number of omap registers - */ -static void cy_as_hal_print_omap_regs(char *name_prefix, - u8 name_base, u32 virt_base, u16 count) -{ - u32 reg_val, reg_addr; - u16 i; - cy_as_hal_print_message(KERN_INFO "\n"); - for (i = 0; i < count; i++) { - - reg_addr = virt_base + (i*4); - /* use virtual addresses here*/ - reg_val = __raw_readl(reg_addr); - cy_as_hal_print_message(KERN_INFO "%s_%d[%8.8x]=%8.8x\n", - name_prefix, name_base+i, - reg_addr, reg_val); - } -} - -/* - * setMUX function for a pad + additional pad flags - */ -static u16 omap_cfg_reg_L(u32 pad_func_index) -{ - static u8 sanity_check = 1; - - u32 reg_vma; - u16 cur_val, wr_val, rdback_val; - - /* - * do sanity check on the omap_mux_pin_cfg[] table - */ - cy_as_hal_print_message(KERN_INFO" OMAP pins user_pad cfg "); - if (sanity_check) { - if ((omap_mux_pin_cfg[END_OF_TABLE].name[0] == 'E') && - (omap_mux_pin_cfg[END_OF_TABLE].name[1] == 'N') && - (omap_mux_pin_cfg[END_OF_TABLE].name[2] == 'D')) { - - cy_as_hal_print_message(KERN_INFO - "table is good.\n"); - } else { - cy_as_hal_print_message(KERN_WARNING - "table is bad, fix it"); - } - /* - * do it only once - */ - sanity_check = 0; - } - - /* - * get virtual address to the PADCNF_REG - */ - reg_vma = (u32)iomux_vma + omap_mux_pin_cfg[pad_func_index].offset; - - /* - * add additional USER PU/PD/EN flags - */ - wr_val = omap_mux_pin_cfg[pad_func_index].mux_val; - cur_val = IORD16(reg_vma); - - /* - * PADCFG regs 16 bit long, packed into 32 bit regs, - * can also be accessed as u16 - */ - IOWR16(reg_vma, wr_val); - rdback_val = IORD16(reg_vma); - - /* - * in case if the caller wants to save the old value - */ - return wr_val; -} - -#define BLKSZ_4K 0x1000 - -/* - * switch GPMC DATA bus mode - */ -void cy_as_hal_gpmc_enable_16bit_bus(bool dbus16_enabled) -{ - uint32_t tmp32; - - /* - * disable gpmc CS4 operation 1st - */ - tmp32 = gpmc_cs_read_reg(AST_GPMC_CS, - GPMC_CS_CONFIG7) & ~GPMC_CONFIG7_CSVALID; - gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG7, tmp32); - - /* - * GPMC NAND data bus can be 8 or 16 bit wide - */ - if (dbus16_enabled) { - DBGPRN("enabling 16 bit bus\n"); - gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG1, - (GPMC_CONFIG1_DEVICETYPE(2) | - GPMC_CONFIG1_WAIT_PIN_SEL(2) | - GPMC_CONFIG1_DEVICESIZE_16) - ); - } else { - DBGPRN(KERN_INFO "enabling 8 bit bus\n"); - gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG1, - (GPMC_CONFIG1_DEVICETYPE(2) | - GPMC_CONFIG1_WAIT_PIN_SEL(2)) - ); - } - - /* - * re-enable astoria CS operation on GPMC - */ - gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG7, - (tmp32 | GPMC_CONFIG7_CSVALID)); - - /* - *remember the state - */ - pnand_16bit = dbus16_enabled; -} - -static int cy_as_hal_gpmc_init(void) -{ - u32 tmp32; - int err; - struct gpmc_timings timings; - - gpmc_base = (u32)ioremap_nocache(OMAP34XX_GPMC_BASE, BLKSZ_4K); - DBGPRN(KERN_INFO "kernel has gpmc_base=%x , val@ the base=%x", - gpmc_base, __raw_readl(gpmc_base) - ); - - /* - * these are globals are full VMAs of the gpmc_base above - */ - ncmd_reg_vma = GPMC_VMA(AST_GPMC_NAND_CMD); - naddr_reg_vma = GPMC_VMA(AST_GPMC_NAND_ADDR); - ndata_reg_vma = GPMC_VMA(AST_GPMC_NAND_DATA); - - /* - * request GPMC CS for ASTORIA request - */ - if (gpmc_cs_request(AST_GPMC_CS, SZ_16M, (void *)&csa_phy) < 0) { - cy_as_hal_print_message(KERN_ERR "error failed to request" - "ncs4 for ASTORIA\n"); - return -1; - } else { - DBGPRN(KERN_INFO "got phy_addr:%x for " - "GPMC CS%d GPMC_CFGREG7[CS4]\n", - csa_phy, AST_GPMC_CS); - } - - /* - * request VM region for 4K addr space for chip select 4 phy address - * technically we don't need it for NAND devices, but do it anyway - * so that data read/write bus cycle can be triggered by reading - * or writing this mem region - */ - if (!request_mem_region(csa_phy, BLKSZ_4K, "AST_OMAP_HAL")) { - err = -EBUSY; - cy_as_hal_print_message(KERN_ERR "error MEM region " - "request for phy_addr:%x failed\n", - csa_phy); - goto out_free_cs; - } - - /* - * REMAP mem region associated with our CS - */ - gpmc_data_vma = (u32)ioremap_nocache(csa_phy, BLKSZ_4K); - if (!gpmc_data_vma) { - err = -ENOMEM; - cy_as_hal_print_message(KERN_ERR "error- ioremap()" - "for phy_addr:%x failed", csa_phy); - - goto out_release_mem_region; - } - cy_as_hal_print_message(KERN_INFO "ioremap(%x) returned vma=%x\n", - csa_phy, gpmc_data_vma); - - gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG1, - (GPMC_CONFIG1_DEVICETYPE(2) | - GPMC_CONFIG1_WAIT_PIN_SEL(2))); - - memset(&timings, 0, sizeof(timings)); - - /* cs timing */ - timings.cs_on = WB_GPMC_CS_t_o_n; - timings.cs_wr_off = WB_GPMC_BUSCYC_t; - timings.cs_rd_off = WB_GPMC_BUSCYC_t; - - /* adv timing */ - timings.adv_on = WB_GPMC_ADV_t_o_n; - timings.adv_rd_off = WB_GPMC_BUSCYC_t; - timings.adv_wr_off = WB_GPMC_BUSCYC_t; - - /* oe timing */ - timings.oe_on = WB_GPMC_OE_t_o_n; - timings.oe_off = WB_GPMC_OE_t_o_f_f; - timings.access = WB_GPMC_RD_t_a_c_c; - timings.rd_cycle = WB_GPMC_BUSCYC_t; - - /* we timing */ - timings.we_on = WB_GPMC_WE_t_o_n; - timings.we_off = WB_GPMC_WE_t_o_f_f; - timings.wr_access = WB_GPMC_WR_t_a_c_c; - timings.wr_cycle = WB_GPMC_BUSCYC_t; - - timings.page_burst_access = WB_GPMC_BUSCYC_t; - timings.wr_data_mux_bus = WB_GPMC_BUSCYC_t; - gpmc_cs_set_timings(AST_GPMC_CS, &timings); - - cy_as_hal_print_omap_regs("GPMC_CONFIG", 1, - GPMC_VMA(GPMC_CFG_REG(1, AST_GPMC_CS)), 7); - - /* - * DISABLE cs4, NOTE GPMC REG7 is already configured - * at this point by gpmc_cs_request - */ - tmp32 = gpmc_cs_read_reg(AST_GPMC_CS, GPMC_CS_CONFIG7) & - ~GPMC_CONFIG7_CSVALID; - gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG7, tmp32); - - /* - * PROGRAM chip select Region, (see OMAP3430 TRM PAGE 1088) - */ - gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG7, - (AS_CS_MASK | AS_CS_BADDR)); - - /* - * by default configure GPMC into 8 bit mode - * (to match astoria default mode) - */ - gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG1, - (GPMC_CONFIG1_DEVICETYPE(2) | - GPMC_CONFIG1_WAIT_PIN_SEL(2))); - - /* - * ENABLE astoria cs operation on GPMC - */ - gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG7, - (tmp32 | GPMC_CONFIG7_CSVALID)); - - /* - * No method currently exists to write this register through GPMC APIs - * need to change WAIT2 polarity - */ - tmp32 = IORD32(GPMC_VMA(GPMC_CONFIG_REG)); - tmp32 = tmp32 | NAND_FORCE_POSTED_WRITE_B | 0x40; - IOWR32(GPMC_VMA(GPMC_CONFIG_REG), tmp32); - - tmp32 = IORD32(GPMC_VMA(GPMC_CONFIG_REG)); - cy_as_hal_print_message("GPMC_CONFIG_REG=0x%x\n", tmp32); - - return 0; - -out_release_mem_region: - release_mem_region(csa_phy, BLKSZ_4K); - -out_free_cs: - gpmc_cs_free(AST_GPMC_CS); - - return err; -} - -/* - * west bridge astoria ISR (Interrupt handler) - */ -static irqreturn_t cy_astoria_int_handler(int irq, - void *dev_id, struct pt_regs *regs) -{ - cy_as_omap_dev_kernel *dev_p; - uint16_t read_val = 0; - uint16_t mask_val = 0; - - /* - * debug stuff, counts number of loops per one intr trigger - */ - uint16_t drq_loop_cnt = 0; - uint8_t irq_pin; - /* - * flags to watch - */ - const uint16_t sentinel = (CY_AS_MEM_P0_INTR_REG_MCUINT | - CY_AS_MEM_P0_INTR_REG_MBINT | - CY_AS_MEM_P0_INTR_REG_PMINT | - CY_AS_MEM_P0_INTR_REG_PLLLOCKINT); - - /* - * sample IRQ pin level (just for statistics) - */ - irq_pin = __gpio_get_value(AST_INT); - - /* - * this one just for debugging - */ - intr_sequence_num++; - - /* - * astoria device handle - */ - dev_p = dev_id; - - /* - * read Astoria intr register - */ - read_val = cy_as_hal_read_register((cy_as_hal_device_tag)dev_p, - CY_AS_MEM_P0_INTR_REG); - - /* - * save current mask value - */ - mask_val = cy_as_hal_read_register((cy_as_hal_device_tag)dev_p, - CY_AS_MEM_P0_INT_MASK_REG); - - DBGPRN("<1>HAL__intr__enter:_seq:%d, P0_INTR_REG:%x\n", - intr_sequence_num, read_val); - - /* - * Disable WB interrupt signal generation while we are in ISR - */ - cy_as_hal_write_register((cy_as_hal_device_tag)dev_p, - CY_AS_MEM_P0_INT_MASK_REG, 0x0000); - - /* - * this is a DRQ Interrupt - */ - if (read_val & CY_AS_MEM_P0_INTR_REG_DRQINT) { - - do { - /* - * handle DRQ interrupt - */ - drq_loop_cnt++; - - cy_handle_d_r_q_interrupt(dev_p); - - /* - * spending to much time in ISR may impact - * average system performance - */ - if (drq_loop_cnt >= MAX_DRQ_LOOPS_IN_ISR) - break; - - /* - * Keep processing if there is another DRQ int flag - */ - } while (cy_as_hal_read_register((cy_as_hal_device_tag)dev_p, - CY_AS_MEM_P0_INTR_REG) & - CY_AS_MEM_P0_INTR_REG_DRQINT); - } - - if (read_val & sentinel) - cy_as_intr_service_interrupt((cy_as_hal_device_tag)dev_p); - - DBGPRN("<1>_hal:_intr__exit seq:%d, mask=%4.4x," - "int_pin:%d DRQ_jobs:%d\n", - intr_sequence_num, - mask_val, - irq_pin, - drq_loop_cnt); - - /* - * re-enable WB hw interrupts - */ - cy_as_hal_write_register((cy_as_hal_device_tag)dev_p, - CY_AS_MEM_P0_INT_MASK_REG, mask_val); - - return IRQ_HANDLED; -} - -static int cy_as_hal_configure_interrupts(void *dev_p) -{ - int result; - int irq_pin = AST_INT; - - irq_set_irq_type(OMAP_GPIO_IRQ(irq_pin), IRQ_TYPE_LEVEL_LOW); - - /* - * for shared IRQS must provide non NULL device ptr - * othervise the int won't register - * */ - result = request_irq(OMAP_GPIO_IRQ(irq_pin), - (irq_handler_t)cy_astoria_int_handler, - IRQF_SHARED, "AST_INT#", dev_p); - - if (result == 0) { - /* - * OMAP_GPIO_IRQ(irq_pin) - omap logical IRQ number - * assigned to this interrupt - * OMAP_GPIO_BIT(AST_INT, GPIO_IRQENABLE1) - print status - * of AST_INT GPIO IRQ_ENABLE FLAG - */ - cy_as_hal_print_message(KERN_INFO"AST_INT omap_pin:" - "%d assigned IRQ #%d IRQEN1=%d\n", - irq_pin, - OMAP_GPIO_IRQ(irq_pin), - OMAP_GPIO_BIT(AST_INT, GPIO_IRQENABLE1) - ); - } else { - cy_as_hal_print_message("cyasomaphal: interrupt " - "failed to register\n"); - gpio_free(irq_pin); - cy_as_hal_print_message(KERN_WARNING - "ASTORIA: can't get assigned IRQ" - "%i for INT#\n", OMAP_GPIO_IRQ(irq_pin)); - } - - return result; -} - -/* - * initialize OMAP pads/pins to user defined functions - */ -static void cy_as_hal_init_user_pads(user_pad_cfg_t *pad_cfg_tab) -{ - /* - * browse through the table an dinitiaze the pins - */ - u32 in_level = 0; - u16 tmp16, mux_val; - - while (pad_cfg_tab->name != NULL) { - - if (gpio_request(pad_cfg_tab->pin_num, NULL) == 0) { - - pad_cfg_tab->valid = 1; - mux_val = omap_cfg_reg_L(pad_cfg_tab->mux_func); - - /* - * always set drv level before changing out direction - */ - __gpio_set_value(pad_cfg_tab->pin_num, - pad_cfg_tab->drv); - - /* - * "0" - OUT, "1", input omap_set_gpio_direction - * (pad_cfg_tab->pin_num, pad_cfg_tab->dir); - */ - if (pad_cfg_tab->dir) - gpio_direction_input(pad_cfg_tab->pin_num); - else - gpio_direction_output(pad_cfg_tab->pin_num, - pad_cfg_tab->drv); - - /* sample the pin */ - in_level = __gpio_get_value(pad_cfg_tab->pin_num); - - cy_as_hal_print_message(KERN_INFO "configured %s to " - "OMAP pad_%d, DIR=%d " - "DOUT=%d, DIN=%d\n", - pad_cfg_tab->name, - pad_cfg_tab->pin_num, - pad_cfg_tab->dir, - pad_cfg_tab->drv, - in_level - ); - } else { - /* - * get the pad_mux value to check on the pin_function - */ - cy_as_hal_print_message(KERN_INFO "couldn't cfg pin %d" - "for signal %s, its already taken\n", - pad_cfg_tab->pin_num, - pad_cfg_tab->name); - } - - tmp16 = *(u16 *)PADCFG_VMA - (omap_mux_pin_cfg[pad_cfg_tab->mux_func].offset); - - cy_as_hal_print_message(KERN_INFO "GPIO_%d(PAD_CFG=%x,OE=%d" - "DOUT=%d, DIN=%d IRQEN=%d)\n\n", - pad_cfg_tab->pin_num, tmp16, - OMAP_GPIO_BIT(pad_cfg_tab->pin_num, GPIO_OE), - OMAP_GPIO_BIT(pad_cfg_tab->pin_num, GPIO_DATA_OUT), - OMAP_GPIO_BIT(pad_cfg_tab->pin_num, GPIO_DATA_IN), - OMAP_GPIO_BIT(pad_cfg_tab->pin_num, GPIO_IRQENABLE1) - ); - - /* - * next pad_cfg deriptor - */ - pad_cfg_tab++; - } - - cy_as_hal_print_message(KERN_INFO"pads configured\n"); -} - - -/* - * release gpios taken by the module - */ -static void cy_as_hal_release_user_pads(user_pad_cfg_t *pad_cfg_tab) -{ - while (pad_cfg_tab->name != NULL) { - - if (pad_cfg_tab->valid) { - gpio_free(pad_cfg_tab->pin_num); - pad_cfg_tab->valid = 0; - cy_as_hal_print_message(KERN_INFO "GPIO_%d " - "released from %s\n", - pad_cfg_tab->pin_num, - pad_cfg_tab->name); - } else { - cy_as_hal_print_message(KERN_INFO "no release " - "for %s, GPIO_%d, wasn't acquired\n", - pad_cfg_tab->name, - pad_cfg_tab->pin_num); - } - pad_cfg_tab++; - } -} - -void cy_as_hal_config_c_s_mux(void) -{ - /* - * FORCE the GPMC CS4 pin (it is in use by the zoom system) - */ - omap_cfg_reg_L(T8_OMAP3430_GPMC_n_c_s4); -} -EXPORT_SYMBOL(cy_as_hal_config_c_s_mux); - -/* - * inits all omap h/w - */ -uint32_t cy_as_hal_processor_hw_init(void) -{ - int i, err; - - cy_as_hal_print_message(KERN_INFO "init OMAP3430 hw...\n"); - - iomux_vma = (u32)ioremap_nocache( - (u32)CTLPADCONF_BASE_ADDR, CTLPADCONF_SIZE); - cy_as_hal_print_message(KERN_INFO "PADCONF_VMA=%x val=%x\n", - iomux_vma, IORD32(iomux_vma)); - - /* - * remap gpio banks - */ - for (i = 0; i < 6; i++) { - gpio_vma_tab[i].virt_addr = (u32)ioremap_nocache( - gpio_vma_tab[i].phy_addr, - gpio_vma_tab[i].size); - - cy_as_hal_print_message(KERN_INFO "%s virt_addr=%x\n", - gpio_vma_tab[i].name, - (u32)gpio_vma_tab[i].virt_addr); - } - - /* - * force OMAP_GPIO_126 to rleased state, - * will be configured to drive reset - */ - gpio_free(AST_RESET); - - /* - *same thing with AStoria CS pin - */ - gpio_free(AST_CS); - - /* - * initialize all the OMAP pads connected to astoria - */ - cy_as_hal_init_user_pads(user_pad_cfg); - - err = cy_as_hal_gpmc_init(); - if (err < 0) - cy_as_hal_print_message(KERN_INFO"gpmc init failed:%d", err); - - cy_as_hal_config_c_s_mux(); - - return gpmc_data_vma; -} -EXPORT_SYMBOL(cy_as_hal_processor_hw_init); - -void cy_as_hal_omap_hardware_deinit(cy_as_omap_dev_kernel *dev_p) -{ - /* - * free omap hw resources - */ - if (gpmc_data_vma != 0) - iounmap((void *)gpmc_data_vma); - - if (csa_phy != 0) - release_mem_region(csa_phy, BLKSZ_4K); - - gpmc_cs_free(AST_GPMC_CS); - - free_irq(OMAP_GPIO_IRQ(AST_INT), dev_p); - - cy_as_hal_release_user_pads(user_pad_cfg); -} - -/* - * These are the functions that are not part of the - * HAL layer, but are required to be called for this HAL - */ - -/* - * Called On AstDevice LKM exit - */ -int stop_o_m_a_p_kernel(const char *pgm, cy_as_hal_device_tag tag) -{ - cy_as_omap_dev_kernel *dev_p = (cy_as_omap_dev_kernel *)tag; - - /* - * TODO: Need to disable WB interrupt handlere 1st - */ - if (0 == dev_p) - return 1; - - cy_as_hal_print_message("<1>_stopping OMAP34xx HAL layer object\n"); - if (dev_p->m_sig != CY_AS_OMAP_KERNEL_HAL_SIG) { - cy_as_hal_print_message("<1>%s: %s: bad HAL tag\n", - pgm, __func__); - return 1; - } - - /* - * disable interrupt - */ - cy_as_hal_write_register((cy_as_hal_device_tag)dev_p, - CY_AS_MEM_P0_INT_MASK_REG, 0x0000); - -#if 0 - if (dev_p->thread_flag == 0) { - dev_p->thread_flag = 1; - wait_for_completion(&dev_p->thread_complete); - cy_as_hal_print_message("cyasomaphal:" - "done cleaning thread\n"); - cy_as_hal_destroy_sleep_channel(&dev_p->thread_sc); - } -#endif - - cy_as_hal_omap_hardware_deinit(dev_p); - - /* - * Rearrange the list - */ - if (m_omap_list_p == dev_p) - m_omap_list_p = dev_p->m_next_p; - - cy_as_hal_free(dev_p); - - cy_as_hal_print_message(KERN_INFO"OMAP_kernel_hal stopped\n"); - return 0; -} - -int omap_start_intr(cy_as_hal_device_tag tag) -{ - cy_as_omap_dev_kernel *dev_p = (cy_as_omap_dev_kernel *)tag; - int ret = 0; - const uint16_t mask = CY_AS_MEM_P0_INTR_REG_DRQINT | - CY_AS_MEM_P0_INTR_REG_MBINT; - - /* - * register for interrupts - */ - ret = cy_as_hal_configure_interrupts(dev_p); - - /* - * enable only MBox & DRQ interrupts for now - */ - cy_as_hal_write_register((cy_as_hal_device_tag)dev_p, - CY_AS_MEM_P0_INT_MASK_REG, mask); - - return 1; -} - -/* - * Below are the functions that communicate with the WestBridge device. - * These are system dependent and must be defined by the HAL layer - * for a given system. - */ - -/* - * GPMC NAND command+addr write phase - */ -static inline void nand_cmd_n_addr(u8 cmdb1, u16 col_addr, u32 row_addr) -{ - /* - * byte order on the bus - */ - u32 tmpa32 = ((row_addr << 16) | col_addr); - u8 RA2 = (u8)(row_addr >> 16); - - if (!pnand_16bit) { - /* - * GPMC PNAND 8bit BUS - */ - /* - * CMD1 - */ - IOWR8(ncmd_reg_vma, cmdb1); - - /* - *pnand bus: - */ - IOWR32(naddr_reg_vma, tmpa32); - - /* - * , always zero - */ - IOWR8(naddr_reg_vma, RA2); - - } else { - /* - * GPMC PNAND 16bit BUS , in 16 bit mode CMD - * and ADDR sent on [d7..d0] - */ - uint8_t CA0, CA1, RA0, RA1; - CA0 = tmpa32 & 0x000000ff; - CA1 = (tmpa32 >> 8) & 0x000000ff; - RA0 = (tmpa32 >> 16) & 0x000000ff; - RA1 = (tmpa32 >> 24) & 0x000000ff; - - /* - * can't use 32 bit writes here omap will not serialize - * them to lower half in16 bit mode - */ - - /* - *pnand bus: - */ - IOWR8(ncmd_reg_vma, cmdb1); - IOWR8(naddr_reg_vma, CA0); - IOWR8(naddr_reg_vma, CA1); - IOWR8(naddr_reg_vma, RA0); - IOWR8(naddr_reg_vma, RA1); - IOWR8(naddr_reg_vma, RA2); - } -} - -/* - * spin until r/b goes high - */ -inline int wait_rn_b_high(void) -{ - u32 w_spins = 0; - - /* - * TODO: note R/b may go low here, need to spin until high - * while (omap_get_gpio_datain(AST_RnB) == 0) { - * w_spins++; - * } - * if (OMAP_GPIO_BIT(AST_RnB, GPIO_DATA_IN) == 0) { - * - * while (OMAP_GPIO_BIT(AST_RnB, GPIO_DATA_IN) == 0) { - * w_spins++; - * } - * printk("<1>RnB=0!:%d\n",w_spins); - * } - */ - return w_spins; -} - -#ifdef ENABLE_GPMC_PF_ENGINE -/* #define PFE_READ_DEBUG - * PNAND block read with OMAP PFE enabled - * status: Not tested, NW, broken , etc - */ -static void p_nand_lbd_read(u16 col_addr, u32 row_addr, u16 count, void *buff) -{ - uint16_t w32cnt; - uint32_t *ptr32; - uint8_t *ptr8; - uint8_t bytes_in_fifo; - - /* debug vars*/ -#ifdef PFE_READ_DEBUG - uint32_t loop_limit; - uint16_t bytes_read = 0; -#endif - - /* - * configure the prefetch engine - */ - uint32_t tmp32; - uint32_t pfe_status; - - /* - * DISABLE GPMC CS4 operation 1st, this is - * in case engine is be already disabled - */ - IOWR32(GPMC_VMA(GPMC_PREFETCH_CONTROL), 0x0); - IOWR32(GPMC_VMA(GPMC_PREFETCH_CONFIG1), GPMC_PREFETCH_CONFIG1_VAL); - IOWR32(GPMC_VMA(GPMC_PREFETCH_CONFIG2), count); - -#ifdef PFE_READ_DEBUG - tmp32 = IORD32(GPMC_VMA(GPMC_PREFETCH_CONFIG1)); - if (tmp32 != GPMC_PREFETCH_CONFIG1_VAL) { - printk(KERN_INFO "<1> prefetch is CONFIG1 read val:%8.8x, != VAL written:%8.8x\n", - tmp32, GPMC_PREFETCH_CONFIG1_VAL); - tmp32 = IORD32(GPMC_VMA(GPMC_PREFETCH_STATUS)); - printk(KERN_INFO "<1> GPMC_PREFETCH_STATUS : %8.8x\n", tmp32); - } - - /* - *sanity check 2 - */ - tmp32 = IORD32(GPMC_VMA(GPMC_PREFETCH_CONFIG2)); - if (tmp32 != (count)) - printk(KERN_INFO "<1> GPMC_PREFETCH_CONFIG2 read val:%d, " - "!= VAL written:%d\n", tmp32, count); -#endif - - /* - * ISSUE PNAND CMD+ADDR, note gpmc puts 32b words - * on the bus least sig. byte 1st - */ - nand_cmd_n_addr(RDPAGE_B1, col_addr, row_addr); - - IOWR8(ncmd_reg_vma, RDPAGE_B2); - - /* - * start the prefetch engine - */ - IOWR32(GPMC_VMA(GPMC_PREFETCH_CONTROL), 0x1); - - ptr32 = buff; - - while (1) { - /* - * GPMC PFE service loop - */ - do { - /* - * spin until PFE fetched some - * PNAND bus words in the FIFO - */ - pfe_status = IORD32(GPMC_VMA(GPMC_PREFETCH_STATUS)); - bytes_in_fifo = (pfe_status >> 24) & 0x7f; - } while (bytes_in_fifo == 0); - - /* whole 32 bit words in fifo */ - w32cnt = bytes_in_fifo >> 2; - -#if 0 - /* - *NOTE: FIFO_PTR indicates number of NAND bus words bytes - * already received in the FIFO and available to be read - * by DMA or MPU whether COUNTVAL indicates number of BUS - * words yet to be read from PNAND bus words - */ - printk(KERN_ERR "<1> got PF_STATUS:%8.8x FIFO_PTR:%d, COUNTVAL:%d, w32cnt:%d\n", - pfe_status, bytes_in_fifo, - (pfe_status & 0x3fff), w32cnt); -#endif - - while (w32cnt--) - *ptr32++ = IORD32(gpmc_data_vma); - - if ((pfe_status & 0x3fff) == 0) { - /* - * PFE acc angine done, there still may be data leftover - * in the FIFO re-read FIFO BYTE counter (check for - * leftovers from 32 bit read accesses above) - */ - bytes_in_fifo = (IORD32( - GPMC_VMA(GPMC_PREFETCH_STATUS)) >> 24) & 0x7f; - - /* - * NOTE we may still have one word left in the fifo - * read it out - */ - ptr8 = ptr32; - switch (bytes_in_fifo) { - - case 0: - /* - * nothing to do we already read the - * FIFO out with 32 bit accesses - */ - break; - case 1: - /* - * this only possible - * for 8 bit pNAND only - */ - *ptr8 = IORD8(gpmc_data_vma); - break; - - case 2: - /* - * this one can occur in either modes - */ - *(uint16_t *)ptr8 = IORD16(gpmc_data_vma); - break; - - case 3: - /* - * this only possible for 8 bit pNAND only - */ - *(uint16_t *)ptr8 = IORD16(gpmc_data_vma); - ptr8 += 2; - *ptr8 = IORD8(gpmc_data_vma); - break; - - case 4: - /* - * shouldn't happen, but has been seen - * in 8 bit mode - */ - *ptr32 = IORD32(gpmc_data_vma); - break; - - default: - printk(KERN_ERR"<1>_error: PFE FIFO bytes leftover is not read:%d\n", - bytes_in_fifo); - break; - } - /* - * read is completed, get out of the while(1) loop - */ - break; - } - } -} -#endif - -#ifdef PFE_LBD_READ_V2 -/* - * PFE engine assisted reads with the 64 byte blocks - */ -static void p_nand_lbd_read(u16 col_addr, u32 row_addr, u16 count, void *buff) -{ - uint8_t rd_cnt; - uint32_t *ptr32; - uint8_t *ptr8; - uint16_t reminder; - uint32_t pfe_status; - - /* - * ISSUE PNAND CMD+ADDR - * note gpmc puts 32b words on the bus least sig. byte 1st - */ - nand_cmd_n_addr(RDPAGE_B1, col_addr, row_addr); - IOWR8(ncmd_reg_vma, RDPAGE_B2); - - /* - * setup PFE block - * count - OMAP number of bytes to access on pnand bus - */ - - IOWR32(GPMC_VMA(GPMC_PREFETCH_CONFIG1), GPMC_PREFETCH_CONFIG1_VAL); - IOWR32(GPMC_VMA(GPMC_PREFETCH_CONFIG2), count); - IOWR32(GPMC_VMA(GPMC_PREFETCH_CONTROL), 0x1); - - ptr32 = buff; - - do { - pfe_status = IORD32(GPMC_VMA(GPMC_PREFETCH_STATUS)); - rd_cnt = pfe_status >> (24+2); - - while (rd_cnt--) - *ptr32++ = IORD32(gpmc_data_vma); - - } while (pfe_status & 0x3fff); - - /* - * read out the leftover - */ - ptr8 = ptr32; - rd_cnt = (IORD32(GPMC_VMA(GPMC_PREFETCH_STATUS)) >> 24) & 0x7f; - - while (rd_cnt--) - *ptr8++ = IORD8(gpmc_data_vma); -} -#endif - -#ifdef PNAND_LBD_READ_NO_PFE -/* - * Endpoint buffer read w/o OMAP GPMC Prefetch Engine - * the original working code, works at max speed for 8 bit xfers - * for 16 bit the bus diagram has gaps - */ -static void p_nand_lbd_read(u16 col_addr, u32 row_addr, u16 count, void *buff) -{ - uint16_t w32cnt; - uint32_t *ptr32; - uint16_t *ptr16; - uint16_t remainder; - - DBGPRN("<1> %s(): NO_PFE\n", __func__); - - ptr32 = buff; - /* number of whole 32 bit words in the transfer */ - w32cnt = count >> 2; - - /* remainder, in bytes(0..3) */ - remainder = count & 03; - - /* - * note gpmc puts 32b words on the bus least sig. byte 1st - */ - nand_cmd_n_addr(RDPAGE_B1, col_addr, row_addr); - IOWR8(ncmd_reg_vma, RDPAGE_B2); - - /* - * read data by 32 bit chunks - */ - while (w32cnt--) - *ptr32++ = IORD32(ndata_reg_vma); - - /* - * now do the remainder(it can be 0, 1, 2 or 3) - * same code for both 8 & 16 bit bus - * do 1 or 2 MORE words - */ - ptr16 = (uint16_t *)ptr32; - - switch (remainder) { - case 1: - /* read one 16 bit word - * IN 8 BIT WE NEED TO READ even number of bytes - */ - case 2: - *ptr16 = IORD16(ndata_reg_vma); - break; - case 3: - /* - * for 3 bytes read 2 16 bit words - */ - *ptr16++ = IORD16(ndata_reg_vma); - *ptr16 = IORD16(ndata_reg_vma); - break; - default: - /* - * remainder is 0 - */ - break; - } -} -#endif - -/* - * uses LBD mode to write N bytes into astoria - * Status: Working, however there are 150ns idle - * timeafter every 2 (16 bit or 4(8 bit) bus cycles - */ -static void p_nand_lbd_write(u16 col_addr, u32 row_addr, u16 count, void *buff) -{ - uint16_t w32cnt; - uint16_t remainder; - uint8_t *ptr8; - uint16_t *ptr16; - uint32_t *ptr32; - - remainder = count & 03; - w32cnt = count >> 2; - ptr32 = buff; - ptr8 = buff; - - /* - * send: CMDB1, CA0,CA1,RA0,RA1,RA2 - */ - nand_cmd_n_addr(PGMPAGE_B1, col_addr, row_addr); - - /* - * blast the data out in 32bit chunks - */ - while (w32cnt--) - IOWR32(ndata_reg_vma, *ptr32++); - - /* - * do the reminder if there is one - * same handling for both 8 & 16 bit pnand: mode - */ - ptr16 = (uint16_t *)ptr32; /* do 1 or 2 words */ - - switch (remainder) { - case 1: - /* - * read one 16 bit word - */ - case 2: - IOWR16(ndata_reg_vma, *ptr16); - break; - - case 3: - /* - * for 3 bytes read 2 16 bit words - */ - IOWR16(ndata_reg_vma, *ptr16++); - IOWR16(ndata_reg_vma, *ptr16); - break; - default: - /* - * reminder is 0 - */ - break; - } - /* - * finally issue a PGM cmd - */ - IOWR8(ncmd_reg_vma, PGMPAGE_B2); -} - -/* - * write Astoria register - */ -static inline void ast_p_nand_casdi_write(u8 reg_addr8, u16 data) -{ - unsigned long flags; - u16 addr16; - /* - * throw an error if called from multiple threads - */ - static atomic_t rdreg_usage_cnt = { 0 }; - - /* - * disable interrupts - */ - local_irq_save(flags); - - if (atomic_read(&rdreg_usage_cnt) != 0) { - cy_as_hal_print_message(KERN_ERR "cy_as_omap_hal:" - "* cy_as_hal_write_register usage:%d\n", - atomic_read(&rdreg_usage_cnt)); - } - - atomic_inc(&rdreg_usage_cnt); - - /* - * 2 flavors of GPMC -> PNAND access - */ - if (pnand_16bit) { - /* - * 16 BIT gpmc NAND mode - */ - - /* - * CMD1, CA1, CA2, - */ - IOWR8(ncmd_reg_vma, 0x85); - IOWR8(naddr_reg_vma, reg_addr8); - IOWR8(naddr_reg_vma, 0x0c); - - /* - * this should be sent on the 16 bit bus - */ - IOWR16(ndata_reg_vma, data); - } else { - /* - * 8 bit nand mode GPMC will automatically - * seriallize 16bit or 32 bit writes into - * 8 bit onesto the lower 8 bit in LE order - */ - addr16 = 0x0c00 | reg_addr8; - - /* - * CMD1, CA1, CA2, - */ - IOWR8(ncmd_reg_vma, 0x85); - IOWR16(naddr_reg_vma, addr16); - IOWR16(ndata_reg_vma, data); - } - - /* - * re-enable interrupts - */ - atomic_dec(&rdreg_usage_cnt); - local_irq_restore(flags); -} - - -/* - * read astoria register via pNAND interface - */ -static inline u16 ast_p_nand_casdo_read(u8 reg_addr8) -{ - u16 data; - u16 addr16; - unsigned long flags; - /* - * throw an error if called from multiple threads - */ - static atomic_t wrreg_usage_cnt = { 0 }; - - /* - * disable interrupts - */ - local_irq_save(flags); - - if (atomic_read(&wrreg_usage_cnt) != 0) { - /* - * if it gets here ( from other threads), this function needs - * need spin_lock_irq save() protection - */ - cy_as_hal_print_message(KERN_ERR"cy_as_omap_hal: " - "cy_as_hal_write_register usage:%d\n", - atomic_read(&wrreg_usage_cnt)); - } - atomic_inc(&wrreg_usage_cnt); - - /* - * 2 flavors of GPMC -> PNAND access - */ - if (pnand_16bit) { - /* - * 16 BIT gpmc NAND mode - * CMD1, CA1, CA2, - */ - - IOWR8(ncmd_reg_vma, 0x05); - IOWR8(naddr_reg_vma, reg_addr8); - IOWR8(naddr_reg_vma, 0x0c); - IOWR8(ncmd_reg_vma, 0x00E0); - - udelay(1); - - /* - * much faster through the gPMC Register space - */ - data = IORD16(ndata_reg_vma); - } else { - /* - * 8 BIT gpmc NAND mode - * CMD1, CA1, CA2, CMD2 - */ - addr16 = 0x0c00 | reg_addr8; - IOWR8(ncmd_reg_vma, 0x05); - IOWR16(naddr_reg_vma, addr16); - IOWR8(ncmd_reg_vma, 0xE0); - udelay(1); - data = IORD16(ndata_reg_vma); - } - - /* - * re-enable interrupts - */ - atomic_dec(&wrreg_usage_cnt); - local_irq_restore(flags); - - return data; -} - - -/* - * This function must be defined to write a register within the WestBridge - * device. The addr value is the address of the register to write with - * respect to the base address of the WestBridge device. - */ -void cy_as_hal_write_register( - cy_as_hal_device_tag tag, - uint16_t addr, uint16_t data) -{ - ast_p_nand_casdi_write((u8)addr, data); -} - -/* - * This function must be defined to read a register from the WestBridge - * device. The addr value is the address of the register to read with - * respect to the base address of the WestBridge device. - */ -uint16_t cy_as_hal_read_register(cy_as_hal_device_tag tag, uint16_t addr) -{ - uint16_t data = 0; - - /* - * READ ASTORIA REGISTER USING CASDO - */ - data = ast_p_nand_casdo_read((u8)addr); - - return data; -} - -/* - * preps Ep pointers & data counters for next packet - * (fragment of the request) xfer returns true if - * there is a next transfer, and false if all bytes in - * current request have been xfered - */ -static inline bool prep_for_next_xfer(cy_as_hal_device_tag tag, uint8_t ep) -{ - - if (!end_points[ep].sg_list_enabled) { - /* - * no further transfers for non storage EPs - * (like EP2 during firmware download, done - * in 64 byte chunks) - */ - if (end_points[ep].req_xfer_cnt >= end_points[ep].req_length) { - DBGPRN("<1> %s():RQ sz:%d non-_sg EP:%d completed\n", - __func__, end_points[ep].req_length, ep); - - /* - * no more transfers, we are done with the request - */ - return false; - } - - /* - * calculate size of the next DMA xfer, corner - * case for non-storage EPs where transfer size - * is not egual N * HAL_DMA_PKT_SZ xfers - */ - if ((end_points[ep].req_length - end_points[ep].req_xfer_cnt) - >= HAL_DMA_PKT_SZ) { - end_points[ep].dma_xfer_sz = HAL_DMA_PKT_SZ; - } else { - /* - * that would be the last chunk less - * than P-port max size - */ - end_points[ep].dma_xfer_sz = end_points[ep].req_length - - end_points[ep].req_xfer_cnt; - } - - return true; - } - - /* - * for SG_list assisted dma xfers - * are we done with current SG ? - */ - if (end_points[ep].seg_xfer_cnt == end_points[ep].sg_p->length) { - /* - * was it the Last SG segment on the list ? - */ - if (sg_is_last(end_points[ep].sg_p)) { - DBGPRN("<1> %s: EP:%d completed," - "%d bytes xfered\n", - __func__, - ep, - end_points[ep].req_xfer_cnt - ); - - return false; - } else { - /* - * There are more SG segments in current - * request's sg list setup new segment - */ - - end_points[ep].seg_xfer_cnt = 0; - end_points[ep].sg_p = sg_next(end_points[ep].sg_p); - /* set data pointer for next DMA sg transfer*/ - end_points[ep].data_p = sg_virt(end_points[ep].sg_p); - DBGPRN("<1> %s new SG:_va:%p\n\n", - __func__, end_points[ep].data_p); - } - - } - - /* - * for sg list xfers it will always be 512 or 1024 - */ - end_points[ep].dma_xfer_sz = HAL_DMA_PKT_SZ; - - /* - * next transfer is required - */ - - return true; -} - -/* - * Astoria DMA read request, APP_CPU reads from WB ep buffer - */ -static void cy_service_e_p_dma_read_request( - cy_as_omap_dev_kernel *dev_p, uint8_t ep) -{ - cy_as_hal_device_tag tag = (cy_as_hal_device_tag)dev_p; - uint16_t v, size; - void *dptr; - uint16_t col_addr = 0x0000; - uint32_t row_addr = CYAS_DEV_CALC_EP_ADDR(ep); - uint16_t ep_dma_reg = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2; - - /* - * get the XFER size frtom WB eP DMA REGISTER - */ - v = cy_as_hal_read_register(tag, ep_dma_reg); - - /* - * amount of data in EP buff in bytes - */ - size = v & CY_AS_MEM_P0_E_pn_DMA_REG_COUNT_MASK; - - /* - * memory pointer for this DMA packet xfer (sub_segment) - */ - dptr = end_points[ep].data_p; - - DBGPRN("<1>HAL:_svc_dma_read on EP_%d sz:%d, intr_seq:%d, dptr:%p\n", - ep, - size, - intr_sequence_num, - dptr - ); - - cy_as_hal_assert(size != 0); - - if (size) { - /* - * the actual WB-->OMAP memory "soft" DMA xfer - */ - p_nand_lbd_read(col_addr, row_addr, size, dptr); - } - - /* - * clear DMAVALID bit indicating that the data has been read - */ - cy_as_hal_write_register(tag, ep_dma_reg, 0); - - end_points[ep].seg_xfer_cnt += size; - end_points[ep].req_xfer_cnt += size; - - /* - * pre-advance data pointer (if it's outside sg - * list it will be reset anyway - */ - end_points[ep].data_p += size; - - if (prep_for_next_xfer(tag, ep)) { - /* - * we have more data to read in this request, - * setup next dma packet due tell WB how much - * data we are going to xfer next - */ - v = end_points[ep].dma_xfer_sz/*HAL_DMA_PKT_SZ*/ | - CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL; - cy_as_hal_write_register(tag, ep_dma_reg, v); - } else { - end_points[ep].pending = cy_false; - end_points[ep].type = cy_as_hal_none; - end_points[ep].buffer_valid = cy_false; - - /* - * notify the API that we are done with rq on this EP - */ - if (callback) { - DBGPRN("<1>trigg rd_dma completion cb: xfer_sz:%d\n", - end_points[ep].req_xfer_cnt); - callback(tag, ep, - end_points[ep].req_xfer_cnt, - CY_AS_ERROR_SUCCESS); - } - } -} - -/* - * omap_cpu needs to transfer data to ASTORIA EP buffer - */ -static void cy_service_e_p_dma_write_request( - cy_as_omap_dev_kernel *dev_p, uint8_t ep) -{ - uint16_t addr; - uint16_t v = 0; - uint32_t size; - uint16_t col_addr = 0x0000; - uint32_t row_addr = CYAS_DEV_CALC_EP_ADDR(ep); - void *dptr; - - cy_as_hal_device_tag tag = (cy_as_hal_device_tag)dev_p; - /* - * note: size here its the size of the dma transfer could be - * anything > 0 && < P_PORT packet size - */ - size = end_points[ep].dma_xfer_sz; - dptr = end_points[ep].data_p; - - /* - * perform the soft DMA transfer, soft in this case - */ - if (size) - p_nand_lbd_write(col_addr, row_addr, size, dptr); - - end_points[ep].seg_xfer_cnt += size; - end_points[ep].req_xfer_cnt += size; - /* - * pre-advance data pointer - * (if it's outside sg list it will be reset anyway) - */ - end_points[ep].data_p += size; - - /* - * now clear DMAVAL bit to indicate we are done - * transferring data and that the data can now be - * sent via USB to the USB host, sent to storage, - * or used internally. - */ - - addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2; - cy_as_hal_write_register(tag, addr, size); - - /* - * finally, tell the USB subsystem that the - * data is gone and we can accept the - * next request if one exists. - */ - if (prep_for_next_xfer(tag, ep)) { - /* - * There is more data to go. Re-init the WestBridge DMA side - */ - v = end_points[ep].dma_xfer_sz | - CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL; - cy_as_hal_write_register(tag, addr, v); - } else { - - end_points[ep].pending = cy_false; - end_points[ep].type = cy_as_hal_none; - end_points[ep].buffer_valid = cy_false; - - /* - * notify the API that we are done with rq on this EP - */ - if (callback) { - /* - * this callback will wake up the process that might be - * sleeping on the EP which data is being transferred - */ - callback(tag, ep, - end_points[ep].req_xfer_cnt, - CY_AS_ERROR_SUCCESS); - } - } -} - -/* - * HANDLE DRQINT from Astoria (called in AS_Intr context - */ -static void cy_handle_d_r_q_interrupt(cy_as_omap_dev_kernel *dev_p) -{ - uint16_t v; - static uint8_t service_ep = 2; - - /* - * We've got DRQ INT, read DRQ STATUS Register */ - v = cy_as_hal_read_register((cy_as_hal_device_tag)dev_p, - CY_AS_MEM_P0_DRQ); - - if (v == 0) { -#ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("stray DRQ interrupt detected\n"); -#endif - return; - } - - /* - * Now, pick a given DMA request to handle, for now, we just - * go round robin. Each bit position in the service_mask - * represents an endpoint from EP2 to EP15. We rotate through - * each of the endpoints to find one that needs to be serviced. - */ - while ((v & (1 << service_ep)) == 0) { - - if (service_ep == 15) - service_ep = 2; - else - service_ep++; - } - - if (end_points[service_ep].type == cy_as_hal_write) { - /* - * handle DMA WRITE REQUEST: app_cpu will - * write data into astoria EP buffer - */ - cy_service_e_p_dma_write_request(dev_p, service_ep); - } else if (end_points[service_ep].type == cy_as_hal_read) { - /* - * handle DMA READ REQUEST: cpu will - * read EP buffer from Astoria - */ - cy_service_e_p_dma_read_request(dev_p, service_ep); - } -#ifndef WESTBRIDGE_NDEBUG - else - cy_as_hal_print_message("cyashalomap:interrupt," - " w/o pending DMA job," - "-check DRQ_MASK logic\n"); -#endif - - /* - * Now bump the EP ahead, so other endpoints get - * a shot before the one we just serviced - */ - if (end_points[service_ep].type == cy_as_hal_none) { - if (service_ep == 15) - service_ep = 2; - else - service_ep++; - } - -} - -void cy_as_hal_dma_cancel_request(cy_as_hal_device_tag tag, uint8_t ep) -{ - DBGPRN("cy_as_hal_dma_cancel_request on ep:%d", ep); - if (end_points[ep].pending) - cy_as_hal_write_register(tag, - CY_AS_MEM_P0_EP2_DMA_REG + ep - 2, 0); - - end_points[ep].buffer_valid = cy_false; - end_points[ep].type = cy_as_hal_none; -} - -/* - * enables/disables SG list assisted DMA xfers for the given EP - * sg_list assisted XFERS can use physical addresses of mem pages in case if the - * xfer is performed by a h/w DMA controller rather then the CPU on P port - */ -void cy_as_hal_set_ep_dma_mode(uint8_t ep, bool sg_xfer_enabled) -{ - end_points[ep].sg_list_enabled = sg_xfer_enabled; - DBGPRN("<1> EP:%d sg_list assisted DMA mode set to = %d\n", - ep, end_points[ep].sg_list_enabled); -} -EXPORT_SYMBOL(cy_as_hal_set_ep_dma_mode); - -/* - * This function must be defined to transfer a block of data to - * the WestBridge device. This function can use the burst write - * (DMA) capabilities of WestBridge to do this, or it can just copy - * the data using writes. - */ -void cy_as_hal_dma_setup_write(cy_as_hal_device_tag tag, - uint8_t ep, void *buf, - uint32_t size, uint16_t maxsize) -{ - uint32_t addr = 0; - uint16_t v = 0; - - /* - * Note: "size" is the actual request size - * "maxsize" - is the P port fragment size - * No EP0 or EP1 traffic should get here - */ - cy_as_hal_assert(ep != 0 && ep != 1); - - /* - * If this asserts, we have an ordering problem. Another DMA request - * is coming down before the previous one has completed. - */ - cy_as_hal_assert(end_points[ep].buffer_valid == cy_false); - end_points[ep].buffer_valid = cy_true; - end_points[ep].type = cy_as_hal_write; - end_points[ep].pending = cy_true; - - /* - * total length of the request - */ - end_points[ep].req_length = size; - - if (size >= maxsize) { - /* - * set xfer size for very 1st DMA xfer operation - * port max packet size ( typically 512 or 1024) - */ - end_points[ep].dma_xfer_sz = maxsize; - } else { - /* - * smaller xfers for non-storage EPs - */ - end_points[ep].dma_xfer_sz = size; - } - - /* - * check the EP transfer mode uses sg_list rather then a memory buffer - * block devices pass it to the HAL, so the hAL could get to the real - * physical address for each segment and set up a DMA controller - * hardware ( if there is one) - */ - if (end_points[ep].sg_list_enabled) { - /* - * buf - pointer to the SG list - * data_p - data pointer to the 1st DMA segment - * seg_xfer_cnt - keeps track of N of bytes sent in current - * sg_list segment - * req_xfer_cnt - keeps track of the total N of bytes - * transferred for the request - */ - end_points[ep].sg_p = buf; - end_points[ep].data_p = sg_virt(end_points[ep].sg_p); - end_points[ep].seg_xfer_cnt = 0; - end_points[ep].req_xfer_cnt = 0; - -#ifdef DBGPRN_DMA_SETUP_WR - DBGPRN("cyasomaphal:%s: EP:%d, buf:%p, buf_va:%p," - "req_sz:%d, maxsz:%d\n", - __func__, - ep, - buf, - end_points[ep].data_p, - size, - maxsize); -#endif - - } else { - /* - * setup XFER for non sg_list assisted EPs - */ - - #ifdef DBGPRN_DMA_SETUP_WR - DBGPRN("<1>%s non storage or sz < 512:" - "EP:%d, sz:%d\n", __func__, ep, size); - #endif - - end_points[ep].sg_p = NULL; - - /* - * must be a VMA of a membuf in kernel space - */ - end_points[ep].data_p = buf; - - /* - * will keep track No of bytes xferred for the request - */ - end_points[ep].req_xfer_cnt = 0; - } - - /* - * Tell WB we are ready to send data on the given endpoint - */ - v = (end_points[ep].dma_xfer_sz & CY_AS_MEM_P0_E_pn_DMA_REG_COUNT_MASK) - | CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL; - - addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2; - - cy_as_hal_write_register(tag, addr, v); -} - -/* - * This function must be defined to transfer a block of data from - * the WestBridge device. This function can use the burst read - * (DMA) capabilities of WestBridge to do this, or it can just - * copy the data using reads. - */ -void cy_as_hal_dma_setup_read(cy_as_hal_device_tag tag, - uint8_t ep, void *buf, - uint32_t size, uint16_t maxsize) -{ - uint32_t addr; - uint16_t v; - - /* - * Note: "size" is the actual request size - * "maxsize" - is the P port fragment size - * No EP0 or EP1 traffic should get here - */ - cy_as_hal_assert(ep != 0 && ep != 1); - - /* - * If this asserts, we have an ordering problem. - * Another DMA request is coming down before the - * previous one has completed. we should not get - * new requests if current is still in process - */ - - cy_as_hal_assert(end_points[ep].buffer_valid == cy_false); - - end_points[ep].buffer_valid = cy_true; - end_points[ep].type = cy_as_hal_read; - end_points[ep].pending = cy_true; - end_points[ep].req_xfer_cnt = 0; - end_points[ep].req_length = size; - - if (size >= maxsize) { - /* - * set xfer size for very 1st DMA xfer operation - * port max packet size ( typically 512 or 1024) - */ - end_points[ep].dma_xfer_sz = maxsize; - } else { - /* - * so that we could handle small xfers on in case - * of non-storage EPs - */ - end_points[ep].dma_xfer_sz = size; - } - - addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2; - - if (end_points[ep].sg_list_enabled) { - /* - * Handle sg-list assisted EPs - * seg_xfer_cnt - keeps track of N of sent packets - * buf - pointer to the SG list - * data_p - data pointer for the 1st DMA segment - */ - end_points[ep].seg_xfer_cnt = 0; - end_points[ep].sg_p = buf; - end_points[ep].data_p = sg_virt(end_points[ep].sg_p); - - #ifdef DBGPRN_DMA_SETUP_RD - DBGPRN("cyasomaphal:DMA_setup_read sg_list EP:%d, " - "buf:%p, buf_va:%p, req_sz:%d, maxsz:%d\n", - ep, - buf, - end_points[ep].data_p, - size, - maxsize); - #endif - v = (end_points[ep].dma_xfer_sz & - CY_AS_MEM_P0_E_pn_DMA_REG_COUNT_MASK) | - CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL; - cy_as_hal_write_register(tag, addr, v); - } else { - /* - * Non sg list EP passed void *buf rather then scatterlist *sg - */ - #ifdef DBGPRN_DMA_SETUP_RD - DBGPRN("%s:non-sg_list EP:%d," - "RQ_sz:%d, maxsz:%d\n", - __func__, ep, size, maxsize); - #endif - - end_points[ep].sg_p = NULL; - - /* - * must be a VMA of a membuf in kernel space - */ - end_points[ep].data_p = buf; - - /* - * Program the EP DMA register for Storage endpoints only. - */ - if (is_storage_e_p(ep)) { - v = (end_points[ep].dma_xfer_sz & - CY_AS_MEM_P0_E_pn_DMA_REG_COUNT_MASK) | - CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL; - cy_as_hal_write_register(tag, addr, v); - } - } -} - -/* - * This function must be defined to allow the WB API to - * register a callback function that is called when a - * DMA transfer is complete. - */ -void cy_as_hal_dma_register_callback(cy_as_hal_device_tag tag, - cy_as_hal_dma_complete_callback cb) -{ - DBGPRN("<1>\n%s: WB API has registered a dma_complete callback:%x\n", - __func__, (uint32_t)cb); - callback = cb; -} - -/* - * This function must be defined to return the maximum size of - * DMA request that can be handled on the given endpoint. The - * return value should be the maximum size in bytes that the DMA - * module can handle. - */ -uint32_t cy_as_hal_dma_max_request_size(cy_as_hal_device_tag tag, - cy_as_end_point_number_t ep) -{ - /* - * Storage reads and writes are always done in 512 byte blocks. - * So, we do the count handling within the HAL, and save on - * some of the data transfer delay. - */ - if ((ep == CYASSTORAGE_READ_EP_NUM) || - (ep == CYASSTORAGE_WRITE_EP_NUM)) { - /* max DMA request size HAL can handle by itself */ - return CYASSTORAGE_MAX_XFER_SIZE; - } else { - /* - * For the USB - Processor endpoints, the maximum transfer - * size depends on the speed of USB operation. So, we use - * the following constant to indicate to the API that - * splitting of the data into chunks less that or equal to - * the max transfer size should be handled internally. - */ - - /* DEFINED AS 0xffffffff in cyasdma.h */ - return CY_AS_DMA_MAX_SIZE_HW_SIZE; - } -} - -/* - * This function must be defined to set the state of the WAKEUP pin - * on the WestBridge device. Generally this is done via a GPIO of - * some type. - */ -cy_bool cy_as_hal_set_wakeup_pin(cy_as_hal_device_tag tag, cy_bool state) -{ - /* - * Not supported as of now. - */ - return cy_false; -} - -void cy_as_hal_pll_lock_loss_handler(cy_as_hal_device_tag tag) -{ - cy_as_hal_print_message("error: astoria PLL lock is lost\n"); - cy_as_hal_print_message("please check the input voltage levels"); - cy_as_hal_print_message("and clock, and restart the system\n"); -} - -/* - * Below are the functions that must be defined to provide the basic - * operating system services required by the API. - */ - -/* - * This function is required by the API to allocate memory. - * This function is expected to work exactly like malloc(). - */ -void *cy_as_hal_alloc(uint32_t cnt) -{ - return kmalloc(cnt, GFP_ATOMIC); -} - -/* - * This function is required by the API to free memory allocated - * with CyAsHalAlloc(). This function is'expected to work exacly - * like free(). - */ -void cy_as_hal_free(void *mem_p) -{ - kfree(mem_p); -} - -/* - * Allocator that can be used in interrupt context. - * We have to ensure that the kmalloc call does not - * sleep in this case. - */ -void *cy_as_hal_c_b_alloc(uint32_t cnt) -{ - return kmalloc(cnt, GFP_ATOMIC); -} - -/* - * This function is required to set a block of memory to a - * specific value. This function is expected to work exactly - * like memset() - */ -void cy_as_hal_mem_set(void *ptr, uint8_t value, uint32_t cnt) -{ - memset(ptr, value, cnt); -} - -/* - * This function is expected to create a sleep channel. - * The data structure that represents the sleep channel object - * sleep channel (which is Linux "wait_queue_head_t wq" for this particular HAL) - * passed as a pointer, and allpocated by the caller - * (typically as a local var on the stack) "Create" word should read as - * "SleepOn", this func doesn't actually create anything - */ -cy_bool cy_as_hal_create_sleep_channel(cy_as_hal_sleep_channel *channel) -{ - init_waitqueue_head(&channel->wq); - return cy_true; -} - -/* - * for this particular HAL it doesn't actually destroy anything - * since no actual sleep object is created in CreateSleepChannel() - * sleep channel is given by the pointer in the argument. - */ -cy_bool cy_as_hal_destroy_sleep_channel(cy_as_hal_sleep_channel *channel) -{ - return cy_true; -} - -/* - * platform specific wakeable Sleep implementation - */ -cy_bool cy_as_hal_sleep_on(cy_as_hal_sleep_channel *channel, uint32_t ms) -{ - wait_event_interruptible_timeout(channel->wq, 0, ((ms * HZ)/1000)); - return cy_true; -} - -/* - * wakes up the process waiting on the CHANNEL - */ -cy_bool cy_as_hal_wake(cy_as_hal_sleep_channel *channel) -{ - wake_up_interruptible_all(&channel->wq); - return cy_true; -} - -uint32_t cy_as_hal_disable_interrupts() -{ - if (0 == intr__enable) - ; - - intr__enable++; - return 0; -} - -void cy_as_hal_enable_interrupts(uint32_t val) -{ - intr__enable--; - if (0 == intr__enable) - ; -} - -/* - * Sleep atleast 150ns, cpu dependent - */ -void cy_as_hal_sleep150(void) -{ - uint32_t i, j; - - j = 0; - for (i = 0; i < 1000; i++) - j += (~i); -} - -void cy_as_hal_sleep(uint32_t ms) -{ - cy_as_hal_sleep_channel channel; - - cy_as_hal_create_sleep_channel(&channel); - cy_as_hal_sleep_on(&channel, ms); - cy_as_hal_destroy_sleep_channel(&channel); -} - -cy_bool cy_as_hal_is_polling() -{ - return cy_false; -} - -void cy_as_hal_c_b_free(void *ptr) -{ - cy_as_hal_free(ptr); -} - -/* - * suppose to reinstate the astoria registers - * that may be clobbered in sleep mode - */ -void cy_as_hal_init_dev_registers(cy_as_hal_device_tag tag, - cy_bool is_standby_wakeup) -{ - /* specific to SPI, no implementation required */ - (void) tag; - (void) is_standby_wakeup; -} - -void cy_as_hal_read_regs_before_standby(cy_as_hal_device_tag tag) -{ - /* specific to SPI, no implementation required */ - (void) tag; -} - -cy_bool cy_as_hal_sync_device_clocks(cy_as_hal_device_tag tag) -{ - /* - * we are in asynchronous mode. so no need to handle this - */ - return true; -} - -/* - * init OMAP h/w resources - */ -int start_o_m_a_p_kernel(const char *pgm, - cy_as_hal_device_tag *tag, cy_bool debug) -{ - cy_as_omap_dev_kernel *dev_p; - int i; - u16 data16[4]; - u8 pncfg_reg; - - /* - * No debug mode support through argument as of now - */ - (void)debug; - - DBGPRN(KERN_INFO"starting OMAP34xx HAL...\n"); - - /* - * Initialize the HAL level endpoint DMA data. - */ - for (i = 0; i < sizeof(end_points)/sizeof(end_points[0]); i++) { - end_points[i].data_p = 0; - end_points[i].pending = cy_false; - end_points[i].size = 0; - end_points[i].type = cy_as_hal_none; - end_points[i].sg_list_enabled = cy_false; - - /* - * by default the DMA transfers to/from the E_ps don't - * use sg_list that implies that the upper devices like - * blockdevice have to enable it for the E_ps in their - * initialization code - */ - } - - /* - * allocate memory for OMAP HAL - */ - dev_p = (cy_as_omap_dev_kernel *)cy_as_hal_alloc( - sizeof(cy_as_omap_dev_kernel)); - if (dev_p == 0) { - cy_as_hal_print_message("out of memory allocating OMAP" - "device structure\n"); - return 0; - } - - dev_p->m_sig = CY_AS_OMAP_KERNEL_HAL_SIG; - - /* - * initialize OMAP hardware and StartOMAPKernelall gpio pins - */ - dev_p->m_addr_base = (void *)cy_as_hal_processor_hw_init(); - - /* - * Now perform a hard reset of the device to have - * the new settings take effect - */ - __gpio_set_value(AST_WAKEUP, 1); - - /* - * do Astoria h/w reset - */ - DBGPRN(KERN_INFO"-_-_pulse -> westbridge RST pin\n"); - - /* - * NEGATIVE PULSE on RST pin - */ - __gpio_set_value(AST_RESET, 0); - mdelay(1); - __gpio_set_value(AST_RESET, 1); - mdelay(50); - - /* - * note AFTER reset PNAND interface is 8 bit mode - * so if gpmc Is configured in 8 bit mode upper half will be FF - */ - pncfg_reg = ast_p_nand_casdo_read(CY_AS_MEM_PNAND_CFG); - -#ifdef PNAND_16BIT_MODE - - /* - * switch to 16 bit mode, force NON-LNA LBD mode, 3 RA addr bytes - */ - ast_p_nand_casdi_write(CY_AS_MEM_PNAND_CFG, 0x0001); - - /* - * now in order to continue to talk to astoria - * sw OMAP GPMC into 16 bit mode as well - */ - cy_as_hal_gpmc_enable_16bit_bus(cy_true); -#else - /* Astoria and GPMC are already in 8 bit mode, just initialize PNAND_CFG */ - ast_p_nand_casdi_write(CY_AS_MEM_PNAND_CFG, 0x0000); -#endif - - /* - * NOTE: if you want to capture bus activity on the LA, - * don't use printks in between the activities you want to capture. - * prinks may take milliseconds, and the data of interest - * will fall outside the LA capture window/buffer - */ - data16[0] = ast_p_nand_casdo_read(CY_AS_MEM_CM_WB_CFG_ID); - data16[1] = ast_p_nand_casdo_read(CY_AS_MEM_PNAND_CFG); - - if (data16[0] != 0xA200) { - /* - * astoria device is not found - */ - printk(KERN_ERR "ERROR: astoria device is not found, CY_AS_MEM_CM_WB_CFG_ID "); - printk(KERN_ERR "read returned:%4.4X: CY_AS_MEM_PNAND_CFG:%4.4x !\n", - data16[0], data16[0]); - goto bus_acc_error; - } - - cy_as_hal_print_message(KERN_INFO" register access CASDO test:" - "\n CY_AS_MEM_CM_WB_CFG_ID:%4.4x\n" - "PNAND_CFG after RST:%4.4x\n " - "CY_AS_MEM_PNAND_CFG" - "after cfg_wr:%4.4x\n\n", - data16[0], pncfg_reg, data16[1]); - - dev_p->thread_flag = 1; - spin_lock_init(&int_lock); - dev_p->m_next_p = m_omap_list_p; - - m_omap_list_p = dev_p; - *tag = dev_p; - - cy_as_hal_configure_interrupts((void *)dev_p); - - cy_as_hal_print_message(KERN_INFO"OMAP3430__hal started tag:%p" - ", kernel HZ:%d\n", dev_p, HZ); - - /* - *make processor to storage endpoints SG assisted by default - */ - cy_as_hal_set_ep_dma_mode(4, true); - cy_as_hal_set_ep_dma_mode(8, true); - - return 1; - - /* - * there's been a NAND bus access error or - * astoria device is not connected - */ -bus_acc_error: - /* - * at this point hal tag hasn't been set yet - * so the device will not call omap_stop - */ - cy_as_hal_omap_hardware_deinit(dev_p); - cy_as_hal_free(dev_p); - return 0; -} - -#else -/* - * Some compilers do not like empty C files, so if the OMAP hal is not being - * compiled, we compile this single function. We do this so that for a - * given target HAL there are not multiple sources for the HAL functions. - */ -void my_o_m_a_p_kernel_hal_dummy_function(void) -{ -} - -#endif diff --git a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/cyashaldef.h b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/cyashaldef.h deleted file mode 100644 index c05e6d6cb702..000000000000 --- a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/cyashaldef.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Cypress West Bridge API header file (cyashaldef.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASHALDEF_H_ -#define _INCLUDED_CYASHALDEF_H_ - -/* Summary - * If set to TRUE, the basic numeric types are defined by the - * West Bridge API code - * - * Description - * The West Bridge API relies on some basic integral types to be - * defined. These types include uint8_t, int8_t, uint16_t, - * int16_t, uint32_t, and int32_t. If this macro is defined the - * West Bridge API will define these types based on some basic - * assumptions. If this value is set and the West Bridge API is - * used to set these types, the definition of these types must be - * examined to insure that they are appropriate for the given - * target architecture and compiler. - * - * Notes - * It is preferred that if the basic platform development - * environment defines these types that the CY_DEFINE_BASIC_TYPES - * macro be undefined and the appropriate target system header file - * be added to the file cyashaldef.h. - */ - -#include - - -#if !defined(__doxygen__) -typedef int cy_bool; -#define cy_true (1) -#define cy_false (0) -#endif - -#endif /* _INCLUDED_CYASHALDEF_H_ */ diff --git a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h deleted file mode 100644 index 6426ea61f3d4..000000000000 --- a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h +++ /dev/null @@ -1,319 +0,0 @@ -/* Cypress Antioch HAL for OMAP KERNEL header file (cyashalomapkernel.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -/* - * This file contains the definition of the hardware abstraction - * layer on OMAP3430 talking to the West Bridge Astoria device - */ - - -#ifndef _INCLUDED_CYASHALOMAP_KERNEL_H_ -#define _INCLUDED_CYASHALOMAP_KERNEL_H_ - -#include -#include -#include -#include -/* include does not seem to work - * moving for patch submission -#include -*/ -#include -typedef struct cy_as_hal_sleep_channel_t { - wait_queue_head_t wq; -} cy_as_hal_sleep_channel; - -/* moved to staging location, eventual location - * considered is here -#include -#include -#include -*/ -#include "../cyashaldef.h" -#include "../../../../../../../include/linux/westbridge/cyastypes.h" -#include "../../../../../../../include/linux/westbridge/cyas_cplus_start.h" -#include "cyasomapdev_kernel.h" - -/* - * Below are the data structures that must be defined by the HAL layer - */ - -/* - * The HAL layer must define a TAG for identifying a specific Astoria - * device in the system. In this case the tag is a void * which is - * really an OMAP device pointer - */ -typedef void *cy_as_hal_device_tag; - - -/* This must be included after the CyAsHalDeviceTag type is defined */ - -/* moved to staging location, eventual location - * considered is here - * #include -*/ -#include "../../../../../../../include/linux/westbridge/cyashalcb.h" -/* - * Below are the functions that communicate with the West Bridge - * device. These are system dependent and must be defined by - * the HAL layer for a given system. - */ - -/* - * This function must be defined to write a register within the Antioch - * device. The addr value is the address of the register to write with - * respect to the base address of the Antioch device. - */ -void -cy_as_hal_write_register(cy_as_hal_device_tag tag, - uint16_t addr, uint16_t data); - -/* - * This function must be defined to read a register from - * the west bridge device. The addr value is the address of - * the register to read with respect to the base address - * of the west bridge device. - */ -uint16_t -cy_as_hal_read_register(cy_as_hal_device_tag tag, uint16_t addr); - -/* - * This function must be defined to transfer a block of data - * to the west bridge device. This function can use the burst write - * (DMA) capabilities of Antioch to do this, or it can just copy - * the data using writes. - */ -void -cy_as_hal_dma_setup_write(cy_as_hal_device_tag tag, - uint8_t ep, void *buf, uint32_t size, uint16_t maxsize); - -/* - * This function must be defined to transfer a block of data - * from the Antioch device. This function can use the burst - * read (DMA) capabilities of Antioch to do this, or it can - * just copy the data using reads. - */ -void -cy_as_hal_dma_setup_read(cy_as_hal_device_tag tag, uint8_t ep, - void *buf, uint32_t size, uint16_t maxsize); - -/* - * This function must be defined to cancel any pending DMA request. - */ -void -cy_as_hal_dma_cancel_request(cy_as_hal_device_tag tag, uint8_t ep); - -/* - * This function must be defined to allow the Antioch API to - * register a callback function that is called when a DMA transfer - * is complete. - */ -void -cy_as_hal_dma_register_callback(cy_as_hal_device_tag tag, - cy_as_hal_dma_complete_callback cb); - -/* - * This function must be defined to return the maximum size of DMA - * request that can be handled on the given endpoint. The return - * value should be the maximum size in bytes that the DMA module can - * handle. - */ -uint32_t -cy_as_hal_dma_max_request_size(cy_as_hal_device_tag tag, - cy_as_end_point_number_t ep); - -/* - * This function must be defined to set the state of the WAKEUP pin - * on the Antioch device. Generally this is done via a GPIO of some - * type. - */ -cy_bool -cy_as_hal_set_wakeup_pin(cy_as_hal_device_tag tag, cy_bool state); - -/* - * This function is called when the Antioch PLL loses lock, because - * of a problem in the supply voltage or the input clock. - */ -void -cy_as_hal_pll_lock_loss_handler(cy_as_hal_device_tag tag); - - -/********************************************************************** - * - * Below are the functions that must be defined to provide the basic - * operating system services required by the API. - * -***********************************************************************/ - -/* - * This function is required by the API to allocate memory. This function - * is expected to work exactly like malloc(). - */ -void * -cy_as_hal_alloc(uint32_t cnt); - -/* - * This function is required by the API to free memory allocated with - * CyAsHalAlloc(). This function is expected to work exacly like free(). - */ -void -cy_as_hal_free(void *mem_p); - -/* - * This function is required by the API to allocate memory during a - * callback. This function must be able to provide storage at inturupt - * time. - */ -void * -cy_as_hal_c_b_alloc(uint32_t cnt); - -/* - * This function is required by the API to free memory allocated with - * CyAsCBHalAlloc(). - */ -void -cy_as_hal_c_b_free(void *ptr); - -/* - * This function is required to set a block of memory to a specific - * value. This function is expected to work exactly like memset() - */ -void -cy_as_hal_mem_set(void *ptr, uint8_t value, uint32_t cnt); - -/* - * This function is expected to create a sleep channel. The data - * structure that represents the sleep channel is given by the - * pointer in the argument. - */ -cy_bool -cy_as_hal_create_sleep_channel(cy_as_hal_sleep_channel *channel); - -/* - * This function is expected to destroy a sleep channel. The data - * structure that represents the sleep channel is given by - * the pointer in the argument. - */ - - -cy_bool -cy_as_hal_destroy_sleep_channel(cy_as_hal_sleep_channel *channel); - -cy_bool -cy_as_hal_sleep_on(cy_as_hal_sleep_channel *channel, uint32_t ms); - -cy_bool -cy_as_hal_wake(cy_as_hal_sleep_channel *channel); - -uint32_t -cy_as_hal_disable_interrupts(void); - -void -cy_as_hal_enable_interrupts(uint32_t); - -void -cy_as_hal_sleep150(void); - -void -cy_as_hal_sleep(uint32_t ms); - -cy_bool -cy_as_hal_is_polling(void); - -void cy_as_hal_init_dev_registers(cy_as_hal_device_tag tag, - cy_bool is_standby_wakeup); - -/* - * required only in spi mode - */ -cy_bool cy_as_hal_sync_device_clocks(cy_as_hal_device_tag tag); - -void cy_as_hal_read_regs_before_standby(cy_as_hal_device_tag tag); - - -#ifndef NDEBUG -#define cy_as_hal_assert(cond) if (!(cond))\ - printk(KERN_WARNING"assertion failed at %s:%d\n", __FILE__, __LINE__); -#else -#define cy_as_hal_assert(cond) -#endif - -#define cy_as_hal_print_message printk - -/* removable debug printks */ -#ifndef WESTBRIDGE_NDEBUG -#define DBG_PRINT_ENABLED -#endif - -/*#define MBOX_ACCESS_DBG_PRINT_ENABLED*/ - - -#ifdef DBG_PRINT_ENABLED - /* Debug printing enabled */ - - #define DBGPRN(...) printk(__VA_ARGS__) - #define DBGPRN_FUNC_NAME printk("<1> %x:_func: %s\n", \ - current->pid, __func__) - -#else - /** NO DEBUG PRINTING **/ - #define DBGPRN(...) - #define DBGPRN_FUNC_NAME - -#endif - -/* -CyAsMiscSetLogLevel(uint8_t level) -{ - debug_level = level; -} - -#ifdef CY_AS_LOG_SUPPORT - -void -cy_as_log_debug_message(int level, const char *str) -{ - if (level <= debug_level) - cy_as_hal_print_message("log %d: %s\n", level, str); -} -*/ - - -/* - * print buffer helper - */ -void cyashal_prn_buf(void *buf, uint16_t offset, int len); - -/* - * These are the functions that are not part of the HAL layer, - * but are required to be called for this HAL. - */ -int start_o_m_a_p_kernel(const char *pgm, - cy_as_hal_device_tag *tag, cy_bool debug); -int stop_o_m_a_p_kernel(const char *pgm, cy_as_hal_device_tag tag); -int omap_start_intr(cy_as_hal_device_tag tag); -void cy_as_hal_set_ep_dma_mode(uint8_t ep, bool sg_xfer_enabled); - -/* moved to staging location -#include -*/ -#include "../../../../../../../include/linux/westbridge/cyas_cplus_start.h" -#endif diff --git a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h deleted file mode 100644 index 46f06ee29357..000000000000 --- a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasmemmap.h +++ /dev/null @@ -1,558 +0,0 @@ -/* - OMAP3430 ZOOM MDK astoria interface defs(cyasmemmap.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ -/* include does not seem to work - * moving for patch submission -#include -#include -*/ -#include -#include - -#ifndef _INCLUDED_CYASMEMMAP_H_ -#define _INCLUDED_CYASMEMMAP_H_ - -/* defines copied from OMAP kernel branch */ - -#define OMAP2_PULL_UP (1 << 4) -#define OMAP2_PULL_ENA (1 << 3) -#define OMAP34XX_MUX_MODE0 0 -#define OMAP34XX_MUX_MODE4 4 -#define OMAP3_INPUT_EN (1 << 8) -#define OMAP34XX_PIN_INPUT_PULLUP (OMAP2_PULL_ENA | OMAP3_INPUT_EN \ - | OMAP2_PULL_UP) - -/* - * for OMAP3430 <-> astoria : ADmux mode, 8 bit data path - * WB Signal- OMAP3430 signal COMMENTS - * --------------------------- -------------------- - * CS_L -GPMC_nCS4_GPIO_53 ZOOM I SOM board - * signal: up_nCS_A_EXT - * AD[7:0]-upD[7:0] buffered on the - * transposer board - * GPMC_ADDR - * [A8:A1]->upD[7:0] - * INT# -GPMC_nWP_GPIO_62 - * DACK -N/C not connected - * WAKEUP-GPIO_167 - * RESET-GPIO_126 - * R/B -GPMC_WAIT2_GPIO_64 - * ------------------------------------------- - * The address range for nCS1B is 0x06000000 - 0x07FF FFFF. -*/ - -/* - *OMAP_ZOOM LEDS - */ -#define LED_0 156 -#define LED_1 128 -#define LED_2 64 -#define LED_3 60 - -#define HIGH 1 -#define LOW 1 - -/* - *omap GPIO number - */ -#define AST_WAKEUP 167 -#define AST_RESET 126 -#define AST__rn_b 64 - -/* - * NOTE THIS PIN IS USED AS WP for OMAP NAND - */ -#define AST_INT 62 - -/* - * as an I/O, it is actually controlled by GPMC - */ -#define AST_CS 55 - - -/* - *GPMC prefetch engine - */ - -/* register and its bit fields */ -#define GPMC_PREFETCH_CONFIG1 0x01E0 - - /*32 bytes for 16 bit pnand mode*/ - #define PFE_THRESHOLD 31 - - /* - * bit fields - * PF_ACCESSMODE - 0 - read mode, 1 - write mode - * PF_DMAMODE - 0 - default only intr line signal will be generated - * PF_SYNCHROMODE - default 0 - engin will start access as soon as - * ctrl re STARTENGINE is set - * PF_WAITPINSEL - FOR synchro mode selects WAIT pin whch edge - * will be monitored - * PF_EN_ENGINE - 1- ENABLES ENGINE, but it needs to be started after - * that C ctrl reg bit 0 - * PF_FIFO_THRESHOLD - FIFO threshold in number of BUS(8 or 16) words - * PF_WEIGHTED_PRIO - NUM of cycles granted to PFE if RND_ROBIN - * prioritization is enabled - * PF_ROUND_ROBIN - if enabled, gives priority to other CS, but - * reserves NUM of cycles for PFE's turn - * PF_ENGIN_CS_SEL - GPMC CS assotiated with PFE function - */ - #define PF_ACCESSMODE (0 << 0) - #define PF_DMAMODE (0 << 2) - #define PF_SYNCHROMODE (0 << 3) - #define PF_WAITPINSEL (0x0 << 4) - #define PF_EN_ENGINE (1 << 7) - #define PF_FIFO_THRESHOLD (PFE_THRESHOLD << 8) - #define PF_WEIGHTED_PRIO (0x0 << 16) - #define PF_ROUND_ROBIN (0 << 23) - #define PF_ENGIN_CS_SEL (AST_GPMC_CS << 24) - #define PF_EN_OPTIM_ACC (0 << 27) - #define PF_CYCLEOPTIM (0x0 << 28) - -#define GPMC_PREFETCH_CONFIG1_VAL (PF_ACCESSMODE | \ - PF_DMAMODE | PF_SYNCHROMODE | \ - PF_WAITPINSEL | PF_EN_ENGINE | \ - PF_FIFO_THRESHOLD | PF_FIFO_THRESHOLD | \ - PF_WEIGHTED_PRIO | PF_ROUND_ROBIN | \ - PF_ENGIN_CS_SEL | PF_EN_OPTIM_ACC | \ - PF_CYCLEOPTIM) - -/* register and its bit fields */ -#define GPMC_PREFETCH_CONFIG2 0x01E4 - /* - * bit fields - * 14 bit field NOTE this counts is also - * is in number of BUS(8 or 16) words - */ - #define PF_TRANSFERCOUNT (0x000) - - -/* register and its bit fields */ -#define GPMC_PREFETCH_CONTROL 0x01EC - /* - * bit fields , ONLY BIT 0 is implemented - * PFWE engin must be programmed with this bit = 0 - */ - #define PFPW_STARTENGINE (1 << 0) - -/* register and its bit fields */ -#define GPMC_PREFETCH_STATUS 0x01F0 - - /* */ - #define PFE_FIFO_THRESHOLD (1 << 16) - -/* - * GPMC posted write/prefetch engine end - */ - - -/* - * chip select number on GPMC ( 0..7 ) - */ -#define AST_GPMC_CS 4 - -/* - * not connected - */ -#define AST_DACK 00 - - -/* - * Physical address above the NAND flash - * we use CS For mapping in OMAP3430 RAM space use 0x0600 0000 - */ -#define CYAS_DEV_BASE_ADDR (0x20000000) - -#define CYAS_DEV_MAX_ADDR (0xFF) -#define CYAS_DEV_ADDR_RANGE (CYAS_DEV_MAX_ADDR << 1) - -#ifdef p_s_r_a_m_INTERFACE - /* in CRAM or PSRAM mode OMAP A1..An wires-> Astoria, there is no A0 line */ - #define CYAS_DEV_CALC_ADDR(cyas_addr) (cyas_addr << 1) - #define CYAS_DEV_CALC_EP_ADDR(ep) (ep << 1) -#else - /* - * For pNAND interface it depends on NAND emulation mode - * SBD/LBD etc we use NON-LNA_LBD mode, so it goes like this: - * forlbd , - * where CA1 address must have bits 2,3 = "11" - * ep is mapped into RA1 bits {4:0} - */ - #define CYAS_DEV_CALC_ADDR(cyas_addr) (cyas_addr | 0x0c00) - #define CYAS_DEV_CALC_EP_ADDR(ep) ep -#endif - -/* - *OMAP3430 i/o access macros - */ -#define IORD32(addr) (*(volatile u32 *)(addr)) -#define IOWR32(addr, val) (*(volatile u32 *)(addr) = val) - -#define IORD16(addr) (*(volatile u16 *)(addr)) -#define IOWR16(addr, val) (*(volatile u16 *)(addr) = val) - -#define IORD8(addr) (*(volatile u8 *)(addr)) -#define IOWR8(addr, val) (*(volatile u8 *)(addr) = val) - -/* - * local defines for accessing to OMAP GPIO *** - */ -#define CTLPADCONF_BASE_ADDR 0x48002000 -#define CTLPADCONF_SIZE 0x1000 - -#define GPIO1_BASE_ADDR 0x48310000 -#define GPIO2_BASE_ADDR 0x49050000 -#define GPIO3_BASE_ADDR 0x49052000 -#define GPIO4_BASE_ADDR 0x49054000 -#define GPIO5_BASE_ADDR 0x49056000 -#define GPIO6_BASE_ADDR 0x49058000 -#define GPIO_SPACE_SIZE 0x1000 - - -/* - * OMAP3430 GPMC timing for pNAND interface - */ -#define GPMC_BASE 0x6E000000 -#define GPMC_REGION_SIZE 0x1000 -#define GPMC_CONFIG_REG (0x50) - -/* - * bit 0 in the GPMC_CONFIG_REG - */ -#define NAND_FORCE_POSTED_WRITE_B 1 - -/* - * WAIT2STATUS, must be (1 << 10) - */ -#define AS_WAIT_PIN_MASK (1 << 10) - - -/* - * GPMC_CONFIG(reg number [1..7] [for chip sel CS[0..7]) - */ -#define GPMC_CFG_REG(N, CS) ((0x60 + (4*(N-1))) + (0x30*CS)) - -/* - *gpmc nand registers for CS4 - */ -#define AST_GPMC_NAND_CMD (0x7c + (0x30*AST_GPMC_CS)) -#define AST_GPMC_NAND_ADDR (0x80 + (0x30*AST_GPMC_CS)) -#define AST_GPMC_NAND_DATA (0x84 + (0x30*AST_GPMC_CS)) - -#define GPMC_STAT_REG (0x54) -#define GPMC_ERR_TYPE (0x48) - -/* - * we get "gpmc_base" from kernel - */ -#define GPMC_VMA(offset) (gpmc_base + offset) - -/* - * GPMC CS space VMA start address - */ -#define GPMC_CS_VMA(offset) (gpmc_data_vma + offset) - -/* - * PAD_CFG mux space VMA - */ -#define PADCFG_VMA(offset) (iomux_vma + offset) - -/* - * CONFIG1: by default, sngle access, async r/w RD_MULTIPLE[30] - * WR_MULTIPLE[28]; GPMC_FCL_DIV[1:0] - */ -#define GPMC_FCLK_DIV ((0) << 0) - -/* - * ADDITIONAL DIVIDER FOR ALL TIMING PARAMS - */ -#define TIME_GRAN_SCALE ((0) << 4) - -/* - * for use by gpmc_set_timings api, measured in ns, not clocks - */ -#define WB_GPMC_BUSCYC_t (7 * 6) -#define WB_GPMC_CS_t_o_n (0) -#define WB_GPMC_ADV_t_o_n (0) -#define WB_GPMC_OE_t_o_n (0) -#define WB_GPMC_OE_t_o_f_f (5 * 6) -#define WB_GPMC_WE_t_o_n (1 * 6) -#define WB_GPMC_WE_t_o_f_f (5 * 6) -#define WB_GPMC_RDS_ADJ (2 * 6) -#define WB_GPMC_RD_t_a_c_c (WB_GPMC_OE_t_o_f_f + WB_GPMC_RDS_ADJ) -#define WB_GPMC_WR_t_a_c_c (WB_GPMC_BUSCYC_t) - -#define DIR_OUT 0 -#define DIR_INP 1 -#define DRV_HI 1 -#define DRV_LO 0 - -/* - * GPMC_CONFIG7[cs] register bit fields - * AS_CS_MASK - 3 bit mask for A26,A25,A24, - * AS_CS_BADDR - 6 BIT VALUE A29 ...A24 - * CSVALID_B - CSVALID bit on GPMC_CONFIG7[cs] register - */ -#define AS_CS_MASK (0X7 << 8) -#define AS_CS_BADDR 0x02 -#define CSVALID_B (1 << 6) - -/* - * DEFINE OMAP34XX GPIO OFFSETS (should have been defined in kernel /arch - * these are offsets from the BASE_ADDRESS of the GPIO BLOCK - */ -#define GPIO_REVISION 0x000 -#define GPIO_SYSCONFIG 0x010 -#define GPIO_SYSSTATUS1 0x014 -#define GPIO_IRQSTATUS1 0x018 -#define GPIO_IRQENABLE1 0x01C -#define GPIO_IRQSTATUS2 0x028 -#define GPIO_CTRL 0x030 -#define GPIO_OE 0x034 -#define GPIO_DATA_IN 0x038 -#define GPIO_DATA_OUT 0x03C -#define GPIO_LEVELDETECT0 0x040 -#define GPIO_LEVELDETECT1 0x044 -#define GPIO_RISINGDETECT 0x048 -#define GPIO_FALLINGDETECT 0x04c -#define GPIO_CLEAR_DATAOUT 0x090 -#define GPIO_SET_DATAOUT 0x094 - -typedef struct { - char *name; - u32 phy_addr; - u32 virt_addr; - u32 size; -} io2vma_tab_t; - -/* - * GPIO phy to translation VMA table - */ -static io2vma_tab_t gpio_vma_tab[6] = { - {"GPIO1_BASE_ADDR", GPIO1_BASE_ADDR , 0 , GPIO_SPACE_SIZE}, - {"GPIO2_BASE_ADDR", GPIO2_BASE_ADDR , 0 , GPIO_SPACE_SIZE}, - {"GPIO3_BASE_ADDR", GPIO3_BASE_ADDR , 0 , GPIO_SPACE_SIZE}, - {"GPIO4_BASE_ADDR", GPIO4_BASE_ADDR , 0 , GPIO_SPACE_SIZE}, - {"GPIO5_BASE_ADDR", GPIO5_BASE_ADDR , 0 , GPIO_SPACE_SIZE}, - {"GPIO6_BASE_ADDR", GPIO6_BASE_ADDR , 0 , GPIO_SPACE_SIZE} -}; -/* - * name - USER signal name assigned to the pin ( for printks) - * mux_func - enum index NAME for the pad_cfg function - * pin_num - pin_number if mux_func is GPIO, if not a GPIO it is -1 - * mux_ptr - pointer to the corresponding pad_cfg_reg - * (used for pad release ) - * mux_save - preserve here original PAD_CNF value for this - * pin (used for pad release) - * dir - if GPIO: 0 - OUT , 1 - IN - * dir_save - save original pin direction - * drv - initial drive level "0" or "1" - * drv_save - save original pin drive level - * valid - 1 if successfuly configured -*/ -typedef struct { - char *name; - u32 mux_func; - int pin_num; - u16 *mux_ptr; - u16 mux_save; - u8 dir; - u8 dir_save; - u8 drv; - u8 drv_save; - u8 valid; -} user_pad_cfg_t; - -/* - * need to ensure that enums are in sync with the - * omap_mux_pin_cfg table, these enums designate - * functions that OMAP pads can be configured to - */ -enum { - B23_OMAP3430_GPIO_167, - D23_OMAP3430_GPIO_126, - H1_OMAP3430_GPIO_62, - H1_OMAP3430_GPMC_n_w_p, - T8_OMAP3430_GPMC_n_c_s4, - T8_OMAP3430_GPIO_55, - R25_OMAP3430_GPIO_156, - R27_OMAP3430_GPIO_128, - K8_OMAP3430_GPIO_64, - K8_GPMC_WAIT2, - G3_OMAP3430_GPIO_60, - G3_OMAP3430_n_b_e0_CLE, - C6_GPMC_WAIT3, - J1_OMAP3430_GPIO_61, - C6_OMAP3430_GPIO_65, - - END_OF_TABLE -}; - -/* - * number of GPIOS we plan to grab - */ -#define GPIO_SLOTS 8 - -/* - * user_pads_init() reads(and saves) from/to this table - * used in conjunction with omap_3430_mux_t table in .h file - * because the way it's done in the kernel code - * TODO: implement restore of the the original cfg and i/o regs - */ - -static user_pad_cfg_t user_pad_cfg[] = { - /* - * name,pad_func,pin_num, mux_ptr, mux_sav, dir, - * dir_sav, drv, drv_save, valid - */ - {"AST_WAKEUP", B23_OMAP3430_GPIO_167, 167, NULL, 0, - DIR_OUT, 0, DRV_HI, 0, 0}, - {"AST_RESET", D23_OMAP3430_GPIO_126, 126, NULL, 0, - DIR_OUT, 0, DRV_HI, 0, 0}, - {"AST__rn_b", K8_GPMC_WAIT2, 64, NULL, 0, - DIR_INP, 0, 0, 0, 0}, - {"AST_INTR", H1_OMAP3430_GPIO_62, 62, NULL, 0, - DIR_INP, 0, DRV_HI, 0, 0}, - {"AST_CS", T8_OMAP3430_GPMC_n_c_s4, 55, NULL, 0, - DIR_OUT, 0, DRV_HI, 0, 0}, - {"LED_0", R25_OMAP3430_GPIO_156, 156, NULL, 0, - DIR_OUT, 0, DRV_LO, 0, 0}, - {"LED_1", R27_OMAP3430_GPIO_128, 128, NULL, 0, - DIR_OUT, 0, DRV_LO, 0, 0}, - {"AST_CLE", G3_OMAP3430_n_b_e0_CLE , 60, NULL, 0, - DIR_OUT, 0, DRV_LO, 0, 0}, - /* - * Z terminator, must always be present - * for sanity check, don't remove - */ - {NULL} -}; - -#define GPIO_BANK(pin) (pin >> 5) -#define REG_WIDTH 32 -#define GPIO_REG_VMA(pin_num, offset) \ - (gpio_vma_tab[GPIO_BANK(pin_num)].virt_addr + offset) - -/* - * OMAP GPIO_REG 32 BIT MASK for a bit or - * flag in gpio_No[0..191] apply it to a 32 bit - * location to set clear or check on a corresponding - * gpio bit or flag - */ -#define GPIO_REG_MASK(pin_num) (1 << \ - (pin_num - (GPIO_BANK(pin_num) * REG_WIDTH))) - -/* - * OMAP GPIO registers bitwise access macros - */ - -#define OMAP_GPIO_BIT(pin_num, reg) \ - ((*((u32 *)GPIO_REG_VMA(pin_num, reg)) \ - & GPIO_REG_MASK(pin_num)) ? 1 : 0) - -#define RD_OMAP_GPIO_BIT(pin_num, v) OMAP_GPIO_BIT(pin_num, reg) - -/* - *these are superfast set/clr bitbang macro, 48ns cyc tyme - */ -#define OMAP_SET_GPIO(pin_num) \ - (*(u32 *)GPIO_REG_VMA(pin_num, GPIO_SET_DATAOUT) \ - = GPIO_REG_MASK(pin_num)) -#define OMAP_CLR_GPIO(pin_num) \ - (*(u32 *)GPIO_REG_VMA(pin_num, GPIO_CLEAR_DATAOUT) \ - = GPIO_REG_MASK(pin_num)) - -#define WR_OMAP_GPIO_BIT(pin_num, v) \ - (v ? (*(u32 *)GPIO_REG_VMA(pin_num, \ - GPIO_SET_DATAOUT) = GPIO_REG_MASK(pin_num)) \ - : (*(u32 *)GPIO_REG_VMA(pin_num, \ - GPIO_CLEAR_DATAOUT) = GPIO_REG_MASK(pin_num))) - -/* - * Note this pin cfg mimicks similar implementation - * in linux kernel, which unfortunately doesn't allow - * us to dynamically insert new custom GPIO mux - * configurations all REG definitions used in this - * applications. to add a new pad_cfg function, insert - * a new ENUM and new pin_cfg entry in omap_mux_pin_cfg[] - * table below - * - * offset - note this is a word offset since the - * SCM regs are 16 bit packed in one 32 bit word - * mux_val - just enough to describe pins used - */ -typedef struct { - char *name; - u16 offset; - u16 mux_val; -} omap_3430_mux_t; - -/* - * "OUTIN" is configuration when DATA reg drives the - * pin but the level at the pin can be sensed - */ -#define PAD_AS_OUTIN (OMAP34XX_MUX_MODE4 | \ - OMAP34XX_PIN_OUTPUT | OMAP34XX_PIN_INPUT) - -omap_3430_mux_t omap_mux_pin_cfg[] = { - /* - * B23_OMAP3430_GPIO_167 - GPIO func to PAD 167 WB wakeup - * D23_OMAP3430_GPIO_126 - drive GPIO_126 ( AST RESET) - * H1_OMAP3430_GPIO_62 - need a pullup on this pin - * H1_OMAP3430_GPMC_n_w_p - GPMC NAND CTRL n_w_p out - * T8_OMAP3430_GPMC_n_c_s4" - T8 is controlled b_y GPMC NAND ctrl - * R25_OMAP3430_GPIO_156 - OMAPZOOM drive LED_0 - * R27_OMAP3430_GPIO_128 - OMAPZOOM drive LED_1 - * K8_OMAP3430_GPIO_64 - OMAPZOOM drive LED_2 - * K8_GPMC_WAIT2 - GPMC WAIT2 function on PAD K8 - * G3_OMAP3430_GPIO_60 - OMAPZOOM drive LED_3 - * G3_OMAP3430_n_b_e0_CLE -GPMC NAND ctrl CLE signal - */ - - {"B23_OMAP3430_GPIO_167", 0x0130, (OMAP34XX_MUX_MODE4)}, - {"D23_OMAP3430_GPIO_126", 0x0132, (OMAP34XX_MUX_MODE4)}, - {"H1_OMAP3430_GPIO_62", 0x00CA, (OMAP34XX_MUX_MODE4 | - OMAP3_INPUT_EN | OMAP34XX_PIN_INPUT_PULLUP) }, - {"H1_OMAP3430_GPMC_n_w_p", 0x00CA, (OMAP34XX_MUX_MODE0)}, - {"T8_OMAP3430_GPMC_n_c_s4", 0x00B6, (OMAP34XX_MUX_MODE0) }, - {"T8_OMAP3430_GPIO_55", 0x00B6, (OMAP34XX_MUX_MODE4) }, - {"R25_OMAP3430_GPIO_156", 0x018C, (OMAP34XX_MUX_MODE4) }, - {"R27_OMAP3430_GPIO_128", 0x0154, (OMAP34XX_MUX_MODE4) }, - {"K8_OMAP3430_GPIO_64", 0x00d0, (OMAP34XX_MUX_MODE4) }, - {"K8_GPMC_WAIT2", 0x00d0, (OMAP34XX_MUX_MODE0) }, - {"G3_OMAP3430_GPIO_60", 0x00C6, (OMAP34XX_MUX_MODE4 | - OMAP3_INPUT_EN)}, - {"G3_OMAP3430_n_b_e0_CLE", 0x00C6, (OMAP34XX_MUX_MODE0)}, - {"C6_GPMC_WAIT3", 0x00d2, (OMAP34XX_MUX_MODE0)}, - {"C6_OMAP3430_GPIO_65", 0x00d2, (OMAP34XX_MUX_MODE4 | - OMAP3_INPUT_EN)}, - {"J1_OMAP3430_GPIO_61", 0x00C8, (OMAP34XX_MUX_MODE4 | - OMAP3_INPUT_EN | OMAP34XX_PIN_INPUT_PULLUP)}, - /* - * don't remove, used for sanity check. - */ - {"END_OF_TABLE"} -}; - - -#endif /* _INCLUDED_CYASMEMMAP_H_ */ - -/*[]*/ diff --git a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasomapdev_kernel.h b/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasomapdev_kernel.h deleted file mode 100644 index 5a64bb6bb053..000000000000 --- a/drivers/staging/westbridge/astoria/arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyasomapdev_kernel.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Cypress Antioch OMAP KERNEL file (cyanomapdev_kernel.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor, -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef __CY_AS_OMAP_DEV_KERNEL_H__ -#define __CY_AS_OMAP_DEV_KERNEL_H__ - - -#include -#include -#include - -/* include does not seem to work - * moving for patch submission -#include -*/ -#include - -/* - * Constants - */ -#define CY_AS_OMAP_KERNEL_HAL_SIG (0x1441) - - -/* - * Data structures - */ -typedef struct cy_as_omap_dev_kernel { - /* This is the signature for this data structure */ - unsigned int m_sig; - - /* Address base of Antioch Device */ - void *m_addr_base; - - /* This is a pointer to the next Antioch device in the system */ - struct cy_as_omap_dev_kernel *m_next_p; - - /* This is for thread sync */ - struct completion thread_complete; - - /* This is for thread to wait for interrupts */ - cy_as_hal_sleep_channel thread_sc; - - /* This is for thread to exit upon StopOmapKernel */ - int thread_flag; /* set 1 to exit */ - - int dma_ch; - - /* This is for dma sync */ - struct completion dma_complete; -} cy_as_omap_dev_kernel; - -#endif - -/*[]*/ diff --git a/drivers/staging/westbridge/astoria/block/Kconfig b/drivers/staging/westbridge/astoria/block/Kconfig deleted file mode 100644 index 851bf96a7b87..000000000000 --- a/drivers/staging/westbridge/astoria/block/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# -# West Bridge block driver configuration -# - -config WESTBRIDGE_BLOCK_DRIVER - tristate "West Bridge Block Driver" - help - Include the West Bridge based block driver - diff --git a/drivers/staging/westbridge/astoria/block/Makefile b/drivers/staging/westbridge/astoria/block/Makefile deleted file mode 100644 index 4a45dd0861e7..000000000000 --- a/drivers/staging/westbridge/astoria/block/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for the kernel westbridge block driver -# - -ifneq ($(CONFIG_WESTBRIDGE_DEBUG),y) - EXTRA_CFLAGS += -DWESTBRIDGE_NDEBUG -endif - -obj-$(CONFIG_WESTBRIDGE_BLOCK_DRIVER) += cyasblkdev.o -cyasblkdev-y := cyasblkdev_block.o cyasblkdev_queue.o - diff --git a/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c b/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c deleted file mode 100644 index 87452bde7c93..000000000000 --- a/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c +++ /dev/null @@ -1,1631 +0,0 @@ -/* cyanblkdev_block.c - West Bridge Linux Block Driver source file -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -/* - * Linux block driver implementation for Cypress West Bridge. - * Based on the mmc block driver implementation by Andrew Christian - * for the linux 2.6.26 kernel. - * mmc_block.c, 5/28/2002 - */ - -/* - * Block driver for media (i.e., flash cards) - * - * Copyright 2002 Hewlett-Packard Company - * - * Use consistent with the GNU GPL is permitted, - * provided that this copyright notice is - * preserved in its entirety in all copies and derived works. - * - * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, - * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS - * FITNESS FOR ANY PARTICULAR PURPOSE. - * - * Many thanks to Alessandro Rubini and Jonathan Corbet! - * - * Author: Andrew Christian - * 28 May 2002 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include "cyasblkdev_queue.h" - -#define CYASBLKDEV_SHIFT 0 /* Only a single partition. */ -#define CYASBLKDEV_MAX_REQ_LEN (256) -#define CYASBLKDEV_NUM_MINORS (256 >> CYASBLKDEV_SHIFT) -#define CY_AS_TEST_NUM_BLOCKS (64) -#define CYASBLKDEV_MINOR_0 1 -#define CYASBLKDEV_MINOR_1 2 -#define CYASBLKDEV_MINOR_2 3 - -static int major; -module_param(major, int, 0444); -MODULE_PARM_DESC(major, - "specify the major device number for cyasblkdev block driver"); - -/* parameters passed from the user space */ -static int vfat_search; -module_param(vfat_search, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(vfat_search, - "dynamically find the location of the first sector"); - -static int private_partition_bus = -1; -module_param(private_partition_bus, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(private_partition_bus, - "bus number for private partition"); - -static int private_partition_size = -1; -module_param(private_partition_size, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(private_partition_size, - "size of the private partition"); - -/* - * There is one cyasblkdev_blk_data per slot. - */ -struct cyasblkdev_blk_data { - spinlock_t lock; - int media_count[2]; - const struct block_device_operations *blkops; - unsigned int usage; - unsigned int suspended; - - /* handle to the west bridge device this handle, typdefed as *void */ - cy_as_device_handle dev_handle; - - /* our custom structure, in addition to request queue, - * adds lock & semaphore items*/ - struct cyasblkdev_queue queue; - - /* 16 entries is enough given max request size - * 16 * 4K (64 K per request)*/ - struct scatterlist sg[16]; - - /* non-zero enables printk of executed reqests */ - unsigned int dbgprn_flags; - - /*gen_disk for private, system disk */ - struct gendisk *system_disk; - cy_as_media_type system_disk_type; - cy_bool system_disk_read_only; - cy_bool system_disk_bus_num; - - /* sector size for the medium */ - unsigned int system_disk_blk_size; - unsigned int system_disk_first_sector; - unsigned int system_disk_unit_no; - - /*gen_disk for bus 0 */ - struct gendisk *user_disk_0; - cy_as_media_type user_disk_0_type; - cy_bool user_disk_0_read_only; - cy_bool user_disk_0_bus_num; - - /* sector size for the medium */ - unsigned int user_disk_0_blk_size; - unsigned int user_disk_0_first_sector; - unsigned int user_disk_0_unit_no; - - /*gen_disk for bus 1 */ - struct gendisk *user_disk_1; - cy_as_media_type user_disk_1_type; - cy_bool user_disk_1_read_only; - cy_bool user_disk_1_bus_num; - - /* sector size for the medium */ - unsigned int user_disk_1_blk_size; - unsigned int user_disk_1_first_sector; - unsigned int user_disk_1_unit_no; -}; - -/* pointer to west bridge block data device superstructure */ -static struct cyasblkdev_blk_data *gl_bd; - -static DEFINE_SEMAPHORE(open_lock); - -/* local forwardd declarationss */ -static cy_as_device_handle *cyas_dev_handle; -static void cyasblkdev_blk_deinit(struct cyasblkdev_blk_data *bd); - -/*change debug print options */ - #define DBGPRN_RD_RQ (1 < 0) - #define DBGPRN_WR_RQ (1 < 1) - #define DBGPRN_RQ_END (1 < 2) - -int blkdev_ctl_dbgprn( - int prn_flags - ) -{ - int cur_options = gl_bd->dbgprn_flags; - - DBGPRN_FUNC_NAME; - - /* set new debug print options */ - gl_bd->dbgprn_flags = prn_flags; - - /* return previous */ - return cur_options; -} -EXPORT_SYMBOL(blkdev_ctl_dbgprn); - -static struct cyasblkdev_blk_data *cyasblkdev_blk_get( - struct gendisk *disk - ) -{ - struct cyasblkdev_blk_data *bd; - - DBGPRN_FUNC_NAME; - - down(&open_lock); - - bd = disk->private_data; - - if (bd && (bd->usage == 0)) - bd = NULL; - - if (bd) { - bd->usage++; - #ifndef NBDEBUG - cy_as_hal_print_message( - "cyasblkdev_blk_get: usage = %d\n", bd->usage); - #endif - } - up(&open_lock); - - return bd; -} - -static void cyasblkdev_blk_put( - struct cyasblkdev_blk_data *bd - ) -{ - DBGPRN_FUNC_NAME; - - down(&open_lock); - - if (bd) { - bd->usage--; - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - " cyasblkdev_blk_put , bd->usage= %d\n", bd->usage); - #endif - } else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "cyasblkdev: blk_put(bd) on bd = NULL!: usage = %d\n", - bd->usage); - #endif - up(&open_lock); - return; - } - - if (bd->usage == 0) { - put_disk(bd->user_disk_0); - put_disk(bd->user_disk_1); - put_disk(bd->system_disk); - cyasblkdev_cleanup_queue(&bd->queue); - - if (CY_AS_ERROR_SUCCESS != - cy_as_storage_release(bd->dev_handle, 0, 0, 0, 0)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "cyasblkdev: cannot release bus 0\n"); - #endif - } - - if (CY_AS_ERROR_SUCCESS != - cy_as_storage_release(bd->dev_handle, 1, 0, 0, 0)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "cyasblkdev: cannot release bus 1\n"); - #endif - } - - if (CY_AS_ERROR_SUCCESS != - cy_as_storage_stop(bd->dev_handle, 0, 0)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "cyasblkdev: cannot stop storage stack\n"); - #endif - } - - #ifdef __CY_ASTORIA_SCM_KERNEL_HAL__ - /* If the SCM Kernel HAL is being used, disable the use - * of scatter/gather lists at the end of block driver usage. - */ - cy_as_hal_disable_scatter_list(cyasdevice_gethaltag()); - #endif - - /*ptr to global struct cyasblkdev_blk_data */ - gl_bd = NULL; - kfree(bd); - } - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "cyasblkdev (blk_put): usage = %d\n", - bd->usage); - #endif - up(&open_lock); -} - -static int cyasblkdev_blk_open( - struct block_device *bdev, - fmode_t mode - ) -{ - struct cyasblkdev_blk_data *bd = cyasblkdev_blk_get(bdev->bd_disk); - int ret = -ENXIO; - - DBGPRN_FUNC_NAME; - - if (bd) { - if (bd->usage == 2) - check_disk_change(bdev); - - ret = 0; - - if (bdev->bd_disk == bd->user_disk_0) { - if ((mode & FMODE_WRITE) && bd->user_disk_0_read_only) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "device marked as readonly " - "and write requested\n"); - #endif - - cyasblkdev_blk_put(bd); - ret = -EROFS; - } - } else if (bdev->bd_disk == bd->user_disk_1) { - if ((mode & FMODE_WRITE) && bd->user_disk_1_read_only) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "device marked as readonly " - "and write requested\n"); - #endif - - cyasblkdev_blk_put(bd); - ret = -EROFS; - } - } else if (bdev->bd_disk == bd->system_disk) { - if ((mode & FMODE_WRITE) && bd->system_disk_read_only) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "device marked as readonly " - "and write requested\n"); - #endif - - cyasblkdev_blk_put(bd); - ret = -EROFS; - } - } - } - - return ret; -} - -static int cyasblkdev_blk_release( - struct gendisk *disk, - fmode_t mode - ) -{ - struct cyasblkdev_blk_data *bd = disk->private_data; - - DBGPRN_FUNC_NAME; - - cyasblkdev_blk_put(bd); - return 0; -} - -static int cyasblkdev_blk_ioctl( - struct block_device *bdev, - fmode_t mode, - unsigned int cmd, - unsigned long arg - ) -{ - DBGPRN_FUNC_NAME; - - if (cmd == HDIO_GETGEO) { - /*for now we only process geometry IOCTL*/ - struct hd_geometry geo; - - memset(&geo, 0, sizeof(struct hd_geometry)); - - geo.cylinders = get_capacity(bdev->bd_disk) / (4 * 16); - geo.heads = 4; - geo.sectors = 16; - geo.start = get_start_sect(bdev); - - /* copy to user space */ - return copy_to_user((void __user *)arg, &geo, sizeof(geo)) - ? -EFAULT : 0; - } - - return -ENOTTY; -} - -/* check_events block_device opp - * this one is called by kernel to confirm if the media really changed - * as we indicated by issuing check_disk_change() call */ -unsigned int cyasblkdev_check_events(struct gendisk *gd, unsigned int clearing) -{ - struct cyasblkdev_blk_data *bd; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("cyasblkdev_media_changed() is called\n"); - #endif - - if (gd) - bd = gd->private_data; - else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "cyasblkdev_media_changed() is called, " - "but gd is null\n"); - #endif - } - - /* return media change state - DISK_EVENT_MEDIA_CHANGE yes, 0 no */ - return 0; -} - -/* this one called by kernel to give us a chence - * to prep the new media before it starts to rescaning - * of the newlly inserted SD media */ -int cyasblkdev_revalidate_disk(struct gendisk *gd) -{ - /*int (*revalidate_disk) (struct gendisk *); */ - - #ifndef WESTBRIDGE_NDEBUG - if (gd) - cy_as_hal_print_message( - "cyasblkdev_revalidate_disk() is called, " - "(gl_bd->usage:%d)\n", gl_bd->usage); - #endif - - /* 0 means ok, kern can go ahead with partition rescan */ - return 0; -} - - -/*standard block device driver interface */ -static struct block_device_operations cyasblkdev_bdops = { - .open = cyasblkdev_blk_open, - .release = cyasblkdev_blk_release, - .ioctl = cyasblkdev_blk_ioctl, - /* .getgeo = cyasblkdev_blk_getgeo, */ - /* added to support media removal( real and simulated) media */ - .check_events = cyasblkdev_check_events, - /* added to support media removal( real and simulated) media */ - .revalidate_disk = cyasblkdev_revalidate_disk, - .owner = THIS_MODULE, -}; - -/* west bridge block device prep request function */ -static int cyasblkdev_blk_prep_rq( - struct cyasblkdev_queue *bq, - struct request *req - ) -{ - struct cyasblkdev_blk_data *bd = bq->data; - int stat = BLKPREP_OK; - - DBGPRN_FUNC_NAME; - - /* If we have no device, we haven't finished initialising. */ - if (!bd || !bd->dev_handle) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message(KERN_ERR - "cyasblkdev %s: killing request - no device/host\n", - req->rq_disk->disk_name); - #endif - stat = BLKPREP_KILL; - } - - if (bd->suspended) { - blk_plug_device(bd->queue.queue); - stat = BLKPREP_DEFER; - } - - /* Check for excessive requests.*/ - if (blk_rq_pos(req) + blk_rq_sectors(req) > get_capacity(req->rq_disk)) { - cy_as_hal_print_message("cyasblkdev: bad request address\n"); - stat = BLKPREP_KILL; - } - - return stat; -} - -/*west bridge storage async api on_completed callback */ -static void cyasblkdev_issuecallback( - /* Handle to the device completing the storage operation */ - cy_as_device_handle handle, - /* The media type completing the operation */ - cy_as_media_type type, - /* The device completing the operation */ - uint32_t device, - /* The unit completing the operation */ - uint32_t unit, - /* The block number of the completed operation */ - uint32_t block_number, - /* The type of operation */ - cy_as_oper_type op, - /* The error status */ - cy_as_return_status_t status - ) -{ - int retry_cnt = 0; - DBGPRN_FUNC_NAME; - - if (status != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: async r/w: op:%d failed with error %d at address %d\n", - __func__, op, status, block_number); - #endif - } - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s calling blk_end_request from issue_callback " - "req=0x%x, status=0x%x, nr_sectors=0x%x\n", - __func__, (unsigned int) gl_bd->queue.req, status, - (unsigned int) blk_rq_sectors(gl_bd->queue.req)); - #endif - - /* note: blk_end_request w/o __ prefix should - * not require spinlocks on the queue*/ - while (blk_end_request(gl_bd->queue.req, - status, blk_rq_sectors(gl_bd->queue.req)*512)) { - retry_cnt++; - } - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s blkdev_callback: ended rq on %d sectors, " - "with err:%d, n:%d times\n", __func__, - (int)blk_rq_sectors(gl_bd->queue.req), status, - retry_cnt - ); - #endif - - spin_lock_irq(&gl_bd->lock); - - /*elevate next request, if there is one*/ - if (!blk_queue_plugged(gl_bd->queue.queue)) { - /* queue is not plugged */ - gl_bd->queue.req = blk_fetch_request(gl_bd->queue.queue); - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s blkdev_callback: " - "blk_fetch_request():%p\n", - __func__, gl_bd->queue.req); - #endif - } - - if (gl_bd->queue.req) { - spin_unlock_irq(&gl_bd->lock); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s blkdev_callback: about to " - "call issue_fn:%p\n", __func__, gl_bd->queue.req); - #endif - - gl_bd->queue.issue_fn(&gl_bd->queue, gl_bd->queue.req); - } else { - spin_unlock_irq(&gl_bd->lock); - } -} - -/* issue astoria blkdev request (issue_fn) */ -static int cyasblkdev_blk_issue_rq( - struct cyasblkdev_queue *bq, - struct request *req - ) -{ - struct cyasblkdev_blk_data *bd = bq->data; - int index = 0; - int ret = CY_AS_ERROR_SUCCESS; - uint32_t req_sector = 0; - uint32_t req_nr_sectors = 0; - int bus_num = 0; - int lcl_unit_no = 0; - - DBGPRN_FUNC_NAME; - - /* - * will construct a scatterlist for the given request; - * the return value is the number of actually used - * entries in the resulting list. Then, this scatterlist - * can be used for the actual DMA prep operation. - */ - spin_lock_irq(&bd->lock); - index = blk_rq_map_sg(bq->queue, req, bd->sg); - - if (req->rq_disk == bd->user_disk_0) { - bus_num = bd->user_disk_0_bus_num; - req_sector = blk_rq_pos(req) + gl_bd->user_disk_0_first_sector; - req_nr_sectors = blk_rq_sectors(req); - lcl_unit_no = gl_bd->user_disk_0_unit_no; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: request made to disk 0 " - "for sector=%d, num_sectors=%d, unit_no=%d\n", - __func__, req_sector, (int) blk_rq_sectors(req), - lcl_unit_no); - #endif - } else if (req->rq_disk == bd->user_disk_1) { - bus_num = bd->user_disk_1_bus_num; - req_sector = blk_rq_pos(req) + gl_bd->user_disk_1_first_sector; - /*SECT_NUM_TRANSLATE(blk_rq_sectors(req));*/ - req_nr_sectors = blk_rq_sectors(req); - lcl_unit_no = gl_bd->user_disk_1_unit_no; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: request made to disk 1 for " - "sector=%d, num_sectors=%d, unit_no=%d\n", __func__, - req_sector, (int) blk_rq_sectors(req), lcl_unit_no); - #endif - } else if (req->rq_disk == bd->system_disk) { - bus_num = bd->system_disk_bus_num; - req_sector = blk_rq_pos(req) + gl_bd->system_disk_first_sector; - req_nr_sectors = blk_rq_sectors(req); - lcl_unit_no = gl_bd->system_disk_unit_no; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: request made to system disk " - "for sector=%d, num_sectors=%d, unit_no=%d\n", __func__, - req_sector, (int) blk_rq_sectors(req), lcl_unit_no); - #endif - } - #ifndef WESTBRIDGE_NDEBUG - else { - cy_as_hal_print_message( - "%s: invalid disk used for request\n", __func__); - } - #endif - - spin_unlock_irq(&bd->lock); - - if (rq_data_dir(req) == READ) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: calling readasync() " - "req_sector=0x%x, req_nr_sectors=0x%x, bd->sg:%x\n\n", - __func__, req_sector, req_nr_sectors, (uint32_t)bd->sg); - #endif - - ret = cy_as_storage_read_async(bd->dev_handle, bus_num, 0, - lcl_unit_no, req_sector, bd->sg, req_nr_sectors, - (cy_as_storage_callback)cyasblkdev_issuecallback); - - if (ret != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s:readasync() error %d at " - "address %ld, unit no %d\n", __func__, ret, - blk_rq_pos(req), lcl_unit_no); - cy_as_hal_print_message("%s:ending i/o request " - "on reg:%x\n", __func__, (uint32_t)req); - #endif - - while (blk_end_request(req, - (ret == CY_AS_ERROR_SUCCESS), - req_nr_sectors*512)) - ; - - bq->req = NULL; - } - } else { - ret = cy_as_storage_write_async(bd->dev_handle, bus_num, 0, - lcl_unit_no, req_sector, bd->sg, req_nr_sectors, - (cy_as_storage_callback)cyasblkdev_issuecallback); - - if (ret != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: write failed with " - "error %d at address %ld, unit no %d\n", - __func__, ret, blk_rq_pos(req), lcl_unit_no); - #endif - - /*end IO op on this request(does both - * end_that_request_... _first & _last) */ - while (blk_end_request(req, - (ret == CY_AS_ERROR_SUCCESS), - req_nr_sectors*512)) - ; - - bq->req = NULL; - } - } - - return ret; -} - -static unsigned long -dev_use[CYASBLKDEV_NUM_MINORS / (8 * sizeof(unsigned long))]; - - -/* storage event callback (note: called in astoria isr context) */ -static void cyasblkdev_storage_callback( - cy_as_device_handle dev_h, - cy_as_bus_number_t bus, - uint32_t device, - cy_as_storage_event evtype, - void *evdata - ) -{ - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: bus:%d, device:%d, evtype:%d, " - "evdata:%p\n ", __func__, bus, device, evtype, evdata); - #endif - - switch (evtype) { - case cy_as_storage_processor: - break; - - case cy_as_storage_removed: - break; - - case cy_as_storage_inserted: - break; - - default: - break; - } -} - -#define SECTORS_TO_SCAN 4096 - -uint32_t cyasblkdev_get_vfat_offset(int bus_num, int unit_no) -{ - /* - * for sd media, vfat partition boot record is not always - * located at sector it greatly depends on the system and - * software that was used to format the sd however, linux - * fs layer always expects it at sector 0, this function - * finds the offset and then uses it in all media r/w - * operations - */ - int sect_no, stat; - uint8_t *sect_buf; - bool br_found = false; - - DBGPRN_FUNC_NAME; - - sect_buf = kmalloc(1024, GFP_KERNEL); - - /* since HAL layer always uses sg lists instead of the - * buffer (for hw dmas) we need to initialize the sg list - * for local buffer*/ - sg_init_one(gl_bd->sg, sect_buf, 512); - - /* - * Check MPR partition table 1st, then try to scan through - * 1st 384 sectors until BR signature(intel JMP istruction - * code and ,0x55AA) is found - */ - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s scanning media for vfat partition...\n", __func__); - #endif - - for (sect_no = 0; sect_no < SECTORS_TO_SCAN; sect_no++) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s before cyasstorageread " - "gl_bd->sg addr=0x%x\n", __func__, - (unsigned int) gl_bd->sg); - #endif - - stat = cy_as_storage_read( - /* Handle to the device of interest */ - gl_bd->dev_handle, - /* The bus to access */ - bus_num, - /* The device to access */ - 0, - /* The unit to access */ - unit_no, - /* absolute sector number */ - sect_no, - /* sg structure */ - gl_bd->sg, - /* The number of blocks to be read */ - 1 - ); - - /* try only sectors with boot signature */ - if ((sect_buf[510] == 0x55) && (sect_buf[511] == 0xaa)) { - /* vfat boot record may also be located at - * sector 0, check it first */ - if (sect_buf[0] == 0xEB) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s vfat partition found " - "at sector:%d\n", - __func__, sect_no); - #endif - - br_found = true; - break; - } - } - - if (stat != 0) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s sector scan error\n", - __func__); - #endif - break; - } - } - - kfree(sect_buf); - - if (br_found) { - return sect_no; - } else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s vfat partition is not found, using 0 offset\n", - __func__); - #endif - return 0; - } -} - -cy_as_storage_query_device_data dev_data = {0}; - -static int cyasblkdev_add_disks(int bus_num, - struct cyasblkdev_blk_data *bd, - int total_media_count, - int devidx) -{ - int ret = 0; - uint64_t disk_cap; - int lcl_unit_no; - cy_as_storage_query_unit_data unit_data = {0}; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s:query device: " - "type:%d, removable:%d, writable:%d, " - "blksize %d, units:%d, locked:%d, " - "erase_sz:%d\n", - __func__, - dev_data.desc_p.type, - dev_data.desc_p.removable, - dev_data.desc_p.writeable, - dev_data.desc_p.block_size, - dev_data.desc_p.number_units, - dev_data.desc_p.locked, - dev_data.desc_p.erase_unit_size - ); - #endif - - /* make sure that device is not locked */ - if (dev_data.desc_p.locked) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: device is locked\n", __func__); - #endif - ret = cy_as_storage_release( - bd->dev_handle, bus_num, 0, 0, 0); - if (ret != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s cannot release" - " storage\n", __func__); - #endif - goto out; - } - goto out; - } - - unit_data.device = 0; - unit_data.unit = 0; - unit_data.bus = bus_num; - ret = cy_as_storage_query_unit(bd->dev_handle, - &unit_data, 0, 0); - if (ret != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: cannot query " - "%d device unit - reason code %d\n", - __func__, bus_num, ret); - #endif - goto out; - } - - if (private_partition_bus == bus_num) { - if (private_partition_size > 0) { - ret = cy_as_storage_create_p_partition( - bd->dev_handle, bus_num, 0, - private_partition_size, 0, 0); - if ((ret != CY_AS_ERROR_SUCCESS) && - (ret != CY_AS_ERROR_ALREADY_PARTITIONED)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: cy_as_storage_" - "create_p_partition after size > 0 check " - "failed with error code %d\n", - __func__, ret); - #endif - - disk_cap = (uint64_t) - (unit_data.desc_p.unit_size); - lcl_unit_no = 0; - - } else if (ret == CY_AS_ERROR_ALREADY_PARTITIONED) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: cy_as_storage_create_p_partition " - "indicates memory already partitioned\n", - __func__); - #endif - - /*check to see that partition - * matches size */ - if (unit_data.desc_p.unit_size != - private_partition_size) { - ret = cy_as_storage_remove_p_partition( - bd->dev_handle, - bus_num, 0, 0, 0); - if (ret == CY_AS_ERROR_SUCCESS) { - ret = cy_as_storage_create_p_partition( - bd->dev_handle, bus_num, 0, - private_partition_size, 0, 0); - if (ret == CY_AS_ERROR_SUCCESS) { - unit_data.bus = bus_num; - unit_data.device = 0; - unit_data.unit = 1; - } else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: cy_as_storage_create_p_partition " - "after removal unexpectedly failed " - "with error %d\n", __func__, ret); - #endif - - /* need to requery bus - * seeing as delete - * successful and create - * failed we have changed - * the disk properties */ - unit_data.bus = bus_num; - unit_data.device = 0; - unit_data.unit = 0; - } - - ret = cy_as_storage_query_unit( - bd->dev_handle, - &unit_data, 0, 0); - if (ret != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: cannot query %d " - "device unit - reason code %d\n", - __func__, bus_num, ret); - #endif - goto out; - } else { - disk_cap = (uint64_t) - (unit_data.desc_p.unit_size); - lcl_unit_no = - unit_data.unit; - } - } else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: cy_as_storage_remove_p_partition " - "failed with error %d\n", - __func__, ret); - #endif - - unit_data.bus = bus_num; - unit_data.device = 0; - unit_data.unit = 1; - - ret = cy_as_storage_query_unit( - bd->dev_handle, &unit_data, 0, 0); - if (ret != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: cannot query %d " - "device unit - reason " - "code %d\n", __func__, - bus_num, ret); - #endif - goto out; - } - - disk_cap = (uint64_t) - (unit_data.desc_p.unit_size); - lcl_unit_no = - unit_data.unit; - } - } else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: partition " - "exists and sizes equal\n", - __func__); - #endif - - /*partition already existed, - * need to query second unit*/ - unit_data.bus = bus_num; - unit_data.device = 0; - unit_data.unit = 1; - - ret = cy_as_storage_query_unit( - bd->dev_handle, &unit_data, 0, 0); - if (ret != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: cannot query %d " - "device unit " - "- reason code %d\n", - __func__, bus_num, ret); - #endif - goto out; - } else { - disk_cap = (uint64_t) - (unit_data.desc_p.unit_size); - lcl_unit_no = unit_data.unit; - } - } - } else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: cy_as_storage_create_p_partition " - "created successfully\n", __func__); - #endif - - disk_cap = (uint64_t) - (unit_data.desc_p.unit_size - - private_partition_size); - - lcl_unit_no = 1; - } - } - #ifndef WESTBRIDGE_NDEBUG - else { - cy_as_hal_print_message( - "%s: invalid partition_size%d\n", __func__, - private_partition_size); - - disk_cap = (uint64_t) - (unit_data.desc_p.unit_size); - lcl_unit_no = 0; - } - #endif - } else { - disk_cap = (uint64_t) - (unit_data.desc_p.unit_size); - lcl_unit_no = 0; - } - - if ((bus_num == 0) || - (total_media_count == 1)) { - sprintf(bd->user_disk_0->disk_name, - "cyasblkdevblk%d", devidx); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: disk unit_sz:%lu blk_sz:%d, " - "start_blk:%lu, capacity:%llu\n", - __func__, (unsigned long) - unit_data.desc_p.unit_size, - unit_data.desc_p.block_size, - (unsigned long) - unit_data.desc_p.start_block, - (uint64_t)disk_cap - ); - #endif - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: setting gendisk disk " - "capacity to %d\n", __func__, (int) disk_cap); - #endif - - /* initializing bd->queue */ - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: init bd->queue\n", - __func__); - #endif - - /* this will create a - * queue kernel thread */ - cyasblkdev_init_queue( - &bd->queue, &bd->lock); - - bd->queue.prep_fn = cyasblkdev_blk_prep_rq; - bd->queue.issue_fn = cyasblkdev_blk_issue_rq; - bd->queue.data = bd; - - /*blk_size should always - * be a multiple of 512, - * set to the max to ensure - * that all accesses aligned - * to the greatest multiple, - * can adjust request to - * smaller block sizes - * dynamically*/ - - bd->user_disk_0_read_only = !dev_data.desc_p.writeable; - bd->user_disk_0_blk_size = dev_data.desc_p.block_size; - bd->user_disk_0_type = dev_data.desc_p.type; - bd->user_disk_0_bus_num = bus_num; - bd->user_disk_0->major = major; - bd->user_disk_0->first_minor = devidx << CYASBLKDEV_SHIFT; - bd->user_disk_0->minors = 8; - bd->user_disk_0->fops = &cyasblkdev_bdops; - bd->user_disk_0->events = DISK_EVENT_MEDIA_CHANGE; - bd->user_disk_0->private_data = bd; - bd->user_disk_0->queue = bd->queue.queue; - bd->dbgprn_flags = DBGPRN_RD_RQ; - bd->user_disk_0_unit_no = lcl_unit_no; - - blk_queue_logical_block_size(bd->queue.queue, - bd->user_disk_0_blk_size); - - set_capacity(bd->user_disk_0, - disk_cap); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: returned from set_capacity %d\n", - __func__, (int) disk_cap); - #endif - - /* need to start search from - * public partition beginning */ - if (vfat_search) { - bd->user_disk_0_first_sector = - cyasblkdev_get_vfat_offset( - bd->user_disk_0_bus_num, - bd->user_disk_0_unit_no); - } else { - bd->user_disk_0_first_sector = 0; - } - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: set user_disk_0_first " - "sector to %d\n", __func__, - bd->user_disk_0_first_sector); - cy_as_hal_print_message( - "%s: add_disk: disk->major=0x%x\n", - __func__, - bd->user_disk_0->major); - cy_as_hal_print_message( - "%s: add_disk: " - "disk->first_minor=0x%x\n", __func__, - bd->user_disk_0->first_minor); - cy_as_hal_print_message( - "%s: add_disk: " - "disk->minors=0x%x\n", __func__, - bd->user_disk_0->minors); - cy_as_hal_print_message( - "%s: add_disk: " - "disk->disk_name=%s\n", - __func__, - bd->user_disk_0->disk_name); - cy_as_hal_print_message( - "%s: add_disk: " - "disk->part_tbl=0x%x\n", __func__, - (unsigned int) - bd->user_disk_0->part_tbl); - cy_as_hal_print_message( - "%s: add_disk: " - "disk->queue=0x%x\n", __func__, - (unsigned int) - bd->user_disk_0->queue); - cy_as_hal_print_message( - "%s: add_disk: " - "disk->flags=0x%x\n", - __func__, (unsigned int) - bd->user_disk_0->flags); - cy_as_hal_print_message( - "%s: add_disk: " - "disk->driverfs_dev=0x%x\n", - __func__, (unsigned int) - bd->user_disk_0->driverfs_dev); - cy_as_hal_print_message( - "%s: add_disk: " - "disk->slave_dir=0x%x\n", - __func__, (unsigned int) - bd->user_disk_0->slave_dir); - cy_as_hal_print_message( - "%s: add_disk: " - "disk->random=0x%x\n", - __func__, (unsigned int) - bd->user_disk_0->random); - cy_as_hal_print_message( - "%s: add_disk: " - "disk->node_id=0x%x\n", - __func__, (unsigned int) - bd->user_disk_0->node_id); - - #endif - - add_disk(bd->user_disk_0); - - } else if ((bus_num == 1) && - (total_media_count == 2)) { - bd->user_disk_1_read_only = !dev_data.desc_p.writeable; - bd->user_disk_1_blk_size = dev_data.desc_p.block_size; - bd->user_disk_1_type = dev_data.desc_p.type; - bd->user_disk_1_bus_num = bus_num; - bd->user_disk_1->major = major; - bd->user_disk_1->first_minor = (devidx + 1) << CYASBLKDEV_SHIFT; - bd->user_disk_1->minors = 8; - bd->user_disk_1->fops = &cyasblkdev_bdops; - bd->user_disk_1->events = DISK_EVENT_MEDIA_CHANGE; - bd->user_disk_1->private_data = bd; - bd->user_disk_1->queue = bd->queue.queue; - bd->dbgprn_flags = DBGPRN_RD_RQ; - bd->user_disk_1_unit_no = lcl_unit_no; - - sprintf(bd->user_disk_1->disk_name, - "cyasblkdevblk%d", (devidx + 1)); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: disk unit_sz:%lu " - "blk_sz:%d, " - "start_blk:%lu, " - "capacity:%llu\n", - __func__, - (unsigned long) - unit_data.desc_p.unit_size, - unit_data.desc_p.block_size, - (unsigned long) - unit_data.desc_p.start_block, - (uint64_t)disk_cap - ); - #endif - - /*blk_size should always be a - * multiple of 512, set to the max - * to ensure that all accesses - * aligned to the greatest multiple, - * can adjust request to smaller - * block sizes dynamically*/ - if (bd->user_disk_0_blk_size > - bd->user_disk_1_blk_size) { - blk_queue_logical_block_size(bd->queue.queue, - bd->user_disk_0_blk_size); - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: set hard sect_sz:%d\n", - __func__, - bd->user_disk_0_blk_size); - #endif - } else { - blk_queue_logical_block_size(bd->queue.queue, - bd->user_disk_1_blk_size); - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: set hard sect_sz:%d\n", - __func__, - bd->user_disk_1_blk_size); - #endif - } - - set_capacity(bd->user_disk_1, disk_cap); - if (vfat_search) { - bd->user_disk_1_first_sector = - cyasblkdev_get_vfat_offset( - bd->user_disk_1_bus_num, - bd->user_disk_1_unit_no); - } else { - bd->user_disk_1_first_sector - = 0; - } - - add_disk(bd->user_disk_1); - } - - if (lcl_unit_no > 0) { - if (bd->system_disk == NULL) { - bd->system_disk = - alloc_disk(8); - - if (bd->system_disk == NULL) { - kfree(bd); - bd = ERR_PTR(-ENOMEM); - return bd; - } - disk_cap = (uint64_t) - (private_partition_size); - - /* set properties of - * system disk */ - bd->system_disk_read_only = !dev_data.desc_p.writeable; - bd->system_disk_blk_size = dev_data.desc_p.block_size; - bd->system_disk_bus_num = bus_num; - bd->system_disk->major = major; - bd->system_disk->first_minor = - (devidx + 2) << CYASBLKDEV_SHIFT; - bd->system_disk->minors = 8; - bd->system_disk->fops = &cyasblkdev_bdops; - bd->system_disk->events = DISK_EVENT_MEDIA_CHANGE; - bd->system_disk->private_data = bd; - bd->system_disk->queue = bd->queue.queue; - /* don't search for vfat - * with system disk */ - bd->system_disk_first_sector = 0; - sprintf( - bd->system_disk->disk_name, - "cyasblkdevblk%d", (devidx + 2)); - - set_capacity(bd->system_disk, - disk_cap); - - add_disk(bd->system_disk); - } - #ifndef WESTBRIDGE_NDEBUG - else { - cy_as_hal_print_message( - "%s: system disk already allocated %d\n", - __func__, bus_num); - } - #endif - } -out: - return ret; -} - -static struct cyasblkdev_blk_data *cyasblkdev_blk_alloc(void) -{ - struct cyasblkdev_blk_data *bd; - int ret = 0; - cy_as_return_status_t stat = -1; - int bus_num = 0; - int total_media_count = 0; - int devidx = 0; - DBGPRN_FUNC_NAME; - - total_media_count = 0; - devidx = find_first_zero_bit(dev_use, CYASBLKDEV_NUM_MINORS); - if (devidx >= CYASBLKDEV_NUM_MINORS) - return ERR_PTR(-ENOSPC); - - __set_bit(devidx, dev_use); - __set_bit(devidx + 1, dev_use); - - bd = kzalloc(sizeof(struct cyasblkdev_blk_data), GFP_KERNEL); - if (bd) { - gl_bd = bd; - - spin_lock_init(&bd->lock); - bd->usage = 1; - - /* setup the block_dev_ops pointer*/ - bd->blkops = &cyasblkdev_bdops; - - /* Get the device handle */ - bd->dev_handle = cyasdevice_getdevhandle(); - if (0 == bd->dev_handle) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: get device failed\n", __func__); - #endif - ret = ENODEV; - goto out; - } - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s west bridge device handle:%x\n", - __func__, (uint32_t)bd->dev_handle); - #endif - - /* start the storage api and get a handle to the - * device we are interested in. */ - - /* Error code to use if the conditions are not satisfied. */ - ret = ENOMEDIUM; - - stat = cy_as_misc_release_resource(bd->dev_handle, cy_as_bus_0); - if ((stat != CY_AS_ERROR_SUCCESS) && - (stat != CY_AS_ERROR_RESOURCE_NOT_OWNED)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: cannot release " - "resource bus 0 - reason code %d\n", - __func__, stat); - #endif - } - - stat = cy_as_misc_release_resource(bd->dev_handle, cy_as_bus_1); - if ((stat != CY_AS_ERROR_SUCCESS) && - (stat != CY_AS_ERROR_RESOURCE_NOT_OWNED)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: cannot release " - "resource bus 0 - reason code %d\n", - __func__, stat); - #endif - } - - /* start storage stack*/ - stat = cy_as_storage_start(bd->dev_handle, 0, 0x101); - if (stat != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: cannot start storage " - "stack - reason code %d\n", __func__, stat); - #endif - goto out; - } - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: storage started:%d ok\n", - __func__, stat); - #endif - - stat = cy_as_storage_register_callback(bd->dev_handle, - cyasblkdev_storage_callback); - if (stat != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: cannot register callback " - "- reason code %d\n", __func__, stat); - #endif - goto out; - } - - for (bus_num = 0; bus_num < 2; bus_num++) { - stat = cy_as_storage_query_bus(bd->dev_handle, - bus_num, &bd->media_count[bus_num], 0, 0); - if (stat == CY_AS_ERROR_SUCCESS) { - total_media_count = total_media_count + - bd->media_count[bus_num]; - } else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: cannot query %d, " - "reason code: %d\n", - __func__, bus_num, stat); - #endif - goto out; - } - } - - if (total_media_count == 0) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: no storage media was found\n", __func__); - #endif - goto out; - } else if (total_media_count >= 1) { - if (bd->user_disk_0 == NULL) { - - bd->user_disk_0 = - alloc_disk(8); - if (bd->user_disk_0 == NULL) { - kfree(bd); - bd = ERR_PTR(-ENOMEM); - return bd; - } - } - #ifndef WESTBRIDGE_NDEBUG - else { - cy_as_hal_print_message("%s: no available " - "gen_disk for disk 0, " - "physically inconsistent\n", __func__); - } - #endif - } - - if (total_media_count == 2) { - if (bd->user_disk_1 == NULL) { - bd->user_disk_1 = - alloc_disk(8); - if (bd->user_disk_1 == NULL) { - kfree(bd); - bd = ERR_PTR(-ENOMEM); - return bd; - } - } - #ifndef WESTBRIDGE_NDEBUG - else { - cy_as_hal_print_message("%s: no available " - "gen_disk for media, " - "physically inconsistent\n", __func__); - } - #endif - } - #ifndef WESTBRIDGE_NDEBUG - else if (total_media_count > 2) { - cy_as_hal_print_message("%s: count corrupted = 0x%d\n", - __func__, total_media_count); - } - #endif - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: %d device(s) found\n", - __func__, total_media_count); - #endif - - for (bus_num = 0; bus_num <= 1; bus_num++) { - /*claim storage for cpu */ - stat = cy_as_storage_claim(bd->dev_handle, - bus_num, 0, 0, 0); - if (stat != CY_AS_ERROR_SUCCESS) { - cy_as_hal_print_message("%s: cannot claim " - "%d bus - reason code %d\n", - __func__, bus_num, stat); - goto out; - } - - dev_data.bus = bus_num; - dev_data.device = 0; - - stat = cy_as_storage_query_device(bd->dev_handle, - &dev_data, 0, 0); - if (stat == CY_AS_ERROR_SUCCESS) { - cyasblkdev_add_disks(bus_num, bd, - total_media_count, devidx); - } else if (stat == CY_AS_ERROR_NO_SUCH_DEVICE) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: no device on bus %d\n", - __func__, bus_num); - #endif - } else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: cannot query %d device " - "- reason code %d\n", - __func__, bus_num, stat); - #endif - goto out; - } - } /* end for (bus_num = 0; bus_num <= 1; bus_num++)*/ - - return bd; - } -out: - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: bd failed to initialize\n", __func__); - #endif - - kfree(bd); - bd = ERR_PTR(-ret); - return bd; -} - - -/*init west bridge block device */ -static int cyasblkdev_blk_initialize(void) -{ - struct cyasblkdev_blk_data *bd; - int res; - - DBGPRN_FUNC_NAME; - - res = register_blkdev(major, "cyasblkdev"); - - if (res < 0) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message(KERN_WARNING - "%s unable to get major %d for cyasblkdev media: %d\n", - __func__, major, res); - #endif - return res; - } - - if (major == 0) - major = res; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s cyasblkdev registered with major number: %d\n", - __func__, major); - #endif - - bd = cyasblkdev_blk_alloc(); - if (IS_ERR(bd)) - return PTR_ERR(bd); - - return 0; -} - -/* start block device */ -static int __init cyasblkdev_blk_init(void) -{ - int res = -ENOMEM; - - DBGPRN_FUNC_NAME; - - /* get the cyasdev handle for future use*/ - cyas_dev_handle = cyasdevice_getdevhandle(); - - if (cyasblkdev_blk_initialize() == 0) - return 0; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("cyasblkdev init error:%d\n", res); - #endif - return res; -} - - -static void cyasblkdev_blk_deinit(struct cyasblkdev_blk_data *bd) -{ - DBGPRN_FUNC_NAME; - - if (bd) { - int devidx; - - if (bd->user_disk_0 != NULL) { - del_gendisk(bd->user_disk_0); - devidx = bd->user_disk_0->first_minor - >> CYASBLKDEV_SHIFT; - __clear_bit(devidx, dev_use); - } - - if (bd->user_disk_1 != NULL) { - del_gendisk(bd->user_disk_1); - devidx = bd->user_disk_1->first_minor - >> CYASBLKDEV_SHIFT; - __clear_bit(devidx, dev_use); - } - - if (bd->system_disk != NULL) { - del_gendisk(bd->system_disk); - devidx = bd->system_disk->first_minor - >> CYASBLKDEV_SHIFT; - __clear_bit(devidx, dev_use); - } - - cyasblkdev_blk_put(bd); - } -} - -/* block device exit */ -static void __exit cyasblkdev_blk_exit(void) -{ - DBGPRN_FUNC_NAME; - - cyasblkdev_blk_deinit(gl_bd); - unregister_blkdev(major, "cyasblkdev"); - -} - -module_init(cyasblkdev_blk_init); -module_exit(cyasblkdev_blk_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("antioch (cyasblkdev) block device driver"); -MODULE_AUTHOR("cypress semiconductor"); - -/*[]*/ diff --git a/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c b/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c deleted file mode 100644 index d1996a27515e..000000000000 --- a/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.c +++ /dev/null @@ -1,417 +0,0 @@ -/* cyanblkdev_queue.h - Antioch Linux Block Driver queue source file -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor, -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -/* - * Request queue handling for Antioch block device driver. - * Based on the mmc queue handling code by Russell King in the - * linux 2.6.10 kernel. - */ - -/* - * linux/drivers/mmc/mmc_queue.c - * - * Copyright (C) 2003 Russell King, 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 - * published by the Free Software Foundation. - * - */ - -#include -#include - -#include "cyasblkdev_queue.h" - -#define CYASBLKDEV_QUEUE_EXIT (1 << 0) -#define CYASBLKDEV_QUEUE_SUSPENDED (1 << 1) -#define CY_AS_USE_ASYNC_API - - - -/* print flags by name */ -const char *rq_flag_bit_names[] = { - "REQ_RW", /* not set, read. set, write */ - "REQ_FAILFAST", /* no low level driver retries */ - "REQ_SORTED", /* elevator knows about this request */ - "REQ_SOFTBARRIER", /* may not be passed by ioscheduler */ - "REQ_HARDBARRIER", /* may not be passed by drive either */ - "REQ_FUA", /* forced unit access */ - "REQ_NOMERGE", /* don't touch this for merging */ - "REQ_STARTED", /* drive already may have started this one */ - "REQ_DONTPREP", /* don't call prep for this one */ - "REQ_QUEUED", /* uses queueing */ - "REQ_ELVPRIV", /* elevator private data attached */ - "REQ_FAILED", /* set if the request failed */ - "REQ_QUIET", /* don't worry about errors */ - "REQ_PREEMPT", /* set for "ide_preempt" requests */ - "REQ_ORDERED_COLOR",/* is before or after barrier */ - "REQ_RW_SYNC", /* request is sync (O_DIRECT) */ - "REQ_ALLOCED", /* request came from our alloc pool */ - "REQ_RW_META", /* metadata io request */ - "REQ_COPY_USER", /* contains copies of user pages */ - "REQ_NR_BITS", /* stops here */ -}; - -void verbose_rq_flags(int flags) -{ - int i; - uint32_t j; - j = 1; - for (i = 0; i < 32; i++) { - if (flags & j) - DBGPRN("<1>%s", rq_flag_bit_names[i]); - j = j << 1; - } -} - - -/* - * Prepare a -BLK_DEV request. Essentially, this means passing the - * preparation off to the media driver. The media driver will - * create request to CyAsDev. - */ -static int cyasblkdev_prep_request( - struct request_queue *q, struct request *req) -{ - DBGPRN_FUNC_NAME; - - /* we only like normal block requests.*/ - if (req->cmd_type != REQ_TYPE_FS && !(req->cmd_flags & REQ_DISCARD)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s:%x bad request received\n", - __func__, current->pid); - #endif - - blk_dump_rq_flags(req, "cyasblkdev bad request"); - return BLKPREP_KILL; - } - - req->cmd_flags |= REQ_DONTPREP; - - return BLKPREP_OK; -} - -/* queue worker thread */ -static int cyasblkdev_queue_thread(void *d) -{ - DECLARE_WAITQUEUE(wait, current); - struct cyasblkdev_queue *bq = d; - struct request_queue *q = bq->queue; - u32 qth_pid; - - DBGPRN_FUNC_NAME; - - /* - * set iothread to ensure that we aren't put to sleep by - * the process freezing. we handle suspension ourselves. - */ - daemonize("cyasblkdev_queue_thread"); - - /* signal to queue_init() so it could contnue */ - complete(&bq->thread_complete); - - down(&bq->thread_sem); - add_wait_queue(&bq->thread_wq, &wait); - - qth_pid = current->pid; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s:%x started, bq:%p, q:%p\n", __func__, qth_pid, bq, q); - #endif - - do { - struct request *req = NULL; - - /* the thread wants to be woken up by signals as well */ - set_current_state(TASK_INTERRUPTIBLE); - - spin_lock_irq(q->queue_lock); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: for bq->queue is null\n", __func__); - #endif - - if (!bq->req) { - /* chk if queue is plugged */ - if (!blk_queue_plugged(q)) { - bq->req = req = blk_fetch_request(q); - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: blk_fetch_request:%x\n", - __func__, (uint32_t)req); - #endif - } else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: queue plugged, " - "skip blk_fetch()\n", __func__); - #endif - } - } - spin_unlock_irq(q->queue_lock); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: checking if request queue is null\n", __func__); - #endif - - if (!req) { - if (bq->flags & CYASBLKDEV_QUEUE_EXIT) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s:got QUEUE_EXIT flag\n", __func__); - #endif - - break; - } - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: request queue is null, goto sleep, " - "thread_sem->count=%d\n", - __func__, bq->thread_sem.count); - if (spin_is_locked(q->queue_lock)) { - cy_as_hal_print_message("%s: queue_lock " - "is locked, need to release\n", __func__); - spin_unlock(q->queue_lock); - - if (spin_is_locked(q->queue_lock)) - cy_as_hal_print_message( - "%s: unlock did not work\n", - __func__); - } else { - cy_as_hal_print_message( - "%s: checked lock, is not locked\n", - __func__); - } - #endif - - up(&bq->thread_sem); - - /* yields to the next rdytorun proc, - * then goes back to sleep*/ - schedule(); - down(&bq->thread_sem); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: wake_up,continue\n", - __func__); - #endif - continue; - } - - /* new req received, issue it to the driver */ - set_current_state(TASK_RUNNING); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: issued a RQ:%x\n", - __func__, (uint32_t)req); - #endif - - bq->issue_fn(bq, req); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: bq->issue_fn() returned\n", - __func__); - #endif - - - } while (1); - - set_current_state(TASK_RUNNING); - remove_wait_queue(&bq->thread_wq, &wait); - up(&bq->thread_sem); - - complete_and_exit(&bq->thread_complete, 0); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: is finished\n", __func__); - #endif - - return 0; -} - -/* - * Generic request handler. it is called for any queue on a - * particular host. When the host is not busy, we look for a request - * on any queue on this host, and attempt to issue it. This may - * not be the queue we were asked to process. - */ -static void cyasblkdev_request(struct request_queue *q) -{ - struct cyasblkdev_queue *bq = q->queuedata; - DBGPRN_FUNC_NAME; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s new request on cyasblkdev_queue_t bq:=%x\n", - __func__, (uint32_t)bq); - #endif - - if (!bq->req) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s wake_up(&bq->thread_wq)\n", - __func__); - #endif - - /* wake up cyasblkdev_queue worker thread*/ - wake_up(&bq->thread_wq); - } else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: don't wake Q_thr, bq->req:%x\n", - __func__, (uint32_t)bq->req); - #endif - } -} - -/* - * cyasblkdev_init_queue - initialise a queue structure. - * @bq: cyasblkdev queue - * @dev: CyAsDeviceHandle to attach this queue - * @lock: queue lock - * - * Initialise a cyasblkdev_request queue. - */ - -/* MAX NUMBER OF SECTORS PER REQUEST **/ -#define Q_MAX_SECTORS 128 - -/* MAX NUMBER OF PHYS SEGMENTS (entries in the SG list)*/ -#define Q_MAX_SGS 16 - -int cyasblkdev_init_queue(struct cyasblkdev_queue *bq, spinlock_t *lock) -{ - int ret; - - DBGPRN_FUNC_NAME; - - /* 1st param is a function that wakes up the queue thread */ - bq->queue = blk_init_queue(cyasblkdev_request, lock); - if (!bq->queue) - return -ENOMEM; - - blk_queue_prep_rq(bq->queue, cyasblkdev_prep_request); - - blk_queue_bounce_limit(bq->queue, BLK_BOUNCE_ANY); - blk_queue_max_hw_sectors(bq->queue, Q_MAX_SECTORS); - - /* As of now, we have the HAL/driver support to - * merge scattered segments and handle them simultaneously. - * so, setting the max_phys_segments to 8. */ - /*blk_queue_max_phys_segments(bq->queue, Q_MAX_SGS); - blk_queue_max_hw_segments(bq->queue, Q_MAX_SGS);*/ - blk_queue_max_segments(bq->queue, Q_MAX_SGS); - - /* should be < then HAL can handle */ - blk_queue_max_segment_size(bq->queue, 512*Q_MAX_SECTORS); - - bq->queue->queuedata = bq; - bq->req = NULL; - - init_completion(&bq->thread_complete); - init_waitqueue_head(&bq->thread_wq); - sema_init(&bq->thread_sem, 1); - - ret = kernel_thread(cyasblkdev_queue_thread, bq, CLONE_KERNEL); - if (ret >= 0) { - /* wait until the thread is spawned */ - wait_for_completion(&bq->thread_complete); - - /* reinitialize the completion */ - init_completion(&bq->thread_complete); - ret = 0; - goto out; - } - -out: - return ret; -} -EXPORT_SYMBOL(cyasblkdev_init_queue); - -/*called from blk_put() */ -void cyasblkdev_cleanup_queue(struct cyasblkdev_queue *bq) -{ - DBGPRN_FUNC_NAME; - - bq->flags |= CYASBLKDEV_QUEUE_EXIT; - wake_up(&bq->thread_wq); - wait_for_completion(&bq->thread_complete); - - blk_cleanup_queue(bq->queue); -} -EXPORT_SYMBOL(cyasblkdev_cleanup_queue); - - -/** - * cyasblkdev_queue_suspend - suspend a CyAsBlkDev request queue - * @bq: CyAsBlkDev queue to suspend - * - * Stop the block request queue, and wait for our thread to - * complete any outstanding requests. This ensures that we - * won't suspend while a request is being processed. - */ -void cyasblkdev_queue_suspend(struct cyasblkdev_queue *bq) -{ - struct request_queue *q = bq->queue; - unsigned long flags; - - DBGPRN_FUNC_NAME; - - if (!(bq->flags & CYASBLKDEV_QUEUE_SUSPENDED)) { - bq->flags |= CYASBLKDEV_QUEUE_SUSPENDED; - - spin_lock_irqsave(q->queue_lock, flags); - blk_stop_queue(q); - spin_unlock_irqrestore(q->queue_lock, flags); - - down(&bq->thread_sem); - } -} -EXPORT_SYMBOL(cyasblkdev_queue_suspend); - -/*cyasblkdev_queue_resume - resume a previously suspended - * CyAsBlkDev request queue @bq: CyAsBlkDev queue to resume */ -void cyasblkdev_queue_resume(struct cyasblkdev_queue *bq) -{ - struct request_queue *q = bq->queue; - unsigned long flags; - - DBGPRN_FUNC_NAME; - - if (bq->flags & CYASBLKDEV_QUEUE_SUSPENDED) { - bq->flags &= ~CYASBLKDEV_QUEUE_SUSPENDED; - - up(&bq->thread_sem); - - spin_lock_irqsave(q->queue_lock, flags); - blk_start_queue(q); - spin_unlock_irqrestore(q->queue_lock, flags); - } -} -EXPORT_SYMBOL(cyasblkdev_queue_resume); - -/*[]*/ diff --git a/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.h b/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.h deleted file mode 100644 index 51cba6ae6718..000000000000 --- a/drivers/staging/westbridge/astoria/block/cyasblkdev_queue.h +++ /dev/null @@ -1,64 +0,0 @@ -/* cyanblkdev_queue.h - Antioch Linux Block Driver queue header file -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYANBLKDEV_QUEUE_H_ -#define _INCLUDED_CYANBLKDEV_QUEUE_H_ - -/* - * may contain various useful MACRO and debug printks - */ - -/* moved to staging location, eventual implementation - * considered is here - * #include - * #include - * */ - -#include "../include/linux/westbridge/cyashal.h" -#include "../include/linux/westbridge/cyastoria.h" - -struct request; -struct task_struct; - -struct cyasblkdev_queue { - struct completion thread_complete; - wait_queue_head_t thread_wq; - struct semaphore thread_sem; - unsigned int flags; - struct request *req; - int (*prep_fn)(struct cyasblkdev_queue *, struct request *); - int (*issue_fn)(struct cyasblkdev_queue *, struct request *); - void *data; - struct request_queue *queue; -}; - -extern int cyasblkdev_init_queue(struct cyasblkdev_queue *, spinlock_t *); -extern void cyasblkdev_cleanup_queue(struct cyasblkdev_queue *); -extern void cyasblkdev_queue_suspend(struct cyasblkdev_queue *); -extern void cyasblkdev_queue_resume(struct cyasblkdev_queue *); - -extern cy_as_device_handle cyasdevice_getdevhandle(void); -#define MOD_LOGS 1 -void verbose_rq_flags(int flags); - -#endif /* _INCLUDED_CYANBLKDEV_QUEUE_H_ */ - -/*[]*/ diff --git a/drivers/staging/westbridge/astoria/device/Kconfig b/drivers/staging/westbridge/astoria/device/Kconfig deleted file mode 100644 index cc99658cf3a4..000000000000 --- a/drivers/staging/westbridge/astoria/device/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# -# West Bridge block driver configuration -# - -config WESTBRIDGE_DEVICE_DRIVER - tristate "West Bridge Device Driver" - help - Include the West Bridge based device driver - diff --git a/drivers/staging/westbridge/astoria/device/Makefile b/drivers/staging/westbridge/astoria/device/Makefile deleted file mode 100644 index 7af8b5b0a8f5..000000000000 --- a/drivers/staging/westbridge/astoria/device/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Makefile for the kernel westbridge device driver -# - -ifneq ($(CONFIG_WESTBRIDGE_DEBUG),y) - EXTRA_CFLAGS += -DWESTBRIDGE_NDEBUG -endif - -obj-$(CONFIG_WESTBRIDGE_DEVICE_DRIVER) += cyasdev.o - - -ifeq ($(CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL),y) -#moved for staging compatbility -#cyasdev-y := ../../../arch/arm/mach-omap2/cyashalomap_kernel.o cyasdevice.o -cyasdev-y := ../arch/arm/mach-omap2/cyashalomap_kernel.o cyasdevice.o \ - ../api/src/cyasdma.o ../api/src/cyasintr.o ../api/src/cyaslep2pep.o \ - ../api/src/cyaslowlevel.o ../api/src/cyasmisc.o ../api/src/cyasmtp.o \ - ../api/src/cyasstorage.o ../api/src/cyasusb.o - -else -# should not get here, need to be built with some hal -cyasdev-y := cyasdevice.o -endif diff --git a/drivers/staging/westbridge/astoria/device/cyasdevice.c b/drivers/staging/westbridge/astoria/device/cyasdevice.c deleted file mode 100644 index 7de35ccffd32..000000000000 --- a/drivers/staging/westbridge/astoria/device/cyasdevice.c +++ /dev/null @@ -1,409 +0,0 @@ -/* -## cyandevice.c - Linux Antioch device driver file -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* moved for staging location - * update/patch submission -#include -#include -#include -*/ - -#include "../include/linux/westbridge/cyastoria.h" -#include "../include/linux/westbridge/cyashal.h" -#include "../include/linux/westbridge/cyasregs.h" - -typedef struct cyasdevice { - /* Handle to the Antioch device */ - cy_as_device_handle dev_handle; - /* Handle to the HAL */ - cy_as_hal_device_tag hal_tag; - spinlock_t common_lock; - unsigned long flags; -} cyasdevice; - -/* global ptr to astoria device */ -static cyasdevice *cy_as_device_controller; -int cy_as_device_init_done; -const char *dev_handle_name = "cy_astoria_dev_handle"; - -#ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL -extern void cy_as_hal_config_c_s_mux(void); -#endif - -static void cyasdevice_deinit(cyasdevice *cy_as_dev) -{ - cy_as_hal_print_message("<1>_cy_as_device deinitialize called\n"); - if (!cy_as_dev) { - cy_as_hal_print_message("<1>_cy_as_device_deinit: " - "device handle %x is invalid\n", (uint32_t)cy_as_dev); - return; - } - - /* stop west_brige */ - if (cy_as_dev->dev_handle) { - cy_as_hal_print_message("<1>_cy_as_device: " - "cy_as_misc_destroy_device called\n"); - if (cy_as_misc_destroy_device(cy_as_dev->dev_handle) != - CY_AS_ERROR_SUCCESS) { - cy_as_hal_print_message( - "<1>_cy_as_device: destroying failed\n"); - } - } - - if (cy_as_dev->hal_tag) { - - #ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL - if (stop_o_m_a_p_kernel(dev_handle_name, - cy_as_dev->hal_tag) != 0) - cy_as_hal_print_message("<1>_cy_as_device: stopping " - "OMAP kernel HAL failed\n"); - - #endif - } - cy_as_hal_print_message("<1>_cy_as_device:HAL layer stopped\n"); - - kfree(cy_as_dev); - cy_as_device_controller = NULL; - cy_as_hal_print_message("<1>_cy_as_device: deinitialized\n"); -} - -/*called from src/cyasmisc.c:MyMiscCallback() as a func - * pointer [dev_p->misc_event_cb] which was previously - * registered by CyAsLLRegisterRequestCallback(..., - * MyMiscCallback); called from CyAsMiscConfigureDevice() - * which is in turn called from cyasdevice_initialize() in - * this src - */ -static void cy_misc_callback(cy_as_device_handle h, - cy_as_misc_event_type evtype, void *evdata) -{ - (void)h; - (void)evdata; - - switch (evtype) { - case cy_as_event_misc_initialized: - cy_as_hal_print_message("<1>_cy_as_device: " - "initialization done callback triggered\n"); - cy_as_device_init_done = 1; - break; - - case cy_as_event_misc_awake: - cy_as_hal_print_message("<1>_cy_as_device: " - "cy_as_event_misc_awake event callback triggered\n"); - cy_as_device_init_done = 1; - break; - default: - break; - } -} - -void cy_as_acquire_common_lock() -{ - spin_lock_irqsave(&cy_as_device_controller->common_lock, - cy_as_device_controller->flags); -} -EXPORT_SYMBOL(cy_as_acquire_common_lock); - -void cy_as_release_common_lock() -{ - spin_unlock_irqrestore(&cy_as_device_controller->common_lock, - cy_as_device_controller->flags); -} -EXPORT_SYMBOL(cy_as_release_common_lock); - -/* reset astoria and reinit all regs */ - #define PNAND_REG_CFG_INIT_VAL 0x0000 -void hal_reset(cy_as_hal_device_tag tag) -{ - cy_as_hal_print_message("<1> send soft hard rst: " - "MEM_RST_CTRL_REG_HARD...\n"); - cy_as_hal_write_register(tag, CY_AS_MEM_RST_CTRL_REG, - CY_AS_MEM_RST_CTRL_REG_HARD); - mdelay(60); - - cy_as_hal_print_message("<1> after RST: si_rev_REG:%x, " - "PNANDCFG_reg:%x\n", - cy_as_hal_read_register(tag, CY_AS_MEM_CM_WB_CFG_ID), - cy_as_hal_read_register(tag, CY_AS_MEM_PNAND_CFG) - ); - - /* set it to LBD */ - cy_as_hal_write_register(tag, CY_AS_MEM_PNAND_CFG, - PNAND_REG_CFG_INIT_VAL); -} -EXPORT_SYMBOL(hal_reset); - - -/* below structures and functions primarily - * implemented for firmware loading */ -static struct platform_device *westbridge_pd; - -static int __devinit wb_probe(struct platform_device *devptr) -{ - cy_as_hal_print_message("%s called\n", __func__); - return 0; -} - -static int __devexit wb_remove(struct platform_device *devptr) -{ - cy_as_hal_print_message("%s called\n", __func__); - return 0; -} - -static struct platform_driver west_bridge_driver = { - .probe = wb_probe, - .remove = __devexit_p(wb_remove), - .driver = { - .name = "west_bridge_dev"}, -}; - -/* west bridge device driver main init */ -static int cyasdevice_initialize(void) -{ - cyasdevice *cy_as_dev = 0; - int ret = 0; - int retval = 0; - cy_as_device_config config; - cy_as_hal_sleep_channel channel; - cy_as_get_firmware_version_data ver_data = {0}; - const char *str = ""; - int spin_lim; - const struct firmware *fw_entry; - - cy_as_device_init_done = 0; - - cy_as_misc_set_log_level(8); - - cy_as_hal_print_message("<1>_cy_as_device initialize called\n"); - - if (cy_as_device_controller != 0) { - cy_as_hal_print_message("<1>_cy_as_device: the device " - "has already been initilaized. ignoring\n"); - return -EBUSY; - } - - /* cy_as_dev = CyAsHalAlloc (sizeof(cyasdevice), SLAB_KERNEL); */ - cy_as_dev = cy_as_hal_alloc(sizeof(cyasdevice)); - if (cy_as_dev == NULL) { - cy_as_hal_print_message("<1>_cy_as_device: " - "memory allocation failed\n"); - return -ENOMEM; - } - memset(cy_as_dev, 0, sizeof(cyasdevice)); - - - /* Init the HAL & CyAsDeviceHandle */ - - #ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL - /* start OMAP HAL init instsnce */ - - if (!start_o_m_a_p_kernel(dev_handle_name, - &(cy_as_dev->hal_tag), cy_false)) { - - cy_as_hal_print_message( - "<1>_cy_as_device: start OMAP34xx HAL failed\n"); - goto done; - } - #endif - - /* Now create the device */ - if (cy_as_misc_create_device(&(cy_as_dev->dev_handle), - cy_as_dev->hal_tag) != CY_AS_ERROR_SUCCESS) { - - cy_as_hal_print_message( - "<1>_cy_as_device: create device failed\n"); - goto done; - } - - memset(&config, 0, sizeof(config)); - config.dmaintr = cy_true; - - ret = cy_as_misc_configure_device(cy_as_dev->dev_handle, &config); - if (ret != CY_AS_ERROR_SUCCESS) { - - cy_as_hal_print_message( - "<1>_cy_as_device: configure device " - "failed. reason code: %d\n", ret); - goto done; - } - - ret = cy_as_misc_register_callback(cy_as_dev->dev_handle, - cy_misc_callback); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_hal_print_message("<1>_cy_as_device: " - "cy_as_misc_register_callback failed. " - "reason code: %d\n", ret); - goto done; - } - - ret = platform_driver_register(&west_bridge_driver); - if (unlikely(ret < 0)) - return ret; - westbridge_pd = platform_device_register_simple( - "west_bridge_dev", -1, NULL, 0); - - if (IS_ERR(westbridge_pd)) { - platform_driver_unregister(&west_bridge_driver); - return PTR_ERR(westbridge_pd); - } - /* Load the firmware */ - ret = request_firmware(&fw_entry, - "west bridge fw", &westbridge_pd->dev); - if (ret) { - cy_as_hal_print_message("cy_as_device: " - "request_firmware failed return val = %d\n", ret); - } else { - cy_as_hal_print_message("cy_as_device: " - "got the firmware %d size=0x%x\n", ret, fw_entry->size); - - ret = cy_as_misc_download_firmware( - cy_as_dev->dev_handle, - fw_entry->data, - fw_entry->size , - 0, 0); - } - - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_hal_print_message("<1>_cy_as_device: cannot download " - "firmware. reason code: %d\n", ret); - goto done; - } - - /* spin until the device init is completed */ - /* 50 -MAX wait time for the FW load & init - * to complete is 5sec*/ - spin_lim = 50; - - cy_as_hal_create_sleep_channel(&channel); - while (!cy_as_device_init_done) { - - cy_as_hal_sleep_on(&channel, 100); - - if (spin_lim-- <= 0) { - cy_as_hal_print_message( - "<1>\n_e_r_r_o_r!: " - "wait for FW init has timed out !!!"); - break; - } - } - cy_as_hal_destroy_sleep_channel(&channel); - - if (spin_lim > 0) - cy_as_hal_print_message( - "cy_as_device: astoria firmware is loaded\n"); - - ret = cy_as_misc_get_firmware_version(cy_as_dev->dev_handle, - &ver_data, 0, 0); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_hal_print_message("<1>_cy_as_device: cannot get firmware " - "version. reason code: %d\n", ret); - goto done; - } - - if ((ver_data.media_type & 0x01) && (ver_data.media_type & 0x06)) - str = "nand and SD/MMC."; - else if ((ver_data.media_type & 0x01) && (ver_data.media_type & 0x08)) - str = "nand and CEATA."; - else if (ver_data.media_type & 0x01) - str = "nand."; - else if (ver_data.media_type & 0x08) - str = "CEATA."; - else - str = "SD/MMC."; - - cy_as_hal_print_message("<1> cy_as_device:_firmware version: %s " - "major=%d minor=%d build=%d,\n_media types supported:%s\n", - ((ver_data.is_debug_mode) ? "debug" : "release"), - ver_data.major, ver_data.minor, ver_data.build, str); - - spin_lock_init(&cy_as_dev->common_lock); - - /* done now */ - cy_as_device_controller = cy_as_dev; - - return 0; - -done: - if (cy_as_dev) - cyasdevice_deinit(cy_as_dev); - - return -EINVAL; -} - -cy_as_device_handle cyasdevice_getdevhandle(void) -{ - if (cy_as_device_controller) { - #ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL - cy_as_hal_config_c_s_mux(); - #endif - - return cy_as_device_controller->dev_handle; - } - return NULL; -} -EXPORT_SYMBOL(cyasdevice_getdevhandle); - -cy_as_hal_device_tag cyasdevice_gethaltag(void) -{ - if (cy_as_device_controller) - return (cy_as_hal_device_tag) - cy_as_device_controller->hal_tag; - - return NULL; -} -EXPORT_SYMBOL(cyasdevice_gethaltag); - - -/*init Westbridge device driver **/ -static int __init cyasdevice_init(void) -{ - if (cyasdevice_initialize() != 0) - return -ENODEV; - - return 0; -} - - -static void __exit cyasdevice_cleanup(void) -{ - - cyasdevice_deinit(cy_as_device_controller); -} - - -MODULE_DESCRIPTION("west bridge device driver"); -MODULE_AUTHOR("cypress semiconductor"); -MODULE_LICENSE("GPL"); - -module_init(cyasdevice_init); -module_exit(cyasdevice_cleanup); - -/*[]*/ diff --git a/drivers/staging/westbridge/astoria/gadget/Kconfig b/drivers/staging/westbridge/astoria/gadget/Kconfig deleted file mode 100644 index 6fbdf2277b03..000000000000 --- a/drivers/staging/westbridge/astoria/gadget/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# -# West Bridge gadget driver configuration -# - -config WESTBRIDGE_GADGET_DRIVER - tristate "West Bridge Gadget Driver" - help - Include the West Bridge based gadget peripheral controller driver - diff --git a/drivers/staging/westbridge/astoria/gadget/Makefile b/drivers/staging/westbridge/astoria/gadget/Makefile deleted file mode 100644 index a5eef7ee60a4..000000000000 --- a/drivers/staging/westbridge/astoria/gadget/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for the kernel westbridge hal -# - -ifneq ($(CONFIG_WESTBRIDGE_DEBUG),y) - EXTRA_CFLAGS += -DWESTBRIDGE_NDEBUG -endif - -obj-$(CONFIG_WESTBRIDGE_GADGET_DRIVER) += cyasgadgetctrl.o -cyasgadgetctrl-y := cyasgadget.o - diff --git a/drivers/staging/westbridge/astoria/gadget/cyasgadget.c b/drivers/staging/westbridge/astoria/gadget/cyasgadget.c deleted file mode 100644 index be851ca54cec..000000000000 --- a/drivers/staging/westbridge/astoria/gadget/cyasgadget.c +++ /dev/null @@ -1,2177 +0,0 @@ -/* cyangadget.c - Linux USB Gadget driver file for the Cypress West Bridge -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -/* - * Cypress West Bridge high/full speed usb device controller code - * Based on the Netchip 2280 device controller by David Brownell - * in the linux 2.6.10 kernel - * - * linux/drivers/usb/gadget/net2280.c - */ - -/* - * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com) - * Copyright (C) 2003 David Brownell - * - * 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 "cyasgadget.h" - -#define CY_AS_DRIVER_DESC "cypress west bridge usb gadget" -#define CY_AS_DRIVER_VERSION "REV B" -#define DMA_ADDR_INVALID (~(dma_addr_t)0) - -static const char cy_as_driver_name[] = "cy_astoria_gadget"; -static const char cy_as_driver_desc[] = CY_AS_DRIVER_DESC; - -static const char cy_as_ep0name[] = "EP0"; -static const char *cy_as_ep_names[] = { - cy_as_ep0name, "EP1", - "EP2", "EP3", "EP4", "EP5", "EP6", "EP7", "EP8", - "EP9", "EP10", "EP11", "EP12", "EP13", "EP14", "EP15" -}; - -/* forward declarations */ -static void -cyas_ep_reset( - struct cyasgadget_ep *an_ep); - -static int -cyasgadget_fifo_status( - struct usb_ep *_ep); - -static void -cyasgadget_stallcallback( - cy_as_device_handle h, - cy_as_return_status_t status, - uint32_t tag, - cy_as_funct_c_b_type cbtype, - void *cbdata); - -/* variables */ -static cyasgadget *cy_as_gadget_controller; - -static int append_mtp; -module_param(append_mtp, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(append_mtp, - "west bridge to append descriptors for mtp 0=no 1=yes"); - -static int msc_enum_bus_0; -module_param(msc_enum_bus_0, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(msc_enum_bus_0, - "west bridge to enumerate bus 0 as msc 0=no 1=yes"); - -static int msc_enum_bus_1; -module_param(msc_enum_bus_1, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(msc_enum_bus_1, - "west bridge to enumerate bus 1 as msc 0=no 1=yes"); - -/* all Callbacks are placed in this subsection*/ -static void cy_as_gadget_usb_event_callback( - cy_as_device_handle h, - cy_as_usb_event ev, - void *evdata - ) -{ - cyasgadget *cy_as_dev; - #ifndef WESTBRIDGE_NDEBUG - struct usb_ctrlrequest *ctrlreq; - #endif - - /* cy_as_dev = container_of(h, cyasgadget, dev_handle); */ - cy_as_dev = cy_as_gadget_controller; - switch (ev) { - case cy_as_event_usb_suspend: - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<1>_cy_as_event_usb_suspend received\n"); - #endif - cy_as_dev->driver->suspend(&cy_as_dev->gadget); - break; - - case cy_as_event_usb_resume: - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<1>_cy_as_event_usb_resume received\n"); - #endif - cy_as_dev->driver->resume(&cy_as_dev->gadget); - break; - - case cy_as_event_usb_reset: - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<1>_cy_as_event_usb_reset received\n"); - #endif - break; - - case cy_as_event_usb_speed_change: - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<1>_cy_as_event_usb_speed_change received\n"); - #endif - break; - - case cy_as_event_usb_set_config: - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<1>_cy_as_event_usb_set_config received\n"); - #endif - break; - - case cy_as_event_usb_setup_packet: - #ifndef WESTBRIDGE_NDEBUG - ctrlreq = (struct usb_ctrlrequest *)evdata; - - cy_as_hal_print_message("<1>_cy_as_event_usb_setup_packet " - "received" - "bRequestType=0x%x," - "bRequest=0x%x," - "wValue=x%x," - "wIndex=0x%x," - "wLength=0x%x,", - ctrlreq->bRequestType, - ctrlreq->bRequest, - ctrlreq->wValue, - ctrlreq->wIndex, - ctrlreq->wLength - ); - #endif - cy_as_dev->outsetupreq = 0; - if ((((uint8_t *)evdata)[0] & USB_DIR_IN) == USB_DIR_OUT) - cy_as_dev->outsetupreq = 1; - cy_as_dev->driver->setup(&cy_as_dev->gadget, - (struct usb_ctrlrequest *)evdata); - break; - - case cy_as_event_usb_status_packet: - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<1>_cy_as_event_usb_status_packet received\n"); - #endif - break; - - case cy_as_event_usb_inquiry_before: - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<1>_cy_as_event_usb_inquiry_before received\n"); - #endif - break; - - case cy_as_event_usb_inquiry_after: - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<1>_cy_as_event_usb_inquiry_after received\n"); - #endif - break; - - case cy_as_event_usb_start_stop: - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<1>_cy_as_event_usb_start_stop received\n"); - #endif - break; - - default: - break; - } -} - -static void cy_as_gadget_mtp_event_callback( - cy_as_device_handle handle, - cy_as_mtp_event evtype, - void *evdata - ) -{ - - cyasgadget *dev = cy_as_gadget_controller; - (void) handle; - - switch (evtype) { - case cy_as_mtp_send_object_complete: - { - cy_as_mtp_send_object_complete_data *send_obj_data = - (cy_as_mtp_send_object_complete_data *) evdata; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<6>MTP EVENT: send_object_complete\n"); - cy_as_hal_print_message( - "<6>_bytes sent = %d\n_send status = %d", - send_obj_data->byte_count, - send_obj_data->status); - #endif - - dev->tmtp_send_complete_data.byte_count = - send_obj_data->byte_count; - dev->tmtp_send_complete_data.status = - send_obj_data->status; - dev->tmtp_send_complete_data.transaction_id = - send_obj_data->transaction_id; - dev->tmtp_send_complete = cy_true; - break; - } - case cy_as_mtp_get_object_complete: - { - cy_as_mtp_get_object_complete_data *get_obj_data = - (cy_as_mtp_get_object_complete_data *) evdata; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<6>MTP EVENT: get_object_complete\n"); - cy_as_hal_print_message( - "<6>_bytes got = %d\n_get status = %d", - get_obj_data->byte_count, get_obj_data->status); - #endif - - dev->tmtp_get_complete_data.byte_count = - get_obj_data->byte_count; - dev->tmtp_get_complete_data.status = - get_obj_data->status; - dev->tmtp_get_complete = cy_true; - break; - } - case cy_as_mtp_block_table_needed: - { - dev->tmtp_need_new_blk_tbl = cy_true; - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<6>MTP EVENT: cy_as_mtp_block_table_needed\n"); - #endif - break; - } - default: - break; - } -} - -static void -cyasgadget_setupreadcallback( - cy_as_device_handle h, - cy_as_end_point_number_t ep, - uint32_t count, - void *buf, - cy_as_return_status_t status) -{ - cyasgadget_ep *an_ep; - cyasgadget_req *an_req; - cyasgadget *cy_as_dev; - unsigned stopped; - unsigned long flags; - (void)buf; - - cy_as_dev = cy_as_gadget_controller; - if (cy_as_dev->driver == NULL) - return; - - an_ep = &cy_as_dev->an_gadget_ep[ep]; - spin_lock_irqsave(&cy_as_dev->lock, flags); - stopped = an_ep->stopped; - -#ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: ep=%d, count=%d, " - "status=%d\n", __func__, ep, count, status); -#endif - - an_req = list_entry(an_ep->queue.next, - cyasgadget_req, queue); - list_del_init(&an_req->queue); - - if (status == CY_AS_ERROR_SUCCESS) - an_req->req.status = 0; - else - an_req->req.status = -status; - an_req->req.actual = count; - an_ep->stopped = 1; - - spin_unlock_irqrestore(&cy_as_dev->lock, flags); - - an_req->req.complete(&an_ep->usb_ep_inst, &an_req->req); - - an_ep->stopped = stopped; - -} -/*called when the write of a setup packet has been completed*/ -static void cyasgadget_setupwritecallback( - cy_as_device_handle h, - cy_as_end_point_number_t ep, - uint32_t count, - void *buf, - cy_as_return_status_t status - ) -{ - cyasgadget_ep *an_ep; - cyasgadget_req *an_req; - cyasgadget *cy_as_dev; - unsigned stopped; - unsigned long flags; - - (void)buf; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called status=0x%x\n", - __func__, status); - #endif - - cy_as_dev = cy_as_gadget_controller; - - if (cy_as_dev->driver == NULL) - return; - - an_ep = &cy_as_dev->an_gadget_ep[ep]; - - spin_lock_irqsave(&cy_as_dev->lock, flags); - - stopped = an_ep->stopped; - -#ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("setup_write_callback: ep=%d, " - "count=%d, status=%d\n", ep, count, status); -#endif - - an_req = list_entry(an_ep->queue.next, cyasgadget_req, queue); - list_del_init(&an_req->queue); - - an_req->req.actual = count; - an_req->req.status = 0; - an_ep->stopped = 1; - - spin_unlock_irqrestore(&cy_as_dev->lock, flags); - - an_req->req.complete(&an_ep->usb_ep_inst, &an_req->req); - - an_ep->stopped = stopped; - -} - -/* called when a read operation has completed.*/ -static void cyasgadget_readcallback( - cy_as_device_handle h, - cy_as_end_point_number_t ep, - uint32_t count, - void *buf, - cy_as_return_status_t status - ) -{ - cyasgadget_ep *an_ep; - cyasgadget_req *an_req; - cyasgadget *cy_as_dev; - unsigned stopped; - cy_as_return_status_t ret; - unsigned long flags; - - (void)h; - (void)buf; - - cy_as_dev = cy_as_gadget_controller; - - if (cy_as_dev->driver == NULL) - return; - - an_ep = &cy_as_dev->an_gadget_ep[ep]; - stopped = an_ep->stopped; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: ep=%d, count=%d, status=%d\n", - __func__, ep, count, status); - #endif - - if (status == CY_AS_ERROR_CANCELED) - return; - - spin_lock_irqsave(&cy_as_dev->lock, flags); - - an_req = list_entry(an_ep->queue.next, cyasgadget_req, queue); - list_del_init(&an_req->queue); - - if (status == CY_AS_ERROR_SUCCESS) - an_req->req.status = 0; - else - an_req->req.status = -status; - - an_req->complete = 1; - an_req->req.actual = count; - an_ep->stopped = 1; - - spin_unlock_irqrestore(&cy_as_dev->lock, flags); - an_req->req.complete(&an_ep->usb_ep_inst, &an_req->req); - - an_ep->stopped = stopped; - - /* We need to call ReadAsync on this end-point - * again, so as to not miss any data packets. */ - if (!an_ep->stopped) { - spin_lock_irqsave(&cy_as_dev->lock, flags); - an_req = 0; - if (!list_empty(&an_ep->queue)) - an_req = list_entry(an_ep->queue.next, - cyasgadget_req, queue); - - spin_unlock_irqrestore(&cy_as_dev->lock, flags); - - if ((an_req) && (an_req->req.status == -EINPROGRESS)) { - ret = cy_as_usb_read_data_async(cy_as_dev->dev_handle, - an_ep->num, cy_false, an_req->req.length, - an_req->req.buf, cyasgadget_readcallback); - - if (ret != CY_AS_ERROR_SUCCESS) - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_read_data_async failed " - "with error code %d\n", ret); - else - an_req->req.status = -EALREADY; - } - } -} - -/* function is called when a usb write operation has completed*/ -static void cyasgadget_writecallback( - cy_as_device_handle h, - cy_as_end_point_number_t ep, - uint32_t count, - void *buf, - cy_as_return_status_t status - ) -{ - cyasgadget_ep *an_ep; - cyasgadget_req *an_req; - cyasgadget *cy_as_dev; - unsigned stopped = 0; - cy_as_return_status_t ret; - unsigned long flags; - - (void)h; - (void)buf; - - cy_as_dev = cy_as_gadget_controller; - if (cy_as_dev->driver == NULL) - return; - - an_ep = &cy_as_dev->an_gadget_ep[ep]; - - if (status == CY_AS_ERROR_CANCELED) - return; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: ep=%d, count=%d, status=%d\n", - __func__, ep, count, status); - #endif - - spin_lock_irqsave(&cy_as_dev->lock, flags); - - an_req = list_entry(an_ep->queue.next, cyasgadget_req, queue); - list_del_init(&an_req->queue); - an_req->req.actual = count; - - /* Verify the status value before setting req.status to zero */ - if (status == CY_AS_ERROR_SUCCESS) - an_req->req.status = 0; - else - an_req->req.status = -status; - - an_ep->stopped = 1; - - spin_unlock_irqrestore(&cy_as_dev->lock, flags); - - an_req->req.complete(&an_ep->usb_ep_inst, &an_req->req); - an_ep->stopped = stopped; - - /* We need to call WriteAsync on this end-point again, so as to not - miss any data packets. */ - if (!an_ep->stopped) { - spin_lock_irqsave(&cy_as_dev->lock, flags); - an_req = 0; - if (!list_empty(&an_ep->queue)) - an_req = list_entry(an_ep->queue.next, - cyasgadget_req, queue); - spin_unlock_irqrestore(&cy_as_dev->lock, flags); - - if ((an_req) && (an_req->req.status == -EINPROGRESS)) { - ret = cy_as_usb_write_data_async(cy_as_dev->dev_handle, - an_ep->num, an_req->req.length, an_req->req.buf, - cy_false, cyasgadget_writecallback); - - if (ret != CY_AS_ERROR_SUCCESS) - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_write_data_async " - "failed with error code %d\n", ret); - else - an_req->req.status = -EALREADY; - } - } -} - -static void cyasgadget_stallcallback( - cy_as_device_handle h, - cy_as_return_status_t status, - uint32_t tag, - cy_as_funct_c_b_type cbtype, - void *cbdata - ) -{ - #ifndef WESTBRIDGE_NDEBUG - if (status != CY_AS_ERROR_SUCCESS) - cy_as_hal_print_message("<1>_set/_clear stall " - "failed with status %d\n", status); - #endif -} - - -/*******************************************************************/ -/* All usb_ep_ops (cyasgadget_ep_ops) are placed in this subsection*/ -/*******************************************************************/ -static int cyasgadget_enable( - struct usb_ep *_ep, - const struct usb_endpoint_descriptor *desc - ) -{ - cyasgadget *an_dev; - cyasgadget_ep *an_ep; - u32 max, tmp; - unsigned long flags; - - an_ep = container_of(_ep, cyasgadget_ep, usb_ep_inst); - if (!_ep || !desc || an_ep->desc || _ep->name == cy_as_ep0name - || desc->bDescriptorType != USB_DT_ENDPOINT) - return -EINVAL; - - an_dev = an_ep->dev; - if (!an_dev->driver || an_dev->gadget.speed == USB_SPEED_UNKNOWN) - return -ESHUTDOWN; - - max = le16_to_cpu(desc->wMaxPacketSize) & 0x1fff; - - spin_lock_irqsave(&an_dev->lock, flags); - _ep->maxpacket = max & 0x7ff; - an_ep->desc = desc; - - /* ep_reset() has already been called */ - an_ep->stopped = 0; - an_ep->out_overflow = 0; - - if (an_ep->cyepconfig.enabled != cy_true) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_end_point_config EP %s mismatch " - "on enabled\n", an_ep->usb_ep_inst.name); - #endif - spin_unlock_irqrestore(&an_dev->lock, flags); - return -EINVAL; - } - - tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); - an_ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0; - - spin_unlock_irqrestore(&an_dev->lock, flags); - - switch (tmp) { - case USB_ENDPOINT_XFER_ISOC: - if (an_ep->cyepconfig.type != cy_as_usb_iso) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_end_point_config EP %s mismatch " - "on type %d %d\n", an_ep->usb_ep_inst.name, - an_ep->cyepconfig.type, cy_as_usb_iso); - #endif - return -EINVAL; - } - break; - case USB_ENDPOINT_XFER_INT: - if (an_ep->cyepconfig.type != cy_as_usb_int) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_end_point_config EP %s mismatch " - "on type %d %d\n", an_ep->usb_ep_inst.name, - an_ep->cyepconfig.type, cy_as_usb_int); - #endif - return -EINVAL; - } - break; - default: - if (an_ep->cyepconfig.type != cy_as_usb_bulk) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_end_point_config EP %s mismatch " - "on type %d %d\n", an_ep->usb_ep_inst.name, - an_ep->cyepconfig.type, cy_as_usb_bulk); - #endif - return -EINVAL; - } - break; - } - - tmp = desc->bEndpointAddress; - an_ep->is_in = (tmp & USB_DIR_IN) != 0; - - if ((an_ep->cyepconfig.dir == cy_as_usb_in) && - (!an_ep->is_in)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_end_point_config EP %s mismatch " - "on dir %d %d\n", an_ep->usb_ep_inst.name, - an_ep->cyepconfig.dir, cy_as_usb_in); - #endif - return -EINVAL; - } else if ((an_ep->cyepconfig.dir == cy_as_usb_out) && - (an_ep->is_in)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_end_point_config EP %s mismatch " - "on dir %d %d\n", an_ep->usb_ep_inst.name, - an_ep->cyepconfig.dir, cy_as_usb_out); - #endif - return -EINVAL; - } - - cy_as_usb_clear_stall(an_dev->dev_handle, an_ep->num, - cyasgadget_stallcallback, 0); - - cy_as_hal_print_message("%s enabled %s (ep%d-%d) max %04x\n", - __func__, _ep->name, an_ep->num, tmp, max); - - return 0; -} - -static int cyasgadget_disable( - struct usb_ep *_ep - ) -{ - cyasgadget_ep *an_ep; - unsigned long flags; - - an_ep = container_of(_ep, cyasgadget_ep, usb_ep_inst); - if (!_ep || !an_ep->desc || _ep->name == cy_as_ep0name) - return -EINVAL; - - spin_lock_irqsave(&an_ep->dev->lock, flags); - cyas_ep_reset(an_ep); - - spin_unlock_irqrestore(&an_ep->dev->lock, flags); - return 0; -} - -static struct usb_request *cyasgadget_alloc_request( - struct usb_ep *_ep, gfp_t gfp_flags - ) -{ - cyasgadget_ep *an_ep; - cyasgadget_req *an_req; - - if (!_ep) - return NULL; - - an_ep = container_of(_ep, cyasgadget_ep, usb_ep_inst); - - an_req = kzalloc(sizeof(cyasgadget_req), gfp_flags); - if (!an_req) - return NULL; - - an_req->req.dma = DMA_ADDR_INVALID; - INIT_LIST_HEAD(&an_req->queue); - - return &an_req->req; -} - -static void cyasgadget_free_request( - struct usb_ep *_ep, - struct usb_request *_req - ) -{ - cyasgadget_req *an_req; - - if (!_ep || !_req) - return; - - an_req = container_of(_req, cyasgadget_req, req); - - kfree(an_req); -} - -/* Load a packet into the fifo we use for usb IN transfers. - * works for all endpoints. */ -static int cyasgadget_queue( - struct usb_ep *_ep, - struct usb_request *_req, - gfp_t gfp_flags - ) -{ - cyasgadget_req *as_req; - cyasgadget_ep *as_ep; - cyasgadget *cy_as_dev; - unsigned long flags; - cy_as_return_status_t ret = 0; - - as_req = container_of(_req, cyasgadget_req, req); - if (!_req || !_req->complete || !_req->buf - || !list_empty(&as_req->queue)) - return -EINVAL; - - as_ep = container_of(_ep, cyasgadget_ep, usb_ep_inst); - - if (!_ep || (!as_ep->desc && (as_ep->num != 0))) - return -EINVAL; - - cy_as_dev = as_ep->dev; - if (!cy_as_dev->driver || - cy_as_dev->gadget.speed == USB_SPEED_UNKNOWN) - return -ESHUTDOWN; - - spin_lock_irqsave(&cy_as_dev->lock, flags); - - _req->status = -EINPROGRESS; - _req->actual = 0; - - spin_unlock_irqrestore(&cy_as_dev->lock, flags); - - /* Call Async functions */ - if (as_ep->is_in) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_write_data_async being called " - "on ep %d\n", as_ep->num); - #endif - - ret = cy_as_usb_write_data_async(cy_as_dev->dev_handle, - as_ep->num, _req->length, _req->buf, - cy_false, cyasgadget_writecallback); - if (ret != CY_AS_ERROR_SUCCESS) - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_write_data_async failed with " - "error code %d\n", ret); - else - _req->status = -EALREADY; - } else if (as_ep->num == 0) { - /* - ret = cy_as_usb_write_data_async(cy_as_dev->dev_handle, - as_ep->num, _req->length, _req->buf, cy_false, - cyasgadget_setupwritecallback); - - if (ret != CY_AS_ERROR_SUCCESS) - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_write_data_async failed with error " - "code %d\n", ret); - */ - if ((cy_as_dev->outsetupreq) && (_req->length)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_read_data_async " - "being called on ep %d\n", - as_ep->num); - #endif - - ret = cy_as_usb_read_data_async ( - cy_as_dev->dev_handle, as_ep->num, - cy_true, _req->length, _req->buf, - cyasgadget_setupreadcallback); - - if (ret != CY_AS_ERROR_SUCCESS) - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_read_data_async failed with " - "error code %d\n", ret); - - } else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_write_data_async " - "being called on ep %d\n", - as_ep->num); - #endif - - ret = cy_as_usb_write_data_async(cy_as_dev->dev_handle, - as_ep->num, _req->length, _req->buf, cy_false, - cyasgadget_setupwritecallback); - - if (ret != CY_AS_ERROR_SUCCESS) - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_write_data_async failed with " - "error code %d\n", ret); - } - - } else if (list_empty(&as_ep->queue)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_read_data_async being called since " - "ep queue empty%d\n", ret); - #endif - - ret = cy_as_usb_read_data_async(cy_as_dev->dev_handle, - as_ep->num, cy_false, _req->length, _req->buf, - cyasgadget_readcallback); - if (ret != CY_AS_ERROR_SUCCESS) - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_read_data_async failed with error " - "code %d\n", ret); - else - _req->status = -EALREADY; - } - - spin_lock_irqsave(&cy_as_dev->lock, flags); - - if (as_req) - list_add_tail(&as_req->queue, &as_ep->queue); - - spin_unlock_irqrestore(&cy_as_dev->lock, flags); - - return 0; -} - -/* dequeue request */ -static int cyasgadget_dequeue( - struct usb_ep *_ep, - struct usb_request *_req - ) -{ - cyasgadget_ep *an_ep; - cyasgadget *dev; - an_ep = container_of(_ep, cyasgadget_ep, usb_ep_inst); - dev = an_ep->dev; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - - cy_as_usb_cancel_async(dev->dev_handle, an_ep->num); - - return 0; -} - -static int cyasgadget_set_halt( - struct usb_ep *_ep, - int value - ) -{ - cyasgadget_ep *an_ep; - int retval = 0; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - - an_ep = container_of(_ep, cyasgadget_ep, usb_ep_inst); - if (!_ep || (!an_ep->desc && an_ep->num != 0)) - return -EINVAL; - - if (!an_ep->dev->driver || an_ep->dev->gadget.speed == - USB_SPEED_UNKNOWN) - return -ESHUTDOWN; - - if (an_ep->desc /* not ep0 */ && - (an_ep->desc->bmAttributes & 0x03) == USB_ENDPOINT_XFER_ISOC) - return -EINVAL; - - if (!list_empty(&an_ep->queue)) - retval = -EAGAIN; - else if (an_ep->is_in && value && - cyasgadget_fifo_status(_ep) != 0) - retval = -EAGAIN; - else { - if (value) { - cy_as_usb_set_stall(an_ep->dev->dev_handle, - an_ep->num, cyasgadget_stallcallback, 0); - } else { - cy_as_usb_clear_stall(an_ep->dev->dev_handle, - an_ep->num, cyasgadget_stallcallback, 0); - } - } - - return retval; -} - -static int cyasgadget_fifo_status( - struct usb_ep *_ep - ) -{ - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - - return 0; -} - -static void cyasgadget_fifo_flush( - struct usb_ep *_ep - ) -{ - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif -} - -static struct usb_ep_ops cyasgadget_ep_ops = { - .enable = cyasgadget_enable, - .disable = cyasgadget_disable, - .alloc_request = cyasgadget_alloc_request, - .free_request = cyasgadget_free_request, - .queue = cyasgadget_queue, - .dequeue = cyasgadget_dequeue, - .set_halt = cyasgadget_set_halt, - .fifo_status = cyasgadget_fifo_status, - .fifo_flush = cyasgadget_fifo_flush, -}; - -/*************************************************************/ -/*This subsection contains all usb_gadget_ops cyasgadget_ops */ -/*************************************************************/ -static int cyasgadget_get_frame( - struct usb_gadget *_gadget - ) -{ - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - return 0; -} - -static int cyasgadget_wakeup( - struct usb_gadget *_gadget - ) -{ - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - return 0; -} - -static int cyasgadget_set_selfpowered( - struct usb_gadget *_gadget, - int value - ) -{ - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - return 0; -} - -static int cyasgadget_pullup( - struct usb_gadget *_gadget, - int is_on - ) -{ - struct cyasgadget *cy_as_dev; - unsigned long flags; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - - if (!_gadget) - return -ENODEV; - - cy_as_dev = container_of(_gadget, cyasgadget, gadget); - - spin_lock_irqsave(&cy_as_dev->lock, flags); - cy_as_dev->softconnect = (is_on != 0); - if (is_on) - cy_as_usb_connect(cy_as_dev->dev_handle, 0, 0); - else - cy_as_usb_disconnect(cy_as_dev->dev_handle, 0, 0); - - spin_unlock_irqrestore(&cy_as_dev->lock, flags); - - return 0; -} - -static int cyasgadget_ioctl( - struct usb_gadget *_gadget, - unsigned code, - unsigned long param - ) -{ - int err = 0; - int retval = 0; - int ret_stat = 0; - cyasgadget *dev = cy_as_gadget_controller; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called, code=%d, param=%ld\n", - __func__, code, param); - #endif - /* - * extract the type and number bitfields, and don't decode - * wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok() - */ - if (_IOC_TYPE(code) != CYASGADGET_IOC_MAGIC) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s, bad magic number = 0x%x\n", - __func__, _IOC_TYPE(code)); - #endif - return -ENOTTY; - } - - if (_IOC_NR(code) > CYASGADGET_IOC_MAXNR) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s, bad ioctl code = 0x%x\n", - __func__, _IOC_NR(code)); - #endif - return -ENOTTY; - } - - /* - * the direction is a bitmask, and VERIFY_WRITE catches R/W - * transfers. `Type' is user-oriented, while - * access_ok is kernel-oriented, so the concept of "read" and - * "write" is reversed - */ - if (_IOC_DIR(code) & _IOC_READ) - err = !access_ok(VERIFY_WRITE, - (void __user *)param, _IOC_SIZE(code)); - else if (_IOC_DIR(code) & _IOC_WRITE) - err = !access_ok(VERIFY_READ, - (void __user *)param, _IOC_SIZE(code)); - - if (err) { - cy_as_hal_print_message("%s, bad ioctl dir = 0x%x\n", - __func__, _IOC_DIR(code)); - return -EFAULT; - } - - switch (code) { - case CYASGADGET_GETMTPSTATUS: - { - cy_as_gadget_ioctl_tmtp_status *usr_d = - (cy_as_gadget_ioctl_tmtp_status *)param; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: got CYASGADGET_GETMTPSTATUS\n", - __func__); - #endif - - retval = __put_user(dev->tmtp_send_complete, - (uint32_t __user *)(&(usr_d->tmtp_send_complete))); - retval = __put_user(dev->tmtp_get_complete, - (uint32_t __user *)(&(usr_d->tmtp_get_complete))); - retval = __put_user(dev->tmtp_need_new_blk_tbl, - (uint32_t __user *)(&(usr_d->tmtp_need_new_blk_tbl))); - - if (copy_to_user((&(usr_d->tmtp_send_complete_data)), - (&(dev->tmtp_send_complete_data)), - sizeof(cy_as_gadget_ioctl_send_object))) - return -EFAULT; - - if (copy_to_user((&(usr_d->tmtp_get_complete_data)), - (&(dev->tmtp_get_complete_data)), - sizeof(cy_as_gadget_ioctl_get_object))) - return -EFAULT; - break; - } - case CYASGADGET_CLEARTMTPSTATUS: - { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s got CYASGADGET_CLEARTMTPSTATUS\n", - __func__); - #endif - - dev->tmtp_send_complete = 0; - dev->tmtp_get_complete = 0; - dev->tmtp_need_new_blk_tbl = 0; - - break; - } - case CYASGADGET_INITSOJ: - { - cy_as_gadget_ioctl_i_s_o_j_d k_d; - cy_as_gadget_ioctl_i_s_o_j_d *usr_d = - (cy_as_gadget_ioctl_i_s_o_j_d *)param; - cy_as_mtp_block_table blk_table; - struct scatterlist sg; - char *alloc_filename; - struct file *file_to_allocate; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s got CYASGADGET_INITSOJ\n", - __func__); - #endif - - memset(&blk_table, 0, sizeof(blk_table)); - - /* Get user argument structure */ - if (copy_from_user(&k_d, usr_d, - sizeof(cy_as_gadget_ioctl_i_s_o_j_d))) - return -EFAULT; - - /* better use fixed size buff*/ - alloc_filename = kmalloc(k_d.name_length + 1, GFP_KERNEL); - if (alloc_filename == NULL) - return -ENOMEM; - - /* get the filename */ - if (copy_from_user(alloc_filename, k_d.file_name, - k_d.name_length + 1)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: CYASGADGET_INITSOJ, " - "copy file name from user space failed\n", - __func__); - #endif - kfree(alloc_filename); - return -EFAULT; - } - - file_to_allocate = filp_open(alloc_filename, O_RDWR, 0); - - if (!IS_ERR(file_to_allocate)) { - - struct address_space *mapping = - file_to_allocate->f_mapping; - const struct address_space_operations *a_ops = - mapping->a_ops; - struct inode *inode = mapping->host; - struct inode *alloc_inode = - file_to_allocate->f_path.dentry->d_inode; - uint32_t num_clusters = 0; - struct buffer_head bh; - struct kstat stat; - int nr_pages = 0; - int ret_stat = 0; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: fhandle is OK, " - "calling vfs_getattr\n", __func__); - #endif - - ret_stat = vfs_getattr(file_to_allocate->f_path.mnt, - file_to_allocate->f_path.dentry, &stat); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: returned from " - "vfs_getattr() stat->blksize=0x%lx\n", - __func__, stat.blksize); - #endif - - /* TODO: get this from disk properties - * (from blockdevice)*/ - #define SECTOR_SIZE 512 - if (stat.blksize != 0) { - num_clusters = (k_d.num_bytes) / SECTOR_SIZE; - - if (((k_d.num_bytes) % SECTOR_SIZE) != 0) - num_clusters++; - } else { - goto initsoj_safe_exit; - } - - bh.b_state = 0; - bh.b_blocknr = 0; - /* block size is arbitrary , we'll use sector size*/ - bh.b_size = SECTOR_SIZE; - - - - /* clear dirty pages in page cache - * (if were any allocated) */ - nr_pages = (k_d.num_bytes) / (PAGE_CACHE_SIZE); - - if (((k_d.num_bytes) % (PAGE_CACHE_SIZE)) != 0) - nr_pages++; - - #ifndef WESTBRIDGE_NDEBUG - /*check out how many pages where actually allocated */ - if (mapping->nrpages != nr_pages) - cy_as_hal_print_message("%s mpage_cleardirty " - "mapping->nrpages %d != num_pages %d\n", - __func__, (int) mapping->nrpages, - nr_pages); - - cy_as_hal_print_message("%s: calling " - "mpage_cleardirty() " - "for %d pages\n", __func__, nr_pages); - #endif - - ret_stat = mpage_cleardirty(mapping, nr_pages); - - /*fill up the the block table from the addr mapping */ - if (a_ops->bmap) { - int8_t blk_table_idx = -1; - uint32_t file_block_idx = 0; - uint32_t last_blk_addr_map = 0, - curr_blk_addr_map = 0; - - #ifndef WESTBRIDGE_NDEBUG - if (alloc_inode->i_bytes == 0) - cy_as_hal_print_message( - "%s: alloc_inode->ibytes =0\n", - __func__); - #endif - - /* iterate through the list of - * blocks (not clusters)*/ - for (file_block_idx = 0; - file_block_idx < num_clusters - /*inode->i_bytes*/; file_block_idx++) { - - /* returns starting sector number */ - curr_blk_addr_map = - a_ops->bmap(mapping, - file_block_idx); - - /*no valid mapping*/ - if (curr_blk_addr_map == 0) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s:hit invalid " - "mapping\n", __func__); - #endif - break; - } else if (curr_blk_addr_map != - (last_blk_addr_map + 1) || - (blk_table.num_blocks - [blk_table_idx] == 65535)) { - - /* next table entry */ - blk_table_idx++; - /* starting sector of a - * scattered cluster*/ - blk_table.start_blocks - [blk_table_idx] = - curr_blk_addr_map; - /* ++ num of blocks in cur - * table entry*/ - blk_table. - num_blocks[blk_table_idx]++; - - #ifndef WESTBRIDGE_NDEBUG - if (file_block_idx != 0) - cy_as_hal_print_message( - "<*> next table " - "entry:%d required\n", - blk_table_idx); - #endif - } else { - /*add contiguous block*/ - blk_table.num_blocks - [blk_table_idx]++; - } /*if (curr_blk_addr_map == 0)*/ - - last_blk_addr_map = curr_blk_addr_map; - } /* end for (file_block_idx = 0; file_block_idx - < inode->i_bytes;) */ - - #ifndef WESTBRIDGE_NDEBUG - /*print result for verification*/ - { - int i; - cy_as_hal_print_message( - "%s: print block table " - "mapping:\n", - __func__); - for (i = 0; i <= blk_table_idx; i++) { - cy_as_hal_print_message( - "<1> %d 0x%x 0x%x\n", i, - blk_table.start_blocks[i], - blk_table.num_blocks[i]); - } - } - #endif - - /* copy the block table to user - * space (for debug purposes) */ - retval = __put_user( - blk_table.start_blocks[blk_table_idx], - (uint32_t __user *) - (&(usr_d->blk_addr_p))); - - retval = __put_user( - blk_table.num_blocks[blk_table_idx], - (uint32_t __user *) - (&(usr_d->blk_count_p))); - - blk_table_idx++; - retval = __put_user(blk_table_idx, - (uint32_t __user *) - (&(usr_d->item_count))); - - } /*end if (a_ops->bmap)*/ - - filp_close(file_to_allocate, NULL); - - dev->tmtp_send_complete = 0; - dev->tmtp_need_new_blk_tbl = 0; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: calling cy_as_mtp_init_send_object()\n", - __func__); - #endif - sg_init_one(&sg, &blk_table, sizeof(blk_table)); - ret_stat = cy_as_mtp_init_send_object(dev->dev_handle, - (cy_as_mtp_block_table *)&sg, - k_d.num_bytes, 0, 0); - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: returned from " - "cy_as_mtp_init_send_object()\n", __func__); - #endif - - } - #ifndef WESTBRIDGE_NDEBUG - else { - cy_as_hal_print_message( - "%s: failed to allocate the file %s\n", - __func__, alloc_filename); - } /* end if (file_to_allocate)*/ - #endif - kfree(alloc_filename); -initsoj_safe_exit: - ret_stat = 0; - retval = __put_user(ret_stat, - (uint32_t __user *)(&(usr_d->ret_val))); - - break; - } - case CYASGADGET_INITGOJ: - { - cy_as_gadget_ioctl_i_g_o_j_d k_d; - cy_as_gadget_ioctl_i_g_o_j_d *usr_d = - (cy_as_gadget_ioctl_i_g_o_j_d *)param; - cy_as_mtp_block_table blk_table; - struct scatterlist sg; - char *map_filename; - struct file *file_to_map; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: got CYASGADGET_INITGOJ\n", - __func__); - #endif - - memset(&blk_table, 0, sizeof(blk_table)); - - /* Get user argument sturcutre */ - if (copy_from_user(&k_d, usr_d, - sizeof(cy_as_gadget_ioctl_i_g_o_j_d))) - return -EFAULT; - - map_filename = kmalloc(k_d.name_length + 1, GFP_KERNEL); - if (map_filename == NULL) - return -ENOMEM; - if (copy_from_user(map_filename, k_d.file_name, - k_d.name_length + 1)) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: copy file name from " - "user space failed\n", __func__); - #endif - kfree(map_filename); - return -EFAULT; - } - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<*>%s: opening %s for kernel " - "mode access map\n", __func__, map_filename); - #endif - file_to_map = filp_open(map_filename, O_RDWR, 0); - if (file_to_map) { - struct address_space *mapping = file_to_map->f_mapping; - const struct address_space_operations - *a_ops = mapping->a_ops; - struct inode *inode = mapping->host; - - int8_t blk_table_idx = -1; - uint32_t file_block_idx = 0; - uint32_t last_blk_addr_map = 0, curr_blk_addr_map = 0; - - /*verify operation exists*/ - if (a_ops->bmap) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<*>%s: bmap found, i_bytes=0x%x, " - "i_size=0x%x, i_blocks=0x%x\n", - __func__, inode->i_bytes, - (unsigned int) inode->i_size, - (unsigned int) inode->i_blocks); - #endif - - k_d.num_bytes = inode->i_size; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "<*>%s: k_d.num_bytes=0x%x\n", - __func__, k_d.num_bytes); - #endif - - for (file_block_idx = 0; - file_block_idx < inode->i_size; - file_block_idx++) { - curr_blk_addr_map = - a_ops->bmap(mapping, - file_block_idx); - - if (curr_blk_addr_map == 0) { - /*no valid mapping*/ - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: no valid " - "mapping\n", __func__); - #endif - break; - } else if (curr_blk_addr_map != - (last_blk_addr_map + 1)) { - /*non-contiguous break*/ - blk_table_idx++; - blk_table.start_blocks - [blk_table_idx] = - curr_blk_addr_map; - blk_table.num_blocks - [blk_table_idx]++; - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: found non-" - "contiguous break", - __func__); - #endif - } else { - /*add contiguous block*/ - blk_table.num_blocks - [blk_table_idx]++; - } - last_blk_addr_map = curr_blk_addr_map; - } - - /*print result for verification*/ - #ifndef WESTBRIDGE_NDEBUG - { - int i = 0; - - for (i = 0; i <= blk_table_idx; i++) { - cy_as_hal_print_message( - "%s %d 0x%x 0x%x\n", - __func__, i, - blk_table.start_blocks[i], - blk_table.num_blocks[i]); - } - } - #endif - } else { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: could not find " - "a_ops->bmap\n", __func__); - #endif - return -EFAULT; - } - - filp_close(file_to_map, NULL); - - dev->tmtp_get_complete = 0; - dev->tmtp_need_new_blk_tbl = 0; - - ret_stat = __put_user( - blk_table.start_blocks[blk_table_idx], - (uint32_t __user *)(&(usr_d->blk_addr_p))); - - ret_stat = __put_user( - blk_table.num_blocks[blk_table_idx], - (uint32_t __user *)(&(usr_d->blk_count_p))); - - sg_init_one(&sg, &blk_table, sizeof(blk_table)); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: calling cy_as_mtp_init_get_object() " - "start=0x%x, num =0x%x, tid=0x%x, " - "num_bytes=0x%x\n", - __func__, - blk_table.start_blocks[0], - blk_table.num_blocks[0], - k_d.tid, - k_d.num_bytes); - #endif - - ret_stat = cy_as_mtp_init_get_object( - dev->dev_handle, - (cy_as_mtp_block_table *)&sg, - k_d.num_bytes, k_d.tid, 0, 0); - if (ret_stat != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: cy_as_mtp_init_get_object " - "failed ret_stat=0x%x\n", - __func__, ret_stat); - #endif - } - } - #ifndef WESTBRIDGE_NDEBUG - else { - cy_as_hal_print_message( - "%s: failed to open file %s\n", - __func__, map_filename); - } - #endif - kfree(map_filename); - - ret_stat = 0; - retval = __put_user(ret_stat, (uint32_t __user *) - (&(usr_d->ret_val))); - break; - } - case CYASGADGET_CANCELSOJ: - { - cy_as_gadget_ioctl_cancel *usr_d = - (cy_as_gadget_ioctl_cancel *)param; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message( - "%s: got CYASGADGET_CANCELSOJ\n", - __func__); - #endif - - ret_stat = cy_as_mtp_cancel_send_object(dev->dev_handle, 0, 0); - - retval = __put_user(ret_stat, (uint32_t __user *) - (&(usr_d->ret_val))); - break; - } - case CYASGADGET_CANCELGOJ: - { - cy_as_gadget_ioctl_cancel *usr_d = - (cy_as_gadget_ioctl_cancel *)param; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: got CYASGADGET_CANCELGOJ\n", - __func__); - #endif - - ret_stat = cy_as_mtp_cancel_get_object(dev->dev_handle, 0, 0); - - retval = __put_user(ret_stat, - (uint32_t __user *)(&(usr_d->ret_val))); - break; - } - default: - { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: unknown ioctl received: %d\n", - __func__, code); - - cy_as_hal_print_message("%s: known codes:\n" - "CYASGADGET_GETMTPSTATUS=%d\n" - "CYASGADGET_CLEARTMTPSTATUS=%d\n" - "CYASGADGET_INITSOJ=%d\n" - "CYASGADGET_INITGOJ=%d\n" - "CYASGADGET_CANCELSOJ=%d\n" - "CYASGADGET_CANCELGOJ=%d\n", - __func__, - CYASGADGET_GETMTPSTATUS, - CYASGADGET_CLEARTMTPSTATUS, - CYASGADGET_INITSOJ, - CYASGADGET_INITGOJ, - CYASGADGET_CANCELSOJ, - CYASGADGET_CANCELGOJ); - #endif - break; - } - } - - return 0; -} - -static const struct usb_gadget_ops cyasgadget_ops = { - .get_frame = cyasgadget_get_frame, - .wakeup = cyasgadget_wakeup, - .set_selfpowered = cyasgadget_set_selfpowered, - .pullup = cyasgadget_pullup, - .ioctl = cyasgadget_ioctl, -}; - - -/* keeping it simple: - * - one bus driver, initted first; - * - one function driver, initted second - * - * most of the work to support multiple controllers would - * be to associate this gadget driver with all of them, or - * perhaps to bind specific drivers to specific devices. - */ - -static void cyas_ep_reset( - cyasgadget_ep *an_ep - ) -{ - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - - an_ep->desc = NULL; - INIT_LIST_HEAD(&an_ep->queue); - - an_ep->stopped = 0; - an_ep->is_in = 0; - an_ep->is_iso = 0; - an_ep->usb_ep_inst.maxpacket = ~0; - an_ep->usb_ep_inst.ops = &cyasgadget_ep_ops; -} - -static void cyas_usb_reset( - cyasgadget *cy_as_dev - ) -{ - cy_as_return_status_t ret; - cy_as_usb_enum_control config; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_device *dev_p = (cy_as_device *)cy_as_dev->dev_handle; - - cy_as_hal_print_message("<1>%s called mtp_firmware=0x%x\n", - __func__, dev_p->is_mtp_firmware); - #endif - - ret = cy_as_misc_release_resource(cy_as_dev->dev_handle, - cy_as_bus_u_s_b); - if (ret != CY_AS_ERROR_SUCCESS && ret != - CY_AS_ERROR_RESOURCE_NOT_OWNED) { - cy_as_hal_print_message("<1>_cy_as_gadget: cannot " - "release usb resource: failed with error code %d\n", - ret); - return; - } - - cy_as_dev->gadget.speed = USB_SPEED_HIGH; - - ret = cy_as_usb_start(cy_as_dev->dev_handle, 0, 0); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_start failed with error code %d\n", - ret); - return; - } - /* P port will do enumeration, not West Bridge */ - config.antioch_enumeration = cy_false; - /* 1 2 : 1-BUS_NUM , 2:Storage_device number, SD - is bus 1*/ - - /* TODO: add module param to enumerate mass storage */ - config.mass_storage_interface = 0; - - if (append_mtp) { - ret = cy_as_mtp_start(cy_as_dev->dev_handle, - cy_as_gadget_mtp_event_callback, 0, 0); - if (ret == CY_AS_ERROR_SUCCESS) { - cy_as_hal_print_message("MTP start passed, enumerating " - "MTP interface\n"); - config.mtp_interface = append_mtp; - /*Do not enumerate NAND storage*/ - config.devices_to_enumerate[0][0] = cy_false; - - /*enumerate SD storage as MTP*/ - config.devices_to_enumerate[1][0] = cy_true; - } - } else { - cy_as_hal_print_message("MTP start not attempted, not " - "enumerating MTP interface\n"); - config.mtp_interface = 0; - /* enumerate mass storage based on module parameters */ - config.devices_to_enumerate[0][0] = msc_enum_bus_0; - config.devices_to_enumerate[1][0] = msc_enum_bus_1; - } - - ret = cy_as_usb_set_enum_config(cy_as_dev->dev_handle, - &config, 0, 0); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_hal_print_message("<1>_cy_as_gadget: " - "cy_as_usb_set_enum_config failed with error " - "code %d\n", ret); - return; - } - - cy_as_usb_set_physical_configuration(cy_as_dev->dev_handle, 1); - -} - -static void cyas_usb_reinit( - cyasgadget *cy_as_dev - ) -{ - int index = 0; - cyasgadget_ep *an_ep_p; - cy_as_return_status_t ret; - cy_as_device *dev_p = (cy_as_device *)cy_as_dev->dev_handle; - - INIT_LIST_HEAD(&cy_as_dev->gadget.ep_list); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called, is_mtp_firmware = " - "0x%x\n", __func__, dev_p->is_mtp_firmware); - #endif - - /* Init the end points */ - for (index = 1; index <= 15; index++) { - an_ep_p = &cy_as_dev->an_gadget_ep[index]; - cyas_ep_reset(an_ep_p); - an_ep_p->usb_ep_inst.name = cy_as_ep_names[index]; - an_ep_p->dev = cy_as_dev; - an_ep_p->num = index; - memset(&an_ep_p->cyepconfig, 0, sizeof(an_ep_p->cyepconfig)); - - /* EP0, EPs 2,4,6,8 need not be added */ - if ((index <= 8) && (index % 2 == 0) && - (!dev_p->is_mtp_firmware)) { - /* EP0 is 64 and EPs 2,4,6,8 not allowed */ - cy_as_dev->an_gadget_ep[index].fifo_size = 0; - } else { - if (index == 1) - an_ep_p->fifo_size = 64; - else - an_ep_p->fifo_size = 512; - list_add_tail(&an_ep_p->usb_ep_inst.ep_list, - &cy_as_dev->gadget.ep_list); - } - } - /* need to setendpointconfig before usb connect, this is not - * quite compatible with gadget methodology (ep_enable called - * by gadget after connect), therefore need to set config in - * initialization and verify compatibility in ep_enable, - * kick up error otherwise*/ - an_ep_p = &cy_as_dev->an_gadget_ep[3]; - an_ep_p->cyepconfig.enabled = cy_true; - an_ep_p->cyepconfig.dir = cy_as_usb_out; - an_ep_p->cyepconfig.type = cy_as_usb_bulk; - an_ep_p->cyepconfig.size = 0; - an_ep_p->cyepconfig.physical = 1; - ret = cy_as_usb_set_end_point_config(an_ep_p->dev->dev_handle, - 3, &an_ep_p->cyepconfig); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_hal_print_message("cy_as_usb_set_end_point_config " - "failed with error code %d\n", ret); - } - - cy_as_usb_set_stall(an_ep_p->dev->dev_handle, 3, 0, 0); - - an_ep_p = &cy_as_dev->an_gadget_ep[5]; - an_ep_p->cyepconfig.enabled = cy_true; - an_ep_p->cyepconfig.dir = cy_as_usb_in; - an_ep_p->cyepconfig.type = cy_as_usb_bulk; - an_ep_p->cyepconfig.size = 0; - an_ep_p->cyepconfig.physical = 2; - ret = cy_as_usb_set_end_point_config(an_ep_p->dev->dev_handle, - 5, &an_ep_p->cyepconfig); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_hal_print_message("cy_as_usb_set_end_point_config " - "failed with error code %d\n", ret); - } - - cy_as_usb_set_stall(an_ep_p->dev->dev_handle, 5, 0, 0); - - an_ep_p = &cy_as_dev->an_gadget_ep[9]; - an_ep_p->cyepconfig.enabled = cy_true; - an_ep_p->cyepconfig.dir = cy_as_usb_in; - an_ep_p->cyepconfig.type = cy_as_usb_bulk; - an_ep_p->cyepconfig.size = 0; - an_ep_p->cyepconfig.physical = 4; - ret = cy_as_usb_set_end_point_config(an_ep_p->dev->dev_handle, - 9, &an_ep_p->cyepconfig); - if (ret != CY_AS_ERROR_SUCCESS) { - cy_as_hal_print_message("cy_as_usb_set_end_point_config " - "failed with error code %d\n", ret); - } - - cy_as_usb_set_stall(an_ep_p->dev->dev_handle, 9, 0, 0); - - if (dev_p->mtp_count != 0) { - /* these need to be set for compatibility with - * the gadget_enable logic */ - an_ep_p = &cy_as_dev->an_gadget_ep[2]; - an_ep_p->cyepconfig.enabled = cy_true; - an_ep_p->cyepconfig.dir = cy_as_usb_out; - an_ep_p->cyepconfig.type = cy_as_usb_bulk; - an_ep_p->cyepconfig.size = 0; - an_ep_p->cyepconfig.physical = 0; - cy_as_usb_set_stall(an_ep_p->dev->dev_handle, 2, 0, 0); - - an_ep_p = &cy_as_dev->an_gadget_ep[6]; - an_ep_p->cyepconfig.enabled = cy_true; - an_ep_p->cyepconfig.dir = cy_as_usb_in; - an_ep_p->cyepconfig.type = cy_as_usb_bulk; - an_ep_p->cyepconfig.size = 0; - an_ep_p->cyepconfig.physical = 0; - cy_as_usb_set_stall(an_ep_p->dev->dev_handle, 6, 0, 0); - } - - cyas_ep_reset(&cy_as_dev->an_gadget_ep[0]); - cy_as_dev->an_gadget_ep[0].usb_ep_inst.name = cy_as_ep_names[0]; - cy_as_dev->an_gadget_ep[0].dev = cy_as_dev; - cy_as_dev->an_gadget_ep[0].num = 0; - cy_as_dev->an_gadget_ep[0].fifo_size = 64; - - cy_as_dev->an_gadget_ep[0].usb_ep_inst.maxpacket = 64; - cy_as_dev->gadget.ep0 = &cy_as_dev->an_gadget_ep[0].usb_ep_inst; - cy_as_dev->an_gadget_ep[0].stopped = 0; - INIT_LIST_HEAD(&cy_as_dev->gadget.ep0->ep_list); -} - -static void cyas_ep0_start( - cyasgadget *dev - ) -{ - cy_as_return_status_t ret; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - - ret = cy_as_usb_register_callback(dev->dev_handle, - cy_as_gadget_usb_event_callback); - if (ret != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: cy_as_usb_register_callback " - "failed with error code %d\n", __func__, ret); - #endif - return; - } - - ret = cy_as_usb_commit_config(dev->dev_handle, 0, 0); - if (ret != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: cy_as_usb_commit_config " - "failed with error code %d\n", __func__, ret); - #endif - return; - } - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: cy_as_usb_commit_config " - "message sent\n", __func__); - #endif - - ret = cy_as_usb_connect(dev->dev_handle, 0, 0); - if (ret != CY_AS_ERROR_SUCCESS) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: cy_as_usb_connect failed " - "with error code %d\n", __func__, ret); - #endif - return; - } - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s: cy_as_usb_connect message " - "sent\n", __func__); - #endif -} - -/* - * When a driver is successfully registered, it will receive - * control requests including set_configuration(), which enables - * non-control requests. then usb traffic follows until a - * disconnect is reported. then a host may connect again, or - * the driver might get unbound. - */ -int usb_gadget_probe_driver(struct usb_gadget_driver *driver, - int (*bind)(struct usb_gadget *)) -{ - cyasgadget *dev = cy_as_gadget_controller; - int retval; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called driver=0x%x\n", - __func__, (unsigned int) driver); - #endif - - /* insist on high speed support from the driver, since - * "must not be used in normal operation" - */ - if (!driver - || !bind - || !driver->unbind - || !driver->setup) - return -EINVAL; - - if (!dev) - return -ENODEV; - - if (dev->driver) - return -EBUSY; - - /* hook up the driver ... */ - dev->softconnect = 1; - driver->driver.bus = NULL; - dev->driver = driver; - dev->gadget.dev.driver = &driver->driver; - - /* Do the needful */ - cyas_usb_reset(dev); /* External usb */ - cyas_usb_reinit(dev); /* Internal */ - - retval = bind(&dev->gadget); - if (retval) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("%s bind to driver %s --> %d\n", - __func__, driver->driver.name, retval); - #endif - - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - return retval; - } - - /* ... then enable host detection and ep0; and we're ready - * for set_configuration as well as eventual disconnect. - */ - cyas_ep0_start(dev); - - return 0; -} -EXPORT_SYMBOL(usb_gadget_probe_driver); - -static void cyasgadget_nuke( - cyasgadget_ep *an_ep - ) -{ - cyasgadget *dev = cy_as_gadget_controller; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - - cy_as_usb_cancel_async(dev->dev_handle, an_ep->num); - an_ep->stopped = 1; - - while (!list_empty(&an_ep->queue)) { - cyasgadget_req *an_req = list_entry - (an_ep->queue.next, cyasgadget_req, queue); - list_del_init(&an_req->queue); - an_req->req.status = -ESHUTDOWN; - an_req->req.complete(&an_ep->usb_ep_inst, &an_req->req); - } -} - -static void cyasgadget_stop_activity( - cyasgadget *dev, - struct usb_gadget_driver *driver - ) -{ - int index; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - - /* don't disconnect if it's not connected */ - if (dev->gadget.speed == USB_SPEED_UNKNOWN) - driver = NULL; - - if (spin_is_locked(&dev->lock)) - spin_unlock(&dev->lock); - - /* Stop hardware; prevent new request submissions; - * and kill any outstanding requests. - */ - cy_as_usb_disconnect(dev->dev_handle, 0, 0); - - for (index = 3; index <= 7; index += 2) { - cyasgadget_ep *an_ep_p = &dev->an_gadget_ep[index]; - cyasgadget_nuke(an_ep_p); - } - - for (index = 9; index <= 15; index++) { - cyasgadget_ep *an_ep_p = &dev->an_gadget_ep[index]; - cyasgadget_nuke(an_ep_p); - } - - /* report disconnect; the driver is already quiesced */ - if (driver) - driver->disconnect(&dev->gadget); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("cy_as_usb_disconnect returned success"); - #endif - - /* Stop Usb */ - cy_as_usb_stop(dev->dev_handle, 0, 0); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("cy_as_usb_stop returned success"); - #endif -} - -int usb_gadget_unregister_driver( - struct usb_gadget_driver *driver - ) -{ - cyasgadget *dev = cy_as_gadget_controller; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - - if (!dev) - return -ENODEV; - - if (!driver || driver != dev->driver) - return -EINVAL; - - cyasgadget_stop_activity(dev, driver); - - driver->unbind(&dev->gadget); - dev->gadget.dev.driver = NULL; - dev->driver = NULL; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("unregistered driver '%s'\n", - driver->driver.name); - #endif - - return 0; -} -EXPORT_SYMBOL(usb_gadget_unregister_driver); - -static void cyas_gadget_release( - struct device *_dev - ) -{ - cyasgadget *dev = dev_get_drvdata(_dev); - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>%s called\n", __func__); - #endif - - kfree(dev); -} - -/* DeInitialize gadget driver */ -static void cyasgadget_deinit( - cyasgadget *cy_as_dev - ) -{ - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget deinitialize called\n"); - #endif - - if (!cy_as_dev) { - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget_deinit: " - "invalid cyasgadget device\n"); - #endif - return; - } - - if (cy_as_dev->driver) { - /* should have been done already by driver model core */ - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1> cy_as_gadget: '%s' " - "is still registered\n", - cy_as_dev->driver->driver.name); - #endif - usb_gadget_unregister_driver(cy_as_dev->driver); - } - - kfree(cy_as_dev); - cy_as_gadget_controller = NULL; -} - -/* Initialize gadget driver */ -static int cyasgadget_initialize(void) -{ - cyasgadget *cy_as_dev = 0; - int retval = 0; - - #ifndef WESTBRIDGE_NDEBUG - cy_as_hal_print_message("<1>_cy_as_gadget [V1.1] initialize called\n"); - #endif - - if (cy_as_gadget_controller != 0) { - cy_as_hal_print_message("<1> cy_as_gadget: the device has " - "already been initilaized. ignoring\n"); - return -EBUSY; - } - - cy_as_dev = kzalloc(sizeof(cyasgadget), GFP_ATOMIC); - if (cy_as_dev == NULL) { - cy_as_hal_print_message("<1> cy_as_gadget: memory " - "allocation failed\n"); - return -ENOMEM; - } - - spin_lock_init(&cy_as_dev->lock); - cy_as_dev->gadget.ops = &cyasgadget_ops; - cy_as_dev->gadget.is_dualspeed = 1; - - /* the "gadget" abstracts/virtualizes the controller */ - /*strcpy(cy_as_dev->gadget.dev.bus_id, "cyasgadget");*/ - cy_as_dev->gadget.dev.release = cyas_gadget_release; - cy_as_dev->gadget.name = cy_as_driver_name; - - /* Get the device handle */ - cy_as_dev->dev_handle = cyasdevice_getdevhandle(); - if (0 == cy_as_dev->dev_handle) { - #ifndef NDEBUG - cy_as_hal_print_message("<1> cy_as_gadget: " - "no west bridge device\n"); - #endif - retval = -EFAULT; - goto done; - } - - /* We are done now */ - cy_as_gadget_controller = cy_as_dev; - return 0; - -/* - * in case of an error - */ -done: - if (cy_as_dev) - cyasgadget_deinit(cy_as_dev); - - return retval; -} - -static int __init cyas_init(void) -{ - int init_res = 0; - - init_res = cyasgadget_initialize(); - - if (init_res != 0) { - printk(KERN_WARNING "<1> gadget ctl instance " - "init error:%d\n", init_res); - if (init_res > 0) { - /* force -E/0 linux convention */ - init_res = init_res * -1; - } - } - - return init_res; -} -module_init(cyas_init); - -static void __exit cyas_cleanup(void) -{ - if (cy_as_gadget_controller != NULL) - cyasgadget_deinit(cy_as_gadget_controller); -} -module_exit(cyas_cleanup); - - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION(CY_AS_DRIVER_DESC); -MODULE_AUTHOR("cypress semiconductor"); - -/*[]*/ diff --git a/drivers/staging/westbridge/astoria/gadget/cyasgadget.h b/drivers/staging/westbridge/astoria/gadget/cyasgadget.h deleted file mode 100644 index e01cea7eeb77..000000000000 --- a/drivers/staging/westbridge/astoria/gadget/cyasgadget.h +++ /dev/null @@ -1,193 +0,0 @@ -/* cyangadget.h - Linux USB Gadget driver file for the Cypress West Bridge -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -/* - * Cypress West Bridge high/full speed USB device controller code - * Based on the Netchip 2280 device controller by David Brownell - * in the linux 2.6.10 kernel - * - * linux/drivers/usb/gadget/net2280.h - */ - -/* - * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com) - * Copyright (C) 2003 David Brownell - * - * 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 _INCLUDED_CYANGADGET_H_ -#define _INCLUDED_CYANGADGET_H_ - -#include -#include -#include -#include -#include - -#include "../include/linux/westbridge/cyastoria.h" -#include "../include/linux/westbridge/cyashal.h" -#include "../include/linux/westbridge/cyasdevice.h" -#include "cyasgadget_ioctl.h" - -#include -#include - -/*char driver defines, revisit*/ -#include -#include -#include -#include /* everything... */ -#include /* error codes */ -#include /* size_t */ -#include -#include /* O_ACCMODE */ -#include -#include -#include -#include -#include /* vmalloc(), vfree */ -#include /*fat_alloc_cluster*/ -#include -#include /* cli(), *_flags */ -#include /* copy_*_user */ - -extern int mpage_cleardirty(struct address_space *mapping, int num_pages); -extern int fat_get_block(struct inode *, sector_t , struct buffer_head *, int); -extern cy_as_device_handle *cyasdevice_getdevhandle(void); - -/* Driver data structures and utilities */ -typedef struct cyasgadget_ep { - struct usb_ep usb_ep_inst; - struct cyasgadget *dev; - - /* analogous to a host-side qh */ - struct list_head queue; - const struct usb_endpoint_descriptor *desc; - unsigned num:8, - fifo_size:12, - in_fifo_validate:1, - out_overflow:1, - stopped:1, - is_in:1, - is_iso:1; - cy_as_usb_end_point_config cyepconfig; -} cyasgadget_ep; - -typedef struct cyasgadget_req { - struct usb_request req; - struct list_head queue; - int ep_num; - unsigned mapped:1, - valid:1, - complete:1, - ep_stopped:1; -} cyasgadget_req; - -typedef struct cyasgadget { - /* each device provides one gadget, several endpoints */ - struct usb_gadget gadget; - spinlock_t lock; - struct cyasgadget_ep an_gadget_ep[16]; - struct usb_gadget_driver *driver; - /* Handle to the West Bridge device */ - cy_as_device_handle dev_handle; - unsigned enabled:1, - protocol_stall:1, - softconnect:1, - outsetupreq:1; - struct completion thread_complete; - wait_queue_head_t thread_wq; - struct semaphore thread_sem; - struct list_head thread_queue; - - cy_bool tmtp_send_complete; - cy_bool tmtp_get_complete; - cy_bool tmtp_need_new_blk_tbl; - /* Data member used to store the SendObjectComplete event data */ - cy_as_mtp_send_object_complete_data tmtp_send_complete_data; - /* Data member used to store the GetObjectComplete event data */ - cy_as_mtp_get_object_complete_data tmtp_get_complete_data; - -} cyasgadget; - -static inline void set_halt(cyasgadget_ep *ep) -{ - return; -} - -static inline void clear_halt(cyasgadget_ep *ep) -{ - return; -} - -#define xprintk(dev, level, fmt, args...) \ - printk(level "%s %s: " fmt, driver_name, \ - pci_name(dev->pdev), ## args) - -#ifdef DEBUG -#undef DEBUG -#define DEBUG(dev, fmt, args...) \ - xprintk(dev, KERN_DEBUG, fmt, ## args) -#else -#define DEBUG(dev, fmt, args...) \ - do { } while (0) -#endif /* DEBUG */ - -#ifdef VERBOSE -#define VDEBUG DEBUG -#else -#define VDEBUG(dev, fmt, args...) \ - do { } while (0) -#endif /* VERBOSE */ - -#define ERROR(dev, fmt, args...) \ - xprintk(dev, KERN_ERR, fmt, ## args) -#define GADG_WARN(dev, fmt, args...) \ - xprintk(dev, KERN_WARNING, fmt, ## args) -#define INFO(dev, fmt, args...) \ - xprintk(dev, KERN_INFO, fmt, ## args) - -/*-------------------------------------------------------------------------*/ - -static inline void start_out_naking(struct cyasgadget_ep *ep) -{ - return; -} - -static inline void stop_out_naking(struct cyasgadget_ep *ep) -{ - return; -} - -#endif /* _INCLUDED_CYANGADGET_H_ */ diff --git a/drivers/staging/westbridge/astoria/gadget/cyasgadget_ioctl.h b/drivers/staging/westbridge/astoria/gadget/cyasgadget_ioctl.h deleted file mode 100644 index 21dd716f116e..000000000000 --- a/drivers/staging/westbridge/astoria/gadget/cyasgadget_ioctl.h +++ /dev/null @@ -1,99 +0,0 @@ -/* cyasgadget_ioctl.h - Linux USB Gadget driver ioctl file for - * Cypress West Bridge -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef CYASGADGET_IOCTL_H -#define CYASGADGET_IOCTL_H - - -#include -#include - -typedef struct cy_as_gadget_ioctl_send_object { - uint32_t status; - uint32_t byte_count; - uint32_t transaction_id; -} cy_as_gadget_ioctl_send_object; - -typedef struct cy_as_gadget_ioctl_get_object { - uint32_t status; - uint32_t byte_count; -} cy_as_gadget_ioctl_get_object; - - -typedef struct cy_as_gadget_ioctl_tmtp_status { - cy_bool tmtp_send_complete; - cy_bool tmtp_get_complete; - cy_bool tmtp_need_new_blk_tbl; - cy_as_gadget_ioctl_send_object tmtp_send_complete_data; - cy_as_gadget_ioctl_get_object tmtp_get_complete_data; - uint32_t t_usec; -} cy_as_gadget_ioctl_tmtp_status; - -/*Init send object data*/ -typedef struct cy_as_gadget_ioctl_i_s_o_j_d { - uint32_t *blk_addr_p; /* starting sector */ - uint16_t *blk_count_p; /* num of sectors in the block */ - /* number of entries in the blk table */ - uint32_t item_count; - uint32_t num_bytes; - /* in case if more prcise timestamping is done in kernel mode */ - uint32_t t_usec; - uint32_t ret_val; - char *file_name; - uint32_t name_length; - -} cy_as_gadget_ioctl_i_s_o_j_d; - - -/*Init get object data*/ -typedef struct cy_as_gadget_ioctl_i_g_o_j_d { - uint32_t *blk_addr_p; - uint16_t *blk_count_p; - uint32_t item_count; - uint32_t num_bytes; - uint32_t tid; - uint32_t ret_val; - char *file_name; - uint32_t name_length; - -} cy_as_gadget_ioctl_i_g_o_j_d; - -typedef struct cy_as_gadget_ioctl_cancel { - uint32_t ret_val; -} cy_as_gadget_ioctl_cancel; - -#define CYASGADGET_IOC_MAGIC 0xEF -#define CYASGADGET_GETMTPSTATUS \ - _IOW(CYASGADGET_IOC_MAGIC, 0, cy_as_gadget_ioctl_tmtp_status) -#define CYASGADGET_CLEARTMTPSTATUS \ - _IO(CYASGADGET_IOC_MAGIC, 1) -#define CYASGADGET_INITSOJ \ - _IOW(CYASGADGET_IOC_MAGIC, 2, cy_as_gadget_ioctl_i_s_o_j_d) -#define CYASGADGET_INITGOJ \ - _IOW(CYASGADGET_IOC_MAGIC, 3, cy_as_gadget_ioctl_i_g_o_j_d) -#define CYASGADGET_CANCELSOJ \ - _IOW(CYASGADGET_IOC_MAGIC, 4, cy_as_gadget_ioctl_cancel) -#define CYASGADGET_CANCELGOJ \ - _IOW(CYASGADGET_IOC_MAGIC, 5, cy_as_gadget_ioctl_cancel) -#define CYASGADGET_IOC_MAXNR 6 - -#endif diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanerr.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanerr.h deleted file mode 100644 index c7d4ebb020c9..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanerr.h +++ /dev/null @@ -1,418 +0,0 @@ -/* Cypress West Bridge API header file (cyanerr.h) - ## Symbols for backward compatibility with previous releases of Antioch SDK. -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYANERR_H_ -#define _INCLUDED_CYANERR_H_ - -#include "cyaserr.h" - -#ifndef __doxygen__ - -/* - * Function completed successfully. - */ -#define CY_AN_ERROR_SUCCESS (CY_AS_ERROR_SUCCESS) - -/* - * A function trying to acquire a resource was unable to do so. - */ -#define CY_AN_ERROR_NOT_ACQUIRED (CY_AS_ERROR_NOT_ACQUIRED) - -/* - * A function trying to acquire a resource was unable to do so. - */ -#define CY_AN_ERROR_NOT_RELEASED (CY_AS_ERROR_NOT_RELEASED) - -/* - * The West Bridge firmware is not loaded. - */ -#define CY_AN_ERROR_NO_FIRMWARE (CY_AS_ERROR_NO_FIRMWARE) - -/* - * A timeout occurred waiting on a response from the West Bridge device - */ -#define CY_AN_ERROR_TIMEOUT (CY_AS_ERROR_TIMEOUT) - -/* - * A request to download firmware was made while not in the CONFIG mode - */ -#define CY_AN_ERROR_NOT_IN_CONFIG_MODE (CY_AS_ERROR_NOT_IN_CONFIG_MODE) - -/* - * This error is returned if the firmware size specified is too invalid. - */ -#define CY_AN_ERROR_INVALID_SIZE (CY_AS_ERROR_INVALID_SIZE) - -/* - * This error is returned if a request is made to acquire a resource that has - * already been acquired. - */ -#define CY_AN_ERROR_RESOURCE_ALREADY_OWNED (CY_AS_ERROR_RESOURCE_ALREADY_OWNED) - -/* - * This error is returned if a request is made to release a resource that has - * not previously been acquired. - */ -#define CY_AN_ERROR_RESOURCE_NOT_OWNED (CY_AS_ERROR_RESOURCE_NOT_OWNED) - -/* - * This error is returned when a request is made for a media that does not - * exist - */ -#define CY_AN_ERROR_NO_SUCH_MEDIA (CY_AS_ERROR_NO_SUCH_MEDIA) - -/* - * This error is returned when a request is made for a device that does - * not exist - */ -#define CY_AN_ERROR_NO_SUCH_DEVICE (CY_AS_ERROR_NO_SUCH_DEVICE) - -/* - * This error is returned when a request is made for a unit that does - * not exist - */ -#define CY_AN_ERROR_NO_SUCH_UNIT (CY_AS_ERROR_NO_SUCH_UNIT) - -/* - * This error is returned when a request is made for a block that does - * not exist - */ -#define CY_AN_ERROR_INVALID_BLOCK (CY_AS_ERROR_INVALID_BLOCK) - -/* - * This error is returned when an invalid trace level is set. - */ -#define CY_AN_ERROR_INVALID_TRACE_LEVEL (CY_AS_ERROR_INVALID_TRACE_LEVEL) - -/* - * This error is returned when West Bridge is already in the standby state - * and an attempt is made to put West Bridge into this state again. - */ -#define CY_AN_ERROR_ALREADY_STANDBY (CY_AS_ERROR_ALREADY_STANDBY) - -/* - * This error is returned when the API needs to set a pin on the - * West Bridge device, but this is not supported by the underlying HAL - * layer. - */ -#define CY_AN_ERROR_SETTING_WAKEUP_PIN (CY_AS_ERROR_SETTING_WAKEUP_PIN) - -/* - * This error is returned when a module is being started that has - * already been started. - */ -#define CY_AN_ERROR_ALREADY_RUNNING (CY_AS_ERROR_ALREADY_RUNNING) - -/* - * This error is returned when a module is being stopped that has - * already been stopped. - */ -#define CY_AN_ERROR_NOT_RUNNING (CY_AS_ERROR_NOT_RUNNING) - -/* - * This error is returned when the caller tries to claim a media that has - * already been claimed. - */ -#define CY_AN_ERROR_MEDIA_ALREADY_CLAIMED (CY_AS_ERROR_MEDIA_ALREADY_CLAIMED) - -/* - * This error is returned when the caller tries to release a media that - * has already been released. - */ -#define CY_AN_ERROR_MEDIA_NOT_CLAIMED (CY_AS_ERROR_MEDIA_NOT_CLAIMED) - -/* - * This error is returned when canceling trying to cancel an asynchronous - * operation when an async operation is not pending. - */ -#define CY_AN_ERROR_NO_OPERATION_PENDING (CY_AS_ERROR_NO_OPERATION_PENDING) - -/* - * This error is returned when an invalid endpoint number is provided - * to an API call. - */ -#define CY_AN_ERROR_INVALID_ENDPOINT (CY_AS_ERROR_INVALID_ENDPOINT) - -/* - * This error is returned when an invalid descriptor type - * is specified in an API call. - */ -#define CY_AN_ERROR_INVALID_DESCRIPTOR (CY_AS_ERROR_INVALID_DESCRIPTOR) - -/* - * This error is returned when an invalid descriptor index - * is specified in an API call. - */ -#define CY_AN_ERROR_BAD_INDEX (CY_AS_ERROR_BAD_INDEX) - -/* - * This error is returned if trying to set a USB descriptor - * when in the P port enumeration mode. - */ -#define CY_AN_ERROR_BAD_ENUMERATION_MODE (CY_AS_ERROR_BAD_ENUMERATION_MODE) - -/* - * This error is returned when the endpoint configuration specified - * is not valid. - */ -#define CY_AN_ERROR_INVALID_CONFIGURATION (CY_AS_ERROR_INVALID_CONFIGURATION) - -/* - * This error is returned when the API cannot verify it is connected - * to an West Bridge device. - */ -#define CY_AN_ERROR_NO_ANTIOCH (CY_AS_ERROR_NO_ANTIOCH) - -/* - * This error is returned when an API function is called and - * CyAnMiscConfigureDevice has not been called to configure West - * Bridge for the current environment. - */ -#define CY_AN_ERROR_NOT_CONFIGURED (CY_AS_ERROR_NOT_CONFIGURED) - -/* - * This error is returned when West Bridge cannot allocate memory required for - * internal API operations. - */ -#define CY_AN_ERROR_OUT_OF_MEMORY (CY_AS_ERROR_OUT_OF_MEMORY) - -/* - * This error is returned when a module is being started that has - * already been started. - */ -#define CY_AN_ERROR_NESTED_SLEEP (CY_AS_ERROR_NESTED_SLEEP) - -/* - * This error is returned when an operation is attempted on an endpoint that has - * been disabled. - */ -#define CY_AN_ERROR_ENDPOINT_DISABLED (CY_AS_ERROR_ENDPOINT_DISABLED) - -/* - * This error is returned when a call is made to an API function when the device - * is in standby. - */ -#define CY_AN_ERROR_IN_STANDBY (CY_AS_ERROR_IN_STANDBY) - -/* - * This error is returned when an API call is made with an invalid handle value. - */ -#define CY_AN_ERROR_INVALID_HANDLE (CY_AS_ERROR_INVALID_HANDLE) - -/* - * This error is returned when an invalid response is returned from the West - * Bridge device. - */ -#define CY_AN_ERROR_INVALID_RESPONSE (CY_AS_ERROR_INVALID_RESPONSE) - -/* - * This error is returned from the callback function for any asynchronous - * read or write request that is canceled. - */ -#define CY_AN_ERROR_CANCELED (CY_AS_ERROR_CANCELED) - -/* - * This error is returned when the call to create sleep channel fails - * in the HAL layer. - */ -#define CY_AN_ERROR_CREATE_SLEEP_CHANNEL_FAILED \ - (CY_AS_ERROR_CREATE_SLEEP_CHANNEL_FAILED) - -/* - * This error is returned when the call to CyAnMiscLeaveStandby - * is made and the device is not in standby. - */ -#define CY_AN_ERROR_NOT_IN_STANDBY (CY_AS_ERROR_NOT_IN_STANDBY) - -/* - * This error is returned when the call to destroy sleep channel fails - * in the HAL layer. - */ -#define CY_AN_ERROR_DESTROY_SLEEP_CHANNEL_FAILED \ - (CY_AS_ERROR_DESTROY_SLEEP_CHANNEL_FAILED) - -/* - * This error is returned when an invalid resource is specified to a call - * to CyAnMiscAcquireResource() or CyAnMiscReleaseResource() - */ -#define CY_AN_ERROR_INVALID_RESOURCE (CY_AS_ERROR_INVALID_RESOURCE) - -/* - * This error occurs when an operation is requested on an endpoint that has - * a currently pending async operation. - */ -#define CY_AN_ERROR_ASYNC_PENDING (CY_AS_ERROR_ASYNC_PENDING) - -/* - * This error is returned when a call to CyAnStorageCancelAsync() or - * CyAnUsbCancelAsync() is made when no asynchronous request is pending. - */ -#define CY_AN_ERROR_ASYNC_NOT_PENDING (CY_AS_ERROR_ASYNC_NOT_PENDING) - -/* - * This error is returned when a request is made to put the West Bridge device - * into standby mode while the USB stack is still active. - */ -#define CY_AN_ERROR_USB_RUNNING (CY_AS_ERROR_USB_RUNNING) - -/* - * A request for in the wrong direction was issued on an endpoint. - */ -#define CY_AN_ERROR_USB_BAD_DIRECTION (CY_AS_ERROR_USB_BAD_DIRECTION) - -/* - * An invalid request was received - */ -#define CY_AN_ERROR_INVALID_REQUEST (CY_AS_ERROR_INVALID_REQUEST) - -/* - * An ACK request was requested while no setup packet was pending. - */ -#define CY_AN_ERROR_NO_SETUP_PACKET_PENDING \ - (CY_AS_ERROR_NO_SETUP_PACKET_PENDING) - -/* - * A call was made to a API function that cannot be called from a callback. - */ -#define CY_AN_ERROR_INVALID_IN_CALLBACK (CY_AS_ERROR_INVALID_IN_CALLBACK) - -/* - * A call was made to CyAnUsbSetEndPointConfig() before - * CyAnUsbSetPhysicalConfiguration() was called. - */ -#define CY_AN_ERROR_ENDPOINT_CONFIG_NOT_SET \ - (CY_AS_ERROR_ENDPOINT_CONFIG_NOT_SET) - -/* - * The physical endpoint referenced is not valid in the current - * physical configuration - */ -#define CY_AN_ERROR_INVALID_PHYSICAL_ENDPOINT \ - (CY_AS_ERROR_INVALID_PHYSICAL_ENDPOINT) - -/* - * The data supplied to the CyAnMiscDownloadFirmware() call is not aligned on a - * WORD (16 bit) boundary. - */ -#define CY_AN_ERROR_ALIGNMENT_ERROR (CY_AS_ERROR_ALIGNMENT_ERROR) - -/* - * A call was made to destroy the West Bridge device, but the USB stack or the - * storage stack was will running. - */ -#define CY_AN_ERROR_STILL_RUNNING (CY_AS_ERROR_STILL_RUNNING) - -/* - * A call was made to the API for a function that is not yet supported. - */ -#define CY_AN_ERROR_NOT_YET_SUPPORTED (CY_AS_ERROR_NOT_YET_SUPPORTED) - -/* - * A NULL callback was provided where a non-NULL callback was required - */ -#define CY_AN_ERROR_NULL_CALLBACK (CY_AS_ERROR_NULL_CALLBACK) - -/* - * This error is returned when a request is made to put the West Bridge device - * into standby mode while the storage stack is still active. - */ -#define CY_AN_ERROR_STORAGE_RUNNING (CY_AS_ERROR_STORAGE_RUNNING) - -/* - * This error is returned when an operation is attempted that cannot be - * completed while the USB stack is connected to a USB host. - */ -#define CY_AN_ERROR_USB_CONNECTED (CY_AS_ERROR_USB_CONNECTED) - -/* - * This error is returned when a USB disconnect is attempted and the - * West Bridge device is not connected. - */ -#define CY_AN_ERROR_USB_NOT_CONNECTED (CY_AS_ERROR_USB_NOT_CONNECTED) - -/* - * This error is returned when an P2S storage operation attempted and - * data could not be read or written to the storage media. - */ -#define CY_AN_ERROR_MEDIA_ACCESS_FAILURE (CY_AS_ERROR_MEDIA_ACCESS_FAILURE) - -/* - * This error is returned when an P2S storage operation attempted and - * the media is write protected. - */ -#define CY_AN_ERROR_MEDIA_WRITE_PROTECTED (CY_AS_ERROR_MEDIA_WRITE_PROTECTED) - -/* - * This error is returned when an attempt is made to cancel a request - * that has already been sent to the West Bridge. - */ -#define CY_AN_ERROR_OPERATION_IN_TRANSIT (CY_AS_ERROR_OPERATION_IN_TRANSIT) - -/* - * This error is returned when an invalid parameter is passed to one of - * the APIs. - */ -#define CY_AN_ERROR_INVALID_PARAMETER (CY_AS_ERROR_INVALID_PARAMETER) - -/* - * This error is returned if an API is not supported by the current - * West Bridge device or the active firmware version. - */ -#define CY_AN_ERROR_NOT_SUPPORTED (CY_AS_ERROR_NOT_SUPPORTED) - -/* - * This error is returned when a call is made to one of the Storage or - * USB APIs while the device is in suspend mode. - */ -#define CY_AN_ERROR_IN_SUSPEND (CY_AS_ERROR_IN_SUSPEND) - -/* - * This error is returned when the call to CyAnMiscLeaveSuspend - * is made and the device is not in suspend mode. - */ -#define CY_AN_ERROR_NOT_IN_SUSPEND (CY_AS_ERROR_NOT_IN_SUSPEND) - -/* - * This error is returned when a command that is disabled by USB is called. - */ -#define CY_AN_ERROR_FEATURE_NOT_ENABLED (CY_AS_ERROR_FEATURE_NOT_ENABLED) - -/* - * This error is returned when an Async storage read or write is called before a - * query device call is issued. - */ -#define CY_AN_ERROR_QUERY_DEVICE_NEEDED (CY_AS_ERROR_QUERY_DEVICE_NEEDED) - -/* - * This error is returned when a call is made to USB or STORAGE Start or - * Stop before a prior Start or Stop has finished. - */ -#define CY_AN_ERROR_STARTSTOP_PENDING (CY_AS_ERROR_STARTSTOP_PENDING) - -/* - * This error is returned when a request is made for a bus that does not exist - */ -#define CY_AN_ERROR_NO_SUCH_BUS (CY_AS_ERROR_NO_SUCH_BUS) - -#endif /* __doxygen__ */ - -#endif /* _INCLUDED_CYANERR_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmedia.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmedia.h deleted file mode 100644 index be074887f5a3..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmedia.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Cypress West Bridge API header file (cyanmedia.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYANMEDIA_H_ -#define _INCLUDED_CYANMEDIA_H_ - -#include "cyas_cplus_start.h" - -/* Summary - Specifies a specific type of media supported by West Bridge - - Description - The West Bridge device supports five specific types - of media as storage/IO devices attached to it's S-Port. This - type is used to indicate the type of media being referenced in - any API call. -*/ -#include "cyasmedia.h" - -/* Flash NAND memory (may be SLC or MLC) */ -#define cy_an_media_nand cy_as_media_nand - -/* An SD flash memory device */ -#define cy_an_media_sd_flash cy_as_media_sd_flash - -/* An MMC flash memory device */ -#define cy_an_media_mmc_flash cy_as_media_mmc_flash - -/* A CE-ATA disk drive */ -#define cy_an_media_ce_ata cy_as_media_ce_ata - - /* SDIO device. */ -#define cy_an_media_sdio cy_as_media_sdio -#define cy_an_media_max_media_value \ - cy_as_media_max_media_value - -typedef cy_as_media_type cy_an_media_type; - -#include "cyas_cplus_end.h" - -#endif /* _INCLUDED_CYANMEDIA_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmisc.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmisc.h deleted file mode 100644 index 0838648dc169..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanmisc.h +++ /dev/null @@ -1,614 +0,0 @@ -/* Cypress West Bridge API header file (cyanmisc.h) - ## Version for backward compatibility with previous Antioch SDK releases. -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYANMISC_H_ -#define _INCLUDED_CYANMISC_H_ - -#include "cyantypes.h" -#include -#include "cyanmedia.h" -#include "cyas_cplus_start.h" - -#define CY_AN_LEAVE_STANDBY_DELAY_CLOCK \ - (CY_AS_LEAVE_STANDBY_DELAY_CLOCK) -#define CY_AN_RESET_DELAY_CLOCK \ - (CY_AS_RESET_DELAY_CLOCK) - -#define CY_AN_LEAVE_STANDBY_DELAY_CRYSTAL \ - (CY_AS_LEAVE_STANDBY_DELAY_CRYSTAL) - -#define CY_AN_RESET_DELAY_CRYSTAL \ - (CY_AS_RESET_DELAY_CRYSTAL) - -/* Defines to convert the old CyAn names to the new - * CyAs names - */ -typedef cy_as_device_handle cy_an_device_handle; - -#define cy_an_device_dack_ack cy_as_device_dack_ack -#define cy_an_device_dack_eob cy_as_device_dack_eob -typedef cy_as_device_dack_mode cy_an_device_dack_mode; - -typedef cy_as_device_config cy_an_device_config; - -#define cy_an_resource_u_s_b cy_as_bus_u_sB -#define cy_an_resource_sdio_MMC cy_as_bus_1 -#define cy_an_resource_nand cy_as_bus_0 -typedef cy_as_resource_type cy_an_resource_type; - -#define cy_an_reset_soft cy_as_reset_soft -#define cy_an_reset_hard cy_as_reset_hard -typedef cy_as_reset_type cy_an_reset_type; -typedef cy_as_funct_c_b_type cy_an_funct_c_b_type; -typedef cy_as_function_callback cy_an_function_callback; - -#define cy_an_event_misc_initialized \ - cy_as_event_misc_initialized -#define cy_an_event_misc_awake \ - cy_as_event_misc_awake -#define cy_an_event_misc_heart_beat \ - cy_as_event_misc_heart_beat -#define cy_an_event_misc_wakeup \ - cy_as_event_misc_wakeup -#define cy_an_event_misc_device_mismatch \ - cy_as_event_misc_device_mismatch -typedef cy_as_misc_event_type \ - cy_an_misc_event_type; -typedef cy_as_misc_event_callback \ - cy_an_misc_event_callback; - -#define cy_an_misc_gpio_0 cy_as_misc_gpio_0 -#define cy_an_misc_gpio_1 cy_as_misc_gpio_1 -#define cy_an_misc_gpio__nand_CE \ - cy_as_misc_gpio__nand_CE -#define cy_an_misc_gpio__nand_CE2 \ - cy_as_misc_gpio__nand_CE2 -#define cy_an_misc_gpio__nand_WP \ - cy_as_misc_gpio__nand_WP -#define cy_an_misc_gpio__nand_CLE \ - cy_as_misc_gpio__nand_CLE -#define cy_an_misc_gpio__nand_ALE \ - cy_as_misc_gpio__nand_ALE -#define cy_an_misc_gpio_U_valid \ - cy_as_misc_gpio_U_valid -#define cy_an_misc_gpio_SD_POW \ - cy_as_misc_gpio_SD_POW -typedef cy_as_misc_gpio cy_an_misc_gpio; - -#define CY_AN_SD_DEFAULT_FREQ CY_AS_SD_DEFAULT_FREQ -#define CY_AN_SD_RATED_FREQ CY_AS_SD_RATED_FREQ -typedef cy_as_low_speed_sd_freq cy_an_low_speed_sd_freq; - -#define CY_AN_HS_SD_FREQ_48 CY_AS_HS_SD_FREQ_48 -#define CY_AN_HS_SD_FREQ_24 CY_AS_HS_SD_FREQ_24 -typedef cy_as_high_speed_sd_freq \ - cy_an_high_speed_sd_freq; - -#define cy_an_misc_active_high cy_as_misc_active_high -#define cy_an_misc_active_low cy_as_misc_active_low -typedef cy_as_misc_signal_polarity cy_an_misc_signal_polarity; - -typedef cy_as_get_firmware_version_data \ - cy_an_get_firmware_version_data; - -enum { - CYAN_FW_TRACE_LOG_NONE = 0, - CYAN_FW_TRACE_LOG_STATE, - CYAN_FW_TRACE_LOG_CALLS, - CYAN_FW_TRACE_LOG_STACK_TRACE, - CYAN_FW_TRACE_MAX_LEVEL -}; - - -/***********************************/ -/***********************************/ -/* FUNCTIONS */ -/***********************************/ -/***********************************/ - - -EXTERN cy_an_return_status_t -cy_an_misc_create_device( - cy_an_device_handle *handle_p, - cy_an_hal_device_tag tag - ); -#define cy_an_misc_create_device(h, tag) \ - cy_as_misc_create_device((cy_as_device_handle *)(h), \ - (cy_as_hal_device_tag)(tag)) - -EXTERN cy_an_return_status_t -cy_an_misc_destroy_device( - cy_an_device_handle handle - ); -#define cy_an_misc_destroy_device(h) \ - cy_as_misc_destroy_device((cy_as_device_handle)(h)) - -EXTERN cy_an_return_status_t -cy_an_misc_configure_device( - cy_an_device_handle handle, - cy_an_device_config *config_p - ); -#define cy_an_misc_configure_device(h, cfg) \ - cy_as_misc_configure_device((cy_as_device_handle)(h), \ - (cy_as_device_config *)(cfg)) - -EXTERN cy_an_return_status_t -cy_an_misc_in_standby( - cy_an_device_handle handle, - cy_bool *standby - ); -#define cy_an_misc_in_standby(h, standby) \ - cy_as_misc_in_standby((cy_as_device_handle)(h), (standby)) - -/* Sync version of Download Firmware */ -EXTERN cy_an_return_status_t -cy_an_misc_download_firmware( - cy_an_device_handle handle, - const void *fw_p, - uint16_t size - ); - -#define cy_an_misc_download_firmware(handle, fw_p, size) \ - cy_as_misc_download_firmware((cy_as_device_handle)\ - (handle), (fw_p), (size), 0, 0) - -/* Async version of Download Firmware */ -EXTERN cy_an_return_status_t -cy_an_misc_download_firmware_e_x( - cy_an_device_handle handle, - const void *fw_p, - uint16_t size, - cy_an_function_callback cb, - uint32_t client - ); - -#define cy_an_misc_download_firmware_e_x(h, fw_p, size, cb, client) \ - cy_as_misc_download_firmware((cy_as_device_handle)(h), \ - (fw_p), (size), (cy_as_function_callback)(cb), (client)) - -/* Sync version of Get Firmware Version */ -EXTERN cy_an_return_status_t -cy_as_misc_get_firmware_version_dep( - cy_as_device_handle handle, - uint16_t *major, - uint16_t *minor, - uint16_t *build, - uint8_t *media_type, - cy_bool *is_debug_mode); - -#define cy_an_misc_get_firmware_version\ - (h, major, minor, bld, type, mode) \ - cy_as_misc_get_firmware_version_dep((cy_as_device_handle)(h), \ - (major), (minor), (bld), (type), (mode)) - -/* Async version of Get Firmware Version*/ -EXTERN cy_an_return_status_t -cy_an_misc_get_firmware_version_e_x( - cy_an_device_handle handle, - cy_an_get_firmware_version_data *data, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_get_firmware_version_e_x\ - (h, data, cb, client) \ - cy_as_misc_get_firmware_version((cy_as_device_handle)(h), \ - (data), (cy_as_function_callback)(cb), (client)) - -/* Sync version of Read MCU Register*/ -EXTERN cy_an_return_status_t -cy_an_misc_read_m_c_u_register( - cy_an_device_handle handle, - uint16_t address, - uint8_t *value - ); - -#define cy_an_misc_read_m_c_u_register(handle, address, value) \ - cy_as_misc_read_m_c_u_register((cy_as_device_handle)(handle), \ - (address), (value), 0, 0) - -/* Async version of Read MCU Register*/ -EXTERN cy_an_return_status_t -cy_an_misc_read_m_c_u_register_e_x( - cy_an_device_handle handle, - uint16_t address, - uint8_t *value, - cy_an_function_callback cb, - uint32_t client - ); - -#define cy_an_misc_read_m_c_u_register_e_x\ - (h, addr, val, cb, client) \ - cy_as_misc_read_m_c_u_register((cy_as_device_handle)(h), \ - (addr), (val), (cy_as_function_callback)(cb), (client)) - -/* Sync version of Write MCU Register*/ -EXTERN cy_an_return_status_t -cy_an_misc_write_m_c_u_register( - cy_an_device_handle handle, - uint16_t address, - uint8_t mask, - uint8_t value - ); -#define cy_an_misc_write_m_c_u_register\ - (handle, address, mask, value) \ - cy_as_misc_write_m_c_u_register((cy_as_device_handle)(handle), \ - (address), (mask), (value), 0, 0) - -/* Async version of Write MCU Register*/ -EXTERN cy_an_return_status_t -cy_an_misc_write_m_c_u_register_e_x( - cy_an_device_handle handle, - uint16_t address, - uint8_t mask, - uint8_t value, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_write_m_c_u_register_e_x\ - (h, addr, mask, val, cb, client) \ - cy_as_misc_write_m_c_u_register((cy_as_device_handle)(h), \ - (addr), (mask), (val), (cy_as_function_callback)(cb), (client)) - -/* Sync version of Write MCU Register*/ -EXTERN cy_an_return_status_t -cy_an_misc_reset( - cy_an_device_handle handle, - cy_an_reset_type type, - cy_bool flush - ); -#define cy_an_misc_reset(handle, type, flush) \ - cy_as_misc_reset((cy_as_device_handle)(handle), \ - (type), (flush), 0, 0) - -/* Async version of Write MCU Register*/ -EXTERN cy_an_return_status_t -cy_an_misc_reset_e_x( - cy_an_device_handle handle, - cy_an_reset_type type, - cy_bool flush, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_reset_e_x(h, type, flush, cb, client) \ - cy_as_misc_reset((cy_as_device_handle)(h), \ - (cy_as_reset_type)(type), (flush), \ - (cy_as_function_callback)(cb), (client)) - -/* Synchronous version of CyAnMiscAcquireResource. */ -EXTERN cy_an_return_status_t -cy_an_misc_acquire_resource( - cy_an_device_handle handle, - cy_an_resource_type type, - cy_bool force - ); -#define cy_an_misc_acquire_resource(h, type, force) \ - cy_as_misc_acquire_resource_dep((cy_as_device_handle)(h), \ - (cy_as_resource_type)(type), (force)) - -/* Asynchronous version of CyAnMiscAcquireResource. */ -EXTERN cy_an_return_status_t -cy_an_misc_acquire_resource_e_x( - cy_an_device_handle handle, - cy_an_resource_type *type, - cy_bool force, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_acquire_resource_e_x\ - (h, type_p, force, cb, client) \ - cy_as_misc_acquire_resource((cy_as_device_handle)(h), \ - (cy_as_resource_type *)(type_p), \ - (force), (cy_as_function_callback)(cb), (client)) - -/* The one and only version of Release resource */ -EXTERN cy_an_return_status_t -cy_an_misc_release_resource( - cy_an_device_handle handle, - cy_an_resource_type type - ); -#define cy_an_misc_release_resource(h, type)\ - cy_as_misc_release_resource((cy_as_device_handle)(h), \ - (cy_as_resource_type)(type)) - -/* Synchronous version of CyAnMiscSetTraceLevel. */ -EXTERN cy_an_return_status_t -cy_an_misc_set_trace_level( - cy_an_device_handle handle, - uint8_t level, - cy_an_media_type media, - uint32_t device, - uint32_t unit - ); - -#define cy_an_misc_set_trace_level\ - (handle, level, media, device, unit) \ - cy_as_misc_set_trace_level_dep((cy_as_device_handle)(handle), \ - (level), (cy_as_media_type)(media), (device), (unit), 0, 0) - -/* Asynchronous version of CyAnMiscSetTraceLevel. */ -EXTERN cy_an_return_status_t -cy_an_misc_set_trace_level_e_x( - cy_an_device_handle handle, - uint8_t level, - cy_an_media_type media, - uint32_t device, - uint32_t unit, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_set_trace_level_e_x\ - (h, level, media, device, unit, cb, client) \ - cy_as_misc_set_trace_level_dep((cy_as_device_handle)(h), \ - (level), (cy_as_media_type)(media), (device), (unit), \ - (cy_as_function_callback)(cb), (client)) - -/* Synchronous version of CyAnMiscEnterStandby. */ -EXTERN cy_an_return_status_t -cy_an_misc_enter_standby( - cy_an_device_handle handle, - cy_bool pin - ); -#define cy_an_misc_enter_standby(handle, pin) \ - cy_as_misc_enter_standby(\ - (cy_as_device_handle)(handle), (pin), 0, 0) - -/* Synchronous version of CyAnMiscEnterStandby. */ -EXTERN cy_an_return_status_t -cy_an_misc_enter_standby_e_x( - cy_an_device_handle handle, - cy_bool pin, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_enter_standby_e_x(h, pin, cb, client) \ - cy_as_misc_enter_standby((cy_as_device_handle)(h), \ - (pin), (cy_as_function_callback)(cb), (client)) - -/* Only one version of CyAnMiscLeaveStandby. */ -EXTERN cy_an_return_status_t -cy_an_misc_leave_standby( - cy_an_device_handle handle, - cy_an_resource_type type - ); -#define cy_an_misc_leave_standby(h, type) \ - cy_as_misc_leave_standby((cy_as_device_handle)(h), \ - (cy_as_resource_type)(type)) - -/* The one version of Misc Register Callback */ -EXTERN cy_an_return_status_t -cy_an_misc_register_callback( - cy_an_device_handle handle, - cy_an_misc_event_callback callback - ); -#define cy_an_misc_register_callback(h, cb) \ - cy_as_misc_register_callback((cy_as_device_handle)(h), \ - (cy_as_misc_event_callback)(cb)) - -/* The only version of SetLogLevel */ -EXTERN void -cy_an_misc_set_log_level( - uint8_t level - ); -#define cy_an_misc_set_log_level(level) \ - cy_as_misc_set_log_level(level) - -/* Sync version of Misc Storage Changed */ -EXTERN cy_an_return_status_t -cy_an_misc_storage_changed( - cy_an_device_handle handle - ); -#define cy_an_misc_storage_changed(handle) \ - cy_as_misc_storage_changed((cy_as_device_handle)(handle), 0, 0) - -/* Async version of Misc Storage Changed */ -EXTERN cy_an_return_status_t -cy_an_misc_storage_changed_e_x( - cy_an_device_handle handle, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_storage_changed_e_x(h, cb, client) \ - cy_as_misc_storage_changed((cy_as_device_handle)(h), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of Heartbeat control */ -EXTERN cy_an_return_status_t -cy_an_misc_heart_beat_control( - cy_an_device_handle handle, - cy_bool enable - ); -#define cy_an_misc_heart_beat_control(handle, enable) \ - cy_as_misc_heart_beat_control((cy_as_device_handle)\ - (handle), (enable), 0, 0) - -/* Async version of Heartbeat control */ -EXTERN cy_an_return_status_t -cy_an_misc_heart_beat_control_e_x( - cy_an_device_handle handle, - cy_bool enable, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_heart_beat_control_e_x(h, enable, cb, client) \ - cy_as_misc_heart_beat_control((cy_as_device_handle)(h), \ - (enable), (cy_as_function_callback)(cb), (client)) - -/* Sync version of Get Gpio */ -EXTERN cy_an_return_status_t -cy_an_misc_get_gpio_value( - cy_an_device_handle handle, - cy_an_misc_gpio pin, - uint8_t *value - ); -#define cy_an_misc_get_gpio_value(handle, pin, value) \ - cy_as_misc_get_gpio_value((cy_as_device_handle)(handle), \ - (cy_as_misc_gpio)(pin), (value), 0, 0) - -/* Async version of Get Gpio */ -EXTERN cy_an_return_status_t -cy_an_misc_get_gpio_value_e_x( - cy_an_device_handle handle, - cy_an_misc_gpio pin, - uint8_t *value, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_get_gpio_value_e_x(h, pin, value, cb, client) \ - cy_as_misc_get_gpio_value((cy_as_device_handle)(h), \ - (cy_as_misc_gpio)(pin), (value), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of Set Gpio */ -EXTERN cy_an_return_status_t -cy_an_misc_set_gpio_value( - cy_an_device_handle handle, - cy_an_misc_gpio pin, - uint8_t value - ); -#define cy_an_misc_set_gpio_value(handle, pin, value) \ - cy_as_misc_set_gpio_value((cy_as_device_handle)(handle), \ - (cy_as_misc_gpio)(pin), (value), 0, 0) - -/* Async version of Set Gpio */ -EXTERN cy_an_return_status_t -cy_an_misc_set_gpio_value_e_x( - cy_an_device_handle handle, - cy_an_misc_gpio pin, - uint8_t value, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_set_gpio_value_e_x\ - (h, pin, value, cb, client) \ - cy_as_misc_set_gpio_value((cy_as_device_handle)(h), \ - (cy_as_misc_gpio)(pin), (value), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of Enter suspend */ -EXTERN cy_an_return_status_t -cy_an_misc_enter_suspend( - cy_an_device_handle handle, - cy_bool usb_wakeup_en, - cy_bool gpio_wakeup_en - ); -#define cy_an_misc_enter_suspend(handle, usb_wakeup_en, \ - gpio_wakeup_en) \ - cy_as_misc_enter_suspend((cy_as_device_handle)(handle), \ - (usb_wakeup_en), (gpio_wakeup_en), 0, 0) - -/* Async version of Enter suspend */ -EXTERN cy_an_return_status_t -cy_an_misc_enter_suspend_e_x( - cy_an_device_handle handle, - cy_bool usb_wakeup_en, - cy_bool gpio_wakeup_en, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_enter_suspend_e_x(h, usb_en, gpio_en, cb, client)\ - cy_as_misc_enter_suspend((cy_as_device_handle)(h), (usb_en), \ - (gpio_en), (cy_as_function_callback)(cb), (client)) - -/* Sync version of Enter suspend */ -EXTERN cy_an_return_status_t -cy_an_misc_leave_suspend( - cy_an_device_handle handle - ); -#define cy_an_misc_leave_suspend(handle) \ - cy_as_misc_leave_suspend((cy_as_device_handle)(handle), 0, 0) - -/* Async version of Enter suspend */ -EXTERN cy_an_return_status_t -cy_an_misc_leave_suspend_e_x( - cy_an_device_handle handle, - cy_an_function_callback cb, - uint32_t client - ); - -#define cy_an_misc_leave_suspend_e_x(h, cb, client) \ - cy_as_misc_leave_suspend((cy_as_device_handle)(h), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of SetLowSpeedSDFreq */ -EXTERN cy_an_return_status_t -cy_an_misc_set_low_speed_sd_freq( - cy_an_device_handle handle, - cy_an_low_speed_sd_freq setting - ); -#define cy_an_misc_set_low_speed_sd_freq(h, setting) \ - cy_as_misc_set_low_speed_sd_freq((cy_as_device_handle)(h), \ - (cy_as_low_speed_sd_freq)(setting), 0, 0) - -/* Async version of SetLowSpeedSDFreq */ -EXTERN cy_an_return_status_t -cy_an_misc_set_low_speed_sd_freq_e_x( - cy_an_device_handle handle, - cy_an_low_speed_sd_freq setting, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_set_low_speed_sd_freq_e_x\ -(h, setting, cb, client) \ - cy_as_misc_set_low_speed_sd_freq((cy_as_device_handle)(h), \ - (cy_as_low_speed_sd_freq)(setting), \ - (cy_as_function_callback)(cb), (client)) - -/* SetHighSpeedSDFreq */ -EXTERN cy_an_return_status_t -cy_an_misc_set_high_speed_sd_freq( - cy_an_device_handle handle, - cy_an_high_speed_sd_freq setting, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_misc_set_high_speed_sd_freq(h, setting, cb, client) \ - cy_as_misc_set_high_speed_sd_freq((cy_as_device_handle)(h), \ - (cy_as_high_speed_sd_freq)(setting), \ - (cy_as_function_callback)(cb), (client)) - -/* ReserveLNABootArea */ -EXTERN cy_an_return_status_t -cy_an_misc_reserve_l_n_a_boot_area( - cy_an_device_handle handle, - uint8_t numzones, - cy_an_function_callback cb, - uint32_t client); -#define cy_an_misc_reserve_l_n_a_boot_area(h, num, cb, client) \ - cy_as_misc_reserve_l_n_a_boot_area((cy_as_device_handle)(h), \ - num, (cy_as_function_callback)(cb), (client)) - -/* SetSDPowerPolarity */ -EXTERN cy_an_return_status_t -cy_an_misc_set_sd_power_polarity( - cy_an_device_handle handle, - cy_an_misc_signal_polarity polarity, - cy_an_function_callback cb, - uint32_t client); -#define cy_an_misc_set_sd_power_polarity(h, pol, cb, client) \ - cy_as_misc_set_sd_power_polarity((cy_as_device_handle)(h), \ - (cy_as_misc_signal_polarity)(pol), \ - (cy_as_function_callback)(cb), (client)) - -#include "cyas_cplus_end.h" - -#endif - diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanregs.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanregs.h deleted file mode 100644 index d670291bd24d..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanregs.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Cypress West Bridge API header file (cyanregs.h) - ## Register and field definitions for the Antioch device. -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYANREG_H_ -#define _INCLUDED_CYANREG_H_ - -#if !defined(__doxygen__) - -#define CY_AN_MEM_CM_WB_CFG_ID (0x80) -#define CY_AN_MEM_CM_WB_CFG_ID_VER_MASK (0x000F) -#define CY_AN_MEM_CM_WB_CFG_ID_HDID_MASK (0xFFF0) -#define CY_AN_MEM_CM_WB_CFG_ID_HDID_ANTIOCH_VALUE (0xA100) -#define CY_AN_MEM_CM_WB_CFG_ID_HDID_ASTORIA_FPGA_VALUE (0x6800) -#define CY_AN_MEM_CM_WB_CFG_ID_HDID_ASTORIA_VALUE (0xA200) - - -#define CY_AN_MEM_RST_CTRL_REG (0x81) -#define CY_AN_MEM_RST_CTRL_REG_HARD (0x0003) -#define CY_AN_MEM_RST_CTRL_REG_SOFT (0x0001) -#define CY_AN_MEM_RST_RSTCMPT (0x0004) - -#define CY_AN_MEM_P0_ENDIAN (0x82) -#define CY_AN_LITTLE_ENDIAN (0x0000) -#define CY_AN_BIG_ENDIAN (0x0101) - -#define CY_AN_MEM_P0_VM_SET (0x83) -#define CY_AN_MEM_P0_VM_SET_VMTYPE_MASK (0x0007) -#define CY_AN_MEM_P0_VM_SET_VMTYPE_RAM (0x0005) -#define CY_AN_MEM_P0_VM_SET_VMTYPE_VMWIDTH (0x0008) -#define CY_AN_MEM_P0_VM_SET_VMTYPE_FLOWCTRL (0x0010) -#define CY_AN_MEM_P0_VM_SET_IFMODE (0x0020) -#define CY_AN_MEM_P0_VM_SET_CFGMODE (0x0040) -#define CY_AN_MEM_P0_VM_SET_DACKEOB (0x0080) -#define CY_AN_MEM_P0_VM_SET_OVERRIDE (0x0100) -#define CY_AN_MEM_P0_VM_SET_INTOVERD (0x0200) -#define CY_AN_MEM_P0_VM_SET_DRQOVERD (0x0400) -#define CY_AN_MEM_P0_VM_SET_DRQPOL (0x0800) -#define CY_AN_MEM_P0_VM_SET_DACKPOL (0x1000) - - -#define CY_AN_MEM_P0_NV_SET (0x84) -#define CY_AN_MEM_P0_NV_SET_WPSWEN (0x0001) -#define CY_AN_MEM_P0_NV_SET_WPPOLAR (0x0002) - -#define CY_AN_MEM_PMU_UPDATE (0x85) -#define CY_AN_MEM_PMU_UPDATE_UVALID (0x0001) -#define CY_AN_MEM_PMU_UPDATE_USBUPDATE (0x0002) -#define CY_AN_MEM_PMU_UPDATE_SDIOUPDATE (0x0004) - -#define CY_AN_MEM_P0_INTR_REG (0x90) -#define CY_AN_MEM_P0_INTR_REG_MCUINT (0x0020) -#define CY_AN_MEM_P0_INTR_REG_DRQINT (0x0800) -#define CY_AN_MEM_P0_INTR_REG_MBINT (0x1000) -#define CY_AN_MEM_P0_INTR_REG_PMINT (0x2000) -#define CY_AN_MEM_P0_INTR_REG_PLLLOCKINT (0x4000) - -#define CY_AN_MEM_P0_INT_MASK_REG (0x91) -#define CY_AN_MEM_P0_INT_MASK_REG_MMCUINT (0x0020) -#define CY_AN_MEM_P0_INT_MASK_REG_MDRQINT (0x0800) -#define CY_AN_MEM_P0_INT_MASK_REG_MMBINT (0x1000) -#define CY_AN_MEM_P0_INT_MASK_REG_MPMINT (0x2000) -#define CY_AN_MEM_P0_INT_MASK_REG_MPLLLOCKINT (0x4000) - -#define CY_AN_MEM_MCU_MB_STAT (0x92) -#define CY_AN_MEM_P0_MCU_MBNOTRD (0x0001) - -#define CY_AN_MEM_P0_MCU_STAT (0x94) -#define CY_AN_MEM_P0_MCU_STAT_CARDINS (0x0001) -#define CY_AN_MEM_P0_MCU_STAT_CARDREM (0x0002) - -#define CY_AN_MEM_PWR_MAGT_STAT (0x95) -#define CY_AN_MEM_PWR_MAGT_STAT_WAKEUP (0x0001) - -#define CY_AN_MEM_P0_RSE_ALLOCATE (0x98) -#define CY_AN_MEM_P0_RSE_ALLOCATE_SDIOAVI (0x0001) -#define CY_AN_MEM_P0_RSE_ALLOCATE_SDIOALLO (0x0002) -#define CY_AN_MEM_P0_RSE_ALLOCATE_NANDAVI (0x0004) -#define CY_AN_MEM_P0_RSE_ALLOCATE_NANDALLO (0x0008) -#define CY_AN_MEM_P0_RSE_ALLOCATE_USBAVI (0x0010) -#define CY_AN_MEM_P0_RSE_ALLOCATE_USBALLO (0x0020) - -#define CY_AN_MEM_P0_RSE_MASK (0x9A) -#define CY_AN_MEM_P0_RSE_MASK_MSDIOBUS_RW (0x0003) -#define CY_AN_MEM_P0_RSE_MASK_MNANDBUS_RW (0x00C0) -#define CY_AN_MEM_P0_RSE_MASK_MUSBBUS_RW (0x0030) - -#define CY_AN_MEM_P0_DRQ (0xA0) -#define CY_AN_MEM_P0_DRQ_EP2DRQ (0x0004) -#define CY_AN_MEM_P0_DRQ_EP3DRQ (0x0008) -#define CY_AN_MEM_P0_DRQ_EP4DRQ (0x0010) -#define CY_AN_MEM_P0_DRQ_EP5DRQ (0x0020) -#define CY_AN_MEM_P0_DRQ_EP6DRQ (0x0040) -#define CY_AN_MEM_P0_DRQ_EP7DRQ (0x0080) -#define CY_AN_MEM_P0_DRQ_EP8DRQ (0x0100) -#define CY_AN_MEM_P0_DRQ_EP9DRQ (0x0200) -#define CY_AN_MEM_P0_DRQ_EP10DRQ (0x0400) -#define CY_AN_MEM_P0_DRQ_EP11DRQ (0x0800) -#define CY_AN_MEM_P0_DRQ_EP12DRQ (0x1000) -#define CY_AN_MEM_P0_DRQ_EP13DRQ (0x2000) -#define CY_AN_MEM_P0_DRQ_EP14DRQ (0x4000) -#define CY_AN_MEM_P0_DRQ_EP15DRQ (0x8000) - -#define CY_AN_MEM_P0_DRQ_MASK (0xA1) -#define CY_AN_MEM_P0_DRQ_MASK_MEP2DRQ (0x0004) -#define CY_AN_MEM_P0_DRQ_MASK_MEP3DRQ (0x0008) -#define CY_AN_MEM_P0_DRQ_MASK_MEP4DRQ (0x0010) -#define CY_AN_MEM_P0_DRQ_MASK_MEP5DRQ (0x0020) -#define CY_AN_MEM_P0_DRQ_MASK_MEP6DRQ (0x0040) -#define CY_AN_MEM_P0_DRQ_MASK_MEP7DRQ (0x0080) -#define CY_AN_MEM_P0_DRQ_MASK_MEP8DRQ (0x0100) -#define CY_AN_MEM_P0_DRQ_MASK_MEP9DRQ (0x0200) -#define CY_AN_MEM_P0_DRQ_MASK_MEP10DRQ (0x0400) -#define CY_AN_MEM_P0_DRQ_MASK_MEP11DRQ (0x0800) -#define CY_AN_MEM_P0_DRQ_MASK_MEP12DRQ (0x1000) -#define CY_AN_MEM_P0_DRQ_MASK_MEP13DRQ (0x2000) -#define CY_AN_MEM_P0_DRQ_MASK_MEP14DRQ (0x4000) -#define CY_AN_MEM_P0_DRQ_MASK_MEP15DRQ (0x8000) - -#define CY_AN_MEM_P0_EP2_DMA_REG (0xA2) -#define CY_AN_MEM_P0_E_pn_DMA_REG_COUNT_MASK (0x7FF) -#define CY_AN_MEM_P0_E_pn_DMA_REG_DMAVAL (1 << 12) -#define CY_AN_MEM_P0_EP3_DMA_REG (0xA3) -#define CY_AN_MEM_P0_EP4_DMA_REG (0xA4) -#define CY_AN_MEM_P0_EP5_DMA_REG (0xA5) -#define CY_AN_MEM_P0_EP6_DMA_REG (0xA6) -#define CY_AN_MEM_P0_EP7_DMA_REG (0xA7) -#define CY_AN_MEM_P0_EP8_DMA_REG (0xA8) -#define CY_AN_MEM_P0_EP9_DMA_REG (0xA9) -#define CY_AN_MEM_P0_EP10_DMA_REG (0xAA) -#define CY_AN_MEM_P0_EP11_DMA_REG (0xAB) -#define CY_AN_MEM_P0_EP12_DMA_REG (0xAC) -#define CY_AN_MEM_P0_EP13_DMA_REG (0xAD) -#define CY_AN_MEM_P0_EP14_DMA_REG (0xAE) -#define CY_AN_MEM_P0_EP15_DMA_REG (0xAF) - -#define CY_AN_MEM_IROS_IO_CFG (0xC1) -#define CY_AN_MEM_IROS_IO_CFG_GPIODRVST_MASK (0x0003) -#define CY_AN_MEM_IROS_IO_CFG_GPIOSLEW_MASK (0x0004) -#define CY_AN_MEM_IROS_IO_CFG_PPIODRVST_MASK (0x0018) -#define CY_AN_MEM_IROS_IO_CFG_PPIOSLEW_MASK (0x0020) -#define CY_AN_MEM_IROS_IO_CFG_SSIODRVST_MASK (0x0300) -#define CY_AN_MEM_IROS_IO_CFG_SSIOSLEW_MASK (0x0400) -#define CY_AN_MEM_IROS_IO_CFG_SNIODRVST_MASK (0x1800) -#define CY_AN_MEM_IROS_IO_CFG_SNIOSLEW_MASK (0x2000) - -#define CY_AN_MEM_PLL_LOCK_LOSS_STAT (0xC4) -#define CY_AN_MEM_PLL_LOCK_LOSS_STAT_PLLSTAT (0x0800) - -#define CY_AN_MEM_P0_MAILBOX0 (0xF0) -#define CY_AN_MEM_P0_MAILBOX1 (0xF1) -#define CY_AN_MEM_P0_MAILBOX2 (0xF2) -#define CY_AN_MEM_P0_MAILBOX3 (0xF3) - -#define CY_AN_MEM_MCU_MAILBOX0 (0xF8) -#define CY_AN_MEM_MCU_MAILBOX1 (0xF9) -#define CY_AN_MEM_MCU_MAILBOX2 (0xFA) -#define CY_AN_MEM_MCU_MAILBOX3 (0xFB) - -#endif /* !defined(__doxygen__) */ - -#endif /* _INCLUDED_CYANREG_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyansdkversion.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyansdkversion.h deleted file mode 100644 index ac26b9556dda..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyansdkversion.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Cypress Antioch Sdk Version file (cyansdkversion.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYANSDK_VERSION_H_ -#define _INCLUDED_CYANSDK_VERSION_H_ - -/* Antioch SDK version 1.3.2 */ -#define CYAN_MAJOR_VERSION (1) -#define CYAN_MINOR_VERSION (3) -#define CYAN_BUILD_NUMBER (473) - -#endif /*_INCLUDED_CYANSDK_VERSION_H_*/ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanstorage.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanstorage.h deleted file mode 100644 index deb9af87fff4..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanstorage.h +++ /dev/null @@ -1,419 +0,0 @@ -/* Cypress West Bridge API header file (cyanstorage.h) - ## Header for backward compatibility with previous releases of Antioch SDK. -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYANSTORAGE_H_ -#define _INCLUDED_CYANSTORAGE_H_ -#ifndef __doxygen__ - -#include "cyanmedia.h" -#include "cyanmisc.h" -#include "cyasstorage.h" -#include "cyas_cplus_start.h" - -#define CY_AN_LUN_PHYSICAL_DEVICE (CY_AS_LUN_PHYSICAL_DEVICE) -#define CY_AN_STORAGE_EP_SIZE (CY_AS_STORAGE_EP_SIZE) - -#define cy_an_storage_antioch cy_as_storage_antioch -#define cy_an_storage_processor cy_as_storage_processor -#define cy_an_storage_removed cy_as_storage_removed -#define cy_an_storage_inserted cy_as_storage_inserted -#define cy_an_sdio_interrupt cy_as_sdio_interrupt -typedef cy_as_storage_event cy_an_storage_event; - -#define cy_an_op_read cy_as_op_read -#define cy_an_op_write cy_as_op_write -typedef cy_as_oper_type cy_an_oper_type; - -typedef cy_as_device_desc cy_an_device_desc; - -typedef cy_as_unit_desc cy_an_unit_desc; - -typedef cy_as_storage_callback_dep \ - cy_an_storage_callback; - -typedef cy_as_storage_event_callback_dep \ - cy_an_storage_event_callback; - -#define cy_an_sd_reg_OCR cy_as_sd_reg_OCR -#define cy_an_sd_reg_CID cy_as_sd_reg_CID -#define cy_an_sd_reg_CSD cy_as_sd_reg_CSD -typedef cy_as_sd_card_reg_type \ - cy_an_sd_card_reg_type; - -typedef cy_as_storage_query_device_data_dep \ - cy_an_storage_query_device_data; - -typedef cy_as_storage_query_unit_data_dep \ - cy_an_storage_query_unit_data; - -typedef cy_as_storage_sd_reg_read_data \ - cy_an_storage_sd_reg_read_data; - -#define CY_AN_SD_REG_OCR_LENGTH (CY_AS_SD_REG_OCR_LENGTH) -#define CY_AN_SD_REG_CID_LENGTH (CY_AS_SD_REG_CID_LENGTH) -#define CY_AN_SD_REG_CSD_LENGTH (CY_AS_SD_REG_CSD_LENGTH) -#define CY_AN_SD_REG_MAX_RESP_LENGTH \ - (CY_AS_SD_REG_MAX_RESP_LENGTH) - -/**** API Functions ******/ - -/* Sync version of Storage Start */ -EXTERN cy_an_return_status_t -cy_an_storage_start( - cy_an_device_handle handle - ); -#define cy_an_storage_start(handle) \ - cy_as_storage_start((cy_as_device_handle)(handle), 0, 0) - -/* Async version of Storage Start */ -EXTERN cy_an_return_status_t -cy_an_storage_start_e_x( - cy_an_device_handle handle, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_storage_start_e_x(h, cb, client) \ - cy_as_storage_start((cy_as_device_handle)(h), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of Storage Stop */ -EXTERN cy_an_return_status_t -cy_an_storage_stop( - cy_an_device_handle handle - ); -#define cy_an_storage_stop(handle) \ - cy_as_storage_stop((cy_as_device_handle)(handle), 0, 0) - -/* Async version of Storage Stop */ -EXTERN cy_an_return_status_t -cy_an_storage_stop_e_x( - cy_an_device_handle handle, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_storage_stop_e_x(h, cb, client) \ - cy_as_storage_stop((cy_as_device_handle)(h), \ - (cy_as_function_callback)(cb), (client)) - -/* Register Call back api */ -EXTERN cy_an_return_status_t -cy_an_storage_register_callback( - cy_an_device_handle handle, - cy_an_storage_event_callback callback - ); -#define cy_an_storage_register_callback(h, cb) \ - cy_as_storage_register_callback_dep((cy_as_device_handle)(h), \ - (cy_as_storage_event_callback_dep)(cb)) - -/* Sync version of Storage Claim */ -EXTERN cy_an_return_status_t -cy_an_storage_claim( - cy_an_device_handle handle, - cy_an_media_type type - ); -#define cy_an_storage_claim(h, type) \ - cy_as_storage_claim_dep((cy_as_device_handle)(h), \ - (cy_as_media_type)(type)) - -/* Async version of Storage Claim */ -EXTERN cy_an_return_status_t -cy_an_storage_claim_e_x( - cy_an_device_handle handle, - cy_an_media_type *type, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_storage_claim_e_x(h, type_p, cb, client) \ - cy_as_storage_claim_dep_EX((cy_as_device_handle)(h), \ - (cy_as_media_type *)(type_p), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync Version of Storage Release */ -EXTERN cy_an_return_status_t -cy_an_storage_release( - cy_an_device_handle handle, - cy_an_media_type type - ); -#define cy_an_storage_release(h, type) \ - cy_as_storage_release_dep((cy_as_device_handle)(h), \ - (cy_as_media_type)(type)) - -/* Async Version of Storage Release */ -EXTERN cy_an_return_status_t -cy_an_storage_release_e_x( - cy_an_device_handle handle, - cy_an_media_type *type, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_storage_release_e_x(h, type_p, cb, client) \ - cy_as_storage_release_dep_EX((cy_as_device_handle)(h), \ - (cy_as_media_type *)(type_p), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of Query Media */ -EXTERN cy_an_return_status_t -cy_an_storage_query_media( - cy_an_device_handle handle, - cy_an_media_type type, - uint32_t *count - ); -#define cy_an_storage_query_media(handle, type, count) \ - cy_as_storage_query_media((cy_as_device_handle)(handle), \ - (cy_as_media_type)(type), (count), 0, 0) - -/* Async version of Query Media */ -EXTERN cy_an_return_status_t -cy_an_storage_query_media_e_x( - cy_an_device_handle handle, - cy_an_media_type type, - uint32_t *count, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_storage_query_media_e_x(h, type, count, cb, client) \ - cy_as_storage_query_media((cy_as_device_handle)(h), \ - (cy_as_media_type)(type), (count), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of Query device */ -EXTERN cy_an_return_status_t -cy_an_storage_query_device( - cy_an_device_handle handle, - cy_an_media_type type, - uint32_t device, - cy_an_device_desc *desc_p - ); -#define cy_an_storage_query_device(h, type, device, desc_p) \ - cy_as_storage_query_device_dep((cy_as_device_handle)(h), \ - (cy_as_media_type)(type), (device), (cy_as_device_desc *)(desc_p)) - -/* Async version of Query device */ -EXTERN cy_an_return_status_t -cy_an_storage_query_device_e_x( - cy_an_device_handle handle, - cy_an_storage_query_device_data *data, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_storage_query_device_e_x(h, data, cb, client) \ - cy_as_storage_query_device_dep_EX((cy_as_device_handle)(h), \ - (cy_as_storage_query_device_data_dep *)(data), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of Query Unit */ -EXTERN cy_an_return_status_t -cy_an_storage_query_unit( - cy_an_device_handle handle, - cy_an_media_type type, - uint32_t device, - uint32_t unit, - cy_an_unit_desc *desc_p - ); -#define cy_an_storage_query_unit(h, type, device, unit, desc_p) \ - cy_as_storage_query_unit_dep((cy_as_device_handle)(h), \ - (cy_as_media_type)(type), (device), \ - (unit), (cy_as_unit_desc *)(desc_p)) - -/* Async version of Query Unit */ -EXTERN cy_an_return_status_t -cy_an_storage_query_unit_e_x( - cy_an_device_handle handle, - cy_an_storage_query_unit_data *data_p, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_storage_query_unit_e_x(h, data_p, cb, client) \ - cy_as_storage_query_unit_dep_EX((cy_as_device_handle)(h), \ - (cy_as_storage_query_unit_data_dep *)(data_p), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of device control */ -EXTERN cy_an_return_status_t -cy_an_storage_device_control( - cy_an_device_handle handle, - cy_bool card_detect_en, - cy_bool write_prot_en - ); -#define cy_an_storage_device_control(handle, \ - card_detect_en, write_prot_en) \ - cy_as_storage_device_control_dep((cy_as_device_handle)(handle), \ - (card_detect_en), (write_prot_en), 0, 0) - -/* Async version of device control */ -EXTERN cy_an_return_status_t -cy_an_storage_device_control_e_x( - cy_an_device_handle handle, - cy_bool card_detect_en, - cy_bool write_prot_en, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_storage_device_control_e_x(h, det_en, prot_en, cb, client) \ - cy_as_storage_device_control_dep((cy_as_device_handle)(h), (det_en), \ - (prot_en), (cy_as_function_callback)(cb), (client)) - -/* Sync Read */ -EXTERN cy_an_return_status_t -cy_an_storage_read( - cy_an_device_handle handle, - cy_an_media_type type, - uint32_t device, - uint32_t unit, - uint32_t block, - void *data_p, - uint16_t num_blocks - ); -#define cy_an_storage_read(h, type, device, unit, block, data_p, nblks) \ - cy_as_storage_read_dep((cy_as_device_handle)(h), \ - (cy_as_media_type)(type), (device), (unit), \ - (block), (data_p), (nblks)) - -/* Async Read */ -EXTERN cy_an_return_status_t -cy_an_storage_read_async( - cy_an_device_handle handle, - cy_an_media_type type, - uint32_t device, - uint32_t unit, - uint32_t block, - void *data_p, - uint16_t num_blocks, - cy_an_storage_callback callback - ); -#define cy_an_storage_read_async(h, type, device, unit, \ - block, data_p, nblks, cb) \ - cy_as_storage_read_async_dep((cy_as_device_handle)(h), \ - (cy_as_media_type)(type), (device), (unit), (block), \ - (data_p), (nblks), (cy_as_storage_callback_dep)(cb)) - -/* Sync Write */ -EXTERN cy_an_return_status_t -cy_an_storage_write( - cy_an_device_handle handle, - cy_an_media_type type, - uint32_t device, - uint32_t unit, - uint32_t block, - void *data_p, - uint16_t num_blocks - ); -#define cy_an_storage_write(h, type, device, unit, \ - block, data_p, nblks) \ - cy_as_storage_write_dep((cy_as_device_handle)(h), \ - (cy_as_media_type)(type), (device), (unit), \ - (block), (data_p), (nblks)) - -/* Async Write */ -EXTERN cy_an_return_status_t -cy_an_storage_write_async( - cy_an_device_handle handle, - cy_an_media_type type, - uint32_t device, - uint32_t unit, - uint32_t block, - void *data_p, - uint16_t num_blocks, - cy_an_storage_callback callback - ); -#define cy_an_storage_write_async(h, type, device, unit, \ - block, data_p, nblks, cb) \ - cy_as_storage_write_async_dep((cy_as_device_handle)(h), \ - (cy_as_media_type)(type), (device), (unit), (block), \ - (data_p), (nblks), (cy_as_storage_callback_dep)(cb)) - -/* Cancel Async */ -EXTERN cy_an_return_status_t -cy_an_storage_cancel_async( - cy_an_device_handle handle - ); -#define cy_an_storage_cancel_async(h) \ - cy_as_storage_cancel_async((cy_as_device_handle)(h)) - -/* Sync SD Register Read*/ -EXTERN cy_an_return_status_t -cy_an_storage_sd_register_read( - cy_an_device_handle handle, - cy_an_media_type type, - uint8_t device, - cy_an_sd_card_reg_type reg_type, - uint8_t read_len, - uint8_t *data_p - ); -#define cy_an_storage_sd_register_read(h, type, device, \ - reg_type, len, data_p) \ - cy_as_storage_sd_register_read_dep((cy_as_device_handle)(h), \ - (cy_as_media_type)(type), (device), \ - (cy_as_sd_card_reg_type)(reg_type), (len), (data_p)) - -/*Async SD Register Read*/ -EXTERN cy_an_return_status_t -cy_an_storage_sd_register_read_e_x( - cy_an_device_handle handle, - cy_an_media_type type, - uint8_t device, - cy_an_sd_card_reg_type reg_type, - cy_an_storage_sd_reg_read_data *data_p, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_storage_sd_register_read_e_x(h, type, device, \ - reg_type, data_p, cb, client) \ - cy_as_storage_sd_register_read_dep_EX((cy_as_device_handle)(h), \ - (cy_as_media_type)(type), (device), \ - (cy_as_sd_card_reg_type)(reg_type), \ - (cy_as_storage_sd_reg_read_data *)(data_p), \ - (cy_as_function_callback)(cb), (client)) - -/* Create partition on storage device */ -EXTERN cy_an_return_status_t -cy_an_storage_create_p_partition( - cy_an_device_handle handle, - cy_an_media_type media, - uint32_t device, - uint32_t size, - cy_an_function_callback cb, - uint32_t client); -#define cy_an_storage_create_p_partition(h, media, dev, \ - size, cb, client) \ - cy_as_storage_create_p_partition_dep((cy_as_device_handle)(h), \ - (cy_as_media_type)(media), (dev), \ - (size), (cy_as_function_callback)(cb), (client)) - -/* Remove partition on storage device */ -EXTERN cy_an_return_status_t -cy_an_storage_remove_p_partition( - cy_an_device_handle handle, - cy_an_media_type media, - uint32_t device, - cy_an_function_callback cb, - uint32_t client); -#define cy_an_storage_remove_p_partition\ -(h, media, dev, cb, client) \ - cy_as_storage_remove_p_partition_dep((cy_as_device_handle)(h), \ - (cy_as_media_type)(media), (dev), \ - (cy_as_function_callback)(cb), (client)) - -#include "cyas_cplus_end.h" -#endif /*__doxygen__ */ - -#endif diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyantioch.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyantioch.h deleted file mode 100644 index d65b35a14ae1..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyantioch.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Cypress West Bridge API header file (cyastioch.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYANTIOCH_H_ -#define _INCLUDED_CYANTIOCH_H_ - -#if !defined(__doxygen__) - -#include "cyanerr.h" -#include "cyanmisc.h" -#include "cyanstorage.h" -#include "cyanusb.h" -#include "cyanch9.h" - -#endif - -#endif diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyantypes.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyantypes.h deleted file mode 100644 index 48cd50f13c12..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyantypes.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Cypress West Bridge API header file (cyantypes.h) -## Type definitions for backward compatibility with previous -## Antioch SDK releases. -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYANTYPES_H_ -#define _INCLUDED_CYANTYPES_H_ - -#include "cyastypes.h" -typedef cy_as_end_point_number_t cy_an_end_point_number_t; -typedef cy_as_return_status_t cy_an_return_status_t; -typedef cy_as_bus_number_t cy_an_bus_number_t; -#endif diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanusb.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanusb.h deleted file mode 100644 index 1e4e7dbe31b0..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyanusb.h +++ /dev/null @@ -1,619 +0,0 @@ -/* Cypress West Bridge API header file (cyanusb.h) - ## Header for backward compatibility with previous Antioch SDK releases. -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYANUSB_H_ -#define _INCLUDED_CYANUSB_H_ - -#if !defined(__doxygen__) - -#include "cyanmisc.h" -#include "cyasusb.h" -#include "cyas_cplus_start.h" - -#define CY_AN_MAX_USB_DESCRIPTOR_SIZE (CY_AS_MAX_USB_DESCRIPTOR_SIZE) - -typedef cy_as_usb_inquiry_data_dep cy_an_usb_inquiry_data; -typedef cy_as_usb_unknown_command_data_dep \ - cy_an_usb_unknown_command_data; -typedef cy_as_usb_start_stop_data_dep cy_an_usb_start_stop_data; -typedef cy_as_m_s_c_progress_data cy_an_m_s_c_progress_data; - -#define cy_an_usb_nand_enum cy_as_usb_nand_enum -#define cy_an_usb_sd_enum cy_as_usb_sd_enum -#define cy_an_usb_mmc_enum cy_as_usb_mmc_enum -#define cy_an_usb_ce_ata_enum cy_as_usb_ce_ata_enum -typedef cy_as_usb_mass_storage_enum cy_an_usb_mass_storage_enum; - -#define cy_an_usb_desc_device cy_as_usb_desc_device -#define cy_an_usb_desc_device_qual cy_as_usb_desc_device_qual -#define cy_an_usb_desc_f_s_configuration \ - cy_as_usb_desc_f_s_configuration -#define cy_an_usb_desc_h_s_configuration \ - cy_as_usb_desc_h_s_configuration -#define cy_an_usb_desc_string cy_as_usb_desc_string -typedef cy_as_usb_desc_type cy_an_usb_desc_type; - -#define cy_an_usb_in cy_as_usb_in -#define cy_an_usb_out cy_as_usb_out -#define cy_an_usb_in_out cy_as_usb_in_out -typedef cy_as_usb_end_point_dir cy_an_usb_end_point_dir; - - -#define cy_an_usb_control cy_as_usb_control -#define cy_an_usb_iso cy_as_usb_iso -#define cy_an_usb_bulk cy_as_usb_bulk -#define cy_an_usb_int cy_as_usb_int -typedef cy_as_usb_end_point_type cy_an_usb_end_point_type; - - -typedef cy_as_usb_enum_control_dep cy_an_usb_enum_control; -typedef cy_as_usb_end_point_config cy_an_usb_end_point_config; - -#define cy_an_usb_m_s_unit0 cy_as_usb_m_s_unit0 -#define cy_an_usb_m_s_unit1 cy_as_usb_m_s_unit1 -#define cy_an_usb_m_s_both cy_as_usb_m_s_both -typedef cy_as_usb_m_s_type_t cy_an_usb_m_s_type_t; - -#define cy_an_event_usb_suspend cy_as_event_usb_suspend -#define cy_an_event_usb_resume cy_as_event_usb_resume -#define cy_an_event_usb_reset cy_as_event_usb_reset -#define cy_an_event_usb_set_config cy_as_event_usb_set_config -#define cy_an_event_usb_speed_change cy_as_event_usb_speed_change -#define cy_an_event_usb_setup_packet cy_as_event_usb_setup_packet -#define cy_an_event_usb_status_packet cy_as_event_usb_status_packet -#define cy_an_event_usb_inquiry_before cy_as_event_usb_inquiry_before -#define cy_an_event_usb_inquiry_after cy_as_event_usb_inquiry_after -#define cy_an_event_usb_start_stop cy_as_event_usb_start_stop -#define cy_an_event_usb_unknown_storage cy_as_event_usb_unknown_storage -#define cy_an_event_usb_m_s_c_progress cy_as_event_usb_m_s_c_progress -typedef cy_as_usb_event cy_an_usb_event; - -typedef cy_as_usb_event_callback_dep cy_an_usb_event_callback; - -typedef cy_as_usb_io_callback cy_an_usb_io_callback; -typedef cy_as_usb_function_callback cy_an_usb_function_callback; - -/******* USB Functions ********************/ - -/* Sync Usb Start */ -extern cy_an_return_status_t -cy_an_usb_start( - cy_an_device_handle handle - ); -#define cy_an_usb_start(handle) \ - cy_as_usb_start((cy_as_device_handle)(handle), 0, 0) - -/*Async Usb Start */ -extern cy_an_return_status_t -cy_an_usb_start_e_x( - cy_an_device_handle handle, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_start_e_x(h, cb, client) \ - cy_as_usb_start((cy_as_device_handle)(h), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync Usb Stop */ -extern cy_an_return_status_t -cy_an_usb_stop( - cy_an_device_handle handle - ); -#define cy_an_usb_stop(handle) \ - cy_as_usb_stop((cy_as_device_handle)(handle), 0, 0) - -/*Async Usb Stop */ -extern cy_an_return_status_t -cy_an_usb_stop_e_x( - cy_an_device_handle handle, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_stop_e_x(h, cb, client) \ - cy_as_usb_stop((cy_as_device_handle)(h), \ - (cy_as_function_callback)(cb), (client)) - -/* Register USB event callback */ -EXTERN cy_an_return_status_t -cy_an_usb_register_callback( - cy_an_device_handle handle, - cy_an_usb_event_callback callback - ); -#define cy_an_usb_register_callback(h, cb) \ - cy_as_usb_register_callback_dep((cy_as_device_handle)(h), \ - (cy_as_usb_event_callback_dep)(cb)) - -/*Sync Usb connect */ -EXTERN cy_an_return_status_t -cy_an_usb_connect( - cy_an_device_handle handle - ); -#define cy_an_usb_connect(handle) \ - cy_as_usb_connect((cy_as_device_handle)(handle), 0, 0) - -/*Async Usb connect */ -extern cy_an_return_status_t -cy_an_usb_connect_e_x( - cy_an_device_handle handle, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_connect_e_x(h, cb, client) \ - cy_as_usb_connect((cy_as_device_handle)(h), \ - (cy_as_function_callback)(cb), (client)) - -/*Sync Usb disconnect */ -EXTERN cy_an_return_status_t -cy_an_usb_disconnect( - cy_an_device_handle handle - ); -#define cy_an_usb_disconnect(handle) \ - cy_as_usb_disconnect((cy_as_device_handle)(handle), 0, 0) - -/*Async Usb disconnect */ -extern cy_an_return_status_t -cy_an_usb_disconnect_e_x( - cy_an_device_handle handle, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_disconnect_e_x(h, cb, client) \ - cy_as_usb_disconnect((cy_as_device_handle)(h), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of set enum config */ -EXTERN cy_an_return_status_t -cy_an_usb_set_enum_config( - cy_an_device_handle handle, - cy_an_usb_enum_control *config_p - ); -#define cy_an_usb_set_enum_config(handle, config_p) \ - cy_as_usb_set_enum_config_dep((cy_as_device_handle)(handle), \ - (cy_as_usb_enum_control_dep *)(config_p), 0, 0) - -/* Async version of set enum config */ -extern cy_an_return_status_t -cy_an_usb_set_enum_config_e_x( - cy_an_device_handle handle, - cy_an_usb_enum_control *config_p, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_set_enum_config_e_x(h, config_p, cb, client) \ - cy_as_usb_set_enum_config_dep((cy_as_device_handle)(h), \ - (cy_as_usb_enum_control_dep *)(config_p), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of get enum config */ -EXTERN cy_an_return_status_t -cy_an_usb_get_enum_config( - cy_an_device_handle handle, - cy_an_usb_enum_control *config_p - ); -#define cy_an_usb_get_enum_config(handle, config_p) \ - cy_as_usb_get_enum_config_dep((cy_as_device_handle)(handle), \ - (cy_as_usb_enum_control_dep *)(config_p), 0, 0) - -/* Async version of get enum config */ -extern cy_an_return_status_t -cy_an_usb_get_enum_config_e_x( - cy_an_device_handle handle, - cy_an_usb_enum_control *config_p, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_get_enum_config_e_x(h, config_p, cb, client) \ - cy_as_usb_get_enum_config_dep((cy_as_device_handle)(h), \ - (cy_as_usb_enum_control_dep *)(config_p), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync Version of Set descriptor */ -EXTERN cy_an_return_status_t -cy_an_usb_set_descriptor( - cy_an_device_handle handle, - cy_an_usb_desc_type type, - uint8_t index, - void *desc_p, - uint16_t length - ); -#define cy_an_usb_set_descriptor(handle, type, index, desc_p, length) \ - cy_as_usb_set_descriptor((cy_as_device_handle)(handle), \ - (cy_as_usb_desc_type)(type), (index), (desc_p), (length), 0, 0) - -/* Async Version of Set descriptor */ -extern cy_an_return_status_t -cy_an_usb_set_descriptor_e_x( - cy_an_device_handle handle, - cy_an_usb_desc_type type, - uint8_t index, - void *desc_p, - uint16_t length, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_set_descriptor_e_x\ - (h, type, index, desc_p, length, cb, client) \ - cy_as_usb_set_descriptor((cy_as_device_handle)(h), \ - (cy_as_usb_desc_type)(type), (index), (desc_p), (length), \ - (cy_as_function_callback)(cb), (client)) - -/* Only version of clear descriptors */ -EXTERN cy_an_return_status_t -cy_an_usb_clear_descriptors( - cy_an_device_handle handle, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_clear_descriptors(h, cb, client) \ - cy_as_usb_clear_descriptors((cy_as_device_handle)(h), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of get descriptor*/ -EXTERN cy_an_return_status_t -cy_an_usb_get_descriptor( - cy_an_device_handle handle, - cy_an_usb_desc_type type, - uint8_t index, - void *desc_p, - uint32_t *length_p - ); -#define cy_an_usb_get_descriptor(h, type, index, desc_p, length_p) \ - cy_as_usb_get_descriptor_dep((cy_as_device_handle)(h), \ - (cy_as_usb_desc_type)(type), (index), (desc_p), (length_p)) - -typedef cy_as_get_descriptor_data cy_an_get_descriptor_data; - -/* Async version of get descriptor */ -extern cy_an_return_status_t -cy_an_usb_get_descriptor_e_x( - cy_an_device_handle handle, - cy_an_usb_desc_type type, - uint8_t index, - cy_an_get_descriptor_data *data, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_get_descriptor_e_x\ - (h, type, index, data, cb, client) \ - cy_as_usb_get_descriptor((cy_as_device_handle)(h), \ - (cy_as_usb_desc_type)(type), (index), \ - (cy_as_get_descriptor_data *)(data), \ - (cy_as_function_callback)(cb), (client)) - -EXTERN cy_an_return_status_t -cy_an_usb_set_physical_configuration( - cy_an_device_handle handle, - uint8_t config - ); -#define cy_an_usb_set_physical_configuration(h, config) \ - cy_as_usb_set_physical_configuration\ - ((cy_as_device_handle)(h), (config)) - -EXTERN cy_an_return_status_t -cy_an_usb_set_end_point_config( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_an_usb_end_point_config *config_p - ); -#define cy_an_usb_set_end_point_config(h, ep, config_p) \ - cy_as_usb_set_end_point_config((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), \ - (cy_as_usb_end_point_config *)(config_p)) - -EXTERN cy_an_return_status_t -cy_an_usb_get_end_point_config( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_an_usb_end_point_config *config_p - ); -#define cy_an_usb_get_end_point_config(h, ep, config_p) \ - cy_as_usb_get_end_point_config((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), \ - (cy_as_usb_end_point_config *)(config_p)) - -/* Sync version of commit */ -EXTERN cy_an_return_status_t -cy_an_usb_commit_config( - cy_an_device_handle handle - ); -#define cy_an_usb_commit_config(handle) \ - cy_as_usb_commit_config((cy_as_device_handle)(handle), 0, 0) - -/* Async version of commit */ -extern cy_an_return_status_t -cy_an_usb_commit_config_e_x( - cy_an_device_handle handle, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_commit_config_e_x(h, cb, client) \ - cy_as_usb_commit_config((cy_as_device_handle)(h), \ - (cy_as_function_callback)(cb), (client)) - -EXTERN cy_an_return_status_t -cy_an_usb_read_data( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_bool pktread, - uint32_t dsize, - uint32_t *dataread, - void *data - ); -#define cy_an_usb_read_data(h, ep, pkt, dsize, dataread, data_p) \ - cy_as_usb_read_data((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), (pkt), (dsize), \ - (dataread), (data_p)) - -EXTERN cy_an_return_status_t -cy_an_usb_read_data_async( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_bool pktread, - uint32_t dsize, - void *data, - cy_an_usb_io_callback callback - ); -#define cy_an_usb_read_data_async(h, ep, pkt, dsize, data_p, cb) \ - cy_as_usb_read_data_async((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), (pkt), (dsize), (data_p), \ - (cy_as_usb_io_callback)(cb)) - -EXTERN cy_an_return_status_t -cy_an_usb_write_data( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - uint32_t dsize, - void *data - ); -#define cy_an_usb_write_data(h, ep, dsize, data_p) \ - cy_as_usb_write_data((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), (dsize), (data_p)) - -EXTERN cy_an_return_status_t -cy_an_usb_write_data_async( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - uint32_t dsize, - void *data, - cy_bool spacket, - cy_an_usb_io_callback callback - ); -#define cy_an_usb_write_data_async(h, ep, dsize, data_p, spacket, cb) \ - cy_as_usb_write_data_async((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), (dsize), (data_p), (spacket), \ - (cy_as_usb_io_callback)(cb)) - -EXTERN cy_an_return_status_t -cy_an_usb_cancel_async( - cy_an_device_handle handle, - cy_an_end_point_number_t ep - ); -#define cy_an_usb_cancel_async(h, ep) \ - cy_as_usb_cancel_async((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep)) - -/* Sync version of set stall */ -EXTERN cy_an_return_status_t -cy_an_usb_set_stall( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_an_usb_function_callback cb, - uint32_t client -); -#define cy_an_usb_set_stall(h, ep, cb, client) \ - cy_as_usb_set_stall_dep((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), \ - (cy_as_usb_function_callback)(cb), (client)) - -/* Async version of set stall */ -extern cy_an_return_status_t -cy_an_usb_set_stall_e_x( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_an_function_callback cb, - uint32_t client -); -#define cy_an_usb_set_stall_e_x(h, ep, cb, client) \ - cy_as_usb_set_stall((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), \ - (cy_as_function_callback)(cb), (client)) - -/*Sync version of clear stall */ -EXTERN cy_an_return_status_t -cy_an_usb_clear_stall( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_an_usb_function_callback cb, - uint32_t client - ); -#define cy_an_usb_clear_stall(h, ep, cb, client) \ - cy_as_usb_clear_stall_dep((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), \ - (cy_as_usb_function_callback)(cb), (client)) - -/*Sync version of clear stall */ -extern cy_an_return_status_t -cy_an_usb_clear_stall_e_x( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_clear_stall_e_x(h, ep, cb, client) \ - cy_as_usb_clear_stall((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync get stall */ -EXTERN cy_an_return_status_t -cy_an_usb_get_stall( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_bool *stall_p - ); -#define cy_an_usb_get_stall(handle, ep, stall_p) \ - cy_as_usb_get_stall((cy_as_device_handle)(handle), \ - (cy_as_end_point_number_t)(ep), (stall_p), 0, 0) - -/* Async get stall */ -extern cy_an_return_status_t -cy_an_usb_get_stall_e_x( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_bool *stall_p, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_get_stall_e_x(h, ep, stall_p, cb, client) \ - cy_as_usb_get_stall((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), (stall_p), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of Set Nak */ -EXTERN cy_an_return_status_t -cy_an_usb_set_nak( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_an_usb_function_callback cb, - uint32_t client -); - -#define cy_an_usb_set_nak(h, ep, cb, client) \ - cy_as_usb_set_nak_dep((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), \ - (cy_as_usb_function_callback)(cb), (client)) - -/* Async version of Set Nak */ -extern cy_an_return_status_t -cy_an_usb_set_nak_e_x( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_an_function_callback cb, - uint32_t client -); -#define cy_an_usb_set_nak_e_x(h, ep, cb, client) \ - cy_as_usb_set_nak((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync version of clear nak */ -EXTERN cy_an_return_status_t -cy_an_usb_clear_nak( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_an_usb_function_callback cb, - uint32_t client - ); -#define cy_an_usb_clear_nak(h, ep, cb, client) \ - cy_as_usb_clear_nak_dep((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), \ - (cy_as_usb_function_callback)(cb), (client)) - -/* Sync version of clear nak */ -extern cy_an_return_status_t -cy_an_usb_clear_nak_e_x( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_clear_nak_e_x(h, ep, cb, client) \ - cy_as_usb_clear_nak((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync Get NAK */ -EXTERN cy_an_return_status_t -cy_an_usb_get_nak( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_bool *nak_p -); -#define cy_an_usb_get_nak(handle, ep, nak_p) \ - cy_as_usb_get_nak((cy_as_device_handle)(handle), \ - (cy_as_end_point_number_t)(ep), (nak_p), 0, 0) - -/* Async Get NAK */ -EXTERN cy_an_return_status_t -cy_an_usb_get_nak_e_x( - cy_an_device_handle handle, - cy_an_end_point_number_t ep, - cy_bool *nak_p, - cy_an_function_callback cb, - uint32_t client -); -#define cy_an_usb_get_nak_e_x(h, ep, nak_p, cb, client) \ - cy_as_usb_get_nak((cy_as_device_handle)(h), \ - (cy_as_end_point_number_t)(ep), (nak_p), \ - (cy_as_function_callback)(cb), (client)) - -/* Sync remote wakup */ -EXTERN cy_an_return_status_t -cy_an_usb_signal_remote_wakeup( - cy_an_device_handle handle - ); -#define cy_an_usb_signal_remote_wakeup(handle) \ - cy_as_usb_signal_remote_wakeup((cy_as_device_handle)(handle), 0, 0) - -/* Async remote wakup */ -EXTERN cy_an_return_status_t -cy_an_usb_signal_remote_wakeup_e_x( - cy_an_device_handle handle, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_signal_remote_wakeup_e_x(h, cb, client) \ - cy_as_usb_signal_remote_wakeup((cy_as_device_handle)(h), \ - (cy_as_function_callback)(cb), (client)) - -/* Only version of SetMSReportThreshold */ -EXTERN cy_an_return_status_t -cy_an_usb_set_m_s_report_threshold( - cy_an_device_handle handle, - uint32_t wr_sectors, - uint32_t rd_sectors, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_set_m_s_report_threshold\ - (h, wr_cnt, rd_cnt, cb, client) \ - cy_as_usb_set_m_s_report_threshold((cy_as_device_handle)(h), \ - wr_cnt, rd_cnt, (cy_as_function_callback)(cb), (client)) - -/* Select storage partitions to be enumerated. */ -EXTERN cy_an_return_status_t -cy_an_usb_select_m_s_partitions( - cy_an_device_handle handle, - cy_an_media_type media, - uint32_t device, - cy_an_usb_m_s_type_t type, - cy_an_function_callback cb, - uint32_t client - ); -#define cy_an_usb_select_m_s_partitions(h, media, dev, type, cb, client) \ - cy_as_usb_select_m_s_partitions_dep((cy_as_device_handle)(h), \ - (cy_as_media_type)(media), (dev), \ - (cy_as_usb_m_s_type_t)(type), (cy_as_function_callback)(cb), (client)) - -#include "cyas_cplus_end.h" -#endif /*__doxygen__*/ -#endif /*_INCLUDED_CYANUSB_H_*/ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_end.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_end.h deleted file mode 100644 index ece44ca34f3b..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_end.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * This file is included at the end of other include files. - * It basically turns off the C++ specific code words that - * insure this code is seen as C code even within - * a C++ compiler. - * - */ - -#ifdef __cplusplus -} -#endif diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_start.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_start.h deleted file mode 100644 index b879cefa9d6b..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyas_cplus_start.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * This file is included after all other headers files, but before any other - * definitions in the file. It basically insures that the definitions within - * the file are seen as C defintions even when compiled by a C++ compiler. - */ - -#ifdef __cplusplus - -extern "C" { - -#endif diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyascast.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyascast.h deleted file mode 100644 index 5f8c852fbb41..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyascast.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Cypress West Bridge API header file (cyascast.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASCAST_H_ -#define _INCLUDED_CYASCAST_H_ - -#ifndef __doxygen__ - -#ifdef _DEBUG -#define cy_cast_int2U_int16(v) \ - (cy_as_hal_assert(v < 65536), (uint16_t)(v)) -#else /* _DEBUG */ -#define cy_cast_int2U_int16(v) ((uint16_t)(v)) -#endif /* _DEBUG */ - -#endif /* __doxygen__ */ -#endif /* _INCLUDED_CYASCAST_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdevice.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdevice.h deleted file mode 100644 index 6452a9070091..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdevice.h +++ /dev/null @@ -1,1057 +0,0 @@ -/* Cypress West Bridge API header file (cyasdevice.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -##Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef __INCLUDED_CYASDEVICE_H__ -#define __INCLUDED_CYASDEVICE_H__ - -#include "cyashal.h" -#include "cyasprotocol.h" -#include "cyasusb.h" -#include "cyasstorage.h" -#include "cyasmtp.h" -#include "cyas_cplus_start.h" - -/*********************************** - * West Bridge Constants - ***********************************/ - -/* The endpoints used by West Bridge for the P port to S port path */ -#define CY_AS_P2S_WRITE_ENDPOINT (0x04) -#define CY_AS_P2S_READ_ENDPOINT (0x08) - -/* The endpoint to use for firmware download */ -#define CY_AS_FIRMWARE_ENDPOINT (0x02) - -/* The maximum size of the firmware image West Bridge can accept */ -#define CY_AS_MAXIMUM_FIRMWARE_SIZE (24 * 1024) - -/* The maximum size of a write for EP0 and EP1 */ -#define CY_AS_EP0_MAX_WRITE_SIZE (128) -#define CY_AS_EP1_MAX_WRITE_SIZE (64) - -/* The bitfields for the device state value */ - -/* The device is in StandBy mode */ -#define CY_AS_DEVICE_STATE_PIN_STANDBY (0x00000001) -/* The device has been configured */ -#define CY_AS_DEVICE_STATE_CONFIGURED (0x00000002) -/* The firmware has been loaded into the device */ -#define CY_AS_DEVICE_STATE_FIRMWARE_LOADED (0x00000004) -/* The interrupt module has been initialized */ -#define CY_AS_DEVICE_STATE_LOWLEVEL_MODULE (0x00000008) -/* The DMA module has been initialized */ -#define CY_AS_DEVICE_STATE_DMA_MODULE (0x00000010) -/* The interrupt module has been initialized */ -#define CY_AS_DEVICE_STATE_INTR_MODULE (0x00000020) -/* The storage module has been initialized */ -#define CY_AS_DEVICE_STATE_STORAGE_MODULE (0x00000040) -/* The USB module has been initialized */ -#define CY_AS_DEVICE_STATE_USB_MODULE (0x00000080) -/* If set, the API wants SCSI messages */ -#define CY_AS_DEVICE_STATE_STORAGE_SCSIMSG (0x00000100) -/* If set, an ASYNC storage operation is pending */ -#define CY_AS_DEVICE_STATE_STORAGE_ASYNC_PENDING (0x00000200) -/* If set, the USB port is connected */ -#define CY_AS_DEVICE_STATE_USB_CONNECTED (0x00000400) -/* If set and USB is connected, it is high speed */ -#define CY_AS_DEVICE_STATE_USB_HIGHSPEED (0x00000800) -/* If set, we are in a callback */ -#define CY_AS_DEVICE_STATE_IN_CALLBACK (0x00001000) -/* If set, we are processing a setup packet */ -#define CY_AS_DEVICE_STATE_IN_SETUP_PACKET (0x00004000) -/* The device was placed in standby via register */ -#define CY_AS_DEVICE_STATE_REGISTER_STANDBY (0x00008000) -/* If set, the device is using a crystal */ -#define CY_AS_DEVICE_STATE_CRYSTAL (0x00010000) -/* If set, wakeup has been called */ -#define CY_AS_DEVICE_STATE_WAKING (0x00020000) -/* If set, EP0 has been stalled. */ -#define CY_AS_DEVICE_STATE_EP0_STALLED (0x00040000) -/* If set, device is in suspend mode. */ -#define CY_AS_DEVICE_STATE_SUSPEND (0x00080000) -/* If set, device is a reset is pending. */ -#define CY_AS_DEVICE_STATE_RESETP (0x00100000) -/* If set, device is a standby is pending. */ -#define CY_AS_DEVICE_STATE_STANDP (0x00200000) -/* If set, device has a storage start or stop pending. */ -#define CY_AS_DEVICE_STATE_SSSP (0x00400000) -/* If set, device has a usb start or stop pending. */ -#define CY_AS_DEVICE_STATE_USSP (0x00800000) -/* If set, device has a mtp start or stop pending. */ -#define CY_AS_DEVICE_STATE_MSSP (0x01000000) -/* If set, P2S DMA transfer can be started. */ -#define CY_AS_DEVICE_STATE_P2SDMA_START (0x02000000) - -/* The bitfields for the endpoint state value */ -/* DMA requests are accepted into the queue */ -#define CY_AS_DMA_ENDPOINT_STATE_ENABLED (0x0001) -/* The endpoint has a sleeping client, waiting on a queue drain */ -#define CY_AS_DMA_ENDPOINT_STATE_SLEEPING (0x0002) -/* The DMA backend to hardware is running */ -#define CY_AS_DMA_ENDPOINT_STATE_DMA_RUNNING (0x0004) -/* There is an outstanding DMA entry deployed to the HAL */ -#define CY_AS_DMA_ENDPOINT_STATE_IN_TRANSIT (0x0008) -/* 0 = OUT (West Bridge -> P Port), 1 = IN (P Port -> West Bridge) */ -#define CY_AS_DMA_ENDPOINT_STATE_DIRECTION (0x0010) - -/* The state values for the request list */ -/* Mask for getting the state information */ -#define CY_AS_REQUEST_LIST_STATE_MASK (0x0f) -/* The request is queued, nothing further */ -#define CY_AS_REQUEST_LIST_STATE_QUEUED (0x00) -/* The request is sent, waiting for response */ -#define CY_AS_REQUEST_LIST_STATE_WAITING (0x01) -/* The response has been received, processing response */ -#define CY_AS_REQUEST_LIST_STATE_RECEIVED (0x02) -/* The request/response is being canceled */ -#define CY_AS_REQUEST_LIST_STATE_CANCELING (0x03) -/* The request is synchronous */ -#define CY_AS_REQUEST_LIST_STATE_SYNC (0x80) - -/* The flag values for a LL RequestResponse */ -/* This request requires an ACK to be sent after it is completed */ -#define CY_AS_REQUEST_RESPONSE_DELAY_ACK (0x01) -/* This request originated from a version V1.1 function call */ -#define CY_AS_REQUEST_RESPONSE_EX (0x02) -/* This request originated from a version V1.2 function call */ -#define CY_AS_REQUEST_RESPONSE_MS (0x04) - - -#define CY_AS_DEVICE_HANDLE_SIGNATURE (0x01211219) - -/* - * This macro returns the endpoint pointer given the - * device pointer and an endpoint number - */ -#define CY_AS_NUM_EP(dev_p, num) ((dev_p)->endp[(num)]) - -/**************************************** - * West Bridge Data Structures - ****************************************/ - -typedef struct cy_as_device cy_as_device; - -/* Summary - This type defines a callback function that will be called - on completion of a DMA operation. - - Description - This function definition is for a function that is called when - the DMA operation is complete. This function is called with the - endpoint number, operation type, buffer pointer and size. - - See Also - * CyAsDmaOper - * CyAsDmaQueueWrite - */ -typedef void (*cy_as_dma_callback)( - /* The device that completed DMA */ - cy_as_device *dev_p, - /* The endpoint that completed DMA */ - cy_as_end_point_number_t ep, - /* The pointer to the buffer that completed DMA */ - void *mem_p, - /* The amount of data transferred */ - uint32_t size, - /* The error code for this DMA xfer */ - cy_as_return_status_t error - ); - -/* Summary - This structure defines a DMA request that is queued - - Description - This structure contains the information about a DMA - request that is queued and is to be sent when possible. -*/ -typedef struct cy_as_dma_queue_entry { - /* Pointer to memory buffer for this request */ - void *buf_p; - /* Size of the memory buffer for DMA operation */ - uint32_t size; - /* Offset into memory buffer for next DMA operation */ - uint32_t offset; - /* If TRUE and IN request */ - cy_bool packet; - /* If TRUE, this is a read request */ - cy_bool readreq; - /* Callback function for when DMA is complete */ - cy_as_dma_callback cb; - /* Pointer to next entry in queue */ - struct cy_as_dma_queue_entry *next_p; -} cy_as_dma_queue_entry; - -/* Summary - This structure defines the endpoint data for a given - - Description - This structure defines all of the information required - to manage DMA for a given endpoint. -*/ -typedef struct cy_as_dma_end_point { - /* The endpoint number */ - cy_as_end_point_number_t ep; - /* The state of this endpoint */ - uint8_t state; - /* The maximum amount of data accepted in a packet by the hw */ - uint16_t maxhwdata; - /* The maximum amount of data accepted by the HAL layer */ - uint32_t maxhaldata; - /* The queue for DMA operations */ - cy_as_dma_queue_entry *queue_p; - /* The last entry in the DMA queue */ - cy_as_dma_queue_entry *last_p; - /* This sleep channel is used to wait while the DMA queue - * drains for a given endpoint */ - cy_as_hal_sleep_channel channel; -} cy_as_dma_end_point; - -#define cy_as_end_point_number_is_usb(n) \ - ((n) != 2 && (n) != 4 && (n) != 6 && (n) != 8) -#define cy_as_end_point_number_is_storage(n) \ - ((n) == 2 || (n) == 4 || (n) == 6 || (n) == 8) - -#define cy_as_dma_end_point_is_enabled(ep) \ - ((ep)->state & CY_AS_DMA_ENDPOINT_STATE_ENABLED) -#define cy_as_dma_end_point_enable(ep) \ - ((ep)->state |= CY_AS_DMA_ENDPOINT_STATE_ENABLED) -#define cy_as_dma_end_point_disable(ep) \ - ((ep)->state &= ~CY_AS_DMA_ENDPOINT_STATE_ENABLED) - -#define cy_as_dma_end_point_is_sleeping(ep) \ - ((ep)->state & CY_AS_DMA_ENDPOINT_STATE_SLEEPING) -#define cy_as_dma_end_point_set_sleep_state(ep) \ - ((ep)->state |= CY_AS_DMA_ENDPOINT_STATE_SLEEPING) -#define cy_as_dma_end_point_set_wake_state(ep) \ - ((ep)->state &= ~CY_AS_DMA_ENDPOINT_STATE_SLEEPING) - -#define cy_as_dma_end_point_is_running(ep) \ - ((ep)->state & CY_AS_DMA_ENDPOINT_STATE_DMA_RUNNING) -#define cy_as_dma_end_point_set_running(ep) \ - ((ep)->state |= CY_AS_DMA_ENDPOINT_STATE_DMA_RUNNING) -#define cy_as_dma_end_point_set_stopped(ep) \ - ((ep)->state &= ~CY_AS_DMA_ENDPOINT_STATE_DMA_RUNNING) - -#define cy_as_dma_end_point_in_transit(ep) \ - ((ep)->state & CY_AS_DMA_ENDPOINT_STATE_IN_TRANSIT) -#define cy_as_dma_end_point_set_in_transit(ep) \ - ((ep)->state |= CY_AS_DMA_ENDPOINT_STATE_IN_TRANSIT) -#define cy_as_dma_end_point_clear_in_transit(ep) \ - ((ep)->state &= ~CY_AS_DMA_ENDPOINT_STATE_IN_TRANSIT) - -#define cy_as_dma_end_point_is_direction_in(ep) \ - (((ep)->state & CY_AS_DMA_ENDPOINT_STATE_DIRECTION) == \ - CY_AS_DMA_ENDPOINT_STATE_DIRECTION) -#define cy_as_dma_end_point_is_direction_out(ep) \ - (((ep)->state & CY_AS_DMA_ENDPOINT_STATE_DIRECTION) == 0) -#define cy_as_dma_end_point_set_direction_in(ep) \ - ((ep)->state |= CY_AS_DMA_ENDPOINT_STATE_DIRECTION) -#define cy_as_dma_end_point_set_direction_out(ep) \ - ((ep)->state &= ~CY_AS_DMA_ENDPOINT_STATE_DIRECTION) - -#define cy_as_dma_end_point_is_usb(p) \ - cy_as_end_point_number_is_usb((p)->ep) -#define cy_as_dma_end_point_is_storage(p) \ - cy_as_end_point_number_is_storage((p)->ep) - -typedef struct cy_as_ll_request_response { - /* The mbox[0] contents - see low level comm section of API doc */ - uint16_t box0; - /* The amount of data stored in this request/response in bytes */ - uint16_t stored; - /* Length of this request in words */ - uint16_t length; - /* Additional status information about the request */ - uint16_t flags; - /* Note: This is over indexed and contains the request/response data */ - uint16_t data[1]; -} cy_as_ll_request_response; - -/* - * The callback function for responses - */ -typedef void (*cy_as_response_callback)( - /* The device that had the response */ - cy_as_device *dev_p, - /* The context receiving a response */ - uint8_t context, - /* The request data */ - cy_as_ll_request_response *rqt, - /* The response data */ - cy_as_ll_request_response *resp, - /* The status of the request */ - cy_as_return_status_t status - ); - -typedef struct cy_as_ll_request_list_node { - /* The request to send */ - cy_as_ll_request_response *rqt; - /* The associated response for the request */ - cy_as_ll_request_response *resp; - /* Length of the response */ - uint16_t length; - /* The callback to call when done */ - cy_as_response_callback callback; - /* The state of the request */ - uint8_t state; - /* The next request in the list */ - struct cy_as_ll_request_list_node *next; -} cy_as_ll_request_list_node; - -#define cy_as_request_get_node_state(node_p) \ - ((node_p)->state & CY_AS_REQUEST_LIST_STATE_MASK) -#define cy_as_request_set_node_state(node_p, st) \ - ((node_p)->state = \ - ((node_p)->state & ~CY_AS_REQUEST_LIST_STATE_MASK) | (st)) - -#define cy_as_request_node_is_sync(node_p) \ - ((node_p)->state & CY_AS_REQUEST_LIST_STATE_SYNC) -#define cy_as_request_node_set_sync(node_p) \ - ((node_p)->state |= CY_AS_REQUEST_LIST_STATE_SYNC) -#define cy_as_request_node_clear_sync(node_p) \ - ((node_p)->state &= ~CY_AS_REQUEST_LIST_STATE_SYNC) - -#ifndef __doxygen__ -typedef enum cy_as_c_b_node_type { - CYAS_INVALID, - CYAS_USB_FUNC_CB, - CYAS_USB_IO_CB, - CYAS_STORAGE_IO_CB, - CYAS_FUNC_CB -} cy_as_c_b_node_type; - -typedef struct cy_as_func_c_b_node { - cy_as_c_b_node_type node_type; - cy_as_function_callback cb_p; - uint32_t client_data; - cy_as_funct_c_b_type data_type; - void *data; - struct cy_as_func_c_b_node *next_p; -} cy_as_func_c_b_node; - -extern cy_as_func_c_b_node* -cy_as_create_func_c_b_node_data(cy_as_function_callback - cb, uint32_t client, cy_as_funct_c_b_type type, void *data); - -extern cy_as_func_c_b_node* -cy_as_create_func_c_b_node(cy_as_function_callback cb, - uint32_t client); - -extern void -cy_as_destroy_func_c_b_node(cy_as_func_c_b_node *node); - -typedef struct cy_as_mtp_func_c_b_node { - cy_as_c_b_node_type type; - cy_as_mtp_function_callback cb_p; - uint32_t client_data; - struct cy_as_mtp_func_c_b_node *next_p; -} cy_as_mtp_func_c_b_node; - -extern cy_as_mtp_func_c_b_node* -cy_as_create_mtp_func_c_b_node(cy_as_mtp_function_callback cb, - uint32_t client); - -extern void -cy_as_destroy_mtp_func_c_b_node(cy_as_mtp_func_c_b_node *node); - -typedef struct cy_as_usb_func_c_b_node { - cy_as_c_b_node_type type; - cy_as_usb_function_callback cb_p; - uint32_t client_data; - struct cy_as_usb_func_c_b_node *next_p; -} cy_as_usb_func_c_b_node; - -extern cy_as_usb_func_c_b_node* -cy_as_create_usb_func_c_b_node(cy_as_usb_function_callback cb, - uint32_t client); - -extern void -cy_as_destroy_usb_func_c_b_node(cy_as_usb_func_c_b_node *node); - -typedef struct cy_as_usb_io_c_b_node { - cy_as_c_b_node_type type; - cy_as_usb_io_callback cb_p; - struct cy_as_usb_io_c_b_node *next_p; -} cy_as_usb_io_c_b_node; - -extern cy_as_usb_io_c_b_node* -cy_as_create_usb_io_c_b_node(cy_as_usb_io_callback cb); - -extern void -cy_as_destroy_usb_io_c_b_node(cy_as_usb_io_c_b_node *node); - -typedef struct cy_as_storage_io_c_b_node { - cy_as_c_b_node_type type; - cy_as_storage_callback cb_p; - /* The media for the currently outstanding async storage request */ - cy_as_media_type media; - /* The device index for the currently outstanding async storage - * request */ - uint32_t device_index; - /* The unit index for the currently outstanding async storage - * request */ - uint32_t unit; - /* The block address for the currently outstanding async storage - * request */ - uint32_t block_addr; - /* The operation for the currently outstanding async storage - * request */ - cy_as_oper_type oper; - cy_as_ll_request_response *req_p; - cy_as_ll_request_response *reply_p; - struct cy_as_storage_io_c_b_node *next_p; -} cy_as_storage_io_c_b_node; - -extern cy_as_storage_io_c_b_node* -cy_as_create_storage_io_c_b_node(cy_as_storage_callback cb, - cy_as_media_type media, uint32_t device_index, - uint32_t unit, uint32_t block_addr, cy_as_oper_type oper, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p); - -extern void -cy_as_destroy_storage_io_c_b_node(cy_as_storage_io_c_b_node *node); - -typedef struct cy_as_c_b_queue { - void *head_p; - void *tail_p; - uint32_t count; - cy_as_c_b_node_type type; -} cy_as_c_b_queue; - -extern cy_as_c_b_queue * -cy_as_create_c_b_queue(cy_as_c_b_node_type type); - -extern void -cy_as_destroy_c_b_queue(cy_as_c_b_queue *queue); - -/* Allocates a new CyAsCBNode */ -extern void -cy_as_insert_c_b_node(cy_as_c_b_queue *queue_p, void *cbnode); - -/* Removes the first CyAsCBNode from the queue and frees it */ -extern void -cy_as_remove_c_b_node(cy_as_c_b_queue *queue_p); - -/* Remove the last CyAsCBNode from the queue and frees it */ -extern void -cy_as_remove_c_b_tail_node(cy_as_c_b_queue *queue_p); - -/* Removes and frees all pending callbacks */ -extern void -cy_as_clear_c_b_queue(cy_as_c_b_queue *queue_p); - -extern cy_as_return_status_t -cy_as_misc_send_request(cy_as_device *dev_p, - cy_as_function_callback cb, - uint32_t client, - cy_as_funct_c_b_type type, - void *data, - cy_as_c_b_queue *queue, - uint16_t req_type, - cy_as_ll_request_response *req_p, - cy_as_ll_request_response *reply_p, - cy_as_response_callback rcb); - -extern void -cy_as_misc_cancel_ex_requests(cy_as_device *dev_p); - -/* Summary - Free all memory allocated by and zero all - structures initialized by CyAsUsbStart. - */ -extern void -cy_as_usb_cleanup( - cy_as_device *dev_p); - -/* Summary - Free all memory allocated and zero all structures initialized - by CyAsStorageStart. - */ -extern void -cy_as_storage_cleanup( - cy_as_device *dev_p); -#endif - -/* Summary - This structure defines the data structure to support a - given command context - - Description - All commands send to the West Bridge device via the mailbox - registers are sent via a context.Each context is independent - and there can be a parallel stream of requests and responses on - each context. This structure is used to manage a single context. -*/ -typedef struct cy_as_context { - /* The context number for this context */ - uint8_t number; - /* This sleep channel is used to sleep while waiting on a - * response from the west bridge device for a request. */ - cy_as_hal_sleep_channel channel; - /* The buffer for received requests */ - cy_as_ll_request_response *req_p; - /* The length of the request being received */ - uint16_t request_length; - /* The callback for the next request received */ - cy_as_response_callback request_callback; - /* A list of low level requests to go to the firmware */ - cy_as_ll_request_list_node *request_queue_p; - /* The list node in the request queue */ - cy_as_ll_request_list_node *last_node_p; - /* Index up to which data is stored. */ - uint16_t queue_index; - /* Index to the next request in the queue. */ - uint16_t rqt_index; - /* Queue of data stored */ - uint16_t data_queue[128]; - -} cy_as_context; - -#define cy_as_context_is_waiting(ctxt) \ - ((ctxt)->state & CY_AS_CTXT_STATE_WAITING_RESPONSE) -#define cy_as_context_set_waiting(ctxt) \ - ((ctxt)->state |= CY_AS_CTXT_STATE_WAITING_RESPONSE) -#define cy_as_context_clear_waiting(ctxt) \ - ((ctxt)->state &= ~CY_AS_CTXT_STATE_WAITING_RESPONSE) - - - -/* Summary - This data structure stores SDIO function - parameters for a SDIO card - - Description -*/ -typedef struct cy_as_sdio_device { - /* Keeps track of IO functions initialized*/ - uint8_t function_init_map; - uint8_t function_suspended_map; - /* Function 0 (Card Common) properties*/ - cy_as_sdio_card card; - /* Function 1-7 (Mapped to array element 0-6) properties.*/ - cy_as_sdio_func function[7]; - -} cy_as_sdio_device; - -/* Summary -Macros to access the SDIO card properties -*/ - -#define cy_as_sdio_get_function_code(handle, bus, i) \ - (((cy_as_device *)handle)->sdiocard[bus].function[i-1].function_code) - -#define cy_as_sdio_get_function_ext_code(handle, bus, i) \ - (((cy_as_device *)handle)->sdiocard[bus].\ - function[i-1].extended_func_code) - -#define cy_as_sdio_get_function_p_s_n(handle, bus, i) \ - (((cy_as_device *)handle)->sdiocard[bus].function[i-1].card_psn) - -#define cy_as_sdio_get_function_blocksize(handle, bus, i) \ - (((cy_as_device *)handle)->sdiocard[bus].function[i-1].blocksize) - -#define cy_as_sdio_get_function_max_blocksize(handle, bus, i) \ - (((cy_as_device *)handle)->sdiocard[bus].function[i-1].maxblocksize) - -#define cy_as_sdio_get_function_csa_support(handle, bus, i) \ - (((cy_as_device *)handle)->sdiocard[bus].function[i-1].csa_bits) - -#define cy_as_sdio_get_function_wakeup_support(handle, bus, i) \ - (((cy_as_device *)handle)->sdiocard[bus].function[i-1]. wakeup_support) - -#define cy_as_sdio_set_function_block_size(handle, bus, i, blocksize) \ - (((cy_as_device *)handle)->sdiocard[bus].function[i-1].blocksize = \ - blocksize) - -#define cy_as_sdio_get_card_num_functions(handle, bus) \ - (((cy_as_device *)handle)->sdiocard[bus].card.num_functions) - -#define cy_as_sdio_get_card_mem_present(handle, bus) \ - (((cy_as_device *)handle)->sdiocard[bus].card.memory_present) - -#define cy_as_sdio_get_card_manf_id(handle, bus) \ - (((cy_as_device *)handle)->sdiocard[bus].card.manufacturer__id) - -#define cy_as_sdio_get_card_manf_info(handle, bus) \ - (((cy_as_device *)handle)->sdiocard[bus].card.manufacturer_info) - -#define cy_as_sdio_get_card_blocksize(handle, bus) \ - (((cy_as_device *)handle)->sdiocard[bus].card.blocksize) - -#define cy_as_sdio_get_card_max_blocksize(handle, bus) \ - (((cy_as_device *)handle)->sdiocard[bus].card.maxblocksize) - -#define cy_as_sdio_get_card_sdio_version(handle, bus) \ - (((cy_as_device *)handle)->sdiocard[bus].card.sdio_version) - -#define cy_as_sdio_get_card_capability(handle, bus) \ - (((cy_as_device *)handle)->sdiocard[bus].card.card_capability) - -#define cy_as_sdio_get_function_init_map(handle, bus) \ - (((cy_as_device *)handle)->sdiocard[bus].function_init_map) - -#define cy_as_sdio_check_function_initialized(handle, bus, i) \ - (((cy_as_sdio_get_function_init_map(handle, bus)) & (0x01<sdiocard[bus].card.blocksize = blocksize) - -#define cy_as_sdio_check_support_bus_suspend(handle, bus) \ - ((cy_as_sdio_get_card_capability(handle, bus) & CY_SDIO_SBS) ? 1 : 0) - -#define cy_as_sdio_check_function_suspended(handle, bus, i) \ - ((((cy_as_device *)handle)->sdiocard[bus].function_suspended_map & \ - (0x01<sdiocard[bus].function_suspended_map) \ - |= (0x01<sdiocard[bus].function_suspended_map) \ - &= (~(0x01<state & CY_AS_DEVICE_STATE_CONFIGURED) -#define cy_as_device_set_configured(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_CONFIGURED) -#define cy_as_device_set_unconfigured(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_CONFIGURED) - -#define cy_as_device_is_dma_running(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_DMA_MODULE) -#define cy_as_device_set_dma_running(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_DMA_MODULE) -#define cy_as_device_set_dma_stopped(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_DMA_MODULE) - -#define cy_as_device_is_low_level_running(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_LOWLEVEL_MODULE) -#define cy_as_device_set_low_level_running(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_LOWLEVEL_MODULE) -#define cy_as_device_set_low_level_stopped(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_LOWLEVEL_MODULE) - -#define cy_as_device_is_intr_running(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_INTR_MODULE) -#define cy_as_device_set_intr_running(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_INTR_MODULE) -#define cy_as_device_set_intr_stopped(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_INTR_MODULE) - -#define cy_as_device_is_firmware_loaded(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_FIRMWARE_LOADED) -#define cy_as_device_set_firmware_loaded(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_FIRMWARE_LOADED) -#define cy_as_device_set_firmware_not_loaded(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_FIRMWARE_LOADED) - -#define cy_as_device_is_storage_running(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_STORAGE_MODULE) -#define cy_as_device_set_storage_running(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_STORAGE_MODULE) -#define cy_as_device_set_storage_stopped(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_STORAGE_MODULE) - -#define cy_as_device_is_usb_running(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_USB_MODULE) -#define cy_as_device_set_usb_running(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_USB_MODULE) -#define cy_as_device_set_usb_stopped(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_USB_MODULE) - -#define cy_as_device_wants_scsi_messages(dp) \ - (((dp)->state & CY_AS_DEVICE_STATE_STORAGE_SCSIMSG) \ - ? cy_true : cy_false) -#define cy_as_device_set_scsi_messages(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_STORAGE_SCSIMSG) -#define cy_as_device_clear_scsi_messages(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_STORAGE_SCSIMSG) - -#define cy_as_device_is_storage_async_pending(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_STORAGE_ASYNC_PENDING) -#define cy_as_device_set_storage_async_pending(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_STORAGE_ASYNC_PENDING) -#define cy_as_device_clear_storage_async_pending(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_STORAGE_ASYNC_PENDING) - -#define cy_as_device_is_usb_connected(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_USB_CONNECTED) -#define cy_as_device_set_usb_connected(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_USB_CONNECTED) -#define cy_as_device_clear_usb_connected(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_USB_CONNECTED) - -#define cy_as_device_is_usb_high_speed(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_USB_HIGHSPEED) -#define cy_as_device_set_usb_high_speed(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_USB_HIGHSPEED) -#define cy_as_device_clear_usb_high_speed(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_USB_HIGHSPEED) - -#define cy_as_device_is_in_callback(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_IN_CALLBACK) -#define cy_as_device_set_in_callback(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_IN_CALLBACK) -#define cy_as_device_clear_in_callback(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_IN_CALLBACK) - -#define cy_as_device_is_setup_i_o_performed(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_SETUP_IO_PERFORMED) -#define cy_as_device_set_setup_i_o_performed(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_SETUP_IO_PERFORMED) -#define cy_as_device_clear_setup_i_o_performed(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_SETUP_IO_PERFORMED) - -#define cy_as_device_is_ack_delayed(dp) \ - ((dp)->usb_delay_ack_count > 0) -#define cy_as_device_set_ack_delayed(dp) \ - ((dp)->usb_delay_ack_count++) -#define cy_as_device_rem_ack_delayed(dp) \ - ((dp)->usb_delay_ack_count--) -#define cy_as_device_clear_ack_delayed(dp) \ - ((dp)->usb_delay_ack_count = 0) - -#define cy_as_device_is_setup_packet(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_IN_SETUP_PACKET) -#define cy_as_device_set_setup_packet(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_IN_SETUP_PACKET) -#define cy_as_device_clear_setup_packet(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_IN_SETUP_PACKET) - -#define cy_as_device_is_ep0_stalled(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_EP0_STALLED) -#define cy_as_device_set_ep0_stalled(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_EP0_STALLED) -#define cy_as_device_clear_ep0_stalled(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_EP0_STALLED) - -#define cy_as_device_is_register_standby(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_REGISTER_STANDBY) -#define cy_as_device_set_register_standby(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_REGISTER_STANDBY) -#define cy_as_device_clear_register_standby(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_REGISTER_STANDBY) - -#define cy_as_device_is_pin_standby(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_PIN_STANDBY) -#define cy_as_device_set_pin_standby(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_PIN_STANDBY) -#define cy_as_device_clear_pin_standby(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_PIN_STANDBY) - -#define cy_as_device_is_crystal(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_CRYSTAL) -#define cy_as_device_is_external_clock(dp) \ - (!((dp)->state & CY_AS_DEVICE_STATE_CRYSTAL)) -#define cy_as_device_set_crystal(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_CRYSTAL) -#define cy_as_device_set_external_clock(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_CRYSTAL) - -#define cy_as_device_is_waking(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_WAKING) -#define cy_as_device_set_waking(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_WAKING) -#define cy_as_device_clear_waking(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_WAKING) - -#define cy_as_device_is_in_suspend_mode(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_SUSPEND) -#define cy_as_device_set_suspend_mode(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_SUSPEND) -#define cy_as_device_clear_suspend_mode(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_SUSPEND) - -#define cy_as_device_is_reset_pending(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_RESETP) -#define cy_as_device_set_reset_pending(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_RESETP) -#define cy_as_device_clear_reset_pending(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_RESETP) - -#define cy_as_device_is_standby_pending(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_STANDP) -#define cy_as_device_set_standby_pending(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_STANDP) -#define cy_as_device_clear_standby_pending(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_STANDP) - -#define cy_as_device_is_s_s_s_pending(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_SSSP) -#define cy_as_device_set_s_s_s_pending(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_SSSP) -#define cy_as_device_clear_s_s_s_pending(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_SSSP) - -#define cy_as_device_is_u_s_s_pending(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_USSP) -#define cy_as_device_set_u_s_s_pending(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_USSP) -#define cy_as_device_clear_u_s_s_pending(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_USSP) - -#define cy_as_device_is_m_s_s_pending(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_MSSP) -#define cy_as_device_set_m_s_s_pending(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_MSSP) -#define cy_as_device_clear_m_s_s_pending(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_MSSP) - -#define cy_as_device_is_p2s_dma_start_recvd(dp) \ - ((dp)->state & CY_AS_DEVICE_STATE_P2SDMA_START) -#define cy_as_device_set_p2s_dma_start_recvd(dp) \ - ((dp)->state |= CY_AS_DEVICE_STATE_P2SDMA_START) -#define cy_as_device_clear_p2s_dma_start_recvd(dp) \ - ((dp)->state &= ~CY_AS_DEVICE_STATE_P2SDMA_START) - -#define cy_as_device_is_usb_async_pending(dp, ep) \ - ((dp)->epasync & (1 << ep)) -#define cy_as_device_set_usb_async_pending(dp, ep) \ - ((dp)->epasync |= (1 << ep)) -#define cy_as_device_clear_usb_async_pending(dp, ep) \ - ((dp)->epasync &= ~(1 << ep)) - -#define cy_as_device_is_nand_storage_supported(dp) \ - ((dp)->media_supported[0] & 1) - -/* Macros to check the type of West Bridge device. */ -#define cy_as_device_is_astoria_dev(dp) \ - (((dp)->silicon_id == CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_VALUE) || \ - ((dp)->silicon_id == CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_FPGA_VALUE)) -#define cy_as_device_is_antioch_dev(dp) \ - ((dp)->silicon_id == CY_AS_MEM_CM_WB_CFG_ID_HDID_ANTIOCH_VALUE) - -#ifdef CY_AS_LOG_SUPPORT -extern void cy_as_log_debug_message(int value, const char *msg); -#else -#define cy_as_log_debug_message(value, msg) -#endif - -/* Summary - This function finds the device object given the HAL tag - - Description - The user associats a device TAG with each West Bridge device - created. This tag is passed from the API functions to and HAL - functions that need to ID a specific West Bridge device. This - tag is also passed in from the user back into the API via - interrupt functions. This function allows the API to find the - device structure associated with a given tag. - - Notes - This function does a simple linear search for the device based - on the TAG. This function is called each time an West Bridge - interrupt handler is called. Therefore this works fine for a - small number of West Bridge devices (e.g. less than five). - Anything more than this and this methodology will need to be - updated. - - Returns - Pointer to a CyAsDevice associated with the tag -*/ -extern cy_as_device * -cy_as_device_find_from_tag( - cy_as_hal_device_tag tag - ); - -#include "cyas_cplus_end.h" - -#endif /* __INCLUDED_CYASDEVICE_H__ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h deleted file mode 100644 index 16dc9f96018c..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasdma.h +++ /dev/null @@ -1,375 +0,0 @@ -/* Cypress West Bridge API header file (cyasdma.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASDMA_H_ -#define _INCLUDED_CYASDMA_H_ - -#include "cyashal.h" -#include "cyasdevice.h" - -#include "cyas_cplus_start.h" - - -/*@@DMA Overview - This module manages the DMA operations to/from the West Bridge - device. The DMA module maintains a DMA queue for each endpoint - so multiple DMA requests may be queued and they will complete - at some future time. - - The DMA module must be started before it can be used. It is - started by calling CyAsDmaStart(). This function initializes - all of the endpoint data structures. - - In order to perform DMA on a particular endpoint, the endpoint - must be enabled by calling CyAsDmaEnableEndPoint(). In addition - to enabling or disabling the endpoint, this function also sets - the direction for a given endpoint. Direction is given in USB - terms. For P port to West Bridge traffic, the endpoint is a - CyAsDirectionIn endpoint. For West Bridge to P port traffic, - the endpoint is a CyAsDirectionOut endpoint. - - Once DMA is started and an endpoint is enabled, DMA requests - are issued by calling CyAsDmaQueueRequest(). This function - queue either a DMA read or DMA write request. The callback - associated with the request is called once the request has been - fulfilled. - - See Also - * CyAsDmaStart - * CyAsDmaEnableEndPoint - * CyAsDmaDirection - * CyAsDmaQueueRequest - */ - -/************************ - * West Bridge Constants - ************************/ -#define CY_AS_DMA_MAX_SIZE_HW_SIZE (0xffffffff) - -/************************ - * West Bridge Data Structures - ************************/ - -/* Summary - This type specifies the direction of an endpoint to the - CyAsDmaEnableEndPoint function. - - Description - When an endpoint is enabled, the direction of the endpoint - can also be set. This type is used to specify the endpoint - type. Note that the direction is specified in USB terms. - Therefore, if the DMA is from the P port to West Bridge, - the direction is IN. - - See Also - * CyAsDmaEnableEndPoint -*/ -typedef enum cy_as_dma_direction { - /* Set the endpoint to type IN (P -> West Bridge) */ - cy_as_direction_in = 0, - /* Set the endpoint to type OUT (West Bridge -> P) */ - cy_as_direction_out = 1, - /* Only valid for EP 0 */ - cy_as_direction_in_out = 2, - /* Do no change the endpoint type */ - cy_as_direction_dont_change = 3 -} cy_as_dma_direction; - -/********************************* - * West Bridge Functions - *********************************/ - -/* Summary - Initialize the DMA module and ready the module for receiving data - - Description - This function initializes the DMA module by initializing all of - the endpoint data structures associated with the device given. - This function also register a DMA complete callback with the HAL - DMA code. This callback is called whenever the HAL DMA subsystem - completes a requested DMA operation. - - Returns - CY_AS_ERROR_SUCCESS - the module initialized successfully - CY_AS_ERROR_OUT_OF_MEMORY - memory allocation failed during - initialization - CY_AS_ERROR_ALREADY_RUNNING - the DMA module was already running - - See Also - * CyAsDmaStop -*/ -extern cy_as_return_status_t -cy_as_dma_start( - /* The device to start */ - cy_as_device *dev_p - ); - -/* Summary - Shutdown the DMA module - - Description - This function shuts down the DMA module for this device by - canceling any DMA requests associated with each endpoint and - then freeing the resources associated with each DMA endpoint. - - Returns - CY_AS_ERROR_SUCCESS - the module shutdown successfully - CY_AS_ERROR_NOT_RUNNING - the DMA module was not running - - See Also - * CyAsDmaStart - * CyAsDmaCancel -*/ -extern cy_as_return_status_t -cy_as_dma_stop( - /* The device to stop */ - cy_as_device *dev_p - ); - -/* Summary - This function cancels all outstanding DMA requests on a given endpoint - - Description - This function cancels any DMA requests outstanding on a given endpoint - by disabling the transfer of DMA requests from the queue to the HAL - layer and then removing any pending DMA requests from the queue. The - callback associated with any DMA requests that are being removed is - called with an error code of CY_AS_ERROR_CANCELED. - - Notes - If a request has already been sent to the HAL layer it will be - completed and not canceled. Only requests that have not been sent to - the HAL layer will be cancelled. - - Returns - CY_AS_ERROR_SUCCESS - the traffic on the endpoint is canceled - successfully - - See Also -*/ -extern cy_as_return_status_t -cy_as_dma_cancel( - /* The device of interest */ - cy_as_device *dev_p, - /* The endpoint to cancel */ - cy_as_end_point_number_t ep, - cy_as_return_status_t err - ); - -/* Summary - This function enables a single endpoint for DMA operations - - Description - In order to enable the queuing of DMA requests on a given - endpoint, the endpoint must be enabled for DMA. This function - enables a given endpoint. In addition, this function sets the - direction of the DMA operation. - - Returns - * CY_AS_ERROR_INVALID_ENDPOINT - invalid endpoint number - * CY_AS_ERROR_SUCCESS - endpoint was enabled or disabled - * successfully - - See Also - * CyAsDmaQueueRequest -*/ -extern cy_as_return_status_t -cy_as_dma_enable_end_point( - /* The device of interest */ - cy_as_device *dev_p, - /* The endpoint to enable or disable */ - cy_as_end_point_number_t ep, - /* CyTrue to enable, CyFalse to disable */ - cy_bool enable, - /* The direction of the endpoint */ - cy_as_dma_direction dir -); - -/* Summary - This function queue a DMA request for a given endpoint - - Description - When an West Bridge API module wishes to do a DMA operation, - this function is called on the associated endpoint to queue - a DMA request. When the DMA request has been fulfilled, the - callback associated with the DMA operation is called. - - Notes - The buffer associated with the DMA request, must remain valid - until after the callback function is calld. - - Returns - * CY_AS_ERROR_SUCCESS - the DMA operation was queued successfully - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint number was invalid - * CY_AS_ERROR_ENDPOINT_DISABLED - the endpoint was disabled - * CY_AS_ERROR_OUT_OF_MEMORY - out of memory processing the request - - See Also - * CyAsDmaEnableEndPoint - * CyAsDmaCancel -*/ -extern cy_as_return_status_t -cy_as_dma_queue_request( - /* The device of interest */ - cy_as_device *dev_p, - /* The endpoint to receive a new request */ - cy_as_end_point_number_t ep, - /* The memory buffer for the DMA request - - * must be valid until after the callback has been called */ - void *mem_p, - /* The size of the DMA request in bytes */ - uint32_t size, - /* If true and a DMA read request, return the next packet - * regardless of size */ - cy_bool packet, - /* If true, this is a read request, - * otherwise it is a write request */ - cy_bool readreq, - /* The callback to call when the DMA request is complete, - * either successfully or via an error */ - cy_as_dma_callback cb - ); - -/* Summary - This function waits until all DMA requests on a given endpoint - have been processed and then return - - Description - There are times when a module in the West Bridge API needs to - wait until the DMA operations have been queued. This function - sleeps until all DMA requests have been fulfilled and only then - returns to the caller. - - Notes - I don't think we will need a list of sleeping clients to support - multiple parallel client modules sleeping on a single endpoint, - but if we do instead of having a single sleep channel in the - endpoint, each client will have to supply a sleep channel and we - will have to maintain a list of sleep channels to wake. - - Returns - * CY_AS_ERROR_SUCCESS - the queue has drained successfully - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given is not valid - * CY_AS_ERROR_NESTED_SLEEP - CyAsDmaQueueRequest() was requested - * on an endpoint where CyAsDmaQueueRequest was already called -*/ -extern cy_as_return_status_t -cy_as_dma_drain_queue( - /* The device of interest */ - cy_as_device *dev_p, - /* The endpoint to drain */ - cy_as_end_point_number_t ep, - /* If CyTrue, call kickstart to start the DMA process, - if cy_false, west bridge will start the DMA process */ - cy_bool kickstart - ); - -/* Summary - Sets the maximum amount of data West Bridge can accept in a single - DMA Operation for the given endpoint - - Description - Depending on the configuration of the West Bridge device endpoint, - the amount of data that can be accepted varies. This function - sets the maximum amount of data West Bridge can accept in a single - DMA operation. The value is stored with the endpoint and passed - to the HAL layer in the CyAsHalDmaSetupWrite() and - CyAsHalDmaSetupRead() functoins. - - Returns - * CY_AS_ERROR_SUCCESS - the value was set successfully - * CY_AS_ERROR_INVALID_SIZE - the size value was not valid -*/ -extern cy_as_return_status_t -cy_as_dma_set_max_dma_size( - /* The device of interest */ - cy_as_device *dev_p, - /* The endpoint to change */ - cy_as_end_point_number_t ep, - /* The max size of this endpoint in bytes */ - uint32_t size - ); - -/* Summary - This function starts the DMA process on a given channel. - - Description - When transferring data from the P port processor to West - Bridge, the DMA operation must be initiated P Port software - for the first transfer. Subsequent transferrs will be - handled at the interrupt level. - - Returns - * CY_AS_ERROR_SUCCESS -*/ -extern cy_as_return_status_t -cy_as_dma_kick_start( - /* The device of interest */ - cy_as_device *dev_p, - /* The endpoint to change */ - cy_as_end_point_number_t ep - ); - -/* Summary - This function receives endpoint data from a request. - - Description - For endpoint 0 and 1 the endpoint data is transferred from - the West Bridge device to the DMA via a lowlevel - requests (via the mailbox registers). - - Returns - * CY_AS_ERROR_SUCCESS -*/ -extern cy_as_return_status_t -cy_as_dma_received_data( - /* The device of interest */ - cy_as_device *dev_p, - /* The endpoint that received data */ - cy_as_end_point_number_t ep, - /* The data size */ - uint32_t dsize, - /* The data buffer */ - void *data - ); - -/* Summary - This function is called when the DMA operation on - an endpoint has been completed. - - Returns - * void - */ -extern void -cy_as_dma_completed_callback( - /* Tag to HAL completing the DMA operation. */ - cy_as_hal_device_tag tag, - /* Endpoint on which DMA has been completed. */ - cy_as_end_point_number_t ep, - /* Length of data received. */ - uint32_t length, - /* Status of DMA operation. */ - cy_as_return_status_t status - ); - -#include "cyas_cplus_end.h" - -#endif /* _INCLUDED_CYASDMA_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaserr.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaserr.h deleted file mode 100644 index 2cd0af1ed781..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaserr.h +++ /dev/null @@ -1,1094 +0,0 @@ -/* Cypress West Bridge API header file (cyaserr.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASERR_H_ -#define _INCLUDED_CYASERR_H_ - -/*@@West Bridge Errors - Summary - This section lists the error codes for West Bridge. - -*/ - -/* Summary - The function completed successfully -*/ -#define CY_AS_ERROR_SUCCESS (0) - -/* Summary - A function trying to acquire a resource was unable to do so. - - Description - This code indicates that a resource that the API was trying to claim - could not be claimed. - - See Also - * CyAsMiscAcquireResource - * CyAsStorageClaim -*/ -#define CY_AS_ERROR_NOT_ACQUIRED (1) - -/* Summary - A function trying to acquire a resource was unable to do so. - - Description - The West Bridge API provides the capability to assign the storage media to - either the West Bridge device or the USB port. This error indicates the - P port was trying to release a storage media and was not able to do - so. This generally means it was not owned by the P port processor. - - See Also - * CyAsStorageRelease -*/ -#define CY_AS_ERROR_NOT_RELEASED (2) - -/* Summary - The West Bridge firmware is not loaded. - - Description - Most of the API functions that are part of the West Bridge API rely on - firmware running on the West Bridge device. This error code is - returned when one of these functions is called and the firmware has - not yet been loaded. - - See Also - * CyAsMiscGetFirmwareVersion - * CyAsMiscReset - * CyAsMiscAcquireResource - * CyAsMiscReleaseResource - * CyAsMiscSetTraceLevel - * CyAsStorageStart - * CyAsStorageStop - * CyAsStorageRegisterCallback - * CyAsStorageClaim - * CyAsStorageRelease - * CyAsStorageQueryMedia - * CyAsStorageQueryDevice - * CyAsStorageQueryUnit - * CyAsStorageRead - * CyAsStorageWrite - * CyAsStorageReadAsync - * CyAsStorageWriteAsync -*/ -#define CY_AS_ERROR_NO_FIRMWARE (3) - -/* Summary - A timeout occurred waiting on a response from the West Bridge device - - Description - When requests are made of the West Bridge device, a response is expected - within a given timeframe. If a response is not recevied within the - given timeframe, a timeout error occurs. -*/ -#define CY_AS_ERROR_TIMEOUT (4) - -/* Summary - A request to download firmware was made while not in the CONFIG mode - - Description - Firmware is downloaded via the CyAsMiscDownloadFirmware() function. This - function can only be called while in the CONFIG mode. This error indicates - that the CyAsMiscDownloadFirmware() call was made while not in the CONFIG - mode. - - See Also - * CyAsMiscDownloadFirmware -*/ -#define CY_AS_ERROR_NOT_IN_CONFIG_MODE (5) - -/* Summary - This error is returned if the firmware size specified is too invalid. - - Description - If the size of the firmware to be downloaded into West Bridge is - invalid, this error is issued. Invalid firmware sizes are those - greater than 24K or a size of zero. - - See Also - * CyAsMiscDownloadFirmare -*/ -#define CY_AS_ERROR_INVALID_SIZE (6) - -/* Summary - This error is returned if a request is made to acquire a resource that has - already been acquired. - - Description - This error is returned if a request is made to acquire a resource that has - already been acquired. - - See Also - * CyAsMiscAcquireResource - * CyAsMiscReleaseResource -*/ -#define CY_AS_ERROR_RESOURCE_ALREADY_OWNED (7) - -/* Summary - This error is returned if a request is made to release a resource that has - not previously been acquired. - - Description - This error is returned if a request is made to release a resource that has - not previously been acquired. - - See Also - * CyAsMiscAcquireResource - * CyAsMiscReleaseResource -*/ -#define CY_AS_ERROR_RESOURCE_NOT_OWNED (8) - -/* Summary - This error is returned when a request is made for a media that - does not exist - - Description - This error is returned when a request is made that references - a storage media that does not exist. This error is returned - when the storage media is not present in the current system, - or if the media value given is not valid. - - See Also - * CyAsMiscSetTraceLevel - * CyAsStorageClaim - * CyAsStorageRelease - * CyAsStorageRead - * CyAsStorageWrite - * CyAsStorageReadAsync - * CyAsStorageWriteAsync -*/ -#define CY_AS_ERROR_NO_SUCH_MEDIA (9) - -/* Summary - This error is returned when a request is made for a device - that does not exist - - Description - This error is returned when a request is made that references a - storage device that does not exist. This error is returned when - the device index is not present in the current system, or if the - device index exceeds 15. - - See Also - * CyAsMiscSetTraceLevel - * CyAsStorageQueryDevice - * CyAsStorageRead - * CyAsStorageWrite - * CyAsStorageReadAsync - * CyAsStorageWriteAsync -*/ -#define CY_AS_ERROR_NO_SUCH_DEVICE (10) - -/* Summary - This error is returned when a request is made for a unit that - does not exist - - Description - This error is returned when a request is made that references - a storage unit that does not exist. This error is returned - when the unit index is not present in the current system, or - if the unit index exceeds 255. - - See Also - * CyAsMiscSetTraceLevel - * CyAsStorageQueryDevice - * CyAsStorageQueryUnit - * CyAsStorageRead - * CyAsStorageWrite - * CyAsStorageReadAsync - * CyAsStorageWriteAsync -*/ -#define CY_AS_ERROR_NO_SUCH_UNIT (11) - -/* Summary - This error is returned when a request is made for a block that - does not exist - - Description - This error is returned when a request is made that references - a storage block that does not exist. This error is returned - when the block address reference an address beyond the end of - the unit selected. - - See Also - * CyAsStorageRead - * CyAsStorageWrite - * CyAsStorageReadAsync - * CyAsStorageWriteAsync -*/ -#define CY_AS_ERROR_INVALID_BLOCK (12) - -/* Summary - This error is returned when an invalid trace level is set. - - Description - This error is returned when the trace level request is greater - than three. - - See Also - * CyAsMiscSetTraceLevel -*/ -#define CY_AS_ERROR_INVALID_TRACE_LEVEL (13) - -/* Summary - This error is returned when West Bridge is already in the standby state - and an attempt is made to put West Bridge into this state again. - - Description - This error is returned when West Bridge is already in the standby state - and an attempt is made to put West Bridge into this state again. - - See Also - * CyAsMiscEnterStandby -*/ -#define CY_AS_ERROR_ALREADY_STANDBY (14) - -/* Summary - This error is returned when the API needs to set a pin on the - West Bridge device, but this is not supported by the underlying HAL - layer. - - Description - This error is returned when the API needs to set a pin on the - West Bridge device, but this is not supported by the underlying HAL - layer. - - See Also - * CyAsMiscEnterStandby - * CyAsMiscLeaveStandby -*/ -#define CY_AS_ERROR_SETTING_WAKEUP_PIN (15) - -/* Summary - This error is returned when a module is being started that has - already been started. - - Description - This error is returned when a module is being started and that module - has already been started. This error does not occur with the - CyAsStorageStart() or CyAsUsbStart() functions as the storage and - USB modules are reference counted. - - Note - At the current time, this error is returned by module internal to - the API but not returned by any of the API functions. -*/ -#define CY_AS_ERROR_ALREADY_RUNNING (16) - -/* Summary - This error is returned when a module is being stopped that has - already been stopped. - - Description - This error is returned when a module is being stopped and that module - has already been stopped. This error does not occur with the - CyAsStorageStop() or CyAsUsbStop() functions as the storage and USB - modules are reference counted. - - Note - At the current time, this error is returned by module internal to - the API but not returned by any of the API functions. -*/ - -#define CY_AS_ERROR_NOT_RUNNING (17) - -/* Summary - This error is returned when the caller tries to claim a media that - has already been claimed. - - Description - This error is returned when the caller tries to claim a media that - has already been claimed. - - See Also - * CyAsStorageClaim -*/ -#define CY_AS_ERROR_MEDIA_ALREADY_CLAIMED (18) - -/* Summary - This error is returned when the caller tries to release a media that has - already been released. - - Description - This error is returned when the caller tries to release a media that has - already been released. - - See Also - * CyAsStorageRelease -*/ -#define CY_AS_ERROR_MEDIA_NOT_CLAIMED (19) - -/* Summary - This error is returned when canceling trying to cancel an asynchronous - operation when an async operation is not pending. - - Description - This error is returned when a call is made to a function to cancel an - asynchronous operation and there is no asynchronous operation pending. - - See Also - * CyAsStorageCancelAsync - * CyAsUsbCancelAsync -*/ -#define CY_AS_ERROR_NO_OPERATION_PENDING (20) - -/* Summary - This error is returned when an invalid endpoint number is provided to - an API call. - - Description - This error is returned when an invalid endpoint number is specified in - an API call. The endpoint number may be invalid because it is greater - than 15, or because it was a reference to an endpoint that is invalid - for West Bridge (2, 4, 6, or 8). - - See Also - * CyAsUsbSetEndPointConfig - * CyAsUsbGetEndPointConfig - * CyAsUsbReadData - * CyAsUsbWriteData - * CyAsUsbReadDataAsync - * CyAsUsbWriteDataAsync - * CyAsUsbSetStall - * CyAsUsbGetStall -*/ -#define CY_AS_ERROR_INVALID_ENDPOINT (21) - -/* Summary - This error is returned when an invalid descriptor type - is specified in an API call. - - Description - This error is returned when an invalid descriptor type - is specified in an API call. - - See Also - * CyAsUsbSetDescriptor - * CyAsUsbGetDescriptor -*/ -#define CY_AS_ERROR_INVALID_DESCRIPTOR (22) - -/* Summary - This error is returned when an invalid descriptor index - is specified in an API call. - - Description - This error is returned when an invalid descriptor index - is specified in an API call. - - See Also - * CyAsUsbSetDescriptor - * CyAsUsbGetDescriptor -*/ -#define CY_AS_ERROR_BAD_INDEX (23) - -/* Summary - This error is returned if trying to set a USB descriptor - when in the P port enumeration mode. - - Description - This error is returned if trying to set a USB descriptor - when in the P port enumeration mode. - - See Also - * CyAsUsbSetDescriptor - * CyAsUsbGetDescriptor -*/ -#define CY_AS_ERROR_BAD_ENUMERATION_MODE (24) - -/* Summary - This error is returned when the endpoint configuration specified - is not valid. - - Description - This error is returned when the endpoint configuration specified - is not valid. - - See Also - * CyAsUsbSetDescriptor - * CyAsUsbGetDescriptor - * CyAsUsbCommitConfig -*/ -#define CY_AS_ERROR_INVALID_CONFIGURATION (25) - -/* Summary - This error is returned when the API cannot verify it is connected - to an West Bridge device. - - Description - When the API is initialized, the API tries to read the ID register from - the West Bridge device. The value from this ID register should match the - value expected before communications with West Bridge are established. This - error means that the contents of the ID register cannot be verified. - - See Also - * CyAsMiscConfigureDevice -*/ -#define CY_AS_ERROR_NO_ANTIOCH (26) - -/* Summary - This error is returned when an API function is called and - CyAsMiscConfigureDevice has not been called to configure West Bridge - for the current environment. - - Description - This error is returned when an API function is called and - CyAsMiscConfigureDevice has not been called to configure West Bridge for - the current environment. - - See Also - * Almost all API function -*/ -#define CY_AS_ERROR_NOT_CONFIGURED (27) - -/* Summary - This error is returned when West Bridge cannot allocate memory required for - internal API operations. - - Description - This error is returned when West Bridge cannot allocate memory required for - internal API operations. - - See Also - * Almost all API functoins -*/ -#define CY_AS_ERROR_OUT_OF_MEMORY (28) - -/* Summary - This error is returned when a module is being started that has - already been started. - - Description - This error is returned when a module is being started and that module - has already been started. This error does not occur with the - CyAsStorageStart() or CyAsUsbStart() functions as the storage and - USB modules are reference counted. - - Note - At the current time, this error is returned by module internal to the API but - not returned by any of the API functions. -*/ -#define CY_AS_ERROR_NESTED_SLEEP (29) - -/* Summary - This error is returned when an operation is attempted on an endpoint that has - been disabled. - - Description - This error is returned when an operation is attempted on an endpoint that has - been disabled. - - See Also - * CyAsUsbReadData - * CyAsUsbWriteData - * CyAsUsbReadDataAsync - * CyAsUsbWriteDataAsync -*/ -#define CY_AS_ERROR_ENDPOINT_DISABLED (30) - -/* Summary - This error is returned when a call is made to an API function when - the device is in standby. - - Description - When the West Bridge device is in standby, the only two API functions that - can be called are CyAsMiscInStandby() and CyAsMiscLeaveStandby(). - Calling any other API function will result in this error. - - See Also -*/ -#define CY_AS_ERROR_IN_STANDBY (31) - -/* Summary - This error is returned when an API call is made with an invalid handle value. - - Description - This error is returned when an API call is made with an invalid handle value. - - See Also -*/ -#define CY_AS_ERROR_INVALID_HANDLE (32) - -/* Summary - This error is returned when an invalid response is returned from - the West Bridge device. - - Description - Many of the API calls result in requests made to the West Bridge - device. This error occurs when the response from West Bridge is - invalid and generally indicates that the West Bridge device - should be reset. - - See Also -*/ -#define CY_AS_ERROR_INVALID_RESPONSE (33) - -/* Summary - This error is returned from the callback function for any asynchronous - read or write request that is canceled. - - Description - When asynchronous requests are canceled, this error is passed to the - callback function associated with the request to indicate that the - request has been canceled - - See Also - * CyAsStorageReadAsync - * CyAsStorageWriteAsync - * CyAsUsbReadDataAsync - * CyAsUsbWriteDataAsync - * CyAsStorageCancelAsync - * CyAsUsbCancelAsync -*/ -#define CY_AS_ERROR_CANCELED (34) - -/* Summary - This error is returned when the call to create sleep channel fails - in the HAL layer. - - Description - This error is returned when the call to create sleep channel fails - in the HAL layer. - - See Also - * CyAsMiscConfigureDevice -*/ -#define CY_AS_ERROR_CREATE_SLEEP_CHANNEL_FAILED (35) - -/* Summary - This error is returned when the call to CyAsMiscLeaveStandby - is made and the device is not in standby. - - Description - This error is returned when the call to CyAsMiscLeaveStandby - is made and the device is not in standby. - - See Also -*/ -#define CY_AS_ERROR_NOT_IN_STANDBY (36) - -/* Summary - This error is returned when the call to destroy sleep channel fails - in the HAL layer. - - Description - This error is returned when the call to destroy sleep channel fails - in the HAL layer. - - See Also - * CyAsMiscDestroyDevice -*/ -#define CY_AS_ERROR_DESTROY_SLEEP_CHANNEL_FAILED (37) - -/* Summary - This error is returned when an invalid resource is specified to a call - to CyAsMiscAcquireResource() or CyAsMiscReleaseResource() - - Description - This error is returned when an invalid resource is specified to a call - to CyAsMiscAcquireResource() or CyAsMiscReleaseResource() - - See Also - * CyAsMiscAcquireResource - * CyAsMiscReleaseResource -*/ -#define CY_AS_ERROR_INVALID_RESOURCE (38) - -/* Summary - This error occurs when an operation is requested on an endpoint that has - a currently pending async operation. - - Description - There can only be a single asynchronous pending operation on a given - endpoint and while the operation is pending on other operation can occur - on the endpoint. In addition, the device cannot enter standby while - any asynchronous operations are pending. - - See Also - * CyAsStorageReadAsync - * CyAsStorageWriteAsync - * CyAsUsbReadDataAsync - * CyAsUsbWriteDataAsync - * CyAsStorageRead - * CyAsStorageWrite - * CyAsUsbReadData - * CyAsUsbWriteData - * CyAsMiscEnterStandby -*/ -#define CY_AS_ERROR_ASYNC_PENDING (39) - -/* Summary - This error is returned when a call to CyAsStorageCancelAsync() or - CyAsUsbCancelAsync() is made when no asynchronous request is pending. - - Description - This error is returned when a call to CyAsStorageCancelAsync() or - CyAsUsbCancelAsync() is made when no asynchronous request is pending. - - See Also - * CyAsStorageCancelAsync - * CyAsUsbCancelAsync -*/ -#define CY_AS_ERROR_ASYNC_NOT_PENDING (40) - -/* Summary - This error is returned when a request is made to put the West Bridge device - into standby mode while the USB stack is still active. - - Description - This error is returned when a request is made to put the West Bridge device - into standby mode while the USB stack is still active. You must call the - function CyAsUsbStop() in order to shut down the USB stack in order to go - into the standby mode. - - See Also - * CyAsMiscEnterStandby -*/ -#define CY_AS_ERROR_USB_RUNNING (41) - -/* Summary - A request for in the wrong direction was issued on an endpoint. - - Description - This error is returned when a write is attempted on an OUT endpoint or - a read is attempted on an IN endpoint. - - See Also - * CyAsUsbReadData - * CyAsUsbWriteData - * CyAsUsbReadDataAsync - * CyAsUsbWriteDataAsync -*/ -#define CY_AS_ERROR_USB_BAD_DIRECTION (42) - -/* Summary - An invalid request was received - - Description - This error is isused if an invalid request is issued. -*/ -#define CY_AS_ERROR_INVALID_REQUEST (43) - -/* Summary - An ACK request was requested while no setup packet was pending. - - Description - This error is issued if CyAsUsbAckSetupPacket() is called when no - setup packet is pending. -*/ -#define CY_AS_ERROR_NO_SETUP_PACKET_PENDING (44) - -/* Summary - A call was made to a API function that cannot be called from a callback. - - Description - Only asynchronous functions can be called from within West Bridge callbacks. - This error results when an invalid function is called from a callback. -*/ -#define CY_AS_ERROR_INVALID_IN_CALLBACK (45) - -/* Summary - A call was made to CyAsUsbSetEndPointConfig() before - CyAsUsbSetPhysicalConfiguration() was called. - - Description - When logical endpoints are configured, you must define the physical - endpoint for the logical endpoint being configured. Therefore - CyAsUsbSetPhysicalConfiguration() must be called to define the - physical endpoints before calling CyAsUsbSetEndPointConfig(). -*/ -#define CY_AS_ERROR_ENDPOINT_CONFIG_NOT_SET (46) - -/* Summary - The physical endpoint referenced is not valid in the current physical - configuration - - Description - When logical endpoints are configured, you must define the physical - endpoint for the logical endpoint being configured. Given the - current physical configuration, the physical endpoint referenced - is not valid. -*/ -#define CY_AS_ERROR_INVALID_PHYSICAL_ENDPOINT (47) - -/* Summary - The data supplied to the CyAsMiscDownloadFirmware() call is not - aligned on a WORD (16 bit) boundary. - - Description - Many systems have problems with the transfer of data a word at a - time when the data is not word aligned. For this reason, we - require that the firmware image be aligned on a word boundary and - be an even number of bytes. This error is returned if these - conditions are not met. -*/ -#define CY_AS_ERROR_ALIGNMENT_ERROR (48) - -/* Summary - A call was made to destroy the West Bridge device, but the USB - stack or the storage stack was will running. - - Description - Before calling CyAsMiscDestroyDevice to destroy an West Bridge - device created via a call to CyAsMiscCreateDevice, the USB and - STORAGE stacks much be stopped via calls to CyAsUsbStop and - CyAsStorageStop. This error indicates that one of these two - stacks have not been stopped. -*/ -#define CY_AS_ERROR_STILL_RUNNING (49) - -/* Summary - A call was made to the API for a function that is not yet supported. - - Description - There are calls that are not yet supported that may be called through - the API. This is done to maintain compatibility in the future with - the API. This error is returned if you are asking for a capability - that does not yet exist. -*/ -#define CY_AS_ERROR_NOT_YET_SUPPORTED (50) - -/* Summary - A NULL callback was provided where a non-NULL callback was required - - Description - When async IO function are called, a callback is required to indicate - that the IO has completed. This callback must be non-NULL. -*/ -#define CY_AS_ERROR_NULL_CALLBACK (51) - -/* Summary - This error is returned when a request is made to put the West Bridge device - into standby mode while the storage stack is still active. - - Description - This error is returned when a request is made to put the West Bridge device - into standby mode while the storage stack is still active. You must call the - function CyAsStorageStop() in order to shut down the storage stack in order - to go into the standby mode. - - See Also - * CyAsMiscEnterStandby -*/ -#define CY_AS_ERROR_STORAGE_RUNNING (52) - -/* Summary - This error is returned when an operation is attempted that cannot be - completed while the USB stack is connected to a USB host. - - Description - This error is returned when an operation is attempted that cannot be - completed while the USB stack is connected to a USB host. In order - to successfully complete the desired operation, CyAsUsbDisconnect() - must be called to disconnect from the host. -*/ -#define CY_AS_ERROR_USB_CONNECTED (53) - -/* Summary - This error is returned when a USB disconnect is attempted and the - West Bridge device is not connected. - - Description - This error is returned when a USB disconnect is attempted and the - West Bridge device is not connected. -*/ -#define CY_AS_ERROR_USB_NOT_CONNECTED (54) - -/* Summary - This error is returned when an P2S storage operation attempted - and data could not be read or written to the storage media. - - Description - This error is returned when an P2S storage operation attempted - and data could not be read or written to the storage media. If - this error is recevied then a retry can be done. -*/ -#define CY_AS_ERROR_MEDIA_ACCESS_FAILURE (55) - -/* Summary - This error is returned when an P2S storage operation attempted - and the media is write protected. - - Description - This error is returned when an P2S storage operation attempted - and the media is write protected. -*/ -#define CY_AS_ERROR_MEDIA_WRITE_PROTECTED (56) - -/* Summary - This error is returned when an attempt is made to cancel a request - that has already been sent to the West Bridge. - - Description - It is not possible to cancel an asynchronous storage read/write - operation after the actual data transfer with the West Bridge - has started. This error is returned if CyAsStorageCancelAsync - is called to cancel such a request. - */ -#define CY_AS_ERROR_OPERATION_IN_TRANSIT (57) - -/* Summary - This error is returned when an invalid parameter is passed to - one of the APIs. - - Description - Some of the West Bridge APIs are applicable to only specific - media types, devices etc. This error code is returned when a - API is called with an invalid parameter type. - */ -#define CY_AS_ERROR_INVALID_PARAMETER (58) - -/* Summary - This error is returned if an API is not supported in the current setup. - - Description - Some of the West Bridge APIs work only with specific device types - or firmware images. This error is returned when such APIs are called - when the current device or firmware does not support the invoked API - function. - */ -#define CY_AS_ERROR_NOT_SUPPORTED (59) - -/* Summary - This error is returned when a call is made to one of the Storage or - USB APIs while the device is in suspend mode. - - Description - This error is returned when a call is made to one of the storage or - USB APIs while the device is in suspend mode. - */ -#define CY_AS_ERROR_IN_SUSPEND (60) - -/* Summary - This error is returned when the call to CyAsMiscLeaveSuspend - is made and the device is not in suspend mode. - - Description - This error is returned when the call to CyAsMiscLeaveSuspend - is made and the device is not in suspend mode. - */ -#define CY_AS_ERROR_NOT_IN_SUSPEND (61) - -/* Summary - This error is returned when a command that is disabled by USB is called. - - Description - The remote wakeup capability should be exercised only if enabled by the - USB host. This error is returned when the CyAsUsbSignalRemoteWakeup API - is called when the feature has not been enabled by the USB host. - */ -#define CY_AS_ERROR_FEATURE_NOT_ENABLED (62) - -/* Summary - This error is returned when an Async storage read or write is called before a - query device call is issued. - - Description - In order for the SDK to properly set up a DMA the block size of a given media - needs to be known. This is done by making a call to CyAsStorageQueryDevice. - This call only needs to be made once per device. If this call is not issued - before an Async read or write is issued this error code is returned. - */ -#define CY_AS_ERROR_QUERY_DEVICE_NEEDED (63) - -/* Summary - This error is returned when a call is made to USB or STORAGE Start or - Stop before a prior Start or Stop has finished. - - Description - The USB and STORAGE start and stop functions can only be called if a - prior start or stop function call has fully completed. This means when - an async EX call is made you must wait until the callback for that call - has been completed before calling start or stop again. - */ -#define CY_AS_ERROR_STARTSTOP_PENDING (64) - -/* Summary - This error is returned when a request is made for a bus that does not exist - - Description - This error is returned when a request is made that references a bus - number that does not exist. This error is returned when the bus number - is not present in the current system, or if the bus number given is not - valid. - - See Also - * CyAsMiscSetTraceLevel - * CyAsStorageClaim - * CyAsStorageRelease - * CyAsStorageRead - * CyAsStorageWrite - * CyAsStorageReadAsync - * CyAsStorageWriteAsync -*/ -#define CY_AS_ERROR_NO_SUCH_BUS (65) - -/* Summary - This error is returned when the bus corresponding to a media type cannot - be resolved. - - Description - In some S-Port configurations, the same media type may be supported on - multiple buses. In this case, it is not possible to resolve the target - address based on the media type. This error indicates that only - bus-based addressing is supported in a particular run-time - configuration. - - See Also - * CyAsMediaType - * CyAsBusNumber_t - */ -#define CY_AS_ERROR_ADDRESS_RESOLUTION_ERROR (66) - -/* Summary - This error is returned when an invalid command is passed to the - CyAsStorageSDIOSync() function. - - Description - This error indiactes an unknown Command type was passed to the SDIO - command handler function. - */ - -#define CY_AS_ERROR_INVALID_COMMAND (67) - - -/* Summary - This error is returned when an invalid function /uninitialized - function is passed to an SDIO function. - - Description - This error indiactes an unknown/uninitialized function number was - passed to a SDIO function. - */ -#define CY_AS_ERROR_INVALID_FUNCTION (68) - -/* Summary - This error is returned when an invalid block size is passed to - CyAsSdioSetBlocksize(). - - Description - This error is returned when an invalid block size (greater than - maximum block size supported) is passed to CyAsSdioSetBlocksize(). - */ - -#define CY_AS_ERROR_INVALID_BLOCKSIZE (69) - -/* Summary - This error is returned when an tuple requested is not found. - - Description - This error is returned when an tuple requested is not found. - */ -#define CY_AS_ERROR_TUPLE_NOT_FOUND (70) - -/* Summary - This error is returned when an extended IO operation to an SDIO function is - Aborted. - Description - This error is returned when an extended IO operation to an SDIO function is - Aborted. */ -#define CY_AS_ERROR_IO_ABORTED (71) - -/* Summary - This error is returned when an extended IO operation to an SDIO function is - Suspended. - Description - This error is returned when an extended IO operation to an SDIO function is - Suspended. */ -#define CY_AS_ERROR_IO_SUSPENDED (72) - -/* Summary - This error is returned when IO is attempted to a Suspended SDIO function. - Description - This error is returned when IO is attempted to a Suspended SDIO function. */ -#define CY_AS_ERROR_FUNCTION_SUSPENDED (73) - -/* Summary - This error is returned if an MTP function is called before MTPStart - has completed. - Description - This error is returned if an MTP function is called before MTPStart - has completed. -*/ -#define CY_AS_ERROR_MTP_NOT_STARTED (74) - -/* Summary - This error is returned by API functions that are not valid in MTP - mode (CyAsStorageClaim for example) - Description - This error is returned by API functions that are not valid in MTP - mode (CyAsStorageClaim for example) -*/ -#define CY_AS_ERROR_NOT_VALID_IN_MTP (75) - -/* Summary - This error is returned when an attempt is made to partition a - storage device that is already partitioned. - - Description - This error is returned when an attempt is made to partition a - storage device that is already partitioned. -*/ -#define CY_AS_ERROR_ALREADY_PARTITIONED (76) - -/* Summary - This error is returned when a call is made to - CyAsUsbSelectMSPartitions after CyAsUsbSetEnumConfig is called. - - Description - This error is returned when a call is made to - CyAsUsbSelectMSPartitions after CyAsUsbSetEnumConfig is called. - */ -#define CY_AS_ERROR_INVALID_CALL_SEQUENCE (77) - -/* Summary - This error is returned when a StorageWrite opperation is attempted - during an ongoing MTP transfer. - Description - This error is returned when a StorageWrite opperation is attempted - during an ongoing MTP transfer. A MTP transfer is initiated by a - call to CyAsMTPInitSendObject or CyAsMTPInitGetObject and is not - finished until the CyAsMTPSendObjectComplete or - CyAsMTPGetObjectComplete event is generated. -*/ -#define CY_AS_ERROR_NOT_VALID_DURING_MTP (78) - -/* Summary - This error is returned when a StorageRead or StorageWrite is - attempted while a UsbRead or UsbWrite on a Turbo endpoint (2 or 6) is - pending, or visa versa. - Description - When there is a pending usb read or write on a turbo endpoint (2 or 6) - a storage read or write call may not be performed. Similarly when there - is a pending storage read or write a usb read or write may not be - performed on a turbo endpoint (2 or 6). -*/ -#define CY_AS_ERROR_STORAGE_EP_TURBO_EP_CONFLICT (79) - -/* Summary - This error is returned when processor requests to reserve greater - number of zones than available for proc booting via lna firmware. - - Description - Astoria does not allocate any nand zones for the processor in this case. -*/ -#define CY_AS_ERROR_EXCEEDED_NUM_ZONES_AVAIL (80) - -#endif /* _INCLUDED_CYASERR_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashal.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashal.h deleted file mode 100644 index b695ba1a9110..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashal.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Cypress West Bridge API header file (cyashal.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASHAL_H_ -#define _INCLUDED_CYASHAL_H_ - -#if !defined(__doxygen__) - -/* The possible HAL layers defined and implemented by Cypress */ - -#ifdef __CY_ASTORIA_FPGA_HAL__ -#ifdef CY_HAL_DEFINED -#error only one HAL layer can be defined -#endif - -#define CY_HAL_DEFINED - -#include "cyashalfpga.h" -#endif - -/***** SCM User space HAL ****/ -#ifdef __CY_ASTORIA_SCM_HAL__ -#ifdef CY_HAL_DEFINED -#error only one HAL layer can be defined -#endif - -#define CY_HAL_DEFINEDŚŚ - -#include "cyanhalscm.h" -#endif -/***** SCM User space HAL ****/ - -/***** SCM Kernel HAL ****/ -#ifdef __CY_ASTORIA_SCM_KERNEL_HAL__ -#ifdef CY_HAL_DEFINED -#error only one HAL layer can be defined -#endif - -#define CY_HAL_DEFINEDÅš - -#include "cyanhalscm_kernel.h" -#endif -/***** SCM Kernel HAL ****/ - -/***** OMAP5912 Kernel HAL ****/ -#ifdef __CY_ASTORIA_OMAP_5912_KERNEL_HAL__ - #ifdef CY_HAL_DEFINED - #error only one HAL layer can be defined - #endif - - #define CY_HAL_DEFINED - - #include "cyanhalomap_kernel.h" -#endif -/***** eof OMAP5912 Kernel HAL ****/ - - - -/***** OMAP3430 Kernel HAL ****/ -#ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL - - #ifdef CY_HAL_DEFINED - #error only one HAL layer can be defined - #endif - - #define CY_HAL_DEFINED -/* moved to staging location, eventual implementation - * considered is here - * #include mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h> -*/ - #include "../../../arch/arm/plat-omap/include/mach/westbridge/westbridge-omap3-pnand-hal/cyashalomap_kernel.h" - -#endif -/*****************************/ - - -/******/ -#ifdef __CY_ASTORIA_CUSTOMER_HAL__ -#ifdef CY_HAL_DEFINED -#error only one HAL layer can be defined -#endif -br -#define CY_HAL_DEFINED -#include "cyashal_customer.h" - -#endif - -#endif /* __doxygen__ */ - -#endif /* _INCLUDED_CYASHAL_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashalcb.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashalcb.h deleted file mode 100644 index 4d1670ee0476..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashalcb.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Cypress West Bridge API header file (cyashalcb.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASHALCB_H_ -#define _INCLUDED_CYASHALCB_H_ - -/* Summary - This type defines a callback function type called when a - DMA operation has completed. - - Description - - See Also - * CyAsHalDmaRegisterCallback - * CyAsHalDmaSetupWrite - * CyAsHalDmaSetupRead -*/ -typedef void (*cy_as_hal_dma_complete_callback)( - cy_as_hal_device_tag tag, - cy_as_end_point_number_t ep, - uint32_t cnt, - cy_as_return_status_t ret); - -typedef cy_as_hal_dma_complete_callback \ - cy_an_hal_dma_complete_callback; -#endif diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashaldoc.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashaldoc.h deleted file mode 100644 index 5bcbe9bf2f5d..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyashaldoc.h +++ /dev/null @@ -1,800 +0,0 @@ -/* Cypress West Bridge API header file (cyashaldoc.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASHALDOC_H_ -#define _INCLUDED_CYASHALDOC_H_ - -#include "cyashaldef.h" - -/*@@Hardware Abstraction Layer (HAL) - Summary - This software module is supplied by the user of the West Bridge - API. This module contains the software that is specific to the - hardware implementation or operating system of the client - system. - - * Sleep Channels * - A sleep channel is a operating system object that provides that - capability for one thread or process to sleep while waiting on - the completion of some hardware event. The hardware event is - usually processed by a hardware interrupt and the interrupt - handler then wakes the thread or process that is sleeping. - - A sleep channel provides the mechanism for this operation. A - sleep channel is created and initialized during the API - initialization. When the API needs to wait for the hardware, - the API performs a SleepOn() operation on the sleep channel. - When hardware event occurs, an interrupt handler processes the - event and then performs a Wake() operation on the sleep channel - to wake the sleeping process or thread. - - * DMA Model * - When the West Bridge API needs to transfer USB or storage data - to/from the West Bridge device, this is done using a "DMA" - operation. In this context the term DMA is used loosely as the - West Bridge API does not really care if the data is transferred - using a burst read or write operation, or if the data is - transferred using programmed I/O operations. When a "DMA" - operation is needed, the West Bridge API calls either - CyAsHalDmaSetupRead() or CyAsHalDmaSetupWrite() depending on the - direction of the data flow. The West Bridge API expects the - "DMA" operation requested in the call to be completed and the - registered "DMA complete" callback to be called. - - The West Bridge API looks at several factors to determine the - size of the "DMA" request to pass to the HAL layer. First the - West Bridge API calls CyAsHalDmaMaxRequestSize() to determine - the maximum amount of data the HAL layer can accept for a "DMA" - operation on the requested endpoint. The West Bridge API will - never exceed this value in a "DMA" request to the HAL layer. - The West Bridge API also sends the maximum amount of data the - West Bridge device can accept as part of the "DMA" request. If - the amount of data in the "DMA" request to the HAL layer - exceeds the amount of data the West Bridge device can accept, - it is expected that the HAL layer has the ability to break the - request into multiple operations. - - If the HAL implementation requires the API to handle the size - of the "DMA" requests for one or more endpoints, the value - CY_AS_DMA_MAX_SIZE_HW_SIZE can be returned from the - CyAsHalDmaMaxRequestSize() call. In this case, the API assumes - that the maximum size of each "DMA" request should be limited - to the maximum that can be accepted by the endpoint in question. - - Notes - See the /api/hal/scm_kernel/cyashalscm_kernel.c file - for an example of how the DMA request size can be managed by - the HAL implementation. - - * Interrupt Handling * - The HAL implementation is required to handle interrupts arriving - from the West Bridge device, and call the appropriate handlers. - If the interrupt arriving is one of PLLLOCKINT, PMINT, MBINT or - MCUINT, the CyAsIntrServiceInterrupt API should be called to - service the interrupt. If the interrupt arriving is DRQINT, the - HAL should identify the endpoint corresponding to which the DRQ - is being generated and perform the read/write transfer from the - West Bridge. See the /api/hal/scm_kernel/ - cyashalscm_kernel.c or /api/hal/fpga/cyashalfpga.c - reference HAL implementations for examples. - - The HAL implementation can choose to poll the West Bridge - interrupt status register instead of using interrupts. In this - case, the polling has to be performed from a different thread/ - task than the one running the APIs. This is required because - there are API calls that block on the reception of data from the - West Bridge, which is delivered only through the interrupt - handlers. - - * Required Functions * - This section defines the types and functions that must be - supplied in order to provide a complete HAL layer for the - West Bridge API. - - Types that must be supplied: - * CyAsHalSleepChannel - - Hardware functions that must be supplied: - * CyAsHalWriteRegister - * CyAsHalReadRegister - * CyAsHalDmaSetupWrite - * CyAsHalDmaSetupRead - * CyAsHalDmaCancelRequest - * CyAsHalDmaRegisterCallback - * CyAsHalDmaMaxRequestSize - * CyAsHalSetWakeupPin - * CyAsHalSyncDeviceClocks - * CyAsHalInitDevRegisters - * CyAsHalReadRegsBeforeStandby - * CyAsHalRestoreRegsAfterStandby - - Operating system functions that must be supplied: - * CyAsHalAlloc - * CyAsHalFree - * CyAsHalCBAlloc - * CyAsHalCBFree - * CyAsHalMemSet - * CyAsHalCreateSleepChannel - * CyAsHalDestroySleepChannel - * CyAsHalSleepOn - * CyAsHalWake - * CyAsHalDisableInterrupts - * CyAsHalEnableInterrupts - * CyAsHalSleep150 - * CyAsHalSleep - * CyAsHalAssert - * CyAsHalPrintMessage - * CyAsHalIsPolling -*/ - -/* Summary - This is the type that represents a sleep channel - - Description - A sleep channel is an operating system object that, when a - thread of control waits on the sleep channel, the thread - sleeps until another thread signals the sleep object. This - object is generally used when a high level API is called - and must wait for a response that is supplied in an interrupt - handler. The thread calling the API is put into a sleep - state and when the reply arrives via the interrupt handler, - the interrupt handler wakes the sleeping thread to indicate - that the expect reply is available. -*/ -typedef struct cy_as_hal_sleep_channel { - /* This structure is filled in with OS specific information - to implementat a sleep channel */ - int m_channel; -} cy_as_hal_sleep_channel; - -/* Summary - This function is called to write a register value - - Description - This function is called to write a specific register to a - specific value. The tag identifies the device of interest. - The address is relative to the base address of the West - Bridge device. - - Returns - Nothing - - See Also - * CyAsHalDeviceTag - * CyAsHalReadRegister -*/ -EXTERN void -cy_as_hal_write_register( -/* The tag to ID a specific West Bridge device */ - cy_as_hal_device_tag tag, - /* The address we are writing to */ - uint16_t addr, - /* The value to write to the register */ - uint16_t value - ); - -/* Summary - This function is called to read a register value - - Description - This function is called to read the contents of a specific - register. The tag identifies the device of interest. The - address is relative to the base address of the West Bridge - device. - - Returns - Contents of the register - - See Also - * CyAsHalDeviceTag - * CyAsHalWriteRegister -*/ -EXTERN uint16_t -cy_as_hal_read_register( - /* The tag to ID a specific West Bridge device */ - cy_as_hal_device_tag tag, - /* The address we are writing to */ - uint16_t addr - ); - -/* Summary - This function initiates a DMA write operation to write - to West Bridge - - Description - This function initiates a DMA write operation. The request - size will not exceed the value the HAL layer returned via - CyAsHalDmaMaxRequestSize(). This request size may exceed - the size of what the West Bridge device will accept as on - packet and the HAL layer may need to divide the request - into multiple hardware DMA operations. - - Returns - None - - See Also - * CyAsHalDmaSetupRead - * CyAsHalDmaMaxRequestSize -*/ -EXTERN void -cy_as_hal_dma_setup_write( - /* The tag to ID a specific West Bridge device */ - cy_as_hal_device_tag tag, - /* The endpoint we are writing to */ - cy_as_end_point_number_t ep, - /* The data to write via DMA */ - void *buf_p, - /* The size of the data at buf_p */ - uint32_t size, - /* The maximum amount of data that the endpoint - * can accept as one packet */ - uint16_t maxsize - ); - -/* Summary - This function initiates a DMA read operation from West Bridge - - Description - This function initiates a DMA read operation. The request - size will not exceed the value the HAL layer returned via - CyAsHalDmaMaxRequestSize(). This request size may exceed - the size of what the Anitoch will accept as one packet and - the HAL layer may need to divide the request into multiple - hardware DMA operations. - - Returns - None - - See Also - * CyAsHalDmaSetupRead - * CyAsHalDmaMaxRequestSize -*/ -EXTERN void -cy_as_hal_dma_setup_read( - /* The tag to ID a specific West Bridge device */ - cy_as_hal_device_tag tag, - /* The endpoint we are reading from */ - cy_as_end_point_number_t ep, - /* The buffer to read data into */ - void *buf_p, - /* The amount of data to read */ - uint32_t size, - /* The maximum amount of data that the endpoint - * can provide in one DMA operation */ - uint16_t maxsize - ); - -/* Summary - This function cancels a pending DMA request - - Description - This function cancels a pending DMA request that has been - passed down to the hardware. The HAL layer can elect to - physically cancel the request if possible, or just ignore - the results of the request if it is not possible. - - Returns - None -*/ -EXTERN void -cy_as_hal_dma_cancel_request( - /* The tag to ID a specific West Bridge device */ - cy_as_hal_device_tag tag, - /* The endpoint we are reading from */ - cy_as_end_point_number_t ep - ); - -/* Summary - This function registers a callback function to be called when - a DMA request is completed - - Description - This function registers a callback that is called when a request - issued via CyAsHalDmaSetupWrite() or CyAsHalDmaSetupRead() has - completed. - - Returns - None - - See Also - * CyAsHalDmaSetupWrite - * CyAsHalDmaSetupRead -*/ -EXTERN void -cy_as_hal_dma_register_callback( - /* The tag to ID a specific West Bridge device */ - cy_as_hal_device_tag tag, - /* The callback to call when a request has completed */ - cy_as_hal_dma_complete_callback cb - ); - -/* Summary - This function returns the maximum size of a DMA request that can - be handled by the HAL. - - Description - When DMA requests are passed to the HAL layer for processing, - the HAL layer may have a limit on the size of the request that - can be handled. This function is called by the DMA manager for - an endpoint when DMA is enabled to get the maximum size of data - the HAL layer can handle. The DMA manager insures that a request - is never sent to the HAL layer that exceeds the size returned by - this function. - - Returns - the maximum size of DMA request the HAL layer can handle -*/ -EXTERN uint32_t -cy_as_hal_dma_max_request_size( - /* The tag to ID a specific West Bridge device */ - cy_as_hal_device_tag tag, - /* The endpoint of interest */ - cy_as_end_point_number_t ep - ); - -/* Summary - This function sets the WAKEUP pin to a specific state on the - West Bridge device. - - Description - In order to enter the standby mode, the WAKEUP pin must be - de-asserted. In order to resume from standby mode, the WAKEUP - pin must be asserted. This function provides the mechanism to - do this. - - Returns - 1 if the pin was changed, 0 if the HAL layer does not support - changing this pin -*/ -EXTERN uint32_t -cy_as_hal_set_wakeup_pin( - /* The tag to ID a specific West Bridge device */ - cy_as_hal_device_tag tag, - /* The desired state of the wakeup pin */ - cy_bool state - ); - -/* Summary - Synchronise the West Bridge device clocks to re-establish device - connectivity. - - Description - When the Astoria bridge device is working in SPI mode, a long - period of inactivity can cause a loss of serial synchronisation - between the processor and Astoria. This function is called by - the API when it detects such a condition, and is expected to take - the action required to re-establish clock synchronisation between - the devices. - - Returns - CyTrue if the attempt to re-synchronise is successful, - CyFalse if not. - */ -EXTERN cy_bool -cy_as_hal_sync_device_clocks( - /* The tag to ID a specific West Bridge device */ - cy_as_hal_device_tag tag, - ); - -/* Summary - Initialize West Bridge device registers that may have been - modified while the device was in standby. - - Description - The content of some West Bridge registers may be lost when - the device is placed in standby mode. This function restores - these register contents so that the device can continue to - function normally after it wakes up from standby mode. - - This function is required to perform operations only when the - API is being used with the Astoria device in one of the PNAND - modes or in the PSPI mode. It can be a no-operation in all - other cases. - - Returns - None - */ -EXTERN void -cy_as_hal_init_dev_registers( - /* The tag to ID a specific West Bridge device */ - cy_as_hal_device_tag tag, - /* Indicates whether this is a wake-up from standby. */ - cy_bool is_standby_wakeup - ); - -/* Summary - This function reads a set of P-port accessible device registers and - stores their value for later use. - - Description - The West Bridge Astoria device silicon has a known problem when - operating in SPI mode on the P-port, where some of the device - registers lose their value when the device goes in and out of - standby mode. The suggested work-around is to reset the Astoria - device as part of the wakeup procedure from standby. - - This requires that the values of some of the P-port accessible - registers be restored to their pre-standby values after it has - been reset. This HAL function can be used to read and store - the values of these registers at the point where the device is - being placed in standby mode. - - Returns - None - - See Also - * CyAsHalRestoreRegsAfterStandby - */ -EXTERN void -cy_as_hal_read_regs_before_standby( - /* The tag to ID a specific West Bridge device */ - cy_as_hal_device_tag tag - ); - -/* Summary - This function restores the old values to a set of P-port - accessible device registers. - - Description - This function is part of the work-around to a known West - Bridge Astoria device error when operating in SPI mode on - the P-port. This function is used to restore a set of - P-port accessible registers to the values they had before - the device was placed in standby mode. - - Returns - None - - See Also - * CyAsHalRestoreRegsAfterStandby - */ -EXTERN void -cy_as_hal_restore_regs_after_standby( - /* The tag to ID a specific West Bridge device */ - cy_as_hal_device_tag tag - ); - -/* - * The functions below this comment are part of the HAL layer, - * as the HAL layer consists of the abstraction to both the - * hardware platform and the operating system. However; the - * functions below this comment all relate to the operating - * environment and not specifically to the hardware platform - * or specific device. - */ - -/* Summary - This function allocates a block of memory - - Description - This is the HAL layer equivalent of the malloc() function. - - Returns - a pointer to a block of memory - - See Also - * CyAsHalFree -*/ -EXTERN void * -cy_as_hal_alloc( - /* The size of the memory block to allocate */ - uint32_t size - ); - -/* Summary - This function frees a previously allocated block of memory - - Description - This is the HAL layer equivalent of the free() function. - - Returns - None - - See Also - * CyAsHalAlloc -*/ -EXTERN void -cy_as_hal_free( - /* Pointer to a memory block to free */ - void *ptr - ); - -/* Summary - This function is a malloc equivalent that can be used from an - interrupt context. - - Description - This function is a malloc equivalent that will be called from the - API in callbacks. This function is required to be able to provide - memory in interrupt context. - - Notes - For platforms where it is not possible to allocate memory in interrupt - context, we provide a reference allocator that takes memory during - initialization and implements malloc/free using this memory. - See the /api/hal/fpga/cyashalblkalloc.[ch] files for the - implementation, and the /api/hal/fpga/cyashalfpga.c file - for an example of the use of this allocator. - - Returns - A pointer to the allocated block of memory - - See Also - * CyAsHalCBFree - * CyAsHalAlloc -*/ -EXTERN void * -cy_as_hal_c_b_alloc( - /* The size of the memory block to allocate */ - uint32_t size - ); - -/* Summary - This function frees the memory allocated through the CyAsHalCBAlloc - call. - - Description - This function frees memory allocated through the CyAsHalCBAlloc - call, and is also required to support calls from interrupt - context. - - Returns - None - - See Also - * CyAsHalCBAlloc - * CyAsHalFree -*/ -EXTERN void -cy_as_hal_c_b_free( - /* Pointer to the memory block to be freed */ - void *ptr - ); - -/* Summary - This function sets a block of memory to a specific value - - Description - This function is the HAL layer equivalent of the memset() function. - - Returns - None -*/ -EXTERN void -cy_as_mem_set( - /* A pointer to a block of memory to set */ - void *ptr, - /* The value to set the memory to */ - uint8_t value, - /* The number of bytes to set */ - uint32_t cnt - ); - -/* Summary - This function creates or initializes a sleep channel - - Description - This function creates or initializes a sleep channel. The - sleep channel defined using the HAL data structure - CyAsHalSleepChannel. - - Returns - CyTrue is the initialization was successful, and CyFalse otherwise - - See Also - * CyAsHalSleepChannel - * CyAsHalDestroySleepChannel - * CyAsHalSleepOn - * CyAsHalWake -*/ -EXTERN cy_bool -cy_as_hal_create_sleep_channel( - /* Pointer to the sleep channel to create/initialize */ - cy_as_hal_sleep_channel *chan - ); - -/* Summary - This function destroys an existing sleep channel - - Description - This function destroys an existing sleep channel. The sleep channel - is of type CyAsHalSleepChannel. - - Returns - CyTrue if the channel was destroyed, and CyFalse otherwise - - See Also - * CyAsHalSleepChannel - * CyAsHalCreateSleepChannel - * CyAsHalSleepOn - * CyAsHalWake -*/ -EXTERN cy_bool -cy_as_hal_destroy_sleep_channel( - /* The sleep channel to destroy */ - cy_as_hal_sleep_channel chan - ); - -/* Summary - This function causes the calling process or thread to sleep until - CyAsHalWake() is called - - Description - This function causes the calling process or threadvto sleep. - When CyAsHalWake() is called on the same sleep channel, this - processes or thread is then wakened and allowed to run - - Returns - CyTrue if the thread or process is asleep, and CyFalse otherwise - - See Also - * CyAsHalSleepChannel - * CyAsHalWake -*/ -EXTERN cy_bool -cy_as_hal_sleep_on( - /* The sleep channel to sleep on */ - cy_as_hal_sleep_channel chan, - /* The maximum time to sleep in milli-seconds */ - uint32_t ms - ); - -/* Summary - This function casues the process or thread sleeping on the given - sleep channel to wake - - Description - This function causes the process or thread sleeping on the given - sleep channel to wake. The channel - - Returns - CyTrue if the thread or process is awake, and CyFalse otherwise - - See Also - * CyAsHalSleepChannel - * CyAsHalSleepOn -*/ -EXTERN cy_bool -cy_as_hal_wake( - /* The sleep channel to wake */ - cy_as_hal_sleep_channel chan - ); - -/* Summary - This function disables interrupts, insuring that short bursts - of code can be run without danger of interrupt handlers running. - - Description - There are cases within the API when lists must be manipulated by - both the API and the associated interrupt handlers. In these - cases, interrupts must be disabled to insure the integrity of the - list during the modification. This function is used to disable - interrupts during the short intervals where these lists are being - changed. - - The HAL must have the ability to nest calls to - CyAsHalDisableInterrupts and CyAsHalEnableInterrupts. - - Returns - Any interrupt related state value which will be passed back into - the subsequent CyAsHalEnableInterrupts call. - - See Also - * CyAsHalEnableInterrupts -*/ -EXTERN uint32_t -cy_as_hal_disable_interrupts(); - -/* Summary - This function re-enables interrupts after a critical section of - code in the API has been completed. - - Description - There are cases within the API when lists must be manipulated by - both the API and the associated interrupt handlers. In these - cases, interrupts must be disabled to insure the integrity of the - list during the modification. This function is used to enable - interrupts after the short intervals where these lists are being - changed. - - See Also - * CyAsHalDisableInterrupts -*/ -EXTERN void -cy_as_hal_enable_interrupts( - /* Value returned by the previous CyAsHalDisableInterrupts call. */ - uint32_t value - ); - -/* Summary - This function sleeps for 150 ns. - - Description - This function sleeps for 150 ns before allowing the calling function - to continue. This function is used for a specific purpose and the - sleep required is at least 150 ns. -*/ -EXTERN void -cy_as_hal_sleep150( - ); - -/* Summary - This function sleeps for the given number of milliseconds - - Description - This function sleeps for at least the given number of milliseonds -*/ -EXTERN void -cy_as_hal_sleep( - uint32_t ms - ); - -/* Summary - This function asserts when the condition evaluates to zero - - Description - Within the API there are conditions which are checked to insure - the integrity of the code. These conditions are checked only - within a DEBUG build. This function is used to check the condition - and if the result evaluates to zero, it should be considered a - fatal error that should be reported to Cypress. -*/ -EXTERN void -cy_as_hal_assert( - /* The condition to evaluate */ - cy_bool cond - ); - -/* Summary - This function prints a message from the API to a human readable device - - Description - There are places within the West Bridge API where printing a message - is useful to the debug process. This function provides the mechanism - to print a message. - - Returns - NONE -*/ -EXTERN void -cy_as_hal_print_message( - /* The message to print */ - const char *fmt_p, - ... /* Variable arguments */ - ); - -/* Summary - This function reports whether the HAL implementation uses - polling to service data coming from the West Bridge. - - Description - This function reports whether the HAL implementation uses - polling to service data coming from the West Bridge. - - Returns - CyTrue if the HAL polls the West Bridge Interrupt Status registers - to complete operations, CyFalse if the HAL is interrupt driven. - */ -EXTERN cy_bool -cy_as_hal_is_polling( - void); - -#endif diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasintr.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasintr.h deleted file mode 100644 index 60a6fffb5d53..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasintr.h +++ /dev/null @@ -1,104 +0,0 @@ -/* Cypress West Bridge API header file (cyasintr.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASINTR_H_ -#define _INCLUDED_CYASINTR_H_ - -#include "cyasdevice.h" - -#include "cyas_cplus_start.h" - -/* Summary - Initialize the interrupt manager module - - Description - This function is called to initialize the interrupt module. - This module enables interrupts as well as servies West Bridge - related interrupts by determining the source of the interrupt - and calling the appropriate handler function. - - Notes - If the dmaintr parameter is TRUE, the initialization code - initializes the interrupt mask to have the DMA related interrupt - enabled via the general purpose interrupt. However, the interrupt - service function assumes that the DMA interrupt is handled by the - HAL layer before the interrupt module handler function is called. - - Returns - * CY_AS_ERROR_SUCCESS - the interrupt module was initialized - * correctly - * CY_AS_ERROR_ALREADY_RUNNING - the interrupt module was already - * started - - See Also - * CyAsIntrStop - * CyAsServiceInterrupt -*/ -cy_as_return_status_t -cy_as_intr_start( - /* Device being initialized */ - cy_as_device *dev_p, - /* If true, enable the DMA interrupt through the INT signal */ - cy_bool dmaintr - ); - -/* Summary - Stop the interrupt manager module - - Description - This function stops the interrupt module and masks all interrupts - from the West Bridge device. - - Returns - * CY_AS_ERROR_SUCCESS - the interrupt module was stopped - * successfully - * CY_AS_ERROR_NOT_RUNNING - the interrupt module was not - * running - - See Also - * CyAsIntrStart - * CyAsServiceInterrupt -*/ -cy_as_return_status_t -cy_as_intr_stop( - /* Device bein stopped */ - cy_as_device *dev_p - ); - - -/* Summary - The interrupt service routine for West Bridge - - Description - When an interrupt is detected, this function is called to - service the West Bridge interrupt. It is safe and efficient - for this function to be called when no West Bridge interrupt - has occurred. This function will determine it is not an West - Bridge interrupt quickly and return. -*/ -void cy_as_intr_service_interrupt( - /* The USER supplied tag for this device */ - cy_as_hal_device_tag tag - ); - -#include "cyas_cplus_end.h" - -#endif /* _INCLUDED_CYASINTR_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslep2pep.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslep2pep.h deleted file mode 100644 index 6626cc454743..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslep2pep.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Cypress West Bridge API header file (cyaslep2pep.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASLEP2PEP_H_ -#define _INCLUDED_CYASLEP2PEP_H_ - -#include "cyasdevice.h" - -extern cy_as_return_status_t -cy_as_usb_map_logical2_physical(cy_as_device *dev_p); - -extern cy_as_return_status_t -cy_as_usb_setup_dma(cy_as_device *dev_p); - -extern cy_as_return_status_t -cy_as_usb_set_dma_sizes(cy_as_device *dev_p); - -#endif diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h deleted file mode 100644 index 5c7972f91ef6..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyaslowlevel.h +++ /dev/null @@ -1,366 +0,0 @@ -/* Cypress West Bridge API header file (cyaslowlevel.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASLOWLEVEL_H_ -#define _INCLUDED_CYASLOWLEVEL_H_ - -/*@@Low Level Communications - - Summary - The low level communications module is responsible for - communications between the West Bridge device and the P - port processor. Communications is organized as a series - of requests and subsequent responses. For each request - there is a one and only one response. Requests may go - from the West Bridge device to the P port processor, or - from the P Port processor to the West Bridge device. - - Description - Requests are issued across what is called a context. A - context is a single channel of communications from one - processor to another processor. There can be only a single - request outstanding on a context at a given time. Contexts - are used to identify subsystems that can only process a - single request at a time, but are independent of other - contexts in the system. For instance, there is a context - for communicating storage commands from the P port processor - to the West Bridge device. There is also a context for - communicating USB commands from the P port processor to the - West Bridge device. - - Requests and responses are identical with the exception of - the type bit in the request/response header. If the type - bit is one, the packet is a request. If this bit is zero, - the packet is a response. Also encoded within the header of - the request/response is the code. The code is a command - code for a request, or a response code for a response. For - a request, the code is a function of the context. The code - 0 has one meaning for the storage context and a different - meaning for the USB context. The code is treated differently - in the response. If the code in the response is less than 16, - then the meaning of the response is global across all - contexts. If the response is greater than or equal to 16, - then the response is specific to the associated context. - - Requests and responses are transferred between processors - through the mailbox registers. It may take one or more cycles - to transmit a complete request or response. The context is - encoded into each cycle of the transfer to insure the - receiving processor can route the data to the appropriate - context for processing. In this way, the traffic from multiple - contexts can be multiplexed into a single data stream through - the mailbox registers by the sending processor, and - demultiplexed from the mailbox registers by the receiving - processor. - - * Firmware Assumptions * - The firmware assumes that mailbox contents will be consumed - immediately. Therefore for multi-cycle packets, the data is - sent in a tight polling loop from the firmware. This implies - that the data must be read from the mailbox register on the P - port side and processed immediately or performance of the - firmware will suffer. In order to insure this is the case, - the data from the mailboxes is read and stored immediately - in a per context buffer. This occurs until the entire packet - is received at which time the request packet is processed. - Since the protocol is designed to allow for only one - outstanding packet at a time, the firmware can never be in a - position of waiting on the mailbox registers while the P port - is processing a request. Only after the response to the - previous request is sent will another request be sent. -*/ - -#include "cyashal.h" -#include "cyasdevice.h" - -#include "cyas_cplus_start.h" - -/* - * Constants - */ -#define CY_AS_REQUEST_RESPONSE_CODE_MASK (0x00ff) -#define CY_AS_REQUEST_RESPONSE_CONTEXT_MASK (0x0F00) -#define CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT (8) -#define CY_AS_REQUEST_RESPONSE_TYPE_MASK (0x4000) -#define CY_AS_REQUEST_RESPONSE_LAST_MASK (0x8000) -#define CY_AS_REQUEST_RESPONSE_CLEAR_STR_FLAG (0x1000) - -/* - * These macros extract the data from a 16 bit value - */ -#define cy_as_mbox_get_code(c) \ - ((uint8_t)((c) & CY_AS_REQUEST_RESPONSE_CODE_MASK)) -#define cy_as_mbox_get_context(c) \ - ((uint8_t)(((c) & CY_AS_REQUEST_RESPONSE_CONTEXT_MASK) \ - >> CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT)) -#define cy_as_mbox_is_last(c) \ - ((c) & CY_AS_REQUEST_RESPONSE_LAST_MASK) -#define cy_as_mbox_is_request(c) \ - (((c) & CY_AS_REQUEST_RESPONSE_TYPE_MASK) != 0) -#define cy_as_mbox_is_response(c) \ - (((c) & CY_AS_REQUEST_RESPONSE_TYPE_MASK) == 0) - -/* - * These macros (not yet written) pack data into or extract data - * from the m_box0 field of the request or response - */ -#define cy_as_ll_request_response__set_code(req, code) \ - ((req)->box0 = \ - ((req)->box0 & ~CY_AS_REQUEST_RESPONSE_CODE_MASK) | \ - (code & CY_AS_REQUEST_RESPONSE_CODE_MASK)) - -#define cy_as_ll_request_response__get_code(req) \ - cy_as_mbox_get_code((req)->box0) - -#define cy_as_ll_request_response__set_context(req, context) \ - ((req)->box0 |= ((context) << \ - CY_AS_REQUEST_RESPONSE_CONTEXT_SHIFT)) - -#define cy_as_ll_request_response__set_clear_storage_flag(req) \ - ((req)->box0 |= CY_AS_REQUEST_RESPONSE_CLEAR_STR_FLAG) - -#define cy_as_ll_request_response__get_context(req) \ - cy_as_mbox_get_context((req)->box0) - -#define cy_as_ll_request_response__is_last(req) \ - cy_as_mbox_is_last((req)->box0) - -#define CY_an_ll_request_response___set_last(req) \ - ((req)->box0 |= CY_AS_REQUEST_RESPONSE_LAST_MASK) - -#define cy_as_ll_request_response__is_request(req) \ - cy_as_mbox_is_request((req)->box0) - -#define cy_as_ll_request_response__set_request(req) \ - ((req)->box0 |= CY_AS_REQUEST_RESPONSE_TYPE_MASK) - -#define cy_as_ll_request_response__set_response(req) \ - ((req)->box0 &= ~CY_AS_REQUEST_RESPONSE_TYPE_MASK) - -#define cy_as_ll_request_response__is_response(req) \ - cy_as_mbox_is_response((req)->box0) - -#define cy_as_ll_request_response__get_word(req, offset) \ - ((req)->data[(offset)]) - -#define cy_as_ll_request_response__set_word(req, offset, \ - value) ((req)->data[(offset)] = value) - -typedef enum cy_as_remove_request_result_t { - cy_as_remove_request_sucessful, - cy_as_remove_request_in_transit, - cy_as_remove_request_not_found -} cy_as_remove_request_result_t; - -/* Summary - Start the low level communications module - - Description -*/ -cy_as_return_status_t -cy_as_ll_start( - cy_as_device *dev_p - ); - -cy_as_return_status_t -cy_as_ll_stop( - cy_as_device *dev_p - ); - - -cy_as_ll_request_response * -cy_as_ll_create_request( - cy_as_device *dev_p, - uint16_t code, - uint8_t context, - /* Length of the request in 16 bit words */ - uint16_t length - ); - -void -cy_as_ll_init_request( - cy_as_ll_request_response *req_p, - uint16_t code, - uint16_t context, - uint16_t length); - -void -cy_as_ll_init_response( - cy_as_ll_request_response *req_p, - uint16_t length); - -void -cy_as_ll_destroy_request( - cy_as_device *dev_p, - cy_as_ll_request_response *); - -cy_as_ll_request_response * -cy_as_ll_create_response( - cy_as_device *dev_p, - /* Length of the request in 16 bit words */ - uint16_t length - ); - -cy_as_remove_request_result_t -cy_as_ll_remove_request( - cy_as_device *dev_p, - cy_as_context *ctxt_p, - cy_as_ll_request_response *req_p, - cy_bool force - ); -void -cy_as_ll_remove_all_requests(cy_as_device *dev_p, - cy_as_context *ctxt_p); - -void -cy_as_ll_destroy_response( - cy_as_device *dev_p, - cy_as_ll_request_response *); - -cy_as_return_status_t -cy_as_ll_send_request( - /* The West Bridge device */ - cy_as_device *dev_p, - /* The request to send */ - cy_as_ll_request_response *req, - /* Storage for a reply, must be sure it is of sufficient size */ - cy_as_ll_request_response *resp, - /* If true, this is a sync request */ - cy_bool sync, - /* Callback to call when reply is received */ - cy_as_response_callback cb -); - -cy_as_return_status_t -cy_as_ll_send_request_wait_reply( - /* The West Bridge device */ - cy_as_device *dev_p, - /* The request to send */ - cy_as_ll_request_response *req, - /* Storage for a reply, must be sure it is of sufficient size */ - cy_as_ll_request_response *resp -); - -/* Summary - This function registers a callback function to be called when a - request arrives on a given context. - - Description - - Returns - * CY_AS_ERROR_SUCCESS -*/ -extern cy_as_return_status_t -cy_as_ll_register_request_callback( - cy_as_device *dev_p, - uint8_t context, - cy_as_response_callback cb - ); - -/* Summary - This function packs a set of bytes given by the data_p pointer - into a request, reply structure. -*/ -extern void -cy_as_ll_request_response__pack( - /* The destintation request or response */ - cy_as_ll_request_response *req, - /* The offset of where to pack the data */ - uint32_t offset, - /* The length of the data to pack in bytes */ - uint32_t length, - /* The data to pack */ - void *data_p - ); - -/* Summary - This function unpacks a set of bytes from a request/reply - structure into a segment of memory given by the data_p pointer. -*/ -extern void -cy_as_ll_request_response__unpack( - /* The source of the data to unpack */ - cy_as_ll_request_response *req, - /* The offset of the data to unpack */ - uint32_t offset, - /* The length of the data to unpack in bytes */ - uint32_t length, - /* The destination of the unpack operation */ - void *data_p - ); - -/* Summary - This function sends a status response back to the West Bridge - device in response to a previously send request -*/ -extern cy_as_return_status_t -cy_as_ll_send_status_response( - /* The West Bridge device */ - cy_as_device *dev_p, - /* The context to send the response on */ - uint8_t context, - /* The success/failure code to send */ - uint16_t code, - /* Flag to clear wait on storage context */ - uint8_t clear_storage); - -/* Summary - This function sends a response back to the West Bridge device. - - Description - This function sends a response back to the West Bridge device. - The response is sent on the context given by the 'context' - variable. The code for the response is given by the 'code' - argument. The data for the response is given by the data and - length arguments. -*/ -extern cy_as_return_status_t -cy_as_ll_send_data_response( - /* The West Bridge device */ - cy_as_device *dev_p, - /* The context to send the response on */ - uint8_t context, - /* The response code to use */ - uint16_t code, - /* The length of the data for the response */ - uint16_t length, - /* The data for the response */ - void *data -); - -/* Summary - This function removes any requests of the given type - from the given context. - - Description - This function removes requests of a given type from the - context given via the context number. -*/ -extern cy_as_return_status_t -cy_as_ll_remove_ep_data_requests( - /* The West Bridge device */ - cy_as_device *dev_p, - cy_as_end_point_number_t ep - ); - -#include "cyas_cplus_end.h" - -#endif /* _INCLUDED_CYASLOWLEVEL_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmedia.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmedia.h deleted file mode 100644 index 0e25ea94481f..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmedia.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Cypress West Bridge API header file (cyasmedia.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASMEDIA_H_ -#define _INCLUDED_CYASMEDIA_H_ - -#include "cyas_cplus_start.h" - - -/* Summary - Specifies a specific type of media supported by West Bridge - - Description - The West Bridge device supports five specific types of media - as storage/IO devices attached to it's S-Port. This type is - used to indicate the type of media being referenced in any - API call. -*/ -typedef enum cy_as_media_type { - /* Flash NAND memory (may be SLC or MLC) */ - cy_as_media_nand = 0x00, - /* An SD flash memory device */ - cy_as_media_sd_flash = 0x01, - /* An MMC flash memory device */ - cy_as_media_mmc_flash = 0x02, - /* A CE-ATA disk drive */ - cy_as_media_ce_ata = 0x03, - /* SDIO device. */ - cy_as_media_sdio = 0x04, - cy_as_media_max_media_value = 0x05 - -} cy_as_media_type; - -#include "cyas_cplus_end.h" - -#endif /* _INCLUDED_CYASMEDIA_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h deleted file mode 100644 index df7c2b66cf27..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc.h +++ /dev/null @@ -1,1549 +0,0 @@ -/* Cypress West Bridge API header file (cyasmisc.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASMISC_H_ -#define _INCLUDED_CYASMISC_H_ - -#include "cyashal.h" -#include "cyastypes.h" -#include "cyasmedia.h" - -#include "cyas_cplus_start.h" - -#define CY_AS_LEAVE_STANDBY_DELAY_CLOCK (1) -#define CY_AS_RESET_DELAY_CLOCK (1) - -#define CY_AS_LEAVE_STANDBY_DELAY_CRYSTAL (5) -#define CY_AS_RESET_DELAY_CRYSTAL (5) - -/* The maximum number of buses supported */ -#define CY_AS_MAX_BUSES (2) - -/* The maximum number of storage devices supported per bus */ -#define CY_AS_MAX_STORAGE_DEVICES (1) - -#define CY_AS_FUNCTCBTYPE_DATA_MASK (0x60000000U) -#define CY_AS_FUNCTCBTYPE_TYPE_MASK (0x1FFFFFFFU) - -#define cy_as_funct_c_b_type_get_type(t) \ - ((cy_as_funct_c_b_type)((t) & CY_AS_FUNCTCBTYPE_TYPE_MASK)) -#define cy_as_funct_c_b_type_contains_data(t) \ - (((cy_as_funct_c_b_type)((t) & \ - CY_AS_FUNCTCBTYPE_DATA_MASK)) == CY_FUNCT_CB_DATA) - -/************************************** - * West Bridge Types - **************************************/ - -/* Summary - Specifies a handle to an West Bridge device - - Description - This type represents an opaque handle to an West Bridge device. - This handle is created via the CyAsMiscCreateDevice() function - and is used in all subsequent calls that communicate to the West - Bridge device. - - See Also - * CyAsMiscCreateDevice - * CyAsMiscDestroyDevice -*/ -typedef void *cy_as_device_handle; - -/* Summary - This data type gives the mode for the DACK# signal -*/ -typedef enum cy_as_device_dack_mode { - cy_as_device_dack_ack, /* Operate in the ACK mode */ - cy_as_device_dack_eob /* Operate in the EOB mode */ -} cy_as_device_dack_mode; - -/* Summary - This data structure gives the options for all hardware features. - - Description - This structure contains the information required to initialize the - West Bridge hardware. Any features of the device that can be - configured by the caller are specified here. - - See Also - * CyAsMiscConfigure -*/ -typedef struct cy_as_device_config { - /* If TRUE, the P port is running in SRAM mode. */ - cy_bool srammode; - /* If TRUE, the P port is synchronous, otherwise async */ - cy_bool sync; - /* If TRUE, DMA req will be delivered via the interrupt signal */ - cy_bool dmaintr; - /* Mode for the DACK# signal */ - cy_as_device_dack_mode dackmode; - /* If TRUE, the DRQ line is active high, otherwise active low */ - cy_bool drqpol; - /* If TRUE, the DACK line is active high, otherwise active low */ - cy_bool dackpol; - /* If TRUE, the clock is connected to a crystal, otherwise it is - connected to a clock */ - cy_bool crystal; -} cy_as_device_config; - - -/* Summary - Specifies a resource that can be owned by either the West Bridge - device or by the processor. - - Description - This enumerated type identifies a resource that can be owned - either by the West Bridge device, or by the processor attached to - the P port of the West Bridge device. - - See Also - * CyAsMiscAcquireResource - * CyAsMiscReleaseResource -*/ -typedef enum cy_as_resource_type { - cy_as_bus_u_s_b = 0, /* The USB D+ and D- pins */ - cy_as_bus_1 = 1, /* The SDIO bus */ - cy_as_bus_0 = 2 /* The NAND bus (not implemented) */ -} cy_as_resource_type; - -/* Summary - Specifies the reset type for a software reset operation. - - Description - When the West Bridge device is reset, there are two types of - reset that arE possible. This type indicates the type of reset - requested. - - Notes - Both of these reset types are software based resets; and are - distinct from a chip level HARD reset that is applied through - the reset pin on the West Bridge. - - The CyAsResetSoft type resets only the on-chip micro-controller - in the West Bridge. In this case, the previously loaded firmware - will continue running. However, the Storage and USB stack - operations will need to be restarted, as any state relating to - these would have been lost. - - The CyAsResetHard type resets the entire West Bridge chip, and will - need a fresh configuration and firmware download. - - See Also - * - */ - -typedef enum cy_as_reset_type { - /* Just resets the West Bridge micro-controller */ - cy_as_reset_soft, - /* Resets entire device, firmware must be reloaded and - the west bridge device must be re-initialized */ - cy_as_reset_hard -} cy_as_reset_type; - - - -/* Summary - This type specifies the polarity of the SD power pin. - - Description - Sets the SD power pin ( port C, bit 6) to active low or - active high. - -*/ - -typedef enum cy_as_misc_signal_polarity { - cy_as_misc_active_high, - cy_as_misc_active_low - -} cy_as_misc_signal_polarity; - - - -/* Summary - This type specifies the type of the data returned by a Function - Callback. - - Description - CY_FUNCT_CB_NODATA - This callback does not return any additional - information in the data field. - CY_FUNCT_CB_DATA - The data field is used, and the CyAsFunctCBType - will also contain the type of this data. - - See Also - CyAsFunctionCallback -*/ -typedef enum cy_as_funct_c_b_type { - CY_FUNCT_CB_INVALID = 0x0U, - /* Data from a CyAsMiscGetFirmwareVersion call. */ - CY_FUNCT_CB_MISC_GETFIRMWAREVERSION, - /* Data from a CyAsMiscHeartBeatControl call. */ - CY_FUNCT_CB_MISC_HEARTBEATCONTROL, - /* Data from a CyAsMiscAcquireResource call. */ - CY_FUNCT_CB_MISC_ACQUIRERESOURCE, - /* Data from a CyAsMiscReadMCURegister call. */ - CY_FUNCT_CB_MISC_READMCUREGISTER, - /* Data from a CyAsMiscWriteMCURegister call. */ - CY_FUNCT_CB_MISC_WRITEMCUREGISTER, - /* Data from a CyAsMiscSetTraceLevel call. */ - CY_FUNCT_CB_MISC_SETTRACELEVEL, - /* Data from a CyAsMiscStorageChanged call. */ - CY_FUNCT_CB_MISC_STORAGECHANGED, - /* Data from a CyAsMiscGetGpioValue call. */ - CY_FUNCT_CB_MISC_GETGPIOVALUE, - /* Data from a CyAsMiscSetGpioValue call. */ - CY_FUNCT_CB_MISC_SETGPIOVALUE, - /* Data from a CyAsMiscDownloadFirmware call. */ - CY_FUNCT_CB_MISC_DOWNLOADFIRMWARE, - /* Data from a CyAsMiscEnterStandby call. */ - CY_FUNCT_CB_MISC_ENTERSTANDBY, - /* Data from a CyAsMiscEnterSuspend call. */ - CY_FUNCT_CB_MISC_ENTERSUSPEND, - /* Data from a CyAsMiscLeaveSuspend call. */ - CY_FUNCT_CB_MISC_LEAVESUSPEND, - /* Data from a CyAsMiscReset call. */ - CY_FUNCT_CB_MISC_RESET, - /* Data from a CyAsMiscSetLowSpeedSDFreq or - * CyAsMiscSetHighSpeedSDFreq call. */ - CY_FUNCT_CB_MISC_SETSDFREQ, - /* Data from a CyAsMiscSwitchPnandMode call */ - CY_FUNCT_CB_MISC_RESERVELNABOOTAREA, - /* Data from a CyAsMiscSetSDPowerPolarity call */ - CY_FUNCT_CB_MISC_SETSDPOLARITY, - - /* Data from a CyAsStorageStart call. */ - CY_FUNCT_CB_STOR_START, - /* Data from a CyAsStorageStop call. */ - CY_FUNCT_CB_STOR_STOP, - /* Data from a CyAsStorageClaim call. */ - CY_FUNCT_CB_STOR_CLAIM, - /* Data from a CyAsStorageRelease call. */ - CY_FUNCT_CB_STOR_RELEASE, - /* Data from a CyAsStorageQueryMedia call. */ - CY_FUNCT_CB_STOR_QUERYMEDIA, - /* Data from a CyAsStorageQueryBus call. */ - CY_FUNCT_CB_STOR_QUERYBUS, - /* Data from a CyAsStorageQueryDevice call. */ - CY_FUNCT_CB_STOR_QUERYDEVICE, - /* Data from a CyAsStorageQueryUnit call. */ - CY_FUNCT_CB_STOR_QUERYUNIT, - /* Data from a CyAsStorageDeviceControl call. */ - CY_FUNCT_CB_STOR_DEVICECONTROL, - /* Data from a CyAsStorageSDRegisterRead call. */ - CY_FUNCT_CB_STOR_SDREGISTERREAD, - /* Data from a CyAsStorageCreatePartition call. */ - CY_FUNCT_CB_STOR_PARTITION, - /* Data from a CyAsStorageGetTransferAmount call. */ - CY_FUNCT_CB_STOR_GETTRANSFERAMOUNT, - /* Data from a CyAsStorageErase call. */ - CY_FUNCT_CB_STOR_ERASE, - /* Data from a CyAsStorageCancelAsync call. */ - CY_FUNCT_CB_ABORT_P2S_XFER, - /* Data from a CyAsUsbStart call. */ - CY_FUNCT_CB_USB_START, - /* Data from a CyAsUsbStop call. */ - CY_FUNCT_CB_USB_STOP, - /* Data from a CyAsUsbConnect call. */ - CY_FUNCT_CB_USB_CONNECT, - /* Data from a CyAsUsbDisconnect call. */ - CY_FUNCT_CB_USB_DISCONNECT, - /* Data from a CyAsUsbSetEnumConfig call. */ - CY_FUNCT_CB_USB_SETENUMCONFIG, - /* Data from a CyAsUsbGetEnumConfig call. */ - CY_FUNCT_CB_USB_GETENUMCONFIG, - /* Data from a CyAsUsbSetDescriptor call. */ - CY_FUNCT_CB_USB_SETDESCRIPTOR, - /* Data from a CyAsUsbGetDescriptor call. */ - CY_FUNCT_CB_USB_GETDESCRIPTOR, - /* Data from a CyAsUsbCommitConfig call. */ - CY_FUNCT_CB_USB_COMMITCONFIG, - /* Data from a CyAsUsbGetNak call. */ - CY_FUNCT_CB_USB_GETNAK, - /* Data from a CyAsUsbGetStall call. */ - CY_FUNCT_CB_USB_GETSTALL, - /* Data from a CyAsUsbSignalRemoteWakeup call. */ - CY_FUNCT_CB_USB_SIGNALREMOTEWAKEUP, - /* Data from a CyAnUsbClearDescriptors call. */ - CY_FUNCT_CB_USB_CLEARDESCRIPTORS, - /* Data from a CyAnUsbSetMSReportThreshold call. */ - CY_FUNCT_CB_USB_SET_MSREPORT_THRESHOLD, - /* Data from a CyAsMTPStart call. */ - CY_FUNCT_CB_MTP_START, - /* Data from a CyAsMTPStop call. */ - CY_FUNCT_CB_MTP_STOP, - /* Data from a CyAsMTPInitSendObject call. */ - CY_FUNCT_CB_MTP_INIT_SEND_OBJECT, - /* Data from a CyAsMTPCancelSendObject call. */ - CY_FUNCT_CB_MTP_CANCEL_SEND_OBJECT, - /* Data from a CyAsMTPInitGetObject call. */ - CY_FUNCT_CB_MTP_INIT_GET_OBJECT, - /* Data from a CyAsMTPCancelGetObject call. */ - CY_FUNCT_CB_MTP_CANCEL_GET_OBJECT, - /* Data from a CyAsMTPSendBlockTable call. */ - CY_FUNCT_CB_MTP_SEND_BLOCK_TABLE, - /* Data from a CyAsMTPStopStorageOnly call. */ - CY_FUNCT_CB_MTP_STOP_STORAGE_ONLY, - CY_FUNCT_CB_NODATA = 0x40000000U, - CY_FUNCT_CB_DATA = 0x20000000U -} cy_as_funct_c_b_type; - -/* Summary - This type specifies the general West Bridge function callback. - - Description - This callback is supplied as an argument to all asynchronous - functions in the API. It iS called after the asynchronous function - has completed. - - See Also - CyAsFunctCBType -*/ -typedef void (*cy_as_function_callback)( - cy_as_device_handle handle, - cy_as_return_status_t status, - uint32_t client, - cy_as_funct_c_b_type type, - void *data); - -/* Summary - This type specifies the general West Bridge event that has - occurred. - - Description - This type is used in the West Bridge misc callback function to - indicate the type of callback. - - See Also -*/ -typedef enum cy_as_misc_event_type { - /* This event is sent when West Bridge has finished - initialization and is ready to respond to API calls. */ - cy_as_event_misc_initialized = 0, - - /* This event is sent when West Bridge has left the - standby state and is ready to respond to commands again. */ - cy_as_event_misc_awake, - - /* This event is sent periodically from the firmware - to the processor. */ - cy_as_event_misc_heart_beat, - - /* This event is sent when the West Bridge has left the - suspend mode and is ready to respond to commands - again. */ - cy_as_event_misc_wakeup, - - /* This event is sent when the firmware image downloaded - cannot run on the active west bridge device. */ - cy_as_event_misc_device_mismatch -} cy_as_misc_event_type; - -/* Summary - This type is the type of a callback function that is called when a - West Bridge misc event occurs. - - Description - At times West Bridge needs to inform the P port processor of events - that have occurred. These events are asynchronous to the thread of - control on the P port processor and as such are generally delivered - via a callback function that is called as part of an interrupt - handler. This type defines the type of function that must be provided - as a callback function for West Bridge misc events. - - See Also - * CyAsMiscEventType -*/ -typedef void (*cy_as_misc_event_callback)( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* The event type being reported */ - cy_as_misc_event_type ev, - /* The data assocaited with the event being reported */ - void *evdata -); - -#ifndef __doxygen__ -/* Summary - This enum provides info of various firmware trace levels. - - Description - - See Also - * CyAsMiscSetTraceLevel -*/ -enum { - CYAS_FW_TRACE_LOG_NONE = 0, /* Log nothing. */ - CYAS_FW_TRACE_LOG_STATE, /* Log state information. */ - CYAS_FW_TRACE_LOG_CALLS, /* Log function calls. */ - CYAS_FW_TRACE_LOG_STACK_TRACE, /* Log function calls with args. */ - CYAS_FW_TRACE_MAX_LEVEL /* Max trace level sentinel. */ -}; -#endif - -/* Summary - This enum lists the controllable GPIOs of the West Bridge device. - - Description - The West Bridge device has GPIOs that can be used for user defined functions. - This enumeration lists the GPIOs that are available on the device. - - Notes - All of the GPIOs except UVALID can only be accessed when using West Bridge - firmware images that support only SD/MMC/MMC+ storage devices. This - functionality is not supported in firmware images that support NAND - storage. - - See Also - * CyAsMiscGetGpioValue - * CyAsMiscSetGpioValue - */ -typedef enum { - cy_as_misc_gpio_0 = 0, /* GPIO[0] pin */ - cy_as_misc_gpio_1, /* GPIO[1] pin */ - cy_as_misc_gpio__nand_CE, /* NAND_CE pin, output only */ - cy_as_misc_gpio__nand_CE2, /* NAND_CE2 pin, output only */ - cy_as_misc_gpio__nand_WP, /* NAND_WP pin, output only */ - cy_as_misc_gpio__nand_CLE, /* NAND_CLE pin, output only */ - cy_as_misc_gpio__nand_ALE, /* NAND_ALE pin, output only */ - /* SD_POW pin, output only, do not drive low while storage is active */ - cy_as_misc_gpio_SD_POW, - cy_as_misc_gpio_U_valid /* UVALID pin */ -} cy_as_misc_gpio; - -/* Summary - This enum lists the set of clock frequencies that are supported for - working with low speed SD media. - - Description - West Bridge firmware uses a clock frequency less than the maximum - possible rate for low speed SD media. This can be changed to a - setting equal to the maximum frequency as desired by the user. This - enumeration lists the different frequency settings that are - supported. - - See Also - * CyAsMiscSetLowSpeedSDFreq - */ -typedef enum cy_as_low_speed_sd_freq { - /* Approx. 21.82 MHz, default value */ - CY_AS_SD_DEFAULT_FREQ = 0, - /* 24 MHz */ - CY_AS_SD_RATED_FREQ -} cy_as_low_speed_sd_freq; - -/* Summary - This enum lists the set of clock frequencies that are supported - for working with high speed SD media. - - Description - West Bridge firmware uses a 48 MHz clock by default to interface - with high speed SD/MMC media. This can be changed to 24 MHz if - so desired by the user. This enum lists the different frequencies - that are supported. - - See Also - * CyAsMiscSetHighSpeedSDFreq - */ -typedef enum cy_as_high_speed_sd_freq { - CY_AS_HS_SD_FREQ_48, /* 48 MHz, default value */ - CY_AS_HS_SD_FREQ_24 /* 24 MHz */ -} cy_as_high_speed_sd_freq; - -/* Summary - Struct encapsulating all information returned by the - CyAsMiscGetFirmwareVersion call. - - Description - This struct encapsulates all return values from the asynchronous - CyAsMiscGetFirmwareVersion call, so that a single data argument - can be passed to the user provided callback function. - - See Also - * CyAsMiscGetFirmwareVersion - */ -typedef struct cy_as_get_firmware_version_data { - /* Return value for major version number for the firmware */ - uint16_t major; - /* Return value for minor version number for the firmware */ - uint16_t minor; - /* Return value for build version number for the firmware */ - uint16_t build; - /* Return value for media types supported in the current firmware */ - uint8_t media_type; - /* Return value to indicate the release or debug mode of firmware */ - cy_bool is_debug_mode; -} cy_as_get_firmware_version_data; - - -/***************************** - * West Bridge Functions - *****************************/ - -/* Summary - This function creates a new West Bridge device and returns a - handle to the device. - - Description - This function initializes the API object that represents the West - Bridge device and returns a handle to this device. This handle is - required for all West Bridge related functions to identify the - specific West Bridge device. - - * Valid In Asynchronous Callback: NO - - Returns - * CY_AS_ERROR_SUCCESS - * CY_AS_ERROR_OUT_OF_MEMORY -*/ -EXTERN cy_as_return_status_t -cy_as_misc_create_device( - /* Return value for handle to created device */ - cy_as_device_handle *handle_p, - /* The HAL specific tag for this device */ - cy_as_hal_device_tag tag - ); - -/* Summary - This functions destroys a previously created West Bridge device. - - Description - When an West Bridge device is created, an opaque handle is returned - that represents the device. This function destroys that handle and - frees all resources associated with the handle. - - * Valid In Asynchronous Callback: NO - - Returns - * CY_AS_ERROR_SUCCESS - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_STILL_RUNNING - The USB or STORAGE stacks are still - * running, they must be stopped before the device can be destroyed - * CY_AS_ERROR_DESTROY_SLEEP_CHANNEL_FAILED - the HAL layer failed to - * destroy a sleep channel -*/ -EXTERN cy_as_return_status_t -cy_as_misc_destroy_device( - /* Handle to the device to destroy */ - cy_as_device_handle handle - ); - -/* Summary - This function initializes the hardware for basic communication with - West Bridge. - - Description - This function initializes the hardware to establish basic - communication with the West Bridge device. This is always the first - function called to initialize communication with the West Bridge - device. - - * Valid In Asynchronous Callback: NO - - Returns - * CY_AS_ERROR_SUCCESS - the basic initialization was completed - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_IN_STANDBY - * CY_AS_ERROR_ALREADY_RUNNING - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_NO_ANTIOCH - cannot find the West Bridge device - * CY_AS_ERROR_CREATE_SLEEP_CHANNEL_FAILED - - * the HAL layer falied to create a sleep channel - - See Also - * CyAsDeviceConfig -*/ -EXTERN cy_as_return_status_t -cy_as_misc_configure_device( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* Configuration information */ - cy_as_device_config *config_p - ); - -/* Summary - This function returns non-zero if West Bridge is in standby and - zero otherwise. - - Description - West Bridge supports a standby mode. This function is used to - query West Bridge to determine if West Bridge is in a standby - mode. - - * Valid In Asynchronous Callback: YES - - Returns - * CY_AS_ERROR_SUCCESS - * CY_AS_ERROR_INVALID_HANDLE -*/ -EXTERN cy_as_return_status_t -cy_as_misc_in_standby( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* Return value for standby state */ - cy_bool *standby - ); - -/* Summary - This function downloads the firmware to West Bridge device. - - Description - This function downloads firmware from a given location and with a - given size to the West Bridge device. After the firmware is - downloaded the West Bridge device is moved out of configuration - mode causing the firmware to be executed. It is an error to call - this function when the device is not in configuration mode. The - device is in configuration mode on power up and may be placed in - configuration mode after power up with a hard reset. - - Notes - The firmware must be on a word align boundary. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the firmware was successfully downloaded - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * was not configured - * CY_AS_ERROR_NOT_IN_CONFIG_MODE - * CY_AS_ERROR_INVALID_SIZE - the size of the firmware - * exceeded 32768 bytes - * CY_AS_ERROR_ALIGNMENT_ERROR - * CY_AS_ERROR_IN_STANDBY - trying to download - * while in standby mode - * CY_AS_ERROR_TIMEOUT - - See Also - * CyAsMiscReset -*/ -EXTERN cy_as_return_status_t -cy_as_misc_download_firmware( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* Pointer to the firmware to be downloaded */ - const void *fw_p, - /* The size of the firmware in bytes */ - uint16_t size, - /* Callback to call when the operation is complete. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - - -/* Summary - This function returns the version number of the firmware running in - the West Bridge device. - - Description - This function queries the West Bridge device and retreives the - firmware version number. If the firmware is not loaded an error is - returned indicated no firmware has been loaded. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the firmware version number was retreived - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been downloaded - * to the device - * CY_AS_ERROR_IN_STANDBY - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a response - * from the West Bridge firmware -*/ -EXTERN cy_as_return_status_t -cy_as_misc_get_firmware_version( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* Return values indicating the firmware version. */ - cy_as_get_firmware_version_data *data, - /* Callback to call when the operation is complete. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -#if !defined(__doxygen__) - -/* Summary - This function reads and returns the contents of an MCU accessible - register on the West Bridge. - - Description - This function requests the firmware to read and return the contents - of an MCU accessible register through the mailboxes. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the register content was retrieved. - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a response - * from the West Bridge firmware - * CY_AS_ERROR_INVALID_RESPONSE - the firmware build does not - * support this command. -*/ -EXTERN cy_as_return_status_t -cy_as_misc_read_m_c_u_register( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* Address of the register to read */ - uint16_t address, - /* Return value for the MCU register content */ - uint8_t *value, - /* Callback to call when the operation is complete. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -/* Summary - This function writes to an MCU accessible register on the West Bridge. - - Description - This function requests the firmware to write a specified value to an - MCU accessible register through the mailboxes. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Notes - This function is only for internal use by the West Bridge API layer. - Calling this function directly can cause device malfunction. - - Returns - * CY_AS_ERROR_SUCCESS - the register content was updated. - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a response - * from the West Bridge firmware - * CY_AS_ERROR_INVALID_RESPONSE - the firmware build does not support - * this command. -*/ -EXTERN cy_as_return_status_t -cy_as_misc_write_m_c_u_register( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* Address of the register to write */ - uint16_t address, - /* Mask to be applied on the register contents. */ - uint8_t mask, - /* Data to be ORed with the register contents. */ - uint8_t value, - /* Callback to call when the operation is complete. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -#endif - -/* Summary - This function will reset the West Bridge device and software API. - - Description - This function will reset the West Bridge device and software API. - The reset operation can be a hard reset or a soft reset. A hard - reset will reset all aspects of the West Bridge device. The device - will enter the configuration state and the firmware will have to be - reloaded. The device will also have to be re-initialized. A soft - reset just resets the West Bridge micro-controller. - - * Valid In Asynchronous Callback: NO - - Notes - When a hard reset is issued, the firmware that may have been - previously loaded will be lost and any configuration information set - via CyAsMiscConfigureDevice() will be lost. This will be reflected - in the API maintained state of the device. In order to re-establish - communications with the West Bridge device, CyAsMiscConfigureDevice() - and CyAsMiscDownloadFirmware() must be called again. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the device has been reset - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - * CY_AS_ERROR_NOT_YET_SUPPORTED - current soft reset is not supported - * CY_AS_ERROR_ASYNC_PENDING - Reset is unable to flush pending async - * reads/writes in polling mode. - - - See Also - * CyAsMiscReset -*/ -EXTERN cy_as_return_status_t -cy_as_misc_reset( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* The type of reset to perform */ - cy_as_reset_type type, - /* If true, flush all pending writes to mass storage - before performing the reset. */ - cy_bool flush, - /* Callback to call when the operation is complete. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -/* Summary - This function acquires a given resource. - - Description - There are resources in the system that are shared between the - West Bridge device and the processor attached to the P port of - the West Bridge device. This API provides a mechanism for the - P port processor to acquire ownership of a resource. - - Notes - The ownership of the resources controlled by CyAsMiscAcquireResource() - and CyAsMiscReleaseResource() defaults to a known state at hardware - reset. After the firmware is loaded and begins execution the state of - these resources may change. At any point if the P Port processor needs - to acquire a resource it should do so explicitly to be sure of - ownership. - - Returns - * CY_AS_ERROR_SUCCESS - the p port successfully acquired the - * resource of interest - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - * CY_AS_ERROR_INVALID_RESOURCE - * CY_AS_ERROR_RESOURCE_ALREADY_OWNED - the p port already - * owns this resource - * CY_AS_ERROR_NOT_ACQUIRED - the resource cannot be acquired - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a - * response from the West Bridge firmware - - See Also - * CyAsResourceType -*/ -EXTERN cy_as_return_status_t -cy_as_misc_acquire_resource( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* The resource to acquire */ - cy_as_resource_type *resource, - /* If true, force West Bridge to release the resource */ - cy_bool force, - /* Callback to call when the operation is complete. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -/* Summary - This function releases a given resource. - - Description - There are resources in the system that are shared between the - West Bridge device and the processor attached to the P port of - the West Bridge device. This API provides a mechanism for the - P port processor to release a resource that has previously been - acquired via the CyAsMiscAcquireResource() call. - - * Valid In Asynchronous Callback: NO - - Returns - * CY_AS_ERROR_SUCCESS - the p port successfully released - * the resource of interest - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - * CY_AS_ERROR_INVALID_RESOURCE - * CY_AS_ERROR_RESOURCE_NOT_OWNED - the p port does not own the - * resource of interest - - See Also - * CyAsResourceType - * CyAsMiscAcquireResource -*/ -EXTERN cy_as_return_status_t -cy_as_misc_release_resource( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* The resource to release */ - cy_as_resource_type resource - ); - -#ifndef __doxygen__ -/* Summary - This function sets the trace level for the West Bridge firmware. - - Description - The West Bridge firmware has the ability to store information - about the state and execution path of the firmware on a mass storage - device attached to the West Bridge device. This function configures - the specific mass storage device to be used and the type of information - to be stored. This state information is used for debugging purposes - and must be interpreted by a Cypress provided tool. - - *Trace Level* - The trace level indicates the amount of information to output. - * 0 = no trace information is output - * 1 = state information is output - * 2 = function call information is output - * 3 = function call, arguments, and return value information is output - - * Valid In Asynchronous Callback: NO - - Notes - The media device and unit specified in this call will be overwritten - and any data currently stored on this device and unit will be lost. - - * NOT IMPLEMENTED YET - - Returns - * CY_AS_ERROR_SUCCESS - the trace configuration has been - * successfully changed - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device - * pair does not exist - * CY_AS_ERROR_NO_SUCH_UNIT - the unit specified does not exist - * CY_AS_ERROR_INVALID_TRACE_LEVEL - the trace level requested - * does not exist - * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a - * response from the West Bridge firmware -*/ -EXTERN cy_as_return_status_t -cy_as_misc_set_trace_level( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* The trace level */ - uint8_t level, - /* The bus for the output */ - cy_as_bus_number_t bus, - /* The device for the output */ - uint32_t device, - /* The unit for the output */ - uint32_t unit, - /* Callback to call when the operation is complete. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); -#endif - -/* Summary - This function places West Bridge into the low power standby mode. - - Description - This function places West Bridge into a low power (sleep) mode, and - cannot be called while the USB stack is active. This function first - instructs the West Bridge firmware that the device is about to be - placed into sleep mode. This allows West Bridge to complete any pending - storage operations. After the West Bridge device has responded that - pending operations are complete, the device is placed in standby mode. - - There are two methods of placing the device in standby mode. If the - WAKEUP pin of the West Bridge is connected to a GPIO on the processor, - the pin is de-asserted (via the HAL layer) and West Bridge enters into - a sleep mode. If the WAKEUP pin is not accessible, the processor can - write into the power management control/status register on the West - Bridge to put the device into sleep mode. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the function completed and West Bridge - * is in sleep mode - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_ALREADY_STANDBY - the West Bridge device is already - * in sleep mode - * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a response - * from the West Bridge firmware - * CY_AS_ERROR_NOT_SUPPORTED - the HAL layer does not support changing - * the WAKEUP pin - * CY_AS_ERROR_USB_RUNNING - The USB stack is still running when the - * EnterStandby call is made - * CY_AS_ERROR_ASYNC_PENDING - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - * CY_AS_ERROR_SETTING_WAKEUP_PIN - * CY_AS_ERROR_ASYNC_PENDING - In polling mode EnterStandby can not - * be called until all pending storage read/write requests have - * finished. - - See Also - * CyAsMiscLeaveStandby -*/ -EXTERN cy_as_return_status_t -cy_as_misc_enter_standby_e_x_u( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* If true, use the wakeup pin, otherwise use the register */ - cy_bool pin, - /* Set true to enable specific usages of the - UVALID signal, please refer to AN xx or ERRATA xx */ - cy_bool uvalid_special, - /* Callback to call when the operation is complete. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -/* Summary - This function is provided for backwards compatibility. - - Description - Calling this function is the same as calling CyAsMiscEnterStandbyEx - with True for the lowpower parameter. - - See Also - * CyAsMiscEnterStandbyEx -*/ -EXTERN cy_as_return_status_t -cy_as_misc_enter_standby(cy_as_device_handle handle, - cy_bool pin, - cy_as_function_callback cb, - uint32_t client - ); - -/* Summary - This function brings West Bridge out of sleep mode. - - Description - This function asserts the WAKEUP pin (via the HAL layer). This - brings the West Bridge out of the sleep state and allows the - West Bridge firmware to process the event causing the wakeup. - When all processing associated with the wakeup is complete, a - callback function is called to tell the P port software that - the firmware processing associated with wakeup is complete. - - * Valid In Asynchronous Callback: NO - - Returns: - * CY_AS_ERROR_SUCCESS - the function completed and West Bridge - * is in sleep mode - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_SETTING_WAKEUP_PIN - * CY_AS_ERROR_NOT_IN_STANDBY - the West Bridge device is not in - * the sleep state - * CY_AS_ERROR_TIMEOUT - there was a timeout waiting for a - * response from the West Bridge firmware - * CY_AS_ERROR_NOT_SUPPORTED - the HAL layer does not support - * changing the WAKEUP pin - - See Also - * CyAsMiscEnterStandby -*/ -EXTERN cy_as_return_status_t -cy_as_misc_leave_standby( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* The resource causing the wakeup */ - cy_as_resource_type resource - ); - -/* Summary - This function registers a callback function to be called when an - asynchronous West Bridge MISC event occurs. - - Description - When asynchronous misc events occur, a callback function can be - called to alert the calling program. This functions allows the - calling program to register a callback. - - * Valid In Asynchronous Callback: NO - - Returns: - * CY_AS_ERROR_SUCCESS - * CY_AS_ERROR_INVALID_HANDLE -*/ -EXTERN cy_as_return_status_t -cy_as_misc_register_callback( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The function to call */ - cy_as_misc_event_callback callback - ); - -/* Summary - This function sets the logging level for log messages. - - Description - The API can print messages via the CyAsHalPrintMessage capability. - This function sets the level of detail seen when printing messages - from the API. - - * Valid In Asynchronous Callback:NO -*/ -EXTERN void -cy_as_misc_set_log_level( - /* Level to set, 0 is fewer messages, 255 is all */ - uint8_t level - ); - - -/* Summary - This function tells West Bridge that SD or MMC media has been - inserted or removed. - - Description - In some hardware configurations, SD or MMC media detection is - handled outside of the West Bridge device. This function is called - when a change is detected to inform the West Bridge firmware to check - for storage media changes. - - * Valid In Asynchronous Callback: NO - - Returns: - * CY_AS_ERROR_SUCCESS - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - * CY_AS_ERROR_IN_STANDBY - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - See Also - * CyAsMiscStorageChanged - -*/ -EXTERN cy_as_return_status_t -cy_as_misc_storage_changed( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* Callback to call when the operation is complete. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -/* Summary - This function instructs the West Bridge firmware to start/stop - sending periodic heartbeat messages to the processor. - - Description - The West Bridge firmware can send heartbeat messages through the - mailbox register once every 500 ms. This message can be an overhead - as it causes regular Mailbox interrupts to happen, and is turned - off by default. The message can be used to test and verify that the - West Bridge firmware is alive. This API can be used to enable or - disable the heartbeat message. - - * Valid In Asynchronous Callback: NO - - Returns - * CY_AS_ERROR_SUCCESS - the function completed successfully - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured yet - * CY_AS_ERROR_NO_FIRMWARE - firmware has not been downloaded to - * the West Bridge device - -*/ -EXTERN cy_as_return_status_t -cy_as_misc_heart_beat_control( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* Message enable/disable selection */ - cy_bool enable, - /* Callback to call when the operation is complete. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -/* Summary - This function gets the current state of a GPIO pin on the - West Bridge device. - - Description - The West Bridge device has GPIO pins that can be used for user - defined functions. This function gets the current state of the - specified GPIO pin. Calling this function will configure the - corresponding pin as an input. - - * Valid In Asynchronous Callback: NO - - Notes - Only GPIO[0], GPIO[1] and UVALID pins can be used as GP inputs. - Of these pins, only the UVALID pin is supported by firmware images - that include NAND storage support. - - Returns - * CY_AS_ERROR_SUCCESS - the function completed successfully - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured yet - * CY_AS_ERROR_NO_FIRMWARE - firmware has not been downloaded - * to the West Bridge device - * CY_AS_ERROR_BAD_INDEX - an invalid GPIO was specified - * CY_AS_ERROR_NOT_SUPPORTED - this feature is not supported - * by the firmware - - See Also - * CyAsMiscGpio - * CyAsMiscSetGpioValue - */ -EXTERN cy_as_return_status_t -cy_as_misc_get_gpio_value( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* Id of the GPIO pin to query */ - cy_as_misc_gpio pin, - /* Current value of the GPIO pin */ - uint8_t *value, - /* Callback to call when the operation is complete. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -/* Summary - This function updates the state of a GPIO pin on the West - Bridge device. - - Description - The West Bridge device has GPIO pins that can be used for - user defined functions. This function updates the output - value driven on a specified GPIO pin. Calling this function - will configure the corresponding pin as an output. - - * Valid In Asynchronous Callback: NO - - Notes - All of the pins listed under CyAsMiscGpio can be used as GP - outputs. This feature is note supported by firmware images - that include NAND storage device support. - - Returns - * CY_AS_ERROR_SUCCESS - the function completed successfully - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured yet - * CY_AS_ERROR_NO_FIRMWARE - firmware has not been downloaded - * to the West Bridge device - * CY_AS_ERROR_BAD_INDEX - an invalid GPIO was specified - * CY_AS_ERROR_NOT_SUPPORTED - this feature is not supported - * by firmware. - - See Also - * CyAsMiscGpio - * CyAsMiscGetGpioValue - */ -EXTERN cy_as_return_status_t -cy_as_misc_set_gpio_value( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* Id of the GPIO pin to set */ - cy_as_misc_gpio pin, - /* Value to be set on the GPIO pin */ - uint8_t value, - /* Callback to call when the operation is complete. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -/* Summary - Set the West Bridge device in the low power suspend mode. - - Description - The West Bridge device has a low power suspend mode where the USB - core and the internal microcontroller are powered down. This - function sets the West Bridge device into this low power mode. - This mode can only be entered when there is no active USB - connection; i.e., when USB has not been connected or is suspended; - and there are no pending USB or storage asynchronous calls. The - device will exit the suspend mode and resume handling USB and - processor requests when any activity is detected on the CE#, D+/D- - or GPIO[0] lines. - - * Valid In Asynchronous Callback: NO - - Notes - The GPIO[0] pin needs to be configured as an input for the gpio - wakeup to work. This flag should not be enabled if the pin is - being used as a GP output. - - Returns - * CY_AS_ERROR_SUCCESS - the device was placed in suspend mode. - * CY_AS_ERROR_INVALID_HANDLE - the West Bridge handle passed - * in is invalid. - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * yet been configured. - * CY_AS_ERROR_NO_FIRMWARE - no firmware has been downloaded - * to the device. - * CY_AS_ERROR_IN_STANDBY - the device is already in sleep mode. - * CY_AS_ERROR_USB_CONNECTED - the USB connection is active. - * CY_AS_ERROR_ASYNC_PENDING - asynchronous storage/USB calls - * are pending. - * CY_AS_ERROR_OUT_OF_MEMORY - failed to allocate memory for - * the operation. - * CY_AS_ERROR_INVALID_RESPONSE - command not recognised by - * firmware. - - See Also - * CyAsMiscLeaveSuspend - */ -EXTERN cy_as_return_status_t -cy_as_misc_enter_suspend( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* Control the USB wakeup source */ - cy_bool usb_wakeup_en, - /* Control the GPIO[0] wakeup source */ - cy_bool gpio_wakeup_en, - /* Callback to call when suspend mode entry is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -/* Summary - Wake up the West Bridge device from suspend mode. - - Description - This call wakes up the West Bridge device from suspend mode, - and makes it ready for accepting other commands from the API. - A CyAsEventMiscWakeup event will be delivered to the callback - registered with CyAsMiscRegisterCallback to indicate that the - wake up is complete. - - The CyAsEventMiscWakeup event will also be delivered if the - wakeup happens due to USB or GPIO activity. - - * Valid In Asynchronous Callback: NO - - Returns - * CY_AS_ERROR_SUCCESS - the device was woken up from - * suspend mode. - * CY_AS_ERROR_INVALID_HANDLE - invalid device handle - * passed in. - * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has - * not been configured. - * CY_AS_ERROR_NO_FIRMWARE - firmware has not been - * downloaded to the device. - * CY_AS_ERROR_NOT_IN_SUSPEND - the device is not in - * suspend mode. - * CY_AS_ERROR_OUT_OF_MEMORY - failed to allocate memory - * for the operation. - * CY_AS_ERROR_TIMEOUT - failed to wake up the device. - - See Also - * CyAsMiscEnterSuspend - */ -EXTERN cy_as_return_status_t -cy_as_misc_leave_suspend( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* Callback to call when device has resumed operation. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -/* Summary - Reserve first numzones zones of nand device for storing - processor boot image. LNA firmware works on the first - numzones zones of nand to enable the processor to boot. - - Description - This function reserves first numzones zones of nand device - for storing processor boot image. This fonction MUST be - completed before starting the storage stack for the setting - to be taken into account. - - * Valid In Asynchronous Callback: YES - - Returns - * CY_AS_ERROR_SUCCESS- zones are reserved. - -*/ -EXTERN cy_as_return_status_t -cy_as_misc_reserve_l_n_a_boot_area( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* number of nand zones to reserve */ - uint8_t numzones, - /* Callback to call when device has resumed operation. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -/* Summary - Select the clock frequency to be used when talking to low - speed (non-high speed) SD media. - - Description - West Bridge firmware uses a clock frequency less than the - maximum possible rate for low speed SD media. This function - selects the frequency setting from between the default speed - and the maximum speed. This fonction MUST be completed before - starting the storage stack for the setting to be taken into - account. - - * Valid in Asynchronous Callback: Yes (if cb is non-zero) - * Nestable: Yes - - Returns - * CY_AS_ERROR_SUCCESS - the operation completed successfully. - * CY_AS_ERROR_INVALID_HANDLE - invalid device handle passed in. - * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has not been - * configured. - * CY_AS_ERROR_NO_FIRMWARE - firmware has not been downloaded - * to the device. - * CY_AS_ERROR_OUT_OF_MEMORY - failed to allocate memory for - * the operation. - * CY_AS_ERROR_IN_SUSPEND - West Bridge is in low power suspend - * mode. - * CY_AS_ERROR_INVALID_PARAMETER - invalid frequency setting - * desired. - * CY_AS_ERROR_TIMEOUT - West Bridge device did not respond to - * the operation. - * CY_AS_ERROR_INVALID_RESPONSE - active firmware does not support - * the operation. - - See Also - * CyAsLowSpeedSDFreq - */ -EXTERN cy_as_return_status_t -cy_as_misc_set_low_speed_sd_freq( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* Frequency setting desired for low speed SD cards */ - cy_as_low_speed_sd_freq setting, - /* Callback to call on completion */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -/* Summary - Select the clock frequency to be used when talking to high speed - SD/MMC media. - - Description - West Bridge firmware uses a 48 MHz clock to interface with high - speed SD/MMC media. This clock rate can be restricted to 24 MHz - if desired. This function selects the frequency setting to be - used. This fonction MUST be completed before starting the storage - stack for the setting to be taken into account. - - * Valid in Asynchronous Callback: Yes (if cb is non-zero) - * Nestable: Yes - - Returns - * CY_AS_ERROR_SUCCESS - the operation completed successfully. - * CY_AS_ERROR_INVALID_HANDLE - invalid device handle passed in. - * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has not been - * configured. - * CY_AS_ERROR_NO_FIRMWARE - firmware has not been downloaded to - * the device. - * CY_AS_ERROR_OUT_OF_MEMORY - failed to allocate memory for the - * operation. - * CY_AS_ERROR_IN_SUSPEND - West Bridge is in low power suspend mode. - * CY_AS_ERROR_INVALID_PARAMETER - invalid frequency setting desired. - * CY_AS_ERROR_TIMEOUT - West Bridge device did not respond to the - * operation. - * CY_AS_ERROR_INVALID_RESPONSE - active firmware does not support - * the operation. - - See Also - * CyAsLowSpeedSDFreq - */ -EXTERN cy_as_return_status_t -cy_as_misc_set_high_speed_sd_freq( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* Frequency setting desired for high speed SD cards */ - cy_as_high_speed_sd_freq setting, - /* Callback to call on completion */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); -/* Summary - Select the polarity of the SD_POW output driven by West Bridge. - - Description - The SD_POW signal driven by West Bridge can be used to control - the supply of Vcc to the SD/MMC media connected to the device. - This signal is driven as an active high signal by default. This - function can be used to change the polarity of this signal if - required. This fonction MUST be completed before starting the - storage stack for the setting to be taken into account. - - * Valid in Asynchronous Callback: Yes (if cb is non-zero) - * Nestable: Yes - - Returns - * CY_AS_ERROR_SUCCESS - the operation completed successfully. - * CY_AS_ERROR_INVALID_HANDLE - invalid device handle passed in. - * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has not been - * configured. - * CY_AS_ERROR_NO_FIRMWARE - firmware has not been downloaded - * to the device. - * CY_AS_ERROR_OUT_OF_MEMORY - failed to allocate memory for - * the operation. - * CY_AS_ERROR_IN_SUSPEND - West Bridge is in low power - * suspend mode. - * CY_AS_ERROR_INVALID_PARAMETER - invalid frequency setting - * desired. - * CY_AS_ERROR_TIMEOUT - West Bridge device did not respond to - * the operation. - * CY_AS_ERROR_INVALID_RESPONSE - active firmware does not - * support the operation. - - See Also - * CyAsMiscSignalPolarity - */ -EXTERN cy_as_return_status_t -cy_as_misc_set_sd_power_polarity( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* Desired polarity setting to the SD_POW signal. */ - cy_as_misc_signal_polarity polarity, - /* Callback to call on completion. */ - cy_as_function_callback cb, - /* Client data to be passed to the callback. */ - uint32_t client - ); - -/* For supporting deprecated functions */ -#include "cyasmisc_dep.h" - -#include "cyas_cplus_end.h" - -#endif /* _INCLUDED_CYASMISC_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc_dep.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc_dep.h deleted file mode 100644 index 8b258efc0182..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmisc_dep.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Cypress West Bridge API header file (cyasmisc_dep.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -/* This header will contain Antioch specific declaration - * of the APIs that are deprecated in Astoria SDK. This is - * for maintaining backward compatibility with prior releases - * of the Antioch SDK. - */ -#ifndef __INCLUDED_CYASMISC_DEP_H__ -#define __INCLUDED_CYASMISC_DEP_H__ - -#ifndef __doxygen__ - -EXTERN cy_as_return_status_t -cy_as_misc_acquire_resource_dep(cy_as_device_handle handle, - cy_as_resource_type resource, - cy_bool force); -EXTERN cy_as_return_status_t -cy_as_misc_get_firmware_version_dep(cy_as_device_handle handle, - uint16_t *major, - uint16_t *minor, - uint16_t *build, - uint8_t *media_type, - cy_bool *is_debug_mode); -EXTERN cy_as_return_status_t -cy_as_misc_set_trace_level_dep(cy_as_device_handle handle, - uint8_t level, - cy_as_media_type media, - uint32_t device, - uint32_t unit, - cy_as_function_callback cb, - uint32_t client); -#endif /*__doxygen*/ - -#endif /*__INCLUDED_CYANSTORAGE_DEP_H__*/ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmtp.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmtp.h deleted file mode 100644 index 05d344969776..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasmtp.h +++ /dev/null @@ -1,646 +0,0 @@ -/* Cypress West Bridge API header file (cyasmtp.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASMTP_H_ -#define _INCLUDED_CYASMTP_H_ - -#include "cyasmisc.h" - -#include "cyas_cplus_start.h" - -/*@@Media Transfer Protocol (MTP) Overview - Summary - The MTP API has been designed to allow MTP enabled West Bridge - devices to implement the MTP protocol while maintaining high - performance. West Bridge has the capability to enter into a - Turbo mode during a MTP SendObject or GetObject operation - enabling it to directly stream the data into or out of the - attached SD card with minimal involvement from the Processor. - - Description - The MTP API is designed to act as a pass through implementation - of the MTP protocol for all operations. Each MTP transaction - received from the Host is passed through West Bridge and along - to the Processor. The Processor can then respond to the - transaction and pass data and/or responses back to the Host - through West Bridge. - - The MTP API also allows for a high speed handling of MTP - SendObject and GetObject operations, referred to as Turbo MTP. - During a Turbo MTP operation West Bridge is responsible for - reading or writing the data for the MTP operation directly from - or to the SD card with minimal interaction from the Processor. - The is done by having the Processor transfer a Block Table - to West Bridge which contains the locations on the SD card that - need to be read or written. During the handling of a Turbo - Operation the Processor will then only periodically need to - send a new Block Table to West Bridge when the first is used up. - See the CyAsMTPInitSendObject and CyAsMTPInitGetObject functions - for more details. - - In order to enable the MTP API you must first have a MTP enabled - West Bridge loaded with MTP firmware. You then must start the USB - and Storage APIs before starting the MTP API. See CyAsMTPStart - for more details. -*/ - -/*@@Endpoints - Summary - When using MTP firmware endpoints 2 and 6 are dedicated - to bulk MTP traffic and endpoint 1 is available for MTP - events. - - Description - When using a MTP enabled West Brdige device endpoints 2 and - 6 are made available for use to implement the MTP protocol. - These endpoints have a few special restrictions noted below - but otherwise the existing USB APIs can be used normally with - these endpoints. - - 1. CyAsUsbSetNak, CyAsUsbClearNak, and CyAsUsbGetNak are - disabled for these endpoints - 2. During a turbo operation CyAsUsbSetStall, CyAsUsbClearStall, - and CyAsUsbGetStall are disabled. - -*/ - - -/* Summary - This constants defines the maximum number of - entries in the Block Table used to describe - the locations for Send/GetObject operations. - - See Also - * CyAsMtpSendObject - * CyAsMtpGetObject -*/ -#define CY_AS_MAX_BLOCK_TABLE_ENTRIES 64 - -/* Summary - Endpoint to be used for MTP reads from the USB host. - */ -#define CY_AS_MTP_READ_ENDPOINT (2) - -/* Summary - Endpoint to be used fro MTP writes to the USB host. - */ -#define CY_AS_MTP_WRITE_ENDPOINT (6) - -/****************************************** - * MTP Types - ******************************************/ - -/* Summary - The BlockTable used for turbo operations. - - Description - This struct is used to specify the blocks - to be used for both read/write and send/getObject - operations. - - The start block is a starting Logical Block Address - and num block is the number of blocks in that contiguous - region. - - start_blocks[i]->[-------] <- start_blocks[i] + num_blocks[i] - - If you need fewer than CY_AS_MAX_BLOCK_TABLE_ENTRIES - the remainder should be left empty. Empty is defined - as num_blocks equal to 0. - - See Also - * CyAsMTPInitSendObject - * CyAsMTPInitGetObject - -*/ -typedef struct cy_as_mtp_block_table { - uint32_t start_blocks[CY_AS_MAX_BLOCK_TABLE_ENTRIES]; - uint16_t num_blocks[CY_AS_MAX_BLOCK_TABLE_ENTRIES]; -} cy_as_mtp_block_table; - -/* Summary - This type specifies the type of MTP event that has occurred. - - Description - MTP events are used to communicate that West Bridge has - either finished the handling of the given operation, or - that it requires additional data to complete the operation. - - In no case does West Bridge send any MTP protocol responses, - this always remain the responsibility of the client. - - See Also - * CyAsMTPInitSendObject - * CyAsMTPInitGetObject - * CyAsMTPSendBlockTable - -*/ -typedef enum cy_as_mtp_event { - /* This event is sent when West Bridge - has finished writing the data from a - send_object. west bridge will -not- send - the MTP response. */ - cy_as_mtp_send_object_complete, - - /* This event is sent when West Bridge - has finished sending the data for a - get_object operation. west bridge will - -not- send the MTP response. */ - cy_as_mtp_get_object_complete, - - /* This event is called when West Bridge - needs a new block_table. this is only a - notification, to transfer a block_table - to west bridge the cy_as_mtp_send_block_table - use the function. while west bridge is waiting - for a block_table during a send_object it - may need to NAK the endpoint. it is important - that the cy_as_mtp_send_block_table call is made - in a timely manner as eventually a delay - will result in an USB reset. this event has - no data */ - cy_as_mtp_block_table_needed -} cy_as_mtp_event; - -/* Summary - Data for the CyAsMTPSendObjectComplete event. - - Description - Notification that a SendObject operation has been - completed. The status of the operation is given - (to distinguish between a cancelled and a success - for example) as well as the block count. The blocks - are used in order based on the current block table. - If more than one block table was used for a given - SendObject the count will include the total number - of blocks written. - - This callback will be made only once per SendObject - operation and it will only be called after all of - the data has been committed to the SD card. - - See Also - * CyAsMTPEvent - - */ -typedef struct cy_as_mtp_send_object_complete_data { - cy_as_return_status_t status; - uint32_t byte_count; - uint32_t transaction_id; -} cy_as_mtp_send_object_complete_data; - -/* Summary - Data for the CyAsMTPGetObjectComplete event. - - Description - Notification that a GetObject has finished. This - event allows the P side to know when to send the MTP - response for the GetObject operation. - - See Also - * CyAsMTPEvent - -*/ -typedef struct cy_as_mtp_get_object_complete_data { - cy_as_return_status_t status; - uint32_t byte_count; -} cy_as_mtp_get_object_complete_data; - -/* Summary - MTP Event callback. - - Description - Callback used to communicate that a SendObject - operation has finished. - - See Also - * CyAsMTPEvent -*/ -typedef void (*cy_as_mtp_event_callback)( - cy_as_device_handle handle, - cy_as_mtp_event evtype, - void *evdata - ); - -/* Summary - This is the callback function called after asynchronous API - functions have completed. - - Description - When calling API functions from callback routines (interrupt - handlers usually) the async version of these functions must - be used. This callback is called when an asynchronous API - function has completed. -*/ -typedef void (*cy_as_mtp_function_callback)( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* The error status of the operation */ - cy_as_return_status_t status, - /* A client supplied 32 bit tag */ - uint32_t client -); - -/************************************** - * MTP Functions - **************************************/ - -/* Summary - This function starts the MTP stack. - - Description - Initializes West Bridge for MTP activity and registers the MTP - event callback. - - Before calling CyAsMTPStart, CyAsUsbStart and CyAsStorageStart must be - called (in either order). - - MTPStart must be called before the device is enumerated. Please - see the documentation for CyAsUsbSetEnumConfig and CyAsUsbEnumControl - for details on enumerating a device for MTP. - - Calling MTPStart will not affect any ongoing P<->S traffic. - - This requires a MTP firmware image to be loaded on West Bridge. - - Returns - * CY_AS_ERROR_SUCCESS - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - * CY_AS_ERROR_IN_SUSPEND - * CY_AS_ERROR_INVALID_IN_CALLBACK - * CY_AS_ERROR_STARTSTOP_PENDING - * CY_AS_ERROR_NOT_RUNNING - CyAsUsbStart or CyAsStorageStart - * have not been called - * CY_AS_ERROR_NOT_SUPPORTED - West Bridge is not running - * firmware with MTP support - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - - See Also - * CyAsMTPStop - * CyAsUsbStart - * CyAsStorageStart - * CyAsUsbSetEnumConfig - * CyAsUsbEnumControl -*/ -cy_as_return_status_t -cy_as_mtp_start( - cy_as_device_handle handle, - cy_as_mtp_event_callback event_c_b, - cy_as_function_callback cb, - uint32_t client - ); - - -/* Summary - This function stops the MTP stack. - - Description - Stops all MTP activity. Any ongoing transfers are - canceled. - - This will not cause a UsbDisconnect but all - MTP activity (both pass through and turbo) will - stop. - - Returns - * CY_AS_ERROR_SUCCESS - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - * CY_AS_ERROR_NOT_RUNNING - * CY_AS_ERROR_IN_SUSPEND - * CY_AS_ERROR_INVALID_IN_CALLBACK - * CY_AS_ERROR_STARTSTOP_PENDING - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - - See Also - * CyAsMTPStart -*/ -cy_as_return_status_t -cy_as_mtp_stop( - cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client - ); - -/* Summary - This function sets up a Turbo SendObject operation. - - Description - Calling this function will setup West Bridge to - enable Tubo handling of the next SendObject - operation received. This will pass down the initial - block table to the firmware and setup a direct u->s - write for the SendObject operation. - - If this function is not called before a SendObject - operation is seen the SendObject operation and data - will be passed along to the P port like any other MTP - command. It would then be the responsibility of the - client to perform a normal StorageWrite call to - store the data on the SD card. N.B. This will be - very slow compared with the Turbo handling. - - The completion of this function only signals that - West Bridge has been set up to receive the next SendObject - operation. When the SendObject operation has been fully - handled and the data written to the SD card a separate - event will be triggered. - - Returns - * CY_AS_ERROR_SUCCESS - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - * CY_AS_ERROR_IN_SUSPEND - * CY_AS_ERROR_NOT_RUNNING - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_ASYNC_PENDING - * CY_AS_ERROR_INVALID_RESPONSE - * CY_AS_ERROR_NOT_SUPPORTED - West Bridge is not running - * firmware with MTP support - - See Also - * CyAsMTPCancelSendObject - * CyAsMTPInitGetObject - * CyAsMTPEvent - * CyAsMTPSendBlockTable -*/ -cy_as_return_status_t -cy_as_mtp_init_send_object( - cy_as_device_handle handle, - cy_as_mtp_block_table *blk_table, - uint32_t num_bytes, - cy_as_function_callback cb, - uint32_t client - ); - -/* Summary - This function cancels an ongoing MTP operation. - - Description - Causes West Bridge to cancel an ongoing SendObject - operation. Note this is only a cancel to West Bridge, - the MTP operation still needs to be canceled by - sending a response. - - West Bridge will automatically set a Stall on the endpoint - when the cancel is received. - - This function is only valid after CyAsMTPInitSendObject - has been called, but before the CyAsMTPSendObjectComplete - event has been sent. - - Returns - * CY_AS_ERROR_SUCCESS - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_RUNNING - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - * CY_AS_ERROR_NOT_SUPPORTED - West Bridge is not running - * firmware with MTP support - * CY_AS_ERROR_NO_OPERATION_PENDING - - See Also - * CyAsMTPInitSendObject -*/ -cy_as_return_status_t -cy_as_mtp_cancel_send_object( - cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client - ); - -/* Summary - This function sets up a turbo GetObject operation. - - Description - Called by the P in response to a GetObject - operation. This provides West Bridge with the block - addresses for the Object data that needs to be - transferred. - - It is the responsibility of the Processor to send the MTP - operation before calling CyAsMTPInitGetObject. West Bridge - will then send the data phase of the transaction, - automatically creating the required container for Data. - Once all of the Data has been transferred a callback will - be issued to inform the Processor that the Data phase has - completed allowing it to send the required MTP response. - - If an entire Block Table is used then after the - last block is transferred the CyAsMTPBtCallback - will be called to allow an additional Block Table(s) - to be specified. - - Returns - * CY_AS_ERROR_SUCCESS - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - * CY_AS_ERROR_NOT_RUNNING - * CY_AS_ERROR_IN_SUSPEND - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_ASYNC_PENDING - * CY_AS_ERROR_INVALID_RESPONSE - * CY_AS_ERROR_NOT_SUPPORTED - West Bridge is not running - * firmware with MTP support - - See Also - * CyAsMTPInitSendObject - * CyAsMTPCancelGetObject - * CyAsMTPEvent - * CyAsMTPSendBlockTable -*/ -cy_as_return_status_t -cy_as_mtp_init_get_object( - cy_as_device_handle handle, - cy_as_mtp_block_table *table_p, - uint32_t num_bytes, - uint32_t transaction_id, - cy_as_function_callback cb, - uint32_t client - ); - -/* Summary - This function cancels an ongoing turbo GetObject - operation. - - Description - Causes West Bridge to cancel an ongoing GetObject - operation. Note this is only a cancel to West Bridge, - the MTP operation still needs to be canceled by - sending a response. - - This function is only valid after CyAsMTPGetSendObject - has been called, but before the CyAsMTPGetObjectComplete - event has been sent. - - Returns - * CY_AS_ERROR_SUCCESS - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_RUNNING - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - * CY_AS_ERROR_NOT_SUPPORTED - West Bridge is not running - * firmware with MTP support - * CY_AS_ERROR_NO_OPERATION_PENDING - - See Also - * CyAsMTPInitGetObject -*/ -cy_as_return_status_t -cy_as_mtp_cancel_get_object( - cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client - ); - -/* Summary - This function is used to transfer a BlockTable as part of - an ongoing MTP operation. - - Description - This function is called in response to the - CyAsMTPBlockTableNeeded event. This allows the client to - pass in a BlockTable structure to West Bridge. - - The memory associated with the table will be copied and - can be safely disposed of when the function returns if - called synchronously, or when the callback is made if - called asynchronously. - - This function is used for both SendObject and GetObject - as both can generate the CyAsMTPBlockTableNeeded event. - - Returns - * CY_AS_ERROR_SUCCESS - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_NOT_CONFIGURED - * CY_AS_ERROR_NO_FIRMWARE - * CY_AS_ERROR_NOT_RUNNING - * CY_AS_ERROR_IN_SUSPEND - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_ASYNC_PENDING - * CY_AS_ERROR_INVALID_RESPONSE - * CY_AS_ERROR_NOT_SUPPORTED - West Bridge is not running - * firmware with MTP support - - See Also - * CyAsMTPInitSendObject - * CyAsMTPInitGetObject -*/ -cy_as_return_status_t -cy_as_mtp_send_block_table( - cy_as_device_handle handle, - cy_as_mtp_block_table *table, - cy_as_function_callback cb, - uint32_t client - ); - -/* Summary - This function is used to mark the start of a storage - read/write burst from the P port processor. - - Description - This function is used to mark the start of a storage - read/write burst from the processor. All USB host access - into the mass storage / MTP endpoints will be blocked - while the read/write burst is ongoing, and will be allowed - to resume only after CyAsMTPStorageOnlyStop is called. - The burst mode is used to reduce the firmware overhead - due to configuring the internal data paths repeatedly, - and can help improve performance when a sequence of - read/writes is performed in a burst. - - This function will not generate a special mailbox request, - it will only set a flag on the next Storage Read/Write - operation. Until such a call is made West Bridge will - continue to accept incoming packets from the Host. - - * Valid in Asynchronous Callback: YES - - Returns - * CY_AS_ERROR_INVALID_HANDLE - Invalid West Bridge device - * handle was passed in. - * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has not - * been configured. - * CY_AS_ERROR_NO_FIRMWARE - Firmware is not active on West - * Bridge device. - * CY_AS_ERROR_NOT_RUNNING - Storage stack is not running. - * CY_AS_ERROR_SUCCESS - Burst mode has been started. - - See Also - * CyAsStorageReadWriteBurstStop - */ -cy_as_return_status_t -cy_as_mtp_storage_only_start( - /* Handle to the West Bridge device. */ - cy_as_device_handle handle - ); - -/* Summary - This function is used to mark the end of a storage read/write - burst from the P port processor. - - Description - This function is used to mark the end of a storage read/write - burst from the processor. At this point, USB access to the - mass storage / MTP endpoints on the West Bridge device will be - re-enabled. - - * Valid in Asynchronous Callback: NO - - Returns - * CY_AS_ERROR_INVALID_HANDLE - Invalid West Bridge device handle - * was passed in. - * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has not been - * configured. - * CY_AS_ERROR_NO_FIRMWARE - Firmware is not active on West Bridge - * device. - * CY_AS_ERROR_NOT_RUNNING - Storage stack is not running. - * CY_AS_ERROR_INVALID_IN_CALLBACK - This API cannot be called - * from a callback. - * CY_AS_ERROR_OUT_OF_MEMORY - Failed to allocate memory to - * process the request. - * CY_AS_ERROR_TIMEOUT - Failed to send request to firmware. - * CY_AS_ERROR_SUCCESS - Burst mode has been stopped. - - See Also - * CyAsStorageReadWriteBurstStart - */ -cy_as_return_status_t -cy_as_mtp_storage_only_stop( - /* Handle to the West Bridge device. */ - cy_as_device_handle handle, - cy_as_function_callback cb, - uint32_t client - ); - -#include "cyas_cplus_end.h" - -#endif diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasprotocol.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasprotocol.h deleted file mode 100644 index 773b645ea7eb..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasprotocol.h +++ /dev/null @@ -1,3838 +0,0 @@ -/* Cypress West Bridge API header file (cyasprotocol.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASPROTOCOL_H_ -#define _INCLUDED_CYASPROTOCOL_H_ - -/* - * Constants defining the per context buffer sizes - */ -#ifndef __doxygen__ -#define CY_CTX_GEN_MAX_DATA_SIZE (8) -#define CY_CTX_RES_MAX_DATA_SIZE (8) -#define CY_CTX_STR_MAX_DATA_SIZE (64) -#define CY_CTX_USB_MAX_DATA_SIZE (130 + 23) -#define CY_CTX_TUR_MAX_DATA_SIZE (12) -#endif - -/* Summary - This response indicates a command has been processed - and returned a status. - - Direction - West Bridge -> P Port Processor - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = all - * Response Code = 0 - - D0 - * 0 = success (CY_AS_ERROR_SUCCESS) - * non-zero = error code - - Description - This response indicates that a request was processed - and no data was generated as a result of the request - beyond a single 16 bit status value. This response - contains the 16 bit data value. - */ -#define CY_RESP_SUCCESS_FAILURE (0) - -/* Summary - This response indicates an invalid request was sent - - Direction - West Bridge -> P Port Processor - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = all - * Response Code = 1 - - D0 - * Mailbox contents for invalid request - - Description - This response is returned when a request is sent - that contains an invalid - context or request code. -*/ -#define CY_RESP_INVALID_REQUEST (1) - -/* Summary - This response indicates a request of invalid length was sent - - Direction - West Bridge -> P Port Processor - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = all - * Response Code = 2 - - D0 - * Mailbox contenxt for invalid request - * Length for invalid request - - Description - The software API and firmware sends requests across the - P Port to West Bridge interface on different contexts. - Each contexts has a maximum size of the request packet - that can be received. The size of a request can be - determined during the first cycle of a request transfer. - If the request is larger than can be handled by the - receiving context this response is returned. Note that - the complete request is received before this response is - sent, but that the request is dropped after this response - is sent. -*/ -#define CY_RESP_INVALID_LENGTH (2) - - -/* Summary - This response indicates a request was made to an - invalid storage address. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = all - * Response Code = 0 - - D0 - Bits 15 - 12 : Media Type - * 0 = NAND - * 1 = SD Flash - * 2 = MMC Flash - * 3 = CE-ATA - - Bits 11 - 8 : Zero based device index - - Bits 7 - 0 : Zero based unit index - - D1 - Upper 16 bits of block address - - D2 - Lower 16 bits of block address - - D3 - Portion of address that is invalid - * 0 = Media Type - * 1 = Device Index - * 2 = Unit Index - * 3 = Block Address - - Description - This response indicates a request to an invalid storage media - address - */ -#define CY_RESP_NO_SUCH_ADDRESS (3) - - -/******************************************************/ - -/*@@General requests - Summary - The general requests include: - * CY_RQT_GET_FIRMWARE_VERSION - * CY_RQT_SET_TRACE_LEVEL - * CY_RQT_INITIALIZATION_COMPLETE - * CY_RQT_READ_MCU_REGISTER - * CY_RQT_WRITE_MCU_REGISTER - * CY_RQT_STORAGE_MEDIA_CHANGED - * CY_RQT_CONTROL_ANTIOCH_HEARTBEAT - * CY_RQT_PREPARE_FOR_STANDBY - * CY_RQT_ENTER_SUSPEND_MODE - * CY_RQT_OUT_OF_SUSPEND - * CY_RQT_GET_GPIO_STATE - * CY_RQT_SET_GPIO_STATE - * CY_RQT_SET_SD_CLOCK_FREQ - * CY_RQT_WB_DEVICE_MISMATCH - * CY_RQT_BOOTLOAD_NO_FIRMWARE - * CY_RQT_RESERVE_LNA_BOOT_AREA - * CY_RQT_ABORT_P2S_XFER - */ - -#ifndef __doxygen__ -#define CY_RQT_GENERAL_RQT_CONTEXT (0) -#endif - -/* Summary - This command returns the firmware version number, - media types supported and debug/release mode information. - - Direction - P Port Processor-> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 0 - * Request Code = 0 - - Description - The response contains the 16-bit major version, the - 16-bit minor version, the 16 bit build number, media - types supported and release/debug mode information. - - Responses - * CY_RESP_FIRMWARE_VERSION - */ -#define CY_RQT_GET_FIRMWARE_VERSION (0) - - -/* Summary - This command changes the trace level and trace information - destination within the West Bridge firmware. - - Direction - P Port Processor-> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 0 - * Request Code = 1 - - D0 - Trace Level - * 0 = no trace information - * 1 = state information - * 2 = function call - * 3 = function call with args/return value - - D1 - Bits 12 - 15 : MediaType - * 0 = NAND - * 1 = SDIO Flash - * 2 = MMC Flash - * 3 = CE-ATA - - Bits 8 - 11 : Zero based device index - - Bits 0 - 7 : Zero based unit index - - Description - The West Bridge firmware contains debugging facilities that can - be used to trace the execution of the firmware. This request - sets the level of tracing information that is stored and the - location where it is stored. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_NO_SUCH_ADDRESS - */ -#define CY_RQT_SET_TRACE_LEVEL (1) - -/* Summary - This command indicates that the firmware is up and ready - for communications with the P port processor. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 2 - - Mailbox0 - * Context = 0 - * Request Code = 3 - - D0 - Major Version - - D1 - Minor Version - - D2 - Build Number - - D3 - Bits 15-8: Media types supported on Bus 1. - Bits 7-0: Media types supported on Bus 0. - Bits 8, 0: NAND support. - * 0: NAND is not supported. - * 1: NAND is supported. - Bits 9, 1: SD memory card support. - * 0: SD memory card is not supported. - * 1: SD memory card is supported. - Bits 10, 2: MMC card support. - * 0: MMC card is not supported. - * 1: MMC card is supported. - Bits 11, 3: CEATA drive support - * 0: CEATA drive is not supported. - * 1: CEATA drive is supported. - Bits 12, 4: SD IO card support. - * 0: SD IO card is not supported. - * 1: SD IO card is supported. - - D4 - Bits 15 - 8 : MTP information - * 0 : MTP not supported in firmware - * 1 : MTP supported in firmware - Bits 7 - 0 : Debug/Release mode information. - * 0 : Release mode - * 1 : Debug mode - - Description - When the West Bridge firmware is loaded it being by performing - initialization. Initialization must be complete before West - Bridge is ready to accept requests from the P port processor. - This request is sent from West Bridge to the P port processor - to indicate that initialization is complete. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_INITIALIZATION_COMPLETE (3) - -/* Summary - This command requests the firmware to read and return the contents - of a MCU accessible - register. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 0 - * Request code = 4 - - D0 - Address of register to read - - Description - This debug command allows the processor to read the contents of - a MCU accessible register. - - Responses - * CY_RESP_MCU_REGISTER_DATA - */ -#define CY_RQT_READ_MCU_REGISTER (4) - -/* Summary - This command requests the firmware to write to an MCU - accessible register. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 0 - * Request code = 5 - - D0 - Address of register to be written - - D1 - Bits 15 - 8 : Mask to be applied to existing data. - Bits 7 - 0 : Data to be ORed with masked data. - - Description - This debug command allows the processor to write to an MCU - accessible register. - Note: This has to be used with caution, and is supported by - the firmware only in special debug builds. - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_WRITE_MCU_REGISTER (5) - -/* Summary - This command tells the West Bridge firmware that a change in - storage media has been detected. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 0 - * Request code = 6 - - Description - If the insertion or removal of SD or MMC cards is detected by - hardware external to West Bridge, this command is used to tell - the West Bridge firmware to re-initialize the storage controlled - by the device. - - Responses - * CY_RESP_SUCCESS_FAILURE -*/ -#define CY_RQT_STORAGE_MEDIA_CHANGED (6) - -/* Summary - This command enables/disables the periodic heartbeat message - from the West Bridge firmware to the processor. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 0 - * Request code = 7 - - Description - This command enables/disables the periodic heartbeat message - from the West Bridge firmware to the processor. The heartbeat - message is left enabled by default, and can lead to a loss - in performance on the P port interface. - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_CONTROL_ANTIOCH_HEARTBEAT (7) - -/* Summary - This command requests the West Bridge firmware to prepare for - the device going into standby - mode. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 0 - * Request code = 8 - - Description - This command is sent by the processor to the West Bridge as - preparation for going into standby mode. The request allows the - firmware to complete any pending/cached storage operations before - going into the low power state. - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_PREPARE_FOR_STANDBY (8) - -/* Summary - Requests the firmware to go into suspend mode. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 0 - * Request code = 9 - - D0 - Bits 7-0: Wakeup control information. - - Description - This command is sent by the processor to the West Bridge to - request the device to be placed in suspend mode. The firmware - will complete any pending/cached storage operations before - going into the low power state. - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_ENTER_SUSPEND_MODE (9) - -/* Summary - Indicates that the device has left suspend mode. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 0 - * Request code = 10 - - Description - This message is sent by the West Bridge to the Processor - to indicate that the device has woken up from suspend mode, - and is ready to accept new requests. - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_OUT_OF_SUSPEND (10) - -/* Summary - Request to get the current state of an West Bridge GPIO pin. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 0 - * Request code = 11 - - D0 - Bits 15 - 8 : GPIO pin identifier - - Responses - * CY_RESP_GPIO_STATE - - Description - Request from the processor to get the current state of - an West Bridge GPIO pin. - */ -#define CY_RQT_GET_GPIO_STATE (11) - -/* Summary - Request to update the output value on an West Bridge - GPIO pin. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 0 - * Request code = 12 - - D0 - Bits 15 - 8 : GPIO pin identifier - Bit 0 : Desired output state - - Responses - * CY_RESP_SUCCESS_FAILURE - - Description - Request from the processor to update the output value on - an West Bridge GPIO pin. - */ -#define CY_RQT_SET_GPIO_STATE (12) - -/* Summary - Set the clock frequency on the SD interface of the West - Bridge device. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 0 - * Request code = 13 - - D0 - Bit 8: Type of SD/MMC media - 0 = low speed media - 1 = high speed media - Bit 0: Clock frequency selection - 0 = Default frequency - 1 = Alternate frequency (24 MHz in both cases) - - Description - This request is sent by the processor to set the operating clock - frequency used on the SD interface of the device. - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_SET_SD_CLOCK_FREQ (13) - -/* Summary - Indicates the firmware downloaded to West Bridge cannot - run on the active device. - - Direction - West Bridge -> P Port processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 0 - * Request code = 14 - - Description - Some versions of West Bridge firmware can only run on specific - types/versions of the West Bridge device. This error is - returned when a firmware image is downloaded onto a device that - does not support it. - - Responses - * None - */ -#define CY_RQT_WB_DEVICE_MISMATCH (14) - -/* Summary - This command is indicates that no firmware was found in the - storage media. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 0 - * Request code = 15 - - Description - The command is received only in case of silicon with bootloader - ROM. The device sends the request if there is no firmware image - found in the storage media or the image is corrupted. The - device is waiting for P port to download a valid firmware image. - - Responses - * None - */ -#define CY_RQT_BOOTLOAD_NO_FIRMWARE (15) - -/* Summary - This command reserves first numzones zones of nand device for - storing processor boot image. - - Direction - P Port Processor-> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 0 - * Request Code = 16 - - D0 - Bits 7-0: numzones - - Description - The first numzones zones in nand device will be used for storing - proc boot image. LNA firmware in Astoria will work on this nand - area and boots the processor which will then use the remaining - nand for usual purposes. - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_RESERVE_LNA_BOOT_AREA (16) - -/* Summary - This command cancels the processing of a P2S operation in - firmware. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 0 - * Request Code = 17 - - Responses - * CY_RESP_SUCCESS_FAILURE -*/ -#define CY_RQT_ABORT_P2S_XFER (17) - -/* - * Used for debugging, ignore for normal operations - */ -#ifndef __doxygen__ -#define CY_RQT_DEBUG_MESSAGE (127) -#endif - -/******************************************************/ - -/*@@General responses - Summary - The general responses include: - * CY_RESP_FIRMWARE_VERSION - * CY_RESP_MCU_REGISTER_DATA - * CY_RESP_GPIO_STATE - */ - - -/* Summary - This response indicates success and contains the firmware - version number, media types supported by the firmware and - release/debug mode information. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 2 - - MailBox0 - * Context = 0 - * Response Code = 16 - - D0 - Major Version - - D1 - Minor Version - - D2 - Build Number - - D3 - Bits 15-8: Media types supported on Bus 1. - Bits 7-0: Media types supported on Bus 0. - Bits 8, 0: NAND support. - * 0: NAND is not supported. - * 1: NAND is supported. - Bits 9, 1: SD memory card support. - * 0: SD memory card is not supported. - * 1: SD memory card is supported. - Bits 10, 2: MMC card support. - * 0: MMC card is not supported. - * 1: MMC card is supported. - Bits 11, 3: CEATA drive support - * 0: CEATA drive is not supported. - * 1: CEATA drive is supported. - Bits 12, 4: SD IO card support. - * 0: SD IO card is not supported. - * 1: SD IO card is supported. - - D4 - Bits 15 - 8 : MTP information - * 0 : MTP not supported in firmware - * 1 : MTP supported in firmware - Bits 7 - 0 : Debug/Release mode information. - * 0 : Release mode - * 1 : Debug mode - - Description - This response is sent to return the firmware version - number to the requestor. - */ -#define CY_RESP_FIRMWARE_VERSION (16) - -/* Summary - This response returns the contents of a MCU accessible - register to the processor. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - MailBox0 - * Context = 0 - * Response code = 17 - - D0 - Bits 7 - 0 : MCU register contents - - Description - This response is sent by the firmware in response to the - CY_RQT_READ_MCU_REGISTER - command. - */ -#define CY_RESP_MCU_REGISTER_DATA (17) - -/* Summary - Reports the current state of an West Bridge GPIO pin. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - MailBox0 - * Context = 0 - * Request code = 18 - - D0 - Bit 0: Current state of the GP input pin - - Description - This response is sent by the West Bridge to report the - current state observed on a general purpose input pin. - */ -#define CY_RESP_GPIO_STATE (18) - - -/* Summary - This command notifies West Bridge the polarity of the - SD power pin - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 0 - * Request Code = 19 - D0: CyAnMiscActivehigh / CyAnMiscActivelow - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - - */ - -#define CY_RQT_SDPOLARITY (19) - -/******************************/ - -/*@@Resource requests - Summary - - The resource requests include: - * CY_RQT_ACQUIRE_RESOURCE - * CY_RQT_RELEASE_RESOURCE - */ - - - - - -#ifndef __doxygen__ -#define CY_RQT_RESOURCE_RQT_CONTEXT (1) -#endif - - -/* Summary - This command is a request from the P port processor - for ownership of a resource. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 1 - * Request Code = 0 - - D0 - Resource - * 0 = USB - * 1 = SDIO/MMC - * 2 = NAND - - D1 - Force Flag - * 0 = Normal - * 1 = Force - - Description - The resource may be the USB pins, the SDIO/MMC bus, - or the NAND bus. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_ERR_NOT_RELEASED - * CY_RESP_SUCCESS_FAILURE:CY_ERR_BAD_RESOURCE - */ -#define CY_RQT_ACQUIRE_RESOURCE (0) - - -/* Summary - This command is a request from the P port processor - to release ownership of a resource. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 1 - * Request Code = 1 - - D0 - Resource - * 0 = USB - * 1 = SDIO/MMC - * 2 = NAND - - Description - The resource may be the USB pins, the SDIO/MMC bus, or - the NAND bus. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_ERR_NOT_OWNER - */ -#define CY_RQT_RELEASE_RESOURCE (1) - - -/****************************/ - -/*@@Storage requests - Summary - The storage commands include: - * CY_RQT_START_STORAGE - * CY_RQT_STOP_STORAGE - * CY_RQT_CLAIM_STORAGE - * CY_RQT_RELEASE_STORAGE - * CY_RQT_QUERY_MEDIA - * CY_RQT_QUERY_DEVICE - * CY_RQT_QUERY_UNIT - * CY_RQT_READ_BLOCK - * CY_RQT_WRITE_BLOCK - * CY_RQT_MEDIA_CHANGED - * CY_RQT_ANTIOCH_CLAIM - * CY_RQT_ANTIOCH_RELEASE - * CY_RQT_SD_INTERFACE_CONTROL - * CY_RQT_SD_REGISTER_READ - * CY_RQT_CHECK_CARD_LOCK - * CY_RQT_QUERY_BUS - * CY_RQT_PARTITION_STORAGE - * CY_RQT_PARTITION_ERASE - * CY_RQT_GET_TRANSFER_AMOUNT - * CY_RQT_ERASE - * CY_RQT_SDIO_READ_DIRECT - * CY_RQT_SDIO_WRITE_DIRECT - * CY_RQT_SDIO_READ_EXTENDED - * CY_RQT_SDIO_WRITE_EXTENDED - * CY_RQT_SDIO_INIT_FUNCTION - * CY_RQT_SDIO_QUERY_CARD - * CY_RQT_SDIO_GET_TUPLE - * CY_RQT_SDIO_ABORT_IO - * CY_RQT_SDIO_INTR - * CY_RQT_SDIO_SUSPEND - * CY_RQT_SDIO_RESUME - * CY_RQT_SDIO_RESET_DEV - * CY_RQT_P2S_DMA_START - */ -#ifndef __doxygen__ -#define CY_RQT_STORAGE_RQT_CONTEXT (2) -#endif - -/* Summary - This command requests initialization of the storage stack. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 0 - - Description - This command is required before any other storage related command - can be send to the West Bridge firmware. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_ERR_ALREADY_RUNNING - */ -#define CY_RQT_START_STORAGE (0) - - -/* Summary - This command requests shutdown of the storage stack. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 1 - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_ERR_NOT_RUNNING - */ -#define CY_RQT_STOP_STORAGE (1) - - -/* Summary - This command requests ownership of the given media - type by the P port processor. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 2 - - D0 - Bits 12 - 15 : Bus Index - Bits 8 - 11 : Zero based device index - - Responses - * CY_RESP_MEDIA_CLAIMED_RELEASED - * CY_RESP_NO_SUCH_ADDRESS - */ -#define CY_RQT_CLAIM_STORAGE (2) - - -/* Summary - This command releases ownership of a given media type - by the P port processor. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 3 - - D0 - Bits 12 - 15 : Bus Index - Bits 8 - 11 : Zero based device index - - Responses - * CY_RESP_MEDIA_CLAIMED_RELEASED - * CY_RESP_NO_SUCH_ADDRESS - */ -#define CY_RQT_RELEASE_STORAGE (3) - - -/* Summary - This command returns the total number of logical devices - of the given type of media. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 4 - - D0 - Bits 12 - 15 : MediaType - * 0 = NAND - * 1 = SDIO Flash - * 2 = MMC Flash - * 3 = CE-ATA - - Bits 8 - 11 : Not Used - - Bits 0 - 7 : Not Used - - Responses - * CY_RESP_MEDIA_DESCRIPTOR - * CY_RESP_NO_SUCH_ADDRESS - */ -#define CY_RQT_QUERY_MEDIA (4) - - -/* Summary - This command queries a given device to determine - information about the number of logical units on - the given device. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 5 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Not Used - - Responses - * CY_RESP_DEVICE_DESCRIPTOR - * CY_RESP_SUCCESS_FAILURE:CY_ERR_INVALID_PARTITION_TABLE - * CY_RESP_NO_SUCH_ADDRESS - */ -#define CY_RQT_QUERY_DEVICE (5) - - -/* Summary - This command queries a given device to determine - information about the size and location of a logical unit - located on a physical device. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 6 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based unit index - - Responses - * CY_RESP_UNIT_DESCRIPTOR - * CY_RESP_SUCCESS_FAILURE:CY_ERR_INVALID_PARTITION_TABLE - * CY_RESP_NO_SUCH_ADDRESS - */ -#define CY_RQT_QUERY_UNIT (6) - - -/* Summary - This command initiates the read of a specific block - from the given media, - device and unit. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 2 - - MailBox0 - * Context = 2 - * Request Code = 7 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based unit index - - D1 - Upper 16 bits of block address - - D2 - Lower 16 bits of block address - - D3 - BIT 8 - 15 : Upper 8 bits of Number of blocks - - BIT 0 - 7 : Reserved - - * D4 * - BITS 8 - 15 : Lower 8 bits of Number of blocks - BITS 1 - 7 : Not Used - BIT 0 : Indicates whether this command is a - part of a P2S only burst. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_ANTIOCH_DEFERRED_ERROR - */ -#define CY_RQT_READ_BLOCK (7) - - -/* Summary - This command initiates the write of a specific block - from the given media, device and unit. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 2 - - MailBox0 - * Context = 2 - * Request Code = 8 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based unit index - - D1 - Upper 16 bits of block address - - D2 - Lower 16 bits of block address - - D3 - BIT 8 - 15 : Upper 8 bits of Number of blocks - - BIT 0 - 7 : Reserved - - * D4 * - BITS 8 - 15 : Lower 8 bits of Number of blocks - BITS 1 - 7 : Not Used - BIT 0 : Indicates whether this command is a - part of a P2S only burst. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_ANTIOCH_DEFERRED_ERROR - */ -#define CY_RQT_WRITE_BLOCK (8) - -/* Summary - This request is sent when the West Bridge device detects - a change in the status of the media. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 2 - * Request Code = 9 - - D0 - Bits 12 - 15 : Bus index - Bits 0 - 7 : Media type - - D1 - Bit 0 : Action - * 0 = Inserted - * 1 = Removed - - Description - When the media manager detects the insertion or removal - of a media from the West Bridge port, this request is sent - from the West Bridge device to the P Port processor to - inform the processor of the change in status of the media. - This request is sent for both an insert operation and a - removal operation. - - Responses - * CY_RESPO_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_MEDIA_CHANGED (9) - -/* Summary - This request is sent when the USB module wishes to claim - storage media. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 2 - * Request Code = 10 - - D0 - Bit 0: - * 0 = do not release NAND - * 1 = release NAND - - Bit 1: - * 0 = do not release SD Flash - * 1 = release SD Flash - - Bit 2: - * 0 = do not release MMC flash - * 1 = release MMC flash - - Bit 3: - * 0 = do not release CE-ATA storage - * 1 = release CE-ATA storage - - Bit 8: - * 0 = do not release storage on bus 0 - * 1 = release storage on bus 0 - - Bit 9: - * 0 = do not release storage on bus 1 - * 1 = release storage on bus 1 - - Description - When the USB cable is attached to the West Bridge device, - West Bridge will enumerate the storage devices per the USB - initialization of West Bridge. In order for West Bridge to - respond to requests received via USB for the mass storage - devices, the USB module must claim the storeage. This - request is a request to the P port processor to release the - storage medium. The medium will not be visible on the USB - host, until it has been released by the processor. -*/ -#define CY_RQT_ANTIOCH_CLAIM (10) - -/* Summary - This request is sent when the P port has asked West Bridge to - release storage media, and the West Bridge device has - completed this. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 2 - * Request Code = 11 - - D0 - Bit 0: - * 0 = No change in ownership of NAND storage - * 1 = NAND ownership has been given to processor - - Bit 1: - * 0 = No change in ownership of SD storage - * 1 = SD ownership has been given to processor - - Bit 2: - * 0 = No change in ownership of MMC storage - * 1 = MMC ownership has been given to processor - - Bit 3: - * 0 = No change in ownership of CE-ATA storage - * 1 = CE-ATA ownership has been given to processor - - Bit 4: - * 0 = No change in ownership of SD IO device - * 1 = SD IO device ownership has been given to processor - - Bit 8: - * 0 = No change in ownership of storage on bus 0 - * 1 = Bus 0 ownership has been given to processor - - Bit 9: - * 0 = No change in ownership of storage on bus 1 - * 1 = Bus 1 ownership has been given to processor - - Description - When the P port asks for control of a particular media, West - Bridge may be able to release the media immediately. West - Bridge may also need to complete the flush of buffers before - releasing the media. In the later case, West Bridge will - indicated a release is not possible immediately and West Bridge - will send this request to the P port when the release has been - completed. -*/ -#define CY_RQT_ANTIOCH_RELEASE (11) - -/* Summary - This request is sent by the Processor to enable/disable the - handling of SD card detection and SD card write protection - by the firmware. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 2 - * Request code = 12 - - D0 - Bit 8: Enable/disable handling of card detection. - Bit 1: SDAT_3 = 0, GIPO_0 = 1 - Bit 0: Enable/disable handling of write protection. - - Description - This request is sent by the Processor to enable/disable - the handling of SD card detection and SD card write - protection by the firmware. - */ -#define CY_RQT_SD_INTERFACE_CONTROL (12) - -/* Summary - Request from the processor to read a register on the SD - card, and return the contents. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 2 - * Request code = 13 - - D0 - Bits 12 - 15 : MediaType - * 0 = Reserved - * 1 = SDIO Flash - * 2 = MMC Flash - * 3 = Reserved - - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Type of register to read - - Description - This request is sent by the processor to instruct the - West Bridge to read a register on the SD/MMC card, and - send the contents back through the CY_RESP_SD_REGISTER_DATA - response. - */ -#define CY_RQT_SD_REGISTER_READ (13) - -/* Summary - Check if the SD/MMC card connected to West Bridge is - password locked. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 2 - * Request code = 14 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - - Description - This request is sent by the processor to check if the - SD/MMC connected to the West Bridge is locked with a - password. - */ -#define CY_RQT_CHECK_CARD_LOCK (14) - -/* Summary - This command returns the total number of logical devices on the - given bus - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 15 - - D0 - Bits 12 - 15 : Bus Number - - Bits 0 - 11: Not Used - - Responses - * CY_RESP_BUS_DESCRIPTOR - * CY_RESP_NO_SUCH_BUS - */ -#define CY_RQT_QUERY_BUS (15) - -/* Summary - Divide a storage device into two partitions. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request code = 16 - - D0 - Bits 12 - 15 : Bus number - Bits 8 - 11 : Device number - Bits 0 - 7 : Not used - - D1 - Size of partition 0 (MS word) - - D2 - Size of partition 0 (LS word) - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_PARTITION_STORAGE (16) - -/* Summary - Remove the partition table and unify all partitions on - a storage device. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request code = 17 - - D0 - Bits 12 - 15 : Bus number - Bits 8 - 11 : Device number - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_PARTITION_ERASE (17) - -/* Summary - Requests the current transfer amount. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request code = 18 - - D0 - Bits 12 - 15 : Bus number - Bits 8 - 11 : Device number - - Responses - * CY_RESP_TRANSFER_COUNT - */ -#define CY_RQT_GET_TRANSFER_AMOUNT (18) - -/* Summary - Erases. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 2 - - MailBox0 - * Context = 2 - * Request code = 19 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based unit index - - D1 - Upper 16 bits of erase unit - - D2 - Lower 16 bits of erase unit - - D3 - BIT 8 - 15 : Upper 8 bits of Number of erase units - BIT 0 - 7 : Reserved - - * D4 * - BIT 8 - 15 : Lower 8 bits of Number of erase units - BIT 0 - 7 : Not Used - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - */ -#define CY_RQT_ERASE (19) - -/* Summary - This command reads 1 byte from an SDIO card. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 23 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based function number - - D1 - Bits 8 - 15 : 0 - Bit 7 : 0 to indicate a read - Bits 4 - 6 : Function number - Bit 3 : 0 - Bit 2 : 1 if SDIO interrupt needs to be re-enabled. - Bits 0 - 1 : Two Most significant bits of Read address - - D2 - Bits 1 - 15 : 15 Least significant bits of Read address - Bit 0 : 0 - - - Responses - * CY_RESP_SUCCESS_FAILURE - * CY_RESP_SDIO_DIRECT -*/ -#define CY_RQT_SDIO_READ_DIRECT (23) - -/* Summary - This command writes 1 byte to an SDIO card. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 24 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based function number - - D1 - Bits 8 - 15 : Data to write - Bit 7 : 1 to indicate a write - Bits 4 - 6 : Function number - Bit 3 : 1 if Read after write is enabled - Bit 2 : 1 if SDIO interrupt needs to be re-enabled. - Bits 0 - 1 : Two Most significant bits of write address - - D2 - Bits 1 - 15 : 15 Least significant bits of write address - Bit 0 : 0 - - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SDIO_DIRECT -*/ -#define CY_RQT_SDIO_WRITE_DIRECT (24) - -/* Summary - This command reads performs a multi block/byte read from - an SDIO card. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 25 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based function number - - D1 - Bit 15 : 0 to indicate a read - Bit 12 - 14 : Function Number - Bit 11 : Block Mode - Bit 10 : OpCode - Bits 0 - 9 : 10 Most significant bits of Read address - - D2 - Bits 9 - 15 : 7 Least significant bits of address - Bits 0 - 8 : Block/Byte Count - - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SDIO_EXT -*/ -#define CY_RQT_SDIO_READ_EXTENDED (25) - -/* Summary - This command reads performs a multi block/byte write - to an SDIO card. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 26 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based function number - - D1 - Bit 15 : 1 to indicate a write - Bit 12 - 14 : Function Number - Bit 11 : Block Mode - Bit 10 : OpCode - Bits 0 - 9 : 10 Most significant bits of Read address - - D2 - Bits 9 - 15 : 7 Least significant bits of address - Bits 0 - 8 : Block/Byte Count - - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SDIO_EXT -*/ -#define CY_RQT_SDIO_WRITE_EXTENDED (26) - -/* Summary - This command initialises an IO function on the SDIO card. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 27 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based function number - - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_SDIO_INIT_FUNCTION (27) - -/* Summary - This command gets properties of the SDIO card. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 28 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_QUERY_CARD -*/ -#define CY_RQT_SDIO_QUERY_CARD (28) - -/* Summary - This command reads a tuple from the CIS of an SDIO card. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 29 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based function number - - D1 - Bits 8 - 15 : Tuple ID to read - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SDIO_GET_TUPLE -*/ -#define CY_RQT_SDIO_GET_TUPLE (29) - -/* Summary - This command Aborts an IO operation. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 30 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based function number - - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_SDIO_ABORT_IO (30) - -/* Summary - SDIO Interrupt request sent to the processor from the West Bridge device. - - Direction - West Bridge ->P Port Processor - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 31 - - D0 - Bits 0 - 7 : Bus Index - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_SDIO_INTR (31) - -/* Summary - This command Suspends an IO operation. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 32 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based function number - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_SDIO_SUSPEND (32) - -/* Summary - This command resumes a suspended operation. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 33 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based function number - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SDIO_RESUME -*/ -#define CY_RQT_SDIO_RESUME (33) - -/* Summary - This command resets an SDIO device. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request Code = 34 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : 0 - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_SDIO_RESET_DEV (34) - -/* Summary - This command asks the API to start the DMA transfer - for a P2S operation. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Request code = 35 - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_P2S_DMA_START (35) - -/******************************************************/ - -/*@@Storage responses - Summary - The storage responses include: - * CY_RESP_MEDIA_CLAIMED_RELEASED - * CY_RESP_MEDIA_DESCRIPTOR - * CY_RESP_DEVICE_DESCRIPTOR - * CY_RESP_UNIT_DESCRIPTOR - * CY_RESP_ANTIOCH_DEFERRED_ERROR - * CY_RESP_SD_REGISTER_DATA - * CY_RESP_SD_LOCK_STATUS - * CY_RESP_BUS_DESCRIPTOR - * CY_RESP_TRANSFER_COUNT - * CY_RESP_SDIO_EXT - * CY_RESP_SDIO_INIT_FUNCTION - * CY_RESP_SDIO_QUERY_CARD - * CY_RESP_SDIO_GET_TUPLE - * CY_RESP_SDIO_DIRECT - * CY_RESP_SDIO_INVALID_FUNCTION - * CY_RESP_SDIO_RESUME - */ - -/* Summary - Based on the request sent, the state of a given media was - changed as indicated by this response. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Response Code = 16 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - - D1 - State of Media - * 0 = released - * 1 = claimed - */ -#define CY_RESP_MEDIA_CLAIMED_RELEASED (16) - - -/* Summary - This response gives the number of physical devices - associated with a given media type. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Response Code = 17 - - D0 - Media Type - Bits 12 - 15 - * 0 = NAND - * 1 = SDIO Flash - * 2 = MMC Flash - * 3 = CE-ATA - - D1 - Number of devices - */ -#define CY_RESP_MEDIA_DESCRIPTOR (17) - - -/* Summary - This response gives description of a physical device. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 2 - - MailBox0 - * Context = 2 - * Response Code = 18 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Type of media present on bus - - D1 - Block Size in bytes - - D2 - Bit 15 : Is device removable - Bit 9 : Is device password locked - Bit 8 : Is device writeable - Bits 0 - 7 : Number Of Units - - D3 - ERASE_UNIT_SIZE high 16 bits - - D4 - ERASE_UNIT_SIZE low 16 bits - - */ -#define CY_RESP_DEVICE_DESCRIPTOR (18) - - -/* Summary - This response gives description of a unit on a - physical device. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 6 - - MailBox0 - * Context = 2 - * Response Code = 19 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based unit index - - D1 - Bits 0 - 7 : Media type - * 1 = NAND - * 2 = SD FLASH - * 4 = MMC FLASH - * 8 = CEATA - * 16 = SD IO - - D2 - Block Size in bytes - - D3 - Start Block Low 16 bits - - D4 - Start Block High 16 bits - - D5 - Unit Size Low 16 bits - - D6 - Unit Size High 16 bits - */ -#define CY_RESP_UNIT_DESCRIPTOR (19) - - -/* Summary - This response is sent as error status for P2S - Storage operation. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 2 - - Mailbox0 - * Context = 2 - * Request Code = 20 - - D0 - Bit 8 : Type of operation (Read / Write) - Bits 7 - 0 : Error code - - D1 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Zero based unit index - - *D2 - D3* - Address where the error occurred. - - D4 - Length of the operation in blocks. - - Description - This error is returned by the West Bridge to the - processor if a storage operation fails due to a - medium error. -*/ -#define CY_RESP_ANTIOCH_DEFERRED_ERROR (20) - -/* Summary - Contents of a register on the SD/MMC card connected to - West Bridge. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - Variable - - Mailbox0 - * Context = 2 - * Request code = 21 - - D0 - Length of data in bytes - - D1 - Dn - The register contents - - Description - This is the response to a CY_RQT_SD_REGISTER_READ - request. -*/ -#define CY_RESP_SD_REGISTER_DATA (21) - -/* Summary - Status of whether the SD card is password locked. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 2 - * Request code = 22 - - D0 - Bit 0 : The card's lock status - - Description - Status of whether the SD card is password locked. -*/ -#define CY_RESP_SD_LOCK_STATUS (22) - - -/* Summary - This response gives the types of physical devices - attached to a given bus. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - MailBox0 - * Context = 2 - * Response Code = 23 - - D0 - Bus Number - Bits 12 - 15 - - D1 - Media present on addressed bus - */ -#define CY_RESP_BUS_DESCRIPTOR (23) - -/* Summary - Amount of data read/written through the USB mass - storage/MTP device. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 2 - - MailBox0 - * Context = 2 - * Request code = 24 - - D0 - MS 16 bits of number of sectors written - - D1 - LS 16 bits of number of sectors written - - D2 - MS 16 bits of number of sectors read - - D3 - LS 16 bits of number of sectors read - - Description - This is the response to the CY_RQT_GET_TRANSFER_AMOUNT - request, and represents the number of sectors of data - that has been written to or read from the storage device - through the USB Mass storage or MTP interface. - */ -#define CY_RESP_TRANSFER_COUNT (24) - -/* Summary - Status of SDIO Extended read/write operation. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 2 - * Request code = 34 - - D0 - Bit 8 : 1 if Read response, 0 if write response - Bits 0-7: Error Status - - Description - Status of SDIO Extended read write operation. -*/ - -#define CY_RESP_SDIO_EXT (34) - -/* Summary - Status of SDIO operation to Initialize a function - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 2 - - Mailbox0 - * Context = 2 - * Request code = 35 - - - D0 - Bits 8-15 : Function Interface Code - Bits 0-7: Extended Function Interface Code - - D1 - Bits 0-15 : Function Block Size - - D2 - Bits 0-15 : Most significant Word of Function PSN - - D3 - Bits 0-15 : Least significant Word of Function PSN - - D4 - Bit 15 : CSA Enabled Status - Bit 14 : CSA Support Status - Bit 9 : CSA No Format Status - Bit 8 : CSA Write Protect Status - Bit 0 : Function Wake Up Support status - - Description - Status of SDIO Function Initialization operation. -*/ -#define CY_RESP_SDIO_INIT_FUNCTION (35) - -/* Summary - Status of SDIO operation to query the Card - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 2 - - Mailbox0 - * Context = 2 - * Request code = 36 - - - D0 - Bits 8-15 : Number of IO functions present - Bit 0: 1 if memory is present - - D1 - Bits 0-15 : Card Manufacturer ID - - D2 - Bits 0-15 : Card Manufacturer Additional Information - - D3 - Bits 0-15 : Function 0 Block Size - - D4 - Bits 8-15 :SDIO Card Capability register - Bits 0-7: SDIO Version - - - Description - Status of SDIO Card Query operation. - */ -#define CY_RESP_SDIO_QUERY_CARD (36) -/* Summary - Status of SDIO CIS read operation - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 2 - * Request code = 37 - - D0 - Bit 8 : 1 - Bits 0-7: Error Status - - D1 - Bits 0 - 7 : Size of data read. - - Description - Status of SDIO Get Tuple Read operation. - */ -#define CY_RESP_SDIO_GET_TUPLE (37) - -/* Summary - Status of SDIO Direct read/write operation. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 2 - * Request code = 38 - - D0 - Bit 8 : Error Status - Bits 0-7: Data Read(If any) - - Description - Status of SDIO Direct read write operation. - -*/ -#define CY_RESP_SDIO_DIRECT (38) - -/* Summary - Indicates an un-initialized function has been used for IO - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 2 - * Request code = 39 - - Description - Indicates an IO request on an uninitialized function. -*/ -#define CY_RESP_SDIO_INVALID_FUNCTION (39) - -/* Summary - Response to a Resume request - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 2 - * Request code = 40 - - D0 - Bits 8-15 : Error Status - Bit 0: 1 if data is available. 0 otherwise. - - Description - Response to a Resume request. Indicates if data is - available after resum or not. -*/ -#define CY_RESP_SDIO_RESUME (40) - -/******************************************************/ - -/*@@USB requests - Summary - The USB requests include: - * CY_RQT_START_USB - * CY_RQT_STOP_USB - * CY_RQT_SET_CONNECT_STATE - * CY_RQT_GET_CONNECT_STATE - * CY_RQT_SET_USB_CONFIG - * CY_RQT_GET_USB_CONFIG - * CY_RQT_STALL_ENDPOINT - * CY_RQT_GET_STALL - * CY_RQT_SET_DESCRIPTOR - * CY_RQT_GET_DESCRIPTOR - * CY_RQT_SET_USB_CONFIG_REGISTERS - * CY_RQT_USB_EVENT - * CY_RQT_USB_EP_DATA - * CY_RQT_ENDPOINT_SET_NAK - * CY_RQT_GET_ENDPOINT_NAK - * CY_RQT_ACK_SETUP_PACKET - * CY_RQT_SCSI_INQUIRY_COMMAND - * CY_RQT_SCSI_START_STOP_COMMAND - * CY_RQT_SCSI_UNKNOWN_COMMAND - * CY_RQT_USB_REMOTE_WAKEUP - * CY_RQT_CLEAR_DESCRIPTORS - * CY_RQT_USB_STORAGE_MONITOR - * CY_RQT_USB_ACTIVITY_UPDATE - * CY_RQT_MS_PARTITION_SELECT - */ -#ifndef __doxygen__ -#define CY_RQT_USB_RQT_CONTEXT (3) -#endif - -/* Summary - This command requests initialization of the USB stack. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Request Code = 0 - - Description - This command is required before any other USB related command can be - sent to the West Bridge firmware. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_ALREADY_RUNNING - */ -#define CY_RQT_START_USB (0) - - -/* Summary - This command requests shutdown of the USB stack. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Request Code = 1 - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING - */ -#define CY_RQT_STOP_USB (1) - - -/* Summary - This command requests that the USB pins be connected - or disconnected to/from the West Bridge device. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Request Code = 2 - - D0 - Desired Connect State - * 0 = DISCONNECTED - * 1 = CONNECTED - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING - */ -#define CY_RQT_SET_CONNECT_STATE (2) - - -/* Summary - This command requests the connection state of the - West Bridge USB pins. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Request Code = 3 - - Responses - * CY_RESP_CONNECT_STATE - * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING - */ -#define CY_RQT_GET_CONNECT_STATE (3) - - -/* Summary - This request configures the USB subsystem. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 2 - - MailBox0 - * Context = 3 - * Request Code = 4 - - D0 - Bits 8 - 15: Media to enumerate (bit mask) - Bits 0 - 7: Enumerate Mass Storage (bit mask) - * 1 = Enumerate device on bus 0 - * 2 = Enumerate device on bus 1 - - D1 - Enumeration Methodology - * 1 = West Bridge enumeration - * 0 = P Port enumeration - - D2 - Mass storage interface number - Interface number to - be used for the mass storage interface - - D3 - Mass storage callbacks - * 1 = relay to P port - * 0 = completely handle in firmware - - Description - This indicates how enumeration should be handled. - Enumeration can be handled by the West Bridge device - or by the P port processor. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_ERR_INVALID_MASK - * CY_RESP_SUCCESS_FAILURE:CY_ERR_INVALID_STORAGE_MEDIA - */ -#define CY_RQT_SET_USB_CONFIG (4) - - -/* Summary - This request retrieves the current USB configuration from - the West Bridge device. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Request Code = 5 - - Responses - * CY_RESP_USB_CONFIG - */ -#define CY_RQT_GET_USB_CONFIG (5) - - -/* Summary - This request stalls the given endpoint. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Request Code = 6 - - D0 - Endpoint Number - - D1 - * 1 = Stall Endpoint - * 0 = Clear Stall - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_INVALID_ENDPOINT - */ -#define CY_RQT_STALL_ENDPOINT (6) - - -/* Summary - This request retrieves the stall status of the - requested endpoint. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Request Code = 7 - - D0 - Endpoint number - - Responses - * CY_RESP_ENDPOINT_STALL - * CY_RESP_SUCCESS_FAILURE:CY_RESP_INVALID_ENDPOINT - */ -#define CY_RQT_GET_STALL (7) - - -/* Summary - This command sets the contents of a descriptor. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Request Code = 8 - - D0 - Bit 15 - Bit 8 - Descriptor Index - - Bit 7 - Bit 0 - Descriptor Type - * Device = 1 - * Device Qualifier = 2 - * Full Speed Configuration = 3 - * High Speed Configuration = 4 - - * D1 - DN * - Actual data for the descriptor - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_ERR_BAD_TYPE - * CY_RESP_SUCCESS_FAILURE:CY_ERR_BAD_INDEX - * CY_RESP_SUCCESS_FAILURE:CY_ERR_BAD_LENGTH - */ -#define CY_RQT_SET_DESCRIPTOR (8) - -/* Summary - This command gets the contents of a descriptor. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Request Code = 9 - - D0 - Bit 15 - Bit 8 - Descriptor Index - - Bit 7 - Bit 0 - Descriptor Type - * Device = 1 - * Device Qualifier = 2 - * Full Speed Configuration = 3 - * High Speed Configuration = 4 - - Responses - * CY_RESP_USB_DESCRIPTOR - * CY_RESP_SUCCESS_FAILURE:CY_ERR_BAD_TYPE - * CY_RESP_SUCCESS_FAILURE:CY_ERR_BAD_INDEX - */ -#define CY_RQT_GET_DESCRIPTOR (9) - -/* Summary - This request is sent from the P port processor to the - West Bridge device to physically configure the endpoints - in the device. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 3 - - MailBox0 - * Context = 3 - * Request Code = 10 - - D0 - Bit 15 - Bit 8 - EP1OUTCFG register value - Bit 7 - Bit 0 - EP1INCFG register value - - * D1 - D2 * - PEPxCFS register values where x = 3, 5, 7, 9 - - * D3 - D7 * - LEPxCFG register values where x = 3, 5, 7, 9, 10, - 11, 12, 13, 14, 15 - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_SET_USB_CONFIG_REGISTERS (10) - -/* Summary - This request is sent to the P port processor when a - USB event occurs and needs to be relayed to the - P port. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 3 - * Request Code = 11 - - D0 - Event Type - * 0 = Reserved - * 1 = Reserved - * 2 = USB Suspend - * 3 = USB Resume - * 4 = USB Reset - * 5 = USB Set Configuration - * 6 = USB Speed change - - D1 - If EventTYpe is USB Speed change - * 0 = Full Speed - * 1 = High Speed - - If EventType is USB Set Configuration - * The number of the configuration to use - * (may be zero to unconfigure) - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_USB_EVENT (11) - -/* Summary - This request is sent in both directions to transfer - endpoint data for endpoints 0 and 1. - - Direction - West Bridge -> P Port Processor - P Port Processor -> West Bridge - - Length (in transfers) - Variable - - Mailbox0 - * Context = 3 - * Request Code = 12 - - D0 - Bit 15 - 14 Data Type - * 0 = Setup (payload should be the 8 byte setup packet) - * 1 = Data - * 2 = Status (payload should be empty) - - Bit 13 Endpoint Number (only 0 and 1 supported) - Bit 12 First Packet (only supported for Host -> - West Bridge traffic) - Bit 11 Last Packet (only supported for Host -> - West Bridge traffic) - - Bit 9 - 0 Data Length (real max data length is 64 bytes - for EP0 and EP1) - - *D1-Dn* - Endpoint data -*/ -#define CY_RQT_USB_EP_DATA (12) - - -/* Summary - This request sets the NAK bit on an endpoint. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Request Code = 13 - - D0 - Endpoint Number - - D1 - * 1 = NAK Endpoint - * 0 = Clear NAK - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_INVALID_ENDPOINT - */ -#define CY_RQT_ENDPOINT_SET_NAK (13) - - -/* Summary - This request retrieves the NAK config status of the - requested endpoint. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Request Code = 14 - - D0 - Endpoint number - - Responses - * CY_RESP_ENDPOINT_NAK - * CY_RESP_SUCCESS_FAILURE:CY_RESP_INVALID_ENDPOINT - */ -#define CY_RQT_GET_ENDPOINT_NAK (14) - -/* Summary - This request acknowledges a setup packet that does not - require any data transfer. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox - * Context = 3 - * Request Code = 15 - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_ACK_SETUP_PACKET (15) - -/* Summary - This request is sent when the USB storage driver within - West Bridge receives an Inquiry request. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - x - variable - - Mailbox0 - * Context = 3 - * Request Code = 16 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Media type being addressed - - D1 - Bits 8 : EVPD bit from request - Bits 0 - 7 : Codepage from the inquiry request - - D2 - Length of the inquiry response in bytes - - * D3 - Dn * - The inquiry response - - Description - When the West Bridge firmware receives an SCSI Inquiry - request from the USB host, the response to this mass - storage command is created by West Bridge and forwarded to - the P port processor. The P port processor may change - this response before it is returned to the USB host. This - request is the method by which this may happen. -*/ -#define CY_RQT_SCSI_INQUIRY_COMMAND (16) - -/* Summary - This request is sent when the USB storage driver within - West Bridge receives a Start/Stop request. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 3 - * Request Code = 17 - - D0 - Bits 12 - 15 : Bus index - Bits 8 - 11 : Zero based device index - Bits 0 - 7 : Media type being addressed - - D1 - Bit 1 - * LoEj Bit (See SCSI-3 specification) - - Bit 0 - * Start Bit (See SCSI-3 specification) - - Description - When the West Bridge firmware received a SCSI Start/Stop - request from the USB host, this request is relayed to the - P port processor. This request is used to relay the command. - The USB firmware will not response to the USB command until - the response to this request is recevied by the firmware. -*/ -#define CY_RQT_SCSI_START_STOP_COMMAND (17) - -/* Summary - This request is sent when the USB storage driver - receives an unknown CBW on mass storage. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 4 - - Mailbox0 - * Context = 3 - * Request Code = 18 - - D0 - Bits 12 - 15 : MediaType - * 0 = NAND - * 1 = SDIO Flash - * 2 = MMC Flash - * 3 = CE-ATA - - D1 - The length of the request in bytes - - D2 - Dn - CBW command block from the SCSI host controller. - - Description - When the firmware recevies a SCSI request that is not - understood, this request is relayed to the - P port processor. -*/ -#define CY_RQT_SCSI_UNKNOWN_COMMAND (18) - -/* Summary - Request the West Bridge to signal remote wakeup - to the USB host. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 3 - * Request code = 19 - - Description - Request from the processor to West Bridge, to signal - remote wakeup to the USB host. - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_USB_REMOTE_WAKEUP (19) - -/* Summary - Request the West Bridge to clear all descriptors tha - were set previously - using the Set Descriptor calls. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 3 - * Request code = 20 - - Description - Request from the processor to West Bridge, to clear - all descriptor information that was previously stored - on the West Bridge using CyAnUsbSetDescriptor calls. - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_CLEAR_DESCRIPTORS (20) - -/* Summary - Request the West Bridge to monitor USB to storage activity - and send periodic updates. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 2 - - Mailbox0 - * Context = 3 - * Request code = 21 - - D0 - Upper 16 bits of write threshold - - D1 - Lower 16 bits of write threshold - - D2 - Upper 16 bits of read threshold - - D3 - Lower 16 bits of read threshold - - Description - Request from the processor to West Bridge, to start - monitoring the level of read/write activity on the - USB mass storage drive and to set the threshold - level at which progress reports are sent. - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_USB_STORAGE_MONITOR (21) - -/* Summary - Event from the West Bridge showing that U2S activity - since the last event has crossed the threshold. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 2 - - Mailbox0 - * Context = 3 - * Request code = 22 - - D0 - Upper 16 bits of sectors written since last event. - - D1 - Lower 16 bits of sectors written since last event. - - D2 - Upper 16 bits of sectors read since last event. - - D3 - Lower 16 bits of sectors read since last event. - - Description - Event notification from the West Bridge indicating - that the number of read/writes on the USB mass - storage device have crossed a pre-defined threshold - level. - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_USB_ACTIVITY_UPDATE (22) - -/* Summary - Request to select the partitions to be enumerated on a - storage device with partitions. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 3 - * Request code = 23 - - D0 - Bits 8-15 : Bus index - Bits 0- 7 : Device index - - D1 - Bits 8-15 : Control whether to enumerate partition 1. - Bits 0- 7 : Control whether to enumerate partition 0. - - Responses - * CY_RESP_SUCCESS_FAILURE - */ -#define CY_RQT_MS_PARTITION_SELECT (23) - -/************/ - -/*@@USB responses - Summary - The USB responses include: - * CY_RESP_USB_CONFIG - * CY_RESP_ENDPOINT_CONFIG - * CY_RESP_ENDPOINT_STALL - * CY_RESP_CONNECT_STATE - * CY_RESP_USB_DESCRIPTOR - * CY_RESP_USB_INVALID_EVENT - * CY_RESP_ENDPOINT_NAK - * CY_RESP_INQUIRY_DATA - * CY_RESP_UNKNOWN_SCSI_COMMAND - */ - -/* Summary - This response contains the enumeration configuration - information for the USB module. - - Direction - 8051->P - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Response Code = 32 - - D0 - Bits 8 - 15: Media to enumerate (bit mask) - Bits 0 - 7: Buses to enumerate (bit mask) - * 1 = Bus 0 - * 2 = Bus 1 - - D1 - Enumeration Methodology - * 0 = West Bridge enumeration - * 1 = P Port enumeration - - D2 - Bits 7 - 0 : Interface Count - the number of interfaces - Bits 15 - 8 : Mass storage callbacks - - */ -#define CY_RESP_USB_CONFIG (32) - - -/* Summary - This response contains the configuration information - for the specified endpoint. - - Direction - 8051->P - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Response Code = 33 - - D0 - Bits 15 - 12 : Endpoint Number (0 - 15) - - Bits 11 - 10 : Endpoint Type - * 0 = Control - * 1 = Bulk - * 2 = Interrupt - * 3 = Isochronous - - Bits 9 : Endpoint Size - * 0 = 512 - * 1 = 1024 - - Bits 8 - 7 : Buffering - * 0 = Double - * 1 = Triple - * 2 = Quad - - Bits 6 : Bit Direction - * 0 = Input - * 1 = Output - */ -#define CY_RESP_ENDPOINT_CONFIG (33) - - -/* Summary - This response contains the stall status for - the specified endpoint. - - Direction - 8051->P - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Response Code = 34 - - D0 - Stall status - * 0 = Active - * 1 = Stalled - */ -#define CY_RESP_ENDPOINT_STALL (34) - - -/* Summary - This response contains the connected/disconnected - state of the West Bridge USB pins. - - Direction - 8051->P - - Length (in transfers) - 1 - - MailBox0 - * Context = 3 - * Response Code = 35 - - D0 - Connect state - * 0 = Disconnected - * 1 = Connected - */ -#define CY_RESP_CONNECT_STATE (35) - -/* Summary - This response contains the information - about the USB configuration - - Direction - West Bridge -> P Port Processor - - Length - x bytes - - Mailbox0 - * Context = 3 - * Response Code = 36 - - D0 - Length in bytes of the descriptor - - * D1 - DN * - Descriptor contents -*/ -#define CY_RESP_USB_DESCRIPTOR (36) - -/* Summary - This response is sent in response to a bad USB event code - - Direction - P Port Processor -> West Bridge - - Length - 1 word (2 bytes) - - Mailbox0 - * Context = 3 - * Response Code = 37 - - D0 - The invalid event code in the request -*/ -#define CY_RESP_USB_INVALID_EVENT (37) - -/* Summary - This response contains the current NAK status of - a USB endpoint. - - Direction - West Bridge -> P port processor - - Length - 1 transfer - - Mailbox0 - * Context = 3 - * Response Code = 38 - - D0 - The NAK status of the endpoint - 1 : NAK bit set - 0 : NAK bit clear -*/ -#define CY_RESP_ENDPOINT_NAK (38) - -/* Summary - This response gives the contents of the inquiry - data back to West Bridge to returns to the USB host. - - Direction - West Bridge -> P Port Processor - - Length - Variable - - MailBox0 - * Context = 3 - * Response Code = 39 - - D0 - Length of the inquiry response - - *D1 - Dn* - Inquiry data -*/ -#define CY_RESP_INQUIRY_DATA (39) - -/* Summary - This response gives the status of an unknown SCSI command. - This also gives three bytes of sense information. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 3 - * Response Code = 40 - - D0 - The length of the reply in bytes - - D1 - * Status of the command - * Sense Key - - D2 - * Additional Sense Code (ASC) - * Additional Sense Code Qualifier (ASCQ) -*/ -#define CY_RESP_UNKNOWN_SCSI_COMMAND (40) -/*******************************************************/ - -/*@@Turbo requests - Summary - The Turbo requests include: - * CY_RQT_START_MTP - * CY_RQT_STOP_MTP - * CY_RQT_INIT_SEND_OBJECT - * CY_RQT_CANCEL_SEND_OBJECT - * CY_RQT_INIT_GET_OBJECT - * CY_RQT_CANCEL_GET_OBJECT - * CY_RQT_SEND_BLOCK_TABLE - * CY_RQT_MTP_EVENT - * CY_RQT_TURBO_CMD_FROM_HOST - * CY_RQT_TURBO_SEND_RESP_DATA_TO_HOST - * CY_RQT_TURBO_SWITCH_ENDPOINT - * CY_RQT_TURBO_START_WRITE_DMA - * CY_RQT_ENABLE_USB_PATH - * CY_RQT_CANCEL_ASYNC_TRANSFER - */ -#ifndef __doxygen__ -#define CY_RQT_TUR_RQT_CONTEXT (4) -#endif - -/* Summary - This command requests initialization of the MTP stack. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 4 - * Request Code = 0 - - Description - This command is required before any other MTP related - command can be sent to the West Bridge firmware. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_ALREADY_RUNNING - */ -#define CY_RQT_START_MTP (0) - -/* Summary - This command requests shutdown of the MTP stack. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 4 - * Request Code = 1 - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING - */ -#define CY_RQT_STOP_MTP (1) - -/* Summary - This command sets up an MTP SendObject operation. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 4 - * Request Code = 2 - - D0 - Total bytes for send object Low 16 bits - - D1 - Total bytes for send object High 16 bits - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING - */ -#define CY_RQT_INIT_SEND_OBJECT (2) - -/* Summary - This command cancels West Bridges handling of - an ongoing MTP SendObject operation. This - does NOT send an MTP response. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 4 - * Request Code = 3 - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_NO_OPERATION_PENDING - */ -#define CY_RQT_CANCEL_SEND_OBJECT (3) - -/* Summary - This command sets up an MTP GetObject operation. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 2 - - MailBox0 - * Context = 4 - * Request Code = 4 - - D0 - Total bytes for get object Low 16 bits - - D1 - Total bytes for get object High 16 bits - - D2 - Transaction Id for get object Low 16 bits - - D3 - Transaction Id for get object High 16 bits - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING - */ -#define CY_RQT_INIT_GET_OBJECT (4) - -/* Summary - This command notifies West Bridge of a new - BlockTable transfer. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 4 - * Request Code = 5 - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING - */ -#define CY_RQT_SEND_BLOCK_TABLE (5) - -/* Summary - This request is sent to the P port processor when a MTP event occurs - and needs to be relayed to the P port. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 2 - - Mailbox0 - * Context = 4 - * Request Code = 6 - - D0 - Bits 15 - 8 : Return Status for GetObject/SendObject - Bits 7 - 0 : Event Type - * 0 = MTP SendObject Complete - * 1 = MTP GetObject Complete - * 2 = BlockTable Needed - - D1 - Lower 16 bits of the length of the data that got transferred - in the Turbo Endpoint.(Applicable to "MTP SendObject Complete" - and "MTP GetObject Complete" events) - - D2 - Upper 16 bits of the length of the data that got transferred - in the Turbo Endpoint. (Applicable to "MTP SendObject Complete" - and "MTP GetObject Complete" events) - - D3 - Lower 16 bits of the Transaction Id of the MTP_SEND_OBJECT - command. (Applicable to "MTP SendObject Complete" event) - - D4 - Upper 16 bits of the Transaction Id of the MTP_SEND_OBJECT - command. (Applicable to "MTP SendObject Complete" event) - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_MTP_EVENT (6) - -/* Summary - This request is sent to the P port processor when a command - is received from Host in a Turbo Endpoint. Upon receiving - this event, P port should read the data from the endpoint as - soon as possible. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - Mailbox0 - * Context = 4 - * Request Code = 7 - - D0 - This contains the EP number. (This will be always two now). - - D1 - Length of the data available in the Turbo Endpoint. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_TURBO_CMD_FROM_HOST (7) - -/* Summary - This request is sent to the West Bridge when the P port - needs to send data to the Host in a Turbo Endpoint. - Upon receiving this event, Firmware will make the end point - available for the P port. If the length is zero, then - firmware will send a zero length packet. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 2 - - Mailbox0 - * Context = 4 - * Request Code = 8 - - D0 - This contains the EP number. (This will be always six now). - - D1 - Lower 16 bits of the length of the data that needs to be - sent in the Turbo Endpoint. - - D2 - Upper 16 bits of the length of the data that needs to be - sent in the Turbo Endpoint. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS -*/ -#define CY_RQT_TURBO_SEND_RESP_DATA_TO_HOST (8) - -/* Summary - This command cancels West Bridges handling of - an ongoing MTP GetObject operation. This - does NOT send an MTP response. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 4 - * Request Code = 9 - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_NO_OPERATION_PENDING - */ -#define CY_RQT_CANCEL_GET_OBJECT (9) - -/* Summary - This command switches a Turbo endpoint - from the U port to the P port. If no data - is in the endpoint the endpoint is - primed to switch as soon as data is placed - in the endpoint. The endpoint will continue - to switch until all data has been transferd. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 2 - - MailBox0 - * Context = 4 - * Request Code = 10 - - D0 - Whether the read is a packet read. - - D1 - Lower 16 bits of the length of the data to switch - the Turbo Endpoint for. - - D2 - Upper 16 bits of the length of the data to switch - the Turbo Endpoint for. - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - * CY_RESP_SUCCESS_FAILURE:CY_RESP_NOT_RUNNING - */ -#define CY_RQT_TURBO_SWITCH_ENDPOINT (10) - -/* Summary - This command requests the API to start the DMA - transfer of a packet of MTP data to the Antioch. - - Direction - West Bridge -> P Port Processor - - Length (in transfers) - 1 - - MailBox0 - * Context = 4 - * Request Code = 11 - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - */ -#define CY_RQT_TURBO_START_WRITE_DMA (11) - -/* Summary - This command requests the firmware to switch the - internal data paths to enable USB access to the - Mass storage / MTP endpoints. - - Direction - P Port Processor -> West Bridge - - Length (in transfers) - 1 - - MailBox0 - * Context = 4 - * Request code = 12 - - Responses - * CY_RESP_SUCCESS_FAILURE:CY_AS_ERROR_SUCCESS - */ -#define CY_RQT_ENABLE_USB_PATH (12) - -/* Summary - Request to cancel an asynchronous MTP write from - the processor side. - - Direction - P Port processor -> West Bridge - - Length (in transfers) - 1 - - Mailbox0 - * Context = 4 - * Request code = 13 - - D0 - * EP number - - Description - This is a request to the firmware to update internal - state so that a pending write on the MTP endpoint - can be cancelled. - */ -#define CY_RQT_CANCEL_ASYNC_TRANSFER (13) - -/******************************************************/ - -/*@@Turbo responses - Summary - The Turbo responses include: - * CY_RESP_MTP_INVALID_EVENT - */ - -/* Summary - This response is sent in response to a bad MTP event code - - Direction - P Port Processor -> West Bridge - - Length - 1 word (2 bytes) - - Mailbox0 - * Context = 4 - * Response Code = 16 - - D0 - The invalid event code in the request -*/ -#define CY_RESP_MTP_INVALID_EVENT (16) - -#ifndef __doxygen__ -#define CY_RQT_CONTEXT_COUNT (5) -#endif - -#endif /* _INCLUDED_CYASPROTOCOL_H_ */ - diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasregs.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasregs.h deleted file mode 100644 index f049d7e32a4b..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasregs.h +++ /dev/null @@ -1,201 +0,0 @@ -/* Cypress West Bridge API header file (cyasregs.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASREG_H_ -#define _INCLUDED_CYASREG_H_ - -#if !defined(__doxygen__) - -#define CY_AS_MEM_CM_WB_CFG_ID (0x80) -#define CY_AS_MEM_CM_WB_CFG_ID_VER_MASK (0x000F) -#define CY_AS_MEM_CM_WB_CFG_ID_HDID_MASK (0xFFF0) -#define CY_AS_MEM_CM_WB_CFG_ID_HDID_ANTIOCH_VALUE (0xA100) -#define CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_FPGA_VALUE (0x6800) -#define CY_AS_MEM_CM_WB_CFG_ID_HDID_ASTORIA_VALUE (0xA200) - - -#define CY_AS_MEM_RST_CTRL_REG (0x81) -#define CY_AS_MEM_RST_CTRL_REG_HARD (0x0003) -#define CY_AS_MEM_RST_CTRL_REG_SOFT (0x0001) -#define CY_AS_MEM_RST_RSTCMPT (0x0004) - -#define CY_AS_MEM_P0_ENDIAN (0x82) -#define CY_AS_LITTLE_ENDIAN (0x0000) -#define CY_AS_BIG_ENDIAN (0x0101) - -#define CY_AS_MEM_P0_VM_SET (0x83) -#define CY_AS_MEM_P0_VM_SET_VMTYPE_MASK (0x0007) -#define CY_AS_MEM_P0_VM_SET_VMTYPE_RAM (0x0005) -#define CY_AS_MEM_P0_VM_SET_VMTYPE_SRAM (0x0007) -#define CY_AS_MEM_P0_VM_SET_VMTYPE_VMWIDTH (0x0008) -#define CY_AS_MEM_P0_VM_SET_VMTYPE_FLOWCTRL (0x0010) -#define CY_AS_MEM_P0_VM_SET_IFMODE (0x0020) -#define CY_AS_MEM_P0_VM_SET_CFGMODE (0x0040) -#define CY_AS_MEM_P0_VM_SET_DACKEOB (0x0080) -#define CY_AS_MEM_P0_VM_SET_OVERRIDE (0x0100) -#define CY_AS_MEM_P0_VM_SET_INTOVERD (0x0200) -#define CY_AS_MEM_P0_VM_SET_DRQOVERD (0x0400) -#define CY_AS_MEM_P0_VM_SET_DRQPOL (0x0800) -#define CY_AS_MEM_P0_VM_SET_DACKPOL (0x1000) - - -#define CY_AS_MEM_P0_NV_SET (0x84) -#define CY_AS_MEM_P0_NV_SET_WPSWEN (0x0001) -#define CY_AS_MEM_P0_NV_SET_WPPOLAR (0x0002) - -#define CY_AS_MEM_PMU_UPDATE (0x85) -#define CY_AS_MEM_PMU_UPDATE_UVALID (0x0001) -#define CY_AS_MEM_PMU_UPDATE_USBUPDATE (0x0002) -#define CY_AS_MEM_PMU_UPDATE_SDIOUPDATE (0x0004) - -#define CY_AS_MEM_P0_INTR_REG (0x90) -#define CY_AS_MEM_P0_INTR_REG_MCUINT (0x0020) -#define CY_AS_MEM_P0_INTR_REG_DRQINT (0x0800) -#define CY_AS_MEM_P0_INTR_REG_MBINT (0x1000) -#define CY_AS_MEM_P0_INTR_REG_PMINT (0x2000) -#define CY_AS_MEM_P0_INTR_REG_PLLLOCKINT (0x4000) - -#define CY_AS_MEM_P0_INT_MASK_REG (0x91) -#define CY_AS_MEM_P0_INT_MASK_REG_MMCUINT (0x0020) -#define CY_AS_MEM_P0_INT_MASK_REG_MDRQINT (0x0800) -#define CY_AS_MEM_P0_INT_MASK_REG_MMBINT (0x1000) -#define CY_AS_MEM_P0_INT_MASK_REG_MPMINT (0x2000) -#define CY_AS_MEM_P0_INT_MASK_REG_MPLLLOCKINT (0x4000) - -#define CY_AS_MEM_MCU_MB_STAT (0x92) -#define CY_AS_MEM_P0_MCU_MBNOTRD (0x0001) - -#define CY_AS_MEM_P0_MCU_STAT (0x94) -#define CY_AS_MEM_P0_MCU_STAT_CARDINS (0x0001) -#define CY_AS_MEM_P0_MCU_STAT_CARDREM (0x0002) - -#define CY_AS_MEM_PWR_MAGT_STAT (0x95) -#define CY_AS_MEM_PWR_MAGT_STAT_WAKEUP (0x0001) - -#define CY_AS_MEM_P0_RSE_ALLOCATE (0x98) -#define CY_AS_MEM_P0_RSE_ALLOCATE_SDIOAVI (0x0001) -#define CY_AS_MEM_P0_RSE_ALLOCATE_SDIOALLO (0x0002) -#define CY_AS_MEM_P0_RSE_ALLOCATE_NANDAVI (0x0004) -#define CY_AS_MEM_P0_RSE_ALLOCATE_NANDALLO (0x0008) -#define CY_AS_MEM_P0_RSE_ALLOCATE_USBAVI (0x0010) -#define CY_AS_MEM_P0_RSE_ALLOCATE_USBALLO (0x0020) - -#define CY_AS_MEM_P0_RSE_MASK (0x9A) -#define CY_AS_MEM_P0_RSE_MASK_MSDIOBUS_RW (0x0003) -#define CY_AS_MEM_P0_RSE_MASK_MNANDBUS_RW (0x00C0) -#define CY_AS_MEM_P0_RSE_MASK_MUSBBUS_RW (0x0030) - -#define CY_AS_MEM_P0_DRQ (0xA0) -#define CY_AS_MEM_P0_DRQ_EP2DRQ (0x0004) -#define CY_AS_MEM_P0_DRQ_EP3DRQ (0x0008) -#define CY_AS_MEM_P0_DRQ_EP4DRQ (0x0010) -#define CY_AS_MEM_P0_DRQ_EP5DRQ (0x0020) -#define CY_AS_MEM_P0_DRQ_EP6DRQ (0x0040) -#define CY_AS_MEM_P0_DRQ_EP7DRQ (0x0080) -#define CY_AS_MEM_P0_DRQ_EP8DRQ (0x0100) -#define CY_AS_MEM_P0_DRQ_EP9DRQ (0x0200) -#define CY_AS_MEM_P0_DRQ_EP10DRQ (0x0400) -#define CY_AS_MEM_P0_DRQ_EP11DRQ (0x0800) -#define CY_AS_MEM_P0_DRQ_EP12DRQ (0x1000) -#define CY_AS_MEM_P0_DRQ_EP13DRQ (0x2000) -#define CY_AS_MEM_P0_DRQ_EP14DRQ (0x4000) -#define CY_AS_MEM_P0_DRQ_EP15DRQ (0x8000) - -#define CY_AS_MEM_P0_DRQ_MASK (0xA1) -#define CY_AS_MEM_P0_DRQ_MASK_MEP2DRQ (0x0004) -#define CY_AS_MEM_P0_DRQ_MASK_MEP3DRQ (0x0008) -#define CY_AS_MEM_P0_DRQ_MASK_MEP4DRQ (0x0010) -#define CY_AS_MEM_P0_DRQ_MASK_MEP5DRQ (0x0020) -#define CY_AS_MEM_P0_DRQ_MASK_MEP6DRQ (0x0040) -#define CY_AS_MEM_P0_DRQ_MASK_MEP7DRQ (0x0080) -#define CY_AS_MEM_P0_DRQ_MASK_MEP8DRQ (0x0100) -#define CY_AS_MEM_P0_DRQ_MASK_MEP9DRQ (0x0200) -#define CY_AS_MEM_P0_DRQ_MASK_MEP10DRQ (0x0400) -#define CY_AS_MEM_P0_DRQ_MASK_MEP11DRQ (0x0800) -#define CY_AS_MEM_P0_DRQ_MASK_MEP12DRQ (0x1000) -#define CY_AS_MEM_P0_DRQ_MASK_MEP13DRQ (0x2000) -#define CY_AS_MEM_P0_DRQ_MASK_MEP14DRQ (0x4000) -#define CY_AS_MEM_P0_DRQ_MASK_MEP15DRQ (0x8000) - -#define CY_AS_MEM_P0_EP2_DMA_REG (0xA2) -#define CY_AS_MEM_P0_E_pn_DMA_REG_COUNT_MASK (0x7FF) -#define CY_AS_MEM_P0_E_pn_DMA_REG_DMAVAL (1 << 12) -#define CY_AS_MEM_P0_EP3_DMA_REG (0xA3) -#define CY_AS_MEM_P0_EP4_DMA_REG (0xA4) -#define CY_AS_MEM_P0_EP5_DMA_REG (0xA5) -#define CY_AS_MEM_P0_EP6_DMA_REG (0xA6) -#define CY_AS_MEM_P0_EP7_DMA_REG (0xA7) -#define CY_AS_MEM_P0_EP8_DMA_REG (0xA8) -#define CY_AS_MEM_P0_EP9_DMA_REG (0xA9) -#define CY_AS_MEM_P0_EP10_DMA_REG (0xAA) -#define CY_AS_MEM_P0_EP11_DMA_REG (0xAB) -#define CY_AS_MEM_P0_EP12_DMA_REG (0xAC) -#define CY_AS_MEM_P0_EP13_DMA_REG (0xAD) -#define CY_AS_MEM_P0_EP14_DMA_REG (0xAE) -#define CY_AS_MEM_P0_EP15_DMA_REG (0xAF) - -#define CY_AS_MEM_IROS_SLB_DATARET (0xC0) - -#define CY_AS_MEM_IROS_IO_CFG (0xC1) -#define CY_AS_MEM_IROS_IO_CFG_GPIODRVST_MASK (0x0003) -#define CY_AS_MEM_IROS_IO_CFG_GPIOSLEW_MASK (0x0004) -#define CY_AS_MEM_IROS_IO_CFG_PPIODRVST_MASK (0x0018) -#define CY_AS_MEM_IROS_IO_CFG_PPIOSLEW_MASK (0x0020) -#define CY_AS_MEM_IROS_IO_CFG_SSIODRVST_MASK (0x0300) -#define CY_AS_MEM_IROS_IO_CFG_SSIOSLEW_MASK (0x0400) -#define CY_AS_MEM_IROS_IO_CFG_SNIODRVST_MASK (0x1800) -#define CY_AS_MEM_IROS_IO_CFG_SNIOSLEW_MASK (0x2000) - -#define CY_AS_MEM_IROS_PLL_CFG (0xC2) - -#define CY_AS_MEM_IROS_PXB_DATARET (0xC3) - -#define CY_AS_MEM_PLL_LOCK_LOSS_STAT (0xC4) -#define CY_AS_MEM_PLL_LOCK_LOSS_STAT_PLLSTAT (0x0800) - -#define CY_AS_MEM_IROS_SLEEP_CFG (0xC5) - -#define CY_AS_MEM_PNAND_CFG (0xDA) -#define CY_AS_MEM_PNAND_CFG_IOWIDTH_MASK (0x0001) -#define CY_AS_MEM_PNAND_CFG_IOWIDTH_8BIT (0x0000) -#define CY_AS_MEM_PNAND_CFG_IOWIDTH_16BIT (0x0001) -#define CY_AS_MEM_PNAND_CFG_BLKTYPE_MASK (0x0002) -#define CY_AS_MEM_PNAND_CFG_BLKTYPE_SMALL (0x0002) -#define CY_AS_MEM_PNAND_CFG_BLKTYPE_LARGE (0x0000) -#define CY_AS_MEM_PNAND_CFG_EPABYTE_POS (4) -#define CY_AS_MEM_PNAND_CFG_EPABYTE_MASK (0x0030) -#define CY_AS_MEM_PNAND_CFG_EPABIT_POS (6) -#define CY_AS_MEM_PNAND_CFG_EPABIT_MASK (0x00C0) -#define CY_AS_MEM_PNAND_CFG_LNAEN_MASK (0x0100) - -#define CY_AS_MEM_P0_MAILBOX0 (0xF0) -#define CY_AS_MEM_P0_MAILBOX1 (0xF1) -#define CY_AS_MEM_P0_MAILBOX2 (0xF2) -#define CY_AS_MEM_P0_MAILBOX3 (0xF3) - -#define CY_AS_MEM_MCU_MAILBOX0 (0xF8) -#define CY_AS_MEM_MCU_MAILBOX1 (0xF9) -#define CY_AS_MEM_MCU_MAILBOX2 (0xFA) -#define CY_AS_MEM_MCU_MAILBOX3 (0xFB) - -#endif /* !defined(__doxygen__) */ - -#endif /* _INCLUDED_CYASREG_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage.h deleted file mode 100644 index 52b93c3e4813..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage.h +++ /dev/null @@ -1,2759 +0,0 @@ -/* Cypress West Bridge API header file (cyasstorage.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASSTORAGE_H_ -#define _INCLUDED_CYASSTORAGE_H_ - -#include "cyasmedia.h" -#include "cyasmisc.h" -#include "cyas_cplus_start.h" - - -/*@@Storage APIs - Summary - This section documents the storage APIs supported by the - West Bridge API. - - Description - The storage API is based on some specific concepts which - are referenced here. - * - * Addressing - * Ownership - * -*/ - -/*@@Storage API Overview - Summary - Storage devices are identified by media type. Each media - type is considered a single logical device. - - Description - Each media type has a consistent block size and consists - of a set of logical blocks numbered from 0 to N - 1 where - N is the size of the - media type in blocks. The mass storage APIs defined below - provide the - capability to query for devices that are present, and - read/write data to/from - these devices. -*/ - -/*@@Addressing - Summary - Blocks within a storage device are address by a hierarchal - block address. This - address consists of the bus number, physical device, - logical unit, and finally - block address. - - Description - While currently only a single device of each media type - is supported, the address - space reserves space in the future for multiple devices - of each type. Therefore - the second element of the address is the specific device - being addressed within - a given device type. For this release of the software, - this value will always be - zero to address the first device. - - The third element of the address is the logical unit. - A device being managed - by West Bridge can be partitioned into multiple logical - units. This partition - information is stored on each device itself. Currently, - one of the storage devices - managed by West Bridge can be partitioned into two - logical units. - - Finally a logical block address is given within the - logical unit to address an - individual block. -*/ - -/*@@Ownership - Summary - While West Bridge supports concurrent block level - operations from both the USB port and - the processor port, this is not desirable in most - situations as the file system - contained on the storage media cannot be accessed - concurrently. To insure access - by only one of USB and the processor, the West Bridge - API provides for ownership of storage - devices based on media type. - - Description - The processor requests ownership of a given media type - by calling CyAsStorageClaim(). - The firmware in West Bridge releases control of the - media and signals the processor through - the event callback registered with - CyAsStorageRegisterCallback(). The specific event is - the CyAsStorageProcessor. The processor can later - release the media via a call to - CyAsStorageRelease(). This call is immediate and - no callback is required. - - If the processor has claimed storage and the USB port - is connected, West Bridge will need to - claim the storage to manage the mass storage device. - West Bridge requests the storage through - the event callback registered with - CyAsStorageRegisterCallback(). The specific event is - CyAsStorageAntioch and is named as such to reflect - the USB view of storage. This callback - is a request for the processor to release storage. - The storage is not actually released - until the processor calls CyAsStorageRelease(). - - Note that the CyAsStorageAntioch is only sent when the - USB storage device is enumerated and - NOT at every USB operation. The ownership of a given - storage media type is assumed to belong - to the processor until the USB connection is established. - At that point, the storage ownership - is transferred to West Bridge. After the USB connection - is broken, ownership can be transferred - back to the processor. -*/ - -/*@@Asynchronous Versus Synchronous Operation - Summary - When read or write operations are performed to the - storage devices, these operations may be - synchronous or asynchronous. A synchronous operation - is an operation where the read or write - operation is requested and the function does not return - until the operation is complete. This - type of function is the easiest to use but does not - provide for optimal usage of the P port processor time. - - Description - An asynchronous operation is one where the function returns - as soon as the request is started. - The specific read and write request will complete at some - time in the future and the P port - processor will be notified via a callback function. While - asynchronous functions provide for - much better usage of the CPU, these function have more - stringent requirements for use. First, - any buffer use for data transfer must be valid from the - function call to request the operation - through when the callback function is called. This basically - implies that stack based buffers - are not acceptable for asynchronous calls. Second, error - handling must be deferred until the - callback function is called indicating any kind of error - that may have occurred. -*/ - -/*@@Partitioning - Summary - West Bridge API and firmware support the creation of up to - two logical partitions on one - of the storage devices that are managed by West Bridge. The - partitions are managed through - the CyAsStorageCreatePPartition and CyAsStorageRemovePPartition - APIs. - - Description - The CyAsStorageCreatePPartition API is used to divide the total - storage on a storage - device into two logical units or partitions. Since the partition - information is stored - on the storage device in a custom format, partitions should - only be created on fixed - storage devices (i.e., no removable SD/MMC cards). Any data - stored on the device - before the creation of the partition, is liable to be lost when - a partition is created. - - The CyAsStorageRemovePPartition API is used to remove the - stored partition information, - so that all of the device's capacity is treated as a single - partition again. - - When a storage device with two partitions (units) is being - enumerated as a mass storage - device through the West Bridge, it is possible to select the - partitions to be made - visible to the USB host. This is done through the - CyAsUsbSelectMSPartitions API. -*/ - -/********************************* - * West Bridge Constants - **********************************/ - -/* Summary - This constants indicates a raw device access to the read/write - functions - - Description - When performing reading and writing operations on the - storage devices attached - to West Bridge, there are cases where writes need to - happen to raw devices, versus - the units contained within a device. This is - specifically required to manage - the partitions within physical devices. This constant - is used in calls to - CyAsStorageRead(), CyAsStorageReadAsync(), - CyAsStorageWrite() and - CyAsStorageWriteAsync(), to indicate that the raw - physical device is being - accessed and not any specific unit on the device. - - See Also - * CyAsStorageRead - * CyAsStorageReadAsync - * CyAsStorageWrite - * CyAsStorageWriteAsync -*/ -#define CY_AS_LUN_PHYSICAL_DEVICE (0xffffffff) - -/* Summary - This constant represents the maximum DMA burst length - supported on a storage endpoint - - Description - West Bridge reserves separate endpoints for accessing - storage media through the - CyAsStorageRead() and CyAsStorageWrite() calls. The - maximum size of these - endpoints is always 512 bytes, regardless of status - and speed of the USB - connection. -*/ -#define CY_AS_STORAGE_EP_SIZE (512) - -/******************************** - * West Bridge Types - *******************************/ - -/* Summary - This type indicates the type of event in an event - callback from West Bridge - - Description - At times West Bridge needs to inform the P port - processor of events that have - occurred. These events are asynchronous to the - thread of control on the P - port processor and as such are generally delivered - via a callback function that - is called as part of an interrupt handler. This - type indicates the resonse for - the call to the callback function. - - See Also - * CyAsStorageEventCallback - * CyAsStorageRegisterCallback -*/ -typedef enum cy_as_storage_event { - /* This event occurs when the West Bridge device has - detected a USB connect and has enumerated the - storage controlled by west bridge to the USB port. - this event is the signal that the processor - needs to release the storage media. west bridge will - not have control of the storage media until the - processor calls cy_as_release_storage() to release - the specific media. */ - cy_as_storage_antioch, - - /* This event occurs when the processor has requested - ownership of a given media type and west bridge has - released the media. this event is an indicator - that the transfer of ownership is complete and the - processor now owns the given media type. */ - cy_as_storage_processor, - - /* This event occurs when a removable media type has - been removed. */ - cy_as_storage_removed, - - /* This event occurs when a removable media type has - been inserted. */ - cy_as_storage_inserted, - - /* This event occurs when the West Bridge device - * percieves an interrrupt from an SDIO card */ - cy_as_sdio_interrupt - -} cy_as_storage_event; - -/* Summary - This type gives the type of the operation in a storage - operation callback - - Description - This type is used in the callback function for asynchronous - operation. This type indicates whether it is a - CyAsStorageRead() or CyAsStorageWrite() operation that - has completed. - - See Also - * - * CyAsStorageRead - * CyAsStorageWrite -*/ -typedef enum cy_as_oper_type { - /* A data read operation */ - cy_as_op_read, - /* A data write operation */ - cy_as_op_write -} cy_as_oper_type; - -/* Summary - This data structure describes a specific type of media - - Description - This data structure is the return value from the - CyAsStorageQueryDevice function. This structure provides - information about the specific storage device being queried. - - See Also - * CyAsStorageQueryDevice -*/ -typedef struct cy_as_device_desc { - /* Type of device */ - cy_as_media_type type; - /* Is the device removable */ - cy_bool removable; - /* Is the device writeable */ - cy_bool writeable; - /* Basic block size for device */ - uint16_t block_size; - /* Number of LUNs on the device */ - uint32_t number_units; - /* Is the device password locked */ - cy_bool locked; - /* Size in bytes of an Erase Unit. Block erase operation - is only supported for SD storage, and the erase_unit_size - is invalid for all other kinds of storage. */ - uint32_t erase_unit_size; -} cy_as_device_desc; - -/* Summary - This data structure describes a specific unit on a - specific type of media - - Description - This data structure is the return value from the - CyAsStorageQueryUnit function. This structure provides - information about the specific unit. - - See Also - * CyAsStorageQueryUnit -*/ -typedef struct cy_as_unit_desc { - /* Type of device */ - cy_as_media_type type; - /* Basic block size for device */ - uint16_t block_size; - /* Physical start block for LUN */ - uint32_t start_block; - /* Number of blocks in the LUN */ - uint32_t unit_size; -} cy_as_unit_desc; - -/* Summary - This function type defines a callback to be called after an - asynchronous operation - - Description - This function type defines a callback function that is called - at the completion of any asynchronous read or write operation. - - See Also - * CyAsStorageReadAsync() - * CyAsStorageWriteAsync() -*/ -typedef void (*cy_as_storage_callback)( - /* Handle to the device completing the storage operation */ - cy_as_device_handle handle, - /* The bus completing the operation */ - cy_as_bus_number_t bus, - /* The device completing the operation */ - uint32_t device, - /* The unit completing the operation */ - uint32_t unit, - /* The block number of the completed operation */ - uint32_t block_number, - /* The type of operation */ - cy_as_oper_type op, - /* The error status */ - cy_as_return_status_t status - ); - -/* Summary - This function type defines a callback to be called in the - event of a storage related event - - Description - At times West Bridge needs to inform the P port processor - of events that have - occurred. These events are asynchronous to the thread of - control on the P - port processor and as such are generally delivered via a - callback function that - is called as part of an interrupt handler. This type - defines the type of function - that must be provided as a callback function. - - See Also - * CyAsStorageEvent - * CyAsStorageRegisterCallback -*/ -typedef void (*cy_as_storage_event_callback)( - /* Handle to the device sending the event notification */ - cy_as_device_handle handle, - /* The bus where the event happened */ - cy_as_bus_number_t bus, - /* The device where the event happened */ - uint32_t device, - /* The event type */ - cy_as_storage_event evtype, - /* Event related data */ - void *evdata - ); - -/* Summary - This function type defines a callback to be called after - an asynchronous sdio operation - - Description - The Callback function is called at the completion of an - asynchronous sdio read or write operation. - - See Also - * CyAsSdioExtendedRead() - * CyAsSdioExtendedWrite() -*/ -typedef void (*cy_as_sdio_callback)( - /* Handle to the device completing the storage operation */ - cy_as_device_handle handle, - /* The bus completing the operation */ - cy_as_bus_number_t bus, - /* The device completing the operation */ - uint32_t device, - /* The function number of the completing the operation. - if the status of the operation is either CY_AS_ERROR_IO_ABORTED - or CY_AS_IO_SUSPENDED then the most significant word parameter will - contain the number of blocks still pending. */ - uint32_t function, - /* The base address of the completed operation */ - uint32_t address, - /* The type of operation */ - cy_as_oper_type op, - /* The status of the operation */ - cy_as_return_status_t status - ); - -/* Summary - Enumeration of SD/MMC card registers that can be read - through the API. - - Description - Some of the registers on the SD/MMC card(s) attached to the - West Bridge can be read through the API layers. This type - enumerates the registers that can be read. - - See Also - * CyAsStorageSDRegisterRead - */ -typedef enum cy_as_sd_card_reg_type { - cy_as_sd_reg_OCR = 0, - cy_as_sd_reg_CID, - cy_as_sd_reg_CSD -} cy_as_sd_card_reg_type; - -/* Summary - Struct encapsulating parameters and return values for a - CyAsStorageQueryDevice call. - - Description - This struct holds the input parameters and the return values - for an asynchronous CyAsStorageQueryDevice call. - - See Also - * CyAsStorageQueryDevice - */ -typedef struct cy_as_storage_query_device_data { - /* The bus with the device to query */ - cy_as_bus_number_t bus; - /* The logical device number to query */ - uint32_t device; - /* The return value for the device descriptor */ - cy_as_device_desc desc_p; -} cy_as_storage_query_device_data; - - -/* Summary - Struct encapsulating parameters and return values - for a CyAsStorageQueryUnit call. - - Description - This struct holds the input parameters and the return - values for an asynchronous CyAsStorageQueryUnit call. - - See Also - * CyAsStorageQueryUnit - */ -typedef struct cy_as_storage_query_unit_data { - /* The bus with the device to query */ - cy_as_bus_number_t bus; - /* The logical device number to query */ - uint32_t device; - /* The unit to query on the device */ - uint32_t unit; - /* The return value for the unit descriptor */ - cy_as_unit_desc desc_p; -} cy_as_storage_query_unit_data; - -/* Summary - Struct encapsulating the input parameter and return - values for a CyAsStorageSDRegisterRead call. - - Description - This struct holds the input parameter and return - values for an asynchronous CyAsStorageSDRegisterRead - call. - - See Also - * CyAsStorageSDRegisterRead - */ -typedef struct cy_as_storage_sd_reg_read_data { - /* Pointer to the result buffer. */ - uint8_t *buf_p; - /* Length of data to be copied in bytes. */ - uint8_t length; -} cy_as_storage_sd_reg_read_data; - -/* Summary - Controls which pins are used for card detection - - Description - When a StorageDeviceControl call is made to enable or - disable card detection this enum is passed in to - control which pin is used for the detection. - - See Also - * CyAsStorageDeviceControl -*/ -typedef enum cy_as_storage_card_detect { - cy_as_storage_detect_GPIO, - cy_as_storage_detect_SDAT_3 -} cy_as_storage_card_detect; - -#ifndef __doxygen__ -#define cy_as_storage_detect_GPIO_0 cy_as_storage_detect_GPIO - -/* Length of OCR value in bytes. */ -#define CY_AS_SD_REG_OCR_LENGTH (4) -/* Length of CID value in bytes. */ -#define CY_AS_SD_REG_CID_LENGTH (16) -/* Length of CSD value in bytes. */ -#define CY_AS_SD_REG_CSD_LENGTH (16) -/* Max. length of register response in words. */ -#define CY_AS_SD_REG_MAX_RESP_LENGTH (10) - -#endif - -/* Summary - This data structure is the data passed via the evdata - paramater on a usb event callback for the mass storage - device progress event. - - Description - This data structure reports the number of sectors that have - been written and read on the USB mass storage device since - the last event report. The corresponding event is only sent - when either the number of writes, or the number of reads has - crossed a pre-set threshold. - - See Also - * CyAsUsbEventCallback - * CyAsUsbRegisterCallback -*/ -typedef struct cy_as_m_s_c_progress_data { - /* Number of sectors written since the last event. */ - uint32_t wr_count; - /* Number of sectors read since the last event. */ - uint32_t rd_count; -} cy_as_m_s_c_progress_data; - -/* Summary -Flag to set Direct Write operation to read back from the -address written to. - - - See Also - *CyAsSdioDirectWrite() -*/ -#define CY_SDIO_RAW (0x01) - - -/* Summary -Flag to set Extended Read and Write to perform IO -using a FIFO i.e. read or write from the specified -address only. - - See Also - *CyAsSdioExtendedRead() - *CyAsSdioExtendedWrite() -*/ -#define CY_SDIO_OP_FIFO (0x00) - -/* Summary -Flag to set Extended Read and Write to perform incremental -IO using the address provided as the base address. - - - See Also - *CyAsSdioExtendedRead() - *CyAsSdioExtendedWrite() -*/ -#define CY_SDIO_OP_INCR (0x02) - -/* Summary -Flag to set Extended Read and Write to Block Mode operation - - See Also - *CyAsSdioExtendedRead() - *CyAsSdioExtendedWrite() -*/ -#define CY_SDIO_BLOCKMODE (0x04) - -/* Summary -Flag to set Extended Read and Write to Byte Mode operation - - See Also - *CyAsSdioExtendedRead() - *CyAsSdioExtendedWrite() -*/ -#define CY_SDIO_BYTEMODE (0x00) - -/* Summary -Flag to force re/initialization of a function. - -Description -If not set a call to CyAsSdioInitFunction() -will not initialize a function that has been previously -initialized. - See Also - *CyAsSdioInitFunction() - */ -#define CY_SDIO_FORCE_INIT (0x40) - -/* Summary -Flag to re-enable the SDIO interrupts. - -Description -Used with a direct read or direct write -after the Interrupt triggerred by SDIO has been serviced -and cleared to reset the West Bridge Sdio Interrupt. - See Also - *CyAsSdioDirectRead() - *CyAsSdioDirectWrite() -*/ - -#define CY_SDIO_REARM_INT (0x80) - - -/* Summary - Flag to check if 4 bit support is enabled on a - low speed card - See Also - */ -#define CY_SDIO_4BLS (0x80) - -/* Summary - Flag to check if card is a low speed card - See Also - */ -#define CY_SDIO_LSC (0x40) - -/* Summary - Flag to check if interrupt during multiblock data - transfer is enabled - See Also - */ -#define CY_SDIO_E4MI (0x20) - -/* Summary - Flag to check if interrupt during multiblock data - transfer is supported - See Also - */ -#define CY_SDIO_S4MI (0x10) - -/* Summary - Flag to check if card supports function suspending. - See Also - */ -#define CY_SDIO_SBS (0x08) - -/* Summary - Flag to check if card supports SDIO Read-Wait - See Also - */ -#define CY_SDIO_SRW (0x04) - -/* Summary - Flag to check if card supports multi-block transfers - See Also - */ -#define CY_SDIO_SMB (0x02) - -/* Summary - Flag to check if card supports Direct IO commands - during execution of an Extended - IO function - See Also - */ -#define CY_SDIO_SDC (0x01) - -/* Summary - Flag to check if function has a CSA area. - See Also - */ -#define CY_SDIO_CSA_SUP (0x40) - -/* Summary - Flag to check if CSA access is enabled. - See Also - */ -#define CY_SDIO_CSA_EN (0x80) - -/* Summary - Flag to check if CSA is Write protected. - See Also - */ -#define CY_SDIO_CSA_WP (0x01) - -/* Summary - Flag to check if CSA formatting is prohibited. - See Also - */ -#define CY_SDIO_CSA_NF (0x02) - -/* Summary - Flag to check if the function allows wake-up from low - power mode using some vendor specific method. - See Also - */ -#define CY_SDIO_FN_WUS (0x01) - - -/* Summary - This data structure stores SDIO function 0 - parameters for a SDIO card -*/ -typedef struct cy_as_sdio_card { - /* Number of functions present on the card. */ - uint8_t num_functions; - /* Memory present(Combo card) or not */ - uint8_t memory_present; - /* 16 bit manufacturer ID */ - uint16_t manufacturer__id; - /* Additional vendor specific info */ - uint16_t manufacturer_info; - /* Max Block size for function 0 */ - uint16_t maxblocksize; - /* Block size used for function 0 */ - uint16_t blocksize; - /* SDIO version supported by the card */ - uint8_t sdio_version; - /* Card capability flags */ - uint8_t card_capability; -} cy_as_sdio_card; - -/* Summary - This data structure stores SDIO function 1-7 parameters - for a SDIO card -*/ -typedef struct cy_as_sdio_func { - /* SDIO function code. 0 if non standard function */ - uint8_t function_code; - /* Extended function type code for non-standard function */ - uint8_t extended_func_code; - /* Max IO Blocksize supported by the function */ - uint16_t maxblocksize; - /* IO Blocksize used by the function */ - uint16_t blocksize; - /* 32 bit product serial number for the function */ - uint32_t card_psn; - /* Code storage area variables */ - uint8_t csa_bits; - /* Function wake-up support */ - uint8_t wakeup_support; -} cy_as_sdio_func; - -/*********************************** - * West Bridge Functions - ************************************/ - -/* Summary - This function starts the West Bridge storage module. - - Description - This function initializes the West Bridge storage software - stack and readies this module to service storage related - requests. If the stack is already running, the reference - count for the stack is incremented. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in - * CY_AS_ERROR_SUCCESS - the module started successfully - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - See Also - * CyAsStorageStop -*/ -EXTERN cy_as_return_status_t -cy_as_storage_start( - /* Handle to the device */ - cy_as_device_handle handle, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -/* Summary - This function stops the West Bridge storage module. - - Description - This function decrements the reference count for the - storage stack and if this count is zero, the storage - stack is shut down. The shutdown frees all resources - associated with the storage stack. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Notes - While all resources associated with the storage stack - will be freed is a shutdown occurs, - resources associated with underlying layers of the - software will not be freed if they - are shared by the USB stack and the USB stack is - active. Specifically the DMA manager, - the interrupt manager, and the West Bridge - communications module are all shared by both the - USB stack and the storage stack. - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge - * device has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not - * been loaded into West Bridge - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_SUCCESS - this module was shut - * down successfully - * CY_AS_ERROR_TIMEOUT - a timeout occurred - * communicating with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - * CY_AS_ERROR_ASYNC_PENDING - * CY_AS_ERROR_OUT_OF_MEMORY - - See Also - * CyAsStorageStart -*/ -EXTERN cy_as_return_status_t -cy_as_storage_stop( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -/* Summary - This function is used to register a callback function - for the storage API. - - Description - At times West Bridge needs to inform the P port processor - of events that have occurred. These events are asynchronous - to the thread of control on the P - port processor and as such are generally delivered via a - callback function that - is called as part of an interrupt handler. This function - registers the callback - function that is called when an event occurs. Each call - to this function - replaces any old callback function with a new callback - function supplied on - the most recent call. This function can also be called - with a callback function - of NULL in order to remove any existing callback function - - * Valid In Asynchronous Callback:YES - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has - * not been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle - * was passed in - * CY_AS_ERROR_SUCCESS - the function was registered - * successfully - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - - See Also - * CyAsStorageEventCallback - * CyAsStorageEvent -*/ -EXTERN cy_as_return_status_t -cy_as_storage_register_callback( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The callback function to call for async storage events */ - cy_as_storage_event_callback callback - ); - -/* Summary - This function claims a given media type. - - Description - This function communicates to West Bridge that the - processor wants control of the - given storage media type. Each media type can be - claimed or released by the - processor independently. As the processor is the - master for the storage, - West Bridge should release control of the requested - media as soon as possible and - signal the processor via the CyAsStorageProcessor event. - - * Valid In Asynchronous Callback: NO - - Notes - This function just notifies West Bridge that the storage - is desired. The storage - has not actually been released by West Bridge until the - registered callback function - is called with the CyAsStorageProcessor event - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_SUCCESS - this request was successfully - * transmitted to the West Bridge device - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_MEDIA - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - * CY_AS_ERROR_NOT_ACQUIRED - - See Also: - * CyAsStorageClaim - * CyAsStorageRelease -*/ -EXTERN cy_as_return_status_t -cy_as_storage_claim( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The bus to claim */ - cy_as_bus_number_t bus, - /* The device to claim */ - uint32_t device, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -/* Summary - This function releases a given media type. - - Description - This function communicates to West Bridge that the - processor has released control of - the given storage media type. Each media type can - be claimed or released by the - processor independently. As the processor is the - master for the storage, West Bridge - can now assume ownership of the media type. No callback - or event is generated. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle - * was passed in - * CY_AS_ERROR_SUCCESS - the media was successfully - * released - * CY_AS_ERROR_MEDIA_NOT_CLAIMED - the media was not - * claimed by the P port - * CY_AS_ERROR_TIMEOUT - a timeout occurred - * communicating with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_MEDIA - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - See Also - * CyAsStorageClaim -*/ -EXTERN cy_as_return_status_t -cy_as_storage_release( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The bus to release */ - cy_as_bus_number_t bus, - /* The device to release */ - uint32_t device, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -/* Summary - This function information about the number of devices present - on a given bus - - Description - This function retrieves information about how many devices on - on the given - West Bridge bus. - - * Valid In Asynchronous Callback: NO - - Notes - While the current implementation of West Bridge only - supports one of logical device of - each media type, future versions WestBridge/Antioch may - support multiple devices. - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_SUCCESS - the media information was - * returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred - * communicating with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - See Also - * CyAsStorageQueryDevice - * CyAsStorageQueryUnit -*/ -EXTERN cy_as_return_status_t -cy_as_storage_query_bus( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The bus to query */ - cy_as_bus_number_t bus, - /* The return value containing the number of - devices present for this media type */ - uint32_t *count, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -/* Summary - This function information about the number of devices - present for a given media type - - Description - This function retrieves information about how many - devices of a given media type are attached to West Bridge. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Notes - While the current implementation of West Bridge only - supports one of logical device of each media type, future - versions West Bridge may support multiple devices. - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_SUCCESS - the media information was - * returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred - * communicating with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - See Also - * CyAsStorageQueryMedia - * CyAsMediaType - * CyAsStorageQueryDevice - * CyAsStorageQueryUnit -*/ -EXTERN cy_as_return_status_t -cy_as_storage_query_media( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The type of media to query */ - cy_as_media_type type, - /* The return value containing the number of - devices present for this media type */ - uint32_t *count, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -/* Summary - This function returns information about a given device - of a specific media type - - Description - This function retrieves information about a device of a - given type of media. The function is called with a given - media type and device and a pointer to a media descriptor - (CyAsDeviceDesc). This function fills in the data in the - media descriptor to provide information about the - attributes of the device of the given device. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Notes - Currently this API only supports a single logical device - of each media type. Therefore the only acceptable value - for the parameter device is zero (0). - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_SUCCESS - the media information was - * returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_NO_SUCH_MEDIA - * CY_AS_ERROR_NO_SUCH_DEVICE - * CY_AS_ERROR_INVALID_RESPONSE - - See Also - * CyAsMediaType - * CyAsStorageQueryMedia - * CyAsStorageQueryUnit - * CyAsDeviceDesc -*/ -EXTERN cy_as_return_status_t -cy_as_storage_query_device( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* Parameters and return value for the query call */ - cy_as_storage_query_device_data *data, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -/* Summary - This function returns information about a given unit on a - specific device - - Description - This function retrieves information about a device of a - given logical unit. The function is called with a given - media type, device address, unit address, and a pointer - to a unit descriptor (CyAsUnitDesc). This function fills - in the data in the unit descriptor to provide information - about the attributes of the device of the given logical - unit. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_SUCCESS - the media information was returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_NO_SUCH_DEVICE - * CY_AS_ERROR_NO_SUCH_UNIT - * CY_AS_ERROR_INVALID_RESPONSE - - - See Also - * CyAsMediaType - * CyAsStorageQueryMedia - * CyAsStorageQueryDevice - * CyAsUnitDesc -*/ -EXTERN cy_as_return_status_t -cy_as_storage_query_unit( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* Parameters and return value for the query call */ - cy_as_storage_query_unit_data *data_p, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -/* Summary - This function enables/disables the handling of SD/MMC card - detection and SD/MMC write protection in West Bridge Firmware. - - Description - If the detection of SD/MMC card insertion or removal is being - done by the Processor directly, the West Bridge firmware needs - to be instructed to disable the card detect feature. Also, if - the hardware design does not use the SD_WP GPIO of the West - Bridge to handle SD card's write protect notch, the handling - of write protection if firmware should be disabled. This API - is used to enable/disable the card detect and write protect - support in West Bridge firmware. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the feature controls were - * set successfully - * CY_AS_ERROR_NO_SUCH_BUS - the specified bus is invalid - * CY_AS_ERROR_NOT_SUPPORTED - function not supported on - * the device in the specified bus - * CY_AS_ERROR_IN_SUSPEND - the West Brdige device is in - * suspended mode - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - -*/ -EXTERN cy_as_return_status_t -cy_as_storage_device_control( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The bus to control */ - cy_as_bus_number_t bus, - /* The device to control */ - uint32_t device, - /* Enable/disable control for card detection */ - cy_bool card_detect_en, - /* Enable/disable control for write protect handling */ - cy_bool write_prot_en, - /* Control which pin is used for card detection */ - cy_as_storage_card_detect config_detect, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -/* Summary - This function reads one or more blocks of data from - the storage system. - - Description - This function synchronously reads one or more blocks - of data from the given media - type/device and places the data into the data buffer - given. This function does not - return until the data is read and placed into the buffer. - - * Valid In Asynchronous Callback: NO - - Notes - If the Samsung CEATA drive is the target for a - read/write operation, the maximum - number of sectors that can be accessed through a - single API call is limited to 2047. - Longer accesses addressed to a Samsung CEATA drive - can result in time-out errors. - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle - * was passed in - * CY_AS_ERROR_SUCCESS - the media information was - * returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred - * communicating with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified - * does not exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified - * media/device pair does not exist - * CY_AS_ERROR_NO_SUCH_UNIT - the unit specified - * does not exist - * CY_AS_ERROR_ASYNC_PENDING - an async operation - * is pending - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was - * error in reading from the media - * CY_AS_ERROR_MEDIA_WRITE_PROTECTED - the media is - * write protected - * CY_AS_ERROR_INVALID_PARAMETER - Reads/Writes greater - * than 4095 logic blocks are not allowed - - See Also - * CyAsStorageReadAsync - * CyAsStorageWrite - * CyAsStorageWriteAsync - * CyAsStorageCancelAsync - * -*/ -EXTERN cy_as_return_status_t -cy_as_storage_read( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The bus to access */ - cy_as_bus_number_t bus, - /* The device to access */ - uint32_t device, - /* The unit to access */ - uint32_t unit, - /* The first block to access */ - uint32_t block, - /* The buffer where data will be placed */ - void *data_p, - /* The number of blocks to be read */ - uint16_t num_blocks - ); - -/* Summary - This function asynchronously reads one or more blocks of data - from the storage system. - - Description - This function asynchronously reads one or more blocks of - data from the given media - type/device and places the data into the data buffer given. - This function returns - as soon as the request is transmitted to the West Bridge - device but before the data is - available. When the read is complete, the callback function - is called to indicate the - data has been placed into the data buffer. Note that the - data buffer must remain - valid from when the read is requested until the callback - function is called. - - * Valid In Asynchronous Callback: YES - - Notes - If the Samsung CEATA drive is the target for a read/write - operation, the maximum - number of sectors that can be accessed through a single API - call is limited to 2047. - Longer accesses addressed to a Samsung CEATA drive can - result in time-out errors. - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle - * was passed in - * CY_AS_ERROR_SUCCESS - the media information was - * returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred - * communicating with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_ASYNC_PENDING - an async operation - * is pending - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error - * in reading from the media - * CY_AS_ERROR_MEDIA_WRITE_PROTECTED - the media is - * write protected - * CY_AS_ERROR_QUERY_DEVICE_NEEDED - Before an - * asynchronous read can be issue a call to - * CyAsStorageQueryDevice must be made - * CY_AS_ERROR_INVALID_PARAMETER - Reads/Writes greater - * than 4095 logic blocks are not allowed - - See Also - * CyAsStorageRead - * CyAsStorageWrite - * CyAsStorageWriteAsync - * CyAsStorageCancelAsync - * CyAsStorageQueryDevice - * -*/ -EXTERN cy_as_return_status_t -cy_as_storage_read_async( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The bus to access */ - cy_as_bus_number_t bus, - /* The device to access */ - uint32_t device, - /* The unit to access */ - uint32_t unit, - /* The first block to access */ - uint32_t block, - /* The buffer where data will be placed */ - void *data_p, - /* The number of blocks to be read */ - uint16_t num_blocks, - /* The function to call when the read is complete - or an error occurs */ - cy_as_storage_callback callback - ); - -/* Summary - This function writes one or more blocks of data - to the storage system. - - Description - This function synchronously writes one or more blocks of - data to the given media/device. - This function does not return until the data is written - into the media. - - * Valid In Asynchronous Callback: NO - - Notes - If the Samsung CEATA drive is the target for a read/write - operation, the maximum - number of sectors that can be accessed through a single - API call is limited to 2047. - Longer accesses addressed to a Samsung CEATA drive can - result in time-out errors. - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_SUCCESS - the media information was - * returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred - * communicating with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does - * not exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified - * media/device pair does not exist - * CY_AS_ERROR_NO_SUCH_UNIT - the unit specified - * does not exist - * CY_AS_ERROR_ASYNC_PENDING - an async operation - * is pending - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error - * in reading from the media - * CY_AS_ERROR_MEDIA_WRITE_PROTECTED - the media is - * write protected - * CY_AS_ERROR_INVALID_PARAMETER - Reads/Writes greater - * than 4095 logic blocks are not allowed - - See Also - * CyAsStorageRead - * CyAsStorageReadAsync - * CyAsStorageWriteAsync - * CyAsStorageCancelAsync - * -*/ -EXTERN cy_as_return_status_t -cy_as_storage_write( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The bus to access */ - cy_as_bus_number_t bus, - /* The device to access */ - uint32_t device, - /* The unit to access */ - uint32_t unit, - /* The first block to access */ - uint32_t block, - /* The buffer containing the data to be written */ - void *data_p, - /* The number of blocks to be written */ - uint16_t num_blocks - ); - -/* Summary - This function asynchronously writes one or more blocks - of data to the storage system - - Description - This function asynchronously writes one or more blocks of - data to the given media type/device. - This function returns as soon as the request is transmitted - to the West Bridge device - but before the data is actually written. When the write is - complete, the callback - function is called to indicate the data has been physically - written into the media. - - * Valid In Asynchronous Callback: YES - - Notes - If the Samsung CEATA drive is the target for a read/write - operation, the maximum - number of sectors that can be accessed through a single API - call is limited to 2047. - Longer accesses addressed to a Samsung CEATA drive can - result in time-out errors. - - Notes - The data buffer must remain valid from when the write is - requested until the callback function is called. - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has - * not been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in - * CY_AS_ERROR_SUCCESS - the media information was returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_ASYNC_PENDING - an async operation is - * pending - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in - * reading from the media - * CY_AS_ERROR_MEDIA_WRITE_PROTECTED - the media is write - * protected - * CY_AS_ERROR_QUERY_DEVICE_NEEDED - A query device call is - * required before async writes are allowed - * CY_AS_ERROR_INVALID_PARAMETER - Reads/Writes greater - * than 4095 logic blocks are not allowed - - See Also - * CyAsStorageRead - * CyAsStorageWrite - * CyAsStorageReadAsync - * CyAsStorageCancelAsync - * CyAsStorageQueryDevice - * -*/ -EXTERN cy_as_return_status_t -cy_as_storage_write_async( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The bus to access */ - cy_as_bus_number_t bus, - /* The device to access */ - uint32_t device, - /* The unit to access */ - uint32_t unit, - /* The first block to access */ - uint32_t block, - /* The buffer where the data to be written is stored */ - void *data_p, - /* The number of blocks to be written */ - uint16_t num_blocks, - /* The function to call when the write is complete - or an error occurs */ - cy_as_storage_callback callback - ); - -/* Summary - This function aborts any outstanding asynchronous operation - - Description - This function aborts any asynchronous block read or block - write operation. As only a single asynchronous block read - or write operation is possible at one time, this aborts - the single operation in progress. - - * Valid In Asynchronous Callback: YES - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in - * CY_AS_ERROR_SUCCESS - the media information was returned - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_OPERATION_PENDING - no asynchronous - * operation is pending - - See Also - * CyAsStorageRead - * CyAsStorageReadAsync - * CyAsStorageWrite - * CyAsStorageWriteAsync - * -*/ -EXTERN cy_as_return_status_t -cy_as_storage_cancel_async( - /* Handle to the device with outstanding async request */ - cy_as_device_handle handle - ); - -/* Summary - This function is used to read the content of SD registers - - Description - This function is used to read the contents of CSD, CID and - CSD registers of the SD Card. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the read operation was successful - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been - * started - * CY_AS_ERROR_IN_SUSPEND - The West Bridge device is in - * suspend mode - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device pair - * does not exist - * CY_AS_ERROR_INVALID_PARAMETER - The register type is invalid - * or the media is not supported on the bus - * CY_AS_ERROR_OUT_OF_MEMORY - failed to get memory to process - * request - * CY_AS_ERROR_INVALID_RESPONSE - communication failure with - * West Bridge firmware - - See Also - * CyAsStorageSDRegReadData - */ -EXTERN cy_as_return_status_t -cy_as_storage_sd_register_read( - /* Handle to the West Bridge device. */ - cy_as_device_handle handle, - /* The bus to query */ - cy_as_bus_number_t bus, - /* The device to query */ - uint8_t device, - /* The type of register to read. */ - cy_as_sd_card_reg_type reg_type, - /* Output data buffer and length. */ - cy_as_storage_sd_reg_read_data *data_p, - /* Callback function to call when done. */ - cy_as_function_callback cb, - /* Call context to send to the cb function. */ - uint32_t client - ); - -/* Summary - Creates a partition starting at the given block and using the - remaining blocks on the card. - - Description - Storage devices attached to West Bridge can be partitioned - into two units. - The visibility of these units through the mass storage - interface can be - individually controlled. This API is used to partition - a device into two. - - * Valid in Asynchronous Callback: Yes (if cb supplied) - * Nestable: Yes - - Returns - * CY_AS_ERROR_SUCCESS - the partition was successfully created - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been - * started - * CY_AS_ERROR_IN_SUSPEND - The West Bridge device is in - * suspend mode - * CY_AS_ERROR_USB_RUNNING - Partition cannot be created while - * USB stack is active - * CY_AS_ERROR_OUT_OF_MEMORY - failed to get memory to - * process request - * CY_AS_ERROR_INVALID_REQUEST - feature not supported by - * active device or firmware - * CY_AS_ERROR_INVALID_RESPONSE - communication failure with - * West Bridge firmware - * CY_AS_ERROR_ALREADY_PARTITIONED - the storage device already - * has been partitioned - * CY_AS_ERROR_INVALID_BLOCK - Size specified for the partition - * exceeds the actual device capacity - - See Also - * - * CyAsStorageRemovePPartition - */ -EXTERN cy_as_return_status_t -cy_as_storage_create_p_partition( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* Bus on which the device to be partitioned is connected */ - cy_as_bus_number_t bus, - /* Device number to be partitioned */ - uint32_t device, - /* Size of partition number 0 in blocks */ - uint32_t size, - /* Callback in case of async call */ - cy_as_function_callback cb, - /* Client context to pass to the callback */ - uint32_t client - ); - -/* Summary - Removes the partition table on a storage device connected - to the West Bridge. - - Description - Storage devices attached to West Bridge can be partitioned - into two units.This partition information is stored on the - device and is non-volatile. This API is used to remove the - stored partition information and make the entire device - visible as a single partition (unit). - - * Valid in Asynchronous Callback: Yes (if cb supplied) - * Nestable: Yes - - Returns - * CY_AS_ERROR_SUCCESS - the partition was successfully - * deleted - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_IN_SUSPEND - The West Bridge device is in - * suspend mode - * CY_AS_ERROR_USB_RUNNING - Partition cannot be created - * while USB stack is active - * CY_AS_ERROR_OUT_OF_MEMORY - failed to get memory to - * process request - * CY_AS_ERROR_INVALID_REQUEST - operation not supported - * by active device/firmware - * CY_AS_ERROR_NO_SUCH_UNIT - the addressed device is - * not partitioned - - See Also - * - * CyAsStorageCreatePPartition - */ -EXTERN cy_as_return_status_t -cy_as_storage_remove_p_partition( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* Bus on which device of interest is connected */ - cy_as_bus_number_t bus, - /* Device number of interest */ - uint32_t device, - /* Callback in case of async call */ - cy_as_function_callback cb, - /* Client context to pass to the callback */ - uint32_t client - ); - -/* Summary - Returns the amount of data read/written to the given - device from the USB host. - - Description - - * Valid in Asynchronous Callback: Yes (if cb supplied) - * Nestable: Yes - - Returns - * CY_AS_ERROR_SUCCESS - API call completed successfully - * CY_AS_ERROR_INVALID_HANDLE - Invalid West Bridge device - * handle - * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - No firmware image has been - * loaded on West Bridge device - * CY_AS_ERROR_NOT_RUNNING - Storage stack has not been - * started - * CY_AS_ERROR_NOT_SUPPORTED - This function is not - * supported by active firmware version - * CY_AS_ERROR_OUT_OF_MEMORY - Failed to get memory to - * process the request - * CY_AS_ERROR_TIMEOUT - West Bridge firmware did not - * respond to request - * CY_AS_ERROR_INVALID_RESPONSE - Unexpected reply from - * West Bridge firmware - - See Also - * CyAsUsbSetMSReportThreshold -*/ -EXTERN cy_as_return_status_t -cy_as_storage_get_transfer_amount( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* Bus on which device of interest is connected */ - cy_as_bus_number_t bus, - /* Device number of interest */ - uint32_t device, - /* Return value containing read/write sector counts. */ - cy_as_m_s_c_progress_data *data_p, - /* Callback in case of async call */ - cy_as_function_callback cb, - /* Client context to pass to the callback */ - uint32_t client - ); - -/* Summary - Performs a Sector Erase on an attached SD Card - - Description - This allows you to erase an attached SD card. The area to erase - is specified in terms of a starting Erase Unit and a number of - Erase Units. The size of each Erase Unit is defined in the - DeviceDesc returned from a StorageQueryDevice call and it can - differ between SD cards. - - A large erase can take a while to complete depending on the SD - card. In such a case it is recommended that an async call is made. - - Returns - * CY_AS_ERROR_SUCCESS - API call completed successfully - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been - * started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed in - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_ASYNC_PENDING - an async operation is pending - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in - * reading from the media - * CY_AS_ERROR_MEDIA_WRITE_PROTECTED - the media is write protected - * CY_AS_ERROR_QUERY_DEVICE_NEEDED - A query device call is - * required before erase is allowed - * CY_AS_ERROR_NO_SUCH_BUS - * CY_AS_ERROR_NO_SUCH_DEVICE - * CY_AS_ERROR_NOT_SUPPORTED - Erase is currently only supported - * on SD and using SD only firmware - * CY_AS_ERROR_OUT_OF_MEMORY - - See Also - * CyAsStorageSDRegisterRead -*/ -EXTERN cy_as_return_status_t -cy_as_storage_erase( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* Bus on which device of interest is connected */ - cy_as_bus_number_t bus, - /* Device number of interest */ - uint32_t device, - /* Erase Unit to start the erase */ - uint32_t erase_unit, - /* Number of Erase Units to erase */ - uint16_t num_erase_units, - /* Callback in case of async call */ - cy_as_function_callback cb, - /* Client context to pass to the callback */ - uint32_t client - ); - -/* Summary - This function is used to read a Tuple from the SDIO CIS area. - - Description - This function is used to read a Tuple from the SDIO CIS area. - This function is to be used only for IO to an SDIO card as - other media will not respond to the SDIO command set. - - * Valid in Asynchronous Callback: NO - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_SUCCESS - the media information was returned - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device - * is in suspend mode - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not - * exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device - * pair does not exist - * CY_AS_ERROR_ASYNC_PENDING - an async operation is pending - * CY_AS_ERROR_INVALID_REQUEST - an invalid IO request - * type was made - * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * received from the firmware - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in - * reading from the media - * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made to - * an invalid function - * CY_AS_ERROR_INVALID_ENDPOINT - A DMA request was made to - * an invalid endpoint - * CY_AS_ERROR_ENDPOINT_DISABLED - A DMA request was made to - * a disabled endpoint - -*/ -cy_as_return_status_t -cy_as_sdio_get_c_i_s_info( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* IO function Number */ - uint8_t n_function_no, - /* Id of tuple to be fetched */ - uint16_t tuple_id, - /* Buffer to hold tuple read from card. - should be at least 256 bytes in size */ - uint8_t *data_p - ); - - -/* Summary - This function is used to read properties of the SDIO card. - - Description - This function is used to read properties of the SDIO card - into a CyAsSDIOCard structure. - This function is to be used only for IO to an SDIO card as - other media will not respond to the SDIO command set. - - * Valid in Asynchronous Callback: NO - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been - * started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_SUCCESS - the card information was returned - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in - * suspend mode - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not - * exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device - * pair does not exist - * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * received from the firmware - -*/ -cy_as_return_status_t -cy_as_sdio_query_card( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* Buffer to store card properties */ - cy_as_sdio_card *data_p - ); - -/* Summary - This function is used to reset a SDIO card. - - Description - This function is used to reset a SDIO card by writing to - the reset bit in the CCCR and reinitializing the card. This - function is to be used only for IO to an SDIO card as - other media will not respond to the SDIO command set. - - * Valid in Asynchronous Callback: NO - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in - * suspend mode - * CY_AS_ERROR_SUCCESS - the media information was returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not - * exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device - * pair does not exist - * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * received from the firmware - */ -cy_as_return_status_t -cy_as_sdio_reset_card( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device - ); - -/* Summary - This function performs a Synchronous 1 byte read from the sdio - device function. - - Description - This function is used to perform a synchronous 1 byte read - from an SDIO card function. This function is to be used only - for IO to an SDIO card as other media will not respond to the - SDIO command set. - - * Valid in Asynchronous Callback: NO - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed - * in - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in - * suspend mode - * CY_AS_ERROR_SUCCESS - the media information was returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device pair - * does not exist - * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was received - * from the firmware - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in reading - * from the media - * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made to an - * invalid function - * CY_AS_ERROR_FUNCTION_SUSPENDED - The function to which read - * was attempted is in suspend -*/ -cy_as_return_status_t -cy_as_sdio_direct_read( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* IO function Number */ - uint8_t n_function_no, - /* Address for IO */ - uint32_t address, - /* Set to CY_SDIO_REARM_INT to reinitialize SDIO interrupt */ - uint8_t misc_buf, - /* Buffer to hold byte read from card */ - uint8_t *data_p - ); - -/* Summary - This function performs a Synchronous 1 byte write to the - sdio device function. - - Description - This function is used to perform a synchronous 1 byte write - to an SDIO card function. - This function is to be used only for IO to an SDIO card as - other media will not respond to the SDIO command set. - - * Valid in Asynchronous Callback: NO - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been - * started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in - * suspend mode - * CY_AS_ERROR_SUCCESS - the media information was returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device - * pair does not exist - * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was received - * from the firmware - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in - * reading from the media - * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made to - * an invalid function - * CY_AS_ERROR_FUNCTION_SUSPENDED - The function to which - * write was attempted is in suspend -*/ -cy_as_return_status_t -cy_as_sdio_direct_write( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* IO function Number */ - uint8_t n_function_no, - /* Address for IO */ - uint32_t address, - /* Set to CY_SDIO_REARM_INT to reinitialize SDIO interrupt, - set to CY_SDIO_RAW for read after write */ - uint8_t misc_buf, - /* Byte to write */ - uint16_t argument, - /* Buffer to hold byte read from card in Read after write mode */ - uint8_t *data_p - ); - -/* Summary - This function is used to set the blocksize of an SDIO function. - - Description - This function is used to set the blocksize of an SDIO function. - This function is to be used only for IO to an SDIO card as - other media will not respond to the SDIO command set. - - * Valid in Asynchronous Callback: NO - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in - * suspend mode - * CY_AS_ERROR_SUCCESS - the media information was - * returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not - * exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device - * pair does not exist - * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory - * available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * received from the firmware - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in - * reading from the media - * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made - * to an invalid function - * CY_AS_ERROR_INVALID_BLOCKSIZE - An incorrect blocksize - * was passed to the function. - * CY_AS_ERROR_FUNCTION_SUSPENDED - The function to which - * write was attempted is in suspend -*/ -cy_as_return_status_t -cy_as_sdio_set_blocksize( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* IO function Number */ - uint8_t n_function_no, - /* Block size to set. */ - uint16_t blocksize - ); - -/* Summary - This function is used to read Multibyte/Block data from a - IO function. - - Description - This function is used to read Multibyte/Block data from a - IO function. This function is to be used only for IO to an - SDIO card as other media will not respond to the SDIO - command set. - - * Valid in Asynchronous Callback: YES - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in - * suspend mode - * CY_AS_ERROR_SUCCESS - the media information was returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device - * pair does not exist - * CY_AS_ERROR_ASYNC_PENDING - an async operation is pending - * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was received - * from the firmware - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in - * reading from the media - * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made to - * an invalid function - * CY_AS_ERROR_INVALID_BLOCKSIZE - An incorrect blocksize or - * block count was passed to the function. - * CY_AS_ERROR_FUNCTION_SUSPENDED - The function to which - * write was attempted is in suspend - * CY_AS_ERROR_IO_ABORTED - The IO operation was aborted - * CY_AS_ERROR_IO_SUSPENDED - The IO operation was suspended - * CY_AS_ERROR_INVALID_REQUEST - An invalid request was - * passed to the card. - -*/ -cy_as_return_status_t -cy_as_sdio_extended_read( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* IO function Number */ - uint8_t n_function_no, - /* Base Address for IO */ - uint32_t address, - /* Set to CY_SDIO_BLOCKMODE for block IO, - CY_SDIO_BYTEMODE for multibyte IO, - CY_SDIO_OP_FIFO to read multiple bytes from the - same address, CY_SDIO_OP_INCR to read bytes from - the incrementing addresses */ - uint8_t misc_buf, - /* Block/Byte count to read */ - uint16_t argument, - /* Buffer to hold data read from card */ - uint8_t *data_p, - /* Callback in case of Asyncronous call. 0 if Synchronous */ - cy_as_sdio_callback callback - ); - -/* Summary - This function is used to write Multibyte/Block data - to a IO function. - - Description - This function is used to write Multibyte/Block data - to a IO function. This function is to be used only - for IO to an SDIO card as other media will not respond - to the SDIO command set. - - * Valid in Asynchronous Callback: YES - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in - * suspend mode - * CY_AS_ERROR_SUCCESS - the media information was returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not - * exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device - * pair does not exist - * CY_AS_ERROR_ASYNC_PENDING - an async operation is pending - * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * received from the firmware - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in - * reading from the media - * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made - * to an invalid function - * CY_AS_ERROR_INVALID_BLOCKSIZE - An incorrect blocksize or - * block count was passed to the function. - * CY_AS_ERROR_FUNCTION_SUSPENDED - The function to which - * write was attempted is in suspend - * CY_AS_ERROR_IO_ABORTED - The IO operation was aborted - * CY_AS_ERROR_IO_SUSPENDED - The IO operation was suspended - * CY_AS_ERROR_INVALID_REQUEST - An invalid request was - * passed to the card. -*/ -cy_as_return_status_t -cy_as_sdio_extended_write( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* IO function Number */ - uint8_t n_function_no, - /* Base Address for IO */ - uint32_t address, - /* Set to CY_SDIO_BLOCKMODE for block IO, - CY_SDIO_BYTEMODE for multibyte IO, - CY_SDIO_OP_FIFO to write multiple bytes to the same address, - CY_SDIO_OP_INCR to write multiple bytes to incrementing - addresses */ - uint8_t misc_buf, - /* Block/Byte count to write - in case of byte mode the count should not exceed the block size - or 512, whichever is smaller. - in case of block mode, maximum number of blocks is 511. */ - uint16_t argument, - /* Buffer to hold data to be written to card. */ - uint8_t *data_p, - /* Callback in case of Asyncronous call. 0 if Synchronous */ - cy_as_sdio_callback callback - ); - -/* Summary - This function is used to initialize a SDIO card function. - - Description - This function is used to initialize a SDIO card function - (1 - 7). This function is to be used only for IO to an - SDIO card as other media will not respond to the SDIO - command set. - - * Valid in Asynchronous Callback: NO - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been - * started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed - * in - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in - * suspend mode - * CY_AS_ERROR_SUCCESS - the media information was returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device - * pair does not exist - * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * received from the firmware - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error in - * reading from the media - * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made - * to an invalid function -*/ -cy_as_return_status_t -cy_as_sdio_init_function( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* IO function Number */ - uint8_t n_function_no, - /* Set to CY_SDIO_FORCE_INIT to reinitialize function */ - uint8_t misc_buf - ); - -/* Summary - This function is used to get properties of a SDIO card function. - - Description - This function is used to get properties of a SDIO card functio - (1 - 7) into a CyAsSDIOFunc structure. This function is to be - used only for IO to an SDIO card as other media will not respond - to the SDIO command set. - - * Valid in Asynchronous Callback: NO - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not been - * started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was passed - * in - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in - * suspend mode - * CY_AS_ERROR_SUCCESS - the media information was returned - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the media specified does - * not exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device pair - * does not exist - * CY_AS_ERROR_INVALID_FUNCTION - An IO request was made to - * an invalid function -*/ -cy_as_return_status_t -cy_as_sdio_query_function( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* IO function Number */ - uint8_t n_function_no, - /* Buffer to store function properties */ - cy_as_sdio_func *data_p - ); - -/* Summary - This function is used to Abort the current IO function. - - Description - This function is used to Abort the current IO function. - This function is to be used only for IO to an SDIO card as - other media will not respond to the SDIO command set. - - * Valid in Asynchronous Callback: NO - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in - * suspend mode - * CY_AS_ERROR_SUCCESS - the media information was - * returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not - * exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified - * media/device pair does not exist - * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory - * available - * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made - * to an invalid function -*/ -cy_as_return_status_t -cy_as_sdio_abort_function( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* IO function Number */ - uint8_t n_function_no - ); - -/* Summary - This function is used to Disable IO to an SDIO function. - - Description - This function is used to Disable IO to an SDIO function. - This function is to be used only for IO to an SDIO card as - other media will not respond to the SDIO command set. - - * Valid in Asynchronous Callback: NO - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is - * in suspend mode - * CY_AS_ERROR_SUCCESS - the media information was - * returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not - * exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified media/device - * pair does not exist - * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made - * to an invalid function -*/ -cy_as_return_status_t -cy_as_sdio_de_init_function( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* IO function Number */ - uint8_t n_function_no - ); - -/* Summary - This function is used to Suspend the current IO function. - - Description - This function is used to Suspend the current IO function. - This function is to be used only for IO to an SDIO card as - other media will not respond to the SDIO command set. - - * Valid in Asynchronous Callback: NO - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has - * not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is in - * suspend mode - * CY_AS_ERROR_SUCCESS - the media information was returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified does not - * exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified - * media/device pair does not exist - * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory - * available - * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was made - * to an invalid function -*/ -cy_as_return_status_t -cy_as_sdio_suspend( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* IO function Number */ - uint8_t n_function_no - ); - -/* Summary - This function is used to resume a Suspended IO function. - - Description - This function is used to resume a Suspended IO function. - This function is to be used only for IO to an SDIO card as - other media will not respond to the SDIO command set. - - * Valid in Asynchronous Callback: NO - * Valid on Antioch device: NO - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device - * has not been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been - * loaded into West Bridge - * CY_AS_ERROR_NOT_RUNNING - the storage stack has not - * been started - * CY_AS_ERROR_INVALID_HANDLE - an invalid handle was - * passed in - * CY_AS_ERROR_IN_SUSPEND - the West Bridge device is - * in suspend mode - * CY_AS_ERROR_SUCCESS - the media information was - * returned - * CY_AS_ERROR_TIMEOUT - a timeout occurred - * communicating with the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the stack is not running - * CY_AS_ERROR_NO_SUCH_BUS - the bus specified - * does not exist - * CY_AS_ERROR_NO_SUCH_DEVICE - the specified - * media/device pair does not exist - * CY_AS_ERROR_ASYNC_PENDING - an async operation - * is pending - * CY_AS_ERROR_OUT_OF_MEMORY - insufficient memory - * available - * CY_AS_ERROR_INVALID_RESPONSE - an error message was - * received from the firmware - * CY_AS_ERROR_MEDIA_ACCESS_FAILURE - there was error - * in reading from the media - * CY_AS_ERROR_INVALID_FUNCTION - An IO attempt was - * made to an invalid function - * CY_AS_ERROR_IO_ABORTED - The IO operation was - * aborted - * CY_AS_ERROR_IO_SUSPENDED - The IO operation was - * suspended - * CY_AS_ERROR_INVALID_REQUEST - An invalid request was - * passed to the card. - -*/ -cy_as_return_status_t -cy_as_sdio_resume( - /* Handle to the Westbridge device */ - cy_as_device_handle handle, - /* Bus to use */ - cy_as_bus_number_t bus, - /* Device number */ - uint32_t device, - /* IO function Number */ - uint8_t n_function_no, - /* Operation to resume (Read or Write) */ - cy_as_oper_type op, - /* Micellaneous buffer same as for Extended read and Write */ - uint8_t misc_buf, - /* Number of pending blocks for IO. Should be less - than or equal to the maximum defined for extended - read and write */ - uint16_t pendingblockcount, - /* Buffer to continue the Suspended IO operation */ - uint8_t *data_p - ); - - - -/* For supporting deprecated functions */ -#include "cyasstorage_dep.h" - -#include "cyas_cplus_end.h" - -#endif /* _INCLUDED_CYASSTORAGE_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage_dep.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage_dep.h deleted file mode 100644 index 566b244bd8c5..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasstorage_dep.h +++ /dev/null @@ -1,309 +0,0 @@ -/* Cypress West Bridge API header file (cyanstorage_dep.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -/* This header will contain Antioch specific declaration - * of the APIs that are deprecated in Astoria SDK. This is - * for maintaining backward compatibility - */ -#ifndef __INCLUDED_CYANSTORAGE_DEP_H__ -#define __INCLUDED_CYANSTORAGE_DEP_H__ - -#ifndef __doxygen__ - -typedef void (*cy_as_storage_callback_dep)( -/* Handle to the device completing the storage operation */ - cy_as_device_handle handle, - /* The media type completing the operation */ - cy_as_media_type type, - /* The device completing the operation */ - uint32_t device, - /* The unit completing the operation */ - uint32_t unit, - /* The block number of the completed operation */ - uint32_t block_number, - /* The type of operation */ - cy_as_oper_type op, - /* The error status */ - cy_as_return_status_t status - ); - -typedef void (*cy_as_storage_event_callback_dep)( - /* Handle to the device sending the event notification */ - cy_as_device_handle handle, - /* The media type */ - cy_as_media_type type, - /* The event type */ - cy_as_storage_event evtype, - /* Event related data */ - void *evdata - ); - -typedef struct cy_as_storage_query_device_data_dep { - /* The type of media to query */ - cy_as_media_type type; - /* The logical device number to query */ - uint32_t device; - /* The return value for the device descriptor */ - cy_as_device_desc desc_p; -} cy_as_storage_query_device_data_dep; - -typedef struct cy_as_storage_query_unit_data_dep { - /* The type of media to query */ - cy_as_media_type type; - /* The logical device number to query */ - uint32_t device; - /* The unit to query on the device */ - uint32_t unit; - /* The return value for the unit descriptor */ - cy_as_unit_desc desc_p; -} cy_as_storage_query_unit_data_dep; - - -/************ FUNCTIONS *********************/ - -EXTERN cy_as_return_status_t -cy_as_storage_register_callback_dep( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The callback function to call for async storage events */ - cy_as_storage_event_callback_dep callback - ); - -EXTERN cy_as_return_status_t -cy_as_storage_claim_dep(cy_as_device_handle handle, - cy_as_media_type type - ); - -EXTERN cy_as_return_status_t -cy_as_storage_claim_dep_EX( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The type of media to claim */ - cy_as_media_type *type, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -EXTERN cy_as_return_status_t -cy_as_storage_release_dep(cy_as_device_handle handle, - cy_as_media_type type - ); - -EXTERN cy_as_return_status_t -cy_as_storage_release_dep_EX( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* Handle to the device of interest */ - cy_as_media_type *type, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -EXTERN cy_as_return_status_t -cy_as_storage_query_device_dep( - cy_as_device_handle handle, - cy_as_media_type media, - uint32_t device, - cy_as_device_desc *desc_p - ); - -EXTERN cy_as_return_status_t -cy_as_storage_query_device_dep_EX( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* Parameters and return value for the query call */ - cy_as_storage_query_device_data_dep *data, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -EXTERN cy_as_return_status_t -cy_as_storage_query_unit_dep( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The type of media to query */ - cy_as_media_type type, - /* The logical device number to query */ - uint32_t device, - /* The unit to query on the device */ - uint32_t unit, - /* The return value for the unit descriptor */ - cy_as_unit_desc *unit_p - ); - -EXTERN cy_as_return_status_t -cy_as_storage_query_unit_dep_EX( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* Parameters and return value for the query call */ - cy_as_storage_query_unit_data_dep *data_p, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - -EXTERN cy_as_return_status_t -cy_as_storage_device_control_dep( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* Enable/disable control for card detection */ - cy_bool card_detect_en, - /* Enable/disable control for write protect handling */ - cy_bool write_prot_en, - /* Callback to be called when the operation is complete */ - cy_as_function_callback cb, - /* Client data to be passed to the callback */ - uint32_t client - ); - - -EXTERN cy_as_return_status_t -cy_as_storage_read_dep( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The type of media to access */ - cy_as_media_type type, - /* The device to access */ - uint32_t device, - /* The unit to access */ - uint32_t unit, - /* The first block to access */ - uint32_t block, - /* The buffer where data will be placed */ - void *data_p, - /* The number of blocks to be read */ - uint16_t num_blocks - ); - -EXTERN cy_as_return_status_t -cy_as_storage_read_async_dep( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The type of media to access */ - cy_as_media_type type, - /* The device to access */ - uint32_t device, - /* The unit to access */ - uint32_t unit, - /* The first block to access */ - uint32_t block, - /* The buffer where data will be placed */ - void *data_p, - /* The number of blocks to be read */ - uint16_t num_blocks, - /* The function to call when the read is complete - or an error occurs */ - cy_as_storage_callback_dep callback - ); -EXTERN cy_as_return_status_t -cy_as_storage_write_dep( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The type of media to access */ - cy_as_media_type type, - /* The device to access */ - uint32_t device, - /* The unit to access */ - uint32_t unit, - /* The first block to access */ - uint32_t block, - /* The buffer containing the data to be written */ - void *data_p, - /* The number of blocks to be written */ - uint16_t num_blocks - ); - -EXTERN cy_as_return_status_t -cy_as_storage_write_async_dep( - /* Handle to the device of interest */ - cy_as_device_handle handle, - /* The type of media to access */ - cy_as_media_type type, - /* The device to access */ - uint32_t device, - /* The unit to access */ - uint32_t unit, - /* The first block to access */ - uint32_t block, - /* The buffer where the data to be written is stored */ - void *data_p, - /* The number of blocks to be written */ - uint16_t num_blocks, - /* The function to call when the write is complete - or an error occurs */ - cy_as_storage_callback_dep callback - ); - -EXTERN cy_as_return_status_t -cy_as_storage_sd_register_read_dep( - cy_as_device_handle handle, - cy_as_media_type type, - uint8_t device, - cy_as_sd_card_reg_type reg_type, - uint8_t read_len, - uint8_t *data_p - ); - -EXTERN cy_as_return_status_t -cy_as_storage_sd_register_read_dep_EX( - /* Handle to the West Bridge device. */ - cy_as_device_handle handle, - /* The type of media to query */ - cy_as_media_type type, - /* The device to query */ - uint8_t device, - /* The type of register to read. */ - cy_as_sd_card_reg_type reg_type, - /* Output data buffer and length. */ - cy_as_storage_sd_reg_read_data *data_p, - /* Callback function to call when done. */ - cy_as_function_callback cb, - /* Call context to send to the cb function. */ - uint32_t client - ); - -EXTERN cy_as_return_status_t -cy_as_storage_create_p_partition_dep( - cy_as_device_handle handle, - cy_as_media_type media, - uint32_t device, - uint32_t size, - cy_as_function_callback cb, - uint32_t client); - -EXTERN cy_as_return_status_t -cy_as_storage_remove_p_partition_dep( - cy_as_device_handle handle, - cy_as_media_type media, - uint32_t device, - cy_as_function_callback cb, - uint32_t client); - -#endif /*__doxygen*/ - -#endif /*__INCLUDED_CYANSTORAGE_DEP_H__*/ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastoria.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastoria.h deleted file mode 100644 index b1b18d0685e4..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastoria.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Cypress West Bridge API header file (cyastioch.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASTORIA_H_ -#define _INCLUDED_CYASTORIA_H_ - -#if !defined(__doxygen__) - -#include "cyaserr.h" -#include "cyasmisc.h" -#include "cyasstorage.h" -#include "cyasusb.h" -#include "cyasmtp.h" - -#endif - -#endif - diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastsdkversion.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastsdkversion.h deleted file mode 100644 index a3c10aa559e2..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastsdkversion.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Cypress Astoria Sdk Version file (cyastsdkversion.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street, Fifth Floor -## Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASTSDK_VERSION_H_ -#define _INCLUDED_CYASTSDK_VERSION_H_ - -/* Astoria SDK version 1.2.1 */ -#define CYAS_MAJOR_VERSION (1) -#define CYAS_MINOR_VERSION (2) -#define CYAS_BUILD_NUMBER (197) - -#endif /*_INCLUDED_CYASTSDK_VERSION_H_*/ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastypes.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastypes.h deleted file mode 100644 index 18043c1f38da..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyastypes.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Cypress West Bridge API header file (cyastypes.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASTYPES_H_ -#define _INCLUDED_CYASTYPES_H_ -/* moved to staging location, eventual implementation - * considered is here -#include -*/ - #include "../../../arch/arm/plat-omap/include/mach/westbridge/cyashaldef.h" - -/* Types that are not available on specific platforms. - * These are used only in the reference HAL implementations and - * are not required for using the API. - */ -#ifdef __unix__ -typedef unsigned long DWORD; -typedef void *LPVOID; -#define WINAPI -#define INFINITE (0xFFFFFFFF) -#define ptr_to_uint(ptr) ((unsigned int)(ptr)) -#endif - -/* Basic types used by the entire API */ - -/* Summary - This type represents an endpoint number -*/ -typedef uint8_t cy_as_end_point_number_t; - -/* Summary - This type is used to return status information from - an API call. -*/ -typedef uint16_t cy_as_return_status_t; - -/* Summary - This type represents a bus number -*/ -typedef uint32_t cy_as_bus_number_t; - -/* Summary - All APIs provided with this release are marked extern - through this definition. This definition can be changed - to meet the scope changes required in the user build - environment. - - For example, this can be changed to __declspec(exportdll) - to enable exporting the API from a DLL. - */ -#define EXTERN extern - -#endif diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h deleted file mode 100644 index e3ba9ca4c75f..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb.h +++ /dev/null @@ -1,1862 +0,0 @@ -/* Cypress West Bridge API header file (cyasusb.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -#ifndef _INCLUDED_CYASUSB_H_ -#define _INCLUDED_CYASUSB_H_ - -#include "cyasmisc.h" - -#include "cyas_cplus_start.h" - -/*@@Enumeration Model - Summary - The USB enumeration process is the process of communicating - to the USB host information - about the capabilities of the connected device. This - process is completed by servicing - requests for various types of descriptors. In the software - APIs described below, this - process is controlled in one of two ways. - - Description - There are advantages to either type of enumeration - and this is why both models are supported. - P Port processor based enumeraton gives the P port - processor maximum control and flexibility - for providing USB configuration information. However, - this does require (near) real time data - responses from the P port processor during the enumeration - process. West Bridge based enumeration - requires no real time information from the P port processor, - ensuring the fastest possible - enumeration times. - - * P Port Based Enumeration * - The first method for handling USB enumeration is for the - processor client to handle all - endpoint zero requests for descriptors. This mode is - configured by indicating to the API - that the processor wants to handle all endpoint zero - requests. This is done by setting - bit 0 in the end_point_mask to a 1. The processor uses - CyAsUsbReadDataAsync() to read the request and - CyAsUsbWriteDataAsync() to write the response. - - * West Bridge Based Enumeration * - The second method for handling USB enumeration is the - configuration information method. - Before enabling a connection from the West Bridge device - to the USB connector, the P Port - processor sends information about the USB configuration to - West Bridge through the configuration - APIs. This information is stored within the West Bridge - device. When a USB cable is attached, - the West Bridge device then handles all descriptor requests - based on the stored information. - Note that this method of enumeration only supports a single - USB configuration. - - In either model of enumeration, the processor client is - responsible for ensuring that - the system meets USB Chapter 9 compliance requirements. This - can be done by providing spec - compliant descriptors, and handling any setup packets that - are sent to the client - appropriately. - - Mass storage class compliance will be ensured by the West - Bridge firmware when the mass - storage functionality is enabled. -*/ - -/*@@Endpoint Configuration - Summary - The West Bridge device has one 64-byte control endpoint, one - 64-byte low bandwidth endpoint, four bulk - endpoints dedicated for mass storage usage, and up to ten - bulk/interrupt/isochronous - endpoints that can be used for USB-to-Processor communication. - - Description - The four storage endpoints (Endpoints 2, 4, 6 and 8) are - reserved for accessing storage - devices attached to West Bridge and are not available for use - by the processor. These are - used implicitly when using the storage API to read/write to - the storage media. - - Endpoint 0 is the standard USB control pipe used for all - enumeration activity. Though - the endpoint buffer is not directly accessible from the - processor, read/write activity - can be performed on this endpoint through the API layers. - This endpoint is always - configured as a bi-directional control endpoint. - - Endpoint 1 is a 64-byte endpoint that can be used for low - bandwidth bulk/interrupt - activity. The physical buffer is not accessible from the - processor, but can be read/written - through the API. As the data coming to this endpoint is - being handled through the - software layers, there can be loss of data if a read call - is not waiting when an OUT - packet arrives. - - Endpoints 3, 5, 7, 9, 10, 11, 12, 13, 14 and 15 are ten - configurable endpoints - mapped to parts of a total 4 KB FIFO buffer space on the - West Bridge device. This 4 KB - physical buffer space is divided into up to four endpoints - called PEP1, PEP2, PEP3 and PEP4 - in this software document. There are multiple configurations - in which this buffer space - can be used, and the size and number of buffers available to - each physical endpoint - vary between these configurations. See the West Bridge PDD - for details on the buffer - orientation corresponding to each configuration. - - * Note * - PEPs 1, 2, 3 and 4 are called Physical EP 3, 5, 7 and 9 in the - West Bridge PDD. The - sequential number scheme is used in the software to disambiguate - these from the logical - endpoint numbers, and also for convenience of array indexing. -*/ - -#if !defined(__doxygen__) - - -#endif - -/* Summary - This constants defines the maximum size of a USB descriptor - when referenced via the CyAsUsbSetDescriptor or - CyAsUsbGetDescriptor functions. - - See Also - * CyAsUsbSetDescriptor - * CyAsUsbGetDescriptor -*/ -#define CY_AS_MAX_USB_DESCRIPTOR_SIZE (128) - -/*************************************** - * West Bridge Types - ***************************************/ - - -/* Summary - This data structure is the data passed via the evdata paramater - on a usb event callback for the inquiry request. - - Description - When a SCSI inquiry request arrives via the USB connection and - the P Port has asked - to receive inquiry requests, this request is forwarded to the - client via the USB - callback. This callback is called twice, once before the - inquiry data is forwarded - to the host (CyAsEventUsbInquiryBefore) and once after the - inquiry has been sent to the - USB host (CyAsEventUsbInquiryAfter). The evdata parameter - is a pointer to this data - structure. - - *CyAsEventUsbInquiryBefore* - If the client just wishes to see the inquiry request and - associated data, then a simple - return from the callback will forward the inquiry response - to the USB host. If the - client wishes to change the data returned to the USB host, - the updated parameter must - be set to CyTrue and the memory area address by the data - parameter should be updated. - The data pointer can be changed to point to a new memory - area and the length field - changed to change the amount of data returned from the - inquiry request. Note that the - data area pointed to by the data parameter must remain - valid and the contents must - remain consistent until after the CyAsEventUsbInquiryAfter - event has occurred. THE LENGTH - MUST BE LESS THAN 192 BYTES OR THE CUSTOM INQUIRY RESPONSE - WILL NOT BE RETURNED. If the - length is too long, the default inquiry response will be - returned. - - *CyAsEventUsbInquiryAfter* - If the client needs to free any data, this event signals that - the data associated with the inquiry is no longer needed. - - See Also - * CyAsUsbEventCallback - * CyAsUsbRegisterCallback -*/ -typedef struct cy_as_usb_inquiry_data { - /* The bus for the event */ - cy_as_bus_number_t bus; - /* The device the event */ - uint32_t device; - /* The EVPD bit from the SCSI INQUIRY request */ - uint8_t evpd; - /* The codepage in the inquiry request */ - uint8_t codepage; - /* This bool must be set to CyTrue indicate that the inquiry - data was changed */ - cy_bool updated; - /* The length of the data */ - uint16_t length; - /* The inquiry data */ - void *data; -} cy_as_usb_inquiry_data; - - -/* Summary - This data structure is the data passed via the evdata - parameter on a usb event - callback for the unknown mass storage request. - - Description - When a SCSI request is made that the mass storage - firmware in West Bridge does not - know how to process, this request is passed to the - processor for handling via - the usb callback. This data structure is used to - pass the request and the - associated response. The user may set the status - to indicate the status of the - request. The status value is the bCSWStatus value - from the USB mass storage - Command Status Wrapper (0 = command passed, 1 = - command failed). If the status - is set to command failed (1), the sense information - should be set as well. For - more information about sense information, see the - USB mass storage specification - as well as the SCSI specifications for block devices. - By default the status is - initialized to 1 (failure) with a sense information - of 05h/20h/00h which - indicates INVALID COMMAND. -*/ -typedef struct cy_as_usb_unknown_command_data { - /* The bus for the event */ - cy_as_bus_number_t bus; - /* The device for the event */ - uint32_t device; - - uint16_t reqlen; - /* The request */ - void *request; - - /* The returned status value for the command */ - uint8_t status; - /* If status is failed, the sense key */ - uint8_t key; - /* If status is failed, the additional sense code */ - uint8_t asc; - /* If status if failed, the additional sense code qualifier */ - uint8_t ascq; -} cy_as_usb_unknown_command_data; - - -/* Summary - This data structure is the data passed via the evdata - paramater on a usb event callback for the start/stop request. - - Description - When a SCSI start stop request arrives via the USB connection - and the P Port has asked - - See Also - * CyAsUsbEventCallback - * CyAsUsbRegisterCallback -*/ -typedef struct cy_as_usb_start_stop_data { - /* The bus for the event */ - cy_as_bus_number_t bus; - /* The device for the event */ - uint32_t device; - /* CyTrue means start request, CyFalse means stop request */ - cy_bool start; - /* CyTrue means LoEj bit set, otherwise false */ - cy_bool loej; -} cy_as_usb_start_stop_data; - -/* Summary - This data type is used to indicate which mass storage devices - are enumerated. - - Description - - See Also - * CyAsUsbEnumControl - * CyAsUsbSetEnumConfig -*/ -typedef enum cy_as_usb_mass_storage_enum { - cy_as_usb_nand_enum = 0x01, - cy_as_usb_sd_enum = 0x02, - cy_as_usb_mmc_enum = 0x04, - cy_as_usb_ce_ata_enum = 0x08 -} cy_as_usb_mass_storage_enum; - -/* Summary - This data type specifies the type of descriptor to transfer - to the West Bridge device - - Description - During enumeration, if West Bridge is handling enumeration, - the West Bridge device needs to USB descriptors - to complete the enumeration. The function CyAsUsbSetDescriptor() - is used to transfer the descriptors - to the West Bridge device. This type is an argument to that - function and specifies which descriptor - is being transferred. - - See Also - * CyAsUsbSetDescriptor - * CyAsUsbGetDescriptor -*/ -typedef enum cy_as_usb_desc_type { - /* A device descriptor - See USB 2.0 specification Chapter 9 */ - cy_as_usb_desc_device = 1, - /* A device descriptor qualifier - - * See USB 2.0 specification Chapter 9 */ - cy_as_usb_desc_device_qual = 2, - /* A configuration descriptor for FS operation - - * See USB 2.0 specification Chapter 9 */ - cy_as_usb_desc_f_s_configuration = 3, - /* A configuration descriptor for HS operation - - * See USB 2.0 specification Chapter 9 */ - cy_as_usb_desc_h_s_configuration = 4, - cy_as_usb_desc_string = 5 -} cy_as_usb_desc_type; - -/* Summary - This type specifies the direction of an endpoint - - Description - This type is used when configuring the endpoint hardware - to specify the direction - of the endpoint. - - See Also - * CyAsUsbEndPointConfig - * CyAsUsbSetEndPointConfig - * CyAsUsbGetEndPointConfig -*/ -typedef enum cy_as_usb_end_point_dir { - /* The endpoint direction is IN (West Bridge -> USB Host) */ - cy_as_usb_in = 0, - /* The endpoint direction is OUT (USB Host -> West Bridge) */ - cy_as_usb_out = 1, - /* The endpoint direction is IN/OUT (valid only for EP 0 & 1) */ - cy_as_usb_in_out = 2 -} cy_as_usb_end_point_dir; - -/* Summary - This type specifies the type of an endpoint - - Description - This type is used when configuring the endpoint hardware - to specify the type of endpoint. - - See Also - * CyAsUsbEndPointConfig - * CyAsUsbSetEndPointConfig - * CyAsUsbGetEndPointConfig -*/ -typedef enum cy_as_usb_end_point_type { - cy_as_usb_control, - cy_as_usb_iso, - cy_as_usb_bulk, - cy_as_usb_int -} cy_as_usb_end_point_type; - -/* Summary - This type is a structure used to indicate the top level - configuration of the USB stack - - Description - In order to configure the USB stack, the CyAsUsbSetEnumConfig() - function is called to indicate - how mass storage is to be handled, the specific number of - interfaces to be supported if - West Bridge is handling enumeration, and the end points of - specifi interest. This structure - contains this information. - - See Also - * CyAsUsbSetConfig - * CyAsUsbGetConfig - * -*/ -typedef struct cy_as_usb_enum_control { - /* Designate which devices on which buses to enumerate */ - cy_bool devices_to_enumerate[CY_AS_MAX_BUSES] - [CY_AS_MAX_STORAGE_DEVICES]; - /* If true, West Bridge will control enumeration. If this - * is false the P port controls enumeration. if the P port - * is controlling enumeration, traffic will be received via - * endpoint zero. */ - cy_bool antioch_enumeration; - /* This is the interface # to use for the mass storage - * interface, if mass storage is enumerated. if mass - * storage is not enumerated this value should be zero. */ - uint8_t mass_storage_interface; - /* This is the interface # to use for the MTP interface, - * if MTP is enumerated. if MTP is not enumerated - * this value should be zero. */ - uint8_t mtp_interface; - /* If true, Inquiry, START/STOP, and unknown mass storage - * requests cause a callback to occur for handling by the - * baseband processor. */ - cy_bool mass_storage_callbacks; -} cy_as_usb_enum_control; - - -/* Summary - This structure is used to configure a single endpoint - - Description - This data structure contains all of the information required - to configure the West Bridge hardware - associated with a given endpoint. - - See Also - * CyAsUsbSetEndPointConfig - * CyAsUsbGetEndPointConfig -*/ -typedef struct cy_as_usb_end_point_config { - /* If true, this endpoint is enabled */ - cy_bool enabled; - /* The direction of this endpoint */ - cy_as_usb_end_point_dir dir; - /* The type of endpoint */ - cy_as_usb_end_point_type type; - /* The physical endpoint #, 1, 2, 3, 4 */ - cy_as_end_point_number_t physical; - /* The size of the endpoint in bytes */ - uint16_t size; -} cy_as_usb_end_point_config; - -/* Summary - List of partition enumeration combinations that can - be selected on a partitioned storage device. - - Description - West Bridge firmware supports creating up to two - partitions on mass storage devices connected to - West Bridge. When there are two partitions on a device, - the user can choose which of these partitions should be - made visible to a USB host through the mass storage - interface. This enumeration lists the various enumeration - selections that can be made. - - See Also - * CyAsStorageCreatePPartition - * CyAsStorageRemovePPartition - * CyAsUsbSelectMSPartitions - */ -typedef enum cy_as_usb_m_s_type_t { - /* Enumerate only partition 0 as CD (autorun) device */ - cy_as_usb_m_s_unit0 = 0, - /* Enumerate only partition 1 as MS device (default setting) */ - cy_as_usb_m_s_unit1, - /* Enumerate both units */ - cy_as_usb_m_s_both -} cy_as_usb_m_s_type_t; - -/* Summary - This type specifies the type of USB event that has occurred - - Description - This type is used in the USB event callback function to - indicate the type of USB event that has occurred. The callback - function includes both this reasons for the callback and a data - parameter associated with the reason. The data parameter is used - in a reason specific way and is documented below with each reason. - - See Also - * CyAsUsbIoCallback -*/ -typedef enum cy_as_usb_event { - /* This event is sent when West Bridge is put into the suspend - state by the USB host. the data parameter is not used and - will be zero. */ - cy_as_event_usb_suspend, - /* This event is sent when West Bridge is taken out of the - suspend state by the USB host. the data parameter is not - used and will be zero. */ - cy_as_event_usb_resume, - /* This event is sent when a USB reset request is received - by the west bridge device. the data parameter is not used and - will be zero. */ - cy_as_event_usb_reset, - /* This event is sent when a USB set configuration request is made. - the data parameter is a pointer to a uint16_t that contains the - configuration number. the configuration number may be zero to - indicate an unconfigure operation. */ - cy_as_event_usb_set_config, - /* This event is sent when the USB connection changes speed. This is - generally a transition from full speed to high speed. the parameter - to this event is a pointer to uint16_t that gives the speed of the - USB connection. zero indicates full speed, one indicates high speed */ - cy_as_event_usb_speed_change, - /* This event is sent when a setup packet is received. - * The data parameter is a pointer to the eight bytes of setup data. */ - cy_as_event_usb_setup_packet, - /* This event is sent when a status packet is received. The data - parameter is not used. */ - cy_as_event_usb_status_packet, - /* This event is sent when mass storage receives an inquiry - request and we have asked to see these requests. */ - cy_as_event_usb_inquiry_before, - /* This event is sent when mass storage has finished processing an - inquiry request and any data associated with the request is no longer - required. */ - cy_as_event_usb_inquiry_after, - /* This event is sent when mass storage receives a start/stop - * request and we have asked to see these requests */ - cy_as_event_usb_start_stop, - /* This event is sent when a Clear Feature request is received. - * The data parameter is the endpoint number. */ - cy_as_event_usb_clear_feature, - /* This event is sent when mass storage receives a request - * that is not known and we have asked to see these requests */ - cy_as_event_usb_unknown_storage, - /* This event is sent when the read/write activity on the USB mass - storage has crossed a pre-set level */ - cy_as_event_usb_m_s_c_progress -} cy_as_usb_event; - -/* Summary - This type is the type of a callback function that is - called when a USB event occurs - - Description - At times West Bridge needs to inform the P port processor - of events that have - occurred. These events are asynchronous to the thread of - control on the P - port processor and as such are generally delivered via a - callback function that - is called as part of an interrupt handler. This type - defines the type of function - that must be provided as a callback function for USB events. - - See Also - * CyAsUsbEvent -*/ -typedef void (*cy_as_usb_event_callback)( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* The event type being reported */ - cy_as_usb_event ev, - /* The data assocaited with the event being reported */ - void *evdata -); - - -/* Summary - This type is the callback function called after an - asynchronous USB read/write operation - - Description - This function type defines a callback function that is - called at the completion of any - asynchronous read or write operation. - - See Also - * CyAsUsbReadDataAsync - * CyAsUsbWriteDataAsync - * CY_AS_ERROR_CANCELED -*/ -typedef void (*cy_as_usb_io_callback)( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* The endpoint that has completed an operation */ - cy_as_end_point_number_t ep, - /* THe amount of data transferred to/from USB */ - uint32_t count, - /* The data buffer for the operation */ - void *buffer, - /* The error status of the operation */ - cy_as_return_status_t status -); - -/* Summary - This type is the callback function called after asynchronous - API functions have completed. - - Description - When calling API functions from callback routines (interrupt - handlers usually) the async version of - these functions must be used. This callback is called when an - asynchronous API function has completed. -*/ -typedef void (*cy_as_usb_function_callback)( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* The error status of the operation */ - cy_as_return_status_t status, - /* A client supplied 32 bit tag */ - uint32_t client -); - - -/******************************************** - * West Bridge Functions - ********************************************/ - -/* Summary - This function starts the USB stack - - Description - This function initializes the West Bridge USB software - stack if it has not yet been stared. - This initializes any required data structures and powers - up any USB specific portions of - the West Bridge hardware. If the stack had already been - started, the USB stack reference count - is incremented. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Notes - This function cannot be called from any type of West Bridge - callback. - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_SUCCESS - the stack initialized and is ready - * for use - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating - * with the West Bridge device - - See Also - * CyAsUsbStop -*/ -EXTERN cy_as_return_status_t -cy_as_usb_start( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - This function stops the USB stack - - Description - This function decrements the reference count for - the USB stack and if this count - is zero, the USB stack is shut down. The shutdown - frees all resources associated - with the USB stack. - - * Valid In Asynchronous Callback: NO - - Notes - While all resources associated with the USB stack will - be freed is a shutdown occurs, - resources associated with underlying layers of the software - will not be freed if they - are shared by the storage stack and the storage stack is active. - Specifically the DMA manager, - the interrupt manager, and the West Bridge communications module - are all shared by both the - USB stack and the storage stack. - - Returns - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - - See Also - * CyAsUsbStart -*/ -EXTERN cy_as_return_status_t -cy_as_usb_stop( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - This function registers a callback function to be called when an - asynchronous USB event occurs - - Description - When asynchronous USB events occur, a callback function can be - called to alert the calling program. This - functions allows the calling program to register a callback. - - * Valid In Asynchronous Callback: YES -*/ -EXTERN cy_as_return_status_t -cy_as_usb_register_callback( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The function to call */ - cy_as_usb_event_callback callback - ); - - -/* Summary - This function connects the West Bridge device D+ and D- signals - physically to the USB host. - - Description - The West Bridge device has the ability to programmatically - disconnect the USB pins on the device - from the USB host. This feature allows for re-enumeration of - the West Bridge device as a different - device when necessary. This function connects the D+ and D- - signal physically to the USB host - if they have been previously disconnected. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - - See Also - * CyAsUsbDisconnect -*/ -EXTERN cy_as_return_status_t -cy_as_usb_connect( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - This function disconnects the West Bridge device D+ and D- - signals physically from the USB host. - - Description - The West Bridge device has the ability to programmatically - disconnect the USB pins on the device - from the USB host. This feature allows for re-enumeration - of the West Bridge device as a different - device when necessary. This function disconnects the D+ - and D- signal physically from the USB host - if they have been previously connected. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - - See Also - * CyAsUsbConnect -*/ -EXTERN cy_as_return_status_t -cy_as_usb_disconnect( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - This function configures the USB stack - - Description - This function is used to configure the USB stack. It is - used to indicate which endpoints are going to - be used, and how to deal with the mass storage USB device - within West Bridge. - - * Valid In Asynchronous Callback: Yes (if cb supplied) - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - - See Also - * CyAsUsbGetEnumConfig - * CyAsUsbEnumControl - */ -EXTERN cy_as_return_status_t -cy_as_usb_set_enum_config( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The USB configuration information */ - cy_as_usb_enum_control *config_p, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - This function retreives the current configuration of - the USB stack - - Description - This function sends a request to West Bridge to retrieve - the current configuration - - * Valid In Asynchronous Callback: Yes (if cb supplied) - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - - See Also - * CyAsUsbSetConfig - * CyAsUsbConfig - */ -EXTERN cy_as_return_status_t -cy_as_usb_get_enum_config( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The return value for USB congifuration information */ - cy_as_usb_enum_control *config_p, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - This function sets the USB descriptor - - Description - This function is used to set the various descriptors - assocaited with the USB enumeration - process. This function should only be called when the - West Bridge enumeration model is selected. - Descriptors set using this function can be cleared by - stopping the USB stack, or by calling - the CyAsUsbClearDescriptors function. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Notes - These descriptors are described in the USB 2.0 specification, - Chapter 9. - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_DESCRIPTOR - the descriptor passed is - * not valid - * CY_AS_ERROR_BAD_INDEX - a bad index was given for the type - * of descriptor given - * CY_AS_ERROR_BAD_ENUMERATION_MODE - this function cannot be - * called if the P port processor doing enumeration - - See Also - * CyAsUsbGetDescriptor - * CyAsUsbClearDescriptors - * -*/ -EXTERN cy_as_return_status_t -cy_as_usb_set_descriptor( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The type of descriptor */ - cy_as_usb_desc_type type, - /* Only valid for string descriptors */ - uint8_t index, - /* The descriptor to be transferred */ - void *desc_p, - /* The length of the descriptor in bytes */ - uint16_t length, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - This function clears all user descriptors stored - on the West Bridge. - - Description - This function is used to clear all descriptors that - were previously - stored on the West Bridge through CyAsUsbSetDescriptor - calls, and go back - to the default descriptor setup in the firmware. This - function should - only be called when the Antioch enumeration model is - selected. - - * Valid In Asynchronous Callback: Yes (if cb supplied) - * Nestable: Yes - - Returns - * CY_AS_ERROR_SUCCESS - all descriptors cleared successfully - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_BAD_ENUMERATION_MODE - this function cannot be - * called if the P port processor is doing enumeration - - See Also - * CyAsUsbSetDescriptor - * -*/ -EXTERN cy_as_return_status_t -cy_as_usb_clear_descriptors( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); -/* Summary - This structure contains the descriptor buffer to be - filled by CyAsUsbGetDescriptor API. - - Description - This data structure the buffer to hold the descriptor - data, and an in/out parameter ti indicate the - length of the buffer and descriptor data in bytes. - - See Also - * CyAsUsbGetDescriptor -*/ -typedef struct cy_as_get_descriptor_data { - /* The buffer to hold the returned descriptor */ - void *desc_p; - /* This is an input and output parameter. - * Before the code this pointer points to a uint32_t - * that contains the length of the buffer. after - * the call, this value contains the amount of data - * actually returned. */ - uint32_t length; - -} cy_as_get_descriptor_data; - -/* Summary - This function retreives a given descriptor from the - West Bridge device - - Description - This function retreives a USB descriptor from the West - Bridge device. This function should only be called when the - West Bridge enumeration model is selected. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Notes - These descriptors are described in the USB 2.0 specification, - Chapter 9. - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_BAD_INDEX - a bad index was given for the type of - * descriptor given - * CY_AS_ERROR_BAD_ENUMERATION_MODE - this function cannot be - * called if the P port processor doing enumeration - - See Also - * CyAsUsbSetDescriptor - * -*/ - -EXTERN cy_as_return_status_t -cy_as_usb_get_descriptor( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The type of descriptor */ - cy_as_usb_desc_type type, - /* Index for string descriptor */ - uint8_t index, - /* Parameters and return value for the get descriptor call */ - cy_as_get_descriptor_data *data, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - This function sets the configuration of the physical - endpoints into one of the twelve supported configuration - - Description - USB endpoints are mapped onto one of four physical - endpoints in the device. Therefore - USB endpoints are known as logical endpoints and these - logical endpoints are mapped to - one of four physical endpoints. In support of these - four physical endpoints there is - four kilo-bytes of buffer spaces that can be used as - buffers for these physical endpoints. - This 4K of buffer space can be configured in one of - twelve ways. This function sets the - buffer configuration for the physical endpoints. - - * Config 1: PEP1 (2 * 512), PEP2 (2 * 512), - * PEP3 (2 * 512), PEP4 (2 * 512) - * Config 2: PEP1 (2 * 512), PEP2 (2 * 512), - * PEP3 (4 * 512), PEP4 (N/A) - * Config 3: PEP1 (2 * 512), PEP2 (2 * 512), - * PEP3 (2 * 1024), PEP4(N/A) - * Config 4: PEP1 (4 * 512), PEP2 (N/A), - * PEP3 (2 * 512), PEP4 (2 * 512) - * Config 5: PEP1 (4 * 512), PEP2 (N/A), - * PEP3 (4 * 512), PEP4 (N/A) - * Config 6: PEP1 (4 * 512), PEP2 (N/A), - * PEP3 (2 * 1024), PEP4 (N/A) - * Config 7: PEP1 (2 * 1024), PEP2 (N/A), - * PEP3 (2 * 512), PEP4 (2 * 512) - * Config 8: PEP1 (2 * 1024), PEP2 (N/A), - * PEP3 (4 * 512), PEP4 (N/A) - * Config 9: PEP1 (2 * 1024), PEP2 (N/A), - * PEP3 (2 * 1024), PEP4 (N/A) - * Config 10: PEP1 (3 * 512), PEP2 (N/A), - * PEP3 (3 * 512), PEP4 (2 * 512) - * Config 11: PEP1 (3 * 1024), PEP2 (N/A), - * PEP3 (N/A), PEP4 (2 * 512) - * Config 12: PEP1 (4 * 1024), PEP2 (N/A), - * PEP3 (N/A), PEP4 (N/A) - - * Valid In Asynchronous Callback: NO - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_CONFIGURATION - the configuration given - * is not between 1 and 12 -*/ -EXTERN cy_as_return_status_t -cy_as_usb_set_physical_configuration( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The physical endpoint configuration number */ - uint8_t config - ); - -/* Summary - This function sets the hardware configuration for a given endpoint - - Description - This function sets the hardware configuration for a given endpoint. - This is the method to set the direction of the endpoint, the type - of endpoint, the size of the endpoint buffer, and the buffering - style for the endpoint. - - * Valid In Asynchronous Callback: NO - - Notes - Add documentation about endpoint configuration limitations - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint parameter is invalid - * CY_AS_ERROR_INVALID_CONFIGURATION - the endpoint configuration - * given is not valid - * CY_AS_ERROR_ENDPOINT_CONFIG_NOT_SET - the physical endpoint - * configuration is not set - - See Also - * CyAsUsbGetEndPointConfig - * CyAsUsbEndPointConfig -*/ -EXTERN cy_as_return_status_t -cy_as_usb_set_end_point_config( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* The configuration information for the endpoint */ - cy_as_usb_end_point_config *config_p - ); - -/* Summary - This function retreives the hardware configuration for - a given endpoint - - Description - This function gets the hardware configuration for the given - endpoint. This include information about the direction of - the endpoint, the type of endpoint, the size of the endpoint - buffer, and the buffering style for the endpoint. - - * Valid In Asynchronous Callback: NO - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint parameter is - * invalid - - See Also - * CyAsUsbSetEndPointConfig - * CyAsUsbEndPointConfig -*/ -EXTERN cy_as_return_status_t -cy_as_usb_get_end_point_config( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest*/ - cy_as_end_point_number_t ep, - /* The return value containing the endpoint config - * information */ - cy_as_usb_end_point_config *config_p - ); - -/* Summary - This function commits the configuration information that - has previously been set. - - Description - The initialization process involves calling CyAsUsbSetEnumConfig() - and CyAsUsbSetEndPointConfig(). These - functions do not actually send the configuration information to - the West Bridge device. Instead, these - functions store away the configuration information and this - CyAsUsbCommitConfig() actually finds the - best hardware configuration based on the requested endpoint - configuration and sends this optimal - confiuration down to the West Bridge device. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - a configuration was found and sent - * to West Bridge - * CY_AS_ERROR_NOT_CONFIGURED - the West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - the firmware has not been loaded - * into West Bridge - * CY_AS_ERROR_INVALID_CONFIGURATION - the configuration requested - * is not possible - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - - See Also - * CyAsUsbSetEndPointConfig - * CyAsUsbSetEnumConfig -*/ - -EXTERN cy_as_return_status_t -cy_as_usb_commit_config( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - This function reads data from a USB endpoint. - - Description - This function reads data from an OUT. This function blocks - until the read is complete. - If this is a packet read, a single received USB packet will - complete the read. If this - is not a packet read, this function will block until all of - the data requested has been - recevied. - - * Valid In Asynchronous Callback: NO - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint parameter is - * invalid - - See Also - * CyAsUsbReadDataAsync - * CyAsUsbWriteData - * CyAsUsbWriteDataAsync -*/ -EXTERN cy_as_return_status_t -cy_as_usb_read_data( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* If CyTrue, this is a packet read */ - cy_bool pktread, - /* The amount of data to read */ - uint32_t dsize, - /* The amount of data read */ - uint32_t *dataread, - /* The buffer to hold the data read */ - void *data - ); - -/* Summary - This function reads data from a USB endpoint - - Description - This function reads data from an OUT endpoint. This - function will return immediately and the callback - provided will be called when the read is complete. - If this is a packet read, then the callback will be - called on the next received packet. If this is not a - packet read, the callback will be called when the - requested data is received. - - * Valid In Asynchronous Callback: YES - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint parameter is - * invalid - - See Also - * CyAsUsbReadData - * CyAsUsbWriteData - * CyAsUsbWriteDataAsync -*/ -EXTERN cy_as_return_status_t -cy_as_usb_read_data_async( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* If CyTrue, this is a packet read */ - cy_bool pktread, - /* The amount of data to read */ - uint32_t dsize, - /* The buffer for storing the data */ - void *data, - /* The callback function to call when the data is read */ - cy_as_usb_io_callback callback - ); - -/* Summary - This function writes data to a USB endpoint - - Description - This function writes data to an IN endpoint data buffer. - Multiple USB packets may be sent until all data requeste - has been sent. This function blocks until all of the data - has been sent. - - * Valid In Asynchronous Callback: NO - - Notes - Calling this function with a dsize of zero will result in - a zero length packet transmitted to the USB host. - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint parameter is - * invalid - - See Also - * CyAsUsbReadData - * CyAsUsbReadDataAsync - * CyAsUsbWriteDataAsync -*/ -EXTERN cy_as_return_status_t -cy_as_usb_write_data( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint to write data to */ - cy_as_end_point_number_t ep, - /* The size of the data to write */ - uint32_t dsize, - /* The data buffer */ - void *data - ); - -/* Summary - This function writes data to a USB endpoint - - Description - This function writes data to an IN endpoint data buffer. - This function returns immediately and when the write - completes, or if an error occurs, the callback function - is called to indicate completion of the write operation. - - * Valid In Asynchronous Callback: YES - - Notes - Calling this function with a dsize of zero will result - in a zero length packet transmitted to the USB host. - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down successfully - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint parameter is - * invalid - - See Also - * CyAsUsbReadData - * CyAsUsbReadDataAsync - * CyAsUsbWriteData -*/ -EXTERN cy_as_return_status_t -cy_as_usb_write_data_async( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint to write data to */ - cy_as_end_point_number_t ep, - /* The size of the data */ - uint32_t dsize, - /* The buffer containing the data */ - void *data, - /* If true, send a short packet to terminate data */ - cy_bool spacket, - /* The callback to call when the data is written */ - cy_as_usb_io_callback callback - ); - -/* Summary - This function aborts an outstanding asynchronous - operation on a given endpoint - - Description - This function aborts any outstanding operation that is - pending on the given endpoint. - - * Valid In Asynchronous Callback: YES - - Returns - * CY_AS_ERROR_SUCCESS - this module was shut down - * successfully - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not - * running - * CY_AS_ERROR_ASYNC_NOT_PENDING - no asynchronous USB - * operation was pending - - See Also - * CyAsUsbReadData - * CyAsUsbReadDataAsync - * CyAsUsbWriteData - * CyAsUsbWriteDataAsync -*/ -EXTERN cy_as_return_status_t -cy_as_usb_cancel_async( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep - ); - -/* Summary - This function sets a stall condition on a given endpoint - - Description - This function sets a stall condition on the given endpoint. - If the callback function is not zero, the function is - executed asynchronously and the callback is called when - the function is completed. If the callback function is - zero, this function executes synchronously and will not - return until the function has completed. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the function succeeded - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given was invalid, - * or was not configured as an OUT endpoint - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_INVALID_IN_CALLBACK (only if no cb supplied) - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - See Also - * CyAsUsbGetStall - * CyAsUsbClearStall -*/ -EXTERN cy_as_return_status_t -cy_as_usb_set_stall( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client -); - -/* Summary - This function clears a stall condition on a given endpoint - - Description - This function clears a stall condition on the given endpoint. - If the callback function is not zero, the function is - executed asynchronously and the callback is called when the - function is completed. If the callback function is zero, this - function executes synchronously and will not return until the - function has completed. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the function succeeded - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given was invalid, - * or was not configured as an OUT endpoint - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_INVALID_IN_CALLBACK (only if no cb supplied) - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - See Also - * CyAsUsbGetStall - * CyAsUsbSetStall -*/ - -EXTERN cy_as_return_status_t -cy_as_usb_clear_stall( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - - -/* Summary - This function returns the stall status for a given endpoint - - Description - This function returns the stall status for a given endpoint - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the function succeeded - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given was invalid, - * or was not configured as an OUT endpoint - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_INVALID_IN_CALLBACK - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - See Also - * CyAsUsbGetStall - * CyAsUsbSetStall - * CyAsUsbClearStall -*/ - -EXTERN cy_as_return_status_t -cy_as_usb_get_stall( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* The return value for the stall state */ - cy_bool *stall_p, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - This function sets a NAK condition on a given endpoint - - Description - This function sets a NAK condition on the given endpoint. - If the callback function is not zero, the function is - executed asynchronously and the callback is called when - the function is completed. If the callback function is - zero, this function executes synchronously and will not - return until the function has completed. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the function succeeded - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given was - * invalid, or was not configured as an OUT endpoint - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_INVALID_IN_CALLBACK (only if no cb supplied) - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - See Also - * CyAsUsbGetNak - * CyAsUsbClearNak -*/ -EXTERN cy_as_return_status_t -cy_as_usb_set_nak( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client -); - -/* Summary - This function clears a NAK condition on a given endpoint - - Description - This function clears a NAK condition on the given endpoint. - If the callback function is not zero, the function is - executed asynchronously and the callback is called when the - function is completed. If the callback function is zero, - this function executes synchronously and will not return - until the function has completed. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the function succeeded - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given was invalid, - * or was not configured as an OUT endpoint - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_INVALID_IN_CALLBACK (only if no cb supplied) - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - See Also - * CyAsUsbGetNak - * CyAsUsbSetNak -*/ -EXTERN cy_as_return_status_t -cy_as_usb_clear_nak( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - This function returns the NAK status for a given endpoint - - Description - This function returns the NAK status for a given endpoint - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the function succeeded - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_INVALID_ENDPOINT - the endpoint given was invalid, - * or was not configured as an OUT endpoint - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_INVALID_IN_CALLBACK - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - - See Also - * CyAsUsbSetNak - * CyAsUsbClearNak -*/ -EXTERN cy_as_return_status_t -cy_as_usb_get_nak( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* The return value for the stall state */ - cy_bool *nak_p, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client -); - -/* Summary - This function triggers a USB remote wakeup from the Processor - API - - Description - When there is a Suspend condition on the USB bus, this function - programmatically takes the USB bus out of thi suspend state. - - * Valid In Asynchronous Callback: YES (if cb supplied) - * Nestable: YES - - Returns - * CY_AS_ERROR_SUCCESS - the function succeeded - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_INVALID_HANDLE - * CY_AS_ERROR_INVALID_IN_CALLBACK - * CY_AS_ERROR_OUT_OF_MEMORY - * CY_AS_ERROR_INVALID_RESPONSE - * CY_AS_ERROR_NOT_IN_SUSPEND - -*/ -EXTERN cy_as_return_status_t -cy_as_usb_signal_remote_wakeup( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - This function sets the threshold levels for mass storage progress - reports from the West Bridge. - - Description - The West Bridge firmware can be configured to track the amount of - read/write activity on the mass storage device, and send progress - reports when the activity level has crossed a threshold level. - This function sets the threshold levels for the progress reports. - Set wr_sectors and rd_sectors to 0, if the progress reports are to - be turned off. - - * Valid In Asynchronous Callback: Yes (if cb supplied) - * Nestable: Yes - - Returns - * CY_AS_ERROR_SUCCESS - the function succeeded - * CY_AS_ERROR_NOT_RUNNING - the USB stack is not running - * CY_AS_ERROR_TIMEOUT - a timeout occurred communicating with - * the West Bridge device - * CY_AS_ERROR_INVALID_HANDLE - Bad handle - * CY_AS_ERROR_INVALID_IN_CALLBACK - Synchronous call made - * while in callback - * CY_AS_ERROR_OUT_OF_MEMORY - Failed allocating memory for - * request processing - * CY_AS_ERROR_NOT_SUPPORTED - Firmware version does not support - * mass storage progress tracking - * CY_AS_ERROR_INVALID_RESPONSE - Unexpected response from - * Firmware - - See Also - * CyAsUsbMSCProgressData - * CyAsEventUsbMSCProgress -*/ -EXTERN cy_as_return_status_t -cy_as_usb_set_m_s_report_threshold( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* Number of sectors written before report is sent */ - uint32_t wr_sectors, - /* Number of sectors read before report is sent */ - uint32_t rd_sectors, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -/* Summary - Specify which of the partitions on a partitioned mass storage - device should be made visible to USB. - - Description - West Bridge firmware supports the creation of up to two - partitions on mass storage devices connected to the West Bridge - device. When there are two partitions on a device, the user can - choose which of these partitions should be made visible to the - USB host through the USB mass storage interface. This function - allows the user to configure the partitions that should be - enumerated. At least one partition should be selected through - this API. If neither partition needs to be enumerated, use - CyAsUsbSetEnumConfig to control this. - - * Valid in Asynchronous callback: Yes (if cb supplied) - * Nestable: Yes - - Returns - * CY_AS_ERROR_SUCCESS - operation completed successfully - * CY_AS_ERROR_INVALID_HANDLE - invalid handle to the West - * Bridge device - * CY_AS_ERROR_NOT_CONFIGURED - West Bridge device has not - * been configured - * CY_AS_ERROR_NO_FIRMWARE - no firmware running on West - * Bridge device - * CY_AS_ERROR_NOT_RUNNING - USB stack has not been started - * CY_AS_ERROR_IN_SUSPEND - West Bridge device is in - * suspend mode - * CY_AS_ERROR_INVALID_CALL_SEQUENCE - this API has to be - * called before CyAsUsbSetEnumConfig - * CY_AS_ERROR_OUT_OF_MEMORY - failed to get memory to - * process the request - * CY_AS_ERROR_NO_SUCH_UNIT - Storage device addressed has - * not been partitioned - * CY_AS_ERROR_NOT_SUPPORTED - operation is not supported by - * active device/firmware. - - See Also - * CyAsStorageCreatePPartition - * CyAsStorageRemovePPartition - * CyAsUsbMsType_t - */ -EXTERN cy_as_return_status_t -cy_as_usb_select_m_s_partitions( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* Bus index of the device being addressed */ - cy_as_bus_number_t bus, - /* Device id of the device being addressed */ - uint32_t device, - /* Selection of partitions to be enumerated */ - cy_as_usb_m_s_type_t type, - /* The callback, if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -extern cy_as_media_type -cy_as_storage_get_media_from_address(uint16_t v); - -extern cy_as_bus_number_t -cy_as_storage_get_bus_from_address(uint16_t v); - -extern uint32_t -cy_as_storage_get_device_from_address(uint16_t v); - -/* For supporting deprecated functions */ -#include "cyasusb_dep.h" - -#include "cyas_cplus_end.h" - -#endif /* _INCLUDED_CYASUSB_H_ */ diff --git a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb_dep.h b/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb_dep.h deleted file mode 100644 index 829eddee39b5..000000000000 --- a/drivers/staging/westbridge/astoria/include/linux/westbridge/cyasusb_dep.h +++ /dev/null @@ -1,224 +0,0 @@ -/* Cypress West Bridge API header file (cyasusb_dep.h) -## =========================== -## Copyright (C) 2010 Cypress Semiconductor -## -## 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 Street -## Fifth Floor, Boston, MA 02110-1301, USA. -## =========================== -*/ - -/* - * This header will contain Antioch specific declaration - * of the APIs that are deprecated in Astoria SDK. This is - * for maintaining backward compatibility. - */ - -#ifndef __INCLUDED_CYASUSB_DEP_H__ -#define __INCLUDED_CYASUSB_DEP_H__ - -#ifndef __doxygen__ - -/* - This data structure is the data passed via the evdata - paramater on a usb event callback for the inquiry request. -*/ - -typedef struct cy_as_usb_inquiry_data_dep { - /* The media for the event */ - cy_as_media_type media; - /* The EVPD bit from the SCSI INQUIRY request */ - uint8_t evpd; - /* The codepage in the inquiry request */ - uint8_t codepage; - /* This bool must be set to CyTrue indicate - * that the inquiry data was changed */ - cy_bool updated; - /* The length of the data */ - uint16_t length; - /* The inquiry data */ - void *data; -} cy_as_usb_inquiry_data_dep; - - -typedef struct cy_as_usb_unknown_command_data_dep { - /* The media for the event */ - cy_as_media_type media; - /* The length of the requst (should be 16 bytes) */ - uint16_t reqlen; - /* The request */ - void *request; - /* The returned status value for the command */ - uint8_t status; - /* If status is failed, the sense key */ - uint8_t key; - /* If status is failed, the additional sense code */ - uint8_t asc; - /* If status if failed, the additional sense code qualifier */ - uint8_t ascq; -} cy_as_usb_unknown_command_data_dep; - - -typedef struct cy_as_usb_start_stop_data_dep { - /* The media type for the event */ - cy_as_media_type media; - /* CyTrue means start request, CyFalse means stop request */ - cy_bool start; - /* CyTrue means LoEj bit set, otherwise false */ - cy_bool loej; -} cy_as_usb_start_stop_data_dep; - - -typedef struct cy_as_usb_enum_control_dep { - /* The bits in this member determine which mass storage devices - are enumerated. see cy_as_usb_mass_storage_enum for more details. */ - uint8_t enum_mass_storage; - /* If true, West Bridge will control enumeration. If this is false the - pport controls enumeration. if the P port is controlling - enumeration, traffic will be received via endpoint zero. */ - cy_bool antioch_enumeration; - /* This is the interface # to use for the mass storage interface, - if mass storage is enumerated. if mass storage is not enumerated - this value should be zero. */ - uint8_t mass_storage_interface; - /* If true, Inquiry, START/STOP, and unknown mass storage - requests cause a callback to occur for handling by the - baseband processor. */ - cy_bool mass_storage_callbacks; -} cy_as_usb_enum_control_dep; - - -typedef void (*cy_as_usb_event_callback_dep)( - /* Handle to the device to configure */ - cy_as_device_handle handle, - /* The event type being reported */ - cy_as_usb_event ev, - /* The data assocaited with the event being reported */ - void *evdata -); - - - -/* Register Callback api */ -EXTERN cy_as_return_status_t -cy_as_usb_register_callback_dep( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The function to call */ - cy_as_usb_event_callback_dep callback - ); - - -extern cy_as_return_status_t -cy_as_usb_set_enum_config_dep( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The USB configuration information */ - cy_as_usb_enum_control_dep *config_p, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - - -extern cy_as_return_status_t -cy_as_usb_get_enum_config_dep( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The return value for USB congifuration information */ - cy_as_usb_enum_control_dep *config_p, - /* The callback if async call */ - cy_as_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -extern cy_as_return_status_t -cy_as_usb_get_descriptor_dep( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The type of descriptor */ - cy_as_usb_desc_type type, - /* Index for string descriptor */ - uint8_t index, - /* The buffer to hold the returned descriptor */ - void *desc_p, - /* This is an input and output parameter. Before the code this pointer - points to a uint32_t that contains the length of the buffer. after - the call, this value contains the amount of data actually returned. */ - uint32_t *length_p - ); - -extern cy_as_return_status_t -cy_as_usb_set_stall_dep( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* The callback if async call */ - cy_as_usb_function_callback cb, - /* Client supplied data */ - uint32_t client -); - -EXTERN cy_as_return_status_t -cy_as_usb_clear_stall_dep( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* The callback if async call */ - cy_as_usb_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -EXTERN cy_as_return_status_t -cy_as_usb_set_nak_dep( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* The callback if async call */ - cy_as_usb_function_callback cb, - /* Client supplied data */ - uint32_t client -); - -EXTERN cy_as_return_status_t -cy_as_usb_clear_nak_dep( - /* Handle to the West Bridge device */ - cy_as_device_handle handle, - /* The endpoint of interest */ - cy_as_end_point_number_t ep, - /* The callback if async call */ - cy_as_usb_function_callback cb, - /* Client supplied data */ - uint32_t client - ); - -EXTERN cy_as_return_status_t -cy_as_usb_select_m_s_partitions_dep( - cy_as_device_handle handle, - cy_as_media_type media, - uint32_t device, - cy_as_usb_m_s_type_t type, - cy_as_function_callback cb, - uint32_t client - ); - -#endif /*__doxygen*/ - -#endif /*__INCLUDED_CYANSTORAGE_DEP_H__*/ diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c index 79e53e46ecca..c5a07fbe10ae 100644 --- a/drivers/staging/winbond/phy_calibration.c +++ b/drivers/staging/winbond/phy_calibration.c @@ -44,147 +44,147 @@ static const s32 Angles[] = { s32 _s13_to_s32(u32 data) { - u32 val; + u32 val; - val = (data & 0x0FFF); + val = (data & 0x0FFF); - if ((data & BIT(12)) != 0) - val |= 0xFFFFF000; + if ((data & BIT(12)) != 0) + val |= 0xFFFFF000; - return ((s32) val); + return ((s32) val); } u32 _s32_to_s13(s32 data) { - u32 val; + u32 val; - if (data > 4095) - data = 4095; - else if (data < -4096) - data = -4096; + if (data > 4095) + data = 4095; + else if (data < -4096) + data = -4096; - val = data & 0x1FFF; + val = data & 0x1FFF; - return val; + return val; } /****************************************************************************/ s32 _s4_to_s32(u32 data) { - s32 val; + s32 val; - val = (data & 0x0007); + val = (data & 0x0007); - if ((data & BIT(3)) != 0) - val |= 0xFFFFFFF8; + if ((data & BIT(3)) != 0) + val |= 0xFFFFFFF8; - return val; + return val; } u32 _s32_to_s4(s32 data) { - u32 val; + u32 val; - if (data > 7) - data = 7; - else if (data < -8) - data = -8; + if (data > 7) + data = 7; + else if (data < -8) + data = -8; - val = data & 0x000F; + val = data & 0x000F; - return val; + return val; } /****************************************************************************/ s32 _s5_to_s32(u32 data) { - s32 val; + s32 val; - val = (data & 0x000F); + val = (data & 0x000F); - if ((data & BIT(4)) != 0) - val |= 0xFFFFFFF0; + if ((data & BIT(4)) != 0) + val |= 0xFFFFFFF0; - return val; + return val; } u32 _s32_to_s5(s32 data) { - u32 val; + u32 val; - if (data > 15) - data = 15; - else if (data < -16) - data = -16; + if (data > 15) + data = 15; + else if (data < -16) + data = -16; - val = data & 0x001F; + val = data & 0x001F; - return val; + return val; } /****************************************************************************/ s32 _s6_to_s32(u32 data) { - s32 val; + s32 val; - val = (data & 0x001F); + val = (data & 0x001F); - if ((data & BIT(5)) != 0) - val |= 0xFFFFFFE0; + if ((data & BIT(5)) != 0) + val |= 0xFFFFFFE0; - return val; + return val; } u32 _s32_to_s6(s32 data) { - u32 val; + u32 val; - if (data > 31) - data = 31; - else if (data < -32) - data = -32; + if (data > 31) + data = 31; + else if (data < -32) + data = -32; - val = data & 0x003F; + val = data & 0x003F; - return val; + return val; } /****************************************************************************/ s32 _s9_to_s32(u32 data) { - s32 val; + s32 val; - val = data & 0x00FF; + val = data & 0x00FF; - if ((data & BIT(8)) != 0) - val |= 0xFFFFFF00; + if ((data & BIT(8)) != 0) + val |= 0xFFFFFF00; - return val; + return val; } u32 _s32_to_s9(s32 data) { - u32 val; + u32 val; - if (data > 255) - data = 255; - else if (data < -256) - data = -256; + if (data > 255) + data = 255; + else if (data < -256) + data = -256; - val = data & 0x01FF; + val = data & 0x01FF; - return val; + return val; } /****************************************************************************/ s32 _floor(s32 n) { - if (n > 0) - n += 5; - else - n -= 5; + if (n > 0) + n += 5; + else + n -= 5; - return (n/10); + return (n/10); } /****************************************************************************/ @@ -195,105 +195,105 @@ s32 _floor(s32 n) */ u32 _sqrt(u32 sqsum) { - u32 sq_rt; + u32 sq_rt; - int g0, g1, g2, g3, g4; - int seed; - int next; - int step; + int g0, g1, g2, g3, g4; + int seed; + int next; + int step; - g4 = sqsum / 100000000; - g3 = (sqsum - g4*100000000) / 1000000; - g2 = (sqsum - g4*100000000 - g3*1000000) / 10000; - g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) / 100; - g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100); + g4 = sqsum / 100000000; + g3 = (sqsum - g4*100000000) / 1000000; + g2 = (sqsum - g4*100000000 - g3*1000000) / 10000; + g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) / 100; + g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100); - next = g4; - step = 0; - seed = 0; - while (((seed+1)*(step+1)) <= next) { - step++; - seed++; - } + next = g4; + step = 0; + seed = 0; + while (((seed+1)*(step+1)) <= next) { + step++; + seed++; + } - sq_rt = seed * 10000; - next = (next-(seed*step))*100 + g3; + sq_rt = seed * 10000; + next = (next-(seed*step))*100 + g3; - step = 0; - seed = 2 * seed * 10; - while (((seed+1)*(step+1)) <= next) { - step++; - seed++; - } + step = 0; + seed = 2 * seed * 10; + while (((seed+1)*(step+1)) <= next) { + step++; + seed++; + } - sq_rt = sq_rt + step * 1000; - next = (next - seed * step) * 100 + g2; - seed = (seed + step) * 10; - step = 0; - while (((seed+1)*(step+1)) <= next) { - step++; - seed++; - } + sq_rt = sq_rt + step * 1000; + next = (next - seed * step) * 100 + g2; + seed = (seed + step) * 10; + step = 0; + while (((seed+1)*(step+1)) <= next) { + step++; + seed++; + } - sq_rt = sq_rt + step * 100; - next = (next - seed * step) * 100 + g1; - seed = (seed + step) * 10; - step = 0; + sq_rt = sq_rt + step * 100; + next = (next - seed * step) * 100 + g1; + seed = (seed + step) * 10; + step = 0; - while (((seed+1)*(step+1)) <= next) { - step++; - seed++; - } + while (((seed+1)*(step+1)) <= next) { + step++; + seed++; + } - sq_rt = sq_rt + step * 10; - next = (next - seed * step) * 100 + g0; - seed = (seed + step) * 10; - step = 0; + sq_rt = sq_rt + step * 10; + next = (next - seed * step) * 100 + g0; + seed = (seed + step) * 10; + step = 0; - while (((seed+1)*(step+1)) <= next) { - step++; - seed++; - } + while (((seed+1)*(step+1)) <= next) { + step++; + seed++; + } - sq_rt = sq_rt + step; + sq_rt = sq_rt + step; - return sq_rt; + return sq_rt; } /****************************************************************************/ void _sin_cos(s32 angle, s32 *sin, s32 *cos) { - s32 X, Y, TargetAngle, CurrAngle; - unsigned Step; + s32 X, Y, TargetAngle, CurrAngle; + unsigned Step; - X = FIXED(AG_CONST); /* AG_CONST * cos(0) */ - Y = 0; /* AG_CONST * sin(0) */ - TargetAngle = abs(angle); - CurrAngle = 0; + X = FIXED(AG_CONST); /* AG_CONST * cos(0) */ + Y = 0; /* AG_CONST * sin(0) */ + TargetAngle = abs(angle); + CurrAngle = 0; - for (Step = 0; Step < 12; Step++) { - s32 NewX; + for (Step = 0; Step < 12; Step++) { + s32 NewX; - if (TargetAngle > CurrAngle) { - NewX = X - (Y >> Step); - Y = (X >> Step) + Y; - X = NewX; - CurrAngle += Angles[Step]; - } else { - NewX = X + (Y >> Step); - Y = -(X >> Step) + Y; - X = NewX; - CurrAngle -= Angles[Step]; - } - } + if (TargetAngle > CurrAngle) { + NewX = X - (Y >> Step); + Y = (X >> Step) + Y; + X = NewX; + CurrAngle += Angles[Step]; + } else { + NewX = X + (Y >> Step); + Y = -(X >> Step) + Y; + X = NewX; + CurrAngle -= Angles[Step]; + } + } - if (angle > 0) { - *cos = X; - *sin = Y; - } else { - *cos = X; - *sin = -Y; - } + if (angle > 0) { + *cos = X; + *sin = Y; + } else { + *cos = X; + *sin = -Y; + } } static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 * pValue) @@ -338,24 +338,24 @@ void _reset_rx_cal(struct hw_data *phw_data) /**********************************************/ void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency) { - u32 reg_agc_ctrl3; - u32 reg_a_acq_ctrl; - u32 reg_b_acq_ctrl; - u32 val; + u32 reg_agc_ctrl3; + u32 reg_a_acq_ctrl; + u32 reg_b_acq_ctrl; + u32 val; - PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n")); - phy_init_rf(phw_data); + PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n")); + phy_init_rf(phw_data); - /* set calibration channel */ - if ((RF_WB_242 == phw_data->phy_type) || + /* set calibration channel */ + if ((RF_WB_242 == phw_data->phy_type) || (RF_WB_242_1 == phw_data->phy_type)) /* 20060619.5 Add */{ - if ((frequency >= 2412) && (frequency <= 2484)) { - /* w89rf242 change frequency to 2390Mhz */ - PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n")); + if ((frequency >= 2412) && (frequency <= 2484)) { + /* w89rf242 change frequency to 2390Mhz */ + PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n")); phy_set_rf_data(phw_data, 3, (3<<24)|0x025586); - } - } else { + } + } else { } @@ -542,7 +542,7 @@ void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data) } if (loop >= 19) - fix_cancel_dc_i = 0; + fix_cancel_dc_i = 0; reg_dc_cancel &= ~(0x03FF); reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_i) << CANCEL_DC_I_SHIFT); @@ -657,7 +657,7 @@ void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data) } if (loop >= 19) - fix_cancel_dc_q = 0; + fix_cancel_dc_q = 0; reg_dc_cancel &= ~(0x001F); reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_q) << CANCEL_DC_Q_SHIFT); @@ -1154,33 +1154,33 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre capture_time = 0; for (capture_time = 0; capture_time < 10; capture_time++) { - /* i. Set "calib_start" to 0x0 */ - reg_mode_ctrl &= ~MASK_CALIB_START; - if (!hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl))/*20060718.1 modify */ - return 0; - PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + /* i. Set "calib_start" to 0x0 */ + reg_mode_ctrl &= ~MASK_CALIB_START; + if (!hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl))/*20060718.1 modify */ + return 0; + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); - reg_mode_ctrl &= ~MASK_IQCAL_MODE; - reg_mode_ctrl |= (MASK_CALIB_START|0x1); - hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); - PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); + reg_mode_ctrl &= ~MASK_IQCAL_MODE; + reg_mode_ctrl |= (MASK_CALIB_START|0x1); + hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl); + PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl)); - /* c. */ - hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val); - PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val)); + /* c. */ + hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val); + PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val)); - iqcal_tone_i = _s13_to_s32(val & 0x00001FFF); - iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13); - PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n", - iqcal_tone_i, iqcal_tone_q)); + iqcal_tone_i = _s13_to_s32(val & 0x00001FFF); + iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13); + PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n", + iqcal_tone_i, iqcal_tone_q)); - hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val); - PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val)); + hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val); + PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val)); - iqcal_image_i = _s13_to_s32(val & 0x00001FFF); - iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13); - PHY_DEBUG(("[CAL] ** iqcal_image_i = %d, iqcal_image_q = %d\n", - iqcal_image_i, iqcal_image_q)); + iqcal_image_i = _s13_to_s32(val & 0x00001FFF); + iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13); + PHY_DEBUG(("[CAL] ** iqcal_image_i = %d, iqcal_image_q = %d\n", + iqcal_image_i, iqcal_image_q)); if (capture_time == 0) continue; else { @@ -1358,7 +1358,7 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre hw_set_dxx_reg(phw_data, 0x54, val); if (loop == 3) - return 0; + return 0; } PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val)); @@ -1476,40 +1476,40 @@ void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency) /******************/ void phy_set_rf_data(struct hw_data *pHwData, u32 index, u32 value) { - u32 ltmp = 0; + u32 ltmp = 0; - switch (pHwData->phy_type) { - case RF_MAXIM_2825: - case RF_MAXIM_V1: /* 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) */ - ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18); - break; + switch (pHwData->phy_type) { + case RF_MAXIM_2825: + case RF_MAXIM_V1: /* 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331) */ + ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18); + break; - case RF_MAXIM_2827: - ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18); - break; + case RF_MAXIM_2827: + ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18); + break; - case RF_MAXIM_2828: - ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18); - break; + case RF_MAXIM_2828: + ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18); + break; - case RF_MAXIM_2829: - ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18); - break; + case RF_MAXIM_2829: + ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse(value, 18); + break; - case RF_AIROHA_2230: - case RF_AIROHA_2230S: /* 20060420 Add this */ - ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(value, 20); - break; + case RF_AIROHA_2230: + case RF_AIROHA_2230S: /* 20060420 Add this */ + ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse(value, 20); + break; - case RF_AIROHA_7230: - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff); - break; + case RF_AIROHA_7230: + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff); + break; - case RF_WB_242: - case RF_WB_242_1:/* 20060619.5 Add */ - ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse(value, 24); - break; - } + case RF_WB_242: + case RF_WB_242_1:/* 20060619.5 Add */ + ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse(value, 24); + break; + } Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); } diff --git a/drivers/staging/wlags49_h2/wl_internal.h b/drivers/staging/wlags49_h2/wl_internal.h index e86aad53b53d..b61c9eb75ad5 100644 --- a/drivers/staging/wlags49_h2/wl_internal.h +++ b/drivers/staging/wlags49_h2/wl_internal.h @@ -67,7 +67,6 @@ /******************************************************************************* * include files ******************************************************************************/ -#include #ifdef BUS_PCMCIA #include #include diff --git a/drivers/staging/wlags49_h2/wl_version.h b/drivers/staging/wlags49_h2/wl_version.h index a5e604cd1983..a5faada136da 100644 --- a/drivers/staging/wlags49_h2/wl_version.h +++ b/drivers/staging/wlags49_h2/wl_version.h @@ -66,7 +66,6 @@ * include files ******************************************************************************/ //#include -#include #ifndef CONFIG_MODVERSIONS #define __NO_VERSION__ diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 729d03d28d75..3c40096f0c05 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -442,9 +442,9 @@ int crcimage(struct imgchunk *fchunk, unsigned int nfchunks, void free_chunks(struct imgchunk *fchunk, unsigned int *nfchunks) { int i; - for (i = 0; i < *nfchunks; i++) { + for (i = 0; i < *nfchunks; i++) kfree(fchunk[i].data); - } + *nfchunks = 0; memset(fchunk, 0, sizeof(*fchunk)); diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 21f25a21c291..417aea5e01cd 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -50,7 +50,6 @@ * -------------------------------------------------------------------- */ -#include #include #include #include diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index cadec2ad0d32..4403e5f80597 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -5,7 +5,6 @@ */ /* #include */ -#include #include #include #include diff --git a/drivers/staging/xgifb/vb_ext.c b/drivers/staging/xgifb/vb_ext.c index 7e1f76adf733..b1a25730b7ca 100644 --- a/drivers/staging/xgifb/vb_ext.c +++ b/drivers/staging/xgifb/vb_ext.c @@ -1,4 +1,3 @@ -#include #include #include #include "XGIfb.h" diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 33c6876d2a80..493b53220397 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1,6 +1,5 @@ #include "vgatypes.h" -#include #include #include /* udelay */ #include "XGIfb.h" diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 2669b1b0f51f..dc4d6e6fc9b3 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "XGIfb.h" diff --git a/drivers/staging/zcache/tmem.c b/drivers/staging/zcache/tmem.c index e954d405b138..975e34bcd722 100644 --- a/drivers/staging/zcache/tmem.c +++ b/drivers/staging/zcache/tmem.c @@ -142,6 +142,7 @@ static void tmem_obj_init(struct tmem_obj *obj, struct tmem_hashbucket *hb, obj->oid = *oidp; obj->objnode_count = 0; obj->pampd_count = 0; + (*tmem_pamops.new_obj)(obj); SET_SENTINEL(obj, OBJ); while (*new) { BUG_ON(RB_EMPTY_NODE(*new)); @@ -274,7 +275,7 @@ static void tmem_objnode_free(struct tmem_objnode *objnode) /* * lookup index in object and return associated pampd (or NULL if not found) */ -static void *tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) +static void **__tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) { unsigned int height, shift; struct tmem_objnode **slot = NULL; @@ -303,9 +304,33 @@ static void *tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) height--; } out: + return slot != NULL ? (void **)slot : NULL; +} + +static void *tmem_pampd_lookup_in_obj(struct tmem_obj *obj, uint32_t index) +{ + struct tmem_objnode **slot; + + slot = (struct tmem_objnode **)__tmem_pampd_lookup_in_obj(obj, index); return slot != NULL ? *slot : NULL; } +static void *tmem_pampd_replace_in_obj(struct tmem_obj *obj, uint32_t index, + void *new_pampd) +{ + struct tmem_objnode **slot; + void *ret = NULL; + + slot = (struct tmem_objnode **)__tmem_pampd_lookup_in_obj(obj, index); + if ((slot != NULL) && (*slot != NULL)) { + void *old_pampd = *(void **)slot; + *(void **)slot = new_pampd; + (*tmem_pamops.free)(old_pampd, obj->pool, NULL, 0); + ret = new_pampd; + } + return ret; +} + static int tmem_pampd_add_to_obj(struct tmem_obj *obj, uint32_t index, void *pampd) { @@ -456,7 +481,7 @@ static void tmem_objnode_node_destroy(struct tmem_obj *obj, if (ht == 1) { obj->pampd_count--; (*tmem_pamops.free)(objnode->slots[i], - obj->pool); + obj->pool, NULL, 0); objnode->slots[i] = NULL; continue; } @@ -473,7 +498,7 @@ static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *obj) return; if (obj->objnode_tree_height == 0) { obj->pampd_count--; - (*tmem_pamops.free)(obj->objnode_tree_root, obj->pool); + (*tmem_pamops.free)(obj->objnode_tree_root, obj->pool, NULL, 0); } else { tmem_objnode_node_destroy(obj, obj->objnode_tree_root, obj->objnode_tree_height); @@ -481,6 +506,7 @@ static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *obj) obj->objnode_tree_height = 0; } obj->objnode_tree_root = NULL; + (*tmem_pamops.free_obj)(obj->pool, obj); } /* @@ -503,15 +529,13 @@ static void tmem_pampd_destroy_all_in_obj(struct tmem_obj *obj) * always flushes for simplicity. */ int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, - struct page *page) + char *data, size_t size, bool raw, bool ephemeral) { struct tmem_obj *obj = NULL, *objfound = NULL, *objnew = NULL; void *pampd = NULL, *pampd_del = NULL; int ret = -ENOMEM; - bool ephemeral; struct tmem_hashbucket *hb; - ephemeral = is_ephemeral(pool); hb = &pool->hashbucket[tmem_oid_hash(oidp)]; spin_lock(&hb->lock); obj = objfound = tmem_obj_find(hb, oidp); @@ -521,7 +545,7 @@ int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, /* if found, is a dup put, flush the old one */ pampd_del = tmem_pampd_delete_from_obj(obj, index); BUG_ON(pampd_del != pampd); - (*tmem_pamops.free)(pampd, pool); + (*tmem_pamops.free)(pampd, pool, oidp, index); if (obj->pampd_count == 0) { objnew = obj; objfound = NULL; @@ -538,7 +562,8 @@ int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, } BUG_ON(obj == NULL); BUG_ON(((objnew != obj) && (objfound != obj)) || (objnew == objfound)); - pampd = (*tmem_pamops.create)(obj->pool, &obj->oid, index, page); + pampd = (*tmem_pamops.create)(data, size, raw, ephemeral, + obj->pool, &obj->oid, index); if (unlikely(pampd == NULL)) goto free; ret = tmem_pampd_add_to_obj(obj, index, pampd); @@ -551,7 +576,7 @@ int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, (void)tmem_pampd_delete_from_obj(obj, index); free: if (pampd) - (*tmem_pamops.free)(pampd, pool); + (*tmem_pamops.free)(pampd, pool, NULL, 0); if (objnew) { tmem_obj_free(objnew, hb); (*tmem_hostops.obj_free)(objnew, pool); @@ -573,41 +598,52 @@ int tmem_put(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, * "put" done with the same handle). */ -int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp, - uint32_t index, struct page *page) +int tmem_get(struct tmem_pool *pool, struct tmem_oid *oidp, uint32_t index, + char *data, size_t *size, bool raw, int get_and_free) { struct tmem_obj *obj; void *pampd; bool ephemeral = is_ephemeral(pool); uint32_t ret = -1; struct tmem_hashbucket *hb; + bool free = (get_and_free == 1) || ((get_and_free == 0) && ephemeral); + bool lock_held = false; hb = &pool->hashbucket[tmem_oid_hash(oidp)]; spin_lock(&hb->lock); + lock_held = true; obj = tmem_obj_find(hb, oidp); if (obj == NULL) goto out; - ephemeral = is_ephemeral(pool); - if (ephemeral) + if (free) pampd = tmem_pampd_delete_from_obj(obj, index); else pampd = tmem_pampd_lookup_in_obj(obj, index); if (pampd == NULL) goto out; - ret = (*tmem_pamops.get_data)(page, pampd, pool); - if (ret < 0) - goto out; - if (ephemeral) { - (*tmem_pamops.free)(pampd, pool); + if (free) { if (obj->pampd_count == 0) { tmem_obj_free(obj, hb); (*tmem_hostops.obj_free)(obj, pool); obj = NULL; } } + if (tmem_pamops.is_remote(pampd)) { + lock_held = false; + spin_unlock(&hb->lock); + } + if (free) + ret = (*tmem_pamops.get_data_and_free)( + data, size, raw, pampd, pool, oidp, index); + else + ret = (*tmem_pamops.get_data)( + data, size, raw, pampd, pool, oidp, index); + if (ret < 0) + goto out; ret = 0; out: - spin_unlock(&hb->lock); + if (lock_held) + spin_unlock(&hb->lock); return ret; } @@ -632,7 +668,7 @@ int tmem_flush_page(struct tmem_pool *pool, pampd = tmem_pampd_delete_from_obj(obj, index); if (pampd == NULL) goto out; - (*tmem_pamops.free)(pampd, pool); + (*tmem_pamops.free)(pampd, pool, oidp, index); if (obj->pampd_count == 0) { tmem_obj_free(obj, hb); (*tmem_hostops.obj_free)(obj, pool); @@ -644,6 +680,30 @@ int tmem_flush_page(struct tmem_pool *pool, return ret; } +/* + * If a page in tmem matches the handle, replace the page so that any + * subsequent "get" gets the new page. Returns 0 if + * there was a page to replace, else returns -1. + */ +int tmem_replace(struct tmem_pool *pool, struct tmem_oid *oidp, + uint32_t index, void *new_pampd) +{ + struct tmem_obj *obj; + int ret = -1; + struct tmem_hashbucket *hb; + + hb = &pool->hashbucket[tmem_oid_hash(oidp)]; + spin_lock(&hb->lock); + obj = tmem_obj_find(hb, oidp); + if (obj == NULL) + goto out; + new_pampd = tmem_pampd_replace_in_obj(obj, index, new_pampd); + ret = (*tmem_pamops.replace_in_obj)(new_pampd, obj); +out: + spin_unlock(&hb->lock); + return ret; +} + /* * "Flush" all pages in tmem matching this oid. */ diff --git a/drivers/staging/zcache/tmem.h b/drivers/staging/zcache/tmem.h index 2e07e217d51f..ed147c4b110d 100644 --- a/drivers/staging/zcache/tmem.h +++ b/drivers/staging/zcache/tmem.h @@ -147,6 +147,7 @@ struct tmem_obj { unsigned int objnode_tree_height; unsigned long objnode_count; long pampd_count; + void *extra; /* for private use by pampd implementation */ DECL_SENTINEL }; @@ -166,10 +167,18 @@ struct tmem_objnode { /* pampd abstract datatype methods provided by the PAM implementation */ struct tmem_pamops { - void *(*create)(struct tmem_pool *, struct tmem_oid *, uint32_t, - struct page *); - int (*get_data)(struct page *, void *, struct tmem_pool *); - void (*free)(void *, struct tmem_pool *); + void *(*create)(char *, size_t, bool, int, + struct tmem_pool *, struct tmem_oid *, uint32_t); + int (*get_data)(char *, size_t *, bool, void *, struct tmem_pool *, + struct tmem_oid *, uint32_t); + int (*get_data_and_free)(char *, size_t *, bool, void *, + struct tmem_pool *, struct tmem_oid *, + uint32_t); + void (*free)(void *, struct tmem_pool *, struct tmem_oid *, uint32_t); + void (*free_obj)(struct tmem_pool *, struct tmem_obj *); + bool (*is_remote)(void *); + void (*new_obj)(struct tmem_obj *); + int (*replace_in_obj)(void *, struct tmem_obj *); }; extern void tmem_register_pamops(struct tmem_pamops *m); @@ -184,9 +193,11 @@ extern void tmem_register_hostops(struct tmem_hostops *m); /* core tmem accessor functions */ extern int tmem_put(struct tmem_pool *, struct tmem_oid *, uint32_t index, - struct page *page); + char *, size_t, bool, bool); extern int tmem_get(struct tmem_pool *, struct tmem_oid *, uint32_t index, - struct page *page); + char *, size_t *, bool, int); +extern int tmem_replace(struct tmem_pool *, struct tmem_oid *, uint32_t index, + void *); extern int tmem_flush_page(struct tmem_pool *, struct tmem_oid *, uint32_t index); extern int tmem_flush_object(struct tmem_pool *, struct tmem_oid *); diff --git a/drivers/staging/zcache/zcache.c b/drivers/staging/zcache/zcache.c index 77ac2d4d3ef1..65a81a0d7c49 100644 --- a/drivers/staging/zcache/zcache.c +++ b/drivers/staging/zcache/zcache.c @@ -49,6 +49,33 @@ (__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | __GFP_NOMEMALLOC) #endif +#define MAX_POOLS_PER_CLIENT 16 + +#define MAX_CLIENTS 16 +#define LOCAL_CLIENT ((uint16_t)-1) +struct zcache_client { + struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT]; + struct xv_pool *xvpool; + bool allocated; + atomic_t refcount; +}; + +static struct zcache_client zcache_host; +static struct zcache_client zcache_clients[MAX_CLIENTS]; + +static inline uint16_t get_client_id_from_client(struct zcache_client *cli) +{ + BUG_ON(cli == NULL); + if (cli == &zcache_host) + return LOCAL_CLIENT; + return cli - &zcache_clients[0]; +} + +static inline bool is_local_client(struct zcache_client *cli) +{ + return cli == &zcache_host; +} + /********** * Compression buddies ("zbud") provides for packing two (or, possibly * in the future, more) compressed ephemeral pages into a single "raw" @@ -72,7 +99,8 @@ #define ZBUD_MAX_BUDS 2 struct zbud_hdr { - uint32_t pool_id; + uint16_t client_id; + uint16_t pool_id; struct tmem_oid oid; uint32_t index; uint16_t size; /* compressed size in bytes, zero means unused */ @@ -120,6 +148,7 @@ static unsigned long zcache_zbud_curr_zbytes; static unsigned long zcache_zbud_cumul_zpages; static unsigned long zcache_zbud_cumul_zbytes; static unsigned long zcache_compress_poor; +static unsigned long zcache_mean_compress_poor; /* forward references */ static void *zcache_get_free_page(void); @@ -294,7 +323,8 @@ static void zbud_free_and_delist(struct zbud_hdr *zh) } } -static struct zbud_hdr *zbud_create(uint32_t pool_id, struct tmem_oid *oid, +static struct zbud_hdr *zbud_create(uint16_t client_id, uint16_t pool_id, + struct tmem_oid *oid, uint32_t index, struct page *page, void *cdata, unsigned size) { @@ -353,6 +383,7 @@ static struct zbud_hdr *zbud_create(uint32_t pool_id, struct tmem_oid *oid, zh->index = index; zh->oid = *oid; zh->pool_id = pool_id; + zh->client_id = client_id; /* can wait to copy the data until the list locks are dropped */ spin_unlock(&zbud_budlists_spinlock); @@ -407,7 +438,8 @@ static unsigned long zcache_evicted_raw_pages; static unsigned long zcache_evicted_buddied_pages; static unsigned long zcache_evicted_unbuddied_pages; -static struct tmem_pool *zcache_get_pool_by_id(uint32_t poolid); +static struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id, + uint16_t poolid); static void zcache_put_pool(struct tmem_pool *pool); /* @@ -417,7 +449,8 @@ static void zbud_evict_zbpg(struct zbud_page *zbpg) { struct zbud_hdr *zh; int i, j; - uint32_t pool_id[ZBUD_MAX_BUDS], index[ZBUD_MAX_BUDS]; + uint32_t pool_id[ZBUD_MAX_BUDS], client_id[ZBUD_MAX_BUDS]; + uint32_t index[ZBUD_MAX_BUDS]; struct tmem_oid oid[ZBUD_MAX_BUDS]; struct tmem_pool *pool; @@ -426,6 +459,7 @@ static void zbud_evict_zbpg(struct zbud_page *zbpg) for (i = 0, j = 0; i < ZBUD_MAX_BUDS; i++) { zh = &zbpg->buddy[i]; if (zh->size) { + client_id[j] = zh->client_id; pool_id[j] = zh->pool_id; oid[j] = zh->oid; index[j] = zh->index; @@ -435,7 +469,7 @@ static void zbud_evict_zbpg(struct zbud_page *zbpg) } spin_unlock(&zbpg->lock); for (i = 0; i < j; i++) { - pool = zcache_get_pool_by_id(pool_id[i]); + pool = zcache_get_pool_by_id(client_id[i], pool_id[i]); if (pool != NULL) { tmem_flush_page(pool, &oid[i], index[i]); zcache_put_pool(pool); @@ -552,9 +586,8 @@ static int zbud_show_unbuddied_list_counts(char *buf) int i; char *p = buf; - for (i = 0; i < NCHUNKS - 1; i++) + for (i = 0; i < NCHUNKS; i++) p += sprintf(p, "%u ", zbud_unbuddied[i].count); - p += sprintf(p, "%d\n", zbud_unbuddied[i].count); return p - buf; } @@ -602,7 +635,23 @@ struct zv_hdr { DECL_SENTINEL }; -static const int zv_max_page_size = (PAGE_SIZE / 8) * 7; +/* rudimentary policy limits */ +/* total number of persistent pages may not exceed this percentage */ +static unsigned int zv_page_count_policy_percent = 75; +/* + * byte count defining poor compression; pages with greater zsize will be + * rejected + */ +static unsigned int zv_max_zsize = (PAGE_SIZE / 8) * 7; +/* + * byte count defining poor *mean* compression; pages with greater zsize + * will be rejected until sufficient better-compressed pages are accepted + * driving the man below this threshold + */ +static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5; + +static unsigned long zv_curr_dist_counts[NCHUNKS]; +static unsigned long zv_cumul_dist_counts[NCHUNKS]; static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id, struct tmem_oid *oid, uint32_t index, @@ -611,13 +660,18 @@ static struct zv_hdr *zv_create(struct xv_pool *xvpool, uint32_t pool_id, struct page *page; struct zv_hdr *zv = NULL; uint32_t offset; + int alloc_size = clen + sizeof(struct zv_hdr); + int chunks = (alloc_size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; int ret; BUG_ON(!irqs_disabled()); - ret = xv_malloc(xvpool, clen + sizeof(struct zv_hdr), + BUG_ON(chunks >= NCHUNKS); + ret = xv_malloc(xvpool, alloc_size, &page, &offset, ZCACHE_GFP_MASK); if (unlikely(ret)) goto out; + zv_curr_dist_counts[chunks]++; + zv_cumul_dist_counts[chunks]++; zv = kmap_atomic(page, KM_USER0) + offset; zv->index = index; zv->oid = *oid; @@ -634,11 +688,14 @@ static void zv_free(struct xv_pool *xvpool, struct zv_hdr *zv) unsigned long flags; struct page *page; uint32_t offset; - uint16_t size; + uint16_t size = xv_get_object_size(zv); + int chunks = (size + (CHUNK_SIZE - 1)) >> CHUNK_SHIFT; ASSERT_SENTINEL(zv, ZVH); - size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(size == 0 || size > zv_max_page_size); + BUG_ON(chunks >= NCHUNKS); + zv_curr_dist_counts[chunks]--; + size -= sizeof(*zv); + BUG_ON(size == 0); INVERT_SENTINEL(zv, ZVH); page = virt_to_page(zv); offset = (unsigned long)zv & ~PAGE_MASK; @@ -656,7 +713,7 @@ static void zv_decompress(struct page *page, struct zv_hdr *zv) ASSERT_SENTINEL(zv, ZVH); size = xv_get_object_size(zv) - sizeof(*zv); - BUG_ON(size == 0 || size > zv_max_page_size); + BUG_ON(size == 0); to_va = kmap_atomic(page, KM_USER0); ret = lzo1x_decompress_safe((char *)zv + sizeof(*zv), size, to_va, &clen); @@ -665,6 +722,159 @@ static void zv_decompress(struct page *page, struct zv_hdr *zv) BUG_ON(clen != PAGE_SIZE); } +#ifdef CONFIG_SYSFS +/* + * show a distribution of compression stats for zv pages. + */ + +static int zv_curr_dist_counts_show(char *buf) +{ + unsigned long i, n, chunks = 0, sum_total_chunks = 0; + char *p = buf; + + for (i = 0; i < NCHUNKS; i++) { + n = zv_curr_dist_counts[i]; + p += sprintf(p, "%lu ", n); + chunks += n; + sum_total_chunks += i * n; + } + p += sprintf(p, "mean:%lu\n", + chunks == 0 ? 0 : sum_total_chunks / chunks); + return p - buf; +} + +static int zv_cumul_dist_counts_show(char *buf) +{ + unsigned long i, n, chunks = 0, sum_total_chunks = 0; + char *p = buf; + + for (i = 0; i < NCHUNKS; i++) { + n = zv_cumul_dist_counts[i]; + p += sprintf(p, "%lu ", n); + chunks += n; + sum_total_chunks += i * n; + } + p += sprintf(p, "mean:%lu\n", + chunks == 0 ? 0 : sum_total_chunks / chunks); + return p - buf; +} + +/* + * setting zv_max_zsize via sysfs causes all persistent (e.g. swap) + * pages that don't compress to less than this value (including metadata + * overhead) to be rejected. We don't allow the value to get too close + * to PAGE_SIZE. + */ +static ssize_t zv_max_zsize_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%u\n", zv_max_zsize); +} + +static ssize_t zv_max_zsize_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + unsigned long val; + int err; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + err = strict_strtoul(buf, 10, &val); + if (err || (val == 0) || (val > (PAGE_SIZE / 8) * 7)) + return -EINVAL; + zv_max_zsize = val; + return count; +} + +/* + * setting zv_max_mean_zsize via sysfs causes all persistent (e.g. swap) + * pages that don't compress to less than this value (including metadata + * overhead) to be rejected UNLESS the mean compression is also smaller + * than this value. In other words, we are load-balancing-by-zsize the + * accepted pages. Again, we don't allow the value to get too close + * to PAGE_SIZE. + */ +static ssize_t zv_max_mean_zsize_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%u\n", zv_max_mean_zsize); +} + +static ssize_t zv_max_mean_zsize_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + unsigned long val; + int err; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + err = strict_strtoul(buf, 10, &val); + if (err || (val == 0) || (val > (PAGE_SIZE / 8) * 7)) + return -EINVAL; + zv_max_mean_zsize = val; + return count; +} + +/* + * setting zv_page_count_policy_percent via sysfs sets an upper bound of + * persistent (e.g. swap) pages that will be retained according to: + * (zv_page_count_policy_percent * totalram_pages) / 100) + * when that limit is reached, further puts will be rejected (until + * some pages have been flushed). Note that, due to compression, + * this number may exceed 100; it defaults to 75 and we set an + * arbitary limit of 150. A poor choice will almost certainly result + * in OOM's, so this value should only be changed prudently. + */ +static ssize_t zv_page_count_policy_percent_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%u\n", zv_page_count_policy_percent); +} + +static ssize_t zv_page_count_policy_percent_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + unsigned long val; + int err; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + err = strict_strtoul(buf, 10, &val); + if (err || (val == 0) || (val > 150)) + return -EINVAL; + zv_page_count_policy_percent = val; + return count; +} + +static struct kobj_attribute zcache_zv_max_zsize_attr = { + .attr = { .name = "zv_max_zsize", .mode = 0644 }, + .show = zv_max_zsize_show, + .store = zv_max_zsize_store, +}; + +static struct kobj_attribute zcache_zv_max_mean_zsize_attr = { + .attr = { .name = "zv_max_mean_zsize", .mode = 0644 }, + .show = zv_max_mean_zsize_show, + .store = zv_max_mean_zsize_store, +}; + +static struct kobj_attribute zcache_zv_page_count_policy_percent_attr = { + .attr = { .name = "zv_page_count_policy_percent", + .mode = 0644 }, + .show = zv_page_count_policy_percent_show, + .store = zv_page_count_policy_percent_store, +}; +#endif + /* * zcache core code starts here */ @@ -677,36 +887,70 @@ static unsigned long zcache_flobj_found; static unsigned long zcache_failed_eph_puts; static unsigned long zcache_failed_pers_puts; -#define MAX_POOLS_PER_CLIENT 16 - -static struct { - struct tmem_pool *tmem_pools[MAX_POOLS_PER_CLIENT]; - struct xv_pool *xvpool; -} zcache_client; - /* * Tmem operations assume the poolid implies the invoking client. - * Zcache only has one client (the kernel itself), so translate - * the poolid into the tmem_pool allocated for it. A KVM version + * Zcache only has one client (the kernel itself): LOCAL_CLIENT. + * RAMster has each client numbered by cluster node, and a KVM version * of zcache would have one client per guest and each client might * have a poolid==N. */ -static struct tmem_pool *zcache_get_pool_by_id(uint32_t poolid) +static struct tmem_pool *zcache_get_pool_by_id(uint16_t cli_id, uint16_t poolid) { struct tmem_pool *pool = NULL; + struct zcache_client *cli = NULL; - if (poolid >= 0) { - pool = zcache_client.tmem_pools[poolid]; + if (cli_id == LOCAL_CLIENT) + cli = &zcache_host; + else { + if (cli_id >= MAX_CLIENTS) + goto out; + cli = &zcache_clients[cli_id]; + if (cli == NULL) + goto out; + atomic_inc(&cli->refcount); + } + if (poolid < MAX_POOLS_PER_CLIENT) { + pool = cli->tmem_pools[poolid]; if (pool != NULL) atomic_inc(&pool->refcount); } +out: return pool; } static void zcache_put_pool(struct tmem_pool *pool) { - if (pool != NULL) - atomic_dec(&pool->refcount); + struct zcache_client *cli = NULL; + + if (pool == NULL) + BUG(); + cli = pool->client; + atomic_dec(&pool->refcount); + atomic_dec(&cli->refcount); +} + +int zcache_new_client(uint16_t cli_id) +{ + struct zcache_client *cli = NULL; + int ret = -1; + + if (cli_id == LOCAL_CLIENT) + cli = &zcache_host; + else if ((unsigned int)cli_id < MAX_CLIENTS) + cli = &zcache_clients[cli_id]; + if (cli == NULL) + goto out; + if (cli->allocated) + goto out; + cli->allocated = 1; +#ifdef CONFIG_FRONTSWAP + cli->xvpool = xv_create_pool(); + if (cli->xvpool == NULL) + goto out; +#endif + ret = 0; +out: + return ret; } /* counters for debugging */ @@ -901,48 +1145,59 @@ static unsigned long zcache_curr_pers_pampd_count_max; /* forward reference */ static int zcache_compress(struct page *from, void **out_va, size_t *out_len); -static void *zcache_pampd_create(struct tmem_pool *pool, struct tmem_oid *oid, - uint32_t index, struct page *page) +static void *zcache_pampd_create(char *data, size_t size, bool raw, int eph, + struct tmem_pool *pool, struct tmem_oid *oid, + uint32_t index) { void *pampd = NULL, *cdata; size_t clen; int ret; - bool ephemeral = is_ephemeral(pool); unsigned long count; + struct page *page = virt_to_page(data); + struct zcache_client *cli = pool->client; + uint16_t client_id = get_client_id_from_client(cli); + unsigned long zv_mean_zsize; + unsigned long curr_pers_pampd_count; - if (ephemeral) { + if (eph) { ret = zcache_compress(page, &cdata, &clen); if (ret == 0) - goto out; if (clen == 0 || clen > zbud_max_buddy_size()) { zcache_compress_poor++; goto out; } - pampd = (void *)zbud_create(pool->pool_id, oid, index, - page, cdata, clen); + pampd = (void *)zbud_create(client_id, pool->pool_id, oid, + index, page, cdata, clen); if (pampd != NULL) { count = atomic_inc_return(&zcache_curr_eph_pampd_count); if (count > zcache_curr_eph_pampd_count_max) zcache_curr_eph_pampd_count_max = count; } } else { - /* - * FIXME: This is all the "policy" there is for now. - * 3/4 totpages should allow ~37% of RAM to be filled with - * compressed frontswap pages - */ - if (atomic_read(&zcache_curr_pers_pampd_count) > - 3 * totalram_pages / 4) + curr_pers_pampd_count = + atomic_read(&zcache_curr_pers_pampd_count); + if (curr_pers_pampd_count > + (zv_page_count_policy_percent * totalram_pages) / 100) goto out; ret = zcache_compress(page, &cdata, &clen); if (ret == 0) goto out; - if (clen > zv_max_page_size) { + /* reject if compression is too poor */ + if (clen > zv_max_zsize) { zcache_compress_poor++; goto out; } - pampd = (void *)zv_create(zcache_client.xvpool, pool->pool_id, + /* reject if mean compression is too poor */ + if ((clen > zv_max_mean_zsize) && (curr_pers_pampd_count > 0)) { + zv_mean_zsize = xv_get_total_size_bytes(cli->xvpool) / + curr_pers_pampd_count; + if (zv_mean_zsize > zv_max_mean_zsize) { + zcache_mean_compress_poor++; + goto out; + } + } + pampd = (void *)zv_create(cli->xvpool, pool->pool_id, oid, index, cdata, clen); if (pampd == NULL) goto out; @@ -958,15 +1213,31 @@ static void *zcache_pampd_create(struct tmem_pool *pool, struct tmem_oid *oid, * fill the pageframe corresponding to the struct page with the data * from the passed pampd */ -static int zcache_pampd_get_data(struct page *page, void *pampd, - struct tmem_pool *pool) +static int zcache_pampd_get_data(char *data, size_t *bufsize, bool raw, + void *pampd, struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index) { int ret = 0; - if (is_ephemeral(pool)) - ret = zbud_decompress(page, pampd); - else - zv_decompress(page, pampd); + BUG_ON(is_ephemeral(pool)); + zv_decompress(virt_to_page(data), pampd); + return ret; +} + +/* + * fill the pageframe corresponding to the struct page with the data + * from the passed pampd + */ +static int zcache_pampd_get_data_and_free(char *data, size_t *bufsize, bool raw, + void *pampd, struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index) +{ + int ret = 0; + + BUG_ON(!is_ephemeral(pool)); + zbud_decompress(virt_to_page(data), pampd); + zbud_free_and_delist((struct zbud_hdr *)pampd); + atomic_dec(&zcache_curr_eph_pampd_count); return ret; } @@ -974,23 +1245,49 @@ static int zcache_pampd_get_data(struct page *page, void *pampd, * free the pampd and remove it from any zcache lists * pampd must no longer be pointed to from any tmem data structures! */ -static void zcache_pampd_free(void *pampd, struct tmem_pool *pool) +static void zcache_pampd_free(void *pampd, struct tmem_pool *pool, + struct tmem_oid *oid, uint32_t index) { + struct zcache_client *cli = pool->client; + if (is_ephemeral(pool)) { zbud_free_and_delist((struct zbud_hdr *)pampd); atomic_dec(&zcache_curr_eph_pampd_count); BUG_ON(atomic_read(&zcache_curr_eph_pampd_count) < 0); } else { - zv_free(zcache_client.xvpool, (struct zv_hdr *)pampd); + zv_free(cli->xvpool, (struct zv_hdr *)pampd); atomic_dec(&zcache_curr_pers_pampd_count); BUG_ON(atomic_read(&zcache_curr_pers_pampd_count) < 0); } } +static void zcache_pampd_free_obj(struct tmem_pool *pool, struct tmem_obj *obj) +{ +} + +static void zcache_pampd_new_obj(struct tmem_obj *obj) +{ +} + +static int zcache_pampd_replace_in_obj(void *pampd, struct tmem_obj *obj) +{ + return -1; +} + +static bool zcache_pampd_is_remote(void *pampd) +{ + return 0; +} + static struct tmem_pamops zcache_pamops = { .create = zcache_pampd_create, .get_data = zcache_pampd_get_data, + .get_data_and_free = zcache_pampd_get_data_and_free, .free = zcache_pampd_free, + .free_obj = zcache_pampd_free_obj, + .new_obj = zcache_pampd_new_obj, + .replace_in_obj = zcache_pampd_replace_in_obj, + .is_remote = zcache_pampd_is_remote, }; /* @@ -1122,6 +1419,7 @@ ZCACHE_SYSFS_RO(put_to_flush); ZCACHE_SYSFS_RO(aborted_preload); ZCACHE_SYSFS_RO(aborted_shrink); ZCACHE_SYSFS_RO(compress_poor); +ZCACHE_SYSFS_RO(mean_compress_poor); ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_raw_pages); ZCACHE_SYSFS_RO_ATOMIC(zbud_curr_zpages); ZCACHE_SYSFS_RO_ATOMIC(curr_obj_count); @@ -1130,6 +1428,10 @@ ZCACHE_SYSFS_RO_CUSTOM(zbud_unbuddied_list_counts, zbud_show_unbuddied_list_counts); ZCACHE_SYSFS_RO_CUSTOM(zbud_cumul_chunk_counts, zbud_show_cumul_chunk_counts); +ZCACHE_SYSFS_RO_CUSTOM(zv_curr_dist_counts, + zv_curr_dist_counts_show); +ZCACHE_SYSFS_RO_CUSTOM(zv_cumul_dist_counts, + zv_cumul_dist_counts_show); static struct attribute *zcache_attrs[] = { &zcache_curr_obj_count_attr.attr, @@ -1143,6 +1445,7 @@ static struct attribute *zcache_attrs[] = { &zcache_failed_eph_puts_attr.attr, &zcache_failed_pers_puts_attr.attr, &zcache_compress_poor_attr.attr, + &zcache_mean_compress_poor_attr.attr, &zcache_zbud_curr_raw_pages_attr.attr, &zcache_zbud_curr_zpages_attr.attr, &zcache_zbud_curr_zbytes_attr.attr, @@ -1160,6 +1463,11 @@ static struct attribute *zcache_attrs[] = { &zcache_aborted_shrink_attr.attr, &zcache_zbud_unbuddied_list_counts_attr.attr, &zcache_zbud_cumul_chunk_counts_attr.attr, + &zcache_zv_curr_dist_counts_attr.attr, + &zcache_zv_cumul_dist_counts_attr.attr, + &zcache_zv_max_zsize_attr.attr, + &zcache_zv_max_mean_zsize_attr.attr, + &zcache_zv_page_count_policy_percent_attr.attr, NULL, }; @@ -1212,19 +1520,20 @@ static struct shrinker zcache_shrinker = { * zcache shims between cleancache/frontswap ops and tmem */ -static int zcache_put_page(int pool_id, struct tmem_oid *oidp, +static int zcache_put_page(int cli_id, int pool_id, struct tmem_oid *oidp, uint32_t index, struct page *page) { struct tmem_pool *pool; int ret = -1; BUG_ON(!irqs_disabled()); - pool = zcache_get_pool_by_id(pool_id); + pool = zcache_get_pool_by_id(cli_id, pool_id); if (unlikely(pool == NULL)) goto out; if (!zcache_freeze && zcache_do_preload(pool) == 0) { /* preload does preempt_disable on success */ - ret = tmem_put(pool, oidp, index, page); + ret = tmem_put(pool, oidp, index, page_address(page), + PAGE_SIZE, 0, is_ephemeral(pool)); if (ret < 0) { if (is_ephemeral(pool)) zcache_failed_eph_puts++; @@ -1244,25 +1553,28 @@ static int zcache_put_page(int pool_id, struct tmem_oid *oidp, return ret; } -static int zcache_get_page(int pool_id, struct tmem_oid *oidp, +static int zcache_get_page(int cli_id, int pool_id, struct tmem_oid *oidp, uint32_t index, struct page *page) { struct tmem_pool *pool; int ret = -1; unsigned long flags; + size_t size = PAGE_SIZE; local_irq_save(flags); - pool = zcache_get_pool_by_id(pool_id); + pool = zcache_get_pool_by_id(cli_id, pool_id); if (likely(pool != NULL)) { if (atomic_read(&pool->obj_count) > 0) - ret = tmem_get(pool, oidp, index, page); + ret = tmem_get(pool, oidp, index, page_address(page), + &size, 0, is_ephemeral(pool)); zcache_put_pool(pool); } local_irq_restore(flags); return ret; } -static int zcache_flush_page(int pool_id, struct tmem_oid *oidp, uint32_t index) +static int zcache_flush_page(int cli_id, int pool_id, + struct tmem_oid *oidp, uint32_t index) { struct tmem_pool *pool; int ret = -1; @@ -1270,7 +1582,7 @@ static int zcache_flush_page(int pool_id, struct tmem_oid *oidp, uint32_t index) local_irq_save(flags); zcache_flush_total++; - pool = zcache_get_pool_by_id(pool_id); + pool = zcache_get_pool_by_id(cli_id, pool_id); if (likely(pool != NULL)) { if (atomic_read(&pool->obj_count) > 0) ret = tmem_flush_page(pool, oidp, index); @@ -1282,7 +1594,8 @@ static int zcache_flush_page(int pool_id, struct tmem_oid *oidp, uint32_t index) return ret; } -static int zcache_flush_object(int pool_id, struct tmem_oid *oidp) +static int zcache_flush_object(int cli_id, int pool_id, + struct tmem_oid *oidp) { struct tmem_pool *pool; int ret = -1; @@ -1290,7 +1603,7 @@ static int zcache_flush_object(int pool_id, struct tmem_oid *oidp) local_irq_save(flags); zcache_flobj_total++; - pool = zcache_get_pool_by_id(pool_id); + pool = zcache_get_pool_by_id(cli_id, pool_id); if (likely(pool != NULL)) { if (atomic_read(&pool->obj_count) > 0) ret = tmem_flush_object(pool, oidp); @@ -1302,34 +1615,52 @@ static int zcache_flush_object(int pool_id, struct tmem_oid *oidp) return ret; } -static int zcache_destroy_pool(int pool_id) +static int zcache_destroy_pool(int cli_id, int pool_id) { struct tmem_pool *pool = NULL; + struct zcache_client *cli = NULL; int ret = -1; if (pool_id < 0) goto out; - pool = zcache_client.tmem_pools[pool_id]; + if (cli_id == LOCAL_CLIENT) + cli = &zcache_host; + else if ((unsigned int)cli_id < MAX_CLIENTS) + cli = &zcache_clients[cli_id]; + if (cli == NULL) + goto out; + atomic_inc(&cli->refcount); + pool = cli->tmem_pools[pool_id]; if (pool == NULL) goto out; - zcache_client.tmem_pools[pool_id] = NULL; + cli->tmem_pools[pool_id] = NULL; /* wait for pool activity on other cpus to quiesce */ while (atomic_read(&pool->refcount) != 0) ; + atomic_dec(&cli->refcount); local_bh_disable(); ret = tmem_destroy_pool(pool); local_bh_enable(); kfree(pool); - pr_info("zcache: destroyed pool id=%d\n", pool_id); + pr_info("zcache: destroyed pool id=%d, cli_id=%d\n", + pool_id, cli_id); out: return ret; } -static int zcache_new_pool(uint32_t flags) +static int zcache_new_pool(uint16_t cli_id, uint32_t flags) { int poolid = -1; struct tmem_pool *pool; + struct zcache_client *cli = NULL; + if (cli_id == LOCAL_CLIENT) + cli = &zcache_host; + else if ((unsigned int)cli_id < MAX_CLIENTS) + cli = &zcache_clients[cli_id]; + if (cli == NULL) + goto out; + atomic_inc(&cli->refcount); pool = kmalloc(sizeof(struct tmem_pool), GFP_KERNEL); if (pool == NULL) { pr_info("zcache: pool creation failed: out of memory\n"); @@ -1337,7 +1668,7 @@ static int zcache_new_pool(uint32_t flags) } for (poolid = 0; poolid < MAX_POOLS_PER_CLIENT; poolid++) - if (zcache_client.tmem_pools[poolid] == NULL) + if (cli->tmem_pools[poolid] == NULL) break; if (poolid >= MAX_POOLS_PER_CLIENT) { pr_info("zcache: pool creation failed: max exceeded\n"); @@ -1346,14 +1677,16 @@ static int zcache_new_pool(uint32_t flags) goto out; } atomic_set(&pool->refcount, 0); - pool->client = &zcache_client; + pool->client = cli; pool->pool_id = poolid; tmem_new_pool(pool, flags); - zcache_client.tmem_pools[poolid] = pool; - pr_info("zcache: created %s tmem pool, id=%d\n", + cli->tmem_pools[poolid] = pool; + pr_info("zcache: created %s tmem pool, id=%d, client=%d\n", flags & TMEM_POOL_PERSIST ? "persistent" : "ephemeral", - poolid); + poolid, cli_id); out: + if (cli != NULL) + atomic_dec(&cli->refcount); return poolid; } @@ -1374,7 +1707,7 @@ static void zcache_cleancache_put_page(int pool_id, struct tmem_oid oid = *(struct tmem_oid *)&key; if (likely(ind == index)) - (void)zcache_put_page(pool_id, &oid, index, page); + (void)zcache_put_page(LOCAL_CLIENT, pool_id, &oid, index, page); } static int zcache_cleancache_get_page(int pool_id, @@ -1386,7 +1719,7 @@ static int zcache_cleancache_get_page(int pool_id, int ret = -1; if (likely(ind == index)) - ret = zcache_get_page(pool_id, &oid, index, page); + ret = zcache_get_page(LOCAL_CLIENT, pool_id, &oid, index, page); return ret; } @@ -1398,7 +1731,7 @@ static void zcache_cleancache_flush_page(int pool_id, struct tmem_oid oid = *(struct tmem_oid *)&key; if (likely(ind == index)) - (void)zcache_flush_page(pool_id, &oid, ind); + (void)zcache_flush_page(LOCAL_CLIENT, pool_id, &oid, ind); } static void zcache_cleancache_flush_inode(int pool_id, @@ -1406,13 +1739,13 @@ static void zcache_cleancache_flush_inode(int pool_id, { struct tmem_oid oid = *(struct tmem_oid *)&key; - (void)zcache_flush_object(pool_id, &oid); + (void)zcache_flush_object(LOCAL_CLIENT, pool_id, &oid); } static void zcache_cleancache_flush_fs(int pool_id) { if (pool_id >= 0) - (void)zcache_destroy_pool(pool_id); + (void)zcache_destroy_pool(LOCAL_CLIENT, pool_id); } static int zcache_cleancache_init_fs(size_t pagesize) @@ -1420,7 +1753,7 @@ static int zcache_cleancache_init_fs(size_t pagesize) BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid)); BUG_ON(pagesize != PAGE_SIZE); - return zcache_new_pool(0); + return zcache_new_pool(LOCAL_CLIENT, 0); } static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) @@ -1429,7 +1762,7 @@ static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid)); BUG_ON(pagesize != PAGE_SIZE); - return zcache_new_pool(0); + return zcache_new_pool(LOCAL_CLIENT, 0); } static struct cleancache_ops zcache_cleancache_ops = { @@ -1483,8 +1816,8 @@ static int zcache_frontswap_put_page(unsigned type, pgoff_t offset, BUG_ON(!PageLocked(page)); if (likely(ind64 == ind)) { local_irq_save(flags); - ret = zcache_put_page(zcache_frontswap_poolid, &oid, - iswiz(ind), page); + ret = zcache_put_page(LOCAL_CLIENT, zcache_frontswap_poolid, + &oid, iswiz(ind), page); local_irq_restore(flags); } return ret; @@ -1502,8 +1835,8 @@ static int zcache_frontswap_get_page(unsigned type, pgoff_t offset, BUG_ON(!PageLocked(page)); if (likely(ind64 == ind)) - ret = zcache_get_page(zcache_frontswap_poolid, &oid, - iswiz(ind), page); + ret = zcache_get_page(LOCAL_CLIENT, zcache_frontswap_poolid, + &oid, iswiz(ind), page); return ret; } @@ -1515,8 +1848,8 @@ static void zcache_frontswap_flush_page(unsigned type, pgoff_t offset) struct tmem_oid oid = oswiz(type, ind); if (likely(ind64 == ind)) - (void)zcache_flush_page(zcache_frontswap_poolid, &oid, - iswiz(ind)); + (void)zcache_flush_page(LOCAL_CLIENT, zcache_frontswap_poolid, + &oid, iswiz(ind)); } /* flush all pages from the passed swaptype */ @@ -1527,7 +1860,8 @@ static void zcache_frontswap_flush_area(unsigned type) for (ind = SWIZ_MASK; ind >= 0; ind--) { oid = oswiz(type, ind); - (void)zcache_flush_object(zcache_frontswap_poolid, &oid); + (void)zcache_flush_object(LOCAL_CLIENT, + zcache_frontswap_poolid, &oid); } } @@ -1535,7 +1869,8 @@ static void zcache_frontswap_init(unsigned ignored) { /* a single tmem poolid is used for all frontswap "types" (swapfiles) */ if (zcache_frontswap_poolid < 0) - zcache_frontswap_poolid = zcache_new_pool(TMEM_POOL_PERSIST); + zcache_frontswap_poolid = + zcache_new_pool(LOCAL_CLIENT, TMEM_POOL_PERSIST); } static struct frontswap_ops zcache_frontswap_ops = { @@ -1624,6 +1959,11 @@ static int __init zcache_init(void) sizeof(struct tmem_objnode), 0, 0, NULL); zcache_obj_cache = kmem_cache_create("zcache_obj", sizeof(struct tmem_obj), 0, 0, NULL); + ret = zcache_new_client(LOCAL_CLIENT); + if (ret) { + pr_err("zcache: can't create client\n"); + goto out; + } #endif #ifdef CONFIG_CLEANCACHE if (zcache_enabled && use_cleancache) { @@ -1642,11 +1982,6 @@ static int __init zcache_init(void) if (zcache_enabled && use_frontswap) { struct frontswap_ops old_ops; - zcache_client.xvpool = xv_create_pool(); - if (zcache_client.xvpool == NULL) { - pr_err("zcache: can't create xvpool\n"); - goto out; - } old_ops = zcache_frontswap_register_ops(); pr_info("zcache: frontswap enabled using kernel " "transcendent memory and xvmalloc\n"); diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index aab4ec482124..d70ec1ad10de 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -177,224 +177,355 @@ static void zram_free_page(struct zram *zram, size_t index) zram->table[index].offset = 0; } -static void handle_zero_page(struct page *page) +static void handle_zero_page(struct bio_vec *bvec) { + struct page *page = bvec->bv_page; void *user_mem; user_mem = kmap_atomic(page, KM_USER0); - memset(user_mem, 0, PAGE_SIZE); + memset(user_mem + bvec->bv_offset, 0, bvec->bv_len); kunmap_atomic(user_mem, KM_USER0); flush_dcache_page(page); } -static void handle_uncompressed_page(struct zram *zram, - struct page *page, u32 index) +static void handle_uncompressed_page(struct zram *zram, struct bio_vec *bvec, + u32 index, int offset) { + struct page *page = bvec->bv_page; unsigned char *user_mem, *cmem; user_mem = kmap_atomic(page, KM_USER0); - cmem = kmap_atomic(zram->table[index].page, KM_USER1) + - zram->table[index].offset; + cmem = kmap_atomic(zram->table[index].page, KM_USER1); - memcpy(user_mem, cmem, PAGE_SIZE); - kunmap_atomic(user_mem, KM_USER0); + memcpy(user_mem + bvec->bv_offset, cmem + offset, bvec->bv_len); kunmap_atomic(cmem, KM_USER1); + kunmap_atomic(user_mem, KM_USER0); flush_dcache_page(page); } -static void zram_read(struct zram *zram, struct bio *bio) +static inline int is_partial_io(struct bio_vec *bvec) { - - int i; - u32 index; - struct bio_vec *bvec; - - zram_stat64_inc(zram, &zram->stats.num_reads); - index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; - - bio_for_each_segment(bvec, bio, i) { - int ret; - size_t clen; - struct page *page; - struct zobj_header *zheader; - unsigned char *user_mem, *cmem; - - page = bvec->bv_page; - - if (zram_test_flag(zram, index, ZRAM_ZERO)) { - handle_zero_page(page); - index++; - continue; - } - - /* Requested page is not present in compressed area */ - if (unlikely(!zram->table[index].page)) { - pr_debug("Read before write: sector=%lu, size=%u", - (ulong)(bio->bi_sector), bio->bi_size); - handle_zero_page(page); - index++; - continue; - } - - /* Page is stored uncompressed since it's incompressible */ - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { - handle_uncompressed_page(zram, page, index); - index++; - continue; - } - - user_mem = kmap_atomic(page, KM_USER0); - clen = PAGE_SIZE; - - cmem = kmap_atomic(zram->table[index].page, KM_USER1) + - zram->table[index].offset; - - ret = lzo1x_decompress_safe( - cmem + sizeof(*zheader), - xv_get_object_size(cmem) - sizeof(*zheader), - user_mem, &clen); - - kunmap_atomic(user_mem, KM_USER0); - kunmap_atomic(cmem, KM_USER1); - - /* Should NEVER happen. Return bio error if it does. */ - if (unlikely(ret != LZO_E_OK)) { - pr_err("Decompression failed! err=%d, page=%u\n", - ret, index); - zram_stat64_inc(zram, &zram->stats.failed_reads); - goto out; - } - - flush_dcache_page(page); - index++; - } - - set_bit(BIO_UPTODATE, &bio->bi_flags); - bio_endio(bio, 0); - return; - -out: - bio_io_error(bio); + return bvec->bv_len != PAGE_SIZE; } -static void zram_write(struct zram *zram, struct bio *bio) +static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, + u32 index, int offset, struct bio *bio) { - int i; + int ret; + size_t clen; + struct page *page; + struct zobj_header *zheader; + unsigned char *user_mem, *cmem, *uncmem = NULL; + + page = bvec->bv_page; + + if (zram_test_flag(zram, index, ZRAM_ZERO)) { + handle_zero_page(bvec); + return 0; + } + + /* Requested page is not present in compressed area */ + if (unlikely(!zram->table[index].page)) { + pr_debug("Read before write: sector=%lu, size=%u", + (ulong)(bio->bi_sector), bio->bi_size); + handle_zero_page(bvec); + return 0; + } + + /* Page is stored uncompressed since it's incompressible */ + if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { + handle_uncompressed_page(zram, bvec, index, offset); + return 0; + } + + if (is_partial_io(bvec)) { + /* Use a temporary buffer to decompress the page */ + uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!uncmem) { + pr_info("Error allocating temp memory!\n"); + return -ENOMEM; + } + } + + user_mem = kmap_atomic(page, KM_USER0); + if (!is_partial_io(bvec)) + uncmem = user_mem; + clen = PAGE_SIZE; + + cmem = kmap_atomic(zram->table[index].page, KM_USER1) + + zram->table[index].offset; + + ret = lzo1x_decompress_safe(cmem + sizeof(*zheader), + xv_get_object_size(cmem) - sizeof(*zheader), + uncmem, &clen); + + if (is_partial_io(bvec)) { + memcpy(user_mem + bvec->bv_offset, uncmem + offset, + bvec->bv_len); + kfree(uncmem); + } + + kunmap_atomic(cmem, KM_USER1); + kunmap_atomic(user_mem, KM_USER0); + + /* Should NEVER happen. Return bio error if it does. */ + if (unlikely(ret != LZO_E_OK)) { + pr_err("Decompression failed! err=%d, page=%u\n", ret, index); + zram_stat64_inc(zram, &zram->stats.failed_reads); + return ret; + } + + flush_dcache_page(page); + + return 0; +} + +static int zram_read_before_write(struct zram *zram, char *mem, u32 index) +{ + int ret; + size_t clen = PAGE_SIZE; + struct zobj_header *zheader; + unsigned char *cmem; + + if (zram_test_flag(zram, index, ZRAM_ZERO) || + !zram->table[index].page) { + memset(mem, 0, PAGE_SIZE); + return 0; + } + + cmem = kmap_atomic(zram->table[index].page, KM_USER0) + + zram->table[index].offset; + + /* Page is stored uncompressed since it's incompressible */ + if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) { + memcpy(mem, cmem, PAGE_SIZE); + kunmap_atomic(cmem, KM_USER0); + return 0; + } + + ret = lzo1x_decompress_safe(cmem + sizeof(*zheader), + xv_get_object_size(cmem) - sizeof(*zheader), + mem, &clen); + kunmap_atomic(cmem, KM_USER0); + + /* Should NEVER happen. Return bio error if it does. */ + if (unlikely(ret != LZO_E_OK)) { + pr_err("Decompression failed! err=%d, page=%u\n", ret, index); + zram_stat64_inc(zram, &zram->stats.failed_reads); + return ret; + } + + return 0; +} + +static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, + int offset) +{ + int ret; + u32 store_offset; + size_t clen; + struct zobj_header *zheader; + struct page *page, *page_store; + unsigned char *user_mem, *cmem, *src, *uncmem = NULL; + + page = bvec->bv_page; + src = zram->compress_buffer; + + if (is_partial_io(bvec)) { + /* + * This is a partial IO. We need to read the full page + * before to write the changes. + */ + uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!uncmem) { + pr_info("Error allocating temp memory!\n"); + ret = -ENOMEM; + goto out; + } + ret = zram_read_before_write(zram, uncmem, index); + if (ret) { + kfree(uncmem); + goto out; + } + } + + /* + * System overwrites unused sectors. Free memory associated + * with this sector now. + */ + if (zram->table[index].page || + zram_test_flag(zram, index, ZRAM_ZERO)) + zram_free_page(zram, index); + + user_mem = kmap_atomic(page, KM_USER0); + + if (is_partial_io(bvec)) + memcpy(uncmem + offset, user_mem + bvec->bv_offset, + bvec->bv_len); + else + uncmem = user_mem; + + if (page_zero_filled(uncmem)) { + kunmap_atomic(user_mem, KM_USER0); + if (is_partial_io(bvec)) + kfree(uncmem); + zram_stat_inc(&zram->stats.pages_zero); + zram_set_flag(zram, index, ZRAM_ZERO); + ret = 0; + goto out; + } + + ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen, + zram->compress_workmem); + + kunmap_atomic(user_mem, KM_USER0); + if (is_partial_io(bvec)) + kfree(uncmem); + + if (unlikely(ret != LZO_E_OK)) { + pr_err("Compression failed! err=%d\n", ret); + goto out; + } + + /* + * Page is incompressible. Store it as-is (uncompressed) + * since we do not want to return too many disk write + * errors which has side effect of hanging the system. + */ + if (unlikely(clen > max_zpage_size)) { + clen = PAGE_SIZE; + page_store = alloc_page(GFP_NOIO | __GFP_HIGHMEM); + if (unlikely(!page_store)) { + pr_info("Error allocating memory for " + "incompressible page: %u\n", index); + ret = -ENOMEM; + goto out; + } + + store_offset = 0; + zram_set_flag(zram, index, ZRAM_UNCOMPRESSED); + zram_stat_inc(&zram->stats.pages_expand); + zram->table[index].page = page_store; + src = kmap_atomic(page, KM_USER0); + goto memstore; + } + + if (xv_malloc(zram->mem_pool, clen + sizeof(*zheader), + &zram->table[index].page, &store_offset, + GFP_NOIO | __GFP_HIGHMEM)) { + pr_info("Error allocating memory for compressed " + "page: %u, size=%zu\n", index, clen); + ret = -ENOMEM; + goto out; + } + +memstore: + zram->table[index].offset = store_offset; + + cmem = kmap_atomic(zram->table[index].page, KM_USER1) + + zram->table[index].offset; + +#if 0 + /* Back-reference needed for memory defragmentation */ + if (!zram_test_flag(zram, index, ZRAM_UNCOMPRESSED)) { + zheader = (struct zobj_header *)cmem; + zheader->table_idx = index; + cmem += sizeof(*zheader); + } +#endif + + memcpy(cmem, src, clen); + + kunmap_atomic(cmem, KM_USER1); + if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) + kunmap_atomic(src, KM_USER0); + + /* Update stats */ + zram_stat64_add(zram, &zram->stats.compr_size, clen); + zram_stat_inc(&zram->stats.pages_stored); + if (clen <= PAGE_SIZE / 2) + zram_stat_inc(&zram->stats.good_compress); + + return 0; + +out: + if (ret) + zram_stat64_inc(zram, &zram->stats.failed_writes); + return ret; +} + +static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index, + int offset, struct bio *bio, int rw) +{ + int ret; + + if (rw == READ) { + down_read(&zram->lock); + ret = zram_bvec_read(zram, bvec, index, offset, bio); + up_read(&zram->lock); + } else { + down_write(&zram->lock); + ret = zram_bvec_write(zram, bvec, index, offset); + up_write(&zram->lock); + } + + return ret; +} + +static void update_position(u32 *index, int *offset, struct bio_vec *bvec) +{ + if (*offset + bvec->bv_len >= PAGE_SIZE) + (*index)++; + *offset = (*offset + bvec->bv_len) % PAGE_SIZE; +} + +static void __zram_make_request(struct zram *zram, struct bio *bio, int rw) +{ + int i, offset; u32 index; struct bio_vec *bvec; - zram_stat64_inc(zram, &zram->stats.num_writes); + switch (rw) { + case READ: + zram_stat64_inc(zram, &zram->stats.num_reads); + break; + case WRITE: + zram_stat64_inc(zram, &zram->stats.num_writes); + break; + } + index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; + offset = (bio->bi_sector & (SECTORS_PER_PAGE - 1)) << SECTOR_SHIFT; bio_for_each_segment(bvec, bio, i) { - int ret; - u32 offset; - size_t clen; - struct zobj_header *zheader; - struct page *page, *page_store; - unsigned char *user_mem, *cmem, *src; + int max_transfer_size = PAGE_SIZE - offset; - page = bvec->bv_page; - src = zram->compress_buffer; + if (bvec->bv_len > max_transfer_size) { + /* + * zram_bvec_rw() can only make operation on a single + * zram page. Split the bio vector. + */ + struct bio_vec bv; - /* - * System overwrites unused sectors. Free memory associated - * with this sector now. - */ - if (zram->table[index].page || - zram_test_flag(zram, index, ZRAM_ZERO)) - zram_free_page(zram, index); + bv.bv_page = bvec->bv_page; + bv.bv_len = max_transfer_size; + bv.bv_offset = bvec->bv_offset; - mutex_lock(&zram->lock); - - user_mem = kmap_atomic(page, KM_USER0); - if (page_zero_filled(user_mem)) { - kunmap_atomic(user_mem, KM_USER0); - mutex_unlock(&zram->lock); - zram_stat_inc(&zram->stats.pages_zero); - zram_set_flag(zram, index, ZRAM_ZERO); - index++; - continue; - } - - ret = lzo1x_1_compress(user_mem, PAGE_SIZE, src, &clen, - zram->compress_workmem); - - kunmap_atomic(user_mem, KM_USER0); - - if (unlikely(ret != LZO_E_OK)) { - mutex_unlock(&zram->lock); - pr_err("Compression failed! err=%d\n", ret); - zram_stat64_inc(zram, &zram->stats.failed_writes); - goto out; - } - - /* - * Page is incompressible. Store it as-is (uncompressed) - * since we do not want to return too many disk write - * errors which has side effect of hanging the system. - */ - if (unlikely(clen > max_zpage_size)) { - clen = PAGE_SIZE; - page_store = alloc_page(GFP_NOIO | __GFP_HIGHMEM); - if (unlikely(!page_store)) { - mutex_unlock(&zram->lock); - pr_info("Error allocating memory for " - "incompressible page: %u\n", index); - zram_stat64_inc(zram, - &zram->stats.failed_writes); + if (zram_bvec_rw(zram, &bv, index, offset, bio, rw) < 0) goto out; - } - offset = 0; - zram_set_flag(zram, index, ZRAM_UNCOMPRESSED); - zram_stat_inc(&zram->stats.pages_expand); - zram->table[index].page = page_store; - src = kmap_atomic(page, KM_USER0); - goto memstore; - } + bv.bv_len = bvec->bv_len - max_transfer_size; + bv.bv_offset += max_transfer_size; + if (zram_bvec_rw(zram, &bv, index+1, 0, bio, rw) < 0) + goto out; + } else + if (zram_bvec_rw(zram, bvec, index, offset, bio, rw) + < 0) + goto out; - if (xv_malloc(zram->mem_pool, clen + sizeof(*zheader), - &zram->table[index].page, &offset, - GFP_NOIO | __GFP_HIGHMEM)) { - mutex_unlock(&zram->lock); - pr_info("Error allocating memory for compressed " - "page: %u, size=%zu\n", index, clen); - zram_stat64_inc(zram, &zram->stats.failed_writes); - goto out; - } - -memstore: - zram->table[index].offset = offset; - - cmem = kmap_atomic(zram->table[index].page, KM_USER1) + - zram->table[index].offset; - -#if 0 - /* Back-reference needed for memory defragmentation */ - if (!zram_test_flag(zram, index, ZRAM_UNCOMPRESSED)) { - zheader = (struct zobj_header *)cmem; - zheader->table_idx = index; - cmem += sizeof(*zheader); - } -#endif - - memcpy(cmem, src, clen); - - kunmap_atomic(cmem, KM_USER1); - if (unlikely(zram_test_flag(zram, index, ZRAM_UNCOMPRESSED))) - kunmap_atomic(src, KM_USER0); - - /* Update stats */ - zram_stat64_add(zram, &zram->stats.compr_size, clen); - zram_stat_inc(&zram->stats.pages_stored); - if (clen <= PAGE_SIZE / 2) - zram_stat_inc(&zram->stats.good_compress); - - mutex_unlock(&zram->lock); - index++; + update_position(&index, &offset, bvec); } set_bit(BIO_UPTODATE, &bio->bi_flags); @@ -406,14 +537,14 @@ static void zram_write(struct zram *zram, struct bio *bio) } /* - * Check if request is within bounds and page aligned. + * Check if request is within bounds and aligned on zram logical blocks. */ static inline int valid_io_request(struct zram *zram, struct bio *bio) { if (unlikely( (bio->bi_sector >= (zram->disksize >> SECTOR_SHIFT)) || - (bio->bi_sector & (SECTORS_PER_PAGE - 1)) || - (bio->bi_size & (PAGE_SIZE - 1)))) { + (bio->bi_sector & (ZRAM_SECTOR_PER_LOGICAL_BLOCK - 1)) || + (bio->bi_size & (ZRAM_LOGICAL_BLOCK_SIZE - 1)))) { return 0; } @@ -440,15 +571,7 @@ static int zram_make_request(struct request_queue *queue, struct bio *bio) return 0; } - switch (bio_data_dir(bio)) { - case READ: - zram_read(zram, bio); - break; - - case WRITE: - zram_write(zram, bio); - break; - } + __zram_make_request(zram, bio, bio_data_dir(bio)); return 0; } @@ -579,7 +702,7 @@ static int create_device(struct zram *zram, int device_id) { int ret = 0; - mutex_init(&zram->lock); + init_rwsem(&zram->lock); mutex_init(&zram->init_lock); spin_lock_init(&zram->stat64_lock); diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h index 408b2c067fc9..abe5221c100d 100644 --- a/drivers/staging/zram/zram_drv.h +++ b/drivers/staging/zram/zram_drv.h @@ -61,7 +61,10 @@ static const unsigned max_zpage_size = PAGE_SIZE / 4 * 3; #define SECTOR_SIZE (1 << SECTOR_SHIFT) #define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT) #define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT) -#define ZRAM_LOGICAL_BLOCK_SIZE 4096 +#define ZRAM_LOGICAL_BLOCK_SHIFT 12 +#define ZRAM_LOGICAL_BLOCK_SIZE (1 << ZRAM_LOGICAL_BLOCK_SHIFT) +#define ZRAM_SECTOR_PER_LOGICAL_BLOCK \ + (1 << (ZRAM_LOGICAL_BLOCK_SHIFT - SECTOR_SHIFT)) /* Flags for zram pages (table[page_no].flags) */ enum zram_pageflags { @@ -104,8 +107,8 @@ struct zram { void *compress_buffer; struct table *table; spinlock_t stat64_lock; /* protect 64-bit stats */ - struct mutex lock; /* protect compression buffers against - * concurrent writes */ + struct rw_semaphore lock; /* protect compression buffers and table + * against concurrent read and writes */ struct request_queue *queue; struct gendisk *disk; int init_done; diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 58aabe679c32..bedc4b9f2ac4 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -191,8 +191,8 @@ config USB_STORAGE_ENE_UB6250 depends on USB && SCSI depends on USB_STORAGE ---help--- - Say Y here if you wish to control a ENE SD Card reader. - To use SM/MS card, please build driver/staging/keucr/keucr.ko + Say Y here if you wish to control a ENE SD/MS Card reader. + To use SM card, please build driver/staging/keucr/keucr.ko This option depends on 'SCSI' support being enabled, but you probably also need 'SCSI device support: SCSI disk support' diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index 31645afff5fc..4dca3ef0668c 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -100,6 +100,141 @@ static struct us_unusual_dev ene_ub6250_unusual_dev_list[] = { #define FDIR_WRITE 0 #define FDIR_READ 1 +/* For MS Card */ + +/* Status Register 1 */ +#define MS_REG_ST1_MB 0x80 /* media busy */ +#define MS_REG_ST1_FB1 0x40 /* flush busy 1 */ +#define MS_REG_ST1_DTER 0x20 /* error on data(corrected) */ +#define MS_REG_ST1_UCDT 0x10 /* unable to correct data */ +#define MS_REG_ST1_EXER 0x08 /* error on extra(corrected) */ +#define MS_REG_ST1_UCEX 0x04 /* unable to correct extra */ +#define MS_REG_ST1_FGER 0x02 /* error on overwrite flag(corrected) */ +#define MS_REG_ST1_UCFG 0x01 /* unable to correct overwrite flag */ +#define MS_REG_ST1_DEFAULT (MS_REG_ST1_MB | MS_REG_ST1_FB1 | MS_REG_ST1_DTER | MS_REG_ST1_UCDT | MS_REG_ST1_EXER | MS_REG_ST1_UCEX | MS_REG_ST1_FGER | MS_REG_ST1_UCFG) + +/* Overwrite Area */ +#define MS_REG_OVR_BKST 0x80 /* block status */ +#define MS_REG_OVR_BKST_OK MS_REG_OVR_BKST /* OK */ +#define MS_REG_OVR_BKST_NG 0x00 /* NG */ +#define MS_REG_OVR_PGST0 0x40 /* page status */ +#define MS_REG_OVR_PGST1 0x20 +#define MS_REG_OVR_PGST_MASK (MS_REG_OVR_PGST0 | MS_REG_OVR_PGST1) +#define MS_REG_OVR_PGST_OK (MS_REG_OVR_PGST0 | MS_REG_OVR_PGST1) /* OK */ +#define MS_REG_OVR_PGST_NG MS_REG_OVR_PGST1 /* NG */ +#define MS_REG_OVR_PGST_DATA_ERROR 0x00 /* data error */ +#define MS_REG_OVR_UDST 0x10 /* update status */ +#define MS_REG_OVR_UDST_UPDATING 0x00 /* updating */ +#define MS_REG_OVR_UDST_NO_UPDATE MS_REG_OVR_UDST +#define MS_REG_OVR_RESERVED 0x08 +#define MS_REG_OVR_DEFAULT (MS_REG_OVR_BKST_OK | MS_REG_OVR_PGST_OK | MS_REG_OVR_UDST_NO_UPDATE | MS_REG_OVR_RESERVED) + +/* Management Flag */ +#define MS_REG_MNG_SCMS0 0x20 /* serial copy management system */ +#define MS_REG_MNG_SCMS1 0x10 +#define MS_REG_MNG_SCMS_MASK (MS_REG_MNG_SCMS0 | MS_REG_MNG_SCMS1) +#define MS_REG_MNG_SCMS_COPY_OK (MS_REG_MNG_SCMS0 | MS_REG_MNG_SCMS1) +#define MS_REG_MNG_SCMS_ONE_COPY MS_REG_MNG_SCMS1 +#define MS_REG_MNG_SCMS_NO_COPY 0x00 +#define MS_REG_MNG_ATFLG 0x08 /* address transfer table flag */ +#define MS_REG_MNG_ATFLG_OTHER MS_REG_MNG_ATFLG /* other */ +#define MS_REG_MNG_ATFLG_ATTBL 0x00 /* address transfer table */ +#define MS_REG_MNG_SYSFLG 0x04 /* system flag */ +#define MS_REG_MNG_SYSFLG_USER MS_REG_MNG_SYSFLG /* user block */ +#define MS_REG_MNG_SYSFLG_BOOT 0x00 /* system block */ +#define MS_REG_MNG_RESERVED 0xc3 +#define MS_REG_MNG_DEFAULT (MS_REG_MNG_SCMS_COPY_OK | MS_REG_MNG_ATFLG_OTHER | MS_REG_MNG_SYSFLG_USER | MS_REG_MNG_RESERVED) + + +#define MS_MAX_PAGES_PER_BLOCK 32 +#define MS_MAX_INITIAL_ERROR_BLOCKS 10 +#define MS_LIB_BITS_PER_BYTE 8 + +#define MS_SYSINF_FORMAT_FAT 1 +#define MS_SYSINF_USAGE_GENERAL 0 + +#define MS_SYSINF_MSCLASS_TYPE_1 1 +#define MS_SYSINF_PAGE_SIZE MS_BYTES_PER_PAGE /* fixed */ + +#define MS_SYSINF_CARDTYPE_RDONLY 1 +#define MS_SYSINF_CARDTYPE_RDWR 2 +#define MS_SYSINF_CARDTYPE_HYBRID 3 +#define MS_SYSINF_SECURITY 0x01 +#define MS_SYSINF_SECURITY_NO_SUPPORT MS_SYSINF_SECURITY +#define MS_SYSINF_SECURITY_SUPPORT 0 + +#define MS_SYSINF_RESERVED1 1 +#define MS_SYSINF_RESERVED2 1 + +#define MS_SYSENT_TYPE_INVALID_BLOCK 0x01 +#define MS_SYSENT_TYPE_CIS_IDI 0x0a /* CIS/IDI */ + +#define SIZE_OF_KIRO 1024 +#define BYTE_MASK 0xff + +/* ms error code */ +#define MS_STATUS_WRITE_PROTECT 0x0106 +#define MS_STATUS_SUCCESS 0x0000 +#define MS_ERROR_FLASH_READ 0x8003 +#define MS_ERROR_FLASH_ERASE 0x8005 +#define MS_LB_ERROR 0xfff0 +#define MS_LB_BOOT_BLOCK 0xfff1 +#define MS_LB_INITIAL_ERROR 0xfff2 +#define MS_STATUS_SUCCESS_WITH_ECC 0xfff3 +#define MS_LB_ACQUIRED_ERROR 0xfff4 +#define MS_LB_NOT_USED_ERASED 0xfff5 +#define MS_NOCARD_ERROR 0xfff8 +#define MS_NO_MEMORY_ERROR 0xfff9 +#define MS_STATUS_INT_ERROR 0xfffa +#define MS_STATUS_ERROR 0xfffe +#define MS_LB_NOT_USED 0xffff + +#define MS_REG_MNG_SYSFLG 0x04 /* system flag */ +#define MS_REG_MNG_SYSFLG_USER MS_REG_MNG_SYSFLG /* user block */ + +#define MS_BOOT_BLOCK_ID 0x0001 +#define MS_BOOT_BLOCK_FORMAT_VERSION 0x0100 +#define MS_BOOT_BLOCK_DATA_ENTRIES 2 + +#define MS_NUMBER_OF_SYSTEM_ENTRY 4 +#define MS_NUMBER_OF_BOOT_BLOCK 2 +#define MS_BYTES_PER_PAGE 512 +#define MS_LOGICAL_BLOCKS_PER_SEGMENT 496 +#define MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT 494 + +#define MS_PHYSICAL_BLOCKS_PER_SEGMENT 0x200 /* 512 */ +#define MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK 0x1ff + +/* overwrite area */ +#define MS_REG_OVR_BKST 0x80 /* block status */ +#define MS_REG_OVR_BKST_OK MS_REG_OVR_BKST /* OK */ +#define MS_REG_OVR_BKST_NG 0x00 /* NG */ + +/* Status Register 1 */ +#define MS_REG_ST1_DTER 0x20 /* error on data(corrected) */ +#define MS_REG_ST1_EXER 0x08 /* error on extra(corrected) */ +#define MS_REG_ST1_FGER 0x02 /* error on overwrite flag(corrected) */ + +/* MemoryStick Register */ +/* Status Register 0 */ +#define MS_REG_ST0_WP 0x01 /* write protected */ +#define MS_REG_ST0_WP_ON MS_REG_ST0_WP + +#define MS_LIB_CTRL_RDONLY 0 +#define MS_LIB_CTRL_WRPROTECT 1 + +/*dphy->log table */ +#define ms_libconv_to_logical(pdx, PhyBlock) (((PhyBlock) >= (pdx)->MS_Lib.NumberOfPhyBlock) ? MS_STATUS_ERROR : (pdx)->MS_Lib.Phy2LogMap[PhyBlock]) +#define ms_libconv_to_physical(pdx, LogBlock) (((LogBlock) >= (pdx)->MS_Lib.NumberOfLogBlock) ? MS_STATUS_ERROR : (pdx)->MS_Lib.Log2PhyMap[LogBlock]) + +#define ms_lib_ctrl_set(pdx, Flag) ((pdx)->MS_Lib.flags |= (1 << (Flag))) +#define ms_lib_ctrl_reset(pdx, Flag) ((pdx)->MS_Lib.flags &= ~(1 << (Flag))) +#define ms_lib_ctrl_check(pdx, Flag) ((pdx)->MS_Lib.flags & (1 << (Flag))) + +#define ms_lib_iswritable(pdx) ((ms_lib_ctrl_check((pdx), MS_LIB_CTRL_RDONLY) == 0) && (ms_lib_ctrl_check(pdx, MS_LIB_CTRL_WRPROTECT) == 0)) +#define ms_lib_clear_pagemap(pdx) memset((pdx)->MS_Lib.pagemap, 0, sizeof((pdx)->MS_Lib.pagemap)) +#define memstick_logaddr(logadr1, logadr0) ((((u16)(logadr1)) << 8) | (logadr0)) + struct SD_STATUS { u8 Insert:1; @@ -132,6 +267,164 @@ struct SM_STATUS { u8 IsMS:1; }; +struct ms_bootblock_cis { + u8 bCistplDEVICE[6]; /* 0 */ + u8 bCistplDEVICE0C[6]; /* 6 */ + u8 bCistplJEDECC[4]; /* 12 */ + u8 bCistplMANFID[6]; /* 16 */ + u8 bCistplVER1[32]; /* 22 */ + u8 bCistplFUNCID[4]; /* 54 */ + u8 bCistplFUNCE0[4]; /* 58 */ + u8 bCistplFUNCE1[5]; /* 62 */ + u8 bCistplCONF[7]; /* 67 */ + u8 bCistplCFTBLENT0[10];/* 74 */ + u8 bCistplCFTBLENT1[8]; /* 84 */ + u8 bCistplCFTBLENT2[12];/* 92 */ + u8 bCistplCFTBLENT3[8]; /* 104 */ + u8 bCistplCFTBLENT4[17];/* 112 */ + u8 bCistplCFTBLENT5[8]; /* 129 */ + u8 bCistplCFTBLENT6[17];/* 137 */ + u8 bCistplCFTBLENT7[8]; /* 154 */ + u8 bCistplNOLINK[3]; /* 162 */ +} ; + +struct ms_bootblock_idi { +#define MS_IDI_GENERAL_CONF 0x848A + u16 wIDIgeneralConfiguration; /* 0 */ + u16 wIDInumberOfCylinder; /* 1 */ + u16 wIDIreserved0; /* 2 */ + u16 wIDInumberOfHead; /* 3 */ + u16 wIDIbytesPerTrack; /* 4 */ + u16 wIDIbytesPerSector; /* 5 */ + u16 wIDIsectorsPerTrack; /* 6 */ + u16 wIDItotalSectors[2]; /* 7-8 high,low */ + u16 wIDIreserved1[11]; /* 9-19 */ + u16 wIDIbufferType; /* 20 */ + u16 wIDIbufferSize; /* 21 */ + u16 wIDIlongCmdECC; /* 22 */ + u16 wIDIfirmVersion[4]; /* 23-26 */ + u16 wIDImodelName[20]; /* 27-46 */ + u16 wIDIreserved2; /* 47 */ + u16 wIDIlongWordSupported; /* 48 */ + u16 wIDIdmaSupported; /* 49 */ + u16 wIDIreserved3; /* 50 */ + u16 wIDIpioTiming; /* 51 */ + u16 wIDIdmaTiming; /* 52 */ + u16 wIDItransferParameter; /* 53 */ + u16 wIDIformattedCylinder; /* 54 */ + u16 wIDIformattedHead; /* 55 */ + u16 wIDIformattedSectorsPerTrack;/* 56 */ + u16 wIDIformattedTotalSectors[2];/* 57-58 */ + u16 wIDImultiSector; /* 59 */ + u16 wIDIlbaSectors[2]; /* 60-61 */ + u16 wIDIsingleWordDMA; /* 62 */ + u16 wIDImultiWordDMA; /* 63 */ + u16 wIDIreserved4[192]; /* 64-255 */ +}; + +struct ms_bootblock_sysent_rec { + u32 dwStart; + u32 dwSize; + u8 bType; + u8 bReserved[3]; +}; + +struct ms_bootblock_sysent { + struct ms_bootblock_sysent_rec entry[MS_NUMBER_OF_SYSTEM_ENTRY]; +}; + +struct ms_bootblock_sysinf { + u8 bMsClass; /* must be 1 */ + u8 bCardType; /* see below */ + u16 wBlockSize; /* n KB */ + u16 wBlockNumber; /* number of physical block */ + u16 wTotalBlockNumber; /* number of logical block */ + u16 wPageSize; /* must be 0x200 */ + u8 bExtraSize; /* 0x10 */ + u8 bSecuritySupport; + u8 bAssemblyDate[8]; + u8 bFactoryArea[4]; + u8 bAssemblyMakerCode; + u8 bAssemblyMachineCode[3]; + u16 wMemoryMakerCode; + u16 wMemoryDeviceCode; + u16 wMemorySize; + u8 bReserved1; + u8 bReserved2; + u8 bVCC; + u8 bVPP; + u16 wControllerChipNumber; + u16 wControllerFunction; /* New MS */ + u8 bReserved3[9]; /* New MS */ + u8 bParallelSupport; /* New MS */ + u16 wFormatValue; /* New MS */ + u8 bFormatType; + u8 bUsage; + u8 bDeviceType; + u8 bReserved4[22]; + u8 bFUValue3; + u8 bFUValue4; + u8 bReserved5[15]; +}; + +struct ms_bootblock_header { + u16 wBlockID; + u16 wFormatVersion; + u8 bReserved1[184]; + u8 bNumberOfDataEntry; + u8 bReserved2[179]; +}; + +struct ms_bootblock_page0 { + struct ms_bootblock_header header; + struct ms_bootblock_sysent sysent; + struct ms_bootblock_sysinf sysinf; +}; + +struct ms_bootblock_cis_idi { + union { + struct ms_bootblock_cis cis; + u8 dmy[256]; + } cis; + + union { + struct ms_bootblock_idi idi; + u8 dmy[256]; + } idi; + +}; + +/* ENE MS Lib struct */ +struct ms_lib_type_extdat { + u8 reserved; + u8 intr; + u8 status0; + u8 status1; + u8 ovrflg; + u8 mngflg; + u16 logadr; +}; + +struct ms_lib_ctrl { + u32 flags; + u32 BytesPerSector; + u32 NumberOfCylinder; + u32 SectorsPerCylinder; + u16 cardType; /* R/W, RO, Hybrid */ + u16 blockSize; + u16 PagesPerBlock; + u16 NumberOfPhyBlock; + u16 NumberOfLogBlock; + u16 NumberOfSegment; + u16 *Phy2LogMap; /* phy2log table */ + u16 *Log2PhyMap; /* log2phy table */ + u16 wrtblk; + unsigned char *pagemap[(MS_MAX_PAGES_PER_BLOCK + (MS_LIB_BITS_PER_BYTE-1)) / MS_LIB_BITS_PER_BYTE]; + unsigned char *blkpag; + struct ms_lib_type_extdat *blkext; + unsigned char copybuf[512]; +}; + /* SD Block Length */ /* 2^9 = 512 Bytes, The HW maximum read/write data length */ @@ -162,7 +455,7 @@ struct ene_ub6250_info { /*----- MS Control Data ---------------- */ bool MS_SWWP; u32 MSP_TotalBlock; - /*MS_LibControl MS_Lib;*/ + struct ms_lib_ctrl MS_Lib; bool MS_IsRWPage; u16 MS_Model; @@ -180,6 +473,7 @@ struct ene_ub6250_info { }; static int ene_sd_init(struct us_data *us); +static int ene_ms_init(struct us_data *us); static int ene_load_bincode(struct us_data *us, unsigned char flag); static void ene_ub6250_info_destructor(void *extra) @@ -431,6 +725,1101 @@ static int sd_scsi_write(struct us_data *us, struct scsi_cmnd *srb) return result; } +/* + * ENE MS Card + */ + +static int ms_lib_set_logicalpair(struct us_data *us, u16 logblk, u16 phyblk) +{ + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + if ((logblk >= info->MS_Lib.NumberOfLogBlock) || (phyblk >= info->MS_Lib.NumberOfPhyBlock)) + return (u32)-1; + + info->MS_Lib.Phy2LogMap[phyblk] = logblk; + info->MS_Lib.Log2PhyMap[logblk] = phyblk; + + return 0; +} + +static int ms_lib_set_logicalblockmark(struct us_data *us, u16 phyblk, u16 mark) +{ + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + if (phyblk >= info->MS_Lib.NumberOfPhyBlock) + return (u32)-1; + + info->MS_Lib.Phy2LogMap[phyblk] = mark; + + return 0; +} + +static int ms_lib_set_initialerrorblock(struct us_data *us, u16 phyblk) +{ + return ms_lib_set_logicalblockmark(us, phyblk, MS_LB_INITIAL_ERROR); +} + +static int ms_lib_set_bootblockmark(struct us_data *us, u16 phyblk) +{ + return ms_lib_set_logicalblockmark(us, phyblk, MS_LB_BOOT_BLOCK); +} + +static int ms_lib_free_logicalmap(struct us_data *us) +{ + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + kfree(info->MS_Lib.Phy2LogMap); + info->MS_Lib.Phy2LogMap = NULL; + + kfree(info->MS_Lib.Log2PhyMap); + info->MS_Lib.Log2PhyMap = NULL; + + return 0; +} + +int ms_lib_alloc_logicalmap(struct us_data *us) +{ + u32 i; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + info->MS_Lib.Phy2LogMap = kmalloc(info->MS_Lib.NumberOfPhyBlock * sizeof(u16), GFP_KERNEL); + info->MS_Lib.Log2PhyMap = kmalloc(info->MS_Lib.NumberOfLogBlock * sizeof(u16), GFP_KERNEL); + + if ((info->MS_Lib.Phy2LogMap == NULL) || (info->MS_Lib.Log2PhyMap == NULL)) { + ms_lib_free_logicalmap(us); + return (u32)-1; + } + + for (i = 0; i < info->MS_Lib.NumberOfPhyBlock; i++) + info->MS_Lib.Phy2LogMap[i] = MS_LB_NOT_USED; + + for (i = 0; i < info->MS_Lib.NumberOfLogBlock; i++) + info->MS_Lib.Log2PhyMap[i] = MS_LB_NOT_USED; + + return 0; +} + +static void ms_lib_clear_writebuf(struct us_data *us) +{ + int i; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + info->MS_Lib.wrtblk = (u16)-1; + ms_lib_clear_pagemap(info); + + if (info->MS_Lib.blkpag) + memset(info->MS_Lib.blkpag, 0xff, info->MS_Lib.PagesPerBlock * info->MS_Lib.BytesPerSector); + + if (info->MS_Lib.blkext) { + for (i = 0; i < info->MS_Lib.PagesPerBlock; i++) { + info->MS_Lib.blkext[i].status1 = MS_REG_ST1_DEFAULT; + info->MS_Lib.blkext[i].ovrflg = MS_REG_OVR_DEFAULT; + info->MS_Lib.blkext[i].mngflg = MS_REG_MNG_DEFAULT; + info->MS_Lib.blkext[i].logadr = MS_LB_NOT_USED; + } + } +} + +static int ms_count_freeblock(struct us_data *us, u16 PhyBlock) +{ + u32 Ende, Count; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + Ende = PhyBlock + MS_PHYSICAL_BLOCKS_PER_SEGMENT; + for (Count = 0; PhyBlock < Ende; PhyBlock++) { + switch (info->MS_Lib.Phy2LogMap[PhyBlock]) { + case MS_LB_NOT_USED: + case MS_LB_NOT_USED_ERASED: + Count++; + default: + break; + } + } + + return Count; +} + +static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr, + u8 PageNum, u32 *PageBuf, struct ms_lib_type_extdat *ExtraDat) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + u8 ExtBuf[4]; + u32 bn = PhyBlockAddr * 0x20 + PageNum; + + /* printk(KERN_INFO "MS --- MS_ReaderReadPage, + PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */ + + result = ene_load_bincode(us, MS_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + /* Read Page Data */ + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x200; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + + bcb->CDB[1] = 0x02; /* in init.c ENE_MSInit() is 0x01 */ + + bcb->CDB[5] = (unsigned char)(bn); + bcb->CDB[4] = (unsigned char)(bn>>8); + bcb->CDB[3] = (unsigned char)(bn>>16); + bcb->CDB[2] = (unsigned char)(bn>>24); + + result = ene_send_scsi_cmd(us, FDIR_READ, PageBuf, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + + /* Read Extra Data */ + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x4; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + bcb->CDB[1] = 0x03; + + bcb->CDB[5] = (unsigned char)(PageNum); + bcb->CDB[4] = (unsigned char)(PhyBlockAddr); + bcb->CDB[3] = (unsigned char)(PhyBlockAddr>>8); + bcb->CDB[2] = (unsigned char)(PhyBlockAddr>>16); + bcb->CDB[6] = 0x01; + + result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + ExtraDat->reserved = 0; + ExtraDat->intr = 0x80; /* Not yet,fireware support */ + ExtraDat->status0 = 0x10; /* Not yet,fireware support */ + + ExtraDat->status1 = 0x00; /* Not yet,fireware support */ + ExtraDat->ovrflg = ExtBuf[0]; + ExtraDat->mngflg = ExtBuf[1]; + ExtraDat->logadr = memstick_logaddr(ExtBuf[2], ExtBuf[3]); + + return USB_STOR_TRANSPORT_GOOD; +} + +static int ms_lib_process_bootblock(struct us_data *us, u16 PhyBlock, u8 *PageData) +{ + struct ms_bootblock_sysent *SysEntry; + struct ms_bootblock_sysinf *SysInfo; + u32 i, result; + u8 PageNumber; + u8 *PageBuffer; + struct ms_lib_type_extdat ExtraData; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + PageBuffer = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); + if (PageBuffer == NULL) + return (u32)-1; + + result = (u32)-1; + + SysInfo = &(((struct ms_bootblock_page0 *)PageData)->sysinf); + + if ((SysInfo->bMsClass != MS_SYSINF_MSCLASS_TYPE_1) || + (be16_to_cpu(SysInfo->wPageSize) != MS_SYSINF_PAGE_SIZE) || + ((SysInfo->bSecuritySupport & MS_SYSINF_SECURITY) == MS_SYSINF_SECURITY_SUPPORT) || + (SysInfo->bReserved1 != MS_SYSINF_RESERVED1) || + (SysInfo->bReserved2 != MS_SYSINF_RESERVED2) || + (SysInfo->bFormatType != MS_SYSINF_FORMAT_FAT) || + (SysInfo->bUsage != MS_SYSINF_USAGE_GENERAL)) + goto exit; + /* */ + switch (info->MS_Lib.cardType = SysInfo->bCardType) { + case MS_SYSINF_CARDTYPE_RDONLY: + ms_lib_ctrl_set(info, MS_LIB_CTRL_RDONLY); + break; + case MS_SYSINF_CARDTYPE_RDWR: + ms_lib_ctrl_reset(info, MS_LIB_CTRL_RDONLY); + break; + case MS_SYSINF_CARDTYPE_HYBRID: + default: + goto exit; + } + + info->MS_Lib.blockSize = be16_to_cpu(SysInfo->wBlockSize); + info->MS_Lib.NumberOfPhyBlock = be16_to_cpu(SysInfo->wBlockNumber); + info->MS_Lib.NumberOfLogBlock = be16_to_cpu(SysInfo->wTotalBlockNumber)-2; + info->MS_Lib.PagesPerBlock = info->MS_Lib.blockSize * SIZE_OF_KIRO / MS_BYTES_PER_PAGE; + info->MS_Lib.NumberOfSegment = info->MS_Lib.NumberOfPhyBlock / MS_PHYSICAL_BLOCKS_PER_SEGMENT; + info->MS_Model = be16_to_cpu(SysInfo->wMemorySize); + + /*Allocate to all number of logicalblock and physicalblock */ + if (ms_lib_alloc_logicalmap(us)) + goto exit; + + /* Mark the book block */ + ms_lib_set_bootblockmark(us, PhyBlock); + + SysEntry = &(((struct ms_bootblock_page0 *)PageData)->sysent); + + for (i = 0; i < MS_NUMBER_OF_SYSTEM_ENTRY; i++) { + u32 EntryOffset, EntrySize; + + EntryOffset = be32_to_cpu(SysEntry->entry[i].dwStart); + + if (EntryOffset == 0xffffff) + continue; + EntrySize = be32_to_cpu(SysEntry->entry[i].dwSize); + + if (EntrySize == 0) + continue; + + if (EntryOffset + MS_BYTES_PER_PAGE + EntrySize > info->MS_Lib.blockSize * (u32)SIZE_OF_KIRO) + continue; + + if (i == 0) { + u8 PrevPageNumber = 0; + u16 phyblk; + + if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_INVALID_BLOCK) + goto exit; + + while (EntrySize > 0) { + + PageNumber = (u8)(EntryOffset / MS_BYTES_PER_PAGE + 1); + if (PageNumber != PrevPageNumber) { + switch (ms_read_readpage(us, PhyBlock, PageNumber, (u32 *)PageBuffer, &ExtraData)) { + case MS_STATUS_SUCCESS: + break; + case MS_STATUS_WRITE_PROTECT: + case MS_ERROR_FLASH_READ: + case MS_STATUS_ERROR: + default: + goto exit; + } + + PrevPageNumber = PageNumber; + } + + phyblk = be16_to_cpu(*(u16 *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE))); + if (phyblk < 0x0fff) + ms_lib_set_initialerrorblock(us, phyblk); + + EntryOffset += 2; + EntrySize -= 2; + } + } else if (i == 1) { /* CIS/IDI */ + struct ms_bootblock_idi *idi; + + if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_CIS_IDI) + goto exit; + + switch (ms_read_readpage(us, PhyBlock, (u8)(EntryOffset / MS_BYTES_PER_PAGE + 1), (u32 *)PageBuffer, &ExtraData)) { + case MS_STATUS_SUCCESS: + break; + case MS_STATUS_WRITE_PROTECT: + case MS_ERROR_FLASH_READ: + case MS_STATUS_ERROR: + default: + goto exit; + } + + idi = &((struct ms_bootblock_cis_idi *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))->idi.idi; + if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF) + goto exit; + + info->MS_Lib.BytesPerSector = le16_to_cpu(idi->wIDIbytesPerSector); + if (info->MS_Lib.BytesPerSector != MS_BYTES_PER_PAGE) + goto exit; + } + } /* End for .. */ + + result = 0; + +exit: + if (result) + ms_lib_free_logicalmap(us); + + kfree(PageBuffer); + + result = 0; + return result; +} + +static void ms_lib_free_writebuf(struct us_data *us) +{ + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + info->MS_Lib.wrtblk = (u16)-1; /* set to -1 */ + + /* memset((fdoExt)->MS_Lib.pagemap, 0, sizeof((fdoExt)->MS_Lib.pagemap)) */ + + ms_lib_clear_pagemap(info); /* (pdx)->MS_Lib.pagemap memset 0 in ms.h */ + + if (info->MS_Lib.blkpag) { + kfree((u8 *)(info->MS_Lib.blkpag)); /* Arnold test ... */ + info->MS_Lib.blkpag = NULL; + } + + if (info->MS_Lib.blkext) { + kfree((u8 *)(info->MS_Lib.blkext)); /* Arnold test ... */ + info->MS_Lib.blkext = NULL; + } +} + + +static void ms_lib_free_allocatedarea(struct us_data *us) +{ + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + ms_lib_free_writebuf(us); /* Free MS_Lib.pagemap */ + ms_lib_free_logicalmap(us); /* kfree MS_Lib.Phy2LogMap and MS_Lib.Log2PhyMap */ + + /* set struct us point flag to 0 */ + info->MS_Lib.flags = 0; + info->MS_Lib.BytesPerSector = 0; + info->MS_Lib.SectorsPerCylinder = 0; + + info->MS_Lib.cardType = 0; + info->MS_Lib.blockSize = 0; + info->MS_Lib.PagesPerBlock = 0; + + info->MS_Lib.NumberOfPhyBlock = 0; + info->MS_Lib.NumberOfLogBlock = 0; +} + + +static int ms_lib_alloc_writebuf(struct us_data *us) +{ + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + info->MS_Lib.wrtblk = (u16)-1; + + info->MS_Lib.blkpag = kmalloc(info->MS_Lib.PagesPerBlock * info->MS_Lib.BytesPerSector, GFP_KERNEL); + info->MS_Lib.blkext = kmalloc(info->MS_Lib.PagesPerBlock * sizeof(struct ms_lib_type_extdat), GFP_KERNEL); + + if ((info->MS_Lib.blkpag == NULL) || (info->MS_Lib.blkext == NULL)) { + ms_lib_free_writebuf(us); + return (u32)-1; + } + + ms_lib_clear_writebuf(us); + +return 0; +} + +static int ms_lib_force_setlogical_pair(struct us_data *us, u16 logblk, u16 phyblk) +{ + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + if (logblk == MS_LB_NOT_USED) + return 0; + + if ((logblk >= info->MS_Lib.NumberOfLogBlock) || + (phyblk >= info->MS_Lib.NumberOfPhyBlock)) + return (u32)-1; + + info->MS_Lib.Phy2LogMap[phyblk] = logblk; + info->MS_Lib.Log2PhyMap[logblk] = phyblk; + + return 0; +} + +static int ms_read_copyblock(struct us_data *us, u16 oldphy, u16 newphy, + u16 PhyBlockAddr, u8 PageNum, unsigned char *buf, u16 len) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + + /* printk(KERN_INFO "MS_ReaderCopyBlock --- PhyBlockAddr = %x, + PageNum = %x\n", PhyBlockAddr, PageNum); */ + result = ene_load_bincode(us, MS_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x200*len; + bcb->Flags = 0x00; + bcb->CDB[0] = 0xF0; + bcb->CDB[1] = 0x08; + bcb->CDB[4] = (unsigned char)(oldphy); + bcb->CDB[3] = (unsigned char)(oldphy>>8); + bcb->CDB[2] = 0; /* (BYTE)(oldphy>>16) */ + bcb->CDB[7] = (unsigned char)(newphy); + bcb->CDB[6] = (unsigned char)(newphy>>8); + bcb->CDB[5] = 0; /* (BYTE)(newphy>>16) */ + bcb->CDB[9] = (unsigned char)(PhyBlockAddr); + bcb->CDB[8] = (unsigned char)(PhyBlockAddr>>8); + bcb->CDB[10] = PageNum; + + result = ene_send_scsi_cmd(us, FDIR_WRITE, buf, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + return USB_STOR_TRANSPORT_GOOD; +} + +static int ms_read_eraseblock(struct us_data *us, u32 PhyBlockAddr) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + u32 bn = PhyBlockAddr; + + /* printk(KERN_INFO "MS --- ms_read_eraseblock, + PhyBlockAddr = %x\n", PhyBlockAddr); */ + result = ene_load_bincode(us, MS_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x200; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF2; + bcb->CDB[1] = 0x06; + bcb->CDB[4] = (unsigned char)(bn); + bcb->CDB[3] = (unsigned char)(bn>>8); + bcb->CDB[2] = (unsigned char)(bn>>16); + + result = ene_send_scsi_cmd(us, FDIR_READ, NULL, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + return USB_STOR_TRANSPORT_GOOD; +} + +static int ms_lib_check_disableblock(struct us_data *us, u16 PhyBlock) +{ + unsigned char *PageBuf = NULL; + u16 result = MS_STATUS_SUCCESS; + u16 blk, index = 0; + struct ms_lib_type_extdat extdat; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + PageBuf = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); + if (PageBuf == NULL) { + result = MS_NO_MEMORY_ERROR; + goto exit; + } + + ms_read_readpage(us, PhyBlock, 1, (u32 *)PageBuf, &extdat); + do { + blk = be16_to_cpu(PageBuf[index]); + if (blk == MS_LB_NOT_USED) + break; + if (blk == info->MS_Lib.Log2PhyMap[0]) { + result = MS_ERROR_FLASH_READ; + break; + } + index++; + } while (1); + +exit: + kfree(PageBuf); + return result; +} + +static int ms_lib_setacquired_errorblock(struct us_data *us, u16 phyblk) +{ + u16 log; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + if (phyblk >= info->MS_Lib.NumberOfPhyBlock) + return (u32)-1; + + log = info->MS_Lib.Phy2LogMap[phyblk]; + + if (log < info->MS_Lib.NumberOfLogBlock) + info->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED; + + if (info->MS_Lib.Phy2LogMap[phyblk] != MS_LB_INITIAL_ERROR) + info->MS_Lib.Phy2LogMap[phyblk] = MS_LB_ACQUIRED_ERROR; + + return 0; +} + +static int ms_lib_overwrite_extra(struct us_data *us, u32 PhyBlockAddr, + u8 PageNum, u8 OverwriteFlag) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + + /* printk("MS --- MS_LibOverwriteExtra, + PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */ + result = ene_load_bincode(us, MS_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x4; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF2; + bcb->CDB[1] = 0x05; + bcb->CDB[5] = (unsigned char)(PageNum); + bcb->CDB[4] = (unsigned char)(PhyBlockAddr); + bcb->CDB[3] = (unsigned char)(PhyBlockAddr>>8); + bcb->CDB[2] = (unsigned char)(PhyBlockAddr>>16); + bcb->CDB[6] = OverwriteFlag; + bcb->CDB[7] = 0xFF; + bcb->CDB[8] = 0xFF; + bcb->CDB[9] = 0xFF; + + result = ene_send_scsi_cmd(us, FDIR_READ, NULL, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + return USB_STOR_TRANSPORT_GOOD; +} + +static int ms_lib_error_phyblock(struct us_data *us, u16 phyblk) +{ + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + if (phyblk >= info->MS_Lib.NumberOfPhyBlock) + return MS_STATUS_ERROR; + + ms_lib_setacquired_errorblock(us, phyblk); + + if (ms_lib_iswritable(info)) + return ms_lib_overwrite_extra(us, phyblk, 0, (u8)(~MS_REG_OVR_BKST & BYTE_MASK)); + + return MS_STATUS_SUCCESS; +} + +static int ms_lib_erase_phyblock(struct us_data *us, u16 phyblk) +{ + u16 log; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + if (phyblk >= info->MS_Lib.NumberOfPhyBlock) + return MS_STATUS_ERROR; + + log = info->MS_Lib.Phy2LogMap[phyblk]; + + if (log < info->MS_Lib.NumberOfLogBlock) + info->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED; + + info->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED; + + if (ms_lib_iswritable(info)) { + switch (ms_read_eraseblock(us, phyblk)) { + case MS_STATUS_SUCCESS: + info->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED_ERASED; + return MS_STATUS_SUCCESS; + case MS_ERROR_FLASH_ERASE: + case MS_STATUS_INT_ERROR: + ms_lib_error_phyblock(us, phyblk); + return MS_ERROR_FLASH_ERASE; + case MS_STATUS_ERROR: + default: + ms_lib_ctrl_set(info, MS_LIB_CTRL_RDONLY); /* MS_LibCtrlSet will used by ENE_MSInit ,need check, and why us to info*/ + ms_lib_setacquired_errorblock(us, phyblk); + return MS_STATUS_ERROR; + } + } + + ms_lib_setacquired_errorblock(us, phyblk); + + return MS_STATUS_SUCCESS; +} + +static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock, + u8 PageNum, struct ms_lib_type_extdat *ExtraDat) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + u8 ExtBuf[4]; + + /* printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum); */ + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x4; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + bcb->CDB[1] = 0x03; + bcb->CDB[5] = (unsigned char)(PageNum); + bcb->CDB[4] = (unsigned char)(PhyBlock); + bcb->CDB[3] = (unsigned char)(PhyBlock>>8); + bcb->CDB[2] = (unsigned char)(PhyBlock>>16); + bcb->CDB[6] = 0x01; + + result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + ExtraDat->reserved = 0; + ExtraDat->intr = 0x80; /* Not yet, waiting for fireware support */ + ExtraDat->status0 = 0x10; /* Not yet, waiting for fireware support */ + ExtraDat->status1 = 0x00; /* Not yet, waiting for fireware support */ + ExtraDat->ovrflg = ExtBuf[0]; + ExtraDat->mngflg = ExtBuf[1]; + ExtraDat->logadr = memstick_logaddr(ExtBuf[2], ExtBuf[3]); + + return USB_STOR_TRANSPORT_GOOD; +} + +static int ms_libsearch_block_from_physical(struct us_data *us, u16 phyblk) +{ + u16 Newblk; + u16 blk; + struct ms_lib_type_extdat extdat; /* need check */ + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + + if (phyblk >= info->MS_Lib.NumberOfPhyBlock) + return MS_LB_ERROR; + + for (blk = phyblk + 1; blk != phyblk; blk++) { + if ((blk & MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK) == 0) + blk -= MS_PHYSICAL_BLOCKS_PER_SEGMENT; + + Newblk = info->MS_Lib.Phy2LogMap[blk]; + if (info->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED_ERASED) { + return blk; + } else if (info->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED) { + switch (ms_lib_read_extra(us, blk, 0, &extdat)) { + case MS_STATUS_SUCCESS: + case MS_STATUS_SUCCESS_WITH_ECC: + break; + case MS_NOCARD_ERROR: + return MS_NOCARD_ERROR; + case MS_STATUS_INT_ERROR: + return MS_LB_ERROR; + case MS_ERROR_FLASH_READ: + default: + ms_lib_setacquired_errorblock(us, blk); + continue; + } /* End switch */ + + if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) { + ms_lib_setacquired_errorblock(us, blk); + continue; + } + + switch (ms_lib_erase_phyblock(us, blk)) { + case MS_STATUS_SUCCESS: + return blk; + case MS_STATUS_ERROR: + return MS_LB_ERROR; + case MS_ERROR_FLASH_ERASE: + default: + ms_lib_error_phyblock(us, blk); + break; + } + } + } /* End for */ + + return MS_LB_ERROR; +} +static int ms_libsearch_block_from_logical(struct us_data *us, u16 logblk) +{ + u16 phyblk; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + phyblk = ms_libconv_to_physical(info, logblk); + if (phyblk >= MS_LB_ERROR) { + if (logblk >= info->MS_Lib.NumberOfLogBlock) + return MS_LB_ERROR; + + phyblk = (logblk + MS_NUMBER_OF_BOOT_BLOCK) / MS_LOGICAL_BLOCKS_PER_SEGMENT; + phyblk *= MS_PHYSICAL_BLOCKS_PER_SEGMENT; + phyblk += MS_PHYSICAL_BLOCKS_PER_SEGMENT - 1; + } + + return ms_libsearch_block_from_physical(us, phyblk); +} + +static int ms_scsi_test_unit_ready(struct us_data *us, struct scsi_cmnd *srb) +{ + struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra); + + /* pr_info("MS_SCSI_Test_Unit_Ready\n"); */ + if (info->MS_Status.Insert && info->MS_Status.Ready) { + return USB_STOR_TRANSPORT_GOOD; + } else { + ene_ms_init(us); + return USB_STOR_TRANSPORT_GOOD; + } + + return USB_STOR_TRANSPORT_GOOD; +} + +static int ms_scsi_inquiry(struct us_data *us, struct scsi_cmnd *srb) +{ + /* pr_info("MS_SCSI_Inquiry\n"); */ + unsigned char data_ptr[36] = { + 0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55, + 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30}; + + usb_stor_set_xfer_buf(data_ptr, 36, srb); + return USB_STOR_TRANSPORT_GOOD; +} + +static int ms_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb) +{ + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + unsigned char mediaNoWP[12] = { + 0x0b, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 }; + unsigned char mediaWP[12] = { + 0x0b, 0x00, 0x80, 0x08, 0x00, 0x00, + 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00 }; + + if (info->MS_Status.WtP) + usb_stor_set_xfer_buf(mediaWP, 12, srb); + else + usb_stor_set_xfer_buf(mediaNoWP, 12, srb); + + return USB_STOR_TRANSPORT_GOOD; +} + +static int ms_scsi_read_capacity(struct us_data *us, struct scsi_cmnd *srb) +{ + u32 bl_num; + u16 bl_len; + unsigned int offset = 0; + unsigned char buf[8]; + struct scatterlist *sg = NULL; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + US_DEBUGP("ms_scsi_read_capacity\n"); + bl_len = 0x200; + if (info->MS_Status.IsMSPro) + bl_num = info->MSP_TotalBlock - 1; + else + bl_num = info->MS_Lib.NumberOfLogBlock * info->MS_Lib.blockSize * 2 - 1; + + info->bl_num = bl_num; + US_DEBUGP("bl_len = %x\n", bl_len); + US_DEBUGP("bl_num = %x\n", bl_num); + + /*srb->request_bufflen = 8; */ + buf[0] = (bl_num >> 24) & 0xff; + buf[1] = (bl_num >> 16) & 0xff; + buf[2] = (bl_num >> 8) & 0xff; + buf[3] = (bl_num >> 0) & 0xff; + buf[4] = (bl_len >> 24) & 0xff; + buf[5] = (bl_len >> 16) & 0xff; + buf[6] = (bl_len >> 8) & 0xff; + buf[7] = (bl_len >> 0) & 0xff; + + usb_stor_access_xfer_buf(buf, 8, srb, &sg, &offset, TO_XFER_BUF); + + return USB_STOR_TRANSPORT_GOOD; +} + +static void ms_lib_phy_to_log_range(u16 PhyBlock, u16 *LogStart, u16 *LogEnde) +{ + PhyBlock /= MS_PHYSICAL_BLOCKS_PER_SEGMENT; + + if (PhyBlock) { + *LogStart = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT + (PhyBlock - 1) * MS_LOGICAL_BLOCKS_PER_SEGMENT;/*496*/ + *LogEnde = *LogStart + MS_LOGICAL_BLOCKS_PER_SEGMENT;/*496*/ + } else { + *LogStart = 0; + *LogEnde = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT;/*494*/ + } +} + +static int ms_lib_read_extrablock(struct us_data *us, u32 PhyBlock, + u8 PageNum, u8 blen, void *buf) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + + /* printk("MS_LibReadExtraBlock --- PhyBlock = %x, + PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen); */ + + /* Read Extra Data */ + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x4 * blen; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + bcb->CDB[1] = 0x03; + bcb->CDB[5] = (unsigned char)(PageNum); + bcb->CDB[4] = (unsigned char)(PhyBlock); + bcb->CDB[3] = (unsigned char)(PhyBlock>>8); + bcb->CDB[2] = (unsigned char)(PhyBlock>>16); + bcb->CDB[6] = blen; + + result = ene_send_scsi_cmd(us, FDIR_READ, buf, 0); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + + return USB_STOR_TRANSPORT_GOOD; +} + +static int ms_lib_scan_logicalblocknumber(struct us_data *us, u16 btBlk1st) +{ + u16 PhyBlock, newblk, i; + u16 LogStart, LogEnde; + struct ms_lib_type_extdat extdat; + u8 buf[0x200]; + u32 count = 0, index = 0; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + for (PhyBlock = 0; PhyBlock < info->MS_Lib.NumberOfPhyBlock;) { + ms_lib_phy_to_log_range(PhyBlock, &LogStart, &LogEnde); + + for (i = 0; i < MS_PHYSICAL_BLOCKS_PER_SEGMENT; i++, PhyBlock++) { + switch (ms_libconv_to_logical(info, PhyBlock)) { + case MS_STATUS_ERROR: + continue; + default: + break; + } + + if (count == PhyBlock) { + ms_lib_read_extrablock(us, PhyBlock, 0, 0x80, &buf); + count += 0x80; + } + index = (PhyBlock % 0x80) * 4; + + extdat.ovrflg = buf[index]; + extdat.mngflg = buf[index+1]; + extdat.logadr = memstick_logaddr(buf[index+2], buf[index+3]); + + if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) { + ms_lib_setacquired_errorblock(us, PhyBlock); + continue; + } + + if ((extdat.mngflg & MS_REG_MNG_ATFLG) == MS_REG_MNG_ATFLG_ATTBL) { + ms_lib_erase_phyblock(us, PhyBlock); + continue; + } + + if (extdat.logadr != MS_LB_NOT_USED) { + if ((extdat.logadr < LogStart) || (LogEnde <= extdat.logadr)) { + ms_lib_erase_phyblock(us, PhyBlock); + continue; + } + + newblk = ms_libconv_to_physical(info, extdat.logadr); + + if (newblk != MS_LB_NOT_USED) { + if (extdat.logadr == 0) { + ms_lib_set_logicalpair(us, extdat.logadr, PhyBlock); + if (ms_lib_check_disableblock(us, btBlk1st)) { + ms_lib_set_logicalpair(us, extdat.logadr, newblk); + continue; + } + } + + ms_lib_read_extra(us, newblk, 0, &extdat); + if ((extdat.ovrflg & MS_REG_OVR_UDST) == MS_REG_OVR_UDST_UPDATING) { + ms_lib_erase_phyblock(us, PhyBlock); + continue; + } else { + ms_lib_erase_phyblock(us, newblk); + } + } + + ms_lib_set_logicalpair(us, extdat.logadr, PhyBlock); + } + } + } /* End for ... */ + + return MS_STATUS_SUCCESS; +} + + +static int ms_scsi_read(struct us_data *us, struct scsi_cmnd *srb) +{ + int result; + unsigned char *cdb = srb->cmnd; + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + u32 bn = ((cdb[2] << 24) & 0xff000000) | ((cdb[3] << 16) & 0x00ff0000) | + ((cdb[4] << 8) & 0x0000ff00) | ((cdb[5] << 0) & 0x000000ff); + u16 blen = ((cdb[7] << 8) & 0xff00) | ((cdb[8] << 0) & 0x00ff); + u32 blenByte = blen * 0x200; + + if (bn > info->bl_num) + return USB_STOR_TRANSPORT_ERROR; + + if (info->MS_Status.IsMSPro) { + result = ene_load_bincode(us, MSP_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + US_DEBUGP("Load MPS RW pattern Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + /* set up the command wrapper */ + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = blenByte; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + bcb->CDB[1] = 0x02; + bcb->CDB[5] = (unsigned char)(bn); + bcb->CDB[4] = (unsigned char)(bn>>8); + bcb->CDB[3] = (unsigned char)(bn>>16); + bcb->CDB[2] = (unsigned char)(bn>>24); + + result = ene_send_scsi_cmd(us, FDIR_READ, scsi_sglist(srb), 1); + } else { + void *buf; + int offset = 0; + u16 phyblk, logblk; + u8 PageNum; + u16 len; + u32 blkno; + + buf = kmalloc(blenByte, GFP_KERNEL); + if (buf == NULL) + return USB_STOR_TRANSPORT_ERROR; + + result = ene_load_bincode(us, MS_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + pr_info("Load MS RW pattern Fail !!\n"); + result = USB_STOR_TRANSPORT_ERROR; + goto exit; + } + + logblk = (u16)(bn / info->MS_Lib.PagesPerBlock); + PageNum = (u8)(bn % info->MS_Lib.PagesPerBlock); + + while (1) { + if (blen > (info->MS_Lib.PagesPerBlock-PageNum)) + len = info->MS_Lib.PagesPerBlock-PageNum; + else + len = blen; + + phyblk = ms_libconv_to_physical(info, logblk); + blkno = phyblk * 0x20 + PageNum; + + /* set up the command wrapper */ + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x200 * len; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + bcb->CDB[1] = 0x02; + bcb->CDB[5] = (unsigned char)(blkno); + bcb->CDB[4] = (unsigned char)(blkno>>8); + bcb->CDB[3] = (unsigned char)(blkno>>16); + bcb->CDB[2] = (unsigned char)(blkno>>24); + + result = ene_send_scsi_cmd(us, FDIR_READ, buf+offset, 0); + if (result != USB_STOR_XFER_GOOD) { + pr_info("MS_SCSI_Read --- result = %x\n", result); + result = USB_STOR_TRANSPORT_ERROR; + goto exit; + } + + blen -= len; + if (blen <= 0) + break; + logblk++; + PageNum = 0; + offset += MS_BYTES_PER_PAGE*len; + } + usb_stor_set_xfer_buf(buf, blenByte, srb); +exit: + kfree(buf); + } + return result; +} + +static int ms_scsi_write(struct us_data *us, struct scsi_cmnd *srb) +{ + int result; + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + unsigned char *cdb = srb->cmnd; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + u32 bn = ((cdb[2] << 24) & 0xff000000) | + ((cdb[3] << 16) & 0x00ff0000) | + ((cdb[4] << 8) & 0x0000ff00) | + ((cdb[5] << 0) & 0x000000ff); + u16 blen = ((cdb[7] << 8) & 0xff00) | ((cdb[8] << 0) & 0x00ff); + u32 blenByte = blen * 0x200; + + if (bn > info->bl_num) + return USB_STOR_TRANSPORT_ERROR; + + if (info->MS_Status.IsMSPro) { + result = ene_load_bincode(us, MSP_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + pr_info("Load MSP RW pattern Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + /* set up the command wrapper */ + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = blenByte; + bcb->Flags = 0x00; + bcb->CDB[0] = 0xF0; + bcb->CDB[1] = 0x04; + bcb->CDB[5] = (unsigned char)(bn); + bcb->CDB[4] = (unsigned char)(bn>>8); + bcb->CDB[3] = (unsigned char)(bn>>16); + bcb->CDB[2] = (unsigned char)(bn>>24); + + result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1); + } else { + void *buf; + int offset; + u16 PhyBlockAddr; + u8 PageNum; + u32 result; + u16 len, oldphy, newphy; + + buf = kmalloc(blenByte, GFP_KERNEL); + if (buf == NULL) + return USB_STOR_TRANSPORT_ERROR; + usb_stor_set_xfer_buf(buf, blenByte, srb); + + result = ene_load_bincode(us, MS_RW_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + pr_info("Load MS RW pattern Fail !!\n"); + result = USB_STOR_TRANSPORT_ERROR; + goto exit; + } + + PhyBlockAddr = (u16)(bn / info->MS_Lib.PagesPerBlock); + PageNum = (u8)(bn % info->MS_Lib.PagesPerBlock); + + while (1) { + if (blen > (info->MS_Lib.PagesPerBlock-PageNum)) + len = info->MS_Lib.PagesPerBlock-PageNum; + else + len = blen; + + oldphy = ms_libconv_to_physical(info, PhyBlockAddr); /* need check us <-> info */ + newphy = ms_libsearch_block_from_logical(us, PhyBlockAddr); + + result = ms_read_copyblock(us, oldphy, newphy, PhyBlockAddr, PageNum, buf+offset, len); + + if (result != USB_STOR_XFER_GOOD) { + pr_info("MS_SCSI_Write --- result = %x\n", result); + result = USB_STOR_TRANSPORT_ERROR; + goto exit; + } + + info->MS_Lib.Phy2LogMap[oldphy] = MS_LB_NOT_USED_ERASED; + ms_lib_force_setlogical_pair(us, PhyBlockAddr, newphy); + + blen -= len; + if (blen <= 0) + break; + PhyBlockAddr++; + PageNum = 0; + offset += MS_BYTES_PER_PAGE*len; + } +exit: + kfree(buf); + } + return result; +} + +/* + * ENE MS Card + */ + static int ene_get_card_type(struct us_data *us, u16 index, void *buf) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; @@ -505,6 +1894,19 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag) US_DEBUGP("SD_RDWR_PATTERN\n"); fw_name = "ene-ub6250/sd_rdwr.bin"; break; + /* For MS */ + case MS_INIT_PATTERN: + US_DEBUGP("MS_INIT_PATTERN\n"); + fw_name = "ene-ub6250/ms_init.bin"; + break; + case MSP_RW_PATTERN: + US_DEBUGP("MSP_RW_PATTERN\n"); + fw_name = "ene-ub6250/msp_rdwr.bin"; + break; + case MS_RW_PATTERN: + US_DEBUGP("MS_RW_PATTERN\n"); + fw_name = "ene-ub6250/ms_rdwr.bin"; + break; default: US_DEBUGP("----------- Unknown PATTERN ----------\n"); goto nofw; @@ -540,6 +1942,182 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag) return result; } +static int ms_card_init(struct us_data *us) +{ + u32 result; + u16 TmpBlock; + unsigned char *PageBuffer0 = NULL, *PageBuffer1 = NULL; + struct ms_lib_type_extdat extdat; + u16 btBlk1st, btBlk2nd; + u32 btBlk1stErred; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + printk(KERN_INFO "MS_CardInit start\n"); + + ms_lib_free_allocatedarea(us); /* Clean buffer and set struct us_data flag to 0 */ + + /* get two PageBuffer */ + PageBuffer0 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); + PageBuffer1 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL); + if ((PageBuffer0 == NULL) || (PageBuffer1 == NULL)) { + result = MS_NO_MEMORY_ERROR; + goto exit; + } + + btBlk1st = btBlk2nd = MS_LB_NOT_USED; + btBlk1stErred = 0; + + for (TmpBlock = 0; TmpBlock < MS_MAX_INITIAL_ERROR_BLOCKS+2; TmpBlock++) { + + switch (ms_read_readpage(us, TmpBlock, 0, (u32 *)PageBuffer0, &extdat)) { + case MS_STATUS_SUCCESS: + break; + case MS_STATUS_INT_ERROR: + break; + case MS_STATUS_ERROR: + default: + continue; + } + + if ((extdat.ovrflg & MS_REG_OVR_BKST) == MS_REG_OVR_BKST_NG) + continue; + + if (((extdat.mngflg & MS_REG_MNG_SYSFLG) == MS_REG_MNG_SYSFLG_USER) || + (be16_to_cpu(((struct ms_bootblock_page0 *)PageBuffer0)->header.wBlockID) != MS_BOOT_BLOCK_ID) || + (be16_to_cpu(((struct ms_bootblock_page0 *)PageBuffer0)->header.wFormatVersion) != MS_BOOT_BLOCK_FORMAT_VERSION) || + (((struct ms_bootblock_page0 *)PageBuffer0)->header.bNumberOfDataEntry != MS_BOOT_BLOCK_DATA_ENTRIES)) + continue; + + if (btBlk1st != MS_LB_NOT_USED) { + btBlk2nd = TmpBlock; + break; + } + + btBlk1st = TmpBlock; + memcpy(PageBuffer1, PageBuffer0, MS_BYTES_PER_PAGE); + if (extdat.status1 & (MS_REG_ST1_DTER | MS_REG_ST1_EXER | MS_REG_ST1_FGER)) + btBlk1stErred = 1; + } + + if (btBlk1st == MS_LB_NOT_USED) { + result = MS_STATUS_ERROR; + goto exit; + } + + /* write protect */ + if ((extdat.status0 & MS_REG_ST0_WP) == MS_REG_ST0_WP_ON) + ms_lib_ctrl_set(info, MS_LIB_CTRL_WRPROTECT); + + result = MS_STATUS_ERROR; + /* 1st Boot Block */ + if (btBlk1stErred == 0) + result = ms_lib_process_bootblock(us, btBlk1st, PageBuffer1); + /* 1st */ + /* 2nd Boot Block */ + if (result && (btBlk2nd != MS_LB_NOT_USED)) + result = ms_lib_process_bootblock(us, btBlk2nd, PageBuffer0); + + if (result) { + result = MS_STATUS_ERROR; + goto exit; + } + + for (TmpBlock = 0; TmpBlock < btBlk1st; TmpBlock++) + info->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR; + + info->MS_Lib.Phy2LogMap[btBlk1st] = MS_LB_BOOT_BLOCK; + + if (btBlk2nd != MS_LB_NOT_USED) { + for (TmpBlock = btBlk1st + 1; TmpBlock < btBlk2nd; TmpBlock++) + info->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR; + + info->MS_Lib.Phy2LogMap[btBlk2nd] = MS_LB_BOOT_BLOCK; + } + + result = ms_lib_scan_logicalblocknumber(us, btBlk1st); + if (result) + goto exit; + + for (TmpBlock = MS_PHYSICAL_BLOCKS_PER_SEGMENT; + TmpBlock < info->MS_Lib.NumberOfPhyBlock; + TmpBlock += MS_PHYSICAL_BLOCKS_PER_SEGMENT) { + if (ms_count_freeblock(us, TmpBlock) == 0) { + ms_lib_ctrl_set(info, MS_LIB_CTRL_WRPROTECT); + break; + } + } + + /* write */ + if (ms_lib_alloc_writebuf(us)) { + result = MS_NO_MEMORY_ERROR; + goto exit; + } + + result = MS_STATUS_SUCCESS; + +exit: + kfree(PageBuffer1); + kfree(PageBuffer0); + + printk(KERN_INFO "MS_CardInit end\n"); + return result; +} + +static int ene_ms_init(struct us_data *us) +{ + struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; + int result; + u8 buf[0x200]; + u16 MSP_BlockSize, MSP_UserAreaBlocks; + struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; + + printk(KERN_INFO "transport --- ENE_MSInit\n"); + + /* the same part to test ENE */ + + result = ene_load_bincode(us, MS_INIT_PATTERN); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR "Load MS Init Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + + memset(bcb, 0, sizeof(struct bulk_cb_wrap)); + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->DataTransferLength = 0x200; + bcb->Flags = 0x80; + bcb->CDB[0] = 0xF1; + bcb->CDB[1] = 0x01; + + result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR "Execution MS Init Code Fail !!\n"); + return USB_STOR_TRANSPORT_ERROR; + } + /* the same part to test ENE */ + info->MS_Status = *(struct MS_STATUS *)&buf[0]; + + if (info->MS_Status.Insert && info->MS_Status.Ready) { + printk(KERN_INFO "Insert = %x\n", info->MS_Status.Insert); + printk(KERN_INFO "Ready = %x\n", info->MS_Status.Ready); + printk(KERN_INFO "IsMSPro = %x\n", info->MS_Status.IsMSPro); + printk(KERN_INFO "IsMSPHG = %x\n", info->MS_Status.IsMSPHG); + printk(KERN_INFO "WtP= %x\n", info->MS_Status.WtP); + if (info->MS_Status.IsMSPro) { + MSP_BlockSize = (buf[6] << 8) | buf[7]; + MSP_UserAreaBlocks = (buf[10] << 8) | buf[11]; + info->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks; + } else { + ms_card_init(us); /* Card is MS (to ms.c)*/ + } + US_DEBUGP("MS Init Code OK !!\n"); + } else { + US_DEBUGP("MS Card Not Ready --- %x\n", buf[0]); + return USB_STOR_TRANSPORT_ERROR; + } + + return USB_STOR_TRANSPORT_GOOD; +} + static int ene_sd_init(struct us_data *us) { int result; @@ -619,7 +2197,13 @@ static int ene_init(struct us_data *us) return USB_STOR_TRANSPORT_ERROR; } } - + if (misc_reg03 & 0x02) { + if (!info->MS_Status.Ready) { + result = ene_ms_init(us); + if (result != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; + } + } return result; } @@ -662,6 +2246,41 @@ static int sd_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) return result; } +/* + * ms_scsi_irp() + */ +int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) +{ + int result; + struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra; + info->SrbStatus = SS_SUCCESS; + switch (srb->cmnd[0]) { + case TEST_UNIT_READY: + result = ms_scsi_test_unit_ready(us, srb); + break; /* 0x00 */ + case INQUIRY: + result = ms_scsi_inquiry(us, srb); + break; /* 0x12 */ + case MODE_SENSE: + result = ms_scsi_mode_sense(us, srb); + break; /* 0x1A */ + case READ_CAPACITY: + result = ms_scsi_read_capacity(us, srb); + break; /* 0x25 */ + case READ_10: + result = ms_scsi_read(us, srb); + break; /* 0x28 */ + case WRITE_10: + result = ms_scsi_write(us, srb); + break; /* 0x2A */ + default: + info->SrbStatus = SS_ILLEGAL_REQUEST; + result = USB_STOR_TRANSPORT_FAILED; + break; + } + return result; +} + static int ene_transport(struct scsi_cmnd *srb, struct us_data *us) { int result = 0; @@ -669,11 +2288,15 @@ static int ene_transport(struct scsi_cmnd *srb, struct us_data *us) /*US_DEBUG(usb_stor_show_command(srb)); */ scsi_set_resid(srb, 0); - if (unlikely(!info->SD_Status.Ready)) + if (unlikely(!(info->SD_Status.Ready || info->MS_Status.Ready))) { result = ene_init(us); - else - result = sd_scsi_irp(us, srb); + } else { + if (info->SD_Status.Ready) + result = sd_scsi_irp(us, srb); + if (info->MS_Status.Ready) + result = ms_scsi_irp(us, srb); + } return 0; } @@ -714,10 +2337,8 @@ static int ene_ub6250_probe(struct usb_interface *intf, } if (!(misc_reg03 & 0x01)) { - result = -ENODEV; - printk(KERN_NOTICE "ums_eneub6250: The driver only supports SD card. " - "To use SM/MS card, please build driver/staging/keucr\n"); - usb_stor_disconnect(intf); + pr_info("ums_eneub6250: The driver only supports SD/MS card. " + "To use SM card, please build driver/staging/keucr\n"); } return result;